From 76aa5f4dc45290450ff0b692fa44474338dec595 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Tue, 21 May 2024 14:46:30 +0200 Subject: [PATCH] doc: add book --- book/.gitignore | 1 + book/book.toml | 6 +++ book/src/SUMMARY.md | 41 ++++++++++++++++ book/src/application.md | 2 + book/src/buttons.md | 1 + book/src/check-box.md | 1 + book/src/color-picker.md | 1 + book/src/column.md | 1 + book/src/commands.md | 83 +++++++++++++++++++++++++++++++++ book/src/container.md | 1 + book/src/context-drawer.md | 1 + book/src/context-menu.md | 1 + book/src/creating-a-widget.md | 1 + book/src/creating-an-overlay.md | 1 + book/src/dialog.md | 1 + book/src/divider.md | 1 + book/src/dropdown.md | 1 + book/src/examples.md | 1 + book/src/flex-row.md | 1 + book/src/grid.md | 1 + book/src/icon.md | 1 + book/src/image.md | 1 + book/src/introduction.md | 18 +++++++ book/src/menu-bar.md | 1 + book/src/mvu.md | 71 ++++++++++++++++++++++++++++ book/src/nav-bar.md | 1 + book/src/pane-grid.md | 1 + book/src/radio.md | 1 + book/src/row.md | 1 + book/src/segmented-buttons.md | 1 + book/src/segmented-controls.md | 1 + book/src/slider.md | 1 + book/src/space.md | 1 + book/src/spin-button.md | 1 + book/src/subscriptions.md | 1 + book/src/svg.md | 1 + book/src/tab-bar.md | 1 + book/src/text-input.md | 1 + book/src/text.md | 9 ++++ book/src/todo.md | 1 + book/src/toggler.md | 1 + book/src/widgets.md | 1 + 42 files changed, 265 insertions(+) create mode 100644 book/.gitignore create mode 100644 book/book.toml create mode 100644 book/src/SUMMARY.md create mode 100644 book/src/application.md create mode 100644 book/src/buttons.md create mode 100644 book/src/check-box.md create mode 100644 book/src/color-picker.md create mode 100644 book/src/column.md create mode 100644 book/src/commands.md create mode 100644 book/src/container.md create mode 100644 book/src/context-drawer.md create mode 100644 book/src/context-menu.md create mode 100644 book/src/creating-a-widget.md create mode 100644 book/src/creating-an-overlay.md create mode 100644 book/src/dialog.md create mode 100644 book/src/divider.md create mode 100644 book/src/dropdown.md create mode 100644 book/src/examples.md create mode 100644 book/src/flex-row.md create mode 100644 book/src/grid.md create mode 100644 book/src/icon.md create mode 100644 book/src/image.md create mode 100644 book/src/introduction.md create mode 100644 book/src/menu-bar.md create mode 100644 book/src/mvu.md create mode 100644 book/src/nav-bar.md create mode 100644 book/src/pane-grid.md create mode 100644 book/src/radio.md create mode 100644 book/src/row.md create mode 100644 book/src/segmented-buttons.md create mode 100644 book/src/segmented-controls.md create mode 100644 book/src/slider.md create mode 100644 book/src/space.md create mode 100644 book/src/spin-button.md create mode 100644 book/src/subscriptions.md create mode 100644 book/src/svg.md create mode 100644 book/src/tab-bar.md create mode 100644 book/src/text-input.md create mode 100644 book/src/text.md create mode 100644 book/src/todo.md create mode 100644 book/src/toggler.md create mode 100644 book/src/widgets.md diff --git a/book/.gitignore b/book/.gitignore new file mode 100644 index 00000000..7585238e --- /dev/null +++ b/book/.gitignore @@ -0,0 +1 @@ +book diff --git a/book/book.toml b/book/book.toml new file mode 100644 index 00000000..fd64a5f0 --- /dev/null +++ b/book/book.toml @@ -0,0 +1,6 @@ +[book] +authors = ["Michael Aaron Murphy"] +language = "en" +multilingual = false +src = "src" +title = "COSMIC Toolkit" diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md new file mode 100644 index 00000000..7aa47cd3 --- /dev/null +++ b/book/src/SUMMARY.md @@ -0,0 +1,41 @@ +# Summary + +- [Introduction](./introduction.md) +- [Model-View-Update (MVU)](./mvu.md) +- [Commands](./commands.md) +- [Subscriptions](./subscriptions.md) +- [A Basic Application](./application.md) +- [Nav Bar](./nav-bar.md) +- [Menu Bar](./menu-bar.md) +- [Context Drawer](./context-drawer.md) +- [Widgets](./widgets.md) + - [Text](./text.md) + - [Container](./container.md) + - [Column](./column.md) + - [Row](./row.md) + - [Buttons](./buttons.md) + - [Icon](./icon.md) + - [Image](./image.md) + - [Svg](./svg.md) + - [Divider](./divider.md) + - [Space](./space.md) + - [Text Input](./text-input.md) + - [Toggler](./toggler.md) + - [Slider](./slider.md) + - [Radio](./radio.md) + - [Check Box](./check-box.md) + - [Dropdown](./dropdown.md) + - [Spin Button](./spin-button.md) + - [Color Picker](./color-picker.md) + - [Flex Row](./flex-row.md) + - [Grid](./grid.md) + - [Segmented Buttons](./segmented-buttons.md) + - [Tab Bar](./tab-bar.md) + - [Segmented Controls](./segmented-controls.md) + - [Context Menu](./context-menu.md) + - [Dialog](./dialog.md) + - [Pane Grid](./pane-grid.md) +- [Creating a Widget](./creating-a-widget.md) +- [Creating an Overlay](./creating-an-overlay.md) +- [Examples](./examples.md) + - [Todo](./todo.md) diff --git a/book/src/application.md b/book/src/application.md new file mode 100644 index 00000000..ecfa26b0 --- /dev/null +++ b/book/src/application.md @@ -0,0 +1,2 @@ +# A Basic Application + diff --git a/book/src/buttons.md b/book/src/buttons.md new file mode 100644 index 00000000..8694b481 --- /dev/null +++ b/book/src/buttons.md @@ -0,0 +1 @@ +# Buttons diff --git a/book/src/check-box.md b/book/src/check-box.md new file mode 100644 index 00000000..497ebbc0 --- /dev/null +++ b/book/src/check-box.md @@ -0,0 +1 @@ +# Check Box diff --git a/book/src/color-picker.md b/book/src/color-picker.md new file mode 100644 index 00000000..802a3aca --- /dev/null +++ b/book/src/color-picker.md @@ -0,0 +1 @@ +# Color Picker diff --git a/book/src/column.md b/book/src/column.md new file mode 100644 index 00000000..af2fe583 --- /dev/null +++ b/book/src/column.md @@ -0,0 +1 @@ +# Column diff --git a/book/src/commands.md b/book/src/commands.md new file mode 100644 index 00000000..0ed7a952 --- /dev/null +++ b/book/src/commands.md @@ -0,0 +1,83 @@ +# Commands + +[Commands][command] are short-lived async tasks that are spawned onto an async executor on a background thread. They must return a message back to the application upon completion, and cannot directly send messages back to the application until they return. + +> **NOTE**: While it is not possible for a command to directly send messages before completion, it is possible to create a subscription from a channel which passes its sender to the application, which may then pass that sender into its commands. + +## Future + +Commands may be created from futures using [cosmic::command::future](future). + +```rs +fn update(&mut self, message: Self::Message) -> Command { + match message { + Message::Clicked => { + self.counter += 1; + self.counter_text = format!("Clicked {} times", self.counter); + + // Await for 3 seconds in the background, and then request to decrease the counter. + return cosmic::command::future(async move { + tokio::time::sleep(Duration::from_millis(3000)).await; + Message::Decrease + }); + } + + Message::Decrease => { + self.counter -= 1; + self.counter_text = format!("Clicked {} times", self.counter); + } + } + + Command::none() +} +``` + +## Batches + +They can also be [batched][batch] for concurrent execution, where messages will be received in the order of completion. + +```rs +fn update(&mut self, message: Self::Message) -> Command { + match message { + Message::BatchStarted => { + eprintln!("started handling batch"); + } + + Message::Clicked => { + self.counter += 1; + self.counter_text = format!("Clicked {} times", self.counter); + + // Run two async tasks concurrently. + return cosmic::command::batch(vec![ + // Await for 3 seconds in the background, and then request to decrease the counter. + cosmic::command::future(async move { + tokio::time::sleep(Duration::from_millis(3000)).await; + Message::Decrease + }), + // Immediately returns a message without waiting. + cosmic::command::message(Message::BatchStarted) + ]); + } + + Message::Decrease => { + self.counter -= 1; + self.counter_text = format!("Clicked {} times", self.counter); + } + } + + Command::none() +} +``` + +## Widget Operations + +They can also be used to perform an operation onto a widget, such as focusing a button or text input. + +```rs +return cosmic::widget::button::focus(self.BUTTON_ID); +``` + +[batch]: https://pop-os.github.io/libcosmic/cosmic/command/fn.batch.html +[command]: https://pop-os.github.io/libcosmic/cosmic/iced_winit/runtime/struct.Command.html +[cosmic-commands]: https://pop-os.github.io/libcosmic/cosmic/app/command/index.html#functions +[future]: https://pop-os.github.io/libcosmic/cosmic/command/fn.future.html \ No newline at end of file diff --git a/book/src/container.md b/book/src/container.md new file mode 100644 index 00000000..cc0210d8 --- /dev/null +++ b/book/src/container.md @@ -0,0 +1 @@ +# Container diff --git a/book/src/context-drawer.md b/book/src/context-drawer.md new file mode 100644 index 00000000..bbf3b90a --- /dev/null +++ b/book/src/context-drawer.md @@ -0,0 +1 @@ +# Context Drawer diff --git a/book/src/context-menu.md b/book/src/context-menu.md new file mode 100644 index 00000000..021893bf --- /dev/null +++ b/book/src/context-menu.md @@ -0,0 +1 @@ +# Context Menu diff --git a/book/src/creating-a-widget.md b/book/src/creating-a-widget.md new file mode 100644 index 00000000..db9e908e --- /dev/null +++ b/book/src/creating-a-widget.md @@ -0,0 +1 @@ +# Creating a Widget diff --git a/book/src/creating-an-overlay.md b/book/src/creating-an-overlay.md new file mode 100644 index 00000000..7ba12ab7 --- /dev/null +++ b/book/src/creating-an-overlay.md @@ -0,0 +1 @@ +# Creating an Overlay diff --git a/book/src/dialog.md b/book/src/dialog.md new file mode 100644 index 00000000..9ebf2583 --- /dev/null +++ b/book/src/dialog.md @@ -0,0 +1 @@ +# Dialog diff --git a/book/src/divider.md b/book/src/divider.md new file mode 100644 index 00000000..d5116f54 --- /dev/null +++ b/book/src/divider.md @@ -0,0 +1 @@ +# Divider diff --git a/book/src/dropdown.md b/book/src/dropdown.md new file mode 100644 index 00000000..78dc117b --- /dev/null +++ b/book/src/dropdown.md @@ -0,0 +1 @@ +# Dropdown diff --git a/book/src/examples.md b/book/src/examples.md new file mode 100644 index 00000000..df635b4e --- /dev/null +++ b/book/src/examples.md @@ -0,0 +1 @@ +# Examples diff --git a/book/src/flex-row.md b/book/src/flex-row.md new file mode 100644 index 00000000..f1df6719 --- /dev/null +++ b/book/src/flex-row.md @@ -0,0 +1 @@ +# Flex Row diff --git a/book/src/grid.md b/book/src/grid.md new file mode 100644 index 00000000..ee8abf42 --- /dev/null +++ b/book/src/grid.md @@ -0,0 +1 @@ +# Grid diff --git a/book/src/icon.md b/book/src/icon.md new file mode 100644 index 00000000..5edd6ec2 --- /dev/null +++ b/book/src/icon.md @@ -0,0 +1 @@ +# Icon diff --git a/book/src/image.md b/book/src/image.md new file mode 100644 index 00000000..77cfc546 --- /dev/null +++ b/book/src/image.md @@ -0,0 +1 @@ +# Image diff --git a/book/src/introduction.md b/book/src/introduction.md new file mode 100644 index 00000000..4376d896 --- /dev/null +++ b/book/src/introduction.md @@ -0,0 +1,18 @@ +# Introduction + +[libcosmic][toolkit] is the platform toolkit for [COSMIC](cosmic)—a GUI toolkit which empowers everyone to build COSMIC-themed applets and applications with ease. Based on the cross-platform [iced][iced] GUI library—which it utilizes for its runtime and rendering primitives—the COSMIC toolkit features personalizable desktop theming, a responsive widget library, a configuration system, platform integrations, and its own interface guidelines for building consistent and responsive applications. + +As a Rust-based GUI toolkit, experience with [Rust](rust) is required. Rust's rich type system and language features are key to what makes the COSMIC toolkit a much friendlier developer experience—enabling secure, reliable, and efficient applications to be developed at a faster pace than would be possible otherwise. For those interested in learning Rust, there are a lot of good resources available: [Learn Rust in a Month of Lunches][month-of-lunches], [Rust in Action][rust-in-action], [Rust by Example][rust-by-example], the official [Rust Book][rust-book], and [Rustlings][rustlings]. + +Although the toolkit was created for the COSMIC desktop environment, it is also cross-platform, and thus it can be used to build COSMIC-themed applications for Linux (X11 & Wayland), [Redox OS](redox-os), Windows, and Mac. Even mobile platforms could be a possibility someday. One of the goals of libcosmic is to enable the creation of a cross-platform ecosystem of applications that are easy to port from one OS to another. We would also welcome any that would like to build their own OS experiences with the COSMIC toolkit. + +[cosmic]: https://github.com/pop-os/cosmic-epoch +[iced]: https://iced.rs/ +[month-of-lunches]: https://www.manning.com/books/learn-rust-in-a-month-of-lunches +[redox-os]: https://redox-os.org/ +[rust]: https://www.rust-lang.org/ +[rust-book]: https://doc.rust-lang.org/stable/book/ +[rust-by-example]: https://doc.rust-lang.org/rust-by-example/ +[rust-in-action]: https://www.manning.com/books/rust-in-action +[rustlings]: https://github.com/rust-lang/rustlings +[toolkit]: https://github.com/pop-os/libcosmic diff --git a/book/src/menu-bar.md b/book/src/menu-bar.md new file mode 100644 index 00000000..be8f3777 --- /dev/null +++ b/book/src/menu-bar.md @@ -0,0 +1 @@ +# MenuBar diff --git a/book/src/mvu.md b/book/src/mvu.md new file mode 100644 index 00000000..713a2413 --- /dev/null +++ b/book/src/mvu.md @@ -0,0 +1,71 @@ +# Model-View-Update (MVU) + +Iced, and thereby COSMIC, uses a model-view-update approach to GUI development; also known as TEA—[The Elm Architecture][tea]. Similar to Elm, this architecture also emerged naturally in the Rust ecosystem as programmers searched for ways to model applications and services which adhere to Rust's [aliasing XOR mutability rule][aliasing-xor-mutability]. + +

+

+ +
The Runtime—from the iced-rs book
+
+

+ +By structuring an application around an event loop which has ownership of a model, each iteration of the loop can immutably borrow the model to create a view, and mutably borrow the model to update the model with received messages. This eliminates the need for shared references, interior mutability, and runtime borrow checking. + +> **BACKGROUND**: Before working on COSMIC, the [Pop!_OS][pop-os] team at [System76][system76] was modeling each of their GTK applications with TEA. This would be eventually be formalized into [Relm4][Relm4], which is now the best way to build GTK4 applications in Rust. Event loops are spawned onto the glib runtime for the application and its components. These event loops await messages from a channel, whose senders would be attached to GTK widgets to enable them to publish messages when triggered. + +## Model + +Every application begins with a struct that implements the [cosmic::Application][app-trait] trait—which will serve as the application's model. All application state will be stored in this model, and it will be wise to cache data that will be needed by your application's widgets. + +```rs +struct AppModel { + counter: u32, + counter_text: String, +} + +impl cosmic::Application for AppModel {} +``` + +## View + +Whenever application or UI state changes; such as the movement of a mouse; the [view method][view-method] will be called to create a view which describes the current state of the UI. The view defines the layout of the interface, how it is to be drawn, and what messages widgets will emit when triggered. The runtime will pass UI events through the view and react upon messages that are emitted. + +```rs +fn view(&self) -> Element { + let button = widget::button(&self.counter_text) + .on_press(Message::Clicked); + + widget::container(button) + .width(iced::Length::Fill) + .height(iced::Length::Shrink) + .center_x() + .center_y() + .into() +} +``` + +## Update + +Messages emitted by the view will later be passed through the application's [update method][update-method]. This will use Rust's pattern matching to choose a branch to execute, make any changes necessary to the application's model, and may optionally return one or more commands. + +```rs +fn update(&mut self, message: Self::Message) -> Command { + match message { + Message::Clicked => { + self.counter += 1; + self.counter_text = format!("Clicked {} times", self.counter); + } + } + + Command::none() +} +``` + +[aliasing-xor-mutability]: https://cmpt-479-982.github.io/week1/safety_features_of_rust.html#the-borrow-checker-and-the-aliasing-xor-mutability-principle +[app-trait]: https://pop-os.github.io/libcosmic/cosmic/app/trait.Application.html +[pop-os]: https://system76.com/pop +[relm4]: https://github.com/Relm4/relm4 +[system76]: https://system76.com/ +[tea]: https://guide.elm-lang.org/architecture/ +[update-method]: https://pop-os.github.io/libcosmic/cosmic/app/trait.Application.html#method.update +[view-method]: https://pop-os.github.io/libcosmic/cosmic/app/trait.Application.html#tymethod.view diff --git a/book/src/nav-bar.md b/book/src/nav-bar.md new file mode 100644 index 00000000..b9025304 --- /dev/null +++ b/book/src/nav-bar.md @@ -0,0 +1 @@ +# Nav Bar diff --git a/book/src/pane-grid.md b/book/src/pane-grid.md new file mode 100644 index 00000000..91d1bdf0 --- /dev/null +++ b/book/src/pane-grid.md @@ -0,0 +1 @@ +# Pane Grid diff --git a/book/src/radio.md b/book/src/radio.md new file mode 100644 index 00000000..aff240e4 --- /dev/null +++ b/book/src/radio.md @@ -0,0 +1 @@ +# Radio diff --git a/book/src/row.md b/book/src/row.md new file mode 100644 index 00000000..c5d6e529 --- /dev/null +++ b/book/src/row.md @@ -0,0 +1 @@ +# Row diff --git a/book/src/segmented-buttons.md b/book/src/segmented-buttons.md new file mode 100644 index 00000000..31c5578d --- /dev/null +++ b/book/src/segmented-buttons.md @@ -0,0 +1 @@ +# Segmented Buttons diff --git a/book/src/segmented-controls.md b/book/src/segmented-controls.md new file mode 100644 index 00000000..ba7c0fa7 --- /dev/null +++ b/book/src/segmented-controls.md @@ -0,0 +1 @@ +# Segmented Controls diff --git a/book/src/slider.md b/book/src/slider.md new file mode 100644 index 00000000..60a0cc1f --- /dev/null +++ b/book/src/slider.md @@ -0,0 +1 @@ +# Slider diff --git a/book/src/space.md b/book/src/space.md new file mode 100644 index 00000000..7df2393a --- /dev/null +++ b/book/src/space.md @@ -0,0 +1 @@ +# Space diff --git a/book/src/spin-button.md b/book/src/spin-button.md new file mode 100644 index 00000000..960e71d1 --- /dev/null +++ b/book/src/spin-button.md @@ -0,0 +1 @@ +# Spin Button diff --git a/book/src/subscriptions.md b/book/src/subscriptions.md new file mode 100644 index 00000000..5abadfc8 --- /dev/null +++ b/book/src/subscriptions.md @@ -0,0 +1 @@ +# Subscriptions diff --git a/book/src/svg.md b/book/src/svg.md new file mode 100644 index 00000000..8c13ab5a --- /dev/null +++ b/book/src/svg.md @@ -0,0 +1 @@ +# Svg diff --git a/book/src/tab-bar.md b/book/src/tab-bar.md new file mode 100644 index 00000000..550cfccc --- /dev/null +++ b/book/src/tab-bar.md @@ -0,0 +1 @@ +# Tab Bar diff --git a/book/src/text-input.md b/book/src/text-input.md new file mode 100644 index 00000000..2d00c066 --- /dev/null +++ b/book/src/text-input.md @@ -0,0 +1 @@ +# Text Input diff --git a/book/src/text.md b/book/src/text.md new file mode 100644 index 00000000..bba08c9c --- /dev/null +++ b/book/src/text.md @@ -0,0 +1,9 @@ +# Text + +The [text module][text-module] provides a variety of standard typography presets to use in your applications. + +## Body + + + +[text-module]: https://pop-os.github.io/libcosmic/cosmic/widget/text/index.html diff --git a/book/src/todo.md b/book/src/todo.md new file mode 100644 index 00000000..1f600ada --- /dev/null +++ b/book/src/todo.md @@ -0,0 +1 @@ +# Todo diff --git a/book/src/toggler.md b/book/src/toggler.md new file mode 100644 index 00000000..8cdf57ec --- /dev/null +++ b/book/src/toggler.md @@ -0,0 +1 @@ +# Toggler diff --git a/book/src/widgets.md b/book/src/widgets.md new file mode 100644 index 00000000..097bbeec --- /dev/null +++ b/book/src/widgets.md @@ -0,0 +1 @@ +# Widgets