diff options
author | Hisham Muhammad <hisham@gobolinux.org> | 2006-03-04 18:16:49 +0000 |
---|---|---|
committer | Hisham Muhammad <hisham@gobolinux.org> | 2006-03-04 18:16:49 +0000 |
commit | d6231bab89d634da5564491196b7c478db038505 (patch) | |
tree | bfc0bf00b138763eb41132fd27a8f389a78bf3a4 /ScreenManager.c |
Initial import.
Diffstat (limited to 'ScreenManager.c')
-rw-r--r-- | ScreenManager.c | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/ScreenManager.c b/ScreenManager.c new file mode 100644 index 00000000..28009ca8 --- /dev/null +++ b/ScreenManager.c @@ -0,0 +1,225 @@ +/* +htop +(C) 2004-2006 Hisham H. Muhammad +Released under the GNU GPL, see the COPYING file +in the source distribution for its full text. +*/ + +#include "ScreenManager.h" +#include "ListBox.h" +#include "Object.h" +#include "TypedVector.h" +#include "FunctionBar.h" + +#include "debug.h" +#include <assert.h> + +#include <stdbool.h> + +/*{ + +typedef enum Orientation_ { + VERTICAL, + HORIZONTAL +} Orientation; + +typedef struct ScreenManager_ { + int x1; + int y1; + int x2; + int y2; + Orientation orientation; + TypedVector* items; + TypedVector* fuBars; + int itemCount; + FunctionBar* fuBar; + bool owner; +} ScreenManager; + +}*/ + +ScreenManager* ScreenManager_new(int x1, int y1, int x2, int y2, Orientation orientation, bool owner) { + ScreenManager* this; + this = malloc(sizeof(ScreenManager)); + this->x1 = x1; + this->y1 = y1; + this->x2 = x2; + this->y2 = y2; + this->fuBar = NULL; + this->orientation = orientation; + this->items = TypedVector_new(LISTBOX_CLASS, owner, DEFAULT_SIZE); + this->fuBars = TypedVector_new(FUNCTIONBAR_CLASS, true, DEFAULT_SIZE); + this->itemCount = 0; + this->owner = owner; + return this; +} + +void ScreenManager_delete(ScreenManager* this) { + TypedVector_delete(this->items); + TypedVector_delete(this->fuBars); + free(this); +} + +inline int ScreenManager_size(ScreenManager* this) { + return this->itemCount; +} + +void ScreenManager_add(ScreenManager* this, ListBox* item, FunctionBar* fuBar, int size) { + if (this->orientation == HORIZONTAL) { + int lastX = 0; + if (this->itemCount > 0) { + ListBox* last = (ListBox*) TypedVector_get(this->items, this->itemCount - 1); + lastX = last->x + last->w + 1; + } + if (size > 0) { + ListBox_resize(item, size, LINES-this->y1+this->y2); + } else { + ListBox_resize(item, COLS-this->x1+this->x2-lastX, LINES-this->y1+this->y2); + } + ListBox_move(item, lastX, this->y1); + } + // TODO: VERTICAL + TypedVector_add(this->items, item); + if (fuBar) + TypedVector_add(this->fuBars, fuBar); + else + TypedVector_add(this->fuBars, FunctionBar_new(0, NULL, NULL, NULL)); + if (!this->fuBar && fuBar) this->fuBar = fuBar; + item->needsRedraw = true; + this->itemCount++; +} + +ListBox* ScreenManager_remove(ScreenManager* this, int index) { + assert(this->itemCount > index); + ListBox* lb = (ListBox*) TypedVector_remove(this->items, index); + TypedVector_remove(this->fuBars, index); + this->fuBar = NULL; + this->itemCount--; + return lb; +} + +void ScreenManager_setFunctionBar(ScreenManager* this, FunctionBar* fuBar) { + if (this->owner && this->fuBar) + FunctionBar_delete((Object*)this->fuBar); + this->fuBar = fuBar; +} + +void ScreenManager_resize(ScreenManager* this, int x1, int y1, int x2, int y2) { + this->x1 = x1; + this->y1 = y1; + this->x2 = x2; + this->y2 = y2; + int items = this->itemCount; + int lastX = 0; + for (int i = 0; i < items - 1; i++) { + ListBox* lb = (ListBox*) TypedVector_get(this->items, i); + ListBox_resize(lb, lb->w, LINES-y1+y2); + ListBox_move(lb, lastX, y1); + lastX = lb->x + lb->w + 1; + } + ListBox* lb = (ListBox*) TypedVector_get(this->items, items-1); + ListBox_resize(lb, COLS-x1+x2-lastX, LINES-y1+y2); + ListBox_move(lb, lastX, y1); +} + +void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) { + bool quit = false; + int focus = 0; + + ListBox* lbFocus = (ListBox*) TypedVector_get(this->items, focus); + if (this->fuBar) + FunctionBar_draw(this->fuBar, NULL); + + int ch; + while (!quit) { + int items = this->itemCount; + for (int i = 0; i < items; i++) { + ListBox* lb = (ListBox*) TypedVector_get(this->items, i); + ListBox_draw(lb, i == focus); + if (i < items) { + if (this->orientation == HORIZONTAL) { + mvvline(lb->y, lb->x+lb->w, ' ', lb->h+1); + } + } + } + FunctionBar* bar = (FunctionBar*) TypedVector_get(this->fuBars, focus); + if (bar) + this->fuBar = bar; + if (this->fuBar) + FunctionBar_draw(this->fuBar, NULL); + + ch = getch(); + + bool loop = false; + if (ch == KEY_MOUSE) { + MEVENT mevent; + int ok = getmouse(&mevent); + if (ok == OK) { + if (mevent.y == LINES - 1) { + ch = FunctionBar_synthesizeEvent(this->fuBar, mevent.x); + } else { + for (int i = 0; i < this->itemCount; i++) { + ListBox* lb = (ListBox*) TypedVector_get(this->items, i); + if (mevent.x > lb->x && mevent.x <= lb->x+lb->w && + mevent.y > lb->y && mevent.y <= lb->y+lb->h) { + focus = i; + lbFocus = lb; + ListBox_setSelected(lb, mevent.y - lb->y + lb->scrollV - 1); + loop = true; + break; + } + } + } + } + } + if (loop) continue; + + if (lbFocus->eventHandler) { + HandlerResult result = lbFocus->eventHandler(lbFocus, ch); + if (result == HANDLED) { + continue; + } else if (result == BREAK_LOOP) { + quit = true; + continue; + } + } + + switch (ch) { + case ERR: + continue; + case KEY_RESIZE: + { + ScreenManager_resize(this, this->x1, this->y1, this->x2, this->y2); + continue; + } + case KEY_LEFT: + tryLeft: + if (focus > 0) + focus--; + lbFocus = (ListBox*) TypedVector_get(this->items, focus); + if (ListBox_getSize(lbFocus) == 0 && focus > 0) + goto tryLeft; + break; + case KEY_RIGHT: + case 9: + tryRight: + if (focus < this->itemCount - 1) + focus++; + lbFocus = (ListBox*) TypedVector_get(this->items, focus); + if (ListBox_getSize(lbFocus) == 0 && focus < this->itemCount - 1) + goto tryRight; + break; + case KEY_F(10): + case 'q': + case 27: + quit = true; + continue; + default: + ListBox_onKey(lbFocus, ch); + break; + } + } + + *lastFocus = lbFocus; + *lastKey = ch; +} |