diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b7b0d464..cde94d8fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ All notable changes to this project are documented in this file. - Added `step-size` to `SpinBox` - Added `TimePickerPopup` and `DatePickerPopup`. - Fixed accessible value and actions on ProgressIndicator, Spinner, Spinbox, CheckBox, Switch + - Made `ComboBox` scrollable ### C++ API diff --git a/internal/compiler/widgets/common/combobox-base.slint b/internal/compiler/widgets/common/combobox-base.slint index 1b7f5af48..2cc9aed61 100644 --- a/internal/compiler/widgets/common/combobox-base.slint +++ b/internal/compiler/widgets/common/combobox-base.slint @@ -33,7 +33,7 @@ export component ComboBoxBase { public function move-selection-down() { root.select(Math.min(root.current-index + 1, root.model.length - 1)); } - + function reset-current() { root.current-index = 0; } diff --git a/internal/compiler/widgets/cosmic-base/combobox.slint b/internal/compiler/widgets/cosmic-base/combobox.slint index 8c3ed4ac6..4dbb3e28e 100644 --- a/internal/compiler/widgets/cosmic-base/combobox.slint +++ b/internal/compiler/widgets/cosmic-base/combobox.slint @@ -1,9 +1,10 @@ // Copyright © SixtyFPS GmbH // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 -import { CosmicFontSettings, CosmicPalette, Icons } from "styling.slint"; +import { CosmicFontSettings, CosmicPalette, Icons, CosmicSizeSettings } from "styling.slint"; import { MenuBorder, ListItem, StateLayerBase } from "components.slint"; import { ComboBoxBase } from "../common/combobox-base.slint"; +import { ScrollView } from "./scrollview.slint"; export component ComboBox { in property <[string]> model <=> base.model; @@ -13,6 +14,9 @@ export component ComboBox { in-out property current-value <=> base.current-value; callback selected <=> base.selected; + + property popup-padding: 4px; + property visible-items: 6; min-width: max(160px, layout.min-height); min-height: max(32px, layout.min-height); @@ -75,29 +79,35 @@ export component ComboBox { enabled: root.enabled; } } - + popup := PopupWindow { x: 0; + // Position the popup so that the first element is over the popup. + // Ideally it should be so that the current element is over the popup. y: root.height + 4px; width: root.width; + height: root.visible-items * CosmicSizeSettings.item-height + 2 * root.popup-padding; MenuBorder { - VerticalLayout { - padding: 8px; + ScrollView { + VerticalLayout { + alignment: start; + padding: root.popup-padding; + + for value[index] in root.model : ListItem { + item: { text: value }; + is-selected: index == root.current-index; + has-hover: touch-area.has-hover; + pressed: touch-area.pressed; - for value[index] in root.model : ListItem { - item: { text: value }; - is-selected: index == root.current-index; - has-hover: touch-area.has-hover; - pressed: touch-area.pressed; - - touch-area := TouchArea { - clicked => { - base.select(index); + touch-area := TouchArea { + clicked => { + base.select(index); + } } } } - } + } } } -} + } diff --git a/internal/compiler/widgets/cosmic-base/components.slint b/internal/compiler/widgets/cosmic-base/components.slint index a7e4d7f80..fa8c42618 100644 --- a/internal/compiler/widgets/cosmic-base/components.slint +++ b/internal/compiler/widgets/cosmic-base/components.slint @@ -1,7 +1,7 @@ // Copyright © SixtyFPS GmbH // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 -import { Icons, CosmicPalette, CosmicFontSettings } from "styling.slint"; +import { Icons, CosmicPalette, CosmicFontSettings, CosmicSizeSettings } from "styling.slint"; export component StateLayerBase { in property border-radius <=> overlay.border-radius; @@ -99,7 +99,7 @@ export component ListItem { in property pressed-y; min-width: layout.min-width; - min-height: max(40px, layout.min-height); + min-height: max(CosmicSizeSettings.item-height, layout.min-height); vertical-stretch: 0; horizontal-stretch: 1; diff --git a/internal/compiler/widgets/cosmic-base/styling.slint b/internal/compiler/widgets/cosmic-base/styling.slint index 608193cb0..55344e710 100644 --- a/internal/compiler/widgets/cosmic-base/styling.slint +++ b/internal/compiler/widgets/cosmic-base/styling.slint @@ -81,3 +81,7 @@ export global Icons { out property edit: @image-url("_edit.svg"); out property calendar: @image-url("_calendar.svg"); } + +export global CosmicSizeSettings { + out property item-height: 40px; +} diff --git a/internal/compiler/widgets/cupertino-base/combobox.slint b/internal/compiler/widgets/cupertino-base/combobox.slint index 392ea1a2e..cbd1bc72d 100644 --- a/internal/compiler/widgets/cupertino-base/combobox.slint +++ b/internal/compiler/widgets/cupertino-base/combobox.slint @@ -1,46 +1,49 @@ // Copyright © SixtyFPS GmbH // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 -import { CupertinoFontSettings, CupertinoPalette, Icons } from "styling.slint"; +import { CupertinoFontSettings, CupertinoPalette, Icons, CupertinoSizeSettings } from "styling.slint"; import { MenuBorder, ListItem, FocusBorder } from "components.slint"; import { ComboBoxBase } from "../common/combobox-base.slint"; +import { ScrollView } from "./scrollview.slint"; export component ComboBox { - in property <[string]> model <=> i-base.model; - in property enabled <=> i-base.enabled; - out property has-focus <=> i-base.has-focus; - in-out property current-index <=> i-base.current-index; - in-out property current-value <=> i-base.current-value; + in property <[string]> model <=> base.model; + in property enabled <=> base.enabled; + out property has-focus <=> base.has-focus; + in-out property current-index <=> base.current-index; + in-out property current-value <=> base.current-value; - callback selected <=> i-base.selected; + callback selected <=> base.selected; - private property background: CupertinoPalette.control-background; + property background: CupertinoPalette.control-background; + property popup-padding: 4px; + property visible-items: 6; - min-width: max(160px, i-layout.min-width); - min-height: max(22px, i-layout.min-height); + min-width: max(160px, layout.min-width); + min-height: max(22px, layout.min-height); horizontal-stretch: 1; vertical-stretch: 0; - forward-focus: i-base; + forward-focus: base; accessible-role: combobox; states [ disabled when !root.enabled : { - i-text.color: CupertinoPalette.foreground-secondary; - i-top-icon.colorize: CupertinoPalette.foreground-secondary; - i-bottom-icon.colorize: CupertinoPalette.foreground-secondary; + text.color: CupertinoPalette.foreground-secondary; + top-icon.colorize: CupertinoPalette.foreground-secondary; + bottom-icon.colorize: CupertinoPalette.foreground-secondary; root.background: CupertinoPalette.tertiary-control-background; } - pressed when i-base.pressed : { + pressed when base.pressed : { root.background: CupertinoPalette.secondary-control-background; } ] - i-base := ComboBoxBase { + base := ComboBoxBase { width: 100%; height: 100%; show-popup => { - i-popup.show(); + popup.show(); } } @@ -72,14 +75,14 @@ export component ComboBox { } } - i-layout := HorizontalLayout { + layout := HorizontalLayout { padding-left: 8px; padding-right: 8px; padding-top: 4px; padding-bottom: 4px; spacing: 4px; - i-text := Text { + text := Text { horizontal-alignment: left; vertical-alignment: center; font-size: CupertinoFontSettings.body.font-size; @@ -129,13 +132,13 @@ export component ComboBox { padding: 4px; spacing: 4px; - i-top-icon := Image { + top-icon := Image { x: (parent.width - self.width) / 2; colorize: CupertinoPalette.accent-foreground; source: Icons.chevron-up; } - i-bottom-icon := Image { + bottom-icon := Image { x: (parent.width - self.width) / 2; colorize: CupertinoPalette.accent-foreground; source: Icons.chevron-down; @@ -144,27 +147,31 @@ export component ComboBox { } } - i-popup := PopupWindow { + popup := PopupWindow { x: 0; y: parent.height + 6px; - min-width: root.width; + width: root.width; + height: root.visible-items * CupertinoSizeSettings.item-height + 2 * root.popup-padding; MenuBorder { - VerticalLayout { - padding: 4px; + ScrollView { + VerticalLayout { + alignment: start; + padding: root.popup-padding; - for value[index] in root.model : ListItem { - padding-horizontal: 0; - item: { text: value }; - is-selected: index == root.current-index; - has-hover: i-touch-area.has-hover; - pressed: i-touch-area.pressed; - pressed-x: i-touch-area.pressed-x; - pressed-y: i-touch-area.pressed-y; + for value[index] in root.model : ListItem { + padding-horizontal: 0; + item: { text: value }; + is-selected: index == root.current-index; + has-hover: touch-area.has-hover; + pressed: touch-area.pressed; + pressed-x: touch-area.pressed-x; + pressed-y: touch-area.pressed-y; - i-touch-area := TouchArea { - clicked => { - i-base.select(index); + touch-area := TouchArea { + clicked => { + base.select(index); + } } } } diff --git a/internal/compiler/widgets/cupertino-base/components.slint b/internal/compiler/widgets/cupertino-base/components.slint index 1ebaa8485..e55ad9a9d 100644 --- a/internal/compiler/widgets/cupertino-base/components.slint +++ b/internal/compiler/widgets/cupertino-base/components.slint @@ -1,7 +1,7 @@ // Copyright © SixtyFPS GmbH // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 -import { CupertinoPalette, CupertinoFontSettings, Icons } from "styling.slint"; +import { CupertinoPalette, CupertinoFontSettings, Icons, CupertinoSizeSettings } from "styling.slint"; export component FocusBorder inherits Rectangle { in property has-focus; @@ -55,7 +55,7 @@ export component ListItem { in property pressed-y; min-width: i-layout.min-width; - min-height: max(22px, i-layout.min-height); + min-height: max(CupertinoSizeSettings.item-height, i-layout.min-height); vertical-stretch: 0; horizontal-stretch: 1; diff --git a/internal/compiler/widgets/cupertino-base/styling.slint b/internal/compiler/widgets/cupertino-base/styling.slint index 8bea9022a..e2a576fbd 100644 --- a/internal/compiler/widgets/cupertino-base/styling.slint +++ b/internal/compiler/widgets/cupertino-base/styling.slint @@ -100,3 +100,7 @@ export global Icons { out property edit: @image-url("_edit.svg"); out property calendar: @image-url("_calendar.svg"); } + +export global CupertinoSizeSettings { + out property item-height: 22px; +} diff --git a/internal/compiler/widgets/fluent-base/combobox.slint b/internal/compiler/widgets/fluent-base/combobox.slint index 78c34322d..d8a236b14 100644 --- a/internal/compiler/widgets/fluent-base/combobox.slint +++ b/internal/compiler/widgets/fluent-base/combobox.slint @@ -1,55 +1,59 @@ // Copyright © SixtyFPS GmbH // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 -import { FluentFontSettings, FluentPalette, Icons } from "styling.slint"; +import { FluentFontSettings, FluentPalette, Icons, FluentSizeSettings } from "styling.slint"; import { MenuBorder, ListItem, FocusBorder } from "components.slint"; import { ComboBoxBase } from "../common/combobox-base.slint"; +import { ScrollView } from "./scrollview.slint"; export component ComboBox { - in property <[string]> model <=> i-base.model; - in property enabled <=> i-base.enabled; - out property has-focus <=> i-base.has-focus; - in-out property current-index <=> i-base.current-index; - in-out property current-value <=> i-base.current-value; + in property <[string]> model <=> base.model; + in property enabled <=> base.enabled; + out property has-focus <=> base.has-focus; + in-out property current-index <=> base.current-index; + in-out property current-value <=> base.current-value; - callback selected <=> i-base.selected; + callback selected <=> base.selected; - min-width: max(160px, i-layout.min-height); - min-height: max(32px, i-layout.min-height); + property popup-padding: 4px; + property visible-items: 6; + + min-width: max(160px, layout.min-height); + min-height: max(32px, layout.min-height); horizontal-stretch: 1; vertical-stretch: 0; - forward-focus: i-base; + forward-focus: base; accessible-role: combobox; states [ disabled when !root.enabled : { - i-background.background: FluentPalette.control-disabled; - i-background.border-color: FluentPalette.border; - i-text.color: FluentPalette.text-disabled; - i-icon.colorize: FluentPalette.text-disabled; + background.background: FluentPalette.control-disabled; + background.border-color: FluentPalette.border; + text.color: FluentPalette.text-disabled; + icon.colorize: FluentPalette.text-disabled; } - pressed when i-base.pressed : { - i-background.background: FluentPalette.control-alt-tertiary; - i-background.border-color: FluentPalette.border; - i-text.color: FluentPalette.text-secondary; - i-icon.colorize: FluentPalette.text-tertiary; + pressed when base.pressed : { + background.background: FluentPalette.control-alt-tertiary; + background.border-color: FluentPalette.border; + text.color: FluentPalette.text-secondary; + icon.colorize: FluentPalette.text-tertiary; } - hover when i-base.has-hover : { - i-background.background: FluentPalette.control-secondary; + hover when base.has-hover : { + background.background: FluentPalette.control-secondary; } ] - i-base := ComboBoxBase { + base := ComboBoxBase { width: 100%; height: 100%; show-popup => { - i-popup.show(); + popup.show(); } } - i-background := Rectangle { + background := Rectangle { border-radius: 3px; background: FluentPalette.control-background; border-width: 1px; @@ -57,12 +61,12 @@ export component ComboBox { animate border-color { duration: 200ms; } - i-layout := HorizontalLayout { + layout := HorizontalLayout { padding-left: 11px; padding-right: 11px; spacing: 8px; - i-text := Text { + text := Text { horizontal-alignment: left; vertical-alignment: center; font-size: FluentFontSettings.body.font-size; @@ -71,7 +75,7 @@ export component ComboBox { text: root.current-value; } - i-icon := Image { + icon := Image { colorize: FluentPalette.text-secondary; width: 12px; source: Icons.dropdown; @@ -83,30 +87,34 @@ export component ComboBox { } // focus border - if (root.has-focus && root.enabled) : FocusBorder { - border-radius: i-background.border-radius; + if root.has-focus && root.enabled : FocusBorder { + border-radius: background.border-radius; } - i-popup := PopupWindow { + popup := PopupWindow { x: 0; // Position the popup so that the first element is over the popup. // Ideally it should be so that the current element is over the popup. y: -4px; width: root.width; + height: root.visible-items * FluentSizeSettings.item-height + 2 * root.popup-padding; MenuBorder { - VerticalLayout { - padding: 4px; + ScrollView { + VerticalLayout { + alignment: start; + padding: root.popup-padding; + + for value[index] in root.model : ListItem { + item: { text: value }; + is-selected: index == root.current-index; + has-hover: touch-area.has-hover; + pressed: touch-area.pressed; - for value[index] in root.model : ListItem { - item: { text: value }; - is-selected: index == root.current-index; - has-hover: i-touch-area.has-hover; - pressed: i-touch-area.pressed; - - i-touch-area := TouchArea { - clicked => { - i-base.select(index); + touch-area := TouchArea { + clicked => { + base.select(index); + } } } } diff --git a/internal/compiler/widgets/fluent-base/components.slint b/internal/compiler/widgets/fluent-base/components.slint index e166d8381..6174e3b6e 100644 --- a/internal/compiler/widgets/fluent-base/components.slint +++ b/internal/compiler/widgets/fluent-base/components.slint @@ -1,7 +1,7 @@ // Copyright © SixtyFPS GmbH // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 -import { FluentPalette, FluentFontSettings } from "styling.slint"; +import { FluentPalette, FluentFontSettings, FluentSizeSettings } from "styling.slint"; export component FocusBorder inherits Rectangle { border-width: 2px; @@ -43,7 +43,7 @@ export component ListItem { in property pressed-y; min-width: i-layout.min-width; - min-height: max(40px, i-layout.min-height); + min-height: max(FluentSizeSettings.item-height, i-layout.min-height); vertical-stretch: 0; horizontal-stretch: 1; diff --git a/internal/compiler/widgets/fluent-base/styling.slint b/internal/compiler/widgets/fluent-base/styling.slint index 7b35b9137..a4e085872 100644 --- a/internal/compiler/widgets/fluent-base/styling.slint +++ b/internal/compiler/widgets/fluent-base/styling.slint @@ -111,3 +111,7 @@ export global Icons { out property edit: @image-url("_edit.svg"); out property calendar: @image-url("_calendar.svg"); } + +export global FluentSizeSettings { + out property item-height: 40px; +} diff --git a/internal/compiler/widgets/material-base/combobox.slint b/internal/compiler/widgets/material-base/combobox.slint index 3fb59b93b..5842b26c7 100644 --- a/internal/compiler/widgets/material-base/combobox.slint +++ b/internal/compiler/widgets/material-base/combobox.slint @@ -2,51 +2,54 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 -import { MaterialPalette, MaterialFontSettings, Elevation, Icons } from "styling.slint"; +import { MaterialPalette, MaterialFontSettings, Elevation, Icons, MaterialSizeSettings } from "styling.slint"; import { ListItem, StateLayer } from "components.slint"; import { ComboBoxBase } from "../common/combobox-base.slint"; +import { ScrollView } from "./scrollview.slint"; export component ComboBox { - in property <[string]> model <=> i-base.model; - in property enabled <=> i-base.enabled; - out property has-focus <=> i-base.has-focus; - in-out property current-index <=> i-base.current-index; - in-out property current-value <=> i-base.current-value; + in property <[string]> model <=> base.model; + in property enabled <=> base.enabled; + out property has-focus <=> base.has-focus; + in-out property current-index <=> base.current-index; + in-out property current-value <=> base.current-value; - callback selected <=> i-base.selected; + callback selected <=> base.selected; + + property visible-items: 6; - min-width: max(160px, i-layout.min-width); - min-height: max(22px, i-layout.min-height); + min-width: max(160px, layout.min-width); + min-height: max(22px, layout.min-height); horizontal-stretch: 1; vertical-stretch: 0; - forward-focus: i-base; + forward-focus: base; accessible-role: combobox; states [ disabled when !root.enabled : { - i-background.border-color: MaterialPalette.control-foreground; - i-background.opacity: 0.38; - i-label.opacity: 0.38; - i-icon.opacity: 0.38; + background.border-color: MaterialPalette.control-foreground; + background.opacity: 0.38; + label.opacity: 0.38; + icon.opacity: 0.38; } focused when root.has-focus : { - i-background.border-width: 2px; - i-background.border-color: MaterialPalette.accent-background; - i-label.color: MaterialPalette.accent-background; - i-icon.colorize: MaterialPalette.accent-background; + background.border-width: 2px; + background.border-color: MaterialPalette.accent-background; + label.color: MaterialPalette.accent-background; + icon.colorize: MaterialPalette.accent-background; } ] - i-base := ComboBoxBase { + base := ComboBoxBase { width: 100%; height: 100%; show-popup => { - i-popup.show(); + popup.show(); } } - i-background := Rectangle { + background := Rectangle { width: 100%; height: 100%; border-radius: 4px; @@ -54,12 +57,12 @@ export component ComboBox { border-color: MaterialPalette.border; } - i-layout := HorizontalLayout { + layout := HorizontalLayout { padding-left: 16px; padding-right: 12px; spacing: 16px; - i-label := Text { + label := Text { text <=> root.current-value; color: MaterialPalette.control-foreground; vertical-alignment: center; @@ -69,7 +72,7 @@ export component ComboBox { font-weight: MaterialFontSettings.body-large.font-weight; } - i-icon := Image { + icon := Image { width: 24px; height: 24px; y: (parent.height - self.height) / 2; @@ -78,12 +81,13 @@ export component ComboBox { } } - i-popup := PopupWindow { + popup := PopupWindow { x: 0; y: root.height; width: root.width; + height: root.visible-items * MaterialSizeSettings.item-height; - i-popup-container := Rectangle { + popup-container := Rectangle { background: MaterialPalette.alternate-background; drop-shadow-color: MaterialPalette.shadow; drop-shadow-blur: Elevation.level2; @@ -91,16 +95,20 @@ export component ComboBox { border-radius: 4px; } - VerticalLayout { - for value[index] in root.model: ListItem { - item: { text: value }; - is-selected: index == root.current-index; - has-hover: i-touch-area.has-hover; - pressed: i-touch-area.pressed; + ScrollView { + VerticalLayout { + alignment: start; - i-touch-area := StateLayer { - clicked => { - i-base.select(index); + for value[index] in root.model: ListItem { + item: { text: value }; + is-selected: index == root.current-index; + has-hover: touch-area.has-hover; + pressed: touch-area.pressed; + + touch-area := StateLayer { + clicked => { + base.select(index); + } } } } diff --git a/internal/compiler/widgets/material-base/components.slint b/internal/compiler/widgets/material-base/components.slint index 22e0c5bbf..3b3f8e648 100644 --- a/internal/compiler/widgets/material-base/components.slint +++ b/internal/compiler/widgets/material-base/components.slint @@ -1,7 +1,7 @@ // Copyright © SixtyFPS GmbH // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 -import { MaterialPalette, MaterialFontSettings } from "styling.slint"; +import { MaterialPalette, MaterialFontSettings, MaterialSizeSettings } from "styling.slint"; export component Ripple inherits Rectangle { in property ripple-x; @@ -101,7 +101,7 @@ export component ListItem { in property pressed-y; min-width: i-layout.min-width; - min-height: max(48px, i-layout.min-height); + min-height: max(MaterialSizeSettings.item-height, i-layout.min-height); vertical-stretch: 0; horizontal-stretch: 1; diff --git a/internal/compiler/widgets/material-base/styling.slint b/internal/compiler/widgets/material-base/styling.slint index dcb28c10e..843dabe35 100644 --- a/internal/compiler/widgets/material-base/styling.slint +++ b/internal/compiler/widgets/material-base/styling.slint @@ -83,3 +83,7 @@ export global Icons { out property edit: @image-url("_edit.svg"); out property calendar: @image-url("_calendar.svg"); } + +export global MaterialSizeSettings { + out property item-height: 48px; +} diff --git a/internal/compiler/widgets/qt/combobox.slint b/internal/compiler/widgets/qt/combobox.slint index f92cd7f53..9b7df621a 100644 --- a/internal/compiler/widgets/qt/combobox.slint +++ b/internal/compiler/widgets/qt/combobox.slint @@ -2,58 +2,64 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 import { ComboBoxBase } from "../common/combobox-base.slint"; +import { ScrollView } from "./scrollview.slint"; export component ComboBox { - in property <[string]> model <=> i-base.model; - in property enabled <=> i-base.enabled; - out property has-focus <=> i-base.has-focus; - in-out property current-index <=> i-base.current-index; - in-out property current-value <=> i-base.current-value; + in property <[string]> model <=> base.model; + in property enabled <=> base.enabled; + out property has-focus <=> base.has-focus; + in-out property current-index <=> base.current-index; + in-out property current-value <=> base.current-value; - callback selected <=> i-base.selected; + callback selected <=> base.selected; + + property popup-height: 224px; accessible-role: combobox; accessible-value <=> root.current-value; - forward-focus: i-base; + forward-focus: base; HorizontalLayout { - i-native := NativeComboBox { + native := NativeComboBox { current-value <=> root.current-value; has-focus <=> root.has-focus; enabled <=> root.enabled; } } - i-base := ComboBoxBase { + base := ComboBoxBase { width: 100%; height: 100%; show-popup => { - i-popup.show(); + popup.show(); } } - i-popup := PopupWindow { + popup := PopupWindow { x: 0; y: root.height; width: root.width; + height: root.popup-height; NativeComboBoxPopup { width: 100%; height: 100%; } - VerticalLayout { - spacing: 0px; + ScrollView { + VerticalLayout { + alignment: start; + + for value[index] in root.model: NativeStandardListViewItem { + item: { text: value }; + is-selected: root.current-index == index; + has-hover: ta.has-hover; + combobox: true; - for value[index] in root.model: NativeStandardListViewItem { - item: { text: value }; - is-selected: root.current-index == index; - has-hover: ta.has-hover; - combobox: true; - - ta := TouchArea { - clicked => { - i-base.select(index); + ta := TouchArea { + clicked => { + base.select(index); + } } } }