~cbondurant/lipuma-devel

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
1

[PATCH v2 1/2] Implement framework for trait-object tools

Details
Message ID
<20221027145912.117044-1-conner.bondurant@triptych.me>
DKIM signature
missing
Download raw message
Patch: +199 -50
---
 src/draw_tools/fractal_line_tool.rs | 152 ++++++++++++++++++++++++++++
 src/draw_tools/mod.rs               |   2 +
 src/draw_tools/tool.rs              |  17 ++++
 src/graphics_scene_widget.rs        |  69 ++++---------
 src/main.rs                         |   1 +
 src/renderobject.rs                 |   8 ++
 6 files changed, 199 insertions(+), 50 deletions(-)
 create mode 100644 src/draw_tools/fractal_line_tool.rs
 create mode 100644 src/draw_tools/mod.rs
 create mode 100644 src/draw_tools/tool.rs

diff --git a/src/draw_tools/fractal_line_tool.rs b/src/draw_tools/fractal_line_tool.rs
new file mode 100644
index 0000000..944ea0a
--- /dev/null
+++ b/src/draw_tools/fractal_line_tool.rs
@@ -0,0 +1,152 @@
use druid::{Data, Point};
use noise::OpenSimplex;
use rand::random;
use std::rc::Rc;

use super::tool::Tool;
use crate::{fractal_line::FractalLine, renderobject::RenderObject};

#[derive(Data, Clone, PartialEq, Eq)]
enum ToolState {
	Drawing,
	Standby,
}

#[derive(Data, Clone)]
pub struct FractalLineTool {
	preview: FractalLine,
	state: ToolState,
}

impl FractalLineTool {
	pub fn new() -> Self {
		Self {
			preview: FractalLine {
				start: Point::ZERO,
				end: Point::ZERO,
				noise: Rc::new(OpenSimplex::new(0)),
				width: 10.0,
				density: 0.05,
				samples: 1000,
			},
			state: ToolState::Standby,
		}
	}
}

impl Tool for FractalLineTool {
	fn enable(&mut self, _data: &mut crate::graphics_scene_widget::GraphicsData) {
		self.state = ToolState::Standby;
	}

	fn disable(&mut self, data: &mut crate::graphics_scene_widget::GraphicsData) {
		match self.state {
			ToolState::Drawing => {
				// get_preview always returns some when drawing
				data.objects.insert(self.get_preview().unwrap());
			}
			ToolState::Standby => (),
		}
	}

	fn on_mouse_move(
		&mut self,
		event: &druid::MouseEvent,
		ctx: &mut druid::EventCtx,
		data: &mut crate::graphics_scene_widget::GraphicsData,
	) {
		match self.state {
			ToolState::Drawing => {
				ctx.set_handled();
				self.preview.end = event.pos;
			}
			ToolState::Standby => (),
		}
	}

	fn on_mouse_down(
		&mut self,
		event: &druid::MouseEvent,
		ctx: &mut druid::EventCtx,
		data: &mut crate::graphics_scene_widget::GraphicsData,
	) {
		self.state = ToolState::Drawing;
		self.preview = FractalLine {
			start: event.pos,
			end: event.pos,
			noise: Rc::new(OpenSimplex::new(random())),
			width: 10.0,
			density: 0.05,
			samples: 1000,
		};
		ctx.set_handled();
	}

	fn on_mouse_up(
		&mut self,
		event: &druid::MouseEvent,
		ctx: &mut druid::EventCtx,
		data: &mut crate::graphics_scene_widget::GraphicsData,
	) {
		match self.state {
			ToolState::Drawing => {
				self.preview.end = event.pos;
				let mut obj = self.get_preview().unwrap();
				obj.z = match data.objects.get_max() {
					Some(obj) => obj.z + 1,
					None => 0,
				};
				self.state = ToolState::Standby;
				data.objects.insert(obj);
				ctx.is_handled();
			}
			ToolState::Standby => (),
		}
	}

	fn on_mouse_wheel(
		&mut self,
		event: &druid::MouseEvent,
		ctx: &mut druid::EventCtx,
		data: &mut crate::graphics_scene_widget::GraphicsData,
	) {
		()
	}

	fn on_key_down(
		&mut self,
		_event: &druid::KeyEvent,
		_ctx: &mut druid::EventCtx,
		_data: &mut crate::graphics_scene_widget::GraphicsData,
	) {
		()
	}

