1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
#ifndef HORIZONTAL_PLOT_SCALE_H
#define HORIZONTAL_PLOT_SCALE_H
#include "axis.h"
#include "linkable.h"
#include <gtkmm/drawingarea.h>
#include <array>
#include <memory>
#include <string>
#include <vector>
struct HorizontalPlotScaleData {
// These are set in initializeMetrics()
double plotWidth = 0.0, fromLeft = 0.0, rightMargin = 0.0;
bool metricsAreInitialized = false;
};
class HorizontalPlotScale
: public Linkable<HorizontalPlotScale, HorizontalPlotScaleData> {
public:
HorizontalPlotScale();
~HorizontalPlotScale();
void SetPlotDimensions(double widgetWidth, double widgetHeight,
double minFromLeft, double fromTop,
bool isSecondAxis) {
if (_widgetWidth != widgetWidth || _widgetHeight != widgetHeight ||
_minFromLeft != minFromLeft || _fromTop != fromTop ||
_isSecondAxis != isSecondAxis) {
_widgetWidth = widgetWidth;
_widgetHeight = widgetHeight;
_minFromLeft = minFromLeft;
_fromTop = fromTop;
_isSecondAxis = isSecondAxis;
Data().metricsAreInitialized = false;
}
}
double CalculateHeight(const Cairo::RefPtr<Cairo::Context>& cairo);
double RightMargin() { return Data().rightMargin; }
double FromLeft() const { return Data().fromLeft; }
double PlotWidth() const { return Data().plotWidth; }
void Draw(const Cairo::RefPtr<Cairo::Context>& cairo);
void SetAxisType(AxisType axisType) { _axisType = axisType; }
void SetTickLabels(const std::vector<std::pair<double, std::string>> labels) {
_tickLabels = std::move(labels);
}
void SetTickRange(double min, double max) {
_tickRange = std::array<double, 2>{min, max};
}
double GetTickRangeMin() const { return _tickRange[0]; }
double GetTickRangeMax() const { return _tickRange[1]; }
void SetLogarithmic(bool logarithmic) { _isLogarithmic = logarithmic; }
void InitializeTicks();
void SetDrawWithDescription(bool drawWithDescription) {
_drawWithDescription = drawWithDescription;
Data().metricsAreInitialized = false;
}
void SetUnitsCaption(const std::string& caption) {
_unitsCaption = caption;
Data().metricsAreInitialized = false;
}
void SetDescriptionFontSize(double fontSize) {
_tickValuesFontSize = fontSize;
Data().metricsAreInitialized = false;
}
void SetTickValuesFontSize(double fontSize) {
_tickValuesFontSize = fontSize;
Data().metricsAreInitialized = false;
}
void SetRotateUnits(bool rotate) {
_rotateUnits = rotate;
Data().metricsAreInitialized = false;
}
double UnitToAxis(double unitValue) const;
double AxisToUnit(double axisValue) const;
void CalculateScales(const Cairo::RefPtr<Cairo::Context>& cairo) {
initializeMetrics(cairo);
}
sigc::signal<void>& SignalLinkedRedraw() { return _signalLinkedRedraw; }
private:
void initializeNumericTicks(double min, double max);
void initializeTimeTicks(double timeMin, double timeMax);
void initializeTextTicks(const std::vector<std::string>& labels);
void drawDescription(const Cairo::RefPtr<Cairo::Context>& cairo);
bool ticksFit(const Cairo::RefPtr<Cairo::Context>& cairo);
void initializeMetrics(const Cairo::RefPtr<Cairo::Context>& cairo);
void initializeLocalMetrics(const Cairo::RefPtr<Cairo::Context>& cairo,
double& plotWidth, double& fromLeft,
double& rightMargin);
// These are set through SetDimensions()
double _widgetWidth, _widgetHeight, _minFromLeft, _fromTop;
bool _isSecondAxis;
std::unique_ptr<class TickSet> _tickSet;
AxisType _axisType;
std::array<double, 2> _tickRange;
std::vector<std::pair<double, std::string>> _tickLabels;
bool _isLogarithmic;
bool _rotateUnits;
bool _drawWithDescription;
std::string _unitsCaption;
double _descriptionFontSize;
double _tickValuesFontSize;
sigc::signal<void> _signalLinkedRedraw;
};
#endif
|