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 }