diff --git a/AvailableMetersPanel.c b/AvailableMetersPanel.c index 29046b94..203bdd7f 100644 --- a/AvailableMetersPanel.c +++ b/AvailableMetersPanel.c @@ -6,6 +6,7 @@ in the source distribution for its full text. */ #include "AvailableMetersPanel.h" +#include "MetersPanel.h" #include "CPUMeter.h" #include "Header.h" @@ -43,6 +44,9 @@ static void AvailableMetersPanel_delete(Object* object) { static inline void AvailableMetersPanel_addMeter(Header* header, Panel* panel, MeterClass* type, int param, int column) { Meter* meter = (Meter*) Header_addMeterByClass(header, type, param, column); Panel_add(panel, (Object*) Meter_toListItem(meter)); + Panel_setSelected(panel, Panel_size(panel) - 1); + ((MetersPanel*)panel)->moving = true; + ((ListItem*)Panel_getSelected(panel))->moving = true; } static HandlerResult AvailableMetersPanel_eventHandler(Panel* super, int ch) { @@ -53,6 +57,7 @@ static HandlerResult AvailableMetersPanel_eventHandler(Panel* super, int ch) { int param = selected->key & 0xff; int type = selected->key >> 16; HandlerResult result = IGNORED; + bool update = false; switch(ch) { case KEY_F(5): @@ -61,18 +66,23 @@ static HandlerResult AvailableMetersPanel_eventHandler(Panel* super, int ch) { { AvailableMetersPanel_addMeter(header, this->leftPanel, Platform_meterTypes[type], param, 0); result = HANDLED; + update = true; break; } + case 0x0a: + case 0x0d: + case KEY_ENTER: case KEY_F(6): case 'r': case 'R': { AvailableMetersPanel_addMeter(header, this->rightPanel, Platform_meterTypes[type], param, 1); - result = HANDLED; + result = (KEY_LEFT << 16) | SYNTH_KEY; + update = true; break; } } - if (result == HANDLED) { + if (update) { this->settings->changed = true; Header_calculateHeight(header); Header_draw(header); diff --git a/CategoriesPanel.c b/CategoriesPanel.c index d691d7f4..7fa31b7d 100644 --- a/CategoriesPanel.c +++ b/CategoriesPanel.c @@ -34,9 +34,13 @@ typedef struct CategoriesPanel_ { }*/ -static const char* MetersFunctions[] = {" ", " ", " ", "Type ", " ", " ", "MoveUp", "MoveDn", "Remove", "Done ", NULL}; +static const char* MetersFunctions[] = {"Type ", "Move ", "Delete", "Done ", NULL}; +static const char* MetersKeys[] = {"Space", "Enter", "Del", "Esc"}; +static int MetersEvents[] = {' ', 13, 27, KEY_DC}; -static const char* AvailableMetersFunctions[] = {" ", " ", " ", " ", "Add L ", "Add R ", " ", " ", " ", "Done ", NULL}; +static const char* AvailableMetersFunctions[] = {"Add ", "Done ", NULL}; +static const char* AvailableMetersKeys[] = {"Enter", "Esc"}; +static int AvailableMetersEvents[] = {13, 27}; static const char* DisplayOptionsFunctions[] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done ", NULL}; @@ -54,12 +58,14 @@ static void CategoriesPanel_delete(Object* object) { } void CategoriesPanel_makeMetersPage(CategoriesPanel* this) { - Panel* leftMeters = (Panel*) MetersPanel_new(this->settings, "Left column", this->header->columns[0], this->scr); - Panel* rightMeters = (Panel*) MetersPanel_new(this->settings, "Right column", this->header->columns[1], this->scr); - Panel* availableMeters = (Panel*) AvailableMetersPanel_new(this->settings, this->header, leftMeters, rightMeters, this->scr, this->pl); - ScreenManager_add(this->scr, leftMeters, FunctionBar_new(MetersFunctions, NULL, NULL), 20); - ScreenManager_add(this->scr, rightMeters, FunctionBar_new(MetersFunctions, NULL, NULL), 20); - ScreenManager_add(this->scr, availableMeters, FunctionBar_new(AvailableMetersFunctions, NULL, NULL), -1); + MetersPanel* leftMeters = MetersPanel_new(this->settings, "Left column", this->header->columns[0], this->scr); + MetersPanel* rightMeters = MetersPanel_new(this->settings, "Right column", this->header->columns[1], this->scr); + leftMeters->rightNeighbor = rightMeters; + rightMeters->leftNeighbor = leftMeters; + Panel* availableMeters = (Panel*) AvailableMetersPanel_new(this->settings, this->header, (Panel*) leftMeters, (Panel*) rightMeters, this->scr, this->pl); + ScreenManager_add(this->scr, (Panel*) leftMeters, FunctionBar_new(MetersFunctions, MetersKeys, MetersEvents), 20); + ScreenManager_add(this->scr, (Panel*) rightMeters, FunctionBar_new(MetersFunctions, MetersKeys, MetersEvents), 20); + ScreenManager_add(this->scr, availableMeters, FunctionBar_new(AvailableMetersFunctions, AvailableMetersKeys, AvailableMetersEvents), -1); } static void CategoriesPanel_makeDisplayOptionsPage(CategoriesPanel* this) { diff --git a/MetersPanel.c b/MetersPanel.c index ee25b0d1..39753ac2 100644 --- a/MetersPanel.c +++ b/MetersPanel.c @@ -15,14 +15,18 @@ in the source distribution for its full text. #include "Settings.h" #include "ScreenManager.h" -typedef struct MetersPanel_ { +typedef struct MetersPanel_ MetersPanel; + +struct MetersPanel_ { Panel super; Settings* settings; Vector* meters; ScreenManager* scr; + MetersPanel* leftNeighbor; + MetersPanel* rightNeighbor; bool moving; -} MetersPanel; +}; }*/ @@ -33,11 +37,34 @@ static void MetersPanel_delete(Object* object) { free(this); } +static inline bool moveToNeighbor(MetersPanel* this, MetersPanel* neighbor, int selected) { + Panel* super = (Panel*) this; + if (this->moving) { + this->moving = false; + ((ListItem*)Panel_getSelected(super))->moving = false; + if (neighbor) { + if (selected < Vector_size(this->meters)) { + Meter* meter = (Meter*) Vector_take(this->meters, selected); + Panel_remove(super, selected); + Vector_insert(neighbor->meters, selected, meter); + Panel_insert(&(neighbor->super), selected, (Object*) Meter_toListItem(meter)); + Panel_setSelected(&(neighbor->super), selected); + + neighbor->moving = true; + ((ListItem*)Panel_getSelected((Panel*)neighbor))->moving = true; + return true; + } + } + } + return false; +} + static HandlerResult MetersPanel_eventHandler(Panel* super, int ch) { MetersPanel* this = (MetersPanel*) super; int selected = Panel_getSelectedIndex(super); HandlerResult result = IGNORED; + bool sideMove = false; switch(ch) { case 0x0a: @@ -93,6 +120,18 @@ static HandlerResult MetersPanel_eventHandler(Panel* super, int ch) { result = HANDLED; break; } + case KEY_RIGHT: + { + sideMove = moveToNeighbor(this, this->rightNeighbor, selected); + // don't set HANDLED; let ScreenManager handle focus. + break; + } + case KEY_LEFT: + { + sideMove = moveToNeighbor(this, this->leftNeighbor, selected); + // don't set HANDLED; let ScreenManager handle focus. + break; + } case KEY_F(9): case KEY_DC: { @@ -104,7 +143,7 @@ static HandlerResult MetersPanel_eventHandler(Panel* super, int ch) { break; } } - if (result == HANDLED) { + if (result == HANDLED || sideMove) { Header* header = (Header*) this->scr->header; this->settings->changed = true; Header_calculateHeight(header); diff --git a/MetersPanel.h b/MetersPanel.h index 06b78da6..e6b47206 100644 --- a/MetersPanel.h +++ b/MetersPanel.h @@ -13,14 +13,18 @@ in the source distribution for its full text. #include "Settings.h" #include "ScreenManager.h" -typedef struct MetersPanel_ { +typedef struct MetersPanel_ MetersPanel; + +struct MetersPanel_ { Panel super; Settings* settings; Vector* meters; ScreenManager* scr; + MetersPanel* leftNeighbor; + MetersPanel* rightNeighbor; bool moving; -} MetersPanel; +}; extern PanelClass MetersPanel_class; diff --git a/Panel.c b/Panel.c index de120d7c..8f73634d 100644 --- a/Panel.c +++ b/Panel.c @@ -33,6 +33,7 @@ typedef enum HandlerResult_ { BREAK_LOOP = 0x04, REFRESH = 0x08, RECALCULATE = 0x10, + SYNTH_KEY = 0x20, } HandlerResult; #define EVENT_SETSELECTED -1 diff --git a/Panel.h b/Panel.h index baac7016..f1947206 100644 --- a/Panel.h +++ b/Panel.h @@ -22,6 +22,7 @@ typedef enum HandlerResult_ { BREAK_LOOP = 0x04, REFRESH = 0x08, RECALCULATE = 0x10, + SYNTH_KEY = 0x20, } HandlerResult; #define EVENT_SETSELECTED -1 diff --git a/ScreenManager.c b/ScreenManager.c index d7353b79..3df812c3 100644 --- a/ScreenManager.c +++ b/ScreenManager.c @@ -231,7 +231,9 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) { } if (Panel_eventHandlerFn(panelFocus)) { HandlerResult result = Panel_eventHandler(panelFocus, ch); -//fprintf(stderr, "eventResult=%d ", result); + if (result & SYNTH_KEY) { + ch = result >> 16; + } if (result & REFRESH) { doRefresh = true; sortTimeout = 0; diff --git a/Vector.c b/Vector.c index f3212f84..94ad32f6 100644 --- a/Vector.c +++ b/Vector.c @@ -192,6 +192,10 @@ void Vector_insert(Vector* this, int idx, void* data_) { assert(idx <= this->items); assert(Object_isA(data, this->type)); assert(Vector_isConsistent(this)); + + if (idx > this->items) { + idx = this->items; + } Vector_checkArraySize(this); //assert(this->array[this->items] == NULL);