Polish CCS case and results interface
This commit is contained in:
@@ -228,6 +228,7 @@ public class CcsAttemptResponse
|
|||||||
public string Location { get; set; } = "";
|
public string Location { get; set; } = "";
|
||||||
public DateTime? DeadlineUtc { get; set; }
|
public DateTime? DeadlineUtc { get; set; }
|
||||||
public DateTime? FinalOrdersDeadlineUtc { get; set; }
|
public DateTime? FinalOrdersDeadlineUtc { get; set; }
|
||||||
|
public int ElapsedSeconds { get; set; }
|
||||||
public string PatientSummary { get; set; } = "";
|
public string PatientSummary { get; set; } = "";
|
||||||
public string ReasonForEncounter { get; set; } = "";
|
public string ReasonForEncounter { get; set; } = "";
|
||||||
public string Appearance { get; set; } = "";
|
public string Appearance { get; set; } = "";
|
||||||
|
|||||||
@@ -224,6 +224,7 @@ public sealed class CcsStore
|
|||||||
Mode = attempt.Mode, State = attempt.State, Revision = attempt.Revision,
|
Mode = attempt.Mode, State = attempt.State, Revision = attempt.Revision,
|
||||||
SimulatedMinute = attempt.SimulatedMinute, Location = attempt.Location,
|
SimulatedMinute = attempt.SimulatedMinute, Location = attempt.Location,
|
||||||
DeadlineUtc = attempt.DeadlineUtc, FinalOrdersDeadlineUtc = attempt.FinalOrdersDeadlineUtc,
|
DeadlineUtc = attempt.DeadlineUtc, FinalOrdersDeadlineUtc = attempt.FinalOrdersDeadlineUtc,
|
||||||
|
ElapsedSeconds = Math.Max(0, (int)Math.Round(((attempt.CompletedUtc ?? DateTime.UtcNow) - attempt.CreatedUtc).TotalSeconds)),
|
||||||
PatientSummary = definition.InitialChart.PatientSummary, ReasonForEncounter = definition.InitialChart.ReasonForEncounter,
|
PatientSummary = definition.InitialChart.PatientSummary, ReasonForEncounter = definition.InitialChart.ReasonForEncounter,
|
||||||
Appearance = definition.InitialChart.Appearance, History = definition.InitialChart.History,
|
Appearance = definition.InitialChart.Appearance, History = definition.InitialChart.History,
|
||||||
Vitals = attempt.CurrentVitals, Chart = attempt.Chart, ActiveOrderCodes = attempt.ActiveOrderCodes,
|
Vitals = attempt.CurrentVitals, Chart = attempt.Chart, ActiveOrderCodes = attempt.ActiveOrderCodes,
|
||||||
|
|||||||
@@ -19,8 +19,11 @@ var report_button: Button
|
|||||||
var workspace: HSplitContainer
|
var workspace: HSplitContainer
|
||||||
var leave_button: Button
|
var leave_button: Button
|
||||||
var leaving := false
|
var leaving := false
|
||||||
|
var theme_service
|
||||||
|
var theme_button: Button
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
|
theme_service = get_node("/root/UIThemeService")
|
||||||
set_anchors_preset(Control.PRESET_FULL_RECT); add_theme_constant_override("separation", 8)
|
set_anchors_preset(Control.PRESET_FULL_RECT); add_theme_constant_override("separation", 8)
|
||||||
var top := HBoxContainer.new(); top.add_theme_constant_override("separation", 8); add_child(top)
|
var top := HBoxContainer.new(); top.add_theme_constant_override("separation", 8); add_child(top)
|
||||||
heading = Label.new(); heading.size_flags_horizontal = Control.SIZE_EXPAND_FILL; Style.set_label(heading, 25, Style.TEXT); top.add_child(heading)
|
heading = Label.new(); heading.size_flags_horizontal = Control.SIZE_EXPAND_FILL; Style.set_label(heading, 25, Style.TEXT); top.add_child(heading)
|
||||||
@@ -29,10 +32,12 @@ func _ready() -> void:
|
|||||||
var larger := Button.new(); larger.text = "A+"; larger.tooltip_text = "Increase text size"; larger.pressed.connect(_zoom.bind(CCSService.TEXT_SCALE_STEP)); top.add_child(larger)
|
var larger := Button.new(); larger.text = "A+"; larger.tooltip_text = "Increase text size"; larger.pressed.connect(_zoom.bind(CCSService.TEXT_SCALE_STEP)); top.add_child(larger)
|
||||||
var clear_highlights := Button.new(); clear_highlights.text = "Clear"; clear_highlights.tooltip_text = "Clear highlights"; clear_highlights.pressed.connect(_clear_highlights); top.add_child(clear_highlights)
|
var clear_highlights := Button.new(); clear_highlights.text = "Clear"; clear_highlights.tooltip_text = "Clear highlights"; clear_highlights.pressed.connect(_clear_highlights); top.add_child(clear_highlights)
|
||||||
report_button = Button.new(); report_button.text = "Report"; report_button.tooltip_text = "Report CCS case"; report_button.pressed.connect(_report); top.add_child(report_button)
|
report_button = Button.new(); report_button.text = "Report"; report_button.tooltip_text = "Report CCS case"; report_button.pressed.connect(_report); top.add_child(report_button)
|
||||||
|
theme_button = Button.new(); theme_button.custom_minimum_size = Vector2(44, 44); theme_button.add_theme_font_size_override("font_size", 22); UISoundService.set_button_sound(theme_button, "toggle"); theme_button.pressed.connect(theme_service.toggle_theme); top.add_child(theme_button); _refresh_theme_button()
|
||||||
workspace = HSplitContainer.new(); workspace.size_flags_vertical = Control.SIZE_EXPAND_FILL; workspace.split_offset = 850; add_child(workspace)
|
workspace = HSplitContainer.new(); workspace.size_flags_vertical = Control.SIZE_EXPAND_FILL; workspace.split_offset = 850; add_child(workspace)
|
||||||
var chart_panel := VBoxContainer.new(); chart_panel.custom_minimum_size.x = 500; workspace.add_child(chart_panel)
|
var chart_scroll := ScrollContainer.new(); chart_scroll.custom_minimum_size.x = 500; chart_scroll.size_flags_horizontal = Control.SIZE_EXPAND_FILL; workspace.add_child(chart_scroll)
|
||||||
summary = RichTextLabel.new(); summary.bbcode_enabled = true; summary.selection_enabled = true; summary.custom_minimum_size.y = 160; summary.set_meta("ccs_region", "summary"); summary.gui_input.connect(_text_input.bind(summary)); chart_panel.add_child(summary)
|
var chart_panel := VBoxContainer.new(); chart_panel.size_flags_horizontal = Control.SIZE_EXPAND_FILL; chart_panel.add_theme_constant_override("separation", 18); chart_scroll.add_child(chart_panel)
|
||||||
chart = RichTextLabel.new(); chart.bbcode_enabled = true; chart.selection_enabled = true; chart.size_flags_vertical = Control.SIZE_EXPAND_FILL; chart.set_meta("ccs_region", "chart"); chart.gui_input.connect(_text_input.bind(chart)); chart_panel.add_child(chart)
|
summary = RichTextLabel.new(); summary.bbcode_enabled = true; summary.selection_enabled = true; summary.fit_content = true; summary.scroll_active = false; summary.set_meta("ccs_region", "summary"); summary.gui_input.connect(_text_input.bind(summary)); chart_panel.add_child(summary)
|
||||||
|
chart = RichTextLabel.new(); chart.bbcode_enabled = true; chart.selection_enabled = true; chart.fit_content = true; chart.scroll_active = false; chart.set_meta("ccs_region", "chart"); chart.gui_input.connect(_text_input.bind(chart)); chart_panel.add_child(chart)
|
||||||
var clerk_scroll := ScrollContainer.new(); clerk_scroll.custom_minimum_size.x = 430; workspace.add_child(clerk_scroll)
|
var clerk_scroll := ScrollContainer.new(); clerk_scroll.custom_minimum_size.x = 430; workspace.add_child(clerk_scroll)
|
||||||
var clerk := VBoxContainer.new(); clerk.size_flags_horizontal = Control.SIZE_EXPAND_FILL; clerk.add_theme_constant_override("separation", 8); clerk_scroll.add_child(clerk)
|
var clerk := VBoxContainer.new(); clerk.size_flags_horizontal = Control.SIZE_EXPAND_FILL; clerk.add_theme_constant_override("separation", 8); clerk_scroll.add_child(clerk)
|
||||||
var order_title := Label.new(); order_title.text = "Order Clerk"; Style.set_label(order_title, 21, Style.CYAN); clerk.add_child(order_title)
|
var order_title := Label.new(); order_title.text = "Order Clerk"; Style.set_label(order_title, 21, Style.CYAN); clerk.add_child(order_title)
|
||||||
@@ -56,6 +61,7 @@ func _ready() -> void:
|
|||||||
CCSService.orders_changed.connect(_render_search)
|
CCSService.orders_changed.connect(_render_search)
|
||||||
CCSService.request_failed.connect(_request_failed)
|
CCSService.request_failed.connect(_request_failed)
|
||||||
CCSService.report_submitted.connect(_report_submitted)
|
CCSService.report_submitted.connect(_report_submitted)
|
||||||
|
if not theme_service.theme_changed.is_connected(_on_theme_changed): theme_service.theme_changed.connect(_on_theme_changed)
|
||||||
report_dialog = preload("res://scripts/ui/ccs_report_dialog.gd").new(); add_child(report_dialog)
|
report_dialog = preload("res://scripts/ui/ccs_report_dialog.gd").new(); add_child(report_dialog)
|
||||||
|
|
||||||
func on_show(payload: Variant = null) -> void:
|
func on_show(payload: Variant = null) -> void:
|
||||||
@@ -101,9 +107,13 @@ func _place_order(code: String) -> void:
|
|||||||
|
|
||||||
func _tick() -> void:
|
func _tick() -> void:
|
||||||
var deadline := CCSService.deadline_unix()
|
var deadline := CCSService.deadline_unix()
|
||||||
if deadline <= 0: clock.text = "Practice | Case time %d min" % int(CCSService.attempt.get("simulatedMinute", 0)); return
|
if deadline <= 0:
|
||||||
|
clock.visible = false
|
||||||
|
clock.text = ""
|
||||||
|
return
|
||||||
|
clock.visible = true
|
||||||
var remaining := maxi(0, int(ceil(deadline - Time.get_unix_time_from_system())))
|
var remaining := maxi(0, int(ceil(deadline - Time.get_unix_time_from_system())))
|
||||||
clock.text = "%02d:%02d | Case time %d min" % [floori(float(remaining) / 60.0), remaining % 60, int(CCSService.attempt.get("simulatedMinute", 0))]
|
clock.text = "%02d:%02d" % [floori(float(remaining) / 60.0), remaining % 60]
|
||||||
if remaining == 0 and not CCSService.is_loading: CCSService.load_attempt(str(CCSService.attempt.get("id", "")))
|
if remaining == 0 and not CCSService.is_loading: CCSService.load_attempt(str(CCSService.attempt.get("id", "")))
|
||||||
|
|
||||||
func leave_case() -> void:
|
func leave_case() -> void:
|
||||||
@@ -192,3 +202,12 @@ func _report() -> void:
|
|||||||
|
|
||||||
func _report_submitted(_id: String) -> void:
|
func _report_submitted(_id: String) -> void:
|
||||||
Style.style_chip(report_button, Style.RED); report_button.tooltip_text = "Report submitted; report another issue"
|
Style.style_chip(report_button, Style.RED); report_button.tooltip_text = "Report submitted; report another issue"
|
||||||
|
|
||||||
|
func _on_theme_changed(_is_dark_mode: bool) -> void:
|
||||||
|
_refresh_theme_button()
|
||||||
|
|
||||||
|
func _refresh_theme_button() -> void:
|
||||||
|
if theme_button == null: return
|
||||||
|
theme_button.text = "☀" if theme_service.is_dark_mode() else "☾"
|
||||||
|
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)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ const Style := preload("res://scripts/ui/ui_style.gd")
|
|||||||
var main: Control
|
var main: Control
|
||||||
var title: Label
|
var title: Label
|
||||||
var score_body: RichTextLabel
|
var score_body: RichTextLabel
|
||||||
|
var criteria_container: VBoxContainer
|
||||||
var timeline_body: RichTextLabel
|
var timeline_body: RichTextLabel
|
||||||
var references: VBoxContainer
|
var references: VBoxContainer
|
||||||
var report_dialog: Control
|
var report_dialog: Control
|
||||||
@@ -11,8 +12,11 @@ var report_button: Button
|
|||||||
var current_attempt := {}
|
var current_attempt := {}
|
||||||
var status: Label
|
var status: Label
|
||||||
var starting_case := false
|
var starting_case := false
|
||||||
|
var theme_service
|
||||||
|
var theme_button: Button
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
|
theme_service = get_node("/root/UIThemeService")
|
||||||
set_anchors_preset(Control.PRESET_FULL_RECT); add_theme_constant_override("separation", 10)
|
set_anchors_preset(Control.PRESET_FULL_RECT); add_theme_constant_override("separation", 10)
|
||||||
var toolbar := HBoxContainer.new(); toolbar.add_theme_constant_override("separation", 8); add_child(toolbar)
|
var toolbar := HBoxContainer.new(); toolbar.add_theme_constant_override("separation", 8); add_child(toolbar)
|
||||||
title = Label.new(); title.size_flags_horizontal = Control.SIZE_EXPAND_FILL; Style.set_label(title, 30, Style.TEXT); toolbar.add_child(title)
|
title = Label.new(); title.size_flags_horizontal = Control.SIZE_EXPAND_FILL; Style.set_label(title, 30, Style.TEXT); toolbar.add_child(title)
|
||||||
@@ -20,9 +24,11 @@ func _ready() -> void:
|
|||||||
var larger := Button.new(); larger.text = "A+"; larger.tooltip_text = "Increase text size"; larger.pressed.connect(_zoom.bind(CCSService.TEXT_SCALE_STEP)); toolbar.add_child(larger)
|
var larger := Button.new(); larger.text = "A+"; larger.tooltip_text = "Increase text size"; larger.pressed.connect(_zoom.bind(CCSService.TEXT_SCALE_STEP)); toolbar.add_child(larger)
|
||||||
var clear := Button.new(); clear.text = "Clear"; clear.tooltip_text = "Clear highlights"; clear.pressed.connect(_clear_highlights); toolbar.add_child(clear)
|
var clear := Button.new(); clear.text = "Clear"; clear.tooltip_text = "Clear highlights"; clear.pressed.connect(_clear_highlights); toolbar.add_child(clear)
|
||||||
report_button = Button.new(); report_button.text = "Report"; report_button.tooltip_text = "Report CCS case"; report_button.pressed.connect(_report); toolbar.add_child(report_button)
|
report_button = Button.new(); report_button.text = "Report"; report_button.tooltip_text = "Report CCS case"; report_button.pressed.connect(_report); toolbar.add_child(report_button)
|
||||||
|
theme_button = Button.new(); theme_button.custom_minimum_size = Vector2(44, 44); theme_button.add_theme_font_size_override("font_size", 22); UISoundService.set_button_sound(theme_button, "toggle"); theme_button.pressed.connect(theme_service.toggle_theme); toolbar.add_child(theme_button); _refresh_theme_button()
|
||||||
var scroll := ScrollContainer.new(); scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL; add_child(scroll)
|
var scroll := ScrollContainer.new(); scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL; add_child(scroll)
|
||||||
var content := VBoxContainer.new(); content.size_flags_horizontal = Control.SIZE_EXPAND_FILL; content.add_theme_constant_override("separation", 14); scroll.add_child(content)
|
var content := VBoxContainer.new(); content.size_flags_horizontal = Control.SIZE_EXPAND_FILL; content.add_theme_constant_override("separation", 14); scroll.add_child(content)
|
||||||
score_body = _study_label("score"); score_body.custom_minimum_size.y = 200; content.add_child(score_body)
|
score_body = _study_label("score"); content.add_child(score_body)
|
||||||
|
criteria_container = VBoxContainer.new(); criteria_container.add_theme_constant_override("separation", 12); content.add_child(criteria_container)
|
||||||
timeline_body = _study_label("timeline"); timeline_body.custom_minimum_size.y = 260; content.add_child(timeline_body)
|
timeline_body = _study_label("timeline"); timeline_body.custom_minimum_size.y = 260; content.add_child(timeline_body)
|
||||||
references = VBoxContainer.new(); content.add_child(references)
|
references = VBoxContainer.new(); content.add_child(references)
|
||||||
CCSService.attempt_changed.connect(_refresh_loaded_attempt); CCSService.report_submitted.connect(_report_submitted)
|
CCSService.attempt_changed.connect(_refresh_loaded_attempt); CCSService.report_submitted.connect(_report_submitted)
|
||||||
@@ -32,6 +38,7 @@ func _ready() -> void:
|
|||||||
var back := Button.new(); back.text = "Back to Step 3 Modes"; back.pressed.connect(func(): main.show_screen("selection", "step3")); row.add_child(back)
|
var back := Button.new(); back.text = "Back to Step 3 Modes"; back.pressed.connect(func(): main.show_screen("selection", "step3")); row.add_child(back)
|
||||||
status = Label.new(); Style.set_label(status, 14, Style.RED); row.add_child(status)
|
status = Label.new(); Style.set_label(status, 14, Style.RED); row.add_child(status)
|
||||||
CCSService.request_failed.connect(_request_failed)
|
CCSService.request_failed.connect(_request_failed)
|
||||||
|
if not theme_service.theme_changed.is_connected(_on_theme_changed): theme_service.theme_changed.connect(_on_theme_changed)
|
||||||
|
|
||||||
func _study_label(region: String) -> RichTextLabel:
|
func _study_label(region: String) -> RichTextLabel:
|
||||||
var label := RichTextLabel.new(); label.bbcode_enabled = true; label.fit_content = true; label.selection_enabled = true; label.set_meta("ccs_region", region); label.gui_input.connect(_text_input.bind(label)); return label
|
var label := RichTextLabel.new(); label.bbcode_enabled = true; label.fit_content = true; label.selection_enabled = true; label.set_meta("ccs_region", region); label.gui_input.connect(_text_input.bind(label)); return label
|
||||||
@@ -48,17 +55,14 @@ func on_show(payload: Variant = null) -> void:
|
|||||||
|
|
||||||
func _score_plain() -> String:
|
func _score_plain() -> String:
|
||||||
var score: Dictionary = current_attempt.get("score", {})
|
var score: Dictionary = current_attempt.get("score", {})
|
||||||
var lines: Array[String] = ["Case result: %d/%d points (%.0f%%)" % [score.get("earnedPoints", 0), score.get("possiblePoints", 0), score.get("percent", 0)]]
|
var elapsed_seconds := int(current_attempt.get("elapsedSeconds", 0))
|
||||||
|
var lines: Array[String] = ["Case result: %d/%d points (%.0f%%)" % [score.get("earnedPoints", 0), score.get("possiblePoints", 0), score.get("percent", 0)], "Time taken: %d min %02d sec" % [floori(float(elapsed_seconds) / 60.0), elapsed_seconds % 60]]
|
||||||
var rating: Dictionary = current_attempt.get("rating", {})
|
var rating: Dictionary = current_attempt.get("rating", {})
|
||||||
if bool(rating.get("rated", false)):
|
if bool(rating.get("rated", false)):
|
||||||
lines.append("CCS ELO: %d (%+d)" % [rating.get("userElo", 1000), rating.get("userEloDelta", 0)])
|
lines.append("CCS ELO: %d (%+d)" % [rating.get("userElo", 1000), rating.get("userEloDelta", 0)])
|
||||||
else:
|
else:
|
||||||
lines.append("CCS ELO unchanged: this case was not rating-eligible.")
|
lines.append("CCS ELO unchanged: this case was not rating-eligible.")
|
||||||
for criterion in current_attempt.get("score", {}).get("criteria", []):
|
return "\n".join(lines)
|
||||||
var observed := str(criterion.get("observedAction", "Not performed"))
|
|
||||||
if criterion.get("observedMinute", null) != null: observed += " at minute %d" % criterion.get("observedMinute", 0)
|
|
||||||
lines.append("%s: %s %s%d\nExpected: %s\nObserved: %s\n%s" % [criterion.get("title", criterion.get("criterionId", "Criterion")), str(criterion.get("status", "missed")).capitalize(), "+" if int(criterion.get("points", 0)) >= 0 else "", criterion.get("points", 0), criterion.get("expectedAction", ""), observed, criterion.get("rationale", "")])
|
|
||||||
return "\n\n".join(lines)
|
|
||||||
|
|
||||||
func _timeline_plain() -> String:
|
func _timeline_plain() -> String:
|
||||||
var lines: Array[String] = ["Case timeline"]
|
var lines: Array[String] = ["Case timeline"]
|
||||||
@@ -69,6 +73,42 @@ func _render_text() -> void:
|
|||||||
var id := str(current_attempt.get("id", ""))
|
var id := str(current_attempt.get("id", ""))
|
||||||
score_body.text = CCSService.highlighted_text(id, "score", _score_plain())
|
score_body.text = CCSService.highlighted_text(id, "score", _score_plain())
|
||||||
timeline_body.text = CCSService.highlighted_text(id, "timeline", _timeline_plain())
|
timeline_body.text = CCSService.highlighted_text(id, "timeline", _timeline_plain())
|
||||||
|
_render_criteria()
|
||||||
|
|
||||||
|
func _render_criteria() -> void:
|
||||||
|
for child in criteria_container.get_children(): child.free()
|
||||||
|
var index := 0
|
||||||
|
for criterion in current_attempt.get("score", {}).get("criteria", []):
|
||||||
|
var criterion_data: Dictionary = criterion
|
||||||
|
var result_status := str(criterion_data.get("status", "missed"))
|
||||||
|
var accent := _status_color(result_status)
|
||||||
|
var panel := PanelContainer.new()
|
||||||
|
panel.add_theme_stylebox_override("panel", Style.panel_box(Style.SURFACE, accent))
|
||||||
|
criteria_container.add_child(panel)
|
||||||
|
var body := VBoxContainer.new(); body.add_theme_constant_override("separation", 7); panel.add_child(body)
|
||||||
|
var criterion_title := Label.new(); criterion_title.text = str(criterion_data.get("title", criterion_data.get("criterionId", "Criterion"))); criterion_title.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART; Style.set_label(criterion_title, 20, Style.TEXT); body.add_child(criterion_title)
|
||||||
|
var status_label := Label.new(); status_label.text = _status_text(result_status, int(criterion_data.get("points", 0))); Style.set_label(status_label, 16, accent); body.add_child(status_label)
|
||||||
|
_add_detail(body, "EXPECTED", str(criterion_data.get("expectedAction", "")), "criterion_%d_expected" % index, Style.CYAN)
|
||||||
|
var observed := str(criterion_data.get("observedAction", "Not performed"))
|
||||||
|
if criterion_data.get("observedMinute", null) != null: observed += " at minute %d" % criterion_data.get("observedMinute", 0)
|
||||||
|
_add_detail(body, "OBSERVED", observed, "criterion_%d_observed" % index, accent)
|
||||||
|
_add_detail(body, "WHY THIS MATTERS", str(criterion_data.get("rationale", "")), "criterion_%d_explanation" % index, Style.AMBER, true)
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
func _add_detail(parent: VBoxContainer, caption: String, value: String, region: String, color: Color, muted_value: bool = false) -> void:
|
||||||
|
var caption_label := Label.new(); caption_label.text = caption; Style.set_label(caption_label, 13, color); parent.add_child(caption_label)
|
||||||
|
var value_label := _study_label(region); value_label.text = CCSService.highlighted_text(str(current_attempt.get("id", "")), region, value); value_label.add_theme_color_override("default_color", Style.MUTED if muted_value else Style.TEXT); parent.add_child(value_label)
|
||||||
|
|
||||||
|
func _status_color(result_status: String) -> Color:
|
||||||
|
if result_status == "credited": return Style.LIME
|
||||||
|
if result_status == "avoided": return Style.AMBER
|
||||||
|
return Style.RED
|
||||||
|
|
||||||
|
func _status_text(result_status: String, points: int) -> String:
|
||||||
|
if result_status == "credited": return "CREDITED | +%d pts" % points
|
||||||
|
if result_status == "harmful": return "HARMFUL | %d pts" % points
|
||||||
|
if result_status == "avoided": return "AVOIDED | 0 pts"
|
||||||
|
return "MISSED | 0 pts"
|
||||||
|
|
||||||
func _render_references() -> void:
|
func _render_references() -> void:
|
||||||
for child in references.get_children(): child.queue_free()
|
for child in references.get_children(): child.queue_free()
|
||||||
@@ -92,6 +132,15 @@ func _zoom(delta: float) -> void:
|
|||||||
func _apply_text_scale() -> void:
|
func _apply_text_scale() -> void:
|
||||||
var font_size := int(round(18.0 * CCSService.text_scale))
|
var font_size := int(round(18.0 * CCSService.text_scale))
|
||||||
for label in [score_body, timeline_body]: label.add_theme_font_size_override("normal_font_size", font_size); label.add_theme_font_size_override("bold_font_size", font_size)
|
for label in [score_body, timeline_body]: label.add_theme_font_size_override("normal_font_size", font_size); label.add_theme_font_size_override("bold_font_size", font_size)
|
||||||
|
_scale_criteria(criteria_container)
|
||||||
|
|
||||||
|
func _scale_criteria(node: Node) -> void:
|
||||||
|
if node is RichTextLabel:
|
||||||
|
node.add_theme_font_size_override("normal_font_size", int(round(17.0 * CCSService.text_scale)))
|
||||||
|
elif node is Label:
|
||||||
|
if not node.has_meta("ccs_base_font_size"): node.set_meta("ccs_base_font_size", node.get_theme_font_size("font_size"))
|
||||||
|
node.add_theme_font_size_override("font_size", int(round(float(node.get_meta("ccs_base_font_size")) * CCSService.text_scale)))
|
||||||
|
for child in node.get_children(): _scale_criteria(child)
|
||||||
|
|
||||||
func _clear_highlights() -> void:
|
func _clear_highlights() -> void:
|
||||||
CCSService.clear_highlights(str(current_attempt.get("id", ""))); _render_text()
|
CCSService.clear_highlights(str(current_attempt.get("id", ""))); _render_text()
|
||||||
@@ -114,3 +163,13 @@ func _request_failed(message: String) -> void:
|
|||||||
if not visible or not starting_case: return
|
if not visible or not starting_case: return
|
||||||
starting_case = false
|
starting_case = false
|
||||||
status.text = message
|
status.text = message
|
||||||
|
|
||||||
|
func _on_theme_changed(_is_dark_mode: bool) -> void:
|
||||||
|
_refresh_theme_button()
|
||||||
|
if visible: _render_text()
|
||||||
|
|
||||||
|
func _refresh_theme_button() -> void:
|
||||||
|
if theme_button == null: return
|
||||||
|
theme_button.text = "☀" if theme_service.is_dark_mode() else "☾"
|
||||||
|
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user