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 of its own. 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.

When the ecosystem’s shared file already holds a language, a theme and icons, the question has been answered in another member: the appearance step is left out, the wizard opens on the application’s first step of its own and Finish makes the application follow the shared values. An application without steps of its own says so with Setup::appearance_only, and then the wizard is not needed at all. Without a whole shared file the appearance step comes first, filled in from what there is.

use qframe::i18n::I18n;
use qframe::prelude::*;
use qframe::storage::{Ecosystem, 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 ecosystem = Ecosystem::QUVYTA;
// An application calls `Setup::new(ecosystem, "code", &i18n, Msg::Setup)`; the example keeps to a
// folder of its own.
let setup = Setup::new_in(&folder, ecosystem, "code", &I18n::builtin(), Msg::Setup).on_finish(Msg::Ready);
let settings = Settings::open(folder.join("code.conf")).member_of(&ecosystem);
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( ecosystem: Ecosystem, app: impl Into<String>, i18n: &I18n, wrap: impl Fn(SetupMsg) -> Msg + Send + Sync + 'static, ) -> Self

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

The shared preferences are resolved without writing anything (Ecosystem::preferences_without_saving), so the appearance step comes filled with what the ecosystem 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 (Ecosystem::adopt) before making this, so a migrated application is not asked again.

Source

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

new with config_dir as the ecosystem’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 appearance_only(self) -> Self

Says that the application adds no steps of its own, so a wizard whose appearance step is answered by the shared file would have nothing to ask. Then it is finished here and now: the application’s file is written following the ecosystem for language, theme and icons, so the question is not asked again, and needed is false. The message of on_finish is not sent; the application’s settings, loaded after this, read the file as it now is.

Without a whole shared file the wizard is needed as before, with the appearance step alone. A write that fails leaves it needed too, on the appearance step and saying why.

Source

pub fn needed(&self) -> bool

Whether the wizard is still to be shown: the application has no settings of its own (no file, or one holding nothing but the mark Ecosystem::settle leaves), the wizard has not finished, and appearance_only did not find the question answered already.

Source

pub fn asks_appearance(&self) -> bool

Whether the appearance step is shown. False when the shared file already holds a language, a theme and icons: the wizard then opens on the application’s first step, 1.

Source

pub fn step(&self) -> usize

The step the wizard is on, counting the appearance step as 0 whether or not it is shown.

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 Ecosystem::set, each to the ecosystem’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.