172 lines
6.4 KiB
GDScript
172 lines
6.4 KiB
GDScript
class_name CardDisplay extends Control
|
|
|
|
# Base card dimensions
|
|
const BASE_CARD_WIDTH = 150
|
|
const BASE_CARD_HEIGHT = 250
|
|
const CARD_MARGIN = 10
|
|
const MAX_HAND_WIDTH_RATIO = 0.7 # Maximum portion of screen width to use for hand
|
|
|
|
var cardDisplays = [] # Array of {panel: Node, card: Card}
|
|
var selectedCard = null
|
|
var container: HBoxContainer
|
|
var cardPreviewScene = preload("res://card_preview_panel.tscn")
|
|
var currently_hovered_card = null
|
|
# Preview card panel instance for hovering
|
|
var hoveredPreview: CardPreviewPanel = null
|
|
var isPreviewVisible = false
|
|
|
|
func _ready():
|
|
# Create the container for the hand
|
|
container = HBoxContainer.new()
|
|
container.name = "Hand"
|
|
container.position = Vector2(10, 500)
|
|
container.size_flags_horizontal = SIZE_EXPAND_FILL
|
|
add_child(container)
|
|
|
|
# Create a hover preview panel that will follow the mouse
|
|
hoveredPreview = cardPreviewScene.instantiate()
|
|
hoveredPreview.visible = false
|
|
add_child(hoveredPreview)
|
|
|
|
func update_hand(hand: Array):
|
|
clear_cards()
|
|
|
|
# Calculate card sizes based on hand size and screen width
|
|
var card_size = calculate_card_size(hand.size())
|
|
|
|
for card in hand:
|
|
add_card_display(card, card_size)
|
|
|
|
func calculate_card_size(hand_size: int) -> Vector2:
|
|
# Get screen dimensions
|
|
var screen_width = get_viewport_rect().size.x
|
|
var screen_height = get_viewport_rect().size.y
|
|
|
|
var max_hand_width = screen_width * MAX_HAND_WIDTH_RATIO
|
|
var width_per_card = max_hand_width / max(hand_size, 1)
|
|
|
|
# Ensure minimum size and preserve aspect ratio
|
|
var card_width = clamp(width_per_card - CARD_MARGIN, 80, BASE_CARD_WIDTH)
|
|
var card_height = card_width * (BASE_CARD_HEIGHT / BASE_CARD_WIDTH)
|
|
|
|
# Ensure cards don't extend off the bottom of the screen
|
|
var max_height = screen_height * 0.4 # Use at most 40% of screen height
|
|
if card_height > max_height:
|
|
card_height = max_height
|
|
card_width = card_height * (BASE_CARD_WIDTH / BASE_CARD_HEIGHT)
|
|
|
|
return Vector2(card_width, card_height)
|
|
|
|
func add_card_display(card, card_size: Vector2 = Vector2(BASE_CARD_WIDTH, BASE_CARD_HEIGHT)):
|
|
# Create a container for the card
|
|
var cardContainer = PanelContainer.new()
|
|
cardContainer.custom_minimum_size = card_size
|
|
|
|
# Create a stylebox for selection highlighting
|
|
var style = StyleBoxFlat.new()
|
|
style.bg_color = Utils.DARK_CELL
|
|
style.corner_radius_top_left = 5
|
|
style.corner_radius_top_right = 5
|
|
style.corner_radius_bottom_left = 5
|
|
style.corner_radius_bottom_right = 5
|
|
cardContainer.add_theme_stylebox_override("panel", style)
|
|
|
|
# Create compact card display
|
|
var compact_card = CompactCardDisplay.new()
|
|
compact_card.set_anchors_preset(Control.PRESET_FULL_RECT)
|
|
compact_card.mouse_filter = Control.MOUSE_FILTER_PASS
|
|
|
|
# Add to container
|
|
cardContainer.add_child(compact_card)
|
|
compact_card.set_card(card)
|
|
|
|
# Connect signals
|
|
cardContainer.gui_input.connect(func(event): _on_card_clicked(event, card))
|
|
cardContainer.mouse_entered.connect(func(): _on_card_mouse_entered(card))
|
|
cardContainer.mouse_exited.connect(func(): _on_card_mouse_exited())
|
|
|
|
# Add to hand container
|
|
container.add_child(cardContainer)
|
|
|
|
# Add to display list
|
|
cardDisplays.append({
|
|
"panel": cardContainer,
|
|
"card": card
|
|
})
|
|
|
|
func _on_card_clicked(event: InputEvent, card: Card):
|
|
if event is InputEventMouseButton and event.pressed:
|
|
if selectedCard == null || selectedCard.id != card.id:
|
|
selectedCard = card
|
|
container.emit_signal("card_pressed", card)
|
|
elif selectedCard.id == card.id:
|
|
selectedCard = null
|
|
highlight_selectedCard(selectedCard)
|
|
|
|
func _on_card_mouse_entered( card: Card):
|
|
# Show card preview when hovering
|
|
# print("_on_card_mouse_entered")
|
|
currently_hovered_card = card
|
|
hoveredPreview.preview_card(card)
|
|
hoveredPreview.visible = true
|
|
|
|
# Position it above the hand area
|
|
var mouse_pos = get_viewport().get_mouse_position()
|
|
hoveredPreview.position = Vector2(mouse_pos.x - hoveredPreview.size.x/2, mouse_pos.y - hoveredPreview.size.y - 20)
|
|
|
|
# Make sure it's visible within screen bounds
|
|
hoveredPreview.position.x = clamp(hoveredPreview.position.x, 10, get_viewport_rect().size.x - hoveredPreview.size.x - 10)
|
|
hoveredPreview.position.y = clamp(hoveredPreview.position.y, 10, get_viewport_rect().size.y - hoveredPreview.size.y - 10)
|
|
|
|
isPreviewVisible = true
|
|
|
|
func _on_card_mouse_exited():
|
|
# Only hide the preview after a delay and if we're not hovering over a new card
|
|
var exited_card = currently_hovered_card
|
|
currently_hovered_card = null
|
|
|
|
# Wait a bit before hiding
|
|
await get_tree().create_timer(0.2).timeout
|
|
|
|
# Only hide if we're not hovering over a new card
|
|
if exited_card == currently_hovered_card or currently_hovered_card == null:
|
|
hoveredPreview.visible = false
|
|
isPreviewVisible = false
|
|
|
|
func _process(delta):
|
|
# If preview is visible, update its position to follow the mouse
|
|
if isPreviewVisible:
|
|
var mouse_pos = get_viewport().get_mouse_position()
|
|
hoveredPreview.position = Vector2(mouse_pos.x - hoveredPreview.size.x/2, mouse_pos.y - hoveredPreview.size.y - 20)
|
|
hoveredPreview.position.x = clamp(hoveredPreview.position.x, 10, get_viewport_rect().size.x - hoveredPreview.size.x - 10)
|
|
hoveredPreview.position.y = clamp(hoveredPreview.position.y, 10, get_viewport_rect().size.y - hoveredPreview.size.y - 10)
|
|
|
|
func highlight_selectedCard(selected: Card) -> void:
|
|
for card_data in cardDisplays:
|
|
var panel = card_data.panel
|
|
var compact_card = panel.get_child(0) as CompactCardDisplay
|
|
|
|
if selected && card_data.card.id == selected.id:
|
|
|
|
# Apply highlighting to the CompactCardDisplay
|
|
if compact_card:
|
|
compact_card.set_selected(true)
|
|
else:
|
|
# Reset highlighting
|
|
if compact_card:
|
|
compact_card.set_selected(false)
|
|
|
|
func get_card_by_uuid(uuid: String) -> Card:
|
|
for card_data in cardDisplays:
|
|
if card_data.card.id == uuid:
|
|
return card_data.card
|
|
return null
|
|
|
|
func getSelectedCard() -> Card:
|
|
return selectedCard
|
|
|
|
func clear_cards():
|
|
for card_data in cardDisplays:
|
|
card_data.panel.queue_free()
|
|
cardDisplays.clear()
|
|
selectedCard = null
|