diff --git a/include/EventManager.hpp b/include/EventManager.hpp new file mode 100644 index 0000000..402d484 --- /dev/null +++ b/include/EventManager.hpp @@ -0,0 +1,44 @@ +#ifndef H_EventManager +#define H_EventManager + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/// This class manages the keyboard events and triggers actions. +class EventManager +{ + public: + EventManager(Display & display_, TreeNodeDiskUsage & rootNode_); + ~EventManager(); + + /// Starts the main event loop. + void MainEventLoop(); + + // Callback functions that are triggered when the corresponding key is pressed. + void CallbackArrowUp(); + void CallbackArrowDown(); + void CallbackArrowLeft(); + void CallbackArrowRight(); + void CallbackEnter(); + void CallbackBackspace(); + void CallbackHome(); + void CallbackHelp(); + void CallbackSort(); + + protected: + Display & display; + TreeNodeDiskUsage & rootNode; + + int currentLine; + TreeNodeDiskUsage *currentNode; +}; + +#endif diff --git a/include/test.hpp b/include/test.hpp index a9e17c3..8052cf7 100644 --- a/include/test.hpp +++ b/include/test.hpp @@ -5,13 +5,12 @@ #include #include #include +#include using std::cout; using std::cerr; using std::endl; -#ifdef D_UNIT_TESTS void runTests(int argc, char *argv[]); -#endif #endif \ No newline at end of file diff --git a/src/EventManager.cpp b/src/EventManager.cpp new file mode 100644 index 0000000..d9f490a --- /dev/null +++ b/src/EventManager.cpp @@ -0,0 +1,145 @@ +#include + +#define KEY_ARROW_UP 'A' +#define KEY_ARROW_DOWN 'B' +#define KEY_ARROW_RIGHT 'C' +#define KEY_ARROW_LEFT 'D' +#define KEY_BACKSPACE 127 +#define KEY_DEL 126 +#define KEY_HOME 'H' +#define KEY_ENTER 10 + +EventManager::EventManager(Display & display_, TreeNodeDiskUsage & rootNode_) + : display(display_), + rootNode(rootNode_) +{} + +EventManager::~EventManager() +{ + +} + +void EventManager::MainEventLoop() +{ + struct termios oldSettings, newSettings; + + tcgetattr(fileno(stdin), &oldSettings); + newSettings = oldSettings; + newSettings.c_lflag &= (~ICANON & ~ECHO); + tcsetattr(fileno(stdin), TCSANOW, &newSettings); + + bool readingSymbol = false; + + while(1) + { + fd_set set; + struct timeval tv; + + tv.tv_sec = 10; + tv.tv_usec = 0; + + FD_ZERO(&set); + FD_SET(fileno(stdin), &set); + + int res = select(fileno(stdin)+1, &set, NULL, NULL, &tv);// res == 0 -> timeout reached + + if(res > 0) + { + char c; + read(fileno(stdin), &c, 1); + // std::cout << (int)c << " = \"" << c << "\"\n";// DEBUG + + // Parse event + if(c == 'q') // Quit program + break; + else if(c == 27) // when an arrow key is pressed, a string of 3 characters is produced : 27, '[', key identifier + { + readingSymbol = true; + continue; + } + + if(!readingSymbol) // Regular key presses that fit in a single character + { + if(c == KEY_ENTER) + CallbackEnter(); + else if(c == KEY_BACKSPACE) + CallbackBackspace(); + else if(c == '?' || c == 'h' || c == 'H') + CallbackHelp(); + else if(c == 's' || c == 'S') + CallbackSort(); + } + else + { + if(c == '[') // second character of the symbol + continue; + + if(c == KEY_ARROW_UP) + CallbackArrowUp(); + else if(c == KEY_ARROW_DOWN) + CallbackArrowDown(); + else if(c == KEY_ARROW_LEFT) + CallbackArrowLeft(); + else if(c == KEY_ARROW_RIGHT) + CallbackArrowRight(); + else if(c == KEY_HOME) + CallbackHome(); + + //std::cout << "symbol read : " << (int)c << " = \"" << c << "\"\n";// DEBUG + readingSymbol = false; + } + } + else if(res < 0) + { + std::cerr << "Event select error.\n"; + break; + } + } + + tcsetattr(fileno(stdin), TCSANOW, &oldSettings); +} + +void EventManager::CallbackArrowUp() +{ + std::cout << "CallbackArrowUp\n"; +} + +void EventManager::CallbackArrowDown() +{ + std::cout << "CallbackArrowDown\n"; +} + +void EventManager::CallbackArrowLeft() +{ + std::cout << "CallbackArrowLeft\n"; +} + +void EventManager::CallbackArrowRight() +{ + std::cout << "CallbackArrowRight\n"; +} + +void EventManager::CallbackEnter() +{ + std::cout << "CallbackEnter\n"; +} + +void EventManager::CallbackBackspace() +{ + std::cout << "CallbackBackspace\n"; +} + +void EventManager::CallbackHome() +{ + std::cout << "CallbackHome\n"; +} + +void EventManager::CallbackHelp() +{ + std::cout << "CallbackHelp\n"; +} + +void EventManager::CallbackSort() +{ + std::cout << "CallbackSort\n"; +} diff --git a/src/main.cpp b/src/main.cpp index 78c9e92..51a84f5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,12 +2,13 @@ #include #include #include +#include using std::cout; using std::cerr; using std::endl; -//#define D_UNIT_TESTS +#define D_UNIT_TESTS #include diff --git a/src/test.cpp b/src/test.cpp index dcea990..8b0fc4e 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -1,12 +1,14 @@ +#include -#ifdef D_UNIT_TESTS -void runTests(int /* argc */, char *argv[]) +void runTests(int argc, char *argv[]) { + std::string rootpath = (argc > 1) ? argv[1] : "."; + if(0) {// stat test - cout << "Reading '" << argv[1] << "'\n"; + cout << "Reading '" << rootpath << "'\n"; struct stat s; - PRINT_VAR(stat(argv[1], &s)); + PRINT_VAR(stat(rootpath.c_str(), &s)); PRINT_VAR(s.st_mode); PRINT_VAR(s.st_mode & S_IFMT); PRINT_VAR((s.st_mode & S_IFMT) == S_IFLNK);// symbolic link @@ -41,7 +43,8 @@ void runTests(int /* argc */, char *argv[]) } if(0) {// basic tree building and printing test - TreeNodeDiskUsage tree(argv[1]); + Display display; + TreeNodeDiskUsage tree(rootpath); cout << "Scanning folder \"" << rootpath << "\" ...\n"; tree.BuildTree(true, display.Cols()); cout << endl; @@ -121,7 +124,7 @@ void runTests(int /* argc */, char *argv[]) PRINT_VAR(Bytes2HumanReadable(1000000000ULL, false)); } - //if(0) + if(0) {// test screen functions Display d; PRINT_VAR(d.Rows()); @@ -186,5 +189,12 @@ void runTests(int /* argc */, char *argv[]) } } } + //if(0) + {// test EventManager + Display display; + TreeNodeDiskUsage tree(rootpath); + tree.BuildTree(false); + EventManager eventManager(display, tree); + eventManager.MainEventLoop(); + } } -#endif // D_UNIT_TESTS \ No newline at end of file