mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 16:38:10 +00:00
PixelPaint: Allow bigger Brush-Tool sizes
This patch allows a bigger brush tool size of 250 pixels and limits the cursor bitmap to a reasonable size so that its not much bigger than the image editor size. If the cursor is bigger as the editor it is rended with a red edge to indicate that the actual cursor is bigger than displayed. This change mitigates the OOM conditions when the cursor gets unusual big.
This commit is contained in:
parent
55edfe5c3c
commit
31ee20e179
4 changed files with 46 additions and 22 deletions
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Ben Jilks <benjyjilks@gmail.com>
|
||||
* Copyright (c) 2021, Mustafa Quraish <mustafa@serenityos.org>
|
||||
* Copyright (c) 2022, Torsten Engelmann <engelTorsten@gmx.de>
|
||||
* Copyright (c) 2022-2023, Torsten Engelmann <engelTorsten@gmx.de>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -149,10 +149,10 @@ ErrorOr<GUI::Widget*> BrushTool::get_properties_widget()
|
|||
|
||||
auto size_label = TRY(size_container->try_add<GUI::Label>("Size:"_string));
|
||||
size_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
|
||||
size_label->set_fixed_size(80, 20);
|
||||
size_label->set_fixed_size(60, 20);
|
||||
|
||||
auto size_slider = TRY(size_container->try_add<GUI::ValueSlider>(Orientation::Horizontal, "px"_string));
|
||||
size_slider->set_range(1, 100);
|
||||
size_slider->set_range(1, 250);
|
||||
size_slider->set_value(m_size);
|
||||
size_slider->set_override_cursor(cursor());
|
||||
|
||||
|
@ -169,7 +169,7 @@ ErrorOr<GUI::Widget*> BrushTool::get_properties_widget()
|
|||
|
||||
auto hardness_label = TRY(hardness_container->try_add<GUI::Label>("Hardness:"_string));
|
||||
hardness_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
|
||||
hardness_label->set_fixed_size(80, 20);
|
||||
hardness_label->set_fixed_size(60, 20);
|
||||
|
||||
auto hardness_slider = TRY(hardness_container->try_add<GUI::ValueSlider>(Orientation::Horizontal, "%"_string));
|
||||
hardness_slider->set_range(1, 100);
|
||||
|
@ -188,19 +188,23 @@ ErrorOr<GUI::Widget*> BrushTool::get_properties_widget()
|
|||
NonnullRefPtr<Gfx::Bitmap> BrushTool::build_cursor()
|
||||
{
|
||||
m_scale_last_created_cursor = m_editor ? m_editor->scale() : 1;
|
||||
auto scaled_size = size() * m_scale_last_created_cursor;
|
||||
auto containing_box_size = 2 * scaled_size;
|
||||
auto containing_box_size = AK::clamp(preferred_cursor_size(), 1.0f, max_allowed_cursor_size());
|
||||
auto centered = containing_box_size / 2;
|
||||
NonnullRefPtr<Gfx::Bitmap> new_cursor = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, Gfx::IntSize(containing_box_size, containing_box_size)).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
Gfx::Painter painter { new_cursor };
|
||||
Gfx::AntiAliasingPainter aa_painter { painter };
|
||||
|
||||
painter.draw_line({ scaled_size - 5, scaled_size }, { scaled_size + 5, scaled_size }, Color::LightGray, 3);
|
||||
painter.draw_line({ scaled_size, scaled_size - 5 }, { scaled_size, scaled_size + 5 }, Color::LightGray, 3);
|
||||
painter.draw_line({ scaled_size - 5, scaled_size }, { scaled_size + 5, scaled_size }, Color::MidGray, 1);
|
||||
painter.draw_line({ scaled_size, scaled_size - 5 }, { scaled_size, scaled_size + 5 }, Color::MidGray, 1);
|
||||
aa_painter.draw_ellipse(Gfx::IntRect(0, 0, containing_box_size, containing_box_size), Color::LightGray, 1);
|
||||
|
||||
painter.draw_line({ centered - 5, centered }, { centered + 5, centered }, Color::LightGray, 3);
|
||||
painter.draw_line({ centered, centered - 5 }, { centered, centered + 5 }, Color::LightGray, 3);
|
||||
painter.draw_line({ centered - 5, centered }, { centered + 5, centered }, Color::MidGray, 1);
|
||||
painter.draw_line({ centered, centered - 5 }, { centered, centered + 5 }, Color::MidGray, 1);
|
||||
if (max_allowed_cursor_size() != containing_box_size) {
|
||||
aa_painter.draw_ellipse(Gfx::IntRect(0, 0, containing_box_size, containing_box_size), Color::LightGray, 1);
|
||||
} else {
|
||||
aa_painter.draw_ellipse(Gfx::IntRect(0, 0, containing_box_size, containing_box_size), Color::Red, 1);
|
||||
aa_painter.draw_ellipse(Gfx::IntRect(3, 3, containing_box_size - 6, containing_box_size - 6), Color::LightGray, 1);
|
||||
}
|
||||
return new_cursor;
|
||||
}
|
||||
|
||||
|
@ -211,4 +215,13 @@ void BrushTool::refresh_editor_cursor()
|
|||
m_editor->update_tool_cursor();
|
||||
}
|
||||
|
||||
float BrushTool::preferred_cursor_size()
|
||||
{
|
||||
return 2 * size() * (m_editor ? m_editor->scale() : 1);
|
||||
}
|
||||
|
||||
float BrushTool::max_allowed_cursor_size()
|
||||
{
|
||||
return m_editor ? Gfx::IntPoint(0, 0).distance_from({ m_editor->width(), m_editor->height() }) * 1.1f : 500;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (c) 2020, Ben Jilks <benjyjilks@gmail.com>
|
||||
* Copyright (c) 2021, Mustafa Quraish <mustafa@serenityos.org>
|
||||
* Copyright (c) 2022, the SerenityOS developers.
|
||||
* Copyright (c) 2022, Torsten Engelmann <engelTorsten@gmx.de>
|
||||
* Copyright (c) 2022-2023, Torsten Engelmann <engelTorsten@gmx.de>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -50,6 +50,8 @@ protected:
|
|||
virtual void draw_line(Gfx::Bitmap& bitmap, Gfx::Color color, Gfx::IntPoint start, Gfx::IntPoint end);
|
||||
virtual NonnullRefPtr<Gfx::Bitmap> build_cursor();
|
||||
void refresh_editor_cursor();
|
||||
virtual float preferred_cursor_size();
|
||||
virtual float max_allowed_cursor_size();
|
||||
float m_scale_last_created_cursor = 0;
|
||||
|
||||
private:
|
||||
|
|
|
@ -69,7 +69,7 @@ ErrorOr<GUI::Widget*> EraseTool::get_properties_widget()
|
|||
size_label->set_fixed_size(80, 20);
|
||||
|
||||
auto size_slider = TRY(size_container->try_add<GUI::ValueSlider>(Orientation::Horizontal, "px"_string));
|
||||
size_slider->set_range(1, 100);
|
||||
size_slider->set_range(1, 250);
|
||||
size_slider->set_value(size());
|
||||
|
||||
size_slider->on_change = [this, size_slider](int value) {
|
||||
|
@ -144,20 +144,28 @@ NonnullRefPtr<Gfx::Bitmap> EraseTool::build_cursor()
|
|||
return BrushTool::build_cursor();
|
||||
|
||||
m_scale_last_created_cursor = m_editor ? m_editor->scale() : 1;
|
||||
int scaled_size = size() * m_scale_last_created_cursor;
|
||||
int cursor_size = AK::clamp(preferred_cursor_size(), 1, max_allowed_cursor_size());
|
||||
|
||||
NonnullRefPtr<Gfx::Bitmap> new_cursor = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, Gfx::IntSize(scaled_size, scaled_size)).release_value_but_fixme_should_propagate_errors();
|
||||
NonnullRefPtr<Gfx::Bitmap> new_cursor = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, Gfx::IntSize(cursor_size, cursor_size)).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
Gfx::IntRect rect { 0, 0, scaled_size, scaled_size };
|
||||
Gfx::Painter painter { new_cursor };
|
||||
|
||||
painter.draw_rect(rect, Color::LightGray);
|
||||
painter.draw_line({ scaled_size / 2 - 5, scaled_size / 2 }, { scaled_size / 2 + 5, scaled_size / 2 }, Color::LightGray, 3);
|
||||
painter.draw_line({ scaled_size / 2, scaled_size / 2 - 5 }, { scaled_size / 2, scaled_size / 2 + 5 }, Color::LightGray, 3);
|
||||
painter.draw_line({ scaled_size / 2 - 5, scaled_size / 2 }, { scaled_size / 2 + 5, scaled_size / 2 }, Color::MidGray, 1);
|
||||
painter.draw_line({ scaled_size / 2, scaled_size / 2 - 5 }, { scaled_size / 2, scaled_size / 2 + 5 }, Color::MidGray, 1);
|
||||
if (preferred_cursor_size() > max_allowed_cursor_size()) {
|
||||
painter.draw_rect({ 0, 0, cursor_size, cursor_size }, Color::Red);
|
||||
painter.draw_rect({ 3, 3, cursor_size - 6, cursor_size - 6 }, Color::LightGray);
|
||||
} else {
|
||||
painter.draw_rect({ 0, 0, cursor_size, cursor_size }, Color::LightGray);
|
||||
}
|
||||
painter.draw_line({ cursor_size / 2 - 5, cursor_size / 2 }, { cursor_size / 2 + 5, cursor_size / 2 }, Color::LightGray, 3);
|
||||
painter.draw_line({ cursor_size / 2, cursor_size / 2 - 5 }, { cursor_size / 2, cursor_size / 2 + 5 }, Color::LightGray, 3);
|
||||
painter.draw_line({ cursor_size / 2 - 5, cursor_size / 2 }, { cursor_size / 2 + 5, cursor_size / 2 }, Color::MidGray, 1);
|
||||
painter.draw_line({ cursor_size / 2, cursor_size / 2 - 5 }, { cursor_size / 2, cursor_size / 2 + 5 }, Color::MidGray, 1);
|
||||
|
||||
return new_cursor;
|
||||
}
|
||||
|
||||
float EraseTool::preferred_cursor_size()
|
||||
{
|
||||
return size() * (m_editor ? m_editor->scale() : 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ protected:
|
|||
virtual Color color_for(GUI::MouseEvent const& event) override;
|
||||
virtual void draw_point(Gfx::Bitmap& bitmap, Gfx::Color color, Gfx::IntPoint point) override;
|
||||
virtual NonnullRefPtr<Gfx::Bitmap> build_cursor() override;
|
||||
virtual float preferred_cursor_size() override;
|
||||
|
||||
private:
|
||||
virtual StringView tool_name() const override { return "Erase Tool"sv; }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue