Loading files
c730ec352This file is pinned to the selected release. Download the original to open it in your design tool.
import { ScrollView } from "scrollview.slint";
import { Data } from "../api.slint";
export component DropDownPopup inherits PopupWindow {
in property <[string]> model;
in property <int> current-index: -1;
in property <string> current-text;
in property <int> default-index: -1;
in property <length> item-height: 25px;
property <int> selected-index: 0;
callback accepted(index: int);
function set-selected-index(index: int) {
if ((index + 1) * item-height) > (view.height - view.viewport-y) {
view.viewport-y = -(index + 1) * item-height + view.height;
} else if (index * item-height) < -(view.viewport-y) {
view.viewport-y = -(index * item-height);
}
selected-index = index;
}
width: self.preferred-width;
close-policy: close-on-click-outside; // For functional scrollbars.
forward-focus: fs;
// Accessibility
accessible-role: list;
accessible-enabled: true;
accessible-item-count: model.length;
init => {
set-selected-index(max(current-index, 0)); // Scroll to current item.
}
fs := FocusScope {
key-pressed(event) => {
if event.text == Key.UpArrow {
if selected-index > 0 {
set-selected-index(selected-index - 1);
}
return accept;
} else if event.text == Key.DownArrow {
if selected-index < (model.length - 1) {
set-selected-index(selected-index + 1);
}
return accept;
} else if event.text == Key.Return {
accepted(selected-index);
root.close();
return accept;
}
reject
}
}
Rectangle {
background: Data.theme.control;
border-color: Data.theme.control-border;
border-width: 1px;
VerticalLayout {
padding: 1px;
view := ScrollView {
preferred-height: l.preferred-height;
viewport-width: l.width;
viewport-height: l.height;
mouse-drag-pan-enabled: true;
l := VerticalLayout {
width: root.width - 2px;
height: self.preferred-height;
max-height: 20 * item-height; // Should be a multiple of item height.
for item[index] in model: item-ta := TouchArea {
property <bool> is-current: (index == current-index) || ((!current-text.is-empty) && (item == current-text));
height: item-height;
// Accessibility
accessible-role: list-item;
accessible-item-index: index;
accessible-item-selectable: true;
accessible-item-selected: (index == selected-index);
accessible-label: item;
changed has-hover => {
if self.has-hover {
selected-index = index;
}
}
Rectangle {
background: {
if is-current {
Data.theme.control-checked
} else if index == selected-index {
Data.theme.control-hovered
} else {
transparent
}
};
HorizontalLayout {
padding-left: 12px;
padding-right: 12px;
spacing: 5px;
item-txt := Text {
font-size: 13px;
color: Data.theme.base-text;
overflow: elide;
vertical-alignment: center;
text: item;
accessible-role: none;
}
if index == default-index: Text {
width: self.preferred-width;
font-size: 11px;
color: Data.theme.base-text-disabled;
vertical-alignment: center;
text: @tr("default").to-lowercase();
}
}
}
clicked => {
accepted(index);
root.close();
}
}
}
}
}
}
}