mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-26 01:48:03 +00:00
103 lines
2.8 KiB
Text
103 lines
2.8 KiB
Text
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
import { MaterialStyleMetrics } from "../styling/material_style_metrics.slint";
|
|
import { MaterialPalette } from "../styling/material_palette.slint";
|
|
import { BaseButton } from "base_button.slint";
|
|
import { Icons } from "../icons/icons.slint";
|
|
import { Animations } from "../styling/animations.slint";
|
|
|
|
export struct SegmentedItem {
|
|
icon: image,
|
|
text: string
|
|
}
|
|
|
|
component SegmentedItemTemplate {
|
|
in property <image> icon;
|
|
in property <string> text;
|
|
in property <int> index;
|
|
in property <bool> selected;
|
|
in property <bool> last;
|
|
|
|
callback clicked <=> base.clicked;
|
|
|
|
accessible-role: list-item;
|
|
accessible-label: root.text;
|
|
accessible-item-selectable: true;
|
|
accessible-item-selected: root.selected;
|
|
accessible-item-index: root.index;
|
|
|
|
if root.selected : Rectangle {
|
|
background: MaterialPalette.secondary_container;
|
|
}
|
|
|
|
base := BaseButton {
|
|
min_layout_width: 0;
|
|
min_layout_height: 0;
|
|
color: MaterialPalette.on_surface;
|
|
vertical_padding: MaterialStyleMetrics.padding_10;
|
|
horizontal_padding: MaterialStyleMetrics.padding_24;
|
|
spacing: MaterialStyleMetrics.spacing_8;
|
|
icon: root.icon;
|
|
text: root.text;
|
|
|
|
|
|
animate width { duration: Animations.standard_accelerate_duration; easing: Animations.standard_easing; }
|
|
}
|
|
|
|
if !root.last : Rectangle {
|
|
x: parent.width - self.width;
|
|
width: 1px;
|
|
height: 100%;
|
|
background: MaterialPalette.outline;
|
|
}
|
|
|
|
states [
|
|
selected when root.selected : {
|
|
base.icon: Icons.check;
|
|
}
|
|
]
|
|
}
|
|
|
|
export component SegmentedButton {
|
|
in property <[SegmentedItem]> items;
|
|
in_out property <int> current_index;
|
|
|
|
callback index_changed(index: int);
|
|
|
|
min_width: max(2 * MaterialStyleMetrics.size_40, layout.min_width);
|
|
min_height: max(MaterialStyleMetrics.size_40, layout.min_height);
|
|
|
|
accessible-role: list;
|
|
accessible-item-count: root.items.length;
|
|
|
|
Rectangle {
|
|
clip: true;
|
|
border_width: 1px;
|
|
border_radius: self.height / 2;
|
|
border_color: MaterialPalette.outline;
|
|
|
|
layout := HorizontalLayout {
|
|
for item[index] in root.items : SegmentedItemTemplate {
|
|
icon: item.icon;
|
|
text: item.text;
|
|
index: index;
|
|
last: index == root.items.length - 1;
|
|
selected: index == root.current_index;
|
|
|
|
clicked => {
|
|
root.select(index);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function select(index: int) {
|
|
if index < 0 || index >= root.items.length {
|
|
return;
|
|
}
|
|
|
|
root.current_index = index;
|
|
root.index_changed(index);
|
|
}
|
|
}
|