// Copyright © SixtyFPS GmbH // SPDX-License-Identifier: MIT import { TextField } from "./text_field.slint"; import { MenuItem } from "../items/menu_item.slint"; import { Icons } from "../icons/icons.slint"; import { MenuInner } from "./menu.slint"; import { StateLayer } from "./state_layer.slint"; import { MaterialPalette } from "../styling/material_palette.slint"; import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint"; import { ScrollView } from "./scroll_view.slint"; export component DropDownMenu { in property label <=> text_field.label; in property enabled <=> text_field.enabled; in property leading_icon <=> text_field.leading_icon; in property <[MenuItem]> items; in_out property current_index: -1; callback selected(index: int); property item_height: MaterialStyleMetrics.size_56; property max_displayed_items: 6; property text <=> text_field.text; min_width: text_field.min_width; min_height: text_field.min_height; forward_focus: text_field; accessible-role: combobox; accessible_enabled: root.enabled; accessible_expandable: true; accessible_value <=> text_field.text; accessible_action_expand => { menu.show(); } text_field := TextField { width: 100%; height: 100%; trailing_icon: Icons.arrow_drop_down; read_only: true; } state_layer := StateLayer { width: 100%; height: 100%; background: MaterialPalette.on_surface; has_hover: touch_area.has_hover; enabled: root.enabled; } touch_area := TouchArea { width: 100%; height: 100%; enabled: root.enabled; clicked => { menu.show(); } } menu := PopupWindow { x: 0; width: root.width; close_policy: close_on_click_outside; forward_focus: inner_text_field; VerticalLayout { alignment: start; inner_text_field := TextField { width: root.width; leading_icon: root.leading_icon; trailing_icon: Icons.arrow_drop_up; text: root.text; label: root.label; read_only: true; leading_icon_clicked => { menu.close(); } trailing_icon_clicked => { menu.close(); } } Rectangle { width: 100%; height: min(max(root.item_height, items.length * root.item_height), root.max_displayed_items * root.item_height); background: MaterialPalette.surface_container; ScrollView { VerticalLayout { menu_inner := MenuInner { current_index: root.current_index; items: root.items; activated(index) => { root.update_selection(index); } } } } } } } function update_selection(index: int) { root.update_text(index); root.current_index = index; menu.close(); root.selected(index); } function update_text(index: int) { if index < 0 || root.current_index >= root.items.length { text_field.text = ""; return; } text_field.text = root.items[index].text; } changed current_index => { root.update_text(root.current_index); } }