Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Made ComboBox scrollable #5581

Merged
merged 2 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion internal/compiler/widgets/common/combobox-base.slint
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
42 changes: 26 additions & 16 deletions internal/compiler/widgets/cosmic-base/combobox.slint
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// 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

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;
Expand All @@ -13,6 +14,9 @@ export component ComboBox {
in-out property <string> current-value <=> base.current-value;

callback selected <=> base.selected;

property <length> popup-padding: 4px;
property <int> visible-items: 6;

min-width: max(160px, layout.min-height);
min-height: max(32px, layout.min-height);
Expand Down Expand Up @@ -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;

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);
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;

touch-area := TouchArea {
clicked => {
base.select(index);
}
}
}
}
}
}
}
}
}
}
4 changes: 2 additions & 2 deletions internal/compiler/widgets/cosmic-base/components.slint
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// 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

import { Icons, CosmicPalette, CosmicFontSettings } from "styling.slint";
import { Icons, CosmicPalette, CosmicFontSettings, CosmicSizeSettings } from "styling.slint";

export component StateLayerBase {
in property <length> border-radius <=> overlay.border-radius;
Expand Down Expand Up @@ -99,7 +99,7 @@ export component ListItem {
in property <length> 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;

Expand Down
4 changes: 4 additions & 0 deletions internal/compiler/widgets/cosmic-base/styling.slint
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,7 @@ export global Icons {
out property <image> edit: @image-url("_edit.svg");
out property <image> calendar: @image-url("_calendar.svg");
}

export global CosmicSizeSettings {
out property <length> item-height: 40px;
}
83 changes: 45 additions & 38 deletions internal/compiler/widgets/cupertino-base/combobox.slint
Original file line number Diff line number Diff line change
@@ -1,46 +1,49 @@
// 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

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 <bool> enabled <=> i-base.enabled;
out property <bool> has-focus <=> i-base.has-focus;
in-out property <int> current-index <=> i-base.current-index;
in-out property <string> current-value <=> i-base.current-value;
in property <[string]> model <=> base.model;
in property <bool> enabled <=> base.enabled;
out property <bool> has-focus <=> base.has-focus;
in-out property <int> current-index <=> base.current-index;
in-out property <string> current-value <=> base.current-value;

callback selected <=> i-base.selected;
callback selected <=> base.selected;

private property <brush> background: CupertinoPalette.control-background;
property <brush> background: CupertinoPalette.control-background;
property <length> popup-padding: 4px;
property <int> 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();
}
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;

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;

i-touch-area := TouchArea {
clicked => {
i-base.select(index);
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: touch-area.has-hover;
pressed: touch-area.pressed;
pressed-x: touch-area.pressed-x;
pressed-y: touch-area.pressed-y;

touch-area := TouchArea {
clicked => {
base.select(index);
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions internal/compiler/widgets/cupertino-base/components.slint
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// 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

import { CupertinoPalette, CupertinoFontSettings, Icons } from "styling.slint";
import { CupertinoPalette, CupertinoFontSettings, Icons, CupertinoSizeSettings } from "styling.slint";

export component FocusBorder inherits Rectangle {
in property <bool> has-focus;
Expand Down Expand Up @@ -55,7 +55,7 @@ export component ListItem {
in property <length> 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;

Expand Down
4 changes: 4 additions & 0 deletions internal/compiler/widgets/cupertino-base/styling.slint
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,7 @@ export global Icons {
out property <image> edit: @image-url("_edit.svg");
out property <image> calendar: @image-url("_calendar.svg");
}

export global CupertinoSizeSettings {
out property <length> item-height: 22px;
}
Loading
Loading