Update Design and Implements of ColorUI.

This commit is contained in:
Kirigaya Kazuto 2017-05-14 14:57:29 +08:00
parent 3a43697243
commit d592a5abe9
2 changed files with 451 additions and 13 deletions

View File

@ -1,8 +1,9 @@
#include "ColorUI.h"
#include <algorithm>
#include <windows.h>
#include <conio.h>
namespace _ColorUI_Internal_Namespace
namespace _cns
{
class _auto_init_console_info_class
@ -92,6 +93,8 @@ inline int _ConsoleColor2winBackColor(ConsoleColor conColor)
return BACKGROUND_RED | BACKGROUND_GREEN;
case ConsoleColor::white:
return BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
default:
return 0;
}
}
@ -160,7 +163,7 @@ KEY GetUserInputKey()
}
}
int GetAction(int& cid,int MinVal,int MaxVal,int EscapeVal=MaxVal)
int GetAction(int& cid,int MinVal,int MaxVal,int EscapeVal)
{
KEY t=GetUserInputKey();
switch(t)
@ -197,9 +200,432 @@ int GetAction(int& cid,int MinVal,int MaxVal,int EscapeVal=MaxVal)
}
}
}/// End of namespace _ColorUI_Internal_Namespace
}/// End of namespace _cns
ColorSelection::ColorSelection()
{
frontColorNormal=ConsoleColor::white;
backColorNormal=ConsoleColor::black;
frontColorActivate=ConsoleColor::black;
backColorActivate=ConsoleColor::yellow;
_is_active=false;
_pframe=nullptr;
}
//virtual
ColorSelection::~ColorSelection()
{
}
//virtual
void ColorSelection::drawText()
{
if(_is_active)
{
_cns::cprint(frontColorActivate,backColorActivate);
}
else
{
_cns::cprint(frontColorNormal,backColorNormal);
}
printf("%s",text.c_str());
}
//virtual
void ColorSelection::drawInfo()
{
printf("%s",info.c_str());
}
bool ColorSelection::hasInfo()
{
return !info.empty();
}
//virtual
void ColorSelection::onActivate()
{
_is_active=true;
}
//virtual
void ColorSelection::onDeActivate()
{
_is_active=false;
}
ColorFrame* ColorSelection::getFrame()
{
return _pframe;
}
void ColorSelection::setFrame(ColorFrame* pFrame)
{
_pframe=pFrame;
}
//virtual
int ColorSelection::onClick()
{
return 0;
}
//virtual
int ColorSelection::onDelete()
{
return 0;
}
ColorPage::ColorPage()
{
titleFrontColor=ConsoleColor::black;
titleBackColor=ConsoleColor::lightblue;
textFrontColor=ConsoleColor::white;
textBackColor=ConsoleColor::black;
_curActive=0;
_pframe=nullptr;
}
//virtual
ColorPage::~ColorPage()
{
}
void ColorPage::add(ColorSelection* p)
{
_vec.push_back(p);
}
int ColorPage::del(ColorSelection* p)
{
auto iter=std::find(_vec.begin(),_vec.end(),p);
if(iter==_vec.end())
{
/// Object to delete is Not Found
return 1;
}
if(_curActive==iter-_vec.begin()+1)
{
/// Current Activated Selection is to be deleted.
_curActive=0;
_vec.erase(iter);
}
else
{
ColorSelection* _curActive_ptr=_vec.at(_curActive-1);
_vec.erase(iter);
_curActive=std::find(_vec.begin(),_vec.end(),_curActive_ptr)-_vec.begin()+1;
}
return 0;
}
int ColorPage::getSelectionSize() const
{
return _vec.size();
}
int ColorPage::getCurrentActive() const
{
return _curActive;
}
ColorFrame* ColorPage::getFrame()
{
return _pframe;
}
void ColorPage::setFrame(ColorFrame* pFrame)
{
_pframe=pFrame;
}
//virtual
void ColorPage::draw()
{
if(!title.empty())
{
_cns::cprint(titleFrontColor,titleBackColor);
printf("%s\n",title.c_str());
}
if(!text.empty())
{
_cns::cprint(textFrontColor,textBackColor);
printf("%s\n",text.c_str());
}
if(!_curActive) // _curActive==0
{
if(!_vec.empty())
{
_curActive=1;
onSelectionOver(_curActive);
}
}
for(auto iter=_vec.begin();iter!=_vec.end();++iter)
{
if(!(*iter)->text.empty())
{
(*iter)->drawText();
}
else
{
_cns::cprint();
printf("(Empty Selection)");
}
printf("\n");
}
_cns::cprint();
printf("---------------\n");
if(_vec.at(_curActive-1)->hasInfo())
{
_vec.at(_curActive-1)->drawInfo();
printf("\n");
}
_cns::cprint();
}
//virtual
int ColorPage::onLoad()
{
return 0;
}
//virtual
void ColorPage::onBackground()
{
}
//virtual
void ColorPage::onForeground()
{
}
//virtual
int ColorPage::onUnload()
{
for(auto& ptr:_vec)
{
if(!ptr->onDelete())
{
delete ptr;
}
}
_vec.clear();
_curActive=0;
return 0;
}
//virtual
void ColorPage::onSelectionOver(int id)
{
_vec.at(_curActive-1)->onDeActivate();
_vec.at(id-1)->onActivate();
_curActive=id;
}
//virtual
int ColorPage::onActive(int id)
{
return _vec.at(id-1)->onClick();
}
//protected
std::vector<ColorSelection*>& ColorPage::_getvec()
{
return _vec;
}
ColorFrame::ColorFrame()
{
_home_page=nullptr;
_cur_page=nullptr;
_next_page=nullptr;
_delete_home_page_on_dtor=true;
_has_started=false;
}
void ColorFrame::setHomePage(ColorPage* pPage,bool deleteOnRemove)
{
if(_has_started) return;
_home_page=pPage;
_delete_home_page_on_dtor=deleteOnRemove;
}
ColorPage* ColorFrame::getHomePage()
{
return _home_page;
}
void ColorFrame::jumpTo(ColorPage* nextPage)
{
_next_page=nextPage;
}
void ColorFrame::clearScreen()
{
_cns::cprint();
system("cls");
}
void ColorFrame::clearInput()
{
fflush(stdin);
}
void ColorFrame::enterInputMode()
{
clearInput();
}
void ColorFrame::exitInputMode()
{
clearInput();
}
void ColorFrame::run()
{
/// A Frame can only be started once.
if(_has_started) return;
_has_started=true;
/// No Home Page
if(_home_page==nullptr) return;
_cur_page=_home_page;
_cur_page->onLoad();
bool stop=false;
int cid=0;
while(!stop)
{
clearScreen();
_cur_page->draw();
if(_cur_page->getSelectionSize()>0)
{
cid=_cur_page->getCurrentActive();
if(_cns::GetAction(cid,1,_cur_page->getSelectionSize(),_cur_page->getSelectionSize()))
{
/// Confirmed Key Pressed.
switch(_cur_page->onActive(cid))
{
case 0:
{
if(_next_page!=nullptr)
{
/// New Page!
/// Bring Current Page to Background
_cur_page->onBackground();
_stk.push(_cur_page);
/// Load New Page
_cur_page=_next_page;
_next_page=nullptr;
_cur_page->onLoad();
}
else
{
/// No New Page. Go Straight.
}
}
break;
case 1:
{
/// Unload Current Page
if(_cur_page->onUnload()==0)
{
delete _cur_page;
}
_cur_page=nullptr;
/// Bring Previous Page to Foreground.
if(_stk.empty())
{
stop=true;
}
else
{
_cur_page=_stk.top();
_stk.pop();
_cur_page->onForeground();
}
}
break;
case 2:
default:
stop=true;
break;
}
}
else
{
/// If not confirmed , just go ahead.
}
}
else
{
/// No Selection on this page
/// Unload Current Page
if(_cur_page->onUnload()==0)
{
delete _cur_page;
}
_cur_page=nullptr;
/// Bring Previous Page to Foreground.
if(_stk.empty())
{
stop=true;
}
else
{
_cur_page=_stk.top();
_stk.pop();
_cur_page->onForeground();
}
}
}
if(_cur_page)
{
if(_cur_page->onUnload()==0)
{
delete _cur_page;
}
_cur_page=nullptr;
}
while(!_stk.empty())
{
_cur_page=_stk.top();
_cur_page->onForeground();
if(_cur_page->onUnload()==0)
{
delete _cur_page;
}
}
_cur_page=nullptr;
}
ColorInputModeGuard::ColorInputModeGuard(ColorFrame* f)
{
_pframe=f;
if(_pframe)
{
_pframe->enterInputMode();
}
}
ColorInputModeGuard::~ColorInputModeGuard()
{
if(_pframe)
{
_pframe->exitInputMode();
}
}

View File

@ -1,6 +1,6 @@
#pragma once
#include <string>
#include <list>
#include <vector>
#include <stack>
enum class ConsoleColor { black=0,red=1,green=2,yellow=3,blue=4,purple=5,lightblue=6,deepgreen=6,white=7 };
@ -21,8 +21,8 @@ public:
virtual void drawInfo();
bool hasInfo();
void onActivate();
void onDeActivate();
virtual void onActivate();
virtual void onDeActivate();
ColorFrame* getFrame();
void setFrame(ColorFrame*);
@ -31,6 +31,9 @@ public:
/// return 1 to return last page.(If no page to return, exit the program)
/// return 0 to continue running.(If you want to change page, you should return 0) (default)
virtual int onClick();
/// return 0 tells the frame to delete this selection. (default)
virtual int onDelete();
private:
bool _is_active;
ColorFrame* _pframe;
@ -46,11 +49,12 @@ public:
virtual ~ColorPage();
/// Add and delete ColorSelections.
void add(ColorSelection* p);
int del(ColorSelection* p);
void add(ColorSelection*);
int del(ColorSelection*);
/// Called by ColorFrame (mostly). Let Frame know how many selections have been added.
int getSelectionSize();
int getSelectionSize() const;
int getCurrentActive() const;
ColorFrame* getFrame();
void setFrame(ColorFrame*);
@ -69,16 +73,16 @@ public:
/// Called when a selection is selected or unselected.
virtual void onSelectionOver(int id);
virtual void onSelectionOut(int id);
/// Returns ColorSelection::onClick()
virtual int onActive(int id);
protected:
/// Get internal selection list, for derived class use.
std::list<ColorSelection*>& _getlst();
std::vector<ColorSelection*>& _getvec();
private:
std::list<ColorSelection*> _lst;
std::vector<ColorSelection*> _vec;
int _curActive;
ColorFrame* _pframe;
};
class ColorFrame
@ -87,8 +91,9 @@ public:
ColorFrame();
~ColorFrame();
void setHomePage(ColorPage*);
ColorPage* getHomePage();
/// Home Page Can ONLY be set before run.
void setHomePage(ColorPage*,bool deleteOnRemove=true);
void run();
@ -101,11 +106,16 @@ public:
void enterInputMode();
void exitInputMode();
/// [ONLY FOR EXPERIMENTAL USE]
void clearScreen();
void clearInput();
private:
ColorPage* _home_page;
ColorPage* _cur_page;
ColorPage* _next_page;
bool _delete_home_page_on_dtor;
bool _has_started;
std::stack<ColorPage*> _stk;
};
@ -114,4 +124,6 @@ class ColorInputModeGuard
public:
ColorInputModeGuard(ColorFrame* f);
~ColorInputModeGuard();
private:
ColorFrame* _pframe;
};