diff --git a/examples/energy-monitor/ui/desktop_window.slint b/examples/energy-monitor/ui/desktop_window.slint index a192274e6..372da1053 100644 --- a/examples/energy-monitor/ui/desktop_window.slint +++ b/examples/energy-monitor/ui/desktop_window.slint @@ -13,7 +13,7 @@ import { Navigation, MenuButton, Menu, Value } from "widgets/widgets.slint"; import { BalanceAdapter, OverviewAdapter, UsageAdapter, WeatherAdapter, MenuPageAdapter, MenuOverviewAdapter, SettingsAdapter } from "pages/pages.slint"; import { KioskOverlay } from "blocks/kiosk_overlay.slint"; -export { OverviewAdapter, UsageAdapter, Value, WeatherAdapter, MenuPageAdapter, MenuOverviewAdapter, SettingsAdapter, +export { OverviewAdapter, UsageAdapter, Value, WeatherAdapter, MenuPageAdapter, MenuOverviewAdapter, SettingsAdapter, BarTileModel, Images, HeaderAdapter } export component MainWindow inherits Window { diff --git a/examples/energy-monitor/ui/mid_main.slint b/examples/energy-monitor/ui/mid_main.slint index 6594a9afc..d52c9497d 100644 --- a/examples/energy-monitor/ui/mid_main.slint +++ b/examples/energy-monitor/ui/mid_main.slint @@ -7,7 +7,7 @@ import { Theme } from "theme.slint"; import { Menu, PageScrollView, PageContainer } from "widgets/widgets.slint"; import { MenuPage } from "pages/pages.slint"; import { Balance, Overview, Usage, UsageAdapter, Weather } from "pages/pages.slint"; - + export component MidMain { private property page-count: 4; private property item-width: i-page-scroll-view.viewport-width / page-count; @@ -16,29 +16,45 @@ export component MidMain { Rectangle { background: Theme.palette.background-gradient; - VerticalLayout { + VerticalLayout { padding-bottom: 50px; spacing: 35px; Header {} - + i-page-scroll-view := PageScrollView { vertical-stretch: 1; PageContainer { Overview {} + + clicked => { + show-page(0); + } } PageContainer { Usage {} + + clicked => { + show-page(1); + } } PageContainer { Balance {} + + clicked => { + show-page(2); + } } PageContainer { Weather {} + + clicked => { + show-page(3); + } } animate viewport-x { duration: Theme.durations.medium; } @@ -47,16 +63,16 @@ export component MidMain { i-menu := Menu { stays-open: true; - + start-y: 35px; end-y: 75px; menu-width: root.width / 3; - menu-height: root.height - 75px; - + menu-height: root.height - 75px; + i-menu-page := MenuPage { - page-changed(index) => { + page-changed(index) => { i-menu.hide(); - i-page-scroll-view.viewport-x = min(0px, max(max-viewport-x, -(index * item-width))); + show-page(index); } close => { @@ -69,4 +85,8 @@ export component MidMain { } } } + + function show-page(index: int) { + i-page-scroll-view.viewport-x = min(0px, max(max-viewport-x, -(index * item-width))); + } } \ No newline at end of file diff --git a/examples/energy-monitor/ui/pages/menu_page/menu_overview.slint b/examples/energy-monitor/ui/pages/menu_page/menu_overview.slint index 865efdde5..a9f79359b 100644 --- a/examples/energy-monitor/ui/pages/menu_page/menu_overview.slint +++ b/examples/energy-monitor/ui/pages/menu_page/menu_overview.slint @@ -16,43 +16,4 @@ export global MenuOverviewAdapter { ]; in-out property current-page; out property count: model.length; -} - -export component MenuOverview inherits Page { - callback page-changed <=> i-page-list.selection-changed; - callback show-settings <=> i-settings-button.clicked; - callback show-about <=> i-about-button.clicked; - - in property <[StandardListViewItem]> model <=> MenuOverviewAdapter.model; - in-out property current-page <=> MenuOverviewAdapter.current-page; - - padding-left: 0; - padding-right: 0; - - VerticalLayout { - padding: Theme.spaces.medium; - spacing: Theme.spaces.small; - - HorizontalLayout { - vertical-stretch: 0; - - i-settings-button := IconButton { - icon: Images.settings; - } - - // spacer - Rectangle { - horizontal-stretch: 1; - } - - i-about-button := IconButton { - icon: Images.information; - } - } - - i-page-list := ListView { - model: root.model; - selected-index <=> root.current-page; - } - } } \ No newline at end of file diff --git a/examples/energy-monitor/ui/pages/menu_page/menu_page.slint b/examples/energy-monitor/ui/pages/menu_page/menu_page.slint index 913217a07..ffae67456 100644 --- a/examples/energy-monitor/ui/pages/menu_page/menu_page.slint +++ b/examples/energy-monitor/ui/pages/menu_page/menu_page.slint @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial import { About } from "about.slint"; -import { MenuOverview, MenuOverviewAdapter } from "menu_overview.slint"; +import { MenuOverviewAdapter } from "menu_overview.slint"; import { Settings, SettingsAdapter } from "settings.slint"; import { Theme } from "../../theme.slint"; @@ -31,45 +31,27 @@ export component MenuPage { width: 2 * parent.width; clip: true; - if(parent.x > -parent.width) : MenuOverview { + if(current-index == 0) : Settings { width: root.width; - page-changed(index) => { - root.page-changed(index); - } - show-settings => { - show-settings = true; - current-index = 1; - - } show-about => { - show-settings = false; current-index = 1; } - } - - if(!show-settings && current-index == 1) : About { - x: root.width; - width: root.width; - - back => { - back(); - } - } - - if(show-settings && current-index == 1) : Settings { - x: root.width; - width: root.width; - - back => { - back(); - } close => { root.close(); } } + if(current-index == 1) : About { + x: root.width; + width: root.width; + + back => { + back(); + } + } + animate x { duration: Theme.durations.fast; } } diff --git a/examples/energy-monitor/ui/pages/menu_page/settings.slint b/examples/energy-monitor/ui/pages/menu_page/settings.slint index 53e078f8b..3e96c963c 100644 --- a/examples/energy-monitor/ui/pages/menu_page/settings.slint +++ b/examples/energy-monitor/ui/pages/menu_page/settings.slint @@ -9,6 +9,7 @@ import { IconButton, CheckBox, RadioButton, Switch, ScrollView, Item, ItemGroupB export global SettingsAdapter { callback check-radio-option(int /* index */); + // fuctions in-out property fuction-one-checked: true; in-out property kiosk-mode-checked; @@ -28,7 +29,7 @@ export global SettingsAdapter { radio-option-one-checked = true; radio-option-two-checked = false; return; - } + } radio-option-one-checked = false; radio-option-two-checked = true; @@ -37,7 +38,7 @@ export global SettingsAdapter { export component Settings inherits Page { callback close(); - callback back <=> i-back-button.clicked; + callback show-about <=> i-back-button.clicked; callback check-radio-option <=> SettingsAdapter.check-radio-option; // fuctions @@ -57,28 +58,28 @@ export component Settings inherits Page { padding-left: 0; padding-right: 0; - VerticalLayout { + VerticalLayout { padding-left: Theme.spaces.medium; padding-right: Theme.spaces.medium; padding-top: Theme.spaces.medium; padding-bottom: Theme.spaces.large; spacing: Theme.spaces.medium; - HorizontalLayout { + HorizontalLayout { vertical-stretch: 0; - alignment: start; + alignment: end; i-back-button := IconButton { horizontal-stretch: 0; - icon: Images.arrow-left; + icon: Images.information; } } // spacer - ScrollView { + ScrollView { vertical-stretch: 1; - VerticalLayout { + VerticalLayout { alignment: start; spacing: Theme.spaces.medium; @@ -94,17 +95,17 @@ export component Settings inherits Page { } } - ItemGroupBox { + ItemGroupBox { title: "Subtitle"; - + Item { text: "Option One"; has-separator: true; - i-radio-option-one := RadioButton { + i-radio-option-one := RadioButton { checked: root.radio-option-one-checked; - - clicked => { + + clicked => { root.check-radio-option(0); } } @@ -117,10 +118,10 @@ export component Settings inherits Page { Item { text: "Option Two"; - i-radio-option-two := RadioButton { + i-radio-option-two := RadioButton { checked: root.radio-option-two-checked; - clicked => { + clicked => { root.check-radio-option(1); } } @@ -131,9 +132,9 @@ export component Settings inherits Page { } } - ItemGroupBox { + ItemGroupBox { title: "Subtitle"; - + Item { text: "Option One"; has-separator: true; @@ -176,7 +177,7 @@ export component Settings inherits Page { Item { text: "Kiosk mode"; - i-kiosk-mode := Switch { + i-kiosk-mode := Switch { checked <=> root.kiosk-mode-checked; changed => { @@ -192,7 +193,7 @@ export component Settings inherits Page { Item { text: "Function Three"; - i-fuction-three := Switch { + i-fuction-three := Switch { checked <=> root.fuction-three-checked; } diff --git a/examples/energy-monitor/ui/pages/pages.slint b/examples/energy-monitor/ui/pages/pages.slint index d3f0a446f..1093b4828 100644 --- a/examples/energy-monitor/ui/pages/pages.slint +++ b/examples/energy-monitor/ui/pages/pages.slint @@ -11,8 +11,8 @@ import { MenuPage, MenuPageAdapter, MenuOverviewAdapter, SettingsAdapter } from export { Balance, BalanceAdapter } export { Overview, OverviewAdapter } -export { Usage, UsageAdapter } +export { Usage, UsageAdapter } export { Weather, WeatherAdapter } export { Page } export { Dashboard } -export { MenuPage, MenuPageAdapter, MenuOverviewAdapter, SettingsAdapter } +export { MenuPage, MenuPageAdapter, MenuOverviewAdapter, SettingsAdapter } diff --git a/examples/energy-monitor/ui/small_main.slint b/examples/energy-monitor/ui/small_main.slint index 5fb430149..5975f436f 100644 --- a/examples/energy-monitor/ui/small_main.slint +++ b/examples/energy-monitor/ui/small_main.slint @@ -29,7 +29,7 @@ export component SmallMain { } pagination-clicked => { - i-menu.show-button(); + i-menu.open-menu(); i-navigation.hide(); } diff --git a/examples/energy-monitor/ui/widgets/menu.slint b/examples/energy-monitor/ui/widgets/menu.slint index 3c091ade7..803d5044d 100644 --- a/examples/energy-monitor/ui/widgets/menu.slint +++ b/examples/energy-monitor/ui/widgets/menu.slint @@ -39,6 +39,7 @@ export component Menu { visible: container-visibility == 1.0; border-radius: 4px; background: Theme.palette.ebony-radial-gradient; + clip: true; // avoid click-through TouchArea {} @@ -54,9 +55,12 @@ export component Menu { alignment: start; i-menu-button := MenuButton { - clicked => { - toggle-open(); + if(open) { + hide(); + } else { + open-menu(); + } } } } @@ -69,19 +73,8 @@ export component Menu { menu-button-visible = false; } - public function show-button() { - menu-button-visible = true; - } - - function toggle-open() { - menu-button-visible = false; - open = !open; - - if(open) { - opend(); - } else { - closed(); - } + public function open-menu() { + open = true; } public function hide() { diff --git a/examples/energy-monitor/ui/widgets/page_scroll_view.slint b/examples/energy-monitor/ui/widgets/page_scroll_view.slint index db23c342e..09b35975d 100644 --- a/examples/energy-monitor/ui/widgets/page_scroll_view.slint +++ b/examples/energy-monitor/ui/widgets/page_scroll_view.slint @@ -8,8 +8,9 @@ import { Theme } from "../theme.slint"; component ScrollBar { private property ref-width: self.width - 4px; - in property range; - in property value; + in-out property page-size; + in-out property value; + in-out property maximum; min-height: 14px; @@ -18,22 +19,45 @@ component ScrollBar { border-radius: 6px; border-color: Theme.palette.slint-blue-300; - Rectangle { - x: 2px - ref-width * value; - y: 2px; + i-indicator := Rectangle { + x: 2px + (root.ref-width - i-indicator.width) * (-root.value / root.maximum); height: parent.height - 4px; background: Theme.palette.slint-blue-300; - width: ref-width * range; + width: max(32px, ref-width * root.page-size / (root.maximum + root.page-size)); border-radius: parent.border-radius - 2px; } } + + TouchArea { + property pressed-value; + + width: parent.width; + height: parent.height; + + pointer-event(event) => { + if (event.button == PointerEventButton.left && event.kind == PointerEventKind.down) { + self.pressed-value = -root.value; + } + } + moved => { + if (self.enabled && self.pressed) { + root.value = -max(0px, min(root.maximum, self.pressed-value + ( + (self.mouse-x - self.pressed-x) * (root.maximum / (root.width - i-indicator.width)) + ))); + } + } + } } export component PageContainer { + callback clicked <=> i-touch-area.clicked; + min-width: 320px; min-height: 240px; max-height: 300px; + i-touch-area := TouchArea {} + Rectangle { border-radius: 6px; background: Theme.palette.dark-deep-blue; @@ -61,15 +85,15 @@ export component PageScrollView { i-flickable := Flickable { vertical-stretch: 1; - + i-layout := HorizontalLayout { padding-left: 20px; padding-right: 20px; spacing: 20px; - + @children - } - } + } + } } HorizontalLayout { @@ -78,7 +102,7 @@ export component PageScrollView { padding-left: 25px; padding-right: 25px; - FloatButton { + FloatButton { visible: i-flickable.viewport-x < 0; horizontal-stretch: 0; icon: Images.arrow-left; @@ -93,16 +117,17 @@ export component PageScrollView { horizontal-stretch: 1; ScrollBar { - value: i-flickable.viewport-x / i-flickable.viewport-width; - range: i-flickable.width / i-flickable.viewport-width; + maximum: i-flickable.viewport-width - i-flickable.width; + page-size: i-flickable.width; + value <=> i-flickable.viewport-x; } } - FloatButton { + FloatButton { visible: i-flickable.viewport-x > i-flickable.width - i-flickable.viewport-width; horizontal-stretch: 0; icon: Images.arrow-right; - + clicked => { scroll-right(); }