mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-21 07:41:51 +00:00
live-preview data tab floating table editor (#8123)
Adds a table editor based on the color picker floating draggable panel. This includes behaviours that keep the panel inside the bounds of the live preview window and light / dark mode.
This commit is contained in:
parent
6d01eec4db
commit
2da6bf4add
18 changed files with 481 additions and 278 deletions
|
@ -20,7 +20,7 @@ import { StringWidget } from "./widgets/string-widget.slint";
|
|||
import { WindowGlobal, WindowManager } from "../windowglobal.slint";
|
||||
|
||||
export component PropertyValueWidget inherits VerticalLayout {
|
||||
in property <PropertyValue> property-value;
|
||||
in-out property <PropertyValue> property-value;
|
||||
in property <PreviewData> preview-data;
|
||||
in property <string> property-name;
|
||||
in property <bool> enabled;
|
||||
|
@ -29,6 +29,8 @@ export component PropertyValueWidget inherits VerticalLayout {
|
|||
in property <bool> strings-are-translatable: true;
|
||||
in property <string> property-container-id;
|
||||
|
||||
callback update-display-string(value: string);
|
||||
|
||||
callback set-bool-binding(value: bool);
|
||||
callback set-color-binding(text: string);
|
||||
callback test-color-binding(text: string) -> bool;
|
||||
|
@ -46,6 +48,11 @@ export component PropertyValueWidget inherits VerticalLayout {
|
|||
callback reset-action();
|
||||
callback code-action();
|
||||
|
||||
function update-display-string-impl(value: string) {
|
||||
self.property-value.display-string = value;
|
||||
self.update-display-string(value);
|
||||
}
|
||||
|
||||
if root.property-value.kind == PropertyValueKind.boolean: BooleanWidget {
|
||||
enabled <=> root.enabled;
|
||||
property-name <=> root.property-name;
|
||||
|
@ -54,6 +61,8 @@ export component PropertyValueWidget inherits VerticalLayout {
|
|||
set-bool-binding(value) => {
|
||||
root.set-bool-binding(value);
|
||||
}
|
||||
|
||||
update-display-string(value) => { root.update-display-string-impl(value); }
|
||||
}
|
||||
|
||||
if root.property-value.kind == PropertyValueKind.color: ColorWidget {
|
||||
|
@ -71,6 +80,9 @@ export component PropertyValueWidget inherits VerticalLayout {
|
|||
set-color-binding(text) => {
|
||||
root.set-color-binding(text);
|
||||
}
|
||||
|
||||
update-display-string(value) => { root.update-display-string-impl(value); }
|
||||
|
||||
reset-action() => {
|
||||
root.reset-action();
|
||||
}
|
||||
|
@ -94,6 +106,9 @@ export component PropertyValueWidget inherits VerticalLayout {
|
|||
set-brush-binding(kind, angle, color, stops) => {
|
||||
root.set-brush-binding(kind, angle, color, stops);
|
||||
}
|
||||
|
||||
update-display-string(value) => { root.update-display-string-impl(value); }
|
||||
|
||||
reset-action() => {
|
||||
root.reset-action();
|
||||
}
|
||||
|
@ -107,6 +122,8 @@ export component PropertyValueWidget inherits VerticalLayout {
|
|||
property-name <=> root.property-name;
|
||||
property-value <=> root.property-value;
|
||||
|
||||
update-display-string(value) => { root.update-display-string-impl(value); }
|
||||
|
||||
reset-action() => {
|
||||
root.reset-action();
|
||||
}
|
||||
|
@ -123,6 +140,8 @@ export component PropertyValueWidget inherits VerticalLayout {
|
|||
set-enum-binding(text) => {
|
||||
root.set-enum-binding(text);
|
||||
}
|
||||
|
||||
update-display-string(value) => { root.update-display-string-impl(value); }
|
||||
}
|
||||
|
||||
if root.property-value.kind == PropertyValueKind.float: FloatWidget {
|
||||
|
@ -136,6 +155,8 @@ export component PropertyValueWidget inherits VerticalLayout {
|
|||
set-float-binding(text, unit) => {
|
||||
root.set-float-binding(text, unit);
|
||||
}
|
||||
|
||||
update-display-string(value) => { root.update-display-string-impl(value); }
|
||||
}
|
||||
|
||||
if root.property-value.kind == PropertyValueKind.integer: IntegerWidget {
|
||||
|
@ -149,6 +170,8 @@ export component PropertyValueWidget inherits VerticalLayout {
|
|||
set-integer-binding(text) => {
|
||||
root.set-code-binding(text);
|
||||
}
|
||||
|
||||
update-display-string(value) => { root.update-display-string-impl(value); }
|
||||
}
|
||||
|
||||
if root.property-value.kind == PropertyValueKind.string: StringWidget {
|
||||
|
@ -160,18 +183,21 @@ export component PropertyValueWidget inherits VerticalLayout {
|
|||
has-reset-action: root.has-reset-action;
|
||||
is-translatable <=> root.strings-are-translatable;
|
||||
|
||||
reset-action() => {
|
||||
root.reset-action();
|
||||
}
|
||||
code-action() => {
|
||||
root.code-action();
|
||||
}
|
||||
test-string-binding(text, is_translated) => {
|
||||
return root.test-string-binding(text, is_translated);
|
||||
}
|
||||
set-string-binding(text, is_translated) => {
|
||||
root.set-string-binding(text, is_translated);
|
||||
}
|
||||
|
||||
update-display-string(value) => { root.update-display-string-impl(value); }
|
||||
|
||||
reset-action() => {
|
||||
root.reset-action();
|
||||
}
|
||||
code-action() => {
|
||||
root.code-action();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,7 +305,7 @@ export component PreviewDataPropertyValueWidget inherits VerticalLayout {
|
|||
private property <PropertyValue> value: Api.get-property-value(root.property-container-id, root.preview-data.name);
|
||||
private property <string> possible-error;
|
||||
|
||||
callback edit-in-spreadsheet(rp: PropertyContainer);
|
||||
callback edit-in-table-editor(property-group-id: string, data: PreviewData);
|
||||
|
||||
function reset-action() {
|
||||
self.set-code-binding(self.value.code);
|
||||
|
@ -347,12 +373,16 @@ export component PreviewDataPropertyValueWidget inherits VerticalLayout {
|
|||
return(root.set-code-binding(is_translated ? "\"\{text}\"" : text));
|
||||
}
|
||||
}
|
||||
if root.preview-data.kind == PreviewDataKind.Table && false: MultiValueWidget {
|
||||
edit-in-spreadsheet(property-group-name, data, values) => {
|
||||
debug("edit-in-spreadsheet TRIGGERED: ", property-group-name, data, values);
|
||||
if root.preview-data.kind == PreviewDataKind.Table: MultiValueWidget {
|
||||
property-value <=> root.value;
|
||||
preview-data: root.preview-data;
|
||||
property-group-id: root.property-container-id;
|
||||
|
||||
edit-in-table-editor(property-group-id, data) => {
|
||||
root.edit-in-table-editor(property-group-id, data);
|
||||
}
|
||||
}
|
||||
if root.preview-data.kind == PreviewDataKind.Json || (root.preview-data.kind == PreviewDataKind.Table && true): JsonWidget {
|
||||
if root.preview-data.kind == PreviewDataKind.Json: JsonWidget {
|
||||
enabled: root.preview-data.has-setter;
|
||||
property-name: root.preview-data.name;
|
||||
property-value <=> root.value;
|
||||
|
|
|
@ -1,31 +1,113 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
||||
|
||||
import { Button } from "std-widgets.slint";
|
||||
import { EditorSpaceSettings } from "../components/styling.slint";
|
||||
import { Button, Palette, StandardButton, ScrollView } from "std-widgets.slint";
|
||||
import { EditorSpaceSettings, EditorPalette, Icons } from "../components/styling.slint";
|
||||
import { Spreadsheet } from "../components/spreadsheet.slint";
|
||||
import { Api, PreviewData, PropertyValueTable } from "../api.slint";
|
||||
|
||||
import { WindowGlobal } from "../windowglobal.slint";
|
||||
import { WindowGlobal, WindowManager } from "../windowglobal.slint";
|
||||
import { EditorSizeSettings } from "styling.slint";
|
||||
import { TableData } from "../properties-state.slint";
|
||||
import { DraggablePanel } from "draggable-panel.slint";
|
||||
|
||||
export component SpreadsheetDialog inherits Dialog {
|
||||
width: Math.min(self.preferred-width, WindowGlobal.window-width * 0.9);
|
||||
height: Math.min(self.preferred-height, WindowGlobal.window-height * 0.9);
|
||||
component TableEditor inherits DraggablePanel {
|
||||
property <string> property-group-id <=> TableData.property-group-id;
|
||||
property <PreviewData> preview-data <=> TableData.preview-data;
|
||||
property <PropertyValueTable> current-table <=> TableData.current-table;
|
||||
private property <length> initial-x;
|
||||
private property <length> initial-y;
|
||||
|
||||
title: "Edit Values";
|
||||
callback close();
|
||||
|
||||
VerticalLayout {
|
||||
Spreadsheet {
|
||||
property <length> content-height;
|
||||
property <length> content-width;
|
||||
|
||||
close => {
|
||||
WindowManager.hide-floating-widget();
|
||||
}
|
||||
|
||||
width: 240px;
|
||||
|
||||
title := Rectangle {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
|
||||
Text {
|
||||
text: "Edit Values";
|
||||
color: EditorPalette.text-color;
|
||||
}
|
||||
|
||||
HorizontalLayout {
|
||||
alignment: end;
|
||||
padding: 8px;
|
||||
Rectangle {
|
||||
x: parent.width - self.width - 5px;
|
||||
width: 25px;
|
||||
height: self.width;
|
||||
background: t-close.has-hover ? EditorPalette.section-color : transparent;
|
||||
border-radius: EditorSizeSettings.property-border-radius;
|
||||
|
||||
Button {
|
||||
text: "Close";
|
||||
t-close := TouchArea {
|
||||
clicked => {
|
||||
root.close();
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
source: Icons.close;
|
||||
colorize: EditorPalette.text-color;
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
x: 0;
|
||||
y: parent.height - self.height;
|
||||
background: EditorPalette.divider-color;
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 100%;
|
||||
height: root.content-height;
|
||||
ScrollView {
|
||||
viewport-width: spread-sheet.preferred-width;
|
||||
viewport-height: spread-sheet.preferred-height;
|
||||
height: 100%;
|
||||
width: root.width;
|
||||
spread-sheet := Spreadsheet {
|
||||
init => {
|
||||
root.content-height = spread-sheet.preferred-height + 4px;
|
||||
root.content-width = spread-sheet.preferred-width + 2 * EditorSpaceSettings.default-padding;
|
||||
root.width = Math.min(root.content-width, WindowGlobal.window-width * 0.9);
|
||||
}
|
||||
property-group-id <=> root.property-group-id;
|
||||
preview-data <=> root.preview-data;
|
||||
current-table <=> root.current-table;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer := Rectangle {
|
||||
width: 100%;
|
||||
height: EditorSizeSettings.standard-margin;
|
||||
}
|
||||
}
|
||||
|
||||
export component TableEditorView {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
in property <length> initial-x: 0;
|
||||
in property <length> initial-y: 0;
|
||||
|
||||
TouchArea {
|
||||
changed pressed => {
|
||||
WindowManager.hide-floating-widget();
|
||||
}
|
||||
}
|
||||
|
||||
table-editor := TableEditor {
|
||||
x: root.initial-x;
|
||||
y: root.initial-y;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,43 +1,110 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
||||
|
||||
import { Palette, Button, LineEdit, CheckBox, ScrollView, VerticalBox } from "std-widgets.slint";
|
||||
import { Api, ColorData, ElementInformation, PreviewData, PreviewDataKind, PropertyDeclaration, PropertyGroup, PropertyInformation, PropertyValue, PropertyValueKind, PropertyValueTable } from "../api.slint";
|
||||
import { EditorSizeSettings, Icons, EditorAnimationSettings, EditorSpaceSettings, EditorSizeSettings, EditorFontSettings, EditorPalette } from "../components/styling.slint";
|
||||
import { Palette } from "std-widgets.slint";
|
||||
import { Api, PreviewData, PreviewDataKind, PropertyValue, PropertyValueKind, PropertyValueTable } from "../api.slint";
|
||||
import { StatusLineApi } from "../components/status-line.slint";
|
||||
import { EditorSizeSettings, Icons, EditorSpaceSettings } from "../components/styling.slint";
|
||||
import { PropertyValueWidget } from "../components/property-widgets.slint";
|
||||
|
||||
export struct CellData {
|
||||
id: string,
|
||||
value: PropertyValue,
|
||||
property-group-id: string,
|
||||
property-name: string,
|
||||
|
||||
row: int,
|
||||
col: int,
|
||||
|
||||
x: length,
|
||||
y: length,
|
||||
width: length,
|
||||
height: length
|
||||
}
|
||||
height: length}
|
||||
|
||||
export component EditWindow inherits Rectangle {
|
||||
in property <CellData> current-cell;
|
||||
drop-shadow-blur: 10px;
|
||||
drop-shadow-color: black.transparentize(0.5);
|
||||
drop-shadow-offset-x: 0;
|
||||
drop-shadow-offset-y: 0;
|
||||
border-radius: EditorSizeSettings.radius;
|
||||
width: self.preferred-width;
|
||||
height: self.preferred-height;
|
||||
background: Palette.alternate-background;
|
||||
export component EditWindow inherits PopupWindow {
|
||||
close-policy: close-on-click-outside;
|
||||
|
||||
callback test(string) -> bool;
|
||||
callback save(string);
|
||||
callback close-editor();
|
||||
HorizontalLayout {
|
||||
padding: EditorSpaceSettings.default-padding;
|
||||
padding-left: EditorSpaceSettings.default-padding + 15px;
|
||||
spacing: EditorSpaceSettings.default-spacing;
|
||||
PropertyValueWidget {
|
||||
property-value: current-cell.value;
|
||||
visible: true;
|
||||
property-name: current-cell.id;
|
||||
enabled: true;
|
||||
|
||||
in property <CellData> current-cell-data;
|
||||
in-out property <PropertyValueTable> current-table;
|
||||
|
||||
content := Rectangle {
|
||||
changed height => {
|
||||
parent.height = self.height;
|
||||
}
|
||||
|
||||
drop-shadow-blur: 10px;
|
||||
drop-shadow-color: black.transparentize(0.5);
|
||||
drop-shadow-offset-x: 0;
|
||||
drop-shadow-offset-y: 0;
|
||||
border-radius: EditorSizeSettings.radius;
|
||||
width: self.preferred-width;
|
||||
height: self.preferred-height;
|
||||
background: Palette.alternate-background;
|
||||
hl := HorizontalLayout {
|
||||
padding: EditorSpaceSettings.default-padding;
|
||||
padding-left: EditorSpaceSettings.default-padding;
|
||||
spacing: EditorSpaceSettings.default-spacing;
|
||||
|
||||
PropertyValueWidget {
|
||||
property-value: root.current-table.values[root.current-cell-data.row][root.current-cell-data.col];
|
||||
property-name: root.current-cell-data.property-group-id;
|
||||
enabled: true;
|
||||
|
||||
changed property-value => {
|
||||
root.current-table.values[root.current-cell-data.row][root.current-cell-data.col] = self.property-value;
|
||||
}
|
||||
|
||||
update-display-string(value) => {
|
||||
root.current-table.values[root.current-cell-data.row][root.current-cell-data.col].display-string = value;
|
||||
}
|
||||
|
||||
test-color-binding(text) => {
|
||||
return root.test("\"\{text}\"");
|
||||
}
|
||||
test-brush-binding(kind, angle, color, stops) => {
|
||||
return root.test(Api.as-json-brush(kind, angle, color, stops));
|
||||
}
|
||||
test-float-binding(text, unit) => {
|
||||
return root.test(text);
|
||||
}
|
||||
test-code-binding(text) => {
|
||||
return root.test(text);
|
||||
}
|
||||
test-string-binding(text, is_translated) => {
|
||||
return root.test(is_translated ? "\"\{text}\"" : text);
|
||||
}
|
||||
|
||||
set-bool-binding(value) => {
|
||||
debug("set-bool-binding");
|
||||
root.save(value ? "true" : "false");
|
||||
}
|
||||
set-color-binding(text) => {
|
||||
debug("set-color-binding");
|
||||
root.save("\"\{text}\"");
|
||||
}
|
||||
set-brush-binding(kind, angle, color, stops) => {
|
||||
debug("set-brush-binding");
|
||||
root.save(Api.as-json-brush(kind, angle, color, stops));
|
||||
}
|
||||
set-float-binding(text, _unit) => {
|
||||
debug("set-float-binding");
|
||||
root.save(text);
|
||||
}
|
||||
set-code-binding(text) => {
|
||||
debug("set-code-binding");
|
||||
root.save(text);
|
||||
}
|
||||
set-string-binding(text, is_translated) => {
|
||||
debug("set-string-binding");
|
||||
root.save(is_translated ? "\"\{text}\"" : text);
|
||||
}
|
||||
set-enum-binding(text) => {
|
||||
debug("set-enum-binding");
|
||||
root.save("\"\{text}\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,6 +114,7 @@ component RowMarker inherits Rectangle {
|
|||
in property <bool> header: false;
|
||||
in property <bool> hovered;
|
||||
width: 30px;
|
||||
|
||||
if (value > 0): Rectangle {
|
||||
height: 30px;
|
||||
background: header ? transparent : Palette.alternate-background;
|
||||
|
@ -81,18 +149,20 @@ component RowMarker inherits Rectangle {
|
|||
}
|
||||
|
||||
component Cell inherits Rectangle {
|
||||
in property <CellData> cell-data;
|
||||
in property <string> id;
|
||||
in property <PropertyValue> property-value;
|
||||
|
||||
in property <bool> is-header: false;
|
||||
in property <bool> is-writeable: false;
|
||||
in-out property <bool> is-editing: false;
|
||||
in property <length> cell-width: 100px;
|
||||
property <bool> cell-clicked: false;
|
||||
in property <string> text: "";
|
||||
in-out property <color> bg-color: cell-clicked ? Palette.accent-background.transparentize(0.8) : transparent;
|
||||
callback edit-clicked(CellData);
|
||||
|
||||
width: cell-width;
|
||||
in property <string> text;
|
||||
|
||||
in-out property <color> bg-color: cell-clicked ? Palette.accent-background.transparentize(0.8) : transparent;
|
||||
|
||||
private property <bool> cell-clicked: false;
|
||||
|
||||
callback edit-clicked();
|
||||
|
||||
width: 100px;
|
||||
height: 30px;
|
||||
border-width: 1px;
|
||||
border-color: Palette.border;
|
||||
|
@ -116,128 +186,56 @@ component Cell inherits Rectangle {
|
|||
|
||||
if is-writeable: TouchArea {
|
||||
clicked => {
|
||||
root.edit-clicked({ id: root.id, value: cell-data.value, row: 0, col: 0 });
|
||||
root.edit-clicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export component Spreadsheet inherits ScrollView {
|
||||
export component Spreadsheet {
|
||||
in property <string> property-group-id;
|
||||
in property <PreviewData> preview-data: {
|
||||
name: "Addresses",
|
||||
has-getter: true,
|
||||
has-setter: true,
|
||||
kind: PreviewDataKind.Table,
|
||||
};
|
||||
in property <PropertyValueTable> current-table: {
|
||||
in-out property <PropertyValueTable> current-table: {
|
||||
is-array: true,
|
||||
headers: ["type", "street", "city", "state", "zip", "favorite","color"],
|
||||
headers: ["type", "street", "city", "state", "zip", "favorite", "color"],
|
||||
values: [
|
||||
[
|
||||
{
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "home"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "123 Oak Lane"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "Richmond"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "VA"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "23226"
|
||||
}, {
|
||||
kind: PropertyValueKind.boolean,
|
||||
value-bool: true,
|
||||
value-string: "True"
|
||||
}, {
|
||||
kind: PropertyValueKind.color,
|
||||
value-string: "#ff0000"
|
||||
}
|
||||
], [
|
||||
{
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "work"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "456 Corporate Blvd"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "Richmond"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "VA"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "23219"
|
||||
}, {
|
||||
kind: PropertyValueKind.boolean,
|
||||
value-bool: false,
|
||||
value-string: "False"
|
||||
}
|
||||
], [
|
||||
{
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "history"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "123 Oak Lane"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "Richmond"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "VA"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "23226"
|
||||
}, {
|
||||
kind: PropertyValueKind.boolean,
|
||||
value-bool: false,
|
||||
value-string: "False"
|
||||
}, {
|
||||
kind: PropertyValueKind.color,
|
||||
value-string: "#aaff00"
|
||||
}
|
||||
], [
|
||||
{
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "world"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "456 Corporate Blvd"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "Richmond"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "VA"
|
||||
}, {
|
||||
kind: PropertyValueKind.string,
|
||||
value-string: "23219"
|
||||
}, {
|
||||
kind: PropertyValueKind.boolean,
|
||||
value-bool: false,
|
||||
value-string: "False"
|
||||
}, {
|
||||
kind: PropertyValueKind.color,
|
||||
value-string: "#ff0000"
|
||||
}
|
||||
{ kind: PropertyValueKind.string, display-string: "home" },
|
||||
{ kind: PropertyValueKind.string, display-string: "123 Oak Lane" },
|
||||
{ kind: PropertyValueKind.string, display-string: "Richmond" },
|
||||
{ kind: PropertyValueKind.string, display-string: "VA" },
|
||||
{ kind: PropertyValueKind.string, display-string: "23226" },
|
||||
{ kind: PropertyValueKind.boolean, value-bool: true, display-string: "true" },
|
||||
{ kind: PropertyValueKind.color, display-string: "#ff0000" }
|
||||
],
|
||||
[
|
||||
{ kind: PropertyValueKind.string, display-string: "work" },
|
||||
{ kind: PropertyValueKind.string, display-string: "456 Corporate Blvd" },
|
||||
{ kind: PropertyValueKind.string, display-string: "Richmond" },
|
||||
{ kind: PropertyValueKind.string, display-string: "VA" },
|
||||
{ kind: PropertyValueKind.string, display-string: "23219" },
|
||||
{ kind: PropertyValueKind.boolean, value-bool: false, display-string: "false" }
|
||||
],
|
||||
[
|
||||
{ kind: PropertyValueKind.string, display-string: "world" },
|
||||
{ kind: PropertyValueKind.string, display-string: "456 Corporate Blvd" },
|
||||
{ kind: PropertyValueKind.string, display-string: "Richmond" },
|
||||
{ kind: PropertyValueKind.string, display-string: "VA" },
|
||||
{ kind: PropertyValueKind.string, display-string: "23219" },
|
||||
{ kind: PropertyValueKind.boolean, value-bool: false, display-string: "false" },
|
||||
{ kind: PropertyValueKind.color, display-string: "#ff0000" }
|
||||
]
|
||||
],
|
||||
|
||||
};
|
||||
|
||||
property <CellData> current-cell;
|
||||
property <bool> edit-window-visible: false;
|
||||
private property <length> selection-x;
|
||||
private property <length> selection-y;
|
||||
|
||||
public function edit-in-spreadsheet(container-name: string, preview-data: PreviewData) {
|
||||
debug("Setting up Spreadsheet:", container-name, preview-data);
|
||||
}
|
||||
private property <CellData> current-cell-data;
|
||||
|
||||
VerticalLayout {
|
||||
HorizontalLayout {
|
||||
|
@ -252,23 +250,31 @@ export component Spreadsheet inherits ScrollView {
|
|||
for data-row[row] in root.current-table.values: HorizontalLayout {
|
||||
RowMarker {
|
||||
value: row + 1;
|
||||
hovered: ta.has-hover ? true : false;
|
||||
hovered: ta.has-hover;
|
||||
|
||||
ta := TouchArea {
|
||||
clicked => {
|
||||
root.selection-x = self.x;
|
||||
root.selection-y = self.y;
|
||||
row_menu.show({x:self.mouse-x + ta.absolute-position.x - row_menu.absolute-position.x,y:self.mouse-y + ta.absolute-position.y - row_menu.absolute-position.y});
|
||||
|
||||
row_menu.row-number = row;
|
||||
row_menu.show({
|
||||
x:self.mouse-x + ta.absolute-position.x - row_menu.absolute-position.x,
|
||||
y:self.mouse-y + ta.absolute-position.y - row_menu.absolute-position.y
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for value[col] in data-row: Cell {
|
||||
text: value.value-string;
|
||||
text: value.display-string;
|
||||
is-writeable: true;
|
||||
edit-clicked(data) => {
|
||||
root.current-cell = {
|
||||
id: data.id,
|
||||
value: value, // Now passing the properly typed CellValue
|
||||
|
||||
edit-clicked() => {
|
||||
root.current-cell-data = {
|
||||
property-group-id: root.property-group-id,
|
||||
property-name: preview-data.name,
|
||||
property-value: root.current-table.values[row][col],
|
||||
row: row,
|
||||
col: col,
|
||||
x: self.x,
|
||||
|
@ -276,46 +282,69 @@ export component Spreadsheet inherits ScrollView {
|
|||
width: self.width,
|
||||
height: self.height
|
||||
};
|
||||
root.edit-window-visible = true;
|
||||
ew.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (edit-window-visible): ew := EditWindow {
|
||||
x: current-cell.x > 15px ? current-cell.x - EditorSpaceSettings.default-padding - 15px : 0; // TODO the end needs to be windowWidth - current-cell.x < current.cell.width * 2;
|
||||
y: current-cell.y - EditorSpaceSettings.default-padding;
|
||||
current-cell: current-cell;
|
||||
save(new-value) => {
|
||||
// Update the specific field based on col index
|
||||
// if (current-cell.col == 0) {
|
||||
// addresses[current-cell.row].type = new-value;
|
||||
// } else if (current-cell.col == 1) {
|
||||
// addresses[current-cell.row].street = new-value;
|
||||
// } else if (current-cell.col == 2) {
|
||||
// addresses[current-cell.row].city = new-value;
|
||||
// } else if (current-cell.col == 3) {
|
||||
// addresses[current-cell.row].state = new-value;
|
||||
// } else if (current-cell.col == 4) {
|
||||
// addresses[current-cell.row].zip = new-value;
|
||||
// }
|
||||
root.edit-window-visible = false;
|
||||
ew := EditWindow {
|
||||
x: self.current-cell-data.x > 15px ? self.current-cell-data.x - EditorSpaceSettings.default-padding - 15px : (self.current-cell-data.x + self.current-cell-data.width > root.width ? root.width - ew.width : 0); // TODO the end needs to be windowWidth - current-cell.x < current.cell.width * 2;
|
||||
y: self.current-cell-data.y - EditorSpaceSettings.default-padding;
|
||||
current-cell-data <=> root.current-cell-data;
|
||||
current-table: root.current-table;
|
||||
|
||||
private property <string> possible-error;
|
||||
|
||||
function edit(new-value: string) -> bool {
|
||||
debug("EW: edit(...): Model has \{root.current-table.values.length} rows");
|
||||
self.current-table.values[self.current-cell-data.row][self.current-cell-data.col].was-edited = true;
|
||||
self.current-table.values[self.current-cell-data.row][self.current-cell-data.col].edited-value = new-value;
|
||||
|
||||
self.possible_error = Api.set-property-value-table(root.property-group-id, root.preview-data.name, root.current-table.values, root.current-table.is-array);
|
||||
StatusLineApi.help-text = self.possible-error;
|
||||
|
||||
return self.possible-error == "";
|
||||
}
|
||||
|
||||
test(new-value) => {
|
||||
return edit(new-value);
|
||||
}
|
||||
|
||||
save(new-value) => {
|
||||
edit(new-value);
|
||||
self.close-editor();
|
||||
}
|
||||
|
||||
close-editor => {
|
||||
root.edit-window-visible = false;
|
||||
debug("EW: Received close-editor");
|
||||
self.close();
|
||||
}
|
||||
}
|
||||
row_menu:= ContextMenuArea {
|
||||
in property <int> position;
|
||||
|
||||
row_menu := ContextMenuArea {
|
||||
in-out property <int> row-number;
|
||||
|
||||
Menu {
|
||||
MenuItem {
|
||||
title: "Add Row Above";
|
||||
activated() => {
|
||||
Api.insert-row-into-value-table(root.current_table, row_menu.row-number);
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
title: "Add Row Below";
|
||||
activated() => {
|
||||
Api.insert-row-into-value-table(root.current_table, row_menu.row-number + 1);
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
title: "Remove Row";
|
||||
activated() => {
|
||||
Api.remove-row-from-value-table(root.current_table, row_menu.row-number);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,9 @@ export global EditorSizeSettings {
|
|||
in property <length> property-bar-width: 360px;
|
||||
in property <length> radius: 5px;
|
||||
in property <length> side-bar-width: 280px;
|
||||
out property <length> standard-margin: 16px;
|
||||
out property <length> small-margin: 12px;
|
||||
out property <length> property-border-radius: 5px;
|
||||
}
|
||||
|
||||
export global EditorPalette {
|
||||
|
@ -78,10 +81,13 @@ export global EditorPalette {
|
|||
out property <brush> interactive-element-selection-secondary: #48dc2a;
|
||||
out property <brush> layout-element-selection-primary: #FFC5FC;
|
||||
out property <brush> layout-element-selection-secondary: #ff8af9;
|
||||
out property <brush> shadow-gradient: @linear-gradient(0deg, Palette.foreground.transparentize(1),Palette.foreground.transparentize(0.75));
|
||||
out property <brush> shadow-gradient: @linear-gradient(0deg, Palette.foreground.transparentize(1), Palette.foreground.transparentize(0.75));
|
||||
|
||||
out property <brush> state-hovered: root.dark-color-scheme ? #ffffff.with-alpha(0.1) : #000000.with-alpha(0.1);
|
||||
out property <brush> state-pressed: root.dark-color-scheme ? #ffffff.with-alpha(0.2) : #000000.with-alpha(0.2);
|
||||
out property <color> text-color: Palette.color-scheme == ColorScheme.dark ? white : #383838;
|
||||
out property <color> section-color: Palette.color-scheme == ColorScheme.dark ? #3f3f3f : #f5f5f5;
|
||||
out property <color> divider-color: Palette.color-scheme == ColorScheme.dark ? #444444 : #e6e6e6;
|
||||
}
|
||||
|
||||
export global EditorAnimationSettings {
|
||||
|
|
|
@ -11,9 +11,10 @@ import { CheckBox } from "std-widgets.slint";
|
|||
export component BooleanWidget inherits GridLayout {
|
||||
in property <bool> enabled;
|
||||
in property <string> property-name;
|
||||
in property <PropertyValue> property-value;
|
||||
in-out property <PropertyValue> property-value;
|
||||
|
||||
callback set-bool-binding(value: bool);
|
||||
callback update-display-string(value: string);
|
||||
|
||||
spacing-vertical: EditorSpaceSettings.default-spacing;
|
||||
width: 100%;
|
||||
|
@ -36,10 +37,18 @@ export component BooleanWidget inherits GridLayout {
|
|||
checkbox := CheckBox {
|
||||
enabled: root.enabled;
|
||||
checked: root.property-value.value-bool;
|
||||
text: self.checked ? "True" : "False";
|
||||
text: self.display-string();
|
||||
|
||||
function display-string() -> string {
|
||||
return self.checked ? "true" : "false";
|
||||
}
|
||||
|
||||
toggled() => {
|
||||
root.property-value.value-bool = self.checked;
|
||||
debug("property-value is now:", root.property-value.value-bool);
|
||||
|
||||
root.set-bool-binding(self.checked);
|
||||
root.update-display-string(self.display-string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,9 +23,16 @@ export component BrushWidget inherits GridLayout {
|
|||
callback code-action();
|
||||
callback reset-action();
|
||||
|
||||
callback update-display-string(value: string);
|
||||
|
||||
callback test-brush-binding(kind: BrushKind, angle: float, color: color, stops: [GradientStop]) -> bool;
|
||||
callback set-brush-binding(kind: BrushKind, angle: float, color: color, stops: [GradientStop]);
|
||||
|
||||
function set-brush-binding_impl(kind: BrushKind, angle: float, color: color, stops: [GradientStop]) {
|
||||
self.update-display-string(kind == BrushKind.solid ? "Solid Color" : kind == BrushKind.linear ? "Linear Gradient" : "Radial Gradient");
|
||||
self.set-brush-binding(kind, angle, color, stops);
|
||||
}
|
||||
|
||||
private property <color> current-color;
|
||||
private property <brush> current-brush;
|
||||
private property <[GradientStop]> current-gradient-stops;
|
||||
|
@ -71,7 +78,7 @@ export component BrushWidget inherits GridLayout {
|
|||
|
||||
function set-color(text: string) {
|
||||
root.current-color = Api.string-to-color(text);
|
||||
root.set-brush-binding(root.current-brush-kind, root.current-angle, root.current-color, root.current-gradient-stops);
|
||||
root.set-brush-binding-impl(root.current-brush-kind, root.current-angle, root.current-color, root.current-gradient-stops);
|
||||
}
|
||||
|
||||
|
||||
|
@ -122,7 +129,7 @@ export component BrushWidget inherits GridLayout {
|
|||
// enabled <=> root.enabled;
|
||||
|
||||
set-color-binding(text) => {
|
||||
root.set-brush-binding(root.current-brush-kind, root.current-angle, root.current-color, root.current-gradient-stops);
|
||||
root.set-brush-binding-impl(root.current-brush-kind, root.current-angle, root.current-color, root.current-gradient-stops);
|
||||
}
|
||||
test-color-binding(text) => {
|
||||
return root.test-brush-binding(root.current-brush-kind, root.current-angle, root.current-color, root.current-gradient-stops);
|
||||
|
@ -152,6 +159,5 @@ export component BrushWidget inherits GridLayout {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@ export component CodeWidget inherits GridLayout {
|
|||
in property <string> property-name;
|
||||
in property <PropertyValue> property-value;
|
||||
|
||||
callback update-display-string(value: string);
|
||||
|
||||
callback code-action();
|
||||
callback reset-action();
|
||||
|
||||
|
|
|
@ -26,6 +26,9 @@ export component ColorWidget inherits VerticalLayout {
|
|||
|
||||
padding-left: 16px;
|
||||
spacing: EditorSpaceSettings.default-spacing;
|
||||
|
||||
callback update-display-string(value: string);
|
||||
|
||||
width: 100%;
|
||||
|
||||
function apply-value() {
|
||||
|
@ -73,6 +76,7 @@ export component ColorWidget inherits VerticalLayout {
|
|||
set-color-binding(text) => {
|
||||
root.set-color-binding(text);
|
||||
}
|
||||
|
||||
test-color-binding(text) => {
|
||||
return root.test-color-binding(text);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ export component EnumWidget inherits GridLayout {
|
|||
}
|
||||
}
|
||||
|
||||
callback update-display-string(value: string);
|
||||
|
||||
callback set-enum-binding(text: string);
|
||||
|
||||
spacing-vertical: EditorSpaceSettings.default-spacing;
|
||||
|
@ -46,6 +48,7 @@ export component EnumWidget inherits GridLayout {
|
|||
model: root.property-value.visual-items;
|
||||
|
||||
selected(value) => {
|
||||
root.update-display-string(property-value.value-string + "." + value);
|
||||
root.set-enum-binding(property-value.value-string + "." + value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ export component FloatWidget inherits GridLayout {
|
|||
in property <string> property-name;
|
||||
in property <PropertyValue> property-value;
|
||||
|
||||
callback update-display-string(value: string);
|
||||
|
||||
callback test-float-binding(text: string, unit: string) -> bool;
|
||||
callback set-float-binding(text: string, unit: string);
|
||||
|
||||
|
@ -30,6 +32,9 @@ export component FloatWidget inherits GridLayout {
|
|||
}
|
||||
|
||||
function set-binding() {
|
||||
if number.text != "" {
|
||||
root.update-display-string("\{number.text}\{self.current-unit}");
|
||||
}
|
||||
root.set-float-binding(number.text == "" ? "" : number.text, self.current-unit);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,20 +4,12 @@
|
|||
import { Palette, Button, ComboBox } from "std-widgets.slint";
|
||||
import { WindowGlobal, WindowManager } from "../../windowglobal.slint";
|
||||
import { Api, GradientStop } from "../../api.slint";
|
||||
import { Icons } from "../../components/styling.slint";
|
||||
import { Icons, EditorPalette, EditorSizeSettings } from "../../components/styling.slint";
|
||||
import { BrushMode, PickerData, PickerMode, WidgetMode } from "../../properties-state.slint";
|
||||
import { SimpleColumn } from "../../components/layout-helpers.slint";
|
||||
import { DraggablePanel } from "../../components/draggable-panel.slint";
|
||||
|
||||
export global Styles {
|
||||
out property <color> section-color: Palette.color-scheme == ColorScheme.dark ? #3f3f3f : #f5f5f5;
|
||||
out property <color> text-color: Palette.color-scheme == ColorScheme.dark ? white : #383838;
|
||||
out property <color> divider-color: Palette.color-scheme == ColorScheme.dark ? #444444 : #e6e6e6;
|
||||
out property <color> background-color: Palette.color-scheme == ColorScheme.dark ? #2c2c2c : white;
|
||||
out property <brush> picker-border-color: Palette.color-scheme == ColorScheme.dark ? #ffffff17 : transparent;
|
||||
out property <length> standard-margin: 16px;
|
||||
out property <length> small-margin: 12px;
|
||||
out property <length> property-border-radius: 5px;
|
||||
out property <length> picker-width: 240px;
|
||||
}
|
||||
|
||||
|
@ -101,7 +93,7 @@ component BrushTypeSelector {
|
|||
in-out property <BrushMode> brush-mode: color;
|
||||
|
||||
HorizontalLayout {
|
||||
padding-left: Styles.small-margin;
|
||||
padding-left: EditorSizeSettings.small-margin;
|
||||
alignment: start;
|
||||
|
||||
Rectangle {
|
||||
|
@ -113,8 +105,8 @@ component BrushTypeSelector {
|
|||
|
||||
Rectangle {
|
||||
visible: is-active;
|
||||
background: Styles.section-color;
|
||||
border-radius: Styles.property-border-radius;
|
||||
background: EditorPalette.section-color;
|
||||
border-radius: EditorSizeSettings.property-border-radius;
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
|
@ -152,8 +144,8 @@ component BrushTypeSelector {
|
|||
|
||||
Rectangle {
|
||||
visible: is-active;
|
||||
background: Styles.section-color;
|
||||
border-radius: Styles.property-border-radius;
|
||||
background: EditorPalette.section-color;
|
||||
border-radius: EditorSizeSettings.property-border-radius;
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
|
@ -190,8 +182,8 @@ component BrushTypeSelector {
|
|||
|
||||
Rectangle {
|
||||
visible: is-active;
|
||||
background: Styles.section-color;
|
||||
border-radius: Styles.property-border-radius;
|
||||
background: EditorPalette.section-color;
|
||||
border-radius: EditorSizeSettings.property-border-radius;
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
|
@ -230,11 +222,11 @@ component ColorModeColorAndApply {
|
|||
alignment: center;
|
||||
spacing: 10px;
|
||||
Rectangle {
|
||||
x: Styles.standard-margin;
|
||||
x: EditorSizeSettings.standard-margin;
|
||||
width: 170px;
|
||||
height: 25px;
|
||||
background: Styles.section-color;
|
||||
border-radius: Styles.property-border-radius;
|
||||
background: EditorPalette.section-color;
|
||||
border-radius: EditorSizeSettings.property-border-radius;
|
||||
border-width: 1px;
|
||||
|
||||
Rectangle {
|
||||
|
@ -259,7 +251,7 @@ component ColorModeColorAndApply {
|
|||
x: 35px;
|
||||
font-family: "Inter";
|
||||
font-size: 12px;
|
||||
color: Styles.text-color;
|
||||
color: EditorPalette.text-color;
|
||||
text: Api.color-to-data(PickerData.current-color).short-text.to-uppercase();
|
||||
letter-spacing: 0.8px;
|
||||
}
|
||||
|
@ -268,7 +260,7 @@ component ColorModeColorAndApply {
|
|||
x: parent.width - 45px;
|
||||
width: 1px;
|
||||
height: parent.height;
|
||||
background: Styles.background-color;
|
||||
background: Palette.background;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
@ -283,7 +275,7 @@ component ColorModeColorAndApply {
|
|||
horizontal-alignment: left;
|
||||
font-family: "Inter";
|
||||
font-size: 12px;
|
||||
color: Styles.text-color;
|
||||
color: EditorPalette.text-color;
|
||||
text: PickerData.alpha;
|
||||
text-cursor-width: 2px;
|
||||
selection-background-color: #3984ec;
|
||||
|
@ -337,7 +329,7 @@ component ColorModeColorAndApply {
|
|||
}
|
||||
|
||||
if widget-mode == WidgetMode.edit: Button {
|
||||
x: Styles.standard-margin;
|
||||
x: EditorSizeSettings.standard-margin;
|
||||
width: 100px;
|
||||
text: "Apply";
|
||||
clicked => {
|
||||
|
@ -349,7 +341,7 @@ component ColorModeColorAndApply {
|
|||
|
||||
component VerticalSpacer {
|
||||
width: 100%;
|
||||
height: Styles.small-margin;
|
||||
height: EditorSizeSettings.small-margin;
|
||||
}
|
||||
|
||||
component GradientSlider {
|
||||
|
@ -366,7 +358,7 @@ component GradientSlider {
|
|||
Rectangle {
|
||||
width: 24px;
|
||||
height: self.width;
|
||||
background: Styles.section-color;
|
||||
background: EditorPalette.section-color;
|
||||
border-radius: 5px;
|
||||
|
||||
TouchArea {
|
||||
|
@ -391,7 +383,7 @@ component GradientSlider {
|
|||
width: 10px;
|
||||
rotation-angle: 45deg;
|
||||
source: Icons.black-square;
|
||||
colorize: Styles.section-color;
|
||||
colorize: EditorPalette.section-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -409,10 +401,10 @@ component GradientStopValue {
|
|||
height: 30px;
|
||||
|
||||
Rectangle {
|
||||
x: Styles.standard-margin;
|
||||
x: EditorSizeSettings.standard-margin;
|
||||
width: 48px;
|
||||
border-radius: Styles.property-border-radius;
|
||||
background: Styles.section-color;
|
||||
border-radius: EditorSizeSettings.property-border-radius;
|
||||
background: EditorPalette.section-color;
|
||||
TextInput {
|
||||
x: 10px;
|
||||
height: 15px;
|
||||
|
@ -420,7 +412,7 @@ component GradientStopValue {
|
|||
horizontal-alignment: left;
|
||||
font-family: "Inter";
|
||||
font-size: 12px;
|
||||
color: Styles.text-color;
|
||||
color: EditorPalette.text-color;
|
||||
text: (PickerData.current-gradient-stops[stop-index].position * 100.0).round();
|
||||
text-cursor-width: 2px;
|
||||
selection-background-color: #3984ec;
|
||||
|
@ -476,8 +468,8 @@ component GradientStopValue {
|
|||
Rectangle {
|
||||
x: 70px;
|
||||
width: 140px;
|
||||
border-radius: Styles.property-border-radius;
|
||||
background: Styles.section-color;
|
||||
border-radius: EditorSizeSettings.property-border-radius;
|
||||
background: EditorPalette.section-color;
|
||||
|
||||
ColorIndicator {
|
||||
x: 5px;
|
||||
|
@ -498,7 +490,7 @@ component GradientStopValue {
|
|||
x: 35px;
|
||||
font-family: "Inter";
|
||||
font-size: 12px;
|
||||
color: Styles.text-color;
|
||||
color: EditorPalette.text-color;
|
||||
text: Api.color-to-data(PickerData.current-gradient-stops[stop-index].color).short-text.to-uppercase();
|
||||
letter-spacing: 0.8px;
|
||||
}
|
||||
|
@ -507,7 +499,7 @@ component GradientStopValue {
|
|||
x: parent.width - 45px;
|
||||
width: 1px;
|
||||
height: parent.height;
|
||||
background: Styles.background-color;
|
||||
background: Palette.background;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
@ -520,7 +512,7 @@ component GradientStopValue {
|
|||
horizontal-alignment: left;
|
||||
font-family: "Inter";
|
||||
font-size: 12px;
|
||||
color: Styles.text-color;
|
||||
color: EditorPalette.text-color;
|
||||
text: (PickerData.current-gradient-stops[stop-index].color.to-hsv().alpha * 100.0).round();
|
||||
text-cursor-width: 2px;
|
||||
selection-background-color: #3984ec;
|
||||
|
@ -580,8 +572,8 @@ component GradientPicker inherits SimpleColumn {
|
|||
height: 50px;
|
||||
|
||||
ComboBox {
|
||||
x: Styles.standard-margin;
|
||||
y: Styles.standard-margin;
|
||||
x: EditorSizeSettings.standard-margin;
|
||||
y: EditorSizeSettings.standard-margin;
|
||||
model: ["Linear", "Radial"];
|
||||
current-value: "Linear";
|
||||
}
|
||||
|
@ -591,11 +583,11 @@ component GradientPicker inherits SimpleColumn {
|
|||
height: 80px;
|
||||
|
||||
Rectangle {
|
||||
width: parent.width - (Styles.standard-margin * 2);
|
||||
width: parent.width - (EditorSizeSettings.standard-margin * 2);
|
||||
height: 30px;
|
||||
|
||||
Rectangle {
|
||||
border-radius: Styles.property-border-radius;
|
||||
border-radius: EditorSizeSettings.property-border-radius;
|
||||
clip: true;
|
||||
background: white;
|
||||
|
||||
|
@ -618,7 +610,7 @@ component GradientPicker inherits SimpleColumn {
|
|||
Rectangle {
|
||||
border-radius: parent.border-radius;
|
||||
border-width: 1px;
|
||||
border-color: Styles.text-color.with-alpha(10%);
|
||||
border-color: EditorPalette.text-color.with-alpha(10%);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -635,9 +627,9 @@ component GradientPicker inherits SimpleColumn {
|
|||
Rectangle {
|
||||
height: 50px;
|
||||
Text {
|
||||
x: Styles.standard-margin;
|
||||
y: Styles.standard-margin;
|
||||
color: Styles.text-color;
|
||||
x: EditorSizeSettings.standard-margin;
|
||||
y: EditorSizeSettings.standard-margin;
|
||||
color: EditorPalette.text-color;
|
||||
text: "Stops";
|
||||
font-family: "Inter";
|
||||
font-size: 11px;
|
||||
|
@ -648,14 +640,14 @@ component GradientPicker inherits SimpleColumn {
|
|||
y: 10px;
|
||||
width: 25px;
|
||||
height: self.width;
|
||||
background: t-plus.has-hover ? Styles.section-color : transparent;
|
||||
border-radius: Styles.property-border-radius;
|
||||
background: t-plus.has-hover ? EditorPalette.section-color : transparent;
|
||||
border-radius: EditorSizeSettings.property-border-radius;
|
||||
|
||||
t-plus := TouchArea { }
|
||||
|
||||
Image {
|
||||
source: Icons.plus;
|
||||
colorize: Styles.text-color;
|
||||
colorize: EditorPalette.text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -672,8 +664,8 @@ component HsvPicker inherits SimpleColumn {
|
|||
saturation-value-holder := Rectangle {
|
||||
height: self.width * 0.75;
|
||||
saturation-value := Rectangle {
|
||||
width: parent.width - (Styles.standard-margin * 2);
|
||||
height: parent.height - (Styles.standard-margin * 2);
|
||||
width: parent.width - (EditorSizeSettings.standard-margin * 2);
|
||||
height: parent.height - (EditorSizeSettings.standard-margin * 2);
|
||||
|
||||
Rectangle {
|
||||
border-radius: 6px;
|
||||
|
@ -693,7 +685,7 @@ component HsvPicker inherits SimpleColumn {
|
|||
Rectangle {
|
||||
border-radius: parent.border-radius;
|
||||
border-width: 1px;
|
||||
border-color: Styles.text-color.with-alpha(10%);
|
||||
border-color: EditorPalette.text-color.with-alpha(10%);
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
|
@ -743,7 +735,7 @@ component HsvPicker inherits SimpleColumn {
|
|||
// The following properties are used to size the hue picker and control the
|
||||
// thumb to now go past the visual bounds. But the TouchArea is intentionally larger
|
||||
// to be usable.
|
||||
property <length> main-width: root.width - (Styles.standard-margin * 2) - main-height;
|
||||
property <length> main-width: root.width - (EditorSizeSettings.standard-margin * 2) - main-height;
|
||||
property <length> main-height: 16px;
|
||||
property <length> rounded-end-width: main-height / 2;
|
||||
VerticalLayout {
|
||||
|
@ -752,8 +744,8 @@ component HsvPicker inherits SimpleColumn {
|
|||
width: 100%;
|
||||
height: 16px;
|
||||
hue-picker := Rectangle {
|
||||
x: Styles.standard-margin;
|
||||
width: root.width - (Styles.standard-margin * 2);
|
||||
x: EditorSizeSettings.standard-margin;
|
||||
width: root.width - (EditorSizeSettings.standard-margin * 2);
|
||||
height: main-height;
|
||||
TouchArea {
|
||||
moved => {
|
||||
|
@ -800,7 +792,7 @@ component HsvPicker inherits SimpleColumn {
|
|||
Rectangle {
|
||||
border-radius: parent.border-radius;
|
||||
border-width: 1px;
|
||||
border-color: Styles.text-color;
|
||||
border-color: EditorPalette.text-color;
|
||||
opacity: 10%;
|
||||
}
|
||||
}
|
||||
|
@ -833,7 +825,7 @@ component HsvPicker inherits SimpleColumn {
|
|||
width: 100%;
|
||||
height: 16px;
|
||||
Rectangle {
|
||||
x: Styles.standard-margin;
|
||||
x: EditorSizeSettings.standard-margin;
|
||||
width: main-width + main-height;
|
||||
height: main-height;
|
||||
Rectangle {
|
||||
|
@ -893,7 +885,7 @@ component HsvPicker inherits SimpleColumn {
|
|||
Rectangle {
|
||||
border-radius: parent.border-radius;
|
||||
border-width: 1px;
|
||||
border-color: Styles.text-color;
|
||||
border-color: EditorPalette.text-color;
|
||||
opacity: 10%;
|
||||
}
|
||||
}
|
||||
|
@ -947,7 +939,7 @@ component HsvPicker inherits SimpleColumn {
|
|||
height: 1px;
|
||||
x: 0;
|
||||
y: parent.height - self.height;
|
||||
background: Styles.divider-color;
|
||||
background: EditorPalette.divider-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -980,14 +972,14 @@ component ColorPicker inherits DraggablePanel {
|
|||
x: parent.width - self.width - 5px;
|
||||
width: 25px;
|
||||
height: self.width;
|
||||
background: t-close.has-hover ? Styles.section-color : transparent;
|
||||
border-radius: Styles.property-border-radius;
|
||||
background: t-close.has-hover ? EditorPalette.section-color : transparent;
|
||||
border-radius: EditorSizeSettings.property-border-radius;
|
||||
|
||||
t-close := TouchArea { }
|
||||
|
||||
Image {
|
||||
source: Icons.close;
|
||||
colorize: Styles.text-color;
|
||||
colorize: EditorPalette.text-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -996,7 +988,7 @@ component ColorPicker inherits DraggablePanel {
|
|||
height: 1px;
|
||||
x: 0;
|
||||
y: parent.height - self.height;
|
||||
background: Styles.divider-color;
|
||||
background: EditorPalette.divider-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1012,7 +1004,7 @@ component ColorPicker inherits DraggablePanel {
|
|||
|
||||
footer := Rectangle {
|
||||
width: 100%;
|
||||
height: Styles.standard-margin;
|
||||
height: EditorSizeSettings.standard-margin;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@ export component IntegerWidget inherits GridLayout {
|
|||
in property <string> property-name;
|
||||
in property <PropertyValue> property-value;
|
||||
|
||||
callback update-display-string(value: string);
|
||||
|
||||
callback test-integer-binding(text: string) -> bool;
|
||||
callback set-integer-binding(text: string);
|
||||
|
||||
|
@ -44,7 +46,8 @@ export component IntegerWidget inherits GridLayout {
|
|||
}
|
||||
|
||||
accepted(text) => {
|
||||
set-integer-binding(text);
|
||||
root.update-display-string(text);
|
||||
root.set-integer-binding(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,12 @@ import { Button } from "std-widgets.slint";
|
|||
|
||||
export component MultiValueWidget inherits GridLayout {
|
||||
in property <bool> enabled;
|
||||
in property <string> property-name;
|
||||
in property <string> property-name: preview-data.name;
|
||||
in property <PropertyValue> property-value;
|
||||
in property <PreviewData> preview-data;
|
||||
in property <string> property-group-name;
|
||||
in property <string> property-group-id;
|
||||
|
||||
callback edit-in-spreadsheet(property-group-name: string, data: PreviewData, values: [[PropertyValue]]);
|
||||
callback edit-in-table-editor(property-group-id: string, data: PreviewData);
|
||||
|
||||
spacing-vertical: EditorSpaceSettings.default-spacing;
|
||||
width: 100%;
|
||||
|
@ -37,7 +37,7 @@ export component MultiValueWidget inherits GridLayout {
|
|||
Button {
|
||||
text: preview-data.has-setter ? @tr("Edit") : @tr("View");
|
||||
clicked => {
|
||||
root.edit-in-spreadsheet(root.property-group-name, root.preview-data, [[ ]]);
|
||||
root.edit-in-table-editor(root.property-group-id, root.preview-data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ export component StringWidget inherits GridLayout {
|
|||
private property <bool> is-translated;
|
||||
private property <string> tr-context-value;
|
||||
|
||||
callback update-display-string(value: string);
|
||||
|
||||
callback code-action();
|
||||
callback reset-action();
|
||||
|
||||
|
@ -36,6 +38,7 @@ export component StringWidget inherits GridLayout {
|
|||
return test-string-binding(Api.string-to-code(text-rle.text, self.is-translated, self.tr-context-value, "", ""), self.is-translated);
|
||||
}
|
||||
function ssb() {
|
||||
update-display-string("\"\{text-rle.text}\"");
|
||||
set-string-binding(Api.string-to-code(text-rle.text, self.is-translated, self.tr-context-value, "", ""), self.is-translated);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,10 +14,9 @@ import { DrawAreaMode, PreviewView } from "./views/preview-view.slint";
|
|||
import { OutOfDateBox } from "./components/out-of-date-box.slint";
|
||||
import { PropertyView } from "./views/property-view.slint";
|
||||
import { PreviewDataView } from "./views/preview-data-view.slint";
|
||||
import { SpreadsheetDialog } from "./components/spreadsheet-dialog.slint";
|
||||
|
||||
import { WindowGlobal, WindowManager } from "windowglobal.slint";
|
||||
import { ColorPickerView, Styles as PickerStyles } from "components/widgets/floating-color-picker-widget.slint";
|
||||
import { TableEditorView } from "components/spreadsheet-dialog.slint";
|
||||
import "./assets/Inter-VariableFont.ttf";
|
||||
|
||||
export { Api }
|
||||
|
@ -34,6 +33,7 @@ export component PreviewUi inherits Window {
|
|||
property <bool> show-left-sidebar;
|
||||
property <bool> show-right-sidebar;
|
||||
property <bool> show-floating-widget <=> WindowManager.showing-color-picker;
|
||||
property <bool> show-floating-table-editor <=> WindowManager.showing-table-editor;
|
||||
property <length> initial-floating-x;
|
||||
|
||||
title: "Slint Live-Preview";
|
||||
|
@ -148,6 +148,13 @@ export component PreviewUi inherits Window {
|
|||
y: (parent.height / 10);
|
||||
}
|
||||
|
||||
if show-floating-table-editor: TableEditorView {
|
||||
init => {
|
||||
self.initial-x = root.initial-floating-x;
|
||||
self.initial-y = 50px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if show-floating-widget: ColorPickerView {
|
||||
init => {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
||||
|
||||
import { GradientStop } from "./api.slint";
|
||||
import { Api, GradientStop, PreviewData, PropertyValueTable } from "./api.slint";
|
||||
|
||||
export enum WidgetMode { edit, preview }
|
||||
|
||||
|
@ -26,4 +26,17 @@ export global PickerData {
|
|||
in-out property <brush> current-brush;
|
||||
in-out property <[GradientStop]> current-gradient-stops;
|
||||
in-out property <float> current-angle;
|
||||
}
|
||||
}
|
||||
|
||||
export global TableData {
|
||||
callback populate-table(property-group-id: string, preview-data: PreviewData);
|
||||
out property <string> property-group-id;
|
||||
out property <PreviewData> preview-data;
|
||||
out property <PropertyValueTable> current-table;
|
||||
|
||||
populate-table(property-group-id, preview-data) => {
|
||||
self.property-group-id = property-group-id;
|
||||
self.preview-data = preview-data;
|
||||
self.current-table = Api.get-property-value-table(property-group-id, preview-data.name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
|
||||
import { Palette, ScrollView, VerticalBox } from "std-widgets.slint";
|
||||
|
||||
import { Api, PropertyContainer } from "../api.slint";
|
||||
import { Api, PropertyContainer, PreviewData } from "../api.slint";
|
||||
import { ExpandableGroup } from "../components/expandable-group.slint";
|
||||
import { PreviewDataPropertyValueWidget } from "../components/property-widgets.slint";
|
||||
import { EditorSpaceSettings } from "../components/styling.slint";
|
||||
import { WindowManager } from "../windowglobal.slint";
|
||||
|
||||
export component PreviewDataView inherits ScrollView {
|
||||
|
||||
|
@ -45,6 +46,9 @@ export component PreviewDataView inherits ScrollView {
|
|||
for p in ep.properties: PreviewDataPropertyValueWidget {
|
||||
preview-data: p;
|
||||
property-container-id: ep.container-id;
|
||||
edit-in-table-editor(property-group-id, data) => {
|
||||
WindowManager.show-floating-table-editor(property-group-id, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
||||
|
||||
|
||||
|
||||
import { Api, BrushKind, ColorData, ElementInformation, GradientStop, PropertyInformation, PropertyValue, PropertyValueKind, PreviewData } from "./api.slint";
|
||||
import { StatusLineApi } from "components/status-line.slint";
|
||||
import { BrushMode, PickerData, PickerMode, WidgetMode } from "./properties-state.slint";
|
||||
|
||||
import { TableData } from "properties-state.slint";
|
||||
|
||||
export global WindowGlobal {
|
||||
in-out property <length> window-width;
|
||||
|
@ -15,19 +12,22 @@ export global WindowGlobal {
|
|||
|
||||
export global WindowManager {
|
||||
out property <bool> showing-color-picker: false;
|
||||
out property <bool> showing-table-editor: false;
|
||||
out property <WidgetMode> widget-mode: edit;
|
||||
out property <PickerMode> picker-mode: color;
|
||||
out property <BrushMode> brush-mode: color;
|
||||
|
||||
property <ElementInformation> current-element-information;
|
||||
out property <PropertyInformation> current-property-information;
|
||||
property <string> current-property-container-id;
|
||||
property <PreviewData> current-preview-data;
|
||||
in-out property <string> current-property-container-id;
|
||||
in-out property <PreviewData> current-preview-data;
|
||||
property <string> possible_error;
|
||||
property <string> brush-string;
|
||||
|
||||
callback show-floating-widget(PropertyInformation, ElementInformation);
|
||||
callback show-floating-preview-widget(property-container-id: string, preview-data: PreviewData, property-value: PropertyValue);
|
||||
callback show-floating-preview-brush-widget(property-container-id: string, preview-data: PreviewData, brush-kind: BrushKind, current-brush: brush, current-gradient-stops: [GradientStop]);
|
||||
callback show-floating-table-editor(property-group-id: string, preview-data: PreviewData);
|
||||
callback hide-floating-widget();
|
||||
callback apply-current-value(value: string);
|
||||
callback update-preview-value(value: string);
|
||||
|
@ -49,6 +49,7 @@ export global WindowManager {
|
|||
|
||||
hide-floating-widget => {
|
||||
showing-color-picker = false;
|
||||
showing-table-editor = false;
|
||||
current-element-information = { };
|
||||
current-property-information = { };
|
||||
widget-mode = WidgetMode.edit;
|
||||
|
@ -73,7 +74,7 @@ export global WindowManager {
|
|||
show-floating-preview-brush-widget(property-container-id, preview-data, brush-kind, current-brush, current-gradient-stops) => {
|
||||
widget-mode = WidgetMode.preview;
|
||||
picker-mode = PickerMode.brush;
|
||||
current-property-container-id = property-container-id;
|
||||
current-property-container-id = property-container-id;
|
||||
current-preview-data = preview-data;
|
||||
if brush-kind == BrushKind.solid {
|
||||
brush-mode = BrushMode.color;
|
||||
|
@ -87,6 +88,11 @@ export global WindowManager {
|
|||
showing-color-picker = true;
|
||||
}
|
||||
|
||||
show-floating-table-editor(property-group-id, preview-data) => {
|
||||
TableData.populate-table(property-group-id, preview-data);
|
||||
showing-table-editor = true;
|
||||
}
|
||||
|
||||
apply-current-value(text) => {
|
||||
Api.set-code-binding(
|
||||
current-element-information.source-uri,
|
||||
|
@ -102,14 +108,13 @@ export global WindowManager {
|
|||
StatusLineApi.help-text = self.possible-error;
|
||||
}
|
||||
|
||||
property <string> brush-string;
|
||||
update-brush() => {
|
||||
PickerData.current-brush = Api.create-brush(BrushKind.linear, 90.0, PickerData.current-brush, PickerData.current-gradient-stops);
|
||||
if widget-mode == WidgetMode.preview {
|
||||
brush-string = Api.as-slint-brush(BrushKind.linear, PickerData.current-angle, PickerData.current-brush, PickerData.current-gradient-stops);
|
||||
self.possible_error = Api.set-json-preview-data(current-property-container-id, current-preview-data.name, "\"\{brush-string}\"");
|
||||
|
||||
StatusLineApi.help-text = self.possible-error;
|
||||
StatusLineApi.help-text = self.possible-error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue