Implement pencil and line tool

This commit is contained in:
2026-02-24 22:20:06 +08:00
parent b567ef1fed
commit 4e999ed459
6 changed files with 1011 additions and 179 deletions

View File

@@ -1,154 +1,7 @@
use iced::widget::{Column, Row, button, column, text, Grid, row};
use iced::{Border, Color, Task};
use iced::padding;
use iced::widget::container;
use iced::Theme;
mod image_button;
mod paint;
mod mouse_area;
#[derive(Default)]
struct Paint {
tool_pressed: [bool; Tool::Count as usize],
}
#[derive(Debug, Clone, Copy)]
pub enum Message {
Decrement,
FreeFormSelectClicked,
SelectClicked,
EraserClicked,
FillWithColorClicked,
PickColorClicked,
MagnifierClicked,
PencilClicked,
BrushClicked,
AirbrushClicked,
TextClicked,
LineClicked,
CurveClicked,
RectangleClicked,
PolygonClicked,
EllipseClicked,
RoundedRectangleClicked,
}
impl Message {
pub fn to_tool_index(&self) -> usize {
match self {
Message::FreeFormSelectClicked => 0,
Message::SelectClicked => 1,
Message::EraserClicked => 2,
Message::FillWithColorClicked => 3,
Message::PickColorClicked => 4,
Message::MagnifierClicked => 5,
Message::PencilClicked => 6,
Message::BrushClicked => 7,
Message::AirbrushClicked => 8,
Message::TextClicked => 9,
Message::LineClicked => 10,
Message::CurveClicked => 11,
Message::RectangleClicked => 12,
Message::PolygonClicked => 13,
Message::EllipseClicked => 14,
Message::RoundedRectangleClicked => 15,
_ => usize::MAX,
}
}
}
pub enum Tool {
FreeFormSelect,
Select,
Eraser,
FillWithColor,
PickColor,
Magnifier,
Pencil,
Brush,
Airbrush,
Text,
Line,
Curve,
Rectangle,
Polygon,
Ellipse,
RoundedRectangle,
Count,
}
impl Paint {
pub fn view(&self) -> Column<'_, Message> {
let mut grid = Grid::new();
grid = grid.columns(2).width(100);
for i in 0..(Tool::Count as usize) {
let msg = match i {
0 => Message::FreeFormSelectClicked,
1 => Message::SelectClicked,
2 => Message::EraserClicked,
3 => Message::FillWithColorClicked,
4 => Message::PickColorClicked,
5 => Message::MagnifierClicked,
6 => Message::PencilClicked,
7 => Message::BrushClicked,
8 => Message::AirbrushClicked,
9 => Message::TextClicked,
10 => Message::LineClicked,
11 => Message::CurveClicked,
12 => Message::RectangleClicked,
13 => Message::PolygonClicked,
14 => Message::EllipseClicked,
15 => Message::RoundedRectangleClicked,
_ => Message::FreeFormSelectClicked,
};
let btn = image_button::image_button(
format!("image/normal/normal_{:02}.jpg", i + 1),
format!("image/selected/selected_{:02}.jpg", i + 1),
self.tool_pressed[i],
).on_press(msg);
grid = grid.push(btn);
}
// We use a column: a simple vertical layout
column![
button("-").on_press(Message::Decrement),
container(grid).padding(padding::left(5).right(5).bottom(100)).style(|theme: &Theme| {
let palette = theme.extended_palette();
container::Style {
background: Some(Color::from_rgb8(192, 192, 192).into()),
text_color: Some(palette.background.weakest.text),
border: Border {
width: 1.0,
radius: 5.0.into(),
color: palette.background.weak.color,
},
..container::Style::default()
}
}),
]
}
pub fn update(&mut self, message: Message) {
self.press_tool(&message);
}
pub fn press_tool(&mut self, message: &Message) {
let idx = message.to_tool_index();
if idx == usize::MAX {
return;
}
let old_value = self.tool_pressed[idx];
for i in 0..(Tool::Count as usize) {
self.tool_pressed[i] = false;
}
self.tool_pressed[idx] = !old_value;
}
}
fn main() -> iced::Result {
iced::run(Paint::update, Paint::view)
pub fn main() -> iced::Result {
paint::main()
}