1 /*
2     This file is part of the Okteta Gui library, made within the KDE community.
3 
4     SPDX-FileCopyrightText: 2003, 2007-2009, 2019 Friedrich W. H. Kossebau <kossebau@kde.org>
5 
6     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
7 */
8 
9 #ifndef OKTETA_ABSTRACTBYTEARRAYCOLUMNRENDERER_P_HPP
10 #define OKTETA_ABSTRACTBYTEARRAYCOLUMNRENDERER_P_HPP
11 
12 // lib
13 #include "abstractbytearraycolumnrenderer.hpp"
14 #include "abstractcolumnrenderer_p.hpp"
15 #include "oktetagui.hpp"
16 // Okteta core
17 #include <Okteta/AbstractByteArrayModel>
18 #include <Okteta/Bookmarkable>
19 #include <Okteta/Character>
20 // Qt
21 #include <QFontMetrics>
22 
23 class QColor;
24 class QBrush;
25 
26 namespace Okteta {
27 
28 class Bookmarkable;
29 
30 class AbstractByteArrayColumnRendererPrivate : public AbstractColumnRendererPrivate
31 {
32 public:
33     AbstractByteArrayColumnRendererPrivate(AbstractByteArrayColumnRenderer* q,
34                                            AbstractColumnStylist* stylist,
35                                            AbstractByteArrayModel* byteArrayModel,
36                                            ByteArrayTableLayout* layout,
37                                            ByteArrayTableRanges* ranges);
38 
39     ~AbstractByteArrayColumnRendererPrivate() override;
40 
41 public: // AbstractColumnRenderer API
42     void renderFirstLine(QPainter* painter, const PixelXRange& Xs, Line firstLineIndex);
43     void renderNextLine(QPainter* painter);
44 
45 public:
46     void prepareRendering(const PixelXRange& Xs);
47 
48 public:
49     void renderLinePositions(QPainter* painter, Line lineIndex, const LineRange& linePositions);
50     /** paints a cursor based on the type of the byte.
51      * @param painter The QPainter
52      * @param byteIndex Index of the byte to paint the cursor for. If -1 a space is used as char.
53      */
54     void renderCursor(QPainter* painter, Address byteIndex);
55     /** paints the byte with background.
56      * @param painter The QPainter
57      * @param byteIndex Index of the byte to paint. If -1 only the background is painted.
58      */
59     void renderByte(QPainter* painter, Address byteIndex);
60     /** paints the byte with background and a frame around.
61      * @param painter The QPainter
62      * @param byteIndex Index of the byte to paint the frame for. If -1 a space is used as char.
63      * @param style the style of the framing
64      */
65     void renderFramedByte(QPainter* painter, Address byteIndex, AbstractByteArrayColumnRenderer::FrameStyle style);
66 
67 public: // modification access
68     /** sets the spacing in the hex column
69      * @param byteSpacingWidth spacing between the bytes in pixels
70      * @param noOfGroupedBytes numbers of grouped bytes, 0 means no grouping
71      * @param groupSpacingWidth spacing between the groups in pixels
72      * returns true if there was a change
73      */
74     bool setSpacing(PixelX byteSpacingWidth, int noOfGroupedBytes = 0, PixelX groupSpacingWidth = 0);
75     /** sets the spacing between the bytes in the hex column
76      * @param byteSpacingWidth spacing between the bytes in pixels
77      * returns true if there was a change
78      */
79     bool setByteSpacingWidth(PixelX byteSpacingWidth);
80     /** sets the number of grouped bytes in the hex column
81      * @param noOfGroupedBytes numbers of grouped bytes, 0 means no grouping
82      * returns true if there was a change
83      */
84     bool setNoOfGroupedBytes(int noOfGroupedBytes);
85     /** sets the spacing between the groups of bytes in the hex column
86      * @param groupSpacingWidth spacing between the groups in pixels
87      * returns true if there was a change
88      */
89     bool setGroupSpacingWidth(PixelX groupSpacingWidth);
90     /** sets the metrics of the used font
91      */
92     void setFontMetrics(const QFontMetrics& fontMetrics);
93     /** */
94     void set(AbstractByteArrayModel* byteArrayModel);
95     /** creates new buffer for x-values; to be called on any change of NoOfBytesPerLine or metrics */
96     void resetXBuffer();
97     /** sets the codec to be used by the char column. */
98     void setCharCodec(const CharCodec* charCodec);
99 
100     void setByteTypeColored(bool byteTypeColored);
101 
102 public: // functional logic
103     /** returns byte linePositions covered by pixels with absolute x-coord x */
104     LinePositionRange linePositionsOfX(PixelX x, PixelX width) const;
105     /** returns byte pos at pixel with absolute x-coord x */
106     LinePosition linePositionOfX(PixelX x) const;
107     /** returns byte pos at pixel with absolute x-coord x, and sets the flag to true if we are closer to the right */
108     LinePosition magneticLinePositionOfX(PixelX x) const;
109     /** returns absolute x-coord of byte at position posInLine */
110     PixelX xOfLinePosition(LinePosition posInLine) const;
111     /** returns right absolute x-coord of byte at position posInLine */
112     PixelX rightXOfLinePosition(LinePosition posInLine) const;
113     /** returns byte pos at pixel with relative x-coord x */
114     LinePosition linePositionOfColumnX(PixelX x) const;
115     /** returns byte linePositions covered by pixels with relative x-coord x */
116     LinePositionRange linePositionsOfColumnXs(PixelX x, PixelX width) const;
117     /** returns relative x-coord of byte at position posInLine */
118     PixelX columnXOfLinePosition(LinePosition posInLine) const;
119     /** returns right relative x-coord of byte at position posInLine */
120     PixelX columnRightXOfLinePosition(LinePosition posInLine) const;
121     /** returns the linePositions that overlap with the x-coords relative to the view */
122     LinePositionRange visibleLinePositions(PixelX x, PixelX width) const;
123     /** returns the */
124     PixelXRange xsOfLinePositionsInclSpaces(const LinePositionRange& linePositions) const;
125     /** */
126     PixelXRange columnXsOfLinePositionsInclSpaces(const LinePositionRange& linePositions) const;
127 
128     QRect byteRect(Coord coord) const;
129 
130 public: // value access
131     PixelX byteWidth() const;
132     PixelX digitWidth() const;
133     PixelX groupSpacingWidth() const;
134     PixelX byteSpacingWidth() const;
135     int noOfGroupedBytes() const;
136 
137     LinePosition firstLinePos() const;
138     LinePosition lastLinePos()  const;
139     LinePositionRange visibleLinePositions() const;
140     const ByteArrayTableLayout* layout() const;
141     bool isByteTypeColored() const;
142 
143 protected: // API to be redefined
144     virtual void renderByteText(QPainter* painter, Byte byte, Character charByte, const QColor& color) const = 0;
145     /** default implementation sets byte width to one digit width */
146     virtual void recalcByteWidth();
147 
148 protected:
149     void renderPlain(QPainter* painter, const LinePositionRange& linePositions, Address byteIndex);
150     void renderSelection(QPainter* painter, const LinePositionRange& linePositions, Address byteIndex, int flag);
151     void renderMarking(QPainter* painter, const LinePositionRange& linePositions, Address byteIndex, int flag);
152     void renderRange(QPainter* painter, const QBrush& brush, const LinePositionRange& linePositions, int flag);
153     void renderSelectionSpaceBehind(QPainter* painter, LinePosition linePosition);
154     void renderSpaceBehind(QPainter* painter, const QBrush& brush, LinePosition linePosition);
155     void renderBookmark(QPainter* painter, const QBrush& brush);
156 
157     void recalcX();
158 
159     bool getNextSelectedAddressRange(AddressRange* selectedRange, unsigned int* flag, const AddressRange& range) const;
160     bool getNextMarkedAddressRange(AddressRange* markedRange, unsigned int* flag, const AddressRange& range) const;
161 
162     void setByteWidth(int byteWidth);
163 
164 protected:
165     /** pointer to the buffer */
166     AbstractByteArrayModel* mByteArrayModel;
167     /** pointer to the layout */
168     const ByteArrayTableLayout* mLayout;
169     /** pointer to the ranges */
170     ByteArrayTableRanges* mRanges;
171     /** */
172     Bookmarkable* mBookmarks;
173     /** */
174     const CharCodec* mCharCodec;
175 
176     /** */
177     PixelX mDigitWidth = 0;
178     /** */
179     PixelY mDigitBaseLine = 0;
180 
181     QFontMetrics mFontMetrics;
182 
183 protected: // individual data
184     /** total width of byte display in pixel */
185     PixelX mByteWidth = 0;
186     /** width of inserting cursor in pixel */
187 //     PixelX mCursorWidth;
188     /** size of the line margin */
189     PixelX mByteSpacingWidth;
190     /** width of spacing in pixel */
191     PixelX mGroupSpacingWidth;
192 
193     /** number of grouped bytes */
194     int mNoOfGroupedBytes;
195 
196     /** pointer to array with buffered linePositions (relative to column position)
197      * a spacing gets assigned to the left byte -> ...c|c|c |c|c...
198      */
199     PixelX* mLinePosLeftPixelX = nullptr;
200     PixelX* mLinePosRightPixelX = nullptr;
201     /** index of right position */
202     LinePosition mLastLinePos = 0;
203 
204     /** */
205     bool mByteTypeColored = true;
206 
207 protected: // buffering rendering data
208     LinePositionRange mRenderLinePositions;
209     Line mRenderLine;
210     PixelX mRenderX;
211     PixelX mRenderWidth;
212     int mSpacingTrigger;
213 
214 protected:
215     AbstractByteArrayColumnRenderer* const q_ptr;
216 
217 private:
218     Q_DECLARE_PUBLIC(AbstractByteArrayColumnRenderer)
219 };
220 
AbstractByteArrayColumnRendererPrivate(AbstractByteArrayColumnRenderer * q,AbstractColumnStylist * stylist,AbstractByteArrayModel * byteArrayModel,ByteArrayTableLayout * layout,ByteArrayTableRanges * ranges)221 inline AbstractByteArrayColumnRendererPrivate::AbstractByteArrayColumnRendererPrivate(AbstractByteArrayColumnRenderer* q,
222                                                                                       AbstractColumnStylist* stylist,
223                                                                                       AbstractByteArrayModel* byteArrayModel,
224                                                                                       ByteArrayTableLayout* layout,
225                                                                                       ByteArrayTableRanges* ranges)
226     : AbstractColumnRendererPrivate(stylist)
227     , mByteArrayModel(byteArrayModel)
228     , mLayout(layout)
229     , mRanges(ranges)
230     , mBookmarks(qobject_cast<Bookmarkable*>(byteArrayModel))
231     , mFontMetrics(QFont())
232     , mByteSpacingWidth(DefaultByteSpacingWidth)
233     , mGroupSpacingWidth(DefaultGroupSpacingWidth)
234     , mNoOfGroupedBytes(DefaultNoOfGroupedBytes)
235     , q_ptr(q)
236 {
237 }
238 
~AbstractByteArrayColumnRendererPrivate()239 inline AbstractByteArrayColumnRendererPrivate::~AbstractByteArrayColumnRendererPrivate()
240 {
241     delete [] mLinePosLeftPixelX;
242     delete [] mLinePosRightPixelX;
243 }
244 
byteWidth() const245 inline PixelX AbstractByteArrayColumnRendererPrivate::byteWidth()         const { return mByteWidth; }
digitWidth() const246 inline PixelX AbstractByteArrayColumnRendererPrivate::digitWidth()        const { return mDigitWidth; }
byteSpacingWidth() const247 inline PixelX AbstractByteArrayColumnRendererPrivate::byteSpacingWidth()  const { return mByteSpacingWidth; }
groupSpacingWidth() const248 inline PixelX AbstractByteArrayColumnRendererPrivate::groupSpacingWidth() const { return mGroupSpacingWidth; }
249 
noOfGroupedBytes() const250 inline int AbstractByteArrayColumnRendererPrivate::noOfGroupedBytes()      const { return mNoOfGroupedBytes; }
251 
firstLinePos() const252 inline LinePosition AbstractByteArrayColumnRendererPrivate::firstLinePos() const { return mRenderLinePositions.start(); }
lastLinePos() const253 inline LinePosition AbstractByteArrayColumnRendererPrivate::lastLinePos()  const { return mRenderLinePositions.end(); }
visibleLinePositions() const254 inline LinePositionRange AbstractByteArrayColumnRendererPrivate::visibleLinePositions() const { return mRenderLinePositions; }
255 
layout() const256 inline const ByteArrayTableLayout* AbstractByteArrayColumnRendererPrivate::layout() const { return mLayout; }
257 
setCharCodec(const CharCodec * charCodec)258 inline void AbstractByteArrayColumnRendererPrivate::setCharCodec(const CharCodec* charCodec)
259 {
260     mCharCodec = charCodec;
261 }
262 
setByteTypeColored(bool byteTypeColored)263 inline void AbstractByteArrayColumnRendererPrivate::setByteTypeColored(bool byteTypeColored)
264 {
265     mByteTypeColored = byteTypeColored;
266 }
isByteTypeColored() const267 inline bool AbstractByteArrayColumnRendererPrivate::isByteTypeColored() const { return mByteTypeColored; }
268 
setByteWidth(int byteWidth)269 inline void AbstractByteArrayColumnRendererPrivate::setByteWidth(int byteWidth) { mByteWidth = byteWidth; }
270 
271 }
272 
273 #endif
274