From efeac65a96c2d6ba8a6992f44dc104dbcb1ecde4 Mon Sep 17 00:00:00 2001 From: Ilia Demianenko Date: Fri, 15 Sep 2023 15:00:33 -0700 Subject: [PATCH 1/3] Only highlight the widgets on mouse down when they are also hovered --- src/ui/ui.c | 93 +++++++++++++++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/src/ui/ui.c b/src/ui/ui.c index 9ba16ad..51c1874 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -524,6 +524,11 @@ void oc_ui_box_deactivate(oc_ui_box* box) box->active = false; } +void oc_ui_box_set_active(oc_ui_box* box, bool active) +{ + box->active = active; +} + bool oc_ui_box_active(oc_ui_box* box) { return (box->active); @@ -539,16 +544,6 @@ bool oc_ui_box_hot(oc_ui_box* box) return (box->hot); } -void oc_ui_box_set_dragging(oc_ui_box* box, bool dragging) -{ - box->dragging = dragging; -} - -bool oc_ui_box_dragging(oc_ui_box* box) -{ - return (box->dragging); -} - oc_ui_sig oc_ui_box_sig(oc_ui_box* box) { //NOTE: compute input signals @@ -1600,7 +1595,7 @@ oc_ui_sig oc_ui_button_behavior(oc_ui_box* box) { oc_ui_box_set_hot(box, false); } - if(!sig.dragging) + if(!sig.hovering && !sig.dragging) { oc_ui_box_deactivate(box); } @@ -2307,10 +2302,10 @@ void oc_ui_menu_begin(const char* label) oc_ui_style hoverStyle = { .bgColor = theme->fill0 }; oc_ui_style_match_before(hoverPattern, &hoverStyle, OC_UI_STYLE_BG_COLOR); - oc_ui_pattern draggingPattern = { 0 }; - oc_ui_pattern_push(&ui->frameArena, &draggingPattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_DRAGGING }); - oc_ui_style draggingStyle = { .bgColor = theme->fill2 }; - oc_ui_style_match_before(draggingPattern, &draggingStyle, OC_UI_STYLE_BG_COLOR); + oc_ui_pattern activePattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, &activePattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_ACTIVE }); + oc_ui_style activeStyle = { .bgColor = theme->fill2 }; + oc_ui_style_match_before(activePattern, &activeStyle, OC_UI_STYLE_BG_COLOR); oc_ui_box* button = oc_ui_box_begin("button", OC_UI_FLAG_CLICKABLE | OC_UI_FLAG_DRAW_BACKGROUND); @@ -2409,10 +2404,10 @@ oc_ui_sig oc_ui_menu_button(const char* name) oc_ui_style hoverStyle = { .bgColor = theme->fill0 }; oc_ui_style_match_before(hoverPattern, &hoverStyle, OC_UI_STYLE_BG_COLOR); - oc_ui_pattern draggingPattern = { 0 }; - oc_ui_pattern_push(&ui->frameArena, &draggingPattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_DRAGGING }); - oc_ui_style draggingStyle = { .bgColor = theme->fill2 }; - oc_ui_style_match_before(draggingPattern, &draggingStyle, OC_UI_STYLE_BG_COLOR); + oc_ui_pattern activePattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, &activePattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_ACTIVE }); + oc_ui_style activeStyle = { .bgColor = theme->fill2 }; + oc_ui_style_match_before(activePattern, &activeStyle, OC_UI_STYLE_BG_COLOR); oc_ui_flags flags = OC_UI_FLAG_CLICKABLE | OC_UI_FLAG_CLIP @@ -2501,12 +2496,13 @@ oc_ui_select_popup_info oc_ui_select_popup(const char* name, oc_ui_select_popup_ .borderSize = 1 }; oc_ui_style_match_after(activePattern, &activeStyle, OC_UI_STYLE_BORDER_COLOR | OC_UI_STYLE_BORDER_SIZE); - oc_ui_pattern draggingPattern = { 0 }; - oc_ui_pattern_push(&ui->frameArena, &draggingPattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_DRAGGING }); - oc_ui_style draggingStyle = { .bgColor = theme->fill2, - .borderColor = theme->primary, - .borderSize = 1 }; - oc_ui_style_match_after(draggingPattern, &draggingStyle, OC_UI_STYLE_BG_COLOR | OC_UI_STYLE_BORDER_COLOR | OC_UI_STYLE_BORDER_SIZE); + oc_ui_pattern mouseDownPattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, &mouseDownPattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_ACTIVE }); + oc_ui_pattern_push(&ui->frameArena, &mouseDownPattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER }); + oc_ui_style mouseDownStyle = { .bgColor = theme->fill2, + .borderColor = theme->primary, + .borderSize = 1 }; + oc_ui_style_match_after(mouseDownPattern, &mouseDownStyle, OC_UI_STYLE_BG_COLOR | OC_UI_STYLE_BORDER_COLOR | OC_UI_STYLE_BORDER_SIZE); oc_ui_box* button = oc_ui_box_make("button", OC_UI_FLAG_CLICKABLE @@ -2624,9 +2620,9 @@ oc_ui_select_popup_info oc_ui_select_popup(const char* name, oc_ui_select_popup_ oc_ui_pattern_push(&ui->frameArena, &hoverPattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER }); oc_ui_style_match_before(hoverPattern, &(oc_ui_style){ .bgColor = theme->fill0 }, OC_UI_STYLE_BG_COLOR); - oc_ui_pattern draggingPattern = { 0 }; - oc_ui_pattern_push(&ui->frameArena, &draggingPattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_DRAGGING }); - oc_ui_style_match_before(draggingPattern, &(oc_ui_style){ .bgColor = theme->fill2 }, OC_UI_STYLE_BG_COLOR); + oc_ui_pattern activePattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, &activePattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_ACTIVE }); + oc_ui_style_match_before(activePattern, &(oc_ui_style){ .bgColor = theme->fill2 }, OC_UI_STYLE_BG_COLOR); oc_ui_box* wrapper = oc_ui_box_begin_str8(info->options[i], OC_UI_FLAG_CLICKABLE | OC_UI_FLAG_DRAW_BACKGROUND); @@ -2672,10 +2668,17 @@ oc_ui_select_popup_info oc_ui_select_popup(const char* name, oc_ui_select_popup_ oc_ui_box_deactivate(button); oc_ui_box_deactivate(panel); } - else if(oc_ui_box_sig(button).clicked) + else { - oc_ui_box_activate(button); - oc_ui_box_activate(panel); + oc_ui_sig sig = oc_ui_box_sig(button); + if(sig.pressed) + { + oc_ui_box_activate(button); + } + if(sig.clicked) + { + oc_ui_box_activate(panel); + } } oc_ui_box_set_closed(panel, !oc_ui_box_active(panel)); } @@ -2732,7 +2735,7 @@ oc_ui_radio_group_info oc_ui_radio_group(const char* name, oc_ui_radio_group_inf } oc_ui_box_set_hot(radio, sig.hovering); - oc_ui_box_set_dragging(radio, sig.dragging); + oc_ui_box_set_active(radio, sig.hovering && sig.dragging); const char* defaultTagStr = "radio"; const char* selectedTagStr = "radio_selected"; @@ -2766,14 +2769,14 @@ oc_ui_radio_group_info oc_ui_radio_group(const char* name, oc_ui_radio_group_inf | OC_UI_STYLE_BORDER_COLOR; oc_ui_style_box_after(radio, hoverPattern, &hoverStyle, hoverMask); - oc_ui_pattern draggingPattern = { 0 }; - oc_ui_pattern_push(&ui->frameArena, &draggingPattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = defaultTag }); - oc_ui_pattern_push(&ui->frameArena, &draggingPattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_DRAGGING }); - oc_ui_style draggingStyle = { .bgColor = theme->fill1, - .borderColor = theme->primary }; - oc_ui_style_mask draggingMask = OC_UI_STYLE_BG_COLOR - | OC_UI_STYLE_BORDER_COLOR; - oc_ui_style_box_after(radio, draggingPattern, &draggingStyle, draggingMask); + oc_ui_pattern activePattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, &activePattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = defaultTag }); + oc_ui_pattern_push(&ui->frameArena, &activePattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_ACTIVE }); + oc_ui_style activeStyle = { .bgColor = theme->fill1, + .borderColor = theme->primary }; + oc_ui_style_mask activeMask = OC_UI_STYLE_BG_COLOR + | OC_UI_STYLE_BORDER_COLOR; + oc_ui_style_box_after(radio, activePattern, &activeStyle, activeMask); oc_ui_tag selectedTag = oc_ui_tag_make(selectedTagStr); oc_ui_pattern selectedPattern = { 0 }; @@ -2790,11 +2793,11 @@ oc_ui_radio_group_info oc_ui_radio_group(const char* name, oc_ui_radio_group_inf oc_ui_style selectedHoverStyle = { .bgColor = theme->primaryHover }; oc_ui_style_box_after(radio, selectedHoverPattern, &selectedHoverStyle, OC_UI_STYLE_BG_COLOR); - oc_ui_pattern selectedDraggingPattern = { 0 }; - oc_ui_pattern_push(&ui->frameArena, &selectedDraggingPattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = selectedTag }); - oc_ui_pattern_push(&ui->frameArena, &selectedDraggingPattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_DRAGGING }); - oc_ui_style selectedDraggingStyle = { .bgColor = theme->primaryActive }; - oc_ui_style_box_after(radio, selectedDraggingPattern, &selectedDraggingStyle, OC_UI_STYLE_BG_COLOR); + oc_ui_pattern selectedActivePattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, &selectedActivePattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = selectedTag }); + oc_ui_pattern_push(&ui->frameArena, &selectedActivePattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_ACTIVE }); + oc_ui_style selectedActiveStyle = { .bgColor = theme->primaryActive }; + oc_ui_style_box_after(radio, selectedActivePattern, &selectedActiveStyle, OC_UI_STYLE_BG_COLOR); oc_ui_container("label", 0) { -- 2.25.1 From d58643eb52995c8d25f6d78d7b71510d1faefb66 Mon Sep 17 00:00:00 2001 From: Martin Fouilleul Date: Sat, 16 Sep 2023 16:18:23 +0200 Subject: [PATCH 2/3] fix button & checkbox to return to normal styling when active but _not_ hovered --- src/ui/ui.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/ui/ui.c b/src/ui/ui.c index 51c1874..98dc9be 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -1633,11 +1633,17 @@ oc_ui_sig oc_ui_button_str8(oc_str8 label) oc_ui_pattern_push(&ui->frameArena, &hoverPattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER }); oc_ui_style hoverStyle = { .bgColor = theme->fill1 }; oc_ui_style_match_before(hoverPattern, &hoverStyle, OC_UI_STYLE_BG_COLOR); - + /* oc_ui_pattern activePattern = { 0 }; oc_ui_pattern_push(&ui->frameArena, &activePattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_ACTIVE }); - oc_ui_style activeStyle = { .bgColor = theme->fill2 }; + oc_ui_style activeStyle = { .bgColor = theme->fill1 }; oc_ui_style_match_before(activePattern, &activeStyle, OC_UI_STYLE_BG_COLOR); +*/ + oc_ui_pattern activeAndHoverPattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, &activeAndHoverPattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_ACTIVE }); + oc_ui_pattern_push(&ui->frameArena, &activeAndHoverPattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER }); + oc_ui_style activeAndHoverStyle = { .bgColor = theme->fill2 }; + oc_ui_style_match_before(activeAndHoverPattern, &activeAndHoverStyle, OC_UI_STYLE_BG_COLOR); oc_ui_flags flags = OC_UI_FLAG_CLICKABLE | OC_UI_FLAG_CLIP @@ -1710,11 +1716,17 @@ oc_ui_sig oc_ui_checkbox(const char* name, bool* checked) oc_ui_pattern_push(&ui->frameArena, &hoverPattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER }); oc_ui_style hoverStyle = { .bgColor = theme->primaryHover }; oc_ui_style_match_before(hoverPattern, &hoverStyle, OC_UI_STYLE_BG_COLOR); - + /* oc_ui_pattern activePattern = { 0 }; oc_ui_pattern_push(&ui->frameArena, &activePattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_ACTIVE }); - oc_ui_style activeStyle = { .bgColor = theme->primaryActive }; + oc_ui_style activeStyle = { .bgColor = theme->primaryHover }; oc_ui_style_match_before(activePattern, &activeStyle, OC_UI_STYLE_BG_COLOR); +*/ + oc_ui_pattern activeAndHoverPattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, &activeAndHoverPattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_ACTIVE }); + oc_ui_pattern_push(&ui->frameArena, &activeAndHoverPattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER }); + oc_ui_style activeAndHoverStyle = { .bgColor = theme->primaryActive }; + oc_ui_style_match_before(activeAndHoverPattern, &activeAndHoverStyle, OC_UI_STYLE_BG_COLOR); oc_ui_flags flags = OC_UI_FLAG_CLICKABLE | OC_UI_FLAG_CLIP @@ -1752,11 +1764,19 @@ oc_ui_sig oc_ui_checkbox(const char* name, bool* checked) .borderColor = theme->primary }; oc_ui_style_match_before(hoverPattern, &hoverStyle, OC_UI_STYLE_BG_COLOR | OC_UI_STYLE_BORDER_COLOR); + /* oc_ui_pattern activePattern = { 0 }; oc_ui_pattern_push(&ui->frameArena, &activePattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_ACTIVE }); - oc_ui_style activeStyle = { .bgColor = theme->fill1, + oc_ui_style activeStyle = { .bgColor = theme->fill0, .borderColor = theme->primary }; oc_ui_style_match_before(activePattern, &activeStyle, OC_UI_STYLE_BG_COLOR | OC_UI_STYLE_BORDER_COLOR); +*/ + oc_ui_pattern activeAndHoverPattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, &activeAndHoverPattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_ACTIVE }); + oc_ui_pattern_push(&ui->frameArena, &activeAndHoverPattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER }); + oc_ui_style activeAndHoverStyle = { .bgColor = theme->fill1, + .borderColor = theme->primary }; + oc_ui_style_match_before(activeAndHoverPattern, &activeAndHoverStyle, OC_UI_STYLE_BG_COLOR); oc_ui_flags flags = OC_UI_FLAG_CLICKABLE | OC_UI_FLAG_CLIP -- 2.25.1 From 300d5aeab424d19fad710b91b3d53e9eca417bea Mon Sep 17 00:00:00 2001 From: Martin Fouilleul Date: Sat, 16 Sep 2023 16:33:08 +0200 Subject: [PATCH 3/3] add a OC_UI_HOT style selector and use that to style radio buttons when the button's label is hovered --- src/ui/ui.c | 30 +++++++++++++++++------------- src/ui/ui.h | 9 +++++---- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/ui/ui.c b/src/ui/ui.c index 98dc9be..b99c789 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -867,6 +867,10 @@ bool oc_ui_style_selector_match(oc_ui_box* box, oc_ui_style_rule* rule, oc_ui_se { res = res && oc_ui_box_hovering(box, oc_ui_mouse_position()); } + if(selector->status & OC_UI_HOT) + { + res = res && box->hot; + } if(selector->status & OC_UI_ACTIVE) { res = res && box->active; @@ -2780,14 +2784,14 @@ oc_ui_radio_group_info oc_ui_radio_group(const char* name, oc_ui_radio_group_inf | OC_UI_STYLE_BORDER_SIZE; oc_ui_style_box_before(radio, defaultPattern, &defaultStyle, defaultMask); - oc_ui_pattern hoverPattern = { 0 }; - oc_ui_pattern_push(&ui->frameArena, &hoverPattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = defaultTag }); - oc_ui_pattern_push(&ui->frameArena, &hoverPattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER }); - oc_ui_style hoverStyle = { .bgColor = theme->fill0, - .borderColor = theme->primary }; - oc_ui_style_mask hoverMask = OC_UI_STYLE_BG_COLOR - | OC_UI_STYLE_BORDER_COLOR; - oc_ui_style_box_after(radio, hoverPattern, &hoverStyle, hoverMask); + oc_ui_pattern hotPattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, &hotPattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = defaultTag }); + oc_ui_pattern_push(&ui->frameArena, &hotPattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOT }); + oc_ui_style hotStyle = { .bgColor = theme->fill0, + .borderColor = theme->primary }; + oc_ui_style_mask hotMask = OC_UI_STYLE_BG_COLOR + | OC_UI_STYLE_BORDER_COLOR; + oc_ui_style_box_after(radio, hotPattern, &hotStyle, hotMask); oc_ui_pattern activePattern = { 0 }; oc_ui_pattern_push(&ui->frameArena, &activePattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = defaultTag }); @@ -2807,11 +2811,11 @@ oc_ui_radio_group_info oc_ui_radio_group(const char* name, oc_ui_radio_group_inf | OC_UI_STYLE_BG_COLOR; oc_ui_style_box_before(radio, selectedPattern, &selectedStyle, selectedMask); - oc_ui_pattern selectedHoverPattern = { 0 }; - oc_ui_pattern_push(&ui->frameArena, &selectedHoverPattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = selectedTag }); - oc_ui_pattern_push(&ui->frameArena, &selectedHoverPattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER }); - oc_ui_style selectedHoverStyle = { .bgColor = theme->primaryHover }; - oc_ui_style_box_after(radio, selectedHoverPattern, &selectedHoverStyle, OC_UI_STYLE_BG_COLOR); + oc_ui_pattern selectedHotPattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, &selectedHotPattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = selectedTag }); + oc_ui_pattern_push(&ui->frameArena, &selectedHotPattern, (oc_ui_selector){ .op = OC_UI_SEL_AND, .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOT }); + oc_ui_style selectedHotStyle = { .bgColor = theme->primaryHover }; + oc_ui_style_box_after(radio, selectedHotPattern, &selectedHotStyle, OC_UI_STYLE_BG_COLOR); oc_ui_pattern selectedActivePattern = { 0 }; oc_ui_pattern_push(&ui->frameArena, &selectedActivePattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = selectedTag }); diff --git a/src/ui/ui.h b/src/ui/ui.h index d2e6d9a..9f86018 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -388,12 +388,13 @@ typedef enum typedef u8 oc_ui_status; -enum +enum oc_ui_status_enum { OC_UI_NONE = 0, OC_UI_HOVER = 1 << 1, - OC_UI_ACTIVE = 1 << 2, - OC_UI_DRAGGING = 1 << 3, + OC_UI_HOT = 1 << 2, + OC_UI_ACTIVE = 1 << 3, + OC_UI_DRAGGING = 1 << 4, }; typedef enum @@ -623,7 +624,7 @@ typedef struct oc_ui_context oc_ui_edit_move editSelectionMode; i32 editWordSelectionInitialCursor; i32 editWordSelectionInitialMark; - + bool clipboardRegistered; oc_ui_theme* theme; -- 2.25.1