feat: 实现取色功能

This commit is contained in:
2026-03-05 14:20:43 +08:00
parent 51055b8ea8
commit d694a69723

View File

@@ -87,6 +87,8 @@ enum Message {
MouseReleased(Point), MouseReleased(Point),
MouseMoved(Point), MouseMoved(Point),
MouseDoubleClick(Point), MouseDoubleClick(Point),
MouseRightPressed(Point),
MouseRightReleased(Point),
Clear, Clear,
SavePNG, SavePNG,
@@ -301,6 +303,7 @@ enum ControlState {
struct PaintApp { struct PaintApp {
tool_states: [bool; Tool::Count as usize], tool_states: [bool; Tool::Count as usize],
tool_selected: Tool, tool_selected: Tool,
prev_tool_selected: Tool,
/// 画图层 /// 画图层
canvas: MSCanvas, canvas: MSCanvas,
@@ -352,6 +355,7 @@ impl PaintApp {
let mut ins = Self { let mut ins = Self {
tool_states: [false; Tool::Count as usize], tool_states: [false; Tool::Count as usize],
tool_selected: Tool::Count, tool_selected: Tool::Count,
prev_tool_selected: Tool::Count,
canvas, canvas,
view_canvas, view_canvas,
is_drawing: false, is_drawing: false,
@@ -377,6 +381,8 @@ impl PaintApp {
.stroke_color(MSColor::BLACK) .stroke_color(MSColor::BLACK)
.line_width(1); .line_width(1);
ins.update_tool_states(Tool::Pencil);
ins ins
} }
@@ -391,7 +397,9 @@ impl PaintApp {
.on_press(|pos| Message::MousePressed(pos)) // 占位,实际逻辑在 on_drag 或自定义 .on_press(|pos| Message::MousePressed(pos)) // 占位,实际逻辑在 on_drag 或自定义
.on_release(|pos| Message::MouseReleased(pos)) .on_release(|pos| Message::MouseReleased(pos))
.on_move(|pos| Message::MouseMoved(pos)) .on_move(|pos| Message::MouseMoved(pos))
.on_double_click(|pos| Message::MouseDoubleClick(pos)); .on_double_click(|pos| Message::MouseDoubleClick(pos))
.on_right_press(|pos| Message::MouseRightPressed(pos))
.on_right_release(|pos| Message::MouseRightReleased(pos));
// 注意mouse_area 的 on_move 给出的坐标通常是相对于 widget 左上角的,这正是我们需要的! // 注意mouse_area 的 on_move 给出的坐标通常是相对于 widget 左上角的,这正是我们需要的!
let canvas_area = container(canvas_area) let canvas_area = container(canvas_area)
.width(Length::Fill) .width(Length::Fill)
@@ -598,6 +606,9 @@ impl PaintApp {
Tool::FillWithColor => { Tool::FillWithColor => {
self.update_with_fill_with_color(message); self.update_with_fill_with_color(message);
} }
Tool::PickColor => {
self.update_with_pick_color(message);
}
Tool::Pencil => { Tool::Pencil => {
self.update_with_pencil(message); self.update_with_pencil(message);
} }
@@ -934,6 +945,30 @@ impl PaintApp {
} }
} }
pub fn update_with_pick_color(&mut self, message: Message) {
match message {
Message::MousePressed(pos) => {
let color_option = self.canvas.pixel_at(pos.x as i32, pos.y as i32);
if let Some(color) = color_option {
self.foreground_color = color;
self.canvas.stroke_color(color);
self.canvas.fill_color(color);
}
}
Message::MouseRightPressed(pos) => {
let color_option = self.canvas.pixel_at(pos.x as i32, pos.y as i32);
if let Some(color) = color_option {
self.background_color = color;
}
}
Message::MouseReleased(_) | Message::MouseRightReleased(_) => {
self.update_tool_states(self.prev_tool_selected);
}
_ => {}
}
}
pub fn update_with_pencil(&mut self, message: Message) { pub fn update_with_pencil(&mut self, message: Message) {
match message { match message {
Message::MousePressed(pos) => { Message::MousePressed(pos) => {
@@ -1345,6 +1380,7 @@ impl PaintApp {
self.tool_states[i] = false; self.tool_states[i] = false;
} }
self.tool_states[idx] = !old_value; self.tool_states[idx] = !old_value;
self.prev_tool_selected = self.tool_selected;
self.tool_selected = idx.into(); self.tool_selected = idx.into();
} }