CategoriesPanel.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. htop - CategoriesPanel.c
  3. (C) 2004-2011 Hisham H. Muhammad
  4. Released under the GNU GPLv2+, see the COPYING file
  5. in the source distribution for its full text.
  6. */
  7. #include "config.h" // IWYU pragma: keep
  8. #include "CategoriesPanel.h"
  9. #include <ctype.h>
  10. #include <stdbool.h>
  11. #include <stdlib.h>
  12. #include "AvailableMetersPanel.h"
  13. #include "ColorsPanel.h"
  14. #include "DisplayOptionsPanel.h"
  15. #include "FunctionBar.h"
  16. #include "Header.h"
  17. #include "HeaderLayout.h"
  18. #include "HeaderOptionsPanel.h"
  19. #include "ListItem.h"
  20. #include "Macros.h"
  21. #include "MetersPanel.h"
  22. #include "Object.h"
  23. #include "ProvideCurses.h"
  24. #include "ScreensPanel.h"
  25. #include "ScreenTabsPanel.h"
  26. #include "Settings.h"
  27. #include "Vector.h"
  28. #include "XUtils.h"
  29. static const char* const CategoriesFunctions[] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done ", NULL};
  30. static void CategoriesPanel_delete(Object* object) {
  31. Panel* super = (Panel*) object;
  32. CategoriesPanel* this = (CategoriesPanel*) object;
  33. Panel_done(super);
  34. free(this);
  35. }
  36. static void CategoriesPanel_makeMetersPage(CategoriesPanel* this) {
  37. size_t columns = HeaderLayout_getColumns(this->scr->header->headerLayout);
  38. MetersPanel** meterPanels = xMallocArray(columns, sizeof(MetersPanel*));
  39. Settings* settings = this->host->settings;
  40. for (size_t i = 0; i < columns; i++) {
  41. char titleBuffer[32];
  42. xSnprintf(titleBuffer, sizeof(titleBuffer), "Column %zu", i + 1);
  43. meterPanels[i] = MetersPanel_new(settings, titleBuffer, this->header->columns[i], this->scr);
  44. if (i != 0) {
  45. meterPanels[i]->leftNeighbor = meterPanels[i - 1];
  46. meterPanels[i - 1]->rightNeighbor = meterPanels[i];
  47. }
  48. ScreenManager_add(this->scr, (Panel*) meterPanels[i], 20);
  49. }
  50. Panel* availableMeters = (Panel*) AvailableMetersPanel_new(this->host, this->header, columns, meterPanels, this->scr);
  51. ScreenManager_add(this->scr, availableMeters, -1);
  52. }
  53. static void CategoriesPanel_makeDisplayOptionsPage(CategoriesPanel* this) {
  54. Settings* settings = this->host->settings;
  55. Panel* displayOptions = (Panel*) DisplayOptionsPanel_new(settings, this->scr);
  56. ScreenManager_add(this->scr, displayOptions, -1);
  57. }
  58. static void CategoriesPanel_makeColorsPage(CategoriesPanel* this) {
  59. Settings* settings = this->host->settings;
  60. Panel* colors = (Panel*) ColorsPanel_new(settings);
  61. ScreenManager_add(this->scr, colors, -1);
  62. }
  63. #if defined(HTOP_PCP) /* all platforms supporting dynamic screens */
  64. static void CategoriesPanel_makeScreenTabsPage(CategoriesPanel* this) {
  65. Settings* settings = this->host->settings;
  66. Panel* screenTabs = (Panel*) ScreenTabsPanel_new(settings);
  67. Panel* screenNames = (Panel*) ((ScreenTabsPanel*)screenTabs)->names;
  68. ScreenManager_add(this->scr, screenTabs, 20);
  69. ScreenManager_add(this->scr, screenNames, -1);
  70. }
  71. #endif
  72. static void CategoriesPanel_makeScreensPage(CategoriesPanel* this) {
  73. Settings* settings = this->host->settings;
  74. Panel* screens = (Panel*) ScreensPanel_new(settings);
  75. Panel* columns = (Panel*) ((ScreensPanel*)screens)->columns;
  76. Panel* availableColumns = (Panel*) ((ScreensPanel*)screens)->availableColumns;
  77. ScreenManager_add(this->scr, screens, 20);
  78. ScreenManager_add(this->scr, columns, 20);
  79. ScreenManager_add(this->scr, availableColumns, -1);
  80. }
  81. static void CategoriesPanel_makeHeaderOptionsPage(CategoriesPanel* this) {
  82. Settings* settings = this->host->settings;
  83. Panel* colors = (Panel*) HeaderOptionsPanel_new(settings, this->scr);
  84. ScreenManager_add(this->scr, colors, -1);
  85. }
  86. typedef void (* CategoriesPanel_makePageFunc)(CategoriesPanel* ref);
  87. typedef struct CategoriesPanelPage_ {
  88. const char* name;
  89. CategoriesPanel_makePageFunc ctor;
  90. } CategoriesPanelPage;
  91. static CategoriesPanelPage categoriesPanelPages[] = {
  92. { .name = "Display options", .ctor = CategoriesPanel_makeDisplayOptionsPage },
  93. { .name = "Header layout", .ctor = CategoriesPanel_makeHeaderOptionsPage },
  94. { .name = "Meters", .ctor = CategoriesPanel_makeMetersPage },
  95. #if defined(HTOP_PCP) /* all platforms supporting dynamic screens */
  96. { .name = "Screen tabs", .ctor = CategoriesPanel_makeScreenTabsPage },
  97. #endif
  98. { .name = "Screens", .ctor = CategoriesPanel_makeScreensPage },
  99. { .name = "Colors", .ctor = CategoriesPanel_makeColorsPage },
  100. };
  101. static HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch) {
  102. CategoriesPanel* this = (CategoriesPanel*) super;
  103. HandlerResult result = IGNORED;
  104. int selected = Panel_getSelectedIndex(super);
  105. switch (ch) {
  106. case EVENT_SET_SELECTED:
  107. result = HANDLED;
  108. break;
  109. case KEY_UP:
  110. case KEY_CTRL('P'):
  111. case KEY_DOWN:
  112. case KEY_CTRL('N'):
  113. case KEY_NPAGE:
  114. case KEY_PPAGE:
  115. case KEY_HOME:
  116. case KEY_END: {
  117. int previous = selected;
  118. Panel_onKey(super, ch);
  119. selected = Panel_getSelectedIndex(super);
  120. if (previous != selected)
  121. result = HANDLED;
  122. break;
  123. }
  124. default:
  125. if (0 < ch && ch < 255 && isgraph((unsigned char)ch))
  126. result = Panel_selectByTyping(super, ch);
  127. if (result == BREAK_LOOP)
  128. result = IGNORED;
  129. break;
  130. }
  131. if (result == HANDLED) {
  132. int size = ScreenManager_size(this->scr);
  133. for (int i = 1; i < size; i++)
  134. ScreenManager_remove(this->scr, 1);
  135. if (selected >= 0 && (size_t)selected < ARRAYSIZE(categoriesPanelPages)) {
  136. categoriesPanelPages[selected].ctor(this);
  137. }
  138. }
  139. return result;
  140. }
  141. const PanelClass CategoriesPanel_class = {
  142. .super = {
  143. .extends = Class(Panel),
  144. .delete = CategoriesPanel_delete
  145. },
  146. .eventHandler = CategoriesPanel_eventHandler
  147. };
  148. CategoriesPanel* CategoriesPanel_new(ScreenManager* scr, Header* header, Machine* host) {
  149. CategoriesPanel* this = AllocThis(CategoriesPanel);
  150. Panel* super = (Panel*) this;
  151. FunctionBar* fuBar = FunctionBar_new(CategoriesFunctions, NULL, NULL);
  152. Panel_init(super, 1, 1, 1, 1, Class(ListItem), true, fuBar);
  153. this->scr = scr;
  154. this->host = host;
  155. this->header = header;
  156. Panel_setHeader(super, "Categories");
  157. for (size_t i = 0; i < ARRAYSIZE(categoriesPanelPages); i++)
  158. Panel_add(super, (Object*) ListItem_new(categoriesPanelPages[i].name, 0));
  159. ScreenManager_add(scr, super, 16);
  160. categoriesPanelPages[0].ctor(this);
  161. return this;
  162. }