use std::sync::mpsc;
use super::common;
pub struct GuiData {
pub components: linked_hash_map::LinkedHashMap<String, Box<dyn common::Component>>,
pub widgets: linked_hash_map::LinkedHashMap<String, Box<dyn common::Widget>>,
}
impl Default for GuiData {
fn default() -> Self {
Self {
components: linked_hash_map::LinkedHashMap::new(),
widgets: linked_hash_map::LinkedHashMap::new(),
}
}
}
pub struct GuiLoop {
egui_mq: egui_miniquad::EguiMq,
to_gui_loop_receiver: mpsc::Receiver<common::ToGuiLoopMessage>,
from_gui_loop_sender: mpsc::Sender<common::FromGuiLoopMessage>,
data: GuiData,
}
impl GuiLoop {
pub fn new(
ctx: &mut miniquad::Context,
to_gui_loop_receiver: mpsc::Receiver<common::ToGuiLoopMessage>,
from_gui_loop_sender: mpsc::Sender<common::FromGuiLoopMessage>,
) -> GuiLoop {
GuiLoop {
egui_mq: egui_miniquad::EguiMq::new(ctx),
to_gui_loop_receiver,
from_gui_loop_sender,
data: GuiData::default(),
}
}
}
impl miniquad::EventHandler for GuiLoop {
fn update(&mut self, _ctx: &mut miniquad::Context) {}
fn draw(&mut self, ctx: &mut miniquad::Context) {
for m in self.to_gui_loop_receiver.try_iter() {
m.update_gui(&mut self.data, ctx);
}
for (_, w) in &mut self.data.widgets {
w.render(ctx);
}
self.egui_mq.run(ctx, |egui_ctx| {
egui::SidePanel::left("ver").show(egui_ctx, |ui| {
for (label, var) in &mut self.data.components {
var.show(label, ui, &mut self.from_gui_loop_sender);
}
});
egui::CentralPanel::default().show(egui_ctx, |ui0| {
if self.data.widgets.is_empty() {
return;
}
let available_width: f32 = 0.95 * ui0.available_width();
let available_height: f32 = 0.95 * ui0.available_height();
let mut aspect_ratios = std::vec::Vec::with_capacity(self.data.widgets.len());
for (_, widget) in &mut self.data.widgets {
aspect_ratios.push(widget.aspect_ratio());
}
aspect_ratios.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
let n = aspect_ratios.len();
let median_aspect_ratio = if n % 2 == 1 {
aspect_ratios[n / 2]
} else {
0.5 * aspect_ratios[n / 2] + 0.5 * aspect_ratios[n / 2 + 1]
};
let mut max_width = 0.0;
let mut max_height = 0.0;
for num_cols in 1..=n {
let num_rows: f32 = ((n as f32) / (num_cols as f32)).ceil();
let w: f32 = available_width / (num_cols as f32);
let h = (w / median_aspect_ratio).min(available_height / num_rows);
let w = median_aspect_ratio * h;
if w > max_width {
max_width = w;
max_height = h;
}
}
ui0.horizontal_wrapped(|ui| {
for (_, widget) in &mut self.data.widgets {
let opt = widget.show(ui, max_width, max_height);
let r = opt.unwrap();
let hp = r.hover_pos();
if hp.is_some() {
}
}
});
});
});
self.egui_mq.draw(ctx);
ctx.commit_frame();
}
fn mouse_motion_event(&mut self, ctx: &mut miniquad::Context, x: f32, y: f32) {
self.egui_mq.mouse_motion_event(ctx, x, y);
}
fn mouse_wheel_event(&mut self, ctx: &mut miniquad::Context, dx: f32, dy: f32) {
self.egui_mq.mouse_wheel_event(ctx, dx, dy);
}
fn mouse_button_down_event(
&mut self,
ctx: &mut miniquad::Context,
mb: miniquad::MouseButton,
x: f32,
y: f32,
) {
self.egui_mq.mouse_button_down_event(ctx, mb, x, y);
}
fn mouse_button_up_event(
&mut self,
ctx: &mut miniquad::Context,
mb: miniquad::MouseButton,
x: f32,
y: f32,
) {
self.egui_mq.mouse_button_up_event(ctx, mb, x, y);
}
fn char_event(
&mut self,
_ctx: &mut miniquad::Context,
character: char,
_keymods: miniquad::KeyMods,
_repeat: bool,
) {
self.egui_mq.char_event(character);
}
fn key_down_event(
&mut self,
ctx: &mut miniquad::Context,
keycode: miniquad::KeyCode,
keymods: miniquad::KeyMods,
_repeat: bool,
) {
self.egui_mq.key_down_event(ctx, keycode, keymods);
}
fn key_up_event(
&mut self,
_ctx: &mut miniquad::Context,
keycode: miniquad::KeyCode,
keymods: miniquad::KeyMods,
) {
self.egui_mq.key_up_event(keycode, keymods);
}
}