diff --git a/profile-widget/profileview.cpp b/profile-widget/profileview.cpp index 072b19620..f6874203a 100644 --- a/profile-widget/profileview.cpp +++ b/profile-widget/profileview.cpp @@ -33,6 +33,7 @@ #ifndef SUBSURFACE_MOBILE #include "core/device.h" +#include "desktop-widgets/simplewidgets.h" #include #include #include @@ -108,7 +109,7 @@ ProfileView::ProfileView(QQuickItem *parent) : setFlag(ItemHasContents, true); setAcceptHoverEvents(true); - setAcceptedMouseButtons(Qt::LeftButton); + setAcceptedMouseButtons(Qt::RightButton | Qt::LeftButton); auto tec = qPrefTechnicalDetails::instance(); connect(tec, &qPrefTechnicalDetails::calcalltissuesChanged , this, &ProfileView::replot); @@ -499,6 +500,15 @@ void ProfileView::removeEvent(DiveEventItem &item) #endif } +// TODO: How should that work on mobile? +void ProfileView::addSetpointChange(int seconds) +{ +#ifndef SUBSURFACE_MOBILE + SetpointDialog dialog(mutable_dive(), dc, seconds); + dialog.exec(); +#endif +} + // Formats cylinder information for display. // eg : "Cyl 1 (AL80 EAN32)" static QString formatCylinderDescription(int i, const cylinder_t &cylinder) @@ -519,6 +529,64 @@ void ProfileView::unhideEvents() replot(); } +void ProfileView::contextMenu(const QPointF pos, const QPoint globalPos) +{ + // No context menu in Plan mode + if (mode == Mode::Plan) + return; + + // Only open the contextmenu on the profile + if (!d || !profileScene->pointOnProfile(pos)) + return; + + std::vector m; + int seconds = profileScene->timeAt(pos); + + // if we have more than one gas, offer to switch to another one + if (d->cylinders.size() > 1) { + std::vector gasChangeMenu; + // If this is before the first sample, offer an "initial gas change". + // This is signaled by seconds = 0 + const struct divecomputer *currentdc = d->get_dc(dc); + if (seconds < 0 || (!currentdc->samples.empty() && seconds <= currentdc->samples[0].time.seconds)) + seconds = 0; + for (auto [i, cylinder]: enumerated_range(d->cylinders)) { + QString label = formatCylinderDescription(i, cylinder); + gasChangeMenu.emplace_back(label, [this, idx = i, seconds] { + Command::addGasSwitch(mutable_dive(), dc, seconds, idx); + }); + } + m.emplace_back(seconds == 0 ? tr("Set initial gas") : tr("Add gas change"), std::move(gasChangeMenu)); + } + + m.emplace_back(tr("Add setpoint change"), [this, seconds]() { addSetpointChange(seconds); }); + m.emplace_back(tr("Add bookmark"), [this, seconds]() { + Command::addEventBookmark(mutable_dive(), dc, seconds); + }); + m.emplace_back(tr("Split dive into two"), [this, seconds]() { + Command::splitDives(mutable_dive(), duration_t{ seconds }); + }); + + std::vector changeModeMenu; + divemode_loop loop(*d->get_dc(dc)); + divemode_t divemode = loop.at(seconds); + if (divemode != OC) + changeModeMenu.emplace_back(gettextFromC::tr(divemode_text_ui[OC]), [this, seconds]() { + Command::addEventDivemodeSwitch(mutable_dive(), dc, seconds, OC); + }); + if (divemode != CCR) + changeModeMenu.emplace_back(gettextFromC::tr(divemode_text_ui[CCR]), [this, seconds]() { + Command::addEventDivemodeSwitch(mutable_dive(), dc, seconds, CCR); + }); + if (divemode != PSCR) + changeModeMenu.emplace_back(gettextFromC::tr(divemode_text_ui[PSCR]), [this, seconds]() { + Command::addEventDivemodeSwitch(mutable_dive(), dc, seconds, PSCR); + }); + m.emplace_back(tr("Change divemode"), changeModeMenu); + + execMenu(m, globalPos); +} + void ProfileView::mousePressEvent(QMouseEvent *event) { // Handle dragging of items @@ -526,6 +594,12 @@ void ProfileView::mousePressEvent(QMouseEvent *event) if (event->isAccepted()) return; + // On Desktop, the right botton opens the menu. + // For Mobile, we will have to think about something. + // Perhaps a "hamburger menu"? + if (event->button() == Qt::RightButton) + return contextMenu(event->pos(), event->globalPos()); + // Open context menu if computer name is clicked if (d && profileScene->pointOnDiveComputerText(event->pos())) { std::vector m; diff --git a/profile-widget/profileview.h b/profile-widget/profileview.h index 26ac67cfa..170adc0cf 100644 --- a/profile-widget/profileview.h +++ b/profile-widget/profileview.h @@ -109,6 +109,8 @@ private: void mouseReleaseEvent(QMouseEvent *event) override; void mouseDoubleClickEvent(QMouseEvent *event) override; void keyPressEvent(QKeyEvent *e) override; + void contextMenu(const QPointF pos, const QPoint globalPos); + void addSetpointChange(int seconds); ChartItemPtr tooltip; void updateTooltip(QPointF pos, bool plannerMode, int animSpeed); diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp index 562f510b5..fed22408c 100644 --- a/profile-widget/profilewidget2.cpp +++ b/profile-widget/profilewidget2.cpp @@ -292,21 +292,8 @@ bool ProfileWidget2::isPlanner() const return currentState == PLAN; } -#if 0 // TODO::: FINISH OR DISABLE -struct int ProfileWidget2::getEntryFromPos(QPointF pos) -{ - // find the time stamp corresponding to the mouse position - int seconds = lrint(timeAxis->valueAt(pos)); - - for (int i = 0; i < plotInfo.nr; i++) { - if (plotInfo.entry[i].sec >= seconds) - return i; - } - return plotInfo.nr - 1; -} -#endif - #ifndef SUBSURFACE_MOBILE +<<<<<<< HEAD static bool isDiveTextItem(const QGraphicsItem *item, const DiveTextItem *textItem) { while (item) { @@ -410,6 +397,8 @@ void ProfileWidget2::connectPlannerModel() connect(plannerModel, &DivePlannerPointsModel::rowsMoved, this, &ProfileWidget2::pointsMoved); } #endif +======= +>>>>>>> 28d057ffb (profile: port context menu to QtQuick) void ProfileWidget2::profileChanged(dive *dive) { diff --git a/qt-quick/chartview.cpp b/qt-quick/chartview.cpp index aada86f96..03c72dd4d 100644 --- a/qt-quick/chartview.cpp +++ b/qt-quick/chartview.cpp @@ -307,6 +307,10 @@ void ChartView::setLayerVisibility(size_t z, bool visible) void ChartView::mousePressEvent(QMouseEvent *event) { + // Only left-button for drag events. + if (event->button() != Qt::LeftButton) + return event->ignore(); + QPointF pos = event->localPos(); for (auto item: dragableItems) {