mirror of
https://github.com/xzeldon/htop.git
synced 2025-07-12 12:14:36 +03:00
Rename ListBox to Panel, matching dit.
This commit is contained in:
353
Panel.c
Normal file
353
Panel.c
Normal file
@ -0,0 +1,353 @@
|
||||
/*
|
||||
htop - Panel.c
|
||||
(C) 2004-2006 Hisham H. Muhammad
|
||||
Released under the GNU GPL, see the COPYING file
|
||||
in the source distribution for its full text.
|
||||
*/
|
||||
|
||||
#include "Object.h"
|
||||
#include "Panel.h"
|
||||
#include "Vector.h"
|
||||
#include "CRT.h"
|
||||
#include "RichString.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include <assert.h>
|
||||
|
||||
#include <curses.h>
|
||||
//#link curses
|
||||
|
||||
/*{
|
||||
|
||||
typedef struct Panel_ Panel;
|
||||
|
||||
typedef enum HandlerResult_ {
|
||||
HANDLED,
|
||||
IGNORED,
|
||||
BREAK_LOOP
|
||||
} HandlerResult;
|
||||
|
||||
typedef HandlerResult(*Panel_EventHandler)(Panel*, int);
|
||||
|
||||
struct Panel_ {
|
||||
Object super;
|
||||
int x, y, w, h;
|
||||
WINDOW* window;
|
||||
Vector* items;
|
||||
int selected;
|
||||
int scrollV, scrollH;
|
||||
int oldSelected;
|
||||
bool needsRedraw;
|
||||
RichString header;
|
||||
Panel_EventHandler eventHandler;
|
||||
};
|
||||
|
||||
extern char* PANEL_CLASS;
|
||||
|
||||
}*/
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
/* private property */
|
||||
char* PANEL_CLASS = "Panel";
|
||||
|
||||
Panel* Panel_new(int x, int y, int w, int h, char* type, bool owner) {
|
||||
Panel* this;
|
||||
this = malloc(sizeof(Panel));
|
||||
Panel_init(this, x, y, w, h, type, owner);
|
||||
return this;
|
||||
}
|
||||
|
||||
void Panel_delete(Object* cast) {
|
||||
Panel* this = (Panel*)cast;
|
||||
Panel_done(this);
|
||||
free(this);
|
||||
}
|
||||
|
||||
void Panel_init(Panel* this, int x, int y, int w, int h, char* type, bool owner) {
|
||||
Object* super = (Object*) this;
|
||||
super->class = PANEL_CLASS;
|
||||
super->delete = Panel_delete;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->w = w;
|
||||
this->h = h;
|
||||
this->eventHandler = NULL;
|
||||
this->items = Vector_new(type, owner, DEFAULT_SIZE);
|
||||
this->scrollV = 0;
|
||||
this->scrollH = 0;
|
||||
this->selected = 0;
|
||||
this->oldSelected = 0;
|
||||
this->needsRedraw = true;
|
||||
this->header.len = 0;
|
||||
}
|
||||
|
||||
void Panel_done(Panel* this) {
|
||||
assert (this != NULL);
|
||||
RichString_delete(this->header);
|
||||
Vector_delete(this->items);
|
||||
}
|
||||
|
||||
inline void Panel_setRichHeader(Panel* this, RichString header) {
|
||||
assert (this != NULL);
|
||||
|
||||
if (this->header.len > 0) {
|
||||
RichString_delete(this->header);
|
||||
}
|
||||
this->header = header;
|
||||
this->needsRedraw = true;
|
||||
}
|
||||
|
||||
inline void Panel_setHeader(Panel* this, char* header) {
|
||||
Panel_setRichHeader(this, RichString_quickString(CRT_colors[PANEL_HEADER_FOCUS], header));
|
||||
}
|
||||
|
||||
void Panel_setEventHandler(Panel* this, Panel_EventHandler eh) {
|
||||
this->eventHandler = eh;
|
||||
}
|
||||
|
||||
void Panel_move(Panel* this, int x, int y) {
|
||||
assert (this != NULL);
|
||||
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->needsRedraw = true;
|
||||
}
|
||||
|
||||
void Panel_resize(Panel* this, int w, int h) {
|
||||
assert (this != NULL);
|
||||
|
||||
if (this->header.len > 0)
|
||||
h--;
|
||||
this->w = w;
|
||||
this->h = h;
|
||||
this->needsRedraw = true;
|
||||
}
|
||||
|
||||
void Panel_prune(Panel* this) {
|
||||
assert (this != NULL);
|
||||
|
||||
Vector_prune(this->items);
|
||||
this->scrollV = 0;
|
||||
this->selected = 0;
|
||||
this->oldSelected = 0;
|
||||
this->needsRedraw = true;
|
||||
}
|
||||
|
||||
void Panel_add(Panel* this, Object* o) {
|
||||
assert (this != NULL);
|
||||
|
||||
Vector_add(this->items, o);
|
||||
this->needsRedraw = true;
|
||||
}
|
||||
|
||||
void Panel_insert(Panel* this, int i, Object* o) {
|
||||
assert (this != NULL);
|
||||
|
||||
Vector_insert(this->items, i, o);
|
||||
this->needsRedraw = true;
|
||||
}
|
||||
|
||||
void Panel_set(Panel* this, int i, Object* o) {
|
||||
assert (this != NULL);
|
||||
|
||||
Vector_set(this->items, i, o);
|
||||
}
|
||||
|
||||
Object* Panel_get(Panel* this, int i) {
|
||||
assert (this != NULL);
|
||||
|
||||
return Vector_get(this->items, i);
|
||||
}
|
||||
|
||||
Object* Panel_remove(Panel* this, int i) {
|
||||
assert (this != NULL);
|
||||
|
||||
this->needsRedraw = true;
|
||||
Object* removed = Vector_remove(this->items, i);
|
||||
if (this->selected > 0 && this->selected >= Vector_size(this->items))
|
||||
this->selected--;
|
||||
return removed;
|
||||
}
|
||||
|
||||
Object* Panel_getSelected(Panel* this) {
|
||||
assert (this != NULL);
|
||||
|
||||
return Vector_get(this->items, this->selected);
|
||||
}
|
||||
|
||||
void Panel_moveSelectedUp(Panel* this) {
|
||||
assert (this != NULL);
|
||||
|
||||
Vector_moveUp(this->items, this->selected);
|
||||
if (this->selected > 0)
|
||||
this->selected--;
|
||||
}
|
||||
|
||||
void Panel_moveSelectedDown(Panel* this) {
|
||||
assert (this != NULL);
|
||||
|
||||
Vector_moveDown(this->items, this->selected);
|
||||
if (this->selected + 1 < Vector_size(this->items))
|
||||
this->selected++;
|
||||
}
|
||||
|
||||
int Panel_getSelectedIndex(Panel* this) {
|
||||
assert (this != NULL);
|
||||
|
||||
return this->selected;
|
||||
}
|
||||
|
||||
int Panel_getSize(Panel* this) {
|
||||
assert (this != NULL);
|
||||
|
||||
return Vector_size(this->items);
|
||||
}
|
||||
|
||||
void Panel_setSelected(Panel* this, int selected) {
|
||||
assert (this != NULL);
|
||||
|
||||
selected = MAX(0, MIN(Vector_size(this->items) - 1, selected));
|
||||
this->selected = selected;
|
||||
}
|
||||
|
||||
void Panel_draw(Panel* this, bool focus) {
|
||||
assert (this != NULL);
|
||||
|
||||
int first, last;
|
||||
int itemCount = Vector_size(this->items);
|
||||
int scrollH = this->scrollH;
|
||||
int y = this->y; int x = this->x;
|
||||
first = this->scrollV;
|
||||
|
||||
if (this->h > itemCount) {
|
||||
last = this->scrollV + itemCount;
|
||||
move(y + last, x + 0);
|
||||
} else {
|
||||
last = MIN(itemCount, this->scrollV + this->h);
|
||||
}
|
||||
if (this->selected < first) {
|
||||
first = this->selected;
|
||||
this->scrollV = first;
|
||||
this->needsRedraw = true;
|
||||
}
|
||||
if (this->selected >= last) {
|
||||
last = MIN(itemCount, this->selected + 1);
|
||||
first = MAX(0, last - this->h);
|
||||
this->scrollV = first;
|
||||
this->needsRedraw = true;
|
||||
}
|
||||
assert(first >= 0);
|
||||
assert(last <= itemCount);
|
||||
|
||||
if (this->header.len > 0) {
|
||||
int attr = focus
|
||||
? CRT_colors[PANEL_HEADER_FOCUS]
|
||||
: CRT_colors[PANEL_HEADER_UNFOCUS];
|
||||
attrset(attr);
|
||||
mvhline(y, x, ' ', this->w);
|
||||
if (scrollH < this->header.len) {
|
||||
mvaddchnstr(y, x, this->header.chstr + scrollH,
|
||||
MIN(this->header.len - scrollH, this->w));
|
||||
}
|
||||
attrset(CRT_colors[RESET_COLOR]);
|
||||
y++;
|
||||
}
|
||||
|
||||
int highlight = focus
|
||||
? CRT_colors[PANEL_HIGHLIGHT_FOCUS]
|
||||
: CRT_colors[PANEL_HIGHLIGHT_UNFOCUS];
|
||||
|
||||
if (this->needsRedraw) {
|
||||
|
||||
for(int i = first, j = 0; j < this->h && i < last; i++, j++) {
|
||||
Object* itemObj = Vector_get(this->items, i);
|
||||
RichString itemRef = RichString_new();
|
||||
itemObj->display(itemObj, &itemRef);
|
||||
int amt = MIN(itemRef.len - scrollH, this->w);
|
||||
if (i == this->selected) {
|
||||
attrset(highlight);
|
||||
RichString_setAttr(&itemRef, highlight);
|
||||
mvhline(y + j, x+0, ' ', this->w);
|
||||
if (amt > 0)
|
||||
mvaddchnstr(y+j, x+0, itemRef.chstr + scrollH, amt);
|
||||
attrset(CRT_colors[RESET_COLOR]);
|
||||
} else {
|
||||
mvhline(y+j, x+0, ' ', this->w);
|
||||
if (amt > 0)
|
||||
mvaddchnstr(y+j, x+0, itemRef.chstr + scrollH, amt);
|
||||
}
|
||||
}
|
||||
for (int i = y + (last - first); i < y + this->h; i++)
|
||||
mvhline(i, x+0, ' ', this->w);
|
||||
this->needsRedraw = false;
|
||||
|
||||
} else {
|
||||
Object* oldObj = Vector_get(this->items, this->oldSelected);
|
||||
RichString oldRef = RichString_new();
|
||||
oldObj->display(oldObj, &oldRef);
|
||||
Object* newObj = Vector_get(this->items, this->selected);
|
||||
RichString newRef = RichString_new();
|
||||
newObj->display(newObj, &newRef);
|
||||
mvhline(y+ this->oldSelected - this->scrollV, x+0, ' ', this->w);
|
||||
if (scrollH < oldRef.len)
|
||||
mvaddchnstr(y+ this->oldSelected - this->scrollV, x+0, oldRef.chstr + this->scrollH, MIN(oldRef.len - scrollH, this->w));
|
||||
attrset(highlight);
|
||||
mvhline(y+this->selected - this->scrollV, x+0, ' ', this->w);
|
||||
RichString_setAttr(&newRef, highlight);
|
||||
if (scrollH < newRef.len)
|
||||
mvaddchnstr(y+this->selected - this->scrollV, x+0, newRef.chstr + this->scrollH, MIN(newRef.len - scrollH, this->w));
|
||||
attrset(CRT_colors[RESET_COLOR]);
|
||||
}
|
||||
this->oldSelected = this->selected;
|
||||
move(0, 0);
|
||||
}
|
||||
|
||||
void Panel_onKey(Panel* this, int key) {
|
||||
assert (this != NULL);
|
||||
switch (key) {
|
||||
case KEY_DOWN:
|
||||
if (this->selected + 1 < Vector_size(this->items))
|
||||
this->selected++;
|
||||
break;
|
||||
case KEY_UP:
|
||||
if (this->selected > 0)
|
||||
this->selected--;
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
if (this->scrollH > 0) {
|
||||
this->scrollH -= 5;
|
||||
this->needsRedraw = true;
|
||||
}
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
this->scrollH += 5;
|
||||
this->needsRedraw = true;
|
||||
break;
|
||||
case KEY_PPAGE:
|
||||
this->selected -= this->h;
|
||||
if (this->selected < 0)
|
||||
this->selected = 0;
|
||||
break;
|
||||
case KEY_NPAGE:
|
||||
this->selected += this->h;
|
||||
int size = Vector_size(this->items);
|
||||
if (this->selected >= size)
|
||||
this->selected = size - 1;
|
||||
break;
|
||||
case KEY_HOME:
|
||||
this->selected = 0;
|
||||
break;
|
||||
case KEY_END:
|
||||
this->selected = Vector_size(this->items) - 1;
|
||||
break;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user