Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for drag and drop #54

Merged
merged 5 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ if (${BUILD_EXAMPLES})
add_subdirectory(samples/moving-objects)
add_subdirectory(samples/mouse-actions)
add_subdirectory(samples/camera-actions)
add_subdirectory(samples/drag-and-drop)
else ()
message(STATUS "Disabled building of examples")
endif ()
3 changes: 2 additions & 1 deletion QGeoView.pro
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ SUBDIRS = \
samples/custom-tiles \
samples/moving-objects \
samples/mouse-actions \
samples/camera-actions
samples/camera-actions \
samples/drag-and-drop
3 changes: 3 additions & 0 deletions lib/include/QGeoView/QGVMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#pragma once

#include <QMimeData>
#include <QWidget>

#include "QGVCamera.h"
Expand Down Expand Up @@ -104,11 +105,13 @@ class QGV_LIB_DECL QGVMap : public QWidget
void mapMouseMove(QPointF projPos);
void mapMousePress(QPointF projPos);
void mapMouseDoubleClicked(QPointF projPos);
void dropOnMap(QGV::GeoPos pos, const QMimeData* data);

private:
QScopedPointer<QGVProjection> mProjection;
QScopedPointer<QGVMapQGView> mQGView;
QScopedPointer<QGVItem> mRootItem;
QList<QGVWidget*> mWidgets;
QSet<QGVItem*> mSelections;
void handleDropDataOnQGVMapQGView(QPointF position, const QMimeData* dropData);
};
13 changes: 13 additions & 0 deletions lib/include/QGeoView/QGVMapQGView.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,14 @@
#include "QGVMapQGItem.h"
#include "QGVMapRubberBand.h"


#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QGraphicsView>
#include <QMenu>
#include <QMimeData>

class QGVMap;

Expand All @@ -45,6 +51,9 @@ class QGV_LIB_DECL QGVMapQGView : public QGraphicsView
void setScaleLimits(double minScale, double maxScale);
void cleanState();

Q_SIGNALS:
void dropData(QPointF position, const QMimeData* dropData);

private:
QRectF viewRect() const;
void changeState(QGV::MapState state);
Expand Down Expand Up @@ -83,6 +92,10 @@ class QGV_LIB_DECL QGVMapQGView : public QGraphicsView
void resizeEvent(QResizeEvent* event) override final;
void showEvent(QShowEvent* event) override final;
void keyPressEvent(QKeyEvent* event) override final;
void dragEnterEvent(QDragEnterEvent* event) override final;
void dragMoveEvent(QDragMoveEvent* event) override final;
void dropEvent(QDropEvent* event) override final;
void dragLeaveEvent(QDragLeaveEvent* event) override final;

private:
QGVMap* mGeoMap;
Expand Down
8 changes: 8 additions & 0 deletions lib/src/QGVMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ QGVMap::QGVMap(QWidget* parent)
layout()->addWidget(mQGView.data());
layout()->setContentsMargins(0, 0, 0, 0);
refreshProjection();
connect(mQGView.data(), &QGVMapQGView::dropData, this, &QGVMap::handleDropDataOnQGVMapQGView);
}

QGVMap::~QGVMap()
Expand Down Expand Up @@ -381,6 +382,13 @@ void QGVMap::mousePressEvent(QMouseEvent* event)
QWidget::mousePressEvent(event);
}

void QGVMap::handleDropDataOnQGVMapQGView(QPointF position, const QMimeData* dropData)
{
const auto mapToProjectionPos = mapToProj(QPoint(position.rx(), position.ry()));
auto geoPos = getProjection()->projToGeo(mapToProjectionPos);
Q_EMIT dropOnMap(geoPos, dropData);
}

