88 lines
4.0 KiB
GDScript
88 lines
4.0 KiB
GDScript
class_name CardView
|
|
extends Control
|
|
## Zeichnet eine Karte (Hand, Sammlung, Booster, Vorschau).
|
|
|
|
signal clicked(view: CardView)
|
|
signal hover(card: Cards.Card, entered: bool)
|
|
|
|
var card: Cards.Card
|
|
var border = null # Color oder null (dann Seltenheitsfarbe)
|
|
var rarity := "gewöhnlich" # nur Optik: Rahmenfarbe der eigenen Stufe
|
|
var dim := false
|
|
|
|
|
|
## focusable: per Gamepad oder Tab anwählbar (Sammlung, Booster); A bzw. Enter wirkt wie ein Klick.
|
|
func _init(c: Cards.Card, sz: Vector2, focusable: bool = false, rar: String = "gewöhnlich") -> void:
|
|
card = c
|
|
rarity = rar
|
|
custom_minimum_size = sz
|
|
size = sz
|
|
mouse_filter = Control.MOUSE_FILTER_STOP
|
|
mouse_entered.connect(func(): hover.emit(card, true))
|
|
mouse_exited.connect(func(): hover.emit(card, false))
|
|
if focusable:
|
|
focus_mode = Control.FOCUS_ALL
|
|
focus_entered.connect(func():
|
|
hover.emit(card, true)
|
|
queue_redraw())
|
|
focus_exited.connect(func():
|
|
hover.emit(card, false)
|
|
queue_redraw())
|
|
|
|
|
|
func _gui_input(event: InputEvent) -> void:
|
|
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
|
|
accept_event()
|
|
clicked.emit(self)
|
|
elif has_focus() and event.is_action_pressed("ui_accept"):
|
|
accept_event()
|
|
clicked.emit(self)
|
|
|
|
|
|
func _draw() -> void:
|
|
var rect := Rect2(Vector2.ZERO, size)
|
|
var big := size.x >= 180
|
|
var mid := size.x >= 115
|
|
var f_name := 18 if big else (14 if mid else 12)
|
|
var f_text := 14 if big else (11 if mid else 10)
|
|
var f_stat := 24 if big else (18 if mid else 15)
|
|
Style.fill_elements(self, rect, card.elements, 8)
|
|
var bcol: Color = border if border != null else Cards.RARITY_COLORS[rarity]
|
|
Style.border(self, rect, bcol, 3 if big else 2, 8)
|
|
# Kosten
|
|
var r := 16 if big else 12
|
|
var cc := Vector2(r + 4, r + 4)
|
|
draw_circle(cc, r, Color("14141c"))
|
|
Style.text(self, str(card.cost), f_stat, Style.GOLD, cc, "center", true)
|
|
# Name und Kombo
|
|
var name_left := 2 * r + 10
|
|
var nm := Style.fit(card.title(), true, f_name, size.x - name_left - 6)
|
|
Style.text(self, nm, f_name, Style.TEXT, Vector2((name_left + size.x - 6) / 2.0, 4), "midtop", true)
|
|
if mid:
|
|
var sub: String = tr(card.combo()) if card.is_combo() else ""
|
|
Style.text(self, sub, f_text, Color("e6e6e6"), Vector2(size.x / 2, 2 * r + 4), "midtop")
|
|
# Textfeld: Höhe folgt dem umbrochenen Text und der Schriftgröße, das Bild bekommt den Rest
|
|
var tsize := Style.fs(f_text)
|
|
var text_w: float = size.x - 20
|
|
var needed: float = Style.FONT.get_multiline_string_size(card.text(), HORIZONTAL_ALIGNMENT_LEFT, text_w, tsize).y + 8 if card.text() != "" else size.y * 0.42
|
|
var box_bottom: float = size.y - (28 if big else 22)
|
|
var band_top: float = 2 * r + 4 + (f_text + 6 if mid else 0) # unter Name und Kombo
|
|
var box_top: float = maxf(maxf(size.y * 0.30, band_top), box_bottom - maxf(needed, size.y * 0.42))
|
|
var box := Rect2(6, box_top, size.x - 12, box_bottom - box_top)
|
|
# Bild
|
|
var band_bottom: float = box_top - 4
|
|
if band_bottom - band_top > 14:
|
|
var gsize: float = minf(band_bottom - band_top, size.x * 0.42)
|
|
Style.glyph(self, card, Vector2(size.x / 2, (band_top + band_bottom) / 2), gsize)
|
|
draw_rect(box, Color(0.06, 0.06, 0.09, 0.67))
|
|
var max_lines := maxi(1, int((box.size.y - 6) / Style.FONT.get_height(tsize))) # große Schrift: lieber kürzen als überlaufen
|
|
draw_multiline_string(Style.FONT, Vector2(box.position.x + 4, box.position.y + 4 + Style.FONT.get_ascent(tsize)),
|
|
card.text(), HORIZONTAL_ALIGNMENT_LEFT, box.size.x - 8, tsize, max_lines, Style.TEXT)
|
|
# Werte
|
|
Style.text(self, str(card.attack), f_stat, Style.YELLOW, Vector2(10, size.y - 6), "bottomleft", true)
|
|
Style.text(self, str(card.health), f_stat, Style.RED, Vector2(size.x - 10, size.y - 6), "bottomright", true)
|
|
if dim:
|
|
draw_rect(rect, Color(0, 0, 0, 0.47))
|
|
if has_focus():
|
|
Style.border(self, rect, Style.GOLD, 4, 8)
|