summaryrefslogtreecommitdiffstats
path: root/stats
diff options
context:
space:
mode:
Diffstat (limited to 'stats')
-rw-r--r--stats/legend.cpp41
-rw-r--r--stats/legend.h5
-rw-r--r--stats/statsview.cpp9
3 files changed, 43 insertions, 12 deletions
diff --git a/stats/legend.cpp b/stats/legend.cpp
index 590de21b0..d0a5c19b1 100644
--- a/stats/legend.cpp
+++ b/stats/legend.cpp
@@ -3,6 +3,7 @@
#include "statscolors.h"
#include "zvalues.h"
+#include <cmath>
#include <QFontMetrics>
#include <QPen>
@@ -18,7 +19,8 @@ Legend::Legend(StatsView &view, const std::vector<QString> &names) :
ChartRectItem(view, ChartZValue::Legend,
QPen(legendBorderColor, legendBorderSize), QBrush(legendColor), legendBoxBorderRadius),
displayedItems(0), width(0.0), height(0.0),
- font(QFont()) // Make configurable
+ font(QFont()), // Make configurable
+ posInitialized(false)
{
entries.reserve(names.size());
QFontMetrics fm(font);
@@ -103,7 +105,38 @@ void Legend::resize()
painter->drawText(rect, entries[i].name);
}
- // For now, place the legend in the top right corner.
- QPointF pos(size.width() - width - 10.0, 10.0);
- setPos(pos);
+ if (!posInitialized) {
+ // At first, place in top right corner
+ setPos(QPointF(size.width() - width - 10.0, 10.0));
+ posInitialized = true;
+ } else {
+ // Try to keep relative position with what it was before
+ setPos(QPointF(size.width() * centerPos.x() - width / 2.0,
+ size.height() * centerPos.y() - height / 2.0));
+ }
+}
+
+void Legend::setPos(QPointF newPos)
+{
+ // Round the position to integers or horrible artifacts appear (at least on desktop)
+ QPointF posInt(round(newPos.x()), round(newPos.y()));
+
+ // Make sure that the center is inside the drawing area,
+ // so that the user can't lose the legend.
+ QSizeF size = sceneSize();
+ if (size.width() < 1.0 || size.height() < 1.0)
+ return;
+ double widthHalf = floor(width / 2.0);
+ double heightHalf = floor(height / 2.0);
+ QPointF sanitizedPos(std::clamp(posInt.x(), -widthHalf, size.width() - widthHalf - 1.0),
+ std::clamp(posInt.y(), -heightHalf, size.height() - heightHalf - 1.0));
+
+ // Set position
+ ChartRectItem::setPos(sanitizedPos);
+
+ // Remember relative position of center for next time
+ QPointF centerPosAbsolute(sanitizedPos.x() + width / 2.0,
+ sanitizedPos.y() + height / 2.0);
+ centerPos = QPointF(centerPosAbsolute.x() / size.width(),
+ centerPosAbsolute.y() / size.height());
}
diff --git a/stats/legend.h b/stats/legend.h
index 1e38f705a..fb88920bd 100644
--- a/stats/legend.h
+++ b/stats/legend.h
@@ -15,6 +15,7 @@ class Legend : public ChartRectItem {
public:
Legend(StatsView &view, const std::vector<QString> &names);
void resize(); // called when the chart size changes.
+ void setPos(QPointF pos); // Attention: not virtual - always call on this class.
private:
// Each entry is a text besides a rectangle showing the color
struct Entry {
@@ -28,6 +29,10 @@ private:
double width;
double height;
QFont font;
+ // The position is specified with respect to the center and in relative terms
+ // with respect to the canvas.
+ QPointF centerPos;
+ bool posInitialized;
int fontHeight;
std::vector<Entry> entries;
void hide();
diff --git a/stats/statsview.cpp b/stats/statsview.cpp
index 983b128fe..f07b00896 100644
--- a/stats/statsview.cpp
+++ b/stats/statsview.cpp
@@ -236,14 +236,7 @@ void StatsView::mouseMoveEvent(QMouseEvent *event)
QSizeF sceneSize = size();
if (sceneSize.width() <= 1.0 || sceneSize.height() <= 1.0)
return;
- QPointF pos = event->pos() - dragStartMouse + dragStartItem;;
- QSizeF itemSize = draggedItem->getRect().size();
- double widthHalf = floor(itemSize.width() / 2);
- double heightHalf = floor(itemSize.height() / 2);
- QSizeF itemSizeHalf(floor(itemSize.width() / 2), floor(itemSize.height() / 2));
- QPointF sanitizedPos(std::clamp(pos.x(), -widthHalf, sceneSize.width() - widthHalf - 1.0),
- std::clamp(pos.y(), -heightHalf, sceneSize.height() - heightHalf - 1.0));
- draggedItem->setPos(sanitizedPos);
+ draggedItem->setPos(event->pos() - dragStartMouse + dragStartItem);
update();
}