123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633 |
- #include "door.h"
- #include <string.h>
- namespace door {
- Panel::Panel(int xp, int yp, int panelWidth) : border_color() {
- x = xp;
- y = yp;
- width = panelWidth;
- hidden = false;
- border_style = BorderStyle::NONE;
-
- }
- Panel::Panel(Panel &&ref) {
- x = ref.x;
- y = ref.y;
- width = ref.width;
- hidden = ref.hidden;
- border_style = ref.border_style;
- title = std::move(ref.title);
- offset = ref.offset;
- lines = std::move(lines);
- }
- void Panel::set(int xp, int yp) {
- x = xp;
- y = yp;
- }
- void Panel::setTitle(std::unique_ptr<Line> t, int off) {
- title = std::move(t);
- offset = off;
- }
- void Panel::setStyle(BorderStyle bs) { border_style = bs; }
- void Panel::setColor(ANSIColor c) { border_color = c; }
- void Panel::hide(void) { hidden = true; }
- void Panel::show(void) { hidden = false; }
- void Panel::addLine(std::unique_ptr<Line> l) { lines.push_back(std::move(l)); }
- struct box_styles {
-
- const char *tl;
-
- const char *tr;
-
- const char *top;
-
- const char *side;
-
- const char *bl;
-
- const char *br;
-
- const char *ml;
-
- const char *mr;
- };
- struct box_styles UBOXES[] = {{"\u250c", "\u2510", "\u2500", "\u2502", "\u2514",
- "\u2518", "\u251c", "\u2524"},
- {"\u2554", "\u2557", "\u2550", "\u2551", "\u255a",
- "\u255d", "\u2560", "\u2563"},
- {"\u2553", "\u2556", "\u2500", "\u2551", "\u2559",
- "\u255c", "\u255f", "\u2562"},
- {"\u2552", "\u2555", "\u2550", "\u2502", "\u2558",
- "\u255b", "\u255e", "\u2561"}};
- struct box_styles BOXES[] = {
-
- {
- "\xda",
- "\xbf",
- "\xc4",
- "\xb3",
- "\xc0",
- "\xd9",
- "\xc3",
- "\xb4",
- },
-
- {
- "\xc9",
- "\xbb",
- "\xcd",
- "\xba",
- "\xc8",
- "\xbc",
- "\xcc",
- "\xb9",
- },
-
- {
- "\xd6",
- "\xb7",
- "\xc4",
- "\xba",
- "\xd3",
- "\xbd",
- "\xc7",
- "\xb6",
- },
-
- {
- "\xd5",
- "\xb8",
- "\xcd",
- "\xb3",
- "\xd4",
- "\xbe",
- "\xc6",
- "\xb5",
- },
- };
- std::ostream &operator<<(std::ostream &os, const Panel &p) {
- if (p.hidden)
- return os;
-
- int style = (int)p.border_style;
- struct box_styles s;
-
-
-
- if (style > 0) {
-
- if (style < 5) {
- if (unicode)
- s = UBOXES[style - 1];
- else
- s = BOXES[style - 1];
- } else {
- s.bl = s.br = s.mr = s.ml = " ";
- s.top = s.side = " ";
- s.tl = s.tr = " ";
- }
- }
-
-
-
- int row = p.y;
- if (style > 0) {
-
- os << door::Goto(p.x, row);
- os << p.border_color << s.tl;
- if (p.title) {
- for (int c = 0; c < p.offset; c++)
- os << s.top;
- os << *(p.title);
- os << p.border_color;
- int left = p.width - (p.offset + (p.title)->length());
- if (left > 0) {
- for (int c = 0; c < left; c++)
- os << s.top;
- };
- os << s.tr;
- } else {
- for (int c = 0; c < p.width; c++)
- os << s.top;
- os << s.tr;
- };
-
- ++row;
- };
- for (auto &line : p.lines) {
- os << door::Goto(p.x, row);
- if (style > 0) {
- os << p.border_color << s.side;
- };
-
- os << *line;
- if (style > 0) {
- os << p.border_color << s.side;
- };
-
- row++;
-
-
- }
-
- if (style > 0) {
- os << door::Goto(p.x, row);
- os << p.border_color << s.bl;
- for (int c = 0; c < p.width; c++)
- os << s.top;
-
- os << s.br;
- };
-
-
- return os;
- }
- renderFunction Menu::defaultSelectedRender = Menu::makeRender(
- ANSIColor(COLOR::BLUE, COLOR::WHITE), ANSIColor(COLOR::BLUE, COLOR::WHITE),
- ANSIColor(COLOR::BLUE, COLOR::WHITE), ANSIColor(COLOR::BLUE, COLOR::WHITE));
- renderFunction Menu::defaultUnselectedRender =
- Menu::makeRender(ANSIColor(COLOR::WHITE, COLOR::BLUE, ATTR::BOLD),
- ANSIColor(COLOR::WHITE, COLOR::BLUE, ATTR::BOLD),
- ANSIColor(COLOR::WHITE, COLOR::BLUE, ATTR::BOLD),
- ANSIColor(COLOR::YELLOW, COLOR::BLUE, ATTR::BOLD));
- Menu::Menu(int x, int y, int width) : Panel(x, y, width) {
- setStyle(BorderStyle::DOUBLE);
-
-
- setRender(true, defaultSelectedRender);
-
- setRender(false, defaultUnselectedRender);
-
-
- chosen = 0;
- }
- Menu::Menu(Menu &&ref) : Panel(ref.x, ref.y, ref.width) {
- x = ref.x;
- y = ref.y;
- width = ref.width;
- border_style = ref.border_style;
- setRender(true, ref.selectedRender);
- setRender(false, ref.unselectedRender);
- options = ref.options;
- lines = std::move(ref.lines);
- chosen = ref.chosen;
- }
- void Menu::addSelection(char c, const char *line) {
- std::string menuline;
- menuline.reserve(5 + strlen(line));
- menuline = "[ ] ";
- menuline[1] = c;
- menuline += line;
-
-
- addLine(std::make_unique<Line>(menuline, width));
- options.push_back(c);
- }
- void Menu::defaultSelection(int d) { chosen = d; }
- void Menu::setRender(bool selected, renderFunction render) {
- if (selected)
- selectedRender = render;
- else
- unselectedRender = render;
- }
- renderFunction Menu::makeRender(ANSIColor c1, ANSIColor c2, ANSIColor c3,
- ANSIColor c4) {
- renderFunction render = [c1, c2, c3, c4](const std::string &txt) -> Render {
- Render r(txt);
- bool option = true;
- ColorOutput co;
-
- co.pos = 0;
- co.len = 0;
- co.c = c1;
-
- int tpos = 0;
- for (char const &c : txt) {
- if (option) {
- if (c == '[' or c == ']') {
- if (co.c != c1)
- if (co.len != 0) {
- r.outputs.push_back(co);
- co.reset();
- co.pos = tpos;
- }
- co.c = c1;
- if (c == ']')
- option = false;
- } else {
- if (co.c != c2)
- if (co.len != 0) {
- r.outputs.push_back(co);
- co.reset();
- co.pos = tpos;
- }
- co.c = c2;
- }
- } else {
- if (isupper(c)) {
-
- if (co.c != c3)
- if (co.len != 0) {
- r.outputs.push_back(co);
- co.reset();
- co.pos = tpos;
- }
- co.c = c3;
- } else {
- if (co.c != c4)
- if (co.len != 0) {
- r.outputs.push_back(co);
- co.reset();
- co.pos = tpos;
- }
- co.c = c4;
- }
- }
- co.len++;
- tpos++;
- }
- if (co.len != 0) {
- r.outputs.push_back(co);
- }
- return r;
- };
- return render;
- }
- int Menu::choose(Door &door) {
-
-
- bool updated = true;
- bool update_and_exit = false;
- while (true) {
- if (updated) {
- for (unsigned int x = 0; x < lines.size(); x++) {
- if (x == chosen) {
- lines[x]->setRender(
- selectedRender);
- } else {
- lines[x]->setRender(
- unselectedRender);
- }
- }
-
- door << *this;
-
-
- };
- if (update_and_exit)
- return chosen + 1;
-
-
- updated = false;
-
- int event = door.sleep_key(door.inactivity);
- if (event < 0) {
-
- return event;
- }
-
- if (event > XKEY_START) {
- switch (event) {
- case XKEY_UP_ARROW:
- if (chosen > 0) {
- chosen--;
- updated = true;
- }
- break;
- case XKEY_DOWN_ARROW:
- if (chosen < lines.size() - 1) {
- chosen++;
- updated = true;
- }
- break;
- case XKEY_HOME:
- if (chosen != 0) {
- chosen = 0;
- updated = true;
- }
- break;
- case XKEY_END:
- if (chosen != lines.size() - 1) {
- chosen = lines.size() - 1;
- updated = true;
- }
- }
- } else if (event == 0x0d) {
-
- return chosen + 1;
- }
- for (unsigned int x = 0; x < lines.size(); x++) {
- if (toupper(options[x]) == toupper(event)) {
-
- if (chosen == x) {
- return x + 1;
- }
-
-
- updated = true;
- chosen = x;
- update_and_exit = true;
- }
- }
- }
- return 0;
- }
- Screen::Screen() { hidden = false; }
- void Screen::addPanel(std::shared_ptr<Panel> p) { parts.push_back(p); }
- void Screen::hide(void) { hidden = true; }
- void Screen::show(void) { hidden = false; }
- std::ostream &operator<<(std::ostream &os, const Screen &s) {
- if (!s.hidden) {
- for (auto part : s.parts) {
- os << part;
- };
-
- }
- return os;
- }
- }
|