WindowManager: Support Dynamic tooltips when dragging.

Originally the operator name was drawn next to the dragging content.
After that there was an option to add custom, static text with the
dragging content. This patch allows dynamic text to be drawn.

The custom text was implemented as out parameter of the poll function
what made the code unclear. This patch introduces a tooltip function
that separates tooltip generation from the poll function.

NOTE: the text should always be returned in its own memory block. This
block will be freed after it is copied in the drag struct.

Reviewed By: Severin

Differential Revision: https://developer.blender.org/D12104
This commit is contained in:
Jeroen Bakker 2021-08-02 15:09:15 +02:00
parent 8edb2222ae
commit d60a7a8744
Notes: blender-bot 2024-01-31 11:35:08 +01:00
Referenced by issue #90371, As a user I want better feedback when dragging materials so it is clear what happens when dropping the material.
16 changed files with 234 additions and 258 deletions

View File

@ -2577,10 +2577,7 @@ void ED_keymap_ui(struct wmKeyConfig *keyconf);
void ED_uilisttypes_ui(void);
void UI_drop_color_copy(struct wmDrag *drag, struct wmDropBox *drop);
bool UI_drop_color_poll(struct bContext *C,
struct wmDrag *drag,
const struct wmEvent *event,
const char **r_tooltip);
bool UI_drop_color_poll(struct bContext *C, struct wmDrag *drag, const struct wmEvent *event);
bool UI_context_copy_to_selected_list(struct bContext *C,
struct PointerRNA *ptr,

View File

@ -1759,10 +1759,7 @@ static void UI_OT_button_string_clear(wmOperatorType *ot)
/** \name Drop Color Operator
* \{ */
bool UI_drop_color_poll(struct bContext *C,
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
bool UI_drop_color_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(event))
{
/* should only return true for regions that include buttons, for now
* return true always */

View File

@ -5695,10 +5695,7 @@ static void keymap_modal_set(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "SCREEN_OT_area_move");
}
static bool blend_file_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool blend_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH) {
if (drag->icon == ICON_FILE_BLEND) {
@ -5728,8 +5725,9 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
/* dropbox for entire window */
ListBase *lb = WM_dropboxmap_find("Window", 0, 0);
WM_dropbox_add(lb, "WM_OT_drop_blend_file", blend_file_drop_poll, blend_file_drop_copy, NULL);
WM_dropbox_add(lb, "UI_OT_drop_color", UI_drop_color_poll, UI_drop_color_copy, NULL);
WM_dropbox_add(
lb, "WM_OT_drop_blend_file", blend_file_drop_poll, blend_file_drop_copy, NULL, NULL);
WM_dropbox_add(lb, "UI_OT_drop_color", UI_drop_color_poll, UI_drop_color_copy, NULL, NULL);
keymap_modal_set(keyconf);
}

View File

@ -605,10 +605,7 @@ static int /*eContextResult*/ clip_context(const bContext *C,
}
/* dropboxes */
static bool clip_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
@ -639,7 +636,7 @@ static void clip_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Clip", SPACE_CLIP, 0);
WM_dropbox_add(lb, "CLIP_OT_open", clip_drop_poll, clip_drop_copy, NULL);
WM_dropbox_add(lb, "CLIP_OT_open", clip_drop_poll, clip_drop_copy, NULL, NULL);
}
static void clip_refresh(const bContext *C, ScrArea *area)

View File

@ -158,10 +158,7 @@ static void console_cursor(wmWindow *win, ScrArea *UNUSED(area), ARegion *region
/* ************* dropboxes ************* */
static bool id_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(tooltip))
static bool id_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
return WM_drag_get_local_ID(drag, 0) != NULL;
}
@ -176,10 +173,7 @@ static void id_drop_copy(wmDrag *drag, wmDropBox *drop)
MEM_freeN(text);
}
static bool path_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(tooltip))
static bool path_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
return (drag->type == WM_DRAG_PATH);
}
@ -196,8 +190,8 @@ static void console_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Console", SPACE_CONSOLE, RGN_TYPE_WINDOW);
WM_dropbox_add(lb, "CONSOLE_OT_insert", id_drop_poll, id_drop_copy, NULL);
WM_dropbox_add(lb, "CONSOLE_OT_insert", path_drop_poll, path_drop_copy, NULL);
WM_dropbox_add(lb, "CONSOLE_OT_insert", id_drop_poll, id_drop_copy, NULL, NULL);
WM_dropbox_add(lb, "CONSOLE_OT_insert", path_drop_poll, path_drop_copy, NULL, NULL);
}
/* ************* end drop *********** */