	fn on_key_up(
		&mut self,
		_event: &druid::KeyEvent,
		_ctx: &mut druid::EventCtx,
		_data: &mut crate::graphics_scene_widget::GraphicsData,
	) {
		()
	}

	fn on_paste(
		&mut self,
		_event: &druid::Clipboard,
		_ctx: &mut druid::EventCtx,
		_data: &mut crate::graphics_scene_widget::GraphicsData,
	) {
		()
	}

	fn get_preview(&self) -> Option<crate::renderobject::RenderObject> {
		match self.state {
			ToolState::Drawing => Some(RenderObject::new(
				u32::MAX,
				Rc::new(Box::new(self.preview.clone())),
			)),
			ToolState::Standby => None,
		}
	}
}
diff --git a/src/draw_tools/mod.rs b/src/draw_tools/mod.rs
new file mode 100644
index 0000000..033ef91
--- /dev/null
+++ b/src/draw_tools/mod.rs
@@ -0,0 +1,2 @@
pub mod fractal_line_tool;
pub mod tool;
diff --git a/src/draw_tools/tool.rs b/src/draw_tools/tool.rs
new file mode 100644
index 0000000..9aec10a
--- /dev/null
+++ b/src/draw_tools/tool.rs
@@ -0,0 +1,17 @@
use crate::{renderobject::RenderObject, GraphicsData};
use druid::{Clipboard, EventCtx, KeyEvent, MouseEvent};

pub trait Tool {
	fn enable(&mut self, data: &mut GraphicsData);
	fn disable(&mut self, data: &mut GraphicsData);

	fn on_mouse_move(&mut self, event: &MouseEvent, ctx: &mut EventCtx, data: &mut GraphicsData);
	fn on_mouse_down(&mut self, event: &MouseEvent, ctx: &mut EventCtx, data: &mut GraphicsData);
	fn on_mouse_up(&mut self, event: &MouseEvent, ctx: &mut EventCtx, data: &mut GraphicsData);

	fn on_mouse_wheel(&mut self, event: &MouseEvent, ctx: &mut EventCtx, data: &mut GraphicsData);
	fn on_key_down(&mut self, event: &KeyEvent, ctx: &mut EventCtx, data: &mut GraphicsData);
	fn on_key_up(&mut self, event: &KeyEvent, ctx: &mut EventCtx, data: &mut GraphicsData);
	fn on_paste(&mut self, event: &Clipboard, ctx: &mut EventCtx, data: &mut GraphicsData);
	fn get_preview(&self) -> Option<RenderObject>;
}
diff --git a/src/graphics_scene_widget.rs b/src/graphics_scene_widget.rs
index 7433c92..1fc6b26 100644
--- a/src/graphics_scene_widget.rs
+++ b/src/graphics_scene_widget.rs
@@ -10,8 +10,9 @@ use druid::{Data, Widget};

use noise::OpenSimplex;

use crate::draw_tools::fractal_line_tool::FractalLineTool;
use crate::draw_tools::tool::Tool;
use crate::drawable::Drawable;
use crate::fractal_line::FractalLine;
use crate::renderobject::RenderObject;

#[derive(Data, Clone, Debug)]
@@ -20,7 +21,7 @@ pub struct Line(Point, Point, Rc<OpenSimplex>);
#[derive(Data, Clone)]
pub struct GraphicsData {
	pub objects: OrdSet<RenderObject>,
	pub preview: Option<FractalLine>,
	pub preview: Option<RenderObject>,
}

