1
1

Compare commits

...

7 Commits

Author SHA1 Message Date
920a58d9b6 Merge branch 'master' into wm-drag-drop-rewrite 2020-06-05 13:09:31 +02:00
c94b620986 Merge branch 'master' into wm-drag-drop-rewrite 2020-03-26 21:18:45 +01:00
Julian Eisel
357ed79cb9 Merge branch 'master' into wm-drag-drop-rewrite 2020-01-29 15:30:41 +01:00
Julian Eisel
0cd92a1e77 Merge branch 'master' into wm-drag-drop-rewrite 2020-01-24 11:35:02 +01:00
Julian Eisel
8291b6736f Apply clang-format to changed files 2019-11-19 15:04:10 +01:00
Julian Eisel
2d191a34a3 Merge branch 'master' into wm-drag-drop-rewrite 2019-11-19 14:24:19 +01:00
Julian Eisel
1e65db3c76 Painfully update patch to latest master 2019-11-18 21:40:11 +01:00
35 changed files with 1177 additions and 1397 deletions

View File

@@ -777,8 +777,8 @@ def km_outliner(params):
# Fall through to generic context menu if the item(s) selected have no type specific actions.
("outliner.operation", {"type": 'RIGHTMOUSE', "value": 'PRESS'}, None),
op_menu("OUTLINER_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}),
("outliner.item_drag_drop", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, None),
("outliner.item_drag_drop", {"type": 'EVT_TWEAK_L', "value": 'ANY', "shift": True}, None),
("outliner.drag_init", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, None),
("outliner.drag_init", {"type": 'EVT_TWEAK_L', "value": 'ANY', "shift": True}, None),
("outliner.show_hierarchy", {"type": 'HOME', "value": 'PRESS'}, None),
("outliner.show_active", {"type": 'PERIOD', "value": 'PRESS'}, None),
("outliner.show_active", {"type": 'NUMPAD_PERIOD', "value": 'PRESS'}, None),

View File

@@ -22,6 +22,7 @@ import bpy
from bpy.types import (
Menu,
Operator,
OperatorFileListElement,
)
from bpy.props import (
BoolProperty,
@@ -2619,6 +2620,32 @@ class WM_OT_drop_blend_file(Operator):
col.operator("wm.append", text="Append...", icon='APPEND_BLEND').filepath = self.filepath
class WM_OT_drop_files(Operator):
bl_idname = "wm.drop_files"
bl_label = "Handle dropped files"
bl_options = {'INTERNAL'}
filepaths: CollectionProperty(type=OperatorFileListElement)
def invoke(self, context, event):
paths = [element.name for element in self.filepaths]
if len(paths) == 1:
if self.handle_single_file(paths[0]):
return {'FINISHED'}
self.handle_multiple_files(paths)
return {'FINISHED'}
def handle_single_file(self, path):
if path.lower().endswith(".blend"):
bpy.ops.wm.drop_blend_file('INVOKE_DEFAULT', filepath=path)
return True
return False
def handle_multiple_files(self, paths):
pass
classes = (
WM_OT_context_collection_boolean_set,
WM_OT_context_cycle_array,
@@ -2662,4 +2689,5 @@ classes = (
WM_OT_batch_rename,
WM_MT_splash,
WM_MT_splash_about,
WM_OT_drop_files,
)

View File

@@ -57,6 +57,10 @@ struct wmMsgBus;
struct wmNotifier;
struct wmWindow;
struct wmWindowManager;
struct wmDragData;
struct wmDropTarget;
struct wmDropTargetFinder;
struct wmEvent;
/* spacetype has everything stored to get an editor working, it gets initialized via
* ED_spacetypes_init() in editors/space_api/spacetypes.c */
@@ -100,8 +104,6 @@ typedef struct SpaceType {
void (*operatortypes)(void);
/* add default items to WM keymap */
void (*keymap)(struct wmKeyConfig *keyconf);
/* on startup, define dropboxes for spacetype+regions */
void (*dropboxes)(void);
/* initialize gizmo-map-types and gizmo-group-types with the region */
void (*gizmos)(void);
@@ -119,6 +121,12 @@ typedef struct SpaceType {
void (*space_subtype_set)(struct ScrArea *area, int value);
void (*space_subtype_item_extend)(struct bContext *C, EnumPropertyItem **item, int *totitem);
/* get drop target for data */
void (*drop_target_find)(struct bContext *C,
struct wmDropTargetFinder *finder,
struct wmDragData *drag_data,
const struct wmEvent *event);
/* region type definitions */
ListBase regiontypes;

View File

@@ -7942,7 +7942,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
wm->xr.runtime = NULL;
BLI_listbase_clear(&wm->jobs);
BLI_listbase_clear(&wm->drags);
memset(&wm->drag, 0, sizeof(wmDragOperation));
wm->windrawable = NULL;
wm->winactive = NULL;

View File

@@ -62,8 +62,6 @@ struct uiFontStyle;
struct uiList;
struct uiStyle;
struct uiWidgetColors;
struct wmDrag;
struct wmDropBox;
struct wmEvent;
struct wmEvent;
struct wmGizmo;
@@ -74,6 +72,9 @@ struct wmMsgBus;
struct wmOperator;
struct wmOperatorType;
struct wmWindow;
struct wmDragData;
struct wmDropTarget;
struct wmDropTargetFinder;
typedef struct uiBlock uiBlock;
typedef struct uiBut uiBut;
@@ -730,9 +731,6 @@ void UI_but_drag_set_value(uiBut *but);
void UI_but_drag_set_image(
uiBut *but, const char *path, int icon, struct ImBuf *ima, float scale, const bool use_free);
bool UI_but_active_drop_name(struct bContext *C);
bool UI_but_active_drop_color(struct bContext *C);
void UI_but_flag_enable(uiBut *but, int flag);
void UI_but_flag_disable(uiBut *but, int flag);
bool UI_but_flag_is_set(uiBut *but, int flag);
@@ -2417,11 +2415,18 @@ typedef struct uiDragColorHandle {
void ED_operatortypes_ui(void);
void ED_keymap_ui(struct wmKeyConfig *keyconf);
#if 0
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);
const char **tooltip);
#endif
void UI_drop_target_find(struct bContext *C,
struct wmDropTargetFinder *finder,
struct wmDragData *drag_data,
const struct wmEvent *event);
bool UI_context_copy_to_selected_list(struct bContext *C,
struct PointerRNA *ptr,

View File

@@ -1924,44 +1924,56 @@ static bool ui_but_drag_init(bContext *C,
else
#endif
if (but->type == UI_BTYPE_COLOR) {
bool valid = false;
uiDragColorHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__);
/* TODO support more button pointer types */
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
ui_but_v3_get(but, drag_info->color);
drag_info->gamma_corrected = true;
valid = true;
float color[3];
ui_but_v3_get(but, color);
WM_drag_start_color(C, color, true);
}
else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
ui_but_v3_get(but, drag_info->color);
drag_info->gamma_corrected = false;
valid = true;
float color[3];
ui_but_v3_get(but, color);
WM_drag_start_color(C, color, false);
}
else if (ELEM(but->pointype, UI_BUT_POIN_FLOAT, UI_BUT_POIN_CHAR)) {
ui_but_v3_get(but, drag_info->color);
copy_v3_v3(drag_info->color, (float *)but->poin);
valid = true;
}
if (valid) {
WM_event_start_drag(C, ICON_COLOR, WM_DRAG_COLOR, drag_info, 0.0, WM_DRAG_FREE_DATA);
float color[3];
copy_v3_v3(color, (float *)but->poin);
WM_drag_start_color(C, color, false);
}
else {
MEM_freeN(drag_info);
return false;
/* maybe more types are needed? */
BLI_assert(false);
}
WM_drag_display_set_color_derived(WM_drag_get_active(C));
}
else {
wmDrag *drag = WM_event_start_drag(
C, but->icon, but->dragtype, but->dragpoin, ui_but_value_get(but), WM_DRAG_NOP);
switch (but->dragtype) {
case WM_DRAG_ID:
WM_drag_start_id(C, but->dragpoin);
break;
case WM_DRAG_PATH:
WM_drag_start_filepath(C, but->dragpoin);
break;
case WM_DRAG_VALUE:
WM_drag_start_value(C, ui_but_value_get(but));
break;
case WM_DRAG_RNA:
WM_drag_start_rna(C, but->dragpoin);
break;
case WM_DRAG_NAME:
WM_drag_start_name(C, but->dragpoin);
break;
default:
/* maybe more types are needed? */
BLI_assert(false);
break;
}
if (but->imb) {
WM_event_drag_image(drag,
but->imb,
but->imb_scale,
BLI_rctf_size_x(&but->rect),
BLI_rctf_size_y(&but->rect));
WM_drag_display_set_image(WM_drag_get_active(C),
but->imb,
but->imb_scale,
BLI_rctf_size_x(&but->rect),
BLI_rctf_size_y(&but->rect));
}
}
return true;
@@ -2191,39 +2203,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)
{
wmDrag *wmd;
ListBase *drags = event->customdata; /* drop event type has listbase customdata by default */
for (wmd = drags->first; wmd; wmd = wmd->next) {
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_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
* \{ */
@@ -2439,19 +2418,24 @@ static void ui_but_copy_text(uiBut *but, char *output, int output_len_max)
ui_but_string_get(but, output, output_len_max);
}
static void ui_but_paste_text(bContext *C, uiBut *but, uiHandleButtonData *data, char *buf_paste)
void ui_but_set_text(bContext *C, uiBut *but, char *text)
{
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
ui_textedit_string_set(but, but->active, buf_paste);
ui_textedit_string_set(but, but->active, text);
if (but->type == UI_BTYPE_SEARCH_MENU) {
but->changed = true;
ui_searchbox_update(C, data->searchbox, but, true);
ui_searchbox_update(C, but->active->searchbox, but, true);
}
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
static void ui_but_paste_text(bContext *C, uiBut *but, char *buf_paste)
{
ui_but_set_text(C, but, buf_paste);
}
static void ui_but_copy_colorband(uiBut *but)
{
if (but->poin != NULL) {
@@ -2688,7 +2672,7 @@ static void ui_but_paste(bContext *C, uiBut *but, uiHandleButtonData *data, cons
if (!has_required_data) {
break;
}
ui_but_paste_text(C, but, data, buf_paste);
ui_but_paste_text(C, but, buf_paste);
break;
case UI_BTYPE_COLORBAND:
@@ -7474,11 +7458,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) &&
@@ -7764,7 +7743,7 @@ static void button_tooltip_timer_reset(bContext *C, uiBut *but)
if ((U.flag & USER_TOOLTIPS) || (data->tooltip_force)) {
if (!but->block->tooltipdisabled) {
if (!wm->drags.first) {
if (!wm->drag.data) {
bool is_label = UI_but_has_tooltip_label(but);
double delay = is_label ? UI_TOOLTIP_DELAY_LABEL : UI_TOOLTIP_DELAY;
WM_tooltip_timer_init_ex(
@@ -11022,35 +11001,4 @@ 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)
{
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 1;
}
}
return 0;
}
bool UI_but_active_drop_color(bContext *C)
{
ARegion *region = CTX_wm_region(C);
if (region) {
uiBut *but = ui_region_find_active_but(region);
if (but && but->type == UI_BTYPE_COLOR) {
return true;
}
}
return false;
}
/** \} */

View File

@@ -813,6 +813,7 @@ extern void ui_but_text_password_hide(char password_str[UI_MAX_DRAW_STR],
extern uiBut *ui_but_find_select_in_enum(uiBut *but, int direction);
bool ui_but_is_editing(const uiBut *but);
float ui_block_calc_pie_segment(struct uiBlock *block, const float event_xy[2]);
void ui_but_set_text(struct bContext *C, uiBut *but, char *text);
void ui_but_add_shortcut(uiBut *but, const char *key_str, const bool do_strip);
void ui_but_clipboard_free(void);

View File

@@ -1705,47 +1705,15 @@ 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))
{
/* should only return true for regions that include buttons, for now
* return true always */
if (drag->type == WM_DRAG_COLOR) {
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *region = CTX_wm_region(C);
if (UI_but_active_drop_color(C)) {
return 1;
}
if (sima && (sima->mode == SI_MODE_PAINT) && sima->image &&
(region && region->regiontype == RGN_TYPE_WINDOW)) {
return 1;
}
}
return 0;
}
void UI_drop_color_copy(wmDrag *drag, wmDropBox *drop)
{
uiDragColorHandle *drag_info = drag->poin;
RNA_float_set_array(drop->ptr, "color", drag_info->color);
RNA_boolean_set(drop->ptr, "gamma", drag_info->gamma_corrected);
}
static int drop_color_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
uiBut *but = NULL;
float color[4];
bool gamma;
bool gamma_corrected;
RNA_float_get_array(op->ptr, "color", color);
gamma = RNA_boolean_get(op->ptr, "gamma");
gamma_corrected = RNA_boolean_get(op->ptr, "gamma_corrected");
/* find button under mouse, check if it has RNA color property and
* if it does copy the data */
@@ -1761,14 +1729,14 @@ static int drop_color_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
if (!gamma) {
if (!gamma_corrected) {
IMB_colormanagement_scene_linear_to_srgb_v3(color);
}
RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color);
RNA_property_update(C, &but->rnapoin, but->rnaprop);
}
else if (RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
if (gamma) {
if (gamma_corrected) {
IMB_colormanagement_srgb_to_scene_linear_v3(color);
}
RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color);
@@ -1776,7 +1744,7 @@ static int drop_color_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
}
else {
if (gamma) {
if (gamma_corrected) {
srgb_to_linearrgb_v3_v3(color, color);
}
@@ -1798,11 +1766,79 @@ static void UI_OT_drop_color(wmOperatorType *ot)
ot->flag = OPTYPE_INTERNAL;
RNA_def_float_color(ot->srna, "color", 3, NULL, 0.0, FLT_MAX, "Color", "Source color", 0.0, 1.0);
RNA_def_boolean(ot->srna, "gamma", 0, "Gamma Corrected", "The source color is gamma corrected ");
RNA_def_boolean(
ot->srna, "gamma_corrected", 0, "Gamma Corrected", "The source color is gamma corrected ");
}
/** \} */
static int drop_text_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
ARegion *ar = CTX_wm_region(C);
uiBut *but = ui_region_find_active_but(ar);
if (!but)
return OPERATOR_CANCELLED;
if (!ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU))
return OPERATOR_CANCELLED;
char *text = RNA_string_get_alloc(op->ptr, "text", NULL, 0);
ui_but_set_text(C, but, text);
MEM_freeN(text);
ED_region_tag_redraw(ar);
return OPERATOR_FINISHED;
}
static void UI_OT_drop_text(wmOperatorType *ot)
{
ot->name = "Drop Text";
ot->idname = "UI_OT_drop_text";
ot->description = "Drop text to buttons";
ot->invoke = drop_text_invoke;
ot->flag = OPTYPE_INTERNAL;
RNA_def_string(ot->srna, "text", NULL, 0, "Text", "Text to drop");
}
static void drop_color_set_properties(wmDragData *drag_data, PointerRNA *ptr)
{
float color[3];
bool gamma_corrected;
WM_drag_query_single_color(drag_data, color, &gamma_corrected);
RNA_float_set_array(ptr, "color", color);
RNA_boolean_set(ptr, "gamma_corrected", gamma_corrected);
}
static void drop_text_set_properies(wmDragData *drag_data, PointerRNA *ptr)
{
ID *id = WM_drag_query_single_id(drag_data);
RNA_string_set(ptr, "text", id->name + 2);
}
void UI_drop_target_find(bContext *C,
wmDropTargetFinder *finder,
wmDragData *drag_data,
const wmEvent *UNUSED(event))
{
ARegion *ar = CTX_wm_region(C);
if (!ar)
return;
uiBut *but = ui_region_find_active_but(ar);
if (!but)
return;
if (but->type == UI_BTYPE_COLOR && WM_drag_query_single_color(drag_data, NULL, NULL)) {
WM_drop_target_propose__template_1(
finder, DROP_TARGET_SIZE_BUT, "UI_OT_drop_color", "Drop Color", drop_color_set_properties);
}
if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU) && WM_drag_query_single_id(drag_data)) {
WM_drop_target_propose__template_1(
finder, DROP_TARGET_SIZE_BUT, "UI_OT_drop_text", "Drop Text", drop_text_set_properies);
}
}
/* -------------------------------------------------------------------- */
/** \name Operator & Keymap Registration
* \{ */
@@ -1820,6 +1856,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_text);
#ifdef WITH_PYTHON
WM_operatortype_append(UI_OT_editsource);
WM_operatortype_append(UI_OT_edittranslation_init);

View File

@@ -1805,6 +1805,8 @@ static void ed_default_handlers(
wm->defaultconf, "Grease Pencil Stroke Weight (Draw)", 0, 0);
WM_event_add_keymap_handler(handlers, keymap_weight_draw);
}
WM_event_ensure_drop_handler(handlers);
}
void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *area)

