Files
RMG/Source/RMG-Input/UserInterface/Layout/AlignCenterLayout.cpp
T

101 lines
3.1 KiB
C++

/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020-2025 Rosalie Wanders <rosalie@mailbox.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "AlignCenterLayout.hpp"
using namespace UserInterface::Layout;
AlignCenterLayout::AlignCenterLayout(int spacing) : QLayout()
{
this->setSpacing(spacing);
}
AlignCenterLayout::~AlignCenterLayout(void)
{
for (int i = 0; i < this->items.count(); i++)
{
delete this->items.at(i);
}
this->items.clear();
}
void AlignCenterLayout::addItem(QLayoutItem *item)
{
this->items.append(item);
}
QSize AlignCenterLayout::sizeHint() const
{
return this->minimumSize();
}
QSize AlignCenterLayout::minimumSize() const
{
QSize size(0, 0);
int count = this->items.count();
for (int i = 0; i < count; i++)
{
QLayoutItem* item = this->items.at(i);
size = size.expandedTo(item->minimumSize());
}
// take spacing for top & bottom into account
size.setHeight(size.height() + (this->spacing() * 2));
return size;
}
QSize AlignCenterLayout::maximumSize() const
{
return this->minimumSize();
}
int AlignCenterLayout::count() const
{
return this->items.count();
}
QLayoutItem* AlignCenterLayout::itemAt(int index) const
{
return index >= 0 && index < this->items.size() ? this->items.value(index) : nullptr;
}
QLayoutItem* AlignCenterLayout::takeAt(int index)
{
return index >= 0 && index < this->items.size() ? this->items.takeAt(index) : nullptr;
}
void AlignCenterLayout::setGeometry(const QRect& rect)
{
QLayout::setGeometry(rect);
QLayoutItem* leftItem = this->items.at(0);
QLayoutItem* centerItem = this->items.at(1);
QLayoutItem* rightItem = this->items.at(2);
// the side widgets are limited to 25% of available width
// the middle widget is limited to 40% of the available width
//
// this also takes into account the situation where there's an overlap
// between widgets, which is something this avoids.
const int spacing = this->spacing();
const int itemHeight = centerItem->minimumSize().height() + spacing;
const int rectWidth = rect.width();
const int topLocation = rect.y() + spacing;
const int centerItemWidth = std::min(centerItem->sizeHint().width(), static_cast<int>(std::ceil(rectWidth / 2.5)));
const int centerItemLocation = ((rectWidth / 2)) - (centerItemWidth / 2);
const int maxSideItemWidth = std::min(centerItemLocation, rectWidth / 4) - spacing;
const int sideItemWidth = std::min(leftItem->minimumSize().width(), maxSideItemWidth);
leftItem->setGeometry(QRect(rect.x(), topLocation, sideItemWidth, itemHeight));
centerItem->setGeometry(QRect(rect.x() + centerItemLocation, topLocation, centerItemWidth, itemHeight));
rightItem->setGeometry(QRect(rect.x() + rectWidth - sideItemWidth, topLocation, sideItemWidth, itemHeight));
}