Polish question player header/toolbar and add configurable block size
- Fix the toolbar wrapping onto two rows: its minimum width was tuned
for an older, narrower button set and never widened back out after
reverting to bare icon buttons.
- Drop the "Time elapsed"/"Ctrl+Enter" readout next to Submit - it was
clutter; the underlying timer logic keeps running unseen.
- Move the RanaZe brand mark above the question-count row instead of
sharing a line with it.
- Progress text drops the word "Question" everywhere ("1 of 10"), and
core/dynamic sessions now cycle against a configurable block size
(Settings > Question block size, default 10) instead of counting up
forever.
This commit is contained in:
@@ -28,10 +28,41 @@ var simulation_block_index := 0
|
|||||||
var simulation_total_blocks := 12
|
var simulation_total_blocks := 12
|
||||||
var simulation_deadline_unix := 0.0
|
var simulation_deadline_unix := 0.0
|
||||||
var review_first_submission_recorded := false
|
var review_first_submission_recorded := false
|
||||||
|
var core_block_size := DEFAULT_CORE_BLOCK_SIZE
|
||||||
|
|
||||||
const CORE_MIN_TARGET_SECONDS := 45.0
|
const CORE_MIN_TARGET_SECONDS := 45.0
|
||||||
const CORE_MAX_TARGET_SECONDS := 150.0
|
const CORE_MAX_TARGET_SECONDS := 150.0
|
||||||
const CORE_RETRY_TARGET_SECONDS := 30.0
|
const CORE_RETRY_TARGET_SECONDS := 30.0
|
||||||
|
const DEFAULT_CORE_BLOCK_SIZE := 10
|
||||||
|
const CORE_BLOCK_SIZE_MIN := 5
|
||||||
|
const CORE_BLOCK_SIZE_MAX := 40
|
||||||
|
const SETTINGS_PATH := "user://settings.cfg"
|
||||||
|
const SETTINGS_SECTION := "session"
|
||||||
|
const SETTINGS_KEY_CORE_BLOCK_SIZE := "core_block_size"
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
_load_core_block_size()
|
||||||
|
|
||||||
|
|
||||||
|
func set_core_block_size(value: int) -> void:
|
||||||
|
var clamped := clampi(value, CORE_BLOCK_SIZE_MIN, CORE_BLOCK_SIZE_MAX)
|
||||||
|
if clamped == core_block_size:
|
||||||
|
return
|
||||||
|
core_block_size = clamped
|
||||||
|
var config := ConfigFile.new()
|
||||||
|
config.load(SETTINGS_PATH)
|
||||||
|
config.set_value(SETTINGS_SECTION, SETTINGS_KEY_CORE_BLOCK_SIZE, core_block_size)
|
||||||
|
if config.save(SETTINGS_PATH) != OK:
|
||||||
|
push_warning("Unable to save core question block size preference.")
|
||||||
|
|
||||||
|
|
||||||
|
func _load_core_block_size() -> void:
|
||||||
|
var config := ConfigFile.new()
|
||||||
|
if config.load(SETTINGS_PATH) == OK:
|
||||||
|
core_block_size = clampi(
|
||||||
|
int(config.get_value(SETTINGS_SECTION, SETTINGS_KEY_CORE_BLOCK_SIZE, DEFAULT_CORE_BLOCK_SIZE)),
|
||||||
|
CORE_BLOCK_SIZE_MIN, CORE_BLOCK_SIZE_MAX)
|
||||||
|
|
||||||
|
|
||||||
func start_dynamic_question(question: Dictionary) -> bool:
|
func start_dynamic_question(question: Dictionary) -> bool:
|
||||||
|
|||||||
@@ -221,13 +221,10 @@ func _ready() -> void:
|
|||||||
header_stack = VBoxContainer.new()
|
header_stack = VBoxContainer.new()
|
||||||
header_stack.add_theme_constant_override("separation", 8)
|
header_stack.add_theme_constant_override("separation", 8)
|
||||||
card_content.add_child(header_stack)
|
card_content.add_child(header_stack)
|
||||||
header_row = HBoxContainer.new()
|
|
||||||
header_row.add_theme_constant_override("separation", 16)
|
|
||||||
header_stack.add_child(header_row)
|
|
||||||
|
|
||||||
var header_brand := HBoxContainer.new()
|
var header_brand := HBoxContainer.new()
|
||||||
header_brand.add_theme_constant_override("separation", 8)
|
header_brand.add_theme_constant_override("separation", 8)
|
||||||
header_row.add_child(header_brand)
|
header_stack.add_child(header_brand)
|
||||||
var header_brand_mark := TextureRect.new()
|
var header_brand_mark := TextureRect.new()
|
||||||
header_brand_mark.texture = Brand.ranaze_mark_texture()
|
header_brand_mark.texture = Brand.ranaze_mark_texture()
|
||||||
header_brand_mark.custom_minimum_size = Vector2(28, 28)
|
header_brand_mark.custom_minimum_size = Vector2(28, 28)
|
||||||
@@ -240,6 +237,10 @@ func _ready() -> void:
|
|||||||
header_wordmark_label.add_theme_font_size_override("font_size", 18)
|
header_wordmark_label.add_theme_font_size_override("font_size", 18)
|
||||||
header_brand.add_child(header_wordmark_label)
|
header_brand.add_child(header_wordmark_label)
|
||||||
|
|
||||||
|
header_row = HBoxContainer.new()
|
||||||
|
header_row.add_theme_constant_override("separation", 16)
|
||||||
|
header_stack.add_child(header_row)
|
||||||
|
|
||||||
var progress_group := VBoxContainer.new()
|
var progress_group := VBoxContainer.new()
|
||||||
progress_group.add_theme_constant_override("separation", 2)
|
progress_group.add_theme_constant_override("separation", 2)
|
||||||
progress_group.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
progress_group.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||||
@@ -660,15 +661,13 @@ func _ready() -> void:
|
|||||||
bottom_progress_bar.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
|
bottom_progress_bar.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
|
||||||
bottom_progress_group.add_child(bottom_progress_bar)
|
bottom_progress_group.add_child(bottom_progress_bar)
|
||||||
|
|
||||||
var time_group := VBoxContainer.new()
|
# The timer readout still runs (BlockSessionService pacing/scoring depends on
|
||||||
time_group.add_theme_constant_override("separation", 0)
|
# it, and _update_timer_bar keeps its text current), it's just no longer
|
||||||
actions.add_child(time_group)
|
# parented into the bottom bar - the caption + digits and the "Ctrl+Enter"
|
||||||
|
# hint were clutter next to the Submit button.
|
||||||
timer_caption_label = Label.new()
|
timer_caption_label = Label.new()
|
||||||
timer_caption_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
|
timer_caption_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
|
||||||
_set_scaled_label(timer_caption_label, 12, Brand.SLATE)
|
_set_scaled_label(timer_caption_label, 12, Brand.SLATE)
|
||||||
time_group.add_child(timer_caption_label)
|
|
||||||
time_group.add_child(timer_label)
|
|
||||||
|
|
||||||
next_button = Button.new()
|
next_button = Button.new()
|
||||||
next_button.text = "Submit Block" if BlockSessionService.session_kind == "simulation" and BlockSessionService.current_index + 1 == BlockSessionService.active_questions.size() else "Next" if BlockSessionService.session_kind == "simulation" else "Submit"
|
next_button.text = "Submit Block" if BlockSessionService.session_kind == "simulation" and BlockSessionService.current_index + 1 == BlockSessionService.active_questions.size() else "Next" if BlockSessionService.session_kind == "simulation" else "Submit"
|
||||||
@@ -678,12 +677,6 @@ func _ready() -> void:
|
|||||||
next_button.pressed.connect(_submit_or_next)
|
next_button.pressed.connect(_submit_or_next)
|
||||||
actions.add_child(next_button)
|
actions.add_child(next_button)
|
||||||
|
|
||||||
var shortcut_hint_label := Label.new()
|
|
||||||
shortcut_hint_label.name = "SubmitShortcutHint"
|
|
||||||
shortcut_hint_label.text = "⌘ Enter" if OS.get_name() == "macOS" else "Ctrl+Enter"
|
|
||||||
_set_scaled_label(shortcut_hint_label, 11, Brand.SLATE)
|
|
||||||
actions.add_child(shortcut_hint_label)
|
|
||||||
|
|
||||||
timer_footer = HBoxContainer.new()
|
timer_footer = HBoxContainer.new()
|
||||||
timer_footer.add_theme_constant_override("separation", 12)
|
timer_footer.add_theme_constant_override("separation", 12)
|
||||||
card_content.add_child(timer_footer)
|
card_content.add_child(timer_footer)
|
||||||
@@ -793,7 +786,9 @@ func _refresh_responsive_layout() -> void:
|
|||||||
header_toolbar_host.reparent(target_parent)
|
header_toolbar_host.reparent(target_parent)
|
||||||
header_toolbar_host.size_flags_horizontal = Control.SIZE_EXPAND_FILL if compact else Control.SIZE_SHRINK_END
|
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
|
question_toolbar.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
header_toolbar_host.custom_minimum_size.x = 0.0 if compact else 520.0
|
# 11 bare 44px icon buttons + the wider 92px Feedback button, with 8px gaps
|
||||||
|
# between all 12 - anything less than this wraps onto a second row.
|
||||||
|
header_toolbar_host.custom_minimum_size.x = 0.0 if compact else 680.0
|
||||||
if size.x < 560.0:
|
if size.x < 560.0:
|
||||||
nav_palette.columns = 5
|
nav_palette.columns = 5
|
||||||
else:
|
else:
|
||||||
@@ -1074,9 +1069,6 @@ func _apply_question_theme() -> void:
|
|||||||
skip_button.add_theme_color_override("font_color", skip_link_color)
|
skip_button.add_theme_color_override("font_color", skip_link_color)
|
||||||
skip_button.add_theme_color_override("font_hover_color", skip_link_color)
|
skip_button.add_theme_color_override("font_hover_color", skip_link_color)
|
||||||
skip_button.add_theme_color_override("font_disabled_color", Brand.muted_color(dark))
|
skip_button.add_theme_color_override("font_disabled_color", Brand.muted_color(dark))
|
||||||
var shortcut_hint := find_child("SubmitShortcutHint", true, false) as Label
|
|
||||||
if shortcut_hint != null:
|
|
||||||
shortcut_hint.add_theme_color_override("font_color", Brand.muted_color(dark))
|
|
||||||
if next_button != null:
|
if next_button != null:
|
||||||
next_button.add_theme_stylebox_override("normal", _primary_action_box(dark, "normal"))
|
next_button.add_theme_stylebox_override("normal", _primary_action_box(dark, "normal"))
|
||||||
next_button.add_theme_stylebox_override("hover", _primary_action_box(dark, "hover"))
|
next_button.add_theme_stylebox_override("hover", _primary_action_box(dark, "hover"))
|
||||||
@@ -2078,8 +2070,9 @@ func _is_session_timer_visible() -> bool:
|
|||||||
|
|
||||||
func _question_progress_text() -> String:
|
func _question_progress_text() -> String:
|
||||||
if BlockSessionService.session_kind == "core":
|
if BlockSessionService.session_kind == "core":
|
||||||
return "Question %d" % (BlockSessionService.core_answer_count + 1)
|
var block_size := BlockSessionService.core_block_size
|
||||||
return "Question %d of %d" % [
|
return "%d of %d" % [(BlockSessionService.core_answer_count % block_size) + 1, block_size]
|
||||||
|
return "%d of %d" % [
|
||||||
mini(BlockSessionService.current_index + 1, BlockSessionService.active_questions.size()),
|
mini(BlockSessionService.current_index + 1, BlockSessionService.active_questions.size()),
|
||||||
BlockSessionService.active_questions.size()
|
BlockSessionService.active_questions.size()
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ const Brand := preload("res://scripts/ui/medmind_style.gd")
|
|||||||
const QUESTION_TEXT_SCALE_MIN := 0.85
|
const QUESTION_TEXT_SCALE_MIN := 0.85
|
||||||
const QUESTION_TEXT_SCALE_MAX := 1.35
|
const QUESTION_TEXT_SCALE_MAX := 1.35
|
||||||
const QUESTION_TEXT_SCALE_STEP := 0.1
|
const QUESTION_TEXT_SCALE_STEP := 0.1
|
||||||
|
const CORE_BLOCK_SIZE_STEP := 5
|
||||||
|
|
||||||
var main: Control
|
var main: Control
|
||||||
var theme_toggle: CheckButton
|
var theme_toggle: CheckButton
|
||||||
var sound_toggle: CheckButton
|
var sound_toggle: CheckButton
|
||||||
var question_scale_value_label: Label
|
var question_scale_value_label: Label
|
||||||
var ccs_scale_value_label: Label
|
var ccs_scale_value_label: Label
|
||||||
|
var core_block_size_value_label: Label
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
@@ -59,6 +61,7 @@ func _ready() -> void:
|
|||||||
|
|
||||||
content.add_child(_build_text_scale_row("Question bank text size", "question"))
|
content.add_child(_build_text_scale_row("Question bank text size", "question"))
|
||||||
content.add_child(_build_text_scale_row("CCS case text size", "ccs"))
|
content.add_child(_build_text_scale_row("CCS case text size", "ccs"))
|
||||||
|
content.add_child(_build_core_block_size_row())
|
||||||
|
|
||||||
var legal_panel := PanelContainer.new()
|
var legal_panel := PanelContainer.new()
|
||||||
legal_panel.custom_minimum_size = Vector2(520, 0)
|
legal_panel.custom_minimum_size = Vector2(520, 0)
|
||||||
@@ -131,6 +134,42 @@ func _build_text_scale_row(label_text: String, kind: String) -> HBoxContainer:
|
|||||||
return row
|
return row
|
||||||
|
|
||||||
|
|
||||||
|
func _build_core_block_size_row() -> HBoxContainer:
|
||||||
|
var row := HBoxContainer.new()
|
||||||
|
row.custom_minimum_size = Vector2(0, 52)
|
||||||
|
row.add_theme_constant_override("separation", 12)
|
||||||
|
|
||||||
|
var label := Label.new()
|
||||||
|
label.text = "Question block size"
|
||||||
|
label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
row.add_child(label)
|
||||||
|
|
||||||
|
var smaller := Button.new()
|
||||||
|
smaller.text = "-"
|
||||||
|
smaller.tooltip_text = "Fewer questions per block"
|
||||||
|
smaller.custom_minimum_size = Vector2(44, 44)
|
||||||
|
smaller.pressed.connect(_adjust_core_block_size.bind(-CORE_BLOCK_SIZE_STEP))
|
||||||
|
row.add_child(smaller)
|
||||||
|
|
||||||
|
core_block_size_value_label = Label.new()
|
||||||
|
core_block_size_value_label.custom_minimum_size = Vector2(56, 0)
|
||||||
|
core_block_size_value_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||||
|
row.add_child(core_block_size_value_label)
|
||||||
|
|
||||||
|
var larger := Button.new()
|
||||||
|
larger.text = "+"
|
||||||
|
larger.tooltip_text = "More questions per block"
|
||||||
|
larger.custom_minimum_size = Vector2(44, 44)
|
||||||
|
larger.pressed.connect(_adjust_core_block_size.bind(CORE_BLOCK_SIZE_STEP))
|
||||||
|
row.add_child(larger)
|
||||||
|
return row
|
||||||
|
|
||||||
|
|
||||||
|
func _adjust_core_block_size(delta: int) -> void:
|
||||||
|
BlockSessionService.set_core_block_size(BlockSessionService.core_block_size + delta)
|
||||||
|
_refresh_text_scale_labels()
|
||||||
|
|
||||||
|
|
||||||
func _adjust_question_text_scale(delta: float) -> void:
|
func _adjust_question_text_scale(delta: float) -> void:
|
||||||
var current: float = AccountProfileService.preferences.get("questionTextScale", 1.0)
|
var current: float = AccountProfileService.preferences.get("questionTextScale", 1.0)
|
||||||
var next_scale: float = clamp(current + delta, QUESTION_TEXT_SCALE_MIN, QUESTION_TEXT_SCALE_MAX)
|
var next_scale: float = clamp(current + delta, QUESTION_TEXT_SCALE_MIN, QUESTION_TEXT_SCALE_MAX)
|
||||||
@@ -149,6 +188,8 @@ func _refresh_text_scale_labels() -> void:
|
|||||||
question_scale_value_label.text = "%d%%" % round(question_scale * 100)
|
question_scale_value_label.text = "%d%%" % round(question_scale * 100)
|
||||||
if ccs_scale_value_label != null:
|
if ccs_scale_value_label != null:
|
||||||
ccs_scale_value_label.text = "%d%%" % round(CCSService.text_scale * 100)
|
ccs_scale_value_label.text = "%d%%" % round(CCSService.text_scale * 100)
|
||||||
|
if core_block_size_value_label != null:
|
||||||
|
core_block_size_value_label.text = str(BlockSessionService.core_block_size)
|
||||||
|
|
||||||
|
|
||||||
func _on_theme_toggled(enabled: bool) -> void:
|
func _on_theme_toggled(enabled: bool) -> void:
|
||||||
|
|||||||
Reference in New Issue
Block a user