View File

@@ -5558,29 +5558,9 @@ 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))
{
if (drag->type == WM_DRAG_PATH) {
if (drag->icon == ICON_FILE_BLEND) {
return 1;
}
}
return 0;
}
static void blend_file_drop_copy(wmDrag *drag, wmDropBox *drop)
{
/* copy drag path to properties */
RNA_string_set(drop->ptr, "filepath", drag->path);
}
/* called in spacetypes.c */
void ED_keymap_screen(wmKeyConfig *keyconf)
{
ListBase *lb;
/* Screen Editing ------------------------------------------------ */
WM_keymap_ensure(keyconf, "Screen Editing", 0, 0);
@@ -5595,11 +5575,6 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
/* Anim Playback ------------------------------------------------ */
WM_keymap_ensure(keyconf, "Frames", 0, 0);
/* dropbox for entire window */
lb = WM_dropboxmap_find("Window", 0, 0);
WM_dropbox_add(lb, "WM_OT_drop_blend_file", blend_file_drop_poll, blend_file_drop_copy);
WM_dropbox_add(lb, "UI_OT_drop_color", UI_drop_color_poll, UI_drop_color_copy);
keymap_modal_set(keyconf);
}

View File

@@ -152,9 +152,6 @@ void ED_spacetypes_init(void)
void ED_spacemacros_init(void)
{
const ListBase *spacetypes;
SpaceType *type;
/* Macros's must go last since they reference other operators.
* We need to have them go after python operators too */
ED_operatormacros_armature();
@@ -171,14 +168,6 @@ void ED_spacemacros_init(void)
ED_operatormacros_sequencer();
ED_operatormacros_paint();
ED_operatormacros_gpencil();
/* register dropboxes (can use macros) */
spacetypes = BKE_spacetypes_list();
for (type = spacetypes->first; type; type = type->next) {
if (type->dropboxes) {
type->dropboxes();
}
}
}
/* called in wm.c */

View File

@@ -314,15 +314,6 @@ static void clip_free(SpaceLink *sl)
}
}
/* spacetype; init callback */
static void clip_init(struct wmWindowManager *UNUSED(wm), ScrArea *area)
{
ListBase *lb = WM_dropboxmap_find("Clip", SPACE_CLIP, 0);
/* add drop boxes */
WM_event_add_dropbox_handler(&area->handlers, lb);
}
static SpaceLink *clip_duplicate(SpaceLink *sl)
{
SpaceClip *scn = MEM_dupallocN(sl);
@@ -601,44 +592,6 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul
return false;
}
/* dropboxes */
static bool clip_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
{
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE, ICON_FILE_BLANK)) {
return true;
}
}
return false;
}
static void clip_drop_copy(wmDrag *drag, wmDropBox *drop)
{
PointerRNA itemptr;
char dir[FILE_MAX], file[FILE_MAX];
BLI_split_dirfile(drag->path, dir, file, sizeof(dir), sizeof(file));
RNA_string_set(drop->ptr, "directory", dir);
RNA_collection_clear(drop->ptr, "files");
RNA_collection_add(drop->ptr, "files", &itemptr);
RNA_string_set(&itemptr, "name", file);
}
/* area+region dropbox definition */
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);
}
static void clip_refresh(const bContext *C, ScrArea *area)
{
wmWindowManager *wm = CTX_wm_manager(C);
@@ -1349,6 +1302,32 @@ static void clip_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, I
}
}
static void drop_init__open_file(wmDragData *drag_data, PointerRNA *ptr)
{
const char *path = WM_drag_query_single_path_image_or_movie(drag_data);
char dir[FILE_MAX], file[FILE_MAX];
BLI_split_dirfile(path, dir, file, sizeof(dir), sizeof(file));
RNA_string_set(ptr, "directory", dir);
RNA_collection_clear(ptr, "files");
PointerRNA itemptr;
RNA_collection_add(ptr, "files", &itemptr);
RNA_string_set(&itemptr, "name", file);
}
static void clip_drop_target_find(bContext *UNUSED(C),
wmDropTargetFinder *finder,
wmDragData *drag_data,
const wmEvent *UNUSED(event))
{
if (WM_drag_query_single_path_image_or_movie(drag_data)) {
WM_drop_target_propose__template_1(
finder, DROP_TARGET_SIZE_AREA, "CLIP_OT_open", "Open File", drop_init__open_file);
}
}
/* only called once, from space/spacetypes.c */
void ED_spacetype_clip(void)
{
@@ -1360,16 +1339,16 @@ void ED_spacetype_clip(void)
st->new = clip_new;
st->free = clip_free;
st->init = clip_init;
st->init = NULL;
st->duplicate = clip_duplicate;
st->operatortypes = clip_operatortypes;
st->keymap = clip_keymap;
st->listener = clip_listener;
st->context = clip_context;
st->gizmos = clip_gizmos;
st->dropboxes = clip_dropboxes;
st->refresh = clip_refresh;
st->id_remap = clip_id_remap;
st->drop_target_find = clip_drop_target_find;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype clip region");

View File

@@ -119,7 +119,6 @@ static SpaceLink *console_duplicate(SpaceLink *sl)
static void console_main_region_init(wmWindowManager *wm, ARegion *region)
{
wmKeyMap *keymap;
ListBase *lb;
const float prev_y_min = region->v2d.cur.ymin; /* so re-sizing keeps the cursor visible */
@@ -138,11 +137,6 @@ static void console_main_region_init(wmWindowManager *wm, ARegion *region)
/* own keymap */
keymap = WM_keymap_ensure(wm->defaultconf, "Console", SPACE_CONSOLE, 0);
WM_event_add_keymap_handler_v2d_mask(&region->handlers, keymap);
/* add drop boxes */
lb = WM_dropboxmap_find("Console", SPACE_CONSOLE, RGN_TYPE_WINDOW);
WM_event_add_dropbox_handler(&region->handlers, lb);
}
/* same as 'text_cursor' */
@@ -157,50 +151,6 @@ static void console_cursor(wmWindow *win, ScrArea *UNUSED(area), ARegion *region
WM_cursor_set(win, wmcursor);
}
/* ************* dropboxes ************* */
static bool id_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(tooltip))
{
return WM_drag_ID(drag, 0) != NULL;
}
static void id_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_ID(drag, 0);
/* copy drag path to properties */
char *text = RNA_path_full_ID_py(G_MAIN, id);
RNA_string_set(drop->ptr, "text", text);
MEM_freeN(text);
}
static bool path_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(tooltip))
{
return (drag->type == WM_DRAG_PATH);
}
static void path_drop_copy(wmDrag *drag, wmDropBox *drop)
{
char pathname[FILE_MAX + 2];
BLI_snprintf(pathname, sizeof(pathname), "\"%s\"", drag->path);
RNA_string_set(drop->ptr, "text", pathname);
}
/* this region dropbox definition */
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);
WM_dropbox_add(lb, "CONSOLE_OT_insert", path_drop_poll, path_drop_copy);
}
/* ************* end drop *********** */
static void console_main_region_draw(const bContext *C, ARegion *region)
@@ -306,6 +256,36 @@ static void console_main_region_listener(wmWindow *UNUSED(win),
}
}
static void drop_init__insert_id_path(wmDragData *drag_data, PointerRNA *ptr)
{
ID *id = WM_drag_query_single_id(drag_data);
char *text = RNA_path_full_ID_py(G_MAIN, id); /* TODO G_MAIN */
RNA_string_set(ptr, "text", text);
MEM_freeN(text);
}
static void drop_init__insert_file_path(wmDragData *drag_data, PointerRNA *ptr)
{
char pathname[FILE_MAX + 2];
BLI_snprintf(pathname, sizeof(pathname), "\"%s\"", WM_drag_query_single_path(drag_data));
RNA_string_set(ptr, "text", pathname);
}
static void console_drop_target_find(bContext *UNUSED(C),
wmDropTargetFinder *finder,
wmDragData *drag_data,
const wmEvent *UNUSED(event))
{
if (WM_drag_query_single_id(drag_data)) {
WM_drop_target_propose__template_1(
finder, DROP_TARGET_SIZE_AREA, "CONSOLE_OT_insert", "Insert", drop_init__insert_id_path);
}
if (WM_drag_query_single_path(drag_data)) {
WM_drop_target_propose__template_1(
finder, DROP_TARGET_SIZE_AREA, "CONSOLE_OT_insert", "Insert", drop_init__insert_file_path);
}
}
/* only called once, from space/spacetypes.c */
void ED_spacetype_console(void)
{
@@ -321,7 +301,7 @@ void ED_spacetype_console(void)
st->duplicate = console_duplicate;
st->operatortypes = console_operatortypes;
st->keymap = console_keymap;
st->dropboxes = console_dropboxes;
st->drop_target_find = console_drop_target_find;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype console region");

View File

@@ -660,31 +660,18 @@ static void file_ui_region_listener(wmWindow *UNUSED(win),
}
}
static bool filepath_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
static void file_drop_target_find(bContext *UNUSED(C),
wmDropTargetFinder *finder,
wmDragData *drag_data,
const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH) {
SpaceFile *sfile = CTX_wm_space_file(C);
if (sfile) {
return 1;
}
if (WM_drag_query_single_path(drag_data)) {
WM_drop_target_propose__template_1(finder,
DROP_TARGET_SIZE_AREA,
"FILE_OT_filepath_drop",
"Open",
WM_drop_init_single_filepath);
}
return 0;
}
static void filepath_drop_copy(wmDrag *drag, wmDropBox *drop)
{
RNA_string_set(drop->ptr, "filepath", drag->path);
}
/* region dropbox definition */
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);
}
/* only called once, from space/spacetypes.c */
@@ -705,7 +692,7 @@ void ED_spacetype_file(void)
st->listener = file_listener;
st->operatortypes = file_operatortypes;
st->keymap = file_keymap;
st->dropboxes = file_dropboxes;
st->drop_target_find = file_drop_target_find;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype file region");

View File

@@ -186,15 +186,6 @@ static void image_free(SpaceLink *sl)
BKE_scopes_free(&simage->scopes);
}
/* spacetype; init callback, add handlers */
static void image_init(struct wmWindowManager *UNUSED(wm), ScrArea *area)
{
ListBase *lb = WM_dropboxmap_find("Image", SPACE_IMAGE, 0);
/* add drop boxes */
WM_event_add_dropbox_handler(&area->handlers, lb);
}
static SpaceLink *image_duplicate(SpaceLink *sl)
{
SpaceImage *simagen = MEM_dupallocN(sl);
@@ -262,39 +253,6 @@ static void image_keymap(struct wmKeyConfig *keyconf)
WM_keymap_ensure(keyconf, "Image", SPACE_IMAGE, 0);
}
/* dropboxes */
static bool image_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
{
ScrArea *area = CTX_wm_area(C);
if (ED_region_overlap_isect_any_xy(area, &event->x)) {
return false;
}
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE, ICON_FILE_BLANK)) {
return true;
}
}
return false;
}
static void image_drop_copy(wmDrag *drag, wmDropBox *drop)
{
/* copy drag path to properties */
RNA_string_set(drop->ptr, "filepath", drag->path);
}
/* area+region dropbox definition */
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);
}
/**
* \note take care not to get into feedback loop here,
* calling composite job causes viewer to refresh.
@@ -1082,6 +1040,20 @@ static void image_space_subtype_item_extend(bContext *UNUSED(C),
RNA_enum_items_add(item, totitem, rna_enum_space_image_mode_items);
}
static void image_drop_target_find(bContext *UNUSED(C),
wmDropTargetFinder *finder,
wmDragData *drag_data,
const wmEvent *UNUSED(event))
{
if (WM_drag_query_single_path_image(drag_data)) {
WM_drop_target_propose__template_1(finder,
DROP_TARGET_SIZE_AREA,
"IMAGE_OT_open",
"Open Image",
WM_drop_init_single_filepath);
}
}
/**************************** spacetype *****************************/
/* only called once, from space/spacetypes.c */
@@ -1095,11 +1067,10 @@ void ED_spacetype_image(void)
st->new = image_new;
st->free = image_free;
st->init = image_init;
st->init = NULL;
st->duplicate = image_duplicate;
st->operatortypes = image_operatortypes;
st->keymap = image_keymap;
st->dropboxes = image_dropboxes;
st->refresh = image_refresh;
st->listener = image_listener;
st->context = image_context;
@@ -1108,6 +1079,7 @@ void ED_spacetype_image(void)
st->space_subtype_item_extend = image_space_subtype_item_extend;
st->space_subtype_get = image_space_subtype_get;
st->space_subtype_set = image_space_subtype_set;
st->drop_target_find = image_drop_target_find;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype image region");

View File

@@ -608,7 +608,6 @@ static void node_cursor(wmWindow *win, ScrArea *area, ARegion *region)
static void node_main_region_init(wmWindowManager *wm, ARegion *region)
{
wmKeyMap *keymap;
ListBase *lb;
UI_view2d_region_reinit(&region->v2d, V2D_COMMONVIEW_CUSTOM, region->winx, region->winy);
@@ -618,11 +617,6 @@ static void node_main_region_init(wmWindowManager *wm, ARegion *region)
keymap = WM_keymap_ensure(wm->defaultconf, "Node Editor", SPACE_NODE, 0);
WM_event_add_keymap_handler_v2d_mask(&region->handlers, keymap);
/* add drop boxes */
lb = WM_dropboxmap_find("Node Editor", SPACE_NODE, RGN_TYPE_WINDOW);
WM_event_add_dropbox_handler(&region->handlers, lb);
}
static void node_main_region_draw(const bContext *C, ARegion *region)
@@ -630,60 +624,6 @@ static void node_main_region_draw(const bContext *C, ARegion *region)
drawnodespace(C, region);
}
/* ************* dropboxes ************* */
static bool node_ima_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
{
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE));
}
else {
return WM_drag_ID(drag, ID_IM) != NULL;
}
}
static bool node_mask_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
{
return WM_drag_ID(drag, ID_MSK) != NULL;
}
static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_ID(drag, 0);
RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_ID(drag, 0);
if (id) {
RNA_string_set(drop->ptr, "name", id->name + 2);
RNA_struct_property_unset(drop->ptr, "filepath");
}
else if (drag->path[0]) {
RNA_string_set(drop->ptr, "filepath", drag->path);
RNA_struct_property_unset(drop->ptr, "name");
}
}
/* this region dropbox definition */
static void node_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Node Editor", SPACE_NODE, RGN_TYPE_WINDOW);
WM_dropbox_add(lb, "NODE_OT_add_file", node_ima_drop_poll, node_id_path_drop_copy);
WM_dropbox_add(lb, "NODE_OT_add_mask", node_mask_drop_poll, node_id_drop_copy);
}
/* ************* end drop *********** */
/* add handlers, stuff you only do once or on area/region changes */
@@ -948,6 +888,37 @@ static void node_space_subtype_item_extend(bContext *C, EnumPropertyItem **item,
}
}
static void file_drop_init__file_path(wmDragData *drag_data, PointerRNA *ptr)
{
RNA_string_set(ptr, "filepath", WM_drag_query_single_path_image_or_movie(drag_data));
RNA_struct_property_unset(ptr, "name");
}
static void file_drop_init__id_name(wmDragData *drag_data, PointerRNA *ptr)
{
RNA_string_set(ptr, "name", WM_drag_query_single_id_of_type(drag_data, ID_IM)->name + 2);
RNA_struct_property_unset(ptr, "filepath");
}
static void node_drop_target_find(bContext *UNUSED(C),
wmDropTargetFinder *finder,
wmDragData *drag_data,
const wmEvent *UNUSED(event))
{
if (WM_drag_query_single_path_image_or_movie(drag_data)) {
WM_drop_target_propose__template_1(
finder, DROP_TARGET_SIZE_AREA, "NODE_OT_add_file", "Load", file_drop_init__file_path);
}
if (WM_drag_query_single_id_of_type(drag_data, ID_IM)) {
WM_drop_target_propose__template_1(
finder, DROP_TARGET_SIZE_AREA, "NODE_OT_add_file", "Insert", file_drop_init__id_name);
}
if (WM_drag_query_single_id_of_type(drag_data, ID_MSK)) {
WM_drop_target_propose__template_1(
finder, DROP_TARGET_SIZE_AREA, "NODE_OT_add_mask", "Insert", WM_drop_init_single_id_name);
}
}
/* only called once, from space/spacetypes.c */
void ED_spacetype_node(void)
{
@@ -966,12 +937,12 @@ void ED_spacetype_node(void)
st->listener = node_area_listener;
st->refresh = node_area_refresh;
st->context = node_context;
st->dropboxes = node_dropboxes;
st->gizmos = node_widgets;
st->id_remap = node_id_remap;
st->space_subtype_item_extend = node_space_subtype_item_extend;
st->space_subtype_get = node_space_subtype_get;
st->space_subtype_set = node_space_subtype_set;
st->drop_target_find = node_drop_target_find;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype node region");

View File

@@ -67,6 +67,7 @@
/* ******************** Drop Target Find *********************** */
#if 0
static TreeElement *outliner_dropzone_element(TreeElement *te,
const float fmval[2],
const bool children)
@@ -1018,3 +1019,5 @@ void outliner_dropboxes(void)
WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, NULL);
WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", collection_drop_poll, NULL);
}
#endif

View File

@@ -98,8 +98,8 @@ static int outliner_highlight_update(bContext *C, wmOperator *UNUSED(op), const
/* Drag and drop does own highlighting. */
wmWindowManager *wm = CTX_wm_manager(C);
if (wm->drags.first) {
return OPERATOR_PASS_THROUGH;
if (wm->drag.data) {
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
}
ARegion *region = CTX_wm_region(C);

View File

@@ -371,14 +371,11 @@ void outliner_set_coordinates(struct ARegion *region, struct SpaceOutliner *soop
void outliner_item_openclose(TreeElement *te, bool open, bool toggle_all);
/* outliner_dragdrop.c */
void outliner_dropboxes(void);
void OUTLINER_OT_item_drag_drop(struct wmOperatorType *ot);
void OUTLINER_OT_parent_drop(struct wmOperatorType *ot);
void OUTLINER_OT_parent_clear(struct wmOperatorType *ot);
void OUTLINER_OT_scene_drop(struct wmOperatorType *ot);
void OUTLINER_OT_material_drop(struct wmOperatorType *ot);
void OUTLINER_OT_collection_drop(struct wmOperatorType *ot);
void OUTLINER_OT_drag_init(struct wmOperatorType *ot);
void outliner_drop_target_find(struct bContext *C,
struct wmDropTargetFinder *finder,
struct wmDragData *drag_data,
const struct wmEvent *event);
/* ...................................................... */

View File

@@ -50,7 +50,7 @@ void outliner_operatortypes(void)
WM_operatortype_append(OUTLINER_OT_select_walk);
WM_operatortype_append(OUTLINER_OT_item_openclose);
WM_operatortype_append(OUTLINER_OT_item_rename);
WM_operatortype_append(OUTLINER_OT_item_drag_drop);
// WM_operatortype_append(OUTLINER_OT_drag_init);
WM_operatortype_append(OUTLINER_OT_operation);
WM_operatortype_append(OUTLINER_OT_scene_operation);
WM_operatortype_append(OUTLINER_OT_object_operation);
@@ -84,12 +84,6 @@ void outliner_operatortypes(void)
WM_operatortype_append(OUTLINER_OT_orphans_purge);
WM_operatortype_append(OUTLINER_OT_parent_drop);
WM_operatortype_append(OUTLINER_OT_parent_clear);
WM_operatortype_append(OUTLINER_OT_scene_drop);
WM_operatortype_append(OUTLINER_OT_material_drop);
WM_operatortype_append(OUTLINER_OT_collection_drop);
/* collections */
WM_operatortype_append(OUTLINER_OT_collection_new);
WM_operatortype_append(OUTLINER_OT_collection_duplicate_linked);

View File

@@ -56,7 +56,6 @@
static void outliner_main_region_init(wmWindowManager *wm, ARegion *region)
{
ListBase *lb;
wmKeyMap *keymap;
/* make sure we keep the hide flags */
@@ -75,10 +74,6 @@ static void outliner_main_region_init(wmWindowManager *wm, ARegion *region)
/* own keymap */
keymap = WM_keymap_ensure(wm->defaultconf, "Outliner", SPACE_OUTLINER, 0);
WM_event_add_keymap_handler_v2d_mask(&region->handlers, keymap);
/* Add dropboxes */
lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW);
WM_event_add_dropbox_handler(&region->handlers, lb);
}
static void outliner_main_region_draw(const bContext *C, ARegion *region)
@@ -416,9 +411,9 @@ void ED_spacetype_outliner(void)
st->duplicate = outliner_duplicate;
st->operatortypes = outliner_operatortypes;
st->keymap = outliner_keymap;
st->dropboxes = outliner_dropboxes;
st->id_remap = outliner_id_remap;
st->deactivate = outliner_deactivate;
// st->drop_target_find = outliner_drop_target_find;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype outliner region");

View File

@@ -358,99 +358,6 @@ static void sequencer_listener(wmWindow *UNUSED(win),
}
}
/* ************* dropboxes ************* */
static bool image_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
{
ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
int hand;
if (drag->type == WM_DRAG_PATH) {
if (ELEM(drag->icon, ICON_FILE_IMAGE, ICON_FILE_BLANK)) { /* Rule might not work? */
if (find_nearest_seq(scene, &region->v2d, &hand, event->mval) == NULL) {
return 1;
}
}
}
return 0;
}
static bool movie_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
{
ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
int hand;
if (drag->type == WM_DRAG_PATH) {
if (ELEM(drag->icon, 0, ICON_FILE_MOVIE, ICON_FILE_BLANK)) { /* Rule might not work? */
if (find_nearest_seq(scene, &region->v2d, &hand, event->mval) == NULL) {
return 1;
}
}
}
return 0;
}
static bool sound_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
{
ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
int hand;
if (drag->type == WM_DRAG_PATH) {
if (ELEM(drag->icon, ICON_FILE_SOUND, ICON_FILE_BLANK)) { /* Rule might not work? */
if (find_nearest_seq(scene, &region->v2d, &hand, event->mval) == NULL) {
return 1;
}
}
}
return 0;
}
static void sequencer_drop_copy(wmDrag *drag, wmDropBox *drop)
{
/* Copy drag path to properties. */
if (RNA_struct_find_property(drop->ptr, "filepath")) {
RNA_string_set(drop->ptr, "filepath", drag->path);
}
if (RNA_struct_find_property(drop->ptr, "directory")) {
PointerRNA itemptr;
char dir[FILE_MAX], file[FILE_MAX];
BLI_split_dirfile(drag->path, dir, file, sizeof(dir), sizeof(file));
RNA_string_set(drop->ptr, "directory", dir);
RNA_collection_clear(drop->ptr, "files");
RNA_collection_add(drop->ptr, "files", &itemptr);
RNA_string_set(&itemptr, "name", file);
}
}
/* This region dropbox definition. */
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);
WM_dropbox_add(lb, "SEQUENCER_OT_movie_strip_add", movie_drop_poll, sequencer_drop_copy);
WM_dropbox_add(lb, "SEQUENCER_OT_sound_strip_add", sound_drop_poll, sequencer_drop_copy);
}
/* ************* end drop *********** */
/* DO NOT make this static, this hides the symbol and breaks API generation script. */
extern const char *sequencer_context_dir[]; /* Quiet warning. */
const char *sequencer_context_dir[] = {"edit_mask", NULL};
@@ -493,7 +400,6 @@ static void sequencer_gizmos(void)
static void sequencer_main_region_init(wmWindowManager *wm, ARegion *region)
{
wmKeyMap *keymap;
ListBase *lb;
UI_view2d_region_reinit(&region->v2d, V2D_COMMONVIEW_CUSTOM, region->winx, region->winy);
@@ -508,11 +414,6 @@ static void sequencer_main_region_init(wmWindowManager *wm, ARegion *region)
/* Own keymap. */
keymap = WM_keymap_ensure(wm->defaultconf, "Sequencer", SPACE_SEQ, 0);
WM_event_add_keymap_handler_v2d_mask(&region->handlers, keymap);
/* Add drop boxes. */
lb = WM_dropboxmap_find("Sequencer", SPACE_SEQ, RGN_TYPE_WINDOW);
WM_event_add_dropbox_handler(&region->handlers, lb);
}
/* Strip editing timeline. */
@@ -835,6 +736,61 @@ static void sequencer_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_
}
}
static void sequencer_drop_copy(wmDragData *drag_data, PointerRNA *ptr)
{
const char *path = WM_drag_query_single_path(drag_data);
if (RNA_struct_find_property(ptr, "filepath")) {
RNA_string_set(ptr, "filepath", path);
}
if (RNA_struct_find_property(ptr, "directory")) {
PointerRNA itemptr;
char dir[FILE_MAX], file[FILE_MAX];
BLI_split_dirfile(path, dir, file, sizeof(dir), sizeof(file));
RNA_string_set(ptr, "directory", dir);
RNA_collection_clear(ptr, "files");
RNA_collection_add(ptr, "files", &itemptr);
RNA_string_set(&itemptr, "name", file);
}
}
static void sequencer_drop_target_find(bContext *C,
wmDropTargetFinder *finder,
wmDragData *drag_data,
const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
int hand;
Sequence *seq = find_nearest_seq(scene, &ar->v2d, &hand, event->mval);
if (WM_drag_query_single_path_image(drag_data) && seq == NULL) {
WM_drop_target_propose__template_1(finder,
DROP_TARGET_SIZE_AREA,
"SEQUENCER_OT_image_strip_add",
"Load image",
sequencer_drop_copy);
}
if (WM_drag_query_single_path_movie(drag_data) && seq == NULL) {
WM_drop_target_propose__template_1(finder,
DROP_TARGET_SIZE_AREA,
"SEQUENCER_OT_movie_strip_add",
"Load Movie",
sequencer_drop_copy);
}
if (WM_drag_query_single_path_sound(drag_data) && seq == NULL) {
WM_drop_target_propose__template_1(finder,
DROP_TARGET_SIZE_AREA,
"SEQUENCER_OT_sound_strip_add",
"Load Sound",
sequencer_drop_copy);
}
}
/* ************************************* */
/* Only called once, from space/spacetypes.c. */
@@ -854,10 +810,10 @@ void ED_spacetype_sequencer(void)
st->keymap = sequencer_keymap;
st->context = sequencer_context;
st->gizmos = sequencer_gizmos;
st->dropboxes = sequencer_dropboxes;
st->refresh = sequencer_refresh;
st->listener = sequencer_listener;
st->id_remap = sequencer_id_remap;
st->drop_target_find = sequencer_drop_target_find;
/* Create regions: */
/* Main window. */

