notesy::wizards

A few pages one after another on a card over everything, the way notesy's own welcome tour goes: a setup to get a plugin going, a tour of what it does. Each page is a view (notesy::view): an icon over its title and a line or two, then whatever's on it, inputs included. It takes the ui permission, as dialogs do.

rustuse notesy::{store, view, wizards, Icon};

pub fn ready() {
    // Once, on its first run.
    if store::get("set_up").unwrap_or(false) {
        return;
    }
    let setup = wizards::open("setup", #{ pages: 3, done: "Start" }, |page| setup_page(page));
    setup.on_change(|target, value| store::set(target, value));
    setup.on_done(|| store::set("set_up", true));
    setup.on_close(|page| store::set("set_up", true));
}

// Each page in a function of its own: Rune loses the value of a block
// that ends in a variable of its own, like a match arm's.
fn setup_page(page) {
    if page == 0 {
        about_page()
    } else if page == 1 {
        city_page()
    } else {
        units_page()
    }
}

fn about_page() {
    let p = view::page("Weather in your notes", view::note("Today's forecast in a panel, and in each daily note."));
    p.icon = "sun";
    p.message = "Two quick questions, and it's ready.";
    p
}

fn city_page() {
    let city = view::input("A town or city, then Enter");
    city.target = "city";
    let now = view::note(`Now: ${store::get("city").unwrap_or("nowhere yet")}`);
    let p = view::page("Where are you?", [city, now]);
    p.icon = Icon::Pin;
    // Its way on waits until there's a city.
    p.ready = store::get("city").is_some();
    p
}

fn units_page() {
    let units = view::segmented(["°C", "°F"], store::get("units").unwrap_or("°C"));
    units.target = "units";
    let p = view::page("Which units?", [units]);
    p.icon = "gauge";
    p
}

The script doesn't wait on it: what the user does comes to the functions it gave, later, as a panel's clicks do.

Function What it does
wizards::open(key, options, build) Opens a wizard of its own, and returns it. build(page) makes page page (from 0): a view::page, or any view, shown as it is. It's built again when the user comes to the page, and after something on it changes.
Option What it is
pages How many pages it has, 1 to 12. It needs it.
done What the way on from its last page says: Done unless it says.
skip The words at its foot that put it away before its end: Skip unless it says, or false for none (Esc and its × still do).
icon Its icon, in its corner by the plugin's name: the plugin's own unless it says.

#A page

view::page(title, parts) makes a page: its parts (a part of a view, or a list of them) under its title. Set any of these on it after:

Field What it is
icon An icon over its title, on a tile in the accent: by name, the plugin's own first. One it draws with keyframes moves (notesy::icons).
message A line or two under its title.
ready false holds its way on (faint, and deaf to clicks, Enter and →) until the page is built again with it true: until what it asks is filled in, say. true unless it says.
auto Seconds it shows before the next comes by itself, 1 to 60: a tour's page. The dot it's on fills as the clock to the next; a click on it, or Space, holds it. Never from its last page, nor while it's not ready.

Its parts are heard as a dialog's are: a click on one with a target reaches on_click, a change to an input on_change, and the page is built again after. Parts can come in as they show (notesy::view).

Method What it does
on_done(handler) handler() when it's gone through to its end and its last way on taken.
on_close(handler) handler(page) when it's put away before that: its skip, its ×, or Esc, on page.
on_click(handler) handler(target) when something on a page with a target is clicked.
on_change(handler) handler(target, value) when a switch, box, field or choice on a page with a target changes.
refresh() Builds its pages again: after what they show changed.
close() Puts it away, unanswered.

#How it shows

As notesy's own welcome tour does: sized to the window, dots at its foot for where it is, the way back and the way on beside them, and the words to put it away. → and Enter go on, ← back, Esc puts it away (while something's being typed into, the keys are the field's, Esc aside). With Motion off (Settings, Appearance), nothing in it moves and nothing goes on by itself.

It waits its turn with the plugin's dialogs: one at a time, never over one of notesy's, and at most 3 of a plugin's dialogs and wizards waiting at once. It says in its corner which plugin it's from, with the plugin's icon, so it can't pass for one of notesy's. What a script opened goes, unanswered, when it stops.

Every page