UI: Refactor how dragging onto text buttons works, fixing issues
There was a bunch of special handling to support dropping data-blocks onto string or search-menu buttons, to change the value of these. This refactor makes that case use the normal drop-box design, where an operator is executed on drop that gets input properties set by the drop-box. This should also make it easier to add support for dragging assets into these buttons. In addition this fixes an issue: Two tooltips were shown when dragging assets over text buttons. None should be shown, because this isn't supported.
This commit is contained in:
parent
0d8f1414a2
commit
b73993bcc9
|
@ -788,7 +788,8 @@ void UI_but_drag_set_value(uiBut *but);
|
|||
void UI_but_drag_set_image(
|
||||
uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale, const bool use_free);
|
||||
|
||||
bool UI_but_active_drop_name(struct bContext *C);
|
||||
uiBut *UI_but_active_drop_name_button(const struct bContext *C);
|
||||
bool UI_but_active_drop_name(const struct bContext *C);
|
||||
bool UI_but_active_drop_color(struct bContext *C);
|
||||
|
||||
void UI_but_flag_enable(uiBut *but, int flag);
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
|
@ -59,6 +61,21 @@ static char *ui_tree_view_drop_tooltip(bContext *C,
|
|||
return UI_tree_view_item_drop_tooltip(hovered_tree_item, drag);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static bool ui_drop_name_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(event))
|
||||
{
|
||||
return UI_but_active_drop_name(C) && (drag->type == WM_DRAG_ID);
|
||||
}
|
||||
|
||||
static void ui_drop_name_copy(wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
const ID *id = WM_drag_get_local_ID(drag, 0);
|
||||
RNA_string_set(drop->ptr, "string", id->name + 2);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void ED_dropboxes_ui()
|
||||
{
|
||||
ListBase *lb = WM_dropboxmap_find("User Interface", SPACE_EMPTY, 0);
|
||||
|
@ -69,4 +86,10 @@ void ED_dropboxes_ui()
|
|||
nullptr,
|
||||
nullptr,
|
||||
ui_tree_view_drop_tooltip);
|
||||
WM_dropbox_add(lb,
|
||||
"UI_OT_drop_name",
|
||||
ui_drop_name_poll,
|
||||
ui_drop_name_copy,
|
||||
WM_drag_free_imported_drag_ID,
|
||||
nullptr);
|
||||
}
|
||||
|
|
|
@ -2442,39 +2442,6 @@ static void ui_apply_but(
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Button Drop Event
|
||||
* \{ */
|
||||
|
||||
/* only call if event type is EVT_DROP */
|
||||
static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleButtonData *data)
|
||||
{
|
||||
ListBase *drags = event->customdata; /* drop event type has listbase customdata by default */
|
||||
|
||||
LISTBASE_FOREACH (wmDrag *, wmd, drags) {
|
||||
/* TODO: asset dropping. */
|
||||
if (wmd->type == WM_DRAG_ID) {
|
||||
/* align these types with UI_but_active_drop_name */
|
||||
if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
|
||||
ID *id = WM_drag_get_local_ID(wmd, 0);
|
||||
|
||||
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
|
||||
|
||||
ui_textedit_string_set(but, data, id->name + 2);
|
||||
|
||||
if (ELEM(but->type, UI_BTYPE_SEARCH_MENU)) {
|
||||
but->changed = true;
|
||||
ui_searchbox_update(C, data->searchbox, but, true);
|
||||
}
|
||||
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Button Copy & Paste
|
||||
* \{ */
|
||||
|
@ -2672,15 +2639,9 @@ static void ui_but_copy_text(uiBut *but, char *output, int output_len_max)
|
|||
|
||||
static void ui_but_paste_text(bContext *C, uiBut *but, uiHandleButtonData *data, char *buf_paste)
|
||||
{
|
||||
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
|
||||
ui_textedit_string_set(but, but->active, buf_paste);
|
||||
|
||||
if (but->type == UI_BTYPE_SEARCH_MENU) {
|
||||
but->changed = true;
|
||||
ui_searchbox_update(C, data->searchbox, but, true);
|
||||
}
|
||||
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
BLI_assert(but->active == data);
|
||||
UNUSED_VARS_NDEBUG(data);
|
||||
ui_but_set_string_interactive(C, but, buf_paste);
|
||||
}
|
||||
|
||||
static void ui_but_copy_colorband(uiBut *but)
|
||||
|
@ -3024,6 +2985,24 @@ void ui_but_text_password_hide(char password_str[UI_MAX_PASSWORD_STR],
|
|||
/** \name Button Text Selection/Editing
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Use handling code to set a string for the button. Handles the case where the string is set for a
|
||||
* search button while the search menu is open, so the results are updated accordingly.
|
||||
* This is basically the same as pasting the string into the button.
|
||||
*/
|
||||
void ui_but_set_string_interactive(bContext *C, uiBut *but, const char *value)
|
||||
{
|
||||
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
|
||||
ui_textedit_string_set(but, but->active, value);
|
||||
|
||||
if (but->type == UI_BTYPE_SEARCH_MENU && but->active) {
|
||||
but->changed = true;
|
||||
ui_searchbox_update(C, but->active->searchbox, but, true);
|
||||
}
|
||||
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
}
|
||||
|
||||
void ui_but_active_string_clear_and_exit(bContext *C, uiBut *but)
|
||||
{
|
||||
if (!but->active) {
|
||||
|
@ -7949,7 +7928,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
|
|||
/* Only hard-coded stuff here, button interactions with configurable
|
||||
* keymaps are handled using operators (see #ED_keymap_ui). */
|
||||
|
||||
if ((data->state == BUTTON_STATE_HIGHLIGHT) || (event->type == EVT_DROP)) {
|
||||
if (data->state == BUTTON_STATE_HIGHLIGHT) {
|
||||
|
||||
/* handle copy and paste */
|
||||
bool is_press_ctrl_but_no_shift = event->val == KM_PRESS && IS_EVENT_MOD(event, ctrl, oskey) &&
|
||||
|
@ -7998,11 +7977,6 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
|
|||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
|
||||
/* handle drop */
|
||||
if (event->type == EVT_DROP) {
|
||||
ui_but_drop(C, event, but, data);
|
||||
}
|
||||
|
||||
if ((data->state == BUTTON_STATE_HIGHLIGHT) &&
|
||||
ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, EVT_PADENTER, EVT_RETKEY) &&
|
||||
(event->val == KM_RELEASE) &&
|
||||
|
@ -11716,20 +11690,25 @@ void UI_screen_free_active_but(const bContext *C, bScreen *screen)
|
|||
}
|
||||
}
|
||||
|
||||
/* returns true if highlighted button allows drop of names */
|
||||
/* called in region context */
|
||||
bool UI_but_active_drop_name(bContext *C)
|
||||
uiBut *UI_but_active_drop_name_button(const bContext *C)
|
||||
{
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
uiBut *but = ui_region_find_active_but(region);
|
||||
|
||||
if (but) {
|
||||
if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
|
||||
return true;
|
||||
return but;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* returns true if highlighted button allows drop of names */
|
||||
/* called in region context */
|
||||
bool UI_but_active_drop_name(const bContext *C)
|
||||
{
|
||||
return UI_but_active_drop_name_button(C) != NULL;
|
||||
}
|
||||
|
||||
bool UI_but_active_drop_color(bContext *C)
|
||||
|
|
|
@ -680,6 +680,7 @@ extern bool ui_but_string_eval_number(struct bContext *C,
|
|||
extern int ui_but_string_get_max_length(uiBut *but);
|
||||
/* Clear & exit the active button's string. */
|
||||
extern void ui_but_active_string_clear_and_exit(struct bContext *C, uiBut *but) ATTR_NONNULL();
|
||||
extern void ui_but_set_string_interactive(struct bContext *C, uiBut *but, const char *value);
|
||||
extern uiBut *ui_but_drag_multi_edit_get(uiBut *but);
|
||||
|
||||
void ui_def_but_icon(uiBut *but, const int icon, const int flag);
|
||||
|
|
|
@ -1863,6 +1863,39 @@ static void UI_OT_drop_color(wmOperatorType *ot)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Drop Name Operator
|
||||
* \{ */
|
||||
|
||||
static int drop_name_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
uiBut *but = UI_but_active_drop_name_button(C);
|
||||
char *str = RNA_string_get_alloc(op->ptr, "string", NULL, 0, NULL);
|
||||
|
||||
if (str) {
|
||||
ui_but_set_string_interactive(C, but, str);
|
||||
MEM_freeN(str);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void UI_OT_drop_name(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Drop Name";
|
||||
ot->idname = "UI_OT_drop_name";
|
||||
ot->description = "Drop name to button";
|
||||
|
||||
ot->poll = ED_operator_regionactive;
|
||||
ot->invoke = drop_name_invoke;
|
||||
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
|
||||
|
||||
RNA_def_string(
|
||||
ot->srna, "string", NULL, 0, "String", "The string value to drop into the button");
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name UI List Search Operator
|
||||
* \{ */
|
||||
|
@ -2025,6 +2058,7 @@ void ED_operatortypes_ui(void)
|
|||
WM_operatortype_append(UI_OT_copy_to_selected_button);
|
||||
WM_operatortype_append(UI_OT_jump_to_target_button);
|
||||
WM_operatortype_append(UI_OT_drop_color);
|
||||
WM_operatortype_append(UI_OT_drop_name);
|
||||
#ifdef WITH_PYTHON
|
||||
WM_operatortype_append(UI_OT_editsource);
|
||||
WM_operatortype_append(UI_OT_edittranslation_init);
|
||||
|
|
|
@ -821,10 +821,7 @@ static void wm_drag_draw_tooltip(bContext *C, wmWindow *win, wmDrag *drag, const
|
|||
|
||||
const char *tooltip = NULL;
|
||||
bool free_tooltip = false;
|
||||
if (UI_but_active_drop_name(C)) {
|
||||
tooltip = IFACE_("Paste name");
|
||||
}
|
||||
else if (drag->active_dropbox) {
|
||||
if (drag->active_dropbox) {
|
||||
tooltip = dropbox_tooltip(C, drag, xy, drag->active_dropbox);
|
||||
free_tooltip = true;
|
||||
}
|
||||
|
@ -907,7 +904,6 @@ void wm_drags_draw(bContext *C, wmWindow *win)
|
|||
xy[1] = win->eventstate->xy[1];
|
||||
}
|
||||
|
||||
/* Set a region. It is used in the `UI_but_active_drop_name`. */
|
||||
bScreen *screen = CTX_wm_screen(C);
|
||||
ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, UNPACK2(xy));
|
||||
ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_ANY, UNPACK2(xy));
|
||||
|
|
Loading…
Reference in New Issue