tui: move installer logo into background and to the top

Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
This commit is contained in:
Christoph Heiss 2023-06-19 15:20:51 +02:00 committed by Thomas Lamprecht
parent 6edd095ad4
commit 08ad8ed63c

View File

@ -4,19 +4,21 @@ use std::{collections::HashMap, env, net::IpAddr, path::PathBuf};
use cursive::{ use cursive::{
event::Event, event::Event,
view::{Nameable, Resizable, ViewWrapper}, theme::{ColorStyle, Effect, PaletteColor, Style},
view::{Nameable, Offset, Resizable, ViewWrapper},
views::{ views::{
Button, Checkbox, Dialog, DummyView, EditView, LinearLayout, PaddedView, Panel, Button, Checkbox, Dialog, DummyView, EditView, Layer, LinearLayout, PaddedView, Panel,
ProgressBar, ResizedView, ScrollView, SelectView, TextContent, TextView, ViewRef, ProgressBar, ResizedView, ScrollView, SelectView, StackView, TextContent, TextView,
ViewRef,
}, },
Cursive, CursiveRunnable, ScreenId, View, Cursive, CursiveRunnable, ScreenId, View, XY,
}; };
mod options; mod options;
use options::*; use options::*;
mod setup; mod setup;
use setup::{LocaleInfo, ProxmoxProduct, RuntimeInfo, SetupInfo}; use setup::{LocaleInfo, RuntimeInfo, SetupInfo};
mod system; mod system;
@ -30,32 +32,15 @@ use views::{
}; };
// TextView::center() seems to garble the first two lines, so fix it manually here. // TextView::center() seems to garble the first two lines, so fix it manually here.
const LOGO_PVE: &str = r#" const PROXMOX_LOGO: &str = r#"
____ _ __ _____ ____
/ __ \_________ _ ______ ___ ____ _ __ | | / / ____/ / __ \_________ _ ______ ___ ____ _ __
/ /_/ / ___/ __ \| |/_/ __ `__ \/ __ \| |/_/ | | / / __/ / /_/ / ___/ __ \| |/_/ __ `__ \/ __ \| |/_/
/ ____/ / / /_/ /> </ / / / / / /_/ /> < | |/ / /___ / ____/ / / /_/ /> </ / / / / / /_/ /> <
/_/ /_/ \____/_/|_/_/ /_/ /_/\____/_/|_| |___/_____/ /_/ /_/ \____/_/|_/_/ /_/ /_/\____/_/|_| "#;
"#;
const LOGO_PBS: &str = r#"
____ ____ _____
/ __ \_________ _ ______ ___ ____ _ __ / __ ) ___/
/ /_/ / ___/ __ \| |/_/ __ `__ \/ __ \| |/_/ / __ \__ \
/ ____/ / / /_/ /> </ / / / / / /_/ /> < / /_/ /__/ /
/_/ /_/ \____/_/|_/_/ /_/ /_/\____/_/|_| /_____/____/
"#;
const LOGO_PMG: &str = r#"
____ __ _________
/ __ \_________ _ ______ ___ ____ _ __ / |/ / ____/
/ /_/ / ___/ __ \| |/_/ __ `__ \/ __ \| |/_/ / /|_/ / / __
/ ____/ / / /_/ /> </ / / / / / /_/ /> < / / / / /_/ /
/_/ /_/ \____/_/|_/_/ /_/ /_/\____/_/|_| /_/ /_/\____/
"#;
struct InstallerView { struct InstallerView {
view: ResizedView<LinearLayout>, view: ResizedView<Dialog>,
} }
impl InstallerView { impl InstallerView {
@ -85,20 +70,12 @@ impl InstallerView {
pub fn with_raw(state: &InstallerState, view: impl View) -> Self { pub fn with_raw(state: &InstallerState, view: impl View) -> Self {
let setup = &state.setup_info; let setup = &state.setup_info;
let logo = match setup.config.product {
ProxmoxProduct::PVE => LOGO_PVE,
ProxmoxProduct::PBS => LOGO_PBS,
ProxmoxProduct::PMG => LOGO_PMG,
};
let title = format!( let title = format!(
"{} ({}-{}) Installer", "{} ({}-{}) Installer",
setup.config.fullname, setup.iso_info.release, setup.iso_info.isorelease setup.config.fullname, setup.iso_info.release, setup.iso_info.isorelease
); );
let inner = LinearLayout::vertical() let inner = Dialog::around(view).title(title);
.child(PaddedView::lrtb(1, 1, 0, 1, TextView::new(logo).center()))
.child(Dialog::around(view).title(title));
Self { Self {
// Limit the maximum to something reasonable, such that it won't get spread out much // Limit the maximum to something reasonable, such that it won't get spread out much
@ -109,7 +86,48 @@ impl InstallerView {
} }
impl ViewWrapper for InstallerView { impl ViewWrapper for InstallerView {
cursive::wrap_impl!(self.view: ResizedView<LinearLayout>); cursive::wrap_impl!(self.view: ResizedView<Dialog>);
}
struct InstallerBackgroundView {
view: StackView,
}
impl InstallerBackgroundView {
pub fn new(state: &InstallerState) -> Self {
let product_name = state
.setup_info
.config
.fullname
.trim_start_matches("Proxmox ");
let logo = format!("{PROXMOX_LOGO} {product_name}");
let style = Style {
effects: Effect::Bold.into(),
color: ColorStyle::back(PaletteColor::View),
};
let mut view = StackView::new();
view.add_fullscreen_layer(Layer::with_color(
DummyView
.full_width()
.fixed_height(logo.lines().count() + 1),
ColorStyle::back(PaletteColor::View),
));
view.add_transparent_layer_at(
XY {
x: Offset::Center,
y: Offset::Absolute(0),
},
TextView::new(logo).style(style),
);
Self { view }
}
}
impl ViewWrapper for InstallerBackgroundView {
cursive::wrap_impl!(self.view: StackView);
} }
#[derive(Clone, Eq, Hash, PartialEq)] #[derive(Clone, Eq, Hash, PartialEq)]
@ -239,17 +257,28 @@ fn switch_to_next_screen(
step: InstallerStep, step: InstallerStep,
constructor: &dyn Fn(&mut Cursive) -> InstallerView, constructor: &dyn Fn(&mut Cursive) -> InstallerView,
) { ) {
let state = siv.user_data::<InstallerState>().cloned().unwrap();
// Check if the screen already exists; if yes, then simply switch to it. // Check if the screen already exists; if yes, then simply switch to it.
if let Some(state) = siv.user_data::<InstallerState>().cloned() { if let Some(screen_id) = state.steps.get(&step) {
if let Some(screen_id) = state.steps.get(&step) { siv.set_screen(*screen_id);
siv.set_screen(*screen_id); return;
return;
}
} }
let v = constructor(siv); let v = constructor(siv);
let screen = siv.add_active_screen(); let screen = siv.add_active_screen();
siv.with_user_data(|state: &mut InstallerState| state.steps.insert(step, screen)); siv.with_user_data(|state: &mut InstallerState| state.steps.insert(step, screen));
if let Some(state) = siv.user_data::<InstallerState>().cloned() {
siv.screen_mut().add_transparent_layer_at(
XY {
x: Offset::Parent(0),
y: Offset::Parent(0),
},
InstallerBackgroundView::new(&state),
);
}
siv.screen_mut().add_layer(v); siv.screen_mut().add_layer(v);
} }