Loading files
import {
IconButton,
ListScrollView,
ListViewItemButton,
PanelHeader,
} from "widgets.slint";
import {
BoardAction,
Data,
GraphicsLayerAction,
GraphicsLayerData,
Helpers,
TabAction,
TabType,
} from "api.slint";
component GraphicsLayerListItem inherits Rectangle {
in-out property <[GraphicsLayerData]> model;
in property <int> index;
in property <bool> enabled: true;
in property <bool> is-current: false;
in property <color> background-color;
property <GraphicsLayerData> item: model[index];
callback selected;
background: {
/*if item.disabled {
Data.theme.control-checked
} else */if is-current {
Data.theme.control-hovered
} else if ta.has-hover {
Data.theme.control-hovered
} else {
transparent
}
};
// Accessibility
accessible-role: list-item;
accessible-enabled: enabled;
accessible-label: item.name;
accessible-item-selectable: true;
//accessible-item-selected: item.focused;
accessible-item-index: index;
accessible-action-default => {
visible-btn.clicked();
}
// Color box
Rectangle {
x: 0;
y: 0;
width: self.height;
height: 100%;
background: background-color;
Rectangle {
background: item.color;
}
}
ta := TouchArea {
enabled: enabled;
HorizontalLayout {
padding: 3px;
padding-left: 27px;
padding-right: 5px;
spacing: 5px;
visible-btn := ListViewItemButton {
z: 10; // For the tooltip.
icon: {
if item.visible {
@image-url("../../bootstrap-icons/icons/eye-fill.svg")
} else {
@image-url("../../bootstrap-icons/icons/eye-slash-fill.svg")
}
};
tooltip: @tr("Toggle Visibility");
tooltip-side: right;
enabled: root.enabled;
colorize: {
if !root.enabled {
Data.theme.control-text-disabled
} else if item.visible {
Data.theme.control-text
} else if self.has-hover {
Data.theme.control-text.mix(Data.theme.control-text-muted, 0.5)
} else {
Data.theme.control-text-muted
}
};
clicked => {
model[index].visible = !item.visible;
}
}
txt := Text {
vertical-alignment: center;
font-size: 12px;
overflow: elide;
color: (root.enabled && item.visible && (!item.disabled)) ? Data.theme.control-text : Data.theme.control-text-muted;
text: item.name;
if !item.visible: Rectangle {
x: 0;
width: parent.preferred-width;
background: parent.color;
height: 1px;
}
}
if item.is-focused: disabled-btn := ListViewItemButton {
z: 10; // For the tooltip.
icon: @image-url("../../bootstrap-icons/icons/star-fill.svg");
tooltip-side: left;
enabled: false;
colorize: {
if !root.enabled {
Data.theme.control-text-disabled
} else if item.visible {
Data.theme.control-text
} else if self.has-hover {
Data.theme.control-text.mix(Data.theme.control-text-muted, 0.5)
} else {
Data.theme.control-text-muted
}
};
//clicked => {
// model[index].disabled = !item.disabled;
//}
}
}
pointer-event(event) => {
if (event.button == PointerEventButton.left) && (event.kind == PointerEventKind.down) {
if item.is-focused || event.modifiers.control {
model[index].disabled = !model[index].disabled;
} else {
model[index].action = GraphicsLayerAction.focus;
}
}
root.selected();
}
double-clicked => {
model[index].action = GraphicsLayerAction.show;
}
}
}
export component GraphicsLayersPanel inherits FocusScope {
property <length> item-height: 22px;
in-out property <[GraphicsLayerData]> model: Data.current-tab.layers;
property <int> current-index: -1;
property <color> background-color: {
if Data.current-tab.type == TabType.board-2d {
Data.current-board-2d-tab.background-color
} else if Data.current-tab.type == TabType.package {
Data.current-package-tab.background-color
} else {
Data.theme.base;
}
};
function set-current-index(index: int) {
if ((index + 1) * item-height) > (view.height - view.viewport-y) {
view.viewport-y = -(index + 1) * item-height + view.height;
} else if (index * item-height) < -(view.viewport-y) {
view.viewport-y = -(index * item-height);
}
current-index = index;
}
// Set focus when panel is shown. Not sure if it's always desired(?).
init => {
root.focus();
}
VerticalLayout {
header := PanelHeader {
z: 10; // For the tooltip.
title: @tr("Layers").to-uppercase();
highlight: root.has-focus;
top-btn := IconButton {
width: self.height;
icon: @image-url("../../bootstrap-icons/icons/front.svg");
icon-scale: 0.6;
tooltip: @tr("Top Layers");
clicked => {
Helpers.trigger-current-tab-action(TabAction.layers-top);
}
}
bot-btn := IconButton {
width: self.height;
icon: @image-url("../../bootstrap-icons/icons/back.svg");
icon-scale: 0.6;
tooltip: @tr("Bottom Layers");
clicked => {
Helpers.trigger-current-tab-action(TabAction.layers-bottom);
}
}
top-bot-btn := IconButton {
width: self.height;
icon: @image-url("../../bootstrap-icons/icons/union.svg");
icon-scale: 0.6;
tooltip: @tr("Top + Bottom Layers");
clicked => {
Helpers.trigger-current-tab-action(TabAction.layers-top-bottom);
}
}
show-all-btn := IconButton {
width: self.height;
icon: @image-url("../../bootstrap-icons/icons/eye-fill.svg");
icon-scale: 0.7;
tooltip: @tr("Show All");
clicked => {
Helpers.trigger-current-tab-action(TabAction.layers-all);
}
}
hide-all-btn := IconButton {
width: self.height;
icon: @image-url("../../bootstrap-icons/icons/eye-slash-fill.svg");
icon-scale: 0.7;
tooltip: @tr("Hide All");
clicked => {
Helpers.trigger-current-tab-action(TabAction.layers-none);
}
}
layer-setup-btn := IconButton {
width: self.height;
icon: @image-url("../../font-awesome/svgs/solid/sliders.svg");
icon-scale: 0.7;
tooltip: @tr("Layer Setup");
clicked => {
Helpers.trigger-current-board-action(BoardAction.open-setup-dialog);
}
}
}
view := ListScrollView {
vertical-stretch: 1;
preferred-height: model.length * item-height;
viewport-height: model.length * item-height;
visible: model.length > 0;
force-show-scrollbars: root.has-focus;
for layer[index] in model: item := GraphicsLayerListItem {
height: item-height;
model: model;
index: index;
is-current: (index == current-index);
background-color: background-color;
selected => {
set-current-index(index);
root.focus();
}
}
}
}
key-pressed(event) => {
if (event.text == Key.DownArrow) && (current-index < model.length - 1) {
set-current-index(current-index + 1);
return accept;
} else if (event.text == Key.UpArrow) && (current-index > 0) {
set-current-index(current-index - 1);
return accept;
} else if (current-index >= 0) && (current-index < model.length) {
if event.text == Key.Space {
model[current-index].visible = !model[current-index].visible;
return accept;
}
}
reject
}
}
ce705b508This file is pinned to the selected release. Download the original to open it in your design tool.