Size CCS speech bubbles to content

This commit is contained in:
hz
2026-08-06 20:39:40 -05:00
parent dfc224660e
commit 6e039f00a7
3 changed files with 45 additions and 2 deletions
+26
View File
@@ -90,6 +90,8 @@ func _run() -> void:
_assert(not screen.active_scene.choice_container.visible, "the next choices should wait until the patient finishes speaking")
_assert(screen.active_scene.dialogue_pages.size() > 1, "long patient responses should split into readable dialogue pages")
_assert(_label_content_fits(screen.active_scene.dialogue_text), "the first patient response page should fit inside its speech bubble")
_assert(is_equal_approx(screen.active_scene.dialogue_text.offset_left, 96.0), "patient dialogue should retain the increased left inset")
_assert(_bubble_matches_content(screen.active_scene), "the speech bubble should size itself to the wrapped response page")
screen.active_scene.advance_dialogue()
_assert(screen.active_scene.dialogue_page_index == 0, "clicking during typing should complete rather than skip the current page")
_assert(screen.active_scene.dialogue_continue_hint.visible, "completed dialogue pages should invite the learner to continue")
@@ -143,6 +145,22 @@ func _run() -> void:
_assert(screen.current_view == "interview_debrief", "a completed graphical interview should remain in CCS Cases 2")
_assert(screen.active_scene.find_child("InterviewDebrief", true, false) != null, "the graphical case should render its debrief")
var sizing_scene = load("res://scenes/ccs_cases_2/doctor_office.tscn").instantiate()
host.add_child(sizing_scene)
await process_frame
sizing_scene.show_patient_dialogue("Short response.")
await process_frame
var short_height: float = sizing_scene.dialogue_bubble.size.y
_assert(is_equal_approx(short_height, sizing_scene.DIALOGUE_BUBBLE_MIN_HEIGHT), "short dialogue should use the minimum bubble height")
sizing_scene.show_patient_dialogue("Line one explains the symptom.\nLine two adds timing.\nLine three adds context.\nLine four concludes.")
await process_frame
_assert(sizing_scene.dialogue_bubble.size.y > short_height, "multi-line dialogue should increase the bubble height")
_assert(sizing_scene.dialogue_bubble.size.y <= sizing_scene.DIALOGUE_BUBBLE_MAX_HEIGHT, "dialogue bubble growth should remain bounded")
_assert(_bubble_matches_content(sizing_scene), "the expanded bubble should contain all wrapped text")
sizing_scene.complete_dialogue_reveal()
_assert(sizing_scene.dialogue_bubble.get_global_rect().encloses(sizing_scene.dialogue_continue_hint.get_global_rect()), "the continuation hint should remain inside the resized bubble")
sizing_scene.queue_free()
screen.on_hide()
await process_frame
_assert(screen.active_scene == null, "hiding CCS Cases 2 should release the doctor scene")
@@ -245,6 +263,14 @@ func _label_content_fits(label: Control) -> bool:
return content_height <= plain_label.size.y + 0.5
func _bubble_matches_content(scene: Control) -> bool:
var required_height: float = scene.dialogue_text.get_content_height() + scene.DIALOGUE_BUBBLE_VERTICAL_CHROME
var expected_height := clampf(
required_height, scene.DIALOGUE_BUBBLE_MIN_HEIGHT, scene.DIALOGUE_BUBBLE_MAX_HEIGHT)
return is_equal_approx(scene.dialogue_bubble.size.y, expected_height) \
and _label_content_fits(scene.dialogue_text)
func _assert(condition: bool, message: String) -> void:
if condition:
return