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:
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<circle cx="16" cy="16" r="15" fill="#ffffff"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 118 B |
@@ -0,0 +1,43 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://neyyjsv1yi2y"
|
||||
path="res://.godot/imported/badge-circle-filled.svg-c615dfa6e3ba91563385092d88757ba4.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/icons/medmind/badge-circle-filled.svg"
|
||||
dest_files=["res://.godot/imported/badge-circle-filled.svg-c615dfa6e3ba91563385092d88757ba4.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
||||
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<circle cx="16" cy="16" r="14.25" fill="#ffffff" fill-opacity="0.08" stroke="#ffffff" stroke-opacity="0.55" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 199 B |
@@ -0,0 +1,43 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://2epi5x1l2k3k"
|
||||
path="res://.godot/imported/badge-circle-outline.svg-48e5795ac9a851c7826f85026138d065.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/icons/medmind/badge-circle-outline.svg"
|
||||
dest_files=["res://.godot/imported/badge-circle-outline.svg-48e5795ac9a851c7826f85026138d065.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
||||
@@ -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