mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-04-15 05:32:21 +00:00
Athlete View 2 of 3
.. Show days since last activity and disable config icon since there isn't an appropriate action for now .. Athletes can be opened and closed via the tiles and a reusable 'Button' overview widget is available for re-use elsewhere. .. Part 3 will enable checking for downloadable data to show an indicator on the tile for e.g. coaches with multiple athletes. NOTE: There are a few issues regarding application context separation from athlete context that need fixing up (if you close the first athlete loaded expect crashes). Will look at this as a separate update since its been there for some time and is not related to the new view per se.
This commit is contained in:
@@ -3735,3 +3735,81 @@ ProgressBar::paint(QPainter*painter, const QStyleOptionGraphicsItem *, QWidget*)
|
||||
painter->fillRect(bar, QBrush(GColor(CPLOTMARKER)));
|
||||
|
||||
}
|
||||
|
||||
Button::Button(QGraphicsItem*parent, QString text) : QGraphicsItem(parent), text(text), state(None)
|
||||
{
|
||||
// not much really
|
||||
setZValue(11);
|
||||
setAcceptHoverEvents(true);
|
||||
}
|
||||
|
||||
void
|
||||
Button::setGeometry(double x, double y, double width, double height)
|
||||
{
|
||||
geom = QRectF(x,y,width, height);
|
||||
}
|
||||
|
||||
void
|
||||
Button::paint(QPainter*painter, const QStyleOptionGraphicsItem *, QWidget*)
|
||||
{
|
||||
|
||||
// button background
|
||||
QColor pc = GCColor::invertColor(GColor(CCARDBACKGROUND));
|
||||
pc.setAlpha(128);
|
||||
painter->setPen(QPen(pc));
|
||||
QPointF pos=mapToParent(geom.x(), geom.y());
|
||||
if (isUnderMouse()) {
|
||||
QColor hover=GColor(CPLOTMARKER);
|
||||
if (state==Clicked) hover.setAlpha(200);
|
||||
else hover.setAlpha(100);
|
||||
painter->setBrush(QBrush(hover));
|
||||
} else painter->setBrush(QBrush(GColor(CCARDBACKGROUND)));
|
||||
painter->drawRoundedRect(pos.x(), pos.y(), geom.width(), geom.height(), 20, 20);
|
||||
|
||||
// text using large font clipped
|
||||
if (isUnderMouse()) {
|
||||
QColor tc = GCColor::invertColor(CPLOTMARKER);
|
||||
tc.setAlpha(200);
|
||||
painter->setPen(tc);
|
||||
} else {
|
||||
QColor tc = GCColor::invertColor(GColor(CCARDBACKGROUND));
|
||||
tc.setAlpha(200);
|
||||
painter->setPen(tc);
|
||||
}
|
||||
painter->setFont(font);
|
||||
painter->drawText(geom, text, Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
}
|
||||
|
||||
bool
|
||||
Button::sceneEvent(QEvent *event)
|
||||
{
|
||||
|
||||
if (event->type() == QEvent::GraphicsSceneHoverMove) {
|
||||
|
||||
// mouse moved so hover paint anyway
|
||||
update();
|
||||
|
||||
} else if (event->type() == QEvent::GraphicsSceneHoverLeave) {
|
||||
|
||||
update();
|
||||
|
||||
} else if (event->type() == QEvent::GraphicsSceneMouseRelease) {
|
||||
|
||||
if (isUnderMouse() && state == Clicked) {
|
||||
emit clicked();
|
||||
}
|
||||
state = None;
|
||||
update();
|
||||
|
||||
|
||||
} else if (event->type() == QEvent::GraphicsSceneMousePress) {
|
||||
|
||||
if (isUnderMouse()) state = Clicked;
|
||||
update();
|
||||
|
||||
} else if (event->type() == QEvent::GraphicsSceneHoverEnter) {
|
||||
|
||||
update();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -654,4 +654,45 @@ class ProgressBar : public QObject, public QGraphicsItem
|
||||
|
||||
QPropertyAnimation *animator;
|
||||
};
|
||||
|
||||
// simple button to use on graphics views
|
||||
class Button : public QObject, public QGraphicsItem
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QGraphicsItem)
|
||||
|
||||
public:
|
||||
Button(QGraphicsItem *parent, QString text);
|
||||
|
||||
void setText(QString text) { this->text = text; update(); }
|
||||
void setFont(QFont font) { this->font = font; }
|
||||
|
||||
// we monkey around with this *A LOT*
|
||||
void setGeometry(double x, double y, double width, double height);
|
||||
QRectF geometry() { return geom; }
|
||||
|
||||
|
||||
// needed as pure virtual in QGraphicsItem
|
||||
void paint(QPainter*, const QStyleOptionGraphicsItem *, QWidget*);
|
||||
|
||||
QRectF boundingRect() const {
|
||||
QPointF pos=mapToParent(geom.x(), geom.y());
|
||||
return QRectF(pos.x(), pos.y(), geom.width(), geom.height());
|
||||
}
|
||||
|
||||
// for interaction
|
||||
bool sceneEvent(QEvent *event);
|
||||
|
||||
signals:
|
||||
void clicked();
|
||||
|
||||
private:
|
||||
QGraphicsItem *parent;
|
||||
QString text;
|
||||
QFont font;
|
||||
|
||||
QRectF geom;
|
||||
enum { None, Clicked } state;
|
||||
};
|
||||
|
||||
#endif // _GC_OverviewItem_h
|
||||
|
||||
@@ -137,8 +137,9 @@ class Context : public QObject
|
||||
|
||||
// athlete load/close
|
||||
void notifyLoadProgress(QString folder, double progress) { emit loadProgress(folder,progress); }
|
||||
void notifyLoadCompleted(QString folder, Context *context) { emit loadCompleted(folder,context); }
|
||||
void notifyLoadCompleted(QString folder, Context *context) { emit loadCompleted(folder,context); } // Athlete loaded
|
||||
void notifyAthleteClose(QString folder, Context *context) { emit athleteClose(folder,context); }
|
||||
void notifyLoadDone(QString folder, Context *context) { emit loadDone(folder, context); } // MainWindow finished
|
||||
|
||||
// preset charts
|
||||
void notifyPresetsChanged() { emit presetsChanged(); }
|
||||
@@ -227,6 +228,7 @@ class Context : public QObject
|
||||
// loading an athlete
|
||||
void loadProgress(QString,double);
|
||||
void loadCompleted(QString, Context*);
|
||||
void loadDone(QString, Context*);
|
||||
void athleteClose(QString, Context*);
|
||||
|
||||
// global filter changed
|
||||
|
||||
@@ -611,6 +611,7 @@ struct RideFileReader {
|
||||
};
|
||||
|
||||
class MetricAggregator;
|
||||
class AthleteCard;
|
||||
class RideFileFactory {
|
||||
|
||||
private:
|
||||
@@ -625,6 +626,7 @@ class RideFileFactory {
|
||||
|
||||
friend class ::MetricAggregator;
|
||||
friend class ::RideCache;
|
||||
friend class ::AthleteCard;
|
||||
|
||||
// will become private as code should work with
|
||||
// in memory representation not on disk .. but as we
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "AthleteView.h"
|
||||
#include "TabView.h"
|
||||
#include "JsonRideFile.h" // for DATETIME_FORMAT
|
||||
|
||||
// athlete card
|
||||
static bool _registerItems()
|
||||
@@ -15,7 +16,9 @@ static bool registered = _registerItems();
|
||||
static const int gl_athletes_per_row = 5;
|
||||
static const int gl_athletes_deep = 15;
|
||||
static const int gl_avatar_width = 5;
|
||||
static const int gl_progress_width = ROWHEIGHT / 2;
|
||||
static const int gl_progress_width = ROWHEIGHT/2;
|
||||
static const int gl_button_height = ROWHEIGHT*1.5;
|
||||
static const int gl_button_width = ROWHEIGHT*5;
|
||||
|
||||
AthleteView::AthleteView(Context *context) : ChartSpace(context, OverviewScope::ATHLETES)
|
||||
{
|
||||
@@ -31,6 +34,12 @@ AthleteView::AthleteView(Context *context) : ChartSpace(context, OverviewScope::
|
||||
|
||||
QString name = i.next();
|
||||
|
||||
// if there is no avatar its not a real folder, even a blank athlete
|
||||
// will get the default avatar. This is to avoid having to work out
|
||||
// what all the random folders are that Qt creates on Windows when
|
||||
// using QtWebEngine, or Python or R or created by user scripts
|
||||
if (!QFile(gcroot + "/" + name + "/config/avatar.png").exists()) continue;
|
||||
|
||||
// add a card for each athlete
|
||||
AthleteCard *ath = new AthleteCard(this, name);
|
||||
addItem(row,col,gl_athletes_deep,ath);
|
||||
@@ -59,17 +68,8 @@ AthleteView::configChanged(qint32)
|
||||
|
||||
AthleteCard::AthleteCard(ChartSpace *parent, QString path) : ChartSpaceItem(parent, path), path(path)
|
||||
{
|
||||
// context and signals
|
||||
if (parent->context->athlete->cyclist == path) {
|
||||
context = parent->context;
|
||||
loadprogress = 100;
|
||||
} else {
|
||||
context = NULL;
|
||||
loadprogress = 0;
|
||||
}
|
||||
|
||||
connect(parent->context->mainWindow, SIGNAL(openingAthlete(QString,Context*)), this, SLOT(opening(QString,Context*)));
|
||||
connect(parent->context, SIGNAL(athleteClose(QString,Context*)), this, SLOT(closing(QString,Context*)));
|
||||
// no config icon thanks
|
||||
setShowConfig(false);
|
||||
|
||||
// avatar
|
||||
QRectF img(ROWHEIGHT,ROWHEIGHT*2,ROWHEIGHT* gl_avatar_width, ROWHEIGHT* gl_avatar_width);
|
||||
@@ -84,22 +84,76 @@ AthleteCard::AthleteCard(ChartSpace *parent, QString path) : ChartSpaceItem(pare
|
||||
painter.drawEllipse(0, 0, img.width(), img.height());
|
||||
avatar = canvas.toImage();
|
||||
|
||||
#if 0
|
||||
// ridecache raw
|
||||
if (loadprogress == 0) {
|
||||
QTime timer;
|
||||
timer.start();
|
||||
QFile rideDB(gcroot + "/" + path + "/cache/rideDB.json");
|
||||
if (rideDB.exists() && rideDB.open(QFile::ReadOnly)) {
|
||||
// open close button
|
||||
button = new Button(this, tr("Open"));
|
||||
button->setFont(parent->midfont);
|
||||
button->setGeometry(geometry().width()-(gl_button_width+ROWHEIGHT), geometry().height()-(gl_button_height+ROWHEIGHT),
|
||||
gl_button_width, gl_button_height);
|
||||
connect(button, SIGNAL(clicked()), this, SLOT(clicked()));
|
||||
|
||||
QByteArray contents = rideDB.readAll();
|
||||
rideDB.close();
|
||||
QJsonDocument json = QJsonDocument::fromJson(contents);
|
||||
}
|
||||
fprintf(stderr, "'%s' read rideDB took %d usecs\n", path.toStdString().c_str(), timer.elapsed()); fflush(stderr);
|
||||
// context and signals
|
||||
if (parent->context->athlete->cyclist == path) {
|
||||
context = parent->context;
|
||||
loadprogress = 100;
|
||||
button->setText("Close");
|
||||
} else {
|
||||
context = NULL;
|
||||
loadprogress = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
connect(parent->context->mainWindow, SIGNAL(openingAthlete(QString,Context*)), this, SLOT(opening(QString,Context*)));
|
||||
connect(parent->context, SIGNAL(athleteClose(QString,Context*)), this, SLOT(closing(QString,Context*)));
|
||||
|
||||
// set stats to none
|
||||
count=0;
|
||||
last=QDateTime();
|
||||
|
||||
// need to fetch by looking at file names, rideDB parse is too expensive here
|
||||
if (loadprogress == 0) {
|
||||
|
||||
// unloaded athletes we just say when last activity was
|
||||
QDate today = QDateTime::currentDateTime().date();
|
||||
QDir dir(gcroot + "/" + path + "/activities");
|
||||
QStringListIterator i(RideFileFactory::instance().listRideFiles(dir));
|
||||
while (i.hasNext()) {
|
||||
|
||||
QString name = i.next();
|
||||
QDateTime date;
|
||||
|
||||
if (RideFile::parseRideFileName(name, &date)) {
|
||||
|
||||
//int ago= date.date().daysTo(today);
|
||||
if (last==QDateTime() || date > last) last = date;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// use ridecache
|
||||
refreshStats();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AthleteCard::refreshStats()
|
||||
{
|
||||
if (context == NULL) return;
|
||||
|
||||
// last 90 days
|
||||
count=context->athlete->rideCache->rides().count();
|
||||
foreach(RideItem *item, context->athlete->rideCache->rides()) {
|
||||
|
||||
// last activity date?
|
||||
if (last==QDateTime() || item->dateTime > last) last = item->dateTime;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AthleteCard::clicked()
|
||||
{
|
||||
if (loadprogress==100) parent->context->mainWindow->closeTab(path);
|
||||
else parent->context->mainWindow->openTab(path);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -109,18 +163,44 @@ AthleteCard::opening(QString name, Context*context)
|
||||
if (name == path) {
|
||||
this->context = context;
|
||||
loadprogress = 100;
|
||||
button->setText("Close");
|
||||
button->hide();
|
||||
connect(context,SIGNAL(loadProgress(QString,double)), this, SLOT(loadProgress(QString,double)));
|
||||
connect(context,SIGNAL(loadDone(QString,Context*)), this, SLOT(loadDone(QString,Context*)));
|
||||
connect(context,SIGNAL(athleteClose(QString,Context*)), this, SLOT(closing(QString,Context*)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AthleteCard::itemGeometryChanged()
|
||||
{
|
||||
button->setGeometry(geometry().width()-(gl_button_width+ROWHEIGHT), geometry().height()-(gl_button_height+ROWHEIGHT),
|
||||
gl_button_width, gl_button_height);
|
||||
}
|
||||
|
||||
void AthleteCard::loadDone(QString name, Context *)
|
||||
{
|
||||
if (this->name == name) {
|
||||
loadprogress = 100;
|
||||
refreshStats();
|
||||
button->show();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void AthleteCard::dragChanged(bool drag)
|
||||
{
|
||||
if (drag || (loadprogress != 100 && loadprogress != 0)) button->hide();
|
||||
else button->show();
|
||||
}
|
||||
|
||||
void
|
||||
AthleteCard::closing(QString name, Context *context)
|
||||
AthleteCard::closing(QString name, Context *)
|
||||
{
|
||||
if (name == path) {
|
||||
this->context = NULL;
|
||||
loadprogress = 0;
|
||||
button->setText("Open");
|
||||
update();
|
||||
}
|
||||
}
|
||||
@@ -139,6 +219,18 @@ AthleteCard::itemPaint(QPainter *painter, const QStyleOptionGraphicsItem *, QWid
|
||||
QRectF img(ROWHEIGHT,ROWHEIGHT*2,ROWHEIGHT* gl_avatar_width, ROWHEIGHT* gl_avatar_width);
|
||||
painter->drawImage(img, avatar);
|
||||
|
||||
// last workout if nothing recent
|
||||
if (/*maxy == 0 && */last != QDateTime() || count == 0) {
|
||||
QRectF rectf = QRectF(ROWHEIGHT,geometry().height()-(ROWHEIGHT*5), geometry().width()-(ROWHEIGHT*2), ROWHEIGHT*1.5);
|
||||
QString message;
|
||||
if (count == 0) message = "No activities.";
|
||||
else message = QString("Last workout %1 days ago").arg(last.daysTo(QDateTime::currentDateTime()));
|
||||
painter->setFont(parent->midfont);
|
||||
painter->setPen(QColor(150,150,150));
|
||||
painter->drawText(rectf, message, Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
}
|
||||
|
||||
|
||||
// load status
|
||||
QRectF progressbar(0, geometry().height()-gl_progress_width, geometry().width() * (loadprogress/100), gl_progress_width);
|
||||
painter->fillRect(progressbar, QBrush(GColor(CPLOTMARKER)));
|
||||
|
||||
@@ -23,11 +23,15 @@ class AthleteCard : public ChartSpaceItem
|
||||
AthleteCard(ChartSpace *parent, QString path);
|
||||
|
||||
void itemPaint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *);
|
||||
void itemGeometryChanged() {}
|
||||
void dragChanged(bool);
|
||||
void itemGeometryChanged();
|
||||
void setData(RideItem *) {}
|
||||
void setDateRange(DateRange) {}
|
||||
QWidget *config() { return new OverviewItemConfig(this); }
|
||||
|
||||
// refresh stats on last workouts etc
|
||||
void refreshStats();
|
||||
|
||||
// create and config
|
||||
static ChartSpaceItem *create(ChartSpace *parent) { return new AthleteCard(parent, ""); }
|
||||
|
||||
@@ -35,11 +39,19 @@ class AthleteCard : public ChartSpaceItem
|
||||
void opening(QString, Context*);
|
||||
void closing(QString, Context*);
|
||||
void loadProgress(QString, double);
|
||||
void loadDone(QString, Context*);
|
||||
|
||||
void clicked();
|
||||
|
||||
private:
|
||||
double loadprogress;
|
||||
Context *context;
|
||||
QString path;
|
||||
QImage avatar;
|
||||
Button *button;
|
||||
|
||||
// little graph of last 90 days
|
||||
int count; // total activities
|
||||
QDateTime last; // date of last activity recorded
|
||||
};
|
||||
|
||||
|
||||
@@ -236,6 +236,7 @@ ChartSpaceItem::sceneEvent(QEvent *event)
|
||||
bool
|
||||
ChartSpaceItem::inHotspot()
|
||||
{
|
||||
if (showconfig == false) return false;
|
||||
|
||||
QPoint vpos = parent->view->mapFromGlobal(QCursor::pos());
|
||||
QPointF spos = parent->view->mapToScene(vpos);
|
||||
@@ -248,6 +249,8 @@ ChartSpaceItem::inHotspot()
|
||||
bool
|
||||
ChartSpaceItem::inCorner()
|
||||
{
|
||||
if (showconfig == false) return false;
|
||||
|
||||
QPoint vpos = parent->view->mapFromGlobal(QCursor::pos());
|
||||
QPointF spos = parent->view->mapToScene(vpos);
|
||||
|
||||
@@ -296,33 +299,37 @@ ChartSpaceItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt, QW
|
||||
if (drag) return;
|
||||
|
||||
// not dragging so we can get to work painting the rest
|
||||
if (parent->state != ChartSpace::DRAG && underMouse()) {
|
||||
|
||||
if (inCorner()) {
|
||||
// config icon
|
||||
if (showconfig) {
|
||||
if (parent->state != ChartSpace::DRAG && underMouse()) {
|
||||
|
||||
// if hovering over the button show a background to indicate
|
||||
// that pressing a button is good
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(QRectF(geometry().width()-40-ROWHEIGHT,0,
|
||||
ROWHEIGHT+40, ROWHEIGHT+40), ROWHEIGHT/5, ROWHEIGHT/5);
|
||||
painter->setPen(Qt::NoPen);
|
||||
QColor darkgray(GColor(CCARDBACKGROUND).lighter(200));
|
||||
painter->setBrush(darkgray);
|
||||
painter->drawPath(path);
|
||||
painter->fillRect(QRectF(geometry().width()-40-ROWHEIGHT, 0, ROWHEIGHT+40-(ROWHEIGHT/5), ROWHEIGHT+40), QBrush(darkgray));
|
||||
painter->fillRect(QRectF(geometry().width()-40-ROWHEIGHT, ROWHEIGHT/5, ROWHEIGHT+40, ROWHEIGHT+40-(ROWHEIGHT/5)), QBrush(darkgray));
|
||||
if (inCorner()) {
|
||||
|
||||
// draw the config button and make it more obvious
|
||||
// when hovering over the card
|
||||
painter->drawPixmap(geometry().width()-20-(ROWHEIGHT*1), 20, ROWHEIGHT*1, ROWHEIGHT*1, accentConfig.pixmap(QSize(ROWHEIGHT*1, ROWHEIGHT*1)));
|
||||
// if hovering over the button show a background to indicate
|
||||
// that pressing a button is good
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(QRectF(geometry().width()-40-ROWHEIGHT,0,
|
||||
ROWHEIGHT+40, ROWHEIGHT+40), ROWHEIGHT/5, ROWHEIGHT/5);
|
||||
painter->setPen(Qt::NoPen);
|
||||
QColor darkgray(GColor(CCARDBACKGROUND).lighter(200));
|
||||
painter->setBrush(darkgray);
|
||||
painter->drawPath(path);
|
||||
painter->fillRect(QRectF(geometry().width()-40-ROWHEIGHT, 0, ROWHEIGHT+40-(ROWHEIGHT/5), ROWHEIGHT+40), QBrush(darkgray));
|
||||
painter->fillRect(QRectF(geometry().width()-40-ROWHEIGHT, ROWHEIGHT/5, ROWHEIGHT+40, ROWHEIGHT+40-(ROWHEIGHT/5)), QBrush(darkgray));
|
||||
|
||||
} else {
|
||||
// draw the config button and make it more obvious
|
||||
// when hovering over the card
|
||||
painter->drawPixmap(geometry().width()-20-(ROWHEIGHT*1), 20, ROWHEIGHT*1, ROWHEIGHT*1, accentConfig.pixmap(QSize(ROWHEIGHT*1, ROWHEIGHT*1)));
|
||||
|
||||
// hover on card - make it more obvious there is a config button
|
||||
painter->drawPixmap(geometry().width()-20-(ROWHEIGHT*1), 20, ROWHEIGHT*1, ROWHEIGHT*1, whiteConfig.pixmap(QSize(ROWHEIGHT*1, ROWHEIGHT*1)));
|
||||
}
|
||||
} else {
|
||||
|
||||
} else painter->drawPixmap(geometry().width()-20-(ROWHEIGHT*1), 20, ROWHEIGHT*1, ROWHEIGHT*1, grayConfig.pixmap(QSize(ROWHEIGHT*1, ROWHEIGHT*1)));
|
||||
// hover on card - make it more obvious there is a config button
|
||||
painter->drawPixmap(geometry().width()-20-(ROWHEIGHT*1), 20, ROWHEIGHT*1, ROWHEIGHT*1, whiteConfig.pixmap(QSize(ROWHEIGHT*1, ROWHEIGHT*1)));
|
||||
}
|
||||
|
||||
} else painter->drawPixmap(geometry().width()-20-(ROWHEIGHT*1), 20, ROWHEIGHT*1, ROWHEIGHT*1, grayConfig.pixmap(QSize(ROWHEIGHT*1, ROWHEIGHT*1)));
|
||||
}
|
||||
|
||||
// thin border
|
||||
if (!drag) {
|
||||
@@ -337,7 +344,10 @@ ChartSpaceItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt, QW
|
||||
painter->drawPath(path);
|
||||
}
|
||||
|
||||
// item paints itself and can completely repaint everything
|
||||
// including the title etc, in case this is useful
|
||||
itemPaint(painter, opt, widget);
|
||||
|
||||
}
|
||||
|
||||
static bool ChartSpaceItemSort(const ChartSpaceItem* left, const ChartSpaceItem* right)
|
||||
|
||||
@@ -66,13 +66,18 @@ class ChartSpaceItem : public QGraphicsWidget
|
||||
|
||||
virtual QWidget *config()=0; // must supply a widget to configure
|
||||
|
||||
// turn off/on the config corner button
|
||||
void setShowConfig(bool x) { showconfig=x; update(); }
|
||||
bool showConfig() const { return showconfig; }
|
||||
|
||||
// what type am I- managed by user
|
||||
int type;
|
||||
|
||||
ChartSpaceItem(ChartSpace *parent, QString name) : QGraphicsWidget(NULL),
|
||||
parent(parent), name(name),
|
||||
column(0), order(0), deep(5), onscene(false),
|
||||
placing(false), drag(false), invisible(false) {
|
||||
placing(false), drag(false), invisible(false),
|
||||
showconfig(true) {
|
||||
|
||||
setAutoFillBackground(false);
|
||||
setFlags(flags() | QGraphicsItem::ItemClipsToShape); // don't paint outside the card
|
||||
@@ -119,6 +124,7 @@ class ChartSpaceItem : public QGraphicsWidget
|
||||
bool onscene, placing, drag;
|
||||
bool incorner;
|
||||
bool invisible;
|
||||
bool showconfig;
|
||||
|
||||
// base paint
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *);
|
||||
|
||||
@@ -1727,6 +1727,9 @@ MainWindow::loadCompleted(QString name, Context *context)
|
||||
// to show it to avoid crappy paint artefacts
|
||||
showTabbar(true);
|
||||
|
||||
// tell everyone
|
||||
currentTab->context->notifyLoadDone(name, context);
|
||||
|
||||
// now do the automatic ride file import
|
||||
context->athlete->importFilesWhenOpeningAthlete();
|
||||
}
|
||||
@@ -1751,6 +1754,18 @@ MainWindow::closeTabClicked(int index)
|
||||
removeTab(tab);
|
||||
}
|
||||
|
||||
bool
|
||||
MainWindow::closeTab(QString name)
|
||||
{
|
||||
for(int i=0; i<tabbar->count(); i++) {
|
||||
if (name == tabbar->tabText(i)) {
|
||||
closeTabClicked(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
MainWindow::closeTab()
|
||||
{
|
||||
@@ -2157,10 +2172,8 @@ MainWindow::configChanged(qint32)
|
||||
tabbar->setShape(QTabBar::RoundedSouth);
|
||||
tabbar->setDrawBase(false);
|
||||
|
||||
if (GCColor::isFlat())
|
||||
tabbarPalette.setBrush(backgroundRole(), GColor(CCHROME));
|
||||
else
|
||||
tabbarPalette.setBrush(backgroundRole(), QColor("#B3B4B6"));
|
||||
tabbarPalette.setBrush(backgroundRole(), GColor(CCHROME));
|
||||
tabbarPalette.setBrush(foregroundRole(), GCColor::invertColor(GColor(CCHROME)));
|
||||
tabbar->setPalette(tabbarPalette);
|
||||
athleteView->setPalette(tabbarPalette);
|
||||
|
||||
|
||||
@@ -150,6 +150,7 @@ class MainWindow : public QMainWindow
|
||||
void openTab(QString name);
|
||||
void loadCompleted(QString name, Context *context);
|
||||
void closeTabClicked(int index); // user clicked to close tab
|
||||
bool closeTab(QString name); // close named athlete
|
||||
bool closeTab(); // close current, might not if the user
|
||||
// changes mind if there are unsaved changes.
|
||||
void removeTab(Tab*); // remove without question
|
||||
|
||||
Reference in New Issue
Block a user