hand show and hide
This commit is contained in:
@@ -82,6 +82,7 @@ func _setup_ui() -> void:
|
||||
hand_display.card_hovered.connect(_on_hand_card_hovered)
|
||||
hand_display.card_unhovered.connect(_on_hand_card_unhovered)
|
||||
hand_display.card_selected.connect(_on_hand_card_selected)
|
||||
hand_display.hand_minimized_changed.connect(_on_hand_minimized_changed)
|
||||
|
||||
# Create damage displays (positioned by 3D camera overlay later)
|
||||
for i in range(2):
|
||||
@@ -89,18 +90,25 @@ func _setup_ui() -> void:
|
||||
damage_displays.append(damage_display)
|
||||
|
||||
func _position_hand_display() -> void:
|
||||
# Get viewport size and position hand at bottom
|
||||
var viewport = get_viewport()
|
||||
if viewport:
|
||||
# get_visible_rect() gives the coordinate space for 2D content
|
||||
# With canvas_items + expand, this is the expanded design space
|
||||
var vp_size = viewport.get_visible_rect().size
|
||||
# Hand cards are 195x273px (triple original), positioned at y=0 in container
|
||||
var card_height = 273.0
|
||||
var hand_height = card_height + 25.0 # Extra space for hover lift
|
||||
var is_min = hand_display and hand_display.is_minimized
|
||||
|
||||
# Position so card bottom is 100px above viewport bottom
|
||||
var bottom_offset = 100.0
|
||||
hand_display.position = Vector2(10, vp_size.y - bottom_offset - card_height)
|
||||
hand_display.size = Vector2(vp_size.x - 20, hand_height)
|
||||
var card_height = 273.0
|
||||
if is_min:
|
||||
# Minimized: push cards down so only the top portion peeks up
|
||||
var peek_height = 65.0 # How much of the card top is visible
|
||||
hand_display.position = Vector2(10, vp_size.y - peek_height)
|
||||
hand_display.size = Vector2(vp_size.x - 20, card_height + 25.0)
|
||||
else:
|
||||
# Full hand: cards at the bottom of the screen
|
||||
var hand_height = card_height + 25.0 # Extra space for hover lift
|
||||
var bottom_offset = 10.0
|
||||
hand_display.position = Vector2(10, vp_size.y - bottom_offset - card_height)
|
||||
hand_display.size = Vector2(vp_size.x - 20, hand_height)
|
||||
|
||||
if not viewport.size_changed.is_connected(_on_viewport_resized):
|
||||
viewport.size_changed.connect(_on_viewport_resized)
|
||||
@@ -108,12 +116,10 @@ func _position_hand_display() -> void:
|
||||
func _on_viewport_resized() -> void:
|
||||
var viewport = get_viewport()
|
||||
if viewport and hand_display:
|
||||
var vp_size = viewport.get_visible_rect().size
|
||||
var card_height = 273.0 # Triple size hand cards
|
||||
var hand_height = card_height + 25.0
|
||||
var bottom_offset = 100.0
|
||||
hand_display.position = Vector2(10, vp_size.y - bottom_offset - card_height)
|
||||
hand_display.size = Vector2(vp_size.x - 20, hand_height)
|
||||
_position_hand_display()
|
||||
|
||||
func _on_hand_minimized_changed(_minimized: bool) -> void:
|
||||
_position_hand_display()
|
||||
|
||||
func _connect_signals() -> void:
|
||||
# GameManager signals
|
||||
|
||||
@@ -8,6 +8,7 @@ signal card_action_requested(card_instance: CardInstance, action: String)
|
||||
signal card_hovered(card_instance: CardInstance)
|
||||
signal card_unhovered
|
||||
signal card_selected(card_instance: CardInstance) # Emitted when selection panel opens
|
||||
signal hand_minimized_changed(minimized: bool) # Emitted when minimize state changes
|
||||
|
||||
# Hand card visuals
|
||||
var hand_cards: Array[Control] = []
|
||||
@@ -32,6 +33,14 @@ var selected_card_panel: Panel = null
|
||||
var card_image_container: Control = null
|
||||
var action_menu: VBoxContainer = null
|
||||
|
||||
# Minimized hand state
|
||||
var is_minimized: bool = false
|
||||
var minimized_bar: HBoxContainer = null
|
||||
var minimized_items: Array = []
|
||||
var toggle_button: Button = null
|
||||
const MINIMIZED_BAR_HEIGHT: float = 30.0
|
||||
const MINIMIZED_ITEM_GAP: float = 4.0
|
||||
|
||||
# Debug visualization (set to true to see positioning markers)
|
||||
const DEBUG_MARKERS: bool = false
|
||||
var debug_container_outline: ColorRect = null
|
||||
@@ -41,6 +50,8 @@ func _ready() -> void:
|
||||
clip_contents = false # Allow cards to extend beyond container bounds
|
||||
resized.connect(_on_resized)
|
||||
_create_selection_ui()
|
||||
_create_toggle_button()
|
||||
_create_minimized_bar()
|
||||
if DEBUG_MARKERS:
|
||||
_create_debug_markers()
|
||||
|
||||
@@ -91,6 +102,175 @@ func _create_selection_ui() -> void:
|
||||
selected_card_panel.size = Vector2(panel_width, panel_height)
|
||||
|
||||
|
||||
func _create_toggle_button() -> void:
|
||||
toggle_button = Button.new()
|
||||
toggle_button.text = "Hide Hand"
|
||||
toggle_button.custom_minimum_size = Vector2(90, 26)
|
||||
toggle_button.size = Vector2(90, 26)
|
||||
toggle_button.mouse_filter = Control.MOUSE_FILTER_STOP
|
||||
toggle_button.z_index = 150
|
||||
|
||||
toggle_button.add_theme_font_size_override("font_size", 11)
|
||||
toggle_button.add_theme_color_override("font_color", Color(0.8, 0.75, 0.65))
|
||||
toggle_button.add_theme_color_override("font_hover_color", Color(1.0, 0.95, 0.8))
|
||||
|
||||
var style_normal = StyleBoxFlat.new()
|
||||
style_normal.bg_color = Color(0.12, 0.12, 0.16, 0.85)
|
||||
style_normal.border_color = Color(0.4, 0.35, 0.25)
|
||||
style_normal.set_border_width_all(1)
|
||||
style_normal.set_corner_radius_all(4)
|
||||
toggle_button.add_theme_stylebox_override("normal", style_normal)
|
||||
|
||||
var style_hover = StyleBoxFlat.new()
|
||||
style_hover.bg_color = Color(0.18, 0.18, 0.24, 0.9)
|
||||
style_hover.border_color = Color(0.6, 0.5, 0.3)
|
||||
style_hover.set_border_width_all(1)
|
||||
style_hover.set_corner_radius_all(4)
|
||||
toggle_button.add_theme_stylebox_override("hover", style_hover)
|
||||
|
||||
var style_pressed = StyleBoxFlat.new()
|
||||
style_pressed.bg_color = Color(0.08, 0.08, 0.1, 0.9)
|
||||
style_pressed.border_color = Color(0.6, 0.5, 0.3)
|
||||
style_pressed.set_border_width_all(1)
|
||||
style_pressed.set_corner_radius_all(4)
|
||||
toggle_button.add_theme_stylebox_override("pressed", style_pressed)
|
||||
|
||||
toggle_button.pressed.connect(_on_toggle_hand)
|
||||
add_child(toggle_button)
|
||||
|
||||
func _create_minimized_bar() -> void:
|
||||
minimized_bar = HBoxContainer.new()
|
||||
minimized_bar.visible = false
|
||||
minimized_bar.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
minimized_bar.add_theme_constant_override("separation", int(MINIMIZED_ITEM_GAP))
|
||||
minimized_bar.z_index = 10
|
||||
add_child(minimized_bar)
|
||||
|
||||
func _on_toggle_hand() -> void:
|
||||
is_minimized = not is_minimized
|
||||
if is_minimized:
|
||||
toggle_button.text = "Show Hand"
|
||||
_deselect_card()
|
||||
# Cards stay visible — Main.gd will reposition so only tops peek up
|
||||
else:
|
||||
toggle_button.text = "Hide Hand"
|
||||
_layout_cards()
|
||||
_position_toggle_button()
|
||||
hand_minimized_changed.emit(is_minimized)
|
||||
|
||||
func _update_minimized_bar() -> void:
|
||||
# Clear previous items
|
||||
for child in minimized_bar.get_children():
|
||||
child.queue_free()
|
||||
minimized_items.clear()
|
||||
|
||||
for i in range(card_instances.size()):
|
||||
var card = card_instances[i]
|
||||
var item = _create_minimized_item(card, i)
|
||||
minimized_bar.add_child(item)
|
||||
minimized_items.append(item)
|
||||
|
||||
# Position the bar centered at the bottom
|
||||
call_deferred("_position_minimized_bar")
|
||||
|
||||
func _create_minimized_item(card: CardInstance, index: int) -> PanelContainer:
|
||||
var item = PanelContainer.new()
|
||||
item.mouse_filter = Control.MOUSE_FILTER_STOP
|
||||
|
||||
var style = StyleBoxFlat.new()
|
||||
style.bg_color = Color(0.1, 0.1, 0.14, 0.9)
|
||||
style.border_color = Color(0.3, 0.3, 0.35)
|
||||
style.set_border_width_all(1)
|
||||
style.set_corner_radius_all(3)
|
||||
style.content_margin_left = 4
|
||||
style.content_margin_right = 8
|
||||
style.content_margin_top = 2
|
||||
style.content_margin_bottom = 2
|
||||
item.add_theme_stylebox_override("panel", style)
|
||||
|
||||
var hbox = HBoxContainer.new()
|
||||
hbox.add_theme_constant_override("separation", 5)
|
||||
hbox.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
item.add_child(hbox)
|
||||
|
||||
# Cost crystal — element-colored circle with cost number
|
||||
var crystal = Panel.new()
|
||||
crystal.custom_minimum_size = Vector2(22, 22)
|
||||
crystal.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
var crystal_style = StyleBoxFlat.new()
|
||||
var elem_color = Enums.get_element_color(card.card_data.get_primary_element())
|
||||
crystal_style.bg_color = elem_color
|
||||
crystal_style.set_corner_radius_all(11)
|
||||
crystal_style.set_border_width_all(1)
|
||||
crystal_style.border_color = elem_color.lightened(0.3)
|
||||
crystal.add_theme_stylebox_override("panel", crystal_style)
|
||||
|
||||
var cost_label = Label.new()
|
||||
cost_label.text = str(card.card_data.cost)
|
||||
cost_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
cost_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
cost_label.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
cost_label.add_theme_font_size_override("font_size", 12)
|
||||
cost_label.add_theme_color_override("font_color", Color.WHITE)
|
||||
cost_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
crystal.add_child(cost_label)
|
||||
hbox.add_child(crystal)
|
||||
|
||||
# Card name
|
||||
var name_label = Label.new()
|
||||
name_label.text = card.card_data.name
|
||||
name_label.add_theme_font_size_override("font_size", 12)
|
||||
name_label.add_theme_color_override("font_color", Color(0.85, 0.82, 0.72))
|
||||
name_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
hbox.add_child(name_label)
|
||||
|
||||
# Click to expand hand and select this card
|
||||
item.gui_input.connect(_on_minimized_item_input.bind(index))
|
||||
|
||||
return item
|
||||
|
||||
func _on_minimized_item_input(event: InputEvent, index: int) -> void:
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
||||
# Expand hand and select the clicked card
|
||||
is_minimized = false
|
||||
toggle_button.text = "Hide Hand"
|
||||
minimized_bar.visible = false
|
||||
for card_ui in hand_cards:
|
||||
card_ui.visible = true
|
||||
_layout_cards()
|
||||
_position_toggle_button()
|
||||
hand_minimized_changed.emit(false)
|
||||
_select_card(index)
|
||||
|
||||
func _position_toggle_button() -> void:
|
||||
if not toggle_button:
|
||||
return
|
||||
var display_width = size.x
|
||||
if display_width <= 0:
|
||||
var viewport = get_viewport()
|
||||
if viewport:
|
||||
display_width = viewport.get_visible_rect().size.x - 20
|
||||
# Position toggle button: right side, above hand area
|
||||
if is_minimized:
|
||||
# Above the minimized bar
|
||||
toggle_button.position = Vector2(display_width - toggle_button.size.x - 5, -toggle_button.size.y - 4)
|
||||
else:
|
||||
# Above the full hand
|
||||
toggle_button.position = Vector2(display_width - toggle_button.size.x - 5, -toggle_button.size.y - 4)
|
||||
|
||||
func _position_minimized_bar() -> void:
|
||||
if not minimized_bar:
|
||||
return
|
||||
var display_width = size.x
|
||||
if display_width <= 0:
|
||||
var viewport = get_viewport()
|
||||
if viewport:
|
||||
display_width = viewport.get_visible_rect().size.x - 20
|
||||
# Center the bar horizontally, positioned at top of hand container area
|
||||
var bar_width = minimized_bar.size.x
|
||||
minimized_bar.position = Vector2((display_width - bar_width) / 2.0, 0)
|
||||
|
||||
func _create_debug_markers() -> void:
|
||||
# Create a visible outline around the hand container bounds
|
||||
# RED = hand container area
|
||||
@@ -162,6 +342,8 @@ func update_hand(cards: Array) -> void:
|
||||
# Create card UI elements
|
||||
_create_card_visuals()
|
||||
|
||||
# Cards stay visible even when minimized — Main.gd handles positioning
|
||||
|
||||
# Defer layout to ensure size is set
|
||||
call_deferred("_layout_cards")
|
||||
|
||||
@@ -234,6 +416,8 @@ func _get_element_color(element: Enums.Element) -> Color:
|
||||
return color.lightened(0.4)
|
||||
|
||||
func _layout_cards() -> void:
|
||||
_position_toggle_button()
|
||||
|
||||
var card_count = hand_cards.size()
|
||||
if card_count == 0:
|
||||
return
|
||||
@@ -258,8 +442,8 @@ func _layout_cards() -> void:
|
||||
var x = start_x + i * CARD_OVERLAP
|
||||
var y = base_y
|
||||
|
||||
# Lift hovered card slightly
|
||||
if i == hovered_card_index and selected_card_index == -1:
|
||||
# Lift hovered card slightly (not when minimized)
|
||||
if i == hovered_card_index and selected_card_index == -1 and not is_minimized:
|
||||
y -= HOVER_LIFT # Lift by 15px
|
||||
|
||||
# Dim selected card in hand
|
||||
@@ -281,7 +465,15 @@ func _on_card_gui_input(event: InputEvent, index: int) -> void:
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
||||
if index >= 0 and index < card_instances.size():
|
||||
if selected_card_index == index:
|
||||
if is_minimized:
|
||||
# Clicking a peeking card expands the hand and selects it
|
||||
is_minimized = false
|
||||
toggle_button.text = "Hide Hand"
|
||||
hand_minimized_changed.emit(false)
|
||||
_layout_cards()
|
||||
_position_toggle_button()
|
||||
_select_card(index)
|
||||
elif selected_card_index == index:
|
||||
_deselect_card()
|
||||
else:
|
||||
_select_card(index)
|
||||
|
||||
Reference in New Issue
Block a user