[Bf-blender-cvs] [9a6c22a764d] ui-asset-view-template: Properly support mouse-selecting items in the asset view list

Julian Eisel noreply at git.blender.org
Wed Mar 3 21:45:21 CET 2021


Commit: 9a6c22a764d82211085f23bf8daf28124e65c450
Author: Julian Eisel
Date:   Wed Mar 3 21:40:43 2021 +0100
Branches: ui-asset-view-template
https://developer.blender.org/rB9a6c22a764d82211085f23bf8daf28124e65c450

Properly support mouse-selecting items in the asset view list

This was very glitchy before and just didn't work in most cases. The mouse
press event was simply caught by the preview icon button and didn't make its
way to the underlying list-row button.

===================================================================

M	source/blender/editors/interface/interface_handlers.c
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_query.c

===================================================================

diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 75ee3300e63..bd4ae7db457 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -1523,7 +1523,7 @@ static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const
    */
   if (drag_info->is_xy_lock_init == false) {
     /* first store the buttons original coords */
-    uiBut *but = ui_but_find_mouse_over_ex(region, xy_input[0], xy_input[1], true);
+    uiBut *but = ui_but_find_mouse_over_ex(region, xy_input[0], xy_input[1], true, NULL);
 
     if (but) {
       if (but->flag & UI_BUT_DRAG_LOCK) {
@@ -1594,7 +1594,7 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void
     wmWindow *win = CTX_wm_window(C);
     ARegion *region = CTX_wm_region(C);
     uiBut *but = ui_but_find_mouse_over_ex(
-        region, drag_info->xy_init[0], drag_info->xy_init[1], true);
+        region, drag_info->xy_init[0], drag_info->xy_init[1], true, NULL);
 
     if (but) {
       ui_apply_but_undo(but);
@@ -4163,7 +4163,7 @@ static uiBut *ui_but_list_row_text_activate(bContext *C,
                                             uiButtonActivateType activate_type)
 {
   ARegion *region = CTX_wm_region(C);
-  uiBut *labelbut = ui_but_find_mouse_over_ex(region, event->x, event->y, true);
+  uiBut *labelbut = ui_but_find_mouse_over_ex(region, event->x, event->y, true, NULL);
 
   if (labelbut && labelbut->type == UI_BTYPE_TEXT && !(labelbut->flag & UI_BUT_DISABLED)) {
     /* exit listrow */
@@ -9015,6 +9015,11 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
   return retval;
 }
 
+static bool ui_but_is_listrow(const uiBut *but)
+{
+  return but->type == UI_BTYPE_LISTROW;
+}
+
 static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *region, uiBut *listbox)
 {
   int retval = WM_UI_HANDLER_CONTINUE;
@@ -9048,7 +9053,23 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *regi
     }
   }
 
-  if (val == KM_PRESS) {
+  /* Pass selection to the underlying listrow button if the foreground button didn't catch it.
+   * KM_CLICK is only sent after an uncaught release event, so the forground button gets all
+   * regular events (including mouse presses to start dragging) and this part only kicks in if it
+   * hasn't handled the release event. Note that if there's no overlaid button, the row selects on
+   * the press event already via regular UI_BTYPE_LISTROW handling. */
+  if (ELEM(type, LEFTMOUSE) && (val == KM_CLICK)) {
+    uiBut *listrow = ui_but_find_mouse_over_ex(
+        region, event->x, event->y, false, ui_but_is_listrow);
+
+    if (listrow) {
+      /* Simulate click on listrow button itself (which may be overlapped by another button). */
+      UI_but_execute(C, region, listrow);
+      /* Could probably also return CONTINUE, in case other buttons want to act on click. */
+      retval = WM_UI_HANDLER_BREAK;
+    }
+  }
+  else if (val == KM_PRESS) {
     if ((ELEM(type, EVT_UPARROWKEY, EVT_DOWNARROWKEY) &&
          !IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) ||
         ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->ctrl &&
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index c39e2b3ff8a..086df7f7785 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -1108,10 +1108,12 @@ bool ui_but_contains_point_px(const uiBut *but, const struct ARegion *region, in
 uiBut *ui_list_find_mouse_over(struct ARegion *region,
                                const struct wmEvent *event) ATTR_WARN_UNUSED_RESULT;
 
+typedef bool (*uiButFindPoll)(const uiBut *but);
 uiBut *ui_but_find_mouse_over_ex(struct ARegion *region,
                                  const int x,
                                  const int y,
-                                 const bool labeledit) ATTR_WARN_UNUSED_RESULT;
+                                 const bool labeledit,
+                                 uiButFindPoll find_poll) ATTR_WARN_UNUSED_RESULT;
 uiBut *ui_but_find_mouse_over(struct ARegion *region,
                               const struct wmEvent *event) ATTR_WARN_UNUSED_RESULT;
 uiBut *ui_but_find_rect_over(const struct ARegion *region,
diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c
index 83e48fad157..3123e1764b6 100644
--- a/source/blender/editors/interface/interface_query.c
+++ b/source/blender/editors/interface/interface_query.c
@@ -265,7 +265,8 @@ bool ui_but_contains_point_px_icon(const uiBut *but, ARegion *region, const wmEv
 }
 
 /* x and y are only used in case event is NULL... */
-uiBut *ui_but_find_mouse_over_ex(ARegion *region, const int x, const int y, const bool labeledit)
+uiBut *ui_but_find_mouse_over_ex(
+    ARegion *region, const int x, const int y, const bool labeledit, uiButFindPoll find_poll)
 {
   uiBut *butover = NULL;
 
@@ -277,6 +278,9 @@ uiBut *ui_but_find_mouse_over_ex(ARegion *region, const int x, const int y, cons
     ui_window_to_block_fl(region, block, &mx, &my);
 
     LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) {
+      if (find_poll && find_poll(but) == false) {
+        continue;
+      }
       if (ui_but_is_interactive(but, labeledit)) {
         if (but->pie_dir != UI_RADIAL_NONE) {
           if (ui_but_isect_pie_seg(block, but)) {
@@ -305,7 +309,7 @@ uiBut *ui_but_find_mouse_over_ex(ARegion *region, const int x, const int y, cons
 
 uiBut *ui_but_find_mouse_over(ARegion *region, const wmEvent *event)
 {
-  return ui_but_find_mouse_over_ex(region, event->x, event->y, event->ctrl != 0);
+  return ui_but_find_mouse_over_ex(region, event->x, event->y, event->ctrl != 0, NULL);
 }
 
 uiBut *ui_but_find_rect_over(const struct ARegion *region, const rcti *rect_px)



More information about the Bf-blender-cvs mailing list