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 <QList>
16#include <QRectF>
17#include <QSizeF>
18
19namespace Marble
20{
21
22class MarbleGraphicsGridLayoutPrivate
23{
24public:
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 && column < d->m_columns) {
72 d->m_items[row][column] = item;
73 }
74}
75
76void MarbleGraphicsGridLayout::updatePositions(MarbleGraphicsItem *parent)
77{
78 // Initialize with 0.0
79 QList<double> maxWidth(d->m_columns, 0.0);
80 QList<double> maxHeight(d->m_rows, 0.0);
81
82 // Determining the cell sizes
83 for (int row = 0; row < d->m_rows; row++) {
84 for (int column = 0; column < d->m_columns; column++) {
85 if (d->m_items[row][column] == nullptr) {
86 continue;
87 }
88
89 QSizeF size = d->m_items[row][column]->size();
90 double width = size.width();
91 double height = size.height();
92
93 if (width > maxWidth[column]) {
94 maxWidth[column] = width;
95 }
96 if (height > maxHeight[row]) {
97 maxHeight[row] = height;
98 }
99 }
100 }
101
102 QList<double> startX(d->m_columns);
103 QList<double> endX(d->m_columns);
104 QList<double> startY(d->m_rows);
105 QList<double> endY(d->m_rows);
106 QRectF contentRect = parent->contentRect();
107
108 for (int i = 0; i < d->m_columns; i++) {
109 if (i == 0) {
110 startX[0] = contentRect.left();
111 } else if (maxWidth[i] == 0) {
112 startX[i] = endX[i - 1];
113 } else {
114 startX[i] = endX[i - 1] + d->m_spacing;
115 }
116
117 endX[i] = startX[i] + maxWidth[i];
118 }
119
120 for (int i = 0; i < d->m_rows; i++) {
121 if (i == 0) {
122 startY[0] = contentRect.left();
123 } else if (maxHeight[i] == 0) {
124 startY[i] = endY[i - 1];
125 } else {
126 startY[i] = endY[i - 1] + d->m_spacing;
127 }
128
129 endY[i] = startY[i] + maxHeight[i];
130 }
131
132 // Setting the positions
133 for (int row = 0; row < d->m_rows; row++) {
134 for (int column = 0; column < d->m_columns; column++) {
135 if (d->m_items[row][column] == nullptr) {
136 continue;
137 }
138
139 double xPos, yPos;
140
141 Qt::Alignment align = alignment(d->m_items[row][column]);
142
143 if (align & Qt::AlignRight) {
144 xPos = endX[column] - d->m_items[row][column]->size().width();
145 } else if (align & Qt::AlignHCenter) {
146 xPos = startX[column] + (maxWidth[column] - d->m_items[row][column]->size().width()) / 2.0;
147 } else {
148 xPos = startX[column];
149 }
150
151 if (align & Qt::AlignBottom) {
152 yPos = endY[row] - d->m_items[row][column]->size().height();
153 } else if (align & Qt::AlignVCenter) {
154 yPos = startY[row] + (maxHeight[row] - d->m_items[row][column]->size().height()) / 2.0;
155 } else {
156 yPos = startY[row];
157 }
158
159 d->m_items[row][column]->setPosition(QPointF(xPos, yPos));
160 }
161 }
162
163 parent->setContentSize(QSizeF(endX[d->m_columns - 1] - contentRect.left(), endY[d->m_rows - 1] - contentRect.top()));
164}
165
166Qt::Alignment MarbleGraphicsGridLayout::alignment() const
167{
168 return d->m_alignment;
169}
170
171Qt::Alignment MarbleGraphicsGridLayout::alignment(ScreenGraphicsItem *item) const
172{
173 return d->m_itemAlignment.value(item, d->m_alignment);
174}
175
176void MarbleGraphicsGridLayout::setAlignment(Qt::Alignment align)
177{
178 d->m_alignment = align;
179}
180
181void MarbleGraphicsGridLayout::setAlignment(ScreenGraphicsItem *item, Qt::Alignment align)
182{
183 d->m_itemAlignment.insert(item, align);
184}
185
186int MarbleGraphicsGridLayout::spacing() const
187{
188 return d->m_spacing;
189}
190
191void MarbleGraphicsGridLayout::setSpacing(int spacing)
192{
193 d->m_spacing = spacing;
194}
195
196} // 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 Nov 8 2024 12:02:44 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.