This commit is contained in:
Tristan Krause 2019-04-04 13:19:11 +02:00
parent 282a0dbc34
commit 793f8a8370
10 changed files with 320 additions and 102 deletions

58
driver/ui/view.cpp Normal file
View file

@ -0,0 +1,58 @@
#include "view.h"
WINDOW* View::win = nullptr;
View::View()
{
if(!win)
throw std::runtime_error("View::win not initialized, missing context!");
getmaxyx(win, height, width); // init width and height
keypad(win, TRUE);
}
void View::setWinContext(WINDOW* win)
{
View::win = win;
}
WINDOW* View::getWinContext()
{
return win;
}
void View::addCall(std::function<void(int)> call)
{
calls.push_back(call);
}
void View::setTitle(std::string title)
{
this->title = title;
}
void View::repaint()
{
// get screen size
struct winsize size;
if (ioctl(0, TIOCGWINSZ, (char *) &size) < 0)
throw std::runtime_error("TIOCGWINSZ error");
start_x = floor((size.ws_col - width) / 2.);
start_y = floor((size.ws_row - height) / 2.);
mvwin(win, start_y, start_x);
wclear(win);
// generic draw
box(win, 0, 0);
int offset_x = (width - title.length()) / 2;
mvwprintw(win, 1, offset_x, "%s", title.c_str());
// specific draw
draw();
refresh();
wrefresh(win);
}

42
driver/ui/view.h Normal file
View file

@ -0,0 +1,42 @@
#ifndef VIEW_H
#define VIEW_H
#include <iostream>
#include <cmath>
#include <vector>
#include <functional>
#include <ncurses.h> // sudo apt-get install libncurses5-dev
#include <sys/ioctl.h>
#include <unistd.h>
class View
{
public:
View(void);
static void setWinContext(WINDOW* win);
static WINDOW* getWinContext(void);
virtual void addCall(std::function<void(int)> call);
void setSize(int width, int height);
void setTitle(std::string title);
virtual void repaint(void);
virtual void draw(void) = 0;
virtual std::function<void(int)> keypress(int& key) = 0;
protected:
int width, height;
int start_x = 0, start_y = 0;
std::string title;
std::vector<std::function<void(int)>> calls;
constexpr static int KEY_ENT = 10;
static WINDOW* win;
};
#endif // VIEW_H

33
driver/ui/view_info.cpp Normal file
View file

@ -0,0 +1,33 @@
#include "view_info.h"
ViewInfo::ViewInfo()
{
}
void ViewInfo::draw()
{
mvwprintw(win, text_offset_y, text_offset_x, "%s", "hello");
}
std::function<void(int)> ViewInfo::keypress(int& key)
{
std::function<void(int)> ret = nullptr;
switch(key)
{
case KEY_MOUSE:
{
// 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
break;
}
case KEY_ENT:
key = -1; // do return from view
break;
default:
break;
}
return ret;
}

18
driver/ui/view_info.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef VIEW_INFO
#define VIEW_INFO
#include "view.h"
class ViewInfo : public View
{
public:
ViewInfo(void);
virtual void draw(void) override;
virtual std::function<void(int)> keypress(int& key) override;
private:
constexpr static int text_offset_x = 2;
constexpr static int text_offset_y = 3;
};
#endif // VIEW_INFO

62
driver/ui/view_main.cpp Normal file
View file

@ -0,0 +1,62 @@
#include "view_main.h"
void ViewMain::draw()
{
for(size_t i = 0; i < choices.size(); i++)
{
if(selection == i)
wattron(win, A_REVERSE);
mvwprintw(win, i + choice_offset_y, choice_offset_x, "%s", choices[i].c_str());
if(selection == i)
wattroff(win, A_REVERSE);
}
}
std::function<void(int)> ViewMain::keypress(int& key)
{
std::function<void(int)> ret = nullptr;
switch(key)
{
case KEY_UP:
selection = (selection - 1) % choices.size();
break;
case KEY_DOWN:
selection = (selection + 1) % choices.size();
break;
case KEY_MOUSE:
{
// http://pronix.linuxdelta.de/C/Linuxprogrammierung/Linuxsystemprogrammieren_C_Kurs_Kapitel10b.shtml
MEVENT event;
bool hit = false;
if(getmouse(&event) == OK && event.bstate & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED))
{
size_t column_start = start_x + choice_offset_x;
size_t row_start = start_y + choice_offset_y;
size_t mouse_x = event.x, mouse_y = event.y;
for(size_t i = 0; i < choices.size(); i++)
if(mouse_y == row_start + i && mouse_x >= column_start && mouse_x < column_start + choices[i].length())
{
if(selection == i || event.bstate & BUTTON1_DOUBLE_CLICKED)
hit = true;
selection = i;
}
}
if(!hit)
break;
// fall through to next case
__attribute__ ((fallthrough));
}
case KEY_ENT:
if(selection == choices.size() - 1) // exit
key = -1; // do return from view
else
ret = calls[selection];
break;
default:
break;
}
repaint();
return ret;
}

24
driver/ui/view_main.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef VIEW_MAIN_H
#define VIEW_MAIN_H
#include <vector>
#include <string>
#include "view.h"
class ViewMain : public View
{
public:
virtual void draw(void) override;
virtual std::function<void(int)> keypress(int& key) override;
private:
constexpr static int choice_offset_x = 2;
constexpr static int choice_offset_y = 3;
size_t selection = 0;
const std::vector<std::string> choices = {
"Beobachten",
"Exit"
};
};
#endif // VIEW_MAIN_H