Render answer-choice badges as SVGs and give rows more breathing room
StyleBoxFlat-drawn circles kept looking rough at this size even after tuning corner detail/antialiasing, so the badges are now two small SVG assets (outline and filled) tinted per-state via modulate instead - crisp regardless of size. Also increased row height, badge size, and margins across the board; the previous pass's padding bump was too timid and the rows still read as cramped.
This commit is contained in:
@@ -9,6 +9,8 @@ const LABS_DARK_ICON := preload("res://assets/icons/medmind/labs-dark.svg")
|
||||
const LABS_LIGHT_ICON := preload("res://assets/icons/medmind/labs-light.svg")
|
||||
const REPORT_QUESTION_DARK_ICON := preload("res://assets/icons/medmind/report-question-dark.svg")
|
||||
const REPORT_QUESTION_LIGHT_ICON := preload("res://assets/icons/medmind/report-question-light.svg")
|
||||
const BADGE_CIRCLE_OUTLINE_ICON := preload("res://assets/icons/medmind/badge-circle-outline.svg")
|
||||
const BADGE_CIRCLE_FILLED_ICON := preload("res://assets/icons/medmind/badge-circle-filled.svg")
|
||||
const FEEDBACK_FADE_SECONDS := 0.45
|
||||
const CORRECT_ADVANCE_DELAY_SECONDS := 1.25
|
||||
const TEXT_SCALE_MIN := 0.85
|
||||
@@ -104,6 +106,7 @@ var question_content: VBoxContainer
|
||||
var media_container: VBoxContainer
|
||||
var timer_bar: ProgressBar
|
||||
var choice_badges: Array[Label] = []
|
||||
var choice_badge_textures: Array[TextureRect] = []
|
||||
var feedback_fog: ColorRect
|
||||
var labs_overlay: Control
|
||||
var labs_panel: PanelContainer
|
||||
@@ -424,7 +427,7 @@ func _ready() -> void:
|
||||
question_content.add_child(question_elo_label)
|
||||
|
||||
var choices_container := VBoxContainer.new()
|
||||
choices_container.add_theme_constant_override("separation", 8)
|
||||
choices_container.add_theme_constant_override("separation", 10)
|
||||
question_content.add_child(choices_container)
|
||||
|
||||
for index in range(5):
|
||||
@@ -434,7 +437,7 @@ func _ready() -> void:
|
||||
choice_rows.append(choice_row)
|
||||
|
||||
var button := Button.new()
|
||||
button.custom_minimum_size = Vector2(0, 54)
|
||||
button.custom_minimum_size = Vector2(0, 68)
|
||||
button.alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||
Style.style_answer_button(button)
|
||||
UISoundService.set_button_sound(button, "select")
|
||||
@@ -443,20 +446,36 @@ func _ready() -> void:
|
||||
button.gui_input.connect(func(event: InputEvent, i := index): _choice_gui_input(event, i))
|
||||
choice_buttons.append(button)
|
||||
|
||||
var badge_wrap := Control.new()
|
||||
badge_wrap.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
badge_wrap.anchor_left = 0.0
|
||||
badge_wrap.anchor_top = 0.0
|
||||
badge_wrap.anchor_right = 0.0
|
||||
badge_wrap.anchor_bottom = 0.0
|
||||
badge_wrap.offset_left = 16
|
||||
badge_wrap.offset_top = 17
|
||||
badge_wrap.offset_right = 50
|
||||
badge_wrap.offset_bottom = 51
|
||||
button.add_child(badge_wrap)
|
||||
|
||||
# The badge circle is a pre-rendered SVG (tinted per-state via modulate) rather than a
|
||||
# StyleBoxFlat corner-radius circle - a perfectly circular StyleBoxFlat is a known Godot
|
||||
# degenerate case that can show a seam/faceting at this size even with AA tuned.
|
||||
var badge_texture := TextureRect.new()
|
||||
badge_texture.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
badge_texture.texture = BADGE_CIRCLE_OUTLINE_ICON
|
||||
badge_texture.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
badge_texture.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
badge_wrap.add_child(badge_texture)
|
||||
choice_badge_textures.append(badge_texture)
|
||||
|
||||
var badge := Label.new()
|
||||
badge.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
badge.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
badge.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
badge.anchor_left = 0.0
|
||||
badge.anchor_top = 0.0
|
||||
badge.anchor_right = 0.0
|
||||
badge.anchor_bottom = 0.0
|
||||
badge.offset_left = 12
|
||||
badge.offset_top = 12
|
||||
badge.offset_right = 42
|
||||
badge.offset_bottom = 42
|
||||
_set_scaled_label(badge, 14, Brand.muted_color(true))
|
||||
button.add_child(badge)
|
||||
badge.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
_set_scaled_label(badge, 15, Brand.muted_color(true))
|
||||
badge_wrap.add_child(badge)
|
||||
choice_badges.append(badge)
|
||||
|
||||
var percent_label := Label.new()
|
||||
@@ -469,9 +488,9 @@ func _ready() -> void:
|
||||
percent_label.anchor_right = 1.0
|
||||
percent_label.anchor_bottom = 0.0
|
||||
percent_label.offset_left = -82
|
||||
percent_label.offset_top = 8
|
||||
percent_label.offset_top = 18
|
||||
percent_label.offset_right = -18
|
||||
percent_label.offset_bottom = 40
|
||||
percent_label.offset_bottom = 50
|
||||
_set_scaled_label(percent_label, 18, Style.TEXT)
|
||||
button.add_child(percent_label)
|
||||
choice_percent_labels.append(percent_label)
|
||||
@@ -486,10 +505,10 @@ func _ready() -> void:
|
||||
top_label.anchor_top = 0.0
|
||||
top_label.anchor_right = 1.0
|
||||
top_label.anchor_bottom = 0.0
|
||||
top_label.offset_left = 54
|
||||
top_label.offset_top = 10
|
||||
top_label.offset_left = 62
|
||||
top_label.offset_top = 18
|
||||
top_label.offset_right = -96
|
||||
top_label.offset_bottom = 42
|
||||
top_label.offset_bottom = 50
|
||||
_set_scaled_rich_text(top_label, 16)
|
||||
top_label.add_theme_color_override("default_color", Style.RED)
|
||||
button.add_child(top_label)
|
||||
@@ -682,10 +701,10 @@ func _question_content_box(dark: bool) -> StyleBoxFlat:
|
||||
|
||||
func _answer_box(dark: bool, state: String) -> StyleBoxFlat:
|
||||
var box := StyleBoxFlat.new()
|
||||
box.content_margin_left = 54
|
||||
box.content_margin_left = 62
|
||||
box.content_margin_right = 82
|
||||
box.content_margin_top = 16
|
||||
box.content_margin_bottom = 16
|
||||
box.content_margin_top = 22
|
||||
box.content_margin_bottom = 22
|
||||
if state == "default" or state == "eliminated":
|
||||
# Flat, divider-style row - most choices sit in a plain list; only the
|
||||
# states below need to visually pop out as their own card.
|
||||
@@ -3015,8 +3034,12 @@ func _style_choice_button_for_state(index: int, choice_id: String) -> void:
|
||||
if state == "selected": accent = Brand.PURPLE
|
||||
elif state == "correct": accent = Brand.SUCCESS
|
||||
elif state == "wrong": accent = Color("fb7185")
|
||||
badge.add_theme_stylebox_override("normal", Brand.icon_circle_box(dark, accent, 15, state in ["selected", "correct", "wrong"]))
|
||||
badge.add_theme_color_override("font_color", Color.WHITE if state in ["selected", "correct", "wrong"] else Brand.muted_color(dark))
|
||||
var filled := state in ["selected", "correct", "wrong"]
|
||||
if index < choice_badge_textures.size():
|
||||
var badge_texture := choice_badge_textures[index]
|
||||
badge_texture.texture = BADGE_CIRCLE_FILLED_ICON if filled else BADGE_CIRCLE_OUTLINE_ICON
|
||||
badge_texture.modulate = accent
|
||||
badge.add_theme_color_override("font_color", Color.WHITE if filled else Brand.muted_color(dark))
|
||||
|
||||
|
||||
func _mark_review_input_handled() -> void:
|
||||
|
||||
Reference in New Issue
Block a user