replace EsListViewSetColumns

This commit is contained in:
nakst 2021-11-20 21:16:43 +00:00
parent 128022faa4
commit a4374b3aa5
11 changed files with 131 additions and 143 deletions

View File

@ -41,14 +41,9 @@ const char *errorTypeStrings[] = {
#include "string.cpp"
EsListViewColumn folderOutputColumns[] = {
#define COLUMN_NAME (0)
{ INTERFACE_STRING(FileManagerColumnName), ES_LIST_VIEW_COLUMN_HAS_MENU },
#define COLUMN_TYPE (1)
{ INTERFACE_STRING(FileManagerColumnType), ES_LIST_VIEW_COLUMN_HAS_MENU },
#define COLUMN_SIZE (2)
{ INTERFACE_STRING(FileManagerColumnSize), ES_LIST_VIEW_COLUMN_HAS_MENU | ES_TEXT_H_RIGHT },
};
#define LOAD_FOLDER_BACK (1)
#define LOAD_FOLDER_FORWARD (2)

View File

@ -167,24 +167,16 @@ bool InstanceLoadFolder(Instance *instance, String path /* takes ownership */, i
}
void InstanceRefreshViewType(Instance *instance) {
EsCommandSetCheck(&instance->commandViewDetails, instance->viewSettings.viewType == VIEW_DETAILS ? ES_CHECK_CHECKED : ES_CHECK_UNCHECKED, false);
EsCommandSetCheck(&instance->commandViewTiles, instance->viewSettings.viewType == VIEW_TILES ? ES_CHECK_CHECKED : ES_CHECK_UNCHECKED, false);
EsCommandSetCheck(&instance->commandViewThumbnails, instance->viewSettings.viewType == VIEW_THUMBNAILS ? ES_CHECK_CHECKED : ES_CHECK_UNCHECKED, false);
if (instance->viewSettings.viewType == VIEW_DETAILS) {
EsCommandSetCheck(&instance->commandViewDetails, ES_CHECK_CHECKED, false);
EsCommandSetCheck(&instance->commandViewTiles, ES_CHECK_UNCHECKED, false);
EsCommandSetCheck(&instance->commandViewThumbnails, ES_CHECK_UNCHECKED, false);
EsListViewChangeStyles(instance->list, &styleFolderView, ES_STYLE_LIST_ITEM, nullptr, nullptr, ES_LIST_VIEW_COLUMNS, ES_LIST_VIEW_TILED);
EsListViewSetColumns(instance->list, folderOutputColumns, sizeof(folderOutputColumns) / sizeof(folderOutputColumns[0]));
EsListViewAddAllColumns(instance->list);
} else if (instance->viewSettings.viewType == VIEW_TILES) {
EsCommandSetCheck(&instance->commandViewTiles, ES_CHECK_CHECKED, false);
EsCommandSetCheck(&instance->commandViewDetails, ES_CHECK_UNCHECKED, false);
EsCommandSetCheck(&instance->commandViewThumbnails, ES_CHECK_UNCHECKED, false);
EsListViewChangeStyles(instance->list, &styleFolderViewTiled, ES_STYLE_LIST_ITEM_TILE, nullptr, nullptr, ES_LIST_VIEW_TILED, ES_LIST_VIEW_COLUMNS);
} else if (instance->viewSettings.viewType == VIEW_THUMBNAILS) {
EsCommandSetCheck(&instance->commandViewThumbnails, ES_CHECK_CHECKED, false);
EsCommandSetCheck(&instance->commandViewTiles, ES_CHECK_UNCHECKED, false);
EsCommandSetCheck(&instance->commandViewDetails, ES_CHECK_UNCHECKED, false);
EsListViewChangeStyles(instance->list, &styleFolderViewTiled, &styleFolderItemThumbnail, nullptr, nullptr, ES_LIST_VIEW_TILED, ES_LIST_VIEW_COLUMNS);
}
}
@ -738,7 +730,7 @@ int ListCallback(EsElement *element, EsMessage *message) {
EsCommandSetCallback(EsCommandByID(instance, ES_COMMAND_PASTE), nullptr);
return 0;
} else if (message->type == ES_MSG_LIST_VIEW_GET_CONTENT) {
int column = message->getContent.column, index = message->getContent.index;
int column = message->getContent.columnID, index = message->getContent.index;
EsAssert(index < (int) instance->listContents.Length() && index >= 0);
ListEntry *listEntry = &instance->listContents[index];
FolderEntry *entry = listEntry->entry;
@ -1084,7 +1076,10 @@ void InstanceCreateUI(Instance *instance) {
instance->list = EsListViewCreate(splitter, ES_CELL_FILL | ES_LIST_VIEW_COLUMNS | ES_LIST_VIEW_MULTI_SELECT, &styleFolderView);
instance->list->accessKey = 'L';
instance->list->messageUser = ListCallback;
EsListViewSetColumns(instance->list, folderOutputColumns, sizeof(folderOutputColumns) / sizeof(folderOutputColumns[0]));
EsListViewRegisterColumn(instance->list, COLUMN_NAME, INTERFACE_STRING(FileManagerColumnName), ES_LIST_VIEW_COLUMN_HAS_MENU);
EsListViewRegisterColumn(instance->list, COLUMN_TYPE, INTERFACE_STRING(FileManagerColumnType), ES_LIST_VIEW_COLUMN_HAS_MENU);
EsListViewRegisterColumn(instance->list, COLUMN_SIZE, INTERFACE_STRING(FileManagerColumnSize), ES_LIST_VIEW_COLUMN_HAS_MENU | ES_TEXT_H_RIGHT);
EsListViewAddAllColumns(instance->list);
EsListViewInsertGroup(instance->list, 0);
// Toolbar:

View File

@ -1,12 +1,5 @@
#include <essence.h>
EsListViewColumn columns[] = {
// Title Flags Initial width
{ "Name", -1, ES_FLAGS_DEFAULT, 150 },
{ "Age", -1, ES_TEXT_H_RIGHT, 100 },
{ "Favorite color", -1, ES_DRAW_CONTENT_RICH_TEXT, 150 },
};
void AddPerson(EsListView *list, const char *name, int age, const char *favoriteColor) {
char ageString[16];
EsStringFormat(ageString, sizeof(ageString), "%d%c", age, 0);
@ -26,7 +19,10 @@ void _start() {
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);
EsListViewSetColumns(list, columns, sizeof(columns) / sizeof(columns[0]));
EsListViewRegisterColumn(list, 0, "Name", -1, ES_FLAGS_DEFAULT, 150);
EsListViewRegisterColumn(list, 1, "Age", -1, ES_TEXT_H_RIGHT, 100);
EsListViewRegisterColumn(list, 2, "Favorite color", -1, ES_DRAW_CONTENT_RICH_TEXT, 150);
EsListViewAddAllColumns(list);
AddPerson(list, "Alice", 20, "\a#e00]Red");
AddPerson(list, "Bob", 30, "\a#080]Green");
AddPerson(list, "Cameron", 40, "\a#00f]Blue");

View File

@ -26,23 +26,6 @@ struct Instance : EsInstance {
#define DISPLAY_GENERAL_LOG (3)
#define DISPLAY_MEMORY (12)
EsListViewColumn listViewProcessesColumns[] = {
{ "Name", -1, 0, 150 },
{ "PID", -1, ES_TEXT_H_RIGHT, 120 },
{ "Memory", -1, ES_TEXT_H_RIGHT, 120 },
{ "CPU", -1, ES_TEXT_H_RIGHT, 120 },
{ "Handles", -1, ES_TEXT_H_RIGHT, 120 },
{ "Threads", -1, ES_TEXT_H_RIGHT, 120 },
};
EsListViewColumn listViewContextSwitchesColumns[] = {
{ "Time stamp (ms)", -1, ES_TEXT_H_RIGHT, 150 },
{ "CPU", -1, ES_TEXT_H_RIGHT, 150 },
{ "Process", -1, 0, 150 },
{ "Thread", -1, 0, 150 },
{ "Count", -1, 0, 150 },
};
const EsStyle styleMonospacedTextbox = {
.inherit = ES_STYLE_TEXTBOX_NO_BORDER,
@ -323,7 +306,7 @@ void UpdateDisplay(Instance *instance, int index) {
int ListViewProcessesCallback(EsElement *element, EsMessage *message) {
if (message->type == ES_MSG_LIST_VIEW_GET_CONTENT) {
int column = message->getContent.column, index = message->getContent.index;
int column = message->getContent.columnID, index = message->getContent.index;
ProcessItem *item = &processes[index];
if (column == 0) GET_CONTENT("%s", item->data.nameBytes, item->data.name);
else if (column == 1) { if (item->data.pid == -1) GET_CONTENT("n/a"); else GET_CONTENT("%d", item->data.pid); }
@ -357,13 +340,6 @@ void AddTab(EsElement *toolbar, uintptr_t index, const char *label, bool asDefau
if (asDefault) EsButtonSetCheck(button, ES_CHECK_CHECKED);
}
void AddListView(EsListView **pointer, EsElement *switcher, EsUICallback callback, EsListViewColumn *columns, size_t columnsSize, uint64_t additionalFlags) {
*pointer = EsListViewCreate(switcher, ES_CELL_FILL | ES_LIST_VIEW_COLUMNS | additionalFlags);
(*pointer)->messageUser = callback;
EsListViewSetColumns(*pointer, columns, columnsSize / sizeof(EsListViewColumn));
EsListViewInsertGroup(*pointer, 0);
}
void TerminateProcess(Instance *instance, EsElement *, EsCommand *) {
if (selectedPID == 0 /* Kernel */) {
// Terminating the kernel process is a meaningless action; the closest equivalent is shutting down.
@ -394,8 +370,16 @@ void ProcessApplicationMessage(EsMessage *message) {
instance->textboxGeneralLog = EsTextboxCreate(switcher, ES_TEXTBOX_MULTILINE | ES_CELL_FILL | ES_ELEMENT_DISABLED, &styleMonospacedTextbox);
AddListView(&instance->listViewProcesses, switcher, ListViewProcessesCallback,
listViewProcessesColumns, sizeof(listViewProcessesColumns), ES_LIST_VIEW_SINGLE_SELECT);
instance->listViewProcesses = EsListViewCreate(switcher, ES_CELL_FILL | ES_LIST_VIEW_COLUMNS | ES_LIST_VIEW_SINGLE_SELECT);
instance->listViewProcesses->messageUser = ListViewProcessesCallback;
EsListViewRegisterColumn(instance->listViewProcesses, 0, "Name", -1, 0, 150);
EsListViewRegisterColumn(instance->listViewProcesses, 1, "PID", -1, ES_TEXT_H_RIGHT, 120);
EsListViewRegisterColumn(instance->listViewProcesses, 2, "Memory", -1, ES_TEXT_H_RIGHT, 120);
EsListViewRegisterColumn(instance->listViewProcesses, 3, "CPU", -1, ES_TEXT_H_RIGHT, 120);
EsListViewRegisterColumn(instance->listViewProcesses, 4, "Handles", -1, ES_TEXT_H_RIGHT, 120);
EsListViewRegisterColumn(instance->listViewProcesses, 5, "Threads", -1, ES_TEXT_H_RIGHT, 120);
EsListViewAddAllColumns(instance->listViewProcesses);
EsListViewInsertGroup(instance->listViewProcesses, 0);
instance->panelMemoryStatistics = EsPanelCreate(switcher,
ES_CELL_FILL | ES_PANEL_TABLE | ES_PANEL_HORIZONTAL | ES_PANEL_V_SCROLL_AUTO, &stylePanelMemoryStatistics);

View File

@ -7559,12 +7559,6 @@ struct InspectorWindow : EsInstance {
EsTextbox *textboxCategoryFilter;
};
EsListViewColumn inspectorElementListColumns[] = {
{ "Name", -1, 0, 300 },
{ "Bounds", -1, 0, 200 },
{ "Information", -1, 0, 200 },
};
int InspectorElementItemCallback(EsElement *element, EsMessage *message) {
InspectorWindow *inspector = (InspectorWindow *) element->instance;
@ -7670,7 +7664,7 @@ int InspectorElementListCallback(EsElement *element, EsMessage *message) {
InspectorWindow *inspector = (InspectorWindow *) element->instance;
if (message->type == ES_MSG_LIST_VIEW_GET_CONTENT) {
int column = message->getContent.column, index = message->getContent.index;
int column = message->getContent.columnID, index = message->getContent.index;
EsAssert(index >= 0 && index < (int) inspector->elements.Length());
InspectorElementEntry *entry = &inspector->elements[index];
@ -8047,7 +8041,10 @@ void InspectorSetup(EsWindow *window) {
inspector->elementList = EsListViewCreate(panel1, ES_CELL_FILL | ES_LIST_VIEW_COLUMNS | ES_LIST_VIEW_SINGLE_SELECT);
inspector->elementList->messageUser = InspectorElementListCallback;
EsListViewSetColumns(inspector->elementList, inspectorElementListColumns, sizeof(inspectorElementListColumns) / sizeof(EsListViewColumn));
EsListViewRegisterColumn(inspector->elementList, 0, "Name", -1, 0, 300);
EsListViewRegisterColumn(inspector->elementList, 1, "Bounds", -1, 0, 200);
EsListViewRegisterColumn(inspector->elementList, 2, "Information", -1, 0, 200);
EsListViewAddAllColumns(inspector->elementList);
EsListViewInsertGroup(inspector->elementList, 0);
{

View File

@ -39,11 +39,20 @@ struct ListViewFixedString {
struct ListViewFixedItem {
ListViewFixedString firstColumn;
// TODO Store the strings in an array per-ListViewColumn.
Array<ListViewFixedString> otherColumns;
EsGeneric data;
uint32_t iconID;
};
struct ListViewColumn {
char *title;
size_t titleBytes;
uint32_t id;
uint32_t flags;
double width;
};
int ListViewProcessItemMessage(EsElement *element, EsMessage *message);
struct EsListView : EsElement {
@ -88,8 +97,8 @@ struct EsListView : EsElement {
size_t emptyMessageBytes;
EsElement *columnHeader;
EsListViewColumn *columns;
size_t columnCount;
Array<ListViewColumn> registeredColumns;
Array<uint32_t> activeColumns; // Indices into registeredColumns.
int columnResizingOriginalWidth;
int64_t totalColumnWidth;
@ -685,7 +694,7 @@ struct EsListView : EsElement {
position += visibleItem->element->width;
} else if ((flags & ES_LIST_VIEW_COLUMNS) && ((~flags & ES_LIST_VIEW_CHOICE_SELECT) || (this->scroll.enabled[0]))) {
int indent = visibleItem->indent * style->gapWrap;
int firstColumn = columns[0].width * theming.scale + secondaryCellStyle->gapMajor;
int firstColumn = activeColumns.Length() ? (registeredColumns[activeColumns[0]].width * theming.scale + secondaryCellStyle->gapMajor) : 0;
visibleItem->startAtSecondColumn = indent > firstColumn;
if (indent > firstColumn) indent = firstColumn;
visibleItem->element->InternalMove(totalColumnWidth - indent, visibleItem->size,
@ -1174,12 +1183,12 @@ struct EsListView : EsElement {
if (flags & ES_LIST_VIEW_COLUMNS) {
EsRectangle bounds = EsRectangleAddBorder(element->GetBounds(), element->style->insets);
for (uintptr_t i = item->startAtSecondColumn ? 1 : 0; i < columnCount; i++) {
m.getContent.column = i;
for (uintptr_t i = item->startAtSecondColumn ? 1 : 0; i < activeColumns.Length(); i++) {
m.getContent.columnID = registeredColumns[activeColumns[i]].id;
m.getContent.icon = 0;
buffer.position = 0;
bounds.r = bounds.l + columns[i].width * theming.scale
bounds.r = bounds.l + registeredColumns[activeColumns[i]].width * theming.scale
- element->style->insets.r - element->style->insets.l;
if (i == 0) {
@ -1195,10 +1204,10 @@ struct EsListView : EsElement {
UIStyle *style = useSelectedCellStyle ? selectedCellStyle : i ? secondaryCellStyle : primaryCellStyle;
style->PaintText(message->painter, element, bounds,
(char *) _buffer, buffer.position, m.getContent.icon,
columns[i].flags, i ? nullptr : &selection);
registeredColumns[activeColumns[i]].flags, i ? nullptr : &selection);
}
bounds.l += columns[i].width * theming.scale + secondaryCellStyle->gapMajor;
bounds.l += registeredColumns[activeColumns[i]].width * theming.scale + secondaryCellStyle->gapMajor;
if (i == 0) {
bounds.l -= item->indent * style->gapWrap;
@ -1580,7 +1589,7 @@ struct EsListView : EsElement {
if (flags & ES_LIST_VIEW_COLUMNS) {
int offset = primaryCellStyle->metrics->iconSize + primaryCellStyle->gapMinor
+ style->insets.l - inlineTextbox->style->insets.l;
inlineTextbox->InternalMove(columns[0].width * theming.scale - offset, item->element->height,
inlineTextbox->InternalMove(registeredColumns[activeColumns[0]].width * theming.scale - offset, item->element->height,
item->element->offsetX + offset, item->element->offsetY);
} else if (flags & ES_LIST_VIEW_TILED) {
if (style->metrics->layoutVertical) {
@ -1669,6 +1678,10 @@ struct EsListView : EsElement {
visibleItems[i].element->Destroy();
}
for (uintptr_t i = 0; i < registeredColumns.Length(); i++) {
EsHeapFree(registeredColumns[i].title);
}
for (uintptr_t i = 0; i < fixedItems.Length(); i++) {
for (uintptr_t j = 0; j < fixedItems[i].otherColumns.Length(); j++) {
EsHeapFree(fixedItems[i].otherColumns[j].string);
@ -1685,6 +1698,8 @@ struct EsListView : EsElement {
fixedItems.Free();
visibleItems.Free();
groups.Free();
activeColumns.Free();
registeredColumns.Free();
} else if (message->type == ES_MSG_KEY_UP) {
if (message->keyboard.scancode == ES_SCANCODE_LEFT_CTRL || message->keyboard.scancode == ES_SCANCODE_RIGHT_CTRL) {
SelectPreview();
@ -1874,10 +1889,10 @@ struct EsListView : EsElement {
EsAssert(index < fixedItems.Length());
ListViewFixedString emptyString = {};
ListViewFixedItem *item = &fixedItems[index];
ListViewFixedString *string = message->getContent.column == 0 ? &item->firstColumn
: message->getContent.column <= item->otherColumns.Length() ? &item->otherColumns[message->getContent.column - 1] : &emptyString;
ListViewFixedString *string = message->getContent.columnID == 0 ? &item->firstColumn
: message->getContent.columnID <= item->otherColumns.Length() ? &item->otherColumns[message->getContent.columnID - 1] : &emptyString;
EsBufferFormat(message->getContent.buffer, "%s", string->bytes, string->string);
if (message->getContent.column == 0) message->getContent.icon = item->iconID;
if (!activeColumns.Length() || message->getContent.columnID == registeredColumns[activeColumns[0]].id) message->getContent.icon = item->iconID;
} else if (message->type == ES_MSG_LIST_VIEW_IS_SELECTED && (flags & ES_LIST_VIEW_FIXED_ITEMS)) {
message->selectItem.isSelected = message->selectItem.index == fixedItemSelection;
} else {
@ -1900,11 +1915,30 @@ int ListViewProcessItemMessage(EsElement *_element, EsMessage *message) {
void ListViewCalculateTotalColumnWidth(EsListView *view) {
view->totalColumnWidth = -view->secondaryCellStyle->gapMajor;
for (uintptr_t i = 0; i < view->columnCount; i++) {
view->totalColumnWidth += view->columns[i].width * theming.scale + view->secondaryCellStyle->gapMajor;
for (uintptr_t i = 0; i < view->activeColumns.Length(); i++) {
view->totalColumnWidth += view->registeredColumns[view->activeColumns[i]].width * theming.scale + view->secondaryCellStyle->gapMajor;
}
}
int ListViewColumnHeaderMessage(EsElement *element, EsMessage *message) {
EsListView *view = (EsListView *) element->userData.p;
if (message->type == ES_MSG_LAYOUT) {
int x = view->style->insets.l - view->scroll.position[0];
for (uintptr_t i = 0; i < element->children.Length(); i += 2) {
EsElement *item = element->children[i], *splitter = element->children[i + 1];
ListViewColumn *column = &view->registeredColumns[item->userData.u];
int splitterLeft = splitter->style->preferredWidth - view->secondaryCellStyle->gapMajor;
item->InternalMove(column->width * theming.scale - splitterLeft, element->height, x, 0);
splitter->InternalMove(splitter->style->preferredWidth, element->height, x + column->width * theming.scale - splitterLeft, 0);
x += column->width * theming.scale + view->secondaryCellStyle->gapMajor;
}
}
return 0;
}
void EsListViewChangeStyles(EsListView *view, const EsStyle *style, const EsStyle *itemStyle,
const EsStyle *headerItemStyle, const EsStyle *footerItemStyle, uint32_t addFlags, uint32_t removeFlags) {
// TODO Animating changes.
@ -1938,29 +1972,11 @@ void EsListViewChangeStyles(EsListView *view, const EsStyle *style, const EsStyl
view->columnHeader = EsCustomElementCreate(view, ES_CELL_FILL, ES_STYLE_LIST_COLUMN_HEADER);
view->columnHeader->cName = "column header";
view->columnHeader->userData = view;
view->columnHeader->messageUser = [] (EsElement *element, EsMessage *message) {
EsListView *view = (EsListView *) element->userData.p;
if (message->type == ES_MSG_LAYOUT) {
int x = view->style->insets.l - view->scroll.position[0];
for (uintptr_t i = 0; i < element->children.Length(); i += 2) {
EsElement *item = element->children[i], *splitter = element->children[i + 1];
EsListViewColumn *column = view->columns + item->userData.u;
int splitterLeft = splitter->style->preferredWidth - view->secondaryCellStyle->gapMajor;
item->InternalMove(column->width * theming.scale - splitterLeft, element->height, x, 0);
splitter->InternalMove(splitter->style->preferredWidth, element->height, x + column->width * theming.scale - splitterLeft, 0);
x += column->width * theming.scale + view->secondaryCellStyle->gapMajor;
}
}
return 0;
};
view->columnHeader->messageUser = ListViewColumnHeaderMessage;
view->scroll.fixedViewport[1] = view->columnHeader->style->preferredHeight;
} else if ((~view->flags & ES_LIST_VIEW_COLUMNS) && view->columnHeader) {
EsElementDestroy(view->columnHeader);
view->activeColumns.Free();
view->columnHeader = nullptr;
view->scroll.fixedViewport[1] = 0;
}
@ -2245,7 +2261,7 @@ void EsListViewRemoveAll(EsListView *view, EsListViewIndex group) {
int ListViewColumnHeaderItemMessage(EsElement *element, EsMessage *message) {
EsListView *view = (EsListView *) element->parent->parent;
EsListViewColumn *column = view->columns + element->userData.u;
ListViewColumn *column = &view->registeredColumns[element->userData.u];
if (message->type == ES_MSG_PAINT) {
EsMessage m = { ES_MSG_LIST_VIEW_GET_COLUMN_SORT };
@ -2267,59 +2283,67 @@ int ListViewColumnHeaderItemMessage(EsElement *element, EsMessage *message) {
return ES_HANDLED;
}
void EsListViewSetColumns(EsListView *view, EsListViewColumn *columns, size_t columnCount) {
EsMessageMutexCheck();
int ListViewColumnSplitterMessage(EsElement *element, EsMessage *message) {
EsListView *view = (EsListView *) element->parent->parent;
ListViewColumn *column = &view->registeredColumns[element->userData.u];
EsAssert(view->flags & ES_LIST_VIEW_COLUMNS); // List view does not have columns flag set.
if (message->type == ES_MSG_MOUSE_LEFT_DOWN) {
view->columnResizingOriginalWidth = column->width * theming.scale;
} else if (message->type == ES_MSG_MOUSE_LEFT_DRAG) {
int width = message->mouseDragged.newPositionX - message->mouseDragged.originalPositionX + view->columnResizingOriginalWidth;
int minimumWidth = element->style->metrics->minimumWidth;
if (width < minimumWidth) width = minimumWidth;
column->width = width / theming.scale;
ListViewCalculateTotalColumnWidth(view);
EsElementRelayout(element->parent);
EsElementRelayout(view);
} else {
return 0;
}
return ES_HANDLED;
}
void EsListViewAddAllColumns(EsListView *view) {
EsElementDestroyContents(view->columnHeader);
view->activeColumns.Free();
view->columns = columns;
view->columnCount = columnCount;
for (uintptr_t i = 0; i < columnCount; i++) {
EsElement *columnHeaderItem = EsCustomElementCreate(view->columnHeader, ES_CELL_FILL,
(columns[i].flags & ES_LIST_VIEW_COLUMN_HAS_MENU) ? ES_STYLE_LIST_COLUMN_HEADER_ITEM_HAS_MENU : ES_STYLE_LIST_COLUMN_HEADER_ITEM);
for (uintptr_t i = 0; i < view->registeredColumns.Length(); i++) {
view->activeColumns.Add(i);
EsStyle *style = (view->registeredColumns[i].flags & ES_LIST_VIEW_COLUMN_HAS_MENU) ? ES_STYLE_LIST_COLUMN_HEADER_ITEM_HAS_MENU : ES_STYLE_LIST_COLUMN_HEADER_ITEM;
EsElement *columnHeaderItem = EsCustomElementCreate(view->columnHeader, ES_CELL_FILL, style);
columnHeaderItem->messageUser = ListViewColumnHeaderItemMessage;
columnHeaderItem->cName = "column header item";
columnHeaderItem->userData = i;
if (!columns[i].width) {
columns[i].width = (i ? view->secondaryCellStyle : view->primaryCellStyle)->preferredWidth / theming.scale;
}
EsElement *splitter = EsCustomElementCreate(view->columnHeader, ES_CELL_FILL, ES_STYLE_LIST_COLUMN_HEADER_SPLITTER);
splitter->messageUser = [] (EsElement *element, EsMessage *message) {
EsListViewColumn *column = (EsListViewColumn *) element->userData.p;
EsListView *view = (EsListView *) element->parent->parent;
if (message->type == ES_MSG_MOUSE_LEFT_DOWN) {
view->columnResizingOriginalWidth = column->width * theming.scale;
} else if (message->type == ES_MSG_MOUSE_LEFT_DRAG) {
int width = message->mouseDragged.newPositionX - message->mouseDragged.originalPositionX + view->columnResizingOriginalWidth;
int minimumWidth = element->style->metrics->minimumWidth;
if (width < minimumWidth) width = minimumWidth;
column->width = width / theming.scale;
ListViewCalculateTotalColumnWidth(view);
EsElementRelayout(element->parent);
EsElementRelayout(view);
} else {
return 0;
}
return ES_HANDLED;
},
splitter->messageUser = ListViewColumnSplitterMessage;
splitter->cName = "column header splitter";
splitter->userData = columns + i;
splitter->userData = i;
}
ListViewCalculateTotalColumnWidth(view);
view->scroll.Refresh();
}
void EsListViewRegisterColumn(EsListView *view, uint32_t id, const char *title, ptrdiff_t titleBytes, uint32_t flags, double initialWidth) {
EsMessageMutexCheck();
EsAssert(view->flags & ES_LIST_VIEW_COLUMNS); // List view does not have columns flag set.
if (!initialWidth) {
initialWidth = (view->registeredColumns.Length() ? view->secondaryCellStyle : view->primaryCellStyle)->preferredWidth / theming.scale;
}
ListViewColumn column = {};
column.id = id;
column.flags = flags;
column.width = initialWidth;
if (titleBytes == -1) titleBytes = EsCStringLength(title);
HeapDuplicate((void **) &column.title, &column.titleBytes, title, titleBytes);
view->registeredColumns.Add(column);
}
void EsListViewContentChanged(EsListView *view) {
EsMessageMutexCheck();

View File

@ -1417,12 +1417,6 @@ struct EsCommand {
STRING title;
};
struct EsListViewColumn {
STRING title;
uint32_t flags;
double width;
};
struct EsApplicationStartupRequest {
int64_t id;
STRING filePath;
@ -1642,8 +1636,8 @@ struct EsMessageGetContent {
EsListViewIndex group;
uint32_t icon;
uint32_t drawContentFlags;
uint32_t columnID;
EsBuffer *buffer;
uint8_t column;
};
struct EsMessageGetIndent {
@ -2570,7 +2564,8 @@ function EsListView *EsListViewCreate(EsElement *parent, uint64_t flags = ES_FLA
function EsListViewIndex EsListViewGetIndexFromItem(EsElement *element, EsListViewIndex *group = ES_NULL);
function void EsListViewEnumerateVisibleItems(EsListView *view, EsListViewEnumerateVisibleItemsCallback callback);
function void EsListViewSetColumns(EsListView *view, EsListViewColumn *columns, size_t columnCount);
function void EsListViewRegisterColumn(EsListView *view, uint32_t id, STRING title = BLANK_STRING, uint32_t flags = ES_FLAGS_DEFAULT, double initialWidth = 0);
function void EsListViewAddAllColumns(EsListView *view); // Call after registering the columns to add them to the header. Call again after EsListViewChangeStyles, as needed.
function void EsListViewSetEmptyMessage(EsListView *view, STRING message = BLANK_STRING);
function void EsListViewSetMaximumItemsPerBand(EsListView *view, int maximumItemsPerBand);
function void EsListViewSelectNone(EsListView *view);

View File

@ -119,3 +119,4 @@ private define ES_STYLE_SCROLLBAR_THUMB_VERTICAL (ES_STYLE_CAST(1369))
define ES_STYLE_TOOLBAR_SPACER (ES_STYLE_CAST(5))
define ES_STYLE_TOOLBAR_BUTTON_GROUP_SEPARATOR (ES_STYLE_CAST(7))
define ES_STYLE_TOOLBAR_SPACER_SMALL (ES_STYLE_CAST(3))
define ES_STYLE_LIST_CHOICE_ITEM_2X (ES_STYLE_CAST(9))

Binary file not shown.

Binary file not shown.

View File

@ -137,9 +137,11 @@ EsEventReset=135
EsEventSet=136
EsInstanceCloseReference=137
EsInstanceClose=138
EsListViewRegisterColumn=139
EsMutexAcquire=140
EsMutexDestroy=141
EsMutexRelease=142
EsListViewAddAllColumns=143
EsSchedulerYield=145
EsSleep=146
EsSpinlockAcquire=147
@ -309,7 +311,6 @@ EsFileDelete=311
EsBufferReadInto=312
EsListViewRemoveAll=313
EsSystemShowShutdownDialog=314
EsListViewSetColumns=315
EsListViewSelect=316
EsUndoClear=317
EsMessageReceive=318