// Copyright © SixtyFPS GmbH // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial import { md } from "md.slint"; import { Item } from "widget-item.slint"; export ComboBox := FocusScope { property <[string]> model; property current-index : 0; property current-value: model[current-index]; callback selected(string); accessible-role: combobox; accessible-value <=> current-value; horizontal-stretch: 1; vertical-stretch: 0; min-width: 160px; height: 56px; container := Rectangle { width: 100%; height: 100%; border-radius: 4px; border-width: 1px; border-color: md.sys.color.outline; } layout := HorizontalLayout { padding-left: 16px; padding-right: 12px; spacing: 16px; label := Text { text <=> root.current-value; height: 100%; color: md.sys.color.on-surface; vertical-alignment: center; // FIXME after Roboto font can be loaded // font-family: md.sys.typescale.body-large.font; font-size: md.sys.typescale.body-large.size; font-weight: md.sys.typescale.body-large.weight; } icon := Path { width: 16px; height: 16px; y: (parent.height - height) / 2; commands: "m24 30.75-12-12 2.15-2.15L24 26.5l9.85-9.85L36 18.8Z"; fill: md.sys.color.on-surface; } } touch := TouchArea { enabled <=> root.enabled; clicked => { root.focus(); popup.show(); } } popup := PopupWindow { y: root.height; width: root.width; popup-container := Rectangle { background: md.sys.color.surface; drop-shadow-color: md.sys.color.shadow; drop-shadow-blur: md.sys.elevation.level2; drop-shadow-offset-y: 1px; border-radius: 4px; } VerticalLayout { for value[idx] in root.model: Item { text: value; selected: idx == root.current-index; clicked => { if (root.enabled) { root.current-index = idx; root.current-value = value; root.selected(root.current-value); } } } } } key-pressed(event) => { if (event.text == Keys.UpArrow) { current-index = Math.max(current-index - 1, 0); current-value = model[current-index]; return accept; } else if (event.text == Keys.DownArrow) { current-index = Math.min(current-index + 1, model.length - 1); current-value = model[current-index]; return accept; } return reject; } states [ disabled when !enabled : { container.border-color: md.sys.color.on-surface; container.opacity: 0.38; label.opacity: 0.38; icon.opacity: 0.38; } focused when has-focus : { container.border-width: 2px; container.border-color: md.sys.color.primary; label.color: md.sys.color.primary; icon.fill: md.sys.color.primary; } ] }