use std::cell::RefCell;
use std::rc::Rc;
use plotters::{prelude::*, style::full_palette::LIME_200};
use plotters_backend::text_anchor::{HPos, Pos, VPos};
use plotters_wxdragon::WxBackend;
use wxdragon::{self as wx, ButtonEvents, WindowEvents, WxWidget};
struct State {
text_transform: FontTransform,
background_mode: wx::BackgroundMode,
}
impl State {
fn toggle_background_mode(&mut self) {
self.background_mode = match self.background_mode {
wx::BackgroundMode::Solid => wx::BackgroundMode::Transparent,
wx::BackgroundMode::Transparent => wx::BackgroundMode::Solid,
}
}
}
struct DrawingPanel {
panel: wx::Panel,
}
impl DrawingPanel {
fn new(parent: &wx::Frame, state: Rc<RefCell<State>>) -> Self {
let panel = wx::PanelBuilder::new(parent)
.with_size(wx::Size::new(800, 600))
.build();
panel.set_background_style(wx::BackgroundStyle::Paint);
panel.on_paint(move |_event| {
let dc = wx::AutoBufferedPaintDC::new(&panel);
let mut backend = WxBackend::new(&dc);
backend.set_background_mode(state.borrow().background_mode);
let x0 = 200;
let y0 = 100;
let dx = 100;
let dy = 100;
let hpos = [HPos::Left, HPos::Center, HPos::Right];
let vpos = [VPos::Top, VPos::Center, VPos::Bottom];
let text_transform = &state.borrow().text_transform;
for i in 0..3 {
for j in 0..3 {
let xi = x0 + 2 * i * dx;
let yi = y0 + 2 * j * dy;
backend
.draw_rect(
(xi - dx / 2, yi - dy / 2),
(xi + dx / 2, yi + dy / 2),
&LIME_200,
true,
)
.unwrap();
backend
.draw_rect(
(xi - dx / 2, yi - dy / 2),
(xi + dx / 2, yi + dy / 2),
&BLACK,
false,
)
.unwrap();
let style =
TextStyle::from(("monospace", 32.0).into_font())
.pos(Pos::new(hpos[i as usize], vpos[j as usize]))
.transform(text_transform.clone());
backend.draw_text("M", &style, (xi, yi)).unwrap();
}
}
backend.present().expect("present");
});
panel.on_size(move |_event| {
panel.refresh(true, None);
});
Self { panel }
}
}
impl std::ops::Deref for DrawingPanel {
type Target = wx::Panel;
fn deref(&self) -> &Self::Target {
&self.panel
}
}
const ID_TOOL_ROTATE_0: wx::Id = wx::ID_HIGHEST + 1;
const ID_TOOL_ROTATE_90: wx::Id = wx::ID_HIGHEST + 2;
const ID_TOOL_ROTATE_180: wx::Id = wx::ID_HIGHEST + 3;
const ID_TOOL_ROTATE_270: wx::Id = wx::ID_HIGHEST + 4;
fn main() {
let _ = wxdragon::main(|_| {
let frame = wx::Frame::builder()
.with_title("Text anchor position example with Plotters")
.build();
frame.center_on_screen();
let state = Rc::new(RefCell::new(State {
text_transform: FontTransform::None,
background_mode: wx::BackgroundMode::Transparent,
}));
add_toolbar(&frame);
let toggle_background_button = wx::ToggleButton::builder(&frame)
.with_label("Toggle background")
.build();
toggle_background_button.set_value(true);
let drawing_panel = DrawingPanel::new(&frame, state.clone());
let main_frame_sizer =
wx::BoxSizer::builder(wx::Orientation::Vertical).build();
main_frame_sizer.add(
&toggle_background_button,
0,
wx::SizerFlag::All | wx::SizerFlag::AlignLeft,
5,
);
main_frame_sizer.add(
&drawing_panel.panel,
1,
wx::SizerFlag::Expand | wx::SizerFlag::All,
0,
);
frame.set_sizer_and_fit(main_frame_sizer, true);
{
let state = state.clone();
let drawing_panel = *drawing_panel;
frame.on_menu(move |event| match event.get_id() {
ID_TOOL_ROTATE_0 | ID_TOOL_ROTATE_90 | ID_TOOL_ROTATE_180
| ID_TOOL_ROTATE_270 => {
state.borrow_mut().text_transform = match event.get_id() {
ID_TOOL_ROTATE_0 => FontTransform::None,
ID_TOOL_ROTATE_90 => FontTransform::Rotate90,
ID_TOOL_ROTATE_180 => FontTransform::Rotate180,
ID_TOOL_ROTATE_270 => FontTransform::Rotate270,
_ => unreachable!(),
};
drawing_panel.refresh(true, None);
}
_ => {
event.skip(true);
}
});
}
{
let state = state.clone();
let drawing_panel = *drawing_panel;
toggle_background_button.on_toggle(move |_event| {
state.borrow_mut().toggle_background_mode();
drawing_panel.refresh(true, None);
});
}
drawing_panel.refresh(true, None);
frame.show(true);
});
}
fn add_toolbar(frame: &wx::Frame) {
use wx::ArtClient::Toolbar;
use wx::ArtId::{GoBack, GoDown, GoForward, GoUp};
if let Some(toolbar) = frame
.create_tool_bar(Some(wx::ToolBarStyle::Default), wx::ID_ANY as i32)
{
if let Some(new_icon) = wx::ArtProvider::get_bitmap(GoUp, Toolbar, None)
{
toolbar.add_tool(ID_TOOL_ROTATE_0, "0", &new_icon, "No rotation");
}
if let Some(new_icon) =
wx::ArtProvider::get_bitmap(GoForward, Toolbar, None)
{
toolbar.add_tool(ID_TOOL_ROTATE_90, "0", &new_icon, "Rotate 90°");
}
if let Some(new_icon) =
wx::ArtProvider::get_bitmap(GoDown, Toolbar, None)
{
toolbar.add_tool(ID_TOOL_ROTATE_180, "0", &new_icon, "Rotate 180°");
}
if let Some(new_icon) =
wx::ArtProvider::get_bitmap(GoBack, Toolbar, None)
{
toolbar.add_tool(ID_TOOL_ROTATE_270, "0", &new_icon, "Rotate 270°");
}
toolbar.realize();
}
}