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>
impl<Msg: Clone + Send + 'static> Setup<Msg>
Sourcepub fn new(
ecosystem: Ecosystem,
app: impl Into<String>,
i18n: &I18n,
wrap: impl Fn(SetupMsg) -> Msg + Send + Sync + 'static,
) -> Self
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.
Sourcepub fn new_in(
config_dir: &Path,
ecosystem: Ecosystem,
app: impl Into<String>,
i18n: &I18n,
wrap: impl Fn(SetupMsg) -> Msg + Send + Sync + 'static,
) -> Self
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.
Sourcepub fn on_finish(self, message: Msg) -> Self
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.
Sourcepub fn install(self, install: Install) -> Self
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.
Sourcepub fn font_dirs(self, dirs: Vec<PathBuf>) -> Self
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.
Sourcepub fn appearance_only(self) -> Self
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.
Sourcepub fn needed(&self) -> bool
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.
Sourcepub fn asks_appearance(&self) -> bool
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.
Sourcepub fn step(&self) -> usize
pub fn step(&self) -> usize
The step the wizard is on, counting the appearance step as 0 whether or not it is shown.
Sourcepub fn preferences(&self) -> &Preferences
pub fn preferences(&self) -> &Preferences
The shared preferences as the appearance step has them now, before anything is written.
Sourcepub fn update(
&mut self,
message: SetupMsg,
settings: &mut Settings,
) -> Command<Msg>
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§
Auto Trait Implementations§
impl<Msg> !RefUnwindSafe for Setup<Msg>
impl<Msg> !UnwindSafe for Setup<Msg>
impl<Msg> Freeze for Setup<Msg>
impl<Msg> Send for Setup<Msg>
impl<Msg> Sync for Setup<Msg>
impl<Msg> Unpin for Setup<Msg>
impl<Msg> UnsafeUnpin for Setup<Msg>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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