2020-11-21 20:40:08 +00:00
|
|
|
/*
|
|
|
|
htop - OptionItem.c
|
|
|
|
(C) 2004-2011 Hisham H. Muhammad
|
2021-09-22 09:33:00 +00:00
|
|
|
Released under the GNU GPLv2+, see the COPYING file
|
2020-11-21 20:40:08 +00:00
|
|
|
in the source distribution for its full text.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "OptionItem.h"
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "CRT.h"
|
2020-12-06 14:22:41 +00:00
|
|
|
#include "Macros.h"
|
2020-11-21 20:40:08 +00:00
|
|
|
#include "RichString.h"
|
2020-12-06 14:22:41 +00:00
|
|
|
#include "XUtils.h"
|
2020-11-21 20:40:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
static void OptionItem_delete(Object* cast) {
|
|
|
|
OptionItem* this = (OptionItem*)cast;
|
|
|
|
assert (this != NULL);
|
|
|
|
|
|
|
|
free(this->text);
|
|
|
|
free(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void CheckItem_display(const Object* cast, RichString* out) {
|
|
|
|
const CheckItem* this = (const CheckItem*)cast;
|
|
|
|
assert (this != NULL);
|
|
|
|
|
2020-12-04 13:44:57 +00:00
|
|
|
RichString_writeAscii(out, CRT_colors[CHECK_BOX], "[");
|
2020-11-21 20:40:08 +00:00
|
|
|
if (CheckItem_get(this)) {
|
2020-12-04 13:44:57 +00:00
|
|
|
RichString_appendAscii(out, CRT_colors[CHECK_MARK], "x");
|
2020-11-21 20:40:08 +00:00
|
|
|
} else {
|
2020-12-04 13:44:57 +00:00
|
|
|
RichString_appendAscii(out, CRT_colors[CHECK_MARK], " ");
|
2020-11-21 20:40:08 +00:00
|
|
|
}
|
2020-12-04 13:44:57 +00:00
|
|
|
RichString_appendAscii(out, CRT_colors[CHECK_BOX], "] ");
|
|
|
|
RichString_appendWide(out, CRT_colors[CHECK_TEXT], this->super.text);
|
2020-11-21 20:40:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void NumberItem_display(const Object* cast, RichString* out) {
|
|
|
|
const NumberItem* this = (const NumberItem*)cast;
|
|
|
|
assert (this != NULL);
|
|
|
|
|
|
|
|
char buffer[12];
|
2020-12-04 13:44:57 +00:00
|
|
|
RichString_writeAscii(out, CRT_colors[CHECK_BOX], "[");
|
2020-11-21 20:40:08 +00:00
|
|
|
int written;
|
|
|
|
if (this->scale < 0) {
|
|
|
|
written = xSnprintf(buffer, sizeof(buffer), "%.*f", -this->scale, pow(10, this->scale) * NumberItem_get(this));
|
|
|
|
} else if (this->scale > 0) {
|
|
|
|
written = xSnprintf(buffer, sizeof(buffer), "%d", (int) (pow(10, this->scale) * NumberItem_get(this)));
|
|
|
|
} else {
|
|
|
|
written = xSnprintf(buffer, sizeof(buffer), "%d", NumberItem_get(this));
|
|
|
|
}
|
2021-04-14 18:47:42 +00:00
|
|
|
RichString_appendnAscii(out, CRT_colors[CHECK_MARK], buffer, written);
|
2020-12-04 13:44:57 +00:00
|
|
|
RichString_appendAscii(out, CRT_colors[CHECK_BOX], "]");
|
2020-11-21 20:40:08 +00:00
|
|
|
for (int i = written; i < 5; i++) {
|
2020-12-04 13:44:57 +00:00
|
|
|
RichString_appendAscii(out, CRT_colors[CHECK_BOX], " ");
|
2020-11-21 20:40:08 +00:00
|
|
|
}
|
2020-12-04 13:44:57 +00:00
|
|
|
RichString_appendWide(out, CRT_colors[CHECK_TEXT], this->super.text);
|
2020-11-21 20:40:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const OptionItemClass OptionItem_class = {
|
|
|
|
.super = {
|
|
|
|
.extends = Class(Object),
|
|
|
|
.delete = OptionItem_delete
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const OptionItemClass CheckItem_class = {
|
|
|
|
.super = {
|
|
|
|
.extends = Class(OptionItem),
|
|
|
|
.delete = OptionItem_delete,
|
|
|
|
.display = CheckItem_display
|
|
|
|
},
|
|
|
|
.kind = OPTION_ITEM_CHECK
|
|
|
|
};
|
|
|
|
|
|
|
|
const OptionItemClass NumberItem_class = {
|
|
|
|
.super = {
|
|
|
|
.extends = Class(OptionItem),
|
|
|
|
.delete = OptionItem_delete,
|
|
|
|
.display = NumberItem_display
|
|
|
|
},
|
|
|
|
.kind = OPTION_ITEM_NUMBER
|
|
|
|
};
|
|
|
|
|
|
|
|
CheckItem* CheckItem_newByRef(const char* text, bool* ref) {
|
|
|
|
CheckItem* this = AllocThis(CheckItem);
|
|
|
|
this->super.text = xStrdup(text);
|
|
|
|
this->value = false;
|
|
|
|
this->ref = ref;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
CheckItem* CheckItem_newByVal(const char* text, bool value) {
|
|
|
|
CheckItem* this = AllocThis(CheckItem);
|
|
|
|
this->super.text = xStrdup(text);
|
|
|
|
this->value = value;
|
|
|
|
this->ref = NULL;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CheckItem_get(const CheckItem* this) {
|
|
|
|
if (this->ref) {
|
|
|
|
return *(this->ref);
|
|
|
|
} else {
|
|
|
|
return this->value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CheckItem_set(CheckItem* this, bool value) {
|
|
|
|
if (this->ref) {
|
|
|
|
*(this->ref) = value;
|
|
|
|
} else {
|
|
|
|
this->value = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CheckItem_toggle(CheckItem* this) {
|
|
|
|
if (this->ref) {
|
|
|
|
*(this->ref) = !*(this->ref);
|
|
|
|
} else {
|
|
|
|
this->value = !this->value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NumberItem* NumberItem_newByRef(const char* text, int* ref, int scale, int min, int max) {
|
|
|
|
assert(min <= max);
|
|
|
|
|
|
|
|
NumberItem* this = AllocThis(NumberItem);
|
|
|
|
this->super.text = xStrdup(text);
|
|
|
|
this->value = 0;
|
|
|
|
this->ref = ref;
|
|
|
|
this->scale = scale;
|
|
|
|
this->min = min;
|
|
|
|
this->max = max;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
NumberItem* NumberItem_newByVal(const char* text, int value, int scale, int min, int max) {
|
|
|
|
assert(min <= max);
|
|
|
|
|
|
|
|
NumberItem* this = AllocThis(NumberItem);
|
|
|
|
this->super.text = xStrdup(text);
|
|
|
|
this->value = CLAMP(value, min, max);
|
|
|
|
this->ref = NULL;
|
|
|
|
this->scale = scale;
|
|
|
|
this->min = min;
|
|
|
|
this->max = max;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
int NumberItem_get(const NumberItem* this) {
|
|
|
|
if (this->ref) {
|
|
|
|
return *(this->ref);
|
|
|
|
} else {
|
|
|
|
return this->value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void NumberItem_decrease(NumberItem* this) {
|
|
|
|
if (this->ref) {
|
|
|
|
*(this->ref) = CLAMP(*(this->ref) - 1, this->min, this->max);
|
|
|
|
} else {
|
|
|
|
this->value = CLAMP(this->value - 1, this->min, this->max);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void NumberItem_increase(NumberItem* this) {
|
|
|
|
if (this->ref) {
|
|
|
|
*(this->ref) = CLAMP(*(this->ref) + 1, this->min, this->max);
|
|
|
|
} else {
|
|
|
|
this->value = CLAMP(this->value + 1, this->min, this->max);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void NumberItem_toggle(NumberItem* this) {
|
|
|
|
if (this->ref) {
|
|
|
|
if (*(this->ref) >= this->max)
|
|
|
|
*(this->ref) = this->min;
|
|
|
|
else
|
|
|
|
*(this->ref) += 1;
|
|
|
|
} else {
|
|
|
|
if (this->value >= this->max)
|
|
|
|
this->value = this->min;
|
|
|
|
else
|
|
|
|
this->value += 1;
|
|
|
|
}
|
|
|
|
}
|