feat: 更新曲线和多边形功能状态控制
This commit is contained in:
@@ -731,14 +731,7 @@ impl MSCanvas {
|
|||||||
/// - x, y: 左上角坐标
|
/// - x, y: 左上角坐标
|
||||||
/// - width, height: 尺寸(必须 > 0)
|
/// - width, height: 尺寸(必须 > 0)
|
||||||
/// - radius: 圆角半径(会被 clamp 到合理范围)
|
/// - radius: 圆角半径(会被 clamp 到合理范围)
|
||||||
pub fn fill_round_rect(
|
pub fn fill_round_rect(&mut self, x: f32, y: f32, width: f32, height: f32, radius: f32) {
|
||||||
&mut self,
|
|
||||||
x: f32,
|
|
||||||
y: f32,
|
|
||||||
width: f32,
|
|
||||||
height: f32,
|
|
||||||
radius: f32,
|
|
||||||
) {
|
|
||||||
if (width as i32) <= 2 * self.line_width
|
if (width as i32) <= 2 * self.line_width
|
||||||
|| (height as i32) <= 2 * self.line_width
|
|| (height as i32) <= 2 * self.line_width
|
||||||
|| width <= 2.0 * radius
|
|| width <= 2.0 * radius
|
||||||
@@ -757,7 +750,10 @@ impl MSCanvas {
|
|||||||
let corners = [
|
let corners = [
|
||||||
((x + radius) as i32, (y + radius) as i32), // 左上
|
((x + radius) as i32, (y + radius) as i32), // 左上
|
||||||
((x + width - 1.0 - radius) as i32, (y + radius) as i32), // 右上
|
((x + width - 1.0 - radius) as i32, (y + radius) as i32), // 右上
|
||||||
((x + width - 1.0 - radius) as i32, (y + height - 1.0 - radius) as i32), // 右下
|
(
|
||||||
|
(x + width - 1.0 - radius) as i32,
|
||||||
|
(y + height - 1.0 - radius) as i32,
|
||||||
|
), // 右下
|
||||||
((x + radius) as i32, (y + height - 1.0 - radius) as i32), // 左下
|
((x + radius) as i32, (y + height - 1.0 - radius) as i32), // 左下
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -906,13 +902,13 @@ impl MSCanvas {
|
|||||||
|
|
||||||
pub fn rect(&mut self, x: i32, y: i32, width: i32, height: i32) {
|
pub fn rect(&mut self, x: i32, y: i32, width: i32, height: i32) {
|
||||||
if width < 2 * self.line_width || height < 2 * self.line_width {
|
if width < 2 * self.line_width || height < 2 * self.line_width {
|
||||||
self.fill_rect(x, y, width, height);
|
self.fill_rect_foreground_color(x, y, width, height);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.fill_rect(x, y, width, self.line_width);
|
self.fill_rect_foreground_color(x, y, width, self.line_width);
|
||||||
self.fill_rect(x, y + height - self.line_width, width, self.line_width);
|
self.fill_rect_foreground_color(x, y + height - self.line_width, width, self.line_width);
|
||||||
self.fill_rect(x, y, self.line_width, height);
|
self.fill_rect_foreground_color(x, y, self.line_width, height);
|
||||||
self.fill_rect(x + width - self.line_width, y, self.line_width, height);
|
self.fill_rect_foreground_color(x + width - self.line_width, y, self.line_width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rect1(&mut self, p1: Point, p2: Point) {
|
pub fn rect1(&mut self, p1: Point, p2: Point) {
|
||||||
@@ -997,7 +993,7 @@ impl MSCanvas {
|
|||||||
while t <= 1.0 {
|
while t <= 1.0 {
|
||||||
let point = self.recursive_bezier(&control_points, t);
|
let point = self.recursive_bezier(&control_points, t);
|
||||||
self.brush_circle(point);
|
self.brush_circle(point);
|
||||||
t += 0.001;
|
t += 0.0005;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
116
src/paint.rs
116
src/paint.rs
@@ -246,6 +246,14 @@ impl Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
enum ControlState {
|
||||||
|
Zero,
|
||||||
|
One,
|
||||||
|
Two,
|
||||||
|
Three,
|
||||||
|
}
|
||||||
|
|
||||||
struct PaintApp {
|
struct PaintApp {
|
||||||
tool_states: [bool; Tool::Count as usize],
|
tool_states: [bool; Tool::Count as usize],
|
||||||
tool_selected: Tool,
|
tool_selected: Tool,
|
||||||
@@ -261,11 +269,9 @@ struct PaintApp {
|
|||||||
end_point: Point,
|
end_point: Point,
|
||||||
|
|
||||||
/// 贝塞尔曲线控制
|
/// 贝塞尔曲线控制
|
||||||
is_controlling: bool,
|
control_state: ControlState,
|
||||||
control_points: Vec<Point>,
|
control_points: Vec<Point>,
|
||||||
|
|
||||||
is_path_beginning: bool,
|
|
||||||
|
|
||||||
/// 用于显示的图像句柄缓存
|
/// 用于显示的图像句柄缓存
|
||||||
/// 每次像素变化后需要重新生成
|
/// 每次像素变化后需要重新生成
|
||||||
image_handle: image::Handle,
|
image_handle: image::Handle,
|
||||||
@@ -290,7 +296,6 @@ impl PaintApp {
|
|||||||
let pixels = canvas.get_pixels();
|
let pixels = canvas.get_pixels();
|
||||||
let config = Config::default();
|
let config = Config::default();
|
||||||
canvas.set_line_width(config.line_width);
|
canvas.set_line_width(config.line_width);
|
||||||
canvas.set_background_color(MSColor::GREEN);
|
|
||||||
Self {
|
Self {
|
||||||
tool_states: [false; Tool::Count as usize],
|
tool_states: [false; Tool::Count as usize],
|
||||||
tool_selected: Tool::Count,
|
tool_selected: Tool::Count,
|
||||||
@@ -298,9 +303,8 @@ impl PaintApp {
|
|||||||
is_drawing: false,
|
is_drawing: false,
|
||||||
begin_point: Point::ORIGIN,
|
begin_point: Point::ORIGIN,
|
||||||
end_point: Point::ORIGIN,
|
end_point: Point::ORIGIN,
|
||||||
is_controlling: false,
|
control_state: ControlState::Zero,
|
||||||
control_points: Vec::with_capacity(2),
|
control_points: Vec::with_capacity(2),
|
||||||
is_path_beginning: false,
|
|
||||||
image_handle: image::Handle::from_rgba(width as u32, height as u32, pixels),
|
image_handle: image::Handle::from_rgba(width as u32, height as u32, pixels),
|
||||||
dirty: false,
|
dirty: false,
|
||||||
config,
|
config,
|
||||||
@@ -797,14 +801,23 @@ impl PaintApp {
|
|||||||
|
|
||||||
pub fn update_with_curve(&mut self, message: Message) {
|
pub fn update_with_curve(&mut self, message: Message) {
|
||||||
match message {
|
match message {
|
||||||
Message::MousePressed(pos) => {
|
Message::MousePressed(pos) => match self.control_state {
|
||||||
if self.is_controlling {
|
ControlState::Zero => {
|
||||||
if self.control_points.len() == 0 {
|
self.begin_point = pos;
|
||||||
|
self.is_drawing = true;
|
||||||
|
self.canvas.save_pixels();
|
||||||
|
self.control_state = ControlState::One;
|
||||||
|
}
|
||||||
|
ControlState::One => {
|
||||||
|
self.is_drawing = true;
|
||||||
self.canvas.restore_pixels();
|
self.canvas.restore_pixels();
|
||||||
self.canvas
|
self.canvas
|
||||||
.quadratic_bezier(self.begin_point, self.end_point, pos);
|
.quadratic_bezier(self.begin_point, self.end_point, pos);
|
||||||
self.control_points.push(pos);
|
self.dirty = true;
|
||||||
} else {
|
self.control_state = ControlState::Two;
|
||||||
|
}
|
||||||
|
ControlState::Two => {
|
||||||
|
self.is_drawing = true;
|
||||||
self.canvas.restore_pixels();
|
self.canvas.restore_pixels();
|
||||||
self.canvas.cubic_bezier(
|
self.canvas.cubic_bezier(
|
||||||
self.begin_point,
|
self.begin_point,
|
||||||
@@ -812,32 +825,56 @@ impl PaintApp {
|
|||||||
self.control_points[0],
|
self.control_points[0],
|
||||||
pos,
|
pos,
|
||||||
);
|
);
|
||||||
|
self.dirty = true;
|
||||||
|
self.control_state = ControlState::Three;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
Message::MouseReleased(pos) => {
|
||||||
|
self.is_drawing = false;
|
||||||
|
match self.control_state {
|
||||||
|
ControlState::One => {
|
||||||
|
self.end_point = pos;
|
||||||
|
}
|
||||||
|
ControlState::Two => {
|
||||||
self.control_points.push(pos);
|
self.control_points.push(pos);
|
||||||
}
|
}
|
||||||
self.dirty = true;
|
ControlState::Three => {
|
||||||
} else {
|
self.control_state = ControlState::Zero;
|
||||||
self.is_drawing = true;
|
|
||||||
self.canvas.save_pixels();
|
|
||||||
self.begin_point = pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Message::MouseReleased(pos) => {
|
|
||||||
if self.control_points.len() == 0 {
|
|
||||||
self.is_drawing = false;
|
|
||||||
self.end_point = pos;
|
|
||||||
self.is_controlling = true;
|
|
||||||
} else if self.control_points.len() == 2 {
|
|
||||||
self.control_points.clear();
|
self.control_points.clear();
|
||||||
self.is_controlling = false;
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::MouseMoved(pos) => {
|
Message::MouseMoved(pos) => {
|
||||||
if self.is_drawing {
|
if self.is_drawing {
|
||||||
|
match self.control_state {
|
||||||
|
ControlState::One => {
|
||||||
self.canvas.restore_pixels();
|
self.canvas.restore_pixels();
|
||||||
self.canvas
|
self.canvas
|
||||||
.draw_line_with_circle_brush(self.begin_point, pos);
|
.draw_line_with_circle_brush(self.begin_point, pos);
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
|
ControlState::Two => {
|
||||||
|
self.canvas.restore_pixels();
|
||||||
|
self.canvas
|
||||||
|
.quadratic_bezier(self.begin_point, self.end_point, pos);
|
||||||
|
self.dirty = true;
|
||||||
|
}
|
||||||
|
ControlState::Three => {
|
||||||
|
self.canvas.restore_pixels();
|
||||||
|
self.canvas.restore_pixels();
|
||||||
|
self.canvas.cubic_bezier(
|
||||||
|
self.begin_point,
|
||||||
|
self.end_point,
|
||||||
|
self.control_points[0],
|
||||||
|
pos,
|
||||||
|
);
|
||||||
|
self.dirty = true;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@@ -857,7 +894,7 @@ impl PaintApp {
|
|||||||
Message::MouseMoved(pos) => {
|
Message::MouseMoved(pos) => {
|
||||||
if self.is_drawing {
|
if self.is_drawing {
|
||||||
self.canvas.restore_pixels();
|
self.canvas.restore_pixels();
|
||||||
self.canvas.stroke_rect1(self.begin_point, pos);
|
self.canvas.rect1(self.begin_point, pos);
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -867,24 +904,27 @@ impl PaintApp {
|
|||||||
|
|
||||||
pub fn update_with_polygon(&mut self, message: Message) {
|
pub fn update_with_polygon(&mut self, message: Message) {
|
||||||
match message {
|
match message {
|
||||||
Message::MousePressed(pos) => {
|
Message::MousePressed(pos) => match self.control_state {
|
||||||
if self.is_path_beginning {
|
ControlState::Zero => {
|
||||||
|
self.is_drawing = true;
|
||||||
|
self.begin_point = pos;
|
||||||
|
self.canvas.save_pixels();
|
||||||
|
self.canvas.begin_path();
|
||||||
|
self.canvas.move_to(pos);
|
||||||
|
self.control_state = ControlState::One;
|
||||||
|
}
|
||||||
|
ControlState::One => {
|
||||||
self.is_drawing = true;
|
self.is_drawing = true;
|
||||||
self.canvas.restore_pixels();
|
self.canvas.restore_pixels();
|
||||||
self.canvas.stroke();
|
self.canvas.stroke();
|
||||||
self.canvas
|
self.canvas
|
||||||
.draw_line_with_circle_brush(self.begin_point, pos);
|
.draw_line_with_circle_brush(self.begin_point, pos);
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
} else {
|
|
||||||
self.is_path_beginning = true;
|
|
||||||
self.is_drawing = true;
|
|
||||||
self.canvas.save_pixels();
|
|
||||||
self.begin_point = pos;
|
|
||||||
self.canvas.begin_path();
|
|
||||||
self.canvas.move_to(pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
Message::MouseReleased(pos) => {
|
Message::MouseReleased(pos) => {
|
||||||
|
self.is_drawing = false;
|
||||||
self.canvas.line_to(pos);
|
self.canvas.line_to(pos);
|
||||||
self.begin_point = pos;
|
self.begin_point = pos;
|
||||||
}
|
}
|
||||||
@@ -901,7 +941,7 @@ impl PaintApp {
|
|||||||
self.canvas.close_path();
|
self.canvas.close_path();
|
||||||
self.canvas.stroke();
|
self.canvas.stroke();
|
||||||
self.is_drawing = false;
|
self.is_drawing = false;
|
||||||
self.is_path_beginning = false;
|
self.control_state = ControlState::Zero;
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -978,7 +1018,7 @@ impl PaintApp {
|
|||||||
self.tool_selected = idx.into();
|
self.tool_selected = idx.into();
|
||||||
|
|
||||||
self.is_drawing = false;
|
self.is_drawing = false;
|
||||||
self.is_path_beginning = false;
|
self.control_state = ControlState::Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 将原始字节转换为 Iced 的图像句柄
|
/// 将原始字节转换为 Iced 的图像句柄
|
||||||
|
|||||||
Reference in New Issue
Block a user