Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_outliner/outliner_ops.c')
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c388
1 files changed, 8 insertions, 380 deletions
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index 0dd492839c9..34d79ea5a61 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -55,353 +55,6 @@
#include "outliner_intern.h"
-typedef struct OutlinerDragDropTooltip {
- TreeElement *te;
- void *handle;
-} OutlinerDragDropTooltip;
-
-enum {
- OUTLINER_ITEM_DRAG_CANCEL,
- OUTLINER_ITEM_DRAG_CONFIRM,
-};
-
-static bool outliner_item_drag_drop_poll(bContext *C)
-{
- SpaceOops *soops = CTX_wm_space_outliner(C);
- return ED_operator_outliner_active(C) &&
- /* Only collection display modes supported for now. Others need more design work */
- ELEM(soops->outlinevis, SO_VIEW_LAYER, SO_LIBRARIES);
-}
-
-static TreeElement *outliner_item_drag_element_find(SpaceOops *soops, ARegion *ar, const wmEvent *event)
-{
- /* note: using EVT_TWEAK_ events to trigger dragging is fine,
- * it sends coordinates from where dragging was started */
- const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]);
- return outliner_find_item_at_y(soops, &soops->tree, my);
-}
-
-static void outliner_item_drag_end(wmWindow *win, OutlinerDragDropTooltip *data)
-{
- MEM_SAFE_FREE(data->te->drag_data);
-
- if (data->handle) {
- WM_draw_cb_exit(win, data->handle);
- }
-
- MEM_SAFE_FREE(data);
-}
-
-static void outliner_item_drag_get_insert_data(
- const SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged,
- TreeElement **r_te_insert_handle, TreeElementInsertType *r_insert_type)
-{
- TreeElement *te_hovered;
- float view_mval[2];
-
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
- te_hovered = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]);
-
- if (te_hovered) {
- /* mouse hovers an element (ignoring x-axis), now find out how to insert the dragged item exactly */
-
- if (te_hovered == te_dragged) {
- *r_te_insert_handle = te_dragged;
- }
- else if (te_hovered != te_dragged) {
- const float margin = UI_UNIT_Y * (1.0f / 4);
-
- *r_te_insert_handle = te_hovered;
- if (view_mval[1] < (te_hovered->ys + margin)) {
- if (TSELEM_OPEN(TREESTORE(te_hovered), soops)) {
- /* inserting after a open item means we insert into it, but as first child */
- if (BLI_listbase_is_empty(&te_hovered->subtree)) {
- *r_insert_type = TE_INSERT_INTO;
- }
- else {
- *r_insert_type = TE_INSERT_BEFORE;
- *r_te_insert_handle = te_hovered->subtree.first;
- }
- }
- else {
- *r_insert_type = TE_INSERT_AFTER;
- }
- }
- else if (view_mval[1] > (te_hovered->ys + (3 * margin))) {
- *r_insert_type = TE_INSERT_BEFORE;
- }
- else {
- *r_insert_type = TE_INSERT_INTO;
- }
- }
- }
- else {
- /* mouse doesn't hover any item (ignoring x-axis), so it's either above list bounds or below. */
-
- TreeElement *first = soops->tree.first;
- TreeElement *last = soops->tree.last;
-
- if (view_mval[1] < last->ys) {
- *r_te_insert_handle = last;
- *r_insert_type = TE_INSERT_AFTER;
- }
- else if (view_mval[1] > (first->ys + UI_UNIT_Y)) {
- *r_te_insert_handle = first;
- *r_insert_type = TE_INSERT_BEFORE;
- }
- else {
- BLI_assert(0);
- }
- }
-}
-
-static void outliner_item_drag_handle(
- SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged)
-{
- TreeElement *te_insert_handle;
- TreeElementInsertType insert_type;
-
- outliner_item_drag_get_insert_data(soops, ar, event, te_dragged, &te_insert_handle, &insert_type);
-
- if (!te_dragged->reinsert_poll &&
- /* there is no reinsert_poll, so we do some generic checks (same types and reinsert callback is available) */
- (TREESTORE(te_dragged)->type == TREESTORE(te_insert_handle)->type) &&
- te_dragged->reinsert)
- {
- /* pass */
- }
- else if (te_dragged == te_insert_handle) {
- /* nothing will happen anyway, no need to do poll check */
- }
- else if (!te_dragged->reinsert_poll ||
- !te_dragged->reinsert_poll(te_dragged, &te_insert_handle, &insert_type))
- {
- te_insert_handle = NULL;
- }
- te_dragged->drag_data->insert_type = insert_type;
- te_dragged->drag_data->insert_handle = te_insert_handle;
-}
-
-/**
- * Returns true if it is a collection and empty.
- */
-static bool is_empty_collection(TreeElement *te)
-{
- Collection *collection = outliner_collection_from_tree_element(te);
-
- if (!collection) {
- return false;
- }
-
- return BLI_listbase_is_empty(&collection->gobject) &&
- BLI_listbase_is_empty(&collection->children);
-}
-
-static bool outliner_item_drag_drop_apply(
- Main *bmain,
- Scene *scene,
- SpaceOops *soops,
- OutlinerDragDropTooltip *data,
- const wmEvent *event)
-{
- TreeElement *dragged_te = data->te;
- TreeElement *insert_handle = dragged_te->drag_data->insert_handle;
- TreeElementInsertType insert_type = dragged_te->drag_data->insert_type;
-
- if ((insert_handle == dragged_te) || !insert_handle) {
- /* No need to do anything */
- }
- else if (dragged_te->reinsert) {
- BLI_assert(!dragged_te->reinsert_poll || dragged_te->reinsert_poll(dragged_te, &insert_handle,
- &insert_type));
- /* call of assert above should not have changed insert_handle and insert_type at this point */
- BLI_assert(dragged_te->drag_data->insert_handle == insert_handle &&
- dragged_te->drag_data->insert_type == insert_type);
-
- /* If the collection was just created and you moved objects/collections inside it,
- * it is strange to have it closed and we not see the newly dragged elements. */
- const bool should_open_collection = (insert_type == TE_INSERT_INTO) && is_empty_collection(insert_handle);
-
- dragged_te->reinsert(bmain, scene, soops, dragged_te, insert_handle, insert_type, event);
-
- if (should_open_collection && !is_empty_collection(insert_handle)) {
- TREESTORE(insert_handle)->flag &= ~TSE_CLOSED;
- }
- return true;
- }
-
- return false;
-}
-
-static int outliner_item_drag_drop_modal(bContext *C, wmOperator *op, const wmEvent *event)
-{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ARegion *ar = CTX_wm_region(C);
- SpaceOops *soops = CTX_wm_space_outliner(C);
- OutlinerDragDropTooltip *data = op->customdata;
- TreeElement *te_dragged = data->te;
- int retval = OPERATOR_RUNNING_MODAL;
- bool redraw = false;
- bool skip_rebuild = true;
-
- switch (event->type) {
- case EVT_MODAL_MAP:
- if (event->val == OUTLINER_ITEM_DRAG_CONFIRM) {
- if (outliner_item_drag_drop_apply(bmain, scene, soops, data, event)) {
- skip_rebuild = false;
- }
- retval = OPERATOR_FINISHED;
- }
- else if (event->val == OUTLINER_ITEM_DRAG_CANCEL) {
- retval = OPERATOR_CANCELLED;
- }
- else {
- BLI_assert(0);
- }
- WM_event_add_mousemove(C); /* update highlight */
- outliner_item_drag_end(CTX_wm_window(C), data);
- redraw = true;
- break;
- case MOUSEMOVE:
- outliner_item_drag_handle(soops, ar, event, te_dragged);
- redraw = true;
- break;
- }
-
- if (redraw) {
- if (skip_rebuild) {
- ED_region_tag_redraw_no_rebuild(ar);
- }
- else {
- ED_region_tag_redraw(ar);
- }
- }
-
- return retval;
-}
-
-static const char *outliner_drag_drop_tooltip_get(
- const TreeElement *te_float)
-{
- const char *name = NULL;
-
- const TreeElement *te_insert = te_float->drag_data->insert_handle;
- if (te_float && outliner_is_collection_tree_element(te_float)) {
- if (te_insert == NULL) {
- name = TIP_("Move collection");
- }
- else {
- switch (te_float->drag_data->insert_type) {
- case TE_INSERT_BEFORE:
- if (te_insert->prev && outliner_is_collection_tree_element(te_insert->prev)) {
- name = TIP_("Move between collections");
- }
- else {
- name = TIP_("Move before collection");
- }
- break;
- case TE_INSERT_AFTER:
- if (te_insert->next && outliner_is_collection_tree_element(te_insert->next)) {
- name = TIP_("Move between collections");
- }
- else {
- name = TIP_("Move after collection");
- }
- break;
- case TE_INSERT_INTO:
- name = TIP_("Move inside collection");
- break;
- }
- }
- }
- else if ((TREESTORE(te_float)->type == 0) && (te_float->idcode == ID_OB)) {
- name = TIP_("Move to collection (Ctrl to link)");
- }
-
- return name;
-}
-
-static void outliner_drag_drop_tooltip_cb(const wmWindow *win, void *vdata)
-{
- OutlinerDragDropTooltip *data = vdata;
- const char *tooltip;
-
- int cursorx, cursory;
- int x, y;
-
- tooltip = outliner_drag_drop_tooltip_get(data->te);
- if (tooltip == NULL) {
- return;
- }
-
- cursorx = win->eventstate->x;
- cursory = win->eventstate->y;
-
- x = cursorx + U.widget_unit;
- y = cursory - U.widget_unit;
-
- /* Drawing. */
- 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};
-
- GPU_blend(true);
- UI_fontstyle_draw_simple_backdrop(fstyle, x, y, tooltip, col_fg, col_bg);
- GPU_blend(false);
-}
-
-static int outliner_item_drag_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
- ARegion *ar = CTX_wm_region(C);
- SpaceOops *soops = CTX_wm_space_outliner(C);
- TreeElement *te_dragged = outliner_item_drag_element_find(soops, ar, event);
-
- if (!te_dragged) {
- return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
- }
-
- OutlinerDragDropTooltip *data = MEM_mallocN(sizeof(OutlinerDragDropTooltip), __func__);
- data->te = te_dragged;
-
- op->customdata = data;
- te_dragged->drag_data = MEM_callocN(sizeof(*te_dragged->drag_data), __func__);
- /* by default we don't change the item position */
- te_dragged->drag_data->insert_handle = te_dragged;
- /* unset highlighted tree element, dragged one will be highlighted instead */
- outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED, false);
-
- ED_region_tag_redraw_no_rebuild(ar);
-
- WM_event_add_modal_handler(C, op);
-
- data->handle = WM_draw_cb_activate(CTX_wm_window(C), outliner_drag_drop_tooltip_cb, data);
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-/**
- * Notes about Outliner Item Drag 'n Drop:
- * Right now only collections display mode is supported. But ideally all/most modes would support this. There are
- * just some open design questions that have to be answered: do we want to allow mixing order of different data types
- * (like render-layers and objects)? Would that be a purely visual change or would that have any other effect? ...
- */
-static void OUTLINER_OT_item_drag_drop(wmOperatorType *ot)
-{
- ot->name = "Drag and Drop";
- ot->idname = "OUTLINER_OT_item_drag_drop";
- ot->description = "Change the hierarchical position of an item by repositioning it using drag and drop";
-
- ot->invoke = outliner_item_drag_drop_invoke;
- ot->modal = outliner_item_drag_drop_modal;
-
- ot->poll = outliner_item_drag_drop_poll;
-
- ot->flag = OPTYPE_UNDO;
-}
-
-
/* ************************** registration **********************************/
void outliner_operatortypes(void)
@@ -457,37 +110,11 @@ void outliner_operatortypes(void)
WM_operatortype_append(OUTLINER_OT_collection_link);
WM_operatortype_append(OUTLINER_OT_collection_instance);
WM_operatortype_append(OUTLINER_OT_collection_exclude_set);
- WM_operatortype_append(OUTLINER_OT_collection_include_set);
-}
-
-static wmKeyMap *outliner_item_drag_drop_modal_keymap(wmKeyConfig *keyconf)
-{
- static EnumPropertyItem modal_items[] = {
- {OUTLINER_ITEM_DRAG_CANCEL, "CANCEL", 0, "Cancel", ""},
- {OUTLINER_ITEM_DRAG_CONFIRM, "CONFIRM", 0, "Confirm/Drop", ""},
- {0, NULL, 0, NULL, NULL}
- };
- const char *map_name = "Outliner Item Drag & Drop Modal Map";
-
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, map_name);
-
- /* this function is called for each spacetype, only needs to add map once */
- if (keymap && keymap->modal_items)
- return NULL;
-
- keymap = WM_modalkeymap_add(keyconf, map_name, modal_items);
-
- /* items for modal map */
- WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, OUTLINER_ITEM_DRAG_CANCEL);
- WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, OUTLINER_ITEM_DRAG_CANCEL);
-
- WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, OUTLINER_ITEM_DRAG_CONFIRM);
- WM_modalkeymap_add_item(keymap, RETKEY, KM_RELEASE, KM_ANY, 0, OUTLINER_ITEM_DRAG_CONFIRM);
- WM_modalkeymap_add_item(keymap, PADENTER, KM_RELEASE, KM_ANY, 0, OUTLINER_ITEM_DRAG_CONFIRM);
-
- WM_modalkeymap_assign(keymap, "OUTLINER_OT_item_drag_drop");
-
- return keymap;
+ WM_operatortype_append(OUTLINER_OT_collection_exclude_clear);
+ WM_operatortype_append(OUTLINER_OT_collection_holdout_set);
+ WM_operatortype_append(OUTLINER_OT_collection_holdout_clear);
+ WM_operatortype_append(OUTLINER_OT_collection_indirect_only_set);
+ WM_operatortype_append(OUTLINER_OT_collection_indirect_only_clear);
}
void outliner_keymap(wmKeyConfig *keyconf)
@@ -570,12 +197,13 @@ void outliner_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OBJECT_OT_move_to_collection", MKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_link_to_collection", MKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "OUTLINER_OT_collection_exclude_set", EKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "OUTLINER_OT_collection_exclude_clear", EKEY, KM_PRESS, KM_ALT, 0);
+
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "select", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "unselected", true);
-
- outliner_item_drag_drop_modal_keymap(keyconf);
}