View File

@@ -272,7 +272,6 @@ static int text_context(const bContext *C, const char *member, bContextDataResul
static void text_main_region_init(wmWindowManager *wm, ARegion *region)
{
wmKeyMap *keymap;
ListBase *lb;
UI_view2d_region_reinit(&region->v2d, V2D_COMMONVIEW_STANDARD, region->winx, region->winy);
@@ -281,11 +280,6 @@ static void text_main_region_init(wmWindowManager *wm, ARegion *region)
WM_event_add_keymap_handler_v2d_mask(&region->handlers, keymap);
keymap = WM_keymap_ensure(wm->defaultconf, "Text", SPACE_TEXT, 0);
WM_event_add_keymap_handler_v2d_mask(&region->handlers, keymap);
/* add drop boxes */
lb = WM_dropboxmap_find("Text", SPACE_TEXT, RGN_TYPE_WINDOW);
WM_event_add_dropbox_handler(&region->handlers, lb);
}
static void text_main_region_draw(const bContext *C, ARegion *region)
@@ -323,58 +317,6 @@ static void text_cursor(wmWindow *win, ScrArea *area, ARegion *region)
WM_cursor_set(win, wmcursor);
}
/* ************* dropboxes ************* */
static bool text_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
{
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
if (ELEM(drag->icon, ICON_FILE_SCRIPT, ICON_FILE_TEXT, ICON_FILE_BLANK)) {
return true;
}
}
return false;
}
static void text_drop_copy(wmDrag *drag, wmDropBox *drop)
{
/* copy drag path to properties */
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))
{
return (drag->type == WM_DRAG_ID);
}
static void text_drop_paste(wmDrag *drag, wmDropBox *drop)
{
char *text;
ID *id = WM_drag_ID(drag, 0);
/* copy drag path to properties */
text = RNA_path_full_ID_py(G_MAIN, id);
RNA_string_set(drop->ptr, "text", text);
MEM_freeN(text);
}
/* this region dropbox definition */
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);
WM_dropbox_add(lb, "TEXT_OT_insert", text_drop_paste_poll, text_drop_paste);
}
/* ************* end drop *********** */
/****************** header region ******************/
/* add handlers, stuff you only do once or on area/region changes */
@@ -434,6 +376,29 @@ static void text_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, I
}
}
static void drop_init__insert_id_path(wmDragData *drag_data, PointerRNA *ptr)
{
ID *id = WM_drag_query_single_id(drag_data);
char *text = RNA_path_full_ID_py(G_MAIN, id); /* TODO G_MAIN */
RNA_string_set(ptr, "text", text);
MEM_freeN(text);
}
static void text_drop_target_find(bContext *C,
wmDropTargetFinder *finder,
wmDragData *drag_data,
const wmEvent *UNUSED(event))
{
if (WM_drag_query_single_path_maybe_text(drag_data)) {
WM_drop_target_propose__template_1(
finder, DROP_TARGET_SIZE_AREA, "TEXT_OT_open", "Open File", WM_drop_init_single_filepath);
}
if (CTX_data_edit_text(C) && WM_drag_query_single_id(drag_data)) {
WM_drop_target_propose__template_1(
finder, DROP_TARGET_SIZE_AREA, "TEXT_OT_insert", "Insert Path", drop_init__insert_id_path);
}
}
/********************* registration ********************/
/* only called once, from space/spacetypes.c */
@@ -453,8 +418,8 @@ void ED_spacetype_text(void)
st->keymap = text_keymap;
st->listener = text_listener;
st->context = text_context;
st->dropboxes = text_dropboxes;
st->id_remap = text_id_remap;
st->drop_target_find = text_drop_target_find;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype text region");

View File

@@ -379,7 +379,6 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
/* add handlers, stuff you only do once or on area/region changes */
static void view3d_main_region_init(wmWindowManager *wm, ARegion *region)
{
ListBase *lb;
wmKeyMap *keymap;
/* object ops. */
@@ -448,11 +447,6 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *region)
keymap = WM_keymap_ensure(wm->defaultconf, "3D View", SPACE_VIEW3D, 0);
WM_event_add_keymap_handler(&region->handlers, keymap);
/* add drop boxes */
lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
WM_event_add_dropbox_handler(&region->handlers, lb);
}
static void view3d_main_region_exit(wmWindowManager *wm, ARegion *region)
@@ -460,153 +454,6 @@ static void view3d_main_region_exit(wmWindowManager *wm, ARegion *region)
ED_view3d_stop_render_preview(wm, region);
}
static bool view3d_drop_id_in_main_region_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
ID_Type id_type)
{
ScrArea *area = CTX_wm_area(C);
if (ED_region_overlap_isect_any_xy(area, &event->x)) {
return false;
}
return WM_drag_ID(drag, id_type) != NULL;
}
static bool view3d_ob_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
{
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))
{
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))
{
return view3d_drop_id_in_main_region_poll(C, drag, event, ID_MA);
}
static bool view3d_ima_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **UNUSED(r_tooltip))
{
if (ED_region_overlap_isect_any_xy(CTX_wm_area(C), &event->x)) {
return false;
}
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE));
}
else {
return WM_drag_ID(drag, ID_IM) != NULL;
}
}
static bool view3d_ima_bg_is_camera_view(bContext *C)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
if ((rv3d && (rv3d->persp == RV3D_CAMOB))) {
View3D *v3d = CTX_wm_view3d(C);
if (v3d && v3d->camera && v3d->camera->type == OB_CAMERA) {
return true;
}
}
return false;
}
static bool view3d_ima_bg_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
const char **r_tooltip)
{
if (!view3d_ima_drop_poll(C, drag, event, r_tooltip)) {
return false;
}
if (ED_view3d_is_object_under_cursor(C, event->mval)) {
return false;
}
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)
{
if (!view3d_ima_drop_poll(C, drag, event, r_tooltip)) {
return false;
}
Object *ob = ED_view3d_give_object_under_cursor(C, event->mval);
if (ob == NULL) {
return true;
}
if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE) {
return true;
}
return false;
}
static bool view3d_volume_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
{
return (drag->type == WM_DRAG_PATH) && (drag->icon == ICON_FILE_VOLUME);
}
static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_ID(drag, ID_OB);
RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_ID(drag, ID_GR);
drop->opcontext = WM_OP_EXEC_DEFAULT;
RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_ID(drag, 0);
RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_ID(drag, 0);
if (id) {
RNA_string_set(drop->ptr, "name", id->name + 2);
RNA_struct_property_unset(drop->ptr, "filepath");
}
else if (drag->path[0]) {
RNA_string_set(drop->ptr, "filepath", drag->path);
RNA_struct_property_unset(drop->ptr, "image");
}
}
static void view3d_lightcache_update(bContext *C)
{
PointerRNA op_ptr;
@@ -627,24 +474,6 @@ static void view3d_lightcache_update(bContext *C)
WM_operator_properties_free(&op_ptr);
}
/* region dropbox definition */
static void view3d_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
WM_dropbox_add(lb, "OBJECT_OT_add_named", view3d_ob_drop_poll, view3d_ob_drop_copy);
WM_dropbox_add(lb, "OBJECT_OT_drop_named_material", view3d_mat_drop_poll, view3d_id_drop_copy);
WM_dropbox_add(
lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy);
WM_dropbox_add(
lb, "OBJECT_OT_drop_named_image", view3d_ima_empty_drop_poll, view3d_id_path_drop_copy);
WM_dropbox_add(lb, "OBJECT_OT_volume_import", view3d_volume_drop_poll, view3d_id_path_drop_copy);
WM_dropbox_add(lb,
"OBJECT_OT_collection_instance_add",
view3d_collection_drop_poll,
view3d_collection_drop_copy);
}
static void view3d_widgets(void)
{
wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(
@@ -1601,6 +1430,72 @@ static void view3d_id_remap(ScrArea *area, SpaceLink *slink, ID *old_id, ID *new
}
}
static bool view3d_ima_bg_is_camera_view(bContext *C)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
if ((rv3d && (rv3d->persp == RV3D_CAMOB))) {
View3D *v3d = CTX_wm_view3d(C);
if (v3d && v3d->camera && v3d->camera->type == OB_CAMERA) {
return true;
}
}
return false;
}
static void view3d_drop_target_find(bContext *C,
wmDropTargetFinder *finder,
wmDragData *drag_data,
const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
if (ar->regiontype != RGN_TYPE_WINDOW)
return;
Object *ob = ED_view3d_give_object_under_cursor(C, event->mval);
if (WM_drag_query_single_collection(drag_data)) {
WM_drop_target_propose__template_2(finder,
DROP_TARGET_SIZE_REGION,
"OBJECT_OT_collection_instance_add",
"New Collection Instance",
WM_drop_init_single_id_name,
WM_OP_EXEC_DEFAULT);
}
if (WM_drag_query_single_object(drag_data)) {
WM_drop_target_propose__template_1(finder,
DROP_TARGET_SIZE_REGION,
"OBJECT_OT_add_named",
"Add Object",
WM_drop_init_single_id_name);
}
if (WM_drag_query_single_material(drag_data) && ob) {
WM_drop_target_propose__template_1(finder,
DROP_TARGET_SIZE_VISIBLE_OBJECT,
"OBJECT_OT_drop_named_material",
"Set Material",
WM_drop_init_single_id_name);
}
if (WM_drag_query_single_path_image(drag_data)) {
if (ob == NULL && view3d_ima_bg_is_camera_view(C)) {
WM_drop_target_propose__template_1(finder,
DROP_TARGET_SIZE_REGION,
"VIEW3D_OT_background_image_add",
"Drop Background",
WM_drop_init_single_filepath);
}
if (ob == NULL || (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE)) {
WM_drop_target_propose__template_1(finder,
DROP_TARGET_SIZE_REGION,
"OBJECT_OT_drop_named_image",
"Drop Image",
WM_drop_init_single_filepath);
}
}
}
/* only called once, from space/spacetypes.c */
void ED_spacetype_view3d(void)
{
@@ -1618,10 +1513,10 @@ void ED_spacetype_view3d(void)
st->duplicate = view3d_duplicate;
st->operatortypes = view3d_operatortypes;
st->keymap = view3d_keymap;
st->dropboxes = view3d_dropboxes;
st->gizmos = view3d_widgets;
st->context = view3d_context;
st->id_remap = view3d_id_remap;
st->drop_target_find = view3d_drop_target_find;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype view3d main region");

View File

@@ -53,6 +53,7 @@ struct bContext;
struct bScreen;
struct uiLayout;
struct wmTimer;
struct wmDragData;
#define OP_MAX_TYPENAME 64
#define KMAP_MAX_NAME 64
@@ -132,6 +133,11 @@ typedef struct wmXrData {
/* reports need to be before wmWindowManager */
typedef struct wmDragOperation {
struct wmDragData *data;
struct wmDropTarget *target;
} wmDragOperation;
/* windowmanager is saved, tag WMAN */
typedef struct wmWindowManager {
ID id;
@@ -165,6 +171,9 @@ typedef struct wmWindowManager {
/** Extra overlay cursors to draw, like circles. */
ListBase paintcursors;
/** Active drag operation. */
struct wmDragOperation drag;
/** Active dragged items. */
ListBase drags;

View File

@@ -55,8 +55,6 @@ struct View3D;
struct ViewLayer;
struct bContext;
struct rcti;
struct wmDrag;
struct wmDropBox;
struct wmEvent;
struct wmEventHandler_Keymap;
struct wmEventHandler_UI;
@@ -67,6 +65,9 @@ struct wmOperator;
struct wmOperatorType;
struct wmPaintCursor;
struct wmTabletData;
struct wmDragData;
struct wmDropTarget;
struct wmDropTargetFinder;
#ifdef WITH_INPUT_NDOF
struct wmNDOFMotionData;
@@ -304,8 +305,7 @@ enum {
WM_HANDLER_DO_FREE = (1 << 7), /* handler tagged to be freed in wm_handlers_do() */
};
struct wmEventHandler_Dropbox *WM_event_add_dropbox_handler(ListBase *handlers,
ListBase *dropboxes);
void WM_event_ensure_drop_handler(ListBase *handlers);
/* mouse */
void WM_event_add_mousemove(wmWindow *win);
@@ -654,23 +654,87 @@ void WM_event_fileselect_event(struct wmWindowManager *wm, void *ophandle, int e
void WM_operator_region_active_win_set(struct bContext *C);
/* drag and drop */
struct wmDrag *WM_event_start_drag(
struct bContext *C, int icon, int type, void *poin, double value, unsigned int flags);
void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx, int sy);
void WM_drag_free(struct wmDrag *drag);
void WM_drag_free_list(struct ListBase *lb);
struct wmDragData *WM_drag_start_id(struct bContext *C, ID *id);
struct wmDragData *WM_drag_start_filepath(struct bContext *C, const char *filepath);
struct wmDragData *WM_drag_start_filepaths(struct bContext *C, const char **filepaths, int amount);
struct wmDragData *WM_drag_start_color(struct bContext *C, float color[3], bool gamma_corrected);
struct wmDragData *WM_drag_start_value(struct bContext *C, double value);
struct wmDragData *WM_drag_start_rna(struct bContext *C, struct PointerRNA *rna);
struct wmDragData *WM_drag_start_name(struct bContext *C, const char *name);
struct wmDragData *WM_drag_start_collection_children(struct bContext *C,
struct ListBase *collection_children);
struct wmDropBox *WM_dropbox_add(
ListBase *lb,
const char *idname,
bool (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event, const char **),
void (*copy)(struct wmDrag *, struct wmDropBox *));
ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
struct wmDragData *WM_drag_get_active(struct bContext *C);
struct wmDragData *WM_drag_data_from_event(const struct wmEvent *event);
void WM_drag_transfer_ownership_to_event(struct wmWindowManager *wm, struct wmEvent *event);
struct wmDropTarget *WM_drag_find_current_target(struct bContext *C,
struct wmDragData *drag_data,
const struct wmEvent *event);
/* ID drag and drop */
void WM_drag_add_ID(struct wmDrag *drag, struct ID *id, struct ID *from_parent);
struct ID *WM_drag_ID(const struct wmDrag *drag, short idcode);
struct ID *WM_drag_ID_from_event(const struct wmEvent *event, short idcode);
void WM_drag_display_set_color(struct wmDragData *drag_data, float color[3]);
void WM_drag_display_set_color_derived(struct wmDragData *drag_data);
void WM_drag_display_set_icon(struct wmDragData *drag_data, int icon_id);
void WM_drag_display_set_image(
struct wmDragData *drag_data, struct ImBuf *imb, float scale, int width, int height);
void WM_drag_data_free(struct wmDragData *drag);
void WM_drop_target_free(struct wmDropTarget *drop_target);
void WM_drag_stop(wmWindowManager *wm);
struct ID *WM_drag_query_single_id(struct wmDragData *drag_data);
struct ID *WM_drag_query_single_id_of_type(struct wmDragData *drag_data, int idtype);
struct Collection *WM_drag_query_single_collection(struct wmDragData *drag_data);
struct Material *WM_drag_query_single_material(struct wmDragData *drag_data);
struct Object *WM_drag_query_single_object(struct wmDragData *drag_data);
const char *WM_drag_query_single_path(struct wmDragData *drag_data);
const char *WM_drag_query_single_path_of_types(struct wmDragData *drag_data, int types);
const char *WM_drag_query_single_path_text(struct wmDragData *drag_data);
const char *WM_drag_query_single_path_maybe_text(struct wmDragData *drag_data);
const char *WM_drag_query_single_path_image(struct wmDragData *drag_data);
const char *WM_drag_query_single_path_movie(struct wmDragData *drag_data);
const char *WM_drag_query_single_path_sound(struct wmDragData *drag_data);
const char *WM_drag_query_single_path_image_or_movie(struct wmDragData *drag_data);
struct ListBase *WM_drag_query_collection_children(struct wmDragData *drag_data);
bool WM_drag_query_single_color(struct wmDragData *drag_data,
float *r_color,
bool *r_gamma_corrected);
typedef void (*wmDropTargetSetProps)(struct wmDragData *, struct PointerRNA *);
enum DropTargetSize {
DROP_TARGET_SIZE_BUT,
DROP_TARGET_SIZE_OUTLINER_ROW,
DROP_TARGET_SIZE_VISIBLE_OBJECT,
DROP_TARGET_SIZE_REGION,
DROP_TARGET_SIZE_AREA,
DROP_TARGET_SIZE_WINDOW,
DROP_TARGET_SIZE_MAX,
};
void WM_drop_target_propose(struct wmDropTargetFinder *finder, struct wmDropTarget *target);
void WM_drop_target_propose__template_1(struct wmDropTargetFinder *finder,
enum DropTargetSize size,
const char *ot_idname,
const char *tooltip,
wmDropTargetSetProps set_properties);
void WM_drop_target_propose__template_2(struct wmDropTargetFinder *finder,
enum DropTargetSize size,
const char *ot_idname,
const char *tooltip,
wmDropTargetSetProps set_properties,
short context);
struct wmDropTarget *WM_drop_target_new(enum DropTargetSize size,
char *ot_idname,
char *tooltip,
wmDropTargetSetProps set_properties,
short context,
bool free,
bool free_idname,
bool free_tooltip);
void WM_drop_init_single_filepath(struct wmDragData *drag_data, struct PointerRNA *ptr);
void WM_drop_init_single_id_name(struct wmDragData *drag_data, struct PointerRNA *ptr);
/* Set OpenGL viewport and scissor */
void wmViewport(const struct rcti *rect);

View File

@@ -814,70 +814,73 @@ typedef void (*wmPaintCursorDraw)(struct bContext *C, int, int, void *customdata
#define WM_DRAG_VALUE 4
#define WM_DRAG_COLOR 5
typedef enum wmDragFlags {
WM_DRAG_NOP = 0,
WM_DRAG_FREE_DATA = 1,
} wmDragFlags;
/* wmDragData.type */
enum DragDataType {
DRAG_DATA_IDS,
DRAG_DATA_FILEPATHS,
DRAG_DATA_COLOR,
DRAG_DATA_VALUE,
DRAG_DATA_RNA,
DRAG_DATA_NAME,
DRAG_DATA_COLLECTION_CHILDREN,
};
/* wmDragData.display_type */
enum DragDisplayType {
DRAG_DISPLAY_NONE = 0,
DRAG_DISPLAY_ICON,
DRAG_DISPLAY_IMAGE,
DRAG_DISPLAY_COLOR,
};
/* note: structs need not exported? */
typedef struct wmDragID {
struct wmDragID *next, *prev;
typedef struct wmDragCollectionChild {
struct ID *id;
struct ID *from_parent;
} wmDragID;
struct Collection *parent;
} wmDragCollectionChild;
typedef struct wmDrag {
struct wmDrag *next, *prev;
typedef struct wmDragData {
enum DragDataType type;
enum DragDisplayType display_type;
union {
ListBase *ids;
struct {
char **paths;
int amount;
} filepaths;
struct {
float color[3];
bool gamma_corrected;
} color;
double value;
struct PointerRNA *rna;
char *name;
ListBase *collection_children;
} data;
union {
struct {
struct ImBuf *imb;
float scale;
int width;
int height;
} image;
int icon_id;
float color[3];
} display;
} wmDragData;
int icon;
/** See 'WM_DRAG_' defines above. */
int type;
void *poin;
char path[1024]; /* FILE_MAX */
double value;
typedef struct wmDropTarget {
char *ot_idname;
char *tooltip;
short context;
int size;
bool free;
bool free_idname;
bool free_tooltip;
void (*set_properties)(struct wmDragData *, struct PointerRNA *);
} wmDropTarget;
/** If no icon but imbuf should be drawn around cursor. */
struct ImBuf *imb;
float scale;
int sx, sy;
/** If set, draws operator name. */
char opname[200];
unsigned int flags;
/** List of wmDragIDs, all are guaranteed to have the same ID type. */
ListBase ids;
} wmDrag;
/**
* Dropboxes are like keymaps, part of the screen/area/region definition.
* Allocation and free is on startup and exit.
*/
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 **);
/** Before exec, this copies drag info to #wmDrop properties. */
void (*copy)(struct wmDrag *, struct wmDropBox *);
/**
* If poll succeeds, operator is called.
* Not saved in file, so can be pointer.
*/
wmOperatorType *ot;
/** Operator properties, assigned to ptr->data and can be written to a file. */
struct IDProperty *properties;
/** RNA pointer to access properties. */
struct PointerRNA *ptr;
/** Default invoke. */
short opcontext;
} wmDropBox;
typedef struct wmDropTargetFinder {
wmDropTarget *current;
} wmDropTargetFinder;
/**
* Struct to store tool-tip timer and possible creation if the time is reached.

View File

@@ -123,7 +123,6 @@ struct wmGizmoMap {
/**
* This is a container for all gizmo types that can be instantiated in a region.
* (similar to dropboxes).
*
* \note There is only ever one of these for every (area, region) combination.
*/

View File

@@ -434,7 +434,7 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
BLI_freelistN(&wm->paintcursors);
WM_drag_free_list(&wm->drags);
WM_drag_stop(wm);
wm_reports_free(wm);

View File

@@ -27,17 +27,21 @@
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
#include "DNA_collection_types.h"
#include "DNA_space_types.h"
#include "MEM_guardedalloc.h"
#include "BLT_translation.h"
#include "BLI_blenlib.h"
#include "BLI_math_vector.h"
#include "BIF_glutil.h"
#include "BKE_context.h"
#include "BKE_idtype.h"
#include "BKE_screen.h"
#include "GPU_glew.h"
#include "GPU_shader.h"
@@ -49,453 +53,512 @@
#include "UI_interface.h"
#include "UI_interface_icons.h"
#include "ED_outliner.h"
#include "ED_fileselect.h"
#include "RNA_access.h"
#include "WM_api.h"
#include "WM_types.h"
#include "wm_event_system.h"
/* ****************************************************** */
/* ********************* Free Data ********************* */
static ListBase dropboxes = {NULL, NULL};
/* drop box maps are stored global for now */
/* these are part of blender's UI/space specs, and not like keymaps */
/* when editors become configurable, they can add own dropbox definitions */
typedef struct wmDropBoxMap {
struct wmDropBoxMap *next, *prev;
ListBase dropboxes;
short spaceid, regionid;
char idname[KMAP_MAX_NAME];
} wmDropBoxMap;
/* spaceid/regionid is zero for window drop maps */
ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid)
static void drag_data_free_filepaths(wmDragData *drag_data)
{
wmDropBoxMap *dm;
for (dm = dropboxes.first; dm; dm = dm->next) {
if (dm->spaceid == spaceid && dm->regionid == regionid) {
if (STREQLEN(idname, dm->idname, KMAP_MAX_NAME)) {
return &dm->dropboxes;
}
}
for (int i = 0; i < drag_data->data.filepaths.amount; i++) {
MEM_freeN(drag_data->data.filepaths.paths[i]);
}
dm = MEM_callocN(sizeof(struct wmDropBoxMap), "dropmap list");
BLI_strncpy(dm->idname, idname, KMAP_MAX_NAME);
dm->spaceid = spaceid;
dm->regionid = regionid;
BLI_addtail(&dropboxes, dm);
return &dm->dropboxes;
MEM_freeN(drag_data->data.filepaths.paths);
}
wmDropBox *WM_dropbox_add(ListBase *lb,
const char *idname,
bool (*poll)(bContext *, wmDrag *, const wmEvent *, const char **),
void (*copy)(wmDrag *, wmDropBox *))
static void drag_data_free_collection_children(wmDragData *drag_data)
{
wmDropBox *drop = MEM_callocN(sizeof(wmDropBox), "wmDropBox");
drop->poll = poll;
drop->copy = copy;
drop->ot = WM_operatortype_find(idname, 0);
drop->opcontext = WM_OP_INVOKE_DEFAULT;
if (drop->ot == NULL) {
MEM_freeN(drop);
printf("Error: dropbox with unknown operator: %s\n", idname);
return NULL;
ListBase *list = drag_data->data.collection_children;
LISTBASE_FOREACH (LinkData *, link, list) {
MEM_freeN(link->data);
}
WM_operator_properties_alloc(&(drop->ptr), &(drop->properties), idname);
BLI_addtail(lb, drop);
return drop;
BLI_freelistN(list);
MEM_freeN(list);
}
void wm_dropbox_free(void)
void WM_drag_data_free(wmDragData *drag_data)
{
wmDropBoxMap *dm;
for (dm = dropboxes.first; dm; dm = dm->next) {
wmDropBox *drop;
for (drop = dm->dropboxes.first; drop; drop = drop->next) {
if (drop->ptr) {
WM_operator_properties_free(drop->ptr);
MEM_freeN(drop->ptr);
}
}
BLI_freelistN(&dm->dropboxes);
switch (drag_data->type) {
case DRAG_DATA_FILEPATHS:
drag_data_free_filepaths(drag_data);
break;
case DRAG_DATA_COLLECTION_CHILDREN:
drag_data_free_collection_children(drag_data);
break;
default:
break;
}
BLI_freelistN(&dropboxes);
MEM_freeN(drag_data);
}
/* *********************************** */
void WM_drop_target_free(wmDropTarget *drop_target)
{
if (drop_target->free_idname) {
MEM_freeN(drop_target->ot_idname);
}
if (drop_target->free_tooltip) {
MEM_freeN(drop_target->tooltip);
}
if (drop_target->free) {
MEM_freeN(drop_target);
}
}
/* note that the pointer should be valid allocated and not on stack */
wmDrag *WM_event_start_drag(
struct bContext *C, int icon, int type, void *poin, double value, unsigned int flags)
void WM_drag_stop(wmWindowManager *wm)
{
if (wm->drag.data) {
WM_drag_data_free(wm->drag.data);
}
if (wm->drag.target) {
WM_drop_target_free(wm->drag.target);
}
wm->drag.data = NULL;
wm->drag.target = NULL;
}
/* ********************* Start Dragging ********************* */
static void start_dragging_data(struct bContext *C, wmDragData *drag_data)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmDrag *drag = MEM_callocN(sizeof(struct wmDrag), "new drag");
/* keep track of future multitouch drag too, add a mousepointer id or so */
/* if multiple drags are added, they're drawn as list */
BLI_addtail(&wm->drags, drag);
drag->flags = flags;
drag->icon = icon;
drag->type = type;
if (type == WM_DRAG_PATH) {
BLI_strncpy(drag->path, poin, FILE_MAX);
}
else if (type == WM_DRAG_ID) {
if (poin) {
WM_drag_add_ID(drag, poin, NULL);
}
}
else {
drag->poin = poin;
}
drag->value = value;
return drag;
WM_drag_stop(wm);
wm->drag.data = drag_data;
wm->drag.target = NULL;
}
void WM_event_drag_image(wmDrag *drag, ImBuf *imb, float scale, int sx, int sy)
static wmDragData *WM_drag_data_new(void)
{
drag->imb = imb;
drag->scale = scale;
drag->sx = sx;
drag->sy = sy;
return MEM_callocN(sizeof(wmDragData), "drag data");
}
void WM_drag_free(wmDrag *drag)
wmDragData *WM_drag_start_id(struct bContext *C, ID *id)
{
if ((drag->flags & WM_DRAG_FREE_DATA) && drag->poin) {
MEM_freeN(drag->poin);
}
wmDragData *drag_data = WM_drag_data_new();
drag_data->type = DRAG_DATA_IDS;
drag_data->data.ids = MEM_callocN(sizeof(ListBase), __func__);
BLI_addtail(drag_data->data.ids, BLI_genericNodeN(id));
BLI_freelistN(&drag->ids);
MEM_freeN(drag);
start_dragging_data(C, drag_data);
return drag_data;
}
void WM_drag_free_list(struct ListBase *lb)
wmDragData *WM_drag_start_filepaths(struct bContext *C, const char **filepaths, int amount)
{
wmDrag *drag;
while ((drag = BLI_pophead(lb))) {
WM_drag_free(drag);
BLI_assert(amount > 0);
char **paths = MEM_malloc_arrayN(amount, sizeof(char *), __func__);
for (int i = 0; i < amount; i++) {
paths[i] = BLI_strdup(filepaths[i]);
}
wmDragData *drag_data = WM_drag_data_new();
drag_data->type = DRAG_DATA_FILEPATHS;
drag_data->data.filepaths.amount = amount;
drag_data->data.filepaths.paths = paths;
start_dragging_data(C, drag_data);
return drag_data;
}
static const char *dropbox_active(bContext *C,
ListBase *handlers,
wmDrag *drag,
const wmEvent *event)
wmDragData *WM_drag_start_filepath(struct bContext *C, const char *filepath)
{
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)) {
/* 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 NULL;
return WM_drag_start_filepaths(C, &filepath, 1);
}
/* return active operator name when mouse is in box */
static const char *wm_dropbox_active(bContext *C, wmDrag *drag, const wmEvent *event)
wmDragData *WM_drag_start_color(struct bContext *C, float color[3], bool gamma_corrected)
{
wmWindow *win = CTX_wm_window(C);
ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
const char *name;
wmDragData *drag_data = WM_drag_data_new();
drag_data->type = DRAG_DATA_COLOR;
copy_v3_v3(drag_data->data.color.color, color);
drag_data->data.color.gamma_corrected = gamma_corrected;
name = dropbox_active(C, &win->handlers, drag, event);
if (name) {
return name;
}
name = dropbox_active(C, &area->handlers, drag, event);
if (name) {
return name;
}
name = dropbox_active(C, &region->handlers, drag, event);
if (name) {
return name;
}
return NULL;
start_dragging_data(C, drag_data);
return drag_data;
}
static void wm_drop_operator_options(bContext *C, wmDrag *drag, const wmEvent *event)
wmDragData *WM_drag_start_value(struct bContext *C, double value)
{
wmWindow *win = CTX_wm_window(C);
const int winsize_x = WM_window_pixels_x(win);
const int winsize_y = WM_window_pixels_y(win);
wmDragData *drag_data = WM_drag_data_new();
drag_data->type = DRAG_DATA_VALUE;
drag_data->data.value = value;
/* for multiwin drags, we only do this if mouse inside */
if (event->x < 0 || event->y < 0 || event->x > winsize_x || event->y > winsize_y) {
start_dragging_data(C, drag_data);
return drag_data;
}
wmDragData *WM_drag_start_rna(struct bContext *C, struct PointerRNA *rna)
{
wmDragData *drag_data = WM_drag_data_new();
drag_data->type = DRAG_DATA_RNA;
drag_data->data.rna = rna;
start_dragging_data(C, drag_data);
return drag_data;
}
wmDragData *WM_drag_start_name(struct bContext *C, const char *name)
{
wmDragData *drag_data = WM_drag_data_new();
drag_data->type = DRAG_DATA_NAME;
drag_data->data.name = BLI_strdup(name);
start_dragging_data(C, drag_data);
return drag_data;
}
wmDragData *WM_drag_start_collection_children(struct bContext *C, ListBase *collection_children)
{
wmDragData *drag_data = WM_drag_data_new();
drag_data->type = DRAG_DATA_COLLECTION_CHILDREN;
drag_data->data.collection_children = collection_children;
start_dragging_data(C, drag_data);
return drag_data;
}
/* ********************* Set Display Options ********************* */
void WM_drag_display_set_image(
wmDragData *drag_data, ImBuf *imb, float scale, int width, int height)
{
drag_data->display_type = DRAG_DISPLAY_IMAGE;
drag_data->display.image.imb = imb;
drag_data->display.image.scale = scale;
drag_data->display.image.width = width;
drag_data->display.image.height = height;
}
void WM_drag_display_set_icon(wmDragData *drag_data, int icon_id)
{
drag_data->display_type = DRAG_DISPLAY_ICON;
drag_data->display.icon_id = icon_id;
}
void WM_drag_display_set_color(wmDragData *drag_data, float color[3])
{
drag_data->display_type = DRAG_DISPLAY_COLOR;
copy_v3_v3(drag_data->display.color, color);
}
void WM_drag_display_set_color_derived(wmDragData *drag_data)
{
BLI_assert(drag_data->type == DRAG_DATA_COLOR);
WM_drag_display_set_color(drag_data, drag_data->data.color.color);
}
/* ********************* Drop Target Creation ********************* */
void WM_drop_target_propose(wmDropTargetFinder *finder, wmDropTarget *target)
{
if (target == NULL) {
return;
}
drag->opname[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));
else if (finder->current == NULL) {
finder->current = target;
}
else if (target->size < finder->current->size) {
WM_drop_target_free(finder->current);
finder->current = target;
}
else {
const char *opname = wm_dropbox_active(C, drag, event);
if (opname) {
BLI_strncpy(drag->opname, opname, sizeof(drag->opname));
// WM_cursor_modal_set(win, WM_CURSOR_COPY);
}
// else
// WM_cursor_modal_restore(win);
/* unsure about cursor type, feels to be too much */
WM_drop_target_free(target);
}
}
/* called in inner handler loop, region context */
void wm_drags_check_ops(bContext *C, const wmEvent *event)
static enum DropTargetSize drop_target_get_current_size(wmDropTargetFinder *finder)
{
if (finder->current)
return finder->current->size;
else
return DROP_TARGET_SIZE_MAX;
}
void WM_drop_target_propose__template_1(wmDropTargetFinder *finder,
enum DropTargetSize size,
const char *ot_idname,
const char *tooltip,
wmDropTargetSetProps set_properties)
{
WM_drop_target_propose__template_2(
finder, size, ot_idname, tooltip, set_properties, WM_OP_INVOKE_DEFAULT);
}
void WM_drop_target_propose__template_2(wmDropTargetFinder *finder,
enum DropTargetSize size,
const char *ot_idname,
const char *tooltip,
wmDropTargetSetProps set_properties,
short context)
{
if (size >= drop_target_get_current_size(finder))
return;
WM_drop_target_propose(
finder,
WM_drop_target_new(
size, (char *)ot_idname, (char *)tooltip, set_properties, context, true, false, false));
}
wmDropTarget *WM_drop_target_new(enum DropTargetSize size,
char *ot_idname,
char *tooltip,
wmDropTargetSetProps set_properties,
short context,
bool free,
bool free_idname,
bool free_tooltip)
{
wmDropTarget *drop_target = MEM_callocN(sizeof(wmDropTarget), __func__);
drop_target->size = size;
drop_target->ot_idname = ot_idname;
drop_target->tooltip = tooltip;
drop_target->set_properties = set_properties;
drop_target->context = context;
drop_target->free = free;
drop_target->free_idname = free_idname;
drop_target->free_tooltip = free_tooltip;
return drop_target;
}
/* ********************* Query Drag Data ********************* */
ID *WM_drag_query_single_id(wmDragData *drag_data)
{
if (drag_data->type == DRAG_DATA_IDS) {
ListBase *list = drag_data->data.ids;
if (BLI_listbase_is_single(list)) {
return (ID *)list->first;
}
}
else if (drag_data->type == DRAG_DATA_COLLECTION_CHILDREN) {
ListBase *list = drag_data->data.collection_children;
if (BLI_listbase_is_single(list)) {
return (ID *)((wmDragCollectionChild *)((LinkData *)list->first)->data)->id;
}
}
return NULL;
}
ID *WM_drag_query_single_id_of_type(wmDragData *drag_data, int idtype)
{
ID *id = WM_drag_query_single_id(drag_data);
if (id && GS(id->name) == idtype)
return id;
return NULL;
}
Collection *WM_drag_query_single_collection(wmDragData *drag_data)
{
return (Collection *)WM_drag_query_single_id_of_type(drag_data, ID_GR);
}
Material *WM_drag_query_single_material(wmDragData *drag_data)
{
return (Material *)WM_drag_query_single_id_of_type(drag_data, ID_MA);
}
Object *WM_drag_query_single_object(wmDragData *drag_data)
{
return (Object *)WM_drag_query_single_id_of_type(drag_data, ID_OB);
}
const char *WM_drag_query_single_path(wmDragData *drag_data)
{
if (drag_data->type == DRAG_DATA_FILEPATHS) {
if (drag_data->data.filepaths.amount == 1) {
return drag_data->data.filepaths.paths[0];
}
}
return NULL;
}
const char *WM_drag_query_single_path_of_types(wmDragData *drag_data, int types)
{
const char *path = WM_drag_query_single_path(drag_data);
if (!path)
return NULL;
if (ED_path_extension_type(path) & types) {
return path;
}
return NULL;
}
const char *WM_drag_query_single_path_maybe_text(wmDragData *drag_data)
{
const char *path = WM_drag_query_single_path(drag_data);
if (!path)
return NULL;
int type = ED_path_extension_type(path);
if (type == 0 || ELEM(type, FILE_TYPE_PYSCRIPT, FILE_TYPE_TEXT)) {
return path;
}
return NULL;
}
const char *WM_drag_query_single_path_image(wmDragData *drag_data)
{
return WM_drag_query_single_path_of_types(drag_data, FILE_TYPE_IMAGE);
}
const char *WM_drag_query_single_path_movie(wmDragData *drag_data)
{
return WM_drag_query_single_path_of_types(drag_data, FILE_TYPE_MOVIE);
}
const char *WM_drag_query_single_path_sound(wmDragData *drag_data)
{
return WM_drag_query_single_path_of_types(drag_data, FILE_TYPE_SOUND);
}
const char *WM_drag_query_single_path_image_or_movie(wmDragData *drag_data)
{
return WM_drag_query_single_path_of_types(drag_data, FILE_TYPE_IMAGE | FILE_TYPE_MOVIE);
}
ListBase *WM_drag_query_collection_children(wmDragData *drag_data)
{
if (drag_data->type == DRAG_DATA_COLLECTION_CHILDREN) {
return drag_data->data.collection_children;
}
return NULL;
}
bool WM_drag_query_single_color(wmDragData *drag_data, float *r_color, bool *r_gamma_corrected)
{
if (drag_data->type == DRAG_DATA_COLOR) {
if (r_color)
memcpy(r_color, drag_data->data.color.color, sizeof(float) * 3);
if (r_gamma_corrected)
*r_gamma_corrected = drag_data->data.color.gamma_corrected;
return true;
}
return false;
}
/* ********************* Draw ********************* */
void WM_drag_draw(bContext *UNUSED(C), wmWindow *win, wmDragOperation *drag_operation)
{
wmDragData *drag_data = drag_operation->data;
wmDropTarget *drop_target = drag_operation->target;
int cursorx = win->eventstate->x;
int cursory = win->eventstate->y;
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
const uchar text_col[] = {255, 255, 255, 255};
if (drop_target && drop_target->tooltip) {
UI_fontstyle_draw_simple(fstyle, cursorx, cursory, drop_target->tooltip, text_col);
}
glEnable(GL_BLEND);
if (drag_data->display_type == DRAG_DISPLAY_ICON) {
UI_icon_draw(cursorx, cursory, drag_data->display.icon_id);
}
else if (drag_data->display_type == DRAG_DISPLAY_COLOR) {
float color[4];
copy_v3_v3(color, drag_data->display.color);
color[3] = 1.0f;
UI_draw_roundbox_4fv(true, cursorx - 5, cursory - 5, cursorx + 5, cursory + 5, 2, color);
}
glDisable(GL_BLEND);
}
/* ****************** Find Current Target ****************** */
static void drop_files_init(wmDragData *drag_data, PointerRNA *ptr)
{
for (int i = 0; i < drag_data->data.filepaths.amount; i++) {
char *path = drag_data->data.filepaths.paths[i];
PointerRNA itemptr;
RNA_collection_add(ptr, "filepaths", &itemptr);
RNA_string_set(&itemptr, "name", path);
}
}
static void get_window_drop_target(bContext *C,
wmDropTargetFinder *finder,
wmDragData *drag_data,
const wmEvent *event)
{
UI_drop_target_find(C, finder, drag_data, event);
if (drag_data->type == DRAG_DATA_FILEPATHS) {
WM_drop_target_propose__template_1(
finder, DROP_TARGET_SIZE_WINDOW, "WM_OT_drop_files", "", drop_files_init);
}
}
wmDropTarget *WM_drag_find_current_target(bContext *C, wmDragData *drag_data, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
if (!sa)
return NULL;
wmDropTargetFinder finder = {0};
SpaceType *st = sa->type;
wmDropTarget *drop_target = NULL;
if (!drop_target && st->drop_target_find) {
st->drop_target_find(C, &finder, drag_data, event);
}
if (!drop_target) {
get_window_drop_target(C, &finder, drag_data, event);
}
return finder.current;
}
/* ****************** Misc ****************** */
void WM_drag_transfer_ownership_to_event(struct wmWindowManager *wm, struct wmEvent *event)
{
if (wm->drag.target) {
WM_drop_target_free(wm->drag.target);
}
event->custom = EVT_DATA_DRAGDROP;
event->customdata = wm->drag.data;
event->customdatafree = true;
wm->drag.data = NULL;
wm->drag.target = NULL;
}
wmDragData *WM_drag_get_active(bContext *C)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmDrag *drag;
for (drag = wm->drags.first; drag; drag = drag->next) {
wm_drop_operator_options(C, drag, event);
}
return wm->drag.data;
}
/* ************** IDs ***************** */
void WM_drag_add_ID(wmDrag *drag, ID *id, ID *from_parent)
wmDragData *WM_drag_data_from_event(const wmEvent *event)
{
/* Don't drag the same ID twice. */
LISTBASE_FOREACH (wmDragID *, drag_id, &drag->ids) {
if (drag_id->id == id) {
if (drag_id->from_parent == NULL) {
drag_id->from_parent = from_parent;
}
return;
}
else if (GS(drag_id->id->name) != GS(id->name)) {
BLI_assert(!"All dragged IDs must have the same type");
return;
}
}
/* Add to list. */
wmDragID *drag_id = MEM_callocN(sizeof(wmDragID), __func__);
drag_id->id = id;
drag_id->from_parent = from_parent;
BLI_addtail(&drag->ids, drag_id);
}
ID *WM_drag_ID(const wmDrag *drag, short idcode)
{
if (drag->type != WM_DRAG_ID) {
if (event->custom != EVT_DATA_DRAGDROP)
return NULL;
}
wmDragID *drag_id = drag->ids.first;
if (!drag_id) {
return NULL;
}
ID *id = drag_id->id;
return (idcode == 0 || GS(id->name) == idcode) ? id : NULL;
return (wmDragData *)event->customdata;
}
ID *WM_drag_ID_from_event(const wmEvent *event, short idcode)
void WM_drop_init_single_filepath(wmDragData *drag_data, PointerRNA *ptr)
{
if (event->custom != EVT_DATA_DRAGDROP) {
return NULL;
}
ListBase *lb = event->customdata;
return WM_drag_ID(lb->first, idcode);
RNA_string_set(ptr, "filepath", WM_drag_query_single_path(drag_data));
}
/* ************** draw ***************** */
static void wm_drop_operator_draw(const char *name, int x, int y)
void WM_drop_init_single_id_name(wmDragData *drag_data, PointerRNA *ptr)
{
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
const float col_fg[4] = {1.0f, 1.0f, 1.0f, 1.0f};
const float col_bg[4] = {0.0f, 0.0f, 0.0f, 0.2f};
UI_fontstyle_draw_simple_backdrop(fstyle, x, y, name, col_fg, col_bg);
}
static const char *wm_drag_name(wmDrag *drag)
{
switch (drag->type) {
case WM_DRAG_ID: {
ID *id = WM_drag_ID(drag, 0);
bool single = (BLI_listbase_count_at_most(&drag->ids, 2) == 1);
if (single) {
return id->name + 2;
}
else if (id) {
return BKE_idtype_idcode_to_name_plural(GS(id->name));
}
break;
}
case WM_DRAG_PATH:
case WM_DRAG_NAME:
return drag->path;
}
return "";
}
static void drag_rect_minmax(rcti *rect, int x1, int y1, int x2, int y2)
{
if (rect->xmin > x1) {
rect->xmin = x1;
}
if (rect->xmax < x2) {
rect->xmax = x2;
}
if (rect->ymin > y1) {
rect->ymin = y1;
}
if (rect->ymax < y2) {
rect->ymax = y2;
}
}
/* called in wm_draw.c */
/* if rect set, do not draw */
void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
{
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
wmWindowManager *wm = CTX_wm_manager(C);
wmDrag *drag;
const int winsize_y = WM_window_pixels_y(win);
int cursorx, cursory, x, y;
cursorx = win->eventstate->x;
cursory = win->eventstate->y;
if (rect) {
rect->xmin = rect->xmax = cursorx;
rect->ymin = rect->ymax = cursory;
}
/* XXX todo, multiline drag draws... but maybe not, more types mixed wont work well */
GPU_blend(true);
for (drag = wm->drags.first; drag; drag = drag->next) {
const uchar text_col[] = {255, 255, 255, 255};
int iconsize = UI_DPI_ICON_SIZE;
int padding = 4 * UI_DPI_FAC;
/* image or icon */
if (drag->imb) {
x = cursorx - drag->sx / 2;
y = cursory - drag->sy / 2;
if (rect) {
drag_rect_minmax(rect, x, y, x + drag->sx, y + drag->sy);
}
else {
float col[4] = {1.0f, 1.0f, 1.0f, 0.65f}; /* this blends texture */
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
immDrawPixelsTexScaled(&state,
x,
y,
drag->imb->x,
drag->imb->y,
GL_RGBA,
GL_UNSIGNED_BYTE,
GL_NEAREST,
drag->imb->rect,
drag->scale,
drag->scale,
1.0f,
1.0f,
col);
}
}
else {
x = cursorx - 2 * padding;
y = cursory - 2 * UI_DPI_FAC;
if (rect) {
drag_rect_minmax(rect, x, y, x + iconsize, y + iconsize);
}
else {
UI_icon_draw_ex(x, y, drag->icon, U.inv_dpi_fac, 0.8, 0.0f, text_col, false);
}
}
/* item name */
if (drag->imb) {
x = cursorx - drag->sx / 2;
y = cursory - drag->sy / 2 - iconsize;
}
else {
x = cursorx + 10 * UI_DPI_FAC;
y = cursory + 1 * UI_DPI_FAC;
}
if (rect) {
int w = UI_fontstyle_string_width(fstyle, wm_drag_name(drag));
drag_rect_minmax(rect, x, y, x + w, y + iconsize);
}
else {
UI_fontstyle_draw_simple(fstyle, x, y, wm_drag_name(drag), text_col);
}
/* operator name with roundbox */
if (drag->opname[0]) {
if (drag->imb) {
x = cursorx - drag->sx / 2;
if (cursory + drag->sy / 2 + padding + iconsize < winsize_y) {
y = cursory + drag->sy / 2 + padding;
}
else {
y = cursory - drag->sy / 2 - padding - iconsize - padding - iconsize;
}
}
else {
x = cursorx - 2 * padding;
if (cursory + iconsize + iconsize < winsize_y) {
y = (cursory + iconsize) + padding;
}
else {
y = (cursory - iconsize) - padding;
}
}
if (rect) {
int w = UI_fontstyle_string_width(fstyle, wm_drag_name(drag));
drag_rect_minmax(rect, x, y, x + w, y + iconsize);
}
else {
wm_drop_operator_draw(drag->opname, x, y);
}
}
}
GPU_blend(false);
RNA_string_set(ptr, "name", WM_drag_query_single_id(drag_data)->name + 2);
}

View File

@@ -795,8 +795,8 @@ static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view)
}
/* needs pixel coords in screen */
if (wm->drags.first) {
wm_drags_draw(C, win, NULL);
if (wm->drag.data) {
WM_drag_draw(C, win, &wm->drag);
}
}

View File

@@ -152,20 +152,25 @@ wmEvent *WM_event_add_simulate(wmWindow *win, const wmEvent *event_to_add)
return event;
}
void wm_event_free(wmEvent *event)
static void wm_event_free_customdata_if_necessary(wmEvent *event)
{
if (event->customdata) {
if (event->customdatafree) {
/* note: pointer to listbase struct elsewhere */
if (event->custom == EVT_DATA_DRAGDROP) {
ListBase *lb = event->customdata;
WM_drag_free_list(lb);
WM_drag_data_free(event->customdata);
}
else {
MEM_freeN(event->customdata);
}
}
}
event->customdata = NULL;
event->customdatafree = false;
}
void wm_event_free(wmEvent *event)
{
wm_event_free_customdata_if_necessary(event);
MEM_freeN(event);
}
@@ -2390,6 +2395,56 @@ static int wm_action_not_handled(int action)
return action == WM_HANDLER_CONTINUE || action == (WM_HANDLER_BREAK | WM_HANDLER_MODAL);
}
static bool wm_event_inside_rect(const wmEvent *event, const rcti *rect)
{
if (wm_event_always_pass(event)) {
return true;
}
if (BLI_rcti_isect_pt_v(rect, &event->x)) {
return true;
}
return false;
}
static bool wm_event_inside_region(const wmEvent *event, const ARegion *region)
{
if (wm_event_always_pass(event)) {
return true;
}
return ED_region_contains_xy(region, &event->x);
}
static ScrArea *area_event_inside(bContext *C, const int xy[2])
{
wmWindow *win = CTX_wm_window(C);
bScreen *screen = CTX_wm_screen(C);
if (screen) {
ED_screen_areas_iter (win, screen, area) {
if (BLI_rcti_isect_pt_v(&area->totrct, xy)) {
return area;
}
}
}
return NULL;
}
static ARegion *region_event_inside(bContext *C, const int xy[2])
{
bScreen *screen = CTX_wm_screen(C);
ScrArea *area = CTX_wm_area(C);
ARegion *region;
if (screen && area) {
for (region = area->regionbase.first; region; region = region->next) {
if (BLI_rcti_isect_pt_v(&region->winrct, xy)) {
return region;
}
}
}
return NULL;
}
#define PRINT \
if (do_debug_handler) \
printf
@@ -2744,50 +2799,44 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
}
}
else if (handler_base->type == WM_HANDLER_TYPE_DROPBOX) {
wmEventHandler_Dropbox *handler = (wmEventHandler_Dropbox *)handler_base;
if (!wm->is_interface_locked && event->type == EVT_DROP) {
wmDropBox *drop = handler->dropboxes->first;
for (; drop; drop = drop->next) {
/* other drop custom types allowed */
if (event->custom == EVT_DATA_DRAGDROP) {
ListBase *lb = (ListBase *)event->customdata;
wmDrag *drag;
wmDragData *drag_data = WM_drag_data_from_event(event);
if (!wm->is_interface_locked && event->type == EVT_DROP && drag_data) {
ARegion *region_old = CTX_wm_region(C);
ARegion *region = region_event_inside(C, &event->x);
CTX_wm_region_set(C, region);
wm_region_mouse_co(C, event);
for (drag = lb->first; drag; drag = drag->next) {
const char *tooltip = NULL;
if (drop->poll(C, drag, event, &tooltip)) {
/* Optionally copy drag information to operator properties. */
if (drop->copy) {
drop->copy(drag, drop);
}
wmDropTarget *drop_target = WM_drag_find_current_target(C, drag_data, event);
/* Pass single matched wmDrag onto the operator. */
BLI_remlink(lb, drag);
ListBase single_lb = {drag, drag};
event->customdata = &single_lb;
if (drop_target) {
wmOperatorType *ot = WM_operatortype_find(drop_target->ot_idname, false);
struct PointerRNA *ptr = NULL;
struct IDProperty *properties = NULL;
WM_operator_properties_alloc(&ptr, &properties, drop_target->ot_idname);
wm_operator_call_internal(
C, drop->ot, drop->ptr, NULL, drop->opcontext, false, event);
action |= WM_HANDLER_BREAK;
if (drop_target->set_properties) {
drop_target->set_properties(drag_data, ptr);
}
/* free the drags */
WM_drag_free_list(lb);
WM_drag_free_list(&single_lb);
wm_operator_call_internal(C, ot, ptr, NULL, drop_target->context, false, event);
action |= WM_HANDLER_BREAK;
event->customdata = NULL;
event->custom = 0;
WM_operator_properties_free(ptr);
WM_drop_target_free(drop_target);
/* XXX fileread case */
if (CTX_wm_window(C) == NULL) {
return action;
}
/* escape from drag loop, got freed */
break;
}
}
if (CTX_wm_window(C) == NULL) {
return action;
}
}
CTX_wm_region_set(C, region_old);
wm_region_mouse_co(C, event);
}
if (drag_data) {
WM_drag_data_free(drag_data);
event->customdata = NULL;
event->custom = 0;
}
}
else if (handler_base->type == WM_HANDLER_TYPE_GIZMO) {
@@ -2990,56 +3039,6 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
* Utilities used by #wm_event_do_handlers.
* \{ */
static bool wm_event_inside_rect(const wmEvent *event, const rcti *rect)
{
if (wm_event_always_pass(event)) {
return true;
}
if (BLI_rcti_isect_pt_v(rect, &event->x)) {
return true;
}
return false;
}
static bool wm_event_inside_region(const wmEvent *event, const ARegion *region)
{
if (wm_event_always_pass(event)) {
return true;
}
return ED_region_contains_xy(region, &event->x);
}
static ScrArea *area_event_inside(bContext *C, const int xy[2])
{
wmWindow *win = CTX_wm_window(C);
bScreen *screen = CTX_wm_screen(C);
if (screen) {
ED_screen_areas_iter (win, screen, area) {
if (BLI_rcti_isect_pt_v(&area->totrct, xy)) {
return area;
}
}
}
return NULL;
}
static ARegion *region_event_inside(bContext *C, const int xy[2])
{
bScreen *screen = CTX_wm_screen(C);
ScrArea *area = CTX_wm_area(C);
ARegion *region;
if (screen && area) {
for (region = area->regionbase.first; region; region = region->next) {
if (BLI_rcti_isect_pt_v(&region->winrct, xy)) {
return region;
}
}
}
return NULL;
}
static void wm_paintcursor_tag(bContext *C, wmPaintCursor *pc, ARegion *region)
{
if (region) {
@@ -3082,39 +3081,25 @@ static void wm_paintcursor_test(bContext *C, const wmEvent *event)
static void wm_event_drag_and_drop_test(wmWindowManager *wm, wmWindow *win, wmEvent *event)
{
bScreen *screen = WM_window_get_active_screen(win);
if (BLI_listbase_is_empty(&wm->drags)) {
if (!wm->drag.data) {
return;
}
bScreen *screen = WM_window_get_active_screen(win);
if (event->type == MOUSEMOVE || ISKEYMODIFIER(event->type)) {
screen->do_draw_drag = true;
}
else if (event->type == EVT_ESCKEY) {
WM_drag_free_list(&wm->drags);
WM_drag_stop(wm);
screen->do_draw_drag = true;
}
else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
wm_event_free_customdata_if_necessary(event);
event->type = EVT_DROP;
WM_drag_transfer_ownership_to_event(wm, event);
/* create customdata, first free existing */
if (event->customdata) {
if (event->customdatafree) {
MEM_freeN(event->customdata);
}
}
event->custom = EVT_DATA_DRAGDROP;
event->customdata = &wm->drags;
event->customdatafree = 1;
/* clear drop icon */
screen->do_draw_drag = true;
/* restore cursor (disabled, see wm_dragdrop.c) */
// WM_cursor_modal_restore(win);
}
}
@@ -3297,7 +3282,7 @@ void wm_event_do_handlers(bContext *C)
}
}
/* check dragging, creates new event or frees, adds draw tag */
/* may change the event into a drop event, adds draw tag */
wm_event_drag_and_drop_test(wm, win, event);
/* builtin tweak, if action is break it removes tweak */
@@ -3346,12 +3331,10 @@ void wm_event_do_handlers(bContext *C)
/* call even on non mouse events, since the */
wm_region_mouse_co(C, event);
if (!BLI_listbase_is_empty(&wm->drags)) {
/* does polls for drop regions and checks uibuts */
/* need to be here to make sure region context is true */
if (ELEM(event->type, MOUSEMOVE, EVT_DROP) || ISKEYMODIFIER(event->type)) {
wm_drags_check_ops(C, event);
}
if (wm->drag.data) {
if (wm->drag.target)
WM_drop_target_free(wm->drag.target);
wm->drag.target = WM_drag_find_current_target(C, wm->drag.data, event);
}
action |= wm_handlers_do(C, event, &region->handlers);
@@ -3906,26 +3889,18 @@ void WM_event_free_ui_handler_all(bContext *C,
}
}
wmEventHandler_Dropbox *WM_event_add_dropbox_handler(ListBase *handlers, ListBase *dropboxes)
void WM_event_ensure_drop_handler(ListBase *handlers)
{
/* only allow same dropbox once */
LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) {
if (handler_base->type == WM_HANDLER_TYPE_DROPBOX) {
wmEventHandler_Dropbox *handler = (wmEventHandler_Dropbox *)handler_base;
if (handler->dropboxes == dropboxes) {
return handler;
}
return;
}
}
wmEventHandler_Dropbox *handler = MEM_callocN(sizeof(*handler), __func__);
handler->head.type = WM_HANDLER_TYPE_DROPBOX;
/* dropbox stored static, no free or copy */
handler->dropboxes = dropboxes;
BLI_addhead(handlers, handler);
return handler;
}
/* XXX solution works, still better check the real cause (ton) */

View File

@@ -536,7 +536,6 @@ void WM_exit_ex(bContext *C, const bool do_python)
wm_operatortype_free();
wm_surfaces_free();
wm_dropbox_free();
WM_menutype_free();
WM_uilisttype_free();

View File

@@ -721,11 +721,6 @@ static void wm_window_ghostwindow_ensure(wmWindowManager *wm, wmWindow *win, boo
keymap = WM_keymap_ensure(wm->defaultconf, "Screen Editing", 0, 0);
WM_event_add_keymap_handler(&win->modalhandlers, keymap);
/* add drop boxes */
{
ListBase *lb = WM_dropboxmap_find("Window", 0, 0);
WM_event_add_dropbox_handler(&win->handlers, lb);
}
wm_window_title(wm, win);
/* add topbar */
@@ -1480,36 +1475,24 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
win->active = 1;
wm_event_add(win, &event);
/* make blender drop event with custom data pointing to wm drags */
event.type = EVT_DROP;
event.val = KM_RELEASE;
event.custom = EVT_DATA_DRAGDROP;
event.customdata = &wm->drags;
event.customdatafree = 1;
wm_event_add(win, &event);
/* printf("Drop detected\n"); */
/* add drag data to wm for paths: */
/* first initialize the dragging */
if (ddd->dataType == GHOST_kDragnDropTypeFilenames) {
GHOST_TStringArray *stra = ddd->data;
int a, icon;
for (a = 0; a < stra->count; a++) {
printf("drop file %s\n", stra->strings[a]);
/* try to get icon type from extension */
icon = ED_file_extension_icon((char *)stra->strings[a]);
WM_event_start_drag(C, icon, WM_DRAG_PATH, stra->strings[a], 0.0, WM_DRAG_NOP);
/* void poin should point to string, it makes a copy */
break; /* only one drop element supported now */
if (stra->count > 0) {
WM_drag_start_filepaths(C, (const char **)stra->strings, stra->count);
}
}
/* then drop it immediatly */
event.type = EVT_DROP;
event.val = KM_RELEASE;
event.shift = query_qual(SHIFT) ? true : false;
event.ctrl = query_qual(CONTROL) ? true : false;
event.alt = query_qual(ALT) ? true : false;
event.oskey = query_qual(OS) ? true : false;
WM_drag_transfer_ownership_to_event(wm, &event);
wm_event_add(win, &event);
break;
}
case GHOST_kEventNativeResolutionChange: {

View File

@@ -160,9 +160,7 @@ void wm_tablet_data_from_ghost(const struct GHOST_TabletData *tablet_data, wmTab
/* wm_keymap.c */
/* wm_dropbox.c */
void wm_dropbox_free(void);
void wm_drags_check_ops(bContext *C, const wmEvent *event);
void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect);
/* wm_dragdrop.c */
void WM_drag_draw(bContext *C, wmWindow *win, struct wmDragOperation *drag_operation);
#endif /* __WM_EVENT_SYSTEM_H__ */