You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
215 lines
5.3 KiB
215 lines
5.3 KiB
/* |
|
htop - OptionItem.c |
|
(C) 2004-2011 Hisham H. Muhammad |
|
Released under the GNU GPLv2+, see the COPYING file |
|
in the source distribution for its full text. |
|
*/ |
|
|
|
#include "OptionItem.h" |
|
|
|
#include <assert.h> |
|
#include <math.h> |
|
#include <stdlib.h> |
|
|
|
#include "CRT.h" |
|
#include "Macros.h" |
|
#include "RichString.h" |
|
#include "XUtils.h" |
|
|
|
|
|
static void OptionItem_delete(Object* cast) { |
|
OptionItem* this = (OptionItem*)cast; |
|
assert (this != NULL); |
|
|
|
free(this->text); |
|
free(this); |
|
} |
|
|
|
static void TextItem_display(const Object* cast, RichString* out) { |
|
const TextItem* this = (const TextItem*)cast; |
|
assert (this != NULL); |
|
|
|
RichString_appendWide(out, CRT_colors[HELP_BOLD], this->super.text); |
|
} |
|
|
|
static void CheckItem_display(const Object* cast, RichString* out) { |
|
const CheckItem* this = (const CheckItem*)cast; |
|
assert (this != NULL); |
|
|
|
RichString_writeAscii(out, CRT_colors[CHECK_BOX], "["); |
|
if (CheckItem_get(this)) { |
|
RichString_appendAscii(out, CRT_colors[CHECK_MARK], "x"); |
|
} else { |
|
RichString_appendAscii(out, CRT_colors[CHECK_MARK], " "); |
|
} |
|
RichString_appendAscii(out, CRT_colors[CHECK_BOX], "] "); |
|
RichString_appendWide(out, CRT_colors[CHECK_TEXT], this->super.text); |
|
} |
|
|
|
static void NumberItem_display(const Object* cast, RichString* out) { |
|
const NumberItem* this = (const NumberItem*)cast; |
|
assert (this != NULL); |
|
|
|
char buffer[12]; |
|
RichString_writeAscii(out, CRT_colors[CHECK_BOX], "["); |
|
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)); |
|
} |
|
RichString_appendnAscii(out, CRT_colors[CHECK_MARK], buffer, written); |
|
RichString_appendAscii(out, CRT_colors[CHECK_BOX], "]"); |
|
for (int i = written; i < 5; i++) { |
|
RichString_appendAscii(out, CRT_colors[CHECK_BOX], " "); |
|
} |
|
RichString_appendWide(out, CRT_colors[CHECK_TEXT], this->super.text); |
|
} |
|
|
|
const OptionItemClass OptionItem_class = { |
|
.super = { |
|
.extends = Class(Object), |
|
.delete = OptionItem_delete |
|
} |
|
}; |
|
|
|
const OptionItemClass TextItem_class = { |
|
.super = { |
|
.extends = Class(OptionItem), |
|
.delete = OptionItem_delete, |
|
.display = TextItem_display |
|
}, |
|
.kind = OPTION_ITEM_TEXT |
|
}; |
|
|
|
|
|
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 |
|
}; |
|
|
|
TextItem* TextItem_new(const char* text) { |
|
TextItem* this = AllocThis(TextItem); |
|
this->super.text = xStrdup(text); |
|
return this; |
|
} |
|
|
|
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; |
|
} |
|
}
|
|
|