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