slint/demos/energy-monitor/ui/widgets/tab_widget.slint
Simon Hausmann a98d4709be Move printer demo and energy-monitor into new top-level demos/ folder
These are showing off use-cases for Slint, but they're not examples showing individual Slint features.

Also removed the old printerdemo while at it.
2024-10-25 12:09:32 +02:00

128 lines
3.2 KiB
Text

// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Theme } from "../theme.slint";
component Tab {
in property <string> title;
in property <bool> selected;
in property <image> icon;
callback clicked <=> i-touch-area.clicked;
private property <angle> angle: Math.atan(self.height / 2 / self.width);
private property <bool> has-icon: root.icon.width > 0 && root.icon.height > 0;
preferred-width: 200px;
states [
selected when selected : {
i-initiator.width: root.width;
i-title.color: Theme.palette.lemon-green;
i-gradient.opacity: 1.0;
}
]
GridLayout {
padding: root.has-icon ? 7px : 25px;
VerticalLayout {
spacing: root.has-icon ? 7px : 0;
if (root.has-icon) : Image {
x: (parent.width - self.width) / 2;
width: 24px;
height: 24px;
source: root.icon;
colorize: i-title.color;
}
i-title := Text {
text: title;
horizontal-alignment: center;
vertical-alignment: center;
font-size: root.has-icon ? Theme.typo.description-light.size : Theme.typo.header-item-light.size;
font-weight: root.has-icon ? Theme.typo.header-item-light.weight : Theme.typo.description-light.weight;
color: Theme.palette.white;
animate color { duration: Theme.durations.medium; }
}
}
}
i-gradient := Rectangle {
opacity: 0;
visible: !root.has-icon;
Rectangle {
y: 0;
width: 50%;
height: 50%;
x: 0;
background: @linear-gradient(angle, rgba(222, 251, 58, 0) , rgba(222, 251, 58, 0.2));
}
Rectangle {
y: 0;
width: 50%;
height: 50%;
x: self.width;
background: @linear-gradient(-angle, rgba(222, 251, 58, 0) , rgba(222, 251, 58, 0.2));
}
animate opacity { duration: Theme.durations.medium; }
}
i-initiator := Rectangle {
width: 0;
y: 0;
height: 1px;
background: Theme.palette.lemon-green;
visible: selected;
animate width { duration: Theme.durations.medium; }
}
i-touch-area := TouchArea {}
}
export struct TabItem {
text: string,
icon: image
}
export component TabWidget {
in property <[TabItem]> tabs;
in-out property <int> selected-tab;
vertical-stretch: 1;
VerticalLayout {
Rectangle {
vertical-stretch: 1;
@children
}
Rectangle {
vertical-stretch: 0;
background: Theme.palette.tab-gradient;
HorizontalLayout {
alignment: center;
min-height: 80px;
vertical-stretch: 0;
for tab[index] in tabs : Tab {
title: tab.text;
icon: tab.icon;
selected: index == selected-tab;
clicked => {
selected-tab = index;
}
}
}
}
}
}