This commit is contained in:
nakst 2021-08-24 19:00:54 +01:00
parent dbc595a344
commit abf4494701
7 changed files with 123 additions and 3 deletions

View File

@ -4946,6 +4946,101 @@ EsIconDisplay *EsIconDisplayCreate(EsElement *parent, uint64_t flags, const EsSt
return display;
}
// --------------------------------- Sliders.
struct EsSlider : EsElement {
EsElement *point;
double value;
uint32_t steps;
int32_t dragOffset;
bool inDrag, endDrag;
};
int ProcessSliderPointMessage(EsElement *element, EsMessage *message) {
EsSlider *slider = (EsSlider *) EsElementGetLayoutParent(element);
if (message->type == ES_MSG_MOUSE_LEFT_DRAG) {
double range = slider->width - slider->point->currentStyle->preferredWidth;
slider->inDrag = true;
EsSliderSetValue(slider, (message->mouseDragged.newPositionX + element->offsetX - slider->dragOffset) / range);
} else if (message->type == ES_MSG_MOUSE_LEFT_UP && slider->inDrag) {
slider->inDrag = false;
slider->endDrag = true; // Force sending the update message.
EsSliderSetValue(slider, slider->value);
slider->endDrag = false;
} else if (message->type == ES_MSG_MOUSE_LEFT_DOWN) {
slider->dragOffset = message->mouseDown.positionX;
EsElementFocus(slider);
} else {
return 0;
}
return ES_HANDLED;
}
int ProcessSliderMessage(EsElement *element, EsMessage *message) {
EsSlider *slider = (EsSlider *) element;
if (message->type == ES_MSG_LAYOUT) {
int pointWidth = slider->point->currentStyle->preferredWidth;
int pointHeight = slider->point->currentStyle->preferredHeight;
slider->point->InternalMove(pointWidth, pointHeight, (slider->width - pointWidth) * slider->value, (slider->height - pointHeight) / 2);
} else if (message->type == ES_MSG_FOCUSED_START) {
slider->point->customStyleState |= THEME_STATE_FOCUSED_ITEM;
slider->point->MaybeRefreshStyle();
} else if (message->type == ES_MSG_FOCUSED_END) {
slider->point->customStyleState &= ~THEME_STATE_FOCUSED_ITEM;
slider->point->MaybeRefreshStyle();
} else if (message->type == ES_MSG_KEY_TYPED && message->keyboard.scancode == ES_SCANCODE_LEFT_ARROW) {
EsSliderSetValue(slider, slider->value - (slider->steps ? 1.0 / slider->steps : 0.02));
} else if (message->type == ES_MSG_KEY_TYPED && message->keyboard.scancode == ES_SCANCODE_RIGHT_ARROW) {
EsSliderSetValue(slider, slider->value + (slider->steps ? 1.0 / slider->steps : 0.02));
} else if (message->type == ES_MSG_KEY_TYPED && message->keyboard.scancode == ES_SCANCODE_HOME) {
EsSliderSetValue(slider, 0.0);
} else if (message->type == ES_MSG_KEY_TYPED && message->keyboard.scancode == ES_SCANCODE_END) {
EsSliderSetValue(slider, 1.0);
} else if (message->type == ES_MSG_PAINT) {
// TODO Draw ticks.
} else {
return 0;
}
return ES_HANDLED;
}
double EsSliderGetValue(EsSlider *slider) {
return slider->value;
}
void EsSliderSetValue(EsSlider *slider, double newValue, bool sendUpdatedMessage) {
newValue = ClampDouble(0.0, 1.0, newValue);
if (slider->steps) {
newValue = EsCRTfloor((slider->steps - 1) * newValue + 0.5) / (slider->steps - 1);
}
double previous = slider->value;
if (previous == newValue && !slider->endDrag) return;
slider->value = newValue;
EsElementRelayout(slider);
if (sendUpdatedMessage) {
EsMessage m = { ES_MSG_SLIDER_MOVED, .sliderMoved = { .value = newValue, .previous = previous, .inDrag = slider->inDrag } };
EsMessageSend(slider, &m);
}
}
EsSlider *EsSliderCreate(EsElement *parent, uint64_t flags, const EsStyle *style, double value, uint32_t steps) {
EsSlider *slider = (EsSlider *) EsHeapAllocate(sizeof(EsSlider), true);
slider->Initialise(parent, flags | ES_ELEMENT_FOCUSABLE, ProcessSliderMessage, style ?: ES_STYLE_SLIDER_TRACK);
slider->cName = "slider";
slider->point = EsCustomElementCreate(slider, ES_FLAGS_DEFAULT, ES_STYLE_SLIDER_POINT);
slider->point->messageUser = ProcessSliderPointMessage;
slider->steps = steps;
EsSliderSetValue(slider, value, false);
return slider;
}
// --------------------------------- Message loop and core UI infrastructure.
void EsElement::PrintTree(int depth) {

View File

@ -13,6 +13,7 @@ opaque_type EsSplitter EsElement;
opaque_type EsImageDisplay EsElement;
opaque_type EsListDisplay EsElement;
opaque_type EsCanvasPane EsElement;
opaque_type EsSlider EsElement;
opaque_type EsTextPlan none;
opaque_type EsPaintTarget none;
opaque_type EsUndoManager none;
@ -945,6 +946,7 @@ enum EsMessageType {
ES_MSG_COLOR_CHANGED = 0x3003 // Color well's color has changed. See message->colorChanged.
ES_MSG_LIST_DISPLAY_GET_MARKER = 0x3004 // Get the string for a marker in an EsListDisplay. See message->getContent.
ES_MSG_REORDER_ITEM_TEST = 0x3005
ES_MSG_SLIDER_MOVED = 0x3006 // The slider has been moved.
// Desktop messages:
ES_MSG_POWER_BUTTON_PRESSED = 0x4801
@ -1637,6 +1639,11 @@ struct EsMessageScrollbarMoved {
int scroll, previous;
};
struct EsMessageSliderMoved {
double value, previous;
bool inDrag;
};
struct EsMessageColorChanged {
uint32_t newColor;
bool pickerClosed;
@ -1782,6 +1789,7 @@ struct EsMessage {
// Specific element messages:
EsMessageScrollbarMoved scrollbarMoved;
EsMessageSliderMoved sliderMoved;
EsMessageColorChanged colorChanged;
EsMessageNumberDragDelta numberDragDelta;
EsMessageNumberUpdated numberUpdated;
@ -2315,7 +2323,6 @@ function EsElement *EsButtonGetCheckBuddy(EsButton *button); // TODO Public pro
// Textboxes.
function EsTextbox *EsTextboxCreate(EsElement *parent, uint64_t flags = ES_FLAGS_DEFAULT, const EsStyle *style = ES_NULL);
function bool EsTextboxFind(EsTextbox *textbox, STRING string, int32_t *line, int32_t *byte, uint32_t flags);
function void EsTextboxInsert(EsTextbox *textbox, STRING string = BLANK_STRING, bool sendUpdatedMessage = true); // Deletes existing selection first.
function char *EsTextboxGetContents(EsTextbox *textbox, size_t *bytes = ES_NULL, uint32_t flags = ES_FLAGS_DEFAULT); // Result will be zero-terminated; free with EsHeapFree.
@ -2336,6 +2343,12 @@ function void EsTextboxSetTextStyle(EsTextbox *textbox, const EsTextStyle *textS
function void EsTextboxSetupSyntaxHighlighting(EsTextbox *textbox, uint32_t language, uint32_t *customColors = ES_NULL, size_t customColorCount = 0);
function void EsTextboxStartEdit(EsTextbox *textbox);
// Sliders.
function EsSlider *EsSliderCreate(EsElement *parent, uint64_t flags = ES_FLAGS_DEFAULT, const EsStyle *style = ES_NULL, double value = 0, uint32_t steps = 0);
function double EsSliderGetValue(EsSlider *slider);
function void EsSliderSetValue(EsSlider *slider, double newValue, bool sendUpdatedMessage = true);
// Panels, spacers and splitters.
function EsPanel *EsPanelCreate(EsElement *parent, uint64_t flags = ES_FLAGS_DEFAULT, const EsStyle *style = ES_NULL);

View File

@ -324,6 +324,15 @@ void SettingsPageMouse(EsElement *element, SettingsPage *page) {
// TODO Use a slider instead?
SettingsAddNumberBox(table, INTERFACE_STRING(DesktopSettingsMouseSpeed), 'M', "general", "cursor_speed", -20, 20, nullptr, 0, 0.05);
table = EsPanelCreate(container, ES_CELL_H_FILL, &styleSettingsCheckboxGroup);
SettingsAddCheckbox(table, INTERFACE_STRING(DesktopSettingsMouseUseAcceleration), 'C', "general", "use_cursor_acceleration");
SettingsAddCheckbox(table, INTERFACE_STRING(DesktopSettingsMouseSlowOnAlt), 'O', "general", "use_cursor_alt_slow");
EsSpacerCreate(container, ES_CELL_H_FILL, ES_STYLE_BUTTON_GROUP_SEPARATOR);
table = EsPanelCreate(container, ES_CELL_H_FILL | ES_PANEL_TABLE | ES_PANEL_HORIZONTAL, &styleSettingsTable);
EsPanelSetBands(table, 2);
// TODO Mouse trails.
EsTextDisplayCreate(table, ES_CELL_H_RIGHT | ES_CELL_H_PUSH, 0, INTERFACE_STRING(DesktopSettingsMouseCursorTrails));
textbox = EsTextboxCreate(table, ES_CELL_H_LEFT | ES_CELL_H_PUSH | ES_TEXTBOX_EDIT_BASED, &styleSettingsNumberTextbox);
@ -342,8 +351,6 @@ void SettingsPageMouse(EsElement *element, SettingsPage *page) {
SettingsAddCheckbox(table, INTERFACE_STRING(DesktopSettingsMouseSwapLeftAndRightButtons), 'B', "general", "swap_left_and_right_buttons");
SettingsAddCheckbox(table, INTERFACE_STRING(DesktopSettingsMouseShowShadow), 'W', "general", "show_cursor_shadow");
SettingsAddCheckbox(table, INTERFACE_STRING(DesktopSettingsMouseLocateCursorOnCtrl), 'L', "general", "locate_cursor_on_ctrl");
SettingsAddCheckbox(table, INTERFACE_STRING(DesktopSettingsMouseUseAcceleration), 'C', "general", "use_cursor_acceleration");
SettingsAddCheckbox(table, INTERFACE_STRING(DesktopSettingsMouseSlowOnAlt), 'O', "general", "use_cursor_alt_slow");
EsSpacerCreate(container, ES_CELL_H_FILL, ES_STYLE_BUTTON_GROUP_SEPARATOR);

View File

@ -88,6 +88,8 @@ define_private ES_STYLE_SCROLLBAR_THUMB_HORIZONTAL (ES_STYLE_CAST(1367))
define_private ES_STYLE_SCROLLBAR_THUMB_VERTICAL (ES_STYLE_CAST(1369))
define_private ES_STYLE_SCROLLBAR_PAD (ES_STYLE_CAST(1371))
define ES_STYLE_SEPARATOR_HORIZONTAL (ES_STYLE_CAST(1373))
define_private ES_STYLE_SLIDER_POINT (ES_STYLE_CAST(1607))
define_private ES_STYLE_SLIDER_TRACK (ES_STYLE_CAST(1601))
define_private ES_STYLE_SPLIT_BAR_HORIZONTAL (ES_STYLE_CAST(1375))
define_private ES_STYLE_SPLIT_BAR_VERTICAL (ES_STYLE_CAST(1377))
define_private ES_STYLE_TASK_BAR_BAR (ES_STYLE_CAST(1379))

Binary file not shown.

Binary file not shown.

View File

@ -294,7 +294,9 @@ EsTextPlanGetLineCount=292
EsTextPlanDestroy=293
EsTextDisplaySetContents=294
EsSystemConfigurationReadInteger=295
EsSliderCreate=296
EsSystemConfigurationReadString=297
EsSliderGetValue=298
EsGameControllerStatePoll=299
EsInstanceDestroy=300
EsRandomU8=301
@ -418,3 +420,4 @@ EsFontDatabaseInsertFile=418
EsFileStoreGetSize=419
EsFileStoreMap=420
EsTimerCancel=421
EsSliderSetValue=422