Last active
January 17, 2022 19:08
-
-
Save ratmice/8e8aec482d86abf582d152c2784e505a to your computer and use it in GitHub Desktop.
prism on struct w/ inner enum..
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use druid::widget::{Flex, Label}; | |
use druid::{Data, Env, LocalizedString, Menu, MenuItem, Widget}; | |
use druid_widget_nursery::{ | |
prism::{Closures, Prism}, | |
MultiRadio, | |
}; | |
use im::Vector; | |
use std::collections::BTreeMap; | |
use std::sync::Arc; | |
#[derive(Clone, Data, Debug, Eq, Ord, PartialEq, PartialOrd)] | |
struct Foo { | |
stuff: String, | |
} | |
#[derive(Clone, Debug, PartialEq, Eq, Data, Prism)] | |
enum Mode { | |
Channels, | |
Devices, | |
} | |
#[derive(Data, Clone, Debug, Eq, PartialEq)] | |
struct AppState { | |
mode: Mode, | |
devices: Arc<BTreeMap<u64, usize>>, | |
channels: Vector<Foo>, | |
} | |
impl Default for AppState { | |
fn default() -> AppState { | |
AppState { | |
mode: Mode::Devices, | |
devices: Arc::new(BTreeMap::new()), | |
channels: Vector::new(), | |
} | |
} | |
} | |
#[derive(Debug)] | |
struct AppStateDevicesPrism(); | |
impl Prism<AppState, Arc<BTreeMap<u64, usize>>> for AppStateDevicesPrism { | |
fn get(&self, data: &AppState) -> Option<Arc<BTreeMap<u64, usize>>> { | |
Some(data.devices.clone()) | |
} | |
fn put(&self, data: &mut AppState, inner: Arc<BTreeMap<u64, usize>>) { | |
data.devices = inner | |
} | |
} | |
#[derive(Debug)] | |
struct AppStateChannelsPrism(); | |
impl Prism<AppState, Vector<Foo>> for AppStateChannelsPrism { | |
fn get(&self, data: &AppState) -> Option<Vector<Foo>> { | |
Some(data.channels.clone()) | |
} | |
fn put(&self, data: &mut AppState, inner: Vector<Foo>) { | |
data.channels = inner | |
} | |
} | |
fn channels_widget() -> impl Widget<Vector<Foo>> { | |
Flex::column().with_child(Label::new("foo")) | |
} | |
fn devices_widget() -> impl Widget<Arc<BTreeMap<u64, usize>>> { | |
Flex::column().with_child(Label::new("bar")) | |
} | |
fn top_widget() -> impl Widget<AppState> { | |
let channels = MultiRadio::new( | |
"Channels", | |
channels_widget(), | |
Vector::new(), | |
Closures( | |
|outer: &AppState| { | |
println!("Channels outer closure: {:?}", outer); | |
if let Mode::Channels = outer.mode { | |
Some(outer.channels.clone()) | |
} else { | |
None | |
} | |
}, | |
move |data: &mut AppState, inner: Vector<Foo>| { | |
data.mode = Mode::Channels; | |
data.channels = inner.clone(); | |
}, | |
), | |
); | |
let devices = MultiRadio::new( | |
"Devices", | |
devices_widget(), | |
Arc::new(BTreeMap::new()), | |
Closures( | |
|outer: &AppState| { | |
println!("Devices outer closure: {:?}", outer); | |
if let Mode::Devices = outer.mode { | |
Some(outer.devices.clone()) | |
} else { | |
None | |
} | |
}, | |
move |data: &mut AppState, inner: Arc<BTreeMap<u64, usize>>| { | |
data.mode = Mode::Devices; | |
data.devices = inner.clone(); | |
}, | |
), | |
); | |
let root = Flex::column().with_child(channels).with_child(devices); | |
root | |
} | |
fn main_menu(_id: Option<druid::WindowId>, _data: &AppState, _env: &Env) -> Menu<AppState> { | |
use druid::commands; | |
Menu::empty().entry( | |
Menu::new(LocalizedString::new("common-menu-file-menu")) | |
.entry( | |
MenuItem::new(LocalizedString::new("common-menu-file-close")) | |
.command(commands::CLOSE_WINDOW), | |
) | |
.entry( | |
MenuItem::new(LocalizedString::new("Quit")) | |
.command(commands::QUIT_APP) | |
.hotkey(druid::SysMods::Cmd, "q"), | |
), | |
) | |
} | |
fn main() { | |
let window = druid::WindowDesc::new(top_widget()) | |
.title("prism struct test") | |
.menu(main_menu); | |
let launcher = | |
druid::AppLauncher::with_window(window).configure_env(druid_widget_nursery::configure_env); | |
launcher.launch(AppState::default()).expect("launch failed"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment