Loading files
c730ec352This file is pinned to the selected release. Download the original to open it in your design tool.
import { LibraryRuleCheckLink } from "libraryrulechecklink.slint";
import {
Button,
CategoryTreeLabel,
CheckBox,
ControlIconButton,
IconButton,
LineEdit,
LinkText,
ListViewItemButton,
OverlayDialog,
TreeView,
} from "../widgets.slint";
import {
Backend,
Data,
LibraryDependency,
LibraryElementCategoryData,
OrganizationPcbDesignRulesAction,
OrganizationPcbDesignRulesData,
PanelPage,
RuleCheckData,
TabAction,
TreeViewItemData,
} from "../api.slint";
component RowHeaderText inherits Text {
width: self.preferred-width;
vertical-alignment: center;
color: Data.theme.base-text;
accessible-role: none;
}
export component IconRowHeader inherits RowHeaderText {
text: @tr("Icon:");
}
export component IconRowCell inherits HorizontalLayout {
in property <image> icon;
in property <length> icon-height: 48px;
in property <bool> read-only: false;
property <bool> has-icon: icon.width > 0;
callback clicked <=> btn.clicked;
alignment: start;
spacing: 8px;
btn := IconButton {
height: icon-height;
style: hyperlink;
colorize: !has-icon;
icon-size: has-icon ? icon-height : 20px;
icon: {
if has-icon {
root.icon
} else {
@image-url("../../../bootstrap-icons/icons/folder2-open.svg")
}
};
enabled: !read-only;
}
if btn.has-hover: Text {
color: Data.theme.control-text-muted;
font-size: 11px;
vertical-alignment: center;
overflow: elide;
text: @tr("Click to change the icon.") + "\n" + @tr("Preferred:") + " PNG, 256x256 px";
accessible-role: none;
}
}
export component NameRowHeader inherits RowHeaderText {
text: @tr("Name:");
}
export component DescriptionRowHeader inherits RowHeaderText {
text: @tr("Description:");
}
export component KeywordsRowHeader inherits RowHeaderText {
text: @tr("Keywords:");
}
export component AuthorRowHeader inherits RowHeaderText {
text: @tr("Author:");
}
export component VersionRowHeader inherits RowHeaderText {
text: @tr("Version:");
}
export component DeprecatedRowHeader inherits RowHeaderText {
text: @tr("Deprecated:");
}
export component DeprecatedRowCell inherits CheckBox {
font-size: 11px;
focusable: true;
text: @tr("Check this if this library element should no longer be used.");
accessible-description: self.text;
}
export component UrlRowHeader inherits RowHeaderText {
text: @tr("URL:");
}
export component UrlRowCell inherits HorizontalLayout {
in property <string> url;
in property <string> url-error;
in property <string> placeholder-text;
in property <bool> read-only;
in property <string> label;
callback text-edited <=> edt.text-edited;
callback text-accepted <=> edt.text-accepted;
callback open-url-clicked(url: string);
open-url-clicked(url) => {
Backend.open-url(url);
}
spacing: 5px;
edt := LineEdit {
text: url;
validation-error: url-error;
placeholder-text: placeholder-text;
read-only: read-only;
accessible-label: label;
}
Rectangle {
horizontal-stretch: 0;
open-btn := IconButton {
height: 16px;
style: hyperlink;
status-tip: edt.text;
icon: @image-url("../../../font-awesome/svgs/solid/arrow-up-right-from-square.svg");
enabled: (!edt.text.is-empty) && url-error.is-empty;
clicked => {
open-url-clicked(edt.text);
}
}
}
}
export component DependenciesRowHeader inherits RowHeaderText {
text: @tr("Dependencies:");
}
export component DependenciesRowCell inherits VerticalLayout {
in-out property <[LibraryDependency]> model;
in property <bool> read-only: false;
callback add-dependency-clicked;
for item[idx] in model: item-ta := TouchArea {
height: item.checked ? 22px : 0;
if item.checked: HorizontalLayout {
padding-left: 3px;
padding-right: 3px;
spacing: 5px;
alignment: start;
Image {
y: (parent.height - self.height) / 2;
width: 18px;
height: self.width;
image-fit: contain;
source: item.icon;
accessible-role: none;
}
item-txt := Text {
vertical-alignment: center;
overflow: elide;
color: Data.theme.base-text;
text: item.name.is-empty ? item.uuid : item.name;
accessible-description: "dependency";
}
if (!read-only) && item-ta.has-hover: ListViewItemButton {
icon: @image-url("../../../font-awesome/svgs/solid/trash-can.svg");
icon-size: 14px;
clicked => {
model[idx].checked = false;
}
}
}
}
if !read-only: HorizontalLayout {
height: 22px;
padding-left: 1px;
padding-right: 3px;
spacing: 5px;
alignment: start;
add-dependency-btn := IconButton {
style: hyperlink;
icon-scale: 0.8;
icon: @image-url("../../../bootstrap-icons/icons/plus-circle.svg");
accessible-label: "add dependency";
clicked => {
add-dependency-clicked();
}
}
if add-dependency-btn.has-hover: Text {
color: Data.theme.base-text;
font-size: 11px;
vertical-alignment: center;
overflow: elide;
text: @tr("Add Dependency");
accessible-role: none;
}
}
}
export component ManufacturerRowHeader inherits RowHeaderText {
text: @tr("Manufacturer:");
}
export component ParentRowHeader inherits RowHeaderText {
text: @tr("Parent:");
}
export component ParentRowCell inherits HorizontalLayout {
in property <[string]> model;
in property <bool> read-only: false;
callback choose-parent-clicked;
alignment: start;
spacing: 5px;
tree-txt := CategoryTreeLabel {
names: model;
color: {
if read-only {
Data.theme.base-text-muted
} else {
Data.theme.base-text
}
};
accessible-description: "parent category";
}
Rectangle {
width: 20px;
}
if !read-only: Rectangle {
width: 1px;
background: Data.theme.base-border;
}
if !read-only: select-btn := IconButton {
y: (parent.height - self.height) / 2;
z: 10; // For the tooltip.
height: 18px;
style: hyperlink;
icon: @image-url("../../../bootstrap-icons/icons/folder2-open.svg");
tooltip: @tr("Choose Parent Category");
tooltip-position: right;
clicked => {
choose-parent-clicked();
}
}
}
export component CategoriesRowHeader inherits RowHeaderText {
text: @tr("Categories:");
}
component CategoriesListViewRow inherits TouchArea {
Rectangle {
height: self.preferred-height;
background: Data.theme.control;
border-color: Data.theme.control-border;
border-width: 1px;
HorizontalLayout {
padding: 2px;
padding-left: 4px;
padding-right: 4px;
spacing: 5px;
@children
}
}
}
export component CategoriesRowCell inherits HorizontalLayout {
in-out property <[LibraryElementCategoryData]> model;
in property <bool> read-only: false;
callback add-triggered();
alignment: start;
// Accessibility
accessible-role: list;
accessible-description: "";
accessible-item-count: model.length;
VerticalLayout {
horizontal-stretch: 0;
spacing: 5px;
for item[index] in model: item-ta := CategoriesListViewRow {
enabled: !read-only;
// Accessibility
accessible-role: list-item;
accessible-enabled: self.enabled;
accessible-label: item-txt.accessible-label;
accessible-item-index: index;
item-txt := CategoryTreeLabel {
names: item.names;
color: {
if read-only {
Data.theme.control-text-muted
} else {
Data.theme.control-text
}
};
accessible-role: none;
}
if !read-only: Rectangle {
width: 10px;
visible: item-ta.has-hover;
}
if !read-only: Rectangle {
width: 1px;
background: Data.theme.control-border;
visible: item-ta.has-hover;
}
if !read-only: item-remove-btn := ControlIconButton {
width: 16px;
style: hyperlink;
icon: @image-url("../../../font-awesome/svgs/solid/trash-can.svg");
visible: item-ta.has-hover;
clicked => {
model[index].delete = true;
}
}
}
if !read-only: add-ta := CategoriesListViewRow {
mouse-cursor: pointer;
// Accessibility
accessible-role: button;
accessible-label: add-txt.text;
accessible-action-default => {
self.clicked();
}
Image {
width: 16px;
height: self.width;
image-fit: contain;
colorize: add-txt.color;
source: @image-url("../../../bootstrap-icons/icons/plus-circle.svg");
accessible-role: none;
}
add-txt := Text {
color: parent.has-hover ? Data.theme.control-text : Data.theme.control-text-disabled.mix(Data.theme.control-text, 0.5);
vertical-alignment: center;
overflow: elide;
text: @tr("Add Category");
accessible-role: none;
}
clicked => {
add-triggered();
}
}
}
}
export component CategoriesChooserDialog inherits OverlayDialog {
in property <[TreeViewItemData]> model;
callback item-picked(index: int, item: TreeViewItemData);
ok-button: false;
view := TreeView {
model: model;
supports-expand: false;
icons-color: Data.theme.base-text;
item-selected(idx, item) => {
item-picked(idx, item);
}
}
init => {
self.focus();
}
}
export component AssemblyTypeRowHeader inherits RowHeaderText {
text: @tr("Assembly:");
}
export component DatasheetRowHeader inherits RowHeaderText {
text: @tr("Datasheet:");
}
export component DatasheetRowCell inherits UrlRowCell {
placeholder-text: @tr("URL to online datasheet (optional)");
}
export component SchematicOnlyRowHeader inherits RowHeaderText {
text: @tr("Schematic-Only:");
}
export component PrefixRowHeader inherits RowHeaderText {
text: @tr("Prefix:");
}
export component DefaultValueRowHeader inherits RowHeaderText {
text: @tr("Default Value:");
}
export component AttributesRowHeader inherits RowHeaderText {
text: @tr("Attributes:");
}
export component PriorityRowHeader inherits RowHeaderText {
text: @tr("Priority:");
}
export component PcbDesignRulesRowHeader inherits RowHeaderText {
text: @tr("PCB Design Rules:");
}
export component PcbDesignRulesRowCell inherits VerticalLayout {
in-out property <[OrganizationPcbDesignRulesData]> model;
in property <bool> read-only: false;
callback add-clicked;
for item[idx] in model: item-ta := TouchArea {
height: 20px;
HorizontalLayout {
alignment: start;
item-btn := LinkText {
vertical-alignment: center;
overflow: elide;
text: "• " + item.name;
accessible-description: "PCB design rules";
clicked => {
model[idx].action = OrganizationPcbDesignRulesAction.edit;
}
}
Rectangle {
width: 5px;
}
if (!read-only) && item-ta.has-hover: rename-btn := ListViewItemButton {
icon: @image-url("../../../font-awesome/svgs/solid/pen-to-square.svg");
icon-size: 12px;
clicked => {
model[idx].action = OrganizationPcbDesignRulesAction.rename;
}
}
if (!read-only) && item-ta.has-hover: duplicate-btn := ListViewItemButton {
icon: @image-url("../../../font-awesome/svgs/solid/copy.svg");
icon-size: 12px;
clicked => {
model[idx].action = OrganizationPcbDesignRulesAction.duplicate;
}
}
if (!read-only) && item-ta.has-hover: delete-btn := ListViewItemButton {
icon: @image-url("../../../font-awesome/svgs/solid/trash-can.svg");
icon-size: 12px;
clicked => {
model[idx].action = OrganizationPcbDesignRulesAction.delete;
}
}
}
}
if !read-only: HorizontalLayout {
alignment: start;
new-btn := LinkText {
vertical-alignment: center;
overflow: elide;
text-color: Data.theme.base-text-muted;
text-color-hovered: Data.theme.base-text;
text: "+ " + @tr("New Design Rules");
clicked => {
add-clicked();
}
}
}
}
export component PcbOutputJobsRowHeader inherits RowHeaderText {
text: @tr("PCB Service:");
}
export component AssemblyOutputJobsRowHeader inherits RowHeaderText {
text: @tr("Assembly Service:");
}
export component MetadataFooterRowCell inherits HorizontalLayout {
in property <int> section-index;
in property <int> tab-index;
in property <bool> wizard-mode: false;
in property <bool> show-back-button: false;
in property <bool> unsaved-changes: false;
in property <RuleCheckData> checks;
in property <bool> read-only: false;
alignment: start;
spacing: 8px;
if !read-only: save-btn := Button {
width: max(self.preferred-width, 100px);
primary: wizard-mode || unsaved-changes;
icon: {
if wizard-mode {
@image-url("../../../font-awesome/svgs/solid/angle-right.svg")
} else {
@image-url("../../../font-awesome/svgs/solid/check.svg")
}
};
text: wizard-mode ? @tr("Next") : @tr("Save");
clicked => {
Backend.trigger-tab(section-index, tab-index, wizard-mode ? TabAction.next : TabAction.save);
}
}
if wizard-mode && show-back-button: back-btn := Button {
width: max(self.preferred-width, 100px);
icon: @image-url("../../../font-awesome/svgs/solid/angle-left.svg");
text: @tr("Back");
clicked => {
Backend.trigger-tab(section-index, tab-index, TabAction.back);
}
}
if !wizard-mode: LibraryRuleCheckLink {
data: checks;
clicked => {
Data.set-current-tab(section-index, tab-index);
Data.panel-page = PanelPage.rule-check;
}
}
}