/*************************************************************************** * 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 #include #include #include #include #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 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::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 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::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"