mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-28 04:45:13 +00:00

Commit 08e20c8586
changed the behavior
of clicked being emitted when the area was both pressed and released.
But that made it hard to hit button on the devices because the touch
screen isn't great.
So activate the button on release instead of click, going effectively
back to previous behavior
330 lines
9.9 KiB
Text
330 lines
9.9 KiB
Text
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
struct ButtonColors {
|
|
base: color,
|
|
pressed: color,
|
|
hovered: color,
|
|
}
|
|
|
|
export global DemoPalette {
|
|
// Color of the home/settings/ink buttons on the left side bar
|
|
out property <color> active-page-icon-color: root.night-mode ? #6284FF : #122F7B;
|
|
out property <color> inactive-page-icon-color: #BDC0D1;
|
|
|
|
out property <color> main-background: #0E133F;
|
|
out property <color> neutral-box: #BDC0D1;
|
|
|
|
out property <color> page-background-color: root.night-mode ? #122F7B : white;
|
|
|
|
out property <color> text-foreground-color: root.night-mode ? #F4F6FF : black;
|
|
out property <color> secondary-foreground-color: root.night-mode ? #C1C3CA : #6C6E7A;
|
|
|
|
out property <color> printer-action-background-color: root.night-mode ? root.main-background : white;
|
|
out property <color> printer-queue-item-background-color: root.page-background-color;
|
|
|
|
out property <color> status-label-text-color: root.night-mode ? #F1FF98 : #6284FF;
|
|
|
|
// Color used for the border / outline of items that can be clicked on, such as the
|
|
// "Print"/"Scan" buttons, the printer queue items (for expansion) or controls such
|
|
// as the combo box or spin box.
|
|
out property <color> control-outline-color: #FFBF63;
|
|
out property <color> control-secondary: #6284FF;
|
|
out property <color> control-foreground: root.night-mode ? white : #122F7B; // FIXME: the night mode color was not part of the design
|
|
|
|
out property <color> primary-push-button-base: #6284FF;
|
|
out property <ButtonColors> primary-push-button-colors: {
|
|
base: root.primary-push-button-base,
|
|
pressed: root.primary-push-button-base.darker(40%),
|
|
hovered: root.primary-push-button-base.darker(20%),
|
|
};
|
|
|
|
out property <color> secondary-push-button-base: #FFBF63;
|
|
out property <ButtonColors> secondary-push-button-colors: {
|
|
base: root.secondary-push-button-base,
|
|
pressed: root.secondary-push-button-base.darker(40%),
|
|
hovered: root.secondary-push-button-base.darker(20%),
|
|
};
|
|
|
|
|
|
out property <color> push-button-text-color: white;
|
|
|
|
out property <length> base-font-size: 12px;
|
|
|
|
in-out property <bool> night-mode: false;
|
|
}
|
|
|
|
export component Page inherits Rectangle {
|
|
in property<string> header <=> h.text;
|
|
background: DemoPalette.page-background-color;
|
|
in property <bool> has-back-button: false;
|
|
callback back;
|
|
|
|
TouchArea {} // protect underneath controls
|
|
|
|
if (root.has-back-button) : Image {
|
|
source: @image-url("images/back.svg");
|
|
image-fit: contain;
|
|
colorize: DemoPalette.control-secondary;
|
|
y: h.y + (h.height - self.height) / 2;
|
|
x: 5px;
|
|
width: 14px;
|
|
height: 24px;
|
|
TouchArea {
|
|
pointer-event(ev) => {
|
|
if (ev.kind == PointerEventKind.up) {
|
|
root.back()
|
|
}
|
|
}
|
|
width: 400%;
|
|
height: 200%;
|
|
x: (parent.width - self.width) / 2;
|
|
y: (parent.height - self.height) / 2;
|
|
}
|
|
}
|
|
|
|
h := Text {
|
|
font-weight: 900;
|
|
font-size: DemoPalette.base-font-size * 1.75;
|
|
color: DemoPalette.text-foreground-color;
|
|
y: 23px - self.font-size;
|
|
x: root.has-back-button ? 30px + 16px : 0px;
|
|
// Allow clicking on the title as well to get back easier when just
|
|
// using fingers on a small screen.
|
|
if (root.has-back-button) : TouchArea {
|
|
pointer-event(ev) => {
|
|
if (ev.kind == PointerEventKind.up) {
|
|
root.back()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
export component Label inherits Text {
|
|
color: DemoPalette.text-foreground-color;
|
|
vertical-alignment: center;
|
|
font-weight: 700;
|
|
vertical-stretch: 0;
|
|
}
|
|
|
|
component SquareButton inherits Rectangle {
|
|
callback clicked;
|
|
in property<image> img;
|
|
border-radius: 3px;
|
|
border-width: 2px;
|
|
border-color: DemoPalette.control-outline-color;
|
|
touch := TouchArea {
|
|
x: -4px;
|
|
y: -4px;
|
|
width: parent.width + 8px;
|
|
height: parent.height + 8px;
|
|
pointer-event(ev) => {
|
|
if (ev.kind == PointerEventKind.up) {
|
|
root.clicked()
|
|
}
|
|
}
|
|
}
|
|
Image {
|
|
height: 12px;
|
|
width: 12px;
|
|
x: (parent.width - self.width)/2;
|
|
y: (parent.height - self.height)/2;
|
|
source <=> root.img;
|
|
image-fit: contain;
|
|
colorize: DemoPalette.control-secondary;
|
|
}
|
|
}
|
|
|
|
export component SpinBox inherits Rectangle {
|
|
in-out property <int> value;
|
|
in property <int> minimum;
|
|
in property <int> maximum: 100;
|
|
height: 32px;
|
|
|
|
HorizontalLayout {
|
|
spacing: 12px;
|
|
padding: 0;
|
|
SquareButton {
|
|
width: root.height - parent.padding * 2;
|
|
img: @image-url("images/minus.svg");
|
|
clicked => {
|
|
if (root.value > root.minimum) {
|
|
root.value -= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
border-radius: 3px;
|
|
border-width: 2px;
|
|
border-color: DemoPalette.control-outline-color;
|
|
Text {
|
|
width: 100%;
|
|
height: 100%;
|
|
vertical-alignment: center;
|
|
horizontal-alignment: center;
|
|
text: root.value;
|
|
color: DemoPalette.control-foreground;
|
|
}
|
|
}
|
|
|
|
SquareButton {
|
|
width: root.height - parent.padding * 2;
|
|
img: @image-url("images/plus.svg");
|
|
clicked => {
|
|
if (root.value < root.maximum) {
|
|
root.value += 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export component ComboBox inherits Rectangle {
|
|
in-out property<string> value;
|
|
in property<[string]> choices;
|
|
border-radius: 3px;
|
|
border-width: 2px;
|
|
border-color: DemoPalette.control-outline-color;
|
|
height: 32px;
|
|
min-width: label.x + label.width + i.width;
|
|
horizontal-stretch: 1; // Work around #2284
|
|
label := Text {
|
|
vertical-alignment: center;
|
|
horizontal-alignment: left;
|
|
text <=> root.value;
|
|
color: DemoPalette.control-foreground;
|
|
height: 100%;
|
|
x: 12px;
|
|
}
|
|
i := Image {
|
|
source: @image-url("images/down.svg");
|
|
colorize: DemoPalette.control-secondary;
|
|
height: 40%;
|
|
width: self.height;
|
|
image-fit: contain;
|
|
x: parent.width - self.width - self.y;
|
|
y: (parent.height - self.height)/2;
|
|
}
|
|
|
|
TouchArea {
|
|
width: 100%;
|
|
height: 100%;
|
|
pointer-event(ev) => {
|
|
if (ev.kind == PointerEventKind.up) {
|
|
popup.show()
|
|
}
|
|
}
|
|
}
|
|
|
|
popup := PopupWindow {
|
|
x:0;
|
|
y: root.height;
|
|
width: root.width;
|
|
Rectangle {
|
|
background: DemoPalette.page-background-color;
|
|
border-radius: 3px;
|
|
border-width: 2px;
|
|
border-color: DemoPalette.control-outline-color;
|
|
}
|
|
VerticalLayout {
|
|
spacing: 6px;
|
|
padding: 3px;
|
|
for value[idx] in root.choices: Rectangle {
|
|
border-radius: 3px;
|
|
background: item-area.has-hover ? DemoPalette.primary-push-button-colors.hovered : #0000;
|
|
HorizontalLayout {
|
|
Text {
|
|
text: value;
|
|
color: item-area.has-hover ? DemoPalette.push-button-text-color : DemoPalette.text-foreground-color;
|
|
font-size: DemoPalette.base-font-size;
|
|
}
|
|
}
|
|
item-area := TouchArea {
|
|
clicked => {
|
|
root.value = value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export component CheckBox inherits Rectangle {
|
|
in-out property <bool> checked;
|
|
in property <string> text;
|
|
|
|
height: 32px;
|
|
|
|
HorizontalLayout {
|
|
spacing: 12px;
|
|
padding: 0;
|
|
SquareButton {
|
|
width: root.height - parent.padding * 2;
|
|
img: root.checked ? @image-url("images/check.svg") : @image-url("");
|
|
clicked => { root.checked = !root.checked; }
|
|
}
|
|
|
|
if root.text != "" : Text {
|
|
text <=> root.text;
|
|
vertical-alignment: center;
|
|
horizontal-alignment: center;
|
|
color: DemoPalette.control-foreground;
|
|
horizontal-stretch: 1;
|
|
}
|
|
}
|
|
|
|
TouchArea {
|
|
pointer-event(ev) => {
|
|
if (ev.kind == PointerEventKind.up) {
|
|
root.checked = !root.checked;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export component PushButton inherits Rectangle {
|
|
callback clicked;
|
|
in property <string> text <=> label.text;
|
|
in property <image> icon <=> img.source;
|
|
in property <bool> primary: true;
|
|
out property <bool> pressed: touch-area.pressed;
|
|
|
|
out property <ButtonColors> colors: root.primary ? DemoPalette.primary-push-button-colors : DemoPalette.secondary-push-button-colors;
|
|
|
|
border-radius: 13.5px;
|
|
|
|
background: root.pressed ? root.colors.pressed : (touch-area.has-hover ? root.colors.hovered : root.colors.base);
|
|
|
|
horizontal-stretch: 1;
|
|
|
|
HorizontalLayout {
|
|
padding-top: 5px;
|
|
padding-bottom: 5px;
|
|
padding-left: parent.border-radius;
|
|
padding-right: parent.border-radius;
|
|
|
|
img := Image {
|
|
horizontal-stretch: 0;
|
|
colorize: DemoPalette.push-button-text-color;
|
|
image-fit: contain;
|
|
width: 17px;
|
|
}
|
|
|
|
label := Text {
|
|
font-weight: 900;
|
|
font-size: DemoPalette.base-font-size * 0.975;
|
|
color: DemoPalette.push-button-text-color;
|
|
horizontal-alignment: center;
|
|
vertical-alignment: center;
|
|
}
|
|
}
|
|
|
|
touch-area := TouchArea {
|
|
pointer-event(ev) => {
|
|
if (ev.kind == PointerEventKind.up) {
|
|
root.clicked()
|
|
}
|
|
}
|
|
}
|
|
}
|