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