mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
profile: port divecomputer menu to QtQuick
This uses QWidgets and therefore will only compile on desktop. We'll have to see how to integrate that on mobile. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
bece0a0652
commit
f0fe52d42b
5 changed files with 88 additions and 52 deletions
|
@ -367,6 +367,11 @@ bool ProfileScene::pointOnProfile(const QPointF &point) const
|
|||
return timeAxis->pointInRange(point.x()) && profileYAxis->pointInRange(point.y());
|
||||
}
|
||||
|
||||
bool ProfileScene::pointOnDiveComputerText(const QPointF &point) const
|
||||
{
|
||||
return diveComputerText->boundingRect().contains(point - diveComputerText->pos());
|
||||
}
|
||||
|
||||
static double max_gas(const plot_info &pi, double gas_pressures::*gas)
|
||||
{
|
||||
double ret = -1;
|
||||
|
|
|
@ -37,6 +37,7 @@ public:
|
|||
void resize(QSizeF size);
|
||||
void clear();
|
||||
bool pointOnProfile(const QPointF &point) const;
|
||||
bool pointOnDiveComputerText(const QPointF &point) const;
|
||||
void anim(double fraction); // Called by the animation with 0.0-1.0 (start to stop).
|
||||
// Can be compared with literal 1.0 to determine "end" state.
|
||||
|
||||
|
|
|
@ -27,6 +27,12 @@
|
|||
#include <QDesktopServices>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#ifndef SUBSURFACE_MOBILE
|
||||
#include "core/device.h"
|
||||
#include <QMenu>
|
||||
#include <QInputDialog>
|
||||
#endif
|
||||
|
||||
static const QColor mouseFollowerColor = QColor(Qt::red).lighter();
|
||||
|
||||
// Class templates for animations (if any). Might want to do our own.
|
||||
|
@ -375,6 +381,47 @@ void ProfileView::wheelEvent(QWheelEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
// Helper to make menus on mobile and desktop
|
||||
struct MenuEntry {
|
||||
QString text;
|
||||
std::function<void()> action;
|
||||
MenuEntry(QString text, std::function<void()> action)
|
||||
: text(text), action(std::move(action))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static void execMenu(const std::vector<MenuEntry> &entries, QPoint pos)
|
||||
{
|
||||
if (entries.empty())
|
||||
return;
|
||||
#ifndef SUBSURFACE_MOBILE
|
||||
QMenu m;
|
||||
for (const MenuEntry &e: entries) {
|
||||
// Dang. Qt doesn't support std::function! This is too many indirections for my taste. :(
|
||||
m.addAction(e.text, [f = e.action] { f(); });
|
||||
}
|
||||
m.exec(pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: How should that work on mobile?
|
||||
void ProfileView::renameCurrentDC()
|
||||
{
|
||||
#ifndef SUBSURFACE_MOBILE
|
||||
bool ok;
|
||||
struct divecomputer *currentdc = mutable_dive()->get_dc(dc);
|
||||
if (!currentdc)
|
||||
return;
|
||||
// TODO: center on window by passing a QWidget as first argument!
|
||||
QString newName = QInputDialog::getText(nullptr, tr("Edit nickname"),
|
||||
tr("Set new nickname for %1 (serial %2):").arg(currentdc->model.c_str()).arg(currentdc->serial.c_str()),
|
||||
QLineEdit::Normal, get_dc_nickname(currentdc).c_str(), &ok);
|
||||
if (ok)
|
||||
Command::editDeviceNickname(currentdc, newName);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ProfileView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
// Handle dragging of items
|
||||
|
@ -382,6 +429,32 @@ void ProfileView::mousePressEvent(QMouseEvent *event)
|
|||
if (event->isAccepted())
|
||||
return;
|
||||
|
||||
// Open context menu if computer name is clicked
|
||||
if (d && profileScene->pointOnDiveComputerText(event->pos())) {
|
||||
std::vector<MenuEntry> m;
|
||||
const struct divecomputer *currentdc = d->get_dc(dc);
|
||||
if (!currentdc->deviceid && dc == 0 && d->number_of_computers() == 1)
|
||||
// nothing to do, can't rename, delete or reorder
|
||||
return;
|
||||
// create menu to show when right clicking on dive computer name
|
||||
if (dc > 0)
|
||||
m.emplace_back(tr("Make first dive computer"), [this]() {
|
||||
Command::moveDiveComputerToFront(mutable_dive(), dc);
|
||||
});
|
||||
if (d->number_of_computers() > 1) {
|
||||
m.emplace_back(tr("Delete this dive computer"), [this]() {
|
||||
Command::deleteDiveComputer(mutable_dive(), dc);
|
||||
});
|
||||
m.emplace_back(tr("Split this dive computer into own dive"), [this]() {
|
||||
Command::splitDiveComputer(mutable_dive(), dc);
|
||||
});
|
||||
}
|
||||
if (currentdc->deviceid)
|
||||
m.emplace_back(tr("Rename this dive computer"), [this] { renameCurrentDC(); });
|
||||
execMenu(m, event->globalPos());
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if current picture is clicked
|
||||
if (highlightedPicture &&
|
||||
highlightedPicture->thumbnail->underMouse(event->pos()) &&
|
||||
|
@ -1188,3 +1261,8 @@ void ProfileView::pictureOffsetChanged(dive *dIn, QString filename, offset_t off
|
|||
}
|
||||
update();
|
||||
}
|
||||
|
||||
dive *ProfileView::mutable_dive() const
|
||||
{
|
||||
return const_cast<dive *>(d);
|
||||
}
|
||||
|
|
|
@ -92,6 +92,7 @@ private:
|
|||
ChartItemPtr<ChartGraphicsSceneItem> profileItem;
|
||||
std::unique_ptr<ProfileAnimation> animation;
|
||||
ChartItemPtr<ChartLineItem> mouseFollowerHorizontal, mouseFollowerVertical;
|
||||
dive *mutable_dive() const; // for functions manipulating the dive
|
||||
|
||||
void plotAreaChanged(const QSizeF &size) override;
|
||||
void resetPointers() override;
|
||||
|
@ -132,6 +133,9 @@ private:
|
|||
void pointsRemoved(const QModelIndex &, int start, int end);
|
||||
void pointsMoved(const QModelIndex &, int start, int end, const QModelIndex &destination, int row);
|
||||
|
||||
// DC related
|
||||
void renameCurrentDC();
|
||||
|
||||
// The list of pictures in this plot. The pictures are sorted by offset in seconds.
|
||||
// For the same offset, sort by filename.
|
||||
// Pictures that are outside of the dive time are not shown.
|
||||
|
|
|
@ -362,26 +362,6 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
|
|||
QMenu m;
|
||||
if (!d)
|
||||
return;
|
||||
// figure out if we are ontop of the dive computer name in the profile
|
||||
QGraphicsItem *sceneItem = itemAt(mapFromGlobal(event->globalPos()));
|
||||
if (isDiveTextItem(sceneItem, profileScene->diveComputerText)) {
|
||||
const struct divecomputer *currentdc = d->get_dc(dc);
|
||||
if (!currentdc->deviceid && dc == 0 && d->number_of_computers() == 1)
|
||||
// nothing to do, can't rename, delete or reorder
|
||||
return;
|
||||
// create menu to show when right clicking on dive computer name
|
||||
if (dc > 0)
|
||||
m.addAction(tr("Make first dive computer"), this, &ProfileWidget2::makeFirstDC);
|
||||
if (d->number_of_computers() > 1) {
|
||||
m.addAction(tr("Delete this dive computer"), this, &ProfileWidget2::deleteCurrentDC);
|
||||
m.addAction(tr("Split this dive computer into own dive"), this, &ProfileWidget2::splitCurrentDC);
|
||||
}
|
||||
if (currentdc->deviceid)
|
||||
m.addAction(tr("Rename this dive computer"), this, &ProfileWidget2::renameCurrentDC);
|
||||
m.exec(event->globalPos());
|
||||
// don't show the regular profile context menu
|
||||
return;
|
||||
}
|
||||
|
||||
// create the profile context menu
|
||||
QPointF scenePos = mapToScene(mapFromGlobal(event->globalPos()));
|
||||
|
@ -479,38 +459,6 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
|
|||
m.exec(event->globalPos());
|
||||
}
|
||||
|
||||
void ProfileWidget2::deleteCurrentDC()
|
||||
{
|
||||
if (d)
|
||||
Command::deleteDiveComputer(mutable_dive(), dc);
|
||||
}
|
||||
|
||||
void ProfileWidget2::splitCurrentDC()
|
||||
{
|
||||
if (d)
|
||||
Command::splitDiveComputer(mutable_dive(), dc);
|
||||
}
|
||||
|
||||
void ProfileWidget2::makeFirstDC()
|
||||
{
|
||||
if (d)
|
||||
Command::moveDiveComputerToFront(mutable_dive(), dc);
|
||||
}
|
||||
|
||||
void ProfileWidget2::renameCurrentDC()
|
||||
{
|
||||
if (!d)
|
||||
return;
|
||||
bool ok;
|
||||
struct divecomputer *currentdc = mutable_dive()->get_dc(dc);
|
||||
QString newName = QInputDialog::getText(this, tr("Edit nickname"),
|
||||
tr("Set new nickname for %1 (serial %2):").arg(QString::fromStdString(currentdc->model)).
|
||||
arg(QString::fromStdString(currentdc->serial)),
|
||||
QLineEdit::Normal, QString::fromStdString(get_dc_nickname(currentdc)), &ok);
|
||||
if (ok)
|
||||
Command::editDeviceNickname(currentdc, newName);
|
||||
}
|
||||
|
||||
void ProfileWidget2::hideEvent(DiveEventItem *item)
|
||||
{
|
||||
if (!d)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue