use pixel_widgets::event::{Key, NodeEvent};
use pixel_widgets::prelude::*;
use pixel_widgets::widget::menu::MenuItem;
use pixel_widgets::Command;
struct Tour {
pub show_dummy: bool,
pub show_login: bool,
pub name: String,
pub password: String,
pub context: pixel_widgets::widget::menu::State,
pub state: ManagedState<String>,
}
enum Message {
LoginPressed,
ShowContext(f32, f32),
ShowDummy,
ShowLogin,
NameChanged(String),
PasswordChanged(String),
PlanetSelected(&'static str),
}
impl Model for Tour {
type Message = Message;
fn update(&mut self, message: Self::Message) -> Vec<Command<Message>> {
match message {
Message::PlanetSelected(planet) => {
println!("{} selected from the planets", planet);
}
Message::ShowDummy => {
self.show_dummy = true;
}
Message::ShowLogin => {
self.show_login = true;
}
Message::ShowContext(x, y) => {
self.context.open(x, y);
}
Message::LoginPressed => {
println!("login pressed!");
}
Message::NameChanged(name) => {
self.name = name;
}
Message::PasswordChanged(password) => {
self.password = password;
}
}
Vec::new()
}
fn view(&mut self) -> Node<Message> {
let mut state = self.state.tracker();
let background = Column::new()
.push(Space)
.push(
Row::new()
.push(Space)
.push(Button::new(state.get("dummy"), Text::new("Open dummy")).on_clicked(Message::ShowDummy))
.push(Button::new(state.get("login"), Text::new("Open login")).on_clicked(Message::ShowLogin)),
)
.on_event(NodeEvent::MouseClick(Key::RightMouseButton), |ctx| {
ctx.push(Message::ShowContext(ctx.cursor().0, ctx.cursor().1))
});
let mut layers = Layers::<Message, &'static str>::with_background(state.get("layers"), background);
let options = [
"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto",
];
layers = layers.push(
"menu",
Menu::new(&mut self.context).extend(vec![
MenuItem::Item {
content: Text::new("Open Dummy").into_node(),
on_select: Some(Message::ShowDummy),
},
MenuItem::Item {
content: Text::new("Open Login").into_node(),
on_select: Some(Message::ShowLogin),
},
MenuItem::Menu {
content: Text::new("Planets").into_node(),
items: options
.iter()
.map(|option| MenuItem::Item {
content: Text::new(option.to_string()).into_node(),
on_select: Some(Message::PlanetSelected(option)),
})
.collect(),
},
MenuItem::Item {
content: Text::new("Option D").into_node(),
on_select: None,
},
]),
);
if self.show_dummy {
layers = layers.push(
"dummy_window",
Window::new(
state.get("dummy_window"),
Row::new()
.push(Text::new("Dummy window").class("title"))
.push(Space)
.push(Space.class("close"))
.class("title"),
Column::new()
.push(Text::new("Select a planet from the dropdown list: "))
.push(
Dropdown::new(state.get("dd")).extend(
options
.iter()
.map(|&option| (Text::new(option), Message::PlanetSelected(option))),
),
),
),
);
}
if self.show_login {
layers = layers.push(
"login_window",
Window::new(
state.get("login_window"),
Row::new()
.push(Text::new("Login window").class("title"))
.push(Space)
.push(Space.class("close"))
.class("title"),
Scroll::new(
state.get("scroll"),
Column::new()
.push(Input::new(state.get("name"), "username", Message::NameChanged))
.push(Input::password(
state.get("password"),
"password",
Message::PasswordChanged,
))
.push(
Button::new(state.get("login"), Text::new("Login")).on_clicked(Message::LoginPressed),
),
),
),
);
}
layers.into_node()
}
}
#[tokio::main]
async fn main() {
let model = Tour {
show_dummy: false,
show_login: false,
name: String::new(),
password: String::new(),
context: Default::default(),
state: ManagedState::default(),
};
let window = winit::window::WindowBuilder::new()
.with_title("Tour")
.with_inner_size(winit::dpi::LogicalSize::new(960, 480));
let loader = pixel_widgets::loader::FsLoader::new("./examples".into()).unwrap();
let mut sandbox = Sandbox::new(model, loader, window).await;
sandbox
.ui
.set_stylesheet("tour.pwss")
.await
.expect("Unable to load stylesheet");
sandbox.run().await;
}