/*************************************************************************** kmultitabbar.cpp - description ------------------- begin : 2001 copyright : (C) 2001,2002,2003 by Joseph Wenninger ***************************************************************************/ /*************************************************************************** This library 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 library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ***************************************************************************/ #include "kmultitabbar.h" #include "kmultitabbar.moc" #include "kmultitabbar_p.h" #include "kmultitabbar_p.moc" #include #include #include #include #include #include #include #include #include #include #include #define NEARBYINT(i) ((int(float(i) + 0.5))) class KMultiTabBarTabPrivate { public: TQPixmap pix; }; KMultiTabBarInternal::KMultiTabBarInternal(TQWidget *tqparent, KMultiTabBar::KMultiTabBarMode bm):TQScrollView(tqparent) { m_expandedTabSize=-1; m_showActiveTabTexts=false; m_tabs.setAutoDelete(true); m_barMode=bm; setHScrollBarMode(AlwaysOff); setVScrollBarMode(AlwaysOff); if (bm==KMultiTabBar::Vertical) { box=new TQWidget(viewport()); mainLayout=new TQVBoxLayout(box); mainLayout->setAutoAdd(true); box->setFixedWidth(24); setFixedWidth(24); } else { box=new TQWidget(viewport()); mainLayout=new TQHBoxLayout(box); mainLayout->setAutoAdd(true); box->setFixedHeight(24); setFixedHeight(24); } addChild(box); setFrameStyle(NoFrame); viewport()->setBackgroundMode(TQt::PaletteBackground); /* box->setPaletteBackgroundColor(TQt::red); setPaletteBackgroundColor(TQt::green);*/ } void KMultiTabBarInternal::setStyle(enum KMultiTabBar::KMultiTabBarStyle style) { m_style=style; for (uint i=0;isetStyle(m_style); if ( (m_style==KMultiTabBar::KDEV3) || (m_style==KMultiTabBar::KDEV3ICON ) ) { delete mainLayout; mainLayout=0; resizeEvent(0); } else if (mainLayout==0) { if (m_barMode==KMultiTabBar::Vertical) { box=new TQWidget(viewport()); mainLayout=new TQVBoxLayout(box); box->setFixedWidth(24); setFixedWidth(24); } else { box=new TQWidget(viewport()); mainLayout=new TQHBoxLayout(box); box->setFixedHeight(24); setFixedHeight(24); } addChild(box); for (uint i=0;iadd(m_tabs.at(i)); mainLayout->setAutoAdd(true); } viewport()->tqrepaint(); } void KMultiTabBarInternal::drawContents ( TQPainter * paint, int clipx, int clipy, int clipw, int cliph ) { TQScrollView::drawContents (paint , clipx, clipy, clipw, cliph ); if (m_position==KMultiTabBar::Right) { paint->setPen(tqcolorGroup().shadow()); paint->drawLine(0,0,0,viewport()->height()); paint->setPen(tqcolorGroup().background().dark(120)); paint->drawLine(1,0,1,viewport()->height()); } else if (m_position==KMultiTabBar::Left) { paint->setPen(tqcolorGroup().light()); paint->drawLine(23,0,23,viewport()->height()); paint->drawLine(22,0,22,viewport()->height()); paint->setPen(tqcolorGroup().shadow()); paint->drawLine(0,0,0,viewport()->height()); } else if (m_position==KMultiTabBar::Bottom) { paint->setPen(tqcolorGroup().shadow()); paint->drawLine(0,0,viewport()->width(),0); paint->setPen(tqcolorGroup().background().dark(120)); paint->drawLine(0,1,viewport()->width(),1); } else { paint->setPen(tqcolorGroup().light()); paint->drawLine(0,23,viewport()->width(),23); paint->drawLine(0,22,viewport()->width(),22); /* paint->setPen(tqcolorGroup().shadow()); paint->drawLine(0,0,0,viewport()->height());*/ } } void KMultiTabBarInternal::contentsMousePressEvent(TQMouseEvent *ev) { ev->ignore(); } void KMultiTabBarInternal::mousePressEvent(TQMouseEvent *ev) { ev->ignore(); } #define CALCDIFF(m_tabs,diff,i) if (m_lines>(int)lines) {\ /*kdDebug()<<"i="<tqgeometry()<setGeometry(0,0,width(),height()); int lines=1; uint space; float tmp=0; if ((m_position==KMultiTabBar::Bottom) || (m_position==KMultiTabBar::Top)) space=width(); else space=height(); int cnt=0; //CALCULATE LINES const uint tabCount=m_tabs.count(); for (uint i=0;ineededSize(); if (tmp>space) { if (cnt>1)i--; else if (i==(tabCount-1)) break; cnt=0; tmp=0; lines++; } } //SET SIZE & PLACE float diff=0; cnt=0; if ((m_position==KMultiTabBar::Bottom) || (m_position==KMultiTabBar::Top)) { setFixedHeight(lines*24); box->setFixedHeight(lines*24); m_lines=height()/24-1; lines=0; CALCDIFF(m_tabs,diff,0) tmp=-diff; //kdDebug()<<"m_lines recalculated="<neededSize()+diff; if (tmp>space) { //kdDebug()<<"about to start new line"<1) { CALCDIFF(m_tabs,diff,i) i--; } else { //kdDebug()<<"placing line on old line"<neededSize()<<"/"<height():m_tabs.at(i)->width()); if ((m_position==KMultiTabBar::Bottom) || (m_position==KMultiTabBar::Top)) box->setGeometry(0,0,size,height()); else box->setGeometry(0,0,width(),size); } } void KMultiTabBarInternal::showActiveTabTexts(bool show) { m_showActiveTabTexts=show; } KMultiTabBarTab* KMultiTabBarInternal::tab(int id) const { for (TQPtrListIterator it(m_tabs);it.current();++it){ if (it.current()->id()==id) return it.current(); } return 0; } bool KMultiTabBarInternal::eventFilter(TQObject *, TQEvent *e) { if (e->type()==TQEvent::Resize) resizeEvent(0); return false; } int KMultiTabBarInternal::appendTab(const TQPixmap &pic ,int id,const TQString& text) { KMultiTabBarTab *tab; m_tabs.append(tab= new KMultiTabBarTab(pic,text,id,box,m_position,m_style)); tab->installEventFilter(this); tab->showActiveTabText(m_showActiveTabTexts); if (m_style==KMultiTabBar::KONTQSBC) { if (m_expandedTabSizeneededSize()) { m_expandedTabSize=tab->neededSize(); for (uint i=0;isetSize(m_expandedTabSize); } else tab->setSize(m_expandedTabSize); } else tab->updateState(); tab->show(); resizeEvent(0); return 0; } void KMultiTabBarInternal::removeTab(int id) { for (uint pos=0;posid()==id) { m_tabs.remove(pos); resizeEvent(0); break; } } } void KMultiTabBarInternal::setPosition(enum KMultiTabBar::KMultiTabBarPosition pos) { m_position=pos; for (uint i=0;isetTabsPosition(m_position); viewport()->tqrepaint(); } KMultiTabBarButton::KMultiTabBarButton(const TQPixmap& pic,const TQString& text, TQPopupMenu *popup, int id,TQWidget *tqparent,KMultiTabBar::KMultiTabBarPosition pos,KMultiTabBar::KMultiTabBarStyle style) :TQPushButton(TQIconSet(),text,tqparent),m_style(style) { setIconSet(pic); setText(text); m_position=pos; if (popup) setPopup(popup); setFlat(true); setFixedHeight(24); setFixedWidth(24); m_id=id; TQToolTip::add(this,text); connect(this,TQT_SIGNAL(clicked()),this,TQT_SLOT(slotClicked())); } KMultiTabBarButton::KMultiTabBarButton(const TQString& text, TQPopupMenu *popup, int id,TQWidget *tqparent,KMultiTabBar::KMultiTabBarPosition pos,KMultiTabBar::KMultiTabBarStyle style) :TQPushButton(TQIconSet(),text,tqparent),m_style(style) { setText(text); m_position=pos; if (popup) setPopup(popup); setFlat(true); setFixedHeight(24); setFixedWidth(24); m_id=id; TQToolTip::add(this,text); connect(this,TQT_SIGNAL(clicked()),this,TQT_SLOT(slotClicked())); } KMultiTabBarButton::~KMultiTabBarButton() { } int KMultiTabBarButton::id() const{ return m_id; } void KMultiTabBarButton::setText(const TQString& text) { TQPushButton::setText(text); m_text=text; TQToolTip::add(this,text); } void KMultiTabBarButton::slotClicked() { emit clicked(m_id); } void KMultiTabBarButton::setPosition(KMultiTabBar::KMultiTabBarPosition pos) { m_position=pos; tqrepaint(); } void KMultiTabBarButton::setStyle(KMultiTabBar::KMultiTabBarStyle style) { m_style=style; tqrepaint(); } void KMultiTabBarButton::hideEvent( TQHideEvent* he) { TQPushButton::hideEvent(he); KMultiTabBar *tb=dynamic_cast(tqparentWidget()); if (tb) tb->updateSeparator(); } void KMultiTabBarButton::showEvent( TQShowEvent* he) { TQPushButton::showEvent(he); KMultiTabBar *tb=dynamic_cast(tqparentWidget()); if (tb) tb->updateSeparator(); } TQSize KMultiTabBarButton::tqsizeHint() const { constPolish(); int w = 0, h = 0; // calculate contents size... #ifndef TQT_NO_ICONSET if ( iconSet() && !iconSet()->isNull() ) { int iw = iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ).width() + 4; int ih = iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ).height(); w += iw; h = TQMAX( h, ih ); } #endif if ( isMenuButton() ) w += tqstyle().tqpixelMetric(TQStyle::PM_MenuButtonIndicator, this); if ( pixmap() ) { TQPixmap *pm = (TQPixmap *)pixmap(); w += pm->width(); h += pm->height(); } else { TQString s( text() ); bool empty = s.isEmpty(); if ( empty ) s = TQString::tqfromLatin1("XXXX"); TQFontMetrics fm = fontMetrics(); TQSize sz = fm.size( ShowPrefix, s ); if(!empty || !w) w += sz.width(); if(!empty || !h) h = TQMAX(h, sz.height()); } return (tqstyle().tqsizeFromContents(TQStyle::CT_ToolButton, this, TQSize(w, h)). expandedTo(TQApplication::globalStrut())); } KMultiTabBarTab::KMultiTabBarTab(const TQPixmap& pic, const TQString& text, int id,TQWidget *tqparent,KMultiTabBar::KMultiTabBarPosition pos, KMultiTabBar::KMultiTabBarStyle style) :KMultiTabBarButton(text,0,id,tqparent,pos,style), m_showActiveTabText(false) { d=new KMultiTabBarTabPrivate(); setIcon(pic); m_expandedSize=24; setToggleButton(true); } KMultiTabBarTab::~KMultiTabBarTab() { delete d; } void KMultiTabBarTab::setTabsPosition(KMultiTabBar::KMultiTabBarPosition pos) { if ((pos!=m_position) && ((pos==KMultiTabBar::Left) || (pos==KMultiTabBar::Right))) { if (!d->pix.isNull()) { TQWMatrix temp;// (1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F); temp.rotate(180); d->pix=d->pix.xForm(temp); setIconSet(d->pix); } } setPosition(pos); // tqrepaint(); } void KMultiTabBarTab::setIcon(const TQString& icon) { TQPixmap pic=SmallIcon(icon); setIcon(pic); } void KMultiTabBarTab::setIcon(const TQPixmap& icon) { if (m_style!=KMultiTabBar::KDEV3) { if ((m_position==KMultiTabBar::Left) || (m_position==KMultiTabBar::Right)) { TQWMatrix rotateMatrix; if (m_position==KMultiTabBar::Left) rotateMatrix.rotate(90); else rotateMatrix.rotate(-90); TQPixmap pic=icon.xForm(rotateMatrix); //TODO FIX THIS, THIS SHOWS WINDOW d->pix=pic; setIconSet(pic); } else setIconSet(icon); } } void KMultiTabBarTab::slotClicked() { updateState(); KMultiTabBarButton::slotClicked(); } void KMultiTabBarTab::setState(bool b) { setOn(b); updateState(); } void KMultiTabBarTab::updateState() { if (m_style!=KMultiTabBar::KONTQSBC) { if ((m_style==KMultiTabBar::KDEV3) || (m_style==KMultiTabBar::KDEV3ICON) || (isOn())) { TQPushButton::setText(m_text); } else { kdDebug()<<"KMultiTabBarTab::updateState(): setting text to an empty TQString***************"<height(),this->width());//KMultiTabBarButton::tqsizeHint(); else sh=TQSize(this->width(),this->height()); } else sh=TQSize(width,height); TQPixmap pixmap( sh.width(),height); ///,sh.height()); pixmap.fill(eraseColor()); TQPainter painter(&pixmap); TQStyle::SFlags st=TQStyle::Style_Default; st|=TQStyle::Style_Enabled; if (isOn()) st|=TQStyle::Style_On; tqstyle().tqdrawControl(TQStyle::CE_PushButton,&painter,this, TQRect(0,0,pixmap.width(),pixmap.height()), tqcolorGroup(),st); tqstyle().tqdrawControl(TQStyle::CE_PushButtonLabel,&painter,this, TQRect(0,0,pixmap.width(),pixmap.height()), tqcolorGroup(),st); switch (m_position) { case KMultiTabBar::Left: paint->rotate(-90); paint->drawPixmap(1-pixmap.width(),0,pixmap); break; case KMultiTabBar::Right: paint->rotate(90); paint->drawPixmap(0,1-pixmap.height(),pixmap); break; default: paint->drawPixmap(0,0,pixmap); break; } // tqstyle().tqdrawControl(TQStyle::CE_PushButtonLabel,painter,this, TQRect(0,0,pixmap.width(),pixmap.height()), // tqcolorGroup(),TQStyle::Style_Enabled); } void KMultiTabBarTab::drawButtonClassic(TQPainter *paint) { TQPixmap pixmap; if ( iconSet()) pixmap = iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ); paint->fillRect(0, 0, 24, 24, tqcolorGroup().background()); if (!isOn()) { if (m_position==KMultiTabBar::Right) { paint->fillRect(0,0,21,21,TQBrush(tqcolorGroup().background())); paint->setPen(tqcolorGroup().background().dark(150)); paint->drawLine(0,22,23,22); paint->drawPixmap(12-pixmap.width()/2,12-pixmap.height()/2,pixmap); paint->setPen(tqcolorGroup().shadow()); paint->drawLine(0,0,0,23); paint->setPen(tqcolorGroup().background().dark(120)); paint->drawLine(1,0,1,23); } else if ((m_position==KMultiTabBar::Bottom) || (m_position==KMultiTabBar::Top)) { paint->fillRect(0,1,23,22,TQBrush(tqcolorGroup().background())); paint->drawPixmap(12-pixmap.width()/2,12-pixmap.height()/2,pixmap); paint->setPen(tqcolorGroup().background().dark(120)); paint->drawLine(23,0,23,23); paint->setPen(tqcolorGroup().light()); paint->drawLine(0,22,23,22); paint->drawLine(0,23,23,23); paint->setPen(tqcolorGroup().shadow()); paint->drawLine(0,0,23,0); paint->setPen(tqcolorGroup().background().dark(120)); paint->drawLine(0,1,23,1); } else { paint->setPen(tqcolorGroup().background().dark(120)); paint->drawLine(0,23,23,23); paint->fillRect(0,0,23,21,TQBrush(tqcolorGroup().background())); paint->drawPixmap(12-pixmap.width()/2,12-pixmap.height()/2,pixmap); paint->setPen(tqcolorGroup().light()); paint->drawLine(23,0,23,23); paint->drawLine(22,0,22,23); paint->setPen(tqcolorGroup().shadow()); paint->drawLine(0,0,0,23); } } else { if (m_position==KMultiTabBar::Right) { paint->setPen(tqcolorGroup().shadow()); paint->drawLine(0,height()-1,23,height()-1); paint->drawLine(0,height()-2,23,height()-2); paint->drawLine(23,0,23,height()-1); paint->drawLine(22,0,22,height()-1); paint->fillRect(0,0,21,height()-3,TQBrush(tqcolorGroup().light())); paint->drawPixmap(10-pixmap.width()/2,10-pixmap.height()/2,pixmap); if (m_showActiveTabText) { if (height()<25+4) return; TQPixmap tpixmap(height()-25-3, width()-2); TQPainter painter(&tpixmap); painter.fillRect(0,0,tpixmap.width(),tpixmap.height(),TQBrush(tqcolorGroup().light())); painter.setPen(tqcolorGroup().text()); painter.drawText(0,+width()/2+TQFontMetrics(TQFont()).height()/2,m_text); paint->rotate(90); kdDebug()<<"tpixmap.width:"<drawPixmap(25,-tpixmap.height()+1,tpixmap); } } else if (m_position==KMultiTabBar::Top) { paint->fillRect(0,0,width()-1,23,TQBrush(tqcolorGroup().light())); paint->drawPixmap(10-pixmap.width()/2,10-pixmap.height()/2,pixmap); if (m_showActiveTabText) { paint->setPen(tqcolorGroup().text()); paint->drawText(25,height()/2+TQFontMetrics(TQFont()).height()/2,m_text); } } else if (m_position==KMultiTabBar::Bottom) { paint->setPen(tqcolorGroup().shadow()); paint->drawLine(0,23,width()-1,23); paint->drawLine(0,22,width()-1,22); paint->fillRect(0,0,width()-1,21,TQBrush(tqcolorGroup().light())); paint->drawPixmap(10-pixmap.width()/2,10-pixmap.height()/2,pixmap); if (m_showActiveTabText) { paint->setPen(tqcolorGroup().text()); paint->drawText(25,height()/2+TQFontMetrics(TQFont()).height()/2,m_text); } } else { paint->setPen(tqcolorGroup().shadow()); paint->drawLine(0,height()-1,23,height()-1); paint->drawLine(0,height()-2,23,height()-2); paint->fillRect(0,0,23,height()-3,TQBrush(tqcolorGroup().light())); paint->drawPixmap(10-pixmap.width()/2,10-pixmap.height()/2,pixmap); if (m_showActiveTabText) { if (height()<25+4) return; TQPixmap tpixmap(height()-25-3, width()-2); TQPainter painter(&tpixmap); painter.fillRect(0,0,tpixmap.width(),tpixmap.height(),TQBrush(tqcolorGroup().light())); painter.setPen(tqcolorGroup().text()); painter.drawText(tpixmap.width()-TQFontMetrics(TQFont()).width(m_text),+width()/2+TQFontMetrics(TQFont()).height()/2,m_text); paint->rotate(-90); kdDebug()<<"tpixmap.width:"<drawPixmap(-24-tpixmap.width(),2,tpixmap); } } } } KMultiTabBar::KMultiTabBar(KMultiTabBarMode bm, TQWidget *tqparent,const char *name):TQWidget(tqparent,name) { m_buttons.setAutoDelete(false); if (bm==Vertical) { m_l=new TQVBoxLayout(this); tqsetSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Expanding, true); // setFixedWidth(24); } else { m_l=new TQHBoxLayout(this); tqsetSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Fixed, true); // setFixedHeight(24); } m_l->setMargin(0); m_l->setAutoAdd(false); m_internal=new KMultiTabBarInternal(this,bm); setPosition((bm==KMultiTabBar::Vertical)?KMultiTabBar::Right:KMultiTabBar::Bottom); setStyle(VSNET); // setStyle(KDEV3); //setStyle(KONTQSBC); m_l->insertWidget(0,m_internal); m_l->insertWidget(0,m_btnTabSep=new TQFrame(this)); m_btnTabSep->setFixedHeight(4); m_btnTabSep->setFrameStyle(TQFrame::Panel | TQFrame::Sunken); m_btnTabSep->setLineWidth(2); m_btnTabSep->hide(); updateGeometry(); } KMultiTabBar::~KMultiTabBar() { } /*int KMultiTabBar::insertButton(TQPixmap pic,int id ,const TQString&) { (new KToolbarButton(pic,id,m_internal))->show(); return 0; }*/ int KMultiTabBar::appendButton(const TQPixmap &pic ,int id,TQPopupMenu *popup,const TQString&) { KMultiTabBarButton *btn; m_buttons.append(btn= new KMultiTabBarButton(pic,TQString(), popup,id,this,m_position,m_internal->m_style)); m_l->insertWidget(0,btn); btn->show(); m_btnTabSep->show(); return 0; } void KMultiTabBar::updateSeparator() { bool hideSep=true; for (TQPtrListIterator it(m_buttons);it.current();++it){ if (it.current()->isVisibleTo(this)) { hideSep=false; break; } } if (hideSep) m_btnTabSep->hide(); else m_btnTabSep->show(); } int KMultiTabBar::appendTab(const TQPixmap &pic ,int id ,const TQString& text) { m_internal->appendTab(pic,id,text); return 0; } KMultiTabBarButton* KMultiTabBar::button(int id) const { for (TQPtrListIterator it(m_buttons);it.current();++it){ if (it.current()->id()==id) return it.current(); } return 0; } KMultiTabBarTab* KMultiTabBar::tab(int id) const { return m_internal->tab(id); } void KMultiTabBar::removeButton(int id) { for (uint pos=0;posid()==id) { m_buttons.take(pos)->deleteLater(); break; } } if (m_buttons.count()==0) m_btnTabSep->hide(); } void KMultiTabBar::removeTab(int id) { m_internal->removeTab(id); } void KMultiTabBar::setTab(int id,bool state) { KMultiTabBarTab *ttab=tab(id); if (ttab) { ttab->setState(state); } } bool KMultiTabBar::isTabRaised(int id) const { KMultiTabBarTab *ttab=tab(id); if (ttab) { return ttab->isOn(); } return false; } void KMultiTabBar::showActiveTabTexts(bool show) { m_internal->showActiveTabTexts(show); } void KMultiTabBar::setStyle(KMultiTabBarStyle style) { m_internal->setStyle(style); } void KMultiTabBar::setPosition(KMultiTabBarPosition pos) { m_position=pos; m_internal->setPosition(pos); for (uint i=0;isetPosition(pos); } void KMultiTabBar::fontChange(const TQFont& /* oldFont */) { for (uint i=0;icount();i++) tabs()->at(i)->resize(); tqrepaint(); } TQPtrList* KMultiTabBar::tabs() {return m_internal->tabs();} TQPtrList* KMultiTabBar::buttons() {return &m_buttons;}