summaryrefslogtreecommitdiffstats
path: root/src/newui/buttonbar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/newui/buttonbar.cpp')
-rw-r--r--src/newui/buttonbar.cpp346
1 files changed, 346 insertions, 0 deletions
diff --git a/src/newui/buttonbar.cpp b/src/newui/buttonbar.cpp
new file mode 100644
index 00000000..8f60dabf
--- /dev/null
+++ b/src/newui/buttonbar.cpp
@@ -0,0 +1,346 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Alexander Dymo *
+ * adymo@kdevelop.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library General Public License as *
+ * published by the Free Software Foundation; either version 2 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "buttonbar.h"
+
+#include <qlayout.h>
+
+#include <kdebug.h>
+#include <kconfig.h>
+#include <kstringhandler.h>
+#include <klocale.h>
+
+#include "button.h"
+
+namespace Ideal {
+
+//ButtonLayout class
+
+ButtonLayout::ButtonLayout(ButtonBar *parent, Direction d, int margin, int spacing, const char *name)
+ :QBoxLayout(parent, d, margin, spacing, name), m_buttonBar(parent)
+{
+}
+
+QSize ButtonLayout::minimumSize() const
+{
+ QSize size = QBoxLayout::minimumSize();
+
+ if (!m_buttonBar->autoResize())
+ return size;
+
+ switch (m_buttonBar->place())
+ {
+ case Ideal::Left:
+ case Ideal::Right:
+ return QSize(size.width(),0);
+ break;
+ case Ideal::Top:
+ case Ideal::Bottom:
+ return QSize(0,size.height());
+ }
+ return QBoxLayout::minimumSize();
+}
+
+
+
+//ButtonBar class
+
+
+ButtonBar::ButtonBar(Place place, ButtonMode mode, QWidget *parent, const char *name)
+ :QWidget(parent, name), m_place(place), l(0), m_shrinked(false), m_autoResize(true)
+{
+ switch (m_place)
+ {
+ case Ideal::Left:
+ case Ideal::Right:
+ l = new ButtonLayout(this, QBoxLayout::TopToBottom, 0, 0);
+ break;
+ case Ideal::Top:
+ case Ideal::Bottom:
+ l = new ButtonLayout(this, QBoxLayout::LeftToRight, 0, 0);
+ break;
+ }
+
+ l->setResizeMode(QLayout::Minimum);
+ setMode(mode);
+
+ l->insertStretch(-1);
+}
+
+ButtonBar::~ButtonBar()
+{
+}
+
+void ButtonBar::addButton(Button *button)
+{
+ int buttonCount = m_buttons.count();
+
+ button->setMode(m_mode);
+ m_buttons.append(button);
+ l->insertWidget(buttonCount, button);
+ button->show();
+ fixDimensions();
+}
+
+void ButtonBar::removeButton(Button *button)
+{
+ m_buttons.remove(button);
+ l->remove(button);
+ delete button;
+}
+
+void ButtonBar::setMode(ButtonMode mode)
+{
+ m_mode = mode;
+ for (ButtonList::iterator it = m_buttons.begin(); it != m_buttons.end(); ++it)
+ (*it)->setMode(mode);
+}
+
+ButtonMode ButtonBar::mode() const
+{
+ return m_mode;
+}
+
+Place ButtonBar::place() const
+{
+ return m_place;
+}
+
+void ButtonBar::fixDimensions()
+{
+ switch (m_place)
+ {
+ case Ideal::Left:
+ case Ideal::Right:
+ setFixedWidth(sizeHint().width());
+ setMinimumHeight(sizeHint().height());
+ setMaximumHeight(32767);
+ break;
+ case Ideal::Top:
+ case Ideal::Bottom:
+ setFixedHeight(sizeHint().height());
+ setMinimumWidth(sizeHint().width());
+ setMaximumWidth(32767);
+ break;
+ }
+}
+
+void ButtonBar::setButtonsPlace(Ideal::Place place)
+{
+ for (ButtonList::iterator it = m_buttons.begin(); it != m_buttons.end(); ++it)
+ (*it)->setPlace(place);
+}
+
+void ButtonBar::resizeEvent(QResizeEvent *ev)
+{
+ int preferredDimension = 0;
+ int actualDimension = 0;
+ int oldDimension = 0;
+ switch (m_place)
+ {
+ case Ideal::Left:
+ case Ideal::Right:
+ preferredDimension = l->QBoxLayout::minimumSize().height();
+ actualDimension = size().height();
+ oldDimension = ev->oldSize().height();
+ break;
+ case Ideal::Top:
+ case Ideal::Bottom:
+ preferredDimension = l->QBoxLayout::minimumSize().width();
+ actualDimension = size().width();
+ oldDimension = ev->oldSize().width();
+ break;
+ }
+
+ if (preferredDimension > actualDimension)
+ shrink(preferredDimension, actualDimension);
+ else if (m_shrinked && (originalDimension() < actualDimension))
+ unshrink();
+ else if (m_shrinked && actualDimension > oldDimension)
+ deshrink(preferredDimension, actualDimension);
+
+ QWidget::resizeEvent(ev);
+}
+
+void ButtonBar::shrink(int preferredDimension, int actualDimension)
+{
+ if (!preferredDimension)
+ return;
+
+ m_shrinked = true;
+
+ uint textLength = 0;
+ QValueList<uint> texts;
+ uint maxLength = 0;
+ for (ButtonList::const_iterator it = m_buttons.constBegin(); it != m_buttons.constEnd(); ++it)
+ {
+ uint length = (*it)->text().length();
+ maxLength = length > maxLength ? length : maxLength ;
+ texts.append(length);
+ textLength += length;
+ }
+
+ uint newPreferredLength = actualDimension * textLength / preferredDimension;
+
+ uint newMaxLength = maxLength;
+ uint newTextLength;
+ do {
+ newMaxLength -= 1;
+ newTextLength = 0;
+ for (QValueList<uint>::iterator it = texts.begin(); it != texts.end(); ++it)
+ {
+ if (*it > newMaxLength)
+ *it = newMaxLength;
+ newTextLength += *it;
+ }
+ } while (newTextLength > newPreferredLength);
+
+ int i = 0;
+ for (ButtonList::iterator it = m_buttons.begin(); it != m_buttons.end(); ++it)
+ {
+ (*it)->setText(KStringHandler::rsqueeze((*it)->realText(), texts[i++]));
+ (*it)->updateSize();
+ }
+}
+
+void ButtonBar::deshrink(int preferredDimension, int actualDimension)
+{
+ if (!preferredDimension)
+ return;
+
+ m_shrinked = true;
+
+ uint textLength = 0;
+ QValueList<uint> texts;
+ uint maxLength = 0;
+ for (ButtonList::const_iterator it = m_buttons.constBegin(); it != m_buttons.constEnd(); ++it)
+ {
+ uint length = (*it)->text().length();
+ maxLength = length > maxLength ? length : maxLength ;
+ texts.append(length);
+ textLength += length;
+ }
+
+ uint newPreferredLength = actualDimension * textLength / preferredDimension;
+
+ if (newPreferredLength <= textLength)
+ return;
+
+ uint newTextLength;
+ uint prevTextLength = 0;
+ do {
+ newTextLength = 0;
+ int i = 0;
+ for (QValueList<uint>::iterator it = texts.begin(); it != texts.end(); ++it, i++)
+ {
+ if (m_buttons[i]->text().contains("..."))
+ (*it)++;
+ newTextLength += *it;
+ }
+ if (newTextLength == prevTextLength)
+ break;
+ prevTextLength = newTextLength;
+ } while (newTextLength < newPreferredLength);
+
+ int i = 0;
+ for (ButtonList::iterator it = m_buttons.begin(); it != m_buttons.end(); ++it)
+ {
+ if (texts[i] >= (*it)->realText().length())
+ (*it)->setText((*it)->realText());
+ else
+ (*it)->setText(KStringHandler::rsqueeze((*it)->realText(), texts[i]));
+ (*it)->updateSize();
+ ++i;
+ }
+}
+
+void ButtonBar::unshrink()
+{
+ for (ButtonList::iterator it = m_buttons.begin(); it != m_buttons.end(); ++it)
+ {
+ (*it)->setText((*it)->realText());
+ (*it)->updateSize();
+ }
+ m_shrinked = false;
+}
+
+int ButtonBar::originalDimension()
+{
+ int size = 0;
+ for (ButtonList::const_iterator it = m_buttons.constBegin(); it != m_buttons.constEnd(); ++it)
+ {
+ size += (*it)->sizeHint((*it)->realText()).width();
+ }
+ return size;
+}
+
+bool ButtonBar::autoResize() const
+{
+ return m_autoResize;
+}
+
+void ButtonBar::setAutoResize(bool b)
+{
+ m_autoResize = b;
+}
+
+Button *ButtonBar::firstButton()
+{
+ if (!m_buttons.isEmpty())
+ return m_buttons.first();
+ return 0;
+}
+
+Button *ButtonBar::nextTo(Button *button)
+{
+ ButtonList::iterator it = m_buttons.find(button);
+ Button *next = 0;
+ if ((*it) == m_buttons.last())
+ next = m_buttons.first();
+ else
+ {
+ it++;
+ next = *it;
+ }
+ if (next->isVisible())
+ return next;
+ else
+ return nextTo(next);
+}
+
+Button *ButtonBar::prevTo(Button *button)
+{
+ ButtonList::iterator it = m_buttons.find(button);
+ Button *prev = 0;
+ if (it == m_buttons.begin())
+ prev = m_buttons.last();
+ else
+ {
+ it--;
+ prev = *it;
+ }
+ if (prev->isVisible())
+ return prev;
+ else
+ return prevTo(prev);
+}
+
+}
+
+#include "buttonbar.moc"