ChartBar context menu in Tab

.. instead of the 'More...' button in the top left of a chart when in
   tabbed mode we now have a menu button when you hover over a tab.

.. the menu button activates the chart menu for now, till we refactor
   to using a chart space.

.. the 'More...' menu is still available when in tiled mode (we need to
   decide what to do there).
This commit is contained in:
Mark Liversedge
2020-06-02 20:40:48 +01:00
parent b6ee709520
commit 45a628b4b9
6 changed files with 110 additions and 23 deletions

View File

@@ -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; i<buttons.count(); i++)
for (int i=0; i<buttons.count(); i++) {
signalMapper->setMapping(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<QMouseEvent*>(e)->x());
clickpos.setY(static_cast<QMouseEvent*>(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<QMouseEvent*>(e)->x());
clickpos.setY(static_cast<QMouseEvent*>(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; i<chartbar->buttons.count(); i++) chartbar->signalMapper->setMapping(chartbar->buttons[i], i);
for (int i=0; i<chartbar->buttons.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);
}

View File

@@ -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

View File

@@ -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<GcWinID>("type");
qRegisterMetaType<QColor>("color");
qRegisterMetaType<DateRange>("dateRange");
qRegisterMetaType<bool>("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();

View File

@@ -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;
QList<QAction*>actions;
};

View File

@@ -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);

View File

@@ -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 *);