mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 04:08:11 +00:00

This tightens the update rects for EraseTool, BrushTool And the marching ants update in Selection. Inflate Selection update rect by 10x10 to avoid misalignment when zoomed out.
109 lines
3.4 KiB
C++
109 lines
3.4 KiB
C++
/*
|
|
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include "EraseTool.h"
|
|
#include "ImageEditor.h"
|
|
#include "Layer.h"
|
|
#include <LibGUI/Action.h>
|
|
#include <LibGUI/BoxLayout.h>
|
|
#include <LibGUI/CheckBox.h>
|
|
#include <LibGUI/Label.h>
|
|
#include <LibGUI/Menu.h>
|
|
#include <LibGUI/Painter.h>
|
|
#include <LibGUI/ValueSlider.h>
|
|
#include <LibGfx/Bitmap.h>
|
|
|
|
namespace PixelPaint {
|
|
|
|
EraseTool::EraseTool()
|
|
{
|
|
}
|
|
|
|
EraseTool::~EraseTool()
|
|
{
|
|
}
|
|
|
|
Gfx::IntRect EraseTool::build_rect(Gfx::IntPoint const& pos, Gfx::IntRect const& widget_rect)
|
|
{
|
|
const int eraser_size = m_thickness;
|
|
const int eraser_radius = eraser_size / 2;
|
|
const auto ex = pos.x();
|
|
const auto ey = pos.y();
|
|
return Gfx::IntRect(ex - eraser_radius, ey - eraser_radius, eraser_size, eraser_size).intersected(widget_rect);
|
|
}
|
|
|
|
void EraseTool::on_mousedown(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&)
|
|
{
|
|
if (event.button() != GUI::MouseButton::Left && event.button() != GUI::MouseButton::Right)
|
|
return;
|
|
Gfx::IntRect r = build_rect(event.position(), layer.rect());
|
|
GUI::Painter painter(layer.bitmap());
|
|
painter.clear_rect(r, get_color());
|
|
layer.did_modify_bitmap(r.inflated(2, 2));
|
|
}
|
|
|
|
void EraseTool::on_mousemove(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&)
|
|
{
|
|
if (event.buttons() & GUI::MouseButton::Left || event.buttons() & GUI::MouseButton::Right) {
|
|
Gfx::IntRect r = build_rect(event.position(), layer.rect());
|
|
GUI::Painter painter(layer.bitmap());
|
|
painter.clear_rect(r, get_color());
|
|
layer.did_modify_bitmap(r.inflated(2, 2));
|
|
}
|
|
}
|
|
|
|
void EraseTool::on_mouseup(Layer&, GUI::MouseEvent& event, GUI::MouseEvent&)
|
|
{
|
|
if (event.button() != GUI::MouseButton::Left && event.button() != GUI::MouseButton::Right)
|
|
return;
|
|
m_editor->did_complete_action();
|
|
}
|
|
|
|
Color EraseTool::get_color() const
|
|
{
|
|
if (m_use_secondary_color)
|
|
return m_editor->secondary_color();
|
|
return Color(255, 255, 255, 0);
|
|
}
|
|
|
|
GUI::Widget* EraseTool::get_properties_widget()
|
|
{
|
|
if (!m_properties_widget) {
|
|
m_properties_widget = GUI::Widget::construct();
|
|
m_properties_widget->set_layout<GUI::VerticalBoxLayout>();
|
|
|
|
auto& thickness_container = m_properties_widget->add<GUI::Widget>();
|
|
thickness_container.set_fixed_height(20);
|
|
thickness_container.set_layout<GUI::HorizontalBoxLayout>();
|
|
|
|
auto& thickness_label = thickness_container.add<GUI::Label>("Size:");
|
|
thickness_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
|
|
thickness_label.set_fixed_size(80, 20);
|
|
|
|
auto& thickness_slider = thickness_container.add<GUI::ValueSlider>(Orientation::Horizontal, "px");
|
|
thickness_slider.set_range(1, 50);
|
|
thickness_slider.set_value(m_thickness);
|
|
|
|
thickness_slider.on_change = [&](int value) {
|
|
m_thickness = value;
|
|
};
|
|
|
|
auto& checkbox_container = m_properties_widget->add<GUI::Widget>();
|
|
checkbox_container.set_fixed_height(20);
|
|
checkbox_container.set_layout<GUI::HorizontalBoxLayout>();
|
|
|
|
auto& use_secondary_color_checkbox = checkbox_container.add<GUI::CheckBox>();
|
|
use_secondary_color_checkbox.set_checked(m_use_secondary_color);
|
|
use_secondary_color_checkbox.set_text("Use secondary color");
|
|
use_secondary_color_checkbox.on_checked = [&](bool checked) {
|
|
m_use_secondary_color = checked;
|
|
};
|
|
}
|
|
|
|
return m_properties_widget.ptr();
|
|
}
|
|
|
|
}
|