Add support for theming

This commit is contained in:
2023-08-05 23:53:58 +02:00
parent d6f024af04
commit 83a9ce23dd
13 changed files with 611 additions and 88 deletions

View File

@@ -23,7 +23,7 @@ pub fn init(app: &App, sender_co: MessageToServer, receiver_s: MessageFromServer
sender_c.send(ClientMessage::Previous).unwrap();
});
let ui_handle = app.as_weak();
let app_handle = app.as_weak();
thread::spawn(move || loop {
if receiver_s.is_empty() {
thread::sleep(Duration::from_millis(200));
@@ -32,12 +32,12 @@ pub fn init(app: &App, sender_co: MessageToServer, receiver_s: MessageFromServer
let msg = receiver_s.recv().unwrap();
info!("Received : {msg:?}");
match msg {
ServerMessage::NowPlaying(title) => ui_handle
ServerMessage::NowPlaying(title) => app_handle
.upgrade_in_event_loop(move |handle| {
handle.global::<MediaLogic>().set_now_playing(title.into())
})
.unwrap(),
ServerMessage::Playing(bool) => ui_handle
ServerMessage::Playing(bool) => app_handle
.upgrade_in_event_loop(move |handle| {
handle.global::<MediaLogic>().set_playing(bool)
})

View File

@@ -1 +1,2 @@
pub mod media;
pub mod virtual_keyboard;

View File

@@ -0,0 +1,16 @@
use slint::*;
use crate::{App,VirtualKeyboardHandler};
pub fn init(app: &App) {
let weak = app.as_weak();
app.global::<VirtualKeyboardHandler>().on_key_pressed({
move |key| {
weak.unwrap()
.window()
.dispatch_event(slint::platform::WindowEvent::KeyPressed { text: key.clone() });
weak.unwrap()
.window()
.dispatch_event(slint::platform::WindowEvent::KeyReleased { text: key });
}
});
}

View File

@@ -2,8 +2,7 @@ mod controller;
mod link;
use log::info;
use crate::{controller::media, link::init_tcp};
use crate::{controller::{media,virtual_keyboard}, link::init_tcp};
slint::include_modules!();
@@ -24,21 +23,3 @@ fn main() -> Result<(), slint::PlatformError> {
app.run()
}
mod virtual_keyboard {
use super::*;
use slint::*;
pub fn init(app: &App) {
let weak = app.as_weak();
app.global::<VirtualKeyboardHandler>().on_key_pressed({
move |key| {
weak.unwrap()
.window()
.dispatch_event(slint::platform::WindowEvent::KeyPressed { text: key.clone() });
weak.unwrap()
.window()
.dispatch_event(slint::platform::WindowEvent::KeyReleased { text: key });
}
});
}
}

View File

@@ -2,6 +2,6 @@
// SPDX-License-Identifier: MIT
export global AppManager {
in-out property <bool> keyboard-enabled: false;
in-out property <bool> keyboard-enabled: true;
in-out property <bool> widgets-enabled: true;
}
}

View File

@@ -1,18 +1,19 @@
import { CoopWindow, VirtualKeyboard, VirtualKeyboardHandler, GroupListViewItem, Palette, Icons } from "_imports/coop-widgets.slint";
import { MediaPage } from "pages/pages.slint";
import { MediaPage , SettingsPage } from "pages/pages.slint";
import { AppManager } from "app-manager.slint";
import { SideBarView } from "side-bar-view.slint";
import { MediaControls, MediaLogic } from "widgets/mediacontrols.slint";
export { VirtualKeyboardHandler }
export { AppManager }
export { Palette }
export { MediaLogic }
export component App inherits CoopWindow {
// preferred-width: 600px;
// preferred-height: 400px;
title: "Deckui";
Rectangle {
background: Palette.background;
}
@@ -23,19 +24,22 @@ export component App inherits CoopWindow {
col: 1;
if (i-side-bar.current-item.parent == 0 && i-side-bar.current-item.item == 0) : MediaPage {}
if (i-side-bar.current-item.parent == 0 && i-side-bar.current-item.item == 1) : SettingsPage {}
//if (i-side-bar.current-item.parent == 1 && i-side-bar.current-item.item == 0) : BrushesPage {}
}
i-side-bar := SideBarView {
// current-item: {parent:0,item:1};
col: 0;
parent-width: root.width;
title: "Deckui";
responsive: true;
property <GroupListViewItem> widgets: {
text: "Widgets",
text: "Home",
items: [
{ leading-icon: Icons.home, text: "Media" },
{ leading-icon: Icons.pin, text: "Settings" },
]
};

View File

@@ -0,0 +1,332 @@
// SPDX-FileCopyrightText: 2022 Florian Blasius <co-sl@tutanota.com>
// SPDX-License-Identifier: MIT
import { Page } from "page.slint";
import { RowTitle, ColumnTitle } from "titles.slint";
import { MediumLabel, Spacer, HorizontalSeparator, Radius, Palette, Size, Space } from "../_imports/coop-widgets.slint";
component BrushRect inherits Rectangle {
width: Size.small;
height: root.width;
border-radius: Radius.medium;
border-width: 1px;
border-color: Palette.border;
}
export component BrushesPage {
GridLayout {
padding: Space.large;
spacing: Space.medium;
// Labels
Row {
RowTitle {
text: "Brushes";
}
}
Row {
ColumnTitle {
text: "Brush";
}
Spacer {}
ColumnTitle {
text: "key";
}
Spacer {}
ColumnTitle {
text: "description";
}
}
Row {
HorizontalSeparator {
colspan: 9;
}
}
// background
Row {
BrushRect {
background: Palette.background;
}
Spacer {}
MediumLabel {
text: "Palette.background";
vertical-alignment: center;
}
Spacer {}
MediumLabel {
text: "background brush of the window";
vertical-alignment: center;
}
}
// background-alt
Row {
BrushRect {
background: Palette.background-alt;
}
Spacer {}
MediumLabel {
text: "Palette.background-alt";
vertical-alignment: center;
}
Spacer {}
MediumLabel {
text: "alternative background brush";
vertical-alignment: center;
}
}
// foreground
Row {
BrushRect {
background: Palette.foreground;
}
Spacer {}
MediumLabel {
text: "Palette.foreground";
vertical-alignment: center;
}
Spacer {}
MediumLabel {
text: "common foreground brush e.g. for text";
vertical-alignment: center;
}
}
// foreground-disabled
Row {
BrushRect {
background: Palette.foreground-disabled;
}
Spacer {}
MediumLabel {
text: "Palette.foreground-disabled";
vertical-alignment: center;
}
Spacer {}
MediumLabel {
text: "common foreground for disabled elements";
vertical-alignment: center;
}
}
// surface
Row {
BrushRect {
background: Palette.surface;
}
Spacer {}
MediumLabel {
text: "Palette.surface";
vertical-alignment: center;
}
Spacer {}
MediumLabel {
text: "widget surface brush e.g. used by button";
vertical-alignment: center;
}
}
// surface-disabled
Row {
BrushRect {
background: Palette.surface-disabled;
}
Spacer {}
MediumLabel {
text: "Palette.surface-disabled";
vertical-alignment: center;
}
Spacer {}
MediumLabel {
text: "widget surface brush of disabled widgets";
vertical-alignment: center;
}
}
// on-surface
Row {
BrushRect {
background: Palette.on-surface;
}
Spacer {}
MediumLabel {
text: "Palette.on-surface";
vertical-alignment: center;
}
Spacer {}
MediumLabel {
text: "content elements on surface background";
vertical-alignment: center;
}
}
// primary
Row {
BrushRect {
background: Palette.primary;
}
Spacer {}
MediumLabel {
text: "Palette.primary";
vertical-alignment: center;
}
Spacer {}
MediumLabel {
text: "defines the accent brush";
vertical-alignment: center;
}
}
// on-primary
Row {
BrushRect {
background: Palette.on-primary;
}
Spacer {}
MediumLabel {
text: "Palette.on-primary";
vertical-alignment: center;
}
Spacer {}
MediumLabel {
text: "content elements on primary background";
vertical-alignment: center;
}
}
// border
Row {
BrushRect {
background: Palette.border;
}
Spacer {}
MediumLabel {
text: "Palette.border";
vertical-alignment: center;
}
Spacer {}
MediumLabel {
text: "brush of borders";
vertical-alignment: center;
}
}
// border-disabled
Row {
BrushRect {
background: Palette.border-disabled;
}
Spacer {}
MediumLabel {
text: "Palette.border-disabled";
vertical-alignment: center;
}
Spacer {}
MediumLabel {
text: "brush of disabled borders";
vertical-alignment: center;
}
}
// shadow
Row {
BrushRect {
background: Palette.shadow;
}
Spacer {}
MediumLabel {
text: "Palette.shadow";
vertical-alignment: center;
}
Spacer {}
MediumLabel {
text: "default drop shadow brush";
vertical-alignment: center;
}
}
// shadow
Row {
BrushRect {
background: Palette.error;
}
Spacer {}
MediumLabel {
text: "Palette.error";
vertical-alignment: center;
}
Spacer {}
MediumLabel {
text: "brush for error representation elements";
vertical-alignment: center;
}
}
// Fills the remaining available space
Row {
Spacer {}
}
}
}

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: 2022 Florian Blasius <co-sl@tutanota.com>
// SPDX-License-Identifier: MIT
import { Page } from "page.slint";
import { MediaControls } from "../widgets/mediacontrols.slint";

View File

@@ -1,64 +1,14 @@
// SPDX-FileCopyrightText: 2022 Florian Blasius <co_sl@tutanota.com>
// SPDX-License-Identifier: MIT
import { AppManager } from "../app-manager.slint";
import { HeaderBar, OutlineButton, CheckBox, Switch, ScrollView, Icons, ComboBox, Palette, ColorTheme, ColorVariant } from "../_imports/coop-widgets.slint";
import { HeaderBar, ScrollView } from "../_imports/coop-widgets.slint";
export component Page inherits GridLayout {
in-out property <string> title <=> i_header_bar.title;
in-out property <bool> keyboard_check_box: true;
in-out property <bool> disabled_check_box: true;
Row {
i_header_bar := HeaderBar {
if (root.keyboard_check_box) : CheckBox {
y: (parent.height - self.height) / 2;
text: "Keyboard enabled";
checked <=> AppManager.keyboard_enabled;
}
if (root.disabled_check_box) : CheckBox {
y: (parent.height - self.height) / 2;
text: "Widgets enabled";
checked <=> AppManager.widgets_enabled;
}
ComboBox {
width: 128px;
placeholder-text: @tr("Select theme:");
current-index: Palette.current-color-theme == ColorTheme.Coop ? 0 : 1;
model: [
{ text: "Coop" },
{ text: "Cosmic" },
];
selected (index) => {
if (index == 0) {
Palette.set-color-theme(ColorTheme.Coop);
return;
}
if (index == 1) {
Palette.set-color-theme(ColorTheme.Cosmic);
}
}
}
VerticalLayout {
alignment: center;
Switch {
on_icon: Icons.mode-night;
off_icon: Icons.light-mode;
checked: !Palette.dark-color-scheme;
toggled(checked) => {
Palette.set-color-variant(checked ? ColorVariant.Light : ColorVariant.Dark);
}
}
}
}
}
@@ -67,4 +17,4 @@ export component Page inherits GridLayout {
@children
}
}
}
}

View File

@@ -1,6 +1,5 @@
// SPDX-FileCopyrightText: 2022 Florian Blasius <co-sl@tutanota.com>
// SPDX-License-Identifier: MIT
import { MediaPage } from "media-page.slint";
import { SettingsPage } from "settings-page.slint";
export { MediaPage, SettingsPage}
export { MediaPage }

View File

@@ -0,0 +1,89 @@
import { Page } from "page.slint";
import { AppManager } from "../app-manager.slint";
import { ComboBox, Switch, Palette, ColorTheme, Icons, ColorVariant, CheckBox } from "../_imports/coop-widgets.slint";
import { ThemeSwitcher, ColorPalette,Settings } from "../themes/palettes.slint";
import { Onedark } from "../themes/onedark.slint";
import { BrushesPage } from "brushes-page.slint";
export component SettingsPage inherits Page {
title: "Settings";
in-out property <bool> keyboard_check_box: true;
in-out property <bool> disabled_check_box: true;
in-out property <ColorPalette> color_palette;
in-out property <bool> built-in-theme: true;
in-out property <int> color_index;
in-out property <bool> debug: false;
Flickable {
VerticalLayout {
alignment: start;
padding: 30px;
spacing: 30px;
if (root.keyboard_check_box) : CheckBox {
text: "Keyboard enabled";
checked <=> AppManager.keyboard_enabled;
}
if (root.disabled_check_box) : CheckBox {
text: "Widgets enabled";
checked <=> AppManager.widgets_enabled;
}
function reload_color() {
root.built-in-theme = true;
if (root.color-index == 0) {
Palette.set-color-theme(ColorTheme.Coop);
return;
} else if (root.color-index == 1) {
Palette.set-color-theme(ColorTheme.Cosmic);
return;
} else if (root.color-index == 2){
root.color-palette = Onedark.palette;
}
root.built-in-theme = false;
ThemeSwitcher.switch(root.color-palette);
}
ComboBox {
width: 128px;
height: 40px;
placeholder-text: @tr("Select theme:");
current-index: root.color-index;
model: [
{ text: "Coop" },
{ text: "Cosmic" },
{ text: "Onedark" },
];
selected (index) => {
root.color-index=index;
reload-color();
}
}
VerticalLayout {
alignment: center;
Switch {
height: 48px;
on_icon: Icons.mode-night;
off_icon: Icons.light-mode;
checked: !Palette.dark-color-scheme;
toggled(checked) => {
Settings.dark-color-scheme = !checked;
if (root.built-in-theme){
Palette.set-color-variant(checked ? ColorVariant.Light : ColorVariant.Dark);
} else {
// ThemeSwitcher.switch(root.color-palette);
reload-color();
}
}
}
}
if root.debug : BrushesPage { }
}
}
}

View File

@@ -0,0 +1,111 @@
import { ColorPalette, Settings } from "palettes.slint";
struct ColorPalette_ {
black : color,
bg0 : color,
bg1 : color,
bg2 : color,
bg3 : color,
bg_d : color,
bg_blue : color,
bg_yellow : color,
fg : color,
purple : color,
green : color,
orange : color,
blue : color,
yellow : color,
cyan : color,
red : color,
grey : color,
light_grey : color,
dark_cyan : color,
dark_red : color,
dark_yellow : color,
dark_purple : color,
diff_add : color,
diff_delete : color,
diff_change : color,
diff_text : color,
}
export global Onedark {
out property <ColorPalette_> darker : {
black : #0e1013,
bg0 : #1f2329,
bg1 : #282c34,
bg2 : #30363f,
bg3 : #323641,
bg_d : #181b20,
bg_blue : #61afef,
bg_yellow : #e8c88c,
fg : #a0a8b7,
purple : #bf68d9,
green : #8ebd6b,
orange : #cc9057,
blue : #4fa6ed,
yellow : #e2b86b,
cyan : #48b0bd,
red : #e55561,
grey : #535965,
light_grey : #7a818e,
dark_cyan : #266269,
dark_red : #8b3434,
dark_yellow : #835d1a,
dark_purple : #7e3992,
diff_add : #272e23,
diff_delete : #2d2223,
diff_change : #172a3a,
diff_text : #274964,
};
out property <ColorPalette_> light: {
black : #101012,
bg0 : #fafafa,
bg1 : #f0f0f0,
bg2 : #e6e6e6,
bg3 : #dcdcdc,
bg_d : #c9c9c9,
bg_blue : #68aee8,
bg_yellow : #e2c792,
fg : #383a42,
purple : #a626a4,
green : #50a14f,
orange : #c18401,
blue : #4078f2,
yellow : #986801,
cyan : #0184bc,
red : #e45649,
grey : #a0a1a7,
light_grey : #818387,
dark_cyan : #2b5d63,
dark_red : #833b3b,
dark_yellow : #7c5c20,
dark_purple : #79428a,
diff_add : #e2fbe4,
diff_delete : #fce2e5,
diff_change : #e2ecfb,
diff_text : #cad3e0,
};
out property <ColorPalette> palette: {
background: Settings.dark-color-scheme ? darker.bg0: light.bg0,
background-alt: Settings.dark-color-scheme ? darker.bg1: light.bg1,
foreground: Settings.dark-color-scheme ? darker.fg: light.fg,
foreground-disabled: Settings.dark-color-scheme ? darker.bg2: light.bg2,
surface: Settings.dark-color-scheme ? darker.bg3: light.bg3,
surface-disabled: Settings.dark-color-scheme ? darker.bg1: light.bg1,
on-surface: Settings.dark-color-scheme ? darker.bg-d: light.bg-d,
primary: Settings.dark-color-scheme ? darker.dark-purple: light.dark-purple,
on-primary: Settings.dark-color-scheme ? darker.bg-d: light.bg-d,
border: Settings.dark-color-scheme ? darker.bg2: light.bg2,
border-disabled: Settings.dark-color-scheme ? darker.bg3: light.bg3,
shadow: Settings.dark-color-scheme ? #00000052 : #00000014,
error: darker.dark-red,
accent: Settings.dark-color-scheme ? darker.dark-purple: light.dark-purple,
on-accent: Settings.dark-color-scheme ? darker.bg-d: light.bg-d,
};
}

View File

@@ -0,0 +1,43 @@
import { Palette } from "../_imports/coop-widgets.slint";
import { StyleMetrics } from "std-widgets.slint";
export global Settings {
in-out property <bool> dark-color-scheme: StyleMetrics.dark-color-scheme;
}
export struct ColorPalette {
background: brush,
background-alt: brush,
foreground: brush,
foreground-disabled: brush,
surface: brush,
surface-disabled: brush,
on-surface: brush,
primary: brush,
on-primary: brush,
border: brush,
border-disabled: brush,
shadow: brush,
error: brush,
accent: brush,
on-accent: brush,
}
export global ThemeSwitcher {
public function switch(palette: ColorPalette) {
Palette.background = palette.background;
Palette.background-alt = palette.background-alt;
Palette.foreground = palette.foreground;
Palette.foreground-disabled = palette.foreground-disabled;
Palette.surface = palette.surface;
Palette.surface-disabled = palette.surface-disabled;
Palette.on-surface = palette.on-surface;
Palette.primary = palette.primary;
Palette.on-primary = palette.on-primary;
Palette.border = palette.border;
Palette.border-disabled = palette.border-disabled;
Palette.shadow = palette.shadow;
Palette.error = palette.error;
Palette.accent = palette.accent;
Palette.on-accent = palette.on-accent;
}
}