View File

@ -815,10 +815,7 @@ static void file_ui_region_listener(const wmRegionListenerParams *listener_param
}
}
static bool filepath_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool filepath_drop_poll(bContext *C, wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH) {
SpaceFile *sfile = CTX_wm_space_file(C);
@ -839,7 +836,7 @@ static void file_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Window", SPACE_EMPTY, RGN_TYPE_WINDOW);
WM_dropbox_add(lb, "FILE_OT_filepath_drop", filepath_drop_poll, filepath_drop_copy, NULL);
WM_dropbox_add(lb, "FILE_OT_filepath_drop", filepath_drop_poll, filepath_drop_copy, NULL, NULL);
}
static int file_space_subtype_get(ScrArea *area)

View File

@ -253,10 +253,7 @@ static void image_keymap(struct wmKeyConfig *keyconf)
}
/* dropboxes */
static bool image_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool image_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ScrArea *area = CTX_wm_area(C);
if (ED_region_overlap_isect_any_xy(area, &event->x)) {
@ -282,7 +279,7 @@ static void image_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Image", SPACE_IMAGE, 0);
WM_dropbox_add(lb, "IMAGE_OT_open", image_drop_poll, image_drop_copy, NULL);
WM_dropbox_add(lb, "IMAGE_OT_open", image_drop_poll, image_drop_copy, NULL, NULL);
}
/**

View File

@ -664,42 +664,29 @@ static void node_main_region_draw(const bContext *C, ARegion *region)
/* ************* dropboxes ************* */
static bool node_group_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool node_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
return WM_drag_is_ID_type(drag, ID_NT);
}
static bool node_object_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool node_object_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
return WM_drag_is_ID_type(drag, ID_OB);
}
static bool node_collection_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
const wmEvent *UNUSED(event))
{
return WM_drag_is_ID_type(drag, ID_GR);
}
static bool node_texture_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool node_texture_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
return WM_drag_is_ID_type(drag, ID_TE);
}
static bool node_ima_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
@ -708,10 +695,7 @@ static bool node_ima_drop_poll(bContext *UNUSED(C),
return WM_drag_is_ID_type(drag, ID_IM);
}
static bool node_mask_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
return WM_drag_is_ID_type(drag, ID_MSK);
}
@ -753,32 +737,38 @@ static void node_dropboxes(void)
"NODE_OT_add_object",
node_object_drop_poll,
node_id_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"NODE_OT_add_collection",
node_collection_drop_poll,
node_id_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"NODE_OT_add_texture",
node_texture_drop_poll,
node_id_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"NODE_OT_add_group",
node_group_drop_poll,
node_group_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"NODE_OT_add_file",
node_ima_drop_poll,
node_id_path_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"NODE_OT_add_mask",
node_mask_drop_poll,
node_id_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
}
/* ************* end drop *********** */

View File

@ -31,6 +31,7 @@
#include "DNA_space_types.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLT_translation.h"
@ -316,10 +317,7 @@ static bool allow_parenting_without_modifier_key(SpaceOutliner *space_outliner)
}
}
static bool parent_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
@ -455,10 +453,7 @@ void OUTLINER_OT_parent_drop(wmOperatorType *ot)
/* ******************** Parent Clear Operator *********************** */
static bool parent_clear_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
@ -541,10 +536,7 @@ void OUTLINER_OT_parent_clear(wmOperatorType *ot)
/* ******************** Scene Drop Operator *********************** */
static bool scene_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
/* Ensure item under cursor is valid drop target */
Object *ob = (Object *)WM_drag_get_local_ID(drag, ID_OB);
@ -609,10 +601,7 @@ void OUTLINER_OT_scene_drop(wmOperatorType *ot)
/* ******************** Material Drop Operator *********************** */
static bool material_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool material_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
/* Ensure item under cursor is valid drop target */
Material *ma = (Material *)WM_drag_get_local_ID(drag, ID_MA);
@ -833,10 +822,7 @@ static bool datastack_drop_are_types_valid(StackDropData *drop_data)
return true;
}
static bool datastack_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **r_tooltip)
static bool datastack_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
if (drag->type != WM_DRAG_DATASTACK) {
return false;
@ -873,28 +859,6 @@ static bool datastack_drop_poll(bContext *C,
break;
}
switch (drop_data->drop_action) {
case DATA_STACK_DROP_REORDER:
*r_tooltip = TIP_("Reorder");
break;
case DATA_STACK_DROP_COPY:
if (drop_data->pchan_parent) {
*r_tooltip = TIP_("Copy to bone");
}
else {
*r_tooltip = TIP_("Copy to object");
}
break;
case DATA_STACK_DROP_LINK:
if (drop_data->pchan_parent) {
*r_tooltip = TIP_("Link all to bone");
}
else {
*r_tooltip = TIP_("Link all to object");
}
break;
}
if (changed) {
ED_region_tag_redraw_no_rebuild(region);
}
@ -902,6 +866,35 @@ static bool datastack_drop_poll(bContext *C,
return true;
}
static char *datastack_drop_tooltip(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event))
{
StackDropData *drop_data = drag->poin;
switch (drop_data->drop_action) {
case DATA_STACK_DROP_REORDER:
return BLI_strdup(TIP_("Reorder"));
break;
case DATA_STACK_DROP_COPY:
if (drop_data->pchan_parent) {
return BLI_strdup(TIP_("Copy to bone"));
}
else {
return BLI_strdup(TIP_("Copy to object"));
}
break;
case DATA_STACK_DROP_LINK:
if (drop_data->pchan_parent) {
return BLI_strdup(TIP_("Link all to bone"));
}
else {
return BLI_strdup(TIP_("Link all to object"));
}
break;
}
return NULL;
}
static void datastack_drop_link(bContext *C, StackDropData *drop_data)
{
Main *bmain = CTX_data_main(C);
@ -1155,10 +1148,7 @@ static bool collection_drop_init(bContext *C,
return true;
}
static bool collection_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **r_tooltip)
static bool collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
ARegion *region = CTX_wm_region(C);
@ -1172,45 +1162,20 @@ static bool collection_drop_poll(bContext *C,
if (!data.from || event->ctrl) {
tselem->flag |= TSE_DRAG_INTO;
changed = true;
*r_tooltip = TIP_("Link inside Collection");
}
else {
switch (data.insert_type) {
case TE_INSERT_BEFORE:
tselem->flag |= TSE_DRAG_BEFORE;
changed = true;
if (te->prev && outliner_is_collection_tree_element(te->prev)) {
*r_tooltip = TIP_("Move between collections");
}
else {
*r_tooltip = TIP_("Move before collection");
}
break;
case TE_INSERT_AFTER:
tselem->flag |= TSE_DRAG_AFTER;
changed = true;
if (te->next && outliner_is_collection_tree_element(te->next)) {
*r_tooltip = TIP_("Move between collections");
}
else {
*r_tooltip = TIP_("Move after collection");
}
break;
case TE_INSERT_INTO: {
tselem->flag |= TSE_DRAG_INTO;
changed = true;
/* Check the type of the drag IDs to avoid the incorrect "Shift to parent"
* for collections. Checking the type of the first ID works fine here since
* all drag IDs are the same type. */
wmDragID *drag_id = (wmDragID *)drag->ids.first;
const bool is_object = (GS(drag_id->id->name) == ID_OB);
if (is_object) {
*r_tooltip = TIP_("Move inside collection (Ctrl to link, Shift to parent)");
}
else {
*r_tooltip = TIP_("Move inside collection (Ctrl to link)");
}
break;
}
}
@ -1226,6 +1191,49 @@ static bool collection_drop_poll(bContext *C,
return false;
}
static char *collection_drop_tooltip(bContext *C, wmDrag *drag, const wmEvent *event)
{
CollectionDrop data;
if (!event->shift && collection_drop_init(C, drag, event, &data)) {
TreeElement *te = data.te;
if (!data.from || event->ctrl) {
return BLI_strdup(TIP_("Link inside Collection"));
}
switch (data.insert_type) {
case TE_INSERT_BEFORE:
if (te->prev && outliner_is_collection_tree_element(te->prev)) {
return BLI_strdup(TIP_("Move between collections"));
}
else {
return BLI_strdup(TIP_("Move before collection"));
}
break;
case TE_INSERT_AFTER:
if (te->next && outliner_is_collection_tree_element(te->next)) {
return BLI_strdup(TIP_("Move between collections"));
}
else {
return BLI_strdup(TIP_("Move after collection"));
}
break;
case TE_INSERT_INTO: {
/* Check the type of the drag IDs to avoid the incorrect "Shift to parent"
* for collections. Checking the type of the first ID works fine here since
* all drag IDs are the same type. */
wmDragID *drag_id = (wmDragID *)drag->ids.first;
const bool is_object = (GS(drag_id->id->name) == ID_OB);
if (is_object) {
return BLI_strdup(TIP_("Move inside collection (Ctrl to link, Shift to parent)"));
}
return BLI_strdup(TIP_("Move inside collection (Ctrl to link)"));
break;
}
}
}
return NULL;
}
static int collection_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
Main *bmain = CTX_data_main(C);
@ -1499,10 +1507,16 @@ void outliner_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW);
WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", parent_drop_poll, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", parent_clear_poll, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", scene_drop_poll, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_datastack_drop", datastack_drop_poll, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", collection_drop_poll, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", parent_drop_poll, NULL, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", parent_clear_poll, NULL, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", scene_drop_poll, NULL, NULL, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, NULL, NULL, NULL);
WM_dropbox_add(
lb, "OUTLINER_OT_datastack_drop", datastack_drop_poll, NULL, NULL, datastack_drop_tooltip);
WM_dropbox_add(lb,
"OUTLINER_OT_collection_drop",
collection_drop_poll,
NULL,
NULL,
collection_drop_tooltip);
}

View File

@ -364,10 +364,7 @@ static void sequencer_listener(const wmSpaceTypeListenerParams *params)
/* ************* dropboxes ************* */
static bool image_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool image_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@ -384,10 +381,7 @@ static bool image_drop_poll(bContext *C,
return 0;
}
static bool movie_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool movie_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@ -403,10 +397,7 @@ static bool movie_drop_poll(bContext *C,
return 0;
}
static bool sound_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool sound_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@ -448,9 +439,12 @@ static void sequencer_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Sequencer", SPACE_SEQ, RGN_TYPE_WINDOW);
WM_dropbox_add(lb, "SEQUENCER_OT_image_strip_add", image_drop_poll, sequencer_drop_copy, NULL);
WM_dropbox_add(lb, "SEQUENCER_OT_movie_strip_add", movie_drop_poll, sequencer_drop_copy, NULL);
WM_dropbox_add(lb, "SEQUENCER_OT_sound_strip_add", sound_drop_poll, sequencer_drop_copy, NULL);
WM_dropbox_add(
lb, "SEQUENCER_OT_image_strip_add", image_drop_poll, sequencer_drop_copy, NULL, NULL);
WM_dropbox_add(
lb, "SEQUENCER_OT_movie_strip_add", movie_drop_poll, sequencer_drop_copy, NULL, NULL);
WM_dropbox_add(
lb, "SEQUENCER_OT_sound_strip_add", sound_drop_poll, sequencer_drop_copy, NULL, NULL);
}
/* ************* end drop *********** */

View File

