diff --git a/src/frontends/qt4/iconpalette.C b/src/frontends/qt4/iconpalette.C index 867f9f210c..84e143edcc 100644 --- a/src/frontends/qt4/iconpalette.C +++ b/src/frontends/qt4/iconpalette.C @@ -27,10 +27,125 @@ using std::vector; namespace lyx { namespace frontend { +FlowLayout::FlowLayout(QWidget *parent) : QLayout(parent) +{ + setMargin(0); + setSpacing(-1); +} + + +FlowLayout::~FlowLayout() +{ + QLayoutItem *item; + while ((item = takeAt(0))) + delete item; +} + + +void FlowLayout::addItem(QLayoutItem *item) +{ + itemList.append(item); +} + + +int FlowLayout::count() const +{ + return itemList.size(); +} + + +QLayoutItem *FlowLayout::itemAt(int index) const +{ + return itemList.value(index); +} + + +QLayoutItem *FlowLayout::takeAt(int index) +{ + if (index >= 0 && index < itemList.size()) + return itemList.takeAt(index); + else + return 0; +} + + +Qt::Orientations FlowLayout::expandingDirections() const +{ + return 0; +} + + +bool FlowLayout::hasHeightForWidth() const +{ + return true; +} + + +int FlowLayout::heightForWidth(int width) const +{ + int height = doLayout(QRect(0, 0, width, 0), true); + return height; +} + + +void FlowLayout::setGeometry(const QRect &rect) +{ + QLayout::setGeometry(rect); + doLayout(rect, false); +} + + +QSize FlowLayout::sizeHint() const +{ + int const ncols = 5; + int const rows = (itemList.size() - 1 )/ncols + 1; + int const cols = qMin(rows * itemList.size(), ncols); + return QSize(cols * minimumSize().width() + 1, + rows * minimumSize().height() + 1); +} + + +QSize FlowLayout::minimumSize() const +{ + QSize size; + int const n = itemList.size(); + for (int i = 0; i < n; ++i) { + size = size.expandedTo(itemList.at(i)->minimumSize()); + } + return size; +} + + +int FlowLayout::doLayout(const QRect &rect, bool testOnly) const +{ + int x = rect.x(); + int y = rect.y(); + int lineHeight = 0; + + for (int i = 0; i < itemList.size(); ++i) { + QLayoutItem * item = itemList.at(i); + int nextX = x + item->sizeHint().width() + spacing(); + if (nextX - spacing() > rect.right() && lineHeight > 0) { + x = rect.x(); + y = y + lineHeight + spacing(); + nextX = x + item->sizeHint().width() + spacing(); + lineHeight = 0; + } + + if (!testOnly) + item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); + + x = nextX; + lineHeight = qMax(lineHeight, item->sizeHint().height()); + } + return y + lineHeight - rect.y(); +} + + IconPalette::IconPalette(QWidget * parent, char const ** entries) : QWidget(parent) { - QGridLayout * layout_ = new QGridLayout(this); + FlowLayout * layout_ = new FlowLayout(this); layout_->setSpacing(0); int const button_size = 40; @@ -41,9 +156,7 @@ IconPalette::IconPalette(QWidget * parent, char const ** entries) p->setToolTip(toqstr(string("\\") + entries[i])); connect(p, SIGNAL(clicked()), this, SLOT(clicked())); buttons_.push_back(make_pair(p, entries[i])); - // put in a grid layout with 5 cols - int const row = i/5; - layout_->addWidget(p, row, i - 5*row); + layout_->addWidget(p); } } diff --git a/src/frontends/qt4/iconpalette.h b/src/frontends/qt4/iconpalette.h index 49c02dfc0b..d8f3aaa21a 100644 --- a/src/frontends/qt4/iconpalette.h +++ b/src/frontends/qt4/iconpalette.h @@ -13,6 +13,9 @@ #define ICONPALETTE_H #include +#include +#include +#include #include #include @@ -23,6 +26,29 @@ class QPushButton; namespace lyx { namespace frontend { +class FlowLayout : public QLayout +{ +public: + FlowLayout(QWidget *parent); + ~FlowLayout(); + + void addItem(QLayoutItem *item); + Qt::Orientations expandingDirections() const; + bool hasHeightForWidth() const; + int heightForWidth(int) const; + QSize minimumSize() const; + void setGeometry(const QRect &rect); + QSize sizeHint() const; + QLayoutItem * takeAt(int index); + QLayoutItem * itemAt(int index) const; + int count() const; + +private: + int doLayout(const QRect &rect, bool testOnly) const; + QList itemList; +}; + + /** * For holding an arbitrary set of icons. */