/* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Mustafa Quraish * Copyright (c) 2022, the SerenityOS developers. * * SPDX-License-Identifier: BSD-2-Clause */ #include "EraseTool.h" #include "../ImageEditor.h" #include "../Layer.h" #include #include #include #include #include #include #include #include #include namespace PixelPaint { Color EraseTool::color_for(GUI::MouseEvent const&) { if (m_use_secondary_color) return m_editor->secondary_color(); return Color(255, 255, 255, 0); } void EraseTool::draw_point(Gfx::Bitmap& bitmap, Gfx::Color const& color, Gfx::IntPoint const& point) { if (m_draw_mode == DrawMode::Pencil) { int radius = size() / 2; Gfx::IntRect rect { point.x() - radius, point.y() - radius, size(), size() }; GUI::Painter painter(bitmap); painter.clear_rect(rect, color); } else { for (int y = point.y() - size(); y < point.y() + size(); y++) { for (int x = point.x() - size(); x < point.x() + size(); x++) { auto distance = point.distance_from({ x, y }); if (x < 0 || x >= bitmap.width() || y < 0 || y >= bitmap.height()) continue; if (distance >= size()) continue; auto old_color = bitmap.get_pixel(x, y); auto falloff = get_falloff(distance); auto new_color = old_color.interpolate(color, falloff); bitmap.set_pixel(x, y, new_color); } } } } GUI::Widget* EraseTool::get_properties_widget() { if (!m_properties_widget) { m_properties_widget = GUI::Widget::construct(); m_properties_widget->set_layout(); auto& size_container = m_properties_widget->add(); size_container.set_fixed_height(20); size_container.set_layout(); auto& size_label = size_container.add("Size:"); size_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); size_label.set_fixed_size(80, 20); auto& size_slider = size_container.add(Orientation::Horizontal, "px"); size_slider.set_range(1, 100); size_slider.set_value(size()); size_slider.on_change = [&](int value) { set_size(value); }; set_primary_slider(&size_slider); auto& hardness_container = m_properties_widget->add(); hardness_container.set_fixed_height(20); hardness_container.set_layout(); auto& hardness_label = hardness_container.add("Hardness:"); hardness_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); hardness_label.set_fixed_size(80, 20); auto& hardness_slider = hardness_container.add(Orientation::Horizontal, "%"); hardness_slider.set_range(1, 100); hardness_slider.set_value(hardness()); hardness_slider.on_change = [&](int value) { set_hardness(value); }; set_secondary_slider(&hardness_slider); auto& secondary_color_container = m_properties_widget->add(); secondary_color_container.set_fixed_height(20); secondary_color_container.set_layout(); auto& use_secondary_color_checkbox = secondary_color_container.add(); 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; }; auto& mode_container = m_properties_widget->add(); mode_container.set_fixed_height(46); mode_container.set_layout(); auto& mode_label = mode_container.add("Draw Mode:"); mode_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); mode_label.set_fixed_size(80, 20); auto& mode_radio_container = mode_container.add(); mode_radio_container.set_layout(); auto& pencil_mode_radio = mode_radio_container.add("Pencil"); auto& brush_mode_radio = mode_radio_container.add("Brush"); pencil_mode_radio.on_checked = [&](bool) { m_draw_mode = DrawMode::Pencil; hardness_slider.set_enabled(false); }; brush_mode_radio.on_checked = [&](bool) { m_draw_mode = DrawMode::Brush; hardness_slider.set_enabled(true); }; pencil_mode_radio.set_checked(true); } return m_properties_widget.ptr(); } }