Skip to content

Add focus indicator for blocks #179

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion addons/block_code/drag_manager/drag.gd
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const BlockCanvas = preload("res://addons/block_code/ui/block_canvas/block_canva
const Constants = preload("res://addons/block_code/ui/constants.gd")
const InstructionTree = preload("res://addons/block_code/instruction_tree/instruction_tree.gd")
const Types = preload("res://addons/block_code/types/types.gd")
const Util = preload("res://addons/block_code/ui/util.gd")

enum DragAction { NONE, PLACE, REMOVE }

Expand Down Expand Up @@ -33,7 +34,7 @@ var target_snap_point: SnapPoint:

var snap_block: Block:
get:
return target_snap_point.get_parent_block() if target_snap_point else null
return Util.get_parent_block(target_snap_point) if target_snap_point else null


func _init(block: Block, block_scope: String, offset: Vector2, block_canvas: BlockCanvas):
Expand Down
1 change: 1 addition & 0 deletions addons/block_code/drag_manager/drag_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func drag_ended():

if block:
connect_block_canvas_signals(block)
block.grab_focus()

_block_canvas.release_scope()

Expand Down
1 change: 1 addition & 0 deletions addons/block_code/ui/blocks/block/block.gd
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func _set_bottom_snap_path(value: NodePath):
func _ready():
if bottom_snap == null:
_set_bottom_snap_path(bottom_snap_path)
focus_mode = FocusMode.FOCUS_ALL
mouse_filter = Control.MOUSE_FILTER_IGNORE


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

[node name="ControlBlock" type="MarginContainer"]
size_flags_horizontal = 0
focus_mode = 2
mouse_filter = 2
script = ExtResource("1_2hbir")
block_name = "control_block"
Expand Down
2 changes: 1 addition & 1 deletion addons/block_code/ui/blocks/entry_block/entry_block.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
[ext_resource type="Script" path="res://addons/block_code/ui/blocks/entry_block/entry_block.gd" id="2_3ik8h"]

[node name="EntryBlock" instance=ExtResource("1_byjbb")]
focus_mode = 2
script = ExtResource("2_3ik8h")
signal_name = ""
defaults = {}
block_name = "entry_block"
label = "EntryBlock"
block_type = 1
Expand Down
25 changes: 21 additions & 4 deletions addons/block_code/ui/blocks/parameter_block/parameter_block.gd
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
class_name ParameterBlock
extends Block

const Constants = preload("res://addons/block_code/ui/constants.gd")
const Util = preload("res://addons/block_code/ui/util.gd")

@export var block_format: String = ""
Expand All @@ -16,16 +17,24 @@ var param_name_input_pairs: Array
var param_input_strings: Dictionary # Only loaded from serialized
var spawned_by: ParameterOutput

var _panel_normal: StyleBox
var _panel_focus: StyleBox


func _ready():
super()

_panel_normal = _panel.get_theme_stylebox("panel").duplicate()
_panel_normal.bg_color = color
_panel_normal.border_color = color.darkened(0.2)

_panel_focus = _panel.get_theme_stylebox("panel").duplicate()
_panel_focus.bg_color = color
_panel_focus.border_color = Constants.FOCUS_BORDER_COLOR
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is indeed awkward since there are now 3 styleboxes including the one saved in the scene. Is it possible to have one stylebox in the code that duplicates the one in the scene and then just mutate the color properties on it instead of overriding back and forth? You could even go further and build the initial override in code instead of taking it from the scene, but I feel like people would prefer to edit the non-color properties in the editor.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is indeed awkward since there are now 3 styleboxes including the one saved in the scene. Is it possible to have one stylebox in the code that duplicates the one in the scene and then just mutate the color properties on it instead of overriding back and forth? You could even go further and build the initial override in code instead of taking it from the scene, but I feel like people would prefer to edit the non-color properties in the editor.

For reference, other Control nodes in Godot have several styleboxes, one per each style. For example Button has styleboxes for Normal, Pressed, Disabled, Focus.
Captura desde 2024-08-01 10-49-20

Copy link
Contributor Author

@dylanmccall dylanmccall Aug 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oooh, should we attach a bunch of different styleboxes and then use theme_type_variation to switch between them? Right now I have it swapping the stylebox for the "Panel" style, but looking at the documentation for that property I see…

The name of a theme type variation used by this Control to look up its own theme items. When empty, the class name of the node is used (e.g. Button for the Button control), as well as the class names of all parent classes (in order of inheritance).

… which helps me to understand why styleboxes have these two completely different naming schemes. But I'm still completely bewildered by how "focus" behaves, which is apparently drawn as an overlay, but does that mean it's a separate node that certain controls (but not the Panel control) show on focus? Or something weirder?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's certainly very interesting. I suppose that would be good because we'd be inheriting whatever Panel theme variation is in the project. I'm going to punt and keep what you have for now, but feel free to keep investigating how to better manage this!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I think I was misunderstanding what these things are, and I think I have the same confusion as this person: https://www.reddit.com/r/godot/comments/1bdc48p/i_am_confused_about_the_name_part_used_in_themes/. Unfortunately, the explanation is making my brain melt.


block_type = Types.BlockType.VALUE
if not Util.node_is_part_of_edited_scene(self):
var new_panel = _panel.get_theme_stylebox("panel").duplicate()
new_panel.bg_color = color
new_panel.border_color = color.darkened(0.2)
_panel.add_theme_stylebox_override("panel", new_panel)
_panel.add_theme_stylebox_override("panel", _panel_normal)

format()

Expand Down Expand Up @@ -73,3 +82,11 @@ static func get_scene_path():

func format():
param_name_input_pairs = StatementBlock.format_string(self, %HBoxContainer, block_format, defaults)


func _on_focus_entered():
_panel.add_theme_stylebox_override("panel", _panel_focus)


func _on_focus_exited():
_panel.add_theme_stylebox_override("panel", _panel_normal)
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ corner_radius_bottom_left = 16
offset_right = 16.0
offset_bottom = 8.0
size_flags_horizontal = 0
focus_mode = 2
mouse_filter = 2
script = ExtResource("1_0hajy")
defaults = null
block_name = "parameter_block"
label = "Param"
block_type = 3
Expand All @@ -46,4 +47,6 @@ unique_name_in_owner = true
layout_mode = 2
mouse_filter = 2

[connection signal="focus_entered" from="." to="." method="_on_focus_entered"]
[connection signal="focus_exited" from="." to="." method="_on_focus_exited"]
[connection signal="mouse_down" from="DragDropArea" to="." method="_on_drag_drop_area_mouse_down"]
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

[node name="StatementBlock" type="MarginContainer"]
size_flags_horizontal = 0
focus_mode = 2
mouse_filter = 2
script = ExtResource("1_6wvlf")
block_name = "statement_block"
Expand Down
12 changes: 10 additions & 2 deletions addons/block_code/ui/blocks/utilities/background/background.gd
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
extends Control

const Constants = preload("res://addons/block_code/ui/constants.gd")
const Util = preload("res://addons/block_code/ui/util.gd")

var outline_color: Color
var parent_block: Block

@export var color: Color:
set = _set_color
Expand Down Expand Up @@ -41,6 +43,12 @@ func _set_shift_bottom(new_shift_bottom):
queue_redraw()


func _ready():
parent_block = Util.get_parent_block(self)
parent_block.focus_entered.connect(queue_redraw)
parent_block.focus_exited.connect(queue_redraw)


func _draw():
var fill_polygon: PackedVector2Array
fill_polygon.append(Vector2(0.0, 0.0))
Expand Down Expand Up @@ -97,5 +105,5 @@ func _draw():
edge_polygon.append(Vector2(0.0, size.y + outline_middle))

draw_colored_polygon(fill_polygon, color)
draw_polyline(stroke_polygon, outline_color, Constants.OUTLINE_WIDTH)
draw_polyline(edge_polygon, outline_color, Constants.OUTLINE_WIDTH)
draw_polyline(stroke_polygon, Constants.FOCUS_BORDER_COLOR if parent_block.has_focus() else outline_color, Constants.OUTLINE_WIDTH)
draw_polyline(edge_polygon, Constants.FOCUS_BORDER_COLOR if parent_block.has_focus() else outline_color, Constants.OUTLINE_WIDTH)
12 changes: 10 additions & 2 deletions addons/block_code/ui/blocks/utilities/background/gutter.gd
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
extends Control

const Constants = preload("res://addons/block_code/ui/constants.gd")
const Util = preload("res://addons/block_code/ui/util.gd")

var outline_color: Color
var parent_block: Block

@export var color: Color:
set = _set_color
Expand All @@ -15,6 +17,12 @@ func _set_color(new_color):
queue_redraw()


func _ready():
parent_block = Util.get_parent_block(self)
parent_block.focus_entered.connect(queue_redraw)
parent_block.focus_exited.connect(queue_redraw)


func _draw():
var fill_polygon: PackedVector2Array
fill_polygon.append(Vector2(0.0, 0.0))
Expand All @@ -33,5 +41,5 @@ func _draw():
right_polygon.append(Vector2(size.x, size.y))

draw_colored_polygon(fill_polygon, color)
draw_polyline(left_polygon, outline_color, Constants.OUTLINE_WIDTH)
draw_polyline(right_polygon, outline_color, Constants.OUTLINE_WIDTH)
draw_polyline(left_polygon, Constants.FOCUS_BORDER_COLOR if parent_block.has_focus() else outline_color, Constants.OUTLINE_WIDTH)
draw_polyline(right_polygon, Constants.FOCUS_BORDER_COLOR if parent_block.has_focus() else outline_color, Constants.OUTLINE_WIDTH)
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,6 @@ func _ready():
_update_snapped_block_from_children()


func get_parent_block() -> Block:
var parent = get_parent()
while parent and not parent is Block:
parent = parent.get_parent()
return parent as Block


func _update_snapped_block_from_children():
# Temporary migration to set the snapped_block property based on children
# of this node.
Expand Down
2 changes: 2 additions & 0 deletions addons/block_code/ui/constants.gd
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ const KNOB_Z = 5.0
const CONTROL_MARGIN = 20.0
const OUTLINE_WIDTH = 3.0
const MINIMUM_SNAP_DISTANCE = 80.0

const FOCUS_BORDER_COLOR = Color(225, 242, 0)
8 changes: 8 additions & 0 deletions addons/block_code/ui/util.gd
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,11 @@ static func node_is_part_of_edited_scene(node: Node) -> bool:

var edited_scene_parent := tree.edited_scene_root.get_parent()
return edited_scene_parent and edited_scene_parent.is_ancestor_of(node)


## Get the nearest Block node that is a parent of the provided node.
static func get_parent_block(node: Node) -> Block:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ended up putting this in the new BlockTreeUtil class I made so as not to re-introduce a circular dependency. The Util class otherwise depends only on native classes.

var parent = node.get_parent()
while parent and not parent is Block:
parent = parent.get_parent()
return parent as Block