forked from GDQuest/learn-gdscript
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUIBaseQuiz.gd
140 lines (107 loc) · 4.04 KB
/
UIBaseQuiz.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
class_name UIBaseQuiz
extends PanelContainer
signal quiz_passed
signal quiz_skipped
const ERROR_OUTLINE := preload("res://ui/theme/quiz_outline_error.tres")
const PASSED_OUTLINE := preload("res://ui/theme/quiz_outline_passed.tres")
const NEUTRAL_OUTLINE := preload("res://ui/theme/quiz_outline_neutral.tres")
const OUTLINE_FLASH_DURATION := 0.8
const OUTLINE_FLASH_DELAY := 0.75
const ERROR_SHAKE_TIME := 0.5
const ERROR_SHAKE_SIZE := 20
export var test_quiz: Resource
var completed_before := false setget set_completed_before
onready var _outline := $Outline as PanelContainer
onready var _question := $MarginContainer/ChoiceView/QuizHeader/Question as Label
onready var _explanation := $MarginContainer/ResultView/Explanation as RichTextLabel
onready var _content := $MarginContainer/ChoiceView/Content as RichTextLabel
onready var _completed_before_icon := (
$MarginContainer/ChoiceView/QuizHeader/CompletedBeforeIcon as TextureRect
)
onready var _choice_view := $MarginContainer/ChoiceView as VBoxContainer
onready var _result_view := $MarginContainer/ResultView as VBoxContainer
onready var _submit_button := $MarginContainer/ChoiceView/HBoxContainer/SubmitButton as Button
onready var _skip_button := $MarginContainer/ChoiceView/HBoxContainer/SkipButton as Button
onready var _result_label := $MarginContainer/ResultView/Label as Label
onready var _correct_answer_label := $MarginContainer/ResultView/CorrectAnswer as Label
onready var _tween := $Tween as Tween
onready var _help_message := $MarginContainer/ChoiceView/HelpMessage as Label
var _quiz: Quiz
var _shake_pos: float = 0
func _ready() -> void:
_completed_before_icon.visible = completed_before
_submit_button.connect("pressed", self, "_test_answer")
_skip_button.connect("pressed", self, "_show_answer", [false])
connect("item_rect_changed", self, "_on_item_rect_changed")
func setup(quiz: Quiz) -> void:
_quiz = quiz
if not is_inside_tree():
yield(self, "ready")
_question.text = _quiz.question
_content.visible = not _quiz.content_bbcode.empty()
_content.bbcode_text = TextUtils.bbcode_add_code_color(_quiz.content_bbcode)
_explanation.visible = not _quiz.explanation_bbcode.empty()
_explanation.bbcode_text = TextUtils.bbcode_add_code_color(_quiz.explanation_bbcode)
func set_completed_before(value: bool) -> void:
completed_before = value
if is_inside_tree():
_completed_before_icon.visible = completed_before
# Virtual
func _get_answers() -> Array:
return []
func _test_answer() -> void:
var result: Quiz.AnswerTestResult = null
_skip_button.disabled = false
if _quiz is QuizChoice:
result = _quiz.test_answer(_get_answers())
else:
# The input field quiz takes a single string as a test answer.
result = _quiz.test_answer(_get_answers().back())
_help_message.text = result.help_message
_help_message.visible = not result.help_message.empty()
_tween.stop_all()
if not result.is_correct:
_outline.modulate.a = 1.0
_outline.add_stylebox_override("panel", ERROR_OUTLINE)
rect_position.y = _shake_pos
_tween.interpolate_property(
self,
"rect_position:y",
_shake_pos + ERROR_SHAKE_SIZE,
_shake_pos,
ERROR_SHAKE_TIME,
Tween.TRANS_ELASTIC,
Tween.EASE_OUT
)
_tween.interpolate_property(
_outline,
"modulate:a",
_outline.modulate.a,
0.0,
OUTLINE_FLASH_DURATION,
Tween.TRANS_LINEAR,
Tween.EASE_IN,
OUTLINE_FLASH_DELAY
)
_tween.start()
else:
_show_answer()
func _show_answer(gave_correct_answer := true) -> void:
_tween.stop_all()
_outline.add_stylebox_override("panel", PASSED_OUTLINE if gave_correct_answer else NEUTRAL_OUTLINE)
_outline.modulate.a = 1.0
_result_view.show()
_choice_view.hide()
if gave_correct_answer:
emit_signal("quiz_passed")
else:
if _quiz.get_answer_count() == 1:
_result_label.text = "The answer was:"
else:
_result_label.text = "The answers were:"
_correct_answer_label.show()
_correct_answer_label.text = _quiz.get_correct_answer_string()
emit_signal("quiz_skipped")
func _on_item_rect_changed() -> void:
if not _tween.is_active() or _tween.tell() > ERROR_SHAKE_TIME:
_shake_pos = rect_position.y