[Bf-blender-cvs] [c5d4607] UI-experiments UI-graphical-redesign: Add widget rollover feedback by implementing a Sub-Button pipeline
Julian Eisel
noreply at git.blender.org
Mon Jun 8 23:40:47 CEST 2015
Commit: c5d4607792bd15fdfe11af67526979c3ef87fe9a
Author: Julian Eisel
Date: Mon Jun 8 23:10:01 2015 +0200
Branches: UI-experiments UI-graphical-redesign
https://developer.blender.org/rBc5d4607792bd15fdfe11af67526979c3ef87fe9a
Add widget rollover feedback by implementing a Sub-Button pipeline
As pretty much agreed on in T38070, this implements widget-rollover for
better visual feedback.
The added Sub-Button pipeline should provide us a solid base for future
ideas like using Sub-Buttons to trigger operators (thinking of 'X'-icons
within tabs or menus e.g.), open popups/menus, provide better cursor
feedback, etc. They are basically independent buttons within buttons.
https://developer.blender.org/F187781
===================================================================
M source/blender/editors/interface/interface.c
M source/blender/editors/interface/interface_handlers.c
M source/blender/editors/interface/interface_intern.h
M source/blender/editors/interface/interface_layout.c
M source/blender/editors/interface/interface_widgets.c
===================================================================
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index c389642..e4104fd 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -161,6 +161,13 @@ void ui_block_to_window_rctf(const ARegion *ar, uiBlock *block, rctf *rct_dst, c
ui_block_to_window_fl(ar, block, &rct_dst->xmax, &rct_dst->ymax);
}
+void ui_block_to_window_rcti(const ARegion *ar, uiBlock *block, rcti *rct_dst, const rcti *rct_src)
+{
+ *rct_dst = *rct_src;
+ ui_block_to_window(ar, block, &rct_dst->xmin, &rct_dst->ymin);
+ ui_block_to_window(ar, block, &rct_dst->xmax, &rct_dst->ymax);
+}
+
void ui_window_to_block_fl(const ARegion *ar, uiBlock *block, float *x, float *y) /* for mouse cursor */
{
float a, b, c, d, e, f, px, py;
@@ -1323,6 +1330,43 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, u
rect->ymax = floorf(rectf.ymax);
}
+
+/* project a rcti to pixels in regionspace */
+void ui_rcti_to_pixelrect(const ARegion *ar, uiBlock *block, rcti *rct_dst, const rcti *rct_src)
+{
+ rcti rect;
+
+ ui_block_to_window_rcti(ar, block, &rect, rct_src);
+
+ rect.xmin -= ar->winrct.xmin;
+ rect.ymin -= ar->winrct.ymin;
+ rect.xmax -= ar->winrct.xmin;
+ rect.ymax -= ar->winrct.ymin;
+
+ rct_dst->xmin = iroundf(rect.xmin);
+ rct_dst->ymin = iroundf(rect.ymin);
+ rct_dst->xmax = iroundf(rect.xmax);
+ rct_dst->ymax = iroundf(rect.ymax);
+}
+
+/* project a rctf to pixels in regionspace */
+void ui_rctf_to_pixelrect(const ARegion *ar, uiBlock *block, rctf *rct_dst, const rctf *rct_src)
+{
+ rctf rect;
+
+ ui_block_to_window_rctf(ar, block, &rect, rct_src);
+
+ rect.xmin -= ar->winrct.xmin;
+ rect.ymin -= ar->winrct.ymin;
+ rect.xmax -= ar->winrct.xmin;
+ rect.ymax -= ar->winrct.ymin;
+
+ rct_dst->xmin = floorf(rect.xmin);
+ rct_dst->ymin = floorf(rect.ymin);
+ rct_dst->xmax = floorf(rect.xmax);
+ rct_dst->ymax = floorf(rect.ymax);
+}
+
/* uses local copy of style, to scale things down, and allow widgets to change stuff */
void UI_block_draw(const bContext *C, uiBlock *block)
{
@@ -2528,6 +2572,10 @@ static void ui_but_free(const bContext *C, uiBut *but)
IMB_freeImBuf((struct ImBuf *)but->poin);
}
+ if ((BLI_listbase_is_empty(&but->subbuts)) == false) {
+ BLI_freelistN(&but->subbuts);
+ }
+
BLI_assert(UI_butstore_is_registered(but->block, but) == false);
MEM_freeN(but);
@@ -3104,6 +3152,25 @@ void ui_block_cm_to_scene_linear_v3(uiBlock *block, float pixel[3])
IMB_colormanagement_display_to_scene_linear_v3(pixel, display);
}
+static uiSubBut *ui_def_subbut(
+ uiBut *but, const int type,
+ uiSubButAlign alignment,
+ const int width, const int height)
+{
+ uiSubBut *sbut = MEM_callocN(sizeof(uiSubBut), "uiSubBut");
+
+ sbut->type = type;
+ sbut->align = alignment;
+ sbut->width = width;
+ sbut->height = height;
+
+ /* sbut->rect is calculated later */
+
+ BLI_addtail(&but->subbuts, sbut);
+
+ return sbut;
+}
+
/**
* \brief ui_def_but is the function that draws many button types
*
@@ -3218,6 +3285,13 @@ static uiBut *ui_def_but(
}
}
+ if (but->type == UI_BTYPE_NUM) {
+ const int sbut_width = MIN2(width / 3, height);
+
+ ui_def_subbut(but, UI_SBUT_TYPE_VAL_DECREASE, UI_SBUT_ALIGN_LEFT, sbut_width, height);
+ ui_def_subbut(but, UI_SBUT_TYPE_VAL_INCREASE, UI_SBUT_ALIGN_RIGHT, sbut_width, height);
+ }
+
/* keep track of UI_interface.h */
if (ELEM(but->type,
UI_BTYPE_BLOCK, UI_BTYPE_BUT, UI_BTYPE_LABEL,
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 016bc7e..5bbbe0c 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -381,6 +381,7 @@ static bool ui_but_contains_pt(uiBut *but, float mx, float my);
static bool ui_but_contains_point_px(ARegion *ar, uiBut *but, int x, int y);
static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, const bool labeledit);
static uiBut *ui_but_find_mouse_over(ARegion *ar, const wmEvent *event);
+static uiSubBut *ui_subbut_find_mouse_over(const ARegion *ar, const uiBut *but, const int mouse_xy[2]);
static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type);
static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state);
static void button_activate_exit(
@@ -4235,68 +4236,8 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
}
if (click) {
- /* we can click on the side arrows to increment/decrement,
- * or click inside to edit the value directly */
- float tempf, softmin, softmax;
- float handlewidth;
- int temp;
-
- softmin = but->softmin;
- softmax = but->softmax;
-
- handlewidth = min_ff(BLI_rctf_size_x(&but->rect) / 3, BLI_rctf_size_y(&but->rect));
-
- if (!ui_but_is_float(but)) {
- if (mx < (but->rect.xmin + handlewidth)) {
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- temp = (int)data->value - 1;
- if (temp >= softmin && temp <= softmax)
- data->value = (double)temp;
- else
- data->cancel = true;
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else if (mx > (but->rect.xmax - handlewidth)) {
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- temp = (int)data->value + 1;
- if (temp >= softmin && temp <= softmax)
- data->value = (double)temp;
- else
- data->cancel = true;
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else {
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- }
- }
- else {
- if (mx < (but->rect.xmin + handlewidth)) {
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- tempf = (float)data->value - 0.01f * but->a1;
- if (tempf < softmin) tempf = softmin;
- data->value = tempf;
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else if (mx > but->rect.xmax - handlewidth) {
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- tempf = (float)data->value + 0.01f * but->a1;
- if (tempf > softmax) tempf = softmax;
- data->value = tempf;
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else {
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- }
- }
-
+ /* start textediting - clicking to increase/decrease numbers is handled via sub-buttons */
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
retval = WM_UI_HANDLER_BREAK;
}
@@ -4306,6 +4247,40 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
return retval;
}
+static int ui_do_subbut_NUM(bContext *C, uiBut *but, const uiSubBut *sbut, const wmEvent *event)
+{
+ uiHandleButtonData *data = but->active;
+ const float softmin = but->softmin;
+ const float softmax = but->softmax;
+ const bool is_float = ui_but_is_float(but);
+ const bool increase = (sbut->type == UI_SBUT_TYPE_VAL_INCREASE);
+ float tempf;
+ int temp;
+
+ if (event->type != LEFTMOUSE || event->val != KM_RELEASE || data->dragchange)
+ return WM_UI_HANDLER_CONTINUE;
+
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+ if (is_float) {
+ tempf = (float)data->value + (increase ? 0.01f : -0.01f) * but->a1;
+ CLAMP(tempf, softmin, softmax);
+ data->value = tempf;
+ }
+ else {
+ temp = (int)data->value + (increase ? 1 : -1);
+ if (IN_RANGE_INCL(temp, softmin, softmax))
+ data->value = (double)temp;
+ else
+ data->cancel = true;
+ }
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+
+ /* always break */
+ return WM_UI_HANDLER_BREAK;
+}
+
static bool ui_numedit_but_SLI(
uiBut *but, uiHandleButtonData *data,
int mx, const bool is_horizontal,
@@ -6742,8 +6717,33 @@ static bool ui_but_menu(bContext *C, uiBut *but)
return true;
}
+static int ui_do_but_subbut(bContext *C, uiBut *but, uiSubBut *sbut, const wmEvent *event)
+{
+ int retval = WM_UI_HANDLER_CONTINUE;
+
+ BLI_assert(sbut->is_hovered);
+
+ switch (but->type) {
+ case UI_BTYPE_NUM:
+ retval = ui_do_subbut_NUM(C, but, sbut, event);
+ break;
+ default:
+ break;
+ }
+
+ if (retval == WM_UI_HANDLER_BREAK) {
+ BLI_assert(ui_but_contains_point_px(CTX_wm_region(C), but, event->x, event->y));
+ button_activate_exit(C, but, but->active, true, false);
+ /* reactivate highlight state */
+ button_activate_init(C, CTX_wm_region(C), but, BUTTON_ACTIVATE_OVER);
+ }
+
+ return retval;
+}
+
static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *event)
{
+ uiSubBut *sbut;
uiHandleButtonData *data;
int retval;
@@ -6887,6 +6887,16 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
}
}
+ sbut = ui_subbut_find_mouse_over(CTX_wm_region(C), but, &event->x);
+
+ if (sbut) {
+ retval = ui_do_but_subbut(C, but, sbut, event);
+
+ if (retval == WM_UI_HANDLER_BREAK) {
+ return retval;
+ }
+ }
+
switch (but->type) {
case UI_BTYPE_BUT:
retval = ui_do_but_BUT(C, but, data, event);
@@ -7356,6 +7366,25 @@ static uiBut *ui_but_find_mouse_over(ARegion *ar, const wmEvent *event)
}
+static uiSubBut *ui_subbut_find_mouse_over(const ARegion *ar, const uiBut *but, const int mouse_xy[2])
+{
+ uiSubBut *sbut;
+ float mx = mouse_xy[0];
+ float my = mouse_xy[1];
+
+ BLI_assert(ui_but_contains_point_px(ar, but, UNPACK2(mouse_xy)));
+
+ ui_window_to_block_fl(ar, but->block, &mx, &my);
+
+ for (sbut = but->subbuts.first; sbut; sbut = sbut->next) {
+ if (BLI_rcti_isect_x(&sbut->rect, mx)) {
+ return sbut;
+ }
+ }
+ return NULL;
+}
+
+
static uiBut *ui_list_find_mouse_over(ARegion *ar, int x, int y)
{
uiBlock *block;
@@ -8038,6 +8067,31 @@ static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiBu
/************ handle events for an activated button ***********/
+static void ui_handle_but_subbuts(ARegion *ar, const uiBut *but, const int mouse_xy[2])
+{
+ uiSubBut *sbut = ui_subbut_find_mouse_over(ar, but, mouse_xy);
+ bool changed = false;
+
+ if (sbut) {
+ if (sbut->is_hovered == false) {
+ sbut->is_hovered = true;
+ changed = true;
+ }
+ }
+ else {
+ for (sbut = but->subbut
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list