File indexing completed on 2024-04-28 16:45:07
0001 /* 0002 SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #pragma once 0007 0008 #include <kscreen/config.h> 0009 #include <kscreen/output.h> 0010 0011 #include <QAbstractListModel> 0012 #include <QPoint> 0013 #include <optional> 0014 0015 class ConfigHandler; 0016 0017 class OutputModel : public QAbstractListModel 0018 { 0019 Q_OBJECT 0020 public: 0021 enum OutputRoles { 0022 EnabledRole = Qt::UserRole + 1, 0023 InternalRole, 0024 PriorityRole, 0025 SizeRole, 0026 /** Position in the graphical view relative to some arbitrary but fixed origin. */ 0027 PositionRole, 0028 /** Position for backend relative to most northwest display corner. */ 0029 NormalizedPositionRole, 0030 AutoRotateRole, 0031 AutoRotateOnlyInTabletModeRole, 0032 RotationRole, 0033 ScaleRole, 0034 ResolutionIndexRole, 0035 ResolutionsRole, 0036 ResolutionRole, 0037 RefreshRateIndexRole, 0038 RefreshRatesRole, 0039 ReplicationSourceModelRole, 0040 ReplicationSourceIndexRole, 0041 ReplicasModelRole, 0042 CapabilitiesRole, 0043 OverscanRole, 0044 VrrPolicyRole, 0045 RgbRangeRole, 0046 InteractiveMoveRole, // This output is currently repositioned interactively 0047 }; 0048 0049 explicit OutputModel(ConfigHandler *configHandler); 0050 ~OutputModel() override = default; 0051 0052 int rowCount(const QModelIndex &parent = QModelIndex()) const override; 0053 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; 0054 bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; 0055 0056 void add(const KScreen::OutputPtr &output); 0057 void remove(int outputId); 0058 0059 /** 0060 * Resets the origin for calculation of positions to the most northwest display corner 0061 * while keeping the normalized positions untouched. 0062 * 0063 * @return true if some (unnormalized) output position changed on this call, otherwise false. 0064 */ 0065 bool normalizePositions(); 0066 bool positionsNormalized() const; 0067 0068 bool isMoving() const; 0069 0070 Q_SIGNALS: 0071 void positionChanged(); 0072 void sizeChanged(); 0073 0074 protected: 0075 QHash<int, QByteArray> roleNames() const override; 0076 0077 private: 0078 struct Output { 0079 Output() 0080 { 0081 } 0082 Output(const Output &output) 0083 : ptr(output.ptr) 0084 , pos(output.pos) 0085 { 0086 } 0087 Output(Output &&) noexcept = default; 0088 Output(KScreen::OutputPtr _ptr, const QPoint &_pos) 0089 : ptr(_ptr) 0090 , pos(_pos) 0091 { 0092 } 0093 Output &operator=(const Output &output) 0094 { 0095 ptr = output.ptr; 0096 pos = output.pos; 0097 posReset = std::nullopt; 0098 return *this; 0099 } 0100 Output &operator=(Output &&) noexcept = default; 0101 0102 KScreen::OutputPtr ptr; 0103 QPoint pos; 0104 // Indicates how to restore position when enabling or un-mirroring a screen. 0105 // Negative value of x means that the output was the left-most, and restoring it would require shifting all the other ones to the right. 0106 // Same for the y and shifting down. 0107 std::optional<QPoint> posReset = std::nullopt; 0108 bool moving = false; 0109 }; 0110 0111 void rolesChanged(int outputId, const QVector<int> &roles); 0112 QModelIndex indexForOutputId(int outputId) const; 0113 0114 void resetPosition(Output &output); 0115 void reposition(); 0116 void updatePositions(); 0117 0118 /** 0119 * @brief Snaps moved output to others 0120 * @param output the moved output 0121 * @param dest the desired destination to be adjusted by snapping 0122 */ 0123 void snap(const Output &output, QPoint &dest); 0124 void maintainSnapping(const Output &changedOutput, const QSize &oldSize, const QSize &newSize); 0125 QPoint mostTopLeftLocationOfPositionableOutputOptionallyIgnoringOneOfThem(std::optional<KScreen::OutputPtr> ignored = std::nullopt) const; 0126 0127 bool setEnabled(int outputIndex, bool enable); 0128 0129 bool setResolution(int outputIndex, int resIndex); 0130 bool setRefreshRate(int outputIndex, int refIndex); 0131 bool setRotation(int outputIndex, KScreen::Output::Rotation rotation); 0132 bool setAutoRotate(int outputIndex, bool value); 0133 bool setAutoRotateOnlyInTabletMode(int outputIndex, bool value); 0134 0135 int resolutionIndex(const KScreen::OutputPtr &output) const; 0136 int refreshRateIndex(const KScreen::OutputPtr &output) const; 0137 QSize resolution(const KScreen::OutputPtr &output) const; 0138 QVariantList resolutionsStrings(const KScreen::OutputPtr &output) const; 0139 QVector<QSize> resolutions(const KScreen::OutputPtr &output) const; 0140 QVector<float> refreshRates(const KScreen::OutputPtr &output) const; 0141 0142 bool positionable(const Output &output) const; 0143 0144 QStringList replicationSourceModel(const KScreen::OutputPtr &output) const; 0145 bool setReplicationSourceIndex(int outputIndex, int sourceIndex); 0146 int replicationSourceIndex(int outputIndex) const; 0147 int replicationSourceId(const Output &output) const; 0148 0149 QVariantList replicasModel(const KScreen::OutputPtr &output) const; 0150 0151 QVector<Output> m_outputs; 0152 0153 ConfigHandler *m_config; 0154 };