diff --git a/Systems/CardDisplay.gd b/Systems/CardDisplay.gd index 2f4ef6d..e04501b 100644 --- a/Systems/CardDisplay.gd +++ b/Systems/CardDisplay.gd @@ -4,16 +4,27 @@ const CARD_WIDTH = 150 const CARD_HEIGHT = 250 const CARD_MARGIN = 10 -var cardDisplays = [] +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 first + # 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() @@ -21,45 +32,83 @@ func update_hand(hand: Array): add_card_display(card) func add_card_display(card): - var cardPanel = PanelContainer.new() - cardPanel.custom_minimum_size = Vector2(CARD_WIDTH, CARD_HEIGHT) + # 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) - cardPanel.add_child(vbox) + 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.custom_minimum_size = Vector2(CARD_WIDTH - 10, 0) + descLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + descLabel.custom_minimum_size = Vector2(CARD_WIDTH - 20, 0) vbox.add_child(descLabel) - var unitWhitelistLabel = Label.new() - unitWhitelistLabel.text = ", ".join(card.unitWhitelist) - unitWhitelistLabel.autowrap_mode = TextServer.AUTOWRAP_WORD - unitWhitelistLabel.custom_minimum_size = Vector2(CARD_WIDTH - 10, 0) - vbox.add_child(unitWhitelistLabel) - - var idLabel = Label.new() - idLabel.text = card.id.substr(card.id.length() - 8, -1) - idLabel.autowrap_mode = true - idLabel.custom_minimum_size = Vector2(CARD_WIDTH - 10, 0) - vbox.add_child(idLabel) - - cardPanel.gui_input.connect(func(event): _on_card_clicked(event, card)) + # 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) - cardDisplays.append(cardPanel) - container.add_child(cardPanel) + # 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: @@ -70,29 +119,71 @@ func _on_card_clicked(event: InputEvent, card: Card): 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 display in cardDisplays: + for card_data in cardDisplays: + var panel = card_data.panel var style = StyleBoxFlat.new() style.bg_color = Utils.DARK_CELL # Default color - var vbox = display.get_child(0) - if selected && vbox.get_meta("card_id") == selected.id: + # 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 - display.add_theme_stylebox_override("panel", style) + panel.add_theme_stylebox_override("panel", style) func get_card_by_uuid(uuid: String) -> Card: - for display in cardDisplays: - var vbox = display.get_child(0) - if vbox.get_meta("card_id") == uuid: - return selectedCard + 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 display in cardDisplays: - display.queue_free() + for card_data in cardDisplays: + card_data.panel.queue_free() cardDisplays.clear() selectedCard = null \ No newline at end of file diff --git a/Systems/CardPreview.gd b/Systems/CardPreview.gd index f6fe7d2..35b8511 100644 --- a/Systems/CardPreview.gd +++ b/Systems/CardPreview.gd @@ -6,88 +6,55 @@ const PREVIEW_HEIGHT = 200 const SCREEN_MARGIN = 20 var currentCard: Card = null -var previewPanel: PanelContainer +var previewPanel: CardPreviewPanel +var movesRemainingLabel: Label func _init() -> void: - previewPanel = PanelContainer.new() - previewPanel.custom_minimum_size = Vector2(PREVIEW_WIDTH, PREVIEW_HEIGHT) + + previewPanel = preload("res://card_preview_panel.tscn").instantiate() position = Vector2(0, 0) - var vbox = VBoxContainer.new() - previewPanel.add_child(vbox) - - var style = StyleBoxFlat.new() - style.bg_color = Color(0.2, 0.2, 0.2, 0.9) - style.corner_radius_top_left = 10 - style.corner_radius_top_right = 10 - style.corner_radius_bottom_left = 10 - style.corner_radius_bottom_right = 10 - previewPanel.add_theme_stylebox_override("panel", style) - previewPanel.hide() + + # Add the preview panel as a child add_child(previewPanel) + + # Add a custom label for moves remaining that we'll show/hide as needed + movesRemainingLabel = Label.new() + movesRemainingLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + movesRemainingLabel.add_theme_font_size_override("font_size", 14) + movesRemainingLabel.visible = false + + # Add the label to the preview panel's content + var content = previewPanel.get_node("CardContent") + if content: + content.add_child(movesRemainingLabel) func show_card_preview(card: Card) -> void: if card == null: - previewPanel.hide() - currentCard = null + hide_preview() return currentCard = card - var vbox = previewPanel.get_child(0) - for child in vbox.get_children(): - child.queue_free() + # Use the preview_card method from CardPreviewPanel + previewPanel.preview_card(card) - var nameLabel = Label.new() - nameLabel.text = card.cardName - nameLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - nameLabel.add_theme_font_size_override("font_size", 18) - vbox.add_child(nameLabel) - - var rankLabel = Label.new() - rankLabel.text = "Rank " + str(card.rank) - rankLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - vbox.add_child(rankLabel) - - var idLabel = Label.new() - idLabel.text = "ID: " + card.id.substr(card.id.length() - 8, -1) - idLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - vbox.add_child(idLabel) - - var durationLabel = Label.new() - durationLabel.text = str(card.remaining_turns) + " turns remaining" - durationLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - vbox.add_child(durationLabel) - - var descLabel = Label.new() - descLabel.text = card.description - descLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - descLabel.autowrap_mode = TextServer.AUTOWRAP_WORD - descLabel.custom_minimum_size = Vector2(PREVIEW_WIDTH - 20, 0) - vbox.add_child(descLabel) - - previewPanel.show() + # Since we're showing a new card, hide the moves remaining label + movesRemainingLabel.visible = false func hide_preview() -> void: - previewPanel.hide() + previewPanel.hide_preview() currentCard = null + movesRemainingLabel.visible = false func update_moves_remaining(moves: int) -> void: if currentCard == null: return - - var vbox = previewPanel.get_child(0) - var movesLabel = Label.new() - movesLabel.text = "Moves remaining this turn: " + str(moves) - movesLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - # Remove old moves label if it exists - for child in vbox.get_children(): - if child.text.begins_with("Moves remaining this turn:"): - child.queue_free() - - vbox.add_child(movesLabel) \ No newline at end of file + # Update and show the moves remaining label + movesRemainingLabel.text = "Moves remaining this turn: " + str(moves) + movesRemainingLabel.visible = true \ No newline at end of file diff --git a/Systems/CardPreviewPanel.gd b/Systems/CardPreviewPanel.gd index b3311c8..002e2da 100644 --- a/Systems/CardPreviewPanel.gd +++ b/Systems/CardPreviewPanel.gd @@ -80,4 +80,4 @@ func preview_card(card: Card): visible = true func hide_preview(): - visible = false \ No newline at end of file + visible = false diff --git a/Systems/Game/ChessGame.gd b/Systems/Game/ChessGame.gd index 21bb759..f8008c2 100644 --- a/Systems/Game/ChessGame.gd +++ b/Systems/Game/ChessGame.gd @@ -257,7 +257,7 @@ func setupUI() -> void: var control_container = VBoxContainer.new() control_container.name = "ZoomControls" - control_container.position = Vector2(windowXSize - 350, windowYSize - 120) + control_container.position = Vector2(windowXSize - 100, windowYSize - 80) var h_container = HBoxContainer.new() h_container.add_child(zoom_out_button) diff --git a/Systems/Game/DeckManagerScreen.gd b/Systems/Game/DeckManagerScreen.gd index 04b976a..4d81ba8 100644 --- a/Systems/Game/DeckManagerScreen.gd +++ b/Systems/Game/DeckManagerScreen.gd @@ -10,7 +10,7 @@ signal back_pressed @onready var card_preview = $CardPreviewPanel # Default deck size (can be overridden via options) -var maxDeckSize = 35 +var maxDeckSize = 40 var deckManager = null var bankCards = [] # Cards available but not in deck diff --git a/card_preview_panel.tscn b/card_preview_panel.tscn index f1898c4..3969327 100644 --- a/card_preview_panel.tscn +++ b/card_preview_panel.tscn @@ -48,6 +48,7 @@ horizontal_alignment = 1 layout_mode = 2 [node name="RankLabel" type="Label" parent="CardContent"] +custom_minimum_size = Vector2(0, 30) layout_mode = 2 theme_override_font_sizes/font_size = 18 text = "Rank 3 (Reused)"