cursive/doc/tutorial_1.md

163 lines
4.6 KiB
Markdown
Raw Normal View History

2016-09-01 01:18:52 +00:00
# Starting with cursive: (1/3)
2016-08-16 00:26:44 +00:00
## Target goal
In this first tutorial, we'll learn the basics of cursive,
2016-08-20 08:22:07 +00:00
and write a very basic first application:
2016-08-16 00:26:44 +00:00
2016-09-28 22:22:21 +00:00
```rust,no_run
2016-08-16 00:26:44 +00:00
use cursive::views::TextView;
fn main() {
let mut siv = cursive::default();
2016-08-16 00:26:44 +00:00
siv.add_global_callback('q', |s| s.quit());
siv.add_layer(TextView::new("Hello cursive! Press <q> to quit."));
siv.run();
}
```
Run the application, and you should have something like this:
2016-08-16 00:36:04 +00:00
2016-09-01 01:21:28 +00:00
![Tutorial 1 goal](./tutorial_1.png)
2016-08-16 00:26:44 +00:00
Now that you have an idea of what we'll do, let's start from scratch.
## Project configuration
Let's create a new project
(this is basic cargo stuff I hope you're familiar with):
```text
% cargo new --bin cursive_example
```
Now, we'll add cursive to the list of dependencies in `Cargo.toml`:
```toml
[package]
name = "cursive_example"
version = "0.1.0"
[dependencies]
cursive = "*"
```
Finally, update `src/main.rs` to import it:
2016-09-28 22:22:21 +00:00
```rust,no_run
2016-08-16 00:26:44 +00:00
fn main() {
}
```
This simple application is now ready to use cursive. So let's do just that!
## The Cursive root
2016-08-16 00:36:04 +00:00
The cursive library is configured through a main [`Cursive`] root.
2016-08-16 00:26:44 +00:00
A typical cursive application will consist of three phases,
all centered around this object:
1. Create a `Cursive` object (we will use the [`cursive::default()`] method for that)
2. Configure the `Cursive` object
3. Run the `Cursive` object
2016-08-16 00:26:44 +00:00
Of these, the configuration phase is often the largest one,
so let's skip it for now.
In its simplest form, a cursive application is therefore:
2016-09-28 22:22:21 +00:00
```rust,no_run
2016-08-16 00:26:44 +00:00
fn main() {
let mut siv = cursive::default();
2016-08-16 00:26:44 +00:00
siv.run();
}
```
It's rather easy to identify the two steps involved.
If you run this, you'll get an empty blue terminal, with no way of properly
2018-07-25 04:27:17 +00:00
leaving the application (you'll have to press <kbd>Ctrl</kbd>+<kbd>C</kbd> to kill it).
2016-08-16 00:26:44 +00:00
[`cursive::default()`]: https://docs.rs/cursive/0/cursive/fn.default.html
2018-03-18 17:09:58 +00:00
[`Cursive`]: https://docs.rs/cursive/0/cursive/struct.Cursive.html
2016-08-16 00:36:04 +00:00
2016-08-16 00:26:44 +00:00
## Interactivity
Let's first add a way to stop the application. We want to quit when the user
2016-09-01 15:22:40 +00:00
presses the letter `q`.
2016-08-16 00:26:44 +00:00
Cursive sends an event for every user input; most of these are just ignored
and have no effect. The `Cursive` root has an [`add_global_callback`] method to
2016-08-16 00:36:04 +00:00
call a function anytime a certain event is fired.
This method takes 2 arguments: a trigger, and a callback.
2016-08-16 00:26:44 +00:00
* The trigger needs to implement `Into<event::Event>`. In addition to
2016-08-16 00:36:04 +00:00
[`event::Event`] itself, this includes [`event::Key`], or simply `char`.
These will trigger when the corresponding key (or letter) is pressed.
* The callback should be a function taking an `&mut Cursive` as an argument. Here,
2016-08-16 00:36:04 +00:00
we want to quit, so we'll use [`Cursive::quit`] in a closure: `|s| s.quit()`.
2016-08-16 00:26:44 +00:00
In the end, we have:
2016-09-28 22:22:21 +00:00
```rust,no_run
2016-08-16 00:26:44 +00:00
fn main() {
let mut siv = cursive::default();
2016-08-16 00:26:44 +00:00
siv.add_global_callback('q', |s| s.quit());
siv.run();
}
```
As expected, running it shows no visible change, but hitting the `q` key does
close the application.
2016-08-16 00:26:44 +00:00
2018-03-18 17:09:58 +00:00
[`add_global_callback`]: https://docs.rs/cursive/0/cursive/struct.Cursive.html#method.add_global_callback
[`event::Event`]: https://docs.rs/cursive/0/cursive/event/enum.Event.html
[`event::Key`]: https://docs.rs/cursive/0/cursive/event/enum.Key.html
[`Cursive::quit`]: https://docs.rs/cursive/0/cursive/struct.Cursive.html#method.quit
2016-08-16 00:36:04 +00:00
2016-08-16 00:26:44 +00:00
## Views
[`Views`] are the main components of the user interface in a cursive
2016-08-16 00:36:04 +00:00
application. At their core, they define what to draw in a rectangle of the
terminal. For instance, a view can print a line of text, or a checkbox, etc.
2016-08-16 00:26:44 +00:00
2016-08-16 00:36:04 +00:00
Here, we'll be using a [`TextView`] to show a short message. `TextView` itself
2016-08-16 00:26:44 +00:00
can also deal with long text and do proper word-wrapping, but we won't need
that today.
The `TextView` constructor just takes the text to use: `TextView::new("...")`.
2016-08-16 00:36:04 +00:00
The `Cursive` root itself uses a [`StackView`] on the entire screen. This
2016-08-16 00:26:44 +00:00
`StackView` unsurprisingly stacks views in layers. It starts empty, so we'll
just need to add our `TextView` as a layer. [`Cursive::add_layer`] lets us do
2016-08-16 00:26:44 +00:00
exactly that.
Once we've added this line, our first application is complete:
2016-09-28 22:22:21 +00:00
```rust,no_run
2016-08-16 00:26:44 +00:00
use cursive::views::TextView;
fn main() {
let mut siv = cursive::default();
2016-08-16 00:26:44 +00:00
siv.add_global_callback('q', |s| s.quit());
siv.add_layer(TextView::new("Hello cursive! Press <q> to quit."));
siv.run();
}
```
2016-08-16 00:36:04 +00:00
[`Views`]: https://docs.rs/cursive/0/cursive/view/trait.View.html
2018-03-18 17:09:58 +00:00
[`TextView`]: https://docs.rs/cursive/0/cursive/views/struct.TextView.html
[`StackView`]: https://docs.rs/cursive/0/cursive/views/struct.StackView.html
[`Cursive::add_layer`]: https://docs.rs/cursive/0/cursive/struct.Cursive.html#method.add_layer
2016-09-01 15:22:40 +00:00
Next: [Starting with Cursive (2/3)](./tutorial_2.md)