mirror of
https://github.com/slint-ui/slint.git
synced 2025-07-14 00:25:19 +00:00

* ComboBox: Don't change on scroll uless we have focus This is what native Windows combobox does. Otherwise this causes problem when combobox are in scrollable Fixes #5929 * ComboBox: Don't scroll at all with the wheel on Mac. This is also Qt's behavior https://doc.qt.io/qt-6/qstyle.html#:~:text=SH_ComboBox_AllowWheelScrolling
128 lines
3.8 KiB
Text
128 lines
3.8 KiB
Text
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
|
|
|
export component ComboBoxBase {
|
|
in property <[string]> model;
|
|
in property <bool> enabled <=> i-focus-scope.enabled;
|
|
out property <bool> has-focus: (i-focus-scope.has-focus || popup-has-focus) && root.enabled;
|
|
out property <bool> pressed <=> i-touch-area.pressed;
|
|
out property <bool> has-hover: i-touch-area.has-hover;
|
|
in-out property <int> current-index: 0;
|
|
in-out property <string> current-value: root.model[root.current-index];
|
|
|
|
// Set from the ComboBox when the popup has the focus
|
|
in-out property <bool> popup-has-focus;
|
|
|
|
callback selected(current-value: string);
|
|
callback show-popup();
|
|
callback close-popup();
|
|
|
|
public function select(index: int) {
|
|
if !root.enabled {
|
|
return;
|
|
}
|
|
root.current-index = index;
|
|
|
|
if root.current-value != root.model[root.current-index] {
|
|
root.update-current-value();
|
|
}
|
|
|
|
root.selected(root.current-value);
|
|
}
|
|
|
|
public function move-selection-up() {
|
|
root.select(Math.max(root.current-index - 1, 0));
|
|
}
|
|
|
|
public function move-selection-down() {
|
|
root.select(Math.min(root.current-index + 1, root.model.length - 1));
|
|
}
|
|
|
|
public function popup-key-handler(event: KeyEvent) -> EventResult {
|
|
if (event.text == Key.UpArrow) {
|
|
root.move-selection-up();
|
|
return accept;
|
|
} else if (event.text == Key.DownArrow) {
|
|
root.move-selection-down();
|
|
return accept;
|
|
} else if (event.text == Key.Return || event.text == Key.Escape) {
|
|
root.close-popup();
|
|
return accept;
|
|
}
|
|
return reject;
|
|
|
|
}
|
|
|
|
function reset-current() {
|
|
root.current-index = 0;
|
|
}
|
|
|
|
function update-current-value() {
|
|
if root.current-index < 0 || root.current-index >= root.model.length {
|
|
root.current-value = "";
|
|
return;
|
|
}
|
|
root.current-value = root.model[root.current-index];
|
|
}
|
|
|
|
changed model => {
|
|
root.reset-current();
|
|
}
|
|
|
|
changed current-index => {
|
|
root.update-current-value();
|
|
}
|
|
|
|
/// Minimum scroll delta so that the scroll wheel changes the value.
|
|
in property <length> scroll-delta: 2px;
|
|
|
|
forward-focus: i-focus-scope;
|
|
|
|
i-focus-scope := FocusScope {
|
|
changed has-focus => {
|
|
if self.has-focus {
|
|
// this means the popup was closed and we get back the focus
|
|
root.popup-has-focus = false;
|
|
}
|
|
}
|
|
key-pressed(event) => {
|
|
if (!self.enabled) {
|
|
return reject;
|
|
}
|
|
if (event.text == Key.UpArrow) {
|
|
root.move-selection-up();
|
|
return accept;
|
|
} else if (event.text == Key.DownArrow) {
|
|
root.move-selection-down();
|
|
return accept;
|
|
} else if (event.text == Key.Return) {
|
|
root.show-popup();
|
|
}
|
|
return reject;
|
|
}
|
|
|
|
i-touch-area := TouchArea {
|
|
enabled: root.enabled;
|
|
|
|
clicked => {
|
|
root.focus();
|
|
root.show-popup();
|
|
}
|
|
|
|
scroll-event(event) => {
|
|
if (!root.has-focus) {
|
|
return reject;
|
|
}
|
|
if (event.delta-y < -root.scroll-delta) {
|
|
root.move-selection-down();
|
|
return accept;
|
|
}
|
|
if (event.delta-y > root.scroll-delta) {
|
|
root.move-selection-up();
|
|
return accept;
|
|
}
|
|
reject
|
|
}
|
|
}
|
|
}
|
|
}
|