diff options
12 files changed, 126 insertions, 43 deletions
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index d9538930f33..55f60329a97 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -1909,19 +1909,19 @@ def km_node_editor(params): ("node.clipboard_paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None), ("node.viewer_border", {"type": 'B', "value": 'PRESS', "ctrl": True}, None), ("node.clear_viewer_border", {"type": 'B', "value": 'PRESS', "ctrl": True, "alt": True}, None), - ("node.translate_attach", {"type": 'G', "value": 'PRESS'}, None), - ("node.translate_attach", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, None), - ("node.translate_attach", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), + ("node.translate_attach", {"type": 'G', "value": 'PRESS'}, {"properties": [("TRANSFORM_OT_translate", [("view2d_edge_pan", True)])]}), + ("node.translate_attach", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, {"properties": [("TRANSFORM_OT_translate", [("view2d_edge_pan", True)])]}), + ("node.translate_attach", {"type": params.select_tweak, "value": 'ANY'}, {"properties": [("TRANSFORM_OT_translate", [("view2d_edge_pan", True)])]}), + ("transform.translate", {"type": 'G', "value": 'PRESS'}, {"properties": [("view2d_edge_pan", True)]}), ("transform.translate", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, - {"properties": [("release_confirm", True)]}), + {"properties": [("release_confirm", True), ("view2d_edge_pan", True)]}), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, - {"properties": [("release_confirm", True)]}), + {"properties": [("release_confirm", True), ("view2d_edge_pan", True)]}), ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), - ("node.move_detach_links", {"type": 'D', "value": 'PRESS', "alt": True}, None), - ("node.move_detach_links_release", {"type": params.action_tweak, "value": 'ANY', "alt": True}, None), - ("node.move_detach_links", {"type": params.select_tweak, "value": 'ANY', "alt": True}, None), + ("node.move_detach_links", {"type": 'D', "value": 'PRESS', "alt": True}, {"properties": [("TRANSFORM_OT_translate", [("view2d_edge_pan", True)])]}), + ("node.move_detach_links_release", {"type": params.action_tweak, "value": 'ANY', "alt": True}, {"properties": [("NODE_OT_translate_attach", [("TRANSFORM_OT_translate", [("view2d_edge_pan", True)])])]}), + ("node.move_detach_links", {"type": params.select_tweak, "value": 'ANY', "alt": True}, {"properties": [("TRANSFORM_OT_translate", [("view2d_edge_pan", True)])]}), ("wm.context_toggle", {"type": 'TAB', "value": 'PRESS', "shift": True}, {"properties": [("data_path", 'tool_settings.use_snap')]}), ("wm.context_menu_enum", {"type": 'TAB', "value": 'PRESS', "shift": True, "ctrl": True}, diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index 6e4002fcc0a..1d51a3e77cf 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -53,8 +53,9 @@ typedef enum { #define NODE_EDGE_PAN_INSIDE_PAD 2 #define NODE_EDGE_PAN_OUTSIDE_PAD 0 /* Disable clamping for node panning, use whole screen. */ #define NODE_EDGE_PAN_SPEED_RAMP 1 -#define NODE_EDGE_PAN_MAX_SPEED 40 /* In UI units per second, slower than default. */ -#define NODE_EDGE_PAN_DELAY 1.0f +#define NODE_EDGE_PAN_MAX_SPEED 26 /* In UI units per second, slower than default. */ +#define NODE_EDGE_PAN_DELAY 0.5f +#define NODE_EDGE_PAN_ZOOM_INFLUENCE 0.5f /* space_node.c */ diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index cb6fb0dba60..69ac48d842f 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -137,6 +137,7 @@ int BIF_countTransformOrientation(const struct bContext *C); #define P_GPENCIL_EDIT (1 << 13) #define P_CURSOR_EDIT (1 << 14) #define P_CLNOR_INVALIDATE (1 << 15) +#define P_VIEW2D_EDGE_PAN (1 << 16) /* For properties performed when confirming the transformation. */ #define P_POST_TRANSFORM (1 << 19) diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index 4ee7df89487..e3c02b4c249 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -26,6 +26,7 @@ #pragma once #include "BLI_compiler_attrs.h" +#include "BLI_rect.h" #ifdef __cplusplus extern "C" { @@ -321,6 +322,14 @@ typedef struct View2DEdgePanData { float max_speed; /** Delay in seconds before maximum speed is reached. */ float delay; + /** Influence factor for view zoom: + * 0 = Constant speed in UI units + * 1 = Constant speed in view space, UI speed slows down when zooming out + */ + float zoom_influence; + + /** Initial view rect. */ + rctf initial_rect; /** Amount to move view relative to zoom. */ float facx, facy; @@ -338,7 +347,8 @@ void UI_view2d_edge_pan_init(struct bContext *C, float outside_pad, float speed_ramp, float max_speed, - float delay); + float delay, + float zoom_influence); void UI_view2d_edge_pan_reset(struct View2DEdgePanData *vpd); @@ -350,6 +360,8 @@ void UI_view2d_edge_pan_apply_event(struct bContext *C, struct View2DEdgePanData *vpd, const struct wmEvent *event); +void UI_view2d_edge_pan_cancel(struct bContext *C, struct View2DEdgePanData *vpd); + void UI_view2d_edge_pan_operator_properties(struct wmOperatorType *ot); void UI_view2d_edge_pan_operator_properties_ex(struct wmOperatorType *ot, @@ -357,7 +369,8 @@ void UI_view2d_edge_pan_operator_properties_ex(struct wmOperatorType *ot, float outside_pad, float speed_ramp, float max_speed, - float delay); + float delay, + float zoom_influence); /* Initialize panning data with operator settings. */ void UI_view2d_edge_pan_operator_init(struct bContext *C, diff --git a/source/blender/editors/interface/view2d_edge_pan.c b/source/blender/editors/interface/view2d_edge_pan.c index 1d300c7b275..eaf8ef30311 100644 --- a/source/blender/editors/interface/view2d_edge_pan.c +++ b/source/blender/editors/interface/view2d_edge_pan.c @@ -71,7 +71,8 @@ void UI_view2d_edge_pan_init(bContext *C, float outside_pad, float speed_ramp, float max_speed, - float delay) + float delay, + float zoom_influence) { if (!UI_view2d_edge_pan_poll(C)) { return; @@ -89,6 +90,7 @@ void UI_view2d_edge_pan_init(bContext *C, vpd->speed_ramp = speed_ramp; vpd->max_speed = max_speed; vpd->delay = delay; + vpd->zoom_influence = zoom_influence; /* Calculate translation factor, based on size of view. */ const float winx = (float)(BLI_rcti_size_x(&vpd->region->winrct) + 1); @@ -104,6 +106,7 @@ void UI_view2d_edge_pan_reset(View2DEdgePanData *vpd) vpd->edge_pan_start_time_x = 0.0; vpd->edge_pan_start_time_y = 0.0; vpd->edge_pan_last_time = PIL_check_seconds_timer(); + vpd->initial_rect = vpd->region->v2d.cur; } /** @@ -168,9 +171,15 @@ static float edge_pan_speed(View2DEdgePanData *vpd, /* Apply a fade in to the speed based on a start time delay. */ const double start_time = x_dir ? vpd->edge_pan_start_time_x : vpd->edge_pan_start_time_y; - const float delay_factor = smootherstep(vpd->delay, (float)(current_time - start_time)); + const float delay_factor = vpd->delay > 0.01f ? + smootherstep(vpd->delay, (float)(current_time - start_time)) : + 1.0f; - return distance_factor * delay_factor * vpd->max_speed * U.widget_unit * (float)U.dpi_fac; + /* Zoom factor increases speed when zooming in and decreases speed when zooming out. */ + const float zoomx = (float)(BLI_rcti_size_x(®ion->winrct) + 1) / BLI_rctf_size_x(®ion->v2d.cur); + const float zoom_factor = 1.0f + CLAMPIS(vpd->zoom_influence, 0.0f, 1.0f) * (zoomx - 1.0f); + + return distance_factor * delay_factor * zoom_factor * vpd->max_speed * U.widget_unit * (float)U.dpi_fac; } static void edge_pan_apply_delta(bContext *C, View2DEdgePanData *vpd, float dx, float dy) @@ -264,6 +273,27 @@ void UI_view2d_edge_pan_apply_event(bContext *C, View2DEdgePanData *vpd, const w UI_view2d_edge_pan_apply(C, vpd, event->x, event->y); } +void UI_view2d_edge_pan_cancel(bContext *C, View2DEdgePanData *vpd) +{ + View2D *v2d = vpd->v2d; + if (!v2d) { + return; + } + + v2d->cur = vpd->initial_rect; + + /* Inform v2d about changes after this operation. */ + UI_view2d_curRect_changed(C, v2d); + + /* Don't rebuild full tree in outliner, since we're just changing our view. */ + ED_region_tag_redraw_no_rebuild(vpd->region); + + /* Request updates to be done. */ + WM_event_add_mousemove(CTX_wm_window(C)); + + UI_view2d_sync(vpd->screen, vpd->area, v2d, V2D_LOCK_COPY); +} + void UI_view2d_edge_pan_operator_properties(wmOperatorType *ot) { /* Default values for edge panning operators. */ @@ -272,7 +302,8 @@ void UI_view2d_edge_pan_operator_properties(wmOperatorType *ot) /*outside_pad*/ 0.0f, /*speed_ramp*/ 1.0f, /*max_speed*/ 500.0f, - /*delay*/ 1.0f); + /*delay*/ 1.0f, + /*zoom_influence*/ 0.0f); } void UI_view2d_edge_pan_operator_properties_ex(struct wmOperatorType *ot, @@ -280,7 +311,8 @@ void UI_view2d_edge_pan_operator_properties_ex(struct wmOperatorType *ot, float outside_pad, float speed_ramp, float max_speed, - float delay) + float delay, + float zoom_influence) { RNA_def_float( ot->srna, @@ -329,6 +361,15 @@ void UI_view2d_edge_pan_operator_properties_ex(struct wmOperatorType *ot, "Delay in seconds before maximum speed is reached", 0.0f, 10.0f); + RNA_def_float(ot->srna, + "zoom_influence", + zoom_influence, + 0.0f, + 1.0f, + "Zoom Influence", + "Influence of the zoom factor on scroll speed", + 0.0f, + 1.0f); } void UI_view2d_edge_pan_operator_init(bContext *C, View2DEdgePanData *vpd, wmOperator *op) @@ -339,7 +380,8 @@ void UI_view2d_edge_pan_operator_init(bContext *C, View2DEdgePanData *vpd, wmOpe RNA_float_get(op->ptr, "outside_padding"), RNA_float_get(op->ptr, "speed_ramp"), RNA_float_get(op->ptr, "max_speed"), - RNA_float_get(op->ptr, "delay")); + RNA_float_get(op->ptr, "delay"), + RNA_float_get(op->ptr, "zoom_influence")); } /** \} */ diff --git a/source/blender/editors/space_node/node_geometry_attribute_search.cc b/source/blender/editors/space_node/node_geometry_attribute_search.cc index a6901c21862..411719cf6c0 100644 --- a/source/blender/editors/space_node/node_geometry_attribute_search.cc +++ b/source/blender/editors/space_node/node_geometry_attribute_search.cc @@ -17,6 +17,7 @@ #include "BLI_index_range.hh" #include "BLI_listbase.h" #include "BLI_map.hh" +#include "BLI_rect.h" #include "BLI_set.hh" #include "BLI_string_ref.hh" #include "BLI_string_search.h" diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index c6c3ca27d6e..e908a61eed9 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -880,6 +880,8 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links) bNodeTree *ntree = snode->edittree; bNodeLinkDrag *nldrag = (bNodeLinkDrag *)op->customdata; bool do_tag_update = false; + /* View will be reset if no links connect. */ + bool reset_view = true; /* avoid updates while applying links */ ntree->is_updating = true; @@ -917,6 +919,8 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links) if (link->tonode) { do_tag_update |= (do_tag_update || node_connected_to_output(bmain, ntree, link->tonode)); } + + reset_view = false; } else { nodeRemLink(ntree, link); @@ -930,6 +934,10 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links) snode_dag_update(C, snode); } + if (reset_view) { + UI_view2d_edge_pan_cancel(C, &nldrag->pan_data); + } + BLI_remlink(&snode->runtime->linkdrag, nldrag); /* links->data pointers are either held by the tree or freed already */ BLI_freelistN(&nldrag->links); @@ -1207,6 +1215,8 @@ static void node_link_cancel(bContext *C, wmOperator *op) BLI_remlink(&snode->runtime->linkdrag, nldrag); + UI_view2d_edge_pan_cancel(C, &nldrag->pan_data); + BLI_freelistN(&nldrag->links); MEM_freeN(nldrag); clear_picking_highlight(&snode->edittree->links); @@ -1258,7 +1268,8 @@ void NODE_OT_link(wmOperatorType *ot) NODE_EDGE_PAN_OUTSIDE_PAD, NODE_EDGE_PAN_SPEED_RAMP, NODE_EDGE_PAN_MAX_SPEED, - NODE_EDGE_PAN_DELAY); + NODE_EDGE_PAN_DELAY, + NODE_EDGE_PAN_ZOOM_INFLUENCE); } /** \} */ diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 4069a72a8fc..7a83fb71c28 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1671,6 +1671,13 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve } } + if ((prop = RNA_struct_find_property(op->ptr, "view2d_edge_pan")) && + RNA_property_is_set(op->ptr, prop)) { + if (RNA_property_boolean_get(op->ptr, prop)) { + options |= CTX_VIEW2D_EDGE_PAN; + } + } + t->options = options; t->mode = mode; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 549ad770ac6..013c5faa54a 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -94,6 +94,8 @@ typedef enum { CTX_OBMODE_XFORM_OBDATA = (1 << 12), /** Transform object parents without moving their children. */ CTX_OBMODE_XFORM_SKIP_CHILDREN = (1 << 13), + /** Enable edge scrolling in 2D views */ + CTX_VIEW2D_EDGE_PAN = (1 << 14), } eTContext; /** #TransInfo.flag */ diff --git a/source/blender/editors/transform/transform_convert_node.c b/source/blender/editors/transform/transform_convert_node.c index 9d2d3713bf0..ecc7f01be33 100644 --- a/source/blender/editors/transform/transform_convert_node.c +++ b/source/blender/editors/transform/transform_convert_node.c @@ -46,12 +46,6 @@ /** \name Node Transform Creation * \{ */ -typedef struct NodeTransCustomData { - /* Initial rect of the view2d, used for computing offset during edge panning */ - rctf initial_v2d_cur; - View2DEdgePanData edge_pan; -} NodeTransCustomData; - /* transcribe given node into TransData2D for Transforming */ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node, const float dpi_fac) { @@ -115,21 +109,16 @@ void createTransNodeData(TransInfo *t) const float dpi_fac = UI_DPI_FAC; SpaceNode *snode = t->area->spacedata.first; - if (t->mode == TFM_TRANSLATION) { - /* Disable cursor wrapping in the node editor for edge pan */ - t->flag |= T_NO_CURSOR_WRAP; - } - /* Custom data to enable edge panning during the node transform */ - NodeTransCustomData *customdata = MEM_callocN(sizeof(*customdata), __func__); + View2DEdgePanData *customdata = MEM_callocN(sizeof(*customdata), __func__); UI_view2d_edge_pan_init(t->context, - &customdata->edge_pan, + customdata, NODE_EDGE_PAN_INSIDE_PAD, NODE_EDGE_PAN_OUTSIDE_PAD, NODE_EDGE_PAN_SPEED_RAMP, NODE_EDGE_PAN_MAX_SPEED, - NODE_EDGE_PAN_DELAY); - customdata->initial_v2d_cur = t->region->v2d.cur; + NODE_EDGE_PAN_DELAY, + NODE_EDGE_PAN_ZOOM_INFLUENCE); t->custom.type.data = customdata; t->custom.type.use_free = true; @@ -176,17 +165,22 @@ void flushTransNodes(TransInfo *t) { const float dpi_fac = UI_DPI_FAC; - NodeTransCustomData *customdata = (NodeTransCustomData *)t->custom.type.data; + View2DEdgePanData *customdata = (View2DEdgePanData *)t->custom.type.data; - if (t->mode == TFM_TRANSLATION) { - /* Edge panning functions expect window coordinates, mval is relative to region */ - const float x = t->region->winrct.xmin + t->mval[0]; - const float y = t->region->winrct.ymin + t->mval[1]; - UI_view2d_edge_pan_apply(t->context, &customdata->edge_pan, x, y); + if (t->options & CTX_VIEW2D_EDGE_PAN) { + if (t->state == TRANS_CANCEL) { + UI_view2d_edge_pan_cancel(t->context, customdata); + } + else { + /* Edge panning functions expect window coordinates, mval is relative to region */ + const float x = t->region->winrct.xmin + t->mval[0]; + const float y = t->region->winrct.ymin + t->mval[1]; + UI_view2d_edge_pan_apply(t->context, customdata, x, y); + } } /* Initial and current view2D rects for additional transform due to view panning and zooming */ - const rctf *rect_src = &customdata->initial_v2d_cur; + const rctf *rect_src = &customdata->initial_rect; const rctf *rect_dst = &t->region->v2d.cur; FOREACH_TRANS_DATA_CONTAINER (t, tc) { diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 81fc1496b1a..9f5e74db501 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -625,6 +625,11 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve } #endif + /* Disable cursor wrap when edge panning is enabled. */ + if (t->options & CTX_VIEW2D_EDGE_PAN) { + t->flag |= T_NO_CURSOR_WRAP; + } + setTransformViewAspect(t, t->aspect); if (op && (prop = RNA_struct_find_property(op->ptr, "center_override")) && diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 45c077b8a07..cbc2adf641f 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -709,6 +709,11 @@ void Transform_Properties(struct wmOperatorType *ot, int flags) RNA_def_property_ui_text(prop, "Center Override", "Force using this center value (when set)"); } + if (flags & P_VIEW2D_EDGE_PAN) { + prop = RNA_def_boolean(ot->srna, "view2d_edge_pan", false, "Edge Pan", "Enable edge panning in 2D view"); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + } + if ((flags & P_NO_DEFAULTS) == 0) { prop = RNA_def_boolean(ot->srna, "release_confirm", @@ -754,7 +759,8 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot) Transform_Properties(ot, P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP | - P_OPTIONS | P_GPENCIL_EDIT | P_CURSOR_EDIT | P_POST_TRANSFORM); + P_OPTIONS | P_GPENCIL_EDIT | P_CURSOR_EDIT | P_VIEW2D_EDGE_PAN | + P_POST_TRANSFORM); } static void TRANSFORM_OT_resize(struct wmOperatorType *ot) |