Skip to content

Instantly share code, notes, and snippets.

@ratmice
Last active January 17, 2022 19:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ratmice/8e8aec482d86abf582d152c2784e505a to your computer and use it in GitHub Desktop.
Save ratmice/8e8aec482d86abf582d152c2784e505a to your computer and use it in GitHub Desktop.
prism on struct w/ inner enum..
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