File indexing completed on 2024-05-05 03:49:47
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2009 Bastian Holst <bastianholst@gmx.de> 0004 // 0005 0006 // Self 0007 #include "MarbleGraphicsGridLayout.h" 0008 0009 // Marble 0010 #include "MarbleDebug.h" 0011 #include "ScreenGraphicsItem.h" 0012 0013 // Qt 0014 #include <QHash> 0015 #include <QRectF> 0016 #include <QSizeF> 0017 #include <QVector> 0018 0019 namespace Marble 0020 { 0021 0022 class MarbleGraphicsGridLayoutPrivate 0023 { 0024 public: 0025 MarbleGraphicsGridLayoutPrivate( int rows, int columns ) 0026 : m_rows( rows ), 0027 m_columns( columns ), 0028 m_spacing( 0 ), 0029 m_alignment( Qt::AlignLeft | Qt::AlignTop ) 0030 { 0031 m_items = new ScreenGraphicsItem **[rows]; 0032 for ( int i = 0; i < rows; ++i ) { 0033 m_items[i] = new ScreenGraphicsItem *[columns]; 0034 } 0035 for ( int row = 0; row < rows; row++ ) { 0036 for ( int column = 0; column < columns; column++ ) { 0037 m_items[row][column] = nullptr; 0038 } 0039 } 0040 } 0041 0042 ~MarbleGraphicsGridLayoutPrivate() 0043 { 0044 for ( int i = 0; i < m_rows; ++i ) { 0045 delete[] m_items[i]; 0046 } 0047 delete[] m_items; 0048 } 0049 0050 // A two dimensional array of pointers to ScreenGraphicsItems 0051 ScreenGraphicsItem ***m_items; 0052 int m_rows; 0053 int m_columns; 0054 int m_spacing; 0055 Qt::Alignment m_alignment; 0056 QHash<ScreenGraphicsItem*, Qt::Alignment> m_itemAlignment; 0057 }; 0058 0059 MarbleGraphicsGridLayout::MarbleGraphicsGridLayout( int rows, int columns ) 0060 : d( new MarbleGraphicsGridLayoutPrivate( rows, columns ) ) 0061 { 0062 } 0063 0064 MarbleGraphicsGridLayout::~MarbleGraphicsGridLayout() 0065 { 0066 delete d; 0067 } 0068 0069 void MarbleGraphicsGridLayout::addItem( ScreenGraphicsItem *item, int row, int column ) 0070 { 0071 if ( row < d->m_rows 0072 && column < d->m_columns ) 0073 { 0074 d->m_items[row][column] = item; 0075 } 0076 } 0077 0078 void MarbleGraphicsGridLayout::updatePositions( MarbleGraphicsItem *parent ) 0079 { 0080 // Initialize with 0.0 0081 QVector<double> maxWidth( d->m_columns, 0.0 ); 0082 QVector<double> maxHeight( d->m_rows, 0.0 ); 0083 0084 // Determining the cell sizes 0085 for ( int row = 0; row < d->m_rows; row++ ) { 0086 for ( int column = 0; column < d->m_columns; column++ ) { 0087 if ( d->m_items[row][column] == nullptr ) { 0088 continue; 0089 } 0090 0091 QSizeF size = d->m_items[row][column]->size(); 0092 double width = size.width(); 0093 double height = size.height(); 0094 0095 if ( width > maxWidth[column] ) { 0096 maxWidth[column] = width; 0097 } 0098 if ( height > maxHeight[row] ) { 0099 maxHeight[row] = height; 0100 } 0101 } 0102 } 0103 0104 QVector<double> startX( d->m_columns ); 0105 QVector<double> endX( d->m_columns ); 0106 QVector<double> startY( d->m_rows ); 0107 QVector<double> endY( d->m_rows ); 0108 QRectF contentRect = parent->contentRect(); 0109 0110 for ( int i = 0; i < d->m_columns; i++ ) { 0111 if ( i == 0 ) { 0112 startX[0] = contentRect.left(); 0113 } 0114 else if ( maxWidth[i] == 0 ) { 0115 startX[i] = endX[i-1]; 0116 } 0117 else { 0118 startX[i] = endX[i-1] + d->m_spacing; 0119 } 0120 0121 endX[i] = startX[i] + maxWidth[i]; 0122 } 0123 0124 for ( int i = 0; i < d->m_rows; i++ ) { 0125 if ( i == 0 ) { 0126 startY[0] = contentRect.left(); 0127 } 0128 else if ( maxHeight[i] == 0 ) { 0129 startY[i] = endY[i-1]; 0130 } 0131 else { 0132 startY[i] = endY[i-1] + d->m_spacing; 0133 } 0134 0135 endY[i] = startY[i] + maxHeight[i]; 0136 } 0137 0138 // Setting the positions 0139 for ( int row = 0; row < d->m_rows; row++ ) { 0140 for ( int column = 0; column < d->m_columns; column++ ) { 0141 if ( d->m_items[row][column] == nullptr ) { 0142 continue; 0143 } 0144 0145 double xPos, yPos; 0146 0147 Qt::Alignment align = alignment( d->m_items[row][column] ); 0148 0149 if ( align & Qt::AlignRight ) { 0150 xPos = endX[column] - d->m_items[row][column]->size().width(); 0151 } 0152 else if ( align & Qt::AlignHCenter ) { 0153 xPos = startX[column] 0154 + ( maxWidth[column] - d->m_items[row][column]->size().width() ) / 2.0; 0155 } 0156 else { 0157 xPos = startX[column]; 0158 } 0159 0160 if ( align & Qt::AlignBottom ) { 0161 yPos = endY[row] - d->m_items[row][column]->size().height(); 0162 } 0163 else if ( align & Qt::AlignVCenter ) { 0164 yPos = startY[row] 0165 + ( maxHeight[row] - d->m_items[row][column]->size().height() ) / 2.0; 0166 } 0167 else { 0168 yPos = startY[row]; 0169 } 0170 0171 d->m_items[row][column]->setPosition( QPointF( xPos, yPos ) ); 0172 } 0173 } 0174 0175 parent->setContentSize( QSizeF( endX[d->m_columns - 1] - contentRect.left(), 0176 endY[d->m_rows - 1] - contentRect.top() ) ); 0177 } 0178 0179 Qt::Alignment MarbleGraphicsGridLayout::alignment() const 0180 { 0181 return d->m_alignment; 0182 } 0183 0184 Qt::Alignment MarbleGraphicsGridLayout::alignment( ScreenGraphicsItem *item ) const 0185 { 0186 return d->m_itemAlignment.value( item, d->m_alignment ); 0187 } 0188 0189 void MarbleGraphicsGridLayout::setAlignment( Qt::Alignment align ) 0190 { 0191 d->m_alignment = align; 0192 } 0193 0194 void MarbleGraphicsGridLayout::setAlignment( ScreenGraphicsItem *item, Qt::Alignment align ) 0195 { 0196 d->m_itemAlignment.insert( item, align ); 0197 } 0198 0199 int MarbleGraphicsGridLayout::spacing() const 0200 { 0201 return d->m_spacing; 0202 } 0203 0204 void MarbleGraphicsGridLayout::setSpacing( int spacing ) 0205 { 0206 d->m_spacing = spacing; 0207 } 0208 0209 } // namespace Marble