Restyle the simulation break and review screens to match the results screen
Both were still on the legacy flat-panel Style system, which made "Review Questions" on the redesigned results screen drop into a visibly older-looking screen. Rebuilt both with the same Brand card/ badge/accent-color language: a hero card for the break screen, and color-coded (green/red-tinted, bordered) choice cards, accent-colored filter chips, and icon headings for the review screen. Pure re-skin - same functions, same data flow, only what they render into changed. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
@@ -1,66 +1,105 @@
|
||||
extends VBoxContainer
|
||||
|
||||
const Style := preload("res://scripts/ui/ui_style.gd")
|
||||
const Brand := preload("res://scripts/ui/medmind_style.gd")
|
||||
|
||||
var main: Control
|
||||
var card: PanelContainer
|
||||
var eyebrow: Label
|
||||
var title: Label
|
||||
var detail: Label
|
||||
var start_button: Button
|
||||
var abandon_button: Button
|
||||
var error_label: Label
|
||||
var note: Label
|
||||
var abandon_armed := false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
add_theme_constant_override("separation", 18)
|
||||
add_theme_constant_override("separation", 16)
|
||||
if not ExamSimulationService.state_changed.is_connected(_on_state_changed):
|
||||
ExamSimulationService.state_changed.connect(_on_state_changed)
|
||||
if not ExamSimulationService.request_failed.is_connected(_on_failed):
|
||||
ExamSimulationService.request_failed.connect(_on_failed)
|
||||
|
||||
var eyebrow := Label.new()
|
||||
card = PanelContainer.new()
|
||||
add_child(card)
|
||||
var card_margin := MarginContainer.new()
|
||||
card_margin.add_theme_constant_override("margin_left", 24)
|
||||
card_margin.add_theme_constant_override("margin_right", 24)
|
||||
card_margin.add_theme_constant_override("margin_top", 22)
|
||||
card_margin.add_theme_constant_override("margin_bottom", 22)
|
||||
card.add_child(card_margin)
|
||||
var card_content := VBoxContainer.new()
|
||||
card_content.add_theme_constant_override("separation", 10)
|
||||
card_margin.add_child(card_content)
|
||||
|
||||
eyebrow = Label.new()
|
||||
eyebrow.text = "STEP 3 DAY 1 SIMULATION"
|
||||
Style.set_label(eyebrow, 14, Style.CYAN)
|
||||
add_child(eyebrow)
|
||||
eyebrow.add_theme_font_override("font", Brand.font)
|
||||
eyebrow.add_theme_font_size_override("font_size", 13)
|
||||
card_content.add_child(eyebrow)
|
||||
|
||||
title = Label.new()
|
||||
Style.set_label(title, 34, Style.TEXT)
|
||||
add_child(title)
|
||||
title.add_theme_font_override("font", Brand.font)
|
||||
title.add_theme_font_size_override("font_size", 26)
|
||||
card_content.add_child(title)
|
||||
|
||||
detail = Label.new()
|
||||
detail.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
Style.set_label(detail, 18, Style.MUTED)
|
||||
add_child(detail)
|
||||
detail.add_theme_font_override("font", Brand.font)
|
||||
detail.add_theme_font_size_override("font_size", 15)
|
||||
card_content.add_child(detail)
|
||||
|
||||
var actions := HBoxContainer.new()
|
||||
actions.add_theme_constant_override("separation", 12)
|
||||
card_content.add_child(actions)
|
||||
|
||||
start_button = Button.new()
|
||||
start_button.custom_minimum_size = Vector2(240, 54)
|
||||
start_button.custom_minimum_size = Vector2(220, 52)
|
||||
start_button.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
||||
Style.style_primary_button(start_button)
|
||||
_style_gradient_button(start_button)
|
||||
start_button.pressed.connect(_start_block)
|
||||
add_child(start_button)
|
||||
actions.add_child(start_button)
|
||||
|
||||
abandon_button = Button.new()
|
||||
abandon_button.text = "Abandon simulation"
|
||||
abandon_button.custom_minimum_size = Vector2(240, 44)
|
||||
abandon_button.custom_minimum_size = Vector2(200, 52)
|
||||
abandon_button.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
||||
Style.style_chip(abandon_button, Style.RED)
|
||||
abandon_button.pressed.connect(_abandon)
|
||||
add_child(abandon_button)
|
||||
actions.add_child(abandon_button)
|
||||
|
||||
error_label = Label.new()
|
||||
error_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
Style.set_label(error_label, 16, Style.RED)
|
||||
error_label.add_theme_font_override("font", Brand.font)
|
||||
error_label.add_theme_font_size_override("font_size", 13)
|
||||
error_label.add_theme_color_override("font_color", Brand.MAGENTA)
|
||||
add_child(error_label)
|
||||
|
||||
var note := Label.new()
|
||||
note = Label.new()
|
||||
note.text = "Each block runs for 30 minutes. You may review and change answers within the active block, but closed blocks cannot be reopened. Leaving during a block does not stop its server timer."
|
||||
note.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
Style.set_label(note, 16, Style.MUTED)
|
||||
note.add_theme_font_override("font", Brand.font)
|
||||
note.add_theme_font_size_override("font_size", 12)
|
||||
add_child(note)
|
||||
|
||||
var spacer := Control.new()
|
||||
spacer.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
add_child(spacer)
|
||||
|
||||
UIThemeService.theme_changed.connect(func(_dark: bool): refresh_theme_controls())
|
||||
refresh_theme_controls()
|
||||
|
||||
|
||||
func refresh_theme_controls() -> void:
|
||||
var dark := UIThemeService.is_dark_mode()
|
||||
card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, true, Brand.ROYAL_BLUE))
|
||||
eyebrow.add_theme_color_override("font_color", Brand.SKY_BLUE)
|
||||
title.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||
detail.add_theme_color_override("font_color", Brand.muted_color(dark))
|
||||
note.add_theme_color_override("font_color", Brand.muted_color(dark))
|
||||
_style_outline_button(abandon_button, Brand.MAGENTA, dark)
|
||||
|
||||
|
||||
func on_show(_payload: Variant = null) -> void:
|
||||
abandon_armed = false
|
||||
@@ -123,3 +162,33 @@ func _on_failed(message: String) -> void:
|
||||
error_label.text = message
|
||||
start_button.disabled = false
|
||||
_refresh()
|
||||
|
||||
|
||||
func _style_gradient_button(button: Button) -> void:
|
||||
Brand.apply_font(button)
|
||||
button.add_theme_font_size_override("font_size", 15)
|
||||
button.add_theme_stylebox_override("normal", Brand.gradient_button_box())
|
||||
button.add_theme_stylebox_override("hover", Brand.gradient_button_box())
|
||||
button.add_theme_stylebox_override("pressed", Brand.gradient_button_box())
|
||||
button.add_theme_color_override("font_color", Color.WHITE)
|
||||
button.add_theme_color_override("font_hover_color", Color.WHITE)
|
||||
|
||||
|
||||
func _style_outline_button(button: Button, accent: Color, dark: bool) -> void:
|
||||
Brand.apply_font(button)
|
||||
button.add_theme_font_size_override("font_size", 14)
|
||||
var normal := StyleBoxFlat.new()
|
||||
normal.bg_color = Color(0, 0, 0, 0)
|
||||
normal.border_color = accent
|
||||
normal.set_border_width_all(1)
|
||||
normal.set_corner_radius_all(10)
|
||||
var hover := StyleBoxFlat.new()
|
||||
hover.bg_color = Color(accent, 0.12)
|
||||
hover.border_color = accent
|
||||
hover.set_border_width_all(1)
|
||||
hover.set_corner_radius_all(10)
|
||||
button.add_theme_stylebox_override("normal", normal)
|
||||
button.add_theme_stylebox_override("hover", hover)
|
||||
button.add_theme_stylebox_override("pressed", hover)
|
||||
button.add_theme_color_override("font_color", accent if dark else accent.darkened(0.08))
|
||||
button.add_theme_color_override("font_hover_color", accent)
|
||||
|
||||
Reference in New Issue
Block a user