This repository has been archived on 2026-08-27. You can view files and clone it, but cannot push or open issues or pull requests.
gopher64-netplay/src/ui/gui/side_bar.slint
Logan McNaughton 5b5acfdd25
update slint (#1117)
* update slint

* more
2026-06-24 15:04:14 +00:00

166 lines
4.1 KiB
Plaintext

// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette } from "std-widgets.slint";
export struct SideBarEntry {
icon: image,
label: string,
}
component SideBarButton inherits Rectangle {
in property <bool> selected;
in property <bool> has-focus;
in property <image> icon;
callback clicked <=> touch.clicked;
width: 48px;
height: 48px;
border-radius: 8px;
highlight := Rectangle {
width: 100%;
height: 100%;
border-radius: parent.border-radius;
background: Palette.control-background;
opacity: 0;
animate opacity { duration: 150ms; }
}
icon-display := Image {
source: root.icon;
width: 24px;
height: 24px;
colorize: Palette.foreground;
x: (parent.width - self.width) / 2;
y: (parent.height - self.height) / 2;
animate colorize { duration: 150ms; }
}
touch := TouchArea {
width: 100%;
height: 100%;
}
states [
selected when root.selected: {
highlight.opacity: 1;
highlight.background: Palette.accent-background;
icon-display.colorize: Palette.accent-foreground;
}
pressed when touch.pressed && !root.selected: {
highlight.opacity: 0.55;
}
hover when touch.has-hover && !root.selected: {
highlight.opacity: 0.4;
}
focused when root.has-focus && !root.selected: {
highlight.opacity: 0.4;
}
]
}
component SideBarItem inherits Rectangle {
in property <int> tab-index;
in property <bool> selected;
in property <bool> has-focus;
in property <image> icon;
in property <string> label;
callback clicked <=> button.clicked;
accessible-role: tab;
accessible-label: root.label;
accessible-item-index: root.tab-index;
accessible-item-selectable: true;
accessible-item-selected: root.selected;
accessible-action-default => {
self.clicked();
}
button := SideBarButton {
Tooltip {
Text {
text: root.label;
}
}
icon: root.icon;
selected: root.selected;
has-focus: root.has-focus;
}
}
export component SideBar inherits Rectangle {
in property <[SideBarEntry]> model: [];
in property <string> title: "Gopher64";
in property <bool> portrait;
in-out property <int> current-item: 0;
Rectangle {
width: 100%;
height: 100%;
background: Palette.background.darker(0.2);
}
// Bottom bar in portrait: icons in a row, centered vertically in the bar.
portrait-strip := HorizontalLayout {
visible: root.portrait;
width: 100%;
height: 100%;
padding: 4px;
spacing: 4px;
alignment: space-evenly;
accessible-role: tab-list;
accessible-label: root.title;
accessible-item-count: root.model.length;
for item[index] in root.model: VerticalLayout {
alignment: center;
SideBarItem {
clicked => {
root.current-item = index;
}
tab-index: index;
icon: item.icon;
label: item.label;
selected: index == root.current-item;
}
}
}
// Left rail in landscape: icons in a column, centered horizontally in the bar.
landscape-strip := VerticalLayout {
visible: !root.portrait;
width: 100%;
height: 100%;
padding: 4px;
spacing: 4px;
alignment: space-evenly;
accessible-role: tab-list;
accessible-label: root.title;
accessible-item-count: root.model.length;
for item[index] in root.model: HorizontalLayout {
alignment: center;
SideBarItem {
clicked => {
root.current-item = index;
}
tab-index: index;
icon: item.icon;
label: item.label;
selected: index == root.current-item;
}
}
}
}