|
|
|
/***************************************************************************
|
|
|
|
* 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 <tqlayout.h>
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <tdeconfig.h>
|
|
|
|
#include <kstringhandler.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
|
|
|
|
#include "button.h"
|
|
|
|
|
|
|
|
namespace Ideal {
|
|
|
|
|
|
|
|
//ButtonLayout class
|
|
|
|
|
|
|
|
ButtonLayout::ButtonLayout(ButtonBar *parent, Direction d, int margin, int spacing, const char *name)
|
|
|
|
:TQBoxLayout(parent, d, margin, spacing, name), m_buttonBar(parent)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
TQSize ButtonLayout::minimumSize() const
|
|
|
|
{
|
|
|
|
TQSize size = TQBoxLayout::minimumSize();
|
|
|
|
|
|
|
|
if (!m_buttonBar->autoResize())
|
|
|
|
return size;
|
|
|
|
|
|
|
|
switch (m_buttonBar->place())
|
|
|
|
{
|
|
|
|
case Ideal::Left:
|
|
|
|
case Ideal::Right:
|
|
|
|
return TQSize(size.width(),0);
|
|
|
|
break;
|
|
|
|
case Ideal::Top:
|
|
|
|
case Ideal::Bottom:
|
|
|
|
return TQSize(0,size.height());
|
|
|
|
}
|
|
|
|
return TQBoxLayout::minimumSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//ButtonBar class
|
|
|
|
|
|
|
|
|
|
|
|
ButtonBar::ButtonBar(Place place, ButtonMode mode, TQWidget *parent, const char *name)
|
|
|
|
:TQWidget(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, TQBoxLayout::TopToBottom, 0, 0);
|
|
|
|
break;
|
|
|
|
case Ideal::Top:
|
|
|
|
case Ideal::Bottom:
|
|
|
|
l = new ButtonLayout(this, TQBoxLayout::LeftToRight, 0, 0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
l->setResizeMode(TQLayout::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(TQResizeEvent *ev)
|
|
|
|
{
|
|
|
|
int preferredDimension = 0;
|
|
|
|
int actualDimension = 0;
|
|
|
|
int oldDimension = 0;
|
|
|
|
switch (m_place)
|
|
|
|
{
|
|
|
|
case Ideal::Left:
|
|
|
|
case Ideal::Right:
|
|
|
|
preferredDimension = l->TQBoxLayout::minimumSize().height();
|
|
|
|
actualDimension = size().height();
|
|
|
|
oldDimension = ev->oldSize().height();
|
|
|
|
break;
|
|
|
|
case Ideal::Top:
|
|
|
|
case Ideal::Bottom:
|
|
|
|
preferredDimension = l->TQBoxLayout::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);
|
|
|
|
|
|
|
|
TQWidget::resizeEvent(ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ButtonBar::shrink(int preferredDimension, int actualDimension)
|
|
|
|
{
|
|
|
|
if (!preferredDimension)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_shrinked = true;
|
|
|
|
|
|
|
|
uint textLength = 0;
|
|
|
|
TQValueList<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 (TQValueList<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;
|
|
|
|
TQValueList<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 (TQValueList<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"
|