mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-31 20:08:35 +00:00
material: Components: added Menu (https://github.com/slint-ui/material-components/issues/130)
* Components: added Menu
* [autofix.ci] apply automated fixes
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Imported from 599653f7ce
This commit is contained in:
parent
f14d04c798
commit
971bff4434
8 changed files with 199 additions and 1 deletions
|
|
@ -0,0 +1,42 @@
|
||||||
|
---
|
||||||
|
<!-- Copyright © SixtyFPS GmbH <info@slint.dev> ; SPDX-License-Identifier: MIT -->
|
||||||
|
title: Menu
|
||||||
|
description: Menu API.
|
||||||
|
---
|
||||||
|
|
||||||
|
import CodeSnippetMD from '/src/components/CodeSnippetMD.astro';
|
||||||
|
import SlintProperty from '/src/components/SlintProperty.astro';
|
||||||
|
|
||||||
|
<CodeSnippetMD imagePath="/src/assets/generated/menu.png" scale="3" imageWidth="300" imageHeight="200" imageAlt="">
|
||||||
|
```slint
|
||||||
|
import { Menu } from "material.slint";
|
||||||
|
export component Example inherits Window {
|
||||||
|
width: 400px;
|
||||||
|
height: 300px;
|
||||||
|
background: transparent;
|
||||||
|
Menu {
|
||||||
|
width: 280px;
|
||||||
|
height: parent.height;
|
||||||
|
items: [
|
||||||
|
{ text: "Copy" },
|
||||||
|
{ text: "Cut" },
|
||||||
|
{ text: "Paste" },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
</CodeSnippetMD>
|
||||||
|
|
||||||
|
A `Menu` display a list of choices on a temporary surface.
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
### items
|
||||||
|
<SlintProperty propName="items" typeName="[struct]" structName="MenuItem">
|
||||||
|
An array of menu items, each containing an icon, a text, and a trailing text.
|
||||||
|
</SlintProperty>
|
||||||
|
|
||||||
|
## Callbacks
|
||||||
|
|
||||||
|
### item_clicked(index: int)
|
||||||
|
Invoked when a menu item is clicked
|
||||||
|
|
@ -30,7 +30,8 @@ import {
|
||||||
Switch,
|
Switch,
|
||||||
Slider,
|
Slider,
|
||||||
TextField,
|
TextField,
|
||||||
RadioButtonTile
|
RadioButtonTile,
|
||||||
|
Menu
|
||||||
} from "../../../../material.slint";
|
} from "../../../../material.slint";
|
||||||
|
|
||||||
import { Group } from "../components/group.slint";
|
import { Group } from "../components/group.slint";
|
||||||
|
|
@ -419,6 +420,34 @@ export component NavigationView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ComponentCard {
|
||||||
|
title: "Menus";
|
||||||
|
|
||||||
|
Horizontal {
|
||||||
|
alignment: center;
|
||||||
|
|
||||||
|
menu_button := TextButton {
|
||||||
|
text: "Show menu";
|
||||||
|
|
||||||
|
clicked => {
|
||||||
|
menu.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
menu := Menu {
|
||||||
|
x: menu_button.x + menu_button.width / 2;
|
||||||
|
y: menu_button.y + menu_button.height / 2;
|
||||||
|
items: [
|
||||||
|
{ icon: OutlinedIcons.account_box, text: "Inbox", enabled: true },
|
||||||
|
{ icon: OutlinedIcons.outbox, text: "Outbox", enabled: true, trailing_text: "Ctrl C" },
|
||||||
|
{ icon: OutlinedIcons.favorite, text: "Fravorites", enabled: true },
|
||||||
|
{ icon: OutlinedIcons.delete, text: "Trash", enabled: false },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ComponentCard {
|
ComponentCard {
|
||||||
title: "Time picker";
|
title: "Time picker";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ export { Avatar, ListTile } from "./ui/components/list.slint";
|
||||||
export { ListView } from "./ui/components/list_view.slint";
|
export { ListView } from "./ui/components/list_view.slint";
|
||||||
export { MaterialText } from "./ui/components/material_text.slint";
|
export { MaterialText } from "./ui/components/material_text.slint";
|
||||||
export { MaterialWindow, MaterialWindowAdapter } from "./ui/components/material_window.slint";
|
export { MaterialWindow, MaterialWindowAdapter } from "./ui/components/material_window.slint";
|
||||||
|
export { Menu } from "./ui/components/menu.slint";
|
||||||
export { NavigationBar } from "./ui/components/navigation_bar.slint";
|
export { NavigationBar } from "./ui/components/navigation_bar.slint";
|
||||||
export { NavigationDrawer, ModalNavigationDrawer } from "./ui/components/navigation_drawer.slint";
|
export { NavigationDrawer, ModalNavigationDrawer } from "./ui/components/navigation_drawer.slint";
|
||||||
export { NavigationRail } from "./ui/components/navigation_rail.slint";
|
export { NavigationRail } from "./ui/components/navigation_rail.slint";
|
||||||
|
|
@ -53,6 +54,7 @@ export { Modal } from "./ui/components/modal.slint";
|
||||||
// items
|
// items
|
||||||
export { ListItem } from "./ui/items/list_item.slint";
|
export { ListItem } from "./ui/items/list_item.slint";
|
||||||
export { NavigationItem, NavigationGroup } from "./ui/items/navigation_item.slint";
|
export { NavigationItem, NavigationGroup } from "./ui/items/navigation_item.slint";
|
||||||
|
export { MenuItem } from "./ui/items/menu_item.slint";
|
||||||
|
|
||||||
// styles
|
// styles
|
||||||
export { Animations } from "./ui/styling/animations.slint";
|
export { Animations } from "./ui/styling/animations.slint";
|
||||||
|
|
|
||||||
113
ui-libraries/material/ui/components/menu.slint
Normal file
113
ui-libraries/material/ui/components/menu.slint
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
// 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 { Elevation } from "elevation.slint";
|
||||||
|
import { StateLayerArea } from "./state_layer.slint";
|
||||||
|
import { Typography } from "../styling/typography.slint";
|
||||||
|
import { Icon } from "./icon.slint";
|
||||||
|
import { MenuItem } from "../items/menu_item.slint";
|
||||||
|
import { MaterialText } from "./material_text.slint";
|
||||||
|
import { Icons } from "../icons/icons.slint";
|
||||||
|
|
||||||
|
component MenuItemTemplate {
|
||||||
|
in property <image> icon;
|
||||||
|
in property <string> text;
|
||||||
|
in property <string> trailing_text;
|
||||||
|
in property <bool> enabled <=> state_area.enabled;
|
||||||
|
|
||||||
|
callback clicked();
|
||||||
|
|
||||||
|
property <bool> has_icon: root.icon.width > 0 && root.icon.height > 0;
|
||||||
|
property <color> color: MaterialPalette.on_surface;
|
||||||
|
property <color> color_variant: MaterialPalette.on_surface_variant;
|
||||||
|
|
||||||
|
min_height: max(MaterialStyleMetrics.size_56, layout.min_height);
|
||||||
|
|
||||||
|
state_area := StateLayerArea {
|
||||||
|
color: root.color;
|
||||||
|
|
||||||
|
layout := HorizontalLayout {
|
||||||
|
padding_left: MaterialStyleMetrics.padding_12;
|
||||||
|
padding_right: self.padding_left;
|
||||||
|
padding_top: MaterialStyleMetrics.padding_8;
|
||||||
|
padding_bottom: self.padding_top;
|
||||||
|
spacing: MaterialStyleMetrics.spacing_12;
|
||||||
|
|
||||||
|
if root.has_icon : VerticalLayout {
|
||||||
|
alignment: center;
|
||||||
|
|
||||||
|
Icon {
|
||||||
|
source: root.icon;
|
||||||
|
colorize: root.color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialText {
|
||||||
|
horizontal_stretch: 1;
|
||||||
|
text: root.text;
|
||||||
|
style: Typography.body_large;
|
||||||
|
color: root.color;
|
||||||
|
vertical_alignment: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
if root.trailing_text != "" : MaterialText {
|
||||||
|
text: root.trailing_text;
|
||||||
|
style: Typography.body_large;
|
||||||
|
color: root.color_variant;
|
||||||
|
vertical_alignment: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clicked => {
|
||||||
|
root.clicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
states [
|
||||||
|
disabled when !root.enabled : {
|
||||||
|
state_area.opacity: MaterialPalette.disable_opacity;
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export component Menu inherits PopupWindow {
|
||||||
|
in property <[MenuItem]> items;
|
||||||
|
|
||||||
|
callback item_clicked(index: int);
|
||||||
|
|
||||||
|
// used to fix clipping of shadows
|
||||||
|
property <int> elevation: 2;
|
||||||
|
|
||||||
|
width: MaterialStyleMetrics.size_200;
|
||||||
|
close_policy: close_on_click_outside;
|
||||||
|
|
||||||
|
wrapper := VerticalLayout {
|
||||||
|
padding: root.elevation * 1px;
|
||||||
|
|
||||||
|
menu := Elevation {
|
||||||
|
level: root.elevation;
|
||||||
|
height: layout.min_height + root.elevation * 1px;
|
||||||
|
border_radius: MaterialStyleMetrics.border_radius_4;
|
||||||
|
background: MaterialPalette.surface_container;
|
||||||
|
|
||||||
|
layout := VerticalLayout {
|
||||||
|
width: root.width;
|
||||||
|
padding_top: MaterialStyleMetrics.padding_8;
|
||||||
|
padding_bottom: self.padding_top;
|
||||||
|
|
||||||
|
for item[index] in root.items : MenuItemTemplate {
|
||||||
|
icon: item.icon;
|
||||||
|
text: item.text;
|
||||||
|
trailing_text: item.trailing_text;
|
||||||
|
enabled: item.enabled;
|
||||||
|
|
||||||
|
clicked => {
|
||||||
|
root.item_clicked(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
ui-libraries/material/ui/icons/arrow_right.svg
Normal file
1
ui-libraries/material/ui/icons/arrow_right.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 17l5-5l-5-5v10z"/></svg>
|
||||||
|
After Width: | Height: | Size: 121 B |
|
|
@ -6,6 +6,7 @@ export global Icons {
|
||||||
out property <image> close: @image-url("close.svg");
|
out property <image> close: @image-url("close.svg");
|
||||||
out property <image> menu: @image-url("menu.svg");
|
out property <image> menu: @image-url("menu.svg");
|
||||||
out property <image> arrow_back: @image-url("arrow_back.svg");
|
out property <image> arrow_back: @image-url("arrow_back.svg");
|
||||||
|
out property <image> arrow_right: @image-url("arrow_right.svg");
|
||||||
out property <image> remove: @image-url("remove.svg");
|
out property <image> remove: @image-url("remove.svg");
|
||||||
out property <image> schedule: @image-url("schedule.svg");
|
out property <image> schedule: @image-url("schedule.svg");
|
||||||
out property <image> keyboard: @image-url("keyboard.svg");
|
out property <image> keyboard: @image-url("keyboard.svg");
|
||||||
|
|
|
||||||
9
ui-libraries/material/ui/items/menu_item.slint
Normal file
9
ui-libraries/material/ui/items/menu_item.slint
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
export struct MenuItem {
|
||||||
|
icon: image,
|
||||||
|
text: string,
|
||||||
|
trailing_text: string,
|
||||||
|
enabled: bool
|
||||||
|
}
|
||||||
|
|
@ -26,6 +26,7 @@ export global MaterialStyleMetrics {
|
||||||
out property <length> size_72: 72px;
|
out property <length> size_72: 72px;
|
||||||
out property <length> size_80: 80px;
|
out property <length> size_80: 80px;
|
||||||
out property <length> size_90: 96px;
|
out property <length> size_90: 96px;
|
||||||
|
out property <length> size_200: 200px;
|
||||||
out property <length> size_256: 256px;
|
out property <length> size_256: 256px;
|
||||||
out property <length> size_344: 344px;
|
out property <length> size_344: 344px;
|
||||||
out property <length> size_360: 360px;
|
out property <length> size_360: 360px;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue