File indexing completed on 2024-04-28 05:38:12
0001 /*************************************************************************** 0002 * Copyright (C) 2010 by Renaud Guezennec * 0003 * * 0004 * * 0005 * rolisteam is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 #include "visualitem.h" 0021 #include <QActionGroup> 0022 #include <QCursor> 0023 #include <QDebug> 0024 #include <QGraphicsSceneHoverEvent> 0025 #include <QGuiApplication> 0026 #include <QKeyEvent> 0027 #include <QMenu> 0028 #include <QUuid> 0029 #include <cmath> 0030 0031 #include <QGraphicsScene> 0032 0033 #include "controller/item_controllers/visualitemcontroller.h" 0034 #include "controller/view_controller/vectorialmapcontroller.h" 0035 0036 QColor VisualItem::m_highlightColor= QColor(Qt::red); 0037 QColor VisualItem::m_selectedColor= QColor(Qt::blue); 0038 int VisualItem::m_highlightWidth= 6; 0039 0040 QStringList VisualItem::s_type2NameList 0041 = QStringList() << QObject::tr("Path") << QObject::tr("Line") << QObject::tr("Ellipse") << QObject::tr("Character") 0042 << QObject::tr("Text") << QObject::tr("Rect") << QObject::tr("Rule") << QObject::tr("Image"); 0043 0044 VisualItem::VisualItem(vmap::VisualItemController* ctrl) : QGraphicsObject(), m_ctrl(ctrl) 0045 { 0046 if(!m_ctrl) 0047 return; 0048 0049 connect(m_ctrl, &vmap::VisualItemController::posChanged, this, [this]() { setPos(m_ctrl->pos()); }); 0050 connect(m_ctrl, &vmap::VisualItemController::removeItem, this, 0051 [this]() 0052 { 0053 auto sceneP = scene(); 0054 if(sceneP) 0055 sceneP->removeItem(this); 0056 deleteLater(); 0057 }); 0058 connect(m_ctrl, &vmap::VisualItemController::destroyed, this, 0059 [this]() 0060 { 0061 auto sceneP = scene(); 0062 if(sceneP) 0063 sceneP->removeItem(this); 0064 deleteLater(); 0065 }); 0066 auto func= [this]() 0067 { 0068 if(m_ctrl->editable()) 0069 m_ctrl->setPos(pos()); 0070 }; 0071 connect(this, &VisualItem::xChanged, this, func); 0072 connect(this, &VisualItem::yChanged, this, func); 0073 0074 // connect(this, &VisualItem::rotationChanged, this, [this]() { m_ctrl->setRotation(rotation()); }); 0075 0076 connect(m_ctrl, &vmap::VisualItemController::colorChanged, this, [this]() { update(); }); 0077 connect(m_ctrl, &vmap::VisualItemController::editableChanged, this, &VisualItem::updateItemFlags); 0078 connect(m_ctrl, &vmap::VisualItemController::rotationChanged, this, [this]() { setRotation(m_ctrl->rotation()); }); 0079 connect(m_ctrl, &vmap::VisualItemController::selectedChanged, this, [this](bool b) { setSelected(b); }); 0080 connect(m_ctrl, &vmap::VisualItemController::selectableChanged, this, &VisualItem::updateItemFlags); 0081 0082 connect(m_ctrl, &vmap::VisualItemController::visibleChanged, this, &VisualItem::evaluateVisible); 0083 connect(m_ctrl, &vmap::VisualItemController::visibilityChanged, this, &VisualItem::evaluateVisible); 0084 connect(m_ctrl, &vmap::VisualItemController::opacityChanged, this, [this]() { setOpacity(m_ctrl->opacity()); }); 0085 connect(m_ctrl, &vmap::VisualItemController::layerChanged, this, 0086 [this]() { setOpacity(m_ctrl->layer() == Core::Layer::GAMEMASTER_LAYER ? 0.5 : 1.0); }); 0087 0088 init(); 0089 0090 connect(m_ctrl, &vmap::VisualItemController::zOrderChanged, this, [this](qreal z) { setZValue(z); }); 0091 0092 setPos(m_ctrl->pos()); 0093 evaluateVisible(); 0094 0095 updateItemFlags(); 0096 setOpacity(m_ctrl->layer() == Core::Layer::GAMEMASTER_LAYER ? 0.5 : 1.0); 0097 } 0098 0099 VisualItem::~VisualItem() {} 0100 0101 void VisualItem::evaluateVisible() 0102 { 0103 // qDebug() << "debug item visibility: Item is visible:" << m_ctrl->visible() << "local is gm:" << 0104 // m_ctrl->localIsGM() 0105 // << "visiblitiy:" << m_ctrl->visibility() << m_ctrl->tool() << m_ctrl->itemType(); 0106 auto localIsGM= m_ctrl->localIsGM(); 0107 auto visibleFromPermission= localIsGM || m_ctrl->visibility() != Core::HIDDEN; 0108 auto visibleLayer= localIsGM || m_ctrl->layer() != Core::Layer::GAMEMASTER_LAYER; 0109 setVisible(m_ctrl->visible() && visibleFromPermission && visibleLayer); 0110 } 0111 void VisualItem::init() 0112 { 0113 0114 setAcceptHoverEvents(true); 0115 setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true); 0116 /*QActionGroup* group= new QActionGroup(this); 0117 m_putGroundLayer= new QAction(m_ctrl->getLayerText(Core::Layer::GROUND), this); 0118 m_putGroundLayer->setData(static_cast<int>(Core::Layer::GROUND)); 0119 m_putObjectLayer= new QAction(m_ctrl->getLayerText(Core::Layer::OBJECT), this); 0120 m_putObjectLayer->setData(static_cast<int>(Core::Layer::OBJECT)); 0121 m_putCharacterLayer= new QAction(m_ctrl->getLayerText(Core::Layer::CHARACTER_LAYER), this); 0122 m_putCharacterLayer->setData(static_cast<int>(Core::Layer::CHARACTER_LAYER)); 0123 0124 m_putGameMasterLayer= new QAction(m_ctrl->getLayerText(Core::Layer::GAMEMASTER_LAYER), this); 0125 m_putGameMasterLayer->setData(static_cast<int>(Core::Layer::GAMEMASTER_LAYER)); 0126 0127 m_putGroundLayer->setCheckable(true); 0128 m_putObjectLayer->setCheckable(true); 0129 m_putCharacterLayer->setCheckable(true); 0130 m_putGameMasterLayer->setCheckable(true); 0131 0132 m_putGroundLayer->setChecked(true); 0133 0134 group->addAction(m_putGroundLayer); 0135 group->addAction(m_putObjectLayer); 0136 group->addAction(m_putCharacterLayer); 0137 group->addAction(m_putGameMasterLayer);*/ 0138 } 0139 vmap::VisualItemController* VisualItem::controller() const 0140 { 0141 return m_ctrl; 0142 } 0143 0144 vmap::VisualItemController::ItemType VisualItem::getType() const 0145 { 0146 return m_ctrl->itemType(); 0147 } 0148 0149 void VisualItem::updateItemFlags() 0150 { 0151 GraphicsItemFlags flags= QGraphicsItem::ItemIsFocusable; 0152 Qt::MouseButtons buttons= Qt::NoButton; 0153 0154 if(m_ctrl->editable()) 0155 { 0156 flags 0157 |= QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges | QGraphicsItem::ItemIsMovable; 0158 buttons= Qt::AllButtons; 0159 } 0160 0161 setAcceptedMouseButtons(buttons); 0162 setFlags(flags); 0163 0164 for(auto& itemChild : m_children) 0165 { 0166 itemChild->setEditableItem(m_ctrl->editable()); 0167 } 0168 } 0169 0170 QColor VisualItem::color() const 0171 { 0172 return m_ctrl->color(); 0173 } 0174 0175 void VisualItem::setColor(QColor color) 0176 { 0177 m_ctrl->setColor(color); 0178 } 0179 0180 void VisualItem::mousePressEvent(QGraphicsSceneMouseEvent* event) 0181 { 0182 QGraphicsItem::mousePressEvent(event); 0183 update(); 0184 } 0185 void VisualItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event) 0186 { 0187 QGraphicsItem::mouseMoveEvent(event); 0188 update(); 0189 } 0190 void VisualItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) 0191 { 0192 QGraphicsItem::mouseReleaseEvent(event); 0193 update(); 0194 endOfGeometryChange(ChildPointItem::Moving); 0195 } 0196 0197 QVariant VisualItem::itemChange(GraphicsItemChange change, const QVariant& value) 0198 { 0199 if(change == ItemPositionChange) 0200 { 0201 QPointF newPos= computeClosePoint(value.toPointF()); 0202 if(newPos != value.toPointF()) 0203 { 0204 return newPos; 0205 } 0206 } 0207 return QGraphicsItem::itemChange(change, value); 0208 } 0209 0210 QString VisualItem::uuid() const 0211 { 0212 return m_ctrl ? m_ctrl->uuid() : QString(); 0213 } 0214 0215 QPointF VisualItem::computeClosePoint(QPointF pos) 0216 { 0217 if(Qt::AltModifier & QGuiApplication::keyboardModifiers()) 0218 { 0219 int size= m_ctrl->gridSize(); 0220 pos.setX(std::round(pos.x() / size) * size); 0221 pos.setY(std::round(pos.y() / size) * size); 0222 } 0223 return pos; 0224 } 0225 void VisualItem::keyPressEvent(QKeyEvent* event) 0226 { 0227 if((event->key() == Qt::Key_Delete) && (isSelected()) && canBeMoved()) 0228 { 0229 // m_ctrl->rem 0230 } 0231 else if((event->key() == Qt::Key_C) && (event->modifiers() == Qt::ControlModifier) && (isSelected())) 0232 { 0233 // emit duplicateItem(this); 0234 event->accept(); 0235 } 0236 QGraphicsItem::keyPressEvent(event); 0237 } 0238 0239 void VisualItem::resizeContents(const QRectF& rect, int pointId, Core::TransformType transformType) 0240 { 0241 /* if(!rect.isValid() || isHoldSize()) 0242 { 0243 return; 0244 } 0245 prepareGeometryChange(); 0246 auto width= m_ctrl->rect().width(); 0247 auto height= m_ctrl->rect().height(); 0248 // sendRectGeometryMsg(); 0249 m_resizing= true; 0250 m_rect= rect; 0251 if(transformType == VisualItem::KeepRatio) 0252 { 0253 auto hfw= height * rect.width() / width; 0254 if(hfw > 1) 0255 { 0256 m_rect.setTop(-hfw / 2); 0257 m_rect.setHeight(hfw); 0258 } 0259 } 0260 0261 updateChildPosition();*/ 0262 } 0263 void VisualItem::updateChildPosition() {} 0264 0265 void VisualItem::addPromoteItemMenu(QMenu* menu) 0266 { 0267 for(auto& type : m_promoteTypeList) 0268 { 0269 QAction* action= menu->addAction(s_type2NameList[type]); 0270 action->setData(type); 0271 connect(action, SIGNAL(triggered()), this, SLOT(promoteItem())); 0272 } 0273 } 0274 void VisualItem::promoteItem() 0275 { 0276 QAction* act= qobject_cast<QAction*>(sender()); 0277 if(nullptr != act) 0278 { 0279 auto type= static_cast<vmap::VisualItemController::ItemType>(act->data().toInt()); 0280 emit promoteItemTo(this, type); 0281 } 0282 } 0283 0284 void VisualItem::addActionContextMenu(QMenu& menu) {} 0285 0286 bool VisualItem::hasFocusOrChild() 0287 { 0288 if(!m_ctrl) 0289 return false; 0290 0291 if(!m_ctrl->editable()) 0292 return false; 0293 0294 auto result= isSelected(); 0295 for(auto const& child : qAsConst(m_children)) 0296 { 0297 if(nullptr == child) 0298 continue; 0299 0300 if(child->isSelected()) 0301 { 0302 result= true; 0303 } 0304 } 0305 return result; 0306 } 0307 0308 bool VisualItem::isLocal() const 0309 { 0310 return !m_ctrl->remote(); 0311 } 0312 0313 void VisualItem::endOfGeometryChange(ChildPointItem::Change change) 0314 { 0315 if(change == ChildPointItem::Resizing) 0316 { 0317 auto oldScenePos= scenePos(); 0318 setTransformOriginPoint(m_ctrl->rect().center()); 0319 auto newScenePos= scenePos(); 0320 auto oldPos= pos(); 0321 m_ctrl->setPos(QPointF(oldPos.x() + (oldScenePos.x() - newScenePos.x()), 0322 oldPos.y() + (oldScenePos.y() - newScenePos.y()))); 0323 } 0324 m_ctrl->endGeometryChange(); 0325 } 0326 0327 void VisualItem::setModifiers(Qt::KeyboardModifiers modifiers) 0328 { 0329 Q_UNUSED(modifiers) 0330 /// @brief must be implemented in child classes. 0331 return; 0332 } 0333 VisualItem* VisualItem::promoteTo(vmap::VisualItemController::ItemType type) 0334 { 0335 Q_UNUSED(type) 0336 /// @brief must be implemented in child classes. 0337 return nullptr; 0338 } 0339 0340 void VisualItem::setChildrenVisible(bool b) 0341 { 0342 if(!b) 0343 { 0344 std::for_each(std::begin(m_children), std::end(m_children), 0345 [](ChildPointItem* item) { item->setVisible(false); }); 0346 return; 0347 } 0348 0349 if(!canBeMoved()) 0350 return; 0351 0352 for(auto& item : m_children) 0353 { 0354 bool isVision= item->control() == ChildPointItem::Control::Vision; 0355 bool hasFog= m_ctrl->visibility() == Core::FOGOFWAR; 0356 bool isGeometry= item->control() == ChildPointItem::Control::Geometry; 0357 0358 item->setVisible(isGeometry || (isVision && hasFog)); 0359 } 0360 } 0361 0362 bool VisualItem::canBeMoved() const 0363 { 0364 return m_ctrl->editable(); 0365 } 0366 0367 QColor VisualItem::getHighlightColor() 0368 { 0369 return m_highlightColor; 0370 } 0371 0372 void VisualItem::setHighlightColor(const QColor& highlightColor) 0373 { 0374 m_highlightColor= highlightColor; 0375 } 0376 0377 int VisualItem::getHighlightWidth() 0378 { 0379 return m_highlightWidth; 0380 } 0381 0382 void VisualItem::setHighlightWidth(int highlightWidth) 0383 { 0384 m_highlightWidth= highlightWidth; 0385 } 0386 0387 void VisualItem::setSize(QSizeF size) 0388 { 0389 updateChildPosition(); 0390 update(); 0391 }