// Copyright © SixtyFPS GmbH // SPDX-License-Identifier: MIT import { MaterialPalette } from "../styling/material_palette.slint"; import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; import { Typography } from "../styling/typography.slint"; import { TextButton } from "./text_button.slint"; import { FilledButton } from "./filled_button.slint"; import { MaterialText } from "./material_text.slint"; import { Animations } from "../styling/animations.slint"; import { Modal } from "./modal.slint"; import { Icon } from "./icon.slint"; import { IconButton } from "./icon_button.slint"; import { Icons } from "../icons/icons.slint"; export component FullscreenDialog inherits PopupWindow { in property title; in property <[string]> actions; callback action(index: int); close_policy: no_auto_close; forward_focus: focus_scope; focus_scope := FocusScope { x: 0; width: 0; key_pressed(event) => { if event.text == Key.Escape { root.close(); return accept; } reject } } background_layer := Rectangle { width: 100%; height: 100%; opacity: 0; background: MaterialPalette.surface; VerticalLayout { spacing: MaterialStyleMetrics.spacing_16; HorizontalLayout { padding: MaterialStyleMetrics.padding_24; spacing: MaterialStyleMetrics.spacing_16; vertical_stretch: 0; IconButton { icon: Icons.close; clicked => { root.close(); } } MaterialText { text: root.title; style: Typography.headline_small; color: MaterialPalette.on_surface; vertical_alignment: center; } for action[index] in root.actions : TextButton { text: action; clicked => { root.action(index); } } } @children } } Timer { interval: 50ms; triggered => { background_layer.opacity = 1; self.running = false; } } } export component BaseDialog { in property title; in property icon; in property <[image]> icon_actions; in property default_action_text; in property <[string]> actions; property has_icon: root.icon.width > 0 && root.icon.height > 0; callback default_action(); callback icon_action(index: int); callback action(index: int); callback close(); forward_focus: focus_scope; focus_scope := FocusScope { x: 0; width: 0; key_pressed(event) => { if event.text == Key.Return && root.default_action_text != "" { root.default_action(); return accept; } if event.text == Key.Escape { root.close(); return accept; } reject } } modal := Modal { width: 100%; height: 100%; background_layer := Rectangle { x: (parent.width - self.width) / 2; y: (parent.height - self.height) / 2; width: layout.min_width; height: layout.min_height; opacity: 0; border_radius: MaterialStyleMetrics.border_radius_28; background: MaterialPalette.surface_container_high; TouchArea { layout := VerticalLayout { padding: MaterialStyleMetrics.padding_24; spacing: MaterialStyleMetrics.spacing_16; if root.has_icon : Icon { x: (parent.width - self.width) / 2; colorize: MaterialPalette.on_surface; source: root.icon; } if root.title != "" : MaterialText { horizontal_alignment: root.has_icon ? center : left; text: root.title; style: Typography.headline_small; color: MaterialPalette.on_surface; } @children HorizontalLayout { spacing: MaterialStyleMetrics.spacing_8; for icon_action[index] in root.icon_actions : IconButton { icon: icon_action; clicked => { root.icon_action(index); } } // Spacer Rectangle {} for action[index] in root.actions : TextButton { text: action; clicked => { root.action(index); } } if root.default_action_text != "" : FilledButton { text: root.default_action_text; clicked => { root.default_action(); } } } } } animate opacity { duration: Animations.opacity_duration; easing: Animations.opacity_easing; } } clicked => { root.close(); } } Timer { interval: 50ms; triggered => { background_layer.opacity = 1; self.running = false; } } } export component Dialog inherits PopupWindow { in property title <=> base.title; in property icon <=> base.icon; in property default_action_text <=> base.default_action_text; in property <[string]> actions <=> base.actions; callback default_action <=> base.default_action; callback action <=> base.action; close_policy: no_auto_close; forward_focus: base; base := BaseDialog { width: 100%; height: 100%; @children close => { root.close(); } } }