Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kiosk mode #533

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions psst-gui/src/data/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ pub struct Config {
pub sort_criteria: SortCriteria,
pub paginated_limit: usize,
pub seek_duration: usize,
pub kiosk_mode: bool,
}

impl Default for Config {
Expand All @@ -118,6 +119,7 @@ impl Default for Config {
sort_criteria: Default::default(),
paginated_limit: 500,
seek_duration: 10,
kiosk_mode: false,
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions psst-gui/src/delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,13 @@ impl Delegate {
}
}

fn show_preferences(&mut self, ctx: &mut DelegateCtx) {
fn show_preferences(&mut self, config: &Config, ctx: &mut DelegateCtx) {
match self.preferences_window {
Some(id) => {
ctx.submit_command(commands::SHOW_WINDOW.to(id));
}
None => {
let window = ui::preferences_window();
let window = ui::preferences_window(config);
self.preferences_window.replace(window.id);
ctx.new_window(window);
}
Expand Down Expand Up @@ -113,7 +113,7 @@ impl AppDelegate<AppState> for Delegate {
self.show_account_setup(ctx);
Handled::Yes
} else if cmd.is(commands::SHOW_PREFERENCES) {
self.show_preferences(ctx);
self.show_preferences(&data.config, ctx);
Handled::Yes
} else if cmd.is(cmd::CLOSE_ALL_WINDOWS) {
self.close_all_windows(ctx);
Expand Down
14 changes: 12 additions & 2 deletions psst-gui/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ mod widget;

use druid::AppLauncher;
use env_logger::{Builder, Env};
use std::env;
use webapi::WebApi;

use crate::{
Expand All @@ -33,7 +34,11 @@ fn main() {

let config = Config::load().unwrap_or_default();
let paginated_limit = config.paginated_limit;
let state = AppState::default_with_config(config);
let mut state = AppState::default_with_config(config);

let args: Vec<String> = env::args().collect();
state.config.kiosk_mode = args.iter().any(|arg| arg == "-k" || arg == "--kiosk");

WebApi::new(
state.session.clone(),
Config::proxy().as_deref(),
Expand All @@ -54,7 +59,12 @@ fn main() {
WebApi::global().load_local_tracks(state.config.username().unwrap());
} else {
// No configured credentials, open the account setup.
let window = ui::account_setup_window();
let mut window = ui::account_setup_window();

if state.config.kiosk_mode {
window = ui::kiosk_setup_window();
}
SO9010 marked this conversation as resolved.
Show resolved Hide resolved

delegate = Delegate::with_preferences(window.id);
launcher = AppLauncher::with_window(window).configure_env(ui::theme::setup);
};
Expand Down
52 changes: 24 additions & 28 deletions psst-gui/src/ui/home.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,16 @@ pub fn home_widget() -> impl Widget<AppState> {
}

fn simple_title_label(title: &str) -> impl Widget<AppState> {
Flex::column()
.with_default_spacer()
.with_child(Label::new(title)
.with_text_size(theme::grid(2.5))
.align_left()
.padding((theme::grid(1.5), 0.0))
Flex::column().with_default_spacer().with_child(
Label::new(title)
.with_text_size(theme::grid(2.5))
.align_left()
.padding((theme::grid(1.5), 0.0)),
)
}

pub fn made_for_you() -> impl Widget<AppState> {
Async::new(spinner_widget, loaded_results_widget, || {Empty})
Async::new(spinner_widget, loaded_results_widget, || Empty)
.lens(
Ctx::make(
AppState::common_ctx,
Expand All @@ -64,7 +63,7 @@ pub fn made_for_you() -> impl Widget<AppState> {
}

pub fn recommended_stations() -> impl Widget<AppState> {
Async::new(spinner_widget, loaded_results_widget, || {Empty})
Async::new(spinner_widget, loaded_results_widget, || Empty)
.lens(
Ctx::make(
AppState::common_ctx,
Expand All @@ -82,27 +81,24 @@ pub fn recommended_stations() -> impl Widget<AppState> {

fn uniquely_yours_results_widget() -> impl Widget<WithCtx<MixedView>> {
Either::new(
|results: &WithCtx<MixedView>, _| {
results.data.playlists.is_empty()
},
|results: &WithCtx<MixedView>, _| results.data.playlists.is_empty(),
Empty,
Flex::column().with_default_spacer()
.with_child(Label::new("Uniquely yours")
.with_text_size(theme::grid(2.5))
.align_left()
.padding((theme::grid(1.5), 0.0))
).with_child(
Scroll::new(
Flex::row()
.with_child(playlist_results_widget())
Flex::column()
.with_default_spacer()
.with_child(
Label::new("Uniquely yours")
.with_text_size(theme::grid(2.5))
.align_left()
.padding((theme::grid(1.5), 0.0)),
)
.align_left(),
),
.with_child(
Scroll::new(Flex::row().with_child(playlist_results_widget())).align_left(),
),
)
}

pub fn uniquely_yours() -> impl Widget<AppState> {
Async::new(spinner_widget, uniquely_yours_results_widget, || {Empty})
Async::new(spinner_widget, uniquely_yours_results_widget, || Empty)
SO9010 marked this conversation as resolved.
Show resolved Hide resolved
.lens(
Ctx::make(
AppState::common_ctx,
Expand All @@ -119,7 +115,7 @@ pub fn uniquely_yours() -> impl Widget<AppState> {
}

pub fn user_top_mixes() -> impl Widget<AppState> {
Async::new(spinner_widget, loaded_results_widget, || {Empty})
Async::new(spinner_widget, loaded_results_widget, || Empty)
.lens(
Ctx::make(
AppState::common_ctx,
Expand All @@ -136,7 +132,7 @@ pub fn user_top_mixes() -> impl Widget<AppState> {
}

pub fn best_of_artists() -> impl Widget<AppState> {
Async::new(spinner_widget, loaded_results_widget, || {Empty})
Async::new(spinner_widget, loaded_results_widget, || Empty)
.lens(
Ctx::make(
AppState::common_ctx,
Expand All @@ -153,7 +149,7 @@ pub fn best_of_artists() -> impl Widget<AppState> {
}

pub fn your_shows() -> impl Widget<AppState> {
Async::new(spinner_widget, loaded_results_widget, || {Empty})
Async::new(spinner_widget, loaded_results_widget, || Empty)
.lens(
Ctx::make(
AppState::common_ctx,
Expand All @@ -170,7 +166,7 @@ pub fn your_shows() -> impl Widget<AppState> {
}

pub fn jump_back_in() -> impl Widget<AppState> {
Async::new(spinner_widget, loaded_results_widget, || {Empty})
Async::new(spinner_widget, loaded_results_widget, || Empty)
.lens(
Ctx::make(
AppState::common_ctx,
Expand All @@ -187,7 +183,7 @@ pub fn jump_back_in() -> impl Widget<AppState> {
}

pub fn shows_that_you_might_like() -> impl Widget<AppState> {
Async::new(spinner_widget, loaded_results_widget, || {Empty})
Async::new(spinner_widget, loaded_results_widget, || Empty)
.lens(
Ctx::make(
AppState::common_ctx,
Expand Down
4 changes: 2 additions & 2 deletions psst-gui/src/ui/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use crate::{
data::{AppState, Nav},
};

pub fn main_menu(_window: Option<WindowId>, _data: &AppState, _env: &Env) -> Menu<AppState> {
if cfg!(target_os = "macos") {
pub fn main_menu(_window: Option<WindowId>, data: &AppState, _env: &Env) -> Menu<AppState> {
if cfg!(target_os = "macos") && !data.config.kiosk_mode {
Menu::empty().entry(mac_app_menu())
} else {
Menu::empty()
Expand Down
71 changes: 62 additions & 9 deletions psst-gui/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use druid::{
im::Vector,
widget::{CrossAxisAlignment, Either, Flex, Label, List, Scroll, Slider, Split, ViewSwitcher},
Color, Env, Insets, Key, LensExt, Menu, MenuItem, Selector, Widget, WidgetExt, WindowDesc,
WindowState,
};
use druid_shell::Cursor;

Expand Down Expand Up @@ -42,20 +43,40 @@ pub mod user;
pub mod utils;

pub fn main_window(config: &Config) -> WindowDesc<AppState> {
let win = WindowDesc::new(root_widget())
let mut win = WindowDesc::new(root_widget(config))
.title(compute_main_window_title)
.with_min_size((theme::grid(65.0), theme::grid(50.0)))
.window_size(config.window_size)
.show_title(false)
.transparent_titlebar(true);

if config.kiosk_mode {
win = win
.set_window_state(WindowState::Maximized)
.resizable(false)
.show_titlebar(false)
.set_always_on_top(true);

// Set the window size to the primary monitor's work area and position it at (0, 0)
if let Some(monitor) = druid::Screen::get_monitors().first() {
let work_area = monitor.virtual_work_rect();
win = win
.window_size(work_area.size())
.set_position(druid::Point::new(0.0, 0.0));
}
} else {
win = win
.window_size(config.window_size)
.with_min_size((theme::grid(65.0), theme::grid(50.0)));
}

if cfg!(target_os = "macos") {
win.menu(menu::main_menu)
} else {
win
}
}

pub fn preferences_window() -> WindowDesc<AppState> {
pub fn preferences_window(config: &Config) -> WindowDesc<AppState> {
// Change this
SO9010 marked this conversation as resolved.
Show resolved Hide resolved
let win_size = (theme::grid(50.0), theme::grid(55.0));

// On Windows, the window size includes the titlebar.
Expand All @@ -66,12 +87,21 @@ pub fn preferences_window() -> WindowDesc<AppState> {
win_size
};

let win = WindowDesc::new(preferences_widget())
let mut win = WindowDesc::new(preferences_widget())
.title("Preferences")
.window_size(win_size)
.resizable(false)
.show_title(false)
.transparent_titlebar(true);

if config.kiosk_mode {
win = win
.set_window_state(WindowState::Maximized)
.resizable(false)
.set_always_on_top(true)
.show_titlebar(false);
} else {
win = win.window_size(win_size)
}
if cfg!(target_os = "macos") {
win.menu(menu::main_menu)
} else {
Expand All @@ -82,9 +112,24 @@ pub fn preferences_window() -> WindowDesc<AppState> {
pub fn account_setup_window() -> WindowDesc<AppState> {
let win = WindowDesc::new(account_setup_widget())
.title("Login")
.resizable(false)
.show_title(false)
.window_size((theme::grid(50.0), theme::grid(45.0)))
.transparent_titlebar(true);
if cfg!(target_os = "macos") {
win.menu(menu::main_menu)
} else {
win
}
}

pub fn kiosk_setup_window() -> WindowDesc<AppState> {
let win = WindowDesc::new(kiosk_setup_widget())
.title("Setup")
.resizable(false)
.show_title(false)
.set_window_state(WindowState::Maximized)
.show_titlebar(false)
.transparent_titlebar(true);
if cfg!(target_os = "macos") {
win.menu(menu::main_menu)
Expand All @@ -109,7 +154,15 @@ fn account_setup_widget() -> impl Widget<AppState> {
)
}

fn root_widget() -> impl Widget<AppState> {
fn kiosk_setup_widget() -> impl Widget<AppState> {
ThemeScope::new(
preferences::kiosk_setup_widget()
.background(theme::BACKGROUND_DARK)
.expand(),
)
}

fn root_widget(config: &Config) -> impl Widget<AppState> {
let playlists = Scroll::new(playlist::list_widget())
.vertical()
.expand_height();
Expand All @@ -119,8 +172,8 @@ fn root_widget() -> impl Widget<AppState> {
.with_child(sidebar_menu_widget())
.with_default_spacer()
.with_flex_child(playlists, 1.0)
.padding(if cfg!(target_os = "macos") {
// Accommodate the window controls on Mac.
.padding(if cfg!(target_os = "macos") && !config.kiosk_mode {
// Accommodate the window controls on macOS
Insets::new(0.0, 24.0, 0.0, 0.0)
SO9010 marked this conversation as resolved.
Show resolved Hide resolved
} else {
Insets::ZERO
Expand Down
Loading