Marble

MarbleGraphicsGridLayout.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2009 Bastian Holst <bastianholst@gmx.de>
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
19namespace Marble
20{
21
22class 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
59MarbleGraphicsGridLayout::MarbleGraphicsGridLayout( int rows, int columns )
60 : d( new MarbleGraphicsGridLayoutPrivate( rows, columns ) )
61{
62}
63
64MarbleGraphicsGridLayout::~MarbleGraphicsGridLayout()
65{
66 delete d;
67}
68
69void 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
78void 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
179Qt::Alignment MarbleGraphicsGridLayout::alignment() const
180{
181 return d->m_alignment;
182}
183
184Qt::Alignment MarbleGraphicsGridLayout::alignment( ScreenGraphicsItem *item ) const
185{
186 return d->m_itemAlignment.value( item, d->m_alignment );
187}
188
189void MarbleGraphicsGridLayout::setAlignment( Qt::Alignment align )
190{
191 d->m_alignment = align;
192}
193
194void MarbleGraphicsGridLayout::setAlignment( ScreenGraphicsItem *item, Qt::Alignment align )
195{
196 d->m_itemAlignment.insert( item, align );
197}
198
199int MarbleGraphicsGridLayout::spacing() const
200{
201 return d->m_spacing;
202}
203
204void MarbleGraphicsGridLayout::setSpacing( int spacing )
205{
206 d->m_spacing = spacing;
207}
208
209} // namespace Marble
Binds a QML item to a specific geodetic location in screen coordinates.
qreal left() const const
qreal top() const const
qreal height() const const
qreal width() const const
AlignLeft
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jul 26 2024 11:57:57 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.