File indexing completed on 2025-01-26 03:34:03

0001 /*
0002     File                 : Axis.h
0003     Project              : LabPlot
0004     Description          : Axis for cartesian coordinate systems.
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2009 Tilman Benkert <thzs@gmx.net>
0007     SPDX-FileCopyrightText: 2011-2022 Alexander Semke <alexander.semke@web.de>
0008     SPDX-FileCopyrightText: 2013-2021 Stefan Gerlach <stefan.gerlach@uni.kn>
0009 
0010     SPDX-License-Identifier: GPL-2.0-or-later
0011 */
0012 
0013 #ifndef AXISNEW_H
0014 #define AXISNEW_H
0015 
0016 #include "backend/lib/Range.h"
0017 #include "backend/worksheet/WorksheetElement.h"
0018 #include "backend/worksheet/plots/cartesian/CartesianCoordinateSystem.h"
0019 
0020 class CartesianPlot;
0021 class Line;
0022 class TextLabel;
0023 class AxisPrivate;
0024 class AbstractColumn;
0025 class QActionGroup;
0026 
0027 using Dimension = CartesianCoordinateSystem::Dimension;
0028 
0029 class Axis : public WorksheetElement {
0030     Q_OBJECT
0031 
0032 public:
0033     enum class RangeType { Auto, AutoData, Custom };
0034     enum class Position { Top, Bottom, Left, Right, Centered, Custom, Logical };
0035     enum class LabelsFormat { Decimal, ScientificE, Powers10, Powers2, PowersE, MultipliesPi, Scientific };
0036     Q_ENUM(LabelsFormat)
0037     enum TicksFlags {
0038         noTicks = 0x00,
0039         ticksIn = 0x01,
0040         ticksOut = 0x02,
0041         ticksBoth = 0x03,
0042     };
0043     Q_DECLARE_FLAGS(TicksDirection, TicksFlags)
0044 
0045     enum class TicksType { TotalNumber, Spacing, CustomColumn, CustomValues, ColumnLabels };
0046     Q_ENUM(TicksType)
0047     enum class ArrowType { NoArrow, SimpleSmall, SimpleBig, FilledSmall, FilledBig, SemiFilledSmall, SemiFilledBig };
0048     enum class ArrowPosition { Left, Right, Both };
0049     enum class LabelsPosition { NoLabels, In, Out };
0050     enum class LabelsTextType { PositionValues, CustomValues };
0051     enum class LabelsBackgroundType { Transparent, Color };
0052 
0053     enum class TicksStartType { Absolute, Offset };
0054 
0055     // LabelsFormat <-> index, see AxisDock::init()
0056     static int labelsFormatToIndex(LabelsFormat format) {
0057         switch (format) {
0058         case LabelsFormat::Decimal:
0059             return 0;
0060         case LabelsFormat::Scientific:
0061             return 1;
0062         case LabelsFormat::ScientificE:
0063             return 2;
0064         case LabelsFormat::Powers10:
0065             return 3;
0066         case LabelsFormat::Powers2:
0067             return 4;
0068         case LabelsFormat::PowersE:
0069             return 5;
0070         case LabelsFormat::MultipliesPi:
0071             return 6;
0072         }
0073         return 0;
0074     }
0075     static LabelsFormat indexToLabelsFormat(int index) {
0076         switch (index) {
0077         case 0:
0078             return LabelsFormat::Decimal;
0079         case 1:
0080             return LabelsFormat::Scientific;
0081         case 2:
0082             return LabelsFormat::ScientificE;
0083         case 3:
0084             return LabelsFormat::Powers10;
0085         case 4:
0086             return LabelsFormat::Powers2;
0087         case 5:
0088             return LabelsFormat::PowersE;
0089         case 6:
0090             return LabelsFormat::MultipliesPi;
0091         }
0092         return LabelsFormat::Decimal;
0093     }
0094 
0095     typedef AxisPrivate Private; // for Axis::Private used in macros instead of AxisPrivate
0096 
0097     explicit Axis(const QString&, Orientation = Orientation::Horizontal);
0098     ~Axis() override;
0099 
0100     QIcon icon() const override;
0101     QMenu* createContextMenu() override;
0102     void setZValue(qreal) override;
0103 
0104     void save(QXmlStreamWriter*) const override;
0105     bool load(XmlStreamReader*, bool preview) override;
0106     void loadThemeConfig(const KConfig&) override;
0107     void saveThemeConfig(const KConfig&) override;
0108 
0109     BASIC_D_ACCESSOR_DECL(RangeType, rangeType, RangeType)
0110     BASIC_D_ACCESSOR_DECL(Orientation, orientation, Orientation)
0111     BASIC_D_ACCESSOR_DECL(Position, position, Position)
0112     BASIC_D_ACCESSOR_DECL(Range<double>, range, Range)
0113     BASIC_D_ACCESSOR_DECL(bool, rangeScale, RangeScale) // if true, the scale of the range will be used
0114     BASIC_D_ACCESSOR_DECL(RangeT::Scale, scale, Scale)
0115     void setStart(const double);
0116     void setEnd(const double);
0117     void setRange(const double, const double);
0118     void setOffset(const double, const bool = true);
0119     double offset() const;
0120     BASIC_D_ACCESSOR_DECL(qreal, scalingFactor, ScalingFactor)
0121     BASIC_D_ACCESSOR_DECL(qreal, zeroOffset, ZeroOffset)
0122     BASIC_D_ACCESSOR_DECL(bool, showScaleOffset, ShowScaleOffset)
0123     BASIC_D_ACCESSOR_DECL(double, logicalPosition, LogicalPosition)
0124 
0125     POINTER_D_ACCESSOR_DECL(TextLabel, title, Title)
0126     BASIC_D_ACCESSOR_DECL(double, titleOffsetX, TitleOffsetX)
0127     BASIC_D_ACCESSOR_DECL(double, titleOffsetY, TitleOffsetY)
0128 
0129     Line* line() const;
0130     BASIC_D_ACCESSOR_DECL(ArrowType, arrowType, ArrowType)
0131     BASIC_D_ACCESSOR_DECL(ArrowPosition, arrowPosition, ArrowPosition)
0132     BASIC_D_ACCESSOR_DECL(double, arrowSize, ArrowSize)
0133 
0134     BASIC_D_ACCESSOR_DECL(TicksDirection, majorTicksDirection, MajorTicksDirection)
0135     BASIC_D_ACCESSOR_DECL(TicksType, majorTicksType, MajorTicksType)
0136     BASIC_D_ACCESSOR_DECL(bool, majorTicksAutoNumber, MajorTicksAutoNumber)
0137     int majorTicksNumber() const;
0138     void setMajorTicksNumber(const int number, bool automatic = false);
0139     BASIC_D_ACCESSOR_DECL(qreal, majorTicksSpacing, MajorTicksSpacing)
0140     BASIC_D_ACCESSOR_DECL(TicksStartType, majorTicksStartType, MajorTicksStartType)
0141     BASIC_D_ACCESSOR_DECL(qreal, majorTickStartOffset, MajorTickStartOffset)
0142     BASIC_D_ACCESSOR_DECL(qreal, majorTickStartValue, MajorTickStartValue)
0143     POINTER_D_ACCESSOR_DECL(const AbstractColumn, majorTicksColumn, MajorTicksColumn)
0144     QString& majorTicksColumnPath() const;
0145     Line* majorTicksLine() const;
0146     BASIC_D_ACCESSOR_DECL(qreal, majorTicksLength, MajorTicksLength)
0147 
0148     BASIC_D_ACCESSOR_DECL(TicksDirection, minorTicksDirection, MinorTicksDirection)
0149     BASIC_D_ACCESSOR_DECL(TicksType, minorTicksType, MinorTicksType)
0150     BASIC_D_ACCESSOR_DECL(bool, minorTicksAutoNumber, MinorTicksAutoNumber)
0151     BASIC_D_ACCESSOR_DECL(int, minorTicksNumber, MinorTicksNumber)
0152     BASIC_D_ACCESSOR_DECL(qreal, minorTicksSpacing, MinorTicksSpacing)
0153     POINTER_D_ACCESSOR_DECL(const AbstractColumn, minorTicksColumn, MinorTicksColumn)
0154     QString& minorTicksColumnPath() const;
0155     Line* minorTicksLine() const;
0156     BASIC_D_ACCESSOR_DECL(qreal, minorTicksLength, MinorTicksLength)
0157 
0158     BASIC_D_ACCESSOR_DECL(LabelsFormat, labelsFormat, LabelsFormat)
0159     BASIC_D_ACCESSOR_DECL(bool, labelsFormatAuto, LabelsFormatAuto)
0160     BASIC_D_ACCESSOR_DECL(bool, labelsAutoPrecision, LabelsAutoPrecision)
0161     BASIC_D_ACCESSOR_DECL(int, labelsPrecision, LabelsPrecision)
0162     CLASS_D_ACCESSOR_DECL(QString, labelsDateTimeFormat, LabelsDateTimeFormat)
0163     BASIC_D_ACCESSOR_DECL(LabelsPosition, labelsPosition, LabelsPosition)
0164     BASIC_D_ACCESSOR_DECL(qreal, labelsOffset, LabelsOffset)
0165     BASIC_D_ACCESSOR_DECL(qreal, labelsRotationAngle, LabelsRotationAngle)
0166     BASIC_D_ACCESSOR_DECL(LabelsTextType, labelsTextType, LabelsTextType)
0167     POINTER_D_ACCESSOR_DECL(const AbstractColumn, labelsTextColumn, LabelsTextColumn)
0168     QString& labelsTextColumnPath() const;
0169     QVector<double> tickLabelValues() const;
0170     QVector<QString> tickLabelStrings() const;
0171     CLASS_D_ACCESSOR_DECL(QColor, labelsColor, LabelsColor)
0172     CLASS_D_ACCESSOR_DECL(QFont, labelsFont, LabelsFont)
0173     BASIC_D_ACCESSOR_DECL(LabelsBackgroundType, labelsBackgroundType, LabelsBackgroundType)
0174     CLASS_D_ACCESSOR_DECL(QColor, labelsBackgroundColor, LabelsBackgroundColor)
0175     CLASS_D_ACCESSOR_DECL(QString, labelsPrefix, LabelsPrefix)
0176     CLASS_D_ACCESSOR_DECL(QString, labelsSuffix, LabelsSuffix)
0177     BASIC_D_ACCESSOR_DECL(qreal, labelsOpacity, LabelsOpacity)
0178     static int maxNumberMajorTicksCustomColumn();
0179 
0180     Line* majorGridLine() const;
0181     Line* minorGridLine() const;
0182 
0183     bool isNumeric() const;
0184 
0185     void setDefault(bool);
0186     bool isDefault() const;
0187 
0188     bool isHovered() const;
0189     void setSuppressRetransform(bool);
0190     void retransform() override;
0191     void retransformTickLabelStrings();
0192     void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override;
0193 
0194 protected:
0195     Axis(const QString&, Orientation, AxisPrivate*);
0196     TextLabel* m_title{nullptr};
0197 
0198 private:
0199     Q_DECLARE_PRIVATE(Axis)
0200     void init(Orientation);
0201     void initActions();
0202     void initMenus();
0203 
0204     QAction* orientationHorizontalAction{nullptr};
0205     QAction* orientationVerticalAction{nullptr};
0206 
0207     QActionGroup* orientationActionGroup{nullptr};
0208     QActionGroup* lineStyleActionGroup{nullptr};
0209     QActionGroup* lineColorActionGroup{nullptr};
0210 
0211     QMenu* orientationMenu{nullptr};
0212     QMenu* lineMenu{nullptr};
0213     QMenu* lineStyleMenu{nullptr};
0214     QMenu* lineColorMenu{nullptr};
0215 
0216 private Q_SLOTS:
0217     void labelChanged();
0218     void retransformTicks();
0219     void majorTicksColumnAboutToBeRemoved(const AbstractAspect*);
0220     void minorTicksColumnAboutToBeRemoved(const AbstractAspect*);
0221 
0222     // SLOTs for changes triggered via QActions in the context menu
0223     void orientationChangedSlot(QAction*);
0224     void lineStyleChanged(QAction*);
0225     void lineColorChanged(QAction*);
0226 
0227 Q_SIGNALS:
0228     void orientationChanged(Orientation);
0229     void positionChanged(Position);
0230     void positionChanged(double);
0231     void scaleChanged(RangeT::Scale);
0232     void rangeScaleChanged(bool);
0233     void startChanged(double);
0234     void rangeTypeChanged(RangeType);
0235     void endChanged(double);
0236     void rangeChanged(Range<double>);
0237     void zeroOffsetChanged(qreal);
0238     void scalingFactorChanged(qreal);
0239     void showScaleOffsetChanged(bool);
0240     void logicalPositionChanged(double);
0241     void shiftSignal(int delta, Dimension dim, int index);
0242 
0243     // title
0244     void titleOffsetXChanged(qreal);
0245     void titleOffsetYChanged(qreal);
0246 
0247     // line
0248     void arrowTypeChanged(ArrowType);
0249     void arrowPositionChanged(ArrowPosition);
0250     void arrowSizeChanged(qreal);
0251 
0252     // major ticks
0253     void majorTicksDirectionChanged(TicksDirection);
0254     void majorTicksTypeChanged(TicksType);
0255     void majorTicksAutoNumberChanged(bool);
0256     void majorTicksNumberChanged(int);
0257     void majorTicksSpacingChanged(qreal);
0258     void majorTicksColumnChanged(const AbstractColumn*);
0259     void majorTicksStartTypeChanged(TicksStartType);
0260     void majorTickStartOffsetChanged(qreal);
0261     void majorTickStartValueChanged(qreal);
0262     void majorTicksLengthChanged(qreal);
0263 
0264     // minor ticks
0265     void minorTicksDirectionChanged(TicksDirection);
0266     void minorTicksTypeChanged(TicksType);
0267     void minorTicksAutoNumberChanged(bool);
0268     void minorTicksNumberChanged(int);
0269     void minorTicksIncrementChanged(qreal);
0270     void minorTicksColumnChanged(const AbstractColumn*);
0271     void minorTicksLengthChanged(qreal);
0272 
0273     // labels
0274     void labelsFormatChanged(LabelsFormat);
0275     void labelsFormatAutoChanged(bool);
0276     void labelsAutoPrecisionChanged(bool);
0277     void labelsPrecisionChanged(int);
0278     void labelsDateTimeFormatChanged(const QString&);
0279     void labelsPositionChanged(LabelsPosition);
0280     void labelsOffsetChanged(double);
0281     void labelsRotationAngleChanged(qreal);
0282     void labelsTextTypeChanged(LabelsTextType);
0283     void labelsTextColumnChanged(const AbstractColumn*);
0284     void labelsColorChanged(QColor);
0285     void labelsFontChanged(QFont);
0286     void labelsBackgroundTypeChanged(LabelsBackgroundType);
0287     void labelsBackgroundColorChanged(QColor);
0288     void labelsPrefixChanged(QString);
0289     void labelsSuffixChanged(QString);
0290     void labelsOpacityChanged(qreal);
0291 
0292     friend class RetransformTest;
0293     friend class AxisTest;
0294     friend class AxisTest2;
0295     friend class AxisTest3;
0296 };
0297 
0298 Q_DECLARE_OPERATORS_FOR_FLAGS(Axis::TicksDirection)
0299 
0300 #endif