Warning, file /graphics/glaxnimate/src/gui/tools/base.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 "base.hpp"
0008 
0009 #include <QGraphicsSceneMouseEvent>
0010 
0011 #include "graphics/item_data.hpp"
0012 #include "model/shapes/precomp_layer.hpp"
0013 #include "model/shapes/text.hpp"
0014 
0015 
0016 using namespace glaxnimate::gui;
0017 
0018 void tools::MouseEvent::forward_to_scene() const
0019 {
0020     QEvent::Type type;
0021     switch ( event->type() )
0022     {
0023         case QEvent::MouseButtonPress:
0024             type = QEvent::GraphicsSceneMousePress;
0025             break;
0026         case QEvent::MouseMove:
0027             type = QEvent::GraphicsSceneMouseMove;
0028             break;
0029         case QEvent::MouseButtonRelease:
0030             type = QEvent::GraphicsSceneMouseRelease;
0031             break;
0032         case QEvent::MouseButtonDblClick:
0033             type = QEvent::GraphicsSceneMouseDoubleClick;
0034             break;
0035         default:
0036             return;
0037     }
0038     
0039     QGraphicsSceneMouseEvent mouse_event(type);
0040     mouse_event.setWidget(view->viewport());
0041     mouse_event.setButtonDownScenePos(press_button, press_scene_pos);
0042     mouse_event.setButtonDownScreenPos(press_button, press_screen_pos);
0043     mouse_event.setScenePos(scene_pos);
0044 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
0045     mouse_event.setScreenPos(event->globalPosition().toPoint());
0046 #else
0047     mouse_event.setScreenPos(event->screenPos().toPoint());
0048 #endif
0049     mouse_event.setLastScenePos(last_scene_pos);
0050     mouse_event.setLastScreenPos(last_screen_pos);
0051     mouse_event.setButtons(event->buttons());
0052     mouse_event.setButton(event->button());
0053     mouse_event.setModifiers(event->modifiers());
0054     mouse_event.setSource(event->source());
0055     mouse_event.setFlags(event->flags());
0056     mouse_event.setAccepted(false);
0057     QCoreApplication::sendEvent(scene, &mouse_event);
0058     
0059     event->setAccepted(mouse_event.isAccepted());
0060 }
0061 
0062 tools::Tool::UnderMouse tools::Tool::under_mouse(const tools::MouseEvent& event, bool only_selectable, SelectionMode mode) const
0063 {
0064     UnderMouse ret;
0065     for ( auto item : event.scene->items(event.scene_pos, Qt::IntersectsItemShape, Qt::DescendingOrder, event.view->viewportTransform()) )
0066     {
0067         if ( !(item->flags() & (QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsFocusable)) )
0068             continue;
0069 
0070         if ( auto node = event.scene->item_to_node(item) )
0071         {
0072             if ( !only_selectable || node->docnode_selectable() )
0073             {
0074                 auto dnitem = static_cast<graphics::DocumentNodeGraphicsItem*>(item);
0075                 if ( !only_selectable || dnitem->selection_mode() >= mode )
0076                     ret.nodes.push_back(dnitem);
0077             }
0078         }
0079         else if ( !ret.handle && item->data(graphics::ItemData::HandleRole).toInt() )
0080         {
0081             ret.handle = static_cast<graphics::MoveHandle*>(item);
0082         }
0083     }
0084 
0085 //     std::stable_sort(ret.nodes.begin(), ret.nodes.end(),
0086 //         [](graphics::DocumentNodeGraphicsItem* a, graphics::DocumentNodeGraphicsItem* b){
0087 //             return a->selection_mode() < b->selection_mode();
0088 //         }
0089 //     );
0090 
0091     return ret;
0092 }
0093 
0094 graphics::MoveHandle * tools::Tool::handle_under_mouse(const tools::MouseEvent& event) const
0095 {
0096 
0097     for ( auto item : event.scene->items(event.scene_pos, Qt::IntersectsItemShape, Qt::DescendingOrder, event.view->viewportTransform()) )
0098     {
0099         if ( !(item->flags() & (QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsFocusable)) )
0100             continue;
0101 
0102         if ( item->data(graphics::ItemData::HandleRole).toInt() )
0103             return static_cast<graphics::MoveHandle*>(item);
0104     }
0105 
0106     return nullptr;
0107 }
0108 
0109 void tools::Tool::edit_clicked(const tools::MouseEvent& event)
0110 {
0111     auto mode = event.modifiers() & Qt::ControlModifier ? SelectionMode::Shape : SelectionMode::Group;
0112     auto clicked_on = under_mouse(event, true, mode).nodes;
0113 
0114     if ( !clicked_on.empty() )
0115     {
0116         auto selected = clicked_on[0]->node();
0117         if ( auto precomp = selected->cast<model::PreCompLayer>() )
0118         {
0119             if ( precomp->composition.get() )
0120                 event.window->set_current_composition(precomp->composition.get());
0121         }
0122         else if ( selected->is_instance<model::TextShape>() )
0123         {
0124             event.scene->user_select({selected}, graphics::DocumentScene::Replace);
0125             event.window->switch_tool(Registry::instance().tool("text"));
0126         }
0127         else
0128         {
0129             event.scene->user_select({selected}, graphics::DocumentScene::Replace);
0130             event.window->switch_tool(Registry::instance().tool("edit"));
0131         }
0132     }
0133 }
0134 
0135 void tools::Tool::on_deselected(graphics::DocumentScene* scene, model::VisualNode* node)
0136 {
0137     scene->hide_editors(node, true, true);
0138 }
0139 
0140 QAction* tools::Tool::get_action()
0141 {
0142     if ( !action )
0143     {
0144         action = new QAction();
0145         action->setCheckable(true);
0146         action->setIcon(icon());
0147         action->setData(QVariant::fromValue(this));
0148     }
0149     return action;
0150 }
0151 
0152 ScalableButton* tools::Tool::get_button()
0153 {
0154     if ( !button )
0155     {
0156         button = new ScalableButton();
0157 
0158         button->setIcon(icon());
0159         button->setCheckable(true);
0160         button->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
0161 
0162         QObject::connect(action, &QAction::toggled, button, &QAbstractButton::setChecked);
0163         QObject::connect(button, &QAbstractButton::clicked, action, &QAction::trigger);
0164     }
0165 
0166     return button;
0167 }
0168 
0169 QWidget* tools::Tool::get_settings_widget()
0170 {
0171     if ( !settings_widget )
0172     {
0173         settings_widget = on_create_widget();
0174     }
0175 
0176     return settings_widget;
0177 }
0178 
0179 void tools::Tool::retranslate()
0180 {
0181     if ( action )
0182     {
0183         action->setText(name());
0184         action->setToolTip(tooltip());
0185 #ifndef Q_OS_ANDROID
0186         action->setShortcut(key_sequence());
0187 #endif
0188     }
0189 
0190     if ( button )
0191     {
0192         button->setText(name());
0193         button->setToolTip(i18n("%1 (%2)", name(), key_sequence().toString()));
0194     }
0195 
0196     on_translate();
0197 }