mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-28 10:49:46 +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,
|
||||
Slider,
|
||||
TextField,
|
||||
RadioButtonTile
|
||||
RadioButtonTile,
|
||||
Menu
|
||||
} from "../../../../material.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 {
|
||||
title: "Time picker";
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ export { Avatar, ListTile } from "./ui/components/list.slint";
|
|||
export { ListView } from "./ui/components/list_view.slint";
|
||||
export { MaterialText } from "./ui/components/material_text.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 { NavigationDrawer, ModalNavigationDrawer } from "./ui/components/navigation_drawer.slint";
|
||||
export { NavigationRail } from "./ui/components/navigation_rail.slint";
|
||||
|
|
@ -53,6 +54,7 @@ export { Modal } from "./ui/components/modal.slint";
|
|||
// items
|
||||
export { ListItem } from "./ui/items/list_item.slint";
|
||||
export { NavigationItem, NavigationGroup } from "./ui/items/navigation_item.slint";
|
||||
export { MenuItem } from "./ui/items/menu_item.slint";
|
||||
|
||||
// styles
|
||||
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> menu: @image-url("menu.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> schedule: @image-url("schedule.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_80: 80px;
|
||||
out property <length> size_90: 96px;
|
||||
out property <length> size_200: 200px;
|
||||
out property <length> size_256: 256px;
|
||||
out property <length> size_344: 344px;
|
||||
out property <length> size_360: 360px;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue