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