expand/collapse tree

This commit is contained in:
Hisham Muhammad 2010-06-17 19:02:03 +00:00
parent bc4f7147cc
commit 9eb912149e
6 changed files with 36 additions and 43 deletions

View File

@ -79,6 +79,7 @@ typedef struct Process_ {
int indent; int indent;
char state; char state;
bool tag; bool tag;
bool showChildren;
pid_t ppid; pid_t ppid;
unsigned int pgrp; unsigned int pgrp;
unsigned int session; unsigned int session;
@ -331,9 +332,9 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
n -= 4; n -= 4;
} }
if (this->pl->direction == 1) if (this->pl->direction == 1)
snprintf(buf, n, " `- "); snprintf(buf, n, " `%s ", this->showChildren ? "-" : "+" );
else else
snprintf(buf, n, " ,- "); snprintf(buf, n, " ,%s ", this->showChildren ? "-" : "+" );
RichString_append(str, CRT_colors[PROCESS_TREE], buffer); RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
Process_writeCommand(this, attr, baseattr, str); Process_writeCommand(this, attr, baseattr, str);
return; return;
@ -460,6 +461,7 @@ Process* Process_new(struct ProcessList_ *pl) {
this->pid = 0; this->pid = 0;
this->pl = pl; this->pl = pl;
this->tag = false; this->tag = false;
this->showChildren = true;
this->updated = false; this->updated = false;
this->utime = 0; this->utime = 0;
this->stime = 0; this->stime = 0;

View File

@ -81,6 +81,7 @@ typedef struct Process_ {
int indent; int indent;
char state; char state;
bool tag; bool tag;
bool showChildren;
pid_t ppid; pid_t ppid;
unsigned int pgrp; unsigned int pgrp;
unsigned int session; unsigned int session;

View File

@ -331,7 +331,7 @@ int ProcessList_size(ProcessList* this) {
return (Vector_size(this->processes)); return (Vector_size(this->processes));
} }
static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int indent, int direction) { static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int indent, int direction, bool show) {
Vector* children = Vector_new(PROCESS_CLASS, false, DEFAULT_SIZE, Process_compare); Vector* children = Vector_new(PROCESS_CLASS, false, DEFAULT_SIZE, Process_compare);
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) { for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
@ -344,17 +344,21 @@ static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int i
int size = Vector_size(children); int size = Vector_size(children);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Process* process = (Process*) (Vector_get(children, i)); Process* process = (Process*) (Vector_get(children, i));
int s = this->processes2->items; if (show) {
if (direction == 1) int s = this->processes2->items;
Vector_add(this->processes2, process); if (direction == 1)
else Vector_add(this->processes2, process);
Vector_insert(this->processes2, 0, process); else
assert(this->processes2->items == s+1); (void)s; Vector_insert(this->processes2, 0, process);
int nextIndent = indent; assert(this->processes2->items == s+1); (void)s;
if (i < size - 1) int nextIndent = indent;
nextIndent = indent | (1 << level); if (i < size - 1)
ProcessList_buildTree(this, process->pid, level+1, nextIndent, direction); nextIndent = indent | (1 << level);
process->indent = indent | (1 << level); ProcessList_buildTree(this, process->pid, level+1, nextIndent, direction, process->showChildren);
process->indent = indent | (1 << level);
} else {
Hashtable_remove(this->processTable, process->pid);
}
} }
Vector_delete(children); Vector_delete(children);
} }
@ -382,13 +386,13 @@ void ProcessList_sort(ProcessList* this) {
init->indent = 0; init->indent = 0;
Vector_add(this->processes2, init); Vector_add(this->processes2, init);
// Recursively empty list // Recursively empty list
ProcessList_buildTree(this, init->pid, 0, 0, direction); ProcessList_buildTree(this, init->pid, 0, 0, direction, true);
// Add leftovers // Add leftovers
while (Vector_size(this->processes)) { while (Vector_size(this->processes)) {
Process* p = (Process*) (Vector_take(this->processes, 0)); Process* p = (Process*) (Vector_take(this->processes, 0));
p->indent = 0; p->indent = 0;
Vector_add(this->processes2, p); Vector_add(this->processes2, p);
ProcessList_buildTree(this, p->pid, 0, 0, direction); ProcessList_buildTree(this, p->pid, 0, 0, direction, p->showChildren);
} }
assert(Vector_size(this->processes2) == vsize); (void)vsize; assert(Vector_size(this->processes2) == vsize); (void)vsize;
assert(Vector_size(this->processes) == 0); assert(Vector_size(this->processes) == 0);

View File

@ -20,8 +20,6 @@ in the source distribution for its full text.
#define DEFAULT_SIZE -1 #define DEFAULT_SIZE -1
#endif #endif
typedef void(*Vector_procedure)(void*);
typedef struct Vector_ { typedef struct Vector_ {
Object **array; Object **array;
Object_Compare compare; Object_Compare compare;
@ -255,16 +253,3 @@ inline int Vector_indexOf(Vector* this, void* search_, Object_Compare compare) {
} }
return -1; return -1;
} }
/*
static void Vector_foreach(Vector* this, Vector_procedure f) {
int i;
assert(Vector_isConsistent(this));
for (i = 0; i < this->items; i++)
f(this->array[i]);
assert(Vector_isConsistent(this));
}
*/

View File

@ -22,8 +22,6 @@ in the source distribution for its full text.
#define DEFAULT_SIZE -1 #define DEFAULT_SIZE -1
#endif #endif
typedef void(*Vector_procedure)(void*);
typedef struct Vector_ { typedef struct Vector_ {
Object **array; Object **array;
Object_Compare compare; Object_Compare compare;
@ -73,8 +71,4 @@ void Vector_add(Vector* this, void* data_);
extern int Vector_indexOf(Vector* this, void* search_, Object_Compare compare); extern int Vector_indexOf(Vector* this, void* search_, Object_Compare compare);
/*
*/
#endif #endif

19
htop.c
View File

@ -117,10 +117,10 @@ static void showHelp(ProcessList* pl) {
mvaddstr(11, 0, " F3 /: incremental name search H: hide/show user threads"); mvaddstr(11, 0, " F3 /: incremental name search H: hide/show user threads");
mvaddstr(12, 0, " K: hide/show kernel threads"); mvaddstr(12, 0, " K: hide/show kernel threads");
mvaddstr(13, 0, " Space: tag processes F: cursor follows process"); mvaddstr(13, 0, " Space: tag processes F: cursor follows process");
mvaddstr(14, 0, " U: untag all processes"); mvaddstr(14, 0, " U: untag all processes + -: expand/collapse tree");
mvaddstr(15, 0, " F9 k: kill process/tagged processes P: sort by CPU%"); mvaddstr(15, 0, " F9 k: kill process/tagged processes P: sort by CPU%");
mvaddstr(16, 0, " - ] F7: higher priority (root only) M: sort by MEM%"); mvaddstr(16, 0, " ] F7: higher priority (root only) M: sort by MEM%");
mvaddstr(17, 0, " + [ F8: lower priority (+ nice) T: sort by TIME"); mvaddstr(17, 0, " [ F8: lower priority (+ nice) T: sort by TIME");
#ifdef HAVE_PLPA #ifdef HAVE_PLPA
if (pl->processorCount > 1) if (pl->processorCount > 1)
mvaddstr(18, 0, " a: set CPU affinity F4 I: invert sort order"); mvaddstr(18, 0, " a: set CPU affinity F4 I: invert sort order");
@ -639,6 +639,16 @@ int main(int argc, char** argv) {
} }
break; break;
} }
case '+':
case '=':
case '-':
{
Process* p = (Process*) Panel_getSelected(panel);
p->showChildren = !p->showChildren;
refreshTimeout = 0;
doRecalculate = true;
break;
}
case KEY_F(9): case KEY_F(9):
case 'k': case 'k':
{ {
@ -751,15 +761,12 @@ int main(int argc, char** argv) {
} }
case KEY_F(8): case KEY_F(8):
case '[': case '[':
case '=':
case '+':
{ {
doRefresh = changePriority(panel, 1); doRefresh = changePriority(panel, 1);
break; break;
} }
case KEY_F(7): case KEY_F(7):
case ']': case ']':
case '-':
{ {
doRefresh = changePriority(panel, -1); doRefresh = changePriority(panel, -1);
break; break;