Loading files
import { Palette, ScrollView } from "std-widgets.slint";
import { Badge } from "badge.slint";
import { Constants } from "../api.slint";
export component TextEdit inherits Rectangle {
in-out property <string> text;
in property <string> placeholder-text;
in property <string> validation-error: validate(edt.text);
in property <bool> has-error: !validation-error.is-empty;
in property <bool> enabled: true;
in property <bool> read-only: false;
in property <length> font-size: 13px;
out property <bool> has-focus <=> edt.has-focus;
property <bool> show-error-badge: enabled && has-error && (!validation-error.is-empty);
pure callback validate(string) -> string;
callback text-edited(string);
text-edited(text) => {
self.text = text;
}
callback text-accepted(string);
callback key-pressed(KeyEvent) -> EventResult;
public function select-all() {
edt.select-all();
}
changed text => {
if text != edt.text {
edt.text = text;
}
}
changed has-focus => {
if !has-focus {
text-accepted(edt.text);
edt.text = self.text;
}
}
preferred-width: max(placeholder-txt.preferred-width, edt.preferred-width) + (2 * edt.x);
preferred-height: max(placeholder-txt.preferred-height, edt.preferred-height) + (2 * edt.y);
horizontal-stretch: 1;
background: #202020;
border-color: {
if enabled && has-error {
edt.has-focus ? #ff0000 : #900000
} else if edt.has-focus {
Constants.librepcb-color
} else if enabled && (!read-only) {
#606060
} else {
transparent
}
}
border-width: 1px;
border-radius: 10px;
forward-focus: edt;
// Accessibility
accessible-role: text-input;
accessible-enabled: enabled;
accessible-value: edt.text;
accessible-placeholder-text: placeholder-text;
accessible-read-only: read-only;
accessible-action-set-value(t) => {
text-edited(t)
}
placeholder-txt := Text {
x: 10px;
y: 8px;
width: root.width - (2 * self.x);
height: parent.height - (2 * self.y);
font-size: font-size;
color: enabled ? #909090 : #707070;
text: placeholder-text;
wrap: word-wrap;
overflow: elide;
visible: edt.text.is-empty && (!placeholder-text.is-empty);
accessible-role: none;
}
view := ScrollView {
x: placeholder-txt.x;
y: placeholder-txt.y;
width: parent.width - (2 * self.x);
height: parent.height - (2 * self.y);
viewport-width: self.width;
viewport-height: edt.preferred-height;
edt := TextInput {
x: 0;
y: 0;
width: parent.width;
height: max(self.preferred-height, parent.height);
font-size: font-size;
color: enabled ? Palette.foreground : Palette.foreground.darker(0.5);
selection-background-color: Constants.librepcb-color;
selection-foreground-color: black;
enabled: enabled;
read-only: read-only;
single-line: false;
wrap: word-wrap;
text: text;
accessible-role: none;
cursor-position-changed(position) => {
if position.y < -view.viewport-y {
view.viewport-y = -position.y;
} else if (position.y + self.font-metrics.ascent - self.font-metrics.descent) > (view.height - view.viewport-y) {
view.viewport-y = view.height - (position.y + self.font-metrics.ascent - self.font-metrics.descent);
}
}
edited => {
text-edited(self.text);
}
key-pressed(event) => {
root.key-pressed(event)
}
}
}
if show-error-badge: validation-error-badge := Badge {
x: root.width - self.width - 20px;
y: -8px;
width: min(self.preferred-width, root.width * 0.8);
background: #101010;
text-color: root.border-color;
font-size: 10px;
text: validation-error;
description: "validation error"; // Accessibility
}
}
2955876e1This file is pinned to the selected release. Download the original to open it in your design tool.