diff --git a/src/Charts/ChartBar.cpp b/src/Charts/ChartBar.cpp index 6b183f186..b996c95ff 100644 --- a/src/Charts/ChartBar.cpp +++ b/src/Charts/ChartBar.cpp @@ -115,6 +115,9 @@ ChartBar::ChartBar(Context *context) : QWidget(context->mainWindow), context(con signalMapper = new QSignalMapper(this); // maps each option connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(clicked(int))); + menuMapper = new QSignalMapper(this); // maps each option + connect(menuMapper, SIGNAL(mapped(int)), this, SLOT(triggerContextMenu(int))); + barMenu = new QMenu("Add"); chartMenu = barMenu->addMenu(tr("Add Chart")); @@ -153,8 +156,8 @@ ChartBar::configChanged(qint32) scrollArea->setStyleSheet(QString("QScrollArea { background: rgb(%1,%2,%3); }").arg(col.red()).arg(col.green()).arg(col.blue())); foreach(ChartBarItem *b, buttons) { - int width = fs.width(b->text) + (30 * dpiXFactor); - if (width < (80*dpiXFactor)) width=80*dpiXFactor; + int width = fs.width(b->text) + (60 * dpiXFactor); + if (width < (90*dpiXFactor)) width=90*dpiXFactor; b->setFont(buttonFont); b->setFixedWidth(width); b->setFixedHeight(height); @@ -170,9 +173,9 @@ ChartBar::addWidget(QString title) // make the right size QFontMetrics fontMetric(buttonFont); - int width = fontMetric.width(title) + (30 * dpiXFactor); + int width = fontMetric.width(title) + (60 * dpiXFactor); int height = (fontMetric.height()+(spacing_*dpiXFactor)); - if (width < (80*dpiXFactor)) width=80*dpiXFactor; + if (width < (90*dpiXFactor)) width=90*dpiXFactor; newbutton->setFixedWidth(width); newbutton->setFixedHeight(height); @@ -182,7 +185,9 @@ ChartBar::addWidget(QString title) // map signals connect(newbutton, SIGNAL(clicked(bool)), signalMapper, SLOT(map())); + connect(newbutton, SIGNAL(contextMenu()), menuMapper, SLOT(map())); signalMapper->setMapping(newbutton, buttons.count()-1); + menuMapper->setMapping(newbutton, buttons.count()-1); newbutton->installEventFilter(this); @@ -196,6 +201,14 @@ ChartBar::setChartMenu() context->mainWindow->setChartMenu(chartMenu); } +void +ChartBar::triggerContextMenu(int index) +{ + QPoint tl = buttons[index]->geometry().topLeft(); + int x = scrollArea->widget()->mapToGlobal(tl).x(); + emit contextMenu(index, x); +} + void ChartBar::menuPopup() { @@ -208,8 +221,8 @@ ChartBar::setText(int index, QString text) { buttons[index]->setText(text); QFontMetrics fontMetric(buttonFont); - int width = fontMetric.width(text) + (30*dpiXFactor); - buttons[index]->setWidth(width < (80*dpiXFactor) ? (80*dpiXFactor) : width); + int width = fontMetric.width(text) + (60*dpiXFactor); + buttons[index]->setWidth(width < (90*dpiXFactor) ? (90*dpiXFactor) : width); buttons[index]->update(); tidy(true); // still fit ? @@ -321,9 +334,10 @@ ChartBar::removeWidget(int index) buttons.takeAt(index); // reset mappings - for (int i=0; isetMapping(buttons[i], i); - + menuMapper->setMapping(buttons[i], i); + } tidy(true); } @@ -418,6 +432,7 @@ ChartBarItem::ChartBarItem(ChartBar *chartbar) : QWidget(chartbar), chartbar(cha QFont font; font.setPointSize(10); setFont(font); + setMouseTracking(true); } void @@ -448,6 +463,18 @@ ChartBarItem::paintEvent(QPaintEvent *) // draw the bar if (checked) painter.fillRect(QRect(0,0,geometry().width(), 3*dpiXFactor), QBrush(GColor(CPLOTMARKER))); + + // draw the menu indicator + if (underMouse() && checked) { + + QPoint mouse = mapFromGlobal(QCursor::pos()); + QBrush brush(Qt::darkGray); + painter.setPen (Qt :: NoPen); + + // different color if under mouse + if (hotspot.contains(mouse)) brush.setColor(GColor(CPLOTMARKER)); + painter.fillPath (triangle, brush); + } painter.restore(); } @@ -472,18 +499,50 @@ ChartBarItem::indexPos(int x) bool ChartBarItem::event(QEvent *e) { + // resize? + if (e->type() == QEvent::Resize) { + int startx = width() - (20*dpiXFactor); + int depth = height() / 4; + int starty = (height() / 2.0) - (depth/2) + 3*dpiXFactor; // middle, taking into account bar at top + int hs = 3 * dpiXFactor; + + // set the triangle + hotspot.clear(); + hotspot.moveTo (startx-hs, starty-hs); + hotspot.lineTo (startx+(hs*2)+(8*dpiXFactor), starty-hs); + hotspot.lineTo (startx+(hs*2)+(8*dpiXFactor), starty+depth+hs); + hotspot.lineTo (startx-hs, starty+depth+hs); + hotspot.lineTo (startx, starty); + + triangle.clear(); + triangle.moveTo (startx, starty); + triangle.lineTo (startx+(8*dpiXFactor), starty); + triangle.lineTo (startx+(4*dpiXFactor), starty+depth); + triangle.lineTo (startx, starty); + } + // entry / exit event repaint for hover color if (e->type() == QEvent::Leave || e->type() == QEvent::Enter) { - repaint(); + update(); } if (e->type() == QEvent::MouseButtonPress && underMouse()) { - // selected with a click (not release) - state = Click; - clickpos.setX(static_cast(e)->x()); - clickpos.setY(static_cast(e)->y()); - emit clicked(checked); + // menu? + if (checked && hotspot.contains(mapFromGlobal(QCursor::pos()))) { + + // menu activated + state = Idle; + emit contextMenu(); + + } else { + + // selected with a click (not release) + state = Click; + clickpos.setX(static_cast(e)->x()); + clickpos.setY(static_cast(e)->y()); + emit clicked(checked); + } } if (e->type() == QEvent::MouseButtonRelease) { @@ -492,7 +551,6 @@ ChartBarItem::event(QEvent *e) // finish dragging, so drop into where we moved it delete dragging; - state = Idle; int index = chartbar->layout->indexOf(this); if (index != originalindex) { @@ -502,13 +560,17 @@ ChartBarItem::event(QEvent *e) // bit naughty modding from child here, but no easy way around it. ChartBarItem *me = chartbar->buttons.takeAt(originalindex); chartbar->buttons.insert(index, me); - for (int i=0; ibuttons.count(); i++) chartbar->signalMapper->setMapping(chartbar->buttons[i], i); + for (int i=0; ibuttons.count(); i++) { + chartbar->signalMapper->setMapping(chartbar->buttons[i], i); + chartbar->menuMapper->setMapping(chartbar->buttons[i], i); + } // tell homewindow chartbar->itemMoved(index, originalindex); } - repaint(); + update(); } + state = Idle; } if (e->type() == QEvent::MouseMove) { @@ -551,6 +613,7 @@ ChartBarItem::event(QEvent *e) chartbar->layout->insertItem(indexpos-1, me); // indexpos-1 because we just got removed } } + update(); // in case hovering over stuff } return QWidget::event(e); } diff --git a/src/Charts/ChartBar.h b/src/Charts/ChartBar.h index eefe1d3c4..da94aa9b3 100644 --- a/src/Charts/ChartBar.h +++ b/src/Charts/ChartBar.h @@ -53,6 +53,7 @@ public slots: void addWidget(QString); void clear(); void clicked(int); + void triggerContextMenu(int); void removeWidget(int); void setText(int index, QString); void setCurrentIndex(int index); @@ -64,6 +65,7 @@ public slots: void configChanged(qint32); // appearance signals: + void contextMenu(int,int); void currentIndexChanged(int); void itemMoved(int from, int to); @@ -86,7 +88,7 @@ private: QToolButton *menuButton; QFont buttonFont; - QSignalMapper *signalMapper; + QSignalMapper *signalMapper, *menuMapper; QMenu *barMenu, *chartMenu; @@ -120,7 +122,7 @@ class ChartBarItem : public QWidget public: ChartBarItem(ChartBar *parent); void setText(QString _text) { text = _text; } - void setChecked(bool _checked) { checked = _checked; repaint(); } + void setChecked(bool _checked) { checked = _checked; update(); } bool isChecked() { return checked; } void setWidth(int x) { setFixedWidth(x); } void setHighlighted(bool x) { highlighted = x; } @@ -130,6 +132,7 @@ class ChartBarItem : public QWidget QString text; signals: void clicked(bool); + void contextMenu(); public slots: void paintEvent(QPaintEvent *); @@ -148,5 +151,7 @@ class ChartBarItem : public QWidget bool checked; bool highlighted; bool red; + + QPainterPath triangle, hotspot; }; #endif diff --git a/src/Charts/GoldenCheetah.cpp b/src/Charts/GoldenCheetah.cpp index 032ad2cb3..c8afac23c 100644 --- a/src/Charts/GoldenCheetah.cpp +++ b/src/Charts/GoldenCheetah.cpp @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2010 Mark Liversedge (liversedge@gmail.com) * * This program is free software; you can redistribute it and/or modify it @@ -191,7 +191,7 @@ GcWindow::GcWindow(Context *context) : QFrame(context->mainWindow), dragState(No qRegisterMetaType("type"); qRegisterMetaType("color"); qRegisterMetaType("dateRange"); - qRegisterMetaType("nomenu"); + nomenu = false; revealed = false; setParent(context->mainWindow); setControls(NULL); @@ -202,7 +202,6 @@ GcWindow::GcWindow(Context *context) : QFrame(context->mainWindow), dragState(No setResizable(false); setMouseTracking(true); setProperty("color", GColor(CPLOTBACKGROUND)); - setProperty("nomenu", false); menu = NULL; // make sure its underneath the toggle button @@ -645,7 +644,7 @@ GcWindow::enterEvent(QEvent *) { if (_noevents) return; - if (property("nomenu") == false && property("isManager").toBool() == false) { + if (nomenu == false) { if (contentsMargins().top() > (20*dpiYFactor)) menuButton->setFixedSize(80*dpiXFactor,30*dpiYFactor); else menuButton->setFixedSize(80*dpiXFactor, 15*dpiYFactor); menuButton->raise(); diff --git a/src/Charts/GoldenCheetah.h b/src/Charts/GoldenCheetah.h index 35f1fb8f3..86eea8361 100644 --- a/src/Charts/GoldenCheetah.h +++ b/src/Charts/GoldenCheetah.h @@ -181,6 +181,7 @@ public: GcWinID type() const { return _type; } void setType(GcWinID x) { _type = x; } // only really used by the window registry + void showMore(bool x) { nomenu=!x; } virtual bool amVisible(); // popover controls @@ -216,6 +217,7 @@ public: QPushButton *settingsButton, *closeButton; QPushButton *menuButton; QMenu *menu; + bool nomenu; QListactions; }; diff --git a/src/Charts/HomeWindow.cpp b/src/Charts/HomeWindow.cpp index 4131386dc..6f975f300 100644 --- a/src/Charts/HomeWindow.cpp +++ b/src/Charts/HomeWindow.cpp @@ -76,6 +76,7 @@ HomeWindow::HomeWindow(Context *context, QString name, QString /* windowtitle */ setControls(cw); setProperty("isManager", true); + nomenu=true; setAcceptDrops(true); QVBoxLayout *layout = new QVBoxLayout(this); @@ -162,6 +163,7 @@ HomeWindow::HomeWindow(Context *context, QString name, QString /* windowtitle */ //connect(tabbed, SIGNAL(tabCloseRequested(int)), this, SLOT(removeChart(int))); connect(chartbar, SIGNAL(itemMoved(int,int)), this, SLOT(tabMoved(int,int))); connect(chartbar, SIGNAL(currentIndexChanged(int)), this, SLOT(tabSelected(int))); + connect(chartbar, SIGNAL(contextMenu(int,int)), this, SLOT(tabMenu(int,int))); connect(titleEdit, SIGNAL(textChanged(const QString&)), SLOT(titleChanged())); // trends view we should select a library chart when a chart is selected. @@ -354,6 +356,14 @@ HomeWindow::rideSelected() } } +void +HomeWindow::tabMenu(int index, int x) +{ + // activate this tab's menu + QPoint pos = QPoint(x, mapToGlobal(chartbar->geometry().bottomLeft()).y()+(2*dpiXFactor)); + charts[index]->menu->exec(pos); +} + void HomeWindow::dateRangeChanged(DateRange dr) { Q_UNUSED( dr ) @@ -492,6 +502,8 @@ HomeWindow::styleChanged(int id) chartbar->addWidget(charts[i]->property("title").toString()); charts[i]->setResizable(false); // we need to show on tab selection! charts[i]->setProperty("dateRange", property("dateRange")); + charts[i]->showMore(false); + charts[i]->menuButton->hide(); // we use tab button charts[i]->hide(); // we need to show on tab selection! // weird bug- set margins *after* tabbed->addwidget since it resets margins (!!) if(charts[i]->showTitle() == true) charts[i]->setContentsMargins(0,25*dpiYFactor,0,0); @@ -502,6 +514,7 @@ HomeWindow::styleChanged(int id) charts[i]->setContentsMargins(0,25*dpiYFactor,0,0); charts[i]->setResizable(false); // we need to show on tab selection! charts[i]->show(); + charts[i]->showMore(true); charts[i]->setProperty("dateRange", property("dateRange")); charts[i]->setProperty("ride", property("ride")); break; @@ -510,6 +523,7 @@ HomeWindow::styleChanged(int id) charts[i]->setContentsMargins(0,15*dpiYFactor,0,0); charts[i]->setResizable(true); // we need to show on tab selection! charts[i]->show(); + charts[i]->showMore(true); charts[i]->setProperty("dateRange", property("dateRange")); charts[i]->setProperty("ride", property("ride")); default: @@ -643,6 +657,7 @@ HomeWindow::addChart(GcChartWindow* newone) case 0 : newone->setResizable(false); // we need to show on tab selection! + newone->showMore(false); //tabbed->addTab(newone, newone->property("title").toString()); tabbed->addWidget(newone); chartbar->addWidget(newone->property("title").toString()); @@ -658,6 +673,7 @@ HomeWindow::addChart(GcChartWindow* newone) newone->setFixedWidth((tileArea->width()-50)); newone->setFixedHeight(newone->width() * 0.7); newone->setResizable(false); // we need to show on tab selection! + newone->showMore(true); int row = chartnum; // / 2; int column = 0; //chartnum % 2; newone->setContentsMargins(0,25*dpiYFactor,0,0); @@ -690,6 +706,7 @@ HomeWindow::addChart(GcChartWindow* newone) newone->setFixedHeight(newheight); newone->setContentsMargins(0,15*dpiYFactor,0,0); newone->setResizable(true); // we need to show on tab selection! + newone->showMore(true); if (currentStyle == 2 && chartCursor >= 0) winFlow->insert(chartCursor, newone); else winFlow->addWidget(newone); diff --git a/src/Charts/HomeWindow.h b/src/Charts/HomeWindow.h index 3da6a8c9e..bd3dfc0e6 100644 --- a/src/Charts/HomeWindow.h +++ b/src/Charts/HomeWindow.h @@ -74,6 +74,7 @@ class HomeWindow : public GcWindow void tabSelected(int id); void tabSelected(int id, bool forride); void tabMoved(int from, int to); + void tabMenu(int index, int x); virtual void dragEnterEvent(QDragEnterEvent *); virtual void dropEvent(QDropEvent *); void resizeEvent(QResizeEvent *);