C++控制臺(tái)強(qiáng)化如何實(shí)現(xiàn)一定界面效果(簡潔版)
TANXL_CONSOLE_LIST VERSION_1_4
在完成了游戲存檔模塊的開發(fā)之后,我試圖用之前制作的Console_List頭文件為基礎(chǔ),制作一個(gè)命令行上的數(shù)據(jù)管理器,但是在實(shí)際使用中我發(fā)現(xiàn)了Console_List的各種不足。
比如提供了接口之后還需要用戶輸入大量的代碼來完成表格的輸出,明顯不能做到讓接口容易被正確使用,不易被誤用。
于是在這個(gè)背景下,我對(duì)Console_List進(jìn)行了完全重寫,在比前幾代代碼減少2/3的情況下,功能大幅加強(qiáng),同時(shí)只需要一次物品初始化,一次調(diào)用顯示函數(shù),明顯更加容易使用。
TANXL_CONSOLE_LIST.H VERSION_1_4
#ifndef TANXL_CONSOLE_LIST #define TANXL_CONSOLE_LIST #ifndef TANXL_LIST//檢查是否使用了其他版本的TANXL_CONSOLE_LIST #define TANXL_LIST #define LIST 1 #endif #endif #if LIST #ifndef IOSTREAM//檢查是否已經(jīng)包含IOSTREAM #define IOSTREAM #include <iostream> #endif #ifndef VECTOR//檢查是否已經(jīng)包含VECTOR #define VECTOR #include <vector> #endif #ifndef CONIO_H//檢查是否已經(jīng)包含CONIO_H #define CONIO_H #include <conio.h> #endif #ifndef IOMANIP//檢查是否已經(jīng)包含IOMANIP #define IOMANIP #include <iomanip> #endif //void Col是原Console_List的核心功能,使用了Linux控制臺(tái)的指令 void Col(unsigned ColN = NULL, bool Under_Line = false)//設(shè)置自定義行的背景顏色 { if (ColN == NULL)std::cout << "\033[0m";//清除顏色 else { if (Under_Line == true) std::cout << "\033[7m"; std::cout << "\033[4;1;m"; if (((ColN & 0xf0) >> 4) > 0 && ((ColN & 0xf0) >> 4) <= 7) std::cout << "\033[3" << ((ColN & 0xf0) >> 4) << "m"; else if ((ColN & 0xf0) >> 4 == 0);//值為0不作修改 else//字體顏色: 1紅色 2綠色 3橙色 4藍(lán)色 5紫色 6淡藍(lán) 7白色 std::cout << "\033[3" << rand() % 7 + 1 << "m"; if ((ColN & 0x0f) > 0 && ((ColN & 0x0f) <= 7)) std::cout << "\033[4" << (ColN & 0x0f) << "m"; else if ((ColN & 0x0f) == 0);//值為0不作修改 else//背景顏色: 1紅色 2綠色 3橙色 4藍(lán)色 5紫色 6淡藍(lán) 7白色 std::cout << "\033[4" << rand() % 7 + 1 << "m"; } } //第三級(jí)別的物品結(jié)構(gòu) struct Function { //void Page_Info() { Col(); std::cout << "This: " << Selector << " - Total: " << SonList.size() << " - Max: " << (SSpace & 0x0000ff) << std::endl; } Function() :Name("NULL"), /*SonList(NULL),*/ Func(NULL) {}; Function(std::string N, void(*F)()) :Name(N),/* SonList(NULL),*/ Func(F) {}; //int Selector{ 0 }; //bool Is_Selected{ false }; std::string Name; void(*Func)(); unsigned SSpace{ 0x171109 };//選項(xiàng)和標(biāo)題的空格數(shù) AA-BB-CC AA左空格 BB右空格 CC頁面物品限制數(shù)量 //std::vector<Function>SonList; }; //第二級(jí)別的物品結(jié)構(gòu) struct Main_Function { void Page_Info() { Col(); std::cout << "This: " << Selector << " - Total: " << SonList.size() << " - Max: " << (SSpace & 0x0000ff) << std::endl; } Main_Function(std::string N = "NULL") :Name(N), SonList(NULL) {}; Main_Function(std::string N, void(*F)()) :Name(N), SonList(NULL), Func(F) {}; int Selector{ 0 }; bool Is_Selected{ false }; std::string Name; void(*Func)() { NULL }; unsigned SSpace{ 0x171109 };//選項(xiàng)和標(biāo)題的空格數(shù) AA-BB-CC AA左空格 BB右空格 CC頁面物品限制數(shù)量 std::vector<Function>SonList; }; //第一級(jí)別的主要物品類 class CONSOLE_LIST { public: void Display(); void Append_Item(std::string New_Item) { SonList.push_back(Main_Function(New_Item)); };//添加二級(jí)物品作為選項(xiàng) //At用于指定第幾個(gè)二級(jí)物品,后續(xù)兩個(gè)量用于生成一個(gè)新的三級(jí)物品 void Append_Svec(int At, std::string Name, void(*Func)()) { SonList.at(At).SonList.push_back(Function(Name, Func)); };//添加二級(jí)物品下的三級(jí)物品,同時(shí)綁定一個(gè)void類型的函數(shù) private: void Page_Info() { Col(); std::cout << "This: " << Selector << " - Total: " << SonList.size() << " - Max: " << (SSpace & 0x0000ff) << std::endl; }//輸出當(dāng)前頁面信息 bool Insert_Action(int* Action_Num, bool* Action_Bol, size_t List_Size);//輸入操作 int Selector{ 0 }; int Pages{ 0 }; bool Is_Selected{ false }; std::vector<Main_Function>SonList; unsigned SSpace{ 0x171109 };//選項(xiàng)和標(biāo)題的空格數(shù) AA-BB-CC AA左空格 BB右空格 CC頁面物品限制數(shù)量 }; void CONSOLE_LIST::Display() { Col(); bool flag{ true }; bool brea{ false }; while (true) { if (!flag) { Is_Selected = false; flag = true; continue; } system("cls"); int* Num{ &Selector }; bool* Bol{ &Is_Selected }; size_t Siz{ SonList.size() }; for (int i = 0; i < SonList.size(); i++) { if (i == Selector) Col(0x71); else Col(0x17); std::cout << std::setw((SSpace & 0xff0000) >> 16) << SonList.at(i).Name << std::setw((SSpace & 0x00ff00) >> 8) << " " << std::endl; if (i == Selector && Is_Selected == true) { Pages = SonList.at(i).Selector / (SSpace & 0x0000ff); for (int j = Pages * (SSpace & 0x0000ff), count = 0; j < SonList.at(i).SonList.size() && count < (SSpace & 0x0000ff); j++&& count++) { if (j == SonList.at(i).Selector) Col(0x71); else Col(0x17); std::cout << std::setw((SSpace & 0xff0000) >> 16) << SonList.at(i).SonList.at(j).Name << std::setw((SSpace & 0x00ff00) >> 8) << " " << std::endl; if (SonList.at(i).Is_Selected == true && j == SonList.at(i).Selector) { SonList.at(i).SonList.at(j).Func(); SonList.at(i).Is_Selected = false; brea = true; break; } } SonList.at(i).Page_Info(); if (brea) break; Num = &SonList.at(i).Selector; Bol = &SonList.at(i).Is_Selected; Siz = SonList.at(i).SonList.size(); } std::cout << std::endl; } Page_Info(); if (brea) { brea = false; continue; } Col(); flag = Insert_Action(Num, Bol, Siz);//等待輸入 } } bool CONSOLE_LIST::Insert_Action(int* Action_Num, bool* Action_Bol, size_t List_Size) { char key = _getch(); if (key == 'c' || key == 'C')//如果輸入了大小寫的C則返回上一級(jí) { *Action_Bol = false; return false; } if (static_cast<int>(key - 48) >= 0 && static_cast<int>(key - 48) <= 9)//判斷是否是從零到九的數(shù)字 { if (static_cast<int>(key - 48) <= List_Size)//如果是,且小于等于選項(xiàng)總數(shù)則直接指定這個(gè)選項(xiàng) *Action_Num = static_cast<int>(key - 48) - 1; else *Action_Num = static_cast<int>(List_Size) - 1;//如果超出了最大值,則指向最大值 *Action_Bol = true; } else if (key == 'w' || key == 'W' || key == 72)//如果輸入了大小寫的W或者上箭頭,則執(zhí)行MoveUp函數(shù) *Action_Num = *Action_Num == 0 ? static_cast<int>(List_Size) - 1 : -- * Action_Num; else if (key == 's' || key == 'S' || key == 80)//如果輸入了大小寫的S或者下箭頭,則執(zhí)行MoveDown函數(shù) *Action_Num = *Action_Num == static_cast<int>(List_Size) - 1 ? 0 : ++ * Action_Num; else if (key == 'a' || key == 'A' || key == 75)//如果輸入了大小寫的A或者左箭頭,則執(zhí)行向上翻頁函數(shù) *Action_Num = *Action_Num - static_cast<int>(SSpace & 0x0000ff) < 0 ? 0 : *Action_Num - (SSpace & 0x0000ff); else if (key == 'd' || key == 'D' || key == 77)//如果輸入了大小寫的D或者右箭頭,則執(zhí)行向下翻頁函數(shù) *Action_Num = *Action_Num + (SSpace & 0x0000ff) > static_cast<int>(List_Size) - 1 ? static_cast<int>(List_Size) - 1 : *Action_Num + (SSpace & 0x0000ff); else if (key == '\r')//回車確認(rèn) *Action_Bol = true; return true; } #endif
以下為使用例:
Main.cpp
#include "TANXL_CONSOLE_LIST.h" void say() { Col(); system("cls"); std::cout << "wdnmd"; system("pause"); } int main() { CONSOLE_LIST TSM; TSM.Append_Item("數(shù)據(jù)管理"); TSM.Append_Svec(0, "數(shù)據(jù)管理1", &say); TSM.Append_Svec(0, "數(shù)據(jù)管理2", &say); TSM.Append_Svec(0, "數(shù)據(jù)管理3", &say); TSM.Append_Svec(0, "數(shù)據(jù)管理4", &say); TSM.Append_Svec(0, "數(shù)據(jù)管理5", &say); TSM.Append_Svec(0, "數(shù)據(jù)管理6", &say); TSM.Append_Svec(0, "數(shù)據(jù)管理7", &say); TSM.Append_Svec(0, "數(shù)據(jù)管理8", &say); TSM.Append_Svec(0, "數(shù)據(jù)管理9", &say); TSM.Append_Svec(0, "數(shù)據(jù)管理10", &say); TSM.Append_Svec(0, "數(shù)據(jù)管理11", &say); TSM.Append_Svec(0, "數(shù)據(jù)管理12", &say); TSM.Append_Svec(0, "數(shù)據(jù)管理13", &say); TSM.Append_Svec(0, "數(shù)據(jù)管理14", &say); TSM.Append_Svec(0, "數(shù)據(jù)管理15", &say); TSM.Append_Item("添加數(shù)據(jù)"); TSM.Append_Svec(1, "添加數(shù)據(jù)1", &say); TSM.Append_Svec(1, "添加數(shù)據(jù)2", &say); TSM.Append_Svec(1, "添加數(shù)據(jù)3", &say); TSM.Append_Item("查看數(shù)據(jù)"); TSM.Append_Svec(2, "查看數(shù)據(jù)1", &say); TSM.Append_Svec(2, "查看數(shù)據(jù)2", &say); TSM.Append_Svec(2, "查看數(shù)據(jù)3", &say); TSM.Append_Item("修改數(shù)據(jù)"); TSM.Append_Svec(3, "修改數(shù)據(jù)1", &say); TSM.Append_Svec(3, "修改數(shù)據(jù)2", &say); TSM.Append_Svec(3, "修改數(shù)據(jù)3", &say); TSM.Append_Item("退出程序"); TSM.Append_Svec(4, "_-確認(rèn)-_", &say); TSM.Append_Svec(4, "_-取消-_", &say); TSM.Display(); }
TANXL_CONSOLE_LIST.H VERSION_1_5
再次對(duì)幾乎所有函數(shù)進(jìn)行重寫,為了操作的一致性移除了三級(jí)物品的設(shè)定,統(tǒng)一由類來進(jìn)行管理。通過遞歸的方法實(shí)現(xiàn)輸出列表,理論上能無限擴(kuò)展深度。
三級(jí)列表
六級(jí)列表
TANXL_CONSOLE_LIST.H VERSION_1_5
// 移除Main_Function Function并將功能整合至CONSOLE類 // 絕大多數(shù)函數(shù)重寫以支持多于一層的表格輸出
#ifndef TANXL_CONSOLE_LIST #define TANXL_CONSOLE_LIST #ifndef TANXL_LIST//檢查是否使用了其他版本的TANXL_CONSOLE_LIST #define TANXL_LIST #define LIST 1 #endif #endif #if LIST #ifndef IOSTREAM//檢查是否已經(jīng)包含IOSTREAM #define IOSTREAM #include <iostream> #endif #ifndef VECTOR//檢查是否已經(jīng)包含VECTOR #define VECTOR #include <vector> #endif #ifndef CONIO_H//檢查是否已經(jīng)包含CONIO_H #define CONIO_H #include <conio.h> #endif #ifndef IOMANIP//檢查是否已經(jīng)包含IOMANIP #define IOMANIP #include <iomanip> #endif //void Col是原Console_List的核心功能,使用了Linux控制臺(tái)的指令 void Col(unsigned ColN = NULL, bool Under_Line = false);//設(shè)置自定義行的背景顏色 //物品類 class CONSOLE { public: explicit CONSOLE(std::string Name = "UNdefined", unsigned Space = 0x171109, void(*FunC)() = NULL); void Display(int Depth = 0, unsigned Def_Col = 0x71, unsigned Real_Sel = 0x75); void MainLoop(); void Append_Item(std::string New_Item, unsigned Col, void(*FunC)(), int Depth = 0, int* Ids = 0); private: bool Insert_Action(int* Action_Num, bool* Action_Bol, size_t List_Size); CONSOLE* Locate(int Target = 0); std::string Name; int Selector; int Page; bool Is_Selected; bool Is_Funcwork; std::vector<CONSOLE>SonList; void (*Func)(); unsigned SSpace;// { 0x171109 }選項(xiàng)和標(biāo)題的空格數(shù) AA-BB-CC AA左空格 BB右空格 CC頁面物品限制數(shù)量 }; #endif
TANXL_CONSOLE_LIST.CPP VERSION_1_5
#include "TANXL_CONSOLE_LIST.h" //void Col是原Console_List的核心功能,使用了Linux控制臺(tái)的指令 void Col(unsigned ColN, bool Under_Line)//設(shè)置自定義行的背景顏色 { if (ColN == NULL)std::cout << "\033[0m";//清除顏色 else { if (Under_Line == true) std::cout << "\033[7m"; std::cout << "\033[4;1;m"; if (((ColN & 0xf0) >> 4) > 0 && ((ColN & 0xf0) >> 4) <= 7) std::cout << "\033[3" << ((ColN & 0xf0) >> 4) << "m"; else if ((ColN & 0xf0) >> 4 == 0);//值為0不作修改 else//字體顏色: 1紅色 2綠色 3橙色 4藍(lán)色 5紫色 6淡藍(lán) 7白色 std::cout << "\033[3" << rand() % 7 + 1 << "m"; if ((ColN & 0x0f) > 0 && ((ColN & 0x0f) <= 7)) std::cout << "\033[4" << (ColN & 0x0f) << "m"; else if ((ColN & 0x0f) == 0);//值為0不作修改 else//背景顏色: 1紅色 2綠色 3橙色 4藍(lán)色 5紫色 6淡藍(lán) 7白色 std::cout << "\033[4" << rand() % 7 + 1 << "m"; } } //構(gòu)造函數(shù) CONSOLE::CONSOLE(std::string NamE, unsigned Space, void(*FunC)()) :Selector(0), Is_Selected(false), SonList(NULL), SSpace(Space), Func(FunC), Is_Funcwork(true), Name(NamE),Page(0) { if (Func == NULL) Is_Funcwork = false; } //添加函數(shù) void CONSOLE::Append_Item(std::string New_Item, unsigned Col, void (*FunC)(), int Depth, int* Ids) { if (Depth == 0) SonList.push_back(CONSOLE(New_Item, Col, FunC)); else { CONSOLE* CP{ this }; for (int i = 0; i < Depth; i++) CP = &CP->SonList.at(Ids[i]); CP->SonList.push_back(CONSOLE(New_Item, Col, FunC)); } } void CONSOLE::Display(int Depth, unsigned Def_Col, unsigned Real_Sel) { Col(); bool Is_Line_Need{ false }; Page = this->Selector / (SSpace & 0x00ff); for (int i = Page * (SSpace & 0x00ff); i < SonList.size() && i < (Page+1)*(SSpace & 0x00ff); i++) { for (int j = Depth; j > 0; j--) std::cout << "\t"; if (i == Selector) Col(Real_Sel); else Col(Def_Col); std::cout << std::setw((SSpace & 0xff0000) >> 16) << SonList.at(i).Name << std::setw((SSpace & 0x00ff00) >> 8) << " " << std::endl; Col(); if (SonList.at(i).SonList.size() == 0 && this->Is_Selected == true && this->Selector == i)//在包含子項(xiàng)目為0時(shí)自動(dòng)退出 { if (SonList.at(i).Is_Funcwork) SonList.at(i).Func(); this->Is_Selected = false; } if (SonList.at(i).SonList.size() != 0 && this->Is_Selected == true && this->Selector == i) { std::cout << std::endl; this->SonList.at(i).Display(Depth + 1, (Def_Col & 0x0f) * 16 + (Def_Col & 0xf0) / 16, Real_Sel); Is_Line_Need = 1; } if (!Is_Line_Need) std::cout << std::endl; if (Is_Line_Need) Is_Line_Need = false; Col(); } } void CONSOLE::MainLoop()//主循環(huán) { bool Insert{ true }; bool Cover{ false }; int* Action_Num { &Locate()->Selector}; bool* Action_Bol{ &Locate()->Is_Selected }; size_t List_Size{ Locate()->SonList.size() }; while (1) { system("cls"); this->Display(); if (!Cover) { Action_Num = &Locate()->Selector; Action_Bol = &Locate()->Is_Selected; List_Size = Locate()->SonList.size(); } else Cover = false; if (!Insert) { Action_Num = &Locate(-1)->Selector; Action_Bol = &Locate(-1)->Is_Selected; List_Size = Locate(-1)->SonList.size(); Locate(-1)->Is_Selected = false; Insert = true; Cover = true; continue; } Insert = Insert_Action(Action_Num, Action_Bol, List_Size); } } bool CONSOLE::Insert_Action(int* Action_Num, bool* Action_Bol, size_t List_Size) { char key = _getch(); if (key == 'c' || key == 'C')//如果輸入了大小寫的C則返回上一級(jí) { *Action_Bol = false; return false; } if (static_cast<int>(key - 48) >= 0 && static_cast<int>(key - 48) <= 9)//判斷是否是從零到九的數(shù)字 { if (static_cast<int>(key - 48) <= static_cast<int>(List_Size))//如果是,且小于等于選項(xiàng)總數(shù)則直接指定這個(gè)選項(xiàng) *Action_Num = static_cast<int>(key - 48) - 1; else *Action_Num = static_cast<int>(List_Size) - 1;//如果超出了最大值,則指向最大值 *Action_Bol = true; } else if (key == 'w' || key == 'W' || key == 72)//如果輸入了大小寫的W或者上箭頭,則執(zhí)行MoveUp函數(shù) *Action_Num = *Action_Num == 0 ? static_cast<int>(List_Size) - 1 : -- * Action_Num; else if (key == 's' || key == 'S' || key == 80)//如果輸入了大小寫的S或者下箭頭,則執(zhí)行MoveDown函數(shù) *Action_Num = *Action_Num == static_cast<int>(List_Size) - 1 ? 0 : ++ * Action_Num; else if (key == 'a' || key == 'A' || key == 75)//如果輸入了大小寫的A或者左箭頭,則執(zhí)行向上翻頁函數(shù) *Action_Num = *Action_Num - static_cast<int>(SSpace & 0x0000ff) < 0 ? 0 : *Action_Num - (SSpace & 0x0000ff); else if (key == 'd' || key == 'D' || key == 77)//如果輸入了大小寫的D或者右箭頭,則執(zhí)行向下翻頁函數(shù) *Action_Num = *Action_Num + static_cast<int>(SSpace & 0x0000ff) > static_cast<int>(List_Size) - 1 ? static_cast<int>(List_Size) - 1 : *Action_Num + (SSpace & 0x0000ff); else if (key == '\r')//回車確認(rèn) *Action_Bol = true; return true; } CONSOLE* CONSOLE::Locate(int Target) { if (Target == 0) { for (int i = 0; i < SonList.size(); i++) { if (i == Selector && Is_Selected == true) return SonList.at(i).Locate(); } return this; } else { for (int i = 0; i < SonList.size(); i++) { if (i == Selector && Is_Selected == true && SonList.at(i).SonList.size() != 0) if (SonList.at(i).Is_Selected == false) return this; else return SonList.at(i).Locate(-1); } return this; } }
Main.CPP(測(cè)試用)
#include "Tanxl_Console_List.h" void say() { Col(); std::cout << "\t\tDefault Function Called" << std::endl; } int main() { CONSOLE TSM; TSM.Append_Item("數(shù)據(jù)管理", 0x171109, &say); TSM.Append_Item("添加數(shù)據(jù)", 0x171109, &say); TSM.Append_Item("查看數(shù)據(jù)", 0x171109, &say); TSM.Append_Item("修改數(shù)據(jù)", 0x171109, &say); TSM.Append_Item("退出程序", 0x171109, &say); int a[] = { 2 }; int b[] = { 2,1 }; TSM.Append_Item("數(shù)據(jù)管理1-", 0x171109, &say, 1, a); TSM.Append_Item("數(shù)據(jù)管理2-", 0x171109, &say, 1, a); TSM.Append_Item("數(shù)據(jù)管理3-", 0x171109, &say, 1, a); TSM.Append_Item("數(shù)據(jù)管理4-", 0x171109, &say, 1, a); TSM.Append_Item("數(shù)據(jù)管理5-", 0x171109, &say, 1, a); TSM.Append_Item("數(shù)據(jù)管理6-", 0x171109, &say, 1, a); TSM.Append_Item("數(shù)據(jù)管理7-", 0x171109, &say, 1, a); TSM.Append_Item("數(shù)據(jù)管理8-", 0x171109, &say, 1, a); TSM.Append_Item("數(shù)據(jù)管理9-", 0x171109, &say, 1, a); TSM.Append_Item("數(shù)據(jù)管理10-", 0x171109, &say, 1, a); TSM.Append_Item("數(shù)據(jù)管理11-", 0x171109, &say, 1, a); TSM.Append_Item("數(shù)據(jù)管理2-1", 0x171109, &say, 2, b); TSM.Append_Item("數(shù)據(jù)管理2-2", 0x171109, &say, 2, b); TSM.Append_Item("數(shù)據(jù)管理2-3", 0x171109, &say, 2, b); TSM.Append_Item("數(shù)據(jù)管理2-4", 0x171109, &say, 2, b); TSM.Append_Item("數(shù)據(jù)管理2-5", 0x171109, &say, 2, b); TSM.Append_Item("數(shù)據(jù)管理2-6", 0x171109, &say, 2, b); TSM.MainLoop(); return 0; }
TANXL_CONSOLE_LIST.H VERSION_1_5+_Final
// 加入枚舉類型用于顏色設(shè)置 使之表現(xiàn)更加直觀 enum EFont_Color { FONT_UNDEFINED = 0x00, FONT_COLOR_RED = 0x10, FONT_COLOR_GREEN = 0x20, FONT_COLOR_ORANGE = 0x30, FONT_COLOR_BLUE = 0x40, FONT_COLOR_PURPLE = 0x50, FONT_COLOR_LIGHTBLUE = 0x60, FONT_COLOR_WHITE = 0x70 }; enum EBack_Color { BACK_UNDEFINED = 0x00, BACK_COLOR_RED = 0x01, BACK_COLOR_GREEN = 0x02, BACK_COLOR_ORANGE = 0x03, BACK_COLOR_BLUE = 0x04, BACK_COLOR_PURPLE = 0x05, BACK_COLOR_LIGHTBLUE = 0x06, BACK_COLOR_WHITE = 0x07 };
void Display(int Depth = 0, unsigned Def_Col = 0x71, unsigned Real_Sel = 0x75); //可以改為更直觀的 ↓ void Display(int Depth = 0, unsigned Def_Col = FONT_COLOR_WHITE | BACK_COLOR_RED, unsigned Real_Sel = FONT_COLOR_WHITE | BACK_COLOR_PURPLE); Col(0x71); /*等價(jià)于*/ Col(FONT_COLOR_WHITE | BACK_COLOR_RED); Col(0x75); /*等價(jià)于*/ Col(FONT_COLOR_WHITE | BACK_COLOR_PURPLE);
TANXL_CONSOLE_LIST.H VERSION_1_5++_Final
細(xì)節(jié)調(diào)整
#ifndef TANXL_CONSOLE_LIST #define TANXL_CONSOLE_LIST #ifndef IOSTREAM//檢查是否已經(jīng)包含IOSTREAM #define IOSTREAM #include <iostream> #endif #ifndef VECTOR//檢查是否已經(jīng)包含VECTOR #define VECTOR #include <vector> #endif #ifndef CONIO_H//檢查是否已經(jīng)包含CONIO_H #define CONIO_H #include <conio.h> #endif #ifndef IOMANIP//檢查是否已經(jīng)包含IOMANIP #define IOMANIP #include <iomanip> #endif enum EFont_Color { FONT_UNDEFINED = 0x00, FONT_COLOR_RED = 0x10, FONT_COLOR_GREEN = 0x20, FONT_COLOR_ORANGE = 0x30, FONT_COLOR_BLUE = 0x40, FONT_COLOR_PURPLE = 0x50, FONT_COLOR_LIGHTBLUE = 0x60, FONT_COLOR_WHITE = 0x70 }; enum EBack_Color { BACK_UNDEFINED = 0x00, BACK_COLOR_RED = 0x01, BACK_COLOR_GREEN = 0x02, BACK_COLOR_ORANGE = 0x03, BACK_COLOR_BLUE = 0x04, BACK_COLOR_PURPLE = 0x05, BACK_COLOR_LIGHTBLUE = 0x06, BACK_COLOR_WHITE = 0x07 }; //void Col是原Console_List的核心功能,使用了Linux控制臺(tái)的指令 void Col(unsigned ColN = NULL, bool Under_Line = false);//設(shè)置自定義行的背景顏色 //物品類 class CONSOLE { public: explicit CONSOLE(std::string Name = "UNdefined", unsigned Space = 0x171109, void(*FunC)() = NULL); void Display(int Depth = 0, unsigned Def_Col = FONT_COLOR_WHITE | BACK_COLOR_RED, unsigned Real_Sel = FONT_COLOR_WHITE | BACK_COLOR_PURPLE); void MainLoop(unsigned Def_Col = FONT_COLOR_WHITE | BACK_COLOR_RED, unsigned Real_Sel = FONT_COLOR_WHITE | BACK_COLOR_PURPLE); void Append_Item(std::string New_Item, unsigned Space = 0x171109, void(*FunC)() = NULL, int Depth = 0, int* Ids = 0); private: bool Insert_Action(int* Action_Num, bool* Action_Bol, size_t List_Size); CONSOLE* Locate(int Target = 0); std::string Name; int Selector; int Page; bool Is_Selected; bool Is_Funcwork; std::vector<CONSOLE>SonList; void (*Func)(); unsigned SSpace;// { 0x171109 }選項(xiàng)和標(biāo)題的空格數(shù) AA-BB-CC AA左空格 BB右空格 CC頁面物品限制數(shù)量 }; #endif
TANXL_CONSOLE_LIST.CPP VERSION_1_5++_Final
#include "TANXL_CONSOLE_LIST.h" //void Col是原Console_List的核心功能,使用了Linux控制臺(tái)的指令 void Col(unsigned ColN, bool Under_Line)//設(shè)置自定義行的背景顏色 { if (ColN == NULL)std::cout << "\033[0m";//清除顏色 else { if (Under_Line == true) std::cout << "\033[7m"; std::cout << "\033[4;1;m"; if (((ColN & 0xf0) >> 4) > 0 && ((ColN & 0xf0) >> 4) <= 7) std::cout << "\033[3" << ((ColN & 0xf0) >> 4) << "m"; else if ((ColN & 0xf0) >> 4 == 0);//值為0不作修改 else//字體顏色: 1紅色 2綠色 3橙色 4藍(lán)色 5紫色 6淡藍(lán) 7白色 std::cout << "\033[3" << rand() % 7 + 1 << "m"; if ((ColN & 0x0f) > 0 && ((ColN & 0x0f) <= 7)) std::cout << "\033[4" << (ColN & 0x0f) << "m"; else if ((ColN & 0x0f) == 0);//值為0不作修改 else//背景顏色: 1紅色 2綠色 3橙色 4藍(lán)色 5紫色 6淡藍(lán) 7白色 std::cout << "\033[4" << rand() % 7 + 1 << "m"; } } //構(gòu)造函數(shù) CONSOLE::CONSOLE(std::string NamE, unsigned Space, void(*FunC)()) :Selector(0), Is_Selected(false), SonList(NULL), SSpace(Space), Func(FunC), Is_Funcwork(true), Name(NamE),Page(0) { if (Func == NULL) Is_Funcwork = false; } //添加函數(shù) void CONSOLE::Append_Item(std::string New_Item, unsigned Space, void (*FunC)(), int Depth, int* Ids) { if (Depth == 0) SonList.push_back(CONSOLE(New_Item, Space, FunC)); else { CONSOLE* CP{ this }; for (int i = 0; i < Depth; i++) CP = &CP->SonList.at(Ids[i]); CP->SonList.push_back(CONSOLE(New_Item, Space, FunC)); } } void CONSOLE::Display(int Depth, unsigned Def_Col, unsigned Real_Sel) { Col(); bool Is_Line_Need{ false }; Page = this->Selector / (SSpace & 0x00ff); for (int i = Page * (SSpace & 0x00ff); i < SonList.size() && i < (Page+1)*(SSpace & 0x00ff); i++) { for (int j = Depth; j > 0; j--) std::cout << "\t"; if (i == Selector) Col(Real_Sel); else Col(Def_Col); std::cout << std::setw((SSpace & 0xff0000) >> 16) << SonList.at(i).Name << std::setw((SSpace & 0x00ff00) >> 8) << " " << std::endl; Col(); if (SonList.at(i).SonList.size() == 0 && this->Is_Selected == true && this->Selector == i)//在包含子項(xiàng)目為0時(shí)自動(dòng)退出 { if (SonList.at(i).Is_Funcwork) SonList.at(i).Func(); this->Is_Selected = false; } if (SonList.at(i).SonList.size() != 0 && this->Is_Selected == true && this->Selector == i) { std::cout << std::endl; this->SonList.at(i).Display(Depth + 1, (Def_Col & 0x0f) * 16 + (Def_Col & 0xf0) / 16, Real_Sel); Is_Line_Need = 1; } if (!Is_Line_Need) std::cout << std::endl; if (Is_Line_Need) Is_Line_Need = false; Col(); } } void CONSOLE::MainLoop(unsigned Def_Col, unsigned Real_Sel) { bool Insert{ true }; bool Cover{ false }; int* Action_Num{ &Locate()->Selector }; bool* Action_Bol{ &Locate()->Is_Selected }; size_t List_Size{ Locate()->SonList.size() }; while (1) { system("cls"); this->Display(); if (!Cover) { Action_Num = &Locate()->Selector; Action_Bol = &Locate()->Is_Selected; List_Size = Locate()->SonList.size(); } else Cover = false; if (!Insert) { Action_Num = &Locate(-1)->Selector; Action_Bol = &Locate(-1)->Is_Selected; List_Size = Locate(-1)->SonList.size(); Locate(-1)->Is_Selected = false; Insert = true; Cover = true; continue; } Insert = Insert_Action(Action_Num, Action_Bol, List_Size); } } bool CONSOLE::Insert_Action(int* Action_Num, bool* Action_Bol, size_t List_Size) { char key = _getch(); if (key == 'c' || key == 'C')//如果輸入了大小寫的C則返回上一級(jí) { *Action_Bol = false; return false; } if (static_cast<int>(key - 48) >= 0 && static_cast<int>(key - 48) <= 9)//判斷是否是從零到九的數(shù)字 { if (static_cast<int>(key - 48) <= static_cast<int>(List_Size))//如果是,且小于等于選項(xiàng)總數(shù)則直接指定這個(gè)選項(xiàng) *Action_Num = static_cast<int>(key - 48) - 1; else *Action_Num = static_cast<int>(List_Size) - 1;//如果超出了最大值,則指向最大值 *Action_Bol = true; } else if (key == 'w' || key == 'W' || key == 72)//如果輸入了大小寫的W或者上箭頭,則執(zhí)行MoveUp *Action_Num = *Action_Num == 0 ? static_cast<int>(List_Size) - 1 : -- * Action_Num; else if (key == 's' || key == 'S' || key == 80)//如果輸入了大小寫的S或者下箭頭,則執(zhí)行MoveDown *Action_Num = *Action_Num == static_cast<int>(List_Size) - 1 ? 0 : ++ * Action_Num; else if (key == 'a' || key == 'A' || key == 75)//如果輸入了大小寫的A或者左箭頭,則執(zhí)行向上翻頁 *Action_Num = *Action_Num - static_cast<int>(SSpace & 0x0000ff) < 0 ? 0 : *Action_Num - (SSpace & 0x0000ff); else if (key == 'd' || key == 'D' || key == 77)//如果輸入了大小寫的D或者右箭頭,則執(zhí)行向下翻頁 *Action_Num = *Action_Num + static_cast<int>(SSpace & 0x0000ff) > static_cast<int>(List_Size) - 1 ? static_cast<int>(List_Size) - 1 : *Action_Num + (SSpace & 0x0000ff); else if (key == '\r')//回車確認(rèn) *Action_Bol = true; return true; } CONSOLE* CONSOLE::Locate(int Target) { if (Target == 0) { for (int i = 0; i < SonList.size(); i++) { if (i == Selector && Is_Selected == true) return SonList.at(i).Locate(); } return this; } else { for (int i = 0; i < SonList.size(); i++) { if (i == Selector && Is_Selected == true && SonList.at(i).SonList.size() != 0) if (SonList.at(i).Is_Selected == false) return this; else return SonList.at(i).Locate(-1); } return this; } }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C語言字符串與字符數(shù)組面試題中最易錯(cuò)考點(diǎn)詳解
這篇文章主要介紹了C語言字符串與字符數(shù)組面試題中最易錯(cuò)考點(diǎn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-09-09C語言中結(jié)構(gòu)體struct編寫的一些要點(diǎn)解析
這篇文章主要介紹了C語言中結(jié)構(gòu)體struct編寫的一些要點(diǎn)解析,談到了結(jié)構(gòu)體的聲明和指針指向等重要知識(shí)點(diǎn),需要的朋友可以參考下2016-04-04