diff options
Diffstat (limited to 'src/newui/buttonbar.cpp')
-rw-r--r-- | src/newui/buttonbar.cpp | 346 |
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" |