OptionItem.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. htop - OptionItem.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 "OptionItem.h"
  9. #include <assert.h>
  10. #include <math.h>
  11. #include <stdlib.h>
  12. #include "CRT.h"
  13. #include "Macros.h"
  14. #include "RichString.h"
  15. #include "XUtils.h"
  16. static void OptionItem_delete(Object* cast) {
  17. OptionItem* this = (OptionItem*)cast;
  18. assert (this != NULL);
  19. free(this->text);
  20. free(this);
  21. }
  22. static void TextItem_display(const Object* cast, RichString* out) {
  23. const TextItem* this = (const TextItem*)cast;
  24. assert (this != NULL);
  25. RichString_appendWide(out, CRT_colors[HELP_BOLD], this->super.text);
  26. }
  27. static void CheckItem_display(const Object* cast, RichString* out) {
  28. const CheckItem* this = (const CheckItem*)cast;
  29. assert (this != NULL);
  30. RichString_writeAscii(out, CRT_colors[CHECK_BOX], "[");
  31. if (CheckItem_get(this)) {
  32. RichString_appendAscii(out, CRT_colors[CHECK_MARK], "x");
  33. } else {
  34. RichString_appendAscii(out, CRT_colors[CHECK_MARK], " ");
  35. }
  36. RichString_appendAscii(out, CRT_colors[CHECK_BOX], "] ");
  37. RichString_appendWide(out, CRT_colors[CHECK_TEXT], this->super.text);
  38. }
  39. static void NumberItem_display(const Object* cast, RichString* out) {
  40. const NumberItem* this = (const NumberItem*)cast;
  41. assert (this != NULL);
  42. char buffer[12];
  43. RichString_writeAscii(out, CRT_colors[CHECK_BOX], "[");
  44. int written;
  45. if (this->scale < 0) {
  46. written = xSnprintf(buffer, sizeof(buffer), "%.*f", -this->scale, pow(10, this->scale) * NumberItem_get(this));
  47. } else if (this->scale > 0) {
  48. written = xSnprintf(buffer, sizeof(buffer), "%d", (int) (pow(10, this->scale) * NumberItem_get(this)));
  49. } else {
  50. written = xSnprintf(buffer, sizeof(buffer), "%d", NumberItem_get(this));
  51. }
  52. RichString_appendnAscii(out, CRT_colors[CHECK_MARK], buffer, written);
  53. RichString_appendAscii(out, CRT_colors[CHECK_BOX], "]");
  54. for (int i = written; i < 5; i++) {
  55. RichString_appendAscii(out, CRT_colors[CHECK_BOX], " ");
  56. }
  57. RichString_appendWide(out, CRT_colors[CHECK_TEXT], this->super.text);
  58. }
  59. const OptionItemClass OptionItem_class = {
  60. .super = {
  61. .extends = Class(Object),
  62. .delete = OptionItem_delete
  63. }
  64. };
  65. const OptionItemClass TextItem_class = {
  66. .super = {
  67. .extends = Class(OptionItem),
  68. .delete = OptionItem_delete,
  69. .display = TextItem_display
  70. },
  71. .kind = OPTION_ITEM_TEXT
  72. };
  73. const OptionItemClass CheckItem_class = {
  74. .super = {
  75. .extends = Class(OptionItem),
  76. .delete = OptionItem_delete,
  77. .display = CheckItem_display
  78. },
  79. .kind = OPTION_ITEM_CHECK
  80. };
  81. const OptionItemClass NumberItem_class = {
  82. .super = {
  83. .extends = Class(OptionItem),
  84. .delete = OptionItem_delete,
  85. .display = NumberItem_display
  86. },
  87. .kind = OPTION_ITEM_NUMBER
  88. };
  89. TextItem* TextItem_new(const char* text) {
  90. TextItem* this = AllocThis(TextItem);
  91. this->super.text = xStrdup(text);
  92. return this;
  93. }
  94. CheckItem* CheckItem_newByRef(const char* text, bool* ref) {
  95. CheckItem* this = AllocThis(CheckItem);
  96. this->super.text = xStrdup(text);
  97. this->value = false;
  98. this->ref = ref;
  99. return this;
  100. }
  101. CheckItem* CheckItem_newByVal(const char* text, bool value) {
  102. CheckItem* this = AllocThis(CheckItem);
  103. this->super.text = xStrdup(text);
  104. this->value = value;
  105. this->ref = NULL;
  106. return this;
  107. }
  108. bool CheckItem_get(const CheckItem* this) {
  109. if (this->ref) {
  110. return *(this->ref);
  111. } else {
  112. return this->value;
  113. }
  114. }
  115. void CheckItem_set(CheckItem* this, bool value) {
  116. if (this->ref) {
  117. *(this->ref) = value;
  118. } else {
  119. this->value = value;
  120. }
  121. }
  122. void CheckItem_toggle(CheckItem* this) {
  123. if (this->ref) {
  124. *(this->ref) = !*(this->ref);
  125. } else {
  126. this->value = !this->value;
  127. }
  128. }
  129. NumberItem* NumberItem_newByRef(const char* text, int* ref, int scale, int min, int max) {
  130. assert(min <= max);
  131. NumberItem* this = AllocThis(NumberItem);
  132. this->super.text = xStrdup(text);
  133. this->value = 0;
  134. this->ref = ref;
  135. this->scale = scale;
  136. this->min = min;
  137. this->max = max;
  138. return this;
  139. }
  140. NumberItem* NumberItem_newByVal(const char* text, int value, int scale, int min, int max) {
  141. assert(min <= max);
  142. NumberItem* this = AllocThis(NumberItem);
  143. this->super.text = xStrdup(text);
  144. this->value = CLAMP(value, min, max);
  145. this->ref = NULL;
  146. this->scale = scale;
  147. this->min = min;
  148. this->max = max;
  149. return this;
  150. }
  151. int NumberItem_get(const NumberItem* this) {
  152. if (this->ref) {
  153. return *(this->ref);
  154. } else {
  155. return this->value;
  156. }
  157. }
  158. void NumberItem_decrease(NumberItem* this) {
  159. if (this->ref) {
  160. *(this->ref) = CLAMP(*(this->ref) - 1, this->min, this->max);
  161. } else {
  162. this->value = CLAMP(this->value - 1, this->min, this->max);
  163. }
  164. }
  165. void NumberItem_increase(NumberItem* this) {
  166. if (this->ref) {
  167. *(this->ref) = CLAMP(*(this->ref) + 1, this->min, this->max);
  168. } else {
  169. this->value = CLAMP(this->value + 1, this->min, this->max);
  170. }
  171. }
  172. void NumberItem_toggle(NumberItem* this) {
  173. if (this->ref) {
  174. if (*(this->ref) >= this->max)
  175. *(this->ref) = this->min;
  176. else
  177. *(this->ref) += 1;
  178. } else {
  179. if (this->value >= this->max)
  180. this->value = this->min;
  181. else
  182. this->value += 1;
  183. }
  184. }