diff --git a/driver/Makefile b/driver/Makefile index df21db9..14a27cd 100644 --- a/driver/Makefile +++ b/driver/Makefile @@ -34,7 +34,7 @@ help: clean: @echo "Cleaning..." - rm -f $(OBJECTS_DRV) $(OBJECTS_UI) $(OUT_CLI) $(OUT_MAIN) + rm -f $(OBJECTS_DRV) $(OBJECTS_UI) $(OBJ_CLI) $(OUT_CLI) $(OBJ_MAIN) $(OUT_MAIN) .cpp.o: $(COMPILE) -c $< -o $@ diff --git a/driver/cli b/driver/cli index 86ca550..8d652a7 100755 Binary files a/driver/cli and b/driver/cli differ diff --git a/driver/cli.cpp b/driver/cli.cpp index 51083aa..86040bc 100644 --- a/driver/cli.cpp +++ b/driver/cli.cpp @@ -3,28 +3,18 @@ #include #include #include +#include #include #include +#include #include "ui/view_main.h" #include "ui/view_info.h" +#include "drv/b15f.h" +// global error message +std::string ERR_MSG; std::vector win_stack; -ViewMain* view_main = nullptr; -ViewInfo* view_info = nullptr; - -void init() -{ - initscr(); - start_color(); - curs_set(0); // 0: invisible, 1: normal, 2: very visible - clear(); - noecho(); - cbreak(); // Line buffering disabled. pass on everything - mousemask(ALL_MOUSE_EVENTS, NULL); - - View::setWinContext(newwin(32, 128, 0, 0)); -} void cleanup() { @@ -33,13 +23,55 @@ void cleanup() endwin(); } -void finish(int key) +void signal_handler(int signal) +{ + if(signal == SIGWINCH) + { + if(win_stack.size()) + { + usleep(1000); + win_stack.back()->repaint(); + } + } + else if(signal == SIGINT) + { + cleanup(); + std::cout << "SIGINT - Abbruch." << std::endl; + if(ERR_MSG.length()) + std::cout << "ERR_MSG: " << ERR_MSG << std::endl; + exit(EXIT_FAILURE); + } +} + +void init() +{ + // init b15 driver + B15F::getInstance(); + + // init all ncurses stuff + initscr(); + start_color(); + curs_set(0); // 0: invisible, 1: normal, 2: very visible + clear(); + noecho(); + cbreak(); // Line buffering disabled. pass on everything + mousemask(ALL_MOUSE_EVENTS, NULL); + + // connect signals to handler + signal(SIGWINCH, signal_handler); + signal(SIGINT, signal_handler); + + // set view context + View::setWinContext(newwin(32, 128, 0, 0)); +} + +void finish(int) { cleanup(); exit(EXIT_SUCCESS); } -void input(int prev_key) +void input(int) { std::function nextCall; int key; @@ -62,19 +94,21 @@ void input(int prev_key) while(!false); } -void show_info(int key) +void show_info(int) { - View* view = new ViewInfo(); + ViewInfo* view = new ViewInfo(); view->setTitle("Info"); + view->setText("Informationen zu Board 15 Famulus Edition\nEs war einmal"); + view->setLabelClose("[ Zurueck ]"); view->repaint(); win_stack.push_back(view); input(0); } -void show_main(int key) +void show_main(int) { - View* view = new ViewMain(); + ViewMain* view = new ViewMain(); view->setTitle("B15F - Command Line Interface"); view->addCall(&show_info); view->addCall(&finish); @@ -86,7 +120,6 @@ void show_main(int key) int main() { - init(); show_main(0); diff --git a/driver/main b/driver/main new file mode 100755 index 0000000..0cb40b6 Binary files /dev/null and b/driver/main differ diff --git a/driver/ui/view.cpp b/driver/ui/view.cpp index 9ec8dda..b1ea7cd 100644 --- a/driver/ui/view.cpp +++ b/driver/ui/view.cpp @@ -5,7 +5,10 @@ WINDOW* View::win = nullptr; View::View() { if(!win) - throw std::runtime_error("View::win not initialized, missing context!"); + { + ERR_MSG = "View::win not initialized, missing context!"; + raise(SIGINT); + } getmaxyx(win, height, width); // init width and height keypad(win, TRUE); } @@ -42,7 +45,7 @@ void View::repaint() start_y = floor((size.ws_row - height) / 2.); mvwin(win, start_y, start_x); - + clear(); wclear(win); // generic draw @@ -56,3 +59,20 @@ void View::repaint() refresh(); wrefresh(win); } + +// from: https://stackoverflow.com/a/37454181 +std::vector View::str_split(const std::string& str, const std::string delim) +{ + std::vector tokens; + size_t prev = 0, pos = 0; + do + { + pos = str.find(delim, prev); + if (pos == std::string::npos) pos = str.length(); + std::string token = str.substr(prev, pos-prev); + if (!token.empty()) tokens.push_back(token); + prev = pos + delim.length(); + } + while (pos < str.length() && prev < str.length()); + return tokens; +} diff --git a/driver/ui/view.h b/driver/ui/view.h index 8cb620e..94dda53 100644 --- a/driver/ui/view.h +++ b/driver/ui/view.h @@ -8,6 +8,9 @@ #include // sudo apt-get install libncurses5-dev #include #include +#include + +extern std::string ERR_MSG; class View { @@ -23,6 +26,7 @@ public: void setTitle(std::string title); virtual void repaint(void); + static std::vector str_split(const std::string& str, const std::string delim); virtual void draw(void) = 0; virtual std::function keypress(int& key) = 0; diff --git a/driver/ui/view_info.cpp b/driver/ui/view_info.cpp index 74fa330..f75c64e 100644 --- a/driver/ui/view_info.cpp +++ b/driver/ui/view_info.cpp @@ -4,9 +4,28 @@ ViewInfo::ViewInfo() { } +void ViewInfo::setText(std::string text) +{ + this->text = text; +} + +void ViewInfo::setLabelClose(std::string label) +{ + this->label_close = label; +} + void ViewInfo::draw() { - mvwprintw(win, text_offset_y, text_offset_x, "%s", "hello"); + int li = 0; + for(std::string line : str_split(text, "\n")) + mvwprintw(win, text_offset_y + li++, text_offset_x, "%s", line.c_str()); + + close_offset_x = (width - label_close.length()) / 2; + close_offset_y = height - 2; + + wattron(win, A_REVERSE); + mvwprintw(win, close_offset_y, close_offset_x, "%s", label_close.c_str()); + wattroff(win, A_REVERSE); } std::function ViewInfo::keypress(int& key) @@ -19,8 +38,13 @@ std::function ViewInfo::keypress(int& key) { // http://pronix.linuxdelta.de/C/Linuxprogrammierung/Linuxsystemprogrammieren_C_Kurs_Kapitel10b.shtml MEVENT event; - if(getmouse(&event) == OK && event.bstate & BUTTON1_CLICKED) - key = -1; // do return from view + if(getmouse(&event) == OK && event.bstate & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED)) + { + size_t column = start_x + close_offset_x; + size_t row = start_y + close_offset_y; + if(event.y == row && event.x >= column && event.x < column + label_close.length()) + key = -1; // do return from view + } break; } case KEY_ENT: diff --git a/driver/ui/view_info.h b/driver/ui/view_info.h index 22d4f27..da811d3 100644 --- a/driver/ui/view_info.h +++ b/driver/ui/view_info.h @@ -7,10 +7,16 @@ class ViewInfo : public View { public: ViewInfo(void); + virtual void setText(std::string text); + virtual void setLabelClose(std::string label); virtual void draw(void) override; virtual std::function keypress(int& key) override; private: + std::string text; + std::string label_close; + int close_offset_x = 0; + int close_offset_y = 0; constexpr static int text_offset_x = 2; constexpr static int text_offset_y = 3; }; diff --git a/driver/ui/view_main.h b/driver/ui/view_main.h index 7792575..4c7935d 100644 --- a/driver/ui/view_main.h +++ b/driver/ui/view_main.h @@ -16,8 +16,8 @@ private: constexpr static int choice_offset_y = 3; size_t selection = 0; const std::vector choices = { - "Beobachten", - "Exit" + "[ Informationen ]", + "[ Beenden ]" }; };