@ -312,10 +312,7 @@ static void text_cursor(wmWindow *win, ScrArea *area, ARegion *region)
/* ************* dropboxes ************* */
static bool text_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool text_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
@ -332,10 +329,7 @@ static void text_drop_copy(wmDrag *drag, wmDropBox *drop)
RNA_string_set(drop->ptr, "filepath", drag->path);
}
static bool text_drop_paste_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static bool text_drop_paste_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
return (drag->type == WM_DRAG_ID);
}
@ -356,8 +350,8 @@ static void text_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Text", SPACE_TEXT, RGN_TYPE_WINDOW);
WM_dropbox_add(lb, "TEXT_OT_open", text_drop_poll, text_drop_copy, NULL);
WM_dropbox_add(lb, "TEXT_OT_insert", text_drop_paste_poll, text_drop_paste, NULL);
WM_dropbox_add(lb, "TEXT_OT_open", text_drop_poll, text_drop_copy, NULL, NULL);
WM_dropbox_add(lb, "TEXT_OT_insert", text_drop_paste_poll, text_drop_paste, NULL, NULL);
}
/* ************* end drop *********** */

View File

@ -513,49 +513,38 @@ static bool view3d_drop_id_in_main_region_poll(bContext *C,
return WM_drag_is_ID_type(drag, id_type);
}
static bool view3d_ob_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool view3d_ob_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
return view3d_drop_id_in_main_region_poll(C, drag, event, ID_OB);
}
static bool view3d_collection_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool view3d_collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
return view3d_drop_id_in_main_region_poll(C, drag, event, ID_GR);
}
static bool view3d_mat_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static bool view3d_mat_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
return view3d_drop_id_in_main_region_poll(C, drag, event, ID_MA);
}
static bool view3d_object_data_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **r_tooltip)
static bool view3d_object_data_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ID_Type id_type = view3d_drop_id_in_main_region_poll_get_id_type(C, drag, event);
if (id_type) {
if (OB_DATA_SUPPORT_ID(id_type)) {
*r_tooltip = TIP_("Create object instance from object-data");
return true;
}
if (id_type && OB_DATA_SUPPORT_ID(id_type)) {
return true;
}
return false;
}
static bool view3d_ima_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
static char *view3d_object_data_drop_tooltip(bContext *UNUSED(C),
wmDrag *UNUSED(drag),
const wmEvent *UNUSED(event))
{
return BLI_strdup(TIP_("Create object instance from object-data"));
}
static bool view3d_ima_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
if (ED_region_overlap_isect_any_xy(CTX_wm_area(C), &event->x)) {
return false;
@ -580,12 +569,9 @@ static bool view3d_ima_bg_is_camera_view(bContext *C)
return false;
}
static bool view3d_ima_bg_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **r_tooltip)
static bool view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
if (!view3d_ima_drop_poll(C, drag, event, r_tooltip)) {
if (!view3d_ima_drop_poll(C, drag, event)) {
return false;
}
@ -596,12 +582,9 @@ static bool view3d_ima_bg_drop_poll(bContext *C,
return view3d_ima_bg_is_camera_view(C);
}
static bool view3d_ima_empty_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **r_tooltip)
static bool view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
if (!view3d_ima_drop_poll(C, drag, event, r_tooltip)) {
if (!view3d_ima_drop_poll(C, drag, event)) {
return false;
}
@ -620,8 +603,7 @@ static bool view3d_ima_empty_drop_poll(bContext *C,
static bool view3d_volume_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
const wmEvent *UNUSED(event))
{
return (drag->type == WM_DRAG_PATH) && (drag->icon == ICON_FILE_VOLUME);
}
@ -700,37 +682,44 @@ static void view3d_dropboxes(void)
"OBJECT_OT_add_named",
view3d_ob_drop_poll,
view3d_ob_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"OBJECT_OT_drop_named_material",
view3d_mat_drop_poll,
view3d_id_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"VIEW3D_OT_background_image_add",
view3d_ima_bg_drop_poll,
view3d_id_path_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"OBJECT_OT_drop_named_image",
view3d_ima_empty_drop_poll,
view3d_id_path_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"OBJECT_OT_volume_import",
view3d_volume_drop_poll,
view3d_id_path_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"OBJECT_OT_collection_instance_add",
view3d_collection_drop_poll,
view3d_collection_drop_copy,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
NULL);
WM_dropbox_add(lb,
"OBJECT_OT_data_instance_add",
view3d_object_data_drop_poll,
view3d_id_drop_copy_with_type,
WM_drag_free_imported_drag_ID);
WM_drag_free_imported_drag_ID,
view3d_object_data_drop_tooltip);
}
static void view3d_widgets(void)

