Skip to main content

Setup

Struct Setup 

Source
pub struct Setup<Msg> { /* private fields */ }
Expand description

The application-owned state of a SetupWizard: which step it is on, what has been chosen on the appearance step and how the Nerd Font install is going.

An application makes one at start, whether or not the wizard is needed, and asks Setup::needed before drawing its own screen: the wizard opens while the application has no settings file of its own, however much the family has already shared. Nothing is written until it finishes, so closing the application half-way leaves the settings folder as it was and the wizard comes again next start.

use qframe::i18n::I18n;
use qframe::prelude::*;
use qframe::storage::{Family, Settings};
use qframe::widgets::{Select, Setup, SetupMsg, SetupWizard};

struct Code {
    setup: Setup<Msg>,
    settings: Settings,
    engine: usize,
}

#[derive(Debug, Clone, PartialEq)]
enum Msg {
    Setup(SetupMsg),
    Engine(usize),
    Ready,
}

impl App for Code {
    type Msg = Msg;
    fn update(&mut self, msg: Msg) -> Command<Msg> {
        match msg {
            Msg::Setup(message) => self.setup.update(message, &mut self.settings),
            Msg::Engine(engine) => {
                self.engine = engine;
                Command::none()
            }
            // The wizard wrote the shared keys and made the file; the application's own keys
            // are its own to write.
            Msg::Ready => {
                self.settings.set("engine", self.engine as i64);
                let _ = self.settings.save();
                Command::none()
            }
        }
    }
    fn view(&self, ui: &mut View<'_, Msg>) {
        if self.setup.needed() {
            SetupWizard::new(&self.setup)
                .step("Containers", |ui| {
                    let engines = Select::new(["podman", "docker"]).selected(Some(self.engine));
                    ui.add(engines.on_select(Msg::Engine));
                })
                .show(ui);
        }
    }
}

let family = Family::QUVYTA;
// An application calls `Setup::new(family, "code", &i18n, Msg::Setup)`; the example keeps to a
// folder of its own.
let setup = Setup::new_in(&folder, family, "code", &I18n::builtin(), Msg::Setup).on_finish(Msg::Ready);
let settings = Settings::open(folder.join("code.conf")).member_of(&family);
let mut app = Harness::new(Code { setup, settings, engine: 0 }, 60, 24);
assert!(app.screen().contains("In every Quvyta application"));
assert!(!folder.exists(), "nothing is written before the wizard finishes");

Implementations§

Source§

impl<Msg: Clone + Send + 'static> Setup<Msg>

Source

pub fn new( family: Family, app: impl Into<String>, i18n: &I18n, wrap: impl Fn(SetupMsg) -> Msg + Send + Sync + 'static, ) -> Self

The setup of application app of family, on its first step, with every message of the first step wrapped as wrap.

The shared preferences are resolved without writing anything (Family::preferences_without_saving), so the appearance step comes filled with what the family already shares, or with what this machine detects, and the user’s settings folder stays as it is until the wizard finishes. An application that has taken over an older settings file migrates it (Family::adopt) before making this, so a migrated application is not asked again.

Source

pub fn new_in( config_dir: &Path, family: Family, app: impl Into<String>, i18n: &I18n, wrap: impl Fn(SetupMsg) -> Msg + Send + Sync + 'static, ) -> Self

new with config_dir as the family’s folder instead of this platform’s, for a test or a demo that must leave the user’s own files alone.

Source

pub fn on_finish(self, message: Msg) -> Self

The message the application is sent once the wizard has written the shared keys and made the application’s file: where the application writes its own keys.

Source

pub fn install(self, install: Install) -> Self

Installs the Nerd Font symbols with install instead of Install::new, for a test or a demo that must leave the user’s own fonts alone.

Source

pub fn font_dirs(self, dirs: Vec<PathBuf>) -> Self

Looks for a Nerd Font in dirs instead of this system’s font folders, for a test or a demo.

Source

pub fn needed(&self) -> bool

Whether the wizard is still to be shown: the application has no settings file of its own and the wizard has not finished.

Source

pub fn step(&self) -> usize

The step the wizard is on, counting the appearance step as 0.

Source

pub fn preferences(&self) -> &Preferences

The shared preferences as the appearance step has them now, before anything is written.

Source

pub fn update( &mut self, message: SetupMsg, settings: &mut Settings, ) -> Command<Msg>

Applies message and returns the command that shows it: a theme, a language or an icon mode is applied at once, so the wizard is drawn the way the user just chose. settings are the application’s own settings as it holds them in memory; they take every shared key too, so a later Settings::save writes what the wizard wrote instead of what the file said before.

On SetupMsg::Finish the three shared keys are written with Family::set, each to the family’s file or the application’s own by its box, and the application’s file is made. Only then is the wizard over and the message of Setup::on_finish sent. A write that fails leaves the wizard open and says why.

Trait Implementations§

Source§

impl<Msg> Debug for Setup<Msg>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<Msg> !RefUnwindSafe for Setup<Msg>

§

impl<Msg> !UnwindSafe for Setup<Msg>

§

impl<Msg> Freeze for Setup<Msg>
where Arc<dyn Fn(SetupMsg) -> Msg + Send + Sync>: Freeze, Option<Msg>: Freeze,

§

impl<Msg> Send for Setup<Msg>
where Arc<dyn Fn(SetupMsg) -> Msg + Send + Sync>: Send, Option<Msg>: Send,

§

impl<Msg> Sync for Setup<Msg>
where Arc<dyn Fn(SetupMsg) -> Msg + Send + Sync>: Sync, Option<Msg>: Sync,

§

impl<Msg> Unpin for Setup<Msg>
where Arc<dyn Fn(SetupMsg) -> Msg + Send + Sync>: Unpin, Option<Msg>: Unpin,

§

impl<Msg> UnsafeUnpin for Setup<Msg>
where Arc<dyn Fn(SetupMsg) -> Msg + Send + Sync>: UnsafeUnpin, Option<Msg>: UnsafeUnpin,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.