Move distractor explanations inline instead of a repeated bottom section
The "WHY OTHER OPTIONS ARE INCORRECT" aggregate section duplicated explanations that selected wrong choices already showed inside their own resolved follow-up quiz. Removed that section entirely; choices the user never picked now get their "why incorrect" explanation docked directly inside their own card (reusing the same followup panel/attached-card styling), so every distractor's explanation lives with its choice instead of in a separate list at the bottom.
This commit is contained in:
@@ -73,10 +73,7 @@ var correct_review_panel: PanelContainer
|
|||||||
var teaching_cards: HFlowContainer
|
var teaching_cards: HFlowContainer
|
||||||
var review_followups_section: VBoxContainer
|
var review_followups_section: VBoxContainer
|
||||||
var review_followups_content: VBoxContainer
|
var review_followups_content: VBoxContainer
|
||||||
var wrong_options_section: VBoxContainer
|
|
||||||
var wrong_options_content: VBoxContainer
|
|
||||||
var review_followup_states: Array = []
|
var review_followup_states: Array = []
|
||||||
var wrong_option_expanded := {}
|
|
||||||
var question_scroll: ScrollContainer
|
var question_scroll: ScrollContainer
|
||||||
var question_elo_label: Label
|
var question_elo_label: Label
|
||||||
var next_button: Button
|
var next_button: Button
|
||||||
@@ -635,19 +632,6 @@ func _build_answer_review_ui() -> void:
|
|||||||
review_followups_content.add_theme_constant_override("separation", 8)
|
review_followups_content.add_theme_constant_override("separation", 8)
|
||||||
review_followups_section.add_child(review_followups_content)
|
review_followups_section.add_child(review_followups_content)
|
||||||
|
|
||||||
wrong_options_section = VBoxContainer.new()
|
|
||||||
wrong_options_section.visible = false
|
|
||||||
wrong_options_section.add_theme_constant_override("separation", 8)
|
|
||||||
question_content.add_child(wrong_options_section)
|
|
||||||
var wrong_options_heading := Label.new()
|
|
||||||
wrong_options_heading.text = "WHY OTHER OPTIONS ARE INCORRECT"
|
|
||||||
wrong_options_heading.name = "WrongOptionsHeading"
|
|
||||||
_set_scaled_label(wrong_options_heading, 15, Brand.text_color(true))
|
|
||||||
wrong_options_section.add_child(wrong_options_heading)
|
|
||||||
wrong_options_content = VBoxContainer.new()
|
|
||||||
wrong_options_content.add_theme_constant_override("separation", 6)
|
|
||||||
wrong_options_section.add_child(wrong_options_content)
|
|
||||||
|
|
||||||
|
|
||||||
func _fit_modal_panels() -> void:
|
func _fit_modal_panels() -> void:
|
||||||
var available := get_viewport_rect().size - Vector2(32, 32)
|
var available := get_viewport_rect().size - Vector2(32, 32)
|
||||||
@@ -875,19 +859,6 @@ func _review_followup_box(_dark: bool, accent: Color, answered: bool) -> StyleBo
|
|||||||
return box
|
return box
|
||||||
|
|
||||||
|
|
||||||
func _wrong_option_box(dark: bool) -> StyleBoxFlat:
|
|
||||||
var box := StyleBoxFlat.new()
|
|
||||||
box.bg_color = Color("0b172b") if dark else Color("ffffff")
|
|
||||||
box.border_color = Color("2b3958") if dark else Brand.LIGHT_BORDER
|
|
||||||
box.set_border_width_all(1)
|
|
||||||
box.set_corner_radius_all(6)
|
|
||||||
box.content_margin_left = 10
|
|
||||||
box.content_margin_right = 10
|
|
||||||
box.content_margin_top = 6
|
|
||||||
box.content_margin_bottom = 6
|
|
||||||
return box
|
|
||||||
|
|
||||||
|
|
||||||
func _style_review_followup_option(button: Button, dark: bool, option_id: String, selected_id: String, correct_id: String, answered: bool) -> void:
|
func _style_review_followup_option(button: Button, dark: bool, option_id: String, selected_id: String, correct_id: String, answered: bool) -> void:
|
||||||
var state := "default"
|
var state := "default"
|
||||||
if answered and option_id == correct_id:
|
if answered and option_id == correct_id:
|
||||||
@@ -929,9 +900,6 @@ func _apply_question_theme() -> void:
|
|||||||
var review_followup_subtitle := find_child("ReviewFollowupSubtitle", true, false) as Label
|
var review_followup_subtitle := find_child("ReviewFollowupSubtitle", true, false) as Label
|
||||||
if review_followup_subtitle != null:
|
if review_followup_subtitle != null:
|
||||||
review_followup_subtitle.add_theme_color_override("font_color", Brand.muted_color(dark))
|
review_followup_subtitle.add_theme_color_override("font_color", Brand.muted_color(dark))
|
||||||
var wrong_options_heading := find_child("WrongOptionsHeading", true, false) as Label
|
|
||||||
if wrong_options_heading != null:
|
|
||||||
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_panel_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)
|
||||||
@@ -975,7 +943,7 @@ func _apply_question_theme() -> void:
|
|||||||
if correct_review_panel != null and correct_review_panel.visible:
|
if correct_review_panel != null and correct_review_panel.visible:
|
||||||
_render_teaching_cards()
|
_render_teaching_cards()
|
||||||
_render_review_followups()
|
_render_review_followups()
|
||||||
_render_wrong_option_reviews()
|
_render_unselected_distractor_explanations()
|
||||||
|
|
||||||
|
|
||||||
func on_show(_payload: Variant = null) -> void:
|
func on_show(_payload: Variant = null) -> void:
|
||||||
@@ -1542,7 +1510,7 @@ func _dock_correct_review_panel(correct_id: String) -> void:
|
|||||||
func _render_answer_review_sections() -> void:
|
func _render_answer_review_sections() -> void:
|
||||||
_render_teaching_cards()
|
_render_teaching_cards()
|
||||||
_render_review_followups()
|
_render_review_followups()
|
||||||
_render_wrong_option_reviews()
|
_render_unselected_distractor_explanations()
|
||||||
|
|
||||||
|
|
||||||
func _clear_answer_review() -> void:
|
func _clear_answer_review() -> void:
|
||||||
@@ -1552,13 +1520,9 @@ func _clear_answer_review() -> void:
|
|||||||
correct_review_panel.visible = false
|
correct_review_panel.visible = false
|
||||||
_clear_container_children(teaching_cards)
|
_clear_container_children(teaching_cards)
|
||||||
_clear_container_children(review_followups_content)
|
_clear_container_children(review_followups_content)
|
||||||
_clear_container_children(wrong_options_content)
|
|
||||||
review_followup_states.clear()
|
review_followup_states.clear()
|
||||||
wrong_option_expanded.clear()
|
|
||||||
if review_followups_section != null:
|
if review_followups_section != null:
|
||||||
review_followups_section.visible = false
|
review_followups_section.visible = false
|
||||||
if wrong_options_section != null:
|
|
||||||
wrong_options_section.visible = false
|
|
||||||
_update_content_vertical_alignment()
|
_update_content_vertical_alignment()
|
||||||
|
|
||||||
|
|
||||||
@@ -1699,58 +1663,53 @@ func _answer_review_followup(index: int, choice_id: String) -> void:
|
|||||||
_render_review_followups()
|
_render_review_followups()
|
||||||
|
|
||||||
|
|
||||||
func _render_wrong_option_reviews() -> void:
|
func _render_unselected_distractor_explanations() -> void:
|
||||||
if wrong_options_content == null:
|
# Choices the user never picked (so never triggered the wrong-answer
|
||||||
return
|
# follow-up quiz) still need their "why incorrect" explanation shown -
|
||||||
_clear_container_children(wrong_options_content)
|
# nest it directly in that choice's own card instead of a repeated
|
||||||
|
# aggregate list at the bottom. Choices that DID trigger a follow-up
|
||||||
|
# already show this same explanation inside the resolved quiz view.
|
||||||
var question := BlockSessionService.get_current_question()
|
var question := BlockSessionService.get_current_question()
|
||||||
var correct_id := str(question.get("correct_choice_id", ""))
|
var correct_id := str(question.get("correct_choice_id", ""))
|
||||||
var explanations: Dictionary = question.get("choice_explanations", {})
|
var choices := _get_presented_choices()
|
||||||
var incorrect_count := 0
|
for index in range(choices.size()):
|
||||||
for choice in _get_presented_choices():
|
if index >= choice_followup_panels.size():
|
||||||
|
continue
|
||||||
|
var choice: Dictionary = choices[index]
|
||||||
if typeof(choice) != TYPE_DICTIONARY:
|
if typeof(choice) != TYPE_DICTIONARY:
|
||||||
continue
|
continue
|
||||||
var choice_id := str(choice.get("id", ""))
|
var choice_id := str(choice.get("id", ""))
|
||||||
if choice_id == correct_id:
|
if choice_id == "" or choice_id == correct_id or followup_states.has(choice_id):
|
||||||
continue
|
continue
|
||||||
incorrect_count += 1
|
_clear_followup_content(index)
|
||||||
_add_wrong_option_review(choice, str(explanations.get(choice_id, "")))
|
var content := choice_followup_contents[index]
|
||||||
wrong_options_section.visible = incorrect_count > 0
|
var body_content := _add_followup_body(content, false)
|
||||||
|
var heading := Label.new()
|
||||||
|
heading.text = "Why this is incorrect:"
|
||||||
|
_set_scaled_label(heading, 14, Color("fb5f6d"))
|
||||||
|
body_content.add_child(heading)
|
||||||
|
var explanation := Label.new()
|
||||||
|
explanation.text = _distractor_explanation_text(choice_id)
|
||||||
|
explanation.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||||
|
_set_scaled_label(explanation, 14, Brand.text_color(_followup_is_dark()))
|
||||||
|
body_content.add_child(explanation)
|
||||||
|
choice_followup_panels[index].add_theme_stylebox_override(
|
||||||
|
"panel",
|
||||||
|
_attached_panel_box(_followup_is_dark(), Color("fb7185"))
|
||||||
|
)
|
||||||
|
choice_followup_panels[index].visible = true
|
||||||
|
_style_choice_button_for_state(index, choice_id)
|
||||||
|
|
||||||
|
|
||||||
func _add_wrong_option_review(choice: Dictionary, explanation: String) -> void:
|
func _distractor_explanation_text(choice_id: String) -> String:
|
||||||
var dark := _followup_is_dark()
|
var question := BlockSessionService.get_current_question()
|
||||||
var choice_id := str(choice.get("id", ""))
|
var explanations: Dictionary = question.get("choice_explanations", {})
|
||||||
var expanded := bool(wrong_option_expanded.get(choice_id, false))
|
var explanation := str(explanations.get(choice_id, "")).strip_edges()
|
||||||
var card := PanelContainer.new()
|
if explanation.begins_with("Correct. "):
|
||||||
card.add_theme_stylebox_override("panel", _wrong_option_box(dark))
|
explanation = explanation.substr(9)
|
||||||
wrong_options_content.add_child(card)
|
if explanation != "":
|
||||||
var content := VBoxContainer.new()
|
return explanation
|
||||||
content.add_theme_constant_override("separation", 6)
|
return "Review the stem finding that makes this option less appropriate."
|
||||||
card.add_child(content)
|
|
||||||
var header := Button.new()
|
|
||||||
header.flat = true
|
|
||||||
header.alignment = HORIZONTAL_ALIGNMENT_LEFT
|
|
||||||
header.text = "%s. %s" % [_display_label_for_choice_id(choice_id), str(choice.get("text", ""))]
|
|
||||||
header.icon = preload("res://assets/icons/lucide/chevron-down.svg") if expanded else preload("res://assets/icons/lucide/chevron-right.svg")
|
|
||||||
header.icon_alignment = HORIZONTAL_ALIGNMENT_RIGHT
|
|
||||||
header.expand_icon = false
|
|
||||||
header.add_theme_color_override("font_color", Brand.text_color(dark))
|
|
||||||
header.add_theme_color_override("icon_normal_color", Brand.muted_color(dark))
|
|
||||||
_set_scaled_button_font(header, 14)
|
|
||||||
header.pressed.connect(_toggle_wrong_option_review.bind(choice_id))
|
|
||||||
content.add_child(header)
|
|
||||||
if expanded:
|
|
||||||
var detail := Label.new()
|
|
||||||
detail.text = explanation
|
|
||||||
detail.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
|
||||||
_set_scaled_label(detail, 14, Brand.muted_color(dark))
|
|
||||||
content.add_child(detail)
|
|
||||||
|
|
||||||
|
|
||||||
func _toggle_wrong_option_review(choice_id: String) -> void:
|
|
||||||
wrong_option_expanded[choice_id] = not bool(wrong_option_expanded.get(choice_id, false))
|
|
||||||
_render_wrong_option_reviews()
|
|
||||||
|
|
||||||
|
|
||||||
func _strip_correct_prefix(value: String) -> String:
|
func _strip_correct_prefix(value: String) -> String:
|
||||||
|
|||||||
Reference in New Issue
Block a user