Commit 8c43218a authored by Hisham Muhammad's avatar Hisham Muhammad
Browse files

Introduce screen tabs

parent e77a16f4
......@@ -26,6 +26,7 @@ in the source distribution for its full text.
#include <math.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <sys/param.h>
#include <sys/time.h>
......@@ -80,7 +81,7 @@ Object* Action_pickFromVector(State* st, Panel* list, int x) {
header->pl->following = pid;
unfollow = true;
}
ScreenManager_run(scr, &panelFocus, &ch);
ScreenManager_run(scr, &panelFocus, &ch, NULL);
if (unfollow) {
header->pl->following = -1;
}
......@@ -106,7 +107,7 @@ static void Action_runSetup(Settings* settings, const Header* header, ProcessLis
CategoriesPanel_makeMetersPage(panelCategories);
Panel* panelFocus;
int ch;
ScreenManager_run(scr, &panelFocus, &ch);
ScreenManager_run(scr, &panelFocus, &ch, "Setup");
ScreenManager_delete(scr);
if (settings->changed) {
Header_writeBackToSettings(header);
......@@ -307,14 +308,33 @@ static Htop_Reaction actionNextScreen(State* st) {
static Htop_Reaction actionPrevScreen(State* st) {
Settings* settings = st->settings;
settings->ssIndex--;
if (settings->ssIndex == -1) {
if (settings->ssIndex == 0) {
settings->ssIndex = settings->nScreens - 1;
} else {
settings->ssIndex--;
}
settings->ss = settings->screens[settings->ssIndex];
return HTOP_REFRESH;
}
Htop_Reaction Action_setScreenTab(Settings* settings, int x) {
int s = 2;
for (unsigned int i = 0; i < settings->nScreens; i++) {
if (x < s) {
return 0;
}
const char* name = settings->screens[i]->name;
int len = strlen(name);
if (x <= s + len + 1) {
settings->ssIndex = i;
settings->ss = settings->screens[i];
return HTOP_REFRESH;
}
s += len + 3;
}
return 0;
}
static Htop_Reaction actionSetAffinity(State* st) {
if (st->pl->cpuCount == 1)
return HTOP_OK;
......
......@@ -49,6 +49,8 @@ Htop_Reaction Action_setSortKey(Settings* settings, ProcessField sortKey);
// ----------------------------------------
Htop_Reaction Action_setScreenTab(Settings* settings, int x);
Htop_Reaction Action_follow(State* st);
......
......@@ -130,6 +130,10 @@ typedef enum ColorElements_ {
CPU_STEAL,
CPU_GUEST,
PANEL_EDIT,
SCREENS_OTH_BORDER,
SCREENS_OTH_TEXT,
SCREENS_CUR_BORDER,
SCREENS_CUR_TEXT,
LAST_COLORELEMENT
} ColorElements;
......@@ -235,6 +239,10 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[CPU_STEAL] = ColorPair(Cyan,Black),
[CPU_GUEST] = ColorPair(Cyan,Black),
[PANEL_EDIT] = ColorPair(White,Blue),
[SCREENS_OTH_BORDER] = ColorPair(Blue,Blue),
[SCREENS_OTH_TEXT] = ColorPair(Black,Blue),
[SCREENS_CUR_BORDER] = ColorPair(Green,Green),
[SCREENS_CUR_TEXT] = ColorPair(Black,Green),
},
[COLORSCHEME_MONOCHROME] = {
[RESET_COLOR] = A_NORMAL,
......@@ -295,6 +303,10 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[CPU_STEAL] = A_REVERSE,
[CPU_GUEST] = A_REVERSE,
[PANEL_EDIT] = A_BOLD,
[SCREENS_OTH_BORDER] = A_DIM,
[SCREENS_OTH_TEXT] = A_DIM,
[SCREENS_CUR_BORDER] = A_REVERSE,
[SCREENS_CUR_TEXT] = A_REVERSE,
},
[COLORSCHEME_BLACKONWHITE] = {
[RESET_COLOR] = ColorPair(Black,White),
......@@ -355,6 +367,10 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[CPU_STEAL] = ColorPair(Cyan,White),
[CPU_GUEST] = ColorPair(Cyan,White),
[PANEL_EDIT] = ColorPair(White,Blue),
[SCREENS_OTH_BORDER] = A_BOLD | ColorPair(Black,White),
[SCREENS_OTH_TEXT] = A_BOLD | ColorPair(Black,White),
[SCREENS_CUR_BORDER] = ColorPair(Green,Green),
[SCREENS_CUR_TEXT] = ColorPair(Black,Green),
},
[COLORSCHEME_LIGHTTERMINAL] = {
[RESET_COLOR] = ColorPair(Black,Black),
......@@ -415,6 +431,10 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[CPU_STEAL] = ColorPair(Black,Black),
[CPU_GUEST] = ColorPair(Black,Black),
[PANEL_EDIT] = ColorPair(White,Blue),
[SCREENS_OTH_BORDER] = ColorPair(Blue,Black),
[SCREENS_OTH_TEXT] = ColorPair(Blue,Black),
[SCREENS_CUR_BORDER] = ColorPair(Green,Green),
[SCREENS_CUR_TEXT] = ColorPair(Black,Green),
},
[COLORSCHEME_MIDNIGHT] = {
[RESET_COLOR] = ColorPair(White,Blue),
......@@ -475,6 +495,10 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[CPU_STEAL] = ColorPair(White,Blue),
[CPU_GUEST] = ColorPair(White,Blue),
[PANEL_EDIT] = ColorPair(White,Blue),
[SCREENS_OTH_BORDER] = A_BOLD | ColorPair(Yellow,Blue),
[SCREENS_OTH_TEXT] = ColorPair(Cyan,Blue),
[SCREENS_CUR_BORDER] = ColorPair(Cyan,Cyan),
[SCREENS_CUR_TEXT] = ColorPair(Black,Cyan),
},
[COLORSCHEME_BLACKNIGHT] = {
[RESET_COLOR] = ColorPair(Cyan,Black),
......@@ -535,6 +559,10 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[CPU_STEAL] = ColorPair(Cyan,Black),
[CPU_GUEST] = ColorPair(Cyan,Black),
[PANEL_EDIT] = ColorPair(White,Cyan),
[SCREENS_OTH_BORDER] = ColorPair(White,Black),
[SCREENS_OTH_TEXT] = ColorPair(Cyan,Black),
[SCREENS_CUR_BORDER] = A_BOLD | ColorPair(White,Black),
[SCREENS_CUR_TEXT] = A_BOLD | ColorPair(Green,Black),
},
[COLORSCHEME_BROKENGRAY] = { 0 } // dynamically generated.
};
......
......@@ -118,6 +118,10 @@ typedef enum ColorElements_ {
CPU_STEAL,
CPU_GUEST,
PANEL_EDIT,
SCREENS_OTH_BORDER,
SCREENS_OTH_TEXT,
SCREENS_CUR_BORDER,
SCREENS_CUR_TEXT,
LAST_COLORELEMENT
} ColorElements;
......
......@@ -145,7 +145,7 @@ CategoriesPanel* CategoriesPanel_new(ScreenManager* scr, Settings* settings, Hea
this->settings = settings;
this->header = header;
this->pl = pl;
Panel_setHeader(super, "Setup");
Panel_setHeader(super, "Categories");
Panel_add(super, (Object*) ListItem_new("Meters", 0));
Panel_add(super, (Object*) ListItem_new("Display options", 0));
Panel_add(super, (Object*) ListItem_new("Colors", 0));
......
......@@ -96,5 +96,6 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager*
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Count CPUs from 0 instead of 1"), &(settings->countCPUsFromZero)));
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Update process names on every refresh"), &(settings->updateProcessNames)));
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Add guest time in CPU meter percentage"), &(settings->accountGuestInCPUMeter)));
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Show tabs for screens"), &(settings->screenTabs)));
return this;
}
......@@ -211,6 +211,9 @@ int Header_calculateHeight(Header* this) {
}
maxHeight = MAX(maxHeight, height);
}
if (this->settings->screenTabs) {
maxHeight++;
}
this->height = maxHeight;
this->pad = pad;
return maxHeight;
......
......@@ -88,6 +88,10 @@ static HandlerResult MainPanel_eventHandler(Panel* super, int ch) {
}
reaction |= HTOP_RECALCULATE | HTOP_REDRAW_BAR | HTOP_SAVE_SETTINGS;
result = HANDLED;
} else if (EVENT_IS_SCREEN_TAB_CLICK(ch)) {
int x = EVENT_SCREEN_TAB_GET_X(ch);
reaction |= Action_setScreenTab(settings, x);
result = HANDLED;
} else if (ch != ERR && this->inc->active) {
bool filterChanged = IncSet_handleKey(this->inc, ch, super, (IncMode_GetPanelValue) MainPanel_getValue, NULL);
if (filterChanged) {
......
......@@ -40,8 +40,12 @@ typedef enum HandlerResult_ {
#define EVENT_SET_SELECTED -1
#define EVENT_HEADER_CLICK(x_) (-10000 + x_)
#define EVENT_IS_HEADER_CLICK(ev_) (ev_ >= -10000 && ev_ <= -9000)
#define EVENT_HEADER_CLICK_GET_X(ev_) (ev_ + 10000)
#define EVENT_IS_HEADER_CLICK(ev_) (ev_ >= -10000 && ev_ < -9000)
#define EVENT_SCREEN_TAB_CLICK(x_) (-20000 + x_)
#define EVENT_SCREEN_TAB_GET_X(ev_) (ev_ + 20000)
#define EVENT_IS_SCREEN_TAB_CLICK(ev_) (ev_ >= -20000 && ev_ < -10000)
typedef HandlerResult(*Panel_EventHandler)(Panel*, int);
......
......@@ -29,8 +29,12 @@ typedef enum HandlerResult_ {
#define EVENT_SET_SELECTED -1
#define EVENT_HEADER_CLICK(x_) (-10000 + x_)
#define EVENT_IS_HEADER_CLICK(ev_) (ev_ >= -10000 && ev_ <= -9000)
#define EVENT_HEADER_CLICK_GET_X(ev_) (ev_ + 10000)
#define EVENT_IS_HEADER_CLICK(ev_) (ev_ >= -10000 && ev_ < -9000)
#define EVENT_SCREEN_TAB_CLICK(x_) (-20000 + x_)
#define EVENT_SCREEN_TAB_GET_X(ev_) (ev_ + 20000)
#define EVENT_IS_SCREEN_TAB_CLICK(ev_) (ev_ >= -20000 && ev_ < -10000)
typedef HandlerResult(*Panel_EventHandler)(Panel*, int);
......
......@@ -13,6 +13,7 @@ in the source distribution for its full text.
#include <assert.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
......@@ -35,6 +36,7 @@ typedef struct ScreenManager_ {
int y2;
Orientation orientation;
Vector* panels;
const char* name;
int panelCount;
const Header* header;
const Settings* settings;
......@@ -160,7 +162,50 @@ static void checkRecalculation(ScreenManager* this, double* oldTime, int* sortTi
*rescan = false;
}
static inline bool drawTab(int* y, int* x, int l, const char* name, bool cur) {
attrset(CRT_colors[cur ? SCREENS_CUR_BORDER : SCREENS_OTH_BORDER]);
mvaddch(*y, *x, '[');
(*x)++;
if (*x >= l) return false;
int nameLen = strlen(name);
int n = MIN(l - *x, nameLen);
attrset(CRT_colors[cur ? SCREENS_CUR_TEXT : SCREENS_OTH_TEXT]);
mvaddnstr(*y, *x, name, n);
*x += n;
if (*x >= l) return false;
attrset(CRT_colors[cur ? SCREENS_CUR_BORDER : SCREENS_OTH_BORDER]);
mvaddch(*y, *x, ']');
*x += 2;
if (*x >= l) return false;
return true;
}
static void ScreenManager_drawScreenTabs(ScreenManager* this) {
ScreenSettings** screens = this->settings->screens;
int cur = this->settings->ssIndex;
int l = COLS;
Panel* panel = (Panel*) Vector_get(this->panels, 0);
int y = panel->y - 1;
int x = 2;
if (this->name) {
drawTab(&y, &x, l, this->name, true);
return;
}
for (int s = 0; screens[s]; s++) {
bool ok = drawTab(&y, &x, l, screens[s]->name, s == cur);
if (!ok) {
break;
}
}
attrset(CRT_colors[RESET_COLOR]);
}
static void ScreenManager_drawPanels(ScreenManager* this, int focus) {
if (this->settings->screenTabs) {
ScreenManager_drawScreenTabs(this);
}
int nPanels = this->panelCount;
for (int i = 0; i < nPanels; i++) {
Panel* panel = (Panel*) Vector_get(this->panels, i);
......@@ -179,7 +224,7 @@ static Panel* setCurrentPanel(ScreenManager* this, int focus) {
return panel;
}
void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey, char* name) {
bool quit = false;
int focus = 0;
......@@ -196,6 +241,8 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
int sortTimeout = 0;
int resetSortTimeout = 5;
this->name = name;
while (!quit) {
if (this->header) {
checkRecalculation(this, &oldTime, &sortTimeout, &redraw, &rescan, &timedOut);
......@@ -224,6 +271,9 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
if (mevent.y == panel->y) {
ch = EVENT_HEADER_CLICK(mevent.x - panel->x);
break;
} else if (this->settings->screenTabs && mevent.y == panel->y - 1) {
ch = EVENT_SCREEN_TAB_CLICK(mevent.x);
break;
} else if (mevent.y > panel->y && mevent.y <= panel->y+panel->h) {
ch = KEY_MOUSE;
if (panel == panelFocus || this->allowFocusChange) {
......
......@@ -27,6 +27,7 @@ typedef struct ScreenManager_ {
int y2;
Orientation orientation;
Vector* panels;
const char* name;
int panelCount;
const Header* header;
const Settings* settings;
......@@ -49,6 +50,6 @@ Panel* ScreenManager_remove(ScreenManager* this, int idx);
void ScreenManager_resize(ScreenManager* this, int x1, int y1, int x2, int y2);
void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey);
void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey, char* name);
#endif
......@@ -149,6 +149,7 @@ static void rebuildSettingsArray(Panel* super) {
ScreenListItem* item = (ScreenListItem*) Panel_get(super, i);
this->settings->screens[i] = item->ss;
}
this->settings->nScreens = n;
}
static void addNewScreen(Panel* super) {
......
......@@ -73,6 +73,7 @@ typedef struct Settings_ {
bool updateProcessNames;
bool accountGuestInCPUMeter;
bool headerMargin;
bool screenTabs;
bool changed;
} Settings;
......@@ -267,6 +268,7 @@ ScreenSettings* Settings_newScreen(Settings* this, const char* name, const char*
ss->direction = 1;
ss->treeView = 0;
readFields(ss->fields, &(ss->flags), line);
ss->sortKey = ss->fields[0];
this->screens[this->nScreens] = ss;
this->nScreens++;
this->screens = xRealloc(this->screens, sizeof(ScreenSettings*) * (this->nScreens + 1));
......@@ -331,6 +333,8 @@ static bool Settings_read(Settings* this, const char* fileName) {
this->highlightThreads = atoi(option[1]);
} else if (String_eq(option[0], "header_margin")) {
this->headerMargin = atoi(option[1]);
} else if (String_eq(option[0], "screen_tabs")) {
this->screenTabs = atoi(option[1]);
} else if (String_eq(option[0], "expand_system_time")) {
// Compatibility option.
this->detailedCPUTime = atoi(option[1]);
......@@ -443,6 +447,7 @@ bool Settings_write(Settings* this) {
fprintf(fd, "highlight_megabytes=%d\n", (int) this->highlightMegabytes);
fprintf(fd, "highlight_threads=%d\n", (int) this->highlightThreads);
fprintf(fd, "header_margin=%d\n", (int) this->headerMargin);
fprintf(fd, "screen_tabs=%d\n", (int) this->screenTabs);
fprintf(fd, "detailed_cpu_time=%d\n", (int) this->detailedCPUTime);
fprintf(fd, "cpu_count_from_zero=%d\n", (int) this->countCPUsFromZero);
fprintf(fd, "update_process_names=%d\n", (int) this->updateProcessNames);
......@@ -559,6 +564,7 @@ Settings* Settings_new(int cpuCount) {
this->highlightMegabytes = true;
this->highlightThreads = true;
this->headerMargin = true;
this->screenTabs = true;
}
this->ssIndex = 0;
......
......@@ -64,6 +64,7 @@ typedef struct Settings_ {
bool updateProcessNames;
bool accountGuestInCPUMeter;
bool headerMargin;
bool screenTabs;
bool changed;
} Settings;
......
......@@ -38,7 +38,7 @@ typedef enum DarwinProcessFields {
ScreenDefaults Platform_defaultScreens[] = {
{
.name = "Default",
.name = "Main",
.columns = "PID USER PRIORITY NICE M_SIZE M_RESIDENT STATE PERCENT_CPU PERCENT_MEM TIME Command",
.sortKey = "PERCENT_CPU",
},
......
......@@ -42,7 +42,7 @@ extern ProcessFieldData Process_fields[];
ScreenDefaults Platform_defaultScreens[] = {
{
.name = "Default",
.name = "Main",
.columns = "PID USER PRIORITY NICE M_SIZE M_RESIDENT STATE PERCENT_CPU PERCENT_MEM TIME Command",
.sortKey = "PERCENT_CPU",
},
......
......@@ -41,7 +41,7 @@ extern ProcessFieldData Process_fields[];
ScreenDefaults Platform_defaultScreens[] = {
{
.name = "Default",
.name = "Main",
.columns = "PID USER PRIORITY NICE M_SIZE M_RESIDENT STATE PERCENT_CPU PERCENT_MEM TIME Command",
.sortKey = "PERCENT_CPU",
},
......
......@@ -237,7 +237,7 @@ int main(int argc, char** argv) {
millisleep(75);
ProcessList_scan(pl);
ScreenManager_run(scr, NULL, NULL);
ScreenManager_run(scr, NULL, NULL, NULL);
attron(CRT_colors[RESET_COLOR]);
mvhline(LINES-1, 0, ' ', COLS);
......
......@@ -84,7 +84,7 @@ const SignalItem Platform_signals[] = {
ScreenDefaults Platform_defaultScreens[] = {
{
.name = "Default",
.name = "Main",
.columns = "PID USER PRIORITY NICE M_SIZE M_RESIDENT M_SHARE STATE PERCENT_CPU PERCENT_MEM TIME Command",
.sortKey = "PERCENT_CPU",
},
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment