diff --git a/Applications/PaintBrush/CreateNewLayerDialog.cpp b/Applications/PaintBrush/CreateNewLayerDialog.cpp new file mode 100644 index 0000000000..e801b80f2b --- /dev/null +++ b/Applications/PaintBrush/CreateNewLayerDialog.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "CreateNewLayerDialog.h" +#include +#include +#include +#include +#include + +namespace PaintBrush { + +CreateNewLayerDialog::CreateNewLayerDialog(const Gfx::Size& suggested_size, GUI::Window* parent_window) + : Dialog(parent_window) +{ + set_title("Create new layer"); + resize(200, 200); + + auto& main_widget = set_main_widget(); + main_widget.set_fill_with_background_color(true); + + auto& layout = main_widget.set_layout(); + layout.set_margins({ 4, 4, 4, 4 }); + + auto& name_label = main_widget.add("Name:"); + name_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); + + m_name_textbox = main_widget.add(); + m_name_textbox->on_change = [this] { + m_layer_name = m_name_textbox->text(); + }; + + auto& width_label = main_widget.add("Width:"); + width_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); + + auto& width_spinbox = main_widget.add(); + + auto& height_label = main_widget.add("Height:"); + height_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); + + auto& height_spinbox = main_widget.add(); + + auto& button_container = main_widget.add(); + button_container.set_layout(); + + auto& ok_button = button_container.add("OK"); + ok_button.on_click = [this](auto) { + done(ExecOK); + }; + + auto& cancel_button = button_container.add("Cancel"); + cancel_button.on_click = [this](auto) { + done(ExecCancel); + }; + + width_spinbox.on_change = [this](int value) { + m_layer_size.set_width(value); + }; + + height_spinbox.on_change = [this](int value) { + m_layer_size.set_height(value); + }; + + width_spinbox.set_range(0, 16384); + height_spinbox.set_range(0, 16384); + + width_spinbox.set_value(suggested_size.width()); + height_spinbox.set_value(suggested_size.height()); +} + +} diff --git a/Applications/PaintBrush/CreateNewLayerDialog.h b/Applications/PaintBrush/CreateNewLayerDialog.h new file mode 100644 index 0000000000..7918484862 --- /dev/null +++ b/Applications/PaintBrush/CreateNewLayerDialog.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +namespace PaintBrush { + +class CreateNewLayerDialog final : public GUI::Dialog { + C_OBJECT(CreateNewLayerDialog); +public: + const Gfx::Size& layer_size() const { return m_layer_size; } + const String& layer_name() const { return m_layer_name; } + +private: + CreateNewLayerDialog(const Gfx::Size& suggested_size, GUI::Window* parent_window); + + Gfx::Size m_layer_size; + String m_layer_name; + + RefPtr m_name_textbox; +}; + +} diff --git a/Applications/PaintBrush/Makefile b/Applications/PaintBrush/Makefile index 9a93358905..54cec5e315 100644 --- a/Applications/PaintBrush/Makefile +++ b/Applications/PaintBrush/Makefile @@ -1,5 +1,6 @@ OBJS = \ BucketTool.o \ + CreateNewLayerDialog.o \ EllipseTool.o \ EraseTool.o \ Image.o \ diff --git a/Applications/PaintBrush/main.cpp b/Applications/PaintBrush/main.cpp index 606bae7645..2eac0f0b9a 100644 --- a/Applications/PaintBrush/main.cpp +++ b/Applications/PaintBrush/main.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "CreateNewLayerDialog.h" #include "Image.h" #include "ImageEditor.h" #include "Layer.h" @@ -122,6 +123,20 @@ int main(int argc, char** argv) return IterationDecision::Continue; }); + auto& layer_menu = menubar->add_menu("Layer"); + layer_menu.add_action(GUI::Action::create("Create new layer...", { Mod_Ctrl | Mod_Shift, Key_N }, [&](auto&) { + auto dialog = PaintBrush::CreateNewLayerDialog::construct(image_editor.image()->size(), window); + if (dialog->exec() == GUI::Dialog::ExecOK) { + auto layer = PaintBrush::Layer::create_with_size(dialog->layer_size(), dialog->layer_name()); + if (!layer) { + GUI::MessageBox::show_error(String::format("Unable to create layer with size %s", dialog->size().to_string().characters())); + return; + } + image_editor.image()->add_layer(layer.release_nonnull()); + image_editor.layers_did_change(); + } + }, window)); + auto& help_menu = menubar->add_menu("Help"); help_menu.add_action(GUI::Action::create("About", [&](auto&) { GUI::AboutDialog::show("PaintBrush", Gfx::Bitmap::load_from_file("/res/icons/32x32/app-paintbrush.png"), window);