File indexing completed on 2024-05-12 17:11:41
0001 #include "itemeditor.h" 0002 0003 #include <QDebug> 0004 #include <QGraphicsPixmapItem> 0005 #include <QMenu> 0006 #include <QMouseEvent> 0007 0008 #include "canvasfield.h" 0009 #include "charactersheet/controllers/fieldcontroller.h" 0010 #include "controllers/editorcontroller.h" 0011 0012 QList<FieldController*> cleanSelection(const QList<QGraphicsItem*>& items, bool& locked, bool& allSame) 0013 { 0014 QList<FieldController*> res; 0015 0016 auto func= [](QGraphicsItem* item) { 0017 auto field= dynamic_cast<CanvasField*>(item); 0018 if(nullptr == field) 0019 return false; 0020 return static_cast<bool>(field->flags() & QGraphicsItem::ItemIsMovable); 0021 }; 0022 0023 allSame= std::all_of(std::begin(items), std::end(items), [](QGraphicsItem* item) { 0024 auto field= dynamic_cast<CanvasField*>(item); 0025 if(nullptr == field) 0026 return false; 0027 return static_cast<bool>(field->flags() & QGraphicsItem::ItemIsMovable); 0028 }); 0029 0030 if(!items.isEmpty()) 0031 locked= func(items.first()); 0032 else 0033 locked= false; 0034 0035 std::transform(std::begin(items), std::end(items), std::back_inserter(res), 0036 [](QGraphicsItem* item) -> FieldController* { 0037 auto field= dynamic_cast<CanvasField*>(item); 0038 if(!field) 0039 return nullptr; 0040 0041 return field->controller(); 0042 }); 0043 0044 res.removeAll(nullptr); 0045 0046 return res; 0047 } 0048 0049 ItemEditor::ItemEditor(QWidget* parent) : QGraphicsView(parent) 0050 { 0051 setAcceptDrops(true); 0052 setViewportUpdateMode(QGraphicsView::FullViewportUpdate); 0053 setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform); 0054 setRubberBandSelectionMode(Qt::IntersectsItemBoundingRect); 0055 setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing); 0056 setAlignment((Qt::AlignLeft | Qt::AlignTop)); 0057 0058 m_fitInView.reset(new QAction(tr("Fit the view"))); 0059 m_fitInView->setCheckable(true); 0060 0061 m_lockItem.reset(new QAction(tr("Lock item"))); 0062 m_lockItem->setCheckable(true); 0063 m_alignOnY.reset(new QAction(tr("Align on Y"))); 0064 m_alignOnX.reset(new QAction(tr("Align on X"))); 0065 m_sameWidth.reset(new QAction(tr("Same Width"))); 0066 m_sameHeight.reset(new QAction(tr("Same Height"))); 0067 m_dupplicate.reset(new QAction(tr("Dupplicate"))); 0068 m_verticalEquaDistance.reset(new QAction(tr("Vertical equidistribution"))); 0069 m_horizontalEquaDistance.reset(new QAction(tr("Horizontal equidistribution"))); 0070 } 0071 0072 void ItemEditor::setController(EditorController* editCtrl) 0073 { 0074 m_ctrl= editCtrl; 0075 0076 connect(m_ctrl, &EditorController::dataChanged, this, [this]() { invalidateScene(); }); 0077 connect(m_lockItem.get(), &QAction::triggered, this, [this](bool checked) { 0078 std::for_each(std::begin(m_selection), std::end(m_selection), [checked](FieldController* ctrl) { 0079 if(!ctrl) 0080 return; 0081 ctrl->setReadOnly(checked); 0082 }); 0083 }); 0084 connect(m_fitInView.get(), &QAction::triggered, this, [this](bool checked) { 0085 if(checked) 0086 { 0087 const QPixmap& pix= m_ctrl->backgroundFromIndex(m_ctrl->currentPage()); 0088 fitInView(QRectF(pix.rect()), Qt::KeepAspectRatioByExpanding); 0089 } 0090 else 0091 { 0092 fitInView(rect()); 0093 } 0094 }); 0095 connect(m_alignOnY.get(), &QAction::triggered, this, 0096 [this]() { m_ctrl->alignOn(false, m_selection, m_underCursorItem); }); 0097 connect(m_alignOnX.get(), &QAction::triggered, this, 0098 [this]() { m_ctrl->alignOn(true, m_selection, m_underCursorItem); }); 0099 0100 connect(m_sameWidth.get(), &QAction::triggered, this, 0101 [this]() { m_ctrl->sameGeometry(true, m_selection, m_underCursorItem); }); 0102 connect(m_sameHeight.get(), &QAction::triggered, this, 0103 [this]() { m_ctrl->sameGeometry(false, m_selection, m_underCursorItem); }); 0104 0105 connect(m_verticalEquaDistance.get(), &QAction::triggered, this, 0106 [this]() { m_ctrl->spreadItemEqualy(m_selection, false); }); 0107 connect(m_horizontalEquaDistance.get(), &QAction::triggered, this, 0108 [this]() { m_ctrl->spreadItemEqualy(m_selection, true); }); 0109 0110 connect(m_ctrl, &EditorController::currentPageChanged, this, [this]() { 0111 if(m_ctrl->currentCanvas()) 0112 setScene(m_ctrl->currentCanvas()); 0113 }); 0114 connect(m_ctrl, &EditorController::pageCountChanged, this, [this]() { 0115 auto c= m_ctrl->currentCanvas(); 0116 if(!c) 0117 return; 0118 0119 setScene(c); 0120 }); 0121 0122 if(m_ctrl->currentCanvas()) 0123 setScene(m_ctrl->currentCanvas()); 0124 } 0125 0126 bool ItemEditor::handle() const 0127 { 0128 return m_handle; 0129 } 0130 0131 void ItemEditor::setHandle(bool handle) 0132 { 0133 m_handle= handle; 0134 } 0135 0136 void ItemEditor::mousePressEvent(QMouseEvent* event) 0137 { 0138 if(!m_handle) 0139 { 0140 setDragMode(QGraphicsView::NoDrag); 0141 event->ignore(); 0142 // qDebug() << "mousePressEvent inside not handle" << event->isAccepted() << scene(); 0143 QGraphicsView::mousePressEvent(event); 0144 return; 0145 } 0146 0147 if(event->button() == Qt::RightButton) 0148 return; 0149 0150 if(event->button() == Qt::LeftButton) 0151 { 0152 QList<QGraphicsItem*> list= items(event->pos()); 0153 0154 list.erase(std::remove_if(list.begin(), list.end(), 0155 [](QGraphicsItem* item) { 0156 static QGraphicsPixmapItem pix; 0157 return item->type() == pix.type(); 0158 }), 0159 list.end()); 0160 0161 if(!list.isEmpty()) 0162 { 0163 setDragMode(QGraphicsView::NoDrag); 0164 } 0165 else 0166 { 0167 setDragMode(QGraphicsView::RubberBandDrag); 0168 } 0169 } 0170 // qDebug() << "mousePressEvent inside end "; 0171 0172 QGraphicsView::mousePressEvent(event); 0173 } 0174 0175 void ItemEditor::mouseReleaseEvent(QMouseEvent* event) 0176 { 0177 QGraphicsView::mouseReleaseEvent(event); 0178 if(dragMode() == QGraphicsView::ScrollHandDrag) 0179 { 0180 setDragMode(QGraphicsView::RubberBandDrag); 0181 } 0182 } 0183 0184 void ItemEditor::contextMenuEvent(QContextMenuEvent* event) 0185 { 0186 m_selection.clear(); 0187 auto pos= event->pos(); 0188 QMenu menu(this); 0189 0190 if(!scene()) 0191 return; 0192 0193 bool allSame; 0194 bool locked; 0195 m_selection= cleanSelection(scene()->selectedItems(), locked, allSame); 0196 auto list= cleanSelection(items(pos), locked, allSame); 0197 0198 if(!list.isEmpty()) 0199 m_underCursorItem= list.first(); 0200 0201 /*for(auto item : list) 0202 { 0203 auto field= dynamic_cast<CanvasField*>(item); 0204 if(nullptr != field) 0205 { 0206 field->setMenu(menu); 0207 menu.addSeparator(); 0208 } 0209 }*/ 0210 menu.addAction(m_fitInView.get()); 0211 menu.addSeparator(); 0212 menu.addAction(m_lockItem.get()); 0213 if(allSame) 0214 m_lockItem->setChecked(locked); 0215 else 0216 m_lockItem->setChecked(false); 0217 menu.addAction(m_alignOnX.get()); 0218 menu.addAction(m_alignOnY.get()); 0219 menu.addAction(m_sameWidth.get()); 0220 menu.addAction(m_sameHeight.get()); 0221 menu.addAction(m_verticalEquaDistance.get()); 0222 menu.addAction(m_horizontalEquaDistance.get()); 0223 menu.addSeparator(); 0224 menu.addAction(m_dupplicate.get()); 0225 0226 menu.exec(QCursor::pos()); 0227 }