void QGVMap::mouseDoubleClickEvent(QMouseEvent* event)
{
if (hasMouseTracking()) {
Expand Down
27 changes: 27 additions & 0 deletions lib/src/QGVMapQGView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ QGVMapQGView::QGVMapQGView(QGVMap* geoMap)
setCacheMode(QGraphicsView::CacheBackground);
setMouseTracking(true);
setBackgroundBrush(QBrush(Qt::lightGray));
setAcceptDrops(true);
}

void QGVMapQGView::setMouseActions(QGV::MouseActions actions)
Expand Down Expand Up @@ -599,3 +600,29 @@ void QGVMapQGView::keyPressEvent(QKeyEvent* event)
{
QWidget::keyPressEvent(event);
}

void QGVMapQGView::dragEnterEvent(QDragEnterEvent* event)
{
event->accept();
}

void QGVMapQGView::dragMoveEvent(QDragMoveEvent* event)
{
event->accept();
}

void QGVMapQGView::dropEvent(QDropEvent* event)
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
Q_EMIT dropData(event->position(), event->mimeData());
#else
QPointF dropPoint = event->posF();
Q_EMIT dropData(dropPoint, event->mimeData());
#endif
event->accept();
}

void QGVMapQGView::dragLeaveEvent(QDragLeaveEvent* event)
{
event->accept();
}
37 changes: 37 additions & 0 deletions samples/drag-and-drop/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
set(CMAKE_CXX_STANDARD 11)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)

# Set the QT version
find_package(Qt6 COMPONENTS Core QUIET)
if (NOT Qt6_FOUND)
set(QT_VERSION 5 CACHE STRING "Qt version for QGeoView")
else()
set(QT_VERSION 6 CACHE STRING "Qt version for QGeoView")
endif()

find_package(Qt${QT_VERSION} REQUIRED COMPONENTS
Core
Gui
Widgets
Network
)

add_executable(qgeoview-samples-drag-and-drop
main.cpp
mainwindow.h
mainwindow.cpp
)

target_link_libraries(qgeoview-samples-drag-and-drop
PRIVATE
Qt${QT_VERSION}::Core
Qt${QT_VERSION}::Network
Qt${QT_VERSION}::Gui
Qt${QT_VERSION}::Widgets
QGeoView
qgeoview-samples-shared
)
15 changes: 15 additions & 0 deletions samples/drag-and-drop/drag-and-drop.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
TARGET = qgeoview-samples-drag-and-drop
TEMPLATE = app
CONFIG-= console

QT += gui widgets network

include(../lib.pri)
include(../shared.pri)

SOURCES += \
main.cpp \
mainwindow.cpp

HEADERS += \
mainwindow.h
37 changes: 37 additions & 0 deletions samples/drag-and-drop/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/***************************************************************************
* QGeoView is a Qt / C ++ widget for visualizing geographic data.
* Copyright (C) 2018-2023 Andrey Yaroshenko.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see https://www.gnu.org/licenses.
****************************************************************************/

#include <QApplication>
#include <QCommandLineParser>

#include "mainwindow.h"

int main(int argc, char* argv[])
{
QApplication app(argc, argv);
app.setApplicationName("QGeoView Samples");

QCommandLineParser parser;
parser.addHelpOption();
parser.addVersionOption();
parser.process(app);

MainWindow window;
window.show();
return app.exec();
}
143 changes: 143 additions & 0 deletions samples/drag-and-drop/mainwindow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/***************************************************************************
* QGeoView is a Qt / C ++ widget for visualizing geographic data.
* Copyright (C) 2018-2023 Andrey Yaroshenko.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see https://www.gnu.org/licenses.
****************************************************************************/

#include "mainwindow.h"

#include <QApplication>
#include <QGuiApplication>
#include <QHBoxLayout>
#include <QIcon>
#include <QTimer>
#include <QTreeWidgetItem>

//#include <QGeoView/QGVLayerBDGEx.h>
#include <QGeoView/QGVLayerGoogle.h>
#include <QGeoView/Raster/QGVIcon.h>
#include <helpers.h>

MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent)
{
setWindowTitle("QGeoView Samples - drag and drop");
setCentralWidget(new QWidget());
centralWidget()->setLayout(new QHBoxLayout());

// setup tree widget
sampleTree = new QTreeWidget(this);
sampleTree->setDragEnabled(true); // enable dragging items from the tree
sampleTree->setMinimumWidth(200);
sampleTree->setMaximumWidth(250);

// setup data into the tree widget
sampleTree->setColumnCount(1);
sampleTree->setHeaderLabel("Sample Tree Items with Icons");

QTreeWidgetItem* itemArrowUp = new QTreeWidgetItem;
QIcon arrowUp_icon = QApplication::style()->standardIcon(QStyle::SP_ArrowUp);
itemArrowUp->setData(0, Qt::DisplayRole, "Arrow Up");
itemArrowUp->setData(0, Qt::DecorationRole, arrowUp_icon);
sampleTree->addTopLevelItem(itemArrowUp);

QTreeWidgetItem* itemArrowDown = new QTreeWidgetItem;
QIcon arrowDown_icon = QApplication::style()->standardIcon(QStyle::SP_ArrowDown);
itemArrowDown->setData(0, Qt::DisplayRole, "Arrow Down");
itemArrowDown->setData(0, Qt::DecorationRole, arrowDown_icon);
sampleTree->addTopLevelItem(itemArrowDown);

QTreeWidgetItem* itemArrowRight = new QTreeWidgetItem;
QIcon arrowRight_icon = QApplication::style()->standardIcon(QStyle::SP_ArrowRight);
itemArrowRight->setData(0, Qt::DisplayRole, "Arrow Right");
itemArrowRight->setData(0, Qt::DecorationRole, arrowRight_icon);
sampleTree->addTopLevelItem(itemArrowRight);

QTreeWidgetItem* itemArrowLeft = new QTreeWidgetItem;
QIcon arrowLeft_icon = QApplication::style()->standardIcon(QStyle::SP_ArrowLeft);
itemArrowLeft->setData(0, Qt::DisplayRole, "Arrow Left");
itemArrowLeft->setData(0, Qt::DecorationRole, arrowLeft_icon);
sampleTree->addTopLevelItem(itemArrowLeft);

centralWidget()->layout()->addWidget(sampleTree);

// QGeoView setup
Helpers::setupCachedNetworkAccessManager(this);
mMap = new QGVMap(this);

// Background layer
// QGVLayer * layerBDGExCTM250 = new QGVLayerBDGEx(QGV::BDGExLayer::ctm250);
// layerBDGExCTM250->setName("BDGEx CTM250");
// mMap->addItem(layerBDGExCTM250);

QGVLayer* layerGoogleSchema = new QGVLayerGoogle(QGV::TilesType::Schema);
layerGoogleSchema->setName("Google Schema");
mMap->addItem(layerGoogleSchema);

// initial area to show
QTimer::singleShot(500, this, &MainWindow::targetArea);
centralWidget()->layout()->addWidget(mMap); // add map to central widget

// handle drop of itens on map
connect(mMap, &QGVMap::dropOnMap, this, &MainWindow::handleDropOnMap);
iconsLayer = new QGVLayer();
mMap->addItem(iconsLayer);
}

MainWindow::~MainWindow()
{
}

void MainWindow::targetArea()
{
QGV::GeoPos geoPos(-23.55651916354534, -46.61844717963553);
auto scaleRect = QGV::GeoRect{
geoPos.latitude() - 0.33, geoPos.longitude() - 0.33, geoPos.latitude() + 0.33, geoPos.longitude() + 0.33
};
mMap->cameraTo(QGVCameraActions(mMap).scaleTo(scaleRect));
return;
}

void MainWindow::handleDropOnMap(QGV::GeoPos pos, const QMimeData* data)
{
QByteArray encoded = data->data("application/x-qabstractitemmodeldatalist");
QDataStream stream(&encoded, QIODevice::ReadOnly);
QIcon iconDropped;
QString strDropped;
while (!stream.atEnd()) {
int row, col;
QMap<int, QVariant> roleDataMap;
stream >> row >> col >> roleDataMap;
for (auto i = 0; i < roleDataMap.size(); i++) {
std::string typeName = roleDataMap[i].typeName();
auto variant = roleDataMap[i];
if (typeName == "QString") {
strDropped = qvariant_cast<QString>(variant);
}
if (typeName == "QIcon") {
iconDropped = qvariant_cast<QIcon>(variant);
}
}
}
qDebug() << strDropped << "(lat, lon):" << pos.latToString() << pos.lonToString();
if (!iconDropped.isNull() && !strDropped.isEmpty()) {
auto* mIcon = new QGVIcon();
auto pixmap = iconDropped.pixmap(QSize(32, 32));
auto image = pixmap.toImage();
mIcon->loadImage(image);
mIcon->setGeometry(pos, QSizeF(32, 32));
iconsLayer->addItem(mIcon);
}
}
Loading
Loading