mirror of https://gitlab.com/nakst/essence
create list sample application
This commit is contained in:
parent
02cc8d14fb
commit
83ea7cc2af
|
@ -47,7 +47,7 @@ EsListViewColumn folderOutputColumns[] = {
|
|||
#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_LIST_VIEW_COLUMN_RIGHT_ALIGNED },
|
||||
{ INTERFACE_STRING(FileManagerColumnSize), ES_LIST_VIEW_COLUMN_HAS_MENU | ES_TEXT_H_RIGHT },
|
||||
};
|
||||
|
||||
#define LOAD_FOLDER_BACK (1)
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
#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);
|
||||
|
||||
EsListViewIndex index = EsListViewFixedItemInsert(list, name);
|
||||
EsListViewFixedItemAddString(list, index, ageString);
|
||||
EsListViewFixedItemAddString(list, index, favoriteColor);
|
||||
}
|
||||
|
||||
void _start() {
|
||||
_init();
|
||||
|
||||
while (true) {
|
||||
EsMessage *message = EsMessageReceive();
|
||||
|
||||
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);
|
||||
EsListViewSetColumns(list, columns, sizeof(columns) / sizeof(columns[0]));
|
||||
AddPerson(list, "Alice", 20, "\a#e00]Red");
|
||||
AddPerson(list, "Bob", 30, "\a#080]Green");
|
||||
AddPerson(list, "Cameron", 40, "\a#00f]Blue");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
[general]
|
||||
name=List
|
||||
|
||||
[build]
|
||||
source=apps/samples/list.cpp
|
|
@ -28,16 +28,16 @@ struct Instance : EsInstance {
|
|||
|
||||
EsListViewColumn listViewProcessesColumns[] = {
|
||||
{ "Name", -1, 0, 150 },
|
||||
{ "PID", -1, ES_LIST_VIEW_COLUMN_RIGHT_ALIGNED, 120 },
|
||||
{ "Memory", -1, ES_LIST_VIEW_COLUMN_RIGHT_ALIGNED, 120 },
|
||||
{ "CPU", -1, ES_LIST_VIEW_COLUMN_RIGHT_ALIGNED, 120 },
|
||||
{ "Handles", -1, ES_LIST_VIEW_COLUMN_RIGHT_ALIGNED, 120 },
|
||||
{ "Threads", -1, ES_LIST_VIEW_COLUMN_RIGHT_ALIGNED, 120 },
|
||||
{ "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_LIST_VIEW_COLUMN_RIGHT_ALIGNED, 150 },
|
||||
{ "CPU", -1, ES_LIST_VIEW_COLUMN_RIGHT_ALIGNED, 150 },
|
||||
{ "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 },
|
||||
|
|
|
@ -193,6 +193,15 @@ const EsStyle styleButtonGroupContainer = {
|
|||
},
|
||||
};
|
||||
|
||||
const EsStyle styleClockButton = {
|
||||
.inherit = ES_STYLE_TASK_BAR_EXTRA,
|
||||
|
||||
.metrics = {
|
||||
.mask = ES_THEME_METRICS_TEXT_FIGURES,
|
||||
.textFigures = ES_TEXT_FIGURE_TABULAR,
|
||||
},
|
||||
};
|
||||
|
||||
struct {
|
||||
Array<InstalledApplication *> installedApplications;
|
||||
Array<ApplicationInstance *> allApplicationInstances;
|
||||
|
@ -371,10 +380,6 @@ int ReorderListLayout(ReorderList *list, int additionalRightMargin, bool clampDr
|
|||
|
||||
size_t childCount = list->items.Length();
|
||||
|
||||
if (!childCount) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int totalWidth = 0;
|
||||
uintptr_t nonExitingChildCount = 0;
|
||||
|
||||
|
@ -394,8 +399,8 @@ int ReorderListLayout(ReorderList *list, int additionalRightMargin, bool clampDr
|
|||
widthClamped = true;
|
||||
}
|
||||
|
||||
int targetWidth = totalWidth / nonExitingChildCount;
|
||||
int extraWidth = totalWidth % nonExitingChildCount;
|
||||
int targetWidth = nonExitingChildCount ? totalWidth / nonExitingChildCount : -1;
|
||||
int extraWidth = nonExitingChildCount ? totalWidth % nonExitingChildCount : 0;
|
||||
|
||||
list->targetWidth = targetWidth;
|
||||
list->extraWidth = extraWidth;
|
||||
|
@ -575,7 +580,7 @@ void WindowTabDestroy(WindowTab *tab) {
|
|||
if (container->taskBarButton) {
|
||||
container->taskBarButton->exiting = true;
|
||||
container->taskBarButton->containerWindow = nullptr;
|
||||
EsElementRelayout(&desktop.taskBar);
|
||||
EsElementRelayout(container->taskBarButton->parent);
|
||||
// The button is destroyed by ReorderItemAnimate, once the exit animation completes.
|
||||
}
|
||||
|
||||
|
@ -2652,7 +2657,7 @@ void DesktopSetup() {
|
|||
desktop.tasksButton = EsButtonCreate(panel, ES_ELEMENT_HIDDEN, ES_STYLE_TASK_BAR_BUTTON);
|
||||
desktop.tasksButton->messageUser = TaskBarTasksButtonMessage;
|
||||
|
||||
EsButton *clockButton = EsButtonCreate(panel, ES_BUTTON_TABULAR | ES_BUTTON_COMPACT, ES_STYLE_TASK_BAR_EXTRA);
|
||||
EsButton *clockButton = EsButtonCreate(panel, ES_BUTTON_COMPACT, &styleClockButton);
|
||||
clockButton->cName = "current time";
|
||||
EsThreadCreate(TaskBarClockUpdateThread, nullptr, clockButton);
|
||||
|
||||
|
|
|
@ -3920,8 +3920,7 @@ int ProcessButtonMessage(EsElement *element, EsMessage *message) {
|
|||
EsDrawContent(message->painter, element,
|
||||
ES_RECT_2S(message->painter->width, message->painter->height),
|
||||
button->label, button->labelBytes, button->iconID,
|
||||
((button->flags & ES_BUTTON_DROPDOWN) ? ES_DRAW_CONTENT_MARKER_DOWN_ARROW : 0)
|
||||
| ((button->flags & ES_BUTTON_TABULAR) ? ES_DRAW_CONTENT_TABULAR : 0));
|
||||
((button->flags & ES_BUTTON_DROPDOWN) ? ES_DRAW_CONTENT_MARKER_DOWN_ARROW : 0));
|
||||
} else if (message->type == ES_MSG_PAINT_ICON) {
|
||||
if (button->imageDisplay) {
|
||||
EsRectangle imageSize = ES_RECT_2S(button->imageDisplay->width, button->imageDisplay->height);
|
||||
|
@ -4233,7 +4232,7 @@ int ProcessMenuItemMessage(EsElement *element, EsMessage *message) {
|
|||
|
||||
EsDrawContent(message->painter, element,
|
||||
ES_RECT_2S(message->painter->width, message->painter->height),
|
||||
(const char *) _buffer, buffer.position, 0, ES_DRAW_CONTENT_CHANGE_ALIGNMENT | ES_TEXT_H_RIGHT | ES_TEXT_V_CENTER);
|
||||
(const char *) _buffer, buffer.position, 0, ES_TEXT_H_RIGHT);
|
||||
} else if (message->type == ES_MSG_GET_WIDTH) {
|
||||
uint8_t _buffer[64];
|
||||
EsBuffer buffer = { .out = _buffer, .bytes = sizeof(_buffer) };
|
||||
|
|
|
@ -1193,18 +1193,9 @@ struct EsListView : EsElement {
|
|||
&& ES_HANDLED == EsMessageSend(this, &m)) {
|
||||
bool useSelectedCellStyle = (item->element->customStyleState & THEME_STATE_SELECTED) && (flags & ES_LIST_VIEW_CHOICE_SELECT);
|
||||
UIStyle *style = useSelectedCellStyle ? selectedCellStyle : i ? secondaryCellStyle : primaryCellStyle;
|
||||
|
||||
uint8_t previousTextAlign = style->textAlign;
|
||||
|
||||
if (columns[i].flags & ES_LIST_VIEW_COLUMN_RIGHT_ALIGNED) {
|
||||
style->textAlign ^= ES_TEXT_H_RIGHT | ES_TEXT_H_LEFT;
|
||||
}
|
||||
|
||||
style->PaintText(message->painter, element, bounds,
|
||||
(char *) _buffer, buffer.position, m.getContent.icon,
|
||||
(columns[i].flags & ES_LIST_VIEW_COLUMN_TABULAR) ? ES_DRAW_CONTENT_TABULAR : ES_FLAGS_DEFAULT,
|
||||
i ? nullptr : &selection);
|
||||
style->textAlign = previousTextAlign;
|
||||
columns[i].flags, i ? nullptr : &selection);
|
||||
}
|
||||
|
||||
bounds.l += columns[i].width * theming.scale + secondaryCellStyle->gapMajor;
|
||||
|
|
|
@ -379,13 +379,15 @@ define ES_TEXT_PLAN_CLIP_UNBREAKABLE_LINES (1 << 11)
|
|||
define ES_TEXT_PLAN_NO_FONT_SUBSTITUTION (1 << 12)
|
||||
// ...plus alignment flags.
|
||||
|
||||
define ES_DRAW_CONTENT_CHANGE_ALIGNMENT (1 << 8)
|
||||
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_TABULAR (1 << 11)
|
||||
define ES_DRAW_CONTENT_RICH_TEXT (1 << 12)
|
||||
// ...plus alignment flags, if CHANGE_ALIGNMENT set.
|
||||
|
||||
define ES_LIST_VIEW_COLUMN_HAS_MENU (1 << 16) // The header can be clicked to open a menu.
|
||||
// ...plus draw content flags and alignment flags.
|
||||
|
||||
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.
|
||||
|
@ -514,7 +516,6 @@ define ES_BUTTON_CHECKBOX (1 << 10)
|
|||
define ES_BUTTON_RADIOBOX (1 << 11)
|
||||
define ES_BUTTON_CANCEL (1 << 12)
|
||||
define ES_BUTTON_PUSH (1 << 13)
|
||||
define ES_BUTTON_TABULAR (1 << 14) // Use tabular text figures.
|
||||
define ES_MENU_ITEM_CHECKED (ES_CHECK_CHECKED)
|
||||
|
||||
define ES_COLOR_WELL_HAS_OPACITY (1 << 0)
|
||||
|
@ -542,10 +543,6 @@ define ES_LIST_VIEW_GROUP_HAS_FOOTER (1 << 1) // The last item in the group is
|
|||
define ES_LIST_VIEW_GROUP_INDENT (1 << 2) // Indent the group's items (excluding the header and footer).
|
||||
define ES_LIST_VIEW_GROUP_COLLAPSABLE (1 << 3) // The group can be collapsed.
|
||||
|
||||
define ES_LIST_VIEW_COLUMN_RIGHT_ALIGNED (1 << 0) // The column's contents is right-aligned.
|
||||
define ES_LIST_VIEW_COLUMN_HAS_MENU (1 << 1) // The header can be clicked to open a menu.
|
||||
define ES_LIST_VIEW_COLUMN_TABULAR (1 << 2) // Use tabular text figures (so that digits are aligned).
|
||||
|
||||
define ES_MENU_AT_CURSOR (1 << 0)
|
||||
define ES_MENU_MAXIMUM_HEIGHT (1 << 1)
|
||||
|
||||
|
@ -627,6 +624,7 @@ define ES_THEME_METRICS_FONT_WEIGHT (1 << 20)
|
|||
define ES_THEME_METRICS_ICON_SIZE (1 << 21)
|
||||
define ES_THEME_METRICS_IS_ITALIC (1 << 22)
|
||||
define ES_THEME_METRICS_LAYOUT_VERTICAL (1 << 23)
|
||||
define ES_THEME_METRICS_TEXT_FIGURES (1 << 24)
|
||||
|
||||
define ES_WINDOW_MOVE_MAXIMIZED (1 << 0)
|
||||
define ES_WINDOW_MOVE_ADJUST_TO_FIT_SCREEN (1 << 1)
|
||||
|
@ -1331,7 +1329,8 @@ struct EsThemeMetrics {
|
|||
int32_t maximumWidth, maximumHeight;
|
||||
int32_t gapMajor, gapMinor, gapWrap;
|
||||
uint32_t textColor, selectedBackground, selectedText, iconColor;
|
||||
int textAlign, textSize, fontFamily, fontWeight, iconSize;
|
||||
int32_t textAlign, textSize, fontFamily, fontWeight, iconSize;
|
||||
uint8_t textFigures;
|
||||
bool isItalic, layoutVertical;
|
||||
};
|
||||
|
||||
|
|
|
@ -2686,6 +2686,17 @@ void EsRichTextParse(const char *inString, ptrdiff_t inStringBytes,
|
|||
textRun->style.decorations |= ES_TEXT_DECORATION_UNDERLINE;
|
||||
} else if (c == '2' /* secondary color */) {
|
||||
textRun->style.color = GetConstantNumber("textSecondary");
|
||||
} else if (c == '#' /* custom color */) {
|
||||
char string[9];
|
||||
size_t bytes = 0;
|
||||
|
||||
while (bytes < sizeof(string)) {
|
||||
if (i >= inStringBytes || inString[i] == ']') break;
|
||||
string[bytes++] = inString[i++];
|
||||
}
|
||||
|
||||
textRun->style.color = EsColorParse(string, bytes);
|
||||
goto parsedFormat;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -207,6 +207,7 @@ typedef struct ThemeMetrics {
|
|||
uint32_t textColor, selectedBackground, selectedText, iconColor;
|
||||
int8_t textAlign, fontWeight;
|
||||
int16_t textSize, iconSize;
|
||||
uint8_t textFigures;
|
||||
bool isItalic, layoutVertical;
|
||||
} ThemeMetrics;
|
||||
|
||||
|
@ -1200,24 +1201,16 @@ typedef struct ThemeAnimation {
|
|||
struct UIStyle {
|
||||
intptr_t referenceCount;
|
||||
|
||||
uint32_t observedStyleStateMask;
|
||||
bool IsStateChangeObserved(uint16_t state1, uint16_t state2);
|
||||
|
||||
// General information.
|
||||
|
||||
uint8_t textAlign;
|
||||
uint16_t textSize;
|
||||
uint32_t textColor;
|
||||
EsFont font;
|
||||
|
||||
EsRectangle insets, borders;
|
||||
uint16_t preferredWidth, preferredHeight;
|
||||
int16_t gapMajor, gapMinor, gapWrap;
|
||||
|
||||
uint32_t observedStyleStateMask;
|
||||
EsRectangle paintOutsets, opaqueInsets;
|
||||
|
||||
float scale;
|
||||
|
||||
EsThemeAppearance *appearance; // An optional, custom appearance provided by the application.
|
||||
|
||||
// Data.
|
||||
|
@ -1242,7 +1235,7 @@ struct UIStyle {
|
|||
// Misc.
|
||||
|
||||
bool IsRegionCompletelyOpaque(EsRectangle region, int width, int height);
|
||||
|
||||
bool IsStateChangeObserved(uint16_t state1, uint16_t state2);
|
||||
inline void GetTextStyle(EsTextStyle *style);
|
||||
};
|
||||
|
||||
|
@ -1326,8 +1319,6 @@ bool ThemeInitialise() {
|
|||
}
|
||||
|
||||
void ThemeStyleCopyInlineMetrics(UIStyle *style) {
|
||||
style->textSize = style->metrics->textSize;
|
||||
style->textColor = style->metrics->textColor;
|
||||
style->font.family = style->metrics->fontFamily;
|
||||
style->font.weight = style->metrics->fontWeight;
|
||||
style->font.italic = style->metrics->isItalic;
|
||||
|
@ -1547,6 +1538,7 @@ void ThemeStylePrepare(UIStyle *style, UIStyleKey key) {
|
|||
if (customMetrics->mask & ES_THEME_METRICS_GAP_MINOR) style->metrics->gapMinor = customMetrics->gapMinor;
|
||||
if (customMetrics->mask & ES_THEME_METRICS_GAP_WRAP) style->metrics->gapWrap = customMetrics->gapWrap;
|
||||
if (customMetrics->mask & ES_THEME_METRICS_TEXT_COLOR) style->metrics->textColor = customMetrics->textColor;
|
||||
if (customMetrics->mask & ES_THEME_METRICS_TEXT_FIGURES) style->metrics->textFigures = customMetrics->textFigures;
|
||||
if (customMetrics->mask & ES_THEME_METRICS_SELECTED_BACKGROUND) style->metrics->selectedBackground = customMetrics->selectedBackground;
|
||||
if (customMetrics->mask & ES_THEME_METRICS_SELECTED_TEXT) style->metrics->selectedText = customMetrics->selectedText;
|
||||
if (customMetrics->mask & ES_THEME_METRICS_ICON_COLOR) style->metrics->iconColor = customMetrics->iconColor;
|
||||
|
@ -1933,13 +1925,18 @@ void UIStyle::PaintText(EsPainter *painter, EsElement *element, EsRectangle rect
|
|||
|
||||
if (textBytes) {
|
||||
EsTextPlanProperties properties = {};
|
||||
properties.flags = (flags & ES_DRAW_CONTENT_CHANGE_ALIGNMENT) ? (flags & 0xFF) : textAlign;
|
||||
properties.flags = textAlign;
|
||||
|
||||
if (flags & ES_TEXT_H_LEFT) properties.flags = (properties.flags & ~(ES_TEXT_H_CENTER | ES_TEXT_H_RIGHT)) | ES_TEXT_H_LEFT;
|
||||
if (flags & ES_TEXT_H_CENTER) properties.flags = (properties.flags & ~(ES_TEXT_H_LEFT | ES_TEXT_H_RIGHT)) | ES_TEXT_H_CENTER;
|
||||
if (flags & ES_TEXT_H_RIGHT) properties.flags = (properties.flags & ~(ES_TEXT_H_LEFT | ES_TEXT_H_CENTER)) | ES_TEXT_H_RIGHT;
|
||||
if (flags & ES_TEXT_V_TOP) properties.flags = (properties.flags & ~(ES_TEXT_V_CENTER | ES_TEXT_V_BOTTOM)) | ES_TEXT_V_TOP;
|
||||
if (flags & ES_TEXT_V_CENTER) properties.flags = (properties.flags & ~(ES_TEXT_V_TOP | ES_TEXT_V_BOTTOM)) | ES_TEXT_V_CENTER;
|
||||
if (flags & ES_TEXT_V_BOTTOM) properties.flags = (properties.flags & ~(ES_TEXT_V_TOP | ES_TEXT_V_CENTER)) | ES_TEXT_V_BOTTOM;
|
||||
|
||||
EsTextRun textRun[2] = {};
|
||||
textRun[1].offset = textBytes;
|
||||
textRun[0].style.font = font;
|
||||
textRun[0].style.size = textSize;
|
||||
textRun[0].style.color = textColor;
|
||||
GetTextStyle(&textRun[0].style);
|
||||
|
||||
if (flags & ES_DRAW_CONTENT_TABULAR) {
|
||||
textRun[0].style.figures = ES_TEXT_FIGURE_TABULAR;
|
||||
|
@ -2038,6 +2035,7 @@ inline void UIStyle::GetTextStyle(EsTextStyle *style) {
|
|||
style->font = font;
|
||||
style->size = metrics->textSize;
|
||||
style->color = metrics->textColor;
|
||||
style->figures = metrics->textFigures;
|
||||
}
|
||||
|
||||
bool UIStyle::IsStateChangeObserved(uint16_t state1, uint16_t state2) {
|
||||
|
|
BIN
res/Theme.dat
BIN
res/Theme.dat
Binary file not shown.
Loading…
Reference in New Issue