Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
c43996719This file is pinned to the selected release. Download the original to open it in your design tool.
import "../../../share/librepcb/fonts/NotoSans-Light.ttf";
import "../../../share/librepcb/fonts/NotoSans-LightItalic.ttf";
import "../../../share/librepcb/fonts/NotoSans-Regular.ttf";
import "../../../share/librepcb/fonts/NotoSans-Italic.ttf";
import "../../../share/librepcb/fonts/NotoSans-Bold.ttf";
import "../../../share/librepcb/fonts/NotoSans-BoldItalic.ttf";
import "../../../share/librepcb/fonts/NotoSansMono-Regular.ttf";
import { MainMenuBar } from "mainmenubar.slint";
import { SideBar } from "sidebar.slint";
import { HomePanel } from "homepanel.slint";
import { DocumentsPanel } from "documentspanel.slint";
import { GraphicsLayersPanel } from "graphicslayerspanel.slint";
import { PlaceDevicesPanel } from "project/placedevicespanel.slint";
import { RuleCheckPanel } from "rulecheckpanel.slint";
import { OrderPanel } from "project/orderpanel.slint";
import { LibrariesPanel } from "library/librariespanel.slint";
import { AboutPanel } from "aboutpanel.slint";
import { WindowSection } from "windowsection.slint";
import { StatusBar } from "statusbar.slint";
import {
Backend,
Data,
EditorCommandSet as Cmd,
FeatureState,
PanelPage,
Shortcuts,
} from "api.slint";
export component AppWindow inherits Window {
property <length> default-panel-width: min(self.width * ((Data.sections.length > 1) ? 0.25 : 0.3), 350px);
property <length> panel-width: clamp(default-panel-width * Data.panel-width-factor, 50px, root.width - 200px);
property <length> actual-panel-width: (Data.panel-page != PanelPage.none) ? panel-width : 0;
title: Data.window-title;
background: Data.theme.window;
icon: @image-url("../../../img/app/librepcb.svg");
default-font-family: "Noto Sans";
preferred-width: 1024px;
preferred-height: 768px;
forward-focus: fs;
fs := FocusScope {
// This is an ugly hack to not make any undesired element having the
// focus after application startup. The preview-mode is true at the
// beginning, so this focus scope will be focused initially. But the
// property changes to false during application startup which seems
// to keep the focus here.
enabled: Data.preview-mode;
focus-on-tab-navigation: false;
key-pressed(event) => {
if menubar.menu-expanded && (event.text == Key.Escape) {
menubar.close-menu();
return accept;
} else if Shortcuts.process(event) {
return accept;
} else if Backend.is-shortcut(event, Cmd.find) && (Data.current-tab.features.find == FeatureState.enabled) {
menubar.focus-search();
return accept;
} else if Backend.is-shortcut(event, Cmd.grid-properties) && (Data.current-tab.features.grid == FeatureState.enabled) {
statusbar.focus-grid-interval();
return accept;
}
reject
}
menubar := MainMenuBar {
x: 0;
y: 0;
z: 200; // For the tooltips.
width: 100%;
height: 26px;
window-height: root.height;
sections-start-x: sidebar.width + actual-panel-width;
focus-root => {
fs.focus();
}
focus-grid-interval => {
statusbar.focus-grid-interval();
}
}
Rectangle {
x: 0;
y: menubar.height;
width: sidebar.width;
height: 1px;
background: Data.theme.base-border;
}
sidebar := SideBar {
x: 0px;
y: menubar.height + 1px;
z: 90; // For the tooltips.
width: ((root.width <= 1200px) || (root.height <= 600px)) ? 35px : 45px;
height: parent.height - self.y - statusbar.height;
}
Rectangle {
x: sidebar.width;
y: sidebar.y;
width: 1px;
height: sidebar.height;
background: Data.theme.base-border;
}
panel := Rectangle {
x: sidebar.width + 1px;
y: sidebar.y - 1px;
z: 80; // For the tooltips.
width: panel-width;
height: sidebar.height;
background: Data.theme.control;
visible: Data.panel-page != PanelPage.none;
TouchArea {
// Note: This touch area goes only to the *right* of the panel,
// to avoid overlapping the panel content. And the width of 5px
// is just enough to allow grabbing the handle even if there's
// a scrollbar in the panel (which have a TouchArea that
// overflows the side panel by 4px).
x: panel.width;
width: self.has-hover ? 10px : 5px;
mouse-cursor: MouseCursor.col-resize;
if self.has-hover || self.pressed: Rectangle {
x: 0;
width: 1px;
background: Data.theme.base-text-disabled;
opacity: 0.7;
}
property <float> previous-panel-width-factor;
property <PanelPage> previous-panel-page;
pointer-event(event) => {
if (event.button == PointerEventButton.left) && (event.kind == PointerEventKind.down) {
previous-panel-page = Data.panel-page;
previous-panel-width-factor = Data.panel-width-factor;
} else if self.pressed && (event.kind == PointerEventKind.move) {
if (self.x + self.mouse-x) > 50px {
Data.panel-page = previous-panel-page;
Data.panel-width-factor = max(self.x + self.mouse-x, 100px) / default-panel-width;
} else if Data.panel-page != PanelPage.none {
Data.panel-page = PanelPage.none;
Data.panel-width-factor = previous-panel-width-factor;
}
}
}
}
if Data.panel-page == PanelPage.home: home-panel := HomePanel { }
if Data.panel-page == PanelPage.documents: documents-panel := DocumentsPanel { }
if Data.panel-page == PanelPage.layers: GraphicsLayersPanel { }
if Data.panel-page == PanelPage.place-devices: PlaceDevicesPanel {
window-height: root.height;
}
if Data.panel-page == PanelPage.rule-check: RuleCheckPanel { }
if Data.panel-page == PanelPage.order: OrderPanel { }
if Data.panel-page == PanelPage.libraries: LibrariesPanel { }
if Data.panel-page == PanelPage.about: AboutPanel { }
}
HorizontalLayout {
x: panel.x + actual-panel-width;
y: sidebar.y - 1px;
width: parent.width - self.x;
height: sidebar.height;
if actual-panel-width > 0: Rectangle {
background: Data.theme.base-border;
width: 1px;
}
for section[i] in Data.sections: HorizontalLayout {
window-section := WindowSection {
section-index: i;
section: section;
window-height: root.height;
}
if i < (Data.sections.length - 1): Rectangle {
width: 1px;
horizontal-stretch: 0;
background: Data.theme.base-border;
}
}
}
Rectangle {
y: statusbar.y - 1px;
height: 1px;
background: Data.theme.base-border;
}
statusbar := StatusBar {
x: 0;
y: parent.height - self.height;
z: 100; // Avoid sidebar to be painted on statusbar if window is small.
width: parent.width;
focus-root => {
fs.focus();
}
}
}
}