View File

@ -34,6 +34,7 @@
#include "BLI_sys_types.h"
#include "DNA_windowmanager_types.h"
#include "WM_keymap.h"
#include "WM_types.h"
#ifdef __cplusplus
extern "C" {
@ -705,13 +706,13 @@ void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx, i
void WM_drag_free(struct wmDrag *drag);
void WM_drag_data_free(int dragtype, void *poin);
void WM_drag_free_list(struct ListBase *lb);
struct wmDropBox *WM_dropbox_add(
ListBase *lb,
const char *idname,
bool (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event, const char **),
bool (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event),
void (*copy)(struct wmDrag *, struct wmDropBox *),
void (*cancel)(struct Main *, struct wmDrag *, struct wmDropBox *));
void (*cancel)(struct Main *, struct wmDrag *, struct wmDropBox *),
WMDropboxTooltipFunc tooltip);
ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
/* ID drag and drop */

View File

@ -114,6 +114,7 @@ struct bContext;
struct wmEvent;
struct wmOperator;
struct wmWindowManager;
struct wmDrag;
#include "BLI_compiler_attrs.h"
#include "DNA_listBase.h"
@ -934,6 +935,10 @@ typedef struct wmDragAsset {
int import_type; /* eFileAssetImportType */
} wmDragAsset;
typedef char *(*WMDropboxTooltipFunc)(struct bContext *,
struct wmDrag *,
const struct wmEvent *event);
typedef struct wmDrag {
struct wmDrag *next, *prev;
@ -949,8 +954,8 @@ typedef struct wmDrag {
float scale;
int sx, sy;
/** If set, draws operator name. */
char opname[200];
/** If filled, draws operator tooltip/operator name. */
char tooltip[200];
unsigned int flags;
/** List of wmDragIDs, all are guaranteed to have the same ID type. */
@ -964,8 +969,8 @@ typedef struct wmDrag {
typedef struct wmDropBox {
struct wmDropBox *next, *prev;
/** Test if the dropbox is active, then can print optype name. */
bool (*poll)(struct bContext *, struct wmDrag *, const wmEvent *, const char **);
/** Test if the dropbox is active. */
bool (*poll)(struct bContext *, struct wmDrag *, const wmEvent *);
/** Before exec, this copies drag info to #wmDrop properties. */
void (*copy)(struct wmDrag *, struct wmDropBox *);
@ -976,6 +981,9 @@ typedef struct wmDropBox {
*/
void (*cancel)(struct Main *, struct wmDrag *, struct wmDropBox *);
/** Custom tooltip shown during dragging. */
WMDropboxTooltipFunc tooltip;
/**
* If poll succeeds, operator is called.
* Not saved in file, so can be pointer.

View File

@ -96,14 +96,16 @@ ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid)
wmDropBox *WM_dropbox_add(ListBase *lb,
const char *idname,
bool (*poll)(bContext *, wmDrag *, const wmEvent *, const char **),
bool (*poll)(bContext *, wmDrag *, const wmEvent *),
void (*copy)(wmDrag *, wmDropBox *),
void (*cancel)(struct Main *, wmDrag *, wmDropBox *))
void (*cancel)(struct Main *, wmDrag *, wmDropBox *),
WMDropboxTooltipFunc tooltip)
{
wmDropBox *drop = MEM_callocN(sizeof(wmDropBox), "wmDropBox");
drop->poll = poll;
drop->copy = copy;
drop->cancel = cancel;
drop->tooltip = tooltip;
drop->ot = WM_operatortype_find(idname, 0);
drop->opcontext = WM_OP_INVOKE_DEFAULT;
@ -218,22 +220,36 @@ void WM_drag_free_list(struct ListBase *lb)
}
}
static const char *dropbox_active(bContext *C,
ListBase *handlers,
wmDrag *drag,
const wmEvent *event)
static char *dropbox_tooltip(bContext *C,
wmDrag *drag,
const wmEvent *event,
const wmDropBox *drop)
{
char *tooltip = NULL;
if (drop->tooltip) {
tooltip = drop->tooltip(C, drag, event);
}
if (!tooltip) {
tooltip = BLI_strdup(WM_operatortype_name(drop->ot, drop->ptr));
}
/* XXX Doing translation here might not be ideal, but later we have no more
* access to ot (and hence op context)... */
return tooltip;
}
static wmDropBox *dropbox_active(bContext *C,
ListBase *handlers,
wmDrag *drag,
const wmEvent *event)
{
LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) {
if (handler_base->type == WM_HANDLER_TYPE_DROPBOX) {
wmEventHandler_Dropbox *handler = (wmEventHandler_Dropbox *)handler_base;
if (handler->dropboxes) {
LISTBASE_FOREACH (wmDropBox *, drop, handler->dropboxes) {
const char *tooltip = NULL;
if (drop->poll(C, drag, event, &tooltip) &&
if (drop->poll(C, drag, event) &&
WM_operator_poll_context(C, drop->ot, drop->opcontext)) {
/* XXX Doing translation here might not be ideal, but later we have no more
* access to ot (and hence op context)... */
return (tooltip) ? tooltip : WM_operatortype_name(drop->ot, drop->ptr);
return drop;
}
}
}
@ -242,29 +258,22 @@ static const char *dropbox_active(bContext *C,
return NULL;
}
/* return active operator name when mouse is in box */
static const char *wm_dropbox_active(bContext *C, wmDrag *drag, const wmEvent *event)
/* return active operator tooltip/name when mouse is in box */
static char *wm_dropbox_active(bContext *C, wmDrag *drag, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
const char *name;
name = dropbox_active(C, &win->handlers, drag, event);
if (name) {
return name;
wmDropBox *drop = dropbox_active(C, &win->handlers, drag, event);
if (!drop) {
ScrArea *area = CTX_wm_area(C);
drop = dropbox_active(C, &area->handlers, drag, event);
}
name = dropbox_active(C, &area->handlers, drag, event);
if (name) {
return name;
if (!drop) {
ARegion *region = CTX_wm_region(C);
drop = dropbox_active(C, &region->handlers, drag, event);
}
name = dropbox_active(C, &region->handlers, drag, event);
if (name) {
return name;
if (drop) {
return dropbox_tooltip(C, drag, event, drop);
}
return NULL;
}
@ -279,17 +288,18 @@ static void wm_drop_operator_options(bContext *C, wmDrag *drag, const wmEvent *e
return;
}
drag->opname[0] = 0;
drag->tooltip[0] = 0;
/* check buttons (XXX todo rna and value) */
if (UI_but_active_drop_name(C)) {
BLI_strncpy(drag->opname, IFACE_("Paste name"), sizeof(drag->opname));
BLI_strncpy(drag->tooltip, IFACE_("Paste name"), sizeof(drag->tooltip));
}
else {
const char *opname = wm_dropbox_active(C, drag, event);
char *tooltip = wm_dropbox_active(C, drag, event);
if (opname) {
BLI_strncpy(drag->opname, opname, sizeof(drag->opname));
if (tooltip) {
BLI_strncpy(drag->tooltip, tooltip, sizeof(drag->tooltip));
MEM_freeN(tooltip);
// WM_cursor_modal_set(win, WM_CURSOR_COPY);
}
// else
@ -584,7 +594,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
}
/* operator name with roundbox */
if (drag->opname[0]) {
if (drag->tooltip[0]) {
if (drag->imb) {
x = cursorx - drag->sx / 2;
@ -611,7 +621,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
drag_rect_minmax(rect, x, y, x + w, y + iconsize);
}
else {
wm_drop_operator_draw(drag->opname, x, y);
wm_drop_operator_draw(drag->tooltip, x, y);
}
}
}

View File

@ -2851,8 +2851,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
if (event->custom == EVT_DATA_DRAGDROP) {
ListBase *lb = (ListBase *)event->customdata;
LISTBASE_FOREACH (wmDrag *, drag, lb) {
const char *tooltip = NULL;
if (drop->poll(C, drag, event, &tooltip)) {
if (drop->poll(C, drag, event)) {
/* Optionally copy drag information to operator properties. Don't call it if the
* operator fails anyway, it might do more than just set properties (e.g.
* typically import an asset). */