You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdevelop/src/newui/buttonbar.cpp

347 lines
9.1 KiB

/***************************************************************************
* 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., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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"