Crate gstore[−][src]
gstore
gstore is a library that provides global and local state management for GTK Apps as well as a bunch of macros to build GTK widgets.
gstore is inspired by react/redux. If you are familiar with these frameworks you might find a lot of their concepts used in gstore.
Contents
- Concepts
- Local State
- Actions
Concepts
gstore is an app framework above of GTK. GTK is a single-threaded UI library. gstore uses a
background thread to handle global state mutations and connects it with the GTK main thread via
user defined enums (called Actions) using std::sync::mpsc::channel
.
Note: currently this leads to a major drawback: The GTK main thread has to check every
n
milliseconds for sent Actions. Please feel free to contact me if you have a better idea how to do this.
The diagram below aims to visualize the basic concept of gstore:
+-----------------------------------------------------------------+
| |
| State |
| |
+-----------------------------------------------------------------+
| |
| Mutexed global state |
| |
+-----+------------------------------------------------+----------+
^ ^
| |
| Read Access | Read/Write Access
| |
| |
+-----+-----+ +--------+----------+
| | | |
| UI thread | | Background thread |
| | | |
+-----------+ send Action on user input +-------------------+
| | | |
| GTK main +-------------------------------->+ runs reducers |
| thread | | |
| | +-------------+ | |
| | | | | |
| | | enum Action | | |
| | | | | |
| | +-------------+ | |
| | | |
| | receive Action when handled | |
| | | |
| +<--------------------------------+ |
| | | |
+-----------+ +-------------------+
The background thread mutates the global state while the UI thread only reads the global state. State mutation means a new version of the state is by a stateless function. In redux this is called reducers. In other languages we know this kind function a fold.
In contrast to redux there are currently no additional restrictions of what to do in a reducers.
- Usage
#[macro_use] extern crate gstore; use gtk::prelude::*; use gstore::prelude::*; // slice // ----------------------------------------------------------------- // Define a slice slice! { CountState { count: i64 = 0 } CountAction { Increment, Decrement } } // define a reducer on that slice fn reduce_count(action: CountAction, state: CountState) -> CountState { match action { CountAction::Increment => CountState { count: state.count + 1, ..state }, CountAction::Decrement => CountState { count: state.count - 1, ..state } } } // define a selector for your slice (the state is the Root state) fn select_count(state: &crate::State) -> i64 { state.counting.count } // define functions for convenient action dispatching fn increment() -> Action { crate::Action::Counting(CountAction::Increment) } fn decrement() -> Action { crate::Action::Counting(CountAction::Decrement) } // ----------------------------------------------------------------- // store // ----------------------------------------------------------------- // combine slices in your store store! { counting: Counting = crate::{CountState, CountAction, reduce_count} } fn main() { let logging_middleware = middleware(|store, next, action: Action| { println!("Handling action {:?}", action); next(store, action.clone()); println!("Handled action {:?}", action); }); let store: Store = Store::new(root_reducer, vec![logging_middleware]); gstore::gtk::run(store, |store| { let window = window(store.clone()); store.dispatch(Action::Start); window }) } // ----------------------------------------------------------------- // window // ----------------------------------------------------------------- // define ui component use_state! { [message: String, set_message] = "The current count:".to_string() } fn window(store: Store) -> gtk::ApplicationWindow { application_window! { widget { properties { default_width: 400 default_height: 400 } children [ label! { properties { label: message() } } ] } } }
Re-exports
pub use once_cell; |
Modules
gtk | |
l10n | |
prelude | |
render_handling | |
store | |
widgets |
Macros
action_row | |
application_window | Creates a new ApplicationWindow. |
button | Creates a GTK button. |
clamp | |
entry | |
gbox | Creates a GTK box. |
header_bar | |
image | |
label | Creates a GTK label. |
label2 | |
list_box | |
preferences_group | |
preferences_page | |
setup_render_handling | |
slice | |
spin_button | |
stack | Creates a GTK stack. |
store | |
switch | |
title_bar | |
use_select | |
use_state | |
view_switcher_bar | |
widget |