mirror of
				https://github.com/slint-ui/slint.git
				synced 2025-11-03 21:24:17 +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
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |