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