This commit is contained in:
2ManyProjects 2025-03-03 01:11:21 -06:00
parent 3d5aa8ade7
commit c3b166112b
6 changed files with 153 additions and 94 deletions

View file

@ -4,62 +4,111 @@ const CARD_WIDTH = 150
const CARD_HEIGHT = 250 const CARD_HEIGHT = 250
const CARD_MARGIN = 10 const CARD_MARGIN = 10
var cardDisplays = [] var cardDisplays = [] # Array of {panel: Node, card: Card}
var selectedCard = null var selectedCard = null
var container: HBoxContainer 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(): func _ready():
# Create the container first # Create the container for the hand
container = HBoxContainer.new() container = HBoxContainer.new()
container.name = "Hand" container.name = "Hand"
container.position = Vector2(10, 500) container.position = Vector2(10, 500)
container.custom_minimum_size = Vector2(0, CARD_HEIGHT)
add_child(container) 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): func update_hand(hand: Array):
clear_cards() clear_cards()
for card in hand: for card in hand:
add_card_display(card) add_card_display(card)
func add_card_display(card): func add_card_display(card):
var cardPanel = PanelContainer.new() # Create a container for the card
cardPanel.custom_minimum_size = Vector2(CARD_WIDTH, CARD_HEIGHT) 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() var vbox = VBoxContainer.new()
vbox.set_meta("card_id", card.id) vbox.set_meta("card_id", card.id)
cardPanel.add_child(vbox) cardContainer.add_child(vbox)
# Card name
var nameLabel = Label.new() var nameLabel = Label.new()
nameLabel.text = card.cardName nameLabel.text = card.cardName
nameLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER nameLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
nameLabel.add_theme_font_size_override("font_size", 16)
vbox.add_child(nameLabel) vbox.add_child(nameLabel)
# Card rank with color
var rankLabel = Label.new() var rankLabel = Label.new()
rankLabel.text = "Rank " + str(card.rank) rankLabel.text = "Rank " + str(card.rank)
rankLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER 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) vbox.add_child(rankLabel)
# Card description (truncated)
var descLabel = Label.new() var descLabel = Label.new()
descLabel.text = card.description descLabel.text = card.description
if descLabel.text.length() > 50:
descLabel.text = descLabel.text.substr(0, 50) + "..."
descLabel.autowrap_mode = TextServer.AUTOWRAP_WORD 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) vbox.add_child(descLabel)
var unitWhitelistLabel = Label.new() # Unit whitelist
unitWhitelistLabel.text = ", ".join(card.unitWhitelist) var unitLabel = Label.new()
unitWhitelistLabel.autowrap_mode = TextServer.AUTOWRAP_WORD if card.unitWhitelist.is_empty():
unitWhitelistLabel.custom_minimum_size = Vector2(CARD_WIDTH - 10, 0) unitLabel.text = "Any piece"
vbox.add_child(unitWhitelistLabel) 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)
var idLabel = Label.new() # Connect signals
idLabel.text = card.id.substr(card.id.length() - 8, -1) cardContainer.gui_input.connect(func(event): _on_card_clicked(event, card))
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)) # Connect hover signals for preview
cardContainer.mouse_entered.connect(func(): _on_card_mouse_entered(card))
cardContainer.mouse_exited.connect(func(): _on_card_mouse_exited())
cardDisplays.append(cardPanel) # Add to display list
container.add_child(cardPanel) cardDisplays.append({
"panel": cardContainer,
"card": card
})
container.add_child(cardContainer)
func _on_card_clicked(event: InputEvent, card: Card): func _on_card_clicked(event: InputEvent, card: Card):
if event is InputEventMouseButton and event.pressed: if event is InputEventMouseButton and event.pressed:
@ -70,29 +119,71 @@ func _on_card_clicked(event: InputEvent, card: Card):
selectedCard = null selectedCard = null
highlight_selectedCard(selectedCard) 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: func highlight_selectedCard(selected: Card) -> void:
for display in cardDisplays: for card_data in cardDisplays:
var panel = card_data.panel
var style = StyleBoxFlat.new() var style = StyleBoxFlat.new()
style.bg_color = Utils.DARK_CELL # Default color style.bg_color = Utils.DARK_CELL # Default color
var vbox = display.get_child(0) # Style corners
if selected && vbox.get_meta("card_id") == selected.id: 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 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: func get_card_by_uuid(uuid: String) -> Card:
for display in cardDisplays: for card_data in cardDisplays:
var vbox = display.get_child(0) if card_data.card.id == uuid:
if vbox.get_meta("card_id") == uuid: return card_data.card
return selectedCard
return null return null
func getSelectedCard() -> Card: func getSelectedCard() -> Card:
return selectedCard return selectedCard
func clear_cards(): func clear_cards():
for display in cardDisplays: for card_data in cardDisplays:
display.queue_free() card_data.panel.queue_free()
cardDisplays.clear() cardDisplays.clear()
selectedCard = null selectedCard = null

View file

@ -6,88 +6,55 @@ const PREVIEW_HEIGHT = 200
const SCREEN_MARGIN = 20 const SCREEN_MARGIN = 20
var currentCard: Card = null var currentCard: Card = null
var previewPanel: PanelContainer var previewPanel: CardPreviewPanel
var movesRemainingLabel: Label
func _init() -> void: 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) 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() previewPanel.hide()
# Add the preview panel as a child
add_child(previewPanel) 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: func show_card_preview(card: Card) -> void:
if card == null: if card == null:
previewPanel.hide() hide_preview()
currentCard = null
return return
currentCard = card currentCard = card
var vbox = previewPanel.get_child(0)
for child in vbox.get_children(): # Use the preview_card method from CardPreviewPanel
child.queue_free() previewPanel.preview_card(card)
var nameLabel = Label.new() # Since we're showing a new card, hide the moves remaining label
nameLabel.text = card.cardName movesRemainingLabel.visible = false
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()
func hide_preview() -> void: func hide_preview() -> void:
previewPanel.hide() previewPanel.hide_preview()
currentCard = null currentCard = null
movesRemainingLabel.visible = false
func update_moves_remaining(moves: int) -> void: func update_moves_remaining(moves: int) -> void:
if currentCard == null: if currentCard == null:
return return
var vbox = previewPanel.get_child(0) # Update and show the moves remaining label
var movesLabel = Label.new() movesRemainingLabel.text = "Moves remaining this turn: " + str(moves)
movesLabel.text = "Moves remaining this turn: " + str(moves) movesRemainingLabel.visible = true
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)

View file

@ -257,7 +257,7 @@ func setupUI() -> void:
var control_container = VBoxContainer.new() var control_container = VBoxContainer.new()
control_container.name = "ZoomControls" 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() var h_container = HBoxContainer.new()
h_container.add_child(zoom_out_button) h_container.add_child(zoom_out_button)

View file

@ -10,7 +10,7 @@ signal back_pressed
@onready var card_preview = $CardPreviewPanel @onready var card_preview = $CardPreviewPanel
# Default deck size (can be overridden via options) # Default deck size (can be overridden via options)
var maxDeckSize = 35 var maxDeckSize = 40
var deckManager = null var deckManager = null
var bankCards = [] # Cards available but not in deck var bankCards = [] # Cards available but not in deck

View file

@ -48,6 +48,7 @@ horizontal_alignment = 1
layout_mode = 2 layout_mode = 2
[node name="RankLabel" type="Label" parent="CardContent"] [node name="RankLabel" type="Label" parent="CardContent"]
custom_minimum_size = Vector2(0, 30)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 18 theme_override_font_sizes/font_size = 18
text = "Rank 3 (Reused)" text = "Rank 3 (Reused)"