Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "ToolboxWidget.h"
28#include "BucketTool.h"
29#include "EllipseTool.h"
30#include "EraseTool.h"
31#include "LineTool.h"
32#include "PaintableWidget.h"
33#include "PenTool.h"
34#include "PickerTool.h"
35#include "RectangleTool.h"
36#include "SprayTool.h"
37#include <LibGUI/BoxLayout.h>
38#include <LibGUI/Button.h>
39
40class ToolButton final : public GUI::Button {
41 C_OBJECT(ToolButton)
42public:
43 ToolButton(const String& name, OwnPtr<Tool>&& tool)
44 : m_tool(move(tool))
45 {
46 set_tooltip(name);
47 }
48
49 const Tool& tool() const { return *m_tool; }
50 Tool& tool() { return *m_tool; }
51
52 virtual void context_menu_event(GUI::ContextMenuEvent& event) override
53 {
54 set_checked(true);
55 m_tool->on_contextmenu(event);
56 }
57
58private:
59 OwnPtr<Tool> m_tool;
60};
61
62ToolboxWidget::ToolboxWidget()
63{
64 set_fill_with_background_color(true);
65
66 set_frame_thickness(1);
67 set_frame_shape(Gfx::FrameShape::Panel);
68 set_frame_shadow(Gfx::FrameShadow::Raised);
69
70 set_size_policy(GUI::SizePolicy::Fixed, GUI::SizePolicy::Fill);
71 set_preferred_size(48, 0);
72
73 set_layout<GUI::VerticalBoxLayout>();
74 layout()->set_margins({ 4, 4, 4, 4 });
75
76 auto add_tool = [&](const StringView& name, const StringView& icon_name, OwnPtr<Tool>&& tool) {
77 auto& button = add<ToolButton>(name, move(tool));
78 button.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed);
79 button.set_preferred_size(0, 32);
80 button.set_checkable(true);
81 button.set_exclusive(true);
82
83 button.set_icon(Gfx::Bitmap::load_from_file(String::format("/res/icons/paintbrush/%s.png", String(icon_name).characters())));
84
85 button.on_checked = [button = &button](auto checked) {
86 if (checked)
87 PaintableWidget::the().set_tool(&button->tool());
88 else
89 PaintableWidget::the().set_tool(nullptr);
90 };
91 };
92
93 add_tool("Pen", "pen", make<PenTool>());
94 add_tool("Bucket Fill", "bucket", make<BucketTool>());
95 add_tool("Spray", "spray", make<SprayTool>());
96 add_tool("Color Picker", "picker", make<PickerTool>());
97 add_tool("Erase", "eraser", make<EraseTool>());
98 add_tool("Line", "line", make<LineTool>());
99 add_tool("Rectangle", "rectangle", make<RectangleTool>());
100 add_tool("Ellipse", "circle", make<EllipseTool>());
101}
102
103ToolboxWidget::~ToolboxWidget()
104{
105}