ChessBuilder/Systems/CardDisplay.gd
2025-03-03 01:11:21 -06:00

189 lines
No EOL
7 KiB
GDScript

class_name CardDisplay extends Control
const CARD_WIDTH = 150
const CARD_HEIGHT = 250
const CARD_MARGIN = 10
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.custom_minimum_size = Vector2(0, CARD_HEIGHT)
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()
for card in hand:
add_card_display(card)
func add_card_display(card):
# Create a container for the card
var cardContainer = PanelContainer.new()
cardContainer.custom_minimum_size = Vector2(CARD_WIDTH, CARD_HEIGHT)
# 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 a simplified card view
var vbox = VBoxContainer.new()
vbox.set_meta("card_id", card.id)
cardContainer.add_child(vbox)
# Card name
var nameLabel = Label.new()
nameLabel.text = card.cardName
nameLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
nameLabel.add_theme_font_size_override("font_size", 16)
vbox.add_child(nameLabel)
# Card rank with color
var rankLabel = Label.new()
rankLabel.text = "Rank " + str(card.rank)
rankLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
# Apply color based on rank
match card.rank:
Card.Rank.RANK_0:
rankLabel.add_theme_color_override("font_color", Color(0.9, 0.1, 0.1, 1.0)) # Red
Card.Rank.RANK_1:
rankLabel.add_theme_color_override("font_color", Color(0.9, 0.6, 0.1, 1.0)) # Orange
Card.Rank.RANK_2:
rankLabel.add_theme_color_override("font_color", Color(0.1, 0.7, 0.1, 1.0)) # Green
Card.Rank.RANK_3:
rankLabel.add_theme_color_override("font_color", Color(0.1, 0.7, 0.9, 1.0)) # Blue
vbox.add_child(rankLabel)
# Card description (truncated)
var descLabel = Label.new()
descLabel.text = card.description
if descLabel.text.length() > 50:
descLabel.text = descLabel.text.substr(0, 50) + "..."
descLabel.autowrap_mode = TextServer.AUTOWRAP_WORD
descLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
descLabel.custom_minimum_size = Vector2(CARD_WIDTH - 20, 0)
vbox.add_child(descLabel)
# Unit whitelist
var unitLabel = Label.new()
if card.unitWhitelist.is_empty():
unitLabel.text = "Any piece"
else:
unitLabel.text = ", ".join(card.unitWhitelist)
unitLabel.autowrap_mode = TextServer.AUTOWRAP_WORD
unitLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
unitLabel.custom_minimum_size = Vector2(CARD_WIDTH - 20, 0)
vbox.add_child(unitLabel)
# Connect signals
cardContainer.gui_input.connect(func(event): _on_card_clicked(event, card))
# Connect hover signals for preview
cardContainer.mouse_entered.connect(func(): _on_card_mouse_entered(card))
cardContainer.mouse_exited.connect(func(): _on_card_mouse_exited())
# Add to display list
cardDisplays.append({
"panel": cardContainer,
"card": card
})
container.add_child(cardContainer)
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
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 style = StyleBoxFlat.new()
style.bg_color = Utils.DARK_CELL # Default color
# Style corners
style.corner_radius_top_left = 5
style.corner_radius_top_right = 5
style.corner_radius_bottom_left = 5
style.corner_radius_bottom_right = 5
if selected && card_data.card.id == selected.id:
style.bg_color = Color(0.4, 0.6, 0.4, 1) # Selected color
panel.add_theme_stylebox_override("panel", style)
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