Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
import { DrawWireToolBar } from "drawwiretoolbar.slint";
import { DrawPolygonToolBar } from "drawpolygontoolbar.slint";
import { AddTextToolBar } from "addtexttoolbar.slint";
import { AddComponentToolBar } from "addcomponenttoolbar.slint";
import { Tab } from "../../tab.slint";
import {
Button,
LinkText,
MenuItem,
MenuPopup,
MenuSeparator,
MessageBox,
SceneButton,
TextInput,
ToolBar,
ToolButton,
ToolButtonGroup,
} from "../../widgets.slint";
import {
Backend,
Constants,
Data,
DismissableMessageAction,
EditorCommandSet as Cmd,
EditorTool,
PanelPage,
ProjectData,
SchematicTabData,
TabAction,
WindowSectionData,
} from "../../api.slint";
export component SchematicTab inherits Tab {
in property <int> section-index;
in-out property <WindowSectionData> section;
property <[SchematicTabData]> tabs: section.schematic-tabs;
property <int> index: section.current-tab-index;
property <ProjectData> project: Data.projects[tabs[index].project-index];
property <length> toolbar-space: view-buttons-l.x - toolbuttons-l.x - toolbuttons-l.width - 10px;
property <length> toolbutton-offset-y: (toolbar-r.width > toolbar-space) ? toolbar-r.height : 0;
property <EditorTool> tool: tabs[index].tool;
function tool-triggered(action: TabAction) {
Data.set-current-tab(section-index, index);
Backend.trigger-tab(section-index, index, action);
}
enabled: true;
function update-tab-data() {
tabs[index].scene-image-pos = self.absolute-position;
}
init => {
update-tab-data();
}
// Needed for https://github.com/LibrePCB/LibrePCB/issues/1725.
changed section-index => {
update-tab-data();
}
// Needed for https://github.com/LibrePCB/LibrePCB/issues/1725.
changed index => {
update-tab-data();
}
changed absolute-position => {
update-tab-data();
}
// When the tool changes, move focus to scene to make tabulator & escape
// working correctly.
changed tool => {
root.focus();
}
if Data.preview-mode: Rectangle {
background: white;
}
img := Image {
width: 100%;
height: 100%;
source: Backend.render-scene(section-index, root.width, root.height, 0, tabs[index].frame);
accessible-role: none;
}
ta := TouchArea {
mouse-cursor: tabs[index].tool-cursor;
// Show overlay, if text is not empty.
if !tabs[index].tool-overlay-text.is-empty: Rectangle {
x: 2 * toolbuttons-l.x + toolbuttons-l.width;
y: toolbuttons-l.y;
width: min(self.preferred-width, 0.5 * parent.width);
height: self.preferred-height;
background: Data.theme.control;
border-radius: 3px;
border-width: 1px;
border-color: Data.theme.control-border;
clip: true;
VerticalLayout {
padding: 6px;
overlay-txt := TextInput {
horizontal-alignment: left;
vertical-alignment: top;
font-family: "Noto Sans Mono";
color: Data.theme.control-text;
text: tabs[index].tool-overlay-text;
read-only: true;
}
}
}
toolbar-r := ToolBar {
y: -1px;
width: min(self.preferred-width, root.width - 10px);
visible: self.width > 30px;
if tabs[index].tool == EditorTool.wire: wire-toolbar := DrawWireToolBar {
section-index: section-index;
section: section;
}
if tabs[index].tool == EditorTool.bus: bus-toolbar := DrawWireToolBar {
section-index: section-index;
section: section;
}
if tabs[index].tool == EditorTool.polygon: polygon-toolbar := DrawPolygonToolBar {
section-index: section-index;
section: section;
}
if tabs[index].tool == EditorTool.text: text-toolbar := AddTextToolBar {
section-index: section-index;
section: section;
}
if tabs[index].tool == EditorTool.component: component-toolbar := AddComponentToolBar {
section-index: section-index;
section: section;
}
}
if tabs[index].tool == EditorTool.select: VerticalLayout {
width: min(self.preferred-width, 0.7 * parent.width, 550px);
padding: 20px;
spacing: 10px;
if tabs[index].install-libraries-msg.visible: install-libraries-msg := MessageBox {
title: @tr("No Libraries Installed");
supports-dont-show-again: tabs[index].install-libraries-msg.supports-dont-show-again;
Text {
wrap: word-wrap;
color: parent.text-color;
text: @tr("In order to add components to this schematic, you first need to install some part libraries or create parts by yourself in your own library.");
}
install-libraries-btn := Button {
border-radius: self.height / 2;
primary: true;
text: @tr("Install Libraries");
clicked => {
Data.panel-page = PanelPage.libraries;
}
}
HorizontalLayout {
alignment: start;
install-libraries-help-btn := LinkText {
text-color: install-libraries-msg.text-color;
text-color-hovered: install-libraries-msg.hover-color;
wrap: word-wrap;
text: "▸ " + @tr("Learn how to create parts by yourself");
status-tip: Constants.user-manual-create-local-library-url;
clicked => {
Backend.open-url(self.status-tip);
}
}
}
dismiss-clicked => {
tabs[index].install-libraries-msg.action = DismissableMessageAction.dismiss;
}
dont-show-again-clicked => {
tabs[index].install-libraries-msg.action = DismissableMessageAction.dont-show-again;
}
}
if tabs[index].add-drawing-frame-msg.visible: add-drawing-frame-msg := MessageBox {
title: @tr("Get Started");
supports-dont-show-again: tabs[index].add-drawing-frame-msg.supports-dont-show-again;
Text {
wrap: word-wrap;
color: parent.text-color;
text: @tr("It's recommended to start a new schematic with adding a drawing frame to it. Then add other components the usual way with the toolbar at the left.");
}
add-drawing-frame-btn := Button {
border-radius: self.height / 2;
primary: true;
text: @tr("Add Drawing Frame");
clicked => {
tool-triggered(TabAction.tool-component-frame);
}
}
HorizontalLayout {
alignment: start;
add-drawing-frame-help-btn := LinkText {
text-color: add-drawing-frame-msg.text-color;
text-color-hovered: add-drawing-frame-msg.hover-color;
wrap: word-wrap;
text: "▸ " + @tr("Learn how to create schematics");
status-tip: Constants.user-manual-create-schematics-url;
clicked => {
Backend.open-url(self.status-tip);
}
}
}
dismiss-clicked => {
tabs[index].add-drawing-frame-msg.action = DismissableMessageAction.dismiss;
}
dont-show-again-clicked => {
tabs[index].add-drawing-frame-msg.action = DismissableMessageAction.dont-show-again;
}
}
}
toolbuttons-l := VerticalLayout {
x: 7px;
y: 7px + toolbutton-offset-y;
width: self.preferred-width;
height: parent.height - 2 * self.y;
alignment: start;
spacing: 5px;
tool-select-btn := ToolButton {
cmd: Cmd.tool-select;
checked: tabs[index].tool == EditorTool.select;
clicked => {
tool-triggered(TabAction.tool-select);
}
}
ToolButtonGroup {
tool-wire-btn := ToolButton {
cmd: Cmd.tool-wire;
icon: @image-url("../../../../../img/actions/draw_wire.png");
checked: tabs[index].tool == EditorTool.wire;
is-last: false;
clicked => {
tool-triggered(TabAction.tool-wire);
}
}
tool-bus-btn := ToolButton {
cmd: Cmd.tool-bus;
icon: @image-url("../../../../../img/actions/draw_bus.png");
has-menu: project.buses.length > 0;
checked: tabs[index].tool == EditorTool.bus;
is-first: false;
is-last: false;
clicked => {
tool-triggered(TabAction.tool-bus);
}
right-clicked => {
if project.buses.length > 0 {
buses-popup.show();
}
}
buses-popup := MenuPopup {
x: parent.width + 5px;
y: 0;
for bus in project.buses: tool-bus-existing-item := MenuItem {
text: bus.name;
icon: @image-url("../../../../font-awesome/svgs/solid/angle-right.svg");
clicked => {
tabs[index].new-bus-uuid = bus.uuid;
}
}
}
}
tool-label-btn := ToolButton {
cmd: Cmd.tool-label;
checked: tabs[index].tool == EditorTool.label;
is-first: false;
clicked => {
tool-triggered(TabAction.tool-label);
}
}
}
ToolButtonGroup {
tool-polygon-btn := ToolButton {
cmd: Cmd.tool-polygon;
checked: tabs[index].tool == EditorTool.polygon;
is-last: false;
clicked => {
tool-triggered(TabAction.tool-polygon);
}
}
tool-text-btn := ToolButton {
cmd: Cmd.tool-text;
checked: tabs[index].tool == EditorTool.text;
is-first: false;
is-last: false;
clicked => {
tool-triggered(TabAction.tool-text);
}
}
tool-image-btn := ToolButton {
cmd: Cmd.tool-image;
checked: tabs[index].tool == EditorTool.image;
is-first: false;
clicked => {
tool-triggered(TabAction.tool-image);
}
}
}
ToolButtonGroup {
tool-component-btn := ToolButton {
cmd: Cmd.tool-component;
checked: tabs[index].tool == EditorTool.component;
is-last: !Data.workspace-contains-standard-components;
clicked => {
tool-triggered(TabAction.tool-component);
}
}
if Data.workspace-contains-standard-components: VerticalLayout {
tool-resistor-btn := ToolButton {
cmd: Cmd.component-resistor;
icon: {
if project.ieee315-symbols {
@image-url("../../../../../img/resistor-us.svg")
} else {
@image-url("../../../../../img/resistor-eu.svg")
}
}
is-first: false;
is-last: false;
clicked => {
tool-triggered(TabAction.tool-component-resistor);
}
}
tool-inductor-btn := ToolButton {
cmd: Cmd.component-inductor;
icon: {
if project.ieee315-symbols {
@image-url("../../../../../img/inductor-us.svg")
} else {
@image-url("../../../../../img/inductor-eu.svg")
}
}
is-first: false;
is-last: false;
clicked => {
tool-triggered(TabAction.tool-component-inductor);
}
}
tool-bipolar-btn := ToolButton {
cmd: Cmd.component-capacitor-bipolar;
icon: {
if project.ieee315-symbols {
@image-url("../../../../../img/capacitor-bipolar-us.svg")
} else {
@image-url("../../../../../img/capacitor-bipolar-eu.svg")
}
}
is-first: false;
is-last: false;
clicked => {
tool-triggered(TabAction.tool-component-capacitor-bipolar);
}
}
tool-unipolar-btn := ToolButton {
cmd: Cmd.component-capacitor-unipolar;
icon: {
if project.ieee315-symbols {
@image-url("../../../../../img/capacitor-unipolar-us.svg")
} else {
@image-url("../../../../../img/capacitor-unipolar-eu.svg")
}
}
is-first: false;
is-last: false;
clicked => {
tool-triggered(TabAction.tool-component-capacitor-unipolar);
}
}
tool-vcc-btn := ToolButton {
cmd: Cmd.component-vcc;
icon: @image-url("../../../../../img/vcc.svg");
is-first: false;
is-last: false;
clicked => {
tool-triggered(TabAction.tool-component-vcc);
}
}
tool-gnd-btn := ToolButton {
cmd: Cmd.component-gnd;
icon: @image-url("../../../../../img/gnd.svg");
is-first: false;
clicked => {
tool-triggered(TabAction.tool-component-gnd);
}
}
}
}
tool-measure-btn := ToolButton {
cmd: Cmd.tool-measure;
checked: tabs[index].tool == EditorTool.measure;
clicked => {
tool-triggered(TabAction.tool-measure);
}
}
}
view-buttons-l := VerticalLayout {
x: parent.width - self.preferred-width - 7px;
y: toolbutton-offset-y + 7px;
width: self.preferred-width;
zoom-fit-btn := SceneButton {
icon: @image-url("../../../../font-awesome/svgs/solid/expand.svg");
icon-scale: 0.9;
base-color: tabs[index].background-color;
base-text-color: tabs[index].foreground-color;
clicked => {
Backend.trigger-tab(section-index, index, TabAction.zoom-fit);
}
}
zoom-in-btn := SceneButton {
icon: @image-url("../../../../bootstrap-icons/icons/zoom-in.svg");
base-color: tabs[index].background-color;
base-text-color: tabs[index].foreground-color;
clicked => {
Backend.trigger-tab(section-index, index, TabAction.zoom-in);
}
}
zoom-out-btn := SceneButton {
icon: @image-url("../../../../bootstrap-icons/icons/zoom-out.svg");
base-color: tabs[index].background-color;
base-text-color: tabs[index].foreground-color;
clicked => {
Backend.trigger-tab(section-index, index, TabAction.zoom-out);
}
}
show-pins-btn := SceneButton {
icon: @image-url("../../../../bootstrap-icons/icons/123.svg");
icon-scale: 0.9;
tooltip: @tr("Pin Numbers");
base-color: tabs[index].background-color;
base-text-color: tabs[index].foreground-color;
style: checkbox;
checked: tabs[index].show-pin-numbers;
clicked => {
tabs[index].show-pin-numbers = !self.checked;
}
}
}
pointer-event(event) => {
if event.kind == PointerEventKind.down {
Data.set-current-tab(section-index, index);
if !root.has-focus {
root.focus();
}
}
Backend.scene-pointer-event(section-index, self.mouse-x, self.mouse-y, event, 0);
}
scroll-event(event) => {
Backend.scene-scrolled(section-index, self.mouse-x, self.mouse-y, event, 0) ? accept : reject
}
}
focus-gained(reason) => {
Data.set-current-tab(section-index, index);
}
key-pressed(event) => {
// If the focus is in the command toolbar, make the Escape key moving
// the focus back to the graphics scene without triggering any action.
if (event.text == Key.Escape) && (!root.has-focus) {
root.focus();
return accept;
}
reject
}
key-released(event) => {
Backend.scene-key-released(section-index, event) ? accept : reject
}
}
94ec4b8feThis file is pinned to the selected release. Download the original to open it in your design tool.