slint/internal/compiler/widgets/common/menu-base.slint
Olivier Goffart d49fe14e4a
Menu: avoid using padding properties (#8847)
Padding properties exists as reserved properties but don't have effect.
But the menu code was using them to store values.

This is now a warning because people got confused by setting padding and
wondering why it has not effect.
This also had some bug in the code were properties were padding was set
on a layout, as well as all the padding-* properties, so the padding was
not taking in account
2025-07-04 16:42:59 +02:00

189 lines
6.2 KiB
Text

// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
export component MenuBarItemBase {
in property <MenuEntry> entry;
in property <brush> default-foreground;
in property <brush> hover-foreground;
in property <brush> pressed-foreground;
in property <brush> default-background;
in property <brush> hover-background;
in property <brush> pressed-background;
in property <length> font-size <=> label.font-size;
in property <int> font-weight <=> label.font-weight;
in property <length> border-radius <=> background-layer.border-radius;
in property <length> horizontal-padding;
in property <length> top-padding;
in property <length> bottom-padding;
callback clicked;
callback hovered;
background-layer := Rectangle {
background: root.default-background;
touch-area := TouchArea {
layout := HorizontalLayout {
padding-top: root.top-padding;
padding-bottom: root.bottom-padding;
padding-left: root.horizontal-padding;
padding-right: root.horizontal-padding;
label := Text {
text: entry.title;
color: root.default-foreground;
}
}
pointer-event(event) => {
if event.kind == PointerEventKind.down {
root.clicked();
}
}
changed has-hover => {
if self.has-hover {
root.hovered();
}
}
}
}
states [
pressed when touch-area.pressed : {
background-layer.background: root.pressed-background;
label.color: root.pressed-foreground;
}
has-hover when touch-area.has-hover : {
background-layer.background: root.hover-background;
label.color: root.hover-foreground;
}
]
}
export component MenuBarBase inherits Rectangle {
in property <length> spacing <=> layout.spacing;
in property <LayoutAlignment> alignment <=> layout.alignment;
in property <length> min-layout-height;
in property <length> horizontal-padding;
min-height: max(root.min-layout-height, layout.min-height);
layout := HorizontalLayout {
alignment: start;
padding-left: root.horizontal-padding;
padding-right: root.horizontal-padding;
@children
}
}
export component MenuFrameBase inherits Rectangle {
in property <length> spacing <=> layout.spacing;
in property <length> layout-min-width;
in property <length> margin;
clip: true;
min-width: max(root.layout-min-width, layout.min-width);
layout := VerticalLayout {
padding: root.margin;
@children
}
}
export component MenuItemBase {
in property <brush> default-foreground;
in property <brush> default-background;
in property <brush> current-foreground;
in property <brush> current-background;
in property <brush> separator-color;
in property <length> font-size <=> label.font-size;
in property <int> font-weight <=> label.font-weight;
in property <length> border-radius <=> background-layer.border-radius;
in property <bool> is-current;
in property <MenuEntry> entry;
in property <image> sub-menu-icon;
in property <length> spacing <=> layout.spacing;
in property <length> icon-size;
in property <length> horizontal-padding;
in property <length> vertical-padding;
callback set-current();
callback clear-current();
callback activate(entry : MenuEntry, y: length);
background-layer := Rectangle {
background: root.default-background;
touch-area := TouchArea {
visible: !entry.is-separator;
enabled: entry.enabled;
layout := HorizontalLayout {
padding-top: root.vertical-padding;
padding-bottom: root.vertical-padding;
padding-left: root.horizontal-padding;
padding-right: root.horizontal-padding;
spacing: 10px;
Image {
width: root.icon-size;
y: (parent.height - self.height) / 2;
source: entry.icon;
accessible-role: none;
}
label := Text {
text: entry.title;
color: root.default-foreground;
vertical-alignment: center;
}
if entry.has-sub-menu : Image {
width: root.icon-size;
y: (parent.height - self.height) / 2;
source: root.sub-menu-icon;
colorize: label.color;
accessible-role: none;
}
}
pointer-event(event) => {
if event.kind == PointerEventKind.move && !root.is-current {
root.set-current()
} else if event.kind == PointerEventKind.down && entry.has-sub-menu && entry.enabled {
activate(entry, self.absolute-position.y);
} else if event.kind == PointerEventKind.up
&& self.mouse-y > 0 && self.mouse-y < self.height
&& self.mouse-x > 0 && self.mouse-x < self.width
&& entry.enabled {
// can't put this in `clicked` because then the menu would close causing a panic in the pointer-event
activate(entry, self.absolute-position.y);
}
}
changed has-hover => {
if !self.has-hover && root.is-current {
root.clear-current();
}
}
}
if entry.is-separator: Rectangle {
height: 1px;
background: root.separator-color;
}
}
states [
is-current when root.is-current : {
background-layer.background: root.current-background;
label.color: root.current-foreground;
}
disabled when !entry.enabled : {
label.opacity: 0.5;
}
]
}