pub enum GraphicsEngineState {
@@ -32,6 +33,7 @@ pub struct GraphicsWidget {
	pub state: GraphicsEngineState,
	change_list: OrdSet<RenderObject>,
	remove_list: Vector<RenderObject>,
	current_tool: Rc<Box<dyn Tool>>,
}

impl GraphicsWidget {
@@ -40,6 +42,7 @@ impl GraphicsWidget {
			state: GraphicsEngineState::Default,
			change_list: OrdSet::new(),
			remove_list: Vector::new(),
			current_tool: Rc::new(Box::new(FractalLineTool::new())),
		}
	}

@@ -66,49 +69,22 @@ impl Widget<GraphicsData> for GraphicsWidget {
	) {
		match event {
			druid::Event::WindowConnected => {}
			druid::Event::MouseDown(event) => match self.state {
				GraphicsEngineState::Default => {
					self.enter_state(GraphicsEngineState::Drawing);
					data.preview = Some(FractalLine {
						start: event.pos,
						end: event.pos,
						noise: Rc::new(OpenSimplex::new(rand::random())),
						width: 10.0,
						density: 0.05,
						samples: 1000,
					});
				}
				GraphicsEngineState::Drawing => (),
			},
			druid::Event::MouseUp(_) => match self.state {
				GraphicsEngineState::Default => (),
				GraphicsEngineState::Drawing => {
					data.objects.insert(RenderObject {
						transform: Affine::scale(1.0),
						drawable: Rc::new(Box::new(data.preview.take().unwrap())),
						z: match data.objects.get_max() {
							Some(v) => v.z + 1,
							None => 0,
						},
					});

					data.preview = None;
					self.enter_state(GraphicsEngineState::Default);
				}
			},
			druid::Event::MouseMove(event) => {
				if let GraphicsEngineState::Drawing = self.state {
					if let Some(preview) = &mut data.preview {
						preview.end = event.pos;
					}
				}
			}
			druid::Event::MouseDown(event) => Rc::get_mut(&mut self.current_tool)
				.unwrap()
				.on_mouse_down(event, ctx, data),
			druid::Event::MouseUp(event) => Rc::get_mut(&mut self.current_tool)
				.unwrap()
				.on_mouse_up(event, ctx, data),
			druid::Event::MouseMove(event) => Rc::get_mut(&mut self.current_tool)
				.unwrap()
				.on_mouse_move(event, ctx, data),
			druid::Event::WindowSize(_) => {
				// Need to request full repaint to ensure everything draws correctly
				ctx.request_paint();
			}
			_ => (),
		}
		data.preview = self.current_tool.get_preview();
	}

	fn lifecycle(
@@ -162,18 +138,11 @@ impl Widget<GraphicsData> for GraphicsWidget {

		if let (Some(old), Some(new)) = (&old_data.preview, &data.preview) {
			if !old.same(new) {
				self.change_list.insert(RenderObject {
					transform: Affine::scale(1.0),
					drawable: Rc::new(Box::new(new.clone())),
					z: match data.objects.get_max() {
						Some(v) => v.z + 1,
						None => 0,
					},
				});
				self.change_list.insert(new.clone());
			}

			ctx.request_paint_rect(old.AABB());
			ctx.request_paint_rect(new.AABB());
			ctx.request_paint_rect(old.get_drawable().AABB());
			ctx.request_paint_rect(new.get_drawable().AABB());
		}
	}

@@ -215,7 +184,7 @@ impl Widget<GraphicsData> for GraphicsWidget {
			robj.paint(ctx, env);
		}
		if let Some(line) = &data.preview {
			line.paint(ctx, env, &Affine::rotate(0.0));
			line.paint(ctx, env);
		}
		ctx.restore().unwrap();
		self.change_list.clear();
diff --git a/src/main.rs b/src/main.rs
index 1418d97..9a77fd3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,6 +2,7 @@ use druid::im::ordset;
use druid::{theme, AppLauncher, Color, PlatformError, Widget, WindowDesc};

mod bound;
mod draw_tools;
mod drawable;
mod fractal_line;
mod graphics_scene_widget;
diff --git a/src/renderobject.rs b/src/renderobject.rs
index b2847d1..f3ba3d2 100644
--- a/src/renderobject.rs
+++ b/src/renderobject.rs
@@ -41,6 +41,14 @@ impl RenderObject {
		});
	}

	pub fn new(z: u32, drawable: Rc<Box<dyn Drawable>>) -> Self {
		Self {
			z,
			transform: Affine::new([1.0, 0.0, 0.0, 1.0, 0.0, 0.0]),
			drawable,
		}
	}

	pub fn get_drawable(&self) -> Rc<Box<dyn Drawable>> {
		Rc::clone(&self.drawable)
	}
-- 
2.34.1

[PATCH v2 2/2] Appendectomy of code no longer needed

Details
Message ID
<20221027145912.117044-2-conner.bondurant@triptych.me>
In-Reply-To
<20221027145912.117044-1-conner.bondurant@triptych.me> (view parent)
DKIM signature
missing
Download raw message
Patch: +5 -30
---
Had to add some more clippy suggestions I missed last time
 src/draw_tools/fractal_line_tool.rs | 14 +++++---------
 src/graphics_scene_widget.rs        | 21 ---------------------
 2 files changed, 5 insertions(+), 30 deletions(-)

diff --git a/src/draw_tools/fractal_line_tool.rs b/src/draw_tools/fractal_line_tool.rs
index 944ea0a..6948d8c 100644
--- a/src/draw_tools/fractal_line_tool.rs
+++ b/src/draw_tools/fractal_line_tool.rs
@@ -53,7 +53,7 @@ impl Tool for FractalLineTool {
		&mut self,
		event: &druid::MouseEvent,
		ctx: &mut druid::EventCtx,
		data: &mut crate::graphics_scene_widget::GraphicsData,
		_data: &mut crate::graphics_scene_widget::GraphicsData,
	) {
		match self.state {
			ToolState::Drawing => {
@@ -68,7 +68,7 @@ impl Tool for FractalLineTool {
		&mut self,
		event: &druid::MouseEvent,
		ctx: &mut druid::EventCtx,
		data: &mut crate::graphics_scene_widget::GraphicsData,
		_data: &mut crate::graphics_scene_widget::GraphicsData,
	) {
		self.state = ToolState::Drawing;
		self.preview = FractalLine {
@@ -106,11 +106,10 @@ impl Tool for FractalLineTool {

	fn on_mouse_wheel(
		&mut self,
		event: &druid::MouseEvent,
		ctx: &mut druid::EventCtx,
		data: &mut crate::graphics_scene_widget::GraphicsData,
		_event: &druid::MouseEvent,
		_ctx: &mut druid::EventCtx,
		_data: &mut crate::graphics_scene_widget::GraphicsData,
	) {
		()
	}

	fn on_key_down(
@@ -119,7 +118,6 @@ impl Tool for FractalLineTool {
		_ctx: &mut druid::EventCtx,
		_data: &mut crate::graphics_scene_widget::GraphicsData,
	) {
		()
	}

	fn on_key_up(
@@ -128,7 +126,6 @@ impl Tool for FractalLineTool {
		_ctx: &mut druid::EventCtx,
		_data: &mut crate::graphics_scene_widget::GraphicsData,
	) {
		()
	}

	fn on_paste(
@@ -137,7 +134,6 @@ impl Tool for FractalLineTool {
		_ctx: &mut druid::EventCtx,
		_data: &mut crate::graphics_scene_widget::GraphicsData,
	) {
		()
	}

	fn get_preview(&self) -> Option<crate::renderobject::RenderObject> {
diff --git a/src/graphics_scene_widget.rs b/src/graphics_scene_widget.rs
index 1fc6b26..433d10f 100644
--- a/src/graphics_scene_widget.rs
+++ b/src/graphics_scene_widget.rs
@@ -2,7 +2,6 @@ use std::rc::Rc;

use druid::im::OrdSet;
use druid::im::Vector;
use druid::Affine;
use druid::Color;
use druid::Point;
use druid::RenderContext;
@@ -12,7 +11,6 @@ use noise::OpenSimplex;

use crate::draw_tools::fractal_line_tool::FractalLineTool;
use crate::draw_tools::tool::Tool;
use crate::drawable::Drawable;
use crate::renderobject::RenderObject;

#[derive(Data, Clone, Debug)]
@@ -24,13 +22,7 @@ pub struct GraphicsData {
	pub preview: Option<RenderObject>,
}

pub enum GraphicsEngineState {
	Default,
	Drawing,
}

pub struct GraphicsWidget {
	pub state: GraphicsEngineState,
	change_list: OrdSet<RenderObject>,
	remove_list: Vector<RenderObject>,
	current_tool: Rc<Box<dyn Tool>>,
@@ -39,24 +31,11 @@ pub struct GraphicsWidget {
impl GraphicsWidget {
	pub fn new() -> Self {
		Self {
			state: GraphicsEngineState::Default,
			change_list: OrdSet::new(),
			remove_list: Vector::new(),
			current_tool: Rc::new(Box::new(FractalLineTool::new())),
		}
	}

	fn enter_state(&mut self, new_state: GraphicsEngineState) {
		self.exit_state();
		self.state = new_state;
	}

	fn exit_state(&self) {
		match self.state {
			GraphicsEngineState::Default => (),
			GraphicsEngineState::Drawing => (),
		}
	}
}

impl Widget<GraphicsData> for GraphicsWidget {
-- 
2.34.1
Reply to thread Export thread (mbox)