mirror of https://gitlab.com/nakst/essence
fixed item sorting
This commit is contained in:
parent
48bb528b9d
commit
400c8f281a
|
@ -829,11 +829,30 @@ int ListCallback(EsElement *element, EsMessage *message) {
|
||||||
}
|
}
|
||||||
} else if (message->type == ES_MSG_LIST_VIEW_COLUMN_MENU) {
|
} else if (message->type == ES_MSG_LIST_VIEW_COLUMN_MENU) {
|
||||||
EsMenu *menu = EsMenuCreate(message->columnMenu.source);
|
EsMenu *menu = EsMenuCreate(message->columnMenu.source);
|
||||||
uint32_t index = (uint32_t) message->columnMenu.index;
|
uint32_t index = message->columnMenu.columnID;
|
||||||
|
const char *ascending = nullptr;
|
||||||
|
const char *descending = nullptr;
|
||||||
|
|
||||||
|
if (index == COLUMN_NAME) {
|
||||||
|
ascending = interfaceString_CommonSortAToZ;
|
||||||
|
descending = interfaceString_CommonSortZToA;
|
||||||
|
} else if (index == COLUMN_TYPE) {
|
||||||
|
ascending = interfaceString_CommonSortAToZ;
|
||||||
|
descending = interfaceString_CommonSortZToA;
|
||||||
|
} else if (index == COLUMN_SIZE) {
|
||||||
|
ascending = interfaceString_CommonSortSmallToLarge;
|
||||||
|
descending = interfaceString_CommonSortLargeToSmall;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define COLUMN_NAME (0)
|
||||||
|
#define COLUMN_TYPE (1)
|
||||||
|
#define COLUMN_SIZE (2)
|
||||||
|
|
||||||
|
EsMenuAddItem(menu, ES_MENU_ITEM_HEADER, INTERFACE_STRING(CommonSortHeader));
|
||||||
EsMenuAddItem(menu, instance->viewSettings.sortColumn == index ? ES_MENU_ITEM_CHECKED : 0,
|
EsMenuAddItem(menu, instance->viewSettings.sortColumn == index ? ES_MENU_ITEM_CHECKED : 0,
|
||||||
INTERFACE_STRING(CommonSortAscending), InstanceChangeSortColumn, index);
|
ascending, -1, InstanceChangeSortColumn, index);
|
||||||
EsMenuAddItem(menu, instance->viewSettings.sortColumn == (index | (1 << 8)) ? ES_MENU_ITEM_CHECKED : 0,
|
EsMenuAddItem(menu, instance->viewSettings.sortColumn == (index | (1 << 8)) ? ES_MENU_ITEM_CHECKED : 0,
|
||||||
INTERFACE_STRING(CommonSortDescending), InstanceChangeSortColumn, index | (1 << 8));
|
descending, -1, InstanceChangeSortColumn, index | (1 << 8));
|
||||||
EsMenuShow(menu);
|
EsMenuShow(menu);
|
||||||
} else if (message->type == ES_MSG_LIST_VIEW_GET_COLUMN_SORT) {
|
} else if (message->type == ES_MSG_LIST_VIEW_GET_COLUMN_SORT) {
|
||||||
if (message->getColumnSort.index == (instance->viewSettings.sortColumn & 0xFF)) {
|
if (message->getColumnSort.index == (instance->viewSettings.sortColumn & 0xFF)) {
|
||||||
|
|
|
@ -14,7 +14,7 @@ const EsListViewEnumString colorStrings[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddPerson(EsListView *list, const char *name, int age, int favoriteColor) {
|
void AddPerson(EsListView *list, const char *name, int age, int favoriteColor) {
|
||||||
EsListViewIndex index = EsListViewFixedItemInsert(list);
|
EsListViewIndex index = EsListViewFixedItemInsert(list, (void *) name /* data */);
|
||||||
EsListViewFixedItemSetString (list, index, COLUMN_NAME, name);
|
EsListViewFixedItemSetString (list, index, COLUMN_NAME, name);
|
||||||
EsListViewFixedItemSetInteger(list, index, COLUMN_AGE, age);
|
EsListViewFixedItemSetInteger(list, index, COLUMN_AGE, age);
|
||||||
EsListViewFixedItemSetInteger(list, index, COLUMN_FAVORITE_COLOR, favoriteColor);
|
EsListViewFixedItemSetInteger(list, index, COLUMN_FAVORITE_COLOR, favoriteColor);
|
||||||
|
@ -30,20 +30,24 @@ void _start() {
|
||||||
EsInstance *instance = EsInstanceCreate(message, "List", -1);
|
EsInstance *instance = EsInstanceCreate(message, "List", -1);
|
||||||
EsPanel *wrapper = EsPanelCreate(instance->window, ES_CELL_FILL, ES_STYLE_PANEL_WINDOW_DIVIDER);
|
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);
|
uint64_t flags;
|
||||||
EsListViewRegisterColumn(list, COLUMN_NAME, "Name", -1,
|
flags = ES_CELL_FILL | ES_LIST_VIEW_COLUMNS | ES_LIST_VIEW_FIXED_ITEMS | ES_LIST_VIEW_SINGLE_SELECT;
|
||||||
ES_FLAGS_DEFAULT, 150);
|
EsListView *list = EsListViewCreate(wrapper, flags);
|
||||||
EsListViewRegisterColumn(list, COLUMN_AGE, "Age", -1,
|
flags = ES_LIST_VIEW_COLUMN_HAS_MENU;
|
||||||
ES_TEXT_H_RIGHT | ES_LIST_VIEW_COLUMN_FIXED_DATA_INTEGERS, 100);
|
EsListViewRegisterColumn(list, COLUMN_NAME, "Name", -1, flags, 150);
|
||||||
EsListViewRegisterColumn(list, COLUMN_FAVORITE_COLOR, "Favorite color", -1,
|
flags = ES_LIST_VIEW_COLUMN_HAS_MENU | ES_TEXT_H_RIGHT | ES_DRAW_CONTENT_TABULAR
|
||||||
ES_DRAW_CONTENT_RICH_TEXT | ES_LIST_VIEW_COLUMN_FIXED_FORMAT_ENUM_STRING | ES_LIST_VIEW_COLUMN_FIXED_DATA_INTEGERS, 150);
|
| ES_LIST_VIEW_COLUMN_FIXED_DATA_INTEGERS | ES_LIST_VIEW_COLUMN_FIXED_SORT_SIZE;
|
||||||
|
EsListViewRegisterColumn(list, COLUMN_AGE, "Age", -1, flags, 100);
|
||||||
|
flags = ES_LIST_VIEW_COLUMN_HAS_MENU | ES_DRAW_CONTENT_RICH_TEXT
|
||||||
|
| ES_LIST_VIEW_COLUMN_FIXED_FORMAT_ENUM_STRING | ES_LIST_VIEW_COLUMN_FIXED_DATA_INTEGERS;
|
||||||
|
EsListViewRegisterColumn(list, COLUMN_FAVORITE_COLOR, "Favorite color", -1, flags, 150);
|
||||||
EsListViewFixedItemSetEnumStringsForColumn(list, COLUMN_FAVORITE_COLOR, colorStrings, sizeof(colorStrings) / sizeof(colorStrings[0]));
|
EsListViewFixedItemSetEnumStringsForColumn(list, COLUMN_FAVORITE_COLOR, colorStrings, sizeof(colorStrings) / sizeof(colorStrings[0]));
|
||||||
EsListViewAddAllColumns(list);
|
EsListViewAddAllColumns(list);
|
||||||
|
|
||||||
AddPerson(list, "Alice", 10, COLOR_RED);
|
AddPerson(list, "Alice", 40, COLOR_RED);
|
||||||
AddPerson(list, "Bob", 20, COLOR_GREEN);
|
AddPerson(list, "Bob", 10, COLOR_GREEN);
|
||||||
AddPerson(list, "Cameron", 30, COLOR_BLUE);
|
AddPerson(list, "Cameron", 30, COLOR_BLUE);
|
||||||
AddPerson(list, "Daniel", 40, COLOR_RED);
|
AddPerson(list, "Daniel", 20, COLOR_RED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,8 @@ struct ListViewColumn {
|
||||||
};
|
};
|
||||||
|
|
||||||
int ListViewProcessItemMessage(EsElement *element, EsMessage *message);
|
int ListViewProcessItemMessage(EsElement *element, EsMessage *message);
|
||||||
|
void ListViewSetSortAscending(EsMenu *menu, EsGeneric context);
|
||||||
|
void ListViewSetSortDescending(EsMenu *menu, EsGeneric context);
|
||||||
|
|
||||||
struct EsListView : EsElement {
|
struct EsListView : EsElement {
|
||||||
ScrollPane scroll;
|
ScrollPane scroll;
|
||||||
|
@ -123,7 +125,12 @@ struct EsListView : EsElement {
|
||||||
|
|
||||||
// Fixed item storage:
|
// Fixed item storage:
|
||||||
Array<ListViewFixedItem> fixedItems;
|
Array<ListViewFixedItem> fixedItems;
|
||||||
|
Array<EsListViewIndex> fixedItemIndices; // For sorting. Converts the actual list index into an index for fixedItems.
|
||||||
ptrdiff_t fixedItemSelection;
|
ptrdiff_t fixedItemSelection;
|
||||||
|
uint32_t fixedItemSortColumnID;
|
||||||
|
#define LIST_SORT_DIRECTION_ASCENDING (1)
|
||||||
|
#define LIST_SORT_DIRECTION_DESCENDING (2)
|
||||||
|
uint8_t fixedItemSortDirection;
|
||||||
|
|
||||||
inline EsRectangle GetListBounds() {
|
inline EsRectangle GetListBounds() {
|
||||||
EsRectangle bounds = GetBounds();
|
EsRectangle bounds = GetBounds();
|
||||||
|
@ -1894,6 +1901,7 @@ struct EsListView : EsElement {
|
||||||
} else if (message->type == ES_MSG_LIST_VIEW_GET_CONTENT && (flags & ES_LIST_VIEW_FIXED_ITEMS)) {
|
} else if (message->type == ES_MSG_LIST_VIEW_GET_CONTENT && (flags & ES_LIST_VIEW_FIXED_ITEMS)) {
|
||||||
uintptr_t index = message->getContent.index;
|
uintptr_t index = message->getContent.index;
|
||||||
EsAssert(index < fixedItems.Length());
|
EsAssert(index < fixedItems.Length());
|
||||||
|
index = fixedItemIndices[index];
|
||||||
ListViewFixedItemData emptyData = {};
|
ListViewFixedItemData emptyData = {};
|
||||||
ListViewFixedItem *item = &fixedItems[index];
|
ListViewFixedItem *item = &fixedItems[index];
|
||||||
ListViewColumn *column = ®isteredColumns[(flags & ES_LIST_VIEW_COLUMNS) ? activeColumns[message->getContent.activeColumnIndex] : 0];
|
ListViewColumn *column = ®isteredColumns[(flags & ES_LIST_VIEW_COLUMNS) ? activeColumns[message->getContent.activeColumnIndex] : 0];
|
||||||
|
@ -1972,6 +1980,31 @@ struct EsListView : EsElement {
|
||||||
#undef BOOLEAN_FORMAT
|
#undef BOOLEAN_FORMAT
|
||||||
} else if (message->type == ES_MSG_LIST_VIEW_IS_SELECTED && (flags & ES_LIST_VIEW_FIXED_ITEMS)) {
|
} else if (message->type == ES_MSG_LIST_VIEW_IS_SELECTED && (flags & ES_LIST_VIEW_FIXED_ITEMS)) {
|
||||||
message->selectItem.isSelected = message->selectItem.index == fixedItemSelection;
|
message->selectItem.isSelected = message->selectItem.index == fixedItemSelection;
|
||||||
|
} else if (message->type == ES_MSG_LIST_VIEW_COLUMN_MENU && (flags & ES_LIST_VIEW_FIXED_ITEMS)) {
|
||||||
|
EsMenu *menu = EsMenuCreate(message->columnMenu.source);
|
||||||
|
menu->userData = this;
|
||||||
|
|
||||||
|
ListViewColumn *column = ®isteredColumns[activeColumns[message->columnMenu.activeColumnIndex]];
|
||||||
|
uint32_t sortMode = column->flags & ES_LIST_VIEW_COLUMN_FIXED_SORT_MASK;
|
||||||
|
uint64_t checkAscending = (fixedItemSortDirection == LIST_SORT_DIRECTION_ASCENDING && column->id == fixedItemSortColumnID) ? ES_MENU_ITEM_CHECKED : 0;
|
||||||
|
uint64_t checkDescending = (fixedItemSortDirection == LIST_SORT_DIRECTION_DESCENDING && column->id == fixedItemSortColumnID) ? ES_MENU_ITEM_CHECKED : 0;
|
||||||
|
|
||||||
|
if (sortMode != ES_LIST_VIEW_COLUMN_FIXED_SORT_NONE) {
|
||||||
|
EsMenuAddItem(menu, ES_MENU_ITEM_HEADER, INTERFACE_STRING(CommonSortHeader));
|
||||||
|
|
||||||
|
if (sortMode == ES_LIST_VIEW_COLUMN_FIXED_SORT_DEFAULT) {
|
||||||
|
EsMenuAddItem(menu, checkAscending, INTERFACE_STRING(CommonSortAToZ), ListViewSetSortAscending, column->id);
|
||||||
|
EsMenuAddItem(menu, checkDescending, INTERFACE_STRING(CommonSortZToA), ListViewSetSortDescending, column->id);
|
||||||
|
} else if (sortMode == ES_LIST_VIEW_COLUMN_FIXED_SORT_TIME) {
|
||||||
|
EsMenuAddItem(menu, checkAscending, INTERFACE_STRING(CommonSortOldToNew), ListViewSetSortAscending, column->id);
|
||||||
|
EsMenuAddItem(menu, checkDescending, INTERFACE_STRING(CommonSortNewToOld), ListViewSetSortDescending, column->id);
|
||||||
|
} else if (sortMode == ES_LIST_VIEW_COLUMN_FIXED_SORT_SIZE) {
|
||||||
|
EsMenuAddItem(menu, checkAscending, INTERFACE_STRING(CommonSortSmallToLarge), ListViewSetSortAscending, column->id);
|
||||||
|
EsMenuAddItem(menu, checkDescending, INTERFACE_STRING(CommonSortLargeToSmall), ListViewSetSortDescending, column->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EsMenuShow(menu);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2011,6 +2044,8 @@ int ListViewColumnHeaderMessage(EsElement *element, EsMessage *message) {
|
||||||
splitter->InternalMove(splitter->style->preferredWidth, element->height, x + column->width * theming.scale - splitterLeft, 0);
|
splitter->InternalMove(splitter->style->preferredWidth, element->height, x + column->width * theming.scale - splitterLeft, 0);
|
||||||
x += column->width * theming.scale + view->secondaryCellStyle->gapMajor;
|
x += column->width * theming.scale + view->secondaryCellStyle->gapMajor;
|
||||||
}
|
}
|
||||||
|
} else if (message->type == ES_MSG_MOUSE_LEFT_DOWN || message->type == ES_MSG_MOUSE_RIGHT_DOWN) {
|
||||||
|
return ES_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2351,8 +2386,10 @@ int ListViewColumnHeaderItemMessage(EsElement *element, EsMessage *message) {
|
||||||
} else if (message->type == ES_MSG_MOUSE_LEFT_CLICK && (column->flags & ES_LIST_VIEW_COLUMN_HAS_MENU)) {
|
} else if (message->type == ES_MSG_MOUSE_LEFT_CLICK && (column->flags & ES_LIST_VIEW_COLUMN_HAS_MENU)) {
|
||||||
EsMessage m = { ES_MSG_LIST_VIEW_COLUMN_MENU };
|
EsMessage m = { ES_MSG_LIST_VIEW_COLUMN_MENU };
|
||||||
m.columnMenu.source = element;
|
m.columnMenu.source = element;
|
||||||
m.columnMenu.index = element->userData.u;
|
m.columnMenu.activeColumnIndex = element->userData.u;
|
||||||
|
m.columnMenu.columnID = view->registeredColumns[element->userData.u].id;
|
||||||
EsMessageSend(view, &m);
|
EsMessageSend(view, &m);
|
||||||
|
} else if (message->type == ES_MSG_MOUSE_LEFT_DOWN) {
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2533,6 +2570,7 @@ EsListViewIndex EsListViewFixedItemInsert(EsListView *view, EsGeneric data, EsLi
|
||||||
item.data = data;
|
item.data = data;
|
||||||
item.iconID = iconID;
|
item.iconID = iconID;
|
||||||
view->fixedItems.Insert(item, index);
|
view->fixedItems.Insert(item, index);
|
||||||
|
view->fixedItemIndices.Insert(index, index);
|
||||||
|
|
||||||
ListViewFixedItemData emptyData = {};
|
ListViewFixedItemData emptyData = {};
|
||||||
|
|
||||||
|
@ -2604,8 +2642,8 @@ bool EsListViewFixedItemFindIndex(EsListView *view, EsGeneric data, EsListViewIn
|
||||||
EsAssert(view->flags & ES_LIST_VIEW_FIXED_ITEMS);
|
EsAssert(view->flags & ES_LIST_VIEW_FIXED_ITEMS);
|
||||||
EsMessageMutexCheck();
|
EsMessageMutexCheck();
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < view->fixedItems.Length(); i++) {
|
for (uintptr_t i = 0; i < view->fixedItemIndices.Length(); i++) {
|
||||||
if (view->fixedItems[i].data == data) {
|
if (view->fixedItems[view->fixedItemIndices[i]].data == data) {
|
||||||
*index = i;
|
*index = i;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2623,7 +2661,7 @@ bool EsListViewFixedItemSelect(EsListView *view, EsGeneric data) {
|
||||||
if (found) {
|
if (found) {
|
||||||
EsListViewSelect(view, 0, index);
|
EsListViewSelect(view, 0, index);
|
||||||
|
|
||||||
// TODO Maybe you should have to separately call EsListViewFocusItem to get this behaviour.
|
// TODO Maybe you should have to separately call EsListViewFocusItem to get this behaviour?
|
||||||
EsListViewFocusItem(view, 0, index);
|
EsListViewFocusItem(view, 0, index);
|
||||||
view->EnsureItemVisible(0, index, 2 /* center */);
|
view->EnsureItemVisible(0, index, 2 /* center */);
|
||||||
}
|
}
|
||||||
|
@ -2639,16 +2677,17 @@ bool EsListViewFixedItemRemove(EsListView *view, EsGeneric data) {
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
EsListViewRemove(view, 0, index, 1);
|
EsListViewRemove(view, 0, index, 1);
|
||||||
|
EsListViewIndex fixedIndex = view->fixedItemIndices[index];
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < view->registeredColumns.Length(); i++) {
|
for (uintptr_t i = 0; i < view->registeredColumns.Length(); i++) {
|
||||||
ListViewColumn *column = &view->registeredColumns[i];
|
ListViewColumn *column = &view->registeredColumns[i];
|
||||||
|
|
||||||
if ((uintptr_t) index < column->items.Length()) {
|
if ((uintptr_t) fixedIndex < column->items.Length()) {
|
||||||
if ((column->flags & ES_LIST_VIEW_COLUMN_FIXED_DATA_MASK) == ES_LIST_VIEW_COLUMN_FIXED_DATA_STRINGS) {
|
if ((column->flags & ES_LIST_VIEW_COLUMN_FIXED_DATA_MASK) == ES_LIST_VIEW_COLUMN_FIXED_DATA_STRINGS) {
|
||||||
EsHeapFree(column->items[index].s.string);
|
EsHeapFree(column->items[fixedIndex].s.string);
|
||||||
}
|
}
|
||||||
|
|
||||||
column->items.Delete(index);
|
column->items.Delete(fixedIndex);
|
||||||
|
|
||||||
if (!column->items.Length()) {
|
if (!column->items.Length()) {
|
||||||
column->items.Free();
|
column->items.Free();
|
||||||
|
@ -2656,7 +2695,14 @@ bool EsListViewFixedItemRemove(EsListView *view, EsGeneric data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
view->fixedItems.Delete(index);
|
view->fixedItems.Delete(fixedIndex);
|
||||||
|
view->fixedItemIndices.Delete(index);
|
||||||
|
|
||||||
|
for (uintptr_t i = 0; i < view->fixedItemIndices.Length(); i++) {
|
||||||
|
if (view->fixedItemIndices[i] > fixedIndex) {
|
||||||
|
view->fixedItemIndices[i]--;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
|
@ -2669,7 +2715,7 @@ bool EsListViewFixedItemGetSelected(EsListView *view, EsGeneric *data) {
|
||||||
if (view->fixedItemSelection == -1 || view->fixedItemSelection >= (intptr_t) view->fixedItems.Length()) {
|
if (view->fixedItemSelection == -1 || view->fixedItemSelection >= (intptr_t) view->fixedItems.Length()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
*data = view->fixedItems[view->fixedItemSelection].data;
|
*data = view->fixedItems[view->fixedItemIndices[view->fixedItemSelection]].data;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2687,6 +2733,87 @@ void EsListViewFixedItemSetEnumStringsForColumn(EsListView *view, uint32_t colum
|
||||||
EsAssert(false);
|
EsAssert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define LIST_VIEW_SORT_FUNCTION(_name, _line) \
|
||||||
|
ES_MACRO_SORT(_name, EsListViewIndex, { \
|
||||||
|
ListViewFixedItemData *left = (ListViewFixedItemData *) &context->items[*_left]; \
|
||||||
|
ListViewFixedItemData *right = (ListViewFixedItemData *) &context->items[*_right]; \
|
||||||
|
result = _line; \
|
||||||
|
}, ListViewColumn *)
|
||||||
|
|
||||||
|
LIST_VIEW_SORT_FUNCTION(ListViewSortByStringsAscending, EsStringCompare(left->s.string, left->s.bytes, right->s.string, right->s.bytes));
|
||||||
|
LIST_VIEW_SORT_FUNCTION(ListViewSortByStringsDescending, -EsStringCompare(left->s.string, left->s.bytes, right->s.string, right->s.bytes));
|
||||||
|
LIST_VIEW_SORT_FUNCTION(ListViewSortByEnumsAscending, EsStringCompare(context->enumStrings[left->i].string, context->enumStrings[left->i].stringBytes,
|
||||||
|
context->enumStrings[right->i].string, context->enumStrings[right->i].stringBytes));
|
||||||
|
LIST_VIEW_SORT_FUNCTION(ListViewSortByEnumsDescending, -EsStringCompare(context->enumStrings[left->i].string, context->enumStrings[left->i].stringBytes,
|
||||||
|
context->enumStrings[right->i].string, context->enumStrings[right->i].stringBytes));
|
||||||
|
LIST_VIEW_SORT_FUNCTION(ListViewSortByIntegersAscending, left->i > right->i ? 1 : left->i == right->i ? 0 : -1);
|
||||||
|
LIST_VIEW_SORT_FUNCTION(ListViewSortByIntegersDescending, left->i < right->i ? 1 : left->i == right->i ? 0 : -1);
|
||||||
|
LIST_VIEW_SORT_FUNCTION(ListViewSortByDoublesAscending, left->d > right->d ? 1 : left->d == right->d ? 0 : -1);
|
||||||
|
LIST_VIEW_SORT_FUNCTION(ListViewSortByDoublesDescending, left->d < right->d ? 1 : left->d == right->d ? 0 : -1);
|
||||||
|
|
||||||
|
void ListViewSetSortDirection(EsListView *view, uint32_t columnID, uint8_t direction) {
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (view->fixedItemSortColumnID == columnID && view->fixedItemSortDirection == direction) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
view->fixedItemSortColumnID = columnID;
|
||||||
|
view->fixedItemSortDirection = direction;
|
||||||
|
|
||||||
|
EsAssert(view->fixedItems.Length() == view->fixedItemIndices.Length());
|
||||||
|
|
||||||
|
void (*sortFunction)(EsListViewIndex *, size_t, ListViewColumn *) = nullptr;
|
||||||
|
|
||||||
|
if ((column->flags & ES_LIST_VIEW_COLUMN_FIXED_DATA_MASK) == ES_LIST_VIEW_COLUMN_FIXED_DATA_STRINGS) {
|
||||||
|
sortFunction = (direction == LIST_SORT_DIRECTION_DESCENDING ? ListViewSortByStringsDescending : ListViewSortByStringsAscending);
|
||||||
|
} else if ((column->flags & ES_LIST_VIEW_COLUMN_FIXED_DATA_MASK) == ES_LIST_VIEW_COLUMN_FIXED_DATA_INTEGERS) {
|
||||||
|
if ((column->flags & ES_LIST_VIEW_COLUMN_FIXED_FORMAT_MASK) == ES_LIST_VIEW_COLUMN_FIXED_FORMAT_ENUM_STRING) {
|
||||||
|
sortFunction = (direction == LIST_SORT_DIRECTION_DESCENDING ? ListViewSortByEnumsDescending : ListViewSortByEnumsAscending);
|
||||||
|
} else {
|
||||||
|
sortFunction = (direction == LIST_SORT_DIRECTION_DESCENDING ? ListViewSortByIntegersDescending : ListViewSortByIntegersAscending);
|
||||||
|
}
|
||||||
|
} else if ((column->flags & ES_LIST_VIEW_COLUMN_FIXED_DATA_MASK) == ES_LIST_VIEW_COLUMN_FIXED_DATA_DOUBLES) {
|
||||||
|
sortFunction = (direction == LIST_SORT_DIRECTION_DESCENDING ? ListViewSortByDoublesDescending : ListViewSortByDoublesAscending);
|
||||||
|
} else {
|
||||||
|
EsAssert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
EsListViewIndex previousSelectionIndex = view->fixedItemSelection >= 0 && (uintptr_t) view->fixedItemSelection < view->fixedItemIndices.Length()
|
||||||
|
? view->fixedItemIndices[view->fixedItemSelection] : -1;
|
||||||
|
|
||||||
|
sortFunction(view->fixedItemIndices.array, view->fixedItems.Length(), column);
|
||||||
|
EsListViewInvalidateAll(view);
|
||||||
|
|
||||||
|
if (previousSelectionIndex != -1) {
|
||||||
|
for (uintptr_t i = 0; i < view->fixedItemIndices.Length(); i++) {
|
||||||
|
if (view->fixedItemIndices[i] == previousSelectionIndex) {
|
||||||
|
EsListViewSelect(view, 0, i);
|
||||||
|
EsListViewFocusItem(view, 0, i);
|
||||||
|
view->EnsureItemVisible(0, i, 2 /* center */);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListViewSetSortAscending(EsMenu *menu, EsGeneric context) {
|
||||||
|
ListViewSetSortDirection((EsListView *) menu->userData.p, context.u, LIST_SORT_DIRECTION_ASCENDING);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListViewSetSortDescending(EsMenu *menu, EsGeneric context) {
|
||||||
|
ListViewSetSortDirection((EsListView *) menu->userData.p, context.u, LIST_SORT_DIRECTION_DESCENDING);
|
||||||
|
}
|
||||||
|
|
||||||
int ListViewInlineTextboxMessage(EsElement *element, EsMessage *message) {
|
int ListViewInlineTextboxMessage(EsElement *element, EsMessage *message) {
|
||||||
int response = ProcessTextboxMessage(element, message);
|
int response = ProcessTextboxMessage(element, message);
|
||||||
|
|
||||||
|
|
|
@ -1699,8 +1699,9 @@ struct EsMessageFocus {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EsMessageColumnMenu {
|
struct EsMessageColumnMenu {
|
||||||
uint8_t index;
|
|
||||||
EsElement *source;
|
EsElement *source;
|
||||||
|
uint32_t columnID;
|
||||||
|
uint16_t activeColumnIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EsMessageGetColumnSort {
|
struct EsMessageGetColumnSort {
|
||||||
|
@ -2621,7 +2622,6 @@ function bool EsListViewFixedItemRemove(EsListView *view, EsGeneric data); // Re
|
||||||
function void EsListViewFixedItemSetString(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 EsListViewFixedItemSetDouble(EsListView *view, EsListViewIndex index, uint32_t columnID, double number);
|
||||||
function void EsListViewFixedItemSetInteger(EsListView *view, EsListViewIndex index, uint32_t columnID, int64_t 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 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 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);
|
function void EsListViewFixedItemSetEnumStringsForColumn(EsListView *view, uint32_t columnID, const EsListViewEnumString *strings, size_t stringCount);
|
||||||
|
|
|
@ -980,6 +980,10 @@ int EsStringCompare(const char *s1, ptrdiff_t _length1, const char *s2, ptrdiff_
|
||||||
size_t length1 = _length1, length2 = _length2;
|
size_t length1 = _length1, length2 = _length2;
|
||||||
|
|
||||||
while (length1 || length2) {
|
while (length1 || length2) {
|
||||||
|
// Skip over rich text markup.
|
||||||
|
if (*s1 == '\a') while (length1 && *s1 != ']') s1++, length1--;
|
||||||
|
if (*s2 == '\a') while (length2 && *s2 != ']') s2++, length2--;
|
||||||
|
|
||||||
if (!length1) return -1;
|
if (!length1) return -1;
|
||||||
if (!length2) return 1;
|
if (!length2) return 1;
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,15 @@ DEFINE_INTERFACE_STRING(CommonSearchPrompt2, "Enter text to search for.");
|
||||||
DEFINE_INTERFACE_STRING(CommonItemFolder, "Folder");
|
DEFINE_INTERFACE_STRING(CommonItemFolder, "Folder");
|
||||||
DEFINE_INTERFACE_STRING(CommonItemFile, "File");
|
DEFINE_INTERFACE_STRING(CommonItemFile, "File");
|
||||||
|
|
||||||
|
DEFINE_INTERFACE_STRING(CommonSortHeader, "Sort" ELLIPSIS);
|
||||||
DEFINE_INTERFACE_STRING(CommonSortAscending, "Sort ascending");
|
DEFINE_INTERFACE_STRING(CommonSortAscending, "Sort ascending");
|
||||||
DEFINE_INTERFACE_STRING(CommonSortDescending, "Sort descending");
|
DEFINE_INTERFACE_STRING(CommonSortDescending, "Sort descending");
|
||||||
|
DEFINE_INTERFACE_STRING(CommonSortAToZ, "A to Z");
|
||||||
|
DEFINE_INTERFACE_STRING(CommonSortZToA, "Z to A");
|
||||||
|
DEFINE_INTERFACE_STRING(CommonSortSmallToLarge, "Smallest first");
|
||||||
|
DEFINE_INTERFACE_STRING(CommonSortLargeToSmall, "Largest first");
|
||||||
|
DEFINE_INTERFACE_STRING(CommonSortOldToNew, "Oldest first");
|
||||||
|
DEFINE_INTERFACE_STRING(CommonSortNewToOld, "Newest first");
|
||||||
|
|
||||||
DEFINE_INTERFACE_STRING(CommonDriveHDD, "Hard disk");
|
DEFINE_INTERFACE_STRING(CommonDriveHDD, "Hard disk");
|
||||||
DEFINE_INTERFACE_STRING(CommonDriveSSD, "SSD");
|
DEFINE_INTERFACE_STRING(CommonDriveSSD, "SSD");
|
||||||
|
|
|
@ -423,7 +423,6 @@ EsSliderSetValue=422
|
||||||
EsClipboardCloseAndAdd=423
|
EsClipboardCloseAndAdd=423
|
||||||
EsListViewFixedItemInsert=424
|
EsListViewFixedItemInsert=424
|
||||||
EsListViewFixedItemSetInteger=425
|
EsListViewFixedItemSetInteger=425
|
||||||
EsListViewFixedItemFindIndex=426
|
|
||||||
EsListViewFixedItemSelect=427
|
EsListViewFixedItemSelect=427
|
||||||
EsListViewFixedItemGetSelected=428
|
EsListViewFixedItemGetSelected=428
|
||||||
EsClipboardHasFormat=429
|
EsClipboardHasFormat=429
|
||||||
|
|
Loading…
Reference in New Issue