mirror of
https://github.com/hulthe/inkopslista.git
synced 2026-09-18 18:03:39 +02:00
favourite buttons are based on how often a good i added to list finished implementing setting category made number of days until button an environment variable rebase on main and fix ran cargo fmt
369 lines
8.2 KiB
Plaintext
369 lines
8.2 KiB
Plaintext
import {
|
|
TabWidget,
|
|
AboutSlint,
|
|
Button,
|
|
LineEdit,
|
|
ListView,
|
|
CheckBox,
|
|
ScrollView,
|
|
GridBox,
|
|
HorizontalBox,
|
|
ComboBox,
|
|
Palette, Spinner, SpinBox,
|
|
} from "std-widgets.slint";
|
|
import { SettingsView } from "settings.slint";
|
|
import { ConnectionStatus, State, SItem, SButtonItem } from "state.slint";
|
|
export { ConnectionStatus, State, SItem }
|
|
|
|
component GoodListItem inherits Rectangle {
|
|
in-out property <SItem> item;
|
|
background: Palette.alternate-background;
|
|
border-radius: 8pt;
|
|
border-width: 10pt;
|
|
HorizontalLayout {
|
|
spacing: 8px;
|
|
padding: 8px;
|
|
|
|
check := CheckBox {
|
|
checked: root.item.checked;
|
|
toggled() => {
|
|
State.check-item(item.name);
|
|
debug("CheckBox checked: ", self.checked);
|
|
}
|
|
}
|
|
|
|
Text {
|
|
opacity: (root.item.checked ? 0.5 : 1.0);
|
|
font-size: 12pt;
|
|
text: root.item.amount;
|
|
width: 30px;
|
|
}
|
|
|
|
Text {
|
|
opacity: (root.item.checked ? 0.5 : 1.0);
|
|
font-size: 12pt;
|
|
text: root.item.name;
|
|
}
|
|
}
|
|
|
|
input := TouchArea {
|
|
clicked => {
|
|
//root.item.checked = !root.item.checked;
|
|
State.check-item(item.name);
|
|
}
|
|
mouse-cursor: pointer;
|
|
}
|
|
}
|
|
|
|
component PlusMinus inherits HorizontalLayout {
|
|
in property <SItem> item;
|
|
plus := Rectangle {
|
|
Text {
|
|
text: "+";
|
|
font-weight: 800;
|
|
font-size: 16pt;
|
|
}
|
|
|
|
background: #ffffff10;
|
|
border-top-left-radius: 10px;
|
|
border-bottom-left-radius: 10px;
|
|
border-color: #00000070;
|
|
border-width: 1px;
|
|
width: self.height;
|
|
plusta := TouchArea {
|
|
clicked => {
|
|
State.inc-amount(item.name);
|
|
}
|
|
mouse-cursor: pointer;
|
|
}
|
|
}
|
|
|
|
minus := Rectangle {
|
|
Text {
|
|
text: "-";
|
|
font-weight: 800;
|
|
font-size: 16pt;
|
|
}
|
|
|
|
background: #ffffff10;
|
|
border-top-right-radius: 10px;
|
|
border-bottom-right-radius: 10px;
|
|
border-color: #00000070;
|
|
border-width: 1px;
|
|
height: 30px;
|
|
width: self.height;
|
|
minusta := TouchArea {
|
|
clicked => {
|
|
State.dec-amount(item.name);
|
|
}
|
|
mouse-cursor: pointer;
|
|
}
|
|
}
|
|
|
|
states [
|
|
plushov when plusta.has-hover: {
|
|
plus.background: #ffffff30;
|
|
}
|
|
minoshov when minusta.has-hover: {
|
|
minus.background: #ffffff30;
|
|
}
|
|
]
|
|
}
|
|
|
|
component GoodListItemAdd inherits Rectangle {
|
|
in-out property <SItem> item;
|
|
background: Palette.alternate-background;
|
|
border-radius: 8pt;
|
|
border-width: 10pt;
|
|
HorizontalLayout {
|
|
spacing: 8px;
|
|
padding: 8px;
|
|
alignment: start;
|
|
PlusMinus {
|
|
item: item;
|
|
}
|
|
|
|
Rectangle {
|
|
height: 30px;
|
|
Text {
|
|
text: root.item.amount;
|
|
font-size: 12pt;
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
height: 30px;
|
|
Text {
|
|
opacity: (root.item.checked ? 0.5 : 1.0);
|
|
font-size: 12pt;
|
|
text: root.item.name;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
component GoodsList {
|
|
in property <[SItem]> items;
|
|
|
|
ListView {
|
|
mouse-drag-pan-enabled: true;
|
|
|
|
for item in items: VerticalLayout {
|
|
GoodListItem {
|
|
item: item;
|
|
}
|
|
|
|
Rectangle {
|
|
height: 4pt;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
component GoodsListAdd {
|
|
in property <[SItem]> items;
|
|
|
|
ListView {
|
|
mouse-drag-pan-enabled: true;
|
|
|
|
for item in items: VerticalLayout {
|
|
GoodListItemAdd {
|
|
item: item;
|
|
}
|
|
|
|
Rectangle {
|
|
height: 4pt;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
component GoodButtons inherits ScrollView {
|
|
in property <length> button-min-width: 100pt;
|
|
in property <length> button-height: 60pt;
|
|
in property <length> button-spacing: 10pt;
|
|
|
|
property <int> count-x: floor(root.width / (button-min-width + button-spacing));
|
|
property <int> count-y: ceil(State.favorites.length / count-x);
|
|
property <length> button-width: ((self.width + button-spacing ) / count-x) - button-spacing;
|
|
|
|
viewport-height: (count-y * (button-height + button-spacing));
|
|
mouse-drag-pan-enabled: true;
|
|
|
|
for item[idx] in State.favorites: Button {
|
|
x: floor(mod(idx, count-x)) * (root.button-width + root.button-spacing);
|
|
y: floor(idx / count-x) * (root.button-height + root.button-spacing);
|
|
width: root.button-width;
|
|
height: root.button-height;
|
|
text: item.name;
|
|
clicked => {
|
|
State.add-to-list(item.name);
|
|
}
|
|
}
|
|
}
|
|
|
|
component ConnStatusIndicator inherits Rectangle {
|
|
width: 18px;
|
|
Image {
|
|
states [
|
|
idle when State.connection-status == ConnectionStatus.Idle: {
|
|
opacity: 0%;
|
|
}
|
|
syncing when State.connection-status == ConnectionStatus.Syncing: {
|
|
colorize: green;
|
|
opacity: 75% + 25% * sin(360deg * animation-tick() / 1s);
|
|
}
|
|
error when State.connection-status == ConnectionStatus.Error: {
|
|
colorize: red;
|
|
opacity: 100%;
|
|
}
|
|
]
|
|
source: @image-url("../images/arrow-down-up.svg");
|
|
width: 24px;
|
|
height: self.width;
|
|
}
|
|
}
|
|
|
|
component RefreshButton inherits HorizontalLayout {
|
|
spacing: 8px;
|
|
alignment: center;
|
|
Button {
|
|
text: "Refresh";
|
|
width: 40%;
|
|
clicked() => {
|
|
State.refresh-list();
|
|
}
|
|
}
|
|
ConnStatusIndicator { }
|
|
}
|
|
|
|
component AddView inherits VerticalLayout {
|
|
in property <[SItem]> list;
|
|
|
|
padding: 8px;
|
|
spacing: 8px;
|
|
|
|
RefreshButton {}
|
|
|
|
goods := GoodsListAdd {
|
|
items <=> list;
|
|
}
|
|
|
|
HorizontalLayout {
|
|
height: 42px;
|
|
input := LineEdit {
|
|
font-size: 20px;
|
|
accepted(text) => {
|
|
if text != "" {
|
|
State.add-to-list(text);
|
|
input.text = "";
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: 4pt; // spacing
|
|
}
|
|
|
|
Button {
|
|
width: self.height;
|
|
text: "+";
|
|
clicked => {
|
|
if input.text != "" {
|
|
State.add-to-list(input.text);
|
|
input.text = "";
|
|
}
|
|
input.clear-focus()
|
|
}
|
|
}
|
|
}
|
|
|
|
GoodButtons { }
|
|
}
|
|
|
|
component ShopView inherits VerticalLayout {
|
|
in property <[SItem]> list;
|
|
|
|
padding: 8px;
|
|
spacing: 8px;
|
|
|
|
RefreshButton { }
|
|
|
|
goods := GoodsList {
|
|
items <=> list;
|
|
}
|
|
|
|
HorizontalLayout {
|
|
padding: 12px;
|
|
Button {
|
|
text: "I am done hehe";
|
|
clicked => {
|
|
State.delete-checked();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
component CatItem inherits HorizontalBox {
|
|
in-out property <SButtonItem> item;
|
|
|
|
Text {
|
|
text: item.name;
|
|
vertical-alignment: center;
|
|
font-size: 16px;
|
|
}
|
|
|
|
ComboBox {
|
|
model: ["kyl", "skafferi", "frys", "övrigt"];
|
|
current-value: item.category;
|
|
width: 60%;
|
|
selected(category) => { State.set-cat(item.name, category) }
|
|
}
|
|
}
|
|
|
|
|
|
component CatView inherits VerticalLayout {
|
|
in-out property <[SButtonItem]> cats;
|
|
|
|
for item in cats: CatItem {
|
|
item: item;
|
|
}
|
|
}
|
|
|
|
export component App inherits Window {
|
|
|
|
title: "Inköpslista";
|
|
icon: @image-url("../images/icon.svg");
|
|
|
|
preferred-height: 700px;
|
|
preferred-width: 480px;
|
|
|
|
TabWidget {
|
|
Tab {
|
|
title: "Add";
|
|
AddView {
|
|
list <=> State.list;
|
|
}
|
|
}
|
|
|
|
Tab {
|
|
title: "Shop";
|
|
ShopView {
|
|
list <=> State.list;
|
|
}
|
|
}
|
|
|
|
Tab {
|
|
title: "Categories";
|
|
CatView {
|
|
cats <=> State.favorites;
|
|
}
|
|
}
|
|
|
|
Tab {
|
|
title: "Settings";
|
|
SettingsView { }
|
|
}
|
|
}
|
|
}
|