mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-18 08:22:15 -07:00
Finally fix the freaking OverlapLayout.
This commit is contained in:
parent
6ee6d1b470
commit
8a5fbb25c0
6 changed files with 104 additions and 99 deletions
|
|
@ -1,13 +1,16 @@
|
||||||
[Rules]
|
[Rules]
|
||||||
# Uncomment a rule to disable logging for that category
|
# Uncomment a rule to disable logging for that category
|
||||||
|
|
||||||
# main = false
|
flow_layout = false
|
||||||
# qt_translator = false
|
flow_widget.* = false
|
||||||
# window_main.* = false
|
|
||||||
# release_channel = false
|
# main = true
|
||||||
# spoiler_background_updater = false
|
qt_translator = false
|
||||||
# theme_manager = false
|
window_main.* = false
|
||||||
# sound_engine = false
|
release_channel = false
|
||||||
|
spoiler_background_updater = false
|
||||||
|
theme_manager = false
|
||||||
|
sound_engine = false
|
||||||
# tapped_out_interface = false
|
# tapped_out_interface = false
|
||||||
|
|
||||||
# tab_game = false
|
# tab_game = false
|
||||||
|
|
@ -33,15 +36,15 @@
|
||||||
|
|
||||||
# user_info_connection = false
|
# user_info_connection = false
|
||||||
|
|
||||||
# picture_loader = false
|
picture_loader = false
|
||||||
# picture_loader.worker = false
|
picture_loader.worker = false
|
||||||
# picture_loader.card_back_cache_fail = false
|
picture_loader.card_back_cache_fail = false
|
||||||
# picture_loader.picture_to_load = false
|
picture_loader.picture_to_load = false
|
||||||
# deck_loader = false
|
# deck_loader = false
|
||||||
# card_database = false
|
# card_database = false
|
||||||
# card_database.loading = false
|
card_database.loading = false
|
||||||
# card_database.loading.success_or_failure = false
|
card_database.loading.success_or_failure = true
|
||||||
# cockatrice_xml.* = false
|
cockatrice_xml.* = false
|
||||||
# cockatrice_xml.xml_3_parser = false
|
# cockatrice_xml.xml_3_parser = false
|
||||||
# cockatrice_xml.xml_4_parser = false
|
# cockatrice_xml.xml_4_parser = false
|
||||||
# card_info = false
|
# card_info = false
|
||||||
|
|
@ -53,6 +56,8 @@ flow_layout.debug = false
|
||||||
flow_widget.debug = false
|
flow_widget.debug = false
|
||||||
flow_widget.size.debug = false
|
flow_widget.size.debug = false
|
||||||
|
|
||||||
|
overlap_layout.debug = false
|
||||||
|
|
||||||
# pixel_map_generator = false
|
# pixel_map_generator = false
|
||||||
|
|
||||||
# filter_string = false
|
# filter_string = false
|
||||||
|
|
@ -33,9 +33,10 @@ OverlapLayout::OverlapLayout(QWidget *parent,
|
||||||
const int overlapPercentage,
|
const int overlapPercentage,
|
||||||
const int maxColumns,
|
const int maxColumns,
|
||||||
const int maxRows,
|
const int maxRows,
|
||||||
const Qt::Orientation direction)
|
const Qt::Orientation _overlapDirection,
|
||||||
|
const Qt::Orientation _flowDirection)
|
||||||
: QLayout(parent), overlapPercentage(overlapPercentage), maxColumns(maxColumns), maxRows(maxRows),
|
: QLayout(parent), overlapPercentage(overlapPercentage), maxColumns(maxColumns), maxRows(maxRows),
|
||||||
direction(direction)
|
overlapDirection(_overlapDirection), flowDirection(_flowDirection)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,17 +150,17 @@ void OverlapLayout::setGeometry(const QRect &rect)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the overlap offsets based on the layout direction and overlap percentage.
|
// Calculate the overlap offsets based on the layout direction and overlap percentage.
|
||||||
const int overlapOffsetWidth = (direction == Qt::Horizontal) ? (maxItemWidth * overlapPercentage / 100) : 0;
|
const int overlapOffsetWidth = (overlapDirection == Qt::Horizontal) ? (maxItemWidth * overlapPercentage / 100) : 0;
|
||||||
const int overlapOffsetHeight = (direction == Qt::Vertical) ? (maxItemHeight * overlapPercentage / 100) : 0;
|
const int overlapOffsetHeight = (overlapDirection == Qt::Vertical) ? (maxItemHeight * overlapPercentage / 100) : 0;
|
||||||
|
|
||||||
// Determine the number of columns based on layout constraints and available space.
|
// Determine the number of columns based on layout constraints and available space.
|
||||||
int columns;
|
int columns;
|
||||||
if (direction == Qt::Horizontal) {
|
if (flowDirection == Qt::Horizontal) {
|
||||||
if (maxColumns > 0) {
|
if (maxColumns > 0) {
|
||||||
// Calculate the maximum possible columns given the available width and overlap.
|
// Calculate the maximum possible columns given the available width and overlap.
|
||||||
const int availableColumns = (availableWidth + overlapOffsetWidth) / (maxItemWidth - overlapOffsetWidth);
|
const int availableColumns = (availableWidth + overlapOffsetWidth) / (maxItemWidth - overlapOffsetWidth);
|
||||||
// Use the smaller of maxColumns and availableColumns.
|
// Use the smaller of maxColumns and availableColumns.
|
||||||
qDebug() << " Max Columns " << maxColumns << " available columns " << availableColumns;
|
qCDebug(OverlapLayoutLog) << " Max Columns " << maxColumns << " available columns " << availableColumns;
|
||||||
columns = qMin(maxColumns, availableColumns);
|
columns = qMin(maxColumns, availableColumns);
|
||||||
} else {
|
} else {
|
||||||
// If no maxColumns constraint, allow as many columns as possible.
|
// If no maxColumns constraint, allow as many columns as possible.
|
||||||
|
|
@ -172,12 +173,12 @@ void OverlapLayout::setGeometry(const QRect &rect)
|
||||||
|
|
||||||
// Determine the number of rows based on layout constraints and available space.
|
// Determine the number of rows based on layout constraints and available space.
|
||||||
int rows;
|
int rows;
|
||||||
if (direction == Qt::Vertical) {
|
if (flowDirection == Qt::Vertical) {
|
||||||
if (maxRows > 0) {
|
if (maxRows > 0) {
|
||||||
// Calculate the maximum possible rows given the available height and overlap.
|
// Calculate the maximum possible rows given the available height and overlap.
|
||||||
const int availableRows = (availableHeight + overlapOffsetHeight) / (maxItemHeight - overlapOffsetHeight);
|
const int availableRows = (availableHeight + overlapOffsetHeight) / (maxItemHeight - overlapOffsetHeight);
|
||||||
// Use the smaller of maxRows and availableRows.
|
// Use the smaller of maxRows and availableRows.
|
||||||
qDebug() << " Max Rows " << maxRows << " available rows " << availableRows;
|
qCDebug(OverlapLayoutLog) << " Max Rows " << maxRows << " available rows " << availableRows;
|
||||||
rows = qMin(maxRows, availableRows);
|
rows = qMin(maxRows, availableRows);
|
||||||
} else {
|
} else {
|
||||||
// If no maxRows constraint, allow as many rows as possible.
|
// If no maxRows constraint, allow as many rows as possible.
|
||||||
|
|
@ -204,7 +205,7 @@ void OverlapLayout::setGeometry(const QRect &rect)
|
||||||
item->setGeometry(QRect(xPos, yPos, maxItemWidth, maxItemHeight));
|
item->setGeometry(QRect(xPos, yPos, maxItemWidth, maxItemHeight));
|
||||||
|
|
||||||
// Update row and column indices based on the layout direction.
|
// Update row and column indices based on the layout direction.
|
||||||
if (direction == Qt::Horizontal) {
|
if (flowDirection == Qt::Horizontal) {
|
||||||
currentColumn++;
|
currentColumn++;
|
||||||
if (currentColumn >= columns) {
|
if (currentColumn >= columns) {
|
||||||
currentColumn = 0;
|
currentColumn = 0;
|
||||||
|
|
@ -226,88 +227,82 @@ void OverlapLayout::setGeometry(const QRect &rect)
|
||||||
*/
|
*/
|
||||||
QSize OverlapLayout::calculatePreferredSize() const
|
QSize OverlapLayout::calculatePreferredSize() const
|
||||||
{
|
{
|
||||||
|
if (itemList.isEmpty()) {
|
||||||
|
return QSize(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// Determine the maximum item dimensions.
|
|
||||||
int maxItemWidth = 0;
|
int maxItemWidth = 0;
|
||||||
int maxItemHeight = 0;
|
int maxItemHeight = 0;
|
||||||
for (QLayoutItem *item : itemList) {
|
|
||||||
if (item == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!item->widget()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize itemSize = item->widget()->sizeHint();
|
for (const auto &item : itemList) {
|
||||||
maxItemWidth = qMax(maxItemWidth, itemSize.width());
|
if (item) {
|
||||||
maxItemHeight = qMax(maxItemHeight, itemSize.height());
|
int itemWidth = item->sizeHint().width();
|
||||||
|
int itemHeight = item->sizeHint().height();
|
||||||
|
maxItemWidth = qMax(maxItemWidth, itemWidth);
|
||||||
|
maxItemHeight = qMax(maxItemHeight, itemHeight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the overlap offsets.
|
// Compute overlap offsets
|
||||||
const int extra_for_overlap = (100 - overlapPercentage);
|
|
||||||
const int overlapOffsetWidth =
|
const int overlapOffsetWidth =
|
||||||
(direction == Qt::Horizontal) ? qRound((maxItemWidth / 100.0) * extra_for_overlap) : 0;
|
(overlapDirection == Qt::Horizontal) ? qRound(maxItemWidth * (overlapPercentage / 100.0)) : 0;
|
||||||
const int overlapOffsetHeight =
|
const int overlapOffsetHeight =
|
||||||
(direction == Qt::Vertical) ? qRound((maxItemHeight / 100.0) * extra_for_overlap) : 0;
|
(overlapDirection == Qt::Vertical) ? qRound(maxItemHeight * (overlapPercentage / 100.0)) : 0;
|
||||||
|
|
||||||
// Variables to hold the total dimensions based on layout orientation.
|
int numWidgets = itemList.size();
|
||||||
int totalWidth = 0;
|
int numColumns = 1;
|
||||||
int totalHeight = 0;
|
int numRows = 1;
|
||||||
|
|
||||||
// Calculate the total size based on the layout direction and constraints.
|
if (flowDirection == Qt::Horizontal) {
|
||||||
if (direction == Qt::Horizontal) {
|
if (maxColumns > 0) {
|
||||||
// Determine the number of columns:
|
// Calculate the number of columns based on maxColumns and available width
|
||||||
// - Use maxColumns if it is greater than 0 (constraint set by the user).
|
const int availableWidth = parentWidget()->width() - parentWidget()->contentsMargins().left() -
|
||||||
// - Otherwise, set the number of columns to the total number of items in the layout.
|
parentWidget()->contentsMargins().right();
|
||||||
const int numColumns = (maxColumns > 0) ? static_cast<int>(maxColumns) : static_cast<int>(itemList.size());
|
const int availableColumns = (availableWidth + overlapOffsetWidth) / (maxItemWidth - overlapOffsetWidth);
|
||||||
|
numColumns = qMin(maxColumns, availableColumns);
|
||||||
|
} else {
|
||||||
|
// If no maxColumns constraint, allow as many columns as possible
|
||||||
|
numColumns = numWidgets;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate the extra space required for overlaps between columns:
|
if (numColumns == 0) {
|
||||||
// - Each overlap reduces the effective width of subsequent items.
|
numColumns = 1;
|
||||||
const int extra_space_for_overlaps = overlapOffsetWidth * (numColumns - 1);
|
}
|
||||||
|
|
||||||
// Total width:
|
// Calculate the number of rows by dividing the number of widgets by the number of columns
|
||||||
// - The first item's width is fully included (maxItemWidth).
|
numRows = (numWidgets + numColumns - 1) / numColumns; // Correct rounding up
|
||||||
// - Add the space for all overlaps between adjacent items.
|
} else if (flowDirection == Qt::Vertical) {
|
||||||
totalWidth = maxItemWidth + extra_space_for_overlaps;
|
if (maxRows > 0) {
|
||||||
|
// Calculate the number of rows based on maxRows and available height
|
||||||
|
const int availableHeight = parentWidget()->height() - parentWidget()->contentsMargins().top() -
|
||||||
|
parentWidget()->contentsMargins().bottom();
|
||||||
|
const int availableRows = (availableHeight + overlapOffsetHeight) / (maxItemHeight - overlapOffsetHeight);
|
||||||
|
numRows = qMin(maxRows, availableRows);
|
||||||
|
} else {
|
||||||
|
// If no maxRows constraint, allow as many rows as needed
|
||||||
|
numRows = numWidgets;
|
||||||
|
}
|
||||||
|
|
||||||
// Determine the number of rows:
|
if (numRows == 0) {
|
||||||
// - Use maxRows if maxColumns is set (to constrain the number of rows).
|
numRows = 1;
|
||||||
// - Otherwise, assume a single row.
|
}
|
||||||
const int numRows =
|
|
||||||
(maxColumns > 0) ? qCeil(static_cast<double>(itemList.size()) / static_cast<double>(numColumns)) : 1;
|
|
||||||
|
|
||||||
// Total height:
|
// Calculate the number of columns by dividing the number of widgets by the number of rows
|
||||||
// - Multiply the number of rows by the item height (maxItemHeight).
|
numColumns = (numWidgets + numRows - 1) / numRows; // Correct rounding up
|
||||||
// - Subtract the height overlap between rows to avoid double-counting.
|
|
||||||
totalHeight = maxItemHeight * numRows - (numRows - 1) * overlapOffsetHeight;
|
|
||||||
} else if (direction == Qt::Vertical) {
|
|
||||||
// Determine the number of columns:
|
|
||||||
// - Use maxRows to calculate how many columns are needed if a row constraint exists.
|
|
||||||
// - Otherwise, assume a single column.
|
|
||||||
const int numColumns =
|
|
||||||
(maxRows != 0) ? qCeil(static_cast<double>(itemList.size()) / static_cast<double>(maxRows)) : 1;
|
|
||||||
|
|
||||||
// Total width:
|
|
||||||
// - Multiply the number of columns by the item width (maxItemWidth).
|
|
||||||
// - Subtract the width overlap between columns to avoid double-counting.
|
|
||||||
totalWidth = maxItemWidth * numColumns - (numColumns - 1) * overlapOffsetWidth;
|
|
||||||
|
|
||||||
// Determine the number of rows:
|
|
||||||
// - Use maxRows if it is greater than 0 (constraint set by the user).
|
|
||||||
// - Otherwise, set the number of rows to the total number of items in the layout.
|
|
||||||
const int numRows = (maxRows > 0) ? static_cast<int>(maxRows) : static_cast<int>(itemList.size());
|
|
||||||
|
|
||||||
// Calculate the extra space required for overlaps between rows:
|
|
||||||
// - Each overlap reduces the effective height of subsequent items.
|
|
||||||
const int extraSpaceForOverlaps = overlapOffsetHeight * (numRows - 1);
|
|
||||||
|
|
||||||
// Total height:
|
|
||||||
// - The first item's height is fully included (maxItemHeight).
|
|
||||||
// - Add the space for all overlaps between adjacent items.
|
|
||||||
totalHeight = maxItemHeight + extraSpaceForOverlaps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {totalWidth, totalHeight};
|
bool hasPartialRow = (numWidgets % numColumns != 0); // True if last row is incomplete
|
||||||
|
|
||||||
|
int totalWidth = maxItemWidth + ((numColumns - 1) * (maxItemWidth - overlapOffsetWidth));
|
||||||
|
int totalHeight = maxItemHeight + ((numRows - 1) * (maxItemHeight - overlapOffsetHeight));
|
||||||
|
|
||||||
|
if (hasPartialRow && overlapDirection == Qt::Horizontal) {
|
||||||
|
totalHeight += overlapOffsetHeight; // Ensure last row gets full space
|
||||||
|
} else if (hasPartialRow && overlapDirection == Qt::Vertical) {
|
||||||
|
totalWidth += overlapOffsetWidth; // Ensure last column gets full space
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSize(totalWidth, totalHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -344,7 +339,7 @@ QSize OverlapLayout::minimumSize() const
|
||||||
*/
|
*/
|
||||||
void OverlapLayout::setDirection(const Qt::Orientation _direction)
|
void OverlapLayout::setDirection(const Qt::Orientation _direction)
|
||||||
{
|
{
|
||||||
direction = _direction;
|
overlapDirection = _direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -381,7 +376,7 @@ void OverlapLayout::setMaxRows(const int _maxRows)
|
||||||
*/
|
*/
|
||||||
int OverlapLayout::calculateMaxColumns() const
|
int OverlapLayout::calculateMaxColumns() const
|
||||||
{
|
{
|
||||||
if (direction != Qt::Vertical || itemList.isEmpty()) {
|
if (overlapDirection != Qt::Vertical || itemList.isEmpty()) {
|
||||||
return 1; // Only relevant if the layout direction is vertical
|
return 1; // Only relevant if the layout direction is vertical
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -413,7 +408,7 @@ int OverlapLayout::calculateMaxColumns() const
|
||||||
*/
|
*/
|
||||||
int OverlapLayout::calculateRowsForColumns(const int columns) const
|
int OverlapLayout::calculateRowsForColumns(const int columns) const
|
||||||
{
|
{
|
||||||
if (direction != Qt::Vertical || itemList.isEmpty() || columns <= 0) {
|
if (overlapDirection != Qt::Vertical || itemList.isEmpty() || columns <= 0) {
|
||||||
return 1; // Only relevant if the layout direction is vertical and there are items
|
return 1; // Only relevant if the layout direction is vertical and there are items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -432,7 +427,7 @@ int OverlapLayout::calculateRowsForColumns(const int columns) const
|
||||||
*/
|
*/
|
||||||
int OverlapLayout::calculateMaxRows() const
|
int OverlapLayout::calculateMaxRows() const
|
||||||
{
|
{
|
||||||
if (direction != Qt::Horizontal || itemList.isEmpty()) {
|
if (overlapDirection != Qt::Horizontal || itemList.isEmpty()) {
|
||||||
return 1; // Only relevant if the layout direction is horizontal
|
return 1; // Only relevant if the layout direction is horizontal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -467,7 +462,7 @@ int OverlapLayout::calculateMaxRows() const
|
||||||
*/
|
*/
|
||||||
int OverlapLayout::calculateColumnsForRows(const int rows) const
|
int OverlapLayout::calculateColumnsForRows(const int rows) const
|
||||||
{
|
{
|
||||||
if (direction != Qt::Horizontal || itemList.isEmpty() || rows <= 0) {
|
if (overlapDirection != Qt::Horizontal || itemList.isEmpty() || rows <= 0) {
|
||||||
return 1; // Only relevant if the layout direction is horizontal and there are items
|
return 1; // Only relevant if the layout direction is horizontal and there are items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,11 @@
|
||||||
|
|
||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QLoggingCategory>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
inline Q_LOGGING_CATEGORY(OverlapLayoutLog, "overlap_layout");
|
||||||
|
|
||||||
class OverlapLayout : public QLayout
|
class OverlapLayout : public QLayout
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -12,7 +15,8 @@ public:
|
||||||
int overlapPercentage = 10,
|
int overlapPercentage = 10,
|
||||||
int maxColumns = 2,
|
int maxColumns = 2,
|
||||||
int maxRows = 2,
|
int maxRows = 2,
|
||||||
Qt::Orientation direction = Qt::Horizontal);
|
Qt::Orientation overlapDirection = Qt::Vertical,
|
||||||
|
Qt::Orientation flowDirection = Qt::Horizontal);
|
||||||
~OverlapLayout();
|
~OverlapLayout();
|
||||||
|
|
||||||
void addItem(QLayoutItem *item) override;
|
void addItem(QLayoutItem *item) override;
|
||||||
|
|
@ -35,7 +39,8 @@ private:
|
||||||
int overlapPercentage;
|
int overlapPercentage;
|
||||||
int maxColumns;
|
int maxColumns;
|
||||||
int maxRows;
|
int maxRows;
|
||||||
Qt::Orientation direction;
|
Qt::Orientation overlapDirection;
|
||||||
|
Qt::Orientation flowDirection;
|
||||||
|
|
||||||
// Calculate the preferred size of the layout
|
// Calculate the preferred size of the layout
|
||||||
QSize calculatePreferredSize() const;
|
QSize calculatePreferredSize() const;
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ void DeckCardZoneDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||||
for (QObject *child : layout->children()) {
|
for (QObject *child : layout->children()) {
|
||||||
QWidget *widget = qobject_cast<QWidget *>(child);
|
QWidget *widget = qobject_cast<QWidget *>(child);
|
||||||
if (widget) {
|
if (widget) {
|
||||||
widget->resize(event->size());
|
widget->setMaximumWidth(width());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,7 @@ OverlapWidget::OverlapWidget(QWidget *parent,
|
||||||
: QWidget(parent), overlapPercentage(overlapPercentage), maxColumns(maxColumns), maxRows(maxRows),
|
: QWidget(parent), overlapPercentage(overlapPercentage), maxColumns(maxColumns), maxRows(maxRows),
|
||||||
direction(direction), adjustOnResize(adjustOnResize)
|
direction(direction), adjustOnResize(adjustOnResize)
|
||||||
{
|
{
|
||||||
this->setMinimumSize(0, 0);
|
overlapLayout = new OverlapLayout(this, overlapPercentage, maxColumns, maxRows, direction, Qt::Horizontal);
|
||||||
overlapLayout = new OverlapLayout(this, overlapPercentage, maxColumns, maxRows, direction);
|
|
||||||
this->setLayout(overlapLayout);
|
this->setLayout(overlapLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ void VisualDeckEditorWidget::updateDisplay()
|
||||||
// Clear the layout first
|
// Clear the layout first
|
||||||
populateCards();
|
populateCards();
|
||||||
zoneContainer = new QWidget(scrollArea);
|
zoneContainer = new QWidget(scrollArea);
|
||||||
|
zoneContainer->setMaximumWidth(scrollArea->viewport()->width());
|
||||||
zoneContainerLayout = new QVBoxLayout(zoneContainer);
|
zoneContainerLayout = new QVBoxLayout(zoneContainer);
|
||||||
|
|
||||||
DeckCardZoneDisplayWidget *mainBoardWidget =
|
DeckCardZoneDisplayWidget *mainBoardWidget =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue