mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-27 05:44:08 +00:00
179 lines
5.5 KiB
Text
179 lines
5.5 KiB
Text
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
import { Palette } from "std-widgets.slint";
|
|
import { WindowInfo, WindowInfoHelper } from "./ui_utils.slint";
|
|
import { StackView, StackPage } from "./controls/stackview.slint";
|
|
import { CityListView } from "./city_weather.slint";
|
|
import { CityWeather } from "./weather_datatypes.slint";
|
|
import { LocationSearchView } from "./location_search.slint";
|
|
import { GeoLocation } from "./location_datatypes.slint";
|
|
import { AppPalette, AppFonts, AppImages } from "./style/styles.slint";
|
|
import { FloatingTextButton } from "./controls/generic.slint";
|
|
import { BusyLayerController, BusyLayer } from "./controls/busy-layer.slint";
|
|
|
|
// Re export for native rust
|
|
export { WindowInfo, AppPalette, BusyLayerController, CityWeather, GeoLocation }
|
|
|
|
component EdgeFloatingTextButton inherits FloatingTextButton {
|
|
out property<length> edge-spacing: 15px;
|
|
}
|
|
|
|
component AnimatedStackPage inherits StackPage {
|
|
// is-active and is-opened are not set as a binding here, only when the value is actually changed.
|
|
// This is to avoid redundant reevaluation of dependent properties and conditional elements.
|
|
// see: https://github.com/slint-ui/slint/issues/5209
|
|
out property<bool> is-active: false;
|
|
out property<bool> is-opened: false;
|
|
|
|
// using a helper int property to be able to use animate
|
|
property<int> is-active-value: 0;
|
|
|
|
property<duration> animation-duration: 250ms;
|
|
|
|
visible: root.is-active;
|
|
|
|
init => { root.is-active = (self.is-active_value == 1); }
|
|
changed is-active-value => { root.is-active = (self.is-active_value == 1); }
|
|
|
|
states [
|
|
active when self.is-current: {
|
|
is-active-value: 1;
|
|
|
|
out {
|
|
animate is-active-value { delay: root.animation-duration; }
|
|
}
|
|
}
|
|
]
|
|
|
|
content := Rectangle {
|
|
changed y => {
|
|
// First open animation is not working properly without the line below. (A bug?)
|
|
// Seems the animation in transition is using old values,
|
|
// and accessing the property somehow forces the update.
|
|
self.y;
|
|
|
|
if (root.is-opened != (self.y == 0)) {
|
|
root.is-opened = (self.y == 0);
|
|
}
|
|
}
|
|
|
|
y: root.is-current ? 0px : root.height;
|
|
|
|
animate y { duration: root.animation-duration; easing: ease-in-out-quad; }
|
|
|
|
@children
|
|
}
|
|
}
|
|
|
|
enum PageType {
|
|
Main,
|
|
AddLocation,
|
|
}
|
|
|
|
export component AppWindow inherits Window {
|
|
background: AppPalette.background;
|
|
default-font-size: AppFonts.default-font-size;
|
|
|
|
preferred-width: 900px;
|
|
preferred-height: 600px;
|
|
|
|
WindowInfoHelper {
|
|
init => {
|
|
// no support for the different modes currently
|
|
// this is to display slint badge in proper colors
|
|
Palette.color-scheme = ColorScheme.dark;
|
|
}
|
|
}
|
|
|
|
stack := StackView {
|
|
function show-page(pageType : PageType) {
|
|
if (pageType == PageType.Main) {
|
|
self.current-index = 0;
|
|
}
|
|
else if (pageType == PageType.AddLocation) {
|
|
self.current-index = 1;
|
|
}
|
|
}
|
|
|
|
function back-to-main() {
|
|
self.show-page(PageType.Main);
|
|
}
|
|
|
|
current-index: 0;
|
|
min-index: 0;
|
|
|
|
StackPage {
|
|
is-current: self.check-is-current(stack.current-index);
|
|
init => { self.page-index = stack.insert-page(); }
|
|
visible: self.page-index <= stack.current-index;
|
|
|
|
CityListView {}
|
|
|
|
// right (refresh) button
|
|
EdgeFloatingTextButton {
|
|
x: parent.width - self.width - self.edge-spacing;
|
|
y: parent.height - self.height - self.edge-spacing;
|
|
|
|
icon-source: AppImages.refresh;
|
|
|
|
clicked => {
|
|
BusyLayerController.set-busy();
|
|
CityWeather.refresh-all();
|
|
}
|
|
}
|
|
|
|
// left (add) button
|
|
EdgeFloatingTextButton {
|
|
x: self.edge-spacing;
|
|
y: parent.height - self.height - self.edge-spacing;
|
|
|
|
visible: CityWeather.can-add-city;
|
|
|
|
icon-source: AppImages.plus;
|
|
|
|
clicked => {
|
|
stack.show-page(PageType.AddLocation);
|
|
}
|
|
}
|
|
}
|
|
|
|
AnimatedStackPage {
|
|
is-current: self.check-is-current(stack.current-index);
|
|
init => { self.page-index = stack.insert-page(); }
|
|
|
|
location-search-view := LocationSearchView {
|
|
property<bool> is-active: parent.is-active;
|
|
property<bool> is-opened: parent.is-opened;
|
|
|
|
changed is-active => {
|
|
if (self.is-active) {
|
|
self.clear();
|
|
}
|
|
}
|
|
|
|
changed is-opened => {
|
|
if (self.is-opened) {
|
|
self.focus();
|
|
}
|
|
}
|
|
|
|
close-request => {
|
|
self.clear-focus();
|
|
stack.back-to-main();
|
|
}
|
|
|
|
EdgeFloatingTextButton {
|
|
x: parent.width - self.width - self.edge-spacing;
|
|
y: parent.height - self.height - self.edge-spacing;
|
|
|
|
icon-source: AppImages.xmark;
|
|
|
|
clicked => { location-search-view.close-request(); }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if BusyLayerController.is-busy: BusyLayer {}
|
|
}
|