diff --git a/scripts/ui/login_screen.gd b/scripts/ui/login_screen.gd index eefbc2b..0ca8ca5 100644 --- a/scripts/ui/login_screen.gd +++ b/scripts/ui/login_screen.gd @@ -27,6 +27,7 @@ var login_input: LineEdit var password_input: LineEdit var password_reveal_entries: Array[Dictionary] = [] var legal_consent_texts: Array[RichTextLabel] = [] +var legal_consent_squares: Array[Panel] = [] var registration_username_input: LineEdit var registration_email_input: LineEdit var registration_password_input: LineEdit @@ -351,25 +352,47 @@ func _add_legal_consent(parent: VBoxContainer) -> CheckBox: # wrapping then stays confined to its column, and "Terms of Service"/ # "Privacy Policy" render as inline links rather than a duplicate row # of link buttons underneath. + # + # The actual toggle state lives on a real CheckBox (kept invisible and + # out of the row's layout) because other code reads .button_pressed - + # but Button/CheckBox reserves vertical space for a text baseline even + # with an empty string, which was making the visible square non-square + # no matter what custom_minimum_size said. Drawing the visible square + # as a plain Panel sidesteps that entirely. + var check := CheckBox.new() + check.visible = false + parent.add_child(check) + var margin := MarginContainer.new() + margin.add_theme_constant_override("margin_left", 6) margin.add_theme_constant_override("margin_top", 8) margin.add_theme_constant_override("margin_bottom", 8) parent.add_child(margin) var row := HBoxContainer.new() row.add_theme_constant_override("separation", 12) margin.add_child(row) - var check := CheckBox.new() - check.name = "LegalConsentCheckBox" - check.custom_minimum_size = Vector2(22, 22) - check.size_flags_vertical = Control.SIZE_SHRINK_BEGIN - check.add_theme_icon_override("unchecked", _blank_icon()) - row.add_child(check) + + var square := Panel.new() + square.custom_minimum_size = Vector2(20, 20) + square.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN + square.size_flags_vertical = Control.SIZE_SHRINK_CENTER + square.mouse_filter = Control.MOUSE_FILTER_STOP + square.set_meta("legal_consent_checkbox", check) + square.gui_input.connect(func(event: InputEvent): + if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT: + check.button_pressed = not check.button_pressed + ) + row.add_child(square) + legal_consent_squares.append(square) + check.toggled.connect(func(_pressed: bool): _refresh_legal_consent_square(square)) + var consent_text := RichTextLabel.new() consent_text.bbcode_enabled = true consent_text.fit_content = true consent_text.scroll_active = false consent_text.meta_underlined = false consent_text.size_flags_horizontal = Control.SIZE_EXPAND_FILL + consent_text.size_flags_vertical = Control.SIZE_SHRINK_CENTER consent_text.add_theme_font_override("normal_font", Brand.font) consent_text.add_theme_font_size_override("normal_font_size", 13) consent_text.meta_clicked.connect(func(meta: Variant): _open_legal_document(str(meta))) @@ -378,10 +401,6 @@ func _add_legal_consent(parent: VBoxContainer) -> CheckBox: return check -func _blank_icon() -> ImageTexture: - return ImageTexture.create_from_image(Image.create(1, 1, false, Image.FORMAT_RGBA8)) - - func _refresh_legal_consent_text(consent_text: RichTextLabel, dark: bool) -> void: var text_hex := Brand.text_color(dark).to_html(false) var link_hex := (Brand.SKY_BLUE if dark else Brand.ROYAL_BLUE).to_html(false) @@ -391,6 +410,19 @@ func _refresh_legal_consent_text(consent_text: RichTextLabel, dark: bool) -> voi ) +func _refresh_legal_consent_square(square: Panel) -> void: + var dark := UIThemeService.is_dark_mode() + var accent := Brand.SKY_BLUE if dark else Brand.ROYAL_BLUE + var checked := square.get_meta("legal_consent_checkbox", null) as CheckBox + var is_checked := checked != null and checked.button_pressed + var box := StyleBoxFlat.new() + box.bg_color = accent if is_checked else Color.TRANSPARENT + box.border_color = accent + box.set_border_width_all(2) + box.set_corner_radius_all(5) + square.add_theme_stylebox_override("panel", box) + + func _add_legal_links(parent: HBoxContainer) -> void: for spec in [["Terms of Service", "terms"], ["Privacy Policy", "privacy"]]: var link := Button.new() @@ -597,15 +629,8 @@ func _apply_theme() -> void: _style_auth_field(input, dark) for consent_text in legal_consent_texts: _refresh_legal_consent_text(consent_text, dark) - var checkbox_box := StyleBoxFlat.new() - checkbox_box.bg_color = Color.TRANSPARENT - checkbox_box.border_color = Brand.SKY_BLUE if dark else Brand.ROYAL_BLUE - checkbox_box.set_border_width_all(2) - checkbox_box.set_corner_radius_all(6) - checkbox_box.set_content_margin_all(0) - for cb in find_children("*", "CheckBox", true, false): - for state in ["normal", "hover", "pressed", "focus"]: - cb.add_theme_stylebox_override(state, checkbox_box) + for square in legal_consent_squares: + _refresh_legal_consent_square(square) for button in find_children("*", "Button", true, false): if button is CheckBox: continue