mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 10:50:00 +00:00
Run the syntax_updater on our widgets
This is commit is just the output of running the syntax updater on the files in the internal/compiler/widgets directory. No extra manual steps were done. Note: In order to run the updater, I did a hack so that the updater wouldn't choke on internal item used by the styles by commenting out the check in ElementType::lookup_type_for_child_element
This commit is contained in:
parent
8760262b60
commit
7947d44e59
27 changed files with 580 additions and 565 deletions
|
@ -3,18 +3,18 @@
|
|||
|
||||
import { StyleMetrics, ScrollView } from "std-widgets-impl.slint";
|
||||
|
||||
export LineEditInner := Rectangle {
|
||||
export component LineEditInner inherits Rectangle {
|
||||
callback accepted(string);
|
||||
callback edited(string);
|
||||
property <string> placeholder-text;
|
||||
property font-size <=> input.font-size;
|
||||
property text <=> input.text;
|
||||
property placeholder-color <=> placeholder.color;
|
||||
property enabled <=> input.enabled;
|
||||
property <bool> has-focus: input.has-focus;
|
||||
property input-type <=> input.input-type;
|
||||
property horizontal-alignment <=> input.horizontal-alignment;
|
||||
property read-only <=> input.read-only;
|
||||
in-out property <string> placeholder-text;
|
||||
in-out property font-size <=> input.font-size;
|
||||
in-out property text <=> input.text;
|
||||
in-out property placeholder-color <=> placeholder.color;
|
||||
in-out property enabled <=> input.enabled;
|
||||
in-out property <bool> has-focus: input.has-focus;
|
||||
in-out property input-type <=> input.input-type;
|
||||
in-out property horizontal-alignment <=> input.horizontal-alignment;
|
||||
in-out property read-only <=> input.read-only;
|
||||
min-height: input.preferred-height;
|
||||
min-width: max(50px, placeholder.min-width);
|
||||
clip: true;
|
||||
|
@ -26,15 +26,15 @@ export LineEditInner := Rectangle {
|
|||
}
|
||||
input := TextInput {
|
||||
property <length> computed_x;
|
||||
x: min(0px, max(parent.width - width, computed_x));
|
||||
width: max(parent.width, preferred-width);
|
||||
x: min(0px, max(parent.width - self.width, self.computed_x));
|
||||
width: max(parent.width, self.preferred-width);
|
||||
height: 100%;
|
||||
color: enabled ? StyleMetrics.textedit-text-color : StyleMetrics.textedit-text-color-disabled;
|
||||
color: self.enabled ? StyleMetrics.textedit-text-color : StyleMetrics.textedit-text-color-disabled;
|
||||
cursor-position-changed(cpos) => {
|
||||
if (cpos.x + computed_x < StyleMetrics.layout-padding) {
|
||||
computed_x = - cpos.x + StyleMetrics.layout-padding;
|
||||
} else if (cpos.x + computed_x > parent.width - StyleMetrics.layout-padding) {
|
||||
computed_x = parent.width - cpos.x - StyleMetrics.layout-padding;
|
||||
if (cpos.x + self.computed_x < StyleMetrics.layout-padding) {
|
||||
self.computed_x = - cpos.x + StyleMetrics.layout-padding;
|
||||
} else if (cpos.x + self.computed_x > parent.width - StyleMetrics.layout-padding) {
|
||||
self.computed_x = parent.width - cpos.x - StyleMetrics.layout-padding;
|
||||
}
|
||||
}
|
||||
accepted => { root.accepted(self.text); }
|
||||
|
@ -44,7 +44,7 @@ export LineEditInner := Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
export TextEdit := ScrollView {
|
||||
export component TextEdit inherits ScrollView {
|
||||
in property <length> font-size <=> input.font-size;
|
||||
in-out property <string> text <=> input.text;
|
||||
has-focus: input.has-focus;
|
||||
|
@ -58,36 +58,36 @@ export TextEdit := ScrollView {
|
|||
horizontal-stretch: 1;
|
||||
vertical-stretch: 1;
|
||||
|
||||
viewport-width: wrap == TextWrap.word-wrap ? root.visible-width : max(root.visible-width, input.preferred-width);
|
||||
viewport-width: root.wrap == TextWrap.word-wrap ? root.visible-width : max(root.visible-width, input.preferred-width);
|
||||
viewport-height: max(self.visible-height, input.preferred-height);
|
||||
|
||||
Rectangle {
|
||||
background: enabled ? StyleMetrics.textedit-background : StyleMetrics.textedit-background-disabled;
|
||||
background: root.enabled ? StyleMetrics.textedit-background : StyleMetrics.textedit-background-disabled;
|
||||
}
|
||||
|
||||
input := TextInput {
|
||||
enabled: true;
|
||||
edited => { root.edited(self.text); }
|
||||
color: enabled ? StyleMetrics.textedit-text-color : StyleMetrics.textedit-text-color-disabled;
|
||||
color: self.enabled ? StyleMetrics.textedit-text-color : StyleMetrics.textedit-text-color-disabled;
|
||||
single-line: false;
|
||||
wrap: word-wrap;
|
||||
cursor-position-changed(cpos) => {
|
||||
if (cpos.x + viewport-x < StyleMetrics.layout-padding) {
|
||||
viewport-x = min(0px, max(parent.visible-width - width, - cpos.x + StyleMetrics.layout-padding ));
|
||||
} else if (cpos.x + viewport-x > parent.visible-width - StyleMetrics.layout-padding) {
|
||||
viewport-x = min(0px, max(parent.visible-width - width, parent.visible-width - cpos.x - StyleMetrics.layout-padding ));
|
||||
if (cpos.x + root.viewport-x < StyleMetrics.layout-padding) {
|
||||
root.viewport-x = min(0px, max(parent.visible-width - self.width, - cpos.x + StyleMetrics.layout-padding ));
|
||||
} else if (cpos.x + root.viewport-x > parent.visible-width - StyleMetrics.layout-padding) {
|
||||
root.viewport-x = min(0px, max(parent.visible-width - self.width, parent.visible-width - cpos.x - StyleMetrics.layout-padding ));
|
||||
}
|
||||
if (cpos.y + viewport-y < StyleMetrics.layout-padding) {
|
||||
viewport-y = min(0px, max(parent.visible-height - height, - cpos.y + StyleMetrics.layout-padding ));
|
||||
} else if (cpos.y + viewport-y > parent.visible-height - StyleMetrics.layout-padding - 20px) {
|
||||
if (cpos.y + root.viewport-y < StyleMetrics.layout-padding) {
|
||||
root.viewport-y = min(0px, max(parent.visible-height - self.height, - cpos.y + StyleMetrics.layout-padding ));
|
||||
} else if (cpos.y + root.viewport-y > parent.visible-height - StyleMetrics.layout-padding - 20px) {
|
||||
// FIXME: font-height hardcoded to 20px
|
||||
viewport-y = min(0px, max(parent.visible-height - height, parent.visible-height - cpos.y - StyleMetrics.layout-padding - 20px));
|
||||
root.viewport-y = min(0px, max(parent.visible-height - self.height, parent.visible-height - cpos.y - StyleMetrics.layout-padding - 20px));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export AboutSlint := Rectangle {
|
||||
export component AboutSlint inherits Rectangle {
|
||||
VerticalLayout {
|
||||
padding: 12px;
|
||||
spacing: 8px;
|
||||
|
|
|
@ -3,18 +3,18 @@
|
|||
|
||||
import { StyleMetrics, Button } from "std-widgets-impl.slint";
|
||||
|
||||
export StandardButton := Button {
|
||||
export component StandardButton inherits Button {
|
||||
in property <StandardButtonKind> kind;
|
||||
text:
|
||||
kind == StandardButtonKind.ok ? "OK" :
|
||||
kind == StandardButtonKind.cancel ? "Cancel" :
|
||||
kind == StandardButtonKind.apply ? "Apply" :
|
||||
kind == StandardButtonKind.close ? "Close" :
|
||||
kind == StandardButtonKind.reset ? "Reset" :
|
||||
kind == StandardButtonKind.help ? "Help" :
|
||||
kind == StandardButtonKind.yes ? "Yes" :
|
||||
kind == StandardButtonKind.no ? "No" :
|
||||
kind == StandardButtonKind.abort ? "Abort" :
|
||||
kind == StandardButtonKind.retry ? "Retry" :
|
||||
kind == StandardButtonKind.ignore ? "Ignore" : "";
|
||||
root.kind == StandardButtonKind.ok ? "OK" :
|
||||
root.kind == StandardButtonKind.cancel ? "Cancel" :
|
||||
root.kind == StandardButtonKind.apply ? "Apply" :
|
||||
root.kind == StandardButtonKind.close ? "Close" :
|
||||
root.kind == StandardButtonKind.reset ? "Reset" :
|
||||
root.kind == StandardButtonKind.help ? "Help" :
|
||||
root.kind == StandardButtonKind.yes ? "Yes" :
|
||||
root.kind == StandardButtonKind.no ? "No" :
|
||||
root.kind == StandardButtonKind.abort ? "Abort" :
|
||||
root.kind == StandardButtonKind.retry ? "Retry" :
|
||||
root.kind == StandardButtonKind.ignore ? "Ignore" : "";
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
import { ColorSchemeSelector } from "color-scheme.slint";
|
||||
|
||||
export global Palette := {
|
||||
property<bool> dark-color-scheme: ColorSchemeSelector.dark-color-scheme;
|
||||
export global Palette {
|
||||
in-out property<bool> dark-color-scheme: ColorSchemeSelector.dark-color-scheme;
|
||||
|
||||
// The colors in light mode are default palette. In the
|
||||
// Fluent UI Theme Designer they match the colors produced
|
||||
|
@ -14,73 +14,73 @@ export global Palette := {
|
|||
// and darkening the "white" and brightening the "neutralLight" variants for improved
|
||||
// contrast (esp. on buttons).
|
||||
|
||||
property<color> themeDarker: #004578;
|
||||
property<color> themeDark: #005a9e;
|
||||
property<color> themeDarkAlt: #106ebe;
|
||||
property<color> themePrimary: #0078d4;
|
||||
property<color> themeSecondary: #2b88d8;
|
||||
property<color> themeTertiary: #71afe5;
|
||||
property<color> themeLight: #c7e0f4;
|
||||
property<color> themeLighter: #deecf9;
|
||||
property<color> themeLighterAlt: #eff6fc;
|
||||
property<color> black: !dark-color-scheme ? #000000 : #f8f8f8;
|
||||
property<color> blackTranslucent40: rgba(0,0,0,0.4);
|
||||
property<color> neutralDark: !dark-color-scheme ? #201f1e : #f4f4f4;
|
||||
property<color> neutralPrimary: !dark-color-scheme ? #323130 : #ffffff;
|
||||
property<color> neutralPrimaryAlt: !dark-color-scheme ? #3b3a39 : #dadada;
|
||||
property<color> neutralSecondary: !dark-color-scheme ? #605e5c : #d0d0d0;
|
||||
property<color> neutralSecondaryAlt: #8a8886;
|
||||
property<color> neutralTertiary: !dark-color-scheme ? #a19f9d : #c8c8c8;
|
||||
property<color> neutralTertiaryAlt: !dark-color-scheme ? #c8c6c4 : #6d6d6d;
|
||||
property<color> neutralQuaternary: #d2d0ce;
|
||||
property<color> neutralQuaternaryAlt: !dark-color-scheme ? #e1dfdd : #484848;
|
||||
property<color> neutralLight: !dark-color-scheme ? #edebe9 : #3f3f3f;
|
||||
property<color> neutralLighter: !dark-color-scheme ? #f3f2f1 : #313131;
|
||||
property<color> neutralLighterAlt: !dark-color-scheme ? #faf9f8 : #282828;
|
||||
property<color> accent: #0078d4;
|
||||
property<color> white: !dark-color-scheme ? #ffffff : #1f1f1f;
|
||||
property<color> whiteTranslucent40: rgba(255,255,255,0.4);
|
||||
property<color> yellowDark: #d29200;
|
||||
property<color> yellow: #ffb900;
|
||||
property<color> yellowLight: #fff100;
|
||||
property<color> orange: #d83b01;
|
||||
property<color> orangeLight: #ea4300;
|
||||
property<color> orangeLighter: #ff8c00;
|
||||
property<color> redDark: #a4262c;
|
||||
property<color> red: #e81123;
|
||||
property<color> magentaDark: #5c005c;
|
||||
property<color> magenta: #b4009e;
|
||||
property<color> magentaLight: #e3008c;
|
||||
property<color> purpleDark: #32145a;
|
||||
property<color> purple: #5c2d91;
|
||||
property<color> purpleLight: #b4a0ff;
|
||||
property<color> blueDark: #002050;
|
||||
property<color> blueMid: #00188f;
|
||||
property<color> blue: #0078d4;
|
||||
property<color> blueLight: #00bcf2;
|
||||
property<color> tealDark: #004b50;
|
||||
property<color> teal: #008272;
|
||||
property<color> tealLight: #00b294;
|
||||
property<color> greenDark: #004b1c;
|
||||
property<color> green: #107c10;
|
||||
property<color> greenLight: #bad80a;
|
||||
in-out property<color> themeDarker: #004578;
|
||||
in-out property<color> themeDark: #005a9e;
|
||||
in-out property<color> themeDarkAlt: #106ebe;
|
||||
in-out property<color> themePrimary: #0078d4;
|
||||
in-out property<color> themeSecondary: #2b88d8;
|
||||
in-out property<color> themeTertiary: #71afe5;
|
||||
in-out property<color> themeLight: #c7e0f4;
|
||||
in-out property<color> themeLighter: #deecf9;
|
||||
in-out property<color> themeLighterAlt: #eff6fc;
|
||||
in-out property<color> black: !root.dark-color-scheme ? #000000 : #f8f8f8;
|
||||
in-out property<color> blackTranslucent40: rgba(0,0,0,0.4);
|
||||
in-out property<color> neutralDark: !root.dark-color-scheme ? #201f1e : #f4f4f4;
|
||||
in-out property<color> neutralPrimary: !root.dark-color-scheme ? #323130 : #ffffff;
|
||||
in-out property<color> neutralPrimaryAlt: !root.dark-color-scheme ? #3b3a39 : #dadada;
|
||||
in-out property<color> neutralSecondary: !root.dark-color-scheme ? #605e5c : #d0d0d0;
|
||||
in-out property<color> neutralSecondaryAlt: #8a8886;
|
||||
in-out property<color> neutralTertiary: !root.dark-color-scheme ? #a19f9d : #c8c8c8;
|
||||
in-out property<color> neutralTertiaryAlt: !root.dark-color-scheme ? #c8c6c4 : #6d6d6d;
|
||||
in-out property<color> neutralQuaternary: #d2d0ce;
|
||||
in-out property<color> neutralQuaternaryAlt: !root.dark-color-scheme ? #e1dfdd : #484848;
|
||||
in-out property<color> neutralLight: !root.dark-color-scheme ? #edebe9 : #3f3f3f;
|
||||
in-out property<color> neutralLighter: !root.dark-color-scheme ? #f3f2f1 : #313131;
|
||||
in-out property<color> neutralLighterAlt: !root.dark-color-scheme ? #faf9f8 : #282828;
|
||||
in-out property<color> accent: #0078d4;
|
||||
in-out property<color> white: !root.dark-color-scheme ? #ffffff : #1f1f1f;
|
||||
in-out property<color> whiteTranslucent40: rgba(255,255,255,0.4);
|
||||
in-out property<color> yellowDark: #d29200;
|
||||
in-out property<color> yellow: #ffb900;
|
||||
in-out property<color> yellowLight: #fff100;
|
||||
in-out property<color> orange: #d83b01;
|
||||
in-out property<color> orangeLight: #ea4300;
|
||||
in-out property<color> orangeLighter: #ff8c00;
|
||||
in-out property<color> redDark: #a4262c;
|
||||
in-out property<color> red: #e81123;
|
||||
in-out property<color> magentaDark: #5c005c;
|
||||
in-out property<color> magenta: #b4009e;
|
||||
in-out property<color> magentaLight: #e3008c;
|
||||
in-out property<color> purpleDark: #32145a;
|
||||
in-out property<color> purple: #5c2d91;
|
||||
in-out property<color> purpleLight: #b4a0ff;
|
||||
in-out property<color> blueDark: #002050;
|
||||
in-out property<color> blueMid: #00188f;
|
||||
in-out property<color> blue: #0078d4;
|
||||
in-out property<color> blueLight: #00bcf2;
|
||||
in-out property<color> tealDark: #004b50;
|
||||
in-out property<color> teal: #008272;
|
||||
in-out property<color> tealLight: #00b294;
|
||||
in-out property<color> greenDark: #004b1c;
|
||||
in-out property<color> green: #107c10;
|
||||
in-out property<color> greenLight: #bad80a;
|
||||
}
|
||||
|
||||
|
||||
export global StyleMetrics := {
|
||||
property<length> layout-spacing: 8px;
|
||||
property<length> layout-padding: 8px;
|
||||
property<length> text-cursor-width: 2px;
|
||||
property<brush> window-background: Palette.white;
|
||||
property<color> default-text-color: Palette.neutralDark;
|
||||
property<brush> textedit-background: Palette.white;
|
||||
property<color> textedit-text-color: Palette.neutralPrimary;
|
||||
property<brush> textedit-background-disabled: Palette.neutralLighter;
|
||||
property<color> textedit-text-color-disabled: Palette.neutralTertiary;
|
||||
property<bool> dark-color-scheme: Palette.dark-color-scheme;
|
||||
export global StyleMetrics {
|
||||
in-out property<length> layout-spacing: 8px;
|
||||
in-out property<length> layout-padding: 8px;
|
||||
in-out property<length> text-cursor-width: 2px;
|
||||
in-out property<brush> window-background: Palette.white;
|
||||
in-out property<color> default-text-color: Palette.neutralDark;
|
||||
in-out property<brush> textedit-background: Palette.white;
|
||||
in-out property<color> textedit-text-color: Palette.neutralPrimary;
|
||||
in-out property<brush> textedit-background-disabled: Palette.neutralLighter;
|
||||
in-out property<color> textedit-text-color-disabled: Palette.neutralTertiary;
|
||||
in-out property<bool> dark-color-scheme: Palette.dark-color-scheme;
|
||||
}
|
||||
|
||||
export Button := Rectangle {
|
||||
export component Button inherits Rectangle {
|
||||
callback clicked;
|
||||
in property<string> text <=> text.text;
|
||||
out property<bool> has-focus: fs.has-focus;
|
||||
|
@ -97,9 +97,9 @@ export Button := Rectangle {
|
|||
|
||||
border-width: 1px;
|
||||
border-radius: 2px;
|
||||
border-color: !enabled ? Palette.neutralLighter : Palette.neutralSecondaryAlt;
|
||||
background: !enabled ? Palette.neutralLighter
|
||||
: (touch.pressed || checked) ? Palette.neutralLight
|
||||
border-color: !root.enabled ? Palette.neutralLighter : Palette.neutralSecondaryAlt;
|
||||
background: !root.enabled ? Palette.neutralLighter
|
||||
: (touch.pressed || root.checked) ? Palette.neutralLight
|
||||
: touch.has-hover ? Palette.neutralLighter
|
||||
: Palette.white;
|
||||
horizontal-stretch: 0;
|
||||
|
@ -112,13 +112,13 @@ export Button := Rectangle {
|
|||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
|
||||
if (icon.width > 0 && icon.height > 0): Image {
|
||||
source <=> icon;
|
||||
if (root.icon.width > 0 && root.icon.height > 0): Image {
|
||||
source <=> root.icon;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
text := Text {
|
||||
color: !enabled ? Palette.neutralTertiary : Palette.neutralDark;
|
||||
color: !root.enabled ? Palette.neutralTertiary : Palette.neutralDark;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
font-weight: 600;
|
||||
|
@ -135,6 +135,7 @@ export Button := Rectangle {
|
|||
}
|
||||
|
||||
fs := FocusScope {
|
||||
x:0;
|
||||
width: 0px; // Do not react on clicks
|
||||
enabled <=> root.enabled;
|
||||
key-pressed(event) => {
|
||||
|
@ -148,33 +149,33 @@ export Button := Rectangle {
|
|||
|
||||
Rectangle { // Focus rectangle
|
||||
x: 3px;
|
||||
y: x;
|
||||
width: parent.width - 2*x;
|
||||
height: parent.height - 2*y;
|
||||
border-width: enabled && has-focus? 1px : 0px;
|
||||
y: self.x;
|
||||
width: parent.width - 2*self.x;
|
||||
height: parent.height - 2*self.y;
|
||||
border-width: root.enabled && root.has-focus? 1px : 0px;
|
||||
border-color: Palette.black;
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar := Rectangle {
|
||||
component ScrollBar inherits Rectangle {
|
||||
background: Palette.white;
|
||||
// border-color: Palette.button-background;
|
||||
border-width: 1px;
|
||||
property <bool> horizontal;
|
||||
property<length> maximum;
|
||||
property<length> page-size;
|
||||
in-out property <bool> horizontal;
|
||||
in-out property<length> maximum;
|
||||
in-out property<length> page-size;
|
||||
// this is always negative and bigger than -maximum
|
||||
property<length> value;
|
||||
in-out property<length> value;
|
||||
|
||||
handle := Rectangle {
|
||||
width: !horizontal ? parent.width : maximum <= 0phx ? 0phx : parent.width * (page-size / (maximum + page-size));
|
||||
height: horizontal ? parent.height : maximum <= 0phx ? 0phx : parent.height * (page-size / (maximum + page-size));
|
||||
width: !root.horizontal ? parent.width : root.maximum <= 0phx ? 0phx : parent.width * (root.page-size / (root.maximum + root.page-size));
|
||||
height: root.horizontal ? parent.height : root.maximum <= 0phx ? 0phx : parent.height * (root.page-size / (root.maximum + root.page-size));
|
||||
|
||||
border-radius: (horizontal ? self.height : self.width) / 2;
|
||||
border-radius: (root.horizontal ? self.height : self.width) / 2;
|
||||
background: touch-area.pressed ? Palette.themePrimary :
|
||||
touch-area.has-hover ? Palette.themeSecondary : Palette.neutralTertiary;
|
||||
x: !horizontal ? 0phx : (root.width - handle.width) * (-value / maximum);
|
||||
y: horizontal ? 0phx : (root.height - handle.height) * (-value / maximum);
|
||||
x: !root.horizontal ? 0phx : (root.width - handle.width) * (-root.value / root.maximum);
|
||||
y: root.horizontal ? 0phx : (root.height - handle.height) * (-root.value / root.maximum);
|
||||
}
|
||||
touch-area := TouchArea {
|
||||
width: parent.width;
|
||||
|
@ -182,21 +183,21 @@ ScrollBar := Rectangle {
|
|||
property <length> pressed-value;
|
||||
pointer-event(event) => {
|
||||
if (event.button == PointerEventButton.left && event.kind == PointerEventKind.down) {
|
||||
pressed-value = -root.value;
|
||||
self.pressed-value = -root.value;
|
||||
}
|
||||
}
|
||||
moved => {
|
||||
if (enabled && pressed) {
|
||||
value = -max(0px, min(root.maximum, pressed-value + (
|
||||
horizontal ? (touch-area.mouse-x - touch-area.pressed-x) * (maximum / (root.width - handle.width))
|
||||
: (touch-area.mouse-y - touch-area.pressed-y) * (maximum / (root.height - handle.height))
|
||||
if (self.enabled && self.pressed) {
|
||||
root.value = -max(0px, min(root.maximum, self.pressed-value + (
|
||||
root.horizontal ? (touch-area.mouse-x - touch-area.pressed-x) * (root.maximum / (root.width - handle.width))
|
||||
: (touch-area.mouse-y - touch-area.pressed-y) * (root.maximum / (root.height - handle.height))
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export ScrollView := Rectangle {
|
||||
export component ScrollView inherits Rectangle {
|
||||
in-out property <length> viewport-width <=> fli.viewport-width;
|
||||
in-out property <length> viewport-height <=> fli.viewport-height;
|
||||
in-out property <length> viewport-x <=> fli.viewport-x;
|
||||
|
@ -205,16 +206,16 @@ export ScrollView := Rectangle {
|
|||
out property <length> visible-height <=> fli.height;
|
||||
in property <bool> enabled: true;
|
||||
// FIXME: remove. This property is currently set by the ListView and is used by the native style to draw the scrollbar differently when it has focus
|
||||
property <bool> has-focus;
|
||||
in-out property <bool> has-focus;
|
||||
min-height: 50px;
|
||||
min-width: 50px;
|
||||
horizontal-stretch: 1;
|
||||
vertical-stretch: 1;
|
||||
|
||||
border-radius: 2px;
|
||||
border-width: !enabled ? 0px : has-focus ? 2px : 1px;
|
||||
border-color: !enabled ? Palette.neutralLighter
|
||||
: has-focus ? Palette.themeSecondary
|
||||
border-width: !root.enabled ? 0px : root.has-focus ? 2px : 1px;
|
||||
border-color: !root.enabled ? Palette.neutralLighter
|
||||
: root.has-focus ? Palette.themeSecondary
|
||||
: Palette.neutralPrimary;
|
||||
|
||||
fli := Flickable {
|
||||
|
|
|
@ -8,7 +8,7 @@ import { StandardButton } from "../common/standardbutton.slint";
|
|||
import { StyleMetrics, ScrollView, Button, Palette } from "std-widgets-impl.slint";
|
||||
export { StyleMetrics, ScrollView, Button, StandardButton, TextEdit, AboutSlint, AboutSlint as AboutSixtyFPS }
|
||||
|
||||
export CheckBox := Rectangle {
|
||||
export component CheckBox inherits Rectangle {
|
||||
callback toggled;
|
||||
in property <string> text <=> text.text;
|
||||
in-out property <bool> checked;
|
||||
|
@ -20,7 +20,7 @@ export CheckBox := Rectangle {
|
|||
|
||||
accessible-label <=> text.text;
|
||||
accessible-checkable: true;
|
||||
accessible-checked <=> checked;
|
||||
accessible-checked <=> root.checked;
|
||||
accessible-role: checkbox;
|
||||
|
||||
HorizontalLayout {
|
||||
|
@ -37,9 +37,9 @@ export CheckBox := Rectangle {
|
|||
: touch.has-hover ? Palette.neutralLighter
|
||||
: Palette.themePrimary;*/
|
||||
|
||||
border-color: checked ? background : !enabled ? Palette.neutralTertiaryAlt : Palette.neutralSecondaryAlt;
|
||||
background: !checked ? Palette.white
|
||||
: !enabled ? Palette.neutralTertiaryAlt
|
||||
border-color: root.checked ? self.background : !root.enabled ? Palette.neutralTertiaryAlt : Palette.neutralSecondaryAlt;
|
||||
background: !root.checked ? Palette.white
|
||||
: !root.enabled ? Palette.neutralTertiaryAlt
|
||||
: touch.has-hover || touch.pressed ? Palette.themeDark
|
||||
: Palette.themePrimary;
|
||||
animate background { duration: 250ms; easing: ease; }
|
||||
|
@ -49,19 +49,19 @@ export CheckBox := Rectangle {
|
|||
width: 20px;
|
||||
height: 20px;
|
||||
|
||||
if (checked || touch.has-hover || touch.pressed) : Path {
|
||||
if (root.checked || touch.has-hover || touch.pressed) : Path {
|
||||
width: 66%;
|
||||
height: 66%;
|
||||
x: (parent.width - width) / 2;
|
||||
y: (parent.height - height) / 2;
|
||||
x: (parent.width - self.width) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
commands: "M.22.5.42.7.78.34.74.3.42.62.26.54z";
|
||||
fill: checked ? Palette.white : Palette.neutralSecondaryAlt;
|
||||
fill: root.checked ? Palette.white : Palette.neutralSecondaryAlt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text := Text {
|
||||
color: !enabled ? Palette.neutralTertiary : Palette.neutralDark;
|
||||
color: !root.enabled ? Palette.neutralTertiary : Palette.neutralDark;
|
||||
horizontal-alignment: left;
|
||||
vertical-alignment: center;
|
||||
vertical-stretch: 1;
|
||||
|
@ -80,6 +80,7 @@ export CheckBox := Rectangle {
|
|||
}
|
||||
|
||||
fs := FocusScope {
|
||||
x:0;
|
||||
width: 0px; // Do not react on clicks
|
||||
enabled <=> root.enabled;
|
||||
|
||||
|
@ -94,33 +95,33 @@ export CheckBox := Rectangle {
|
|||
|
||||
Rectangle { // Focus rectangle
|
||||
x: -3px;
|
||||
y: x;
|
||||
width: parent.width - 2*x;
|
||||
height: parent.height - 2*y;
|
||||
border-width: enabled && has-focus ? 1px : 0px;
|
||||
y: self.x;
|
||||
width: parent.width - 2*self.x;
|
||||
height: parent.height - 2*self.y;
|
||||
border-width: root.enabled && root.has-focus ? 1px : 0px;
|
||||
border-color: Palette.black;
|
||||
}
|
||||
}
|
||||
|
||||
SpinBoxButton := Rectangle {
|
||||
component SpinBoxButton inherits Rectangle {
|
||||
callback clicked <=> touch.clicked;
|
||||
property<string> text; // text and font-size are not used, but present in the other styles
|
||||
property <length> font-size;
|
||||
property<bool> enabled <=> touch.enabled;
|
||||
background: !enabled ? transparent
|
||||
in-out property<string> text; // text and font-size are not used, but present in the other styles
|
||||
in-out property <length> font-size;
|
||||
in-out property<bool> enabled <=> touch.enabled;
|
||||
background: !root.enabled ? transparent
|
||||
: touch.pressed ? Palette.neutralLight
|
||||
: touch.has-hover ? Palette.neutralLighter
|
||||
: Palette.white;
|
||||
|
||||
property <color> symbol-color: !enabled ? Palette.neutralTertiary
|
||||
in-out property <color> symbol-color: !root.enabled ? Palette.neutralTertiary
|
||||
: touch.pressed || touch.has-hover ? Palette.neutralPrimary
|
||||
: Palette.neutralSecondary;
|
||||
touch := TouchArea { }
|
||||
}
|
||||
|
||||
export SpinBox := FocusScope {
|
||||
export component SpinBox inherits FocusScope {
|
||||
// FIXME: remove?
|
||||
property <bool> checked;
|
||||
in-out property <bool> checked;
|
||||
in-out property <int> value;
|
||||
in property <int> minimum;
|
||||
in property <int> maximum: 100;
|
||||
|
@ -133,13 +134,13 @@ export SpinBox := FocusScope {
|
|||
vertical-stretch: 0;
|
||||
|
||||
accessible-role: spinbox;
|
||||
accessible-value: value;
|
||||
accessible-value-minimum: minimum;
|
||||
accessible-value-maximum: maximum;
|
||||
accessible-value-step: (maximum - minimum) / 100;
|
||||
accessible-value: root.value;
|
||||
accessible-value-minimum: root.minimum;
|
||||
accessible-value-maximum: root.maximum;
|
||||
accessible-value-step: (root.maximum - root.minimum) / 100;
|
||||
|
||||
Rectangle {
|
||||
background: !enabled ? Palette.neutralLighter : Palette.white;
|
||||
background: !root.enabled ? Palette.neutralLighter : Palette.white;
|
||||
}
|
||||
|
||||
l := GridLayout {
|
||||
|
@ -148,8 +149,8 @@ export SpinBox := FocusScope {
|
|||
padding-bottom: 3px;
|
||||
text := Text {
|
||||
rowspan: 2;
|
||||
text: value;
|
||||
color: !enabled ? Palette.neutralTertiary : Palette.neutralDark;
|
||||
text: root.value;
|
||||
color: !root.enabled ? Palette.neutralTertiary : Palette.neutralDark;
|
||||
horizontal-alignment: left;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
@ -161,8 +162,8 @@ export SpinBox := FocusScope {
|
|||
commands: "M978.2,688.9l-84.2,82.1c-15.7,15.3-41.1,15.3-56.7,0l-341-304.2L162.6,764.5c-15.5,15.1-41,15.1-56.6,0l-84.3-82.1c-15.6-15.2-15.6-39.9,0-55.2l446.6-398.2c15.7-15.3,41-15.3,56.7,0l6.9,6.7l446.3,398.1C993.9,649,993.9,673.7,978.2,688.9z";
|
||||
fill: parent.symbol-color;
|
||||
height: 33%;
|
||||
x: (parent.width - width) / 2;
|
||||
y: (parent.height - height) / 2;
|
||||
x: (parent.width - self.width) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
}
|
||||
clicked => {
|
||||
if (root.value < root.maximum) {
|
||||
|
@ -178,8 +179,8 @@ export SpinBox := FocusScope {
|
|||
commands: "M21.8,311.1l84.2-82.1c15.7-15.2,41-15.2,56.7,0l341.1,304.1l333.7-297.5c15.5-15.2,41-15.2,56.6,0l84.3,82.1c15.6,15.2,15.6,40,0,55.2L531.7,771c-15.7,15.3-41,15.3-56.7,0l-6.9-6.7L21.8,366.3C6.1,351,6.1,326.3,21.8,311.1z";
|
||||
fill: parent.symbol-color;
|
||||
height: 33%;
|
||||
x: (parent.width - width) / 2;
|
||||
y: (parent.height - height) / 2;
|
||||
x: (parent.width - self.width) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
}
|
||||
clicked => {
|
||||
if (root.value > root.minimum) {
|
||||
|
@ -192,23 +193,23 @@ export SpinBox := FocusScope {
|
|||
}
|
||||
|
||||
Rectangle {
|
||||
x: enabled && has-focus ? -2px : 0px;
|
||||
y: x;
|
||||
width: parent.width - 2*x;
|
||||
height: parent.height - 2*y;
|
||||
x: root.enabled && root.has-focus ? -2px : 0px;
|
||||
y: self.x;
|
||||
width: parent.width - 2*self.x;
|
||||
height: parent.height - 2*self.y;
|
||||
border-radius: 2px;
|
||||
border-width: !enabled ? 0px : has-focus ? 3px : 1px;
|
||||
border-color: !enabled ? Palette.neutralLighter
|
||||
: has-focus ? Palette.themeSecondary
|
||||
border-width: !root.enabled ? 0px : root.has-focus ? 3px : 1px;
|
||||
border-color: !root.enabled ? Palette.neutralLighter
|
||||
: root.has-focus ? Palette.themeSecondary
|
||||
: Palette.neutralDark;
|
||||
}
|
||||
|
||||
key-pressed(event) => {
|
||||
if (enabled && event.text == Key.UpArrow && value < maximum) {
|
||||
value += 1;
|
||||
if (root.enabled && event.text == Key.UpArrow && root.value < root.maximum) {
|
||||
root.value += 1;
|
||||
accept
|
||||
} else if (enabled && event.text == Key.DownArrow && value > minimum) {
|
||||
value -= 1;
|
||||
} else if (root.enabled && event.text == Key.DownArrow && root.value > root.minimum) {
|
||||
root.value -= 1;
|
||||
accept
|
||||
} else {
|
||||
reject
|
||||
|
@ -216,7 +217,7 @@ export SpinBox := FocusScope {
|
|||
}
|
||||
}
|
||||
|
||||
export Slider := Rectangle {
|
||||
export component Slider inherits Rectangle {
|
||||
in property<float> maximum: 100;
|
||||
in property<float> minimum: 0;
|
||||
in-out property<float> value;
|
||||
|
@ -230,29 +231,29 @@ export Slider := Rectangle {
|
|||
vertical-stretch: 0;
|
||||
|
||||
accessible-role: slider;
|
||||
accessible-value: value;
|
||||
accessible-value-minimum: minimum;
|
||||
accessible-value-maximum: maximum;
|
||||
accessible-value-step: (maximum - minimum) / 100;
|
||||
accessible-value: root.value;
|
||||
accessible-value-minimum: root.minimum;
|
||||
accessible-value-maximum: root.maximum;
|
||||
accessible-value-step: (root.maximum - root.minimum) / 100;
|
||||
|
||||
|
||||
Rectangle {
|
||||
width: parent.width - parent.min-height;
|
||||
x: parent.height / 2;
|
||||
height: parent.min-height / 4;
|
||||
y: (parent.height - height) / 2;
|
||||
border-radius: height/2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
border-radius: self.height/2;
|
||||
background: !root.enabled ? Palette.neutralLighter
|
||||
: touch.has-hover ? Palette.themeLight
|
||||
: Palette.neutralTertiaryAlt;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: (parent.width - parent.min-height) * ((value - minimum) / (maximum - minimum));
|
||||
width: (parent.width - parent.min-height) * ((root.value - root.minimum) / (root.maximum - root.minimum));
|
||||
x: parent.height / 2;
|
||||
height: parent.min-height / 4;
|
||||
y: (parent.height - height) / 2;
|
||||
border-radius: height/2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
border-radius: self.height/2;
|
||||
background: !root.enabled ? Palette.neutralTertiary
|
||||
: touch.has-hover ? Palette.themeSecondary
|
||||
: Palette.neutralSecondary;
|
||||
|
@ -260,16 +261,16 @@ export Slider := Rectangle {
|
|||
|
||||
handle := Rectangle {
|
||||
property<length> border: 3px;
|
||||
width: height;
|
||||
height: parent.height - 2 * border;
|
||||
width: self.height;
|
||||
height: parent.height - 2 * self.border;
|
||||
border-width: 3px;
|
||||
border-radius: height / 2;
|
||||
border-radius: self.height / 2;
|
||||
border-color: !root.enabled ? Palette.neutralTertiaryAlt
|
||||
: touch.has-hover ? Palette.themePrimary
|
||||
: Palette.neutralSecondary;
|
||||
background: Palette.white;
|
||||
x: (root.width - handle.width) * (value - minimum)/(maximum - minimum);
|
||||
y: border;
|
||||
x: (root.width - handle.width) * (root.value - root.minimum)/(root.maximum - root.minimum);
|
||||
y: self.border;
|
||||
}
|
||||
touch := TouchArea {
|
||||
width: parent.width;
|
||||
|
@ -277,27 +278,28 @@ export Slider := Rectangle {
|
|||
property <float> pressed-value;
|
||||
pointer-event(event) => {
|
||||
if (event.button == PointerEventButton.left && event.kind == PointerEventKind.down) {
|
||||
pressed-value = root.value;
|
||||
self.pressed-value = root.value;
|
||||
}
|
||||
}
|
||||
moved => {
|
||||
if (enabled && pressed) {
|
||||
value = max(root.minimum, min(root.maximum,
|
||||
pressed-value + (touch.mouse-x - touch.pressed-x) * (maximum - minimum) / (root.width - handle.width)));
|
||||
root.changed(value);
|
||||
if (self.enabled && self.pressed) {
|
||||
root.value = max(root.minimum, min(root.maximum,
|
||||
self.pressed-value + (touch.mouse-x - touch.pressed-x) * (root.maximum - root.minimum) / (root.width - handle.width)));
|
||||
root.changed(root.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fs := FocusScope {
|
||||
x:0;
|
||||
width: 0px;
|
||||
|
||||
key-pressed(event) => {
|
||||
if (enabled && event.text == Key.RightArrow) {
|
||||
value = Math.min(value + 1, maximum);
|
||||
if (self.enabled && event.text == Key.RightArrow) {
|
||||
root.value = Math.min(root.value + 1, root.maximum);
|
||||
accept
|
||||
} else if (enabled && event.text == Key.LeftArrow) {
|
||||
value = Math.max(value - 1, minimum);
|
||||
} else if (self.enabled && event.text == Key.LeftArrow) {
|
||||
root.value = Math.max(root.value - 1, root.minimum);
|
||||
accept
|
||||
} else {
|
||||
reject
|
||||
|
@ -306,14 +308,14 @@ export Slider := Rectangle {
|
|||
}
|
||||
|
||||
Rectangle { // Focus rectangle
|
||||
border-width: enabled && has-focus ? 1px : 0px;
|
||||
border-width: root.enabled && root.has-focus ? 1px : 0px;
|
||||
border-color: Palette.black;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export GroupBox := VerticalLayout {
|
||||
export component GroupBox inherits VerticalLayout {
|
||||
in property <string> title <=> label.text;
|
||||
in property<bool> enabled: true;
|
||||
spacing: 8px;
|
||||
|
@ -321,7 +323,7 @@ export GroupBox := VerticalLayout {
|
|||
padding-bottom: 8px;
|
||||
label := Text {
|
||||
vertical-stretch: 0;
|
||||
color: !enabled ? Palette.neutralTertiary : Palette.neutralDark;
|
||||
color: !root.enabled ? Palette.neutralTertiary : Palette.neutralDark;
|
||||
font-weight: 600;
|
||||
}
|
||||
Rectangle {
|
||||
|
@ -332,44 +334,44 @@ export GroupBox := VerticalLayout {
|
|||
}
|
||||
}
|
||||
|
||||
export TabWidgetImpl := Rectangle {
|
||||
property <length> content-x: 0;
|
||||
property <length> content-y: tabbar-preferred-height;
|
||||
property <length> content-height: height - tabbar-preferred-height;
|
||||
property <length> content-width: width;
|
||||
property <length> tabbar-x: 0;
|
||||
property <length> tabbar-y: 0;
|
||||
property <length> tabbar-height: tabbar-preferred-height;
|
||||
property <length> tabbar-width: width;
|
||||
export component TabWidgetImpl inherits Rectangle {
|
||||
in-out property <length> content-x: 0;
|
||||
in-out property <length> content-y: root.tabbar-preferred-height;
|
||||
in-out property <length> content-height: root.height - root.tabbar-preferred-height;
|
||||
in-out property <length> content-width: root.width;
|
||||
in-out property <length> tabbar-x: 0;
|
||||
in-out property <length> tabbar-y: 0;
|
||||
in-out property <length> tabbar-height: root.tabbar-preferred-height;
|
||||
in-out property <length> tabbar-width: root.width;
|
||||
|
||||
property <length> tabbar-preferred-height;
|
||||
property <length> tabbar-preferred-width;
|
||||
property <length> content-min-height;
|
||||
property <length> content-min-width;
|
||||
property <int> current-index;
|
||||
property <int> current-focused;
|
||||
in-out property <length> tabbar-preferred-height;
|
||||
in-out property <length> tabbar-preferred-width;
|
||||
in-out property <length> content-min-height;
|
||||
in-out property <length> content-min-width;
|
||||
in-out property <int> current-index;
|
||||
in-out property <int> current-focused;
|
||||
|
||||
preferred-width: content-min-width;
|
||||
min-width: max(content-min-width, tabbar-preferred-width);
|
||||
preferred-height: content-min-height + tabbar-preferred-height;
|
||||
min-height: content-min-height + tabbar-preferred-height;
|
||||
preferred-width: root.content-min-width;
|
||||
min-width: max(root.content-min-width, root.tabbar-preferred-width);
|
||||
preferred-height: root.content-min-height + root.tabbar-preferred-height;
|
||||
min-height: root.content-min-height + root.tabbar-preferred-height;
|
||||
}
|
||||
|
||||
export TabImpl := Rectangle {
|
||||
property<string> title <=> t.text;
|
||||
export component TabImpl inherits Rectangle {
|
||||
in-out property<string> title <=> t.text;
|
||||
//property<image> icon;
|
||||
property<bool> enabled: true;
|
||||
property<bool> has-focus: current-focused == tab-index;
|
||||
property<bool> pressed;
|
||||
property<int> current; // The currently selected tab
|
||||
property<int> current-focused; // The currently focused tab
|
||||
property<int> tab-index; // The index of this tab
|
||||
property<int> num-tabs; // The total number of tabs
|
||||
in-out property<bool> enabled: true;
|
||||
in-out property<bool> has-focus: root.current-focused == root.tab-index;
|
||||
in-out property<bool> pressed;
|
||||
in-out property<int> current; // The currently selected tab
|
||||
in-out property<int> current-focused; // The currently focused tab
|
||||
in-out property<int> tab-index; // The index of this tab
|
||||
in-out property<int> num-tabs; // The total number of tabs
|
||||
|
||||
min-height: t.preferred-height + 16px;
|
||||
preferred-width: t.preferred-width + 16px;
|
||||
|
||||
background: !enabled ? Palette.neutralLighter
|
||||
background: !root.enabled ? Palette.neutralLighter
|
||||
: touch.pressed ? Palette.neutralLight
|
||||
: touch.has-hover ? Palette.neutralLighter
|
||||
: Palette.white;
|
||||
|
@ -377,12 +379,12 @@ export TabImpl := Rectangle {
|
|||
vertical-stretch: 0;
|
||||
|
||||
accessible-role: tab;
|
||||
accessible-label <=> title;
|
||||
accessible-label <=> root.title;
|
||||
|
||||
touch := TouchArea {
|
||||
enabled <=> root.enabled;
|
||||
clicked => {
|
||||
current = tab-index;
|
||||
root.current = root.tab-index;
|
||||
}
|
||||
}
|
||||
t := Text {
|
||||
|
@ -390,7 +392,7 @@ export TabImpl := Rectangle {
|
|||
height: parent.height;
|
||||
vertical-alignment: center;
|
||||
horizontal-alignment: center;
|
||||
color: !enabled ? Palette.neutralTertiary : Palette.neutralPrimary;
|
||||
color: !root.enabled ? Palette.neutralTertiary : Palette.neutralPrimary;
|
||||
font-weight: root.current == root.tab-index ? 600 : 500;
|
||||
}
|
||||
|
||||
|
@ -399,21 +401,21 @@ export TabImpl := Rectangle {
|
|||
width: touch.has-hover && root.current == root.tab-index ? parent.width : parent.width - 16px;
|
||||
animate width { duration: 250ms; easing: ease-out; }
|
||||
background: root.current == root.tab-index ? Palette.themeSecondary : transparent;
|
||||
y: parent.height - height;
|
||||
x: (parent.width - width) / 2;
|
||||
y: parent.height - self.height;
|
||||
x: (parent.width - self.width) / 2;
|
||||
}
|
||||
|
||||
Rectangle { // Focus Rectangle
|
||||
border-width: enabled && has-focus ? 1px : 0px;
|
||||
border-width: root.enabled && root.has-focus ? 1px : 0px;
|
||||
border-color: Palette.black;
|
||||
}
|
||||
}
|
||||
|
||||
export TabBarImpl := Rectangle {
|
||||
export component TabBarImpl inherits Rectangle {
|
||||
// injected properties:
|
||||
property<int> current; // The currently selected tab
|
||||
property<int> current-focused: fs.has-focus ? fs.focused-tab : -1; // The currently focused tab
|
||||
property<int> num-tabs; // The total number of tabs
|
||||
in-out property<int> current; // The currently selected tab
|
||||
in-out property<int> current-focused: fs.has-focus ? fs.focused-tab : -1; // The currently focused tab
|
||||
in-out property<int> num-tabs; // The total number of tabs
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: 8px;
|
||||
|
@ -422,23 +424,24 @@ export TabBarImpl := Rectangle {
|
|||
}
|
||||
|
||||
accessible-role: tab;
|
||||
accessible-delegate-focus: current-focused >= 0 ? current-focused : current;
|
||||
accessible-delegate-focus: root.current-focused >= 0 ? root.current-focused : root.current;
|
||||
|
||||
fs := FocusScope {
|
||||
x:0;
|
||||
width: 0px; // Do not react on clicks
|
||||
property<int> focused-tab: 0;
|
||||
|
||||
key-pressed(event) => {
|
||||
if (event.text == "\n") {
|
||||
current = current-focused;
|
||||
root.current = root.current-focused;
|
||||
return accept;
|
||||
}
|
||||
if (event.text == Key.LeftArrow) {
|
||||
focused-tab = Math.max(focused-tab - 1, 0);
|
||||
self.focused-tab = Math.max(self.focused-tab - 1, 0);
|
||||
return accept;
|
||||
}
|
||||
if (event.text == Key.RightArrow) {
|
||||
focused-tab = Math.min(focused-tab + 1, num-tabs - 1);
|
||||
self.focused-tab = Math.min(self.focused-tab + 1, root.num-tabs - 1);
|
||||
return accept;
|
||||
}
|
||||
return reject;
|
||||
|
@ -446,7 +449,7 @@ export TabBarImpl := Rectangle {
|
|||
|
||||
key-released(event) => {
|
||||
if (event.text == " ") {
|
||||
current = current-focused;
|
||||
root.current = root.current-focused;
|
||||
return accept;
|
||||
}
|
||||
return reject;
|
||||
|
@ -454,9 +457,9 @@ export TabBarImpl := Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
export TabWidget := TabWidget {}
|
||||
export component TabWidget inherits TabWidget {}
|
||||
|
||||
export LineEdit := Rectangle {
|
||||
export component LineEdit inherits Rectangle {
|
||||
in property <length> font-size <=> inner.font-size;
|
||||
in-out property <string> text <=> inner.text;
|
||||
in property <string> placeholder-text <=> inner.placeholder-text;
|
||||
|
@ -474,11 +477,11 @@ export LineEdit := Rectangle {
|
|||
vertical-stretch: 0;
|
||||
min-height: max(32px, l.min-height);
|
||||
|
||||
background: !enabled ? Palette.neutralLighter : Palette.white;
|
||||
background: !root.enabled ? Palette.neutralLighter : Palette.white;
|
||||
border-radius: 2px;
|
||||
border-width: !enabled ? 0px : has-focus ? 2px : 1px;
|
||||
border-color: !enabled ? Palette.neutralLighter
|
||||
: has-focus ? Palette.themeSecondary
|
||||
border-width: !root.enabled ? 0px : root.has-focus ? 2px : 1px;
|
||||
border-color: !root.enabled ? Palette.neutralLighter
|
||||
: root.has-focus ? Palette.themeSecondary
|
||||
: Palette.neutralPrimary;
|
||||
|
||||
l := HorizontalLayout {
|
||||
|
@ -487,19 +490,19 @@ export LineEdit := Rectangle {
|
|||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
inner := LineEditInner {
|
||||
placeholder-color: !enabled ? Palette.neutralTertiary : Palette.neutralSecondary;
|
||||
placeholder-color: !self.enabled ? Palette.neutralTertiary : Palette.neutralSecondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export ListView := ScrollView {
|
||||
export component ListView inherits ScrollView {
|
||||
@children
|
||||
}
|
||||
|
||||
StandardListViewBase := ListView {
|
||||
property<[StandardListViewItem]> model;
|
||||
property<int> current-item: -1;
|
||||
for item[idx] in model : Rectangle {
|
||||
component StandardListViewBase inherits ListView {
|
||||
in-out property<[StandardListViewItem]> model;
|
||||
in-out property<int> current-item: -1;
|
||||
for item[idx] in root.model : Rectangle {
|
||||
l := HorizontalLayout {
|
||||
padding: 8px;
|
||||
spacing: 0px;
|
||||
|
@ -513,19 +516,19 @@ StandardListViewBase := ListView {
|
|||
touch := TouchArea {
|
||||
width: parent.width;
|
||||
height: parent.height;
|
||||
clicked => { current-item = idx; }
|
||||
clicked => { root.current-item = idx; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export StandardListView := StandardListViewBase {
|
||||
export component StandardListView inherits StandardListViewBase {
|
||||
FocusScope {
|
||||
key-pressed(event) => {
|
||||
if (event.text == Key.UpArrow && current-item > 0) {
|
||||
current-item -= 1;
|
||||
if (event.text == Key.UpArrow && root.current-item > 0) {
|
||||
root.current-item -= 1;
|
||||
return accept;
|
||||
} else if (event.text == Key.DownArrow && current-item + 1 < model.length) {
|
||||
current-item += 1;
|
||||
} else if (event.text == Key.DownArrow && root.current-item + 1 < root.model.length) {
|
||||
root.current-item += 1;
|
||||
return accept;
|
||||
}
|
||||
reject
|
||||
|
@ -533,24 +536,24 @@ export StandardListView := StandardListViewBase {
|
|||
}
|
||||
}
|
||||
|
||||
export ComboBox := FocusScope {
|
||||
export component ComboBox inherits FocusScope {
|
||||
in property <[string]> model;
|
||||
in-out property <int> current-index : 0;
|
||||
in-out property <string> current-value: model[current-index];
|
||||
in-out property <string> current-value: root.model[root.current-index];
|
||||
//property <bool> is-open: false;
|
||||
callback selected(string);
|
||||
|
||||
accessible-role: combobox;
|
||||
accessible-value <=> current-value;
|
||||
accessible-value <=> root.current-value;
|
||||
|
||||
key-pressed(event) => {
|
||||
if (event.text == Key.UpArrow) {
|
||||
current-index = Math.max(current-index - 1, 0);
|
||||
current-value = model[current-index];
|
||||
root.current-index = Math.max(root.current-index - 1, 0);
|
||||
root.current-value = root.model[root.current-index];
|
||||
return accept;
|
||||
} else if (event.text == Key.DownArrow) {
|
||||
current-index = Math.min(current-index + 1, model.length - 1);
|
||||
current-value = model[current-index];
|
||||
root.current-index = Math.min(root.current-index + 1, root.model.length - 1);
|
||||
root.current-value = root.model[root.current-index];
|
||||
return accept;
|
||||
// PopupWindow can not get hidden again at this time, so do not allow to pop that up.
|
||||
// } else if (event.text == Key.Return) {
|
||||
|
@ -561,11 +564,11 @@ export ComboBox := FocusScope {
|
|||
}
|
||||
|
||||
Rectangle {
|
||||
background: !enabled ? Palette.neutralLighter : Palette.white;
|
||||
background: !root.enabled ? Palette.neutralLighter : Palette.white;
|
||||
border-radius: 2px;
|
||||
border-width: !enabled ? 0px : has-focus ? 3px : 1px;
|
||||
border-color: !enabled ? Palette.neutralLighter
|
||||
: has-focus ? Palette.themeSecondary
|
||||
border-width: !root.enabled ? 0px : root.has-focus ? 3px : 1px;
|
||||
border-color: !root.enabled ? Palette.neutralLighter
|
||||
: root.has-focus ? Palette.themeSecondary
|
||||
: Palette.neutralPrimary;
|
||||
}
|
||||
|
||||
|
@ -586,7 +589,7 @@ export ComboBox := FocusScope {
|
|||
horizontal-alignment: left;
|
||||
vertical-alignment: center;
|
||||
horizontal-stretch: 1;
|
||||
color: !enabled ? Palette.neutralTertiary
|
||||
color: !root.enabled ? Palette.neutralTertiary
|
||||
: root.has-focus || touch.has-hover ? Palette.neutralPrimary
|
||||
: Palette.neutralSecondary;
|
||||
min-width: 0;
|
||||
|
@ -594,8 +597,8 @@ export ComboBox := FocusScope {
|
|||
Rectangle {
|
||||
width: 25px;
|
||||
Path {
|
||||
x: (parent.width - width) / 2;
|
||||
y: (parent.height - height) / 2;
|
||||
x: (parent.width - self.width) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
height: 8px;
|
||||
width: 25px;
|
||||
commands: "M.22.4.5.64.78.4.74.36.5.6.26.36z";
|
||||
|
@ -614,6 +617,7 @@ export ComboBox := FocusScope {
|
|||
}
|
||||
|
||||
popup := PopupWindow {
|
||||
x:0;
|
||||
y: root.height;
|
||||
width: root.width;
|
||||
Rectangle {
|
||||
|
@ -649,15 +653,15 @@ export ComboBox := FocusScope {
|
|||
}
|
||||
}
|
||||
|
||||
export VerticalBox := VerticalLayout {
|
||||
export component VerticalBox inherits VerticalLayout {
|
||||
spacing: StyleMetrics.layout-spacing;
|
||||
padding: StyleMetrics.layout-padding;
|
||||
}
|
||||
export HorizontalBox := HorizontalLayout {
|
||||
export component HorizontalBox inherits HorizontalLayout {
|
||||
spacing: StyleMetrics.layout-spacing;
|
||||
padding: StyleMetrics.layout-padding;
|
||||
}
|
||||
export GridBox := GridLayout {
|
||||
export component GridBox inherits GridLayout {
|
||||
spacing: StyleMetrics.layout-spacing;
|
||||
padding: StyleMetrics.layout-padding;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint-ui.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial
|
||||
|
||||
export global ColorSchemeSelector := {
|
||||
property<bool> dark-color-scheme: true;
|
||||
export global ColorSchemeSelector {
|
||||
in-out property<bool> dark-color-scheme: true;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint-ui.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial
|
||||
|
||||
export global ColorSchemeSelector := {
|
||||
property<bool> dark-color-scheme: false;
|
||||
export global ColorSchemeSelector {
|
||||
in-out property<bool> dark-color-scheme: false;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint-ui.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial
|
||||
|
||||
export global ColorSchemeSelector := {
|
||||
property<bool> dark-color-scheme: SlintInternal.dark-color-scheme;
|
||||
export global ColorSchemeSelector {
|
||||
in-out property<bool> dark-color-scheme: SlintInternal.dark-color-scheme;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import { md } from "md.slint";
|
||||
|
||||
export Ripple := Rectangle {
|
||||
export component Ripple inherits Rectangle {
|
||||
in property<length> ripple-x;
|
||||
in property<length> ripple-y;
|
||||
in property<bool> active;
|
||||
|
@ -11,27 +11,26 @@ export Ripple := Rectangle {
|
|||
in property<brush> ripple-color <=> circle.background;
|
||||
|
||||
circle := Rectangle {
|
||||
x: root.ripple-x - width / 2;
|
||||
y: root.ripple-y - width / 2;
|
||||
height: width;
|
||||
border-radius: width / 2;
|
||||
x: root.ripple-x - self.width / 2;
|
||||
y: root.ripple-y - self.width / 2;
|
||||
height: self.width;
|
||||
border-radius: self.width / 2;
|
||||
}
|
||||
|
||||
states [
|
||||
active when root.active && root.has-effect: {
|
||||
circle.width: root.width * 2 * 1.4142;
|
||||
in {
|
||||
animate circle.width { duration: 2s; easing: ease-out; }
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
transitions [
|
||||
in active : {
|
||||
animate circle.width { duration: 2s; easing: ease-out; }
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
// A touch area that also represents a visual state.
|
||||
export StateLayer := TouchArea {
|
||||
export component StateLayer inherits TouchArea {
|
||||
in property<bool> focusable;
|
||||
in property<brush> selection-background;
|
||||
in property<brush> ripple-color;
|
||||
|
@ -63,6 +62,7 @@ export StateLayer := TouchArea {
|
|||
}
|
||||
|
||||
fs := FocusScope {
|
||||
x:0;
|
||||
width: 0px; // Do not react on clicks
|
||||
enabled: root.enabled && root.focusable;
|
||||
|
||||
|
@ -81,7 +81,7 @@ export StateLayer := TouchArea {
|
|||
}
|
||||
checked when root.checked: {
|
||||
ripple.opacity: 1.0;
|
||||
ripple.background: selection-background;
|
||||
ripple.background: root.selection-background;
|
||||
}
|
||||
hover when root.has-hover: {
|
||||
ripple.opacity: 0.08;
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
|
||||
import { StyleMetrics } from "std-widgets-impl.slint";
|
||||
|
||||
export VerticalBox := VerticalLayout {
|
||||
export component VerticalBox inherits VerticalLayout {
|
||||
spacing: StyleMetrics.layout-spacing;
|
||||
padding: StyleMetrics.layout-padding;
|
||||
}
|
||||
export HorizontalBox := HorizontalLayout {
|
||||
export component HorizontalBox inherits HorizontalLayout {
|
||||
spacing: StyleMetrics.layout-spacing;
|
||||
padding: StyleMetrics.layout-padding;
|
||||
}
|
||||
export GridBox := GridLayout {
|
||||
export component GridBox inherits GridLayout {
|
||||
spacing: StyleMetrics.layout-spacing;
|
||||
padding: StyleMetrics.layout-padding;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import { ColorSchemeSelector } from "color-scheme.slint";
|
||||
|
||||
// helper to create material design token like path md.sys.colors.
|
||||
struct Color := {
|
||||
struct Color {
|
||||
background: color,
|
||||
surface: color,
|
||||
surface-variant: color,
|
||||
|
@ -23,20 +23,20 @@ struct Color := {
|
|||
}
|
||||
|
||||
// typo settings
|
||||
struct Label := {
|
||||
struct Label {
|
||||
size: relative-font-size,
|
||||
weight: int
|
||||
}
|
||||
|
||||
// helper to create material design token like path md.sys.elevation.
|
||||
struct Elevation := {
|
||||
struct Elevation {
|
||||
level0: length,
|
||||
level1: length,
|
||||
level2: length
|
||||
}
|
||||
|
||||
// helper to create material design token like path md.sys.typescale.
|
||||
struct Typescale := {
|
||||
struct Typescale {
|
||||
label-large: Label,
|
||||
label-medium: Label,
|
||||
body-large: Label,
|
||||
|
@ -45,33 +45,33 @@ struct Typescale := {
|
|||
}
|
||||
|
||||
// helper to create material design token like path md.sys.
|
||||
struct Sys := {
|
||||
struct Sys {
|
||||
color: Color,
|
||||
elevation: Elevation,
|
||||
typescale: Typescale
|
||||
}
|
||||
|
||||
// Material Desigin v3 style defintions.
|
||||
export global md := {
|
||||
property<bool> dark-color-scheme: ColorSchemeSelector.dark-color-scheme;
|
||||
export global md {
|
||||
in-out property<bool> dark-color-scheme: ColorSchemeSelector.dark-color-scheme;
|
||||
|
||||
property<Sys> sys: {
|
||||
in-out property<Sys> sys: {
|
||||
color: {
|
||||
background: !dark-color-scheme ? #FFFBFE : #1C1B1F,
|
||||
surface: !dark-color-scheme ? #FFFBFE : #1C1B1F,
|
||||
surface-variant: !dark-color-scheme ? #E7E0EC.darker(0.2) : #49454F,
|
||||
on-surface: !dark-color-scheme ? #1C1B1F : #E6E1E5,
|
||||
on-surface-variant: !dark-color-scheme ? #49454E : #CAC4D0,
|
||||
surface-tint: !dark-color-scheme ? #6750A4 : #D0BCFF,
|
||||
primary: !dark-color-scheme ? #6750A4 : #D0BCFF,
|
||||
primary-ripple: !dark-color-scheme ? #D0BCFF : #6750A4,
|
||||
on-primary: !dark-color-scheme ? #FFFFFF : #371E73,
|
||||
background: !root.dark-color-scheme ? #FFFBFE : #1C1B1F,
|
||||
surface: !root.dark-color-scheme ? #FFFBFE : #1C1B1F,
|
||||
surface-variant: !root.dark-color-scheme ? #E7E0EC.darker(0.2) : #49454F,
|
||||
on-surface: !root.dark-color-scheme ? #1C1B1F : #E6E1E5,
|
||||
on-surface-variant: !root.dark-color-scheme ? #49454E : #CAC4D0,
|
||||
surface-tint: !root.dark-color-scheme ? #6750A4 : #D0BCFF,
|
||||
primary: !root.dark-color-scheme ? #6750A4 : #D0BCFF,
|
||||
primary-ripple: !root.dark-color-scheme ? #D0BCFF : #6750A4,
|
||||
on-primary: !root.dark-color-scheme ? #FFFFFF : #371E73,
|
||||
shadow: #000000,
|
||||
outline: !dark-color-scheme ? #79747E : #938F99,
|
||||
outline-variant: !dark-color-scheme ? #C4C7C5 : #444746,
|
||||
secondary-container: !dark-color-scheme ? #E8DEF8 : #4A4458,
|
||||
on-secondary-container: !dark-color-scheme ? #1E192B : #E8DEF8,
|
||||
secondary-ripple: !dark-color-scheme ? #fffc : #000000,
|
||||
outline: !root.dark-color-scheme ? #79747E : #938F99,
|
||||
outline-variant: !root.dark-color-scheme ? #C4C7C5 : #444746,
|
||||
secondary-container: !root.dark-color-scheme ? #E8DEF8 : #4A4458,
|
||||
on-secondary-container: !root.dark-color-scheme ? #1E192B : #E8DEF8,
|
||||
secondary-ripple: !root.dark-color-scheme ? #fffc : #000000,
|
||||
},
|
||||
|
||||
elevation: {
|
||||
|
|
|
@ -9,19 +9,19 @@ import { md } from "md.slint";
|
|||
|
||||
export { Button, CheckBox, ScrollView }
|
||||
|
||||
export global StyleMetrics := {
|
||||
property<length> layout-spacing: 8px;
|
||||
property<length> layout-padding: 8px;
|
||||
property<length> text-cursor-width: 2px;
|
||||
export global StyleMetrics {
|
||||
in-out property<length> layout-spacing: 8px;
|
||||
in-out property<length> layout-padding: 8px;
|
||||
in-out property<length> text-cursor-width: 2px;
|
||||
|
||||
property<color> default-text-color: md.sys.color.on-surface;
|
||||
property<brush> textedit-background: transparent;
|
||||
property<color> textedit-text-color: md.sys.color.on-surface;
|
||||
property<brush> textedit-background-disabled: transparent;
|
||||
property<color> textedit-text-color-disabled: md.sys.color.on-surface;
|
||||
property<bool> dark-color-scheme: md.dark-color-scheme;
|
||||
in-out property<color> default-text-color: md.sys.color.on-surface;
|
||||
in-out property<brush> textedit-background: transparent;
|
||||
in-out property<color> textedit-text-color: md.sys.color.on-surface;
|
||||
in-out property<brush> textedit-background-disabled: transparent;
|
||||
in-out property<color> textedit-text-color-disabled: md.sys.color.on-surface;
|
||||
in-out property<bool> dark-color-scheme: md.dark-color-scheme;
|
||||
|
||||
property <string> default-font-family: "Roboto";
|
||||
in-out property <string> default-font-family: "Roboto";
|
||||
|
||||
property<brush> window-background: md.sys.color.background;
|
||||
in-out property<brush> window-background: md.sys.color.background;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import { StateLayer } from "comp-state-layer.slint";
|
|||
import { md } from "md.slint";
|
||||
|
||||
// Default button widget with Material Design Filled Button look and feel.
|
||||
export Button := Rectangle {
|
||||
export component Button inherits Rectangle {
|
||||
callback clicked;
|
||||
|
||||
in-out property<string> text <=> label.text;
|
||||
|
@ -54,8 +54,8 @@ export Button := Rectangle {
|
|||
padding-right: 24px;
|
||||
spacing: 8px;
|
||||
|
||||
if (icon.width > 0 && icon.height > 0): Image {
|
||||
source <=> icon;
|
||||
if (root.icon.width > 0 && root.icon.height > 0): Image {
|
||||
source <=> root.icon;
|
||||
width: 24px;
|
||||
opacity: label.opacity;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import { md } from "md.slint";
|
||||
|
||||
// Selection control that can be toggled between checked und unchecked by click.
|
||||
export CheckBox := Rectangle {
|
||||
export component CheckBox inherits Rectangle {
|
||||
callback toggled;
|
||||
|
||||
in property <string> text <=> label.text;
|
||||
|
@ -16,7 +16,7 @@ export CheckBox := Rectangle {
|
|||
|
||||
accessible-label <=> label.text;
|
||||
accessible-checkable: true;
|
||||
accessible-checked <=> checked;
|
||||
accessible-checked <=> root.checked;
|
||||
accessible-role: checkbox;
|
||||
|
||||
layout := HorizontalLayout {
|
||||
|
@ -37,19 +37,19 @@ export CheckBox := Rectangle {
|
|||
state-layer := Rectangle {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
x: (parent.width - width) / 2;
|
||||
y: (parent.height - height) / 2;
|
||||
x: (parent.width - self.width) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
opacity: 0;
|
||||
background: md.sys.color.primary;
|
||||
border-radius: 20px;
|
||||
animate opacity { duration: 300ms; easing: ease; }
|
||||
}
|
||||
|
||||
if (checked) : Path {
|
||||
if (root.checked) : Path {
|
||||
width: 66%;
|
||||
height: 66%;
|
||||
x: (parent.width - width) / 2;
|
||||
y: (parent.height - height) / 2;
|
||||
x: (parent.width - self.width) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
commands: "M18.9 35.7 7.7 24.5l2.15-2.15 9.05 9.05 19.2-19.2 2.15 2.15Z";
|
||||
fill: md.sys.color.on-primary;
|
||||
|
||||
|
@ -88,6 +88,7 @@ export CheckBox := Rectangle {
|
|||
}
|
||||
|
||||
fs := FocusScope {
|
||||
x:0;
|
||||
width: 0px; // Do not react on clicks
|
||||
enabled <=> root.enabled;
|
||||
|
||||
|
@ -101,7 +102,7 @@ export CheckBox := Rectangle {
|
|||
}
|
||||
|
||||
states [
|
||||
disabled-selected when !enabled && checked : {
|
||||
disabled-selected when !root.enabled && root.checked : {
|
||||
container.border-width: 0px;
|
||||
container.border-color: transparent;
|
||||
container.background: md.sys.color.primary;
|
||||
|
@ -109,7 +110,7 @@ export CheckBox := Rectangle {
|
|||
label.opacity: 0.38;
|
||||
label.color: md.sys.color.primary;
|
||||
}
|
||||
disabled when !enabled : {
|
||||
disabled when !root.enabled : {
|
||||
container.opacity: 0.38;
|
||||
label.opacity: 0.38;
|
||||
label.color: md.sys.color.primary;
|
||||
|
@ -117,32 +118,32 @@ export CheckBox := Rectangle {
|
|||
pressed when touch.pressed && !root.checked : {
|
||||
state-layer.opacity: 0.12;
|
||||
}
|
||||
pressed-selected when touch.pressed && checked : {
|
||||
pressed-selected when touch.pressed && root.checked : {
|
||||
state-layer.opacity: 0.12;
|
||||
state-layer.background: md.sys.color.on-surface;
|
||||
container.border-width: 0px;
|
||||
container.border-color: transparent;
|
||||
container.background: md.sys.color.primary;
|
||||
}
|
||||
hover-selected when touch.has-hover && checked : {
|
||||
hover-selected when touch.has-hover && root.checked : {
|
||||
state-layer.opacity: 0.08;
|
||||
container.border-width: 0px;
|
||||
container.border-color: transparent;
|
||||
container.background: md.sys.color.primary;
|
||||
}
|
||||
hover when touch.has-hover && !checked : {
|
||||
hover when touch.has-hover && !root.checked : {
|
||||
state-layer.background: md.sys.color.on-surface;
|
||||
state-layer.opacity: 0.08;
|
||||
}
|
||||
selected when !touch.has-hover && checked : {
|
||||
selected when !touch.has-hover && root.checked : {
|
||||
container.border-width: 0px;
|
||||
container.border-color: transparent;
|
||||
container.background: md.sys.color.primary;
|
||||
}
|
||||
focused-selected when fs.has-focus && checked : {
|
||||
focused-selected when fs.has-focus && root.checked : {
|
||||
state-layer.opacity: 0.12;
|
||||
}
|
||||
focused when fs.has-focus && !checked : {
|
||||
focused when fs.has-focus && !root.checked : {
|
||||
state-layer.background: md.sys.color.on-surface;
|
||||
state-layer.opacity: 0.12;
|
||||
}
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
import { md } from "md.slint";
|
||||
import { Item } from "widget-item.slint";
|
||||
|
||||
export ComboBox := FocusScope {
|
||||
export component ComboBox inherits FocusScope {
|
||||
in property <[string]> model;
|
||||
in-out property <int> current-index : 0;
|
||||
in-out property <string> current-value: model[current-index];
|
||||
in-out property <string> current-value: root.model[root.current-index];
|
||||
callback selected(string);
|
||||
|
||||
accessible-role: combobox;
|
||||
accessible-value <=> current-value;
|
||||
accessible-value <=> root.current-value;
|
||||
|
||||
horizontal-stretch: 1;
|
||||
vertical-stretch: 0;
|
||||
|
@ -46,7 +46,7 @@ export ComboBox := FocusScope {
|
|||
icon := Path {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
y: (parent.height - height) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
commands: "m24 30.75-12-12 2.15-2.15L24 26.5l9.85-9.85L36 18.8Z";
|
||||
fill: md.sys.color.on-surface;
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ export ComboBox := FocusScope {
|
|||
}
|
||||
|
||||
popup := PopupWindow {
|
||||
x:0;
|
||||
y: root.height;
|
||||
width: root.width;
|
||||
|
||||
|
@ -89,25 +90,25 @@ export ComboBox := FocusScope {
|
|||
|
||||
key-pressed(event) => {
|
||||
if (event.text == Key.UpArrow) {
|
||||
current-index = Math.max(current-index - 1, 0);
|
||||
current-value = model[current-index];
|
||||
root.current-index = Math.max(root.current-index - 1, 0);
|
||||
root.current-value = root.model[root.current-index];
|
||||
return accept;
|
||||
} else if (event.text == Key.DownArrow) {
|
||||
current-index = Math.min(current-index + 1, model.length - 1);
|
||||
current-value = model[current-index];
|
||||
root.current-index = Math.min(root.current-index + 1, root.model.length - 1);
|
||||
root.current-value = root.model[root.current-index];
|
||||
return accept;
|
||||
}
|
||||
return reject;
|
||||
}
|
||||
|
||||
states [
|
||||
disabled when !enabled : {
|
||||
disabled when !root.enabled : {
|
||||
container.border-color: md.sys.color.on-surface;
|
||||
container.opacity: 0.38;
|
||||
label.opacity: 0.38;
|
||||
icon.opacity: 0.38;
|
||||
}
|
||||
focused when has-focus : {
|
||||
focused when root.has-focus : {
|
||||
container.border-width: 2px;
|
||||
container.border-color: md.sys.color.primary;
|
||||
label.color: md.sys.color.primary;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import { md } from "md.slint";
|
||||
|
||||
// A container widget with a title.
|
||||
export GroupBox := Rectangle {
|
||||
export component GroupBox inherits Rectangle {
|
||||
in property <string> title <=> label.text;
|
||||
in property<bool> enabled: true;
|
||||
|
||||
|
@ -32,6 +32,7 @@ export GroupBox := Rectangle {
|
|||
}
|
||||
|
||||
label-container := Rectangle {
|
||||
y:0;
|
||||
x: 8px;
|
||||
width: label.width + 8px;
|
||||
height: label.height + 8px;
|
||||
|
@ -50,7 +51,7 @@ export GroupBox := Rectangle {
|
|||
}
|
||||
|
||||
states [
|
||||
disabled when !enabled : {
|
||||
disabled when !root.enabled : {
|
||||
container.border-color: md.sys.color.on-surface;
|
||||
container.opacity: 0.38;
|
||||
label.opacity: 0.38;
|
||||
|
|
|
@ -5,7 +5,7 @@ import { StateLayer } from "comp-state-layer.slint";
|
|||
import { md } from "md.slint";
|
||||
|
||||
// A selectable item that is used by `StandardListView` and `ComboBox`.
|
||||
export Item := Rectangle {
|
||||
export component Item inherits Rectangle {
|
||||
callback clicked <=> state-layer.clicked;
|
||||
|
||||
in property<bool> selected;
|
||||
|
@ -38,7 +38,7 @@ export Item := Rectangle {
|
|||
}
|
||||
|
||||
states [
|
||||
selected when selected : {
|
||||
selected when root.selected : {
|
||||
state-layer.background: md.sys.color.secondary-container;
|
||||
}
|
||||
]
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import { md } from "md.slint";
|
||||
|
||||
// Single line text input field with Material Design Outline TextField look and feel.
|
||||
export LineEdit := Rectangle {
|
||||
export component LineEdit inherits Rectangle {
|
||||
in property <length> font-size <=> input.font-size;
|
||||
in-out property <string> text <=> input.text;
|
||||
in property <string> placeholder-text <=> placeholder.text;
|
||||
|
@ -56,8 +56,8 @@ export LineEdit := Rectangle {
|
|||
property <length> computed_x;
|
||||
property <length> padding-outer: layout.padding-left + layout.padding-right;
|
||||
|
||||
x: min(0px, max(parent.width - width, computed_x));
|
||||
width: max(parent.width, preferred-width);
|
||||
x: min(0px, max(parent.width - self.width, self.computed_x));
|
||||
width: max(parent.width, self.preferred-width);
|
||||
height: 100%;
|
||||
color: md.sys.color.on-surface;
|
||||
vertical-alignment: center;
|
||||
|
@ -67,10 +67,10 @@ export LineEdit := Rectangle {
|
|||
accepted => { root.accepted(self.text); }
|
||||
edited => { root.edited(self.text); }
|
||||
cursor-position-changed(cpos) => {
|
||||
if (cpos.x + computed_x < padding-outer) {
|
||||
computed_x = - cpos.x + padding-outer;
|
||||
} else if (cpos.x + computed_x > parent.width - padding-outer) {
|
||||
computed_x = parent.width - cpos.x - padding-outer;
|
||||
if (cpos.x + self.computed_x < self.padding-outer) {
|
||||
self.computed_x = - cpos.x + self.padding-outer;
|
||||
} else if (cpos.x + self.computed_x > parent.width - self.padding-outer) {
|
||||
self.computed_x = parent.width - cpos.x - self.padding-outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,13 +78,13 @@ export LineEdit := Rectangle {
|
|||
}
|
||||
|
||||
states [
|
||||
disabled when !enabled : {
|
||||
disabled when !root.enabled : {
|
||||
container.border-color: md.sys.color.on-surface;
|
||||
container.opacity: 0.38;
|
||||
input.opacity: 0.38;
|
||||
placeholder.opacity: 0.38;
|
||||
}
|
||||
focused when has-focus : {
|
||||
focused when root.has-focus : {
|
||||
container.border-width: 2px;
|
||||
container.border-color: md.sys.color.primary;
|
||||
input.color: md.sys.color.primary;
|
||||
|
|
|
@ -6,30 +6,30 @@ import { ScrollView } from "widget-scrollview.slint";
|
|||
import { Item } from "widget-item.slint";
|
||||
|
||||
// `ListView` is like a `Scrollview` but it should have a for element, and the content are automatically layed out in a list.
|
||||
export ListView := ScrollView {
|
||||
export component ListView inherits ScrollView {
|
||||
@children
|
||||
}
|
||||
|
||||
StandardListViewBase := ListView {
|
||||
component StandardListViewBase inherits ListView {
|
||||
in property<[StandardListViewItem]> model;
|
||||
in-out property<int> current-item: -1;
|
||||
|
||||
for item[idx] in model : Item {
|
||||
for item[idx] in root.model : Item {
|
||||
selected: idx == root.current-item;
|
||||
text: item.text;
|
||||
clicked => { current-item = idx; }
|
||||
clicked => { root.current-item = idx; }
|
||||
}
|
||||
}
|
||||
|
||||
// Like `ListView`, but with a default delegate, and a `model` property which is a model of type `StandardListViewItem`.
|
||||
export StandardListView := StandardListViewBase {
|
||||
export component StandardListView inherits StandardListViewBase {
|
||||
FocusScope {
|
||||
key-pressed(event) => {
|
||||
if (event.text == Key.UpArrow && current-item > 0) {
|
||||
current-item -= 1;
|
||||
if (event.text == Key.UpArrow && root.current-item > 0) {
|
||||
root.current-item -= 1;
|
||||
return accept;
|
||||
} else if (event.text == Key.DownArrow && current-item + 1 < model.length) {
|
||||
current-item += 1;
|
||||
} else if (event.text == Key.DownArrow && root.current-item + 1 < root.model.length) {
|
||||
root.current-item += 1;
|
||||
return accept;
|
||||
}
|
||||
reject
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
|
||||
import { md } from "md.slint";
|
||||
|
||||
ScrollBar := Rectangle {
|
||||
property <bool> horizontal;
|
||||
property<length> maximum;
|
||||
property<length> page-size;
|
||||
component ScrollBar inherits Rectangle {
|
||||
in-out property <bool> horizontal;
|
||||
in-out property<length> maximum;
|
||||
in-out property<length> page-size;
|
||||
// this is always negative and bigger than -maximum
|
||||
property<length> value;
|
||||
property<bool> enabled <=> touch.enabled;
|
||||
in-out property<length> value;
|
||||
in-out property<bool> enabled <=> touch.enabled;
|
||||
|
||||
state_layer := Rectangle {
|
||||
width: 100%;
|
||||
|
@ -23,10 +23,10 @@ ScrollBar := Rectangle {
|
|||
}
|
||||
|
||||
handle := Rectangle {
|
||||
x: !horizontal ? 0phx : (root.width - handle.width) * (-value / maximum);
|
||||
y: horizontal ? 0phx : (root.height - handle.height) * (-value / maximum);
|
||||
width: !horizontal ? parent.width : maximum <= 0phx ? 0phx : parent.width * (page-size / (maximum + page-size));
|
||||
height: horizontal ? parent.height : maximum <= 0phx ? 0phx : parent.height * (page-size / (maximum + page-size));
|
||||
x: !root.horizontal ? 0phx : (root.width - handle.width) * (-root.value / root.maximum);
|
||||
y: root.horizontal ? 0phx : (root.height - handle.height) * (-root.value / root.maximum);
|
||||
width: !root.horizontal ? parent.width : root.maximum <= 0phx ? 0phx : parent.width * (root.page-size / (root.maximum + root.page-size));
|
||||
height: root.horizontal ? parent.height : root.maximum <= 0phx ? 0phx : parent.height * (root.page-size / (root.maximum + root.page-size));
|
||||
|
||||
container := Rectangle {
|
||||
width: 100%;
|
||||
|
@ -45,14 +45,14 @@ ScrollBar := Rectangle {
|
|||
|
||||
pointer-event(event) => {
|
||||
if (event.button == PointerEventButton.left && event.kind == PointerEventKind.down) {
|
||||
pressed-value = -root.value;
|
||||
self.pressed-value = -root.value;
|
||||
}
|
||||
}
|
||||
moved => {
|
||||
if (enabled && pressed) {
|
||||
value = -max(0px, min(root.maximum, pressed-value + (
|
||||
horizontal ? (touch.mouse-x - touch.pressed-x) * (maximum / (root.width - handle.width))
|
||||
: (touch.mouse-y - touch.pressed-y) * (maximum / (root.height - handle.height))
|
||||
if (self.enabled && self.pressed) {
|
||||
root.value = -max(0px, min(root.maximum, self.pressed-value + (
|
||||
root.horizontal ? (touch.mouse-x - touch.pressed-x) * (root.maximum / (root.width - handle.width))
|
||||
: (touch.mouse-y - touch.pressed-y) * (root.maximum / (root.height - handle.height))
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ ScrollBar := Rectangle {
|
|||
}
|
||||
|
||||
// Scrollview contains a viewport that is bigger than the view and can be scrolled.
|
||||
export ScrollView := Rectangle {
|
||||
export component ScrollView inherits Rectangle {
|
||||
in-out property <length> viewport-width <=> fli.viewport-width;
|
||||
in-out property <length> viewport-height <=> fli.viewport-height;
|
||||
in-out property <length> viewport-x <=> fli.viewport-x;
|
||||
|
@ -81,7 +81,7 @@ export ScrollView := Rectangle {
|
|||
out property <length> visible-width <=> fli.width;
|
||||
out property <length> visible-height <=> fli.height;
|
||||
in property <bool> enabled: true;
|
||||
property <bool> has-focus;
|
||||
in-out property <bool> has-focus;
|
||||
|
||||
background: md.sys.color.surface;
|
||||
min-height: 50px;
|
||||
|
@ -90,6 +90,7 @@ export ScrollView := Rectangle {
|
|||
vertical-stretch: 1;
|
||||
|
||||
fli := Flickable {
|
||||
x:0;y:0;
|
||||
interactive: false;
|
||||
viewport-y <=> vbar.value;
|
||||
viewport-x <=> hbar.value;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import { md } from "md.slint";
|
||||
|
||||
// Allows to select a value from a range of values.
|
||||
export Slider := Rectangle {
|
||||
export component Slider inherits Rectangle {
|
||||
in property<float> maximum: 100;
|
||||
in property<float> minimum: 0;
|
||||
in-out property<float> value;
|
||||
|
@ -16,15 +16,15 @@ export Slider := Rectangle {
|
|||
height: 20px;
|
||||
|
||||
accessible-role: slider;
|
||||
accessible-value: value;
|
||||
accessible-value-minimum: minimum;
|
||||
accessible-value-maximum: maximum;
|
||||
accessible-value-step: (maximum - minimum) / 100;
|
||||
accessible-value: root.value;
|
||||
accessible-value-minimum: root.minimum;
|
||||
accessible-value-maximum: root.maximum;
|
||||
accessible-value-step: (root.maximum - root.minimum) / 100;
|
||||
|
||||
container := Rectangle {
|
||||
background: md.sys.color.surface-variant;
|
||||
opacity: 0.38;
|
||||
y: (parent.height - height) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
border-radius: 2px;
|
||||
|
@ -33,7 +33,7 @@ export Slider := Rectangle {
|
|||
track := Rectangle {
|
||||
background: md.sys.color.primary;
|
||||
x: container.x;
|
||||
y: (parent.height - height) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
width: handle.x + (handle.width / 2);
|
||||
height: container.height;
|
||||
border-radius: container.border-radius;
|
||||
|
@ -42,21 +42,21 @@ export Slider := Rectangle {
|
|||
state-layer := Rectangle {
|
||||
opacity: 0;
|
||||
background: md.sys.color.primary;
|
||||
x: handle.x - (width - handle.width) / 2;
|
||||
y: (parent.height - height) / 2;
|
||||
x: handle.x - (self.width - handle.width) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: max(width, height) / 2;
|
||||
border-radius: max(self.width, self.height) / 2;
|
||||
animate opacity { duration: 250ms; easing: ease; }
|
||||
}
|
||||
|
||||
handle := Rectangle {
|
||||
background: md.sys.color.primary;
|
||||
x: (parent.width - handle.width) * (value - minimum) / (maximum - minimum);
|
||||
y: (parent.height - height) / 2;
|
||||
x: (parent.width - handle.width) * (root.value - root.minimum) / (root.maximum - root.minimum);
|
||||
y: (parent.height - self.height) / 2;
|
||||
width: root.height;
|
||||
height: root.height;
|
||||
border-radius: max(width, height) / 2;
|
||||
border-radius: max(self.width, self.height) / 2;
|
||||
drop-shadow-color: md.sys.color.shadow;
|
||||
drop-shadow-blur: md.sys.elevation.level1;
|
||||
drop-shadow-offset-y: 1px;
|
||||
|
@ -66,31 +66,32 @@ export Slider := Rectangle {
|
|||
|
||||
touch := TouchArea {
|
||||
property <float> pressed-value;
|
||||
property <bool> handle-hover: has-hover && mouse-x >= handle.x && mouse-x <= handle.x + handle.width
|
||||
&& mouse-y >= handle.y && mouse-y <= handle.y + handle.height;
|
||||
property <bool> handle-hover: self.has-hover && self.mouse-x >= handle.x && self.mouse-x <= handle.x + handle.width
|
||||
&& self.mouse-y >= handle.y && self.mouse-y <= handle.y + handle.height;
|
||||
pointer-event(event) => {
|
||||
if (event.button == PointerEventButton.left && event.kind == PointerEventKind.down) {
|
||||
pressed-value = root.value;
|
||||
self.pressed-value = root.value;
|
||||
}
|
||||
}
|
||||
moved => {
|
||||
if (enabled && pressed) {
|
||||
value = max(root.minimum, min(root.maximum,
|
||||
pressed-value + (touch.mouse-x - touch.pressed-x) * (maximum - minimum) / (root.width - handle.width)));
|
||||
root.changed(value);
|
||||
if (self.enabled && self.pressed) {
|
||||
root.value = max(root.minimum, min(root.maximum,
|
||||
self.pressed-value + (touch.mouse-x - touch.pressed-x) * (root.maximum - root.minimum) / (root.width - handle.width)));
|
||||
root.changed(root.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fs := FocusScope {
|
||||
x:0;
|
||||
width: 0px;
|
||||
|
||||
key-pressed(event) => {
|
||||
if (enabled && event.text == Key.RightArrow) {
|
||||
value = Math.min(value + 1, maximum);
|
||||
if (self.enabled && event.text == Key.RightArrow) {
|
||||
root.value = Math.min(root.value + 1, root.maximum);
|
||||
accept
|
||||
} else if (enabled && event.text == Key.LeftArrow) {
|
||||
value = Math.max(value - 1, minimum);
|
||||
} else if (self.enabled && event.text == Key.LeftArrow) {
|
||||
root.value = Math.max(root.value - 1, root.minimum);
|
||||
accept
|
||||
} else {
|
||||
reject
|
||||
|
@ -99,7 +100,7 @@ export Slider := Rectangle {
|
|||
}
|
||||
|
||||
states [
|
||||
disabled when !enabled : {
|
||||
disabled when !root.enabled : {
|
||||
handle.background: md.sys.color.on-surface;
|
||||
handle.drop-shadow-blur: md.sys.elevation.level0;
|
||||
track.background: md.sys.color.on-surface;
|
||||
|
|
|
@ -3,24 +3,25 @@
|
|||
|
||||
import { md } from "md.slint";
|
||||
|
||||
SpinBoxButton := Rectangle {
|
||||
component SpinBoxButton inherits Rectangle {
|
||||
callback clicked <=> touch.clicked;
|
||||
|
||||
property<bool> pressed: self.enabled && touch.pressed;
|
||||
property<bool> enabled <=> touch.enabled;
|
||||
property<float> icon-opacity: 1;
|
||||
property<brush> icon-fill: md.sys.color.on-primary;
|
||||
in-out property<bool> pressed: self.enabled && touch.pressed;
|
||||
in-out property<bool> enabled <=> touch.enabled;
|
||||
in-out property<float> icon-opacity: 1;
|
||||
in-out property<brush> icon-fill: md.sys.color.on-primary;
|
||||
|
||||
width: height;
|
||||
width: root.height;
|
||||
|
||||
container := Rectangle {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: max(width, height) / 2;
|
||||
border-radius: max(self.width, self.height) / 2;
|
||||
background: md.sys.color.primary;
|
||||
}
|
||||
|
||||
state-layer := Rectangle {
|
||||
x:0;y:0;
|
||||
opacity: 0;
|
||||
width: container.width;
|
||||
height: container.height;
|
||||
|
@ -54,8 +55,8 @@ SpinBoxButton := Rectangle {
|
|||
}
|
||||
|
||||
// Increment and decrement a value in the given range.
|
||||
export SpinBox := FocusScope {
|
||||
property <bool> checked;
|
||||
export component SpinBox inherits FocusScope {
|
||||
in-out property <bool> checked;
|
||||
in-out property <int> value;
|
||||
in property <int> minimum;
|
||||
in property <int> maximum: 100;
|
||||
|
@ -68,10 +69,10 @@ export SpinBox := FocusScope {
|
|||
height: 56px;
|
||||
|
||||
accessible-role: spinbox;
|
||||
accessible-value: value;
|
||||
accessible-value-minimum: minimum;
|
||||
accessible-value-maximum: maximum;
|
||||
accessible-value-step: (maximum - minimum) / 100;
|
||||
accessible-value: root.value;
|
||||
accessible-value-minimum: root.minimum;
|
||||
accessible-value-maximum: root.maximum;
|
||||
accessible-value-step: (root.maximum - root.minimum) / 100;
|
||||
|
||||
container := Rectangle {
|
||||
width: 100%;
|
||||
|
@ -89,7 +90,7 @@ export SpinBox := FocusScope {
|
|||
spacing: 16px;
|
||||
|
||||
label := Text {
|
||||
text: value;
|
||||
text: root.value;
|
||||
height: 100%;
|
||||
color: md.sys.color.on-surface;
|
||||
vertical-alignment: center;
|
||||
|
@ -105,8 +106,8 @@ export SpinBox := FocusScope {
|
|||
enabled: root.enabled;
|
||||
|
||||
Path {
|
||||
x: (parent.width - width) / 2;
|
||||
y: (parent.height - height) / 2;
|
||||
x: (parent.width - self.width) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
width: 44%;
|
||||
height: 44%;
|
||||
commands: "M14.15 30.75 12 28.6l12-12 12 11.95-2.15 2.15L24 20.85Z";
|
||||
|
@ -127,8 +128,8 @@ export SpinBox := FocusScope {
|
|||
enabled: root.enabled;
|
||||
|
||||
Path {
|
||||
x: (parent.width - width) / 2;
|
||||
y: (parent.height - height) / 2;
|
||||
x: (parent.width - self.width) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
width: 44%;
|
||||
height: 44%;
|
||||
commands: "m24 30.75-12-12 2.15-2.15L24 26.5l9.85-9.85L36 18.8Z";
|
||||
|
@ -149,11 +150,11 @@ export SpinBox := FocusScope {
|
|||
}
|
||||
|
||||
key-pressed(event) => {
|
||||
if (enabled && event.text == Key.UpArrow && value < maximum) {
|
||||
value += 1;
|
||||
if (root.enabled && event.text == Key.UpArrow && root.value < root.maximum) {
|
||||
root.value += 1;
|
||||
accept
|
||||
} else if (enabled && event.text == Key.DownArrow && value > minimum) {
|
||||
value -= 1;
|
||||
} else if (root.enabled && event.text == Key.DownArrow && root.value > root.minimum) {
|
||||
root.value -= 1;
|
||||
accept
|
||||
} else {
|
||||
reject
|
||||
|
@ -161,12 +162,12 @@ export SpinBox := FocusScope {
|
|||
}
|
||||
|
||||
states [
|
||||
disabled when !enabled : {
|
||||
disabled when !root.enabled : {
|
||||
container.border-color: md.sys.color.on-surface;
|
||||
container.opacity: 0.38;
|
||||
label.opacity: 0.38;
|
||||
}
|
||||
focused when has-focus : {
|
||||
focused when root.has-focus : {
|
||||
container.border-width: 2px;
|
||||
container.border-color: md.sys.color.primary;
|
||||
label.color: md.sys.color.primary;
|
||||
|
|
|
@ -4,43 +4,43 @@
|
|||
|
||||
import { md } from "md.slint";
|
||||
|
||||
export TabWidgetImpl := Rectangle {
|
||||
property <length> content-x: 0;
|
||||
property <length> content-y: tabbar-preferred-height;
|
||||
property <length> content-height: height - tabbar-preferred-height;
|
||||
property <length> content-width: width;
|
||||
property <length> tabbar-x: 0;
|
||||
property <length> tabbar-y: 0;
|
||||
property <length> tabbar-height: tabbar-preferred-height;
|
||||
property <length> tabbar-width: width;
|
||||
export component TabWidgetImpl inherits Rectangle {
|
||||
in-out property <length> content-x: 0;
|
||||
in-out property <length> content-y: root.tabbar-preferred-height;
|
||||
in-out property <length> content-height: root.height - root.tabbar-preferred-height;
|
||||
in-out property <length> content-width: root.width;
|
||||
in-out property <length> tabbar-x: 0;
|
||||
in-out property <length> tabbar-y: 0;
|
||||
in-out property <length> tabbar-height: root.tabbar-preferred-height;
|
||||
in-out property <length> tabbar-width: root.width;
|
||||
|
||||
property <length> tabbar-preferred-height;
|
||||
property <length> tabbar-preferred-width;
|
||||
property <length> content-min-height;
|
||||
property <length> content-min-width;
|
||||
property <int> current-index;
|
||||
property <int> current-focused;
|
||||
in-out property <length> tabbar-preferred-height;
|
||||
in-out property <length> tabbar-preferred-width;
|
||||
in-out property <length> content-min-height;
|
||||
in-out property <length> content-min-width;
|
||||
in-out property <int> current-index;
|
||||
in-out property <int> current-focused;
|
||||
|
||||
preferred-width: content-min-width;
|
||||
min-width: max(content-min-width, tabbar-preferred-width);
|
||||
preferred-height: content-min-height + tabbar-preferred-height;
|
||||
min-height: content-min-height + tabbar-preferred-height;
|
||||
preferred-width: root.content-min-width;
|
||||
min-width: max(root.content-min-width, root.tabbar-preferred-width);
|
||||
preferred-height: root.content-min-height + root.tabbar-preferred-height;
|
||||
min-height: root.content-min-height + root.tabbar-preferred-height;
|
||||
}
|
||||
|
||||
export TabImpl := Rectangle {
|
||||
property<string> title <=> label.text;
|
||||
property<bool> enabled: true;
|
||||
property<bool> has-focus: current-focused == tab-index;
|
||||
property<bool> active: tab-index == current;
|
||||
property<bool> pressed;
|
||||
property<int> current; // The currently selected tab
|
||||
property<int> current-focused; // The currently focused tab
|
||||
property<int> tab-index; // The index of this tab
|
||||
property<int> num-tabs; // The total number of tabs
|
||||
export component TabImpl inherits Rectangle {
|
||||
in-out property<string> title <=> label.text;
|
||||
in-out property<bool> enabled: true;
|
||||
in-out property<bool> has-focus: root.current-focused == root.tab-index;
|
||||
in-out property<bool> active: root.tab-index == root.current;
|
||||
in-out property<bool> pressed;
|
||||
in-out property<int> current; // The currently selected tab
|
||||
in-out property<int> current-focused; // The currently focused tab
|
||||
in-out property<int> tab-index; // The index of this tab
|
||||
in-out property<int> num-tabs; // The total number of tabs
|
||||
|
||||
height: 48px;
|
||||
accessible-role: tab;
|
||||
accessible-label <=> title;
|
||||
accessible-label <=> root.title;
|
||||
|
||||
container := Rectangle {
|
||||
background: md.sys.color.surface;
|
||||
|
@ -61,7 +61,7 @@ export TabImpl := Rectangle {
|
|||
|
||||
label := Text {
|
||||
vertical-alignment: center;
|
||||
color: !active ? md.sys.color.on-surface : md.sys.color.primary;
|
||||
color: !root.active ? md.sys.color.on-surface : md.sys.color.primary;
|
||||
// FIXME after Roboto font can be loaded
|
||||
//font-family: md.sys.typescale.title-small.font;
|
||||
font-size: md.sys.typescale.title-small.size;
|
||||
|
@ -72,10 +72,10 @@ export TabImpl := Rectangle {
|
|||
}
|
||||
|
||||
indicator := Rectangle {
|
||||
opacity: !active ? 0 : 1;
|
||||
opacity: !root.active ? 0 : 1;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
y: parent.height - height;
|
||||
y: parent.height - self.height;
|
||||
background: md.sys.color.primary;
|
||||
|
||||
animate opacity { duration: 250ms; easing: ease; }
|
||||
|
@ -84,16 +84,16 @@ export TabImpl := Rectangle {
|
|||
touch := TouchArea {
|
||||
enabled <=> root.enabled;
|
||||
clicked => {
|
||||
current = tab-index;
|
||||
root.current = root.tab-index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export TabBarImpl := Rectangle {
|
||||
export component TabBarImpl inherits Rectangle {
|
||||
// injected properties:
|
||||
property<int> current; // The currently selected tab
|
||||
property<int> current-focused: fs.has-focus ? fs.focused-tab : -1; // The currently focused tab
|
||||
property<int> num-tabs; // The total number of tabs
|
||||
in-out property<int> current; // The currently selected tab
|
||||
in-out property<int> current-focused: fs.has-focus ? fs.focused-tab : -1; // The currently focused tab
|
||||
in-out property<int> num-tabs; // The total number of tabs
|
||||
|
||||
HorizontalLayout {
|
||||
alignment: start;
|
||||
|
@ -101,23 +101,24 @@ export TabBarImpl := Rectangle {
|
|||
}
|
||||
|
||||
accessible-role: tab;
|
||||
accessible-delegate-focus: current-focused >= 0 ? current-focused : current;
|
||||
accessible-delegate-focus: root.current-focused >= 0 ? root.current-focused : root.current;
|
||||
|
||||
fs := FocusScope {
|
||||
x:0;
|
||||
width: 0px; // Do not react on clicks
|
||||
property<int> focused-tab: 0;
|
||||
|
||||
key-pressed(event) => {
|
||||
if (event.text == "\n") {
|
||||
current = current-focused;
|
||||
root.current = root.current-focused;
|
||||
return accept;
|
||||
}
|
||||
if (event.text == Key.LeftArrow) {
|
||||
focused-tab = Math.max(focused-tab - 1, 0);
|
||||
self.focused-tab = Math.max(self.focused-tab - 1, 0);
|
||||
return accept;
|
||||
}
|
||||
if (event.text == Key.RightArrow) {
|
||||
focused-tab = Math.min(focused-tab + 1, num-tabs - 1);
|
||||
self.focused-tab = Math.min(self.focused-tab + 1, root.num-tabs - 1);
|
||||
return accept;
|
||||
}
|
||||
return reject;
|
||||
|
@ -125,7 +126,7 @@ export TabBarImpl := Rectangle {
|
|||
|
||||
key-released(event) => {
|
||||
if (event.text == " ") {
|
||||
current = current-focused;
|
||||
root.current = root.current-focused;
|
||||
return accept;
|
||||
}
|
||||
return reject;
|
||||
|
@ -134,4 +135,4 @@ export TabBarImpl := Rectangle {
|
|||
}
|
||||
|
||||
|
||||
export TabWidget := TabWidget {}
|
||||
export component TabWidget inherits TabWidget {}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint-ui.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial
|
||||
|
||||
export global ColorSchemeSelector := {
|
||||
property<bool> dark-color-scheme: true;
|
||||
export global ColorSchemeSelector {
|
||||
in-out property<bool> dark-color-scheme: true;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint-ui.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial
|
||||
|
||||
export global ColorSchemeSelector := {
|
||||
property<bool> dark-color-scheme: false;
|
||||
export global ColorSchemeSelector {
|
||||
in-out property<bool> dark-color-scheme: false;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint-ui.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial
|
||||
|
||||
export global ColorSchemeSelector := {
|
||||
property<bool> dark-color-scheme: SlintInternal.dark-color-scheme;
|
||||
export global ColorSchemeSelector {
|
||||
in-out property<bool> dark-color-scheme: SlintInternal.dark-color-scheme;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
export { NativeStyleMetrics as StyleMetrics }
|
||||
|
||||
export ScrollView := NativeScrollView {
|
||||
export component ScrollView inherits NativeScrollView {
|
||||
in-out property <length> viewport-width <=> fli.viewport-width;
|
||||
in-out property <length> viewport-height <=> fli.viewport-height;
|
||||
in-out property <length> viewport-x <=> fli.viewport-x;
|
||||
|
|
|
@ -8,55 +8,56 @@ import { StyleMetrics, ScrollView } from "std-widgets-impl.slint";
|
|||
export { StyleMetrics, ScrollView, TextEdit, AboutSlint, AboutSlint as AboutSixtyFPS }
|
||||
|
||||
// FIXME: the font-size should be removed but is required right now to compile the printer-demo
|
||||
export Button := NativeButton {
|
||||
export component Button inherits NativeButton {
|
||||
// FIXME: remove
|
||||
property<length> font-size;
|
||||
accessible-checkable <=> checkable;
|
||||
accessible-checked <=> checked;
|
||||
accessible-label <=> text;
|
||||
in-out property<length> font-size;
|
||||
accessible-checkable <=> root.checkable;
|
||||
accessible-checked <=> root.checked;
|
||||
accessible-label <=> root.text;
|
||||
accessible-role: button;
|
||||
checkable: false;
|
||||
enabled: true;
|
||||
}
|
||||
|
||||
export StandardButton := NativeButton {
|
||||
export component StandardButton inherits NativeButton {
|
||||
in property<StandardButtonKind> kind <=> self.standard-button-kind;
|
||||
accessible-checkable <=> checkable;
|
||||
accessible-checked <=> checked;
|
||||
accessible-label <=> text;
|
||||
accessible-checkable <=> root.checkable;
|
||||
accessible-checked <=> root.checked;
|
||||
accessible-label <=> root.text;
|
||||
accessible-role: button;
|
||||
is-standard-button: true;
|
||||
checkable: false;
|
||||
}
|
||||
|
||||
export CheckBox := NativeCheckBox {
|
||||
export component CheckBox inherits NativeCheckBox {
|
||||
accessible-checkable: true;
|
||||
accessible-checked <=> checked;
|
||||
accessible-label <=> text;
|
||||
accessible-checked <=> root.checked;
|
||||
accessible-label <=> root.text;
|
||||
accessible-role: checkbox;
|
||||
}
|
||||
export SpinBox := NativeSpinBox {
|
||||
export component SpinBox inherits NativeSpinBox {
|
||||
// FIXME: remove
|
||||
property<length> font-size;
|
||||
in-out property<length> font-size;
|
||||
|
||||
accessible-role: spinbox;
|
||||
accessible-value: value;
|
||||
accessible-value-minimum: minimum;
|
||||
accessible-value-maximum: maximum;
|
||||
accessible-value-step: (maximum - minimum) / 100;
|
||||
accessible-value: root.value;
|
||||
accessible-value-minimum: root.minimum;
|
||||
accessible-value-maximum: root.maximum;
|
||||
accessible-value-step: (root.maximum - root.minimum) / 100;
|
||||
|
||||
}
|
||||
|
||||
export Slider := NativeSlider {
|
||||
export component Slider inherits NativeSlider {
|
||||
accessible-role: slider;
|
||||
accessible-value: value;
|
||||
accessible-value-minimum: minimum;
|
||||
accessible-value-maximum: maximum;
|
||||
accessible-value-step: (maximum - minimum) / 100;
|
||||
accessible-value: root.value;
|
||||
accessible-value-minimum: root.minimum;
|
||||
accessible-value-maximum: root.maximum;
|
||||
accessible-value-step: (root.maximum - root.minimum) / 100;
|
||||
|
||||
out property <bool> has-focus: fs.has-focus;
|
||||
|
||||
fs := FocusScope {
|
||||
x:0;
|
||||
width: 0px;
|
||||
|
||||
key-pressed(event) => {
|
||||
|
@ -74,7 +75,7 @@ export Slider := NativeSlider {
|
|||
|
||||
}
|
||||
|
||||
export GroupBox := NativeGroupBox {
|
||||
export component GroupBox inherits NativeGroupBox {
|
||||
GridLayout {
|
||||
padding-left: root.native-padding-left;
|
||||
padding-right: root.native-padding-right;
|
||||
|
@ -84,7 +85,7 @@ export GroupBox := NativeGroupBox {
|
|||
}
|
||||
}
|
||||
|
||||
export LineEdit := NativeLineEdit {
|
||||
export component LineEdit inherits NativeLineEdit {
|
||||
in property <length> font-size <=> inner.font-size;
|
||||
in-out property <string> text <=> inner.text;
|
||||
in property <string> placeholder-text <=> inner.placeholder-text;
|
||||
|
@ -105,38 +106,38 @@ export LineEdit := NativeLineEdit {
|
|||
padding-top: root.native-padding-top;
|
||||
padding-bottom: root.native-padding-bottom;
|
||||
inner := LineEditInner {
|
||||
placeholder-color: enabled ? StyleMetrics.placeholder-color : StyleMetrics.placeholder-color-disabled;
|
||||
placeholder-color: self.enabled ? StyleMetrics.placeholder-color : StyleMetrics.placeholder-color-disabled;
|
||||
enabled <=> root.enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export ListView := ScrollView {
|
||||
export component ListView inherits ScrollView {
|
||||
@children
|
||||
}
|
||||
|
||||
StandardListViewBase := ListView {
|
||||
component StandardListViewBase inherits ListView {
|
||||
in property<[StandardListViewItem]> model;
|
||||
in-out property<int> current-item: -1;
|
||||
for item[i] in model : NativeStandardListViewItem {
|
||||
for item[i] in root.model : NativeStandardListViewItem {
|
||||
item: item;
|
||||
index: i;
|
||||
is-selected: current-item == i;
|
||||
is-selected: root.current-item == i;
|
||||
has-hover: ta.has-hover;
|
||||
ta := TouchArea {
|
||||
clicked => { current-item = i; }
|
||||
clicked => { root.current-item = i; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export StandardListView := StandardListViewBase {
|
||||
export component StandardListView inherits StandardListViewBase {
|
||||
FocusScope {
|
||||
key-pressed(event) => {
|
||||
if (event.text == Key.UpArrow && current-item > 0) {
|
||||
current-item -= 1;
|
||||
if (event.text == Key.UpArrow && root.current-item > 0) {
|
||||
root.current-item -= 1;
|
||||
accept
|
||||
} else if (event.text == Key.DownArrow && current-item + 1 < model.length) {
|
||||
current-item += 1;
|
||||
} else if (event.text == Key.DownArrow && root.current-item + 1 < root.model.length) {
|
||||
root.current-item += 1;
|
||||
accept
|
||||
} else {
|
||||
reject
|
||||
|
@ -145,7 +146,7 @@ export StandardListView := StandardListViewBase {
|
|||
}
|
||||
}
|
||||
|
||||
export ComboBox := NativeComboBox {
|
||||
export component ComboBox inherits NativeComboBox {
|
||||
in property <[string]> model;
|
||||
in-out property <int> current-index : -1;
|
||||
enabled: true;
|
||||
|
@ -153,9 +154,10 @@ export ComboBox := NativeComboBox {
|
|||
callback selected(string);
|
||||
|
||||
accessible-role: combobox;
|
||||
accessible-value <=> current-value;
|
||||
accessible-value <=> root.current-value;
|
||||
|
||||
popup := PopupWindow {
|
||||
x:0;
|
||||
Rectangle { background: NativeStyleMetrics.window-background; }
|
||||
NativeComboBoxPopup {
|
||||
width: 100%;
|
||||
|
@ -167,14 +169,14 @@ export ComboBox := NativeComboBox {
|
|||
spacing: 0px;
|
||||
for value[i] in root.model: NativeStandardListViewItem {
|
||||
item: { text: value };
|
||||
is-selected: current-index == i;
|
||||
is-selected: root.current-index == i;
|
||||
has-hover: ta.has-hover;
|
||||
ta := TouchArea {
|
||||
clicked => {
|
||||
if (root.enabled) {
|
||||
current-index = i;
|
||||
current-value = value;
|
||||
selected(current-value);
|
||||
root.current-index = i;
|
||||
root.current-value = value;
|
||||
root.selected(root.current-value);
|
||||
}
|
||||
//is-open = false;
|
||||
}
|
||||
|
@ -187,11 +189,11 @@ export ComboBox := NativeComboBox {
|
|||
key-pressed(event) => {
|
||||
if (event.text == Key.UpArrow) {
|
||||
root.current-index = Math.max(root.current-index - 1, 0);
|
||||
root.current-value = model[root.current-index];
|
||||
root.current-value = root.model[root.current-index];
|
||||
return accept;
|
||||
} else if (event.text == Key.DownArrow) {
|
||||
root.current-index = Math.min(root.current-index + 1, root.model.length - 1);
|
||||
root.current-value = model[root.current-index];
|
||||
root.current-value = root.model[root.current-index];
|
||||
return accept;
|
||||
// PopupWindow can not get hidden again at this time, so do not allow to pop that up.
|
||||
// } else if (event.text == Key.Return) {
|
||||
|
@ -203,21 +205,21 @@ export ComboBox := NativeComboBox {
|
|||
}
|
||||
}
|
||||
|
||||
export TabWidgetImpl := NativeTabWidget { }
|
||||
export component TabWidgetImpl inherits NativeTabWidget { }
|
||||
|
||||
export TabImpl := NativeTab {
|
||||
export component TabImpl inherits NativeTab {
|
||||
accessible-role: tab;
|
||||
accessible-label <=> title;
|
||||
accessible-label <=> root.title;
|
||||
}
|
||||
|
||||
export TabBarImpl := Rectangle {
|
||||
export component TabBarImpl inherits Rectangle {
|
||||
// injected properties:
|
||||
property<int> current; // The currently selected tab
|
||||
property<int> current-focused: fs.has-focus ? current : -1; // The currently focused tab
|
||||
property<int> num-tabs; // The total number of tabs
|
||||
in-out property<int> current; // The currently selected tab
|
||||
in-out property<int> current-focused: fs.has-focus ? root.current : -1; // The currently focused tab
|
||||
in-out property<int> num-tabs; // The total number of tabs
|
||||
|
||||
accessible-role: tab;
|
||||
accessible-delegate-focus: current;
|
||||
accessible-delegate-focus: root.current;
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: 0px; // Qt renders Tabs next to each other and renders "spacing" as part of the tab itself
|
||||
|
@ -226,6 +228,7 @@ export TabBarImpl := Rectangle {
|
|||
}
|
||||
|
||||
fs := FocusScope {
|
||||
x:0;
|
||||
width: 0px; // Do not react on clicks
|
||||
key-pressed(event) => {
|
||||
if (event.text == Key.LeftArrow) {
|
||||
|
@ -233,7 +236,7 @@ export TabBarImpl := Rectangle {
|
|||
return accept;
|
||||
}
|
||||
if (event.text == Key.RightArrow) {
|
||||
root.current = Math.min(root.current + 1, num-tabs - 1);
|
||||
root.current = Math.min(root.current + 1, root.num-tabs - 1);
|
||||
return accept;
|
||||
}
|
||||
return reject;
|
||||
|
@ -241,19 +244,19 @@ export TabBarImpl := Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
export TabWidget := TabWidget {}
|
||||
export component TabWidget inherits TabWidget {}
|
||||
|
||||
export VerticalBox := VerticalLayout {
|
||||
export component VerticalBox inherits VerticalLayout {
|
||||
spacing: NativeStyleMetrics.layout-spacing;
|
||||
padding: NativeStyleMetrics.layout-spacing;
|
||||
}
|
||||
|
||||
export HorizontalBox := HorizontalLayout {
|
||||
export component HorizontalBox inherits HorizontalLayout {
|
||||
spacing: NativeStyleMetrics.layout-spacing;
|
||||
padding: NativeStyleMetrics.layout-spacing;
|
||||
}
|
||||
|
||||
export GridBox := GridLayout {
|
||||
export component GridBox inherits GridLayout {
|
||||
spacing: NativeStyleMetrics.layout-spacing;
|
||||
padding: NativeStyleMetrics.layout-spacing;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue