mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Drag drop works for objects
This commit is contained in:
parent
b26c874446
commit
8dc0682d81
@ -550,7 +550,7 @@ void MainWindow::loadObjectsTree()
|
||||
|
||||
//model
|
||||
objectsModel.setHorizontalHeaderLabels(QStringList() << tr("Type"));
|
||||
objectBrowser = new ObjectBrowser(this);
|
||||
objectBrowser = new ObjectBrowserProxyModel(this);
|
||||
objectBrowser->setSourceModel(&objectsModel);
|
||||
objectBrowser->setDynamicSortFilter(false);
|
||||
objectBrowser->setRecursiveFilteringEnabled(true);
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "resourceExtractor/ResourceConverter.h"
|
||||
|
||||
class CMap;
|
||||
class ObjectBrowser;
|
||||
class ObjectBrowserProxyModel;
|
||||
class CGObjectInstance;
|
||||
|
||||
namespace Ui
|
||||
@ -133,7 +133,7 @@ private:
|
||||
|
||||
private:
|
||||
Ui::MainWindow * ui;
|
||||
ObjectBrowser * objectBrowser = nullptr;
|
||||
ObjectBrowserProxyModel * objectBrowser = nullptr;
|
||||
QGraphicsScene * scenePreview;
|
||||
|
||||
QString filename;
|
||||
|
@ -303,7 +303,7 @@
|
||||
<widget class="QLineEdit" name="filter"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="treeView">
|
||||
<widget class="ObjectBrowser" name="treeView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
@ -319,8 +319,11 @@
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::NoDragDrop</enum>
|
||||
<enum>QAbstractItemView::DragOnly</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectItems</enum>
|
||||
@ -1206,6 +1209,11 @@
|
||||
<extends>QGraphicsView</extends>
|
||||
<header>mapview.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ObjectBrowser</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>objectbrowser.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "mainwindow.h"
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include "mapcontroller.h"
|
||||
#include "../lib/mapObjects/CObjectClassesHandler.h"
|
||||
|
||||
MinimapView::MinimapView(QWidget * parent):
|
||||
QGraphicsView(parent)
|
||||
@ -161,13 +162,7 @@ void MapView::mouseMoveEvent(QMouseEvent *mouseEvent)
|
||||
|
||||
if(sh.x || sh.y)
|
||||
{
|
||||
if(sc->selectionObjectsView.newObject)
|
||||
{
|
||||
sc->selectionObjectsView.shift = QPoint(tile.x, tile.y);
|
||||
sc->selectionObjectsView.selectObject(sc->selectionObjectsView.newObject);
|
||||
sc->selectionObjectsView.selectionMode = SelectionObjectsLayer::MOVEMENT;
|
||||
}
|
||||
else if(mouseEvent->buttons() & Qt::LeftButton)
|
||||
if(sc->selectionObjectsView.newObject && (mouseEvent->buttons() & Qt::LeftButton))
|
||||
{
|
||||
if(sc->selectionObjectsView.selectionMode == SelectionObjectsLayer::SELECTION)
|
||||
{
|
||||
@ -324,7 +319,7 @@ void MapView::mouseReleaseEvent(QMouseEvent *event)
|
||||
bool tab = false;
|
||||
if(sc->selectionObjectsView.selectionMode == SelectionObjectsLayer::MOVEMENT)
|
||||
{
|
||||
if(sc->selectionObjectsView.newObject)
|
||||
/*if(sc->selectionObjectsView.newObject)
|
||||
{
|
||||
QString errorMsg;
|
||||
if(controller->canPlaceObject(sc->level, sc->selectionObjectsView.newObject, errorMsg))
|
||||
@ -335,8 +330,8 @@ void MapView::mouseReleaseEvent(QMouseEvent *event)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
controller->commitObjectShift(sc->level);
|
||||
else*/
|
||||
controller->commitObjectShift(sc->level);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -355,6 +350,100 @@ void MapView::mouseReleaseEvent(QMouseEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
void MapView::dragEnterEvent(QDragEnterEvent * event)
|
||||
{
|
||||
if(!controller || !controller->map())
|
||||
return;
|
||||
|
||||
auto * sc = static_cast<MapScene*>(scene());
|
||||
if(!sc)
|
||||
return;
|
||||
|
||||
if(event->mimeData()->hasFormat("application/vcmi.object"))
|
||||
{
|
||||
auto encodedData = event->mimeData()->data("application/vcmi.object");
|
||||
QDataStream stream(&encodedData, QIODevice::ReadOnly);
|
||||
QJsonObject data;
|
||||
stream >> data;
|
||||
if(!data.empty())
|
||||
{
|
||||
auto preview = data["preview"];
|
||||
if(preview != QJsonValue::Undefined)
|
||||
{
|
||||
auto objId = data["id"].toInt();
|
||||
auto objSubId = data["subid"].toInt();
|
||||
auto templateId = data["template"].toInt();
|
||||
auto factory = VLC->objtypeh->getHandlerFor(objId, objSubId);
|
||||
auto templ = factory->getTemplates()[templateId];
|
||||
controller->discardObject(sc->level);
|
||||
controller->createObject(sc->level, factory->create(templ));
|
||||
}
|
||||
}
|
||||
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
}
|
||||
|
||||
void MapView::dropEvent(QDropEvent * event)
|
||||
{
|
||||
if(!controller || !controller->map())
|
||||
return;
|
||||
|
||||
auto * sc = static_cast<MapScene*>(scene());
|
||||
if(!sc)
|
||||
return;
|
||||
|
||||
if(sc->selectionObjectsView.newObject)
|
||||
{
|
||||
QString errorMsg;
|
||||
if(controller->canPlaceObject(sc->level, sc->selectionObjectsView.newObject, errorMsg))
|
||||
{
|
||||
controller->commitObjectCreate(sc->level);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->discardObject(sc->level);
|
||||
QMessageBox::information(this, "Can't place object", errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void MapView::dragMoveEvent(QDragMoveEvent * event)
|
||||
{
|
||||
auto * sc = static_cast<MapScene*>(scene());
|
||||
if(!sc)
|
||||
return;
|
||||
|
||||
auto rect = event->answerRect();
|
||||
auto pos = mapToScene(rect.bottomRight()); //TODO: do we need to check size?
|
||||
int3 tile(pos.x() / 32 + 1, pos.y() / 32 + 1, sc->level);
|
||||
|
||||
if(sc->selectionObjectsView.newObject)
|
||||
{
|
||||
sc->selectionObjectsView.shift = QPoint(tile.x, tile.y);
|
||||
sc->selectionObjectsView.selectObject(sc->selectionObjectsView.newObject);
|
||||
sc->selectionObjectsView.selectionMode = SelectionObjectsLayer::MOVEMENT;
|
||||
sc->selectionObjectsView.draw();
|
||||
}
|
||||
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void MapView::dragLeaveEvent(QDragLeaveEvent * event)
|
||||
{
|
||||
if(!controller || !controller->map())
|
||||
return;
|
||||
|
||||
auto * sc = static_cast<MapScene*>(scene());
|
||||
if(!sc)
|
||||
return;
|
||||
|
||||
controller->discardObject(sc->level);
|
||||
}
|
||||
|
||||
|
||||
bool MapView::viewportEvent(QEvent *event)
|
||||
{
|
||||
if(auto * sc = static_cast<MapScene*>(scene()))
|
||||
|
@ -98,6 +98,10 @@ public slots:
|
||||
void mouseMoveEvent(QMouseEvent * mouseEvent) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void dragEnterEvent(QDragEnterEvent * event) override;
|
||||
void dragMoveEvent(QDragMoveEvent *event) override;
|
||||
void dragLeaveEvent(QDragLeaveEvent *event) override;
|
||||
void dropEvent(QDropEvent * event) override;
|
||||
|
||||
void cameraChanged(const QPointF & pos);
|
||||
|
||||
@ -127,7 +131,7 @@ public:
|
||||
|
||||
public slots:
|
||||
void mouseMoveEvent(QMouseEvent * mouseEvent) override;
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
void mousePressEvent(QMouseEvent * event) override;
|
||||
|
||||
signals:
|
||||
void cameraPositionChanged(const QPointF & newPosition);
|
||||
|
@ -12,12 +12,12 @@
|
||||
#include "objectbrowser.h"
|
||||
#include "../lib/mapObjects/CObjectClassesHandler.h"
|
||||
|
||||
ObjectBrowser::ObjectBrowser(QObject *parent)
|
||||
ObjectBrowserProxyModel::ObjectBrowserProxyModel(QObject *parent)
|
||||
: QSortFilterProxyModel{parent}, terrain(Terrain::ANY_TERRAIN)
|
||||
{
|
||||
}
|
||||
|
||||
bool ObjectBrowser::filterAcceptsRow(int source_row, const QModelIndex & source_parent) const
|
||||
bool ObjectBrowserProxyModel::filterAcceptsRow(int source_row, const QModelIndex & source_parent) const
|
||||
{
|
||||
bool result = QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
|
||||
@ -57,7 +57,7 @@ bool ObjectBrowser::filterAcceptsRow(int source_row, const QModelIndex & source_
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ObjectBrowser::filterAcceptsRowText(int source_row, const QModelIndex &source_parent) const
|
||||
bool ObjectBrowserProxyModel::filterAcceptsRowText(int source_row, const QModelIndex &source_parent) const
|
||||
{
|
||||
if(source_parent.isValid())
|
||||
{
|
||||
@ -76,3 +76,48 @@ bool ObjectBrowser::filterAcceptsRowText(int source_row, const QModelIndex &sour
|
||||
return (filter.isNull() || filter.isEmpty() || item->text().contains(filter, Qt::CaseInsensitive));
|
||||
}
|
||||
|
||||
Qt::ItemFlags ObjectBrowserProxyModel::flags(const QModelIndex & index) const
|
||||
{
|
||||
Qt::ItemFlags defaultFlags = QSortFilterProxyModel::flags(index);
|
||||
|
||||
if (index.isValid())
|
||||
return Qt::ItemIsDragEnabled | defaultFlags;
|
||||
|
||||
return defaultFlags;
|
||||
}
|
||||
|
||||
QStringList ObjectBrowserProxyModel::mimeTypes() const
|
||||
{
|
||||
QStringList types;
|
||||
types << "application/vcmi.object";
|
||||
return types;
|
||||
}
|
||||
|
||||
QMimeData * ObjectBrowserProxyModel::mimeData(const QModelIndexList & indexes) const
|
||||
{
|
||||
assert(indexes.size() == 1);
|
||||
|
||||
auto * standardModel = qobject_cast<QStandardItemModel*>(sourceModel());
|
||||
assert(standardModel);
|
||||
|
||||
QModelIndex index = indexes.front();
|
||||
QMimeData * mimeData = new QMimeData;
|
||||
QByteArray encodedData;
|
||||
|
||||
QDataStream stream(&encodedData, QIODevice::WriteOnly);
|
||||
|
||||
if(index.isValid())
|
||||
{
|
||||
auto text = standardModel->itemFromIndex(mapToSource(index))->data().toJsonObject();
|
||||
stream << text;
|
||||
}
|
||||
|
||||
mimeData->setData("application/vcmi.object", encodedData);
|
||||
return mimeData;
|
||||
}
|
||||
|
||||
ObjectBrowser::ObjectBrowser(QWidget * parent):
|
||||
QTreeView(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -13,10 +13,16 @@
|
||||
#include <QSortFilterProxyModel>
|
||||
#include "../lib/Terrain.h"
|
||||
|
||||
class ObjectBrowser : public QSortFilterProxyModel
|
||||
class ObjectBrowserProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
public:
|
||||
explicit ObjectBrowser(QObject *parent = nullptr);
|
||||
explicit ObjectBrowserProxyModel(QObject *parent = nullptr);
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
|
||||
QStringList mimeTypes() const override;
|
||||
|
||||
QMimeData * mimeData(const QModelIndexList & indexes) const override;
|
||||
|
||||
TerrainId terrain;
|
||||
QString filter;
|
||||
@ -25,3 +31,9 @@ protected:
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const override;
|
||||
bool filterAcceptsRowText(int source_row, const QModelIndex &source_parent) const;
|
||||
};
|
||||
|
||||
class ObjectBrowser : public QTreeView
|
||||
{
|
||||
public:
|
||||
ObjectBrowser(QWidget * parent);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user