feat: add theme, complete footer
@@ -0,0 +1,17 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||||
|
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M11 10.27 7 3.34" />
|
||||||
|
<path d="m11 13.73-4 6.93" />
|
||||||
|
<path d="M12 22v-2" />
|
||||||
|
<path d="M12 2v2" />
|
||||||
|
<path d="M14 12h8" />
|
||||||
|
<path d="m17 20.66-1-1.73" />
|
||||||
|
<path d="m17 3.34-1 1.73" />
|
||||||
|
<path d="M2 12h2" />
|
||||||
|
<path d="m20.66 17-1.73-1" />
|
||||||
|
<path d="m20.66 7-1.73 1" />
|
||||||
|
<path d="m3.34 17 1.73-1" />
|
||||||
|
<path d="m3.34 7 1.73 1" />
|
||||||
|
<circle cx="12" cy="12" r="2" />
|
||||||
|
<circle cx="12" cy="12" r="8" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 606 B |
|
Before Width: | Height: | Size: 314 B After Width: | Height: | Size: 314 B |
|
Before Width: | Height: | Size: 313 B After Width: | Height: | Size: 313 B |
@@ -0,0 +1,5 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||||
|
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path
|
||||||
|
d="M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 320 B |
@@ -0,0 +1,12 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||||
|
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<circle cx="12" cy="12" r="4" />
|
||||||
|
<path d="M12 2v2" />
|
||||||
|
<path d="M12 20v2" />
|
||||||
|
<path d="m4.93 4.93 1.41 1.41" />
|
||||||
|
<path d="m17.66 17.66 1.41 1.41" />
|
||||||
|
<path d="M2 12h2" />
|
||||||
|
<path d="M20 12h2" />
|
||||||
|
<path d="m6.34 17.66-1.41 1.41" />
|
||||||
|
<path d="m19.07 4.93-1.41 1.41" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 467 B |
@@ -63,10 +63,6 @@ fn init() -> State {
|
|||||||
println!("Settings clicked");
|
println!("Settings clicked");
|
||||||
});
|
});
|
||||||
|
|
||||||
main_window.on_feedback_clicked(move || {
|
|
||||||
println!("Feedback clicked");
|
|
||||||
});
|
|
||||||
|
|
||||||
main_window.on_open_clicked(move || {
|
main_window.on_open_clicked(move || {
|
||||||
println!("Open clicked");
|
println!("Open clicked");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { Theme } from "theme.slint";
|
||||||
|
|
||||||
|
export component GradientButton inherits Rectangle {
|
||||||
|
callback clicked <=> touch.clicked;
|
||||||
|
in property <string> text;
|
||||||
|
|
||||||
|
background: Theme.gradient-main;
|
||||||
|
border-radius: Theme.radius;
|
||||||
|
drop-shadow-offset-x: Theme.shadow-primary-x;
|
||||||
|
drop-shadow-offset-y: Theme.shadow-primary-y;
|
||||||
|
drop-shadow-blur: Theme.shadow-primary-blur;
|
||||||
|
drop-shadow-color: touch.has-hover ? Theme.shadow-color : transparent;
|
||||||
|
horizontal-stretch: 0;
|
||||||
|
|
||||||
|
animate drop-shadow-color { duration: 300ms; }
|
||||||
|
|
||||||
|
touch := TouchArea {
|
||||||
|
mouse-cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalLayout {
|
||||||
|
padding: Theme.spacing-sm;
|
||||||
|
padding-left: Theme.spacing-xl;
|
||||||
|
padding-right: Theme.spacing-xl;
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: text;
|
||||||
|
font-family: "Segoe UI";
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
min-width: self.preferred-width;
|
||||||
|
min-height: self.preferred-height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,37 +1,66 @@
|
|||||||
import {
|
import { IconButton } from "icon_button.slint";
|
||||||
Button,
|
import { Theme } from "theme.slint";
|
||||||
HorizontalBox,
|
import { GradientButton } from "button.slint";
|
||||||
VerticalBox,
|
|
||||||
} from "std-widgets.slint";
|
|
||||||
|
|
||||||
export component Footer inherits Rectangle {
|
export component Footer inherits Rectangle {
|
||||||
callback settings-clicked();
|
callback settings-clicked();
|
||||||
callback feedback-clicked();
|
|
||||||
callback open-clicked();
|
callback open-clicked();
|
||||||
|
|
||||||
HorizontalBox {
|
property <image> cog_icon: @image-url("../icons/cog.svg");
|
||||||
spacing: 16px;
|
property <image> sun_icon: @image-url("../icons/sun.svg");
|
||||||
padding-top: 16px;
|
property <image> moon_icon: @image-url("../icons/moon.svg");
|
||||||
|
|
||||||
HorizontalBox {
|
width: 448px;
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
height: 1px;
|
||||||
|
width: 100%;
|
||||||
|
y: 0px;
|
||||||
|
background: Theme.border-main;
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalLayout {
|
||||||
|
alignment: space-between;
|
||||||
|
spacing: Theme.spacing-lg;
|
||||||
|
padding: Theme.spacing-md;
|
||||||
|
padding-left: Theme.spacing-lg;
|
||||||
|
|
||||||
|
HorizontalLayout {
|
||||||
spacing: 16px;
|
spacing: 16px;
|
||||||
|
|
||||||
Button {
|
VerticalLayout {
|
||||||
text: "⚙️ Настроить";
|
alignment: center;
|
||||||
|
IconButton {
|
||||||
|
icon: sun_icon;
|
||||||
|
clicked => {
|
||||||
|
Theme.toggle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VerticalLayout {
|
||||||
|
alignment: center;
|
||||||
|
IconButton {
|
||||||
|
icon: cog_icon;
|
||||||
clicked => {
|
clicked => {
|
||||||
root.settings-clicked();
|
root.settings-clicked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Button {
|
HorizontalLayout {
|
||||||
text: "💬 Обратная связь";
|
alignment: center;
|
||||||
clicked => {
|
VerticalLayout {
|
||||||
root.feedback-clicked();
|
alignment: center;
|
||||||
|
Text {
|
||||||
|
text: "Escape - закрыть";
|
||||||
|
color: Theme.text-hint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
GradientButton {
|
||||||
text: "Открыть";
|
text: "Открыть";
|
||||||
clicked => {
|
clicked => {
|
||||||
root.open-clicked();
|
root.open-clicked();
|
||||||
|
|||||||
@@ -1,40 +1,38 @@
|
|||||||
import { BrowserConfig } from "./types.slint";
|
import { BrowserConfig } from "./types.slint";
|
||||||
|
import { Theme } from "theme.slint";
|
||||||
|
|
||||||
export component Header inherits Rectangle {
|
export component Header inherits Rectangle {
|
||||||
in property <string> url;
|
in property <string> url;
|
||||||
property <brush> icon-gradient: @linear-gradient(135deg, rgb(59, 130, 246), rgb(6, 182, 212));
|
|
||||||
|
|
||||||
VerticalLayout {
|
VerticalLayout {
|
||||||
// width: 100%;
|
width: 100%;
|
||||||
width: 448px;
|
padding: Theme.spacing-md;
|
||||||
padding: 12px;
|
padding-top: Theme.spacing-xl;
|
||||||
padding-top: 20px;
|
spacing: Theme.spacing-md;
|
||||||
spacing: 12px;
|
|
||||||
|
|
||||||
HorizontalLayout {
|
HorizontalLayout {
|
||||||
spacing: 12px;
|
spacing: Theme.spacing-md;
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
border-radius: 12px;
|
border-radius: Theme.radius;
|
||||||
background: icon-gradient;
|
background: Theme.gradient-main;
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
source: @image-url("../logos/globe.svg");
|
source: @image-url("../icons/globe.svg");
|
||||||
colorize: white;
|
colorize: white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VerticalLayout {
|
VerticalLayout {
|
||||||
alignment: center;
|
alignment: center;
|
||||||
spacing: 4px;
|
spacing: Theme.spacing-xs;
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
font-family: "Segpoe UI";
|
font-family: "Segpoe UI";
|
||||||
text: "Выберите браузер";
|
text: "Выберите браузер";
|
||||||
color: #ffffff;
|
color: Theme.text-main;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
@@ -42,7 +40,7 @@ export component Header inherits Rectangle {
|
|||||||
Text {
|
Text {
|
||||||
font-family: "Segpoe UI";
|
font-family: "Segpoe UI";
|
||||||
text: "Для открытия ссылки";
|
text: "Для открытия ссылки";
|
||||||
color: #94a3b8;
|
color: Theme.text-muted;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,22 +48,22 @@ export component Header inherits Rectangle {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
height: 44px;
|
height: 44px;
|
||||||
border-radius: 12px;
|
border-radius: Theme.radius;
|
||||||
background: #1e293b;
|
background: Theme.surface-elevated;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-color: #334155;
|
border-color: Theme.border-main;
|
||||||
|
|
||||||
HorizontalLayout {
|
HorizontalLayout {
|
||||||
padding: 12px;
|
padding: Theme.spacing-md;
|
||||||
padding-left: 16px;
|
padding-left: Theme.spacing-lg;
|
||||||
padding-right: 16px;
|
padding-right: Theme.spacing-lg;
|
||||||
spacing: 8px;
|
spacing: Theme.spacing-sm;
|
||||||
alignment: start;
|
alignment: start;
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
source: @image-url("../logos/external_link.svg");
|
source: @image-url("../icons/external_link.svg");
|
||||||
width: 16px;
|
width: 16px;
|
||||||
colorize: #64748b;
|
colorize: Theme.text-control-muted;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +72,7 @@ export component Header inherits Rectangle {
|
|||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: "ku6epxboctuk.github.io";
|
text: "ku6epxboctuk.github.io";
|
||||||
color: #cbd5e1;
|
color: Theme.text-control;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-family: "Consolas";
|
font-family: "Consolas";
|
||||||
}
|
}
|
||||||
@@ -87,6 +85,6 @@ export component Header inherits Rectangle {
|
|||||||
height: 1px;
|
height: 1px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
y: parent.height - self.height;
|
y: parent.height - self.height;
|
||||||
background: #334155;
|
background: Theme.border-main;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
export component IconButton inherits Rectangle {
|
||||||
|
callback clicked <=> touch.clicked;
|
||||||
|
|
||||||
|
in property <image> icon;
|
||||||
|
property <color> icon_color: touch.has-hover ? #ffffff : #94a3b8;
|
||||||
|
height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
background: transparent;
|
||||||
|
touch := TouchArea {
|
||||||
|
mouse-cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
source: icon;
|
||||||
|
colorize: icon_color;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ import { BrowserItem } from "./browser_item.slint";
|
|||||||
import { Header } from "./header.slint";
|
import { Header } from "./header.slint";
|
||||||
import { Footer } from "./footer.slint";
|
import { Footer } from "./footer.slint";
|
||||||
import { BrowserConfig } from "./types.slint";
|
import { BrowserConfig } from "./types.slint";
|
||||||
|
import { Theme } from "theme.slint";
|
||||||
|
|
||||||
export component MainWindow inherits Window {
|
export component MainWindow inherits Window {
|
||||||
in property <[BrowserConfig]> browser-model: [];
|
in property <[BrowserConfig]> browser-model: [];
|
||||||
@@ -15,7 +16,6 @@ export component MainWindow inherits Window {
|
|||||||
callback toggle-remember(bool);
|
callback toggle-remember(bool);
|
||||||
callback toggle-always-ask(bool);
|
callback toggle-always-ask(bool);
|
||||||
callback settings-clicked();
|
callback settings-clicked();
|
||||||
callback feedback-clicked();
|
|
||||||
callback open-clicked();
|
callback open-clicked();
|
||||||
callback request-drag();
|
callback request-drag();
|
||||||
|
|
||||||
@@ -30,20 +30,19 @@ export component MainWindow inherits Window {
|
|||||||
width: 488px;
|
width: 488px;
|
||||||
height: 800px;
|
height: 800px;
|
||||||
|
|
||||||
padding: 20px;
|
padding: Theme.spacing-xl;
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
max-width: 448px;
|
max-width: 448px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 760px;
|
height: 760px;
|
||||||
border-radius: 16px;
|
border-radius: Theme.radius-lg;
|
||||||
clip: true;
|
clip: true;
|
||||||
background: #0f172a;
|
background: Theme.surface-main;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-color: #334155;
|
border-color: Theme.border-main;
|
||||||
|
|
||||||
VerticalLayout {
|
VerticalLayout {
|
||||||
padding: 12px;
|
|
||||||
|
|
||||||
Header {
|
Header {
|
||||||
url: current-url;
|
url: current-url;
|
||||||
@@ -83,9 +82,8 @@ export component MainWindow inherits Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Footer {
|
Footer {
|
||||||
settings-clicked => settings-clicked();
|
settings-clicked => root.settings-clicked();
|
||||||
feedback-clicked => feedback-clicked();
|
open-clicked => root.open-clicked();
|
||||||
open-clicked => open-clicked();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
export global Theme {
|
||||||
|
in-out property <bool> is-dark: true;
|
||||||
|
|
||||||
|
out property <length> width: 448px;
|
||||||
|
|
||||||
|
out property <brush> surface-main: is-dark ? #0f172a : #ffffff;
|
||||||
|
out property <brush> surface-control: is-dark ? #1e293b4d : #ffffff;
|
||||||
|
out property <brush> surface-elevated: is-dark ? #1e293b80 : #ffffff;
|
||||||
|
out property <brush> surface-hover: is-dark ? #1e293b : #ffffff;
|
||||||
|
|
||||||
|
out property <brush> border-main: is-dark ? #334155 : #ffffff;
|
||||||
|
|
||||||
|
out property <brush> gradient-main: @linear-gradient(135deg, rgb(59, 130, 246), rgb(6, 182, 212));
|
||||||
|
|
||||||
|
out property <brush> text-main: is-dark ? #ffffff : #000000;
|
||||||
|
out property <brush> text-muted: is-dark ? #94a3b8 : #000000;
|
||||||
|
|
||||||
|
out property <brush> text-control: is-dark ? #cbd5e1 : #000000;
|
||||||
|
out property <brush> text-control-muted: is-dark ? #64748b : #000000;
|
||||||
|
|
||||||
|
out property <brush> text-hint: is-dark ? #475569 : #000000;
|
||||||
|
|
||||||
|
out property <brush> shadow-color: is-dark ? #3b82f640 : #000000;
|
||||||
|
|
||||||
|
out property <length> shadow-primary-x: 0px;
|
||||||
|
out property <length> shadow-primary-y: 10px;
|
||||||
|
out property <length> shadow-primary-blur: 15px;
|
||||||
|
|
||||||
|
out property <length> radius: 12px;
|
||||||
|
out property <length> radius-lg: 16px;
|
||||||
|
|
||||||
|
out property <length> spacing-xl: 20px;
|
||||||
|
out property <length> spacing-lg: 16px;
|
||||||
|
out property <length> spacing-md: 12px;
|
||||||
|
out property <length> spacing-sm: 8px;
|
||||||
|
out property <length> spacing-xs: 4px;
|
||||||
|
|
||||||
|
callback toggle();
|
||||||
|
toggle => {
|
||||||
|
is-dark = !is-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||