2019-11-24 18:21:23 +03:00
|
|
|
use crate::game::{State, Transition};
|
|
|
|
use crate::ui::UI;
|
2019-12-09 00:44:43 +03:00
|
|
|
use ezgui::{
|
2019-12-21 02:56:04 +03:00
|
|
|
Button, Color, EventCtx, GfxCtx, Line, ManagedWidget, MultiKey, RewriteColor, Slider, Text,
|
2019-12-09 00:44:43 +03:00
|
|
|
};
|
2019-12-17 01:13:08 +03:00
|
|
|
use std::collections::HashMap;
|
2019-11-24 18:21:23 +03:00
|
|
|
|
2019-12-19 02:14:59 +03:00
|
|
|
type Callback = Box<dyn Fn(&mut EventCtx, &mut UI) -> Option<Transition>>;
|
2019-11-24 18:21:23 +03:00
|
|
|
|
2019-12-21 02:56:04 +03:00
|
|
|
pub enum Outcome {
|
|
|
|
Transition(Transition),
|
|
|
|
Clicked(String),
|
2019-11-30 21:09:31 +03:00
|
|
|
}
|
|
|
|
|
2019-12-21 02:56:04 +03:00
|
|
|
pub struct Composite {
|
|
|
|
inner: ezgui::Composite,
|
|
|
|
callbacks: HashMap<String, Callback>,
|
2019-11-30 21:09:31 +03:00
|
|
|
}
|
|
|
|
|
2019-12-21 02:56:04 +03:00
|
|
|
impl Composite {
|
|
|
|
pub fn new(inner: ezgui::Composite) -> Composite {
|
|
|
|
Composite {
|
|
|
|
inner,
|
|
|
|
callbacks: HashMap::new(),
|
2019-12-16 20:42:12 +03:00
|
|
|
}
|
2019-11-30 21:09:31 +03:00
|
|
|
}
|
2019-11-24 18:21:23 +03:00
|
|
|
|
2019-12-21 02:56:04 +03:00
|
|
|
pub fn cb(mut self, action: &str, cb: Callback) -> Composite {
|
|
|
|
if !self.inner.get_all_click_actions().contains(action) {
|
|
|
|
panic!("No button produces action {}", action);
|
|
|
|
}
|
2019-12-16 04:09:41 +03:00
|
|
|
|
2019-12-21 02:56:04 +03:00
|
|
|
self.callbacks.insert(action.to_string(), cb);
|
2019-12-16 04:09:41 +03:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2019-12-21 02:56:04 +03:00
|
|
|
pub fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Option<Outcome> {
|
|
|
|
self.event_with_sliders(ctx, ui, HashMap::new())
|
2019-12-16 20:42:12 +03:00
|
|
|
}
|
2019-12-19 02:27:52 +03:00
|
|
|
|
2019-12-21 02:56:04 +03:00
|
|
|
pub fn event_with_sliders(
|
|
|
|
&mut self,
|
|
|
|
ctx: &mut EventCtx,
|
|
|
|
ui: &mut UI,
|
|
|
|
sliders: HashMap<String, &mut Slider>,
|
|
|
|
) -> Option<Outcome> {
|
|
|
|
match self.inner.event_with_sliders(ctx, sliders)? {
|
|
|
|
ezgui::Outcome::Clicked(x) => {
|
|
|
|
if let Some(ref cb) = self.callbacks.get(&x) {
|
|
|
|
let t = (cb)(ctx, ui)?;
|
|
|
|
Some(Outcome::Transition(t))
|
|
|
|
} else {
|
|
|
|
Some(Outcome::Clicked(x))
|
|
|
|
}
|
|
|
|
}
|
2019-12-19 02:27:52 +03:00
|
|
|
}
|
|
|
|
}
|
2019-12-16 20:42:12 +03:00
|
|
|
|
2019-12-21 02:56:04 +03:00
|
|
|
pub fn draw(&self, g: &mut GfxCtx) {
|
|
|
|
self.inner.draw(g);
|
2019-12-16 21:10:01 +03:00
|
|
|
}
|
|
|
|
|
2019-12-21 02:56:04 +03:00
|
|
|
pub fn draw_with_sliders(&self, g: &mut GfxCtx, sliders: HashMap<String, &Slider>) {
|
|
|
|
self.inner.draw_with_sliders(g, sliders);
|
2019-12-16 20:42:12 +03:00
|
|
|
}
|
2019-12-21 02:56:04 +03:00
|
|
|
}
|
2019-12-16 20:42:12 +03:00
|
|
|
|
2019-12-21 02:56:04 +03:00
|
|
|
impl Composite {
|
2019-11-30 20:15:51 +03:00
|
|
|
pub fn img_button(
|
|
|
|
ctx: &EventCtx,
|
|
|
|
filename: &str,
|
|
|
|
hotkey: Option<MultiKey>,
|
2019-12-21 02:56:04 +03:00
|
|
|
label: &str,
|
2019-11-30 20:15:51 +03:00
|
|
|
) -> ManagedWidget {
|
2019-12-21 02:56:04 +03:00
|
|
|
ManagedWidget::btn(Button::rectangle_img(filename, hotkey, ctx, label))
|
2019-11-24 18:21:27 +03:00
|
|
|
}
|
|
|
|
|
2019-12-08 21:24:01 +03:00
|
|
|
pub fn svg_button(
|
2019-11-30 20:15:51 +03:00
|
|
|
ctx: &EventCtx,
|
2019-11-24 18:21:27 +03:00
|
|
|
filename: &str,
|
2019-11-28 20:55:56 +03:00
|
|
|
tooltip: &str,
|
2019-11-24 18:21:27 +03:00
|
|
|
hotkey: Option<MultiKey>,
|
2019-11-30 20:15:51 +03:00
|
|
|
) -> ManagedWidget {
|
2019-12-21 02:56:04 +03:00
|
|
|
ManagedWidget::btn(Button::rectangle_svg(
|
|
|
|
filename,
|
|
|
|
tooltip,
|
|
|
|
hotkey,
|
|
|
|
RewriteColor::Change(Color::WHITE, Color::ORANGE),
|
|
|
|
ctx,
|
|
|
|
))
|
2019-11-24 18:21:27 +03:00
|
|
|
}
|
|
|
|
|
2019-12-21 02:56:04 +03:00
|
|
|
pub fn text_button(ctx: &EventCtx, label: &str, hotkey: Option<MultiKey>) -> ManagedWidget {
|
|
|
|
Composite::detailed_text_button(
|
2019-11-30 20:15:51 +03:00
|
|
|
ctx,
|
|
|
|
Text::from(Line(label).fg(Color::BLACK)),
|
|
|
|
hotkey,
|
2019-12-21 02:56:04 +03:00
|
|
|
label,
|
2019-11-30 20:15:51 +03:00
|
|
|
)
|
2019-11-24 18:21:30 +03:00
|
|
|
}
|
|
|
|
|
2019-11-30 20:15:51 +03:00
|
|
|
pub fn detailed_text_button(
|
|
|
|
ctx: &EventCtx,
|
|
|
|
txt: Text,
|
|
|
|
hotkey: Option<MultiKey>,
|
2019-12-21 02:56:04 +03:00
|
|
|
label: &str,
|
2019-11-30 20:15:51 +03:00
|
|
|
) -> ManagedWidget {
|
2019-11-24 18:21:27 +03:00
|
|
|
// TODO Default style. Lots of variations.
|
2019-12-21 02:56:04 +03:00
|
|
|
ManagedWidget::btn(Button::text(
|
|
|
|
txt,
|
|
|
|
Color::WHITE,
|
|
|
|
Color::ORANGE,
|
|
|
|
hotkey,
|
|
|
|
label,
|
2019-12-20 20:35:27 +03:00
|
|
|
ctx,
|
2019-12-21 02:56:04 +03:00
|
|
|
))
|
2019-11-24 18:21:23 +03:00
|
|
|
}
|
|
|
|
}
|
2019-12-16 04:09:41 +03:00
|
|
|
|
|
|
|
pub struct ManagedGUIState {
|
|
|
|
composite: Composite,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ManagedGUIState {
|
2019-12-21 02:56:04 +03:00
|
|
|
pub fn new(composite: Composite) -> Box<dyn State> {
|
|
|
|
Box::new(ManagedGUIState { composite })
|
2019-12-16 04:09:41 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl State for ManagedGUIState {
|
|
|
|
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition {
|
2019-12-16 21:10:01 +03:00
|
|
|
match self.composite.event(ctx, ui) {
|
|
|
|
Some(Outcome::Transition(t)) => t,
|
|
|
|
Some(Outcome::Clicked(x)) => panic!(
|
|
|
|
"Can't have a button {} without a callback in ManagedGUIState",
|
|
|
|
x
|
|
|
|
),
|
|
|
|
None => Transition::Keep,
|
2019-12-16 04:09:41 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn draw_default_ui(&self) -> bool {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
|
|
|
fn draw(&self, g: &mut GfxCtx, ui: &UI) {
|
|
|
|
// Happens to be a nice background color too ;)
|
|
|
|
g.clear(ui.cs.get("grass"));
|
|
|
|
self.composite.draw(g);
|
|
|
|
}
|
|
|
|
}
|