Warning, file /graphics/glaxnimate/src/gui/tools/fill_tool.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #include <QPointer>
0008 
0009 #include "base.hpp"
0010 #include "widgets/tools/fill_tool_widget.hpp"
0011 
0012 #include "model/shapes/fill.hpp"
0013 #include "model/shapes/stroke.hpp"
0014 #include "command/undo_macro_guard.hpp"
0015 #include "command/shape_commands.hpp"
0016 
0017 
0018 namespace glaxnimate::gui::tools {
0019 
0020 class FillTool : public Tool
0021 {
0022 public:
0023     QString id() const override { return "fill"; }
0024     QIcon icon() const override { return QIcon::fromTheme("fill-color"); }
0025     QString name() const override { return i18n("Fill"); }
0026     QKeySequence key_sequence() const override { return QKeySequence(i18n("F8"), QKeySequence::PortableText); }
0027     static int static_group() noexcept { return Registry::Style; }
0028     int group() const noexcept override { return static_group(); }
0029 
0030     void mouse_move(const MouseEvent& event) override
0031     {
0032         auto um = under_mouse(event, true, SelectionMode::Shape);
0033         highlight = nullptr;
0034         for ( auto node : um.nodes )
0035         {
0036             if ( auto path = node->node()->cast<model::Shape>() )
0037             {
0038                 if ( !event.scene->has_editors(path) )
0039                     highlight = path;
0040                 break;
0041             }
0042         }
0043     }
0044 
0045     void mouse_release(const MouseEvent& event) override
0046     {
0047         if ( !highlight )
0048             return;
0049 
0050         auto document = event.window->document();
0051         model::ShapeListProperty* prop = highlight->owner();
0052 
0053         command::UndoMacroGuard guard(i18n("Apply Style"), document);
0054 
0055         bool add_fill = widget()->fill();
0056         bool add_stroke = widget()->stroke();
0057 
0058         for ( const auto& se : *prop )
0059         {
0060             if ( add_fill )
0061             {
0062                 if ( auto fill = se->cast<model::Fill>() )
0063                 {
0064                     fill->use.set_undoable(QVariant::fromValue((model::BrushStyle*)nullptr));
0065                     fill->color.set_undoable(event.window->current_color());
0066                     add_fill = false;
0067                     continue;
0068                 }
0069             }
0070 
0071             if ( add_stroke )
0072             {
0073                 if ( auto stroke = se->cast<model::Stroke>() )
0074                 {
0075                     stroke->use.set_undoable(QVariant::fromValue((model::BrushStyle*)nullptr));
0076                     stroke->set_pen_style_undoable(event.window->current_pen_style());
0077                     add_stroke = false;
0078                     continue;
0079                 }
0080             }
0081         }
0082 
0083         int index = prop->index_of(highlight.data());
0084 
0085         if ( add_fill )
0086         {
0087             auto fill = std::make_unique<model::Fill>(document);
0088             document->set_best_name(fill.get(), i18n("%1 Fill", highlight->name.get()));
0089             fill->color.set(event.window->current_color());
0090 
0091             document->undo_stack().push(
0092                 new command::AddShape(prop, std::move(fill), index)
0093             );
0094         }
0095 
0096         if ( add_stroke )
0097         {
0098             auto stroke = std::make_unique<model::Stroke>(document);
0099             document->set_best_name(stroke.get(), i18n("%1 Stroke", highlight->name.get()));
0100             stroke->set_pen_style(event.window->current_pen_style());
0101 
0102             document->undo_stack().push(
0103                 new command::AddShape(prop, std::move(stroke), index)
0104             );
0105         }
0106 
0107         event.window->set_current_document_node(highlight->docnode_visual_parent());
0108 
0109         highlight = nullptr;
0110     }
0111 
0112     void key_press(const KeyEvent& event) override
0113     {
0114         if ( event.key() == Qt::Key_Shift )
0115         {
0116             widget()->swap_fill_color();
0117             event.repaint();
0118         }
0119     }
0120     void key_release(const KeyEvent& event) override
0121     {
0122         if ( event.key() == Qt::Key_Shift )
0123         {
0124             widget()->swap_fill_color();
0125             event.repaint();
0126         }
0127     }
0128 
0129     QCursor cursor() override { return Qt::CrossCursor; }
0130 
0131     void mouse_press(const MouseEvent& event) override { Q_UNUSED(event); }
0132     void mouse_double_click(const MouseEvent& event) override { Q_UNUSED(event); }
0133 
0134     void paint(const PaintEvent& event) override
0135     {
0136         if ( highlight )
0137         {
0138             QPainterPath p;
0139             highlight->to_bezier(highlight->time()).add_to_painter_path(p);
0140             QTransform trans = highlight->transform_matrix(highlight->time()) * event.view->viewportTransform();
0141             p = trans.map(p);
0142             event.painter->setPen(widget()->stroke() ? event.window->current_pen_style() : Qt::NoPen);
0143             event.painter->setBrush(widget()->fill() ? event.window->current_color() : Qt::transparent);
0144             event.painter->drawPath(p);
0145         }
0146     }
0147 
0148     void enable_event(const Event&) override
0149     {
0150         highlight = nullptr;
0151     }
0152 
0153     void disable_event(const Event&) override
0154     {
0155         highlight = nullptr;
0156     }
0157 
0158 protected:
0159     QWidget* on_create_widget() override
0160     {
0161         return new FillToolWidget();
0162     }
0163 
0164     FillToolWidget* widget()
0165     {
0166         return static_cast<FillToolWidget*>(get_settings_widget());
0167     }
0168 
0169 private:
0170     QPointer<model::Shape> highlight;
0171 
0172     static Autoreg<FillTool> autoreg;
0173 };
0174 
0175 
0176 tools::Autoreg<tools::FillTool> tools::FillTool::autoreg{max_priority+1};
0177 
0178 } // namespace glaxnimate::gui::tools
0179