diff --git a/material_maker/doc/user_interface_shortcuts.rst b/material_maker/doc/user_interface_shortcuts.rst index 403d95a93..9e503f1b3 100644 --- a/material_maker/doc/user_interface_shortcuts.rst +++ b/material_maker/doc/user_interface_shortcuts.rst @@ -84,6 +84,9 @@ Graph Editor +-------------------------------------------------------+----------------------------------------------------+ | :kbd:`Ctrl/Cmd-Shift-F` | Frame selected node(s) | +-------------------------------------------------------+----------------------------------------------------+ +| :kbd:`Alt-LMB` | Centers graph view to input aperture node | +| | (from output aperture nodes) | ++-------------------------------------------------------+----------------------------------------------------+ | :kbd:`F` | Color selected comment/aperture node(s) | +-------------------------------------------------------+----------------------------------------------------+ | :kbd:`C` | Centers view | diff --git a/material_maker/nodes/portal/portal.gd b/material_maker/nodes/portal/portal.gd index 0116b2bfe..018963245 100644 --- a/material_maker/nodes/portal/portal.gd +++ b/material_maker/nodes/portal/portal.gd @@ -9,6 +9,8 @@ var is_editing := false var syncing_io := false +var is_navigating_source : bool = false + func _ready() -> void: super._ready() get_titlebar_hbox().get_children().map(func(n): n.hide()) @@ -76,22 +78,63 @@ func _exit_tree() -> void: node.reset_slot() func _gui_input(event : InputEvent) -> void: - if event is InputEventMouseButton and event.double_click: + if event is InputEventMouseButton and event.double_click and not event.alt_pressed: setup_portal_edit() +func mouse_in_node_rect() -> bool: + return Rect2(Vector2.ZERO, size).has_point(get_local_mouse_position()) + +func mouse_in_label_rect() -> bool: + return %Dragger.get_rect().has_point(get_local_mouse_position()) + +func set_link_hint(enabled : bool) -> void: + if is_portal_out(): + for node : Control in [self, %Dragger]: + node.mouse_default_cursor_shape = CURSOR_POINTING_HAND if enabled else CURSOR_ARROW + +func jump_to_source() -> void: + if is_navigating_source or is_portal_in(): + return + is_navigating_source = true + set_link_hint(false) + var graph : MMGraphEdit = get_parent() + if not graph: + return + var source_portal : MMGraphPortal = get_link_source(get_link(), graph) + if source_portal != null: + graph.scroll_offset = (source_portal.position_offset + + 0.5 * source_portal.size) * graph.zoom - 0.5 * graph.size + + var tween : Tween = get_tree().create_tween() + tween.tween_property(source_portal, "modulate", Color(1.5, 1.5, 1.5, 1.0), 0.2).set_trans(Tween.TRANS_CUBIC) + tween.tween_property(source_portal, "modulate", Color.WHITE, 0.6).set_trans(Tween.TRANS_CUBIC).set_delay(0.5) + source_portal.set_deferred("selected", true) + await tween.finished + is_navigating_source = false + +func set_portal_tip_text() -> void: + const editing_tip : String = "Enter: Rename, Ctrl/Cmd+Enter: Batch rename" + var normal_tip = "%s#LMB: Select node, #LMB#LMB/F2/Enter: Rename" + normal_tip = normal_tip % ["Alt + #LMB: Jump to source, " if is_portal_out() else ""] + if mouse_in_node_rect(): + mm_globals.set_tip_text(tr(normal_tip), 1.0, 2) + elif mouse_in_label_rect(): + mm_globals.set_tip_text(tr(editing_tip if is_editing else normal_tip), 1.0, 2) + func _input(event : InputEvent) -> void: - if event is InputEventKey and event.pressed and selected and not is_editing: + if event is InputEventKey: match event.get_keycode_with_modifiers(): KEY_F2, KEY_ENTER: - setup_portal_edit() + if event.pressed and selected and not is_editing: + setup_portal_edit() + KEY_ALT: + set_link_hint(event.pressed) elif event is InputEventMouseMotion: - if Rect2(Vector2.ZERO, size).has_point(get_local_mouse_position()): - mm_globals.set_tip_text(tr("#LMB: Select node, #LMB#LMB/F2/Enter: Rename link"), 1.0, 2) - elif %Dragger.get_rect().has_point(get_local_mouse_position()): - if is_editing: - mm_globals.set_tip_text(tr("Enter: Rename link, Ctrl/Cmd+Enter: Batch rename links"), 1.0, 2) - else: - mm_globals.set_tip_text(tr("#LMB: Select node, #LMB#LMB: Rename link"), 1.0, 2) + set_portal_tip_text() + elif event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed: + if event.alt_pressed and (mouse_in_node_rect() or mouse_in_label_rect()): + accept_event() + jump_to_source() func _on_dragger_gui_input(event : InputEvent) -> void: if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT: