Adapting visual refinements from agenda in calendar (#4754)

* Adapting visual refinements from agenda in calendar

* Removed colored background for seasons and events (instead coloring
  the icons)
* Metric name shown in lighter font, removed brackets
* Added option (agenda and calendar) to remove the metric name
* Put settings of agenda in scrollarea to avoid squeezing

* Fixed clipping
This commit is contained in:
Joachim Kohlhammer
2025-12-14 13:37:37 +01:00
committed by GitHub
parent f17257885b
commit 2d0e2a9b7d
5 changed files with 113 additions and 55 deletions

View File

@@ -49,6 +49,7 @@ AgendaWindow::AgendaWindow(Context *context)
setPrimaryMainField("Route");
setPrimaryFallbackField("Workout Code");
setSecondaryMetric("workout_time");
setShowSecondaryLabel(true);
setTertiaryField("Notes");
setShowTertiaryFor(0);
setActivityMaxTertiaryLines(3);
@@ -193,6 +194,22 @@ AgendaWindow::getSecondaryMetric
}
void
AgendaWindow::setShowSecondaryLabel
(bool showSecondaryLabel)
{
showSecondaryLabelCheck->setChecked(showSecondaryLabel);
}
bool
AgendaWindow::isShowSecondaryLabel
() const
{
return showSecondaryLabelCheck->isChecked();
}
void
AgendaWindow::setShowTertiaryFor
(int showFor)
@@ -357,6 +374,7 @@ AgendaWindow::mkControls
primaryMainCombo = new QComboBox();
primaryFallbackCombo = new QComboBox();
secondaryCombo = new QComboBox();
showSecondaryLabelCheck = new QCheckBox(tr("Show Label"));
showTertiaryForCombo = new QComboBox();
tertiaryCombo = new QComboBox();
updatePrimaryConfigCombos();
@@ -388,20 +406,29 @@ AgendaWindow::mkControls
activityForm->addItem(new QSpacerItem(0, 20 * dpiYFactor));
activityForm->addRow(new QLabel(HLO + tr("Metric Line") + HLC));
activityForm->addRow(tr("Metric"), secondaryCombo);
activityForm->addRow("", showSecondaryLabelCheck);
activityForm->addItem(new QSpacerItem(0, 20 * dpiYFactor));
activityForm->addRow(new QLabel(HLO + tr("Detail Line") + HLC));
activityForm->addRow(tr("Show Line for"), showTertiaryForCombo);
activityForm->addRow(tr("Field"), tertiaryCombo);
activityForm->addRow(tr("Visible Lines"), activityMaxTertiaryLinesSpin);
QScrollArea *activityScroller = new QScrollArea();
activityScroller->setWidgetResizable(true);
activityScroller->setWidget(centerLayoutInWidget(activityForm, false));
QFormLayout *eventForm = newQFormLayout();
eventForm->setContentsMargins(0, 10 * dpiYFactor, 0, 10 * dpiYFactor);
eventForm->addRow(new QLabel(HLO + tr("Detail Line") + HLC));
eventForm->addRow(tr("Visible Lines"), eventMaxTertiaryLinesSpin);
QScrollArea *eventScroller = new QScrollArea();
eventScroller->setWidgetResizable(true);
eventScroller->setWidget(centerLayoutInWidget(eventForm, false));
QTabWidget *controlsTabs = new QTabWidget();
controlsTabs->addTab(centerLayoutInWidget(activityForm, false), tr("Activities"));
controlsTabs->addTab(centerLayoutInWidget(eventForm, false), tr("Events"));
controlsTabs->addTab(activityScroller, tr("Activities"));
controlsTabs->addTab(eventScroller, tr("Events"));
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
connect(agendaPastDaysSpin, QOverload<int>::of(&QSpinBox::valueChanged), this, &AgendaWindow::setAgendaPastDays);
@@ -424,6 +451,7 @@ AgendaWindow::mkControls
connect(activityMaxTertiaryLinesSpin, &QSpinBox::valueChanged, this, &AgendaWindow::setActivityMaxTertiaryLines);
connect(eventMaxTertiaryLinesSpin, &QSpinBox::valueChanged, this, &AgendaWindow::setEventMaxTertiaryLines);
#endif
connect(showSecondaryLabelCheck, &QCheckBox::toggled, this, &AgendaWindow::updateActivities);
setControls(controlsTabs);
}
@@ -546,9 +574,11 @@ AgendaWindow::getActivities
if (! rideMetricUnit.isEmpty()) {
activity.secondary += " " + rideMetricUnit;
}
activity.secondaryMetric = rideMetricName;
if (isShowSecondaryLabel()) {
activity.secondaryMetric = rideMetricName;
}
} else {
activity.secondary = "";
activity.secondary = tr("N/A");
activity.secondaryMetric = "";
}
if (showTertiaryFor == 0 || (showTertiaryFor == 1 && rideItem->dateTime.date() == today)) {
@@ -711,6 +741,10 @@ void
AgendaWindow::updateActivities
()
{
if (agendaView->selectedDate() != QDate::currentDate()) {
agendaView->updateDate();
return;
}
QHash<QDate, QList<CalendarEntry>> activities = getActivities(agendaView->firstVisibleDay(), agendaView->selectedDate(), agendaView->lastVisibleDay());
std::pair<QList<CalendarEntry>, QList<CalendarEntry>> phases;
QHash<QDate, QList<CalendarEntry>> events;

View File

@@ -43,6 +43,7 @@ class AgendaWindow : public GcChartWindow
Q_PROPERTY(QString primaryMainField READ getPrimaryMainField WRITE setPrimaryMainField USER true)
Q_PROPERTY(QString primaryFallbackField READ getPrimaryFallbackField WRITE setPrimaryFallbackField USER true)
Q_PROPERTY(QString secondaryMetric READ getSecondaryMetric WRITE setSecondaryMetric USER true)
Q_PROPERTY(bool showSecondaryLabel READ isShowSecondaryLabel WRITE setShowSecondaryLabel USER true)
Q_PROPERTY(int showTertiaryFor READ getShowTertiaryFor WRITE setShowTertiaryFor USER true)
Q_PROPERTY(QString tertiaryField READ getTertiaryField WRITE setTertiaryField USER true)
Q_PROPERTY(int activityMaxTertiaryLines READ getActivityMaxTertiaryLines WRITE setActivityMaxTertiaryLines USER true)
@@ -59,6 +60,7 @@ class AgendaWindow : public GcChartWindow
QString getPrimaryMainField() const;
QString getPrimaryFallbackField() const;
QString getSecondaryMetric() const;
bool isShowSecondaryLabel() const;
int getShowTertiaryFor() const;
QString getTertiaryField() const;
int getActivityMaxTertiaryLines() const;
@@ -70,6 +72,7 @@ class AgendaWindow : public GcChartWindow
void setPrimaryMainField(const QString &name);
void setPrimaryFallbackField(const QString &name);
void setSecondaryMetric(const QString &name);
void setShowSecondaryLabel(bool showSecondaryLabel);
void setShowTertiaryFor(int showFor);
void setTertiaryField(const QString &name);
void setActivityMaxTertiaryLines(int maxTertiaryLines);
@@ -88,6 +91,7 @@ class AgendaWindow : public GcChartWindow
QComboBox *primaryMainCombo;
QComboBox *primaryFallbackCombo;
QComboBox *secondaryCombo;
QCheckBox *showSecondaryLabelCheck;
QComboBox *showTertiaryForCombo;
QComboBox *tertiaryCombo;
QSpinBox *activityMaxTertiaryLinesSpin;

View File

@@ -45,6 +45,7 @@ CalendarWindow::CalendarWindow(Context *context)
setStartHour(8);
setEndHour(21);
setShowSecondaryLabel(true);
QVBoxLayout *mainLayout = new QVBoxLayout();
setChartLayout(mainLayout);
@@ -350,6 +351,14 @@ CalendarWindow::getSecondaryMetric
}
bool
CalendarWindow::isShowSecondaryLabel
() const
{
return showSecondaryLabelCheck->isChecked();
}
QString
CalendarWindow::getTertiaryField
() const
@@ -390,6 +399,14 @@ CalendarWindow::setSecondaryMetric
}
void
CalendarWindow::setShowSecondaryLabel
(bool showSecondaryLabel)
{
showSecondaryLabelCheck->setChecked(showSecondaryLabel);
}
void
CalendarWindow::setSummaryMetrics
(const QString &summaryMetrics)
@@ -512,6 +529,7 @@ CalendarWindow::mkControls
primaryMainCombo = new QComboBox();
primaryFallbackCombo = new QComboBox();
secondaryCombo = new QComboBox();
showSecondaryLabelCheck = new QCheckBox(tr("Show Label"));
tertiaryCombo = new QComboBox();
updatePrimaryConfigCombos();
updateSecondaryConfigCombo();
@@ -551,6 +569,7 @@ CalendarWindow::mkControls
entriesForm->addItem(new QSpacerItem(0, 20 * dpiYFactor));
entriesForm->addRow(new QLabel(HLO + tr("Metric Line") + HLC));
entriesForm->addRow(tr("Metric"), secondaryCombo);
entriesForm->addRow("", showSecondaryLabelCheck);
entriesForm->addItem(new QSpacerItem(0, 20 * dpiYFactor));
entriesForm->addRow(new QLabel(HLO + tr("Detail Line (Day and Week View only)") + HLC));
entriesForm->addRow(tr("Field"), tertiaryCombo);
@@ -582,6 +601,7 @@ CalendarWindow::mkControls
connect(summaryDayCheck, &QCheckBox::toggled, this, &CalendarWindow::setSummaryVisibleDay);
connect(summaryWeekCheck, &QCheckBox::toggled, this, &CalendarWindow::setSummaryVisibleWeek);
connect(summaryMonthCheck, &QCheckBox::toggled, this, &CalendarWindow::setSummaryVisibleMonth);
connect(showSecondaryLabelCheck, &QCheckBox::toggled, this, &CalendarWindow::updateActivities);
connect(multiMetricSelector, &MultiMetricSelector::selectedChanged, this, &CalendarWindow::updateActivities);
setControls(controlsTabs);
@@ -704,7 +724,9 @@ CalendarWindow::getActivities
if (! rideMetricUnit.isEmpty()) {
activity.secondary += " " + rideMetricUnit;
}
activity.secondaryMetric = rideMetricName;
if (isShowSecondaryLabel()) {
activity.secondaryMetric = rideMetricName;
}
} else {
activity.secondary = "";
activity.secondaryMetric = "";

View File

@@ -48,6 +48,7 @@ class CalendarWindow : public GcChartWindow
Q_PROPERTY(QString primaryMainField READ getPrimaryMainField WRITE setPrimaryMainField USER true)
Q_PROPERTY(QString primaryFallbackField READ getPrimaryFallbackField WRITE setPrimaryFallbackField USER true)
Q_PROPERTY(QString secondaryMetric READ getSecondaryMetric WRITE setSecondaryMetric USER true)
Q_PROPERTY(bool showSecondaryLabel READ isShowSecondaryLabel WRITE setShowSecondaryLabel USER true)
Q_PROPERTY(QString tertiaryField READ getTertiaryField WRITE setTertiaryField USER true)
Q_PROPERTY(QString summaryMetrics READ getSummaryMetrics WRITE setSummaryMetrics USER true)
@@ -67,6 +68,7 @@ class CalendarWindow : public GcChartWindow
QString getPrimaryMainField() const;
QString getPrimaryFallbackField() const;
QString getSecondaryMetric() const;
bool isShowSecondaryLabel() const;
QString getTertiaryField() const;
QString getSummaryMetrics() const;
QStringList getSummaryMetricsList() const;
@@ -82,6 +84,7 @@ class CalendarWindow : public GcChartWindow
void setPrimaryMainField(const QString &name);
void setPrimaryFallbackField(const QString &name);
void setSecondaryMetric(const QString &name);
void setShowSecondaryLabel(bool showSecondaryLabel);
void setTertiaryField(const QString &name);
void setSummaryMetrics(const QString &summaryMetrics);
void setSummaryMetrics(const QStringList &summaryMetrics);
@@ -106,6 +109,7 @@ class CalendarWindow : public GcChartWindow
QComboBox *primaryMainCombo;
QComboBox *primaryFallbackCombo;
QComboBox *secondaryCombo;
QCheckBox *showSecondaryLabelCheck;
QComboBox *tertiaryCombo;
MultiMetricSelector *multiMetricSelector;
Calendar *calendar = nullptr;

View File

@@ -36,6 +36,7 @@ static bool toolTipHeadlineEntry(const QPoint &pos, QAbstractItemView *view, con
static bool toolTipDayEntry(const QPoint &pos, QAbstractItemView *view, const CalendarDay &day, int idx);
static bool toolTipMore(const QPoint &pos, QAbstractItemView *view, const CalendarDay &day);
static QRect paintHeadline(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &index, HitTester &headlineTester, const QString &dateFormat, int pressedEntryIdx, int leftMargin, int rightMargin, int topMargin, int lineSpacing, int radius);
static void paintMetric(QPainter *painter, const QRect &rect, const QFont::Weight &valueWeight, const QFont::Weight &labelWeight, const QString &value, const QString &label);
//////////////////////////////////////////////////////////////////////////////
@@ -463,11 +464,7 @@ CalendarDetailedDayDelegate::paint
painter->drawText(textRect, Qt::AlignLeft | Qt::AlignTop, entry.primary);
if (--numLines > 0 && ! entry.secondary.isEmpty()) {
textRect.translate(0, lineHeight + priSecSpacing);
if (! entry.secondaryMetric.isEmpty()) {
painter->drawText(textRect, Qt::AlignLeft | Qt::AlignTop, entry.secondary + " (" + entry.secondaryMetric + ")");
} else {
painter->drawText(textRect, Qt::AlignLeft | Qt::AlignTop, entry.secondary);
}
paintMetric(painter, textRect, QFont::Normal, QFont::ExtraLight, entry.secondary, entry.secondaryMetric);
}
if (--numLines > 0 && ! entry.tertiary.isEmpty()) {
QRect tertiaryRect(left + horPadding,
@@ -875,7 +872,7 @@ CalendarCompactDayDelegate::paint
titleRect.y() + lineSpacing + lineHeight,
titleRect.width(),
titleRect.height());
painter->drawText(subRect, Qt::AlignLeft | Qt::AlignTop, calEntry.secondary + " (" + calEntry.secondaryMetric + ")");
paintMetric(painter, subRect, QFont::Normal, QFont::ExtraLight, calEntry.secondary, calEntry.secondaryMetric);
}
painter->restore();
@@ -1340,51 +1337,23 @@ AgendaEntryDelegate::paint
painter->drawText(textRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextDontClip, primary);
painter->restore();
if (! entry.secondary.isEmpty()) {
painter->save();
QFont metricValueFont = painter->font();
metricValueFont.setWeight(secondaryWeight);
QFontMetrics metricValueFM(metricValueFont);
painter->setFont(metricValueFont);
textRect.translate(0, lineHeight + lineSpacing);
QRect secRect = metricValueFM.boundingRect(entry.secondary);
secRect.setRect(textRect.x(), textRect.y(), secRect.width(), secRect.height());
painter->drawText(secRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextDontClip, entry.secondary);
paintMetric(painter, textRect, secondaryWeight, secondaryMetricWeight, entry.secondary, entry.secondaryMetric);
}
if (! entry.tertiary.isEmpty()) {
painter->save();
painter->setPen(GCColor::inactiveColor(painter->pen().color(), attributes.tertiaryDimLevel));
int y = opt.rect.y() + attributes.padding.top() + pixmapSize.height() + 2 * lineSpacing;
QStringList tertiaryLines;
int numLines;
int tertiaryHeight;
layoutTertiaryText(entry.tertiary, opt.font, textWidth, numLines, tertiaryHeight, &tertiaryLines, true);
QRect tertiaryRect(textX, y, textWidth, lineHeight);
for (const QString &tertiaryLine : tertiaryLines) {
painter->drawText(tertiaryRect, Qt::AlignLeft | Qt::AlignTop, tertiaryLine);
tertiaryRect.translate(0, lineHeight);
}
painter->restore();
if (! entry.secondaryMetric.isEmpty()) {
painter->save();
QFont metricLabelFont = painter->font();
metricLabelFont.setWeight(secondaryMetricWeight);
QFontMetrics metricLabelFM(metricLabelFont);
painter->setFont(metricLabelFont);
int remainingWidth = opt.rect.x() + opt.rect.width() - secRect.right() - attributes.padding.left() - attributes.padding.right();
QString txt = " " + entry.secondaryMetric;
QRect secMetricRect = metricLabelFM.boundingRect(txt);
if (secMetricRect.width() > remainingWidth) {
txt = metricLabelFM.elidedText(txt, Qt::ElideRight, remainingWidth);
}
secMetricRect.setRect(secRect.x() + secRect.width() + 2 * dpiXFactor,
secRect.y(),
remainingWidth,
secMetricRect.height());
painter->drawText(secMetricRect, Qt::AlignLeft | Qt::AlignTop, txt);
painter->restore();
}
if (! entry.tertiary.isEmpty()) {
painter->save();
painter->setPen(GCColor::inactiveColor(painter->pen().color(), attributes.tertiaryDimLevel));
int y = opt.rect.y() + attributes.padding.top() + pixmapSize.height() + 2 * lineSpacing;
QStringList tertiaryLines;
int numLines;
int tertiaryHeight;
layoutTertiaryText(entry.tertiary, opt.font, textWidth, numLines, tertiaryHeight, &tertiaryLines, true);
QRect tertiaryRect(textX, y, textWidth, lineHeight);
for (const QString &tertiaryLine : tertiaryLines) {
painter->drawText(tertiaryRect, Qt::AlignLeft | Qt::AlignTop, tertiaryLine);
tertiaryRect.translate(0, lineHeight);
}
painter->restore();
}
}
painter->restore();
@@ -1772,6 +1741,7 @@ paintHeadline
CalendarDay calendarDay = index.data(CalendarHeadlineDelegate::DayRole).value<CalendarDay>();
QColor dayColor;
bool isToday = (calendarDay.date == QDate::currentDate());
bool selected = false;
QLocale locale;
QString dateText = locale.toString(calendarDay.date, dateFormat);
@@ -1802,6 +1772,7 @@ paintHeadline
} else {
dayColor = opt.palette.color((calendarDay.isDimmed == DayDimLevel::Full || calendarDay.isDimmed == DayDimLevel::Partial) ? QPalette::Disabled : QPalette::Active, QPalette::Text);
}
selected = pressedEntryIdx < 0 && opt.state & QStyle::State_Selected;
painter->setFont(dayFont);
painter->setPen(dayColor);
@@ -1814,7 +1785,7 @@ paintHeadline
if (x < dayRect.x() + dayRect.width() + lineSpacing) {
break;
}
QPixmap pixmap = svgOnBackground(calEntry.iconFile, QSize(lineHeight, lineHeight), 0, calEntry.color, radius);
QPixmap pixmap = svgAsColoredPixmap(calEntry.iconFile, QSize(lineHeight, lineHeight), 0, selected ? dayColor : calEntry.color);
QRect headlineEntryRect(x, opt.rect.y() + topMargin, lineHeight, lineHeight);
painter->drawPixmap(x, opt.rect.y() + topMargin, pixmap);
headlineTester.append(index, headlineEntryRect);
@@ -1822,3 +1793,26 @@ paintHeadline
return dayRect;
}
static void
paintMetric
(QPainter *painter, const QRect &rect, const QFont::Weight &valueWeight, const QFont::Weight &labelWeight, const QString &value, const QString &label)
{
painter->save();
QFont font = painter->font();
font.setWeight(valueWeight);
painter->setFont(font);
QFontMetrics valueFM(font);
int valueWidth = valueFM.horizontalAdvance(value);
painter->drawText(rect, Qt::AlignLeft | Qt::AlignTop, value);
if (! label.isEmpty()) {
QRect labelRect(rect);
labelRect.setX(rect.x() + valueWidth + valueFM.horizontalAdvance(" "));
font.setWeight(labelWeight);
QFontMetrics labelFM(font);
painter->setFont(font);
painter->drawText(labelRect, Qt::AlignLeft | Qt::AlignTop, label);
}
painter->restore();
}