Przeglądaj źródła

ENH: Implemented justified style for flow layout

It allows variable sized items (so that they use the space optimally) and nice visual alignment at the same time
(all rows have the same width).
Andras Lasso 8 lat temu
rodzic
commit
138d8aab54

+ 22 - 2
Libs/Widgets/Testing/Cpp/ctkFlowLayoutTest1.cpp

@@ -54,7 +54,27 @@ int ctkFlowLayoutTest1(int argc, char * argv [] )
  
   widget1.setLayout(flowLayout1);
   widget1.show();
-  
+
+  QWidget widget1justified(0);
+  widget1justified.setWindowTitle("1) Horizontal, justified");
+  ctkFlowLayout* flowLayout1justified = new ctkFlowLayout(&widget1justified);
+  flowLayout1justified->setAlignItems(false);
+  flowLayout1justified->setAlignment(Qt::AlignJustify);
+
+  flowLayout1justified->addWidget(new QPushButton("1 text text text text"));
+  flowLayout1justified->addWidget(new QPushButton("2 text text text text text text text text"));
+  flowLayout1justified->addWidget(new QPushButton("3 text"));
+  flowLayout1justified->addWidget(new QPushButton("4 text text text text text text"));
+  flowLayout1justified->addWidget(new QPushButton("5 text text"));
+  flowLayout1justified->addWidget(new QPushButton("6 text text text text"));
+  flowLayout1justified->addWidget(new QPushButton("7 text text text text text text text"));
+  flowLayout1justified->addWidget(new QPushButton("8 text text text"));
+  flowLayout1justified->addWidget(new QPushButton("9"));
+  flowLayout1justified->addWidget(new QPushButton("10 text text text text text text text text text"));
+
+  widget1justified.setLayout(flowLayout1justified);
+  widget1justified.show();
+
   QWidget widget2(0);
   widget2.setWindowTitle("2) Horizontal");
   ctkFlowLayout* flowLayout2 = new ctkFlowLayout;
@@ -103,7 +123,7 @@ int ctkFlowLayoutTest1(int argc, char * argv [] )
   flowLayout4->setOrientation(Qt::Vertical);
   flowLayout4->setVerticalSpacing(0);
   flowLayout4->setHorizontalSpacing(0);
-  
+
   if (argc < 2 || QString(argv[1]) != "-I")
     {
     QTimer::singleShot(200, &app, SLOT(quit()));

+ 14 - 0
Libs/Widgets/ctkFlowLayout.cpp

@@ -126,6 +126,7 @@ int ctkFlowLayoutPrivate::doLayout(const QRect& rect, bool testOnly)const
   int spaceX = q->horizontalSpacing();
   int spaceY = q->verticalSpacing();
   int space = this->Orientation == Qt::Horizontal ? spaceX : spaceY;
+  QLayoutItem* previousItem = NULL;
   foreach (QLayoutItem* item, this->ItemList)
     {
     QWidget *wid = item->widget();
@@ -146,6 +147,18 @@ int ctkFlowLayoutPrivate::doLayout(const QRect& rect, bool testOnly)const
     if (this->Orientation == Qt::Horizontal &&
         (next.x() - space > max) && length > 0)
       {
+      // If justified alignment is requested then expand the last item in the row
+      // to fill the available space. If the width of items were highly varying then
+      // expanding width of all items proportionally could provide visually more
+      // apealing results, but expanding only the last item was much simpler to implement,
+      // and works very well most of the cases.
+      if (!testOnly && q->alignment() == Qt::AlignJustify && previousItem)
+        {
+        QRect geometry = previousItem->geometry();
+        geometry.adjust(0, 0, max + space - pos.x(), 0);
+        previousItem->setGeometry(geometry);
+        maxX = qMax(maxX, geometry.right() + right);
+        }
       pos = QPoint(effectiveRect.x(), pos.y() + length + space);
       next = pos + QPoint(itemSize.width() + space, 0);
       length = 0;
@@ -168,6 +181,7 @@ int ctkFlowLayoutPrivate::doLayout(const QRect& rect, bool testOnly)const
     pos = next;
     length = qMax(length, this->Orientation == Qt::Horizontal ?
       itemSize.height() : itemSize.width());
+    previousItem = item;
     }
   return this->Orientation == Qt::Horizontal ? maxY : maxX;
 }