1*5900e8ecSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*5900e8ecSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*5900e8ecSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*5900e8ecSAndrew Rist  * distributed with this work for additional information
6*5900e8ecSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*5900e8ecSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*5900e8ecSAndrew Rist  * "License"); you may not use this file except in compliance
9*5900e8ecSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*5900e8ecSAndrew Rist  *
11*5900e8ecSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*5900e8ecSAndrew Rist  *
13*5900e8ecSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*5900e8ecSAndrew Rist  * software distributed under the License is distributed on an
15*5900e8ecSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*5900e8ecSAndrew Rist  * KIND, either express or implied.  See the License for the
17*5900e8ecSAndrew Rist  * specific language governing permissions and limitations
18*5900e8ecSAndrew Rist  * under the License.
19*5900e8ecSAndrew Rist  *
20*5900e8ecSAndrew Rist  *************************************************************/
21*5900e8ecSAndrew Rist 
22*5900e8ecSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "precompiled_svtools.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include "svtools/toolpanel/paneltabbar.hxx"
27cdf0e10cSrcweir #include "svtools/toolpanel/toolpaneldeck.hxx"
28cdf0e10cSrcweir #include "svtools/svtdata.hxx"
29cdf0e10cSrcweir #include "svtools/svtools.hrc"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "tabitemdescriptor.hxx"
32cdf0e10cSrcweir #include "paneltabbarpeer.hxx"
33cdf0e10cSrcweir #include "tabbargeometry.hxx"
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include <vcl/button.hxx>
36cdf0e10cSrcweir #include <vcl/help.hxx>
37cdf0e10cSrcweir #include <vcl/virdev.hxx>
38cdf0e10cSrcweir #include <tools/diagnose_ex.h>
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #include <boost/optional.hpp>
41cdf0e10cSrcweir #include <vector>
42cdf0e10cSrcweir 
43cdf0e10cSrcweir // space around an item
44cdf0e10cSrcweir #define ITEM_OUTER_SPACE        2 * 3
45cdf0e10cSrcweir // spacing before and after an item's text
46cdf0e10cSrcweir #define ITEM_TEXT_FLOW_SPACE    5
47cdf0e10cSrcweir // space between item icon and icon text
48cdf0e10cSrcweir #define ITEM_ICON_TEXT_DISTANCE 4
49cdf0e10cSrcweir 
50cdf0e10cSrcweir //........................................................................
51cdf0e10cSrcweir namespace svt
52cdf0e10cSrcweir {
53cdf0e10cSrcweir //........................................................................
54cdf0e10cSrcweir 
55cdf0e10cSrcweir     using ::com::sun::star::uno::Reference;
56cdf0e10cSrcweir     using ::com::sun::star::awt::XWindowPeer;
57cdf0e10cSrcweir 
58cdf0e10cSrcweir     typedef sal_uInt16  ItemFlags;
59cdf0e10cSrcweir 
60cdf0e10cSrcweir     #define ITEM_STATE_NORMAL   0x00
61cdf0e10cSrcweir     #define ITEM_STATE_ACTIVE   0x01
62cdf0e10cSrcweir     #define ITEM_STATE_HOVERED  0x02
63cdf0e10cSrcweir     #define ITEM_STATE_FOCUSED  0x04
64cdf0e10cSrcweir     #define ITEM_POSITION_FIRST 0x08
65cdf0e10cSrcweir     #define ITEM_POSITION_LAST  0x10
66cdf0e10cSrcweir 
67cdf0e10cSrcweir 	//==================================================================================================================
68cdf0e10cSrcweir 	//= helper
69cdf0e10cSrcweir 	//==================================================================================================================
70cdf0e10cSrcweir     namespace
71cdf0e10cSrcweir     {
lcl_ItemToControlState(const ItemFlags i_nItemFlags)72cdf0e10cSrcweir         ControlState lcl_ItemToControlState( const ItemFlags i_nItemFlags )
73cdf0e10cSrcweir         {
74cdf0e10cSrcweir             ControlState nState = CTRL_STATE_ENABLED;
75cdf0e10cSrcweir             if ( i_nItemFlags & ITEM_STATE_FOCUSED )    nState |= CTRL_STATE_FOCUSED | CTRL_STATE_PRESSED;
76cdf0e10cSrcweir             if ( i_nItemFlags & ITEM_STATE_HOVERED )    nState |= CTRL_STATE_ROLLOVER;
77cdf0e10cSrcweir             if ( i_nItemFlags & ITEM_STATE_ACTIVE )     nState |= CTRL_STATE_SELECTED;
78cdf0e10cSrcweir             return nState;
79cdf0e10cSrcweir         }
80cdf0e10cSrcweir     }
81cdf0e10cSrcweir 
82cdf0e10cSrcweir 	//==================================================================================================================
83cdf0e10cSrcweir 	//= ITabBarRenderer
84cdf0e10cSrcweir 	//==================================================================================================================
85cdf0e10cSrcweir     class SAL_NO_VTABLE ITabBarRenderer
86cdf0e10cSrcweir     {
87cdf0e10cSrcweir     public:
88cdf0e10cSrcweir         /** fills the background of our target device
89cdf0e10cSrcweir         */
90cdf0e10cSrcweir         virtual void        renderBackground() const = 0;
91cdf0e10cSrcweir         virtual Rectangle   calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const = 0;
92cdf0e10cSrcweir         virtual void        preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const = 0;
93cdf0e10cSrcweir         virtual void        postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const = 0;
94cdf0e10cSrcweir 
95cdf0e10cSrcweir         // TODO: postRenderItem takes the "real" window, i.e. effectively the tab bar. This is because
96cdf0e10cSrcweir         // DrawSelectionBackground needs to be applied after everything else is painted, and is available at the Window
97cdf0e10cSrcweir         // class, but not at the OutputDevice. This makes the API somewhat weird, as we're now mixing operations on the
98cdf0e10cSrcweir         // target device, done in a normalized geometry, with operations on the window, done in a transformed geometry.
99cdf0e10cSrcweir         // So, we should get rid of postRenderItem completely.
100cdf0e10cSrcweir     };
101cdf0e10cSrcweir     typedef ::boost::shared_ptr< ITabBarRenderer >  PTabBarRenderer;
102cdf0e10cSrcweir 
103cdf0e10cSrcweir 	//==================================================================================================================
104cdf0e10cSrcweir 	//= VCLItemRenderer - declaration
105cdf0e10cSrcweir 	//==================================================================================================================
106cdf0e10cSrcweir     class VCLItemRenderer : public ITabBarRenderer
107cdf0e10cSrcweir     {
108cdf0e10cSrcweir     public:
VCLItemRenderer(OutputDevice & i_rTargetDevice)109cdf0e10cSrcweir         VCLItemRenderer( OutputDevice& i_rTargetDevice )
110cdf0e10cSrcweir             :m_rTargetDevice( i_rTargetDevice )
111cdf0e10cSrcweir         {
112cdf0e10cSrcweir         }
113cdf0e10cSrcweir 
114cdf0e10cSrcweir         // ITabBarRenderer
115cdf0e10cSrcweir         virtual void        renderBackground() const;
116cdf0e10cSrcweir         virtual Rectangle   calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const;
117cdf0e10cSrcweir         virtual void        preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const;
118cdf0e10cSrcweir         virtual void        postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const;
119cdf0e10cSrcweir 
120cdf0e10cSrcweir     protected:
getTargetDevice() const121cdf0e10cSrcweir         OutputDevice&   getTargetDevice() const { return m_rTargetDevice; }
122cdf0e10cSrcweir 
123cdf0e10cSrcweir     private:
124cdf0e10cSrcweir         OutputDevice&   m_rTargetDevice;
125cdf0e10cSrcweir     };
126cdf0e10cSrcweir 
127cdf0e10cSrcweir 	//==================================================================================================================
128cdf0e10cSrcweir 	//= VCLItemRenderer - implementation
129cdf0e10cSrcweir 	//==================================================================================================================
130cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
renderBackground() const131cdf0e10cSrcweir     void VCLItemRenderer::renderBackground() const
132cdf0e10cSrcweir     {
133cdf0e10cSrcweir         getTargetDevice().DrawRect( Rectangle( Point(), getTargetDevice().GetOutputSizePixel() ) );
134cdf0e10cSrcweir     }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
calculateDecorations(const Rectangle & i_rContentArea,const ItemFlags i_nItemFlags) const137cdf0e10cSrcweir     Rectangle VCLItemRenderer::calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const
138cdf0e10cSrcweir     {
139cdf0e10cSrcweir         (void)i_nItemFlags;
140cdf0e10cSrcweir         // no decorations at all
141cdf0e10cSrcweir         return i_rContentArea;
142cdf0e10cSrcweir     }
143cdf0e10cSrcweir 
144cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
preRenderItem(const Rectangle & i_rContentRect,const ItemFlags i_nItemFlags) const145cdf0e10cSrcweir     void VCLItemRenderer::preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const
146cdf0e10cSrcweir     {
147cdf0e10cSrcweir         (void)i_rContentRect;
148cdf0e10cSrcweir         (void)i_nItemFlags;
149cdf0e10cSrcweir     }
150cdf0e10cSrcweir 
151cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
postRenderItem(Window & i_rActualWindow,const Rectangle & i_rItemRect,const ItemFlags i_nItemFlags) const152cdf0e10cSrcweir     void VCLItemRenderer::postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const
153cdf0e10cSrcweir     {
154cdf0e10cSrcweir         const bool bActive = ( ( i_nItemFlags & ITEM_STATE_ACTIVE ) != 0 );
155cdf0e10cSrcweir         const bool bHovered = ( ( i_nItemFlags & ITEM_STATE_HOVERED ) != 0 );
156cdf0e10cSrcweir         const bool bFocused = ( ( i_nItemFlags & ITEM_STATE_FOCUSED ) != 0 );
157cdf0e10cSrcweir         if ( bActive || bHovered || bFocused )
158cdf0e10cSrcweir         {
159cdf0e10cSrcweir             Rectangle aSelectionRect( i_rItemRect );
160cdf0e10cSrcweir             aSelectionRect.Left() += ITEM_OUTER_SPACE / 2;
161cdf0e10cSrcweir             aSelectionRect.Top() += ITEM_OUTER_SPACE / 2;
162cdf0e10cSrcweir             aSelectionRect.Right() -= ITEM_OUTER_SPACE / 2;
163cdf0e10cSrcweir             aSelectionRect.Bottom() -= ITEM_OUTER_SPACE / 2;
164cdf0e10cSrcweir             i_rActualWindow.DrawSelectionBackground(
165cdf0e10cSrcweir                 aSelectionRect,
166cdf0e10cSrcweir                 ( bHovered || bFocused ) ? ( bActive ? 1 : 2 ) : 0 /* hilight */,
167cdf0e10cSrcweir                 bActive /* check */,
168cdf0e10cSrcweir                 sal_True /* border */,
169cdf0e10cSrcweir                 sal_False /* ext border only */,
170cdf0e10cSrcweir                 0 /* corner radius */,
171cdf0e10cSrcweir                 NULL,
172cdf0e10cSrcweir                 NULL
173cdf0e10cSrcweir             );
174cdf0e10cSrcweir         }
175cdf0e10cSrcweir     }
176cdf0e10cSrcweir 
177cdf0e10cSrcweir 	//==================================================================================================================
178cdf0e10cSrcweir 	//= NWFToolboxItemRenderer - declaration
179cdf0e10cSrcweir 	//==================================================================================================================
180cdf0e10cSrcweir     class NWFToolboxItemRenderer : public ITabBarRenderer
181cdf0e10cSrcweir     {
182cdf0e10cSrcweir     public:
NWFToolboxItemRenderer(OutputDevice & i_rTargetDevice)183cdf0e10cSrcweir         NWFToolboxItemRenderer( OutputDevice& i_rTargetDevice )
184cdf0e10cSrcweir             :m_rTargetDevice( i_rTargetDevice )
185cdf0e10cSrcweir         {
186cdf0e10cSrcweir         }
187cdf0e10cSrcweir 
188cdf0e10cSrcweir         // ITabBarRenderer
189cdf0e10cSrcweir         virtual void        renderBackground() const;
190cdf0e10cSrcweir         virtual Rectangle   calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const;
191cdf0e10cSrcweir         virtual void        preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const;
192cdf0e10cSrcweir         virtual void        postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const;
193cdf0e10cSrcweir 
194cdf0e10cSrcweir     protected:
getTargetDevice() const195cdf0e10cSrcweir         OutputDevice&   getTargetDevice() const { return m_rTargetDevice; }
196cdf0e10cSrcweir 
197cdf0e10cSrcweir     private:
198cdf0e10cSrcweir         OutputDevice&   m_rTargetDevice;
199cdf0e10cSrcweir     };
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 	//==================================================================================================================
202cdf0e10cSrcweir 	//= NWFToolboxItemRenderer - implementation
203cdf0e10cSrcweir 	//==================================================================================================================
204cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
renderBackground() const205cdf0e10cSrcweir     void NWFToolboxItemRenderer::renderBackground() const
206cdf0e10cSrcweir     {
207cdf0e10cSrcweir         getTargetDevice().DrawRect( Rectangle( Point(), getTargetDevice().GetOutputSizePixel() ) );
208cdf0e10cSrcweir     }
209cdf0e10cSrcweir 
210cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
calculateDecorations(const Rectangle & i_rContentArea,const ItemFlags i_nItemFlags) const211cdf0e10cSrcweir     Rectangle NWFToolboxItemRenderer::calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const
212cdf0e10cSrcweir     {
213cdf0e10cSrcweir         // don't ask GetNativeControlRegion, this will not deliver proper results in all cases.
214cdf0e10cSrcweir         // Instead, simply assume that both the content and the bounding region are the same.
215cdf0e10cSrcweir //        const ControlState nState( lcl_ItemToControlState( i_nItemFlags );
216cdf0e10cSrcweir //        const ImplControlValue aControlValue;
217cdf0e10cSrcweir //        bool bNativeOK = m_rTargetWindow.GetNativeControlRegion(
218cdf0e10cSrcweir //            CTRL_TOOLBAR, PART_BUTTON,
219cdf0e10cSrcweir //            i_rContentArea, nState,
220cdf0e10cSrcweir //            aControlValue, ::rtl::OUString(),
221cdf0e10cSrcweir //            aBoundingRegion, aContentRegion
222cdf0e10cSrcweir //        );
223cdf0e10cSrcweir         (void)i_nItemFlags;
224cdf0e10cSrcweir         return Rectangle(
225cdf0e10cSrcweir             Point( i_rContentArea.Left() - 1, i_rContentArea.Top() - 1 ),
226cdf0e10cSrcweir             Size( i_rContentArea.GetWidth() + 2, i_rContentArea.GetHeight() + 2 )
227cdf0e10cSrcweir         );
228cdf0e10cSrcweir     }
229cdf0e10cSrcweir 
230cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
preRenderItem(const Rectangle & i_rContentRect,const ItemFlags i_nItemFlags) const231cdf0e10cSrcweir     void NWFToolboxItemRenderer::preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const
232cdf0e10cSrcweir     {
233cdf0e10cSrcweir         const ControlState nState = lcl_ItemToControlState( i_nItemFlags );
234cdf0e10cSrcweir 
235cdf0e10cSrcweir         ImplControlValue aControlValue;
236cdf0e10cSrcweir         aControlValue.setTristateVal( ( i_nItemFlags & ITEM_STATE_ACTIVE ) ? BUTTONVALUE_ON : BUTTONVALUE_OFF );
237cdf0e10cSrcweir 
238cdf0e10cSrcweir         bool bNativeOK = getTargetDevice().DrawNativeControl( CTRL_TOOLBAR, PART_BUTTON, i_rContentRect, nState, aControlValue, rtl::OUString() );
239cdf0e10cSrcweir         (void)bNativeOK;
240cdf0e10cSrcweir         OSL_ENSURE( bNativeOK, "NWFToolboxItemRenderer::preRenderItem: inconsistent NWF implementation!" );
241cdf0e10cSrcweir             // IsNativeControlSupported returned true, previously, otherwise we would not be here ...
242cdf0e10cSrcweir     }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
postRenderItem(Window & i_rActualWindow,const Rectangle & i_rItemRect,const ItemFlags i_nItemFlags) const245cdf0e10cSrcweir     void NWFToolboxItemRenderer::postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const
246cdf0e10cSrcweir     {
247cdf0e10cSrcweir         (void)i_rActualWindow;
248cdf0e10cSrcweir         (void)i_rItemRect;
249cdf0e10cSrcweir         (void)i_nItemFlags;
250cdf0e10cSrcweir     }
251cdf0e10cSrcweir 
252cdf0e10cSrcweir 	//==================================================================================================================
253cdf0e10cSrcweir 	//= NWFTabItemRenderer - declaration
254cdf0e10cSrcweir 	//==================================================================================================================
255cdf0e10cSrcweir     class NWFTabItemRenderer : public ITabBarRenderer
256cdf0e10cSrcweir     {
257cdf0e10cSrcweir     public:
NWFTabItemRenderer(OutputDevice & i_rTargetDevice)258cdf0e10cSrcweir         NWFTabItemRenderer( OutputDevice& i_rTargetDevice )
259cdf0e10cSrcweir             :m_rTargetDevice( i_rTargetDevice )
260cdf0e10cSrcweir         {
261cdf0e10cSrcweir         }
262cdf0e10cSrcweir 
263cdf0e10cSrcweir         // ITabBarRenderer
264cdf0e10cSrcweir         virtual void        renderBackground() const;
265cdf0e10cSrcweir         virtual Rectangle   calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const;
266cdf0e10cSrcweir         virtual void        preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const;
267cdf0e10cSrcweir         virtual void        postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const;
268cdf0e10cSrcweir 
269cdf0e10cSrcweir     protected:
getTargetDevice() const270cdf0e10cSrcweir         OutputDevice&   getTargetDevice() const { return m_rTargetDevice; }
271cdf0e10cSrcweir 
272cdf0e10cSrcweir     private:
273cdf0e10cSrcweir         OutputDevice&   m_rTargetDevice;
274cdf0e10cSrcweir     };
275cdf0e10cSrcweir 
276cdf0e10cSrcweir 	//==================================================================================================================
277cdf0e10cSrcweir 	//= NWFTabItemRenderer - implementation
278cdf0e10cSrcweir 	//==================================================================================================================
279cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
renderBackground() const280cdf0e10cSrcweir     void NWFTabItemRenderer::renderBackground() const
281cdf0e10cSrcweir     {
282cdf0e10cSrcweir         Rectangle aBackground( Point(), getTargetDevice().GetOutputSizePixel() );
283cdf0e10cSrcweir         getTargetDevice().DrawRect( aBackground );
284cdf0e10cSrcweir 
285cdf0e10cSrcweir         aBackground.Top() = aBackground.Bottom();
286cdf0e10cSrcweir         getTargetDevice().DrawNativeControl( CTRL_TAB_PANE, PART_ENTIRE_CONTROL, aBackground,
287cdf0e10cSrcweir             CTRL_STATE_ENABLED, ImplControlValue(), ::rtl::OUString() );
288cdf0e10cSrcweir     }
289cdf0e10cSrcweir 
290cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
calculateDecorations(const Rectangle & i_rContentArea,const ItemFlags i_nItemFlags) const291cdf0e10cSrcweir     Rectangle NWFTabItemRenderer::calculateDecorations( const Rectangle& i_rContentArea, const ItemFlags i_nItemFlags ) const
292cdf0e10cSrcweir     {
293cdf0e10cSrcweir         const ControlState nState( lcl_ItemToControlState( i_nItemFlags ) );
294cdf0e10cSrcweir 
295cdf0e10cSrcweir         TabitemValue tiValue;
296cdf0e10cSrcweir 
297cdf0e10cSrcweir         Rectangle aBoundingRegion, aContentRegion;
298cdf0e10cSrcweir         bool bNativeOK = getTargetDevice().GetNativeControlRegion(
299cdf0e10cSrcweir             CTRL_TAB_ITEM, PART_ENTIRE_CONTROL,
300cdf0e10cSrcweir             i_rContentArea, nState,
301cdf0e10cSrcweir             tiValue, ::rtl::OUString(),
302cdf0e10cSrcweir             aBoundingRegion, aContentRegion
303cdf0e10cSrcweir         );
304cdf0e10cSrcweir         (void)bNativeOK;
305cdf0e10cSrcweir         OSL_ENSURE( bNativeOK, "NWFTabItemRenderer::calculateDecorations: GetNativeControlRegion not implemented for CTRL_TAB_ITEM?!" );
306cdf0e10cSrcweir 
307cdf0e10cSrcweir         return aBoundingRegion;
308cdf0e10cSrcweir     }
309cdf0e10cSrcweir 
310cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
preRenderItem(const Rectangle & i_rContentRect,const ItemFlags i_nItemFlags) const311cdf0e10cSrcweir     void NWFTabItemRenderer::preRenderItem( const Rectangle& i_rContentRect, const ItemFlags i_nItemFlags ) const
312cdf0e10cSrcweir     {
313cdf0e10cSrcweir         const ControlState nState = lcl_ItemToControlState( i_nItemFlags );
314cdf0e10cSrcweir 
315cdf0e10cSrcweir         TabitemValue tiValue;
316cdf0e10cSrcweir         if ( i_nItemFlags & ITEM_POSITION_FIRST )
317cdf0e10cSrcweir             tiValue.mnAlignment |= TABITEM_FIRST_IN_GROUP;
318cdf0e10cSrcweir         if ( i_nItemFlags & ITEM_POSITION_LAST )
319cdf0e10cSrcweir             tiValue.mnAlignment |= TABITEM_LAST_IN_GROUP;
320cdf0e10cSrcweir 
321cdf0e10cSrcweir 
322cdf0e10cSrcweir         bool bNativeOK = getTargetDevice().DrawNativeControl( CTRL_TAB_ITEM, PART_ENTIRE_CONTROL, i_rContentRect, nState, tiValue, rtl::OUString() );
323cdf0e10cSrcweir         (void)bNativeOK;
324cdf0e10cSrcweir         OSL_ENSURE( bNativeOK, "NWFTabItemRenderer::preRenderItem: inconsistent NWF implementation!" );
325cdf0e10cSrcweir             // IsNativeControlSupported returned true, previously, otherwise we would not be here ...
326cdf0e10cSrcweir     }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
postRenderItem(Window & i_rActualWindow,const Rectangle & i_rItemRect,const ItemFlags i_nItemFlags) const329cdf0e10cSrcweir     void NWFTabItemRenderer::postRenderItem( Window& i_rActualWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags ) const
330cdf0e10cSrcweir     {
331cdf0e10cSrcweir         (void)i_rActualWindow;
332cdf0e10cSrcweir         (void)i_rItemRect;
333cdf0e10cSrcweir         (void)i_nItemFlags;
334cdf0e10cSrcweir     }
335cdf0e10cSrcweir 
336cdf0e10cSrcweir     //==================================================================================================================
337cdf0e10cSrcweir 	//= PanelTabBar_Impl
338cdf0e10cSrcweir 	//==================================================================================================================
339cdf0e10cSrcweir     class PanelTabBar_Impl : public IToolPanelDeckListener
340cdf0e10cSrcweir     {
341cdf0e10cSrcweir     public:
342cdf0e10cSrcweir         PanelTabBar_Impl( PanelTabBar& i_rTabBar, IToolPanelDeck& i_rPanelDeck, const TabAlignment i_eAlignment, const TabItemContent i_eItemContent );
343cdf0e10cSrcweir 
~PanelTabBar_Impl()344cdf0e10cSrcweir         ~PanelTabBar_Impl()
345cdf0e10cSrcweir         {
346cdf0e10cSrcweir             m_rPanelDeck.RemoveListener( *this );
347cdf0e10cSrcweir         }
348cdf0e10cSrcweir 
349cdf0e10cSrcweir         // IToolPanelDeckListener
PanelInserted(const PToolPanel & i_pPanel,const size_t i_nPosition)350cdf0e10cSrcweir         virtual void PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition )
351cdf0e10cSrcweir         {
352cdf0e10cSrcweir             (void)i_pPanel;
353cdf0e10cSrcweir             (void)i_nPosition;
354cdf0e10cSrcweir             m_bItemsDirty = true;
355cdf0e10cSrcweir             m_rTabBar.Invalidate();
356cdf0e10cSrcweir 
357cdf0e10cSrcweir             Relayout();
358cdf0e10cSrcweir         }
359cdf0e10cSrcweir 
PanelRemoved(const size_t i_nPosition)360cdf0e10cSrcweir         virtual void PanelRemoved( const size_t i_nPosition )
361cdf0e10cSrcweir         {
362cdf0e10cSrcweir             m_bItemsDirty = true;
363cdf0e10cSrcweir             m_rTabBar.Invalidate();
364cdf0e10cSrcweir 
365cdf0e10cSrcweir             if ( i_nPosition < m_nScrollPosition )
366cdf0e10cSrcweir                 --m_nScrollPosition;
367cdf0e10cSrcweir 
368cdf0e10cSrcweir             Relayout();
369cdf0e10cSrcweir         }
370cdf0e10cSrcweir 
371cdf0e10cSrcweir         virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive );
372cdf0e10cSrcweir         virtual void LayouterChanged( const PDeckLayouter& i_rNewLayouter );
373cdf0e10cSrcweir         virtual void Dying();
374cdf0e10cSrcweir 
UpdateScrollButtons()375cdf0e10cSrcweir         void    UpdateScrollButtons()
376cdf0e10cSrcweir         {
377cdf0e10cSrcweir             m_aScrollBack.Enable( m_nScrollPosition > 0 );
378cdf0e10cSrcweir             m_aScrollForward.Enable( m_nScrollPosition < m_aItems.size() - 1 );
379cdf0e10cSrcweir         }
380cdf0e10cSrcweir 
381cdf0e10cSrcweir         void                        Relayout();
382cdf0e10cSrcweir         void                        EnsureItemsCache();
383cdf0e10cSrcweir         ::boost::optional< size_t > FindItemForPoint( const Point& i_rPoint ) const;
384cdf0e10cSrcweir         void                        DrawItem( const size_t i_nItemIndex, const Rectangle& i_rBoundaries ) const;
385cdf0e10cSrcweir         void                        InvalidateItem( const size_t i_nItemIndex, const ItemFlags i_nAdditionalItemFlags = 0 ) const;
386cdf0e10cSrcweir         void                        CopyFromRenderDevice( const Rectangle& i_rLogicalRect ) const;
387cdf0e10cSrcweir         Rectangle                   GetActualLogicalItemRect( const Rectangle& i_rLogicalItemRect ) const;
388cdf0e10cSrcweir         Rectangle                   GetItemScreenRect( const size_t i_nItemPos ) const;
389cdf0e10cSrcweir 
390cdf0e10cSrcweir         void                        FocusItem( const ::boost::optional< size_t >& i_rItemPos );
391cdf0e10cSrcweir 
IsVertical() const392cdf0e10cSrcweir         inline bool                 IsVertical() const
393cdf0e10cSrcweir         {
394cdf0e10cSrcweir             return  (   ( m_eTabAlignment == TABS_LEFT )
395cdf0e10cSrcweir                     ||  ( m_eTabAlignment == TABS_RIGHT )
396cdf0e10cSrcweir                     );
397cdf0e10cSrcweir         }
398cdf0e10cSrcweir 
399cdf0e10cSrcweir     protected:
400cdf0e10cSrcweir         DECL_LINK( OnScroll, const PushButton* );
401cdf0e10cSrcweir 
402cdf0e10cSrcweir         void        impl_calcItemRects();
403cdf0e10cSrcweir         Size        impl_calculateItemContentSize( const PToolPanel& i_pPanel, const TabItemContent i_eItemContent ) const;
404cdf0e10cSrcweir         void        impl_renderItemContent( const PToolPanel& i_pPanel, const Rectangle& i_rContentArea, const TabItemContent i_eItemContent ) const;
405cdf0e10cSrcweir         ItemFlags   impl_getItemFlags( const size_t i_nItemIndex ) const;
406cdf0e10cSrcweir 
407cdf0e10cSrcweir     public:
408cdf0e10cSrcweir         PanelTabBar&                m_rTabBar;
409cdf0e10cSrcweir         TabBarGeometry              m_aGeometry;
410cdf0e10cSrcweir         NormalizedArea              m_aNormalizer;
411cdf0e10cSrcweir         TabAlignment                m_eTabAlignment;
412cdf0e10cSrcweir         IToolPanelDeck&             m_rPanelDeck;
413cdf0e10cSrcweir 
414cdf0e10cSrcweir         VirtualDevice               m_aRenderDevice;
415cdf0e10cSrcweir         PTabBarRenderer             m_pRenderer;
416cdf0e10cSrcweir 
417cdf0e10cSrcweir         ::boost::optional< size_t > m_aHoveredItem;
418cdf0e10cSrcweir         ::boost::optional< size_t > m_aFocusedItem;
419cdf0e10cSrcweir         bool                        m_bMouseButtonDown;
420cdf0e10cSrcweir 
421cdf0e10cSrcweir         ItemDescriptors             m_aItems;
422cdf0e10cSrcweir         bool                        m_bItemsDirty;
423cdf0e10cSrcweir 
424cdf0e10cSrcweir         PushButton                  m_aScrollBack;
425cdf0e10cSrcweir         PushButton                  m_aScrollForward;
426cdf0e10cSrcweir 
427cdf0e10cSrcweir         size_t                      m_nScrollPosition;
428cdf0e10cSrcweir     };
429cdf0e10cSrcweir 
430cdf0e10cSrcweir     //==================================================================================================================
431cdf0e10cSrcweir 	//= helper
432cdf0e10cSrcweir 	//==================================================================================================================
433cdf0e10cSrcweir     namespace
434cdf0e10cSrcweir     {
435cdf0e10cSrcweir 	    //--------------------------------------------------------------------------------------------------------------
436cdf0e10cSrcweir     #if OSL_DEBUG_LEVEL > 0
lcl_checkConsistency(const PanelTabBar_Impl & i_rImpl)437cdf0e10cSrcweir         static void lcl_checkConsistency( const PanelTabBar_Impl& i_rImpl )
438cdf0e10cSrcweir         {
439cdf0e10cSrcweir             if ( !i_rImpl.m_bItemsDirty )
440cdf0e10cSrcweir             {
441cdf0e10cSrcweir                 if ( i_rImpl.m_rPanelDeck.GetPanelCount() != i_rImpl.m_aItems.size() )
442cdf0e10cSrcweir                 {
443cdf0e10cSrcweir                     OSL_ENSURE( false, "lcl_checkConsistency: inconsistent array sizes!" );
444cdf0e10cSrcweir                     return;
445cdf0e10cSrcweir                 }
446cdf0e10cSrcweir                 for ( size_t i = 0; i < i_rImpl.m_rPanelDeck.GetPanelCount(); ++i )
447cdf0e10cSrcweir                 {
448cdf0e10cSrcweir                     if ( i_rImpl.m_rPanelDeck.GetPanel( i ).get() != i_rImpl.m_aItems[i].pPanel.get() )
449cdf0e10cSrcweir                     {
450cdf0e10cSrcweir                         OSL_ENSURE( false, "lcl_checkConsistency: array elements are inconsistent!" );
451cdf0e10cSrcweir                         return;
452cdf0e10cSrcweir                     }
453cdf0e10cSrcweir                 }
454cdf0e10cSrcweir             }
455cdf0e10cSrcweir         }
456cdf0e10cSrcweir 
457cdf0e10cSrcweir         #define DBG_CHECK( data ) \
458cdf0e10cSrcweir             lcl_checkConsistency( data );
459cdf0e10cSrcweir     #else
460cdf0e10cSrcweir         #define DBG_CHECK( data ) \
461cdf0e10cSrcweir             (void)data;
462cdf0e10cSrcweir     #endif
463cdf0e10cSrcweir 
464cdf0e10cSrcweir         //--------------------------------------------------------------------------------------------------------------
465cdf0e10cSrcweir         class ClipItemRegion
466cdf0e10cSrcweir         {
467cdf0e10cSrcweir         public:
ClipItemRegion(const PanelTabBar_Impl & i_rImpl)468cdf0e10cSrcweir             ClipItemRegion( const PanelTabBar_Impl& i_rImpl )
469cdf0e10cSrcweir                 :m_rDevice( i_rImpl.m_rTabBar )
470cdf0e10cSrcweir             {
471cdf0e10cSrcweir                 m_rDevice.Push( PUSH_CLIPREGION );
472cdf0e10cSrcweir                 m_rDevice.SetClipRegion( i_rImpl.m_aNormalizer.getTransformed( i_rImpl.m_aGeometry.getItemsRect(), i_rImpl.m_eTabAlignment ) );
473cdf0e10cSrcweir             }
474cdf0e10cSrcweir 
~ClipItemRegion()475cdf0e10cSrcweir             ~ClipItemRegion()
476cdf0e10cSrcweir             {
477cdf0e10cSrcweir                 m_rDevice.Pop();
478cdf0e10cSrcweir             }
479cdf0e10cSrcweir 
480cdf0e10cSrcweir         private:
481cdf0e10cSrcweir             OutputDevice&   m_rDevice;
482cdf0e10cSrcweir         };
483cdf0e10cSrcweir     }
484cdf0e10cSrcweir 
485cdf0e10cSrcweir 	//==================================================================================================================
486cdf0e10cSrcweir 	//= PanelTabBar_Impl - implementation
487cdf0e10cSrcweir 	//==================================================================================================================
488cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
PanelTabBar_Impl(PanelTabBar & i_rTabBar,IToolPanelDeck & i_rPanelDeck,const TabAlignment i_eAlignment,const TabItemContent i_eItemContent)489cdf0e10cSrcweir     PanelTabBar_Impl::PanelTabBar_Impl( PanelTabBar& i_rTabBar, IToolPanelDeck& i_rPanelDeck, const TabAlignment i_eAlignment, const TabItemContent i_eItemContent )
490cdf0e10cSrcweir         :m_rTabBar( i_rTabBar )
491cdf0e10cSrcweir         ,m_aGeometry( i_eItemContent )
492cdf0e10cSrcweir         ,m_aNormalizer()
493cdf0e10cSrcweir         ,m_eTabAlignment( i_eAlignment )
494cdf0e10cSrcweir         ,m_rPanelDeck( i_rPanelDeck )
495cdf0e10cSrcweir         ,m_aRenderDevice( i_rTabBar )
496cdf0e10cSrcweir         ,m_pRenderer()
497cdf0e10cSrcweir         ,m_aHoveredItem()
498cdf0e10cSrcweir         ,m_aFocusedItem()
499cdf0e10cSrcweir         ,m_bMouseButtonDown( false )
500cdf0e10cSrcweir         ,m_aItems()
501cdf0e10cSrcweir         ,m_bItemsDirty( true )
502cdf0e10cSrcweir         ,m_aScrollBack( &i_rTabBar, WB_BEVELBUTTON )
503cdf0e10cSrcweir         ,m_aScrollForward( &i_rTabBar, WB_BEVELBUTTON )
504cdf0e10cSrcweir         ,m_nScrollPosition( 0 )
505cdf0e10cSrcweir     {
506cdf0e10cSrcweir #ifdef WNT
507cdf0e10cSrcweir         if ( m_aRenderDevice.IsNativeControlSupported( CTRL_TAB_ITEM, PART_ENTIRE_CONTROL ) )
508cdf0e10cSrcweir             // this mode requires the NWF framework to be able to render those items onto a virtual
509cdf0e10cSrcweir             // device. For some frameworks (some GTK themes, in particular), this is known to fail.
510cdf0e10cSrcweir             // So, be on the safe side for the moment.
511cdf0e10cSrcweir             m_pRenderer.reset( new NWFTabItemRenderer( m_aRenderDevice ) );
512cdf0e10cSrcweir         else
513cdf0e10cSrcweir #endif
514cdf0e10cSrcweir         if ( m_aRenderDevice.IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) )
515cdf0e10cSrcweir             m_pRenderer.reset( new NWFToolboxItemRenderer( m_aRenderDevice ) );
516cdf0e10cSrcweir         else
517cdf0e10cSrcweir             m_pRenderer.reset( new VCLItemRenderer( m_aRenderDevice ) );
518cdf0e10cSrcweir 
519cdf0e10cSrcweir         m_aRenderDevice.SetLineColor();
520cdf0e10cSrcweir 
521cdf0e10cSrcweir         m_rPanelDeck.AddListener( *this );
522cdf0e10cSrcweir 
523cdf0e10cSrcweir         m_aScrollBack.SetSymbol( IsVertical() ? SYMBOL_ARROW_UP : SYMBOL_ARROW_LEFT );
524cdf0e10cSrcweir         m_aScrollBack.Show();
525cdf0e10cSrcweir         m_aScrollBack.SetClickHdl( LINK( this, PanelTabBar_Impl, OnScroll ) );
526cdf0e10cSrcweir         m_aScrollBack.SetAccessibleDescription( String( SvtResId( STR_SVT_TOOL_PANEL_BUTTON_FWD ) ) );
527cdf0e10cSrcweir         m_aScrollBack.SetAccessibleName( m_aScrollBack.GetAccessibleDescription() );
528cdf0e10cSrcweir 
529cdf0e10cSrcweir         m_aScrollForward.SetSymbol( IsVertical() ? SYMBOL_ARROW_DOWN : SYMBOL_ARROW_RIGHT );
530cdf0e10cSrcweir         m_aScrollForward.Show();
531cdf0e10cSrcweir         m_aScrollForward.SetClickHdl( LINK( this, PanelTabBar_Impl, OnScroll ) );
532cdf0e10cSrcweir         m_aScrollForward.SetAccessibleDescription( String( SvtResId( STR_SVT_TOOL_PANEL_BUTTON_BACK ) ) );
533cdf0e10cSrcweir         m_aScrollForward.SetAccessibleName( m_aScrollForward.GetAccessibleDescription() );
534cdf0e10cSrcweir     }
535cdf0e10cSrcweir 
536cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
impl_calcItemRects()537cdf0e10cSrcweir     void PanelTabBar_Impl::impl_calcItemRects()
538cdf0e10cSrcweir     {
539cdf0e10cSrcweir         m_aItems.resize(0);
540cdf0e10cSrcweir 
541cdf0e10cSrcweir         Point aCompletePos( m_aGeometry.getFirstItemPosition() );
542cdf0e10cSrcweir         Point aIconOnlyPos( aCompletePos );
543cdf0e10cSrcweir         Point aTextOnlyPos( aCompletePos );
544cdf0e10cSrcweir 
545cdf0e10cSrcweir         for (   size_t i = 0;
546cdf0e10cSrcweir                 i < m_rPanelDeck.GetPanelCount();
547cdf0e10cSrcweir                 ++i
548cdf0e10cSrcweir             )
549cdf0e10cSrcweir         {
550cdf0e10cSrcweir             PToolPanel pPanel( m_rPanelDeck.GetPanel( i ) );
551cdf0e10cSrcweir 
552cdf0e10cSrcweir             ItemDescriptor aItem;
553cdf0e10cSrcweir             aItem.pPanel = pPanel;
554cdf0e10cSrcweir 
555cdf0e10cSrcweir             Rectangle aContentArea;
556cdf0e10cSrcweir 
557cdf0e10cSrcweir             const Size aCompleteSize( impl_calculateItemContentSize( pPanel, TABITEM_IMAGE_AND_TEXT ) );
558cdf0e10cSrcweir             const Size aIconOnlySize( impl_calculateItemContentSize( pPanel, TABITEM_IMAGE_ONLY ) );
559cdf0e10cSrcweir             const Size aTextOnlySize( impl_calculateItemContentSize( pPanel, TABITEM_TEXT_ONLY ) );
560cdf0e10cSrcweir 
561cdf0e10cSrcweir             // TODO: have one method calculating all sizes?
562cdf0e10cSrcweir 
563cdf0e10cSrcweir             // remember the three areas
564cdf0e10cSrcweir             aItem.aCompleteArea = Rectangle( aCompletePos, aCompleteSize );
565cdf0e10cSrcweir             aItem.aIconOnlyArea = Rectangle( aIconOnlyPos, aIconOnlySize );
566cdf0e10cSrcweir             aItem.aTextOnlyArea = Rectangle( aTextOnlyPos, aTextOnlySize );
567cdf0e10cSrcweir 
568cdf0e10cSrcweir             m_aItems.push_back( aItem );
569cdf0e10cSrcweir 
570cdf0e10cSrcweir             aCompletePos = aItem.aCompleteArea.TopRight();
571cdf0e10cSrcweir             aIconOnlyPos = aItem.aIconOnlyArea.TopRight();
572cdf0e10cSrcweir             aTextOnlyPos = aItem.aTextOnlyArea.TopRight();
573cdf0e10cSrcweir         }
574cdf0e10cSrcweir 
575cdf0e10cSrcweir         m_bItemsDirty = false;
576cdf0e10cSrcweir     }
577cdf0e10cSrcweir 
578cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
impl_calculateItemContentSize(const PToolPanel & i_pPanel,const TabItemContent i_eItemContent) const579cdf0e10cSrcweir     Size PanelTabBar_Impl::impl_calculateItemContentSize( const PToolPanel& i_pPanel, const TabItemContent i_eItemContent ) const
580cdf0e10cSrcweir     {
581cdf0e10cSrcweir         // calculate the size needed for the content
582cdf0e10cSrcweir         OSL_ENSURE( i_eItemContent != TABITEM_AUTO, "PanelTabBar_Impl::impl_calculateItemContentSize: illegal TabItemContent value!" );
583cdf0e10cSrcweir 
584cdf0e10cSrcweir         const Image aImage( i_pPanel->GetImage() );
585cdf0e10cSrcweir         const bool bUseImage = !!aImage && ( i_eItemContent != TABITEM_TEXT_ONLY );
586cdf0e10cSrcweir 
587cdf0e10cSrcweir         const ::rtl::OUString sItemText( i_pPanel->GetDisplayName() );
588cdf0e10cSrcweir         const bool bUseText = ( sItemText.getLength() != 0 ) && ( i_eItemContent != TABITEM_IMAGE_ONLY );
589cdf0e10cSrcweir 
590cdf0e10cSrcweir         Size aItemContentSize;
591cdf0e10cSrcweir         if ( bUseImage )
592cdf0e10cSrcweir         {
593cdf0e10cSrcweir             aItemContentSize = aImage.GetSizePixel();
594cdf0e10cSrcweir         }
595cdf0e10cSrcweir 
596cdf0e10cSrcweir         if ( bUseText )
597cdf0e10cSrcweir         {
598cdf0e10cSrcweir             if ( bUseImage )
599cdf0e10cSrcweir                 aItemContentSize.Width() += ITEM_ICON_TEXT_DISTANCE;
600cdf0e10cSrcweir 
601cdf0e10cSrcweir             // add space for text
602cdf0e10cSrcweir             const Size aTextSize( m_rTabBar.GetCtrlTextWidth( sItemText ), m_rTabBar.GetTextHeight() );
603cdf0e10cSrcweir             aItemContentSize.Width() += aTextSize.Width();
604cdf0e10cSrcweir             aItemContentSize.Height() = ::std::max( aItemContentSize.Height(), aTextSize.Height() );
605cdf0e10cSrcweir 
606cdf0e10cSrcweir             aItemContentSize.Width() += 2 * ITEM_TEXT_FLOW_SPACE;
607cdf0e10cSrcweir         }
608cdf0e10cSrcweir 
609cdf0e10cSrcweir         if ( !bUseImage && !bUseText )
610cdf0e10cSrcweir         {
611cdf0e10cSrcweir             // have a minimal size - this is pure heuristics, but if it doesn't suit your needs, then give your panels
612cdf0e10cSrcweir             // a name and or image! :)
613cdf0e10cSrcweir             aItemContentSize = Size( 16, 16 );
614cdf0e10cSrcweir         }
615cdf0e10cSrcweir 
616cdf0e10cSrcweir         aItemContentSize.Width() += 2 * ITEM_OUTER_SPACE;
617cdf0e10cSrcweir         aItemContentSize.Height() += 2 * ITEM_OUTER_SPACE;
618cdf0e10cSrcweir 
619cdf0e10cSrcweir         return aItemContentSize;
620cdf0e10cSrcweir     }
621cdf0e10cSrcweir 
622cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
impl_renderItemContent(const PToolPanel & i_pPanel,const Rectangle & i_rContentArea,const TabItemContent i_eItemContent) const623cdf0e10cSrcweir     void PanelTabBar_Impl::impl_renderItemContent( const PToolPanel& i_pPanel, const Rectangle& i_rContentArea, const TabItemContent i_eItemContent ) const
624cdf0e10cSrcweir     {
625cdf0e10cSrcweir         OSL_ENSURE( i_eItemContent != TABITEM_AUTO, "PanelTabBar_Impl::impl_renderItemContent: illegal TabItemContent value!" );
626cdf0e10cSrcweir 
627cdf0e10cSrcweir         Rectangle aRenderArea( i_rContentArea );
628cdf0e10cSrcweir         if ( IsVertical() )
629cdf0e10cSrcweir         {
630cdf0e10cSrcweir             aRenderArea.Top() += ITEM_OUTER_SPACE;
631cdf0e10cSrcweir         }
632cdf0e10cSrcweir         else
633cdf0e10cSrcweir         {
634cdf0e10cSrcweir             aRenderArea.Left() += ITEM_OUTER_SPACE;
635cdf0e10cSrcweir         }
636cdf0e10cSrcweir 
637cdf0e10cSrcweir         // draw the image
638cdf0e10cSrcweir         const Image aItemImage( i_pPanel->GetImage() );
639cdf0e10cSrcweir         const Size aImageSize( aItemImage.GetSizePixel() );
640cdf0e10cSrcweir         const bool bUseImage = !!aItemImage && ( i_eItemContent != TABITEM_TEXT_ONLY );
641cdf0e10cSrcweir 
642cdf0e10cSrcweir         if ( bUseImage )
643cdf0e10cSrcweir         {
644cdf0e10cSrcweir             Point aImagePos;
645cdf0e10cSrcweir             if ( IsVertical() )
646cdf0e10cSrcweir             {
647cdf0e10cSrcweir                 aImagePos.X() = aRenderArea.Left() + ( aRenderArea.GetWidth() - aImageSize.Width() ) / 2;
648cdf0e10cSrcweir                 aImagePos.Y() = aRenderArea.Top();
649cdf0e10cSrcweir             }
650cdf0e10cSrcweir             else
651cdf0e10cSrcweir             {
652cdf0e10cSrcweir                 aImagePos.X() = aRenderArea.Left();
653cdf0e10cSrcweir                 aImagePos.Y() = aRenderArea.Top() + ( aRenderArea.GetHeight() - aImageSize.Height() ) / 2;
654cdf0e10cSrcweir             }
655cdf0e10cSrcweir             m_rTabBar.DrawImage( aImagePos, aItemImage );
656cdf0e10cSrcweir         }
657cdf0e10cSrcweir 
658cdf0e10cSrcweir         const ::rtl::OUString sItemText( i_pPanel->GetDisplayName() );
659cdf0e10cSrcweir         const bool bUseText = ( sItemText.getLength() != 0 ) && ( i_eItemContent != TABITEM_IMAGE_ONLY );
660cdf0e10cSrcweir 
661cdf0e10cSrcweir         if ( bUseText )
662cdf0e10cSrcweir         {
663cdf0e10cSrcweir             if ( IsVertical() )
664cdf0e10cSrcweir             {
665cdf0e10cSrcweir                 if ( bUseImage )
666cdf0e10cSrcweir                     aRenderArea.Top() += aImageSize.Height() + ITEM_ICON_TEXT_DISTANCE;
667cdf0e10cSrcweir                 aRenderArea.Top() += ITEM_TEXT_FLOW_SPACE;
668cdf0e10cSrcweir             }
669cdf0e10cSrcweir             else
670cdf0e10cSrcweir             {
671cdf0e10cSrcweir                 if ( bUseImage )
672cdf0e10cSrcweir                     aRenderArea.Left() += aImageSize.Width() + ITEM_ICON_TEXT_DISTANCE;
673cdf0e10cSrcweir                 aRenderArea.Left() += ITEM_TEXT_FLOW_SPACE;
674cdf0e10cSrcweir             }
675cdf0e10cSrcweir 
676cdf0e10cSrcweir             // draw the text
677cdf0e10cSrcweir             const Size aTextSize( m_rTabBar.GetCtrlTextWidth( sItemText ), m_rTabBar.GetTextHeight() );
678cdf0e10cSrcweir             Point aTextPos( aRenderArea.TopLeft() );
679cdf0e10cSrcweir             if ( IsVertical() )
680cdf0e10cSrcweir             {
681cdf0e10cSrcweir                 m_rTabBar.Push( PUSH_FONT );
682cdf0e10cSrcweir 
683cdf0e10cSrcweir                 Font aFont( m_rTabBar.GetFont() );
684cdf0e10cSrcweir                 aFont.SetOrientation( 2700 );
685cdf0e10cSrcweir                 aFont.SetVertical( sal_True );
686cdf0e10cSrcweir                 m_rTabBar.SetFont( aFont );
687cdf0e10cSrcweir 
688cdf0e10cSrcweir                 aTextPos.X() += aTextSize.Height();
689cdf0e10cSrcweir                 aTextPos.X() += ( aRenderArea.GetWidth() - aTextSize.Height() ) / 2;
690cdf0e10cSrcweir             }
691cdf0e10cSrcweir             else
692cdf0e10cSrcweir             {
693cdf0e10cSrcweir                 aTextPos.Y() += ( aRenderArea.GetHeight() - aTextSize.Height() ) / 2;
694cdf0e10cSrcweir             }
695cdf0e10cSrcweir 
696cdf0e10cSrcweir             m_rTabBar.DrawText( aTextPos, sItemText );
697cdf0e10cSrcweir 
698cdf0e10cSrcweir             if ( IsVertical() )
699cdf0e10cSrcweir             {
700cdf0e10cSrcweir                 m_rTabBar.Pop();
701cdf0e10cSrcweir             }
702cdf0e10cSrcweir         }
703cdf0e10cSrcweir     }
704cdf0e10cSrcweir 
705cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
CopyFromRenderDevice(const Rectangle & i_rLogicalRect) const706cdf0e10cSrcweir     void PanelTabBar_Impl::CopyFromRenderDevice( const Rectangle& i_rLogicalRect ) const
707cdf0e10cSrcweir     {
708cdf0e10cSrcweir         BitmapEx aBitmap( m_aRenderDevice.GetBitmapEx(
709cdf0e10cSrcweir             i_rLogicalRect.TopLeft(),
710cdf0e10cSrcweir             Size(
711cdf0e10cSrcweir                 i_rLogicalRect.GetSize().Width(),
712cdf0e10cSrcweir                 i_rLogicalRect.GetSize().Height()
713cdf0e10cSrcweir             )
714cdf0e10cSrcweir         ) );
715cdf0e10cSrcweir         if ( IsVertical() )
716cdf0e10cSrcweir         {
717cdf0e10cSrcweir             aBitmap.Rotate( 2700, COL_BLACK );
718cdf0e10cSrcweir             if ( m_eTabAlignment == TABS_LEFT )
719cdf0e10cSrcweir                 aBitmap.Mirror( BMP_MIRROR_HORZ );
720cdf0e10cSrcweir         }
721cdf0e10cSrcweir         else if ( m_eTabAlignment == TABS_BOTTOM )
722cdf0e10cSrcweir         {
723cdf0e10cSrcweir             aBitmap.Mirror( BMP_MIRROR_VERT );
724cdf0e10cSrcweir         }
725cdf0e10cSrcweir 
726cdf0e10cSrcweir         const Rectangle aActualRect( m_aNormalizer.getTransformed( i_rLogicalRect, m_eTabAlignment ) );
727cdf0e10cSrcweir         m_rTabBar.DrawBitmapEx( aActualRect.TopLeft(), aBitmap );
728cdf0e10cSrcweir     }
729cdf0e10cSrcweir 
730cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
InvalidateItem(const size_t i_nItemIndex,const ItemFlags i_nAdditionalItemFlags) const731cdf0e10cSrcweir     void PanelTabBar_Impl::InvalidateItem( const size_t i_nItemIndex, const ItemFlags i_nAdditionalItemFlags ) const
732cdf0e10cSrcweir     {
733cdf0e10cSrcweir         const ItemDescriptor& rItem( m_aItems[ i_nItemIndex ] );
734cdf0e10cSrcweir         const ItemFlags nItemFlags( impl_getItemFlags( i_nItemIndex ) | i_nAdditionalItemFlags );
735cdf0e10cSrcweir 
736cdf0e10cSrcweir         const Rectangle aNormalizedContent( GetActualLogicalItemRect( rItem.GetCurrentRect() ) );
737cdf0e10cSrcweir         const Rectangle aNormalizedBounds( m_pRenderer->calculateDecorations( aNormalizedContent, nItemFlags ) );
738cdf0e10cSrcweir 
739cdf0e10cSrcweir         const Rectangle aActualBounds = m_aNormalizer.getTransformed( aNormalizedBounds, m_eTabAlignment );
740cdf0e10cSrcweir         m_rTabBar.Invalidate( aActualBounds );
741cdf0e10cSrcweir     }
742cdf0e10cSrcweir 
743cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
impl_getItemFlags(const size_t i_nItemIndex) const744cdf0e10cSrcweir     ItemFlags PanelTabBar_Impl::impl_getItemFlags( const size_t i_nItemIndex ) const
745cdf0e10cSrcweir     {
746cdf0e10cSrcweir         ItemFlags nItemFlags( ITEM_STATE_NORMAL );
747cdf0e10cSrcweir         if ( m_aHoveredItem == i_nItemIndex )
748cdf0e10cSrcweir         {
749cdf0e10cSrcweir             nItemFlags |= ITEM_STATE_HOVERED;
750cdf0e10cSrcweir             if ( m_bMouseButtonDown )
751cdf0e10cSrcweir                 nItemFlags |= ITEM_STATE_ACTIVE;
752cdf0e10cSrcweir         }
753cdf0e10cSrcweir 
754cdf0e10cSrcweir         if ( m_rPanelDeck.GetActivePanel() == i_nItemIndex )
755cdf0e10cSrcweir             nItemFlags |= ITEM_STATE_ACTIVE;
756cdf0e10cSrcweir 
757cdf0e10cSrcweir         if ( m_aFocusedItem == i_nItemIndex )
758cdf0e10cSrcweir             nItemFlags |= ITEM_STATE_FOCUSED;
759cdf0e10cSrcweir 
760cdf0e10cSrcweir         if ( 0 == i_nItemIndex )
761cdf0e10cSrcweir             nItemFlags |= ITEM_POSITION_FIRST;
762cdf0e10cSrcweir 
763cdf0e10cSrcweir         if ( m_rPanelDeck.GetPanelCount() - 1 == i_nItemIndex )
764cdf0e10cSrcweir             nItemFlags |= ITEM_POSITION_LAST;
765cdf0e10cSrcweir 
766cdf0e10cSrcweir         return nItemFlags;
767cdf0e10cSrcweir     }
768cdf0e10cSrcweir 
769cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
DrawItem(const size_t i_nItemIndex,const Rectangle & i_rBoundaries) const770cdf0e10cSrcweir     void PanelTabBar_Impl::DrawItem( const size_t i_nItemIndex, const Rectangle& i_rBoundaries ) const
771cdf0e10cSrcweir     {
772cdf0e10cSrcweir         const ItemDescriptor& rItem( m_aItems[ i_nItemIndex ] );
773cdf0e10cSrcweir         const ItemFlags nItemFlags( impl_getItemFlags( i_nItemIndex ) );
774cdf0e10cSrcweir 
775cdf0e10cSrcweir         // the normalized bounding and content rect
776cdf0e10cSrcweir         const Rectangle aNormalizedContent( GetActualLogicalItemRect( rItem.GetCurrentRect() ) );
777cdf0e10cSrcweir         const Rectangle aNormalizedBounds( m_pRenderer->calculateDecorations( aNormalizedContent, nItemFlags ) );
778cdf0e10cSrcweir 
779cdf0e10cSrcweir         // check whether the item actually overlaps with the painting area
780cdf0e10cSrcweir         if ( !i_rBoundaries.IsEmpty() )
781cdf0e10cSrcweir         {
782cdf0e10cSrcweir             const Rectangle aItemRect( GetActualLogicalItemRect( rItem.GetCurrentRect() ) );
783cdf0e10cSrcweir             if ( !aItemRect.IsOver( i_rBoundaries ) )
784cdf0e10cSrcweir                 return;
785cdf0e10cSrcweir         }
786cdf0e10cSrcweir 
787cdf0e10cSrcweir         m_rTabBar.SetUpdateMode( sal_False );
788cdf0e10cSrcweir 
789cdf0e10cSrcweir         // the aligned bounding and content rect
790cdf0e10cSrcweir         const Rectangle aActualBounds = m_aNormalizer.getTransformed( aNormalizedBounds, m_eTabAlignment );
791cdf0e10cSrcweir         const Rectangle aActualContent = m_aNormalizer.getTransformed( aNormalizedContent, m_eTabAlignment );
792cdf0e10cSrcweir 
793cdf0e10cSrcweir         // render item "background" layer
794cdf0e10cSrcweir         m_pRenderer->preRenderItem( aNormalizedContent, nItemFlags );
795cdf0e10cSrcweir 
796cdf0e10cSrcweir         // copy from the virtual device to ourself
797cdf0e10cSrcweir         CopyFromRenderDevice( aNormalizedBounds );
798cdf0e10cSrcweir 
799cdf0e10cSrcweir         // render the actual item content
800cdf0e10cSrcweir         impl_renderItemContent( rItem.pPanel, aActualContent, rItem.eContent );
801cdf0e10cSrcweir 
802cdf0e10cSrcweir         // render item "foreground" layer
803cdf0e10cSrcweir         m_pRenderer->postRenderItem( m_rTabBar, aActualBounds, nItemFlags );
804cdf0e10cSrcweir 
805cdf0e10cSrcweir         m_rTabBar.SetUpdateMode( sal_True );
806cdf0e10cSrcweir     }
807cdf0e10cSrcweir 
808cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
EnsureItemsCache()809cdf0e10cSrcweir     void PanelTabBar_Impl::EnsureItemsCache()
810cdf0e10cSrcweir     {
811cdf0e10cSrcweir         if ( m_bItemsDirty == false )
812cdf0e10cSrcweir         {
813cdf0e10cSrcweir             DBG_CHECK( *this );
814cdf0e10cSrcweir             return;
815cdf0e10cSrcweir         }
816cdf0e10cSrcweir         impl_calcItemRects();
817cdf0e10cSrcweir         OSL_POSTCOND( m_bItemsDirty == false, "PanelTabBar_Impl::EnsureItemsCache: cache still dirty!" );
818cdf0e10cSrcweir         DBG_CHECK( *this );
819cdf0e10cSrcweir     }
820cdf0e10cSrcweir 
821cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
Relayout()822cdf0e10cSrcweir     void PanelTabBar_Impl::Relayout()
823cdf0e10cSrcweir     {
824cdf0e10cSrcweir         EnsureItemsCache();
825cdf0e10cSrcweir 
826cdf0e10cSrcweir         const Size aOutputSize( m_rTabBar.GetOutputSizePixel() );
827cdf0e10cSrcweir         m_aNormalizer = NormalizedArea( Rectangle( Point(), aOutputSize ), IsVertical() );
828cdf0e10cSrcweir         const Size aLogicalOutputSize( m_aNormalizer.getReferenceSize() );
829cdf0e10cSrcweir 
830cdf0e10cSrcweir         // forward actual output size to our render device
831cdf0e10cSrcweir         m_aRenderDevice.SetOutputSizePixel( aLogicalOutputSize );
832cdf0e10cSrcweir 
833cdf0e10cSrcweir         // re-calculate the size of the scroll buttons and of the items
834cdf0e10cSrcweir         m_aGeometry.relayout( aLogicalOutputSize, m_aItems );
835cdf0e10cSrcweir 
836cdf0e10cSrcweir         if ( m_aGeometry.getButtonBackRect().IsEmpty() )
837cdf0e10cSrcweir         {
838cdf0e10cSrcweir             m_aScrollBack.Hide();
839cdf0e10cSrcweir         }
840cdf0e10cSrcweir         else
841cdf0e10cSrcweir         {
842cdf0e10cSrcweir             const Rectangle aButtonBack( m_aNormalizer.getTransformed( m_aGeometry.getButtonBackRect(), m_eTabAlignment ) );
843cdf0e10cSrcweir             m_aScrollBack.SetPosSizePixel( aButtonBack.TopLeft(), aButtonBack.GetSize() );
844cdf0e10cSrcweir             m_aScrollBack.Show();
845cdf0e10cSrcweir         }
846cdf0e10cSrcweir 
847cdf0e10cSrcweir         if ( m_aGeometry.getButtonForwardRect().IsEmpty() )
848cdf0e10cSrcweir         {
849cdf0e10cSrcweir             m_aScrollForward.Hide();
850cdf0e10cSrcweir         }
851cdf0e10cSrcweir         else
852cdf0e10cSrcweir         {
853cdf0e10cSrcweir             const Rectangle aButtonForward( m_aNormalizer.getTransformed( m_aGeometry.getButtonForwardRect(), m_eTabAlignment ) );
854cdf0e10cSrcweir             m_aScrollForward.SetPosSizePixel( aButtonForward.TopLeft(), aButtonForward.GetSize() );
855cdf0e10cSrcweir             m_aScrollForward.Show();
856cdf0e10cSrcweir         }
857cdf0e10cSrcweir 
858cdf0e10cSrcweir         UpdateScrollButtons();
859cdf0e10cSrcweir     }
860cdf0e10cSrcweir 
861cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
FindItemForPoint(const Point & i_rPoint) const862cdf0e10cSrcweir     ::boost::optional< size_t > PanelTabBar_Impl::FindItemForPoint( const Point& i_rPoint ) const
863cdf0e10cSrcweir     {
864cdf0e10cSrcweir         Point aPoint( IsVertical() ? i_rPoint.Y() : i_rPoint.X(), IsVertical() ? i_rPoint.X() : i_rPoint.Y() );
865cdf0e10cSrcweir 
866cdf0e10cSrcweir         if ( !m_aGeometry.getItemsRect().IsInside( aPoint ) )
867cdf0e10cSrcweir             return ::boost::optional< size_t >();
868cdf0e10cSrcweir 
869cdf0e10cSrcweir         size_t i=0;
870cdf0e10cSrcweir         for (   ItemDescriptors::const_iterator item = m_aItems.begin();
871cdf0e10cSrcweir                 item != m_aItems.end();
872cdf0e10cSrcweir                 ++item, ++i
873cdf0e10cSrcweir             )
874cdf0e10cSrcweir         {
875cdf0e10cSrcweir             Rectangle aItemRect( GetActualLogicalItemRect( item->GetCurrentRect() ) );
876cdf0e10cSrcweir             if ( aItemRect.IsInside( aPoint ) )
877cdf0e10cSrcweir             {
878cdf0e10cSrcweir                 return ::boost::optional< size_t >( i );
879cdf0e10cSrcweir             }
880cdf0e10cSrcweir         }
881cdf0e10cSrcweir         return ::boost::optional< size_t >();
882cdf0e10cSrcweir     }
883cdf0e10cSrcweir 
884cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
GetItemScreenRect(const size_t i_nItemPos) const885cdf0e10cSrcweir     Rectangle PanelTabBar_Impl::GetItemScreenRect( const size_t i_nItemPos ) const
886cdf0e10cSrcweir     {
887cdf0e10cSrcweir         ENSURE_OR_RETURN( i_nItemPos < m_aItems.size(), "PanelTabBar_Impl::GetItemScreenRect: invalid item pos!", Rectangle() );
888cdf0e10cSrcweir         const ItemDescriptor& rItem( m_aItems[ i_nItemPos ] );
889cdf0e10cSrcweir         const Rectangle aItemRect( m_aNormalizer.getTransformed(
890cdf0e10cSrcweir             GetActualLogicalItemRect( rItem.GetCurrentRect() ),
891cdf0e10cSrcweir             m_eTabAlignment ) );
892cdf0e10cSrcweir 
893cdf0e10cSrcweir 		const Rectangle aTabBarRect( m_rTabBar.GetWindowExtentsRelative( NULL ) );
894cdf0e10cSrcweir         return Rectangle(
895cdf0e10cSrcweir             Point( aTabBarRect.Left() + aItemRect.Left(), aTabBarRect.Top() + aItemRect.Top() ),
896cdf0e10cSrcweir             aItemRect.GetSize()
897cdf0e10cSrcweir         );
898cdf0e10cSrcweir     }
899cdf0e10cSrcweir 
900cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
FocusItem(const::boost::optional<size_t> & i_rItemPos)901cdf0e10cSrcweir     void PanelTabBar_Impl::FocusItem( const ::boost::optional< size_t >& i_rItemPos )
902cdf0e10cSrcweir     {
903cdf0e10cSrcweir         // reset old focus item
904cdf0e10cSrcweir         if ( !!m_aFocusedItem )
905cdf0e10cSrcweir             InvalidateItem( *m_aFocusedItem );
906cdf0e10cSrcweir         m_aFocusedItem.reset();
907cdf0e10cSrcweir 
908cdf0e10cSrcweir         // mark the active icon as focused
909cdf0e10cSrcweir         if ( !!i_rItemPos )
910cdf0e10cSrcweir         {
911cdf0e10cSrcweir             m_aFocusedItem = i_rItemPos;
912cdf0e10cSrcweir             InvalidateItem( *m_aFocusedItem );
913cdf0e10cSrcweir         }
914cdf0e10cSrcweir     }
915cdf0e10cSrcweir 
916cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
IMPL_LINK(PanelTabBar_Impl,OnScroll,const PushButton *,i_pButton)917cdf0e10cSrcweir     IMPL_LINK( PanelTabBar_Impl, OnScroll, const PushButton*, i_pButton )
918cdf0e10cSrcweir     {
919cdf0e10cSrcweir         if ( i_pButton == &m_aScrollBack )
920cdf0e10cSrcweir         {
921cdf0e10cSrcweir             OSL_ENSURE( m_nScrollPosition > 0, "PanelTabBar_Impl::OnScroll: inconsistency!" );
922cdf0e10cSrcweir             --m_nScrollPosition;
923cdf0e10cSrcweir             m_rTabBar.Invalidate();
924cdf0e10cSrcweir         }
925cdf0e10cSrcweir         else if ( i_pButton == &m_aScrollForward )
926cdf0e10cSrcweir         {
927cdf0e10cSrcweir             OSL_ENSURE( m_nScrollPosition < m_aItems.size() - 1, "PanelTabBar_Impl::OnScroll: inconsistency!" );
928cdf0e10cSrcweir             ++m_nScrollPosition;
929cdf0e10cSrcweir             m_rTabBar.Invalidate();
930cdf0e10cSrcweir         }
931cdf0e10cSrcweir 
932cdf0e10cSrcweir         UpdateScrollButtons();
933cdf0e10cSrcweir 
934cdf0e10cSrcweir         return 0L;
935cdf0e10cSrcweir     }
936cdf0e10cSrcweir 
937cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
GetActualLogicalItemRect(const Rectangle & i_rLogicalItemRect) const938cdf0e10cSrcweir     Rectangle PanelTabBar_Impl::GetActualLogicalItemRect( const Rectangle& i_rLogicalItemRect ) const
939cdf0e10cSrcweir     {
940cdf0e10cSrcweir         // care for the offset imposed by our geometry, i.e. whether or not we have scroll buttons
941cdf0e10cSrcweir         Rectangle aItemRect( i_rLogicalItemRect );
942cdf0e10cSrcweir         aItemRect.Move( m_aGeometry.getItemsRect().Left() - m_aGeometry.getButtonBackRect().Left(), 0 );
943cdf0e10cSrcweir 
944cdf0e10cSrcweir         // care for the current scroll position
945cdf0e10cSrcweir         OSL_ENSURE( m_nScrollPosition < m_aItems.size(), "GetActualLogicalItemRect: invalid scroll position!" );
946cdf0e10cSrcweir         if ( ( m_nScrollPosition > 0 ) && ( m_nScrollPosition < m_aItems.size() ) )
947cdf0e10cSrcweir         {
948cdf0e10cSrcweir             long nOffsetX = m_aItems[ m_nScrollPosition ].GetCurrentRect().Left() - m_aItems[ 0 ].GetCurrentRect().Left();
949cdf0e10cSrcweir             long nOffsetY = m_aItems[ m_nScrollPosition ].GetCurrentRect().Top() - m_aItems[ 0 ].GetCurrentRect().Top();
950cdf0e10cSrcweir             aItemRect.Move( -nOffsetX, -nOffsetY );
951cdf0e10cSrcweir         }
952cdf0e10cSrcweir 
953cdf0e10cSrcweir         return aItemRect;
954cdf0e10cSrcweir     }
955cdf0e10cSrcweir 
956cdf0e10cSrcweir 	//==================================================================================================================
957cdf0e10cSrcweir 	//= PanelTabBar_Impl
958cdf0e10cSrcweir 	//==================================================================================================================
959cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
ActivePanelChanged(const::boost::optional<size_t> & i_rOldActive,const::boost::optional<size_t> & i_rNewActive)960cdf0e10cSrcweir     void PanelTabBar_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive )
961cdf0e10cSrcweir     {
962cdf0e10cSrcweir         EnsureItemsCache();
963cdf0e10cSrcweir 
964cdf0e10cSrcweir         if ( !!i_rOldActive )
965cdf0e10cSrcweir             InvalidateItem( *i_rOldActive, ITEM_STATE_ACTIVE );
966cdf0e10cSrcweir         if ( !!i_rNewActive )
967cdf0e10cSrcweir             InvalidateItem( *i_rNewActive );
968cdf0e10cSrcweir     }
969cdf0e10cSrcweir 
970cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
LayouterChanged(const PDeckLayouter & i_rNewLayouter)971cdf0e10cSrcweir     void PanelTabBar_Impl::LayouterChanged( const PDeckLayouter& i_rNewLayouter )
972cdf0e10cSrcweir     {
973cdf0e10cSrcweir         // not interested in
974cdf0e10cSrcweir         (void)i_rNewLayouter;
975cdf0e10cSrcweir     }
976cdf0e10cSrcweir 
977cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
Dying()978cdf0e10cSrcweir     void PanelTabBar_Impl::Dying()
979cdf0e10cSrcweir     {
980cdf0e10cSrcweir         // not interested in - the notifier is a member of this instance here, so we're dying ourself at the moment
981cdf0e10cSrcweir     }
982cdf0e10cSrcweir 
983cdf0e10cSrcweir 	//==================================================================================================================
984cdf0e10cSrcweir 	//= PanelTabBar
985cdf0e10cSrcweir 	//==================================================================================================================
986cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
PanelTabBar(Window & i_rParentWindow,IToolPanelDeck & i_rPanelDeck,const TabAlignment i_eAlignment,const TabItemContent i_eItemContent)987cdf0e10cSrcweir     PanelTabBar::PanelTabBar( Window& i_rParentWindow, IToolPanelDeck& i_rPanelDeck, const TabAlignment i_eAlignment, const TabItemContent i_eItemContent )
988cdf0e10cSrcweir         :Control( &i_rParentWindow, 0 )
989cdf0e10cSrcweir         ,m_pImpl( new PanelTabBar_Impl( *this, i_rPanelDeck, i_eAlignment, i_eItemContent ) )
990cdf0e10cSrcweir     {
991cdf0e10cSrcweir         DBG_CHECK( *m_pImpl );
992cdf0e10cSrcweir     }
993cdf0e10cSrcweir 
994cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
~PanelTabBar()995cdf0e10cSrcweir     PanelTabBar::~PanelTabBar()
996cdf0e10cSrcweir     {
997cdf0e10cSrcweir     }
998cdf0e10cSrcweir 
999cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
GetTabItemContent() const1000cdf0e10cSrcweir     TabItemContent PanelTabBar::GetTabItemContent() const
1001cdf0e10cSrcweir     {
1002cdf0e10cSrcweir         return m_pImpl->m_aGeometry.getItemContent();
1003cdf0e10cSrcweir     }
1004cdf0e10cSrcweir 
1005cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
SetTabItemContent(const TabItemContent & i_eItemContent)1006cdf0e10cSrcweir     void PanelTabBar::SetTabItemContent( const TabItemContent& i_eItemContent )
1007cdf0e10cSrcweir     {
1008cdf0e10cSrcweir         m_pImpl->m_aGeometry.setItemContent( i_eItemContent );
1009cdf0e10cSrcweir         m_pImpl->Relayout();
1010cdf0e10cSrcweir         Invalidate();
1011cdf0e10cSrcweir     }
1012cdf0e10cSrcweir 
1013cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
GetPanelDeck() const1014cdf0e10cSrcweir     IToolPanelDeck& PanelTabBar::GetPanelDeck() const
1015cdf0e10cSrcweir     {
1016cdf0e10cSrcweir         DBG_CHECK( *m_pImpl );
1017cdf0e10cSrcweir         return m_pImpl->m_rPanelDeck;
1018cdf0e10cSrcweir     }
1019cdf0e10cSrcweir 
1020cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
GetOptimalSize(WindowSizeType i_eType) const1021cdf0e10cSrcweir     Size PanelTabBar::GetOptimalSize( WindowSizeType i_eType ) const
1022cdf0e10cSrcweir     {
1023cdf0e10cSrcweir         m_pImpl->EnsureItemsCache();
1024cdf0e10cSrcweir         Size aOptimalSize( m_pImpl->m_aGeometry.getOptimalSize( m_pImpl->m_aItems, i_eType == WINDOWSIZE_MINIMUM ) );
1025cdf0e10cSrcweir         if ( m_pImpl->IsVertical() )
1026cdf0e10cSrcweir             ::std::swap( aOptimalSize.Width(), aOptimalSize.Height() );
1027cdf0e10cSrcweir         return aOptimalSize;
1028cdf0e10cSrcweir     }
1029cdf0e10cSrcweir 
1030cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
Resize()1031cdf0e10cSrcweir     void PanelTabBar::Resize()
1032cdf0e10cSrcweir     {
1033cdf0e10cSrcweir         Control::Resize();
1034cdf0e10cSrcweir         m_pImpl->Relayout();
1035cdf0e10cSrcweir     }
1036cdf0e10cSrcweir 
1037cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
Paint(const Rectangle & i_rRect)1038cdf0e10cSrcweir     void PanelTabBar::Paint( const Rectangle& i_rRect )
1039cdf0e10cSrcweir     {
1040cdf0e10cSrcweir         m_pImpl->EnsureItemsCache();
1041cdf0e10cSrcweir 
1042cdf0e10cSrcweir         // background
1043cdf0e10cSrcweir         const Rectangle aNormalizedPaintArea( m_pImpl->m_aNormalizer.getNormalized( i_rRect, m_pImpl->m_eTabAlignment ) );
1044cdf0e10cSrcweir         m_pImpl->m_aRenderDevice.Push( PUSH_CLIPREGION );
1045cdf0e10cSrcweir         m_pImpl->m_aRenderDevice.SetClipRegion( aNormalizedPaintArea );
1046cdf0e10cSrcweir         m_pImpl->m_pRenderer->renderBackground();
1047cdf0e10cSrcweir         m_pImpl->m_aRenderDevice.Pop();
1048cdf0e10cSrcweir         m_pImpl->CopyFromRenderDevice( aNormalizedPaintArea );
1049cdf0e10cSrcweir 
1050cdf0e10cSrcweir         // ensure the items really paint into their own playground only
1051cdf0e10cSrcweir         ClipItemRegion aClipItems( *m_pImpl );
1052cdf0e10cSrcweir 
1053cdf0e10cSrcweir         const Rectangle aLogicalPaintRect( m_pImpl->m_aNormalizer.getNormalized( i_rRect, m_pImpl->m_eTabAlignment ) );
1054cdf0e10cSrcweir 
1055cdf0e10cSrcweir         const ::boost::optional< size_t > aActivePanel( m_pImpl->m_rPanelDeck.GetActivePanel() );
1056cdf0e10cSrcweir         const ::boost::optional< size_t > aHoveredPanel( m_pImpl->m_aHoveredItem );
1057cdf0e10cSrcweir 
1058cdf0e10cSrcweir         // items:
1059cdf0e10cSrcweir         // 1. paint all non-active, non-hovered items
1060cdf0e10cSrcweir         size_t i=0;
1061cdf0e10cSrcweir         for (   ItemDescriptors::const_iterator item = m_pImpl->m_aItems.begin();
1062cdf0e10cSrcweir                 item != m_pImpl->m_aItems.end();
1063cdf0e10cSrcweir                 ++item, ++i
1064cdf0e10cSrcweir             )
1065cdf0e10cSrcweir         {
1066cdf0e10cSrcweir             if ( i == aActivePanel )
1067cdf0e10cSrcweir                 continue;
1068cdf0e10cSrcweir 
1069cdf0e10cSrcweir             if ( aHoveredPanel == i )
1070cdf0e10cSrcweir                 continue;
1071cdf0e10cSrcweir 
1072cdf0e10cSrcweir             m_pImpl->DrawItem( i, aLogicalPaintRect );
1073cdf0e10cSrcweir         }
1074cdf0e10cSrcweir 
1075cdf0e10cSrcweir         // 2. paint the item which is hovered, /without/ the mouse button pressed down
1076cdf0e10cSrcweir         if ( !!aHoveredPanel && !m_pImpl->m_bMouseButtonDown )
1077cdf0e10cSrcweir             m_pImpl->DrawItem( *aHoveredPanel, aLogicalPaintRect );
1078cdf0e10cSrcweir 
1079cdf0e10cSrcweir         // 3. paint the active item
1080cdf0e10cSrcweir         if ( !!aActivePanel )
1081cdf0e10cSrcweir             m_pImpl->DrawItem( *aActivePanel, aLogicalPaintRect );
1082cdf0e10cSrcweir 
1083cdf0e10cSrcweir         // 4. paint the item which is hovered, /with/ the mouse button pressed down
1084cdf0e10cSrcweir         if ( !!aHoveredPanel && m_pImpl->m_bMouseButtonDown )
1085cdf0e10cSrcweir             m_pImpl->DrawItem( *aHoveredPanel, aLogicalPaintRect );
1086cdf0e10cSrcweir     }
1087cdf0e10cSrcweir 
1088cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
MouseMove(const MouseEvent & i_rMouseEvent)1089cdf0e10cSrcweir     void PanelTabBar::MouseMove( const MouseEvent& i_rMouseEvent )
1090cdf0e10cSrcweir     {
1091cdf0e10cSrcweir         m_pImpl->EnsureItemsCache();
1092cdf0e10cSrcweir 
1093cdf0e10cSrcweir         ::boost::optional< size_t > aOldItem( m_pImpl->m_aHoveredItem );
1094cdf0e10cSrcweir         ::boost::optional< size_t > aNewItem( m_pImpl->FindItemForPoint( i_rMouseEvent.GetPosPixel() ) );
1095cdf0e10cSrcweir 
1096cdf0e10cSrcweir         if  ( i_rMouseEvent.IsLeaveWindow() )
1097cdf0e10cSrcweir             aNewItem.reset();
1098cdf0e10cSrcweir 
1099cdf0e10cSrcweir         if ( aOldItem != aNewItem )
1100cdf0e10cSrcweir         {
1101cdf0e10cSrcweir             if ( !!aOldItem )
1102cdf0e10cSrcweir                 m_pImpl->InvalidateItem( *aOldItem );
1103cdf0e10cSrcweir 
1104cdf0e10cSrcweir             m_pImpl->m_aHoveredItem = aNewItem;
1105cdf0e10cSrcweir 
1106cdf0e10cSrcweir             if ( !!aNewItem )
1107cdf0e10cSrcweir                 m_pImpl->InvalidateItem( *aNewItem );
1108cdf0e10cSrcweir         }
1109cdf0e10cSrcweir     }
1110cdf0e10cSrcweir 
1111cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
MouseButtonDown(const MouseEvent & i_rMouseEvent)1112cdf0e10cSrcweir     void PanelTabBar::MouseButtonDown( const MouseEvent& i_rMouseEvent )
1113cdf0e10cSrcweir     {
1114cdf0e10cSrcweir         Control::MouseButtonDown( i_rMouseEvent );
1115cdf0e10cSrcweir 
1116cdf0e10cSrcweir         if ( !i_rMouseEvent.IsLeft() )
1117cdf0e10cSrcweir             return;
1118cdf0e10cSrcweir 
1119cdf0e10cSrcweir         m_pImpl->EnsureItemsCache();
1120cdf0e10cSrcweir 
1121cdf0e10cSrcweir         ::boost::optional< size_t > aHitItem( m_pImpl->FindItemForPoint( i_rMouseEvent.GetPosPixel() ) );
1122cdf0e10cSrcweir         if ( !aHitItem )
1123cdf0e10cSrcweir             return;
1124cdf0e10cSrcweir 
1125cdf0e10cSrcweir         CaptureMouse();
1126cdf0e10cSrcweir         m_pImpl->m_bMouseButtonDown = true;
1127cdf0e10cSrcweir 
1128cdf0e10cSrcweir         m_pImpl->InvalidateItem( *aHitItem );
1129cdf0e10cSrcweir     }
1130cdf0e10cSrcweir 
1131cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
MouseButtonUp(const MouseEvent & i_rMouseEvent)1132cdf0e10cSrcweir     void PanelTabBar::MouseButtonUp( const MouseEvent& i_rMouseEvent )
1133cdf0e10cSrcweir     {
1134cdf0e10cSrcweir         Control::MouseButtonUp( i_rMouseEvent );
1135cdf0e10cSrcweir 
1136cdf0e10cSrcweir         if ( m_pImpl->m_bMouseButtonDown )
1137cdf0e10cSrcweir         {
1138cdf0e10cSrcweir             ::boost::optional< size_t > aHitItem( m_pImpl->FindItemForPoint( i_rMouseEvent.GetPosPixel() ) );
1139cdf0e10cSrcweir             if ( !!aHitItem )
1140cdf0e10cSrcweir             {
1141cdf0e10cSrcweir                 // re-draw that item now that we're not in mouse-down mode anymore
1142cdf0e10cSrcweir                 m_pImpl->InvalidateItem( *aHitItem );
1143cdf0e10cSrcweir                 // activate the respective panel
1144cdf0e10cSrcweir                 m_pImpl->m_rPanelDeck.ActivatePanel( *aHitItem );
1145cdf0e10cSrcweir             }
1146cdf0e10cSrcweir 
1147cdf0e10cSrcweir             OSL_ENSURE( IsMouseCaptured(), "PanelTabBar::MouseButtonUp: inconsistency!" );
1148cdf0e10cSrcweir             if ( IsMouseCaptured() )
1149cdf0e10cSrcweir                 ReleaseMouse();
1150cdf0e10cSrcweir             m_pImpl->m_bMouseButtonDown = false;
1151cdf0e10cSrcweir         }
1152cdf0e10cSrcweir     }
1153cdf0e10cSrcweir 
1154cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
RequestHelp(const HelpEvent & i_rHelpEvent)1155cdf0e10cSrcweir     void PanelTabBar::RequestHelp( const HelpEvent& i_rHelpEvent )
1156cdf0e10cSrcweir     {
1157cdf0e10cSrcweir         m_pImpl->EnsureItemsCache();
1158cdf0e10cSrcweir 
1159cdf0e10cSrcweir         ::boost::optional< size_t > aHelpItem( m_pImpl->FindItemForPoint( ScreenToOutputPixel( i_rHelpEvent.GetMousePosPixel() ) ) );
1160cdf0e10cSrcweir         if ( !aHelpItem )
1161cdf0e10cSrcweir             return;
1162cdf0e10cSrcweir 
1163cdf0e10cSrcweir         const ItemDescriptor& rItem( m_pImpl->m_aItems[ *aHelpItem ] );
1164cdf0e10cSrcweir         if ( rItem.eContent != TABITEM_IMAGE_ONLY )
1165cdf0e10cSrcweir             // if the text is displayed for the item, we do not need to show it as tooltip
1166cdf0e10cSrcweir             return;
1167cdf0e10cSrcweir 
1168cdf0e10cSrcweir         const ::rtl::OUString sItemText( rItem.pPanel->GetDisplayName() );
1169cdf0e10cSrcweir 		if ( i_rHelpEvent.GetMode() == HELPMODE_BALLOON )
1170cdf0e10cSrcweir 			Help::ShowBalloon( this, OutputToScreenPixel( rItem.GetCurrentRect().Center() ), rItem.GetCurrentRect(), sItemText );
1171cdf0e10cSrcweir 		else
1172cdf0e10cSrcweir 			Help::ShowQuickHelp( this, rItem.GetCurrentRect(), sItemText );
1173cdf0e10cSrcweir     }
1174cdf0e10cSrcweir 
1175cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
GetFocus()1176cdf0e10cSrcweir     void PanelTabBar::GetFocus()
1177cdf0e10cSrcweir     {
1178cdf0e10cSrcweir         Control::GetFocus();
1179cdf0e10cSrcweir         if ( !m_pImpl->m_aFocusedItem )
1180cdf0e10cSrcweir             m_pImpl->FocusItem( m_pImpl->m_rPanelDeck.GetActivePanel() );
1181cdf0e10cSrcweir     }
1182cdf0e10cSrcweir 
1183cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
LoseFocus()1184cdf0e10cSrcweir     void PanelTabBar::LoseFocus()
1185cdf0e10cSrcweir     {
1186cdf0e10cSrcweir         Control::LoseFocus();
1187cdf0e10cSrcweir 
1188cdf0e10cSrcweir         if ( !!m_pImpl->m_aFocusedItem )
1189cdf0e10cSrcweir         {
1190cdf0e10cSrcweir             m_pImpl->InvalidateItem( *m_pImpl->m_aFocusedItem );
1191cdf0e10cSrcweir         }
1192cdf0e10cSrcweir 
1193cdf0e10cSrcweir         m_pImpl->m_aFocusedItem.reset();
1194cdf0e10cSrcweir     }
1195cdf0e10cSrcweir 
1196cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
1197cdf0e10cSrcweir     class KeyInputHandler
1198cdf0e10cSrcweir     {
1199cdf0e10cSrcweir     public:
KeyInputHandler(Control & i_rControl,const KeyEvent & i_rKeyEvent)1200cdf0e10cSrcweir         KeyInputHandler( Control& i_rControl, const KeyEvent& i_rKeyEvent )
1201cdf0e10cSrcweir             :m_rControl( i_rControl )
1202cdf0e10cSrcweir             ,m_rKeyEvent( i_rKeyEvent )
1203cdf0e10cSrcweir             ,m_bHandled( false )
1204cdf0e10cSrcweir         {
1205cdf0e10cSrcweir         }
1206cdf0e10cSrcweir 
~KeyInputHandler()1207cdf0e10cSrcweir         ~KeyInputHandler()
1208cdf0e10cSrcweir         {
1209cdf0e10cSrcweir             if ( !m_bHandled )
1210cdf0e10cSrcweir                 m_rControl.Control::KeyInput( m_rKeyEvent );
1211cdf0e10cSrcweir         }
1212cdf0e10cSrcweir 
setHandled()1213cdf0e10cSrcweir         void   setHandled()
1214cdf0e10cSrcweir         {
1215cdf0e10cSrcweir             m_bHandled = true;
1216cdf0e10cSrcweir         }
1217cdf0e10cSrcweir 
1218cdf0e10cSrcweir     private:
1219cdf0e10cSrcweir         Control&        m_rControl;
1220cdf0e10cSrcweir         const KeyEvent& m_rKeyEvent;
1221cdf0e10cSrcweir         bool            m_bHandled;
1222cdf0e10cSrcweir     };
1223cdf0e10cSrcweir 
1224cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
KeyInput(const KeyEvent & i_rKeyEvent)1225cdf0e10cSrcweir     void PanelTabBar::KeyInput( const KeyEvent& i_rKeyEvent )
1226cdf0e10cSrcweir     {
1227cdf0e10cSrcweir         KeyInputHandler aKeyInputHandler( *this, i_rKeyEvent );
1228cdf0e10cSrcweir 
1229cdf0e10cSrcweir         const KeyCode& rKeyCode( i_rKeyEvent.GetKeyCode() );
1230cdf0e10cSrcweir         if ( rKeyCode.GetModifier() != 0 )
1231cdf0e10cSrcweir             // only interested in mere key presses
1232cdf0e10cSrcweir             return;
1233cdf0e10cSrcweir 
1234cdf0e10cSrcweir         // if there are less than 2 panels, we cannot travel them ...
1235cdf0e10cSrcweir         const size_t nPanelCount( m_pImpl->m_rPanelDeck.GetPanelCount() );
1236cdf0e10cSrcweir         if ( nPanelCount < 2 )
1237cdf0e10cSrcweir             return;
1238cdf0e10cSrcweir 
1239cdf0e10cSrcweir         OSL_PRECOND( !!m_pImpl->m_aFocusedItem, "PanelTabBar::KeyInput: we should have a focused item here!" );
1240cdf0e10cSrcweir             // if we get KeyInput events, we should have the focus. In this case, m_aFocusedItem should not be empty,
1241cdf0e10cSrcweir             // except if there are no panels, but then we bail out of this method here earlier ...
1242cdf0e10cSrcweir 
1243cdf0e10cSrcweir         bool bFocusNext = false;
1244cdf0e10cSrcweir         bool bFocusPrev = false;
1245cdf0e10cSrcweir 
1246cdf0e10cSrcweir         switch ( rKeyCode.GetCode() )
1247cdf0e10cSrcweir         {
1248cdf0e10cSrcweir         case KEY_UP:    bFocusPrev = true; break;
1249cdf0e10cSrcweir         case KEY_DOWN:  bFocusNext = true; break;
1250cdf0e10cSrcweir         case KEY_LEFT:
1251cdf0e10cSrcweir             if ( IsRTLEnabled() )
1252cdf0e10cSrcweir                 bFocusNext = true;
1253cdf0e10cSrcweir             else
1254cdf0e10cSrcweir                 bFocusPrev = true;
1255cdf0e10cSrcweir             break;
1256cdf0e10cSrcweir         case KEY_RIGHT:
1257cdf0e10cSrcweir             if ( IsRTLEnabled() )
1258cdf0e10cSrcweir                 bFocusPrev = true;
1259cdf0e10cSrcweir             else
1260cdf0e10cSrcweir                 bFocusNext = true;
1261cdf0e10cSrcweir             break;
1262cdf0e10cSrcweir         case KEY_RETURN:
1263cdf0e10cSrcweir             m_pImpl->m_rPanelDeck.ActivatePanel( *m_pImpl->m_aFocusedItem );
1264cdf0e10cSrcweir             break;
1265cdf0e10cSrcweir         }
1266cdf0e10cSrcweir 
1267cdf0e10cSrcweir         if ( !bFocusNext && !bFocusPrev )
1268cdf0e10cSrcweir             return;
1269cdf0e10cSrcweir 
1270cdf0e10cSrcweir         m_pImpl->InvalidateItem( *m_pImpl->m_aFocusedItem );
1271cdf0e10cSrcweir         if ( bFocusNext )
1272cdf0e10cSrcweir         {
1273cdf0e10cSrcweir             m_pImpl->m_aFocusedItem.reset( ( *m_pImpl->m_aFocusedItem + 1 ) % nPanelCount );
1274cdf0e10cSrcweir         }
1275cdf0e10cSrcweir         else
1276cdf0e10cSrcweir         {
1277cdf0e10cSrcweir             m_pImpl->m_aFocusedItem.reset( ( *m_pImpl->m_aFocusedItem + nPanelCount - 1 ) % nPanelCount );
1278cdf0e10cSrcweir         }
1279cdf0e10cSrcweir         m_pImpl->InvalidateItem( *m_pImpl->m_aFocusedItem );
1280cdf0e10cSrcweir 
1281cdf0e10cSrcweir         // don't delegate to base class
1282cdf0e10cSrcweir         aKeyInputHandler.setHandled();
1283cdf0e10cSrcweir     }
1284cdf0e10cSrcweir 
1285cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
DataChanged(const DataChangedEvent & i_rDataChanedEvent)1286cdf0e10cSrcweir     void PanelTabBar::DataChanged( const DataChangedEvent& i_rDataChanedEvent )
1287cdf0e10cSrcweir     {
1288cdf0e10cSrcweir         Control::DataChanged( i_rDataChanedEvent );
1289cdf0e10cSrcweir 
1290cdf0e10cSrcweir         if  (   ( i_rDataChanedEvent.GetType() == DATACHANGED_SETTINGS )
1291cdf0e10cSrcweir             &&  ( ( i_rDataChanedEvent.GetFlags() & SETTINGS_STYLE ) != 0 )
1292cdf0e10cSrcweir             )
1293cdf0e10cSrcweir         {
1294cdf0e10cSrcweir             Invalidate();
1295cdf0e10cSrcweir         }
1296cdf0e10cSrcweir     }
1297cdf0e10cSrcweir 
1298cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
IsVertical() const1299cdf0e10cSrcweir     bool PanelTabBar::IsVertical() const
1300cdf0e10cSrcweir     {
1301cdf0e10cSrcweir         return m_pImpl->IsVertical();
1302cdf0e10cSrcweir     }
1303cdf0e10cSrcweir 
1304cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
GetScrollButton(const bool i_bForward)1305cdf0e10cSrcweir     PushButton& PanelTabBar::GetScrollButton( const bool i_bForward )
1306cdf0e10cSrcweir     {
1307cdf0e10cSrcweir         return i_bForward ? m_pImpl->m_aScrollForward : m_pImpl->m_aScrollBack;
1308cdf0e10cSrcweir     }
1309cdf0e10cSrcweir 
1310cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
GetFocusedPanelItem() const1311cdf0e10cSrcweir     ::boost::optional< size_t > PanelTabBar::GetFocusedPanelItem() const
1312cdf0e10cSrcweir     {
1313cdf0e10cSrcweir         return m_pImpl->m_aFocusedItem;
1314cdf0e10cSrcweir     }
1315cdf0e10cSrcweir 
1316cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
FocusPanelItem(const size_t i_nItemPos)1317cdf0e10cSrcweir     void PanelTabBar::FocusPanelItem( const size_t i_nItemPos )
1318cdf0e10cSrcweir     {
1319cdf0e10cSrcweir         ENSURE_OR_RETURN_VOID( i_nItemPos < m_pImpl->m_rPanelDeck.GetPanelCount(), "PanelTabBar::FocusPanelItem: illegal item pos!" );
1320cdf0e10cSrcweir 
1321cdf0e10cSrcweir         if ( !HasChildPathFocus() )
1322cdf0e10cSrcweir             GrabFocus();
1323cdf0e10cSrcweir 
1324cdf0e10cSrcweir         m_pImpl->FocusItem( i_nItemPos );
1325cdf0e10cSrcweir         OSL_POSTCOND( !!m_pImpl->m_aFocusedItem, "PanelTabBar::FocusPanelItem: have the focus, but no focused item?" );
1326cdf0e10cSrcweir         if ( !!m_pImpl->m_aFocusedItem )
1327cdf0e10cSrcweir             m_pImpl->InvalidateItem( *m_pImpl->m_aFocusedItem );
1328cdf0e10cSrcweir         m_pImpl->m_aFocusedItem.reset( i_nItemPos );
1329cdf0e10cSrcweir     }
1330cdf0e10cSrcweir 
1331cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
GetItemScreenRect(const size_t i_nItemPos) const1332cdf0e10cSrcweir     Rectangle PanelTabBar::GetItemScreenRect( const size_t i_nItemPos ) const
1333cdf0e10cSrcweir     {
1334cdf0e10cSrcweir         return m_pImpl->GetItemScreenRect( i_nItemPos );
1335cdf0e10cSrcweir     }
1336cdf0e10cSrcweir 
1337cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
GetComponentInterface(sal_Bool i_bCreate)1338cdf0e10cSrcweir     Reference< XWindowPeer > PanelTabBar::GetComponentInterface( sal_Bool i_bCreate )
1339cdf0e10cSrcweir     {
1340cdf0e10cSrcweir         Reference< XWindowPeer > xWindowPeer( Control::GetComponentInterface( sal_False ) );
1341cdf0e10cSrcweir         if ( !xWindowPeer.is() && i_bCreate )
1342cdf0e10cSrcweir         {
1343cdf0e10cSrcweir             xWindowPeer.set( new PanelTabBarPeer( *this ) );
1344cdf0e10cSrcweir             SetComponentInterface( xWindowPeer );
1345cdf0e10cSrcweir         }
1346cdf0e10cSrcweir         return xWindowPeer;
1347cdf0e10cSrcweir     }
1348cdf0e10cSrcweir 
1349cdf0e10cSrcweir //........................................................................
1350cdf0e10cSrcweir } // namespace svt
1351cdf0e10cSrcweir //........................................................................
1352