mirror of
https://github.com/xzeldon/htop.git
synced 2025-01-31 09:07:25 +03:00
157086e750
RichString_writeFrom takes a top spot during performance analysis due to the calls to mbstowcs() and iswprint(). Most of the time we know in advance that we are only going to print regular ASCII characters.
192 lines
4.7 KiB
C
192 lines
4.7 KiB
C
/*
|
|
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 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_appendAscii(out, CRT_colors[CHECK_MARK], buffer);
|
|
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 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;
|
|
}
|
|
}
|