Simplify question toolbar branding
This commit is contained in:
+45
-114
@@ -2,6 +2,10 @@ extends VBoxContainer
|
||||
|
||||
const Style := preload("res://scripts/ui/ui_style.gd")
|
||||
const Brand := preload("res://scripts/ui/medmind_style.gd")
|
||||
const CLEAR_HIGHLIGHT_DARK_ICON := preload("res://assets/icons/medmind/clear-highlight-darkmode.png")
|
||||
const CLEAR_HIGHLIGHT_LIGHT_ICON := preload("res://assets/icons/medmind/clear-highlight-lightmode.png")
|
||||
const REPORT_QUESTION_DARK_ICON := preload("res://assets/icons/medmind/report-question-darkmode.png")
|
||||
const REPORT_QUESTION_LIGHT_ICON := preload("res://assets/icons/medmind/report-question-lightmode.png")
|
||||
const FEEDBACK_FADE_SECONDS := 0.45
|
||||
const CORRECT_ADVANCE_DELAY_SECONDS := 1.25
|
||||
const TEXT_SCALE_MIN := 0.85
|
||||
@@ -54,7 +58,6 @@ var simulation_submit_pending := false
|
||||
|
||||
var progress_button: Button
|
||||
var timer_label: Label
|
||||
var player_stats_label: Label
|
||||
var stem_label: RichTextLabel
|
||||
var lead_label: Label
|
||||
var explanation_label: RichTextLabel
|
||||
@@ -75,6 +78,7 @@ var skip_button: Button
|
||||
var text_smaller_button: Button
|
||||
var text_larger_button: Button
|
||||
var labs_button: Button
|
||||
var clear_highlight_button: Button
|
||||
var flag_button: Button
|
||||
var report_button: Button
|
||||
var app_feedback_button: Button
|
||||
@@ -142,12 +146,6 @@ func _ready() -> void:
|
||||
QuestionBankService.question_rating_updated.connect(_on_question_rating_updated)
|
||||
if not QuestionBankService.question_skipped.is_connected(_on_question_skipped):
|
||||
QuestionBankService.question_skipped.connect(_on_question_skipped)
|
||||
if not ProfileService.profile_changed.is_connected(_refresh_player_stats):
|
||||
ProfileService.profile_changed.connect(_refresh_player_stats)
|
||||
if not QuestionBankService.ratings_changed.is_connected(_refresh_player_stats):
|
||||
QuestionBankService.ratings_changed.connect(_refresh_player_stats)
|
||||
if not AuthState.auth_changed.is_connected(_refresh_player_stats):
|
||||
AuthState.auth_changed.connect(_refresh_player_stats)
|
||||
if not QuestionBankService.question_report_submitted.is_connected(_on_question_report_submitted):
|
||||
QuestionBankService.question_report_submitted.connect(_on_question_report_submitted)
|
||||
if not QuestionBankService.question_report_failed.is_connected(_on_question_report_failed):
|
||||
@@ -184,14 +182,6 @@ func _ready() -> void:
|
||||
header_row.add_theme_constant_override("separation", 10)
|
||||
header_stack.add_child(header_row)
|
||||
|
||||
var step_badge := Label.new()
|
||||
step_badge.text = "STEP 3"
|
||||
step_badge.name = "StepBadge"
|
||||
step_badge.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
step_badge.custom_minimum_size = Vector2(70, 34)
|
||||
_set_scaled_label(step_badge, 13, Brand.PURPLE)
|
||||
header_row.add_child(step_badge)
|
||||
|
||||
progress_button = Button.new()
|
||||
progress_button.flat = true
|
||||
progress_button.alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||
@@ -210,11 +200,6 @@ func _ready() -> void:
|
||||
timer_label.visible = false
|
||||
timer_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
|
||||
|
||||
player_stats_label = Label.new()
|
||||
player_stats_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
|
||||
_set_scaled_label(player_stats_label, 13, Brand.SLATE)
|
||||
header_row.add_child(player_stats_label)
|
||||
|
||||
question_toolbar = HFlowContainer.new()
|
||||
question_toolbar.add_theme_constant_override("h_separation", 8)
|
||||
question_toolbar.add_theme_constant_override("v_separation", 8)
|
||||
@@ -255,11 +240,9 @@ func _ready() -> void:
|
||||
labs_button.pressed.connect(_show_labs_modal)
|
||||
question_toolbar.add_child(labs_button)
|
||||
|
||||
var clear_highlight_button := Button.new()
|
||||
clear_highlight_button = Button.new()
|
||||
clear_highlight_button.tooltip_text = "Clear highlights"
|
||||
clear_highlight_button.icon = _make_clear_highlights_icon()
|
||||
clear_highlight_button.custom_minimum_size = Vector2(44, 44)
|
||||
Style.style_chip(clear_highlight_button, Style.CYAN)
|
||||
UISoundService.set_button_sound(clear_highlight_button, "eliminate")
|
||||
clear_highlight_button.pressed.connect(_clear_current_highlights)
|
||||
question_toolbar.add_child(clear_highlight_button)
|
||||
@@ -281,9 +264,7 @@ func _ready() -> void:
|
||||
|
||||
report_button = Button.new()
|
||||
report_button.tooltip_text = "Report question"
|
||||
report_button.icon = _make_report_icon()
|
||||
report_button.custom_minimum_size = Vector2(44, 44)
|
||||
Style.style_chip(report_button, Style.CYAN)
|
||||
UISoundService.set_button_sound(report_button, "open")
|
||||
report_button.pressed.connect(_toggle_report_current_question)
|
||||
question_toolbar.add_child(report_button)
|
||||
@@ -610,7 +591,6 @@ func _refresh_responsive_layout() -> void:
|
||||
header_toolbar_host.size_flags_horizontal = Control.SIZE_EXPAND_FILL if compact else Control.SIZE_SHRINK_END
|
||||
question_toolbar.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
header_toolbar_host.custom_minimum_size.x = 0.0 if compact else 520.0
|
||||
player_stats_label.visible = size.x >= 720.0
|
||||
app_feedback_button.text = "" if size.x < 760.0 else "Feedback"
|
||||
app_feedback_button.custom_minimum_size.x = 44 if size.x < 760.0 else 92
|
||||
if size.x < 560.0:
|
||||
@@ -671,6 +651,40 @@ func _toolbar_box(dark: bool, active: bool = false) -> StyleBoxFlat:
|
||||
return box
|
||||
|
||||
|
||||
func _theme_toggle_box(dark: bool, hovered: bool = false) -> StyleBoxFlat:
|
||||
var box := StyleBoxFlat.new()
|
||||
box.bg_color = Color("111b30") if dark else Brand.LIGHT_SURFACE
|
||||
box.border_color = Brand.AMBER if hovered else (Color("33415d") if dark else Brand.LIGHT_BORDER)
|
||||
box.set_border_width_all(1)
|
||||
box.set_corner_radius_all(22)
|
||||
return box
|
||||
|
||||
|
||||
func _style_theme_toggle_button(dark: bool) -> void:
|
||||
if theme_button == null:
|
||||
return
|
||||
Brand.set_theme_toggle_icon(theme_button, dark)
|
||||
theme_button.tooltip_text = "Switch to light mode" if dark else "Switch to dark mode"
|
||||
theme_button.add_theme_stylebox_override("normal", _theme_toggle_box(dark))
|
||||
theme_button.add_theme_stylebox_override("hover", _theme_toggle_box(dark, true))
|
||||
theme_button.add_theme_stylebox_override("pressed", _theme_toggle_box(dark, true))
|
||||
theme_button.add_theme_stylebox_override("focus", StyleBoxEmpty.new())
|
||||
|
||||
|
||||
func _style_asset_toolbar_button(button: Button, texture: Texture2D) -> void:
|
||||
if button == null:
|
||||
return
|
||||
button.text = ""
|
||||
button.icon = texture
|
||||
button.expand_icon = true
|
||||
button.add_theme_constant_override("icon_max_width", 44)
|
||||
var empty := StyleBoxEmpty.new()
|
||||
for state in ["normal", "hover", "pressed", "focus"]:
|
||||
button.add_theme_stylebox_override(state, empty)
|
||||
for color_name in ["icon_normal_color", "icon_hover_color", "icon_pressed_color", "icon_focus_color"]:
|
||||
button.add_theme_color_override(color_name, Color.WHITE)
|
||||
|
||||
|
||||
func _primary_action_box(dark: bool, state: String) -> StyleBoxFlat:
|
||||
var box := StyleBoxFlat.new()
|
||||
if state == "disabled":
|
||||
@@ -770,14 +784,9 @@ func _apply_question_theme() -> void:
|
||||
question_panel.add_theme_stylebox_override("panel", _question_content_box(dark))
|
||||
if navigator_popup != null:
|
||||
navigator_popup.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
|
||||
var step_badge := header_row.get_node_or_null("StepBadge") as Label
|
||||
if step_badge != null:
|
||||
step_badge.add_theme_stylebox_override("normal", Brand.badge_box(dark, Brand.PURPLE))
|
||||
step_badge.add_theme_color_override("font_color", Brand.PURPLE if not dark else Color("c4b5fd"))
|
||||
progress_button.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||
progress_button.add_theme_color_override("font_hover_color", Brand.SKY_BLUE)
|
||||
progress_button.add_theme_color_override("font_disabled_color", Brand.text_color(dark))
|
||||
player_stats_label.add_theme_color_override("font_color", Brand.muted_color(dark))
|
||||
timer_label.add_theme_color_override("font_color", Brand.muted_color(dark))
|
||||
stem_label.add_theme_color_override("default_color", Brand.text_color(dark))
|
||||
lead_label.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||
@@ -797,7 +806,7 @@ func _apply_question_theme() -> void:
|
||||
var navigator_heading := navigator_popup.find_child("NavigatorHeading", true, false) as Label
|
||||
if navigator_heading != null:
|
||||
navigator_heading.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||
for control in [theme_button, text_smaller_button, text_larger_button, labs_button, flag_button, report_button, app_feedback_button]:
|
||||
for control in [text_smaller_button, text_larger_button, labs_button, flag_button, app_feedback_button]:
|
||||
if control == null:
|
||||
continue
|
||||
var active: bool = control == flag_button and flagged
|
||||
@@ -806,6 +815,9 @@ func _apply_question_theme() -> void:
|
||||
control.add_theme_stylebox_override("pressed", _toolbar_box(dark, true))
|
||||
control.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||
control.add_theme_color_override("icon_normal_color", Brand.SKY_BLUE)
|
||||
_style_asset_toolbar_button(clear_highlight_button, CLEAR_HIGHLIGHT_DARK_ICON if dark else CLEAR_HIGHLIGHT_LIGHT_ICON)
|
||||
_style_asset_toolbar_button(report_button, REPORT_QUESTION_DARK_ICON if dark else REPORT_QUESTION_LIGHT_ICON)
|
||||
_style_theme_toggle_button(dark)
|
||||
if skip_button != null:
|
||||
skip_button.add_theme_stylebox_override("normal", _toolbar_box(dark))
|
||||
skip_button.add_theme_stylebox_override("hover", _toolbar_box(dark, true))
|
||||
@@ -1029,7 +1041,6 @@ func _load_question() -> void:
|
||||
|
||||
_refresh_nav_palette()
|
||||
_refresh_toolbar_state()
|
||||
_refresh_player_stats()
|
||||
_apply_question_theme()
|
||||
|
||||
|
||||
@@ -1843,19 +1854,12 @@ func _refresh_toolbar_state() -> void:
|
||||
|
||||
|
||||
func refresh_theme_controls() -> void:
|
||||
_refresh_theme_button()
|
||||
if media_viewer_background != null:
|
||||
media_viewer_background.color = Style.BACKGROUND
|
||||
if labs_button != null:
|
||||
labs_button.icon = _make_labs_icon()
|
||||
if flag_button != null:
|
||||
flag_button.icon = _make_flag_icon()
|
||||
if report_button != null:
|
||||
report_button.icon = _make_report_icon()
|
||||
if question_toolbar != null:
|
||||
for child in question_toolbar.get_children():
|
||||
if child is Button and child.tooltip_text == "Clear highlights":
|
||||
child.icon = _make_clear_highlights_icon()
|
||||
_refresh_toolbar_state()
|
||||
_apply_saved_choice_state()
|
||||
_apply_question_theme()
|
||||
@@ -1864,19 +1868,7 @@ func refresh_theme_controls() -> void:
|
||||
func _refresh_theme_button() -> void:
|
||||
if theme_button == null:
|
||||
return
|
||||
Brand.set_theme_toggle_icon(theme_button, theme_service.is_dark_mode())
|
||||
theme_button.tooltip_text = "Switch to light mode" if theme_service.is_dark_mode() else "Switch to dark mode"
|
||||
Style.style_chip(theme_button, Style.CYAN)
|
||||
|
||||
|
||||
func _refresh_player_stats() -> void:
|
||||
if player_stats_label == null:
|
||||
return
|
||||
var display_name := AuthState.role.to_upper() if AuthState.role != "" else AuthState.username
|
||||
player_stats_label.text = "Rating: %d | %s" % [
|
||||
QuestionBankService.overall_elo,
|
||||
display_name
|
||||
]
|
||||
_style_theme_toggle_button(theme_service.is_dark_mode())
|
||||
|
||||
|
||||
func _adjust_question_text_scale(delta: float) -> void:
|
||||
@@ -3369,67 +3361,6 @@ func _make_flag_icon() -> Texture2D:
|
||||
return ImageTexture.create_from_image(image)
|
||||
|
||||
|
||||
func _make_clear_highlights_icon() -> Texture2D:
|
||||
var image := Image.create(24, 24, false, Image.FORMAT_RGBA8)
|
||||
image.fill(Color(0, 0, 0, 0))
|
||||
var handle_color := Style.TEXT
|
||||
var bristle_color := Style.AMBER
|
||||
for offset in range(3):
|
||||
_draw_icon_line(image, Vector2i(6 + offset, 16), Vector2i(16 + offset, 6), handle_color)
|
||||
for x in range(13, 20):
|
||||
for y in range(15, 19):
|
||||
if x + y < 36:
|
||||
image.set_pixel(x, y, bristle_color)
|
||||
for x in range(12, 20):
|
||||
image.set_pixel(x, 19, bristle_color)
|
||||
return ImageTexture.create_from_image(image)
|
||||
|
||||
|
||||
func _make_report_icon() -> Texture2D:
|
||||
var image := Image.create(24, 24, false, Image.FORMAT_RGBA8)
|
||||
image.fill(Color(0, 0, 0, 0))
|
||||
var body_color := Style.TEXT
|
||||
var accent_color := Style.RED
|
||||
for x in range(5, 14):
|
||||
for y in range(9, 15):
|
||||
image.set_pixel(x, y, body_color)
|
||||
for x in range(14, 20):
|
||||
image.set_pixel(x, 7, accent_color)
|
||||
image.set_pixel(x, 16, accent_color)
|
||||
for y in range(8, 16):
|
||||
image.set_pixel(20, y, accent_color)
|
||||
for y in range(10, 14):
|
||||
image.set_pixel(4, y, body_color)
|
||||
for y in range(15, 21):
|
||||
image.set_pixel(8, y, body_color)
|
||||
if y < 20:
|
||||
image.set_pixel(9, y, body_color)
|
||||
_draw_icon_line(image, Vector2i(2, 5), Vector2i(5, 8), accent_color)
|
||||
_draw_icon_line(image, Vector2i(2, 19), Vector2i(5, 16), accent_color)
|
||||
return ImageTexture.create_from_image(image)
|
||||
|
||||
|
||||
func _draw_icon_line(image: Image, from: Vector2i, to: Vector2i, color: Color) -> void:
|
||||
var dx := int(abs(to.x - from.x))
|
||||
var sx := 1 if from.x < to.x else -1
|
||||
var dy := -int(abs(to.y - from.y))
|
||||
var sy := 1 if from.y < to.y else -1
|
||||
var err: int = dx + dy
|
||||
var point := from
|
||||
while true:
|
||||
if point.x >= 0 and point.x < image.get_width() and point.y >= 0 and point.y < image.get_height():
|
||||
image.set_pixel(point.x, point.y, color)
|
||||
if point == to:
|
||||
break
|
||||
var e2: int = 2 * err
|
||||
if e2 >= dy:
|
||||
err += dy
|
||||
point.x += sx
|
||||
if e2 <= dx:
|
||||
err += dx
|
||||
point.y += sy
|
||||
|
||||
|
||||
func _refresh_nav_palette() -> void:
|
||||
if nav_palette == null:
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user