File indexing completed on 2025-01-05 03:59:16

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