Redesign flag/report icons as vector assets and dock review panels inside their choice card
Flag question now uses a clean vector flag (dark/light SVG variants, replacing a hand-drawn pixel-art icon that got muddied by the shared toolbar icon-tint override). Report question is now a megaphone instead of a second flag glyph, since both toolbar buttons looked identical before. The correct-answer explanation and the wrong-answer follow-up quiz previously rendered as separate bordered boxes sitting below the entire choice list. Both now dock inside their own choice's card: the explanation panel reparents onto the correct choice's row, the follow-up panel was already there but visually detached. A shared _attached_panel_box style drops the shared border/corner between the choice button and its panel so they read as one continuous card.
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
||||||
|
<rect x="5" y="3.4" width="1.6" height="17.2" rx="0.8" fill="#F6F8FF"/>
|
||||||
|
<path d="M6.6 4.8H17.3L14.6 8.4L17.3 12H6.6V4.8Z" fill="#FFC857"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 223 B |
@@ -0,0 +1,43 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://pffbgabfvqoi"
|
||||||
|
path="res://.godot/imported/flag-dark.svg-991f8446e8d6e35dda3f6918b79c2529.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/icons/medmind/flag-dark.svg"
|
||||||
|
dest_files=["res://.godot/imported/flag-dark.svg-991f8446e8d6e35dda3f6918b79c2529.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,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
||||||
|
<rect x="5" y="3.4" width="1.6" height="17.2" rx="0.8" fill="#0F172A"/>
|
||||||
|
<path d="M6.6 4.8H17.3L14.6 8.4L17.3 12H6.6V4.8Z" fill="#986400"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 223 B |
@@ -0,0 +1,43 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://rrjvnmtbkc2c"
|
||||||
|
path="res://.godot/imported/flag-light.svg-028b26500c0b5f2e10e3a85231e2e56d.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/icons/medmind/flag-light.svg"
|
||||||
|
dest_files=["res://.godot/imported/flag-light.svg-028b26500c0b5f2e10e3a85231e2e56d.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
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
||||||
<path d="M5 3V21" stroke="#CBD5E1" stroke-width="1.8" stroke-linecap="round"/>
|
<rect x="3" y="13.4" width="3.6" height="5.6" rx="1.4" stroke="#CBD5E1" stroke-width="1.8" stroke-linejoin="round"/>
|
||||||
<path d="M5 5.2C9 2.8 13 7.1 19 4.5L16.5 9.8 19 15.2C13 17.8 9 13.5 5 15.9V5.2Z" stroke="#FF3344" stroke-width="1.8" stroke-linejoin="round"/>
|
<path d="M6.6 9.6 15 6.1V17.9L6.6 14.4V9.6Z" stroke="#CBD5E1" stroke-width="1.8" stroke-linejoin="round"/>
|
||||||
<path d="M12 7.8V11.5M12 14V14.1" stroke="#FF3344" stroke-width="1.8" stroke-linecap="round"/>
|
<path d="M18.2 7.4 21 5.6M19.1 12H22M18.2 16.6 21 18.4" stroke="#FF3344" stroke-width="1.8" stroke-linecap="round"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 403 B After Width: | Height: | Size: 427 B |
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://d1rf1y5ym0abp"
|
uid="uid://2h8hksovbjvl"
|
||||||
path="res://.godot/imported/report-question-dark.svg-0c56358e403130829c20d7684d988f4f.ctex"
|
path="res://.godot/imported/report-question-dark.svg-0c56358e403130829c20d7684d988f4f.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": false
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
||||||
<path d="M5 3V21" stroke="#26344F" stroke-width="1.8" stroke-linecap="round"/>
|
<rect x="3" y="13.4" width="3.6" height="5.6" rx="1.4" stroke="#26344F" stroke-width="1.8" stroke-linejoin="round"/>
|
||||||
<path d="M5 5.2C9 2.8 13 7.1 19 4.5L16.5 9.8 19 15.2C13 17.8 9 13.5 5 15.9V5.2Z" stroke="#EF3340" stroke-width="1.8" stroke-linejoin="round"/>
|
<path d="M6.6 9.6 15 6.1V17.9L6.6 14.4V9.6Z" stroke="#26344F" stroke-width="1.8" stroke-linejoin="round"/>
|
||||||
<path d="M12 7.8V11.5M12 14V14.1" stroke="#EF3340" stroke-width="1.8" stroke-linecap="round"/>
|
<path d="M18.2 7.4 21 5.6M19.1 12H22M18.2 16.6 21 18.4" stroke="#FF3344" stroke-width="1.8" stroke-linecap="round"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 403 B After Width: | Height: | Size: 427 B |
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://btqfcwm8c1ymy"
|
uid="uid://gljo3k630b6f"
|
||||||
path="res://.godot/imported/report-question-light.svg-d6a637ee28802ff5e54da98728d1db20.ctex"
|
path="res://.godot/imported/report-question-light.svg-d6a637ee28802ff5e54da98728d1db20.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": 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 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_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 REPORT_QUESTION_LIGHT_ICON := preload("res://assets/icons/medmind/report-question-light.svg")
|
||||||
|
const FLAG_DARK_ICON := preload("res://assets/icons/medmind/flag-dark.svg")
|
||||||
|
const FLAG_LIGHT_ICON := preload("res://assets/icons/medmind/flag-light.svg")
|
||||||
const BADGE_CIRCLE_OUTLINE_ICON := preload("res://assets/icons/medmind/badge-circle-outline.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 BADGE_CIRCLE_FILLED_ICON := preload("res://assets/icons/medmind/badge-circle-filled.svg")
|
||||||
const FEEDBACK_FADE_SECONDS := 0.45
|
const FEEDBACK_FADE_SECONDS := 0.45
|
||||||
@@ -274,7 +276,6 @@ func _ready() -> void:
|
|||||||
flag_button = Button.new()
|
flag_button = Button.new()
|
||||||
flag_button.toggle_mode = true
|
flag_button.toggle_mode = true
|
||||||
flag_button.tooltip_text = "Flag question"
|
flag_button.tooltip_text = "Flag question"
|
||||||
flag_button.icon = _make_flag_icon()
|
|
||||||
flag_button.custom_minimum_size = Vector2(44, 44)
|
flag_button.custom_minimum_size = Vector2(44, 44)
|
||||||
Style.style_chip(flag_button, Style.AMBER)
|
Style.style_chip(flag_button, Style.AMBER)
|
||||||
UISoundService.set_button_sound(flag_button, "toggle")
|
UISoundService.set_button_sound(flag_button, "toggle")
|
||||||
@@ -434,7 +435,7 @@ func _ready() -> void:
|
|||||||
|
|
||||||
for index in range(5):
|
for index in range(5):
|
||||||
var choice_row := VBoxContainer.new()
|
var choice_row := VBoxContainer.new()
|
||||||
choice_row.add_theme_constant_override("separation", 6)
|
choice_row.add_theme_constant_override("separation", 0)
|
||||||
choices_container.add_child(choice_row)
|
choices_container.add_child(choice_row)
|
||||||
choice_rows.append(choice_row)
|
choice_rows.append(choice_row)
|
||||||
|
|
||||||
@@ -701,7 +702,7 @@ func _question_content_box(dark: bool) -> StyleBoxFlat:
|
|||||||
return box
|
return box
|
||||||
|
|
||||||
|
|
||||||
func _answer_box(dark: bool, state: String) -> StyleBoxFlat:
|
func _answer_box(dark: bool, state: String, attached: bool = false) -> StyleBoxFlat:
|
||||||
var box := StyleBoxFlat.new()
|
var box := StyleBoxFlat.new()
|
||||||
box.content_margin_left = 62
|
box.content_margin_left = 62
|
||||||
box.content_margin_right = 82
|
box.content_margin_right = 82
|
||||||
@@ -727,6 +728,46 @@ func _answer_box(dark: bool, state: String) -> StyleBoxFlat:
|
|||||||
box.border_color = border
|
box.border_color = border
|
||||||
box.set_border_width_all(2)
|
box.set_border_width_all(2)
|
||||||
box.set_corner_radius_all(14)
|
box.set_corner_radius_all(14)
|
||||||
|
if attached:
|
||||||
|
# A review/follow-up panel is docked directly beneath this choice - drop the
|
||||||
|
# shared edge so the two read as one continuous card instead of two stacked boxes.
|
||||||
|
box.border_width_bottom = 0
|
||||||
|
box.corner_radius_bottom_left = 0
|
||||||
|
box.corner_radius_bottom_right = 0
|
||||||
|
return box
|
||||||
|
|
||||||
|
|
||||||
|
func _attached_panel_box(dark: bool, accent: Color) -> StyleBoxFlat:
|
||||||
|
var box := StyleBoxFlat.new()
|
||||||
|
box.bg_color = Color("17183b") if dark else Color("eff4ff")
|
||||||
|
if accent == Brand.SUCCESS:
|
||||||
|
box.bg_color = Color("08251d") if dark else Color("ecfdf3")
|
||||||
|
elif accent == Color("fb7185"):
|
||||||
|
box.bg_color = Color("32131d") if dark else Color("fff1f2")
|
||||||
|
box.border_color = accent
|
||||||
|
box.border_width_left = 2
|
||||||
|
box.border_width_right = 2
|
||||||
|
box.border_width_bottom = 2
|
||||||
|
box.border_width_top = 0
|
||||||
|
box.corner_radius_top_left = 0
|
||||||
|
box.corner_radius_top_right = 0
|
||||||
|
box.corner_radius_bottom_left = 14
|
||||||
|
box.corner_radius_bottom_right = 14
|
||||||
|
box.content_margin_left = 12
|
||||||
|
box.content_margin_right = 12
|
||||||
|
box.content_margin_top = 10
|
||||||
|
box.content_margin_bottom = 10
|
||||||
|
return box
|
||||||
|
|
||||||
|
|
||||||
|
func _correct_review_panel_box(dark: bool) -> StyleBoxFlat:
|
||||||
|
# correct_review_panel already pads its content via an inner MarginContainer,
|
||||||
|
# so skip the shared attached-panel content margin to avoid doubling it up.
|
||||||
|
var box := _attached_panel_box(dark, Brand.SUCCESS)
|
||||||
|
box.content_margin_left = 0
|
||||||
|
box.content_margin_right = 0
|
||||||
|
box.content_margin_top = 0
|
||||||
|
box.content_margin_bottom = 0
|
||||||
return box
|
return box
|
||||||
|
|
||||||
|
|
||||||
@@ -768,7 +809,7 @@ func _style_theme_toggle_button(dark: bool) -> void:
|
|||||||
theme_button.add_theme_constant_override("h_separation", 0)
|
theme_button.add_theme_constant_override("h_separation", 0)
|
||||||
|
|
||||||
|
|
||||||
func _style_asset_toolbar_button(button: Button, texture: Texture2D, dark: bool) -> void:
|
func _style_asset_toolbar_button(button: Button, texture: Texture2D, dark: bool, active: bool = false) -> void:
|
||||||
if button == null:
|
if button == null:
|
||||||
return
|
return
|
||||||
button.text = ""
|
button.text = ""
|
||||||
@@ -782,7 +823,7 @@ func _style_asset_toolbar_button(button: Button, texture: Texture2D, dark: bool)
|
|||||||
button.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
button.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||||
button.add_theme_constant_override("h_separation", 0)
|
button.add_theme_constant_override("h_separation", 0)
|
||||||
button.add_theme_constant_override("icon_max_width", 23)
|
button.add_theme_constant_override("icon_max_width", 23)
|
||||||
button.add_theme_stylebox_override("normal", _toolbar_box(dark))
|
button.add_theme_stylebox_override("normal", _toolbar_box(dark, active))
|
||||||
button.add_theme_stylebox_override("hover", _toolbar_box(dark, true))
|
button.add_theme_stylebox_override("hover", _toolbar_box(dark, true))
|
||||||
button.add_theme_stylebox_override("pressed", _toolbar_box(dark, true))
|
button.add_theme_stylebox_override("pressed", _toolbar_box(dark, true))
|
||||||
button.add_theme_stylebox_override("focus", StyleBoxEmpty.new())
|
button.add_theme_stylebox_override("focus", StyleBoxEmpty.new())
|
||||||
@@ -813,15 +854,6 @@ func _primary_action_box(dark: bool, state: String) -> StyleBoxFlat:
|
|||||||
return box
|
return box
|
||||||
|
|
||||||
|
|
||||||
func _correct_review_box(dark: bool) -> StyleBoxFlat:
|
|
||||||
var box := StyleBoxFlat.new()
|
|
||||||
box.bg_color = Color("08251d") if dark else Color("f0fdf4")
|
|
||||||
box.border_color = Color(Brand.SUCCESS, 0.62)
|
|
||||||
box.set_border_width_all(1)
|
|
||||||
box.set_corner_radius_all(7)
|
|
||||||
return box
|
|
||||||
|
|
||||||
|
|
||||||
func _teaching_card_box(dark: bool, accent: Color) -> StyleBoxFlat:
|
func _teaching_card_box(dark: bool, accent: Color) -> StyleBoxFlat:
|
||||||
var box := StyleBoxFlat.new()
|
var box := StyleBoxFlat.new()
|
||||||
box.bg_color = Color(accent, 0.08 if dark else 0.045)
|
box.bg_color = Color(accent, 0.08 if dark else 0.045)
|
||||||
@@ -906,15 +938,15 @@ func _apply_question_theme() -> void:
|
|||||||
if wrong_options_heading != null:
|
if wrong_options_heading != null:
|
||||||
wrong_options_heading.add_theme_color_override("font_color", Brand.text_color(dark))
|
wrong_options_heading.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||||
if correct_review_panel != null:
|
if correct_review_panel != null:
|
||||||
correct_review_panel.add_theme_stylebox_override("panel", _correct_review_box(dark))
|
correct_review_panel.add_theme_stylebox_override("panel", _correct_review_panel_box(dark))
|
||||||
question_elo_label.add_theme_color_override("font_color", Brand.AMBER)
|
question_elo_label.add_theme_color_override("font_color", Brand.AMBER)
|
||||||
var navigator_heading := navigator_popup.find_child("NavigatorHeading", true, false) as Label
|
var navigator_heading := navigator_popup.find_child("NavigatorHeading", true, false) as Label
|
||||||
if navigator_heading != null:
|
if navigator_heading != null:
|
||||||
navigator_heading.add_theme_color_override("font_color", Brand.text_color(dark))
|
navigator_heading.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||||
for control in [text_smaller_button, text_larger_button, flag_button, bookmark_button, notes_button, flashcard_button, app_feedback_button]:
|
for control in [text_smaller_button, text_larger_button, bookmark_button, notes_button, flashcard_button, app_feedback_button]:
|
||||||
if control == null:
|
if control == null:
|
||||||
continue
|
continue
|
||||||
var active: bool = (control == flag_button and flagged) or (control == bookmark_button and BookmarkService.is_bookmarked(str(BlockSessionService.get_current_question().get("id", ""))))
|
var active: bool = control == bookmark_button and BookmarkService.is_bookmarked(str(BlockSessionService.get_current_question().get("id", "")))
|
||||||
control.add_theme_stylebox_override("normal", _toolbar_box(dark, active))
|
control.add_theme_stylebox_override("normal", _toolbar_box(dark, active))
|
||||||
control.add_theme_stylebox_override("hover", _toolbar_box(dark, true))
|
control.add_theme_stylebox_override("hover", _toolbar_box(dark, true))
|
||||||
control.add_theme_stylebox_override("pressed", _toolbar_box(dark, true))
|
control.add_theme_stylebox_override("pressed", _toolbar_box(dark, true))
|
||||||
@@ -923,6 +955,7 @@ func _apply_question_theme() -> void:
|
|||||||
_style_asset_toolbar_button(labs_button, LABS_DARK_ICON if dark else LABS_LIGHT_ICON, dark)
|
_style_asset_toolbar_button(labs_button, LABS_DARK_ICON if dark else LABS_LIGHT_ICON, dark)
|
||||||
_style_asset_toolbar_button(clear_highlight_button, CLEAR_HIGHLIGHT_DARK_ICON if dark else CLEAR_HIGHLIGHT_LIGHT_ICON, dark)
|
_style_asset_toolbar_button(clear_highlight_button, CLEAR_HIGHLIGHT_DARK_ICON if dark else CLEAR_HIGHLIGHT_LIGHT_ICON, dark)
|
||||||
_style_asset_toolbar_button(report_button, REPORT_QUESTION_DARK_ICON if dark else REPORT_QUESTION_LIGHT_ICON, dark)
|
_style_asset_toolbar_button(report_button, REPORT_QUESTION_DARK_ICON if dark else REPORT_QUESTION_LIGHT_ICON, dark)
|
||||||
|
_style_asset_toolbar_button(flag_button, FLAG_DARK_ICON if dark else FLAG_LIGHT_ICON, dark, flagged)
|
||||||
_style_theme_toggle_button(dark)
|
_style_theme_toggle_button(dark)
|
||||||
if skip_button != null:
|
if skip_button != null:
|
||||||
skip_button.add_theme_stylebox_override("normal", _toolbar_box(dark))
|
skip_button.add_theme_stylebox_override("normal", _toolbar_box(dark))
|
||||||
@@ -1485,6 +1518,10 @@ func _show_explanation() -> void:
|
|||||||
var question := BlockSessionService.get_current_question()
|
var question := BlockSessionService.get_current_question()
|
||||||
for button in choice_buttons:
|
for button in choice_buttons:
|
||||||
button.disabled = true
|
button.disabled = true
|
||||||
|
var correct_id := str(question.get("correct_choice_id", ""))
|
||||||
|
_dock_correct_review_panel(correct_id)
|
||||||
|
correct_review_panel.visible = true
|
||||||
|
correct_answer_heading.text = "Correct Answer: %s" % _display_label_for_choice_id(correct_id)
|
||||||
var choices := _get_presented_choices()
|
var choices := _get_presented_choices()
|
||||||
for index in range(choices.size()):
|
for index in range(choices.size()):
|
||||||
var choice: Dictionary = choices[index]
|
var choice: Dictionary = choices[index]
|
||||||
@@ -1495,14 +1532,19 @@ func _show_explanation() -> void:
|
|||||||
explanation_plain_text = str(question.get("explanation", ""))
|
explanation_plain_text = str(question.get("explanation", ""))
|
||||||
_render_explanation()
|
_render_explanation()
|
||||||
explanation_label.visible = true
|
explanation_label.visible = true
|
||||||
correct_review_panel.visible = true
|
|
||||||
var correct_id := str(question.get("correct_choice_id", ""))
|
|
||||||
correct_answer_heading.text = "Correct Answer: %s" % _display_label_for_choice_id(correct_id)
|
|
||||||
_update_question_elo_label(true)
|
_update_question_elo_label(true)
|
||||||
_refresh_nav_palette()
|
_refresh_nav_palette()
|
||||||
_update_content_vertical_alignment()
|
_update_content_vertical_alignment()
|
||||||
|
|
||||||
|
|
||||||
|
func _dock_correct_review_panel(correct_id: String) -> void:
|
||||||
|
var index := _choice_index_for_id(correct_id)
|
||||||
|
if index < 0 or index >= choice_rows.size():
|
||||||
|
return
|
||||||
|
if correct_review_panel.get_parent() != choice_rows[index]:
|
||||||
|
correct_review_panel.reparent(choice_rows[index])
|
||||||
|
|
||||||
|
|
||||||
func _render_answer_review_sections() -> void:
|
func _render_answer_review_sections() -> void:
|
||||||
_render_teaching_cards()
|
_render_teaching_cards()
|
||||||
_render_review_followups()
|
_render_review_followups()
|
||||||
@@ -2110,8 +2152,6 @@ func _on_review_pass_completed(summary: Dictionary) -> void:
|
|||||||
func refresh_theme_controls() -> void:
|
func refresh_theme_controls() -> void:
|
||||||
if media_viewer_background != null:
|
if media_viewer_background != null:
|
||||||
media_viewer_background.color = Style.BACKGROUND
|
media_viewer_background.color = Style.BACKGROUND
|
||||||
if flag_button != null:
|
|
||||||
flag_button.icon = _make_flag_icon()
|
|
||||||
_refresh_toolbar_state()
|
_refresh_toolbar_state()
|
||||||
_apply_saved_choice_state()
|
_apply_saved_choice_state()
|
||||||
_apply_question_theme()
|
_apply_question_theme()
|
||||||
@@ -3035,11 +3075,12 @@ func _style_choice_button_for_state(index: int, choice_id: String) -> void:
|
|||||||
elif eliminated.has(choice_id):
|
elif eliminated.has(choice_id):
|
||||||
state = "eliminated"
|
state = "eliminated"
|
||||||
var button := choice_buttons[index]
|
var button := choice_buttons[index]
|
||||||
var normal_box := _answer_box(dark, state)
|
var attached := _row_has_attached_panel(index)
|
||||||
|
var normal_box := _answer_box(dark, state, attached)
|
||||||
button.add_theme_stylebox_override("normal", normal_box)
|
button.add_theme_stylebox_override("normal", normal_box)
|
||||||
button.add_theme_stylebox_override("disabled", normal_box)
|
button.add_theme_stylebox_override("disabled", normal_box)
|
||||||
button.add_theme_stylebox_override("pressed", _answer_box(dark, "selected" if state == "default" else state))
|
button.add_theme_stylebox_override("pressed", _answer_box(dark, "selected" if state == "default" else state, attached))
|
||||||
button.add_theme_stylebox_override("hover", _answer_box(dark, "selected" if state == "default" else state))
|
button.add_theme_stylebox_override("hover", _answer_box(dark, "selected" if state == "default" else state, attached))
|
||||||
var text_color := Brand.muted_color(dark) if state == "eliminated" else Brand.text_color(dark)
|
var text_color := Brand.muted_color(dark) if state == "eliminated" else Brand.text_color(dark)
|
||||||
button.add_theme_color_override("font_color", text_color)
|
button.add_theme_color_override("font_color", text_color)
|
||||||
button.add_theme_color_override("font_disabled_color", text_color)
|
button.add_theme_color_override("font_disabled_color", text_color)
|
||||||
@@ -3057,6 +3098,16 @@ func _style_choice_button_for_state(index: int, choice_id: String) -> void:
|
|||||||
badge.add_theme_color_override("font_color", Color.WHITE if filled else Brand.muted_color(dark))
|
badge.add_theme_color_override("font_color", Color.WHITE if filled else Brand.muted_color(dark))
|
||||||
|
|
||||||
|
|
||||||
|
func _row_has_attached_panel(index: int) -> bool:
|
||||||
|
if index < 0 or index >= choice_rows.size():
|
||||||
|
return false
|
||||||
|
if index < choice_followup_panels.size() and choice_followup_panels[index].visible:
|
||||||
|
return true
|
||||||
|
if correct_review_panel != null and correct_review_panel.visible and correct_review_panel.get_parent() == choice_rows[index]:
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
|
||||||
func _mark_review_input_handled() -> void:
|
func _mark_review_input_handled() -> void:
|
||||||
get_viewport().set_input_as_handled()
|
get_viewport().set_input_as_handled()
|
||||||
|
|
||||||
@@ -3266,6 +3317,7 @@ func _render_followup_state(choice_id: String) -> void:
|
|||||||
else:
|
else:
|
||||||
_build_resolved_followup(index, state)
|
_build_resolved_followup(index, state)
|
||||||
choice_followup_panels[index].visible = true
|
choice_followup_panels[index].visible = true
|
||||||
|
_style_choice_button_for_state(index, choice_id)
|
||||||
|
|
||||||
|
|
||||||
func _build_resolved_followup(index: int, state: Dictionary) -> void:
|
func _build_resolved_followup(index: int, state: Dictionary) -> void:
|
||||||
@@ -3351,26 +3403,13 @@ func _add_followup_body(content: VBoxContainer, is_correct: bool) -> VBoxContain
|
|||||||
func _style_followup_card(index: int, state: Dictionary) -> void:
|
func _style_followup_card(index: int, state: Dictionary) -> void:
|
||||||
if index < 0 or index >= choice_followup_panels.size():
|
if index < 0 or index >= choice_followup_panels.size():
|
||||||
return
|
return
|
||||||
|
var is_correct := bool(state.get("is_main_correct", false))
|
||||||
choice_followup_panels[index].add_theme_stylebox_override(
|
choice_followup_panels[index].add_theme_stylebox_override(
|
||||||
"panel",
|
"panel",
|
||||||
_followup_card_box(_followup_is_dark(), bool(state.get("is_main_correct", false)))
|
_attached_panel_box(_followup_is_dark(), Brand.SUCCESS if is_correct else Color("fb7185"))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func _followup_card_box(dark: bool, is_correct: bool) -> StyleBoxFlat:
|
|
||||||
var accent := Brand.SUCCESS if is_correct else Color("fb5f6d")
|
|
||||||
var box := StyleBoxFlat.new()
|
|
||||||
box.bg_color = Color("0b172b") if dark else Color("ffffff")
|
|
||||||
box.border_color = Color(accent, 0.72)
|
|
||||||
box.set_border_width_all(1)
|
|
||||||
box.set_corner_radius_all(7)
|
|
||||||
box.content_margin_left = 12
|
|
||||||
box.content_margin_right = 12
|
|
||||||
box.content_margin_top = 10
|
|
||||||
box.content_margin_bottom = 10
|
|
||||||
return box
|
|
||||||
|
|
||||||
|
|
||||||
func _followup_body_box(dark: bool, is_correct: bool) -> StyleBoxFlat:
|
func _followup_body_box(dark: bool, is_correct: bool) -> StyleBoxFlat:
|
||||||
var accent := Brand.SUCCESS if is_correct else Color("fb5f6d")
|
var accent := Brand.SUCCESS if is_correct else Color("fb5f6d")
|
||||||
var box := StyleBoxFlat.new()
|
var box := StyleBoxFlat.new()
|
||||||
@@ -3529,22 +3568,6 @@ func _update_question_elo_label(show_label: bool) -> void:
|
|||||||
question_elo_label.visible = true
|
question_elo_label.visible = true
|
||||||
|
|
||||||
|
|
||||||
func _make_flag_icon() -> Texture2D:
|
|
||||||
var image := Image.create(24, 24, false, Image.FORMAT_RGBA8)
|
|
||||||
image.fill(Color(0, 0, 0, 0))
|
|
||||||
for y in range(4, 20):
|
|
||||||
image.set_pixel(6, y, Style.TEXT)
|
|
||||||
image.set_pixel(7, y, Style.TEXT)
|
|
||||||
for x in range(8, 18):
|
|
||||||
for y in range(4, 11):
|
|
||||||
if x < 16 or y < 9:
|
|
||||||
image.set_pixel(x, y, Style.AMBER)
|
|
||||||
for y in range(11, 14):
|
|
||||||
for x in range(8, 14 - (y - 11)):
|
|
||||||
image.set_pixel(x, y, Style.AMBER)
|
|
||||||
return ImageTexture.create_from_image(image)
|
|
||||||
|
|
||||||
|
|
||||||
func _refresh_nav_palette() -> void:
|
func _refresh_nav_palette() -> void:
|
||||||
if nav_palette == null:
|
if nav_palette == null:
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user