diff options
author | Rüdiger Timm <rt@openoffice.org> | 2008-12-16 16:42:03 +0000 |
---|---|---|
committer | Rüdiger Timm <rt@openoffice.org> | 2008-12-16 16:42:03 +0000 |
commit | 85702858a81c72b40f0e7e3ce05e677ffb996da9 (patch) | |
tree | 74fe6e751f34dab60017fa96ebce62bce617a9d3 /vcl/source | |
parent | 69b684b12e42bf1396bdffca88ca880ac3c2e00b (diff) |
CWS-TOOLING: integrate CWS alf01
2008-12-10 09:35:35 +0100 as r265152 : #158798# hide internal service
2008-12-09 15:29:11 +0100 cd r265098 : #158857# Check index correctly, must be zero
2008-12-09 12:06:21 +0100 mhu r265075 : #158857# Fixed compiler warning(s).
2008-12-09 11:09:34 +0100 cd r265064 : #158857# Added access to the window state configuration to support setting title of internal docking windows via <Module>WindowState.xcu files
2008-12-09 10:43:53 +0100 as r265063 : #158798# make resizes working better
2008-12-08 17:08:05 +0100 mhu r265010 : #158857# Fixed compiler warning(s).
2008-12-08 15:19:04 +0100 as r264999 : #158857# make WindowContentFactories.xcs part of installation set
2008-12-08 13:23:37 +0100 as r264993 : #158857# actualize size on child window
2008-12-08 10:14:05 +0100 cd r264977 : #158857# More helper functions and support to show/hide internal docking windows
2008-12-08 10:13:08 +0100 cd r264976 : #158857# SfxTitleDockingWindow now uses a factory for content window. Additional documentation for special IDs
2008-12-05 07:58:07 +0100 as r264885 : remove obsolete code (not referenced inside makefile any longer)
2008-12-04 18:57:08 +0100 mhu r264871 : #158857# Fixed compiler warning.
2008-12-04 16:13:12 +0100 mhu r264851 : #158857# Fixed compiler warning.
2008-12-04 15:46:45 +0100 as r264849 : solve merge conflicts right
2008-12-04 09:20:26 +0100 cd r264818 : 2008-12-04 09:19:32 +0100 cd r264817 : 2008-12-04 09:19:07 +0100 cd r264816 : Resolved conflicts
2008-12-04 09:13:27 +0100 cd r264815 : New window content factory manager with configuration support added.
2008-12-03 15:15:50 +0100 as r264791 : #158798# make sure tab window will show its content the first time its made visible
2008-12-03 10:59:30 +0100 as r264752 : #158798# new helper service for a dockable tab control window
2008-12-02 15:39:48 +0100 as r264707 : #158798# fix crash in MouseButtonDown for TabControl
2008-12-02 10:28:20 +0100 cd r264665 : #158857# Resolved conflicts on merge
2008-12-02 09:58:36 +0100 cd r264662 : #158857# Added predefined slots for the internal docking windows. Currently only ten predefined docking windows are possible
2008-12-01 09:44:49 +0100 cd r264586 : #158857# Fix problem with close the floated docking window with closer
2008-11-28 13:42:34 +0100 cd r264550 : #158857# First additional code to create a docking window. Very preliminary and not near to final code
2008-11-28 11:53:51 +0100 cd r264538 : #158857# First additional code to create a docking window. Very preliminary and not near to final code
2008-11-28 11:32:38 +0100 cd r264534 : #158857# First version of docking window factory and additional helper classes
2008-11-21 09:46:36 +0100 jsc r264110 : #158798# remove warnings
2008-11-20 17:59:07 +0100 pb r264090 : fix: #158798# tabcontainerwindow.obj and tabdialog.obj added
2008-11-20 17:55:57 +0100 pb r264089 : fix: #i158798# implementation of service TabContainerWindow
2008-11-20 17:52:52 +0100 pb r264088 : fix: #158798# implementation of the TabDialog and its Pages for the TabContainerWindow service
2008-11-20 17:51:26 +0100 pb r264087 : fix: #i158798# TabContainerWindow added
2008-11-20 17:50:11 +0100 pb r264086 : fix: #158798# tabcontainerwindow.obj and tabdialog.obj added
2008-11-20 17:47:16 +0100 pb r264085 : fix: #158798# new resource: TabDialog DLG_TABCONTAINER
2008-11-20 17:46:06 +0100 pb r264084 : fix: #i158798# added ids for TABCONTAINER...
2008-11-20 17:43:19 +0100 pb r264082 : fix: #158798# IMPLEMENTATION/SERVICENAME_TABCONTAINERWINDOW added
2008-11-20 17:43:00 +0100 pb r264081 : fix: #i158798# implementation of service TabContainerWindow
2008-11-20 17:40:42 +0100 pb r264080 : fix: #158798# TabContainerWindow.idl added
2008-11-20 17:36:57 +0100 pb r264079 : fix: #158798# new service TabContainerWindow
2008-11-20 17:33:05 +0100 pb r264077 : fix: #158798# show tooltip if only a image is shown
2008-11-18 15:10:08 +0100 jsc r263770 : CWS-TOOLING: rebase CWS alf01 to trunk@263288 (milestone: DEV300:m35)
2008-11-18 09:55:21 +0100 jsc r263749 : merge from trunk
2008-11-18 09:54:30 +0100 jsc r263748 : merge from trunk
2008-11-13 17:01:17 +0100 pl r263655 : fix some warnings
2008-10-21 15:38:37 +0200 pl r262572 : #i95201# add: EnablePage
2008-10-20 18:57:53 +0200 pl r262335 : #i95201# add: images for tab items
2008-10-20 17:26:50 +0200 pl r262330 : #i95201# remove old tools list
Diffstat (limited to 'vcl/source')
-rw-r--r-- | vcl/source/control/tabctrl.cxx | 633 |
1 files changed, 378 insertions, 255 deletions
diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx index 5509e7a4eb18..25a086060fcf 100644 --- a/vcl/source/control/tabctrl.cxx +++ b/vcl/source/control/tabctrl.cxx @@ -46,6 +46,7 @@ #include <vcl/tabpage.hxx> #include <vcl/tabctrl.hxx> #include <vcl/controllayout.hxx> +#include <vcl/sound.hxx> #include <vcl/window.h> @@ -54,18 +55,6 @@ // ======================================================================= -struct ImplTabCtrlData -{ - PushButton* mpLeftBtn; - PushButton* mpRightBtn; - std::hash_map< int, int > maLayoutPageIdToLine; - std::hash_map< int, int > maLayoutLineToPageId; - std::vector< Rectangle > maTabRectangles; - Point maItemsOffset; // offset of the tabitems -}; - -// ----------------------------------------------------------------------- - struct ImplTabItem { USHORT mnId; @@ -77,10 +66,28 @@ struct ImplTabItem ULONG mnHelpId; Rectangle maRect; USHORT mnLine; - BOOL mbFullVisible; + bool mbFullVisible; + bool mbEnabled; + Image maTabImage; + + ImplTabItem() + : mnId( 0 ), mnTabPageResId( 0 ), mpTabPage( NULL ), mnHelpId( 0 ), + mnLine( 0 ), mbFullVisible( FALSE ), mbEnabled( true ) + {} }; -DECLARE_LIST( ImplTabItemList, ImplTabItem* ) +// ----------------------------------------------------------------------- + +struct ImplTabCtrlData +{ + PushButton* mpLeftBtn; + PushButton* mpRightBtn; + std::hash_map< int, int > maLayoutPageIdToLine; + std::hash_map< int, int > maLayoutLineToPageId; + std::vector< Rectangle > maTabRectangles; + Point maItemsOffset; // offset of the tabitems + std::vector< ImplTabItem > maItemList; +}; // ----------------------------------------------------------------------- @@ -133,7 +140,6 @@ void TabControl::ImplInit( Window* pParent, WinBits nStyle ) Control::ImplInit( pParent, nStyle, NULL ); - mpItemList = new ImplTabItemList( 8, 8 ); mnLastWidth = 0; mnLastHeight = 0; mnBtnSize = 0; @@ -283,17 +289,6 @@ TabControl::~TabControl() { ImplFreeLayoutData(); - // Alle Items loeschen - ImplTabItem* pItem = mpItemList->First(); - while ( pItem ) - { - delete pItem; - pItem = mpItemList->Next(); - } - - // Itemlist loeschen - delete mpItemList; - // TabCtrl-Daten loeschen if ( mpTabCtrlData ) { @@ -309,13 +304,11 @@ TabControl::~TabControl() ImplTabItem* TabControl::ImplGetItem( USHORT nId ) const { - ImplTabItem* pItem = mpItemList->First(); - while ( pItem ) + for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin(); + it != mpTabCtrlData->maItemList.end(); ++it ) { - if ( pItem->mnId == nId ) - return pItem; - - pItem = mpItemList->Next(); + if( it->mnId == nId ) + return &(*it); } return NULL; @@ -395,6 +388,16 @@ Size TabControl::ImplGetItemSize( ImplTabItem* pItem, long nMaxWidth ) { pItem->maFormatText = pItem->maText; Size aSize( GetCtrlTextWidth( pItem->maFormatText ), GetTextHeight() ); + Size aImageSize( 0, 0 ); + if( !!pItem->maTabImage ) + { + aImageSize = pItem->maTabImage.GetSizePixel(); + if( pItem->maFormatText.Len() ) + aImageSize.Width() += GetTextHeight()/4; + } + aSize.Width() += aImageSize.Width(); + if( aImageSize.Height() > aSize.Height() ) + aSize.Height() = aImageSize.Height(); Region aCtrlRegion( Rectangle( (const Point&)Point( 0, 0 ), aSize ) ); Region aBoundingRgn, aContentRgn; @@ -403,8 +406,8 @@ Size TabControl::ImplGetItemSize( ImplTabItem* pItem, long nMaxWidth ) CTRL_STATE_ENABLED, aControlValue, rtl::OUString(), aBoundingRgn, aContentRgn ) ) { - Rectangle aCont(aContentRgn.GetBoundRect()); - return aCont.GetSize(); + Rectangle aCont(aContentRgn.GetBoundRect()); + return aCont.GetSize(); } aSize.Width() += TAB_TABOFFSET_X*2; @@ -426,6 +429,7 @@ Size TabControl::ImplGetItemSize( ImplTabItem* pItem, long nMaxWidth ) { pItem->maFormatText.Erase( pItem->maFormatText.Len()-aAppendStr.Len()-1, 1 ); aSize.Width() = GetCtrlTextWidth( pItem->maFormatText ); + aSize.Width() += aImageSize.Width(); aSize.Width() += TAB_TABOFFSET_X*2; } while ( (aSize.Width()+4 >= nMaxWidth) && (pItem->maFormatText.Len() > aAppendStr.Len()) ); @@ -436,6 +440,12 @@ Size TabControl::ImplGetItemSize( ImplTabItem* pItem, long nMaxWidth ) } } + if( pItem->maFormatText.Len() == 0 ) + { + if( aSize.Height() < aImageSize.Height()+4 ) //leave space for focus rect + aSize.Height() = aImageSize.Height()+4; + } + return aSize; } @@ -449,7 +459,7 @@ Rectangle TabControl::ImplGetTabRect( USHORT nItemPos, long nWidth, long nHeight if ( nHeight == -1 ) nHeight = aWinSize.Height(); - if ( !mpItemList->Count() ) + if ( mpTabCtrlData->maItemList.empty() ) { return Rectangle( Point( TAB_OFFSET, TAB_OFFSET ), Size( nWidth-TAB_OFFSET*2, nHeight-TAB_OFFSET*2 ) ); @@ -495,7 +505,6 @@ Rectangle TabControl::ImplGetTabRect( USHORT nItemPos, long nWidth, long nHeight long nTextWidth2 = GetTextWidth( aTestStr ); mbExtraSpace = (nTextWidth1 == nTextWidth2); - ImplTabItem* pItem; Size aSize; const long nOffsetX = 2 + GetItemsOffset().X(); const long nOffsetY = 2 + GetItemsOffset().Y(); @@ -509,128 +518,124 @@ Rectangle TabControl::ImplGetTabRect( USHORT nItemPos, long nWidth, long nHeight nMaxWidth -= GetItemsOffset().X(); mbScroll = FALSE; - if( 1 ) + + USHORT nLines = 0; + USHORT nCurLine = 0; + long nLineWidthAry[100]; + USHORT nLinePosAry[101]; + + nLineWidthAry[0] = 0; + nLinePosAry[0] = 0; + for( std::vector<ImplTabItem>::iterator it = mpTabCtrlData->maItemList.begin(); + it != mpTabCtrlData->maItemList.end(); ++it ) { - USHORT nLines = 0; - USHORT nCurLine = 0; - long nLineWidthAry[100]; - USHORT nLinePosAry[101]; - - nLineWidthAry[0] = 0; - nLinePosAry[0] = 0; - pItem = mpItemList->First(); - while ( pItem ) + aSize = ImplGetItemSize( &(*it), nMaxWidth ); + + if ( ((nX+aSize.Width()) > nWidth - 2) && (nWidth > 2+nOffsetX) ) { - aSize = ImplGetItemSize( pItem, nMaxWidth ); + if ( nLines == 99 ) + break; - if ( ((nX+aSize.Width()) > nWidth - 2) && (nWidth > 2+nOffsetX) ) - { - if ( nLines == 99 ) - break; + nX = nOffsetX; + nY += aSize.Height(); + nLines++; + nLineWidthAry[nLines] = 0; + nLinePosAry[nLines] = nPos; + } - nX = nOffsetX; - nY += aSize.Height(); - nLines++; - nLineWidthAry[nLines] = 0; - nLinePosAry[nLines] = nPos; - } + Rectangle aNewRect( Point( nX, nY ), aSize ); + if ( mbSmallInvalidate && (it->maRect != aNewRect) ) + mbSmallInvalidate = FALSE; + it->maRect = aNewRect; + it->mnLine = nLines; + it->mbFullVisible = TRUE; - Rectangle aNewRect( Point( nX, nY ), aSize ); - if ( mbSmallInvalidate && (pItem->maRect != aNewRect) ) - mbSmallInvalidate = FALSE; - pItem->maRect = aNewRect; - pItem->mnLine = nLines; - pItem->mbFullVisible = TRUE; + nLineWidthAry[nLines] += aSize.Width(); + nX += aSize.Width(); - nLineWidthAry[nLines] += aSize.Width(); - nX += aSize.Width(); + if ( it->mnId == mnCurPageId ) + nCurLine = nLines; - if ( pItem->mnId == mnCurPageId ) - nCurLine = nLines; + nPos++; + } - pItem = mpItemList->Next(); - nPos++; + if ( nLines && !mpTabCtrlData->maItemList.empty() ) + { + long nDX = 0; + long nModDX = 0; + long nIDX = 0; + USHORT i; + USHORT n; + long nLineHeightAry[100]; + long nIH = mpTabCtrlData->maItemList[0].maRect.Bottom()-2; + + i = 0; + while ( i < nLines+1 ) + { + if ( i <= nCurLine ) + nLineHeightAry[i] = nIH*(nLines-(nCurLine-i)) + GetItemsOffset().Y(); + else + nLineHeightAry[i] = nIH*(i-nCurLine-1) + GetItemsOffset().Y(); + i++; } - if ( nLines ) + i = 0; + n = 0; + nLinePosAry[nLines+1] = (USHORT)mpTabCtrlData->maItemList.size(); + for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin(); + it != mpTabCtrlData->maItemList.end(); ++it ) { - long nDX = 0; - long nModDX = 0; - long nIDX = 0; - USHORT i; - USHORT n; - long nLineHeightAry[100]; - long nIH = mpItemList->GetObject( 0 )->maRect.Bottom()-2; - - i = 0; - while ( i < nLines+1 ) + if ( i == nLinePosAry[n] ) { - if ( i <= nCurLine ) - nLineHeightAry[i] = nIH*(nLines-(nCurLine-i)) + GetItemsOffset().Y(); - else - nLineHeightAry[i] = nIH*(i-nCurLine-1) + GetItemsOffset().Y(); - i++; - } + if ( n == nLines+1 ) + break; - i = 0; - n = 0; - nLinePosAry[nLines+1] = (USHORT)mpItemList->Count(); - pItem = mpItemList->First(); - while ( pItem ) - { - if ( i == nLinePosAry[n] ) + nIDX = 0; + if( nLinePosAry[n+1]-i > 0 ) { - if ( n == nLines+1 ) - break; - - nIDX = 0; - if( nLinePosAry[n+1]-i > 0 ) - { - nDX = (nWidth-nOffsetX-nLineWidthAry[n]) / (nLinePosAry[n+1]-i); - nModDX = (nWidth-nOffsetX-nLineWidthAry[n]) % (nLinePosAry[n+1]-i); - } - else - { - // FIXME: this is a bad case of tabctrl way too small - nDX = 0; - nModDX = 0; - } - n++; + nDX = (nWidth-nOffsetX-nLineWidthAry[n]) / (nLinePosAry[n+1]-i); + nModDX = (nWidth-nOffsetX-nLineWidthAry[n]) % (nLinePosAry[n+1]-i); } - - pItem->maRect.Left() += nIDX; - pItem->maRect.Right() += nIDX+nDX; - pItem->maRect.Top() = nLineHeightAry[n-1]; - pItem->maRect.Bottom() = nLineHeightAry[n-1]+nIH; - nIDX += nDX; - - if ( nModDX ) + else { - nIDX++; - pItem->maRect.Right()++; - nModDX--; + // FIXME: this is a bad case of tabctrl way too small + nDX = 0; + nModDX = 0; } + n++; + } + + it->maRect.Left() += nIDX; + it->maRect.Right() += nIDX+nDX; + it->maRect.Top() = nLineHeightAry[n-1]; + it->maRect.Bottom() = nLineHeightAry[n-1]+nIH; + nIDX += nDX; - pItem = mpItemList->Next(); - i++; + if ( nModDX ) + { + nIDX++; + it->maRect.Right()++; + nModDX--; } + + i++; } - else {//only one line - if(ImplGetSVData()->maNWFData.mbCenteredTabs) { - pItem = mpItemList->First(); - int nRightSpace=nMaxWidth;//space left on the right by the tabs - while ( pItem ) - { - nRightSpace-=pItem->maRect.Right()-pItem->maRect.Left(); - pItem = mpItemList->Next(); - } - pItem = mpItemList->First(); - while ( pItem ) - { - pItem->maRect.Left()+=(int) (nRightSpace/2); - pItem->maRect.Right()+=(int) (nRightSpace/2); - pItem = mpItemList->Next(); - } + } + else + {//only one line + if(ImplGetSVData()->maNWFData.mbCenteredTabs) + { + int nRightSpace=nMaxWidth;//space left on the right by the tabs + for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin(); + it != mpTabCtrlData->maItemList.end(); ++it ) + { + nRightSpace-=it->maRect.Right()-it->maRect.Left(); + } + for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin(); + it != mpTabCtrlData->maItemList.end(); ++it ) + { + it->maRect.Left()+=(int) (nRightSpace/2); + it->maRect.Right()+=(int) (nRightSpace/2); } } } @@ -642,7 +647,7 @@ Rectangle TabControl::ImplGetTabRect( USHORT nItemPos, long nWidth, long nHeight ImplPosScrollBtns(); } - return mpItemList->GetObject( nItemPos )->maRect; + return size_t(nItemPos) < mpTabCtrlData->maItemList.size() ? mpTabCtrlData->maItemList[nItemPos].maRect : Rectangle(); } // ----------------------------------------------------------------------- @@ -803,23 +808,48 @@ void TabControl::ImplShowFocus() aFont.SetWeight( (!ImplGetSVData()->maNWFData.mbNoBoldTabFocus) ? WEIGHT_BOLD : WEIGHT_LIGHT ); SetFont( aFont ); - USHORT nCurPos = GetPagePos( mnCurPageId ); - Rectangle aRect = ImplGetTabRect( nCurPos ); - ImplTabItem* pItem = mpItemList->GetObject( nCurPos ); - Size aTabSize = aRect.GetSize(); - long nTextHeight = GetTextHeight(); - long nTextWidth = GetCtrlTextWidth( pItem->maFormatText ); - USHORT nOff; + USHORT nCurPos = GetPagePos( mnCurPageId ); + Rectangle aRect = ImplGetTabRect( nCurPos ); + const ImplTabItem& rItem = mpTabCtrlData->maItemList[ nCurPos ]; + Size aTabSize = aRect.GetSize(); + Size aImageSize( 0, 0 ); + long nTextHeight = GetTextHeight(); + long nTextWidth = GetCtrlTextWidth( rItem.maFormatText ); + USHORT nOff; if ( !(GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_MONO) ) nOff = 1; else nOff = 0; - aRect.Left() = aRect.Left()+((aTabSize.Width()-nTextWidth)/2)-nOff-1-1; - aRect.Top() = aRect.Top()+((aTabSize.Height()-nTextHeight)/2)-1-1; - aRect.Right() = aRect.Left()+nTextWidth+2; - aRect.Bottom() = aRect.Top()+nTextHeight+2; + if( !! rItem.maTabImage ) + { + aImageSize = rItem.maTabImage.GetSizePixel(); + if( rItem.maFormatText.Len() ) + aImageSize.Width() += GetTextHeight()/4; + } + + if( rItem.maFormatText.Len() ) + { + // show focus around text + aRect.Left() = aRect.Left()+aImageSize.Width()+((aTabSize.Width()-nTextWidth-aImageSize.Width())/2)-nOff-1-1; + aRect.Top() = aRect.Top()+((aTabSize.Height()-nTextHeight)/2)-1-1; + aRect.Right() = aRect.Left()+nTextWidth+2; + aRect.Bottom() = aRect.Top()+nTextHeight+2; + } + else + { + // show focus around image + long nXPos = aRect.Left()+((aTabSize.Width()-nTextWidth-aImageSize.Width())/2)-nOff-1; + long nYPos = aRect.Top(); + if( aImageSize.Height() < aRect.GetHeight() ) + nYPos += (aRect.GetHeight() - aImageSize.Height())/2; + + aRect.Left() = nXPos - 2; + aRect.Top() = nYPos - 2; + aRect.Right() = aRect.Left() + aImageSize.Width() + 4; + aRect.Bottom() = aRect.Top() + aImageSize.Height() + 4; + } ShowFocus( aRect ); SetFont( aOldFont ); @@ -907,14 +937,15 @@ void TabControl::ImplDrawItem( ImplTabItem* pItem, const Rectangle& rCurRect, bo if( IsMouseOver() && pItem->maRect.IsInside( GetPointerPosPixel() ) ) { nState |= CTRL_STATE_ROLLOVER; - ImplTabItem* pI; - int idx=0; - while( (pI = mpItemList->GetObject(idx++)) != NULL ) - if( (pI != pItem) && (pI->maRect.IsInside( GetPointerPosPixel() ) ) ) + for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin(); + it != mpTabCtrlData->maItemList.end(); ++it ) + { + if( (&(*it) != pItem) && (it->maRect.IsInside( GetPointerPosPixel() ) ) ) { nState &= ~CTRL_STATE_ROLLOVER; // avoid multiple highlighted tabs break; } + } } TabitemValue tiValue; @@ -994,15 +1025,37 @@ void TabControl::ImplDrawItem( ImplTabItem* pItem, const Rectangle& rCurRect, bo SetFont( aFont ); Size aTabSize = aRect.GetSize(); + Size aImageSize( 0, 0 ); long nTextHeight = GetTextHeight(); long nTextWidth = GetCtrlTextWidth( pItem->maFormatText ); - DrawCtrlText( Point( aRect.Left()+((aTabSize.Width()-nTextWidth)/2)-nOff-nOff3, - aRect.Top()+((aTabSize.Height()-nTextHeight)/2)-nOff3 ), - pItem->maFormatText, - 0, STRING_LEN, TEXT_DRAW_MNEMONIC, - bLayout ? &mpLayoutData->m_aUnicodeBoundRects : NULL, - bLayout ? &mpLayoutData->m_aDisplayText : NULL - ); + if( !! pItem->maTabImage ) + { + aImageSize = pItem->maTabImage.GetSizePixel(); + if( pItem->maFormatText.Len() ) + aImageSize.Width() += GetTextHeight()/4; + } + long nXPos = aRect.Left()+((aTabSize.Width()-nTextWidth-aImageSize.Width())/2)-nOff-nOff3; + long nYPos = aRect.Top()+((aTabSize.Height()-nTextHeight)/2)-nOff3; + if( pItem->maFormatText.Len() ) + { + USHORT nStyle = TEXT_DRAW_MNEMONIC; + if( ! pItem->mbEnabled ) + nStyle |= TEXT_DRAW_DISABLE; + DrawCtrlText( Point( nXPos + aImageSize.Width(), nYPos ), + pItem->maFormatText, + 0, STRING_LEN, nStyle, + bLayout ? &mpLayoutData->m_aUnicodeBoundRects : NULL, + bLayout ? &mpLayoutData->m_aDisplayText : NULL + ); + } + + if( !! pItem->maTabImage ) + { + Point aImgTL( nXPos, aRect.Top() ); + if( aImageSize.Height() < aRect.GetHeight() ) + aImgTL.Y() += (aRect.GetHeight() - aImageSize.Height())/2; + DrawImage( aImgTL, pItem->maTabImage, pItem->mbEnabled ? 0 : IMAGE_DRAW_DISABLE ); + } } // ----------------------------------------------------------------------- @@ -1018,7 +1071,14 @@ IMPL_LINK( TabControl, ImplScrollBtnHdl, PushButton*, EMPTYARG ) void TabControl::MouseButtonDown( const MouseEvent& rMEvt ) { if ( rMEvt.IsLeft() ) - SelectTabPage( GetPageId( rMEvt.GetPosPixel() ) ); + { + USHORT nPageId = GetPageId( rMEvt.GetPosPixel() ); + ImplTabItem* pItem = ImplGetItem( nPageId ); + if( pItem && pItem->mbEnabled ) + SelectTabPage( nPageId ); + else + Sound::Beep( SOUND_ERROR, this ); + } } // ----------------------------------------------------------------------- @@ -1059,17 +1119,14 @@ void TabControl::ImplPaint( const Rectangle& rRect, bool bLayout ) // find current item ImplTabItem* pCurItem = NULL; - ImplTabItem* pItem = mpItemList->First(); - pItem = mpItemList->First(); - while ( pItem ) + for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin(); + it != mpTabCtrlData->maItemList.end(); ++it ) { - if ( pItem->mnId == mnCurPageId ) + if ( it->mnId == mnCurPageId ) { - pCurItem = pItem; + pCurItem = &(*it); break; } - - pItem = mpItemList->Next(); } // Draw the TabPage border @@ -1178,25 +1235,26 @@ void TabControl::ImplPaint( const Rectangle& rRect, bool bLayout ) bool bDrawTabsRTL = IsNativeControlSupported( CTRL_TAB_ITEM, PART_TABS_DRAW_RTL ); ImplTabItem * pFirstTab = NULL; ImplTabItem * pLastTab = NULL; - unsigned idx; + size_t idx; // Event though there is a tab overlap with GTK+, the first tab is not // overlapped on the left side. Other tookits ignore this option. if ( bDrawTabsRTL ) { - pFirstTab = mpItemList->First(); - pLastTab = mpItemList->Last(); - idx = mpItemList->Count()-1; + pFirstTab = &mpTabCtrlData->maItemList.front(); + pLastTab = &mpTabCtrlData->maItemList.back(); + idx = mpTabCtrlData->maItemList.size()-1; } else { - pLastTab = mpItemList->Last(); - pFirstTab = mpItemList->First(); + pLastTab = &mpTabCtrlData->maItemList.back(); + pFirstTab = &mpTabCtrlData->maItemList.front(); idx = 0; } - while ( (pItem = mpItemList->GetObject(idx)) != NULL ) + while ( idx < mpTabCtrlData->maItemList.size() ) { + ImplTabItem* pItem = &mpTabCtrlData->maItemList[idx]; if ( pItem != pCurItem ) { Region aClipRgn( GetActiveClipRegion() ); @@ -1250,18 +1308,15 @@ void TabControl::Resize() mbSmallInvalidate = FALSE; else { - ImplTabItem* pItem; - pItem = mpItemList->First(); - while ( pItem ) + for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin(); + it != mpTabCtrlData->maItemList.end(); ++it ) { - if ( !pItem->mbFullVisible || - (pItem->maRect.Right()-2 >= nNewWidth) ) + if ( !it->mbFullVisible || + (it->maRect.Right()-2 >= nNewWidth) ) { mbSmallInvalidate = FALSE; break; } - - pItem = mpItemList->Next(); } } @@ -1341,7 +1396,7 @@ void TabControl::RequestHelp( const HelpEvent& rHEvt ) } } - // Bei Quick- oder Ballloon-Help zeigen wir den Text an, + // Bei Quick- oder Balloon-Help zeigen wir den Text an, // wenn dieser abgeschnitten ist if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) ) { @@ -1366,6 +1421,25 @@ void TabControl::RequestHelp( const HelpEvent& rHEvt ) } } } + + if ( rHEvt.GetMode() & HELPMODE_QUICK ) + { + ImplTabItem* pItem = ImplGetItem( nItemId ); + const XubString& rHelpText = pItem->maHelpText; + // show tooltip if not text but image is set and helptext is available + if ( rHelpText.Len() > 0 && pItem->maText.Len() == 0 && !!pItem->maTabImage ) + { + Rectangle aItemRect = ImplGetTabRect( GetPagePos( nItemId ) ); + Point aPt = OutputToScreenPixel( aItemRect.TopLeft() ); + aItemRect.Left() = aPt.X(); + aItemRect.Top() = aPt.Y(); + aPt = OutputToScreenPixel( aItemRect.BottomRight() ); + aItemRect.Right() = aPt.X(); + aItemRect.Bottom() = aPt.Y(); + Help::ShowQuickHelp( this, aItemRect, rHelpText ); + return; + } + } } Control::RequestHelp( rHEvt ); @@ -1393,14 +1467,13 @@ void TabControl::Command( const CommandEvent& rCEvt ) if ( bMenu ) { PopupMenu aMenu; - ImplTabItem* pItem = mpItemList->First(); - while ( pItem ) + for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin(); + it != mpTabCtrlData->maItemList.end(); ++it ) { - aMenu.InsertItem( pItem->mnId, pItem->maText, MIB_CHECKABLE | MIB_RADIOCHECK ); - if ( pItem->mnId == mnCurPageId ) - aMenu.CheckItem( pItem->mnId ); - aMenu.SetHelpId( pItem->mnId, pItem->mnHelpId ); - pItem = mpItemList->Next(); + aMenu.InsertItem( it->mnId, it->maText, MIB_CHECKABLE | MIB_RADIOCHECK ); + if ( it->mnId == mnCurPageId ) + aMenu.CheckItem( it->mnId ); + aMenu.SetHelpId( it->mnId, it->mnHelpId ); } USHORT nId = aMenu.Execute( this, aMenuPos ); @@ -1464,18 +1537,17 @@ void TabControl::DataChanged( const DataChangedEvent& rDCEvt ) Rectangle* TabControl::ImplFindPartRect( const Point& rPt ) { - ImplTabItem* pItem = mpItemList->First(); ImplTabItem* pFoundItem = NULL; int nFound = 0; - while ( pItem ) + for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin(); + it != mpTabCtrlData->maItemList.end(); ++it ) { - if ( pItem->maRect.IsInside( rPt ) ) + if ( it->maRect.IsInside( rPt ) ) { // assure that only one tab is highlighted at a time nFound++; - pFoundItem = pItem; + pFoundItem = &(*it); } - pItem = mpItemList->Next(); } // assure that only one tab is highlighted at a time return nFound == 1 ? &pFoundItem->maRect : NULL; @@ -1625,8 +1697,8 @@ void TabControl::InsertPage( const ResId& rResId, USHORT nPos ) // PageResID if ( nObjMask & RSC_TABCONTROLITEM_PAGERESID ) { - ImplTabItem* pItem = mpItemList->GetObject( GetPagePos( nItemId ) ); - pItem->mnTabPageResId = sal::static_int_cast<USHORT>(ReadLongRes()); + ImplTabItem& rItem = mpTabCtrlData->maItemList[ GetPagePos( nItemId ) ]; + rItem.mnTabPageResId = sal::static_int_cast<USHORT>(ReadLongRes()); } } @@ -1639,12 +1711,25 @@ void TabControl::InsertPage( USHORT nPageId, const XubString& rText, DBG_ASSERT( GetPagePos( nPageId ) == TAB_PAGE_NOTFOUND, "TabControl::InsertPage(): PageId already exists" ); - // CurPageId gegebenenfalls setzen + // set current page id if ( !mnCurPageId ) mnCurPageId = nPageId; - // PageItem anlegen - ImplTabItem* pItem = new ImplTabItem; + // insert new page item + ImplTabItem* pItem = NULL; + if( nPos == TAB_APPEND || size_t(nPos) >= mpTabCtrlData->maItemList.size() ) + { + mpTabCtrlData->maItemList.push_back( ImplTabItem() ); + pItem = &mpTabCtrlData->maItemList.back(); + } + else + { + std::vector< ImplTabItem >::iterator new_it = + mpTabCtrlData->maItemList.insert( mpTabCtrlData->maItemList.begin() + nPos, ImplTabItem() ); + pItem = &(*new_it); + } + + // init new page item pItem->mnId = nPageId; pItem->mpTabPage = NULL; pItem->mnTabPageResId = 0; @@ -1652,9 +1737,6 @@ void TabControl::InsertPage( USHORT nPageId, const XubString& rText, pItem->maText = rText; pItem->mbFullVisible = FALSE; - // In die StarView-Liste eintragen - mpItemList->Insert( pItem, nPos ); - mbFormat = TRUE; if ( IsUpdateMode() ) Invalidate(); @@ -1670,30 +1752,32 @@ void TabControl::RemovePage( USHORT nPageId ) { USHORT nPos = GetPagePos( nPageId ); - // Existiert Item + // does the item exist ? if ( nPos != TAB_PAGE_NOTFOUND ) { - // Item-Daten loeschen und Windows-Item entfernen - ImplTabItem* pItem = mpItemList->Remove( nPos ); + //remove page item + std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin() + nPos; + bool bIsCurrentPage = (it->mnId == mnCurPageId); + mpTabCtrlData->maItemList.erase( it ); + // If current page is removed, than first page gets the current page - if ( pItem->mnId == mnCurPageId ) + if ( bIsCurrentPage ) { mnCurPageId = 0; - // don't do this by simply setting mnCurPageId to pFirstItem->mnId - // this leaves a lot of stuff (such trivias as _showing_ the new current page) undone - // instead, call SetCurPageId - // without this, the next (outside) call to SetCurPageId with the id of the first page - // will result in doing nothing (as we assume that nothing changed, then), and the page - // will never be shown. - // 86875 - 05/11/2001 - frank.schoenheit@germany.sun.com - - ImplTabItem* pFirstItem = mpItemList->GetObject( 0 ); - if ( pFirstItem ) - SetCurPageId( pFirstItem->mnId ); - + if( ! mpTabCtrlData->maItemList.empty() ) + { + // don't do this by simply setting mnCurPageId to pFirstItem->mnId + // this leaves a lot of stuff (such trivias as _showing_ the new current page) undone + // instead, call SetCurPageId + // without this, the next (outside) call to SetCurPageId with the id of the first page + // will result in doing nothing (as we assume that nothing changed, then), and the page + // will never be shown. + // 86875 - 05/11/2001 - frank.schoenheit@germany.sun.com + + SetCurPageId( mpTabCtrlData->maItemList[0].mnId ); + } } - delete pItem; mbFormat = TRUE; if ( IsUpdateMode() ) @@ -1709,17 +1793,8 @@ void TabControl::RemovePage( USHORT nPageId ) void TabControl::Clear() { - // Alle Items loeschen - ImplTabItem* pItem = mpItemList->First(); - while ( pItem ) - { - // Item-Daten loeschen - delete pItem; - pItem = mpItemList->Next(); - } - - // Items aus der Liste loeschen - mpItemList->Clear(); + // clear item list + mpTabCtrlData->maItemList.clear(); mnCurPageId = 0; ImplFreeLayoutData(); @@ -1733,33 +1808,49 @@ void TabControl::Clear() // ----------------------------------------------------------------------- +void TabControl::EnablePage( USHORT i_nPageId, bool i_bEnable ) +{ + ImplTabItem* pItem = ImplGetItem( i_nPageId ); + + if ( pItem && pItem->mbEnabled != i_bEnable ) + { + pItem->mbEnabled = i_bEnable; + mbFormat = TRUE; + if( pItem->mnId == mnCurPageId ) + { + // SetCurPageId will change to an enabled page + SetCurPageId( mnCurPageId ); + } + else if ( IsUpdateMode() ) + Invalidate(); + } +} + +// ----------------------------------------------------------------------- + USHORT TabControl::GetPageCount() const { - return (USHORT)mpItemList->Count(); + return (USHORT)mpTabCtrlData->maItemList.size(); } // ----------------------------------------------------------------------- USHORT TabControl::GetPageId( USHORT nPos ) const { - ImplTabItem* pItem = mpItemList->GetObject( nPos ); - if ( pItem ) - return pItem->mnId; - else - return 0; + if( size_t(nPos) < mpTabCtrlData->maItemList.size() ) + return mpTabCtrlData->maItemList[ nPos ].mnId; + return 0; } // ----------------------------------------------------------------------- USHORT TabControl::GetPagePos( USHORT nPageId ) const { - ImplTabItem* pItem = mpItemList->First(); - while ( pItem ) + for( std::vector< ImplTabItem >::const_iterator it = mpTabCtrlData->maItemList.begin(); + it != mpTabCtrlData->maItemList.end(); ++it ) { - if ( pItem->mnId == nPageId ) - return (USHORT)mpItemList->GetCurPos(); - - pItem = mpItemList->Next(); + if ( it->mnId == nPageId ) + return (USHORT)(it - mpTabCtrlData->maItemList.begin()); } return TAB_PAGE_NOTFOUND; @@ -1769,12 +1860,10 @@ USHORT TabControl::GetPagePos( USHORT nPageId ) const USHORT TabControl::GetPageId( const Point& rPos ) const { - USHORT i = 0; - while ( i < mpItemList->Count() ) + for( size_t i = 0; i < mpTabCtrlData->maItemList.size(); ++i ) { - if ( ((TabControl*)this)->ImplGetTabRect( i ).IsInside( rPos ) ) - return mpItemList->GetObject( i )->mnId; - i++; + if ( ((TabControl*)this)->ImplGetTabRect( static_cast<USHORT>(i) ).IsInside( rPos ) ) + return mpTabCtrlData->maItemList[ i ].mnId; } return 0; @@ -1784,16 +1873,27 @@ USHORT TabControl::GetPageId( const Point& rPos ) const void TabControl::SetCurPageId( USHORT nPageId ) { - if ( nPageId == mnCurPageId ) + USHORT nPos = GetPagePos( nPageId ); + while( nPos != TAB_PAGE_NOTFOUND && + ! mpTabCtrlData->maItemList[nPos].mbEnabled ) { - if ( mnActPageId ) - mnActPageId = nPageId; - return; + nPos++; + if( size_t(nPos) >= mpTabCtrlData->maItemList.size() ) + nPos = 0; + if( mpTabCtrlData->maItemList[nPos].mnId == nPageId ) + break; } - ImplTabItem* pItem = ImplGetItem( nPageId ); - if ( pItem ) + if( nPos != TAB_PAGE_NOTFOUND ) { + nPageId = mpTabCtrlData->maItemList[nPos].mnId; + if ( nPageId == mnCurPageId ) + { + if ( mnActPageId ) + mnActPageId = nPageId; + return; + } + if ( mnActPageId ) mnActPageId = nPageId; else @@ -1978,6 +2078,29 @@ ULONG TabControl::GetHelpId( USHORT nPageId ) const // ----------------------------------------------------------------------- +void TabControl::SetPageImage( USHORT i_nPageId, const Image& i_rImage ) +{ + ImplTabItem* pItem = ImplGetItem( i_nPageId ); + + if ( pItem ) + { + pItem->maTabImage = i_rImage; + mbFormat = TRUE; + if ( IsUpdateMode() ) + Invalidate(); + } +} + +// ----------------------------------------------------------------------- + +const Image* TabControl::GetPageImage( USHORT i_nPageId ) const +{ + const ImplTabItem* pItem = ImplGetItem( i_nPageId ); + return pItem ? &pItem->maTabImage : NULL; +} + +// ----------------------------------------------------------------------- + Rectangle TabControl::GetCharacterBounds( USHORT nPageId, long nIndex ) const { Rectangle aRet; |