Add hover hints for icon commands

This commit is contained in:
2026-06-20 08:52:26 +09:00
parent 0787de0031
commit ab9d8d849b
2 changed files with 186 additions and 0 deletions

View File

@@ -186,6 +186,10 @@ const HUD_COMMAND_GRID_SIZE := Vector2(420, 46)
const HUD_COMMAND_BUTTON_SIZE := Vector2(72, 42)
const HUD_COMMAND_GRID_COLUMNS := 4
const TOP_TOOL_BUTTON_SIZE := Vector2(46, 46)
const COMMAND_HINT_PANEL_SIZE := Vector2(246, 78)
const COMMAND_HINT_ICON_SIZE := Vector2(30, 30)
const COMMAND_HINT_TITLE_SIZE := Vector2(184, 22)
const COMMAND_HINT_DETAIL_SIZE := Vector2(208, 32)
const PREP_MENU_BUTTON_SIZE := Vector2(48, 38)
const BATTLE_UNIT_LIST_PANEL_SIZE := Vector2(420, 360)
const BATTLE_UNIT_LIST_ROW_SIZE := Vector2(372, 58)
@@ -541,6 +545,11 @@ var targeting_hint_title_label: Label
var targeting_hint_detail_label: Label
var targeting_hint_back_button: Button
var targeting_hint_cancel_move_button: Button
var command_hint_panel: PanelContainer
var command_hint_icon: TextureRect
var command_hint_title_label: Label
var command_hint_detail_label: Label
var command_hint_source_button: Button
var threat_button: Button
var battle_unit_list_button: Button
var battle_unit_list_panel: PanelContainer
@@ -1150,6 +1159,7 @@ func _configure_hud_command_button(button: Button, icon_kind: String = "") -> vo
button.expand_icon = true
button.set_meta("icon_only", true)
button.set_meta("command_icon", icon_kind)
_connect_command_hint_button(button)
func _configure_top_tool_button(button: Button, node_name: String, icon_kind: String, tooltip: String) -> void:
@@ -1164,7 +1174,9 @@ func _configure_top_tool_button(button: Button, node_name: String, icon_kind: St
button.icon = _make_toolbar_icon(icon_kind)
button.expand_icon = true
button.set_meta("icon_only", true)
button.set_meta("command_icon", icon_kind)
button.add_theme_font_size_override("font_size", 1)
_connect_command_hint_button(button)
func _configure_title_menu_button(button: Button, node_name: String, icon_kind: String, label: String, tooltip: String, minimum_size: Vector2, important: bool = false) -> void:
@@ -1508,6 +1520,153 @@ func _format_local_command_tooltip(label: String, hint: String) -> String:
return "%s\n%s" % [normalized_label, normalized_hint]
func _connect_command_hint_button(button: Button) -> void:
if button == null or bool(button.get_meta("command_hint_connected", false)):
return
button.mouse_entered.connect(_on_command_hint_button_mouse_entered.bind(button))
button.mouse_exited.connect(_on_command_hint_button_mouse_exited)
button.set_meta("command_hint_connected", true)
func _create_command_hint_panel(root: Control) -> void:
if root == null:
return
command_hint_panel = PanelContainer.new()
command_hint_panel.name = "CommandHintPanel"
command_hint_panel.visible = false
command_hint_panel.mouse_filter = Control.MOUSE_FILTER_IGNORE
command_hint_panel.custom_minimum_size = COMMAND_HINT_PANEL_SIZE
command_hint_panel.size = COMMAND_HINT_PANEL_SIZE
_apply_panel_style(command_hint_panel, "target_hint")
root.add_child(command_hint_panel)
var row := HBoxContainer.new()
row.name = "CommandHintRow"
row.custom_minimum_size = Vector2(COMMAND_HINT_PANEL_SIZE.x - 22.0, COMMAND_HINT_PANEL_SIZE.y - 18.0)
row.add_theme_constant_override("separation", 8)
command_hint_panel.add_child(row)
command_hint_icon = TextureRect.new()
command_hint_icon.name = "CommandHintIcon"
command_hint_icon.custom_minimum_size = COMMAND_HINT_ICON_SIZE
command_hint_icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
command_hint_icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
row.add_child(command_hint_icon)
var text_column := VBoxContainer.new()
text_column.name = "CommandHintText"
text_column.add_theme_constant_override("separation", 2)
row.add_child(text_column)
command_hint_title_label = Label.new()
command_hint_title_label.name = "CommandHintTitle"
command_hint_title_label.custom_minimum_size = COMMAND_HINT_TITLE_SIZE
command_hint_title_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT
_apply_label_style(command_hint_title_label, UI_OLD_BRONZE, LOCAL_COMMAND_TITLE_FONT_SIZE)
text_column.add_child(command_hint_title_label)
command_hint_detail_label = Label.new()
command_hint_detail_label.name = "CommandHintDetail"
command_hint_detail_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
command_hint_detail_label.custom_minimum_size = COMMAND_HINT_DETAIL_SIZE
_apply_label_style(command_hint_detail_label, UI_PARCHMENT_TEXT, LOCAL_COMMAND_DETAIL_FONT_SIZE)
text_column.add_child(command_hint_detail_label)
func _on_command_hint_button_mouse_entered(button: Button) -> void:
_show_command_hint_for_button(button)
func _on_command_hint_button_mouse_exited() -> void:
_hide_command_hint()
func _show_command_hint_for_button(button: Button) -> void:
if command_hint_panel == null or button == null or not is_instance_valid(button):
return
var label := _command_hint_button_label(button)
var detail := _command_hint_button_detail(button)
if label.is_empty() and detail.is_empty():
_hide_command_hint()
return
var tooltip := _format_local_command_tooltip(label, detail)
command_hint_source_button = button
command_hint_panel.visible = true
command_hint_panel.tooltip_text = tooltip
command_hint_panel.position = _command_hint_panel_position(button)
command_hint_panel.move_to_front()
if command_hint_title_label != null:
_set_fitted_label_text(command_hint_title_label, label, LOCAL_COMMAND_TITLE_FONT_SIZE, LOCAL_COMMAND_TITLE_MIN_FONT_SIZE, COMMAND_HINT_TITLE_SIZE)
command_hint_title_label.tooltip_text = tooltip
if command_hint_detail_label != null:
_set_fitted_label_text(command_hint_detail_label, detail, LOCAL_COMMAND_DETAIL_FONT_SIZE, LOCAL_COMMAND_DETAIL_MIN_FONT_SIZE, COMMAND_HINT_DETAIL_SIZE)
command_hint_detail_label.tooltip_text = tooltip
if command_hint_icon != null:
command_hint_icon.texture = _make_toolbar_icon(str(button.get_meta("command_icon", "status")))
command_hint_icon.tooltip_text = tooltip
_set_control_tree_tooltip(command_hint_panel, tooltip)
func _hide_command_hint() -> void:
command_hint_source_button = null
if command_hint_panel != null:
command_hint_panel.visible = false
func _refresh_command_hint_if_source(button: Button) -> void:
if command_hint_panel == null or not command_hint_panel.visible:
return
if command_hint_source_button == button:
_show_command_hint_for_button(button)
func _command_hint_button_label(button: Button) -> String:
var label := str(button.get_meta("command_label", "")).strip_edges()
if not label.is_empty():
return label
var tooltip_lines := str(button.tooltip_text).split("\n", false)
if not tooltip_lines.is_empty():
return str(tooltip_lines[0]).strip_edges()
return str(button.text).strip_edges()
func _command_hint_button_detail(button: Button) -> String:
if bool(button.disabled):
var disabled_hint := str(button.get_meta("disabled_hint", "")).strip_edges()
var command_hint := str(button.get_meta("command_hint", "")).strip_edges()
if not command_hint.is_empty():
return command_hint
if not disabled_hint.is_empty():
return disabled_hint
var hint := str(button.get_meta("command_hint", "")).strip_edges()
if not hint.is_empty():
return hint
var tooltip_lines := str(button.tooltip_text).split("\n", false)
if tooltip_lines.size() > 1:
var detail_lines: Array[String] = []
for index in range(1, tooltip_lines.size()):
detail_lines.append(str(tooltip_lines[index]).strip_edges())
return _join_strings(detail_lines, "\n")
return ""
func _command_hint_panel_position(button: Button) -> Vector2:
var button_rect := button.get_global_rect()
var viewport_size := _viewport_size_for_layout()
var panel_size := COMMAND_HINT_PANEL_SIZE
var gap := 8.0
var x := button_rect.position.x
if button_rect.get_center().x > viewport_size.x * 0.5:
x = button_rect.end.x - panel_size.x
var y := button_rect.end.y + gap
if y + panel_size.y > viewport_size.y - 10.0:
y = button_rect.position.y - panel_size.y - gap
return Vector2(
clampf(x, 10.0, maxf(10.0, viewport_size.x - panel_size.x - 10.0)),
clampf(y, 10.0, maxf(10.0, viewport_size.y - panel_size.y - 10.0))
)
func _make_top_hud_chip(node_name: String, icon_kind: String, chip_size: Vector2, variant: String) -> Dictionary:
var chip := PanelContainer.new()
chip.name = node_name
@@ -3361,6 +3520,8 @@ func _create_hud() -> void:
log_box.add_theme_stylebox_override("normal", _make_panel_style(Color(0.11, 0.07, 0.045, 0.78), UI_RICE_PAPER_DARK, 1, 6, 6, 0))
side_column.add_child(log_box)
_create_command_hint_panel(root)
screen_backdrop = _make_screen_backdrop()
root.add_child(screen_backdrop)
@@ -16041,6 +16202,7 @@ func _set_action_button_state(button: Button, label: String, disabled: bool, too
button.text = normalized_label
button.tooltip_text = normalized_tooltip
button.disabled = disabled
_refresh_command_hint_if_source(button)
func _set_action_button_blocked(button: Button, base_label: String, reason_label: String, tooltip: String) -> void:
@@ -16051,6 +16213,7 @@ func _set_action_button_blocked(button: Button, base_label: String, reason_label
_set_action_button_state(button, base_label, true, blocked_tooltip)
if button != null:
button.set_meta("disabled_hint", reason)
_refresh_command_hint_if_source(button)
func _action_phase_block_reason() -> Dictionary: