diff --git a/source/blender/editors/include/UI_interface_c.hh b/source/blender/editors/include/UI_interface_c.hh index 7b12ff1c07b..ccd45b469f1 100644 --- a/source/blender/editors/include/UI_interface_c.hh +++ b/source/blender/editors/include/UI_interface_c.hh @@ -2647,19 +2647,6 @@ void template_tree(uiLayout *layout, bContext *C); */ bool UI_list_item_index_is_filtered_visible(const struct uiList *ui_list, int item_idx); -/** - * \return An RNA pointer for the operator properties. - */ -PointerRNA *UI_list_custom_activate_operator_set(uiList *ui_list, - blender::StringRefNull opname, - bool create_properties); -/** - * \return An RNA pointer for the operator properties. - */ -PointerRNA *UI_list_custom_drag_operator_set(uiList *ui_list, - blender::StringRefNull opname, - bool create_properties); - /* UI Operators */ struct uiDragColorHandle { float color[4]; @@ -2902,18 +2889,6 @@ void UI_butstore_register(uiButStore *bs_handle, uiBut **but_p); bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src); void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p); -/** - * A version of #WM_key_event_operator_string that's limited to UI elements. - * - * This supports showing shortcuts in context-menus (for example), - * for actions that can also be activated using shortcuts while the cursor is over the button. - * Without this those shortcuts aren't discoverable for users. - */ -std::optional UI_key_event_operator_string(const bContext *C, - blender::StringRefNull opname, - IDProperty *properties, - bool is_strict); - /* ui_interface_region_tooltip.c */ /** diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index 89278a6c358..5d771b7ac65 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -1261,42 +1261,6 @@ static void ui_apply_but_VIEW_ITEM(bContext *C, ui_apply_but_ROW(C, block, but, data); } -/** - * \note Ownership of \a properties is moved here. The #uiAfterFunc owns it now. - * - * \param context_but: The button to use context from when calling or polling the operator. - * - * \returns true if the operator was executed, otherwise false. - */ -static bool ui_list_invoke_item_operator(bContext *C, - const uiBut *context_but, - wmOperatorType *ot, - PointerRNA **properties) -{ - if (!ui_but_context_poll_operator(C, ot, context_but)) { - return false; - } - - /* Allow the context to be set from the hovered button, so the list item draw callback can set - * context for the operators. */ - ui_handle_afterfunc_add_operator_ex(ot, properties, WM_OP_INVOKE_DEFAULT, context_but); - return true; -} - -static void ui_apply_but_LISTROW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data) -{ - uiBut *listbox = ui_list_find_from_row(data->region, but); - if (listbox) { - uiList *list = static_cast(listbox->custom_data); - if (list && list->dyn_data->custom_activate_optype) { - ui_list_invoke_item_operator( - C, but, list->dyn_data->custom_activate_optype, &list->dyn_data->custom_activate_opptr); - } - } - - ui_apply_but_ROW(C, block, but, data); -} - static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data) { if (!data->text_edit.edit_string) { @@ -2410,15 +2374,13 @@ static void ui_apply_but( case UI_BTYPE_CHECKBOX_N: ui_apply_but_TOG(C, but, data); break; + case UI_BTYPE_LISTROW: case UI_BTYPE_ROW: ui_apply_but_ROW(C, block, but, data); break; case UI_BTYPE_VIEW_ITEM: ui_apply_but_VIEW_ITEM(C, block, but, data); break; - case UI_BTYPE_LISTROW: - ui_apply_but_LISTROW(C, block, but, data); - break; case UI_BTYPE_TAB: ui_apply_but_TAB(C, but, data); break; @@ -5208,15 +5170,6 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, con { ret = WM_UI_HANDLER_CONTINUE; } - /* Same special case handling for UI lists. Return CONTINUE so that a tweak or CLICK event - * will be sent for the list to work with. */ - const uiBut *listbox = ui_list_find_mouse_over(data->region, event); - if (listbox) { - const uiList *ui_list = static_cast(listbox->custom_data); - if (ui_list && ui_list->dyn_data->custom_drag_optype) { - ret = WM_UI_HANDLER_CONTINUE; - } - } const uiBut *view_but = ui_view_item_find_mouse_over(data->region, event->xy); if (view_but) { ret = WM_UI_HANDLER_CONTINUE; @@ -9957,133 +9910,6 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) return retval; } -/** - * Activate the underlying list-row button, so the row is highlighted. - * Early exits if \a activate_dragging is true, but the custom drag operator fails to execute. - * Gives the wanted behavior where the item is activated on a click-drag event when the custom drag - * operator is executed. - */ -static int ui_list_activate_hovered_row(bContext *C, - ARegion *region, - const uiList *ui_list, - const wmEvent *event, - bool activate_dragging) -{ - const bool do_drag = activate_dragging && ui_list->dyn_data->custom_drag_optype; - - if (do_drag) { - const uiBut *hovered_but = ui_but_find_mouse_over(region, event); - if (!ui_list_invoke_item_operator(C, - hovered_but, - ui_list->dyn_data->custom_drag_optype, - &ui_list->dyn_data->custom_drag_opptr)) - { - return WM_UI_HANDLER_CONTINUE; - } - } - - int mouse_xy[2]; - WM_event_drag_start_xy(event, mouse_xy); - - uiBut *listrow = ui_list_row_find_mouse_over(region, mouse_xy); - if (listrow) { - wmOperatorType *custom_activate_optype = ui_list->dyn_data->custom_activate_optype; - - /* Hacky: Ensure the custom activate operator is not called when the custom drag operator - * was. Only one should run! */ - if (activate_dragging && do_drag) { - ((uiList *)ui_list)->dyn_data->custom_activate_optype = nullptr; - } - - /* Simulate click on listrow button itself (which may be overlapped by another button). Also - * calls the custom activate operator (#uiListDyn::custom_activate_optype). */ - UI_but_execute(C, region, listrow); - - ((uiList *)ui_list)->dyn_data->custom_activate_optype = custom_activate_optype; - } - - return WM_UI_HANDLER_BREAK; -} - -static bool ui_list_is_hovering_draggable_but(bContext *C, - const uiList *list, - const ARegion *region, - const wmEvent *event) -{ - /* On a tweak event, uses the coordinates from where tweaking was started. */ - int mouse_xy[2]; - WM_event_drag_start_xy(event, mouse_xy); - - const uiBut *hovered_but = ui_but_find_mouse_over_ex( - region, mouse_xy, false, false, nullptr, nullptr); - - if (list->dyn_data->custom_drag_optype) { - if (ui_but_context_poll_operator(C, list->dyn_data->custom_drag_optype, hovered_but)) { - return true; - } - } - - return (hovered_but && ui_but_drag_is_draggable(hovered_but)); -} - -static int ui_list_handle_click_drag(bContext *C, - const uiList *ui_list, - ARegion *region, - const wmEvent *event) -{ - if (event->type != LEFTMOUSE) { - return WM_UI_HANDLER_CONTINUE; - } - - int retval = WM_UI_HANDLER_CONTINUE; - - const bool is_draggable = ui_list_is_hovering_draggable_but(C, ui_list, region, event); - bool activate = false; - bool activate_dragging = false; - - if (event->val == KM_CLICK_DRAG) { - if (is_draggable) { - activate_dragging = true; - activate = true; - } - } - /* #KM_CLICK is only sent after an uncaught release event, so the foreground 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. */ - else if (event->val == KM_CLICK) { - activate = true; - } - - if (activate) { - retval = ui_list_activate_hovered_row(C, region, ui_list, event, activate_dragging); - } - - return retval; -} - -static void ui_list_activate_row_from_index( - bContext *C, ARegion *region, uiBut *listbox, uiList *ui_list, int index) -{ - uiBut *new_active_row = ui_list_row_find_index(region, index, listbox); - if (new_active_row) { - /* Preferred way to update the active item, also calls the custom activate operator - * (#uiListDyn::custom_activate_optype). */ - UI_but_execute(C, region, new_active_row); - } - else { - /* A bit ugly, set the active index in RNA directly. That's because a button that's - * scrolled away in the list box isn't created at all. - * The custom activate operator (#uiListDyn::custom_activate_optype) is not called in this case - * (which may need the row button context). */ - RNA_property_int_set(&listbox->rnapoin, listbox->rnaprop, index); - RNA_property_update(C, &listbox->rnapoin, listbox->rnaprop); - ui_apply_but_undo(listbox); - } - - ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM; -} - static int ui_list_get_increment(const uiList *ui_list, const int type, const int columns) { int increment = 0; @@ -10139,10 +9965,7 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *regi } } - if (event->type == LEFTMOUSE) { - retval = ui_list_handle_click_drag(C, ui_list, region, event); - } - else if (val == KM_PRESS) { + if (val == KM_PRESS) { if ((ELEM(type, EVT_UPARROWKEY, EVT_DOWNARROWKEY, EVT_LEFTARROWKEY, EVT_RIGHTARROWKEY) && (event->modifier == 0)) || (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && (event->modifier == KM_CTRL))) @@ -10196,7 +10019,12 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *regi CLAMP(value, min, max); if (value != value_orig) { - ui_list_activate_row_from_index(C, region, listbox, ui_list, value); + RNA_property_int_set(&listbox->rnapoin, listbox->rnaprop, value); + RNA_property_update(C, &listbox->rnapoin, listbox->rnaprop); + + ui_apply_but_undo(listbox); + + ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM; redraw = true; } retval = WM_UI_HANDLER_BREAK; diff --git a/source/blender/editors/interface/interface_intern.hh b/source/blender/editors/interface/interface_intern.hh index 22a94cfdb6f..6ed525e7a83 100644 --- a/source/blender/editors/interface/interface_intern.hh +++ b/source/blender/editors/interface/interface_intern.hh @@ -1504,7 +1504,6 @@ bool ui_but_contains_point_px(const uiBut *but, const ARegion *region, const int uiBut *ui_list_find_mouse_over(const ARegion *region, const wmEvent *event) ATTR_WARN_UNUSED_RESULT; -uiBut *ui_list_find_from_row(const ARegion *region, const uiBut *row_but) ATTR_WARN_UNUSED_RESULT; uiBut *ui_list_row_find_mouse_over(const ARegion *region, const int xy[2]) ATTR_NONNULL(1, 2) ATTR_WARN_UNUSED_RESULT; uiBut *ui_list_row_find_index(const ARegion *region, diff --git a/source/blender/editors/interface/interface_query.cc b/source/blender/editors/interface/interface_query.cc index 5bf845033c5..d4f468aab30 100644 --- a/source/blender/editors/interface/interface_query.cc +++ b/source/blender/editors/interface/interface_query.cc @@ -459,17 +459,6 @@ static bool ui_list_contains_row(const uiBut *listbox_but, const uiBut *listrow_ return ui_but_rna_equals(listbox_but, listrow_but); } -static bool ui_but_is_listbox_with_row(const uiBut *but, const void *customdata) -{ - const uiBut *row_but = static_cast(customdata); - return (but->type == UI_BTYPE_LISTBOX) && ui_list_contains_row(but, row_but); -} - -uiBut *ui_list_find_from_row(const ARegion *region, const uiBut *row_but) -{ - return ui_but_find(region, ui_but_is_listbox_with_row, row_but); -} - static bool ui_but_is_listrow(const uiBut *but, const void * /*customdata*/) { return but->type == UI_BTYPE_LISTROW; diff --git a/source/blender/editors/interface/interface_utils.cc b/source/blender/editors/interface/interface_utils.cc index cc955ac5ae6..87780f9e740 100644 --- a/source/blender/editors/interface/interface_utils.cc +++ b/source/blender/editors/interface/interface_utils.cc @@ -26,7 +26,6 @@ #include "BKE_context.hh" #include "BKE_global.hh" -#include "BKE_idprop.hh" #include "BKE_lib_id.hh" #include "BKE_screen.hh" @@ -1032,115 +1031,3 @@ void UI_butstore_update(uiBlock *block) } /** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Key Event from UI - * \{ */ - -/** - * Follow the logic from #wm_keymap_item_find_in_keymap. - */ -static bool ui_key_event_property_match(const StringRefNull opname, - IDProperty *properties, - const bool is_strict, - wmOperatorType *ui_optype, - PointerRNA *ui_opptr) -{ - if (ui_optype->idname != opname) { - return false; - } - - bool match = false; - if (properties) { - if (ui_opptr && - IDP_EqualsProperties_ex(properties, static_cast(ui_opptr->data), is_strict)) - { - match = true; - } - } - else { - match = true; - } - return match; -} - -std::optional UI_key_event_operator_string(const bContext *C, - const StringRefNull opname, - IDProperty *properties, - const bool is_strict) -{ - /* NOTE: currently only actions on UI Lists are supported (for the asset manager). - * Other kinds of events can be supported as needed. */ - - ARegion *region = CTX_wm_region(C); - if (region == nullptr) { - return std::nullopt; - } - - /* Early exit regions which don't have UI-Lists. */ - if ((region->runtime->type->keymapflag & ED_KEYMAP_UI) == 0) { - return std::nullopt; - } - - uiBut *but = UI_region_active_but_get(region); - if (but == nullptr) { - return std::nullopt; - } - - if (but->type != UI_BTYPE_PREVIEW_TILE) { - return std::nullopt; - } - - short event_val = KM_NOTHING; - short event_type = KM_NOTHING; - - uiBut *listbox = nullptr; - for (int i = but->block->buttons.size() - 1; i >= 0; i--) { - uiBut *but_iter = but->block->buttons[i].get(); - if ((but_iter->type == UI_BTYPE_LISTBOX) && ui_but_contains_rect(but_iter, &but->rect)) { - listbox = but_iter; - break; - } - } - - if (listbox && listbox->custom_data) { - uiList *list = static_cast(listbox->custom_data); - uiListDyn *dyn_data = list->dyn_data; - if ((dyn_data->custom_activate_optype != nullptr) && - ui_key_event_property_match(opname, - properties, - is_strict, - dyn_data->custom_activate_optype, - dyn_data->custom_activate_opptr)) - { - event_val = KM_CLICK; - event_type = LEFTMOUSE; - } - else if ((dyn_data->custom_activate_optype != nullptr) && - ui_key_event_property_match(opname, - properties, - is_strict, - dyn_data->custom_drag_optype, - dyn_data->custom_drag_opptr)) - { - event_val = KM_CLICK_DRAG; - event_type = LEFTMOUSE; - } - } - - if ((event_val != KM_NOTHING) && (event_type != KM_NOTHING)) { - return WM_keymap_item_raw_to_string(KM_NOTHING, - KM_NOTHING, - KM_NOTHING, - KM_NOTHING, - KM_NOTHING, - 0, - event_val, - event_type, - false); - } - - return std::nullopt; -} - -/** \} */ diff --git a/source/blender/editors/interface/templates/interface_template_list.cc b/source/blender/editors/interface/templates/interface_template_list.cc index d84e473c217..2de215ca1a8 100644 --- a/source/blender/editors/interface/templates/interface_template_list.cc +++ b/source/blender/editors/interface/templates/interface_template_list.cc @@ -346,15 +346,6 @@ static void uilist_free_dyn_data(uiList *ui_list) return; } - if (dyn_data->custom_activate_opptr) { - WM_operator_properties_free(dyn_data->custom_activate_opptr); - MEM_delete(dyn_data->custom_activate_opptr); - } - if (dyn_data->custom_drag_opptr) { - WM_operator_properties_free(dyn_data->custom_drag_opptr); - MEM_delete(dyn_data->custom_drag_opptr); - } - MEM_SAFE_FREE(dyn_data->items_filter_flags); MEM_SAFE_FREE(dyn_data->items_filter_neworder); MEM_SAFE_FREE(dyn_data->customdata); @@ -1300,46 +1291,6 @@ void uiTemplateList(uiLayout *layout, nullptr); } -PointerRNA *UI_list_custom_activate_operator_set(uiList *ui_list, - const StringRefNull opname, - bool create_properties) -{ - uiListDyn *dyn_data = ui_list->dyn_data; - dyn_data->custom_activate_optype = WM_operatortype_find(opname.c_str(), false); - if (!dyn_data->custom_activate_optype) { - return nullptr; - } - - if (create_properties) { - PointerRNA *opptr = dyn_data->custom_activate_opptr; - WM_operator_properties_alloc(&dyn_data->custom_activate_opptr, - opptr ? (IDProperty **)&opptr->data : nullptr, - opname.c_str()); - } - - return dyn_data->custom_activate_opptr; -} - -PointerRNA *UI_list_custom_drag_operator_set(uiList *ui_list, - const StringRefNull opname, - bool create_properties) -{ - uiListDyn *dyn_data = ui_list->dyn_data; - dyn_data->custom_drag_optype = WM_operatortype_find(opname.c_str(), false); - if (!dyn_data->custom_drag_optype) { - return nullptr; - } - - if (create_properties) { - PointerRNA *opptr = dyn_data->custom_drag_opptr; - WM_operator_properties_alloc(&dyn_data->custom_drag_opptr, - opptr ? (IDProperty **)&opptr->data : nullptr, - opname.c_str()); - } - - return dyn_data->custom_drag_opptr; -} - /* -------------------------------------------------------------------- */ /** \name List-types Registration diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 3da1449bbc4..65a9299c7b7 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -303,9 +303,6 @@ typedef struct uiListDyn { int *items_filter_neworder; struct wmOperatorType *custom_drag_optype; - struct PointerRNA *custom_drag_opptr; - struct wmOperatorType *custom_activate_optype; - struct PointerRNA *custom_activate_opptr; } uiListDyn; typedef struct uiList { /* some list UI data need to be saved in file */ diff --git a/source/blender/windowmanager/intern/wm_keymap.cc b/source/blender/windowmanager/intern/wm_keymap.cc index e30846bb0ec..8d71572ccd7 100644 --- a/source/blender/windowmanager/intern/wm_keymap.cc +++ b/source/blender/windowmanager/intern/wm_keymap.cc @@ -1645,13 +1645,6 @@ std::optional WM_key_event_operator_string(const bContext *C, return WM_keymap_item_to_string(kmi, false); } - /* Check UI state (non key-map actions for UI regions). */ - if (std::optional result = UI_key_event_operator_string( - C, opname, properties, is_strict)) - { - return result; - } - return std::nullopt; }