File indexing completed on 2024-05-12 04:43:04
0001 /*************************************************************************** 0002 * Copyright (C) 2018 by Emmanuel Lepage Vallee * 0003 * Author : Emmanuel Lepage Vallee <emmanuel.lepage@kde.org> * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 3 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0017 **************************************************************************/ 0018 #include "geometry_p.h" 0019 0020 #include <private/viewport_p.h> 0021 0022 #define S StateTracker::Geometry::State:: 0023 const StateTracker::Geometry::State StateTracker::Geometry::m_fStateMap[5][7] = { 0024 /* MOVE RESIZE PLACE RESET MODIFY DECORATE VIEW */ 0025 /*INIT */ { S INIT, S SIZE , S POSITION, S INIT, S INIT , S INIT , S INIT }, 0026 /*SIZE */ { S SIZE, S SIZE , S PENDING , S INIT, S SIZE , S SIZE , S SIZE }, 0027 /*POSITION */ { S INIT, S PENDING, S POSITION, S INIT, S POSITION, S POSITION, S POSITION }, 0028 /*PENDING */ { S SIZE, S PENDING, S PENDING , S INIT, S POSITION, S PENDING , S VALID }, 0029 /*VALID */ { S SIZE, S PENDING, S PENDING , S INIT, S POSITION, S PENDING , S VALID }, 0030 }; 0031 #undef S 0032 0033 #define A &StateTracker::Geometry:: 0034 const StateTracker::Geometry::StateF StateTracker::Geometry::m_fStateMachine[5][7] = { 0035 /* MOVE RESIZE PLACE RESET MODIFY DECORATE VIEW */ 0036 /*INIT */ { A nothing , A nothing , A nothing , A nothing , A nothing , A nothing , A error }, 0037 /*SIZE */ { A nothing , A dropSize , A nothing , A dropSize , A nothing , A nothing , A error }, 0038 /*POSITION */ { A invalidate, A nothing , A nothing , A dropPos , A nothing , A nothing , A error }, 0039 /*PENDING */ { A nothing , A nothing , A nothing , A invalidate, A invalidate, A nothing , A buildCache}, 0040 /*VALID */ { A nothing , A dropCache, A dropCache, A invalidate, A dropCache , A dropCache, A buildCache}, 0041 }; 0042 #undef A 0043 0044 void StateTracker::Geometry::nothing() 0045 {} 0046 0047 void StateTracker::Geometry::invalidate() 0048 { 0049 dropCache(); 0050 } 0051 0052 void StateTracker::Geometry::error() 0053 { 0054 Q_ASSERT(false); 0055 } 0056 0057 void StateTracker::Geometry::dropCache() 0058 { 0059 //TODO 0060 } 0061 0062 void StateTracker::Geometry::buildCache() 0063 { 0064 //TODO 0065 } 0066 0067 void StateTracker::Geometry::dropSize() 0068 { 0069 dropCache(); 0070 m_Size = {}; 0071 } 0072 0073 void StateTracker::Geometry::dropPos() 0074 { 0075 dropCache(); 0076 m_Position = {}; 0077 } 0078 0079 StateTracker::Geometry::State StateTracker::Geometry::performAction(IndexMetadata::GeometryAction a) 0080 { 0081 const int s = (int)m_State; 0082 m_State = m_fStateMap[s][(int)a]; 0083 0084 (this->*StateTracker::Geometry::m_fStateMachine[s][(int)a])(); 0085 0086 // Validate the state 0087 //BEGIN debug 0088 /*switch(m_State) { 0089 case StateTracker::Geometry::State::VALID: 0090 case StateTracker::Geometry::State::PENDING: 0091 Q_ASSERT(!(m_Position.x() == -1 && m_Position.y() == -1)); 0092 Q_ASSERT(m_Size.isValid()); 0093 break; 0094 case StateTracker::Geometry::State::SIZE: 0095 Q_ASSERT(m_Size.isValid()); 0096 break; 0097 case StateTracker::Geometry::State::POSITION: 0098 Q_ASSERT(!(m_Position.x() == -1 && m_Position.y() == -1)); 0099 break; 0100 case StateTracker::Geometry::State::INIT: 0101 break; 0102 }*/ 0103 //END debug 0104 0105 return m_State; 0106 } 0107 0108 QRectF StateTracker::Geometry::rawGeometry() const 0109 { 0110 const_cast<StateTracker::Geometry*>(this)->performAction(IndexMetadata::GeometryAction::VIEW); 0111 0112 Q_ASSERT(m_State == StateTracker::Geometry::State::VALID); 0113 0114 return QRectF(m_Position, m_Size); 0115 } 0116 0117 QRectF StateTracker::Geometry::contentGeometry() const 0118 { 0119 auto g = rawGeometry(); 0120 0121 g.setY(g.y() + borderDecoration( Qt::TopEdge )); 0122 g.setX(g.x() + borderDecoration( Qt::LeftEdge )); 0123 0124 return g; 0125 } 0126 0127 QRectF StateTracker::Geometry::decoratedGeometry() const 0128 { 0129 //TODO cache this, extend the state machine to have a "really valid" state 0130 auto g = rawGeometry(); 0131 0132 const auto topDeco = borderDecoration( Qt::TopEdge ); 0133 const auto botDeco = borderDecoration( Qt::BottomEdge ); 0134 const auto lefDeco = borderDecoration( Qt::LeftEdge ); 0135 const auto rigDeco = borderDecoration( Qt::RightEdge ); 0136 0137 g.setHeight(g.height() + topDeco + botDeco); 0138 g.setWidth (g.width () + lefDeco + rigDeco); 0139 0140 return g; 0141 } 0142 0143 QSizeF StateTracker::Geometry::size() const 0144 { 0145 Q_ASSERT(m_State != StateTracker::Geometry::State::INIT); 0146 Q_ASSERT(m_State != StateTracker::Geometry::State::POSITION); 0147 0148 return m_State == StateTracker::Geometry::State::SIZE ? 0149 m_Size : decoratedGeometry().size(); 0150 } 0151 0152 QPointF StateTracker::Geometry::position() const 0153 { 0154 return m_State == StateTracker::Geometry::State::POSITION ? 0155 m_Position : decoratedGeometry().topLeft(); 0156 } 0157 0158 void StateTracker::Geometry::setPosition(const QPointF& pos) 0159 { 0160 m_Position = pos; 0161 performAction(IndexMetadata::GeometryAction::PLACE); 0162 } 0163 0164 void StateTracker::Geometry::setSize(const QSizeF& size) 0165 { 0166 m_Size = size; 0167 performAction(IndexMetadata::GeometryAction::RESIZE); 0168 } 0169 0170 StateTracker::Geometry::State StateTracker::Geometry::state() const 0171 { 0172 return m_State; 0173 } 0174 0175 qreal StateTracker::Geometry::borderDecoration(Qt::Edge e) const 0176 { 0177 return m_lBorderDecoration.get(e); 0178 } 0179 0180 void StateTracker::Geometry::setBorderDecoration(Qt::Edge e, qreal r) 0181 { 0182 if (m_lBorderDecoration.get(e) == r) 0183 return; 0184 0185 m_lBorderDecoration.set(r, e); 0186 0187 performAction(IndexMetadata::GeometryAction::DECORATE); 0188 }