mirror of
				https://github.com/slint-ui/slint.git
				synced 2025-10-31 03:54:25 +00:00 
			
		
		
		
	 9853384f56
			
		
	
	
		9853384f56
		
			
		
	
	
	
	
		
			
			* 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
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |