fixed item column formatters

This commit is contained in:
nakst 2021-11-21 12:27:50 +00:00
parent 4f00b61da9
commit 48bb528b9d
9 changed files with 273 additions and 83 deletions

View File

@ -238,24 +238,24 @@ void VariantsPopupCreate(Instance *instance, EsElement *element, EsCommand *) {
EsPanel *panel = EsPanelCreate(menu, ES_PANEL_HORIZONTAL, ES_STYLE_PANEL_POPUP);
EsListView *list = EsListViewCreate(panel, ES_LIST_VIEW_CHOICE_SELECT | ES_LIST_VIEW_FIXED_ITEMS, ES_STYLE_LIST_CHOICE_BORDERED);
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 1), 0, INTERFACE_STRING(FontBookVariantNormal100));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 2), 0, INTERFACE_STRING(FontBookVariantNormal200));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 3), 0, INTERFACE_STRING(FontBookVariantNormal300));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 4), 0, INTERFACE_STRING(FontBookVariantNormal400));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 5), 0, INTERFACE_STRING(FontBookVariantNormal500));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 6), 0, INTERFACE_STRING(FontBookVariantNormal600));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 7), 0, INTERFACE_STRING(FontBookVariantNormal700));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 8), 0, INTERFACE_STRING(FontBookVariantNormal800));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 9), 0, INTERFACE_STRING(FontBookVariantNormal900));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 11), 0, INTERFACE_STRING(FontBookVariantItalic100));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 12), 0, INTERFACE_STRING(FontBookVariantItalic200));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 13), 0, INTERFACE_STRING(FontBookVariantItalic300));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 14), 0, INTERFACE_STRING(FontBookVariantItalic400));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 15), 0, INTERFACE_STRING(FontBookVariantItalic500));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 16), 0, INTERFACE_STRING(FontBookVariantItalic600));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 17), 0, INTERFACE_STRING(FontBookVariantItalic700));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 18), 0, INTERFACE_STRING(FontBookVariantItalic800));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 19), 0, INTERFACE_STRING(FontBookVariantItalic900));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 1), 0, INTERFACE_STRING(FontBookVariantNormal100));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 2), 0, INTERFACE_STRING(FontBookVariantNormal200));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 3), 0, INTERFACE_STRING(FontBookVariantNormal300));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 4), 0, INTERFACE_STRING(FontBookVariantNormal400));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 5), 0, INTERFACE_STRING(FontBookVariantNormal500));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 6), 0, INTERFACE_STRING(FontBookVariantNormal600));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 7), 0, INTERFACE_STRING(FontBookVariantNormal700));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 8), 0, INTERFACE_STRING(FontBookVariantNormal800));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 9), 0, INTERFACE_STRING(FontBookVariantNormal900));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 11), 0, INTERFACE_STRING(FontBookVariantItalic100));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 12), 0, INTERFACE_STRING(FontBookVariantItalic200));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 13), 0, INTERFACE_STRING(FontBookVariantItalic300));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 14), 0, INTERFACE_STRING(FontBookVariantItalic400));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 15), 0, INTERFACE_STRING(FontBookVariantItalic500));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 16), 0, INTERFACE_STRING(FontBookVariantItalic600));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 17), 0, INTERFACE_STRING(FontBookVariantItalic700));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 18), 0, INTERFACE_STRING(FontBookVariantItalic800));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 19), 0, INTERFACE_STRING(FontBookVariantItalic900));
EsListViewFixedItemSelect(list, instance->fontVariant);
list->messageUser = [] (EsElement *element, EsMessage *message) {

View File

@ -4,14 +4,20 @@
#define COLUMN_AGE (1)
#define COLUMN_FAVORITE_COLOR (2)
void AddPerson(EsListView *list, const char *name, int age, const char *favoriteColor) {
char ageString[16];
EsStringFormat(ageString, sizeof(ageString), "%d%c", age, 0);
const EsListViewEnumString colorStrings[] = {
#define COLOR_RED (0)
{ "\a#e00]Red", -1 },
#define COLOR_GREEN (1)
{ "\a#080]Green", -1 },
#define COLOR_BLUE (2)
{ "\a#00f]Blue", -1 },
};
void AddPerson(EsListView *list, const char *name, int age, int favoriteColor) {
EsListViewIndex index = EsListViewFixedItemInsert(list);
EsListViewFixedItemSet(list, index, COLUMN_NAME, name);
EsListViewFixedItemSet(list, index, COLUMN_AGE, ageString);
EsListViewFixedItemSet(list, index, COLUMN_FAVORITE_COLOR, favoriteColor);
EsListViewFixedItemSetString (list, index, COLUMN_NAME, name);
EsListViewFixedItemSetInteger(list, index, COLUMN_AGE, age);
EsListViewFixedItemSetInteger(list, index, COLUMN_FAVORITE_COLOR, favoriteColor);
}
void _start() {
@ -23,14 +29,21 @@ void _start() {
if (message->type == ES_MSG_INSTANCE_CREATE) {
EsInstance *instance = EsInstanceCreate(message, "List", -1);
EsPanel *wrapper = EsPanelCreate(instance->window, ES_CELL_FILL, ES_STYLE_PANEL_WINDOW_DIVIDER);
EsListView *list = EsListViewCreate(wrapper, ES_CELL_FILL | ES_LIST_VIEW_COLUMNS | ES_LIST_VIEW_FIXED_ITEMS);
EsListViewRegisterColumn(list, COLUMN_NAME, "Name", -1, ES_FLAGS_DEFAULT, 150);
EsListViewRegisterColumn(list, COLUMN_AGE, "Age", -1, ES_TEXT_H_RIGHT, 100);
EsListViewRegisterColumn(list, COLUMN_FAVORITE_COLOR, "Favorite color", -1, ES_DRAW_CONTENT_RICH_TEXT, 150);
EsListViewRegisterColumn(list, COLUMN_NAME, "Name", -1,
ES_FLAGS_DEFAULT, 150);
EsListViewRegisterColumn(list, COLUMN_AGE, "Age", -1,
ES_TEXT_H_RIGHT | ES_LIST_VIEW_COLUMN_FIXED_DATA_INTEGERS, 100);
EsListViewRegisterColumn(list, COLUMN_FAVORITE_COLOR, "Favorite color", -1,
ES_DRAW_CONTENT_RICH_TEXT | ES_LIST_VIEW_COLUMN_FIXED_FORMAT_ENUM_STRING | ES_LIST_VIEW_COLUMN_FIXED_DATA_INTEGERS, 150);
EsListViewFixedItemSetEnumStringsForColumn(list, COLUMN_FAVORITE_COLOR, colorStrings, sizeof(colorStrings) / sizeof(colorStrings[0]));
EsListViewAddAllColumns(list);
AddPerson(list, "Alice", 20, "\a#e00]Red");
AddPerson(list, "Bob", 30, "\a#080]Green");
AddPerson(list, "Cameron", 40, "\a#00f]Blue");
AddPerson(list, "Alice", 10, COLOR_RED);
AddPerson(list, "Bob", 20, COLOR_GREEN);
AddPerson(list, "Cameron", 30, COLOR_BLUE);
AddPerson(list, "Daniel", 40, COLOR_RED);
}
}
}

View File

@ -141,17 +141,17 @@ void FormatPopupCreate(Instance *instance) {
if (currentSize < presetTextSizes[0]) {
// The current size is not in the list; add it.
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, currentSize), 0, buffer,
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, currentSize), 0, buffer,
EsStringFormat(buffer, sizeof(buffer), "%d pt", currentSize));
}
for (uintptr_t i = 0; i < presetSizeCount; i++) {
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, presetTextSizes[i]), 0, buffer,
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, presetTextSizes[i]), 0, buffer,
EsStringFormat(buffer, sizeof(buffer), "%d pt", presetTextSizes[i]));
if (currentSize > presetTextSizes[i] && (i == presetSizeCount - 1 || (i != presetSizeCount - 1 && currentSize < presetTextSizes[i + 1]))) {
// The current size is not in the list; add it.
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, currentSize), 0, buffer,
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, currentSize), 0, buffer,
EsStringFormat(buffer, sizeof(buffer), "%d pt", currentSize));
}
}
@ -177,9 +177,9 @@ void FormatPopupCreate(Instance *instance) {
EsPanel *column = EsPanelCreate(panel, ES_FLAGS_DEFAULT, &styleFormatPopupColumn);
EsTextDisplayCreate(column, ES_CELL_H_EXPAND, ES_STYLE_TEXT_LABEL, INTERFACE_STRING(CommonFormatLanguage));
EsListView *list = EsListViewCreate(column, ES_LIST_VIEW_CHOICE_SELECT | ES_LIST_VIEW_FIXED_ITEMS, ES_STYLE_LIST_CHOICE_BORDERED);
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, 0), 0, INTERFACE_STRING(CommonFormatPlainText));
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, ES_SYNTAX_HIGHLIGHTING_LANGUAGE_C), 0, "C/C++", -1);
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, ES_SYNTAX_HIGHLIGHTING_LANGUAGE_INI), 0, "Ini", -1);
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, 0), 0, INTERFACE_STRING(CommonFormatPlainText));
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, ES_SYNTAX_HIGHLIGHTING_LANGUAGE_C), 0, "C/C++", -1);
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, ES_SYNTAX_HIGHLIGHTING_LANGUAGE_INI), 0, "Ini", -1);
EsListViewFixedItemSelect(list, instance->syntaxHighlightingLanguage);
list->messageUser = [] (EsElement *element, EsMessage *message) {

View File

@ -42,13 +42,23 @@ struct ListViewFixedItem {
uint32_t iconID;
};
struct ListViewFixedItemData {
union {
ListViewFixedString s;
double d;
int64_t i;
};
};
struct ListViewColumn {
char *title;
size_t titleBytes;
uint32_t id;
uint32_t flags;
double width;
Array<ListViewFixedString> items;
Array<ListViewFixedItemData> items;
const EsListViewEnumString *enumStrings;
size_t enumStringCount;
};
int ListViewProcessItemMessage(EsElement *element, EsMessage *message);
@ -1678,8 +1688,10 @@ struct EsListView : EsElement {
}
for (uintptr_t i = 0; i < registeredColumns.Length(); i++) {
for (uintptr_t j = 0; j < registeredColumns[i].items.Length(); j++) {
EsHeapFree(registeredColumns[i].items[j].string);
if ((registeredColumns[i].flags & ES_LIST_VIEW_COLUMN_FIXED_DATA_MASK) == ES_LIST_VIEW_COLUMN_FIXED_DATA_STRINGS) {
for (uintptr_t j = 0; j < registeredColumns[i].items.Length(); j++) {
EsHeapFree(registeredColumns[i].items[j].s.string);
}
}
EsHeapFree(registeredColumns[i].title);
@ -1882,12 +1894,82 @@ struct EsListView : EsElement {
} else if (message->type == ES_MSG_LIST_VIEW_GET_CONTENT && (flags & ES_LIST_VIEW_FIXED_ITEMS)) {
uintptr_t index = message->getContent.index;
EsAssert(index < fixedItems.Length());
ListViewFixedString emptyString = {};
ListViewFixedItemData emptyData = {};
ListViewFixedItem *item = &fixedItems[index];
ListViewColumn *column = &registeredColumns[(flags & ES_LIST_VIEW_COLUMNS) ? activeColumns[message->getContent.activeColumnIndex] : 0];
ListViewFixedString *string = index < column->items.Length() ? &column->items[index] : &emptyString;
EsBufferFormat(message->getContent.buffer, "%s", string->bytes, string->string);
if (!activeColumns.Length() || message->getContent.columnID == registeredColumns[activeColumns[0]].id) message->getContent.icon = item->iconID;
ListViewFixedItemData *data = index < column->items.Length() ? &column->items[index] : &emptyData;
uint32_t format = column->flags & ES_LIST_VIEW_COLUMN_FIXED_FORMAT_MASK;
uint32_t type = column->flags & ES_LIST_VIEW_COLUMN_FIXED_DATA_MASK;
if (!activeColumns.Length() || message->getContent.columnID == registeredColumns[activeColumns[0]].id) {
message->getContent.icon = item->iconID;
}
#define BOOLEAN_FORMAT(trueString, falseString) \
if (type == ES_LIST_VIEW_COLUMN_FIXED_DATA_INTEGERS) { \
EsBufferFormat(message->getContent.buffer, "%z", data->i ? interfaceString_ ## trueString : interfaceString_ ## falseString); \
} else { \
EsAssert(false); \
}
#define NUMBER_FORMAT(unitString) \
if (type == ES_LIST_VIEW_COLUMN_FIXED_DATA_INTEGERS) { \
EsBufferFormat(message->getContent.buffer, "%d%z", data->i, interfaceString_ ## unitString); \
} else if (type == ES_LIST_VIEW_COLUMN_FIXED_DATA_DOUBLES) { \
EsBufferFormat(message->getContent.buffer, "%F%z", data->d, interfaceString_ ## unitString); \
} else { \
EsAssert(false); \
}
#define UNIT_FORMAT(unitString1, unitString2, unitString3) \
double d = type == ES_LIST_VIEW_COLUMN_FIXED_DATA_INTEGERS ? data->i : type == ES_LIST_VIEW_COLUMN_FIXED_DATA_DOUBLES ? data->d : 0; \
if (d < 10000) EsBufferFormat(message->getContent.buffer, "%F%z", d, interfaceString_ ## unitString1); \
else if (d < 10000000) EsBufferFormat(message->getContent.buffer, "%.F%z", 1, d / 1000, interfaceString_ ## unitString2); \
else EsBufferFormat(message->getContent.buffer, "%.F%z", 1, d / 1000000, interfaceString_ ## unitString3);
if (format == ES_LIST_VIEW_COLUMN_FIXED_FORMAT_DEFAULT) {
if (type == ES_LIST_VIEW_COLUMN_FIXED_DATA_STRINGS) {
EsBufferFormat(message->getContent.buffer, "%s", data->s.bytes, data->s.string);
} else if (type == ES_LIST_VIEW_COLUMN_FIXED_DATA_DOUBLES) {
EsBufferFormat(message->getContent.buffer, "%F", data->d);
} else if (type == ES_LIST_VIEW_COLUMN_FIXED_DATA_INTEGERS) {
EsBufferFormat(message->getContent.buffer, "%d", data->i);
}
} else if (format == ES_LIST_VIEW_COLUMN_FIXED_FORMAT_BYTES) {
if (type == ES_LIST_VIEW_COLUMN_FIXED_DATA_INTEGERS) {
EsBufferFormat(message->getContent.buffer, "%D", data->i);
} else {
EsAssert(false);
}
} else if (format == ES_LIST_VIEW_COLUMN_FIXED_FORMAT_ENUM_STRING) {
if (type == ES_LIST_VIEW_COLUMN_FIXED_DATA_INTEGERS) {
EsAssert(data->i >= 0 && (uintptr_t) data->i < column->enumStringCount);
EsBufferFormat(message->getContent.buffer, "%s", column->enumStrings[data->i].stringBytes, column->enumStrings[data->i].string);
} else {
EsAssert(false);
}
} else if (format == ES_LIST_VIEW_COLUMN_FIXED_FORMAT_YES_NO) {
BOOLEAN_FORMAT(CommonBooleanYes, CommonBooleanNo);
} else if (format == ES_LIST_VIEW_COLUMN_FIXED_FORMAT_ON_OFF) {
BOOLEAN_FORMAT(CommonBooleanOn, CommonBooleanOff);
} else if (format == ES_LIST_VIEW_COLUMN_FIXED_FORMAT_PERCENTAGE) {
NUMBER_FORMAT(CommonUnitPercent);
} else if (format == ES_LIST_VIEW_COLUMN_FIXED_FORMAT_BITS) {
NUMBER_FORMAT(CommonUnitBits);
} else if (format == ES_LIST_VIEW_COLUMN_FIXED_FORMAT_PIXELS) {
NUMBER_FORMAT(CommonUnitPixels);
} else if (format == ES_LIST_VIEW_COLUMN_FIXED_FORMAT_DPI) {
NUMBER_FORMAT(CommonUnitDPI);
} else if (format == ES_LIST_VIEW_COLUMN_FIXED_FORMAT_SECONDS) {
NUMBER_FORMAT(CommonUnitSeconds);
} else if (format == ES_LIST_VIEW_COLUMN_FIXED_FORMAT_HERTZ) {
UNIT_FORMAT(CommonUnitHz, CommonUnitKHz, CommonUnitMHz);
} else if (format == ES_LIST_VIEW_COLUMN_FIXED_FORMAT_BYTE_RATE) {
UNIT_FORMAT(CommonUnitBps, CommonUnitKBps, CommonUnitMBps);
} else {
EsAssert(false);
}
#undef NUMBER_FORMAT
#undef BOOLEAN_FORMAT
} else if (message->type == ES_MSG_LIST_VIEW_IS_SELECTED && (flags & ES_LIST_VIEW_FIXED_ITEMS)) {
message->selectItem.isSelected = message->selectItem.index == fixedItemSelection;
} else {
@ -2452,13 +2534,13 @@ EsListViewIndex EsListViewFixedItemInsert(EsListView *view, EsGeneric data, EsLi
item.iconID = iconID;
view->fixedItems.Insert(item, index);
ListViewFixedString emptyString = {};
ListViewFixedItemData emptyData = {};
for (uintptr_t i = 0; i < view->registeredColumns.Length(); i++) {
ListViewColumn *column = &view->registeredColumns[i];
if (column->items.Length() >= (uintptr_t) index) {
column->items.InsertPointer(&emptyString, index);
column->items.InsertPointer(&emptyData, index);
}
}
@ -2467,40 +2549,57 @@ EsListViewIndex EsListViewFixedItemInsert(EsListView *view, EsGeneric data, EsLi
return index;
}
void EsListViewFixedItemSet(EsListView *view, EsListViewIndex index, uint32_t columnID, const char *string, ptrdiff_t stringBytes) {
void ListViewFixedItemSetInternal(EsListView *view, EsListViewIndex index, uint32_t columnID, ListViewFixedItemData data, uint32_t dataType) {
EsAssert(view->flags & ES_LIST_VIEW_FIXED_ITEMS);
EsMessageMutexCheck();
EsAssert(index >= 0 && index < (intptr_t) view->fixedItems.Length());
ListViewColumn *column = nullptr;
for (uintptr_t i = 0; i < view->registeredColumns.Length(); i++) {
if (view->registeredColumns[i].id == columnID) {
column = &view->registeredColumns[i];
break;
}
}
EsAssert(column);
EsAssert((column->flags & ES_LIST_VIEW_COLUMN_FIXED_DATA_MASK) == dataType);
// Make sure that the column's array of items has been updated to match to the size of fixedItems.
if (column->items.Length() < view->fixedItems.Length()) {
uintptr_t oldLength = column->items.Length();
column->items.SetLength(view->fixedItems.Length());
EsMemoryZero(&column->items[oldLength], (view->fixedItems.Length() - oldLength) * sizeof(column->items[0]));
}
if (dataType == ES_LIST_VIEW_COLUMN_FIXED_DATA_STRINGS) {
EsHeapFree(column->items[index].s.string);
}
column->items[index] = data;
EsListViewInvalidateContent(view, 0, index);
}
void EsListViewFixedItemSetString(EsListView *view, EsListViewIndex index, uint32_t columnID, const char *string, ptrdiff_t stringBytes) {
ListViewFixedString fixedString = {};
fixedString.bytes = stringBytes == -1 ? EsCStringLength(string) : stringBytes;
size_t outBytes;
HeapDuplicate((void **) &fixedString, &outBytes, string, fixedString.bytes);
if (outBytes == fixedString.bytes) {
ListViewColumn *column = nullptr;
for (uintptr_t i = 0; i < view->registeredColumns.Length(); i++) {
if (view->registeredColumns[i].id == columnID) {
column = &view->registeredColumns[i];
break;
}
}
EsAssert(column);
// Make sure that the column's array of items has been updated to match to the size of fixedItems.
if (column->items.Length() < view->fixedItems.Length()) {
uintptr_t oldLength = column->items.Length();
column->items.SetLength(view->fixedItems.Length());
EsMemoryZero(&column->items[oldLength], (view->fixedItems.Length() - oldLength) * sizeof(column->items[0]));
}
EsHeapFree(column->items[index].string);
column->items[index] = fixedString;
EsListViewInvalidateContent(view, 0, index);
ListViewFixedItemSetInternal(view, index, columnID, { .s = fixedString }, ES_LIST_VIEW_COLUMN_FIXED_DATA_STRINGS);
}
}
void EsListViewFixedItemSetDouble(EsListView *view, EsListViewIndex index, uint32_t columnID, double number) {
ListViewFixedItemSetInternal(view, index, columnID, { .d = number }, ES_LIST_VIEW_COLUMN_FIXED_DATA_DOUBLES);
}
void EsListViewFixedItemSetInteger(EsListView *view, EsListViewIndex index, uint32_t columnID, int64_t number) {
ListViewFixedItemSetInternal(view, index, columnID, { .i = number }, ES_LIST_VIEW_COLUMN_FIXED_DATA_INTEGERS);
}
bool EsListViewFixedItemFindIndex(EsListView *view, EsGeneric data, EsListViewIndex *index) {
EsAssert(view->flags & ES_LIST_VIEW_FIXED_ITEMS);
EsMessageMutexCheck();
@ -2545,7 +2644,10 @@ bool EsListViewFixedItemRemove(EsListView *view, EsGeneric data) {
ListViewColumn *column = &view->registeredColumns[i];
if ((uintptr_t) index < column->items.Length()) {
EsHeapFree(column->items[index].string);
if ((column->flags & ES_LIST_VIEW_COLUMN_FIXED_DATA_MASK) == ES_LIST_VIEW_COLUMN_FIXED_DATA_STRINGS) {
EsHeapFree(column->items[index].s.string);
}
column->items.Delete(index);
if (!column->items.Length()) {
@ -2572,6 +2674,19 @@ bool EsListViewFixedItemGetSelected(EsListView *view, EsGeneric *data) {
}
}
void EsListViewFixedItemSetEnumStringsForColumn(EsListView *view, uint32_t columnID, const EsListViewEnumString *strings, size_t stringCount) {
for (uintptr_t i = 0; i < view->registeredColumns.Length(); i++) {
if (view->registeredColumns[i].id == columnID) {
view->registeredColumns[i].enumStrings = strings;
view->registeredColumns[i].enumStringCount = stringCount;
EsListViewInvalidateAll(view);
return;
}
}
EsAssert(false);
}
int ListViewInlineTextboxMessage(EsElement *element, EsMessage *message) {
int response = ProcessTextboxMessage(element, message);

View File

@ -357,9 +357,6 @@ define ES_SYSTEM_SNAPSHOT_PROCESSES (1)
define ES_HANDLED (-1)
define ES_REJECTED (-2)
define ES_LIST_VIEW_COLUMN_SORT_ASCENDING (1)
define ES_LIST_VIEW_COLUMN_SORT_DESCENDING (2)
define ES_TEXT_H_LEFT (1 << 0)
define ES_TEXT_H_CENTER (1 << 1)
define ES_TEXT_H_RIGHT (1 << 2)
@ -380,11 +377,37 @@ define ES_DRAW_CONTENT_TABULAR (1 << 8)
define ES_DRAW_CONTENT_MARKER_DOWN_ARROW (1 << 9)
define ES_DRAW_CONTENT_MARKER_UP_ARROW (1 << 10)
define ES_DRAW_CONTENT_RICH_TEXT (1 << 12)
// ...plus alignment flags, if CHANGE_ALIGNMENT set.
// ...plus alignment flags.
define ES_LIST_VIEW_COLUMN_HAS_MENU (1 << 16) // The header can be clicked to open a menu.
define ES_LIST_VIEW_COLUMN_HAS_MENU ( 1 << 16) // The header can be clicked to open a menu.
define ES_LIST_VIEW_COLUMN_FIXED_DATA_STRINGS ( 0 << 22) // Data types for fixed items.
define ES_LIST_VIEW_COLUMN_FIXED_DATA_INTEGERS ( 1 << 22)
define ES_LIST_VIEW_COLUMN_FIXED_DATA_DOUBLES ( 2 << 22)
define ES_LIST_VIEW_COLUMN_FIXED_DATA_MASK ( 3 << 22)
define ES_LIST_VIEW_COLUMN_FIXED_SORT_DEFAULT ( 0 << 24) // Sort types for fixed items.
define ES_LIST_VIEW_COLUMN_FIXED_SORT_TIME ( 1 << 24)
define ES_LIST_VIEW_COLUMN_FIXED_SORT_SIZE ( 2 << 24)
define ES_LIST_VIEW_COLUMN_FIXED_SORT_NONE ( 3 << 24)
define ES_LIST_VIEW_COLUMN_FIXED_SORT_MASK ( 7 << 24)
define ES_LIST_VIEW_COLUMN_FIXED_FORMAT_DEFAULT ( 0 << 27) // Format types for fixed items.
define ES_LIST_VIEW_COLUMN_FIXED_FORMAT_YES_NO ( 1 << 27)
define ES_LIST_VIEW_COLUMN_FIXED_FORMAT_ON_OFF ( 2 << 27)
define ES_LIST_VIEW_COLUMN_FIXED_FORMAT_PERCENTAGE ( 3 << 27)
define ES_LIST_VIEW_COLUMN_FIXED_FORMAT_BYTES ( 4 << 27)
define ES_LIST_VIEW_COLUMN_FIXED_FORMAT_BITS ( 5 << 27)
define ES_LIST_VIEW_COLUMN_FIXED_FORMAT_BYTE_RATE ( 6 << 27) // Bytes per second.
define ES_LIST_VIEW_COLUMN_FIXED_FORMAT_SECONDS ( 7 << 27)
define ES_LIST_VIEW_COLUMN_FIXED_FORMAT_HERTZ ( 8 << 27)
define ES_LIST_VIEW_COLUMN_FIXED_FORMAT_PIXELS ( 9 << 27)
define ES_LIST_VIEW_COLUMN_FIXED_FORMAT_DPI (10 << 27)
define ES_LIST_VIEW_COLUMN_FIXED_FORMAT_ENUM_STRING (11 << 27)
define ES_LIST_VIEW_COLUMN_FIXED_FORMAT_MASK (31 << 27)
// ...plus draw content flags and alignment flags.
// For ES_MSG_LIST_VIEW_GET_COLUMN_SORT.
define ES_LIST_VIEW_COLUMN_SORT_ASCENDING (1 << 0)
define ES_LIST_VIEW_COLUMN_SORT_DESCENDING (1 << 1)
define ES_FILE_READ_SHARED (0x1) // Read-only. The file can still be opened for writing.
define ES_FILE_READ (0x2) // Read-only. The file will not openable for writing. This will fail if the file is already opened for writing.
define ES_FILE_WRITE_SHARED (0x4) // Read-write. The file can still be opened for writing. This will fail if the file is already opened for exclusive writing.
@ -1944,6 +1967,10 @@ struct EsDateComponents {
uint16_t millisecond; // 0-999.
};
struct EsListViewEnumString {
STRING string;
};
// Function pointer types.
function_pointer void EsThreadEntryCallback(EsGeneric argument);
@ -2591,7 +2618,10 @@ function void EsListViewRemoveAll(EsListView *view, EsListViewIndex group);
// (Fixed items.)
function EsListViewIndex EsListViewFixedItemInsert(EsListView *view, EsGeneric data = ES_NULL, EsListViewIndex index = -1, uint32_t iconID = 0);
function bool EsListViewFixedItemRemove(EsListView *view, EsGeneric data); // Returns false if the item was not found.
function void EsListViewFixedItemSet(EsListView *view, EsListViewIndex index, uint32_t columnID, STRING string = BLANK_STRING);
function void EsListViewFixedItemSetString(EsListView *view, EsListViewIndex index, uint32_t columnID, STRING string = BLANK_STRING);
function void EsListViewFixedItemSetDouble(EsListView *view, EsListViewIndex index, uint32_t columnID, double number);
function void EsListViewFixedItemSetInteger(EsListView *view, EsListViewIndex index, uint32_t columnID, int64_t number);
function bool EsListViewFixedItemFindIndex(EsListView *view, EsGeneric data, EsListViewIndex *index); // Returns false if the item was not found.
function bool EsListViewFixedItemSelect(EsListView *view, EsGeneric data); // Returns false if the item was not found.
function bool EsListViewFixedItemGetSelected(EsListView *view, EsGeneric *data); // Returns false if no item was selected.
function void EsListViewFixedItemSetEnumStringsForColumn(EsListView *view, uint32_t columnID, const EsListViewEnumString *strings, size_t stringCount);

View File

@ -649,7 +649,7 @@ void SettingsPageKeyboard(EsElement *element, SettingsPage *page) {
while (EsINIParse(&s)) {
if (s.key[0] != ';') {
EsListViewFixedItemSet(list, EsListViewFixedItemInsert(list, s.key), 0, s.value, s.valueBytes);
EsListViewFixedItemSetString(list, EsListViewFixedItemInsert(list, s.key), 0, s.value, s.valueBytes);
EsAssert(s.keyBytes == 2);
if (s.key[0] + ((uint16_t) s.key[1] << 8) == api.global->keyboardLayout) {

View File

@ -540,6 +540,7 @@ void WriteCStringToCallback(FormatCallback callback, void *callbackData, const c
void _StringFormat(FormatCallback callback, void *callbackData, const char *format, va_list arguments) {
int c;
int pad = 0;
int decimalPlaces = -1;
uint32_t flags = 0;
char buffer[32];
@ -647,13 +648,18 @@ void _StringFormat(FormatCallback callback, void *callbackData, const char *form
} break;
case 's': {
size_t length = va_arg(arguments, size_t);
ptrdiff_t length = va_arg(arguments, ptrdiff_t);
char *string = va_arg(arguments, char *);
char *position = string;
while (position < string + length) {
callback(utf8_value(position), callbackData);
position = utf8_advance(position);
if (length == -1) {
WriteCStringToCallback(callback, callbackData, string ?: "[null]");
} else {
char *position = string;
while (position < string + length) {
callback(utf8_value(position), callbackData);
position = utf8_advance(position);
}
}
} break;
@ -731,14 +737,17 @@ void _StringFormat(FormatCallback callback, void *callbackData, const char *form
_FormatInteger(callback, callbackData, integer, pad, flags & ES_STRING_FORMAT_SIMPLE);
// Decimal separator.
if (digitCount) {
if (digitCount && decimalPlaces) {
callback('.', callbackData);
}
// Fractional digits.
for (uintptr_t i = 0; i < digitCount; i++) {
if ((int) i == decimalPlaces) break;
callback('0' + digits[i], callbackData);
}
decimalPlaces = -1;
} break;
case '*': {
@ -746,6 +755,11 @@ void _StringFormat(FormatCallback callback, void *callbackData, const char *form
goto repeat;
} break;
case '.': {
decimalPlaces = va_arg(arguments, int);
goto repeat;
} break;
case 'f': {
flags = va_arg(arguments, uint32_t);
goto repeat;

View File

@ -82,10 +82,25 @@ DEFINE_INTERFACE_STRING(CommonEmpty, "empty");
DEFINE_INTERFACE_STRING(CommonUnitPercent, "%");
DEFINE_INTERFACE_STRING(CommonUnitBytes, " B");
DEFINE_INTERFACE_STRING(CommonUnitKilobytes, " KB");
DEFINE_INTERFACE_STRING(CommonUnitKilobytes, " kB"); // We use this for 10^3, so let's go for the proper SI prefix, rather than the traditional "KB".
DEFINE_INTERFACE_STRING(CommonUnitMegabytes, " MB");
DEFINE_INTERFACE_STRING(CommonUnitGigabytes, " GB");
DEFINE_INTERFACE_STRING(CommonUnitMilliseconds, " ms");
DEFINE_INTERFACE_STRING(CommonUnitSeconds, " s");
DEFINE_INTERFACE_STRING(CommonUnitBits, " bits");
DEFINE_INTERFACE_STRING(CommonUnitPixels, " px");
DEFINE_INTERFACE_STRING(CommonUnitDPI, " dpi");
DEFINE_INTERFACE_STRING(CommonUnitBps, " Bps");
DEFINE_INTERFACE_STRING(CommonUnitKBps, " kBps");
DEFINE_INTERFACE_STRING(CommonUnitMBps, " MBps");
DEFINE_INTERFACE_STRING(CommonUnitHz, " Hz");
DEFINE_INTERFACE_STRING(CommonUnitKHz, " kHz");
DEFINE_INTERFACE_STRING(CommonUnitMHz, " MHz");
DEFINE_INTERFACE_STRING(CommonBooleanYes, "Yes");
DEFINE_INTERFACE_STRING(CommonBooleanNo, "No");
DEFINE_INTERFACE_STRING(CommonBooleanOn, "On");
DEFINE_INTERFACE_STRING(CommonBooleanOff, "Off");
// Desktop.

View File

@ -142,7 +142,6 @@ EsMutexAcquire=140
EsMutexDestroy=141
EsMutexRelease=142
EsListViewAddAllColumns=143
EsListViewFixedItemSet=144
EsSchedulerYield=145
EsSleep=146
EsSpinlockAcquire=147
@ -298,6 +297,7 @@ EsSliderCreate=296
EsSystemConfigurationReadString=297
EsSliderGetValue=298
EsGameControllerStatePoll=299
EsListViewFixedItemSetString=300
EsRandomU8=301
EsRandomU64=302
EsConnectionPoll=303
@ -312,6 +312,7 @@ EsFileDelete=311
EsBufferReadInto=312
EsListViewRemoveAll=313
EsSystemShowShutdownDialog=314
EsListViewFixedItemSetDouble=315
EsListViewSelect=316
EsUndoClear=317
EsMessageReceive=318
@ -421,6 +422,7 @@ EsTimerCancel=421
EsSliderSetValue=422
EsClipboardCloseAndAdd=423
EsListViewFixedItemInsert=424
EsListViewFixedItemSetInteger=425
EsListViewFixedItemFindIndex=426
EsListViewFixedItemSelect=427
EsListViewFixedItemGetSelected=428
@ -489,3 +491,4 @@ EsDialogGetContentArea=490
_EsDebugCommand=491
DateToLinear=492
EsRectangleContainsAll=493
EsListViewFixedItemSetEnumStringsForColumn=494