Another change to Coord trait stuff
This commit is contained in:
parent
401560d35e
commit
e97598b69f
1641
Cargo.lock
generated
1641
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -13,4 +13,4 @@ zip = "0.6.2"
|
||||
image = "0.24.2"
|
||||
|
||||
[workspace]
|
||||
members = ["board-builder-impl-fltk"]
|
||||
members = ["board-builder-impl-fltk", "board-builder-impl-egui"]
|
12
board-builder-impl-egui/Cargo.toml
Normal file
12
board-builder-impl-egui/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "board-builder-impl-egui"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
board-builder = { path = "../" }
|
||||
eframe = "0.18.0"
|
||||
rfd = "0.8.2"
|
||||
image = "0.24.2"
|
90
board-builder-impl-egui/src/main.rs
Normal file
90
board-builder-impl-egui/src/main.rs
Normal file
@ -0,0 +1,90 @@
|
||||
use eframe::egui;
|
||||
use egui::*;
|
||||
|
||||
use rfd::FileDialog;
|
||||
|
||||
use board_builder::Board;
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let native_options = eframe::NativeOptions::default();
|
||||
eframe::run_native("Board Builder", native_options, Box::new(|_cc| Box::new(BoardBuilderApp::default())));
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct BoardBuilderApp {
|
||||
board: Board,
|
||||
texture: Option<TextureHandle>,
|
||||
image: Option<image::DynamicImage>,
|
||||
}
|
||||
|
||||
impl eframe::App for BoardBuilderApp {
|
||||
fn update(&mut self, ctx: &Context, _frame: &mut eframe::Frame) {
|
||||
TopBottomPanel::top("menubar").show(ctx, |ui| {
|
||||
menu::bar(ui, |ui| {
|
||||
fn choose_file() {
|
||||
FileDialog::new().pick_file();
|
||||
}
|
||||
ui.menu_button("File", |ui| {
|
||||
ui.button("New");
|
||||
if ui.button("Open...").clicked() {
|
||||
choose_file();
|
||||
}
|
||||
if ui.button("Save As...").clicked() {
|
||||
choose_file();
|
||||
}
|
||||
if ui.button("Open Image...").clicked() {
|
||||
let image_file = FileDialog::new()
|
||||
.add_filter("Image", &["png", "jpg", "jpeg", "gif", "webp", "bmp", "tiff"])
|
||||
.pick_file();
|
||||
if let Some(image_file) = image_file {
|
||||
self.load_image(ctx, &image_file);
|
||||
}
|
||||
}
|
||||
});
|
||||
ui.menu_button("Edit", |ui| {
|
||||
ui.button("Edit Nodes");
|
||||
ui.button("Edit Edges");
|
||||
ui.button("Edit Labels...");
|
||||
})
|
||||
});
|
||||
});
|
||||
CentralPanel::default().show(ctx, |ui| {
|
||||
if let Some(texture) = self.texture.as_ref() {
|
||||
let size = ui.available_size();
|
||||
ui.image(texture, size);
|
||||
let (response, painter) = ui.allocate_painter(size, Sense::click());
|
||||
let view = View(response.rect);
|
||||
self.draw_board(&painter, view);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl BoardBuilderApp {
|
||||
fn load_image(&mut self, ctx: &Context, image_file: &Path) -> Result<(), image::ImageError> {
|
||||
let image = image::io::Reader::open(image_file)?.decode()?;
|
||||
let egui_image = egui::ColorImage::from_rgba_unmultiplied(
|
||||
[image.width() as _, image.height() as _],
|
||||
image.to_rgba8().as_flat_samples().as_slice(),
|
||||
);
|
||||
|
||||
self.image = Some(image);
|
||||
self.texture = Some(ctx.load_texture("board-image", egui_image));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw_board(&mut self, painter: &Painter, view: View) {
|
||||
for node in &self.board.nodes {
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct View(Rect);
|
||||
|
||||
impl board_builder::CoordTransformer<Pos2> for View {
|
||||
fn origin(&self) -> Pos2 { self.0.min }
|
||||
fn extremes(&self) -> Pos2 { self.0.max }
|
||||
}
|
@ -133,13 +133,38 @@ mod dispatch {
|
||||
}
|
||||
|
||||
struct FrameView<'a>(&'a frame::Frame);
|
||||
struct Pos(i32, i32);
|
||||
|
||||
impl<'a> CoordTransformer<i32> for FrameView<'a> {
|
||||
fn origin(&self) -> (i32, i32) { (self.0.x(), self.0.y()) }
|
||||
fn extremes(&self) -> (i32, i32) { (self.0.x()+self.0.w(), self.0.y()+self.0.h()) }
|
||||
impl<'a> FrameView<'a> {
|
||||
fn origin(&self) -> Pos {
|
||||
Pos(self.0.x(), self.0.y())
|
||||
}
|
||||
|
||||
fn extremes(&self) -> Pos {
|
||||
Pos(self.0.x() + self.0.w(), self.0.y() + self.0.h())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> CoordTransformer<Pos> for FrameView<'a> {
|
||||
fn origin(&self) -> Pos { self.origin() }
|
||||
fn extremes(&self) -> Pos { self.extremes() }
|
||||
}
|
||||
|
||||
impl From<(f32, f32)> for Pos {
|
||||
fn from((x, y): (f32, f32)) -> Self {
|
||||
Pos(x as i32, y as i32)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Pos> for (f32, f32) {
|
||||
fn from(Pos(x, y): Pos) -> Self {
|
||||
(x as f32, y as f32)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////// App State ////////////////////
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum EditMode {
|
||||
Node,
|
||||
@ -253,7 +278,7 @@ fn main() {
|
||||
let f = FrameView(f);
|
||||
for (&id, node) in &board.nodes {
|
||||
// Draw the node
|
||||
let (x, y) = f.from_coords(node.x, node.y);
|
||||
let Pos(x, y) = f.from_coords(node.x, node.y);
|
||||
if state.selected_node == Some(id) {
|
||||
set_draw_color(Color::Red);
|
||||
draw_text(&node.name, x, y);
|
||||
@ -264,7 +289,7 @@ fn main() {
|
||||
// Draw edges
|
||||
for other_id in &node.edges {
|
||||
let other = board.nodes.get(other_id).unwrap();
|
||||
let (x1, y1) = f.from_coords(other.x, other.y);
|
||||
let Pos(x1, y1) = f.from_coords(other.x, other.y);
|
||||
draw_line(x, y, x1, y1);
|
||||
}
|
||||
}
|
||||
@ -274,7 +299,7 @@ fn main() {
|
||||
Event::Push => {
|
||||
let f = FrameView(f);
|
||||
let edit_mode = STATE.get().lock().unwrap().edit_mode;
|
||||
let coords = f.to_coords(app::event_x(), app::event_y());
|
||||
let coords = f.to_coords(Pos(app::event_x(), app::event_y()));
|
||||
|
||||
match edit_mode {
|
||||
EditMode::Node => dispatch::node_press(coords),
|
||||
|
38
src/lib.rs
38
src/lib.rs
@ -139,33 +139,21 @@ fn inv_lerp(v0: f32, v1: f32, a: f32) -> f32 {
|
||||
(a - v0) / (v1 - v0)
|
||||
}
|
||||
|
||||
pub trait CoordTransformer<I: CoordtypeConvertible> {
|
||||
fn origin(&self) -> (I, I);
|
||||
fn extremes(&self) -> (I, I);
|
||||
fn to_coords(&self, x: I, y: I) -> (f32, f32) {
|
||||
let (sx, sy) = self.origin();
|
||||
let (ex, ey) = self.extremes();
|
||||
pub trait CoordTransformer<I: Into<(f32, f32)> + From<(f32, f32)>> {
|
||||
fn origin(&self) -> I;
|
||||
fn extremes(&self) -> I;
|
||||
fn to_coords(&self, pos: I) -> (f32, f32) {
|
||||
let (sx, sy) = self.origin().into();
|
||||
let (ex, ey) = self.extremes().into();
|
||||
let (x, y) = pos.into();
|
||||
(
|
||||
inv_lerp(sx.to_coordtype(), ex.to_coordtype(), x.to_coordtype()),
|
||||
inv_lerp(sy.to_coordtype(), ey.to_coordtype(), y.to_coordtype()),
|
||||
inv_lerp(sx, ex, x),
|
||||
inv_lerp(sy, ey, y),
|
||||
)
|
||||
}
|
||||
fn from_coords(&self, x: f32, y: f32) -> (I, I) {
|
||||
let (sx, sy) = self.origin();
|
||||
let (ex, ey) = self.extremes();
|
||||
(
|
||||
CoordtypeConvertible::from_coordtype(lerp(sx.to_coordtype(), ex.to_coordtype(), x)),
|
||||
CoordtypeConvertible::from_coordtype(lerp(sy.to_coordtype(), ey.to_coordtype(), y)),
|
||||
)
|
||||
fn from_coords(&self, x: f32, y: f32) -> I {
|
||||
let (sx, sy) = self.origin().into();
|
||||
let (ex, ey) = self.extremes().into();
|
||||
(lerp(sx, ex, x), lerp(sy, ey, y)).into()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CoordtypeConvertible {
|
||||
fn to_coordtype(self) -> f32;
|
||||
fn from_coordtype(coordtype: f32) -> Self;
|
||||
}
|
||||
|
||||
impl CoordtypeConvertible for i32 {
|
||||
fn to_coordtype(self) -> f32 { self as f32 }
|
||||
fn from_coordtype(coordtype: f32) -> i32 { coordtype as i32 }
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user