File indexing completed on 2024-04-14 05:45:55
0001 /* 0002 This file is part of the Okteta Gui library, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2003, 2009 Friedrich W. H. Kossebau <kossebau@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #ifndef OKTETA_COORD_HPP 0010 #define OKTETA_COORD_HPP 0011 0012 // lib 0013 #include "lineposition.hpp" 0014 #include "line.hpp" 0015 // Okteta core 0016 #include <Okteta/Address> 0017 #include <Okteta/Size> 0018 0019 namespace Okteta { 0020 0021 /** 0022 * a class which represents a coord in a 2-dim. system 0023 * 0024 * It consists of a line number and a position in the line. 0025 * The coord starts at (0,0). Line numbers increase downwards, positions to the right. 0026 * With any of both at a negative number the coord is invalid. 0027 * The index at coord(0,0) is 0. 0028 * 0029 * @author Friedrich W. H. Kossebau 0030 */ 0031 class Coord 0032 { 0033 public: 0034 /** constructs a section by width 0035 * @param index starting index 0036 * @param lineWidth width of the section 0037 */ 0038 static Coord fromIndex(Address index, LinePositionSize lineWidth); 0039 0040 public: 0041 /** creates a coord with 0,0 */ 0042 Coord() = default; 0043 constexpr Coord(LinePosition pos, Line line); 0044 Coord(const Coord& other) = default; 0045 Coord& operator=(const Coord& other) = default; 0046 0047 ~Coord() = default; 0048 0049 public: // logic 0050 constexpr bool operator==(const Coord& other) const; 0051 constexpr bool operator!=(const Coord& other) const; 0052 constexpr bool operator<(const Coord& other) const; 0053 constexpr bool operator<=(const Coord& other) const; 0054 constexpr bool operator>(const Coord& other) const; 0055 constexpr bool operator>=(const Coord& other) const; 0056 0057 /** tests if the coord is prior in the same line than the given coord. 0058 * If at least one of both is invalid the result is undefined. 0059 * @return true if the pos is left to the pos of other and both are in the same line, otherwise false. 0060 */ 0061 constexpr bool isPriorInLineThan(Coord other) const; 0062 /** tests if the coord is later in the same line than the given coord. 0063 * If at least one of both is invalid the result is undefined. 0064 * @return true if the pos is right to the pos of other and both are in the same line, otherwise false 0065 */ 0066 constexpr bool isLaterInLineThan(Coord other) const; 0067 /** @return true if the line is below lines, otherwise false */ 0068 constexpr bool isBelow(Line line) const; 0069 /** @return true if the line is above lines, otherwise false */ 0070 constexpr bool isAbove(Line line) const; 0071 /** @return true if the coord is at (0,0) */ 0072 constexpr bool isAtStart() const; 0073 /** @return true if the pos is greater than 0, otherwise false */ 0074 constexpr bool isBehindLineStart() const; 0075 /** @return true if the pos is smaller than maxPos, otherwise false */ 0076 constexpr bool isBeforeLineEnd(LinePosition maxPos) const; 0077 0078 /** calculates the index the coord is at with a given line width 0079 * If the coord is invalid the result is undefined. 0080 * @param lineWidth given width of line 0081 * @return index the coord is at 0082 */ 0083 constexpr Address indexByLineWidth(LinePositionSize lineWidth) const; 0084 0085 public: 0086 /** set the coord by calculating it for an index with a given line width 0087 * @param index index in the buffer 0088 * @param lineWidth given line width 0089 */ 0090 void setByIndexNWidth(Address index, LinePositionSize lineWidth); 0091 /** sets both position and line */ 0092 void set(LinePosition pos, Line line); 0093 /** sets the position */ 0094 void setPos(LinePosition pos); 0095 /** sets the line */ 0096 void setLine(Line line); 0097 0098 /** moves the coord one position to the left. If the coord is invalid the result is undefined. */ 0099 void goLeft(); 0100 /** moves the coord a given number of positions to the left. 0101 * If the coord is invalid the result is undefined or the position smaller than the given number 0102 * the behaviour is undefined. 0103 * @param positions number of positions 0104 */ 0105 void goLeft(LinePositionSize positions); 0106 /** moves the coord one position to the left, or if the position is already at the line start 0107 * to the given position in the previous line. If the coord is invalid the result is undefined. 0108 * @param maxPos maximal allowed position 0109 */ 0110 void goCLeft(LinePosition maxPos); 0111 /** moves the coord one position to the right. If the coord is invalid the result is undefined. */ 0112 void goRight(); 0113 /** moves the coord a given number of positions to the right. If the coord is invalid the result is undefined. 0114 * @param positions number of positions 0115 */ 0116 void goRight(LinePositionSize positions); 0117 /** moves the coord one position to the right, or if the position has already reached or passed maxPos 0118 * to the first position in the next line. If the coord is invalid the result is undefined. 0119 * @param maxPos maximal allowed position 0120 */ 0121 void goCRight(LinePosition maxPos); 0122 /** sets coord to (0,0) */ 0123 void gotoStart(); 0124 void gotoEndOfPreviousLine(LinePosition lastPos); 0125 /** sets the coord to the start of the next line. 0126 * If the coord is invalid the behaviour is undefined. 0127 */ 0128 void gotoStartOfNextLine(); 0129 /** sets the position to the start of the line or 0130 * if the line is the same as that of the given coord to the position of it. 0131 * If one or more of the coords is invalid the behaviour is undefined. 0132 * @param other a possible line start coord 0133 */ 0134 void goLineStart(Coord other); 0135 /** sets the position to the given pos or 0136 * if the line is the same as that of the given coord to the position of that. 0137 * If one or more of the coords is invalid the behaviour is undefined. 0138 * @param lastPos last position in normal line 0139 * @param other a possible line end coord 0140 */ 0141 void goLineEnd(LinePosition lastPos, Coord other); 0142 /** moves the coord 1 lines upwards. There is no check whether the first line is overstepped. */ 0143 void goUp(); 0144 /** moves the coord lines lines downwards. */ 0145 void goDown(); 0146 /** moves the coord lines lines upwards. There is no check whether the first line is overstepped. 0147 * @param lines number of lines 0148 */ 0149 void goUp(LineSize lines); 0150 /** moves the coord lines lines downwards. 0151 * @param lines number of lines 0152 */ 0153 void goDown(LineSize lines); 0154 0155 public: // state value access 0156 /** @return the pos in the line */ 0157 constexpr LinePosition pos() const; 0158 /** @return the line number */ 0159 constexpr Line line() const; 0160 /** @return true if the coord is valid */ 0161 constexpr bool isValid() const; 0162 0163 private: // member variables 0164 /** Position in mLine */ 0165 LinePosition mPos = 0; 0166 /** mLine */ 0167 Line mLine = 0; 0168 }; 0169 0170 inline constexpr Coord::Coord(LinePosition pos, Line line) 0171 : mPos(pos) 0172 , mLine(line) 0173 {} 0174 0175 inline Coord Coord::fromIndex(Address index, LinePositionSize lineWidth) 0176 { 0177 const Line line = index / lineWidth; 0178 const LinePosition pos = index - line * lineWidth; 0179 return Coord(pos, line); 0180 } 0181 0182 inline constexpr bool Coord::operator==(const Coord& other) const { return mPos == other.mPos && mLine == other.mLine; } 0183 inline constexpr bool Coord::operator!=(const Coord& other) const { return !(*this == other); } 0184 0185 inline constexpr bool Coord::operator<(const Coord& other) const 0186 { return mLine < other.mLine || (mLine == other.mLine && mPos < other.mPos); } 0187 inline constexpr bool Coord::operator<=(const Coord& other) const 0188 { return mLine < other.mLine || (mLine == other.mLine && mPos <= other.mPos); } 0189 inline constexpr bool Coord::operator>(const Coord& other) const 0190 { return mLine > other.mLine || (mLine == other.mLine && mPos > other.mPos); } 0191 inline constexpr bool Coord::operator>=(const Coord& other) const 0192 { return mLine > other.mLine || (mLine == other.mLine && mPos >= other.mPos); } 0193 0194 inline constexpr LinePosition Coord::pos() const { return mPos; } 0195 inline constexpr Line Coord::line() const { return mLine; } 0196 inline constexpr bool Coord::isValid() const { return mLine >= 0 && mPos >= 0; } 0197 0198 inline void Coord::setByIndexNWidth(Address index, LinePositionSize lineWidth) 0199 { 0200 mLine = index / lineWidth; 0201 mPos = index - mLine * lineWidth; 0202 } 0203 0204 inline void Coord::set(LinePosition pos, Line line) 0205 { 0206 mPos = pos; 0207 mLine = line; 0208 } 0209 inline void Coord::setPos(LinePosition pos) { mPos = pos; } 0210 inline void Coord::setLine(Line line) { mLine = line; } 0211 0212 inline void Coord::goCRight(LinePosition maxPos) 0213 { 0214 if (isBeforeLineEnd(maxPos)) { 0215 goRight(); 0216 } else { 0217 gotoStartOfNextLine(); 0218 } 0219 } 0220 inline void Coord::goCLeft(LinePosition maxPos) 0221 { 0222 if (isBehindLineStart()) { 0223 goLeft(); 0224 } else { 0225 gotoEndOfPreviousLine(maxPos); 0226 } 0227 } 0228 0229 inline void Coord::goRight() { ++mPos; } 0230 inline void Coord::goLeft() { --mPos; } 0231 inline void Coord::goRight(LinePositionSize positions) { mPos += positions; } 0232 inline void Coord::goLeft(LinePositionSize positions) { mPos -= positions; } 0233 0234 inline void Coord::gotoStart() { mPos = mLine = 0; } 0235 0236 inline void Coord::gotoEndOfPreviousLine(LinePosition lastPos) 0237 { 0238 --mLine; 0239 mPos = lastPos; 0240 } 0241 0242 inline void Coord::gotoStartOfNextLine() 0243 { 0244 ++mLine; 0245 mPos = 0; 0246 } 0247 0248 inline void Coord::goLineStart(Coord other) 0249 { 0250 mPos = (mLine == other.mLine) ? other.mPos : 0; 0251 } 0252 0253 inline void Coord::goLineEnd(LinePosition lastPos, Coord other) 0254 { 0255 mPos = (mLine == other.mLine) ? other.mPos : lastPos; 0256 } 0257 0258 inline void Coord::goUp() { --mLine; } 0259 inline void Coord::goDown() { ++mLine; } 0260 inline void Coord::goUp(LineSize lines) { mLine -= lines; } 0261 inline void Coord::goDown(LineSize lines) { mLine += lines; } 0262 0263 inline constexpr Address Coord::indexByLineWidth(LinePositionSize lineWidth) const 0264 { 0265 return mLine * lineWidth + mPos; 0266 } 0267 0268 inline constexpr bool Coord::isPriorInLineThan(Coord other) const 0269 { 0270 return mLine == other.mLine && mPos < other.mPos; 0271 } 0272 0273 inline constexpr bool Coord::isLaterInLineThan(Coord other) const 0274 { 0275 return mLine == other.mLine && mPos > other.mPos; 0276 } 0277 0278 inline constexpr bool Coord::isBelow(Line line) const { return mLine > line; } 0279 inline constexpr bool Coord::isAbove(Line line) const { return mLine < line; } 0280 0281 inline constexpr bool Coord::isBehindLineStart() const { return mPos > 0; } 0282 inline constexpr bool Coord::isBeforeLineEnd(LinePosition maxPos) const { return mPos < maxPos; } 0283 0284 inline constexpr bool Coord::isAtStart() const { return mPos == 0 && mLine == 0; } 0285 0286 inline Coord operator+(Coord other, LinePosition pos) 0287 { 0288 return Coord(other.pos() + pos, other.line()); 0289 } 0290 0291 } 0292 0293 #endif