Marble

MarbleGraphicsGridLayout.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2009 Bastian Holst <[email protected]>
4 //
5 
6 // Self
7 #include "MarbleGraphicsGridLayout.h"
8 
9 // Marble
10 #include "MarbleDebug.h"
11 #include "ScreenGraphicsItem.h"
12 
13 // Qt
14 #include <QHash>
15 #include <QRectF>
16 #include <QSizeF>
17 #include <QVector>
18 
19 namespace Marble
20 {
21 
22 class MarbleGraphicsGridLayoutPrivate
23 {
24  public:
25  MarbleGraphicsGridLayoutPrivate( int rows, int columns )
26  : m_rows( rows ),
27  m_columns( columns ),
28  m_spacing( 0 ),
29  m_alignment( Qt::AlignLeft | Qt::AlignTop )
30  {
31  m_items = new ScreenGraphicsItem **[rows];
32  for ( int i = 0; i < rows; ++i ) {
33  m_items[i] = new ScreenGraphicsItem *[columns];
34  }
35  for ( int row = 0; row < rows; row++ ) {
36  for ( int column = 0; column < columns; column++ ) {
37  m_items[row][column] = nullptr;
38  }
39  }
40  }
41 
42  ~MarbleGraphicsGridLayoutPrivate()
43  {
44  for ( int i = 0; i < m_rows; ++i ) {
45  delete[] m_items[i];
46  }
47  delete[] m_items;
48  }
49 
50  // A two dimensional array of pointers to ScreenGraphicsItems
51  ScreenGraphicsItem ***m_items;
52  int m_rows;
53  int m_columns;
54  int m_spacing;
55  Qt::Alignment m_alignment;
57 };
58 
59 MarbleGraphicsGridLayout::MarbleGraphicsGridLayout( int rows, int columns )
60  : d( new MarbleGraphicsGridLayoutPrivate( rows, columns ) )
61 {
62 }
63 
64 MarbleGraphicsGridLayout::~MarbleGraphicsGridLayout()
65 {
66  delete d;
67 }
68 
69 void MarbleGraphicsGridLayout::addItem( ScreenGraphicsItem *item, int row, int column )
70 {
71  if ( row < d->m_rows
72  && column < d->m_columns )
73  {
74  d->m_items[row][column] = item;
75  }
76 }
77 
78 void MarbleGraphicsGridLayout::updatePositions( MarbleGraphicsItem *parent )
79 {
80  // Initialize with 0.0
81  QVector<double> maxWidth( d->m_columns, 0.0 );
82  QVector<double> maxHeight( d->m_rows, 0.0 );
83 
84  // Determining the cell sizes
85  for ( int row = 0; row < d->m_rows; row++ ) {
86  for ( int column = 0; column < d->m_columns; column++ ) {
87  if ( d->m_items[row][column] == nullptr ) {
88  continue;
89  }
90 
91  QSizeF size = d->m_items[row][column]->size();
92  double width = size.width();
93  double height = size.height();
94 
95  if ( width > maxWidth[column] ) {
96  maxWidth[column] = width;
97  }
98  if ( height > maxHeight[row] ) {
99  maxHeight[row] = height;
100  }
101  }
102  }
103 
104  QVector<double> startX( d->m_columns );
105  QVector<double> endX( d->m_columns );
106  QVector<double> startY( d->m_rows );
107  QVector<double> endY( d->m_rows );
108  QRectF contentRect = parent->contentRect();
109 
110  for ( int i = 0; i < d->m_columns; i++ ) {
111  if ( i == 0 ) {
112  startX[0] = contentRect.left();
113  }
114  else if ( maxWidth[i] == 0 ) {
115  startX[i] = endX[i-1];
116  }
117  else {
118  startX[i] = endX[i-1] + d->m_spacing;
119  }
120 
121  endX[i] = startX[i] + maxWidth[i];
122  }
123 
124  for ( int i = 0; i < d->m_rows; i++ ) {
125  if ( i == 0 ) {
126  startY[0] = contentRect.left();
127  }
128  else if ( maxHeight[i] == 0 ) {
129  startY[i] = endY[i-1];
130  }
131  else {
132  startY[i] = endY[i-1] + d->m_spacing;
133  }
134 
135  endY[i] = startY[i] + maxHeight[i];
136  }
137 
138  // Setting the positions
139  for ( int row = 0; row < d->m_rows; row++ ) {
140  for ( int column = 0; column < d->m_columns; column++ ) {
141  if ( d->m_items[row][column] == nullptr ) {
142  continue;
143  }
144 
145  double xPos, yPos;
146 
147  Qt::Alignment align = alignment( d->m_items[row][column] );
148 
149  if ( align & Qt::AlignRight ) {
150  xPos = endX[column] - d->m_items[row][column]->size().width();
151  }
152  else if ( align & Qt::AlignHCenter ) {
153  xPos = startX[column]
154  + ( maxWidth[column] - d->m_items[row][column]->size().width() ) / 2.0;
155  }
156  else {
157  xPos = startX[column];
158  }
159 
160  if ( align & Qt::AlignBottom ) {
161  yPos = endY[row] - d->m_items[row][column]->size().height();
162  }
163  else if ( align & Qt::AlignVCenter ) {
164  yPos = startY[row]
165  + ( maxHeight[row] - d->m_items[row][column]->size().height() ) / 2.0;
166  }
167  else {
168  yPos = startY[row];
169  }
170 
171  d->m_items[row][column]->setPosition( QPointF( xPos, yPos ) );
172  }
173  }
174 
175  parent->setContentSize( QSizeF( endX[d->m_columns - 1] - contentRect.left(),
176  endY[d->m_rows - 1] - contentRect.top() ) );
177 }
178 
179 Qt::Alignment MarbleGraphicsGridLayout::alignment() const
180 {
181  return d->m_alignment;
182 }
183 
184 Qt::Alignment MarbleGraphicsGridLayout::alignment( ScreenGraphicsItem *item ) const
185 {
186  return d->m_itemAlignment.value( item, d->m_alignment );
187 }
188 
189 void MarbleGraphicsGridLayout::setAlignment( Qt::Alignment align )
190 {
191  d->m_alignment = align;
192 }
193 
194 void MarbleGraphicsGridLayout::setAlignment( ScreenGraphicsItem *item, Qt::Alignment align )
195 {
196  d->m_itemAlignment.insert( item, align );
197 }
198 
199 int MarbleGraphicsGridLayout::spacing() const
200 {
201  return d->m_spacing;
202 }
203 
204 void MarbleGraphicsGridLayout::setSpacing( int spacing )
205 {
206  d->m_spacing = spacing;
207 }
208 
209 } // namespace Marble
qreal left() const const
AlignLeft
qreal height() const const
Binds a QML item to a specific geodetic location in screen coordinates.
qreal top() const const
qreal width() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Oct 2 2023 03:52:09 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.