New Sidebar and deprecate Scope Bar

.. remove the old scope bar in favour of a more modern sidebar as we
   transition the UI to a new design.

.. the newmainwindow approach is not practical, as making 2 UX coexist
   at the same time was impossible and would lead to major issues.

.. note a number of views are on the sidebar but disabled, they will
   be added over time.
This commit is contained in:
Mark Liversedge
2020-04-11 15:34:22 +01:00
parent feacfefbf4
commit 28b242815b
21 changed files with 511 additions and 83 deletions

View File

@@ -290,8 +290,8 @@ GcSplitterHandle::init(QString title, Qt::Orientation orientation,
// set handle size according to font metric
QFont font;
QFontMetrics fm(font);
bigHandle = fm.height() + 5;
smallHandle = fm.height() + 2;
bigHandle = fm.height() + 8;
smallHandle = fm.height() + 5;
// use the sizes as set
if (metal) setFixedHeight(bigHandle);
@@ -347,7 +347,7 @@ GcSplitterHandle::addActions(QList<QAction*> actions)
QToolButton *p = new QToolButton(this);
p->setStyleSheet("QToolButton { border: none; padding: 0px; }");
p->setAutoFillBackground(false);
p->setFixedSize(20*dpiXFactor,20*dpiYFactor);
p->setFixedSize(22*dpiXFactor,22*dpiYFactor);
p->setIcon(action->icon());
p->setIconSize(QSize(10*dpiXFactor,10*dpiYFactor));
p->setFocusPolicy(Qt::NoFocus);
@@ -402,7 +402,7 @@ GcSplitterHandle::paintBackground(QPaintEvent *)
GcSplitterControl::GcSplitterControl(QWidget *parent) : QToolBar(parent)
{
setContentsMargins(0,0,0,0);
setFixedHeight(20 *dpiYFactor);
setFixedHeight(22 *dpiYFactor);
setIconSize(QSize(14 *dpiXFactor,14 *dpiYFactor));
setToolButtonStyle(Qt::ToolButtonIconOnly);
setAutoFillBackground(false);
@@ -429,8 +429,8 @@ GcSplitterControl::paintBackground(QPaintEvent *)
// setup a painter and the area to paint
QPainter painter(this);
QLinearGradient active = GCColor::linearGradient(20 *dpiYFactor, true);
QLinearGradient inactive = GCColor::linearGradient(20 *dpiYFactor, false);
QLinearGradient active = GCColor::linearGradient(22 *dpiYFactor, true);
QLinearGradient inactive = GCColor::linearGradient(22 *dpiYFactor, false);
// fill with a linear gradient
painter.setPen(Qt::NoPen);

View File

@@ -24,7 +24,7 @@ GcToolBar::GcToolBar(QWidget *parent) : QWidget(parent)
//Height will be set when widget is added in MainWindow
setContentsMargins(0,0,0,0);
layout = new QHBoxLayout(this);
layout->setSpacing(10 *dpiXFactor);
layout->setSpacing(5 *dpiXFactor);
layout->setContentsMargins(0,0,0,0);
installEventFilter(this);
}

View File

@@ -24,6 +24,7 @@
#include <QAction>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include "Colors.h"
class GcToolBar : public QWidget
{
@@ -48,10 +49,10 @@ class Spacer : public QWidget
{
public:
Spacer(QWidget *parent) : QWidget(parent) {
QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setSizePolicy(sizePolicy);
}
QSize sizeHint() const { return QSize(10, 1); }
QSize sizeHint() const { return QSize(40*dpiXFactor, 1); }
};
#endif

View File

@@ -88,9 +88,9 @@
// GUI Widgets
#include "Tab.h"
#include "GcToolBar.h"
#include "NewSideBar.h"
#include "HelpWindow.h"
#include "HomeWindow.h"
#include "GcScopeBar.h"
#if !defined(Q_OS_MAC)
#include "QTFullScreen.h" // not mac!
#endif
@@ -214,14 +214,38 @@ MainWindow::MainWindow(const QDir &home)
appsettings->setValue(GC_SETTINGS_LAST, context->athlete->home->root().dirName());
/*----------------------------------------------------------------------
* ScopeBar
* ScopeBar as sidebar from v3.6
*--------------------------------------------------------------------*/
scopebar = new GcScopeBar(context);
connect(scopebar, SIGNAL(selectDiary()), this, SLOT(selectDiary()));
connect(scopebar, SIGNAL(selectHome()), this, SLOT(selectHome()));
connect(scopebar, SIGNAL(selectAnal()), this, SLOT(selectAnalysis()));
connect(scopebar, SIGNAL(selectTrain()), this, SLOT(selectTrain()));
connect(scopebar, SIGNAL(selectInterval()), this, SLOT(selectInterval()));
sidebar = new NewSideBar(context, this);
sidebar->addItem(QImage(":sidebar/athlete.png"), tr("athletes"), 0);
sidebar->setItemEnabled(0, false);
sidebar->addItem(QImage(":sidebar/plan.png"), tr("plan"), 1);
sidebar->setItemEnabled(1, false);
sidebar->addItem(QImage(":sidebar/trends.png"), tr("trends"), 2);
sidebar->addItem(QImage(":sidebar/assess.png"), tr("activities"), 3);
sidebar->setItemSelected(3, true);
sidebar->addItem(QImage(":sidebar/reflect.png"), tr("reflect"), 4);
sidebar->setItemEnabled(4, false);
sidebar->addItem(QImage(":sidebar/train.png"), tr("train"), 5);
sidebar->addStretch();
sidebar->addItem(QImage(":sidebar/apps.png"), tr("apps"), 6);
sidebar->setItemEnabled(6, false);
sidebar->addStretch();
// we can click on the quick icons, but they aren't selectable views
sidebar->addItem(QImage(":sidebar/sync.png"), tr("sync"), 7);
sidebar->setItemSelectable(7, false);
sidebar->addItem(QImage(":sidebar/prefs.png"), tr("settings"), 8);
sidebar->setItemSelectable(8, false);
connect(sidebar, SIGNAL(itemClicked(int)), this, SLOT(sidebarClicked(int)));
connect(sidebar, SIGNAL(itemSelected(int)), this, SLOT(sidebarSelected(int)));
/*----------------------------------------------------------------------
* What's this Context Help
@@ -266,16 +290,16 @@ MainWindow::MainWindow(const QDir &home)
HelpWhatsThis *helpLowBar = new HelpWhatsThis(lowbar);
lowbar->setWhatsThis(helpLowBar->getWhatsThisText(HelpWhatsThis::ToolBar_ToggleComparePane));
sidebar = new QPushButton(this);
sidebar->setIcon(sidebarIcon);
sidebar->setFixedHeight(24 * dpiYFactor);
sidebar->setIconSize(isize);
sidebar->setStyle(toolStyle);
sidebar->setToolTip(tr("Toggle Sidebar"));
sidebar->setPalette(metal);
connect(sidebar, SIGNAL(clicked(bool)), this, SLOT(toggleSidebar()));
HelpWhatsThis *helpSideBar = new HelpWhatsThis(sidebar);
sidebar->setWhatsThis(helpSideBar->getWhatsThisText(HelpWhatsThis::ToolBar_ToggleSidebar));
sidelist = new QPushButton(this);
sidelist->setIcon(sidebarIcon);
sidelist->setFixedHeight(24 * dpiYFactor);
sidelist->setIconSize(isize);
sidelist->setStyle(toolStyle);
sidelist->setToolTip(tr("Toggle Sidebar"));
sidelist->setPalette(metal);
connect(sidelist, SIGNAL(clicked(bool)), this, SLOT(toggleSidebar()));
HelpWhatsThis *helpSideBar = new HelpWhatsThis(sidelist);
sidelist->setWhatsThis(helpSideBar->getWhatsThisText(HelpWhatsThis::ToolBar_ToggleSidebar));
styleSelector = new QtSegmentControl(this);
styleSelector->setStyle(toolStyle);
@@ -295,37 +319,35 @@ MainWindow::MainWindow(const QDir &home)
if (dpiXFactor > 1) {
QString nopad = QString("QPushButton { padding-left: 0px; padding-right: 0px; "
" padding-top: 0px; padding-bottom: 0px; }");
sidebar->setStyleSheet(nopad);
sidelist->setStyleSheet(nopad);
lowbar->setStyleSheet(nopad);
}
#endif
head->addWidget(new Spacer(this));
head->addStretch();
head->addWidget(scopebar);
head->addStretch();
head->addWidget(sidebar);
head->addWidget(lowbar);
head->addWidget(styleSelector);
head->setFixedHeight(scopebar->height() + 7);
// add a search box on far right, but with a little space too
searchBox = new SearchFilterBox(this,context,false);
anim = new QPropertyAnimation(searchBox, "xwidth", this);
searchBox->setStyle(toolStyle);
searchBox->setFixedWidth(150 * dpiYFactor);
head->addWidget(searchBox);
searchBox->setFixedWidth(400 * dpiXFactor);
searchBox->setFixedHeight(28 * dpiYFactor);
head->addStretch();
head->addWidget(sidelist);
head->addWidget(lowbar);
head->addWidget(styleSelector);
head->setFixedHeight(searchBox->height() + (10 *dpiXFactor));
connect(searchBox, SIGNAL(searchResults(QStringList)), this, SLOT(setFilter(QStringList)));
connect(searchBox, SIGNAL(searchClear()), this, SLOT(clearFilter()));
connect(searchBox->searchbox, SIGNAL(haveFocus()), this, SLOT(searchFocusIn()));
connect(searchBox->searchbox, SIGNAL(lostFocus()), this, SLOT(searchFocusOut()));
HelpWhatsThis *helpSearchBox = new HelpWhatsThis(searchBox);
searchBox->setWhatsThis(helpSearchBox->getWhatsThisText(HelpWhatsThis::SearchFilterBox));
Spacer *spacer = new Spacer(this);
spacer->setFixedWidth(5 *dpiYFactor);
head->addWidget(spacer);
head->addWidget(searchBox);
spacer = new Spacer(this);
spacer->setFixedWidth(5 *dpiYFactor);
head->addWidget(spacer);
/*----------------------------------------------------------------------
@@ -364,8 +386,17 @@ MainWindow::MainWindow(const QDir &home)
mainLayout->setSpacing(0);
mainLayout->setContentsMargins(0,0,0,0);
mainLayout->addWidget(head);
mainLayout->addWidget(tabbar);
mainLayout->addWidget(tabStack);
QHBoxLayout *lrlayout = new QHBoxLayout();
mainLayout->addLayout(lrlayout);
lrlayout->setSpacing(0);
lrlayout->setContentsMargins(0,0,0,0);
lrlayout->addWidget(sidebar);
QVBoxLayout *tablayout = new QVBoxLayout();
tablayout->setSpacing(0);
tablayout->setContentsMargins(0,0,0,0);
lrlayout->addLayout(tablayout);
tablayout->addWidget(tabbar);
tablayout->addWidget(tabStack);
setCentralWidget(central);
/*----------------------------------------------------------------------
@@ -561,7 +592,6 @@ MainWindow::MainWindow(const QDir &home)
viewMenu->addSeparator();
viewMenu->addAction(tr("Activities"), this, SLOT(selectAnalysis()));
viewMenu->addAction(tr("Trends"), this, SLOT(selectHome()));
viewMenu->addAction(tr("Train"), this, SLOT(selectTrain()));
#ifdef GC_HAVE_ICAL
viewMenu->addAction(tr("Diary"), this, SLOT(selectDiary()));
#endif
@@ -959,6 +989,7 @@ MainWindow::moveEvent(QMoveEvent*)
void
MainWindow::closeEvent(QCloseEvent* event)
{
fprintf(stderr,"window close started\n"); fflush(stderr);
QList<Tab*> closing = tabList;
bool needtosave = false;
bool importrunning = false;
@@ -1008,6 +1039,8 @@ MainWindow::closeEvent(QCloseEvent* event)
}
appsettings->setValue(GC_SETTINGS_MAIN_GEOM, saveGeometry());
appsettings->setValue(GC_SETTINGS_MAIN_STATE, saveState());
fprintf(stderr,"window close compeleted\n"); fflush(stderr);
}
MainWindow::~MainWindow()
@@ -1147,6 +1180,34 @@ MainWindow::support()
QDesktopServices::openUrl(QUrl("https://groups.google.com/forum/#!forum/golden-cheetah-users"));
}
void
MainWindow::sidebarClicked(int id)
{
// sync quick link
if (id == 7) checkCloud();
// prefs
if (id == 8) showOptions();
}
void
MainWindow::sidebarSelected(int id)
{
switch (id) {
case 0: // athlete not written yet
case 1: // plan not written yet
break;
case 2: selectHome(); break;
case 3: selectAnalysis(); break;
case 4: // reflect not written yet
break;
case 5: selectTrain(); break;
case 6: // apps not written yet
break;
}
}
void
MainWindow::selectAnalysis()
{
@@ -1223,12 +1284,9 @@ MainWindow::setToolButtons()
}
#endif
#ifdef Q_OS_MAC // bizarre issue with searchbox focus on tab voew change
anim->stop();
searchBox->clearFocus();
searchFocusOut();
scopebar->setFocus(Qt::TabFocusReason);
#endif
scopebar->setSelected(index);
}
/*----------------------------------------------------------------------
@@ -1923,7 +1981,6 @@ MainWindow::saveGCState(Context *context)
context->showToolbar = showhideToolbar->isChecked();
context->searchText = searchBox->text();
context->style = styleAction->isChecked();
context->setIndex(scopebar->selected());
}
void
@@ -1934,9 +1991,6 @@ MainWindow::restoreGCState(Context *context)
showToolbar(context->showToolbar);
//showTabbar(context->showTabbar);
showLowbar(context->showLowbar);
scopebar->setSelected(context->viewIndex);
scopebar->setContext(context);
scopebar->setHighlighted(); // to reflect context
searchBox->setContext(context);
searchBox->setText(context->searchText);
}
@@ -2266,26 +2320,6 @@ void MainWindow::showCreateFixPyScriptDlg() {
}
#endif
// grow/shrink searchbox if there is space...
void
MainWindow::searchFocusIn()
{
if (searchBox->searchbox->hasFocus()) {
anim->setDuration(300);
anim->setEasingCurve(QEasingCurve::InOutQuad);
anim->setStartValue(searchBox->width());
anim->setEndValue(500 * dpiYFactor);
anim->start();
}
}
void
MainWindow::searchFocusOut()
{
anim->stop();
searchBox->setFixedWidth(150 *dpiYFactor);
}
#ifdef GC_HAS_CLOUD_DB
void
MainWindow::cloudDBuserEditChart()

View File

@@ -62,6 +62,7 @@ class QtSegmentControl;
class SaveSingleDialogWidget;
class ChooseCyclistDialog;
class SearchFilterBox;
class NewSideBar;
class MainWindow;
@@ -128,10 +129,6 @@ class MainWindow : public QMainWindow
// chart importing
void importCharts(QStringList);
// search box gets and loses focus - make big/small
void searchFocusIn();
void searchFocusOut();
// open and closing windows and tabs
void closeAll(); // close all windows and tabs
@@ -149,6 +146,10 @@ class MainWindow : public QMainWindow
void removeTab(Tab*); // remove without question
void switchTab(int index); // for switching between one tab and another
// sidebar selecting views and actions
void sidebarClicked(int id);
void sidebarSelected(int id);
// Athlete Backup
void setBackupAthleteMenu();
void backupAthlete(QString name);
@@ -263,19 +264,18 @@ class MainWindow : public QMainWindow
private:
GcScopeBar *scopebar;
NewSideBar *sidebar;
Tab *currentTab;
QList<Tab*> tabList;
#ifndef Q_OS_MAC
QTFullScreen *fullScreen;
#endif
QPropertyAnimation *anim;
SearchFilterBox *searchBox;
// Not on Mac so use other types
QPushButton *sidebar, *lowbar;
QPushButton *sidelist, *lowbar;
QtSegmentControl *styleSelector;
GcToolBar *head;

278
src/Gui/NewSideBar.cpp Normal file
View File

@@ -0,0 +1,278 @@
#include "Context.h"
#include "NewSideBar.h"
#include "Colors.h"
static constexpr int gl_itemwidth = 70;
static constexpr int gl_itemheight = 50;
static constexpr int gl_margin = 0;
NewSideBar::NewSideBar(Context *context, QWidget *parent) : QWidget(parent), context(context)
{
setFixedWidth(gl_itemwidth *dpiXFactor);
setAutoFillBackground(true);
lastid=0;
QVBoxLayout *mainlayout = new QVBoxLayout(this);
mainlayout->setSpacing(0);
mainlayout->setContentsMargins(0,0,0,0);
top=new QWidget(this);
bottom=new QWidget(this);
middle=new QWidget(this);
middle->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
mainlayout->addWidget(top);
mainlayout->addWidget(middle);
mainlayout->addWidget(bottom);
layout = new QVBoxLayout(middle);
layout->setSpacing(0);
layout->setContentsMargins(0,gl_margin *dpiXFactor,0,gl_margin*dpiYFactor);
connect(context, SIGNAL(configChanged(qint32)), this, SLOT(configChanged(qint32)));
configChanged(0);
show();
}
void
NewSideBar::clicked(int id)
{
// un selectable item was clicked (e.g. symc or settings)
emit itemClicked(id);
}
void
NewSideBar::selected(int id)
{
// we selected one, so need to set it selected
// and deselect everyone else
QMapIterator<int,NewSideBarItem*>i(items);
while(i.hasNext()) {
i.next();
if (i.key() == id) i.value()->setSelected(true);
else i.value()->setSelected(false);
i.value()->update();
}
emit itemSelected(id);
}
int
NewSideBar::addItem(QImage icon, QString name, int id)
{
// allocated an id
if (id == -1) id=lastid++;
NewSideBarItem *add = new NewSideBarItem(this, id, icon, name);
layout->addWidget(add);
items.insert(id, add);
return id;
}
// leave a gap- we have main icons, gap, apps, gap, sync, prefs
void
NewSideBar::addStretch()
{
layout->addStretch();
}
// is it shown, is it usable?
void
NewSideBar::setItemVisible(int id, bool x)
{
NewSideBarItem *item = items.value(id, NULL);
if (item) item->setVisible(x);
}
void
NewSideBar::setItemEnabled(int id, bool x)
{
NewSideBarItem *item = items.value(id, NULL);
if (item) item->setEnabled(x);
}
// can we select it, select it by program?
void
NewSideBar::setItemSelectable(int id, bool x)
{
NewSideBarItem *item = items.value(id, NULL);
if (item) item->setSelectable(x);
}
void
NewSideBar::setItemSelected(int id, bool x)
{
NewSideBarItem *item = items.value(id, NULL);
if (item) item->setSelected(x);
}
void
NewSideBar::configChanged(qint32)
{
QFont font;
QFontMetrics fm(font);
top->setFixedHeight(fm.height() + 8); // no scaling...
bottom->setFixedHeight(fm.height() + 4); // no scaling...
QColor col=GColor(CCHROME);
QString style=QString("QWidget { background: rgb(%1,%2,%3); }").arg(col.red()).arg(col.green()).arg(col.blue());
top->setStyleSheet(style);
bottom->setStyleSheet(style);
col=GColor(CPLOTBACKGROUND);
col=GCColor::invertColor(col); // invert makes dark white, light black
col=GCColor::invertColor(col); // invert again, so now its white or black
style=QString("QWidget { background: rgb(%1,%2,%3); }").arg(col.red()).arg(col.green()).arg(col.blue());
middle->setStyleSheet(style);
}
NewSideBarItem::NewSideBarItem(NewSideBar *sidebar, int id, QImage icon, QString name) : QWidget(sidebar), sidebar(sidebar), id(id), icon(icon), name(name)
{
clicked = selected = false;
selectable = enabled = true;
// some basics
setFixedSize(gl_itemwidth *dpiXFactor,gl_itemheight *dpiYFactor);
setAutoFillBackground(true);
// trap events
installEventFilter(this);
connect(sidebar->context, SIGNAL(configChanged(qint32)), this, SLOT(configChanged(qint32)));
configChanged(0);
show();
}
void
NewSideBarItem::setSelectable(bool x)
{
selectable = x;
update();
}
void
NewSideBarItem::setEnabled(bool x)
{
enabled = x;
update();
}
void
NewSideBarItem::setSelected(bool x)
{
selected = x;
update();
}
// trap all events for me
bool
NewSideBarItem::eventFilter(QObject *, QEvent *e)
{
switch(e->type()) {
case QEvent::Enter:
case QEvent::Leave:
case QEvent::MouseMove:
update();
break;
case QEvent::MouseButtonPress:
clicked=true;
break;
case QEvent::MouseButtonRelease:
if (underMouse() && clicked) {
// user clicked on us!
if (enabled && selectable && !selected) sidebar->selected(id);
else if (enabled && !selectable) sidebar->clicked(id);
}
clicked=false;
break;
default:
break;
}
return false;
}
static QImage imageRGB(QImage &source, QColor target)
{
QImage returning = source;
if (target == QColor(Qt::white)) target = QColor(255,255,254, 255); // white is the alpha
for(int x=0; x< returning.width(); x++)
for(int y=0; y< returning.height(); y++) {
QColor v = returning.pixelColor(x,y);
if (v.red() == 0 && v.blue() == 0 && v.green() == 0)
returning.setPixelColor(x,y,target);
}
return returning;
}
void
NewSideBarItem::configChanged(qint32)
{
QColor col(Qt::darkGray);
QString style=QString("QWidget { background: rgb(%1,%2,%3); }").arg(col.red()).arg(col.green()).arg(col.blue());
setStyleSheet(style);
// set foreground colors
fg_normal = GCColor::invertColor(GColor(CPLOTBACKGROUND));
// if foreground is white then we're "dark" if its
// black the we're "light" so this controls palette
bool dark = (fg_normal == QColor(Qt::white));
if (dark) fg_disabled = QColor(80,80,80);
else fg_disabled = QColor(180,180,180);
// set background colors
col=GColor(CPLOTBACKGROUND);
bool isblack = (col == QColor(Qt::black)); // e.g. mustang theme
col=GCColor::invertColor(col); // invert makes dark white, light black
col=GCColor::invertColor(col); // invert again, so now its white or black
bg_normal = col;
// on select
bg_select =GColor(CPLOTBACKGROUND);
if (dark) bg_select = bg_select.lighter(200);
else bg_select = bg_select.darker(200);
if (isblack) bg_select = QColor(30,30,30);
// on hover
bg_hover =GColor(CPLOTBACKGROUND);
if (dark) bg_hover = bg_hover.lighter(300);
else bg_hover = bg_hover.darker(300);
if (isblack) bg_hover = QColor(50,50,50);
iconNormal = QPixmap::fromImage(imageRGB(icon, fg_normal), Qt::ColorOnly|Qt::PreferDither|Qt::DiffuseAlphaDither);
iconDisabled = QPixmap::fromImage(imageRGB(icon, fg_disabled), Qt::ColorOnly|Qt::PreferDither|Qt::DiffuseAlphaDither);
}
void
NewSideBarItem::paintEvent(QPaintEvent *)
{
QPainter painter(this);
// background is normal, unless selected or hovering
QBrush brush(bg_normal);
if (selected) brush = QBrush(bg_select);
else if (underMouse() && enabled) brush = QBrush(bg_hover);
painter.fillRect(QRectF(0,0,gl_itemwidth*dpiXFactor, gl_itemheight*dpiXFactor), brush);
// icon is normal or disabled
if (enabled) painter.drawPixmap(27*dpiXFactor,6*dpiXFactor,24*dpiXFactor,24*dpiXFactor,iconNormal);
else painter.drawPixmap(27*dpiXFactor,6*dpiXFactor,24*dpiXFactor,24*dpiXFactor,iconDisabled);
// block
if (selected) painter.fillRect(QRectF(0,0,3*dpiXFactor,gl_itemheight*dpiXFactor), QBrush(GColor(CPLOTMARKER)));
// draw name
QPen pen(fg_normal);
if (!enabled) pen = QPen(fg_disabled);
QFont f;
f.setPixelSize(12*dpiYFactor);
painter.setFont(f);
painter.setPen(pen);
painter.drawText(QRect(5*dpiXFactor,24*dpiYFactor,(gl_itemwidth-5)*dpiXFactor,20*dpiYFactor), Qt::AlignCenter| Qt::AlignBottom, name);
}

105
src/Gui/NewSideBar.h Normal file
View File

@@ -0,0 +1,105 @@
#include <QWidget>
#include <QMap>
#include <QVBoxLayout>
class Context;
class NewSideBarItem;
class NewSideBar : public QWidget
{
Q_OBJECT
friend class ::NewSideBarItem;
public:
NewSideBar(Context *context, QWidget *parent);
public slots:
// managing items - the id can be assigned or will get a default
// it returns the id used
int addItem(QImage icon, QString name, int id=-1);
// leave a gap- we have main icons, gap, apps, gap, sync, prefs
void addStretch();
// is it shown, is it usable?
void setItemVisible(int id, bool);
void setItemEnabled(int id, bool);
// can we select it, select it by program?
void setItemSelectable(int id, bool);
void setItemSelected(int id, bool);
// config changed
void configChanged(qint32);
// called by children
void clicked(int id);
void selected(int id);
signals:
void itemSelected(int id);
void itemClicked(int id);
protected:
Context *context;
private:
QWidget *top, *middle, *bottom; // bars at top and the bottom
QMap<int,NewSideBarItem*> items;
int lastid; // when autoallocating
QVBoxLayout *layout;
};
// tightly bound with parent
class NewSideBarItem : public QWidget
{
Q_OBJECT
public:
NewSideBarItem(NewSideBar *sidebar, int id, QImage icon, QString name);
void setSelectable(bool);
void setEnabled(bool);
void setSelected(bool);
//void setVisible(bool); - standard qwidget method, we do not need to implement
bool isSelected() const { return selected; }
bool isEnabled() const { return enabled; }
bool isSelectable() const { return selectable; }
//bool isVisible() const { return QWidget::isVisible(); } - standard qwidget method
// trap all events for me
bool eventFilter(QObject *oj, QEvent *e);
public slots:
// config changed
void configChanged(qint32);
void paintEvent(QPaintEvent *event);
private:
NewSideBar *sidebar; // for emitting signals
int id;
// pre-rendered/calculated icons and colors
QImage icon;
QPixmap iconNormal, iconDisabled;
QColor fg_normal, fg_disabled;
QColor bg_normal, bg_hover, bg_select, bg_disable;
QFont textfont;
QString name;
bool selected;
bool selectable;
bool enabled;
bool clicked;
};

View File

@@ -56,7 +56,7 @@ RideNavigator::RideNavigator(Context *context, bool mainwindow) : GcChartWindow(
mainLayout = new QVBoxLayout;
setChartLayout(mainLayout);
mainLayout->setSpacing(0);
if (mainwindow) mainLayout->setContentsMargins(0,0,0,0);
if (mainwindow) mainLayout->setContentsMargins(5*dpiXFactor,0,0,0);
else mainLayout->setContentsMargins(2,2,2,2); // so we can resize!
searchFilter = new SearchFilter(this);

View File

@@ -35,7 +35,7 @@
SearchBox::SearchBox(Context *context, QWidget *parent, bool nochooser)
: QLineEdit(parent), context(context), parent(parent), filtered(false), nochooser(nochooser), active(false)
{
setFixedHeight(21 *dpiYFactor);
//setFixedHeight(21 *dpiYFactor);
//clear button
clearButton = new QToolButton(this);
clearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }");

View File

@@ -35,6 +35,7 @@ SearchFilterBox::SearchFilterBox(QWidget *parent, Context *context, bool nochoos
// no column chooser if my parent widget is a modal widget
searchbox = new SearchBox(context, this, nochooser);
searchbox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
contents->addWidget(searchbox);
freeSearch = new FreeSearch(this, context);

View File

@@ -1,6 +1,15 @@
<RCC>
<qresource prefix="/">
<file>webservice/httpserver.ini</file>
<file>sidebar/apps.png</file>
<file>sidebar/assess.png</file>
<file>sidebar/athlete.png</file>
<file>sidebar/plan.png</file>
<file>sidebar/prefs.png</file>
<file>sidebar/reflect.png</file>
<file>sidebar/sync.png</file>
<file>sidebar/train.png</file>
<file>sidebar/trends.png</file>
<file>images/devices/garminusb.png</file>
<file>images/devices/computrainer.png</file>
<file>images/devices/kickr.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@@ -754,7 +754,7 @@ HEADERS += Gui/AboutDialog.h Gui/AddIntervalDialog.h Gui/AnalysisSidebar.h Gui/C
Gui/GcWindowRegistry.h Gui/GenerateHeatMapDialog.h Gui/GProgressDialog.h Gui/HelpWhatsThis.h Gui/HelpWindow.h \
Gui/IntervalTreeView.h Gui/LTMSidebar.h Gui/MainWindow.h Gui/NewCyclistDialog.h Gui/Pages.h Gui/RideNavigator.h Gui/RideNavigatorProxy.h \
Gui/SaveDialogs.h Gui/SearchBox.h Gui/SearchFilterBox.h Gui/SolveCPDialog.h Gui/Tab.h Gui/TabView.h Gui/ToolsRhoEstimator.h \
Gui/Views.h Gui/BatchExportDialog.h Gui/DownloadRideDialog.h Gui/ManualRideDialog.h Gui/NewMainWindow.h \
Gui/Views.h Gui/BatchExportDialog.h Gui/DownloadRideDialog.h Gui/ManualRideDialog.h Gui/NewMainWindow.h Gui/NewSideBar.h \
Gui/MergeActivityWizard.h Gui/RideImportWizard.h Gui/SplitActivityWizard.h Gui/SolverDisplay.h
# metrics and models
@@ -852,7 +852,7 @@ SOURCES += Gui/AboutDialog.cpp Gui/AddIntervalDialog.cpp Gui/AnalysisSidebar.cpp
Gui/GcWindowRegistry.cpp Gui/GenerateHeatMapDialog.cpp Gui/GProgressDialog.cpp Gui/HelpWhatsThis.cpp Gui/HelpWindow.cpp \
Gui/IntervalTreeView.cpp Gui/LTMSidebar.cpp Gui/MainWindow.cpp Gui/NewCyclistDialog.cpp Gui/Pages.cpp Gui/RideNavigator.cpp Gui/SaveDialogs.cpp \
Gui/SearchBox.cpp Gui/SearchFilterBox.cpp Gui/SolveCPDialog.cpp Gui/Tab.cpp Gui/TabView.cpp Gui/ToolsRhoEstimator.cpp Gui/Views.cpp \
Gui/BatchExportDialog.cpp Gui/DownloadRideDialog.cpp Gui/ManualRideDialog.cpp Gui/EditUserMetricDialog.cpp Gui/NewMainWindow.cpp \
Gui/BatchExportDialog.cpp Gui/DownloadRideDialog.cpp Gui/ManualRideDialog.cpp Gui/EditUserMetricDialog.cpp Gui/NewMainWindow.cpp Gui/NewSideBar.cpp \
Gui/MergeActivityWizard.cpp Gui/RideImportWizard.cpp Gui/SplitActivityWizard.cpp Gui/SolverDisplay.cpp
## Models and Metrics