summaryrefslogtreecommitdiff
path: root/svtools
diff options
context:
space:
mode:
Diffstat (limited to 'svtools')
-rw-r--r--svtools/inc/svtools/toolpanel/decklayouter.hxx17
-rw-r--r--svtools/inc/svtools/toolpanel/tablayouter.hxx24
-rw-r--r--svtools/inc/svtools/toolpanel/toolpanel.hxx13
-rw-r--r--svtools/inc/svtools/toolpanel/toolpanelcontainer.hxx85
-rw-r--r--svtools/inc/svtools/toolpanel/toolpaneldeck.hxx27
-rw-r--r--svtools/source/toolpanel/dummypanel.cxx15
-rw-r--r--svtools/source/toolpanel/dummypanel.hxx8
-rw-r--r--svtools/source/toolpanel/makefile.mk5
-rw-r--r--svtools/source/toolpanel/paneltabbar.cxx595
-rw-r--r--svtools/source/toolpanel/paneltabbar.hxx75
-rw-r--r--svtools/source/toolpanel/refbase.cxx56
-rw-r--r--svtools/source/toolpanel/refbase.hxx78
-rw-r--r--svtools/source/toolpanel/tablayouter.cxx77
-rw-r--r--svtools/source/toolpanel/toolpanelcollection.cxx43
-rw-r--r--svtools/source/toolpanel/toolpanelcollection.hxx (renamed from svtools/inc/svtools/toolpanel/toolpanelcollection.hxx)19
-rw-r--r--svtools/source/toolpanel/toolpaneldeck.cxx86
-rw-r--r--svtools/workben/toolpanel/toolpaneltest.cxx59
17 files changed, 1216 insertions, 66 deletions
diff --git a/svtools/inc/svtools/toolpanel/decklayouter.hxx b/svtools/inc/svtools/toolpanel/decklayouter.hxx
index b6e27162a29c..6ee858e482c6 100644
--- a/svtools/inc/svtools/toolpanel/decklayouter.hxx
+++ b/svtools/inc/svtools/toolpanel/decklayouter.hxx
@@ -27,7 +27,7 @@
#ifndef DECKLAYOUTER_HXX
#define DECKLAYOUTER_HXX
-#include <boost/shared_ptr.hpp>
+#include <rtl/ref.hxx>
class Rectangle;
@@ -39,7 +39,7 @@ namespace svt
//====================================================================
//= IDeckLayouter
//====================================================================
- class IDeckLayouter
+ class IDeckLayouter : public ::rtl::IReference
{
public:
/** re-arranges the elements of the tool deck, taking into account the
@@ -48,16 +48,25 @@ namespace svt
@param i_rDeckPlayground
the playground for the complete tool panel deck
@return
- the content area for the single tool panels
+ the content area for a single tool panel
*/
virtual Rectangle Layout( const Rectangle& i_rDeckPlayground ) = 0;
+ /** destroys the instance
+
+ Since the layouter is ref-counted, but might keep references to non-ref-counted objects
+ (in particular, the ToolPanelDeck, which is a VCL-Window, and thus cannot be ref-counted),
+ Destroy is the definitive way to dispose the instance. Technically, it's still alive afterwards,
+ but non-functioal.
+ */
+ virtual void Destroy() = 0;
+
virtual ~IDeckLayouter()
{
}
};
- typedef ::boost::shared_ptr< IDeckLayouter > PDeckLayouter;
+ typedef ::rtl::Reference< IDeckLayouter > PDeckLayouter;
//........................................................................
} // namespace svt
diff --git a/svtools/inc/svtools/toolpanel/tablayouter.hxx b/svtools/inc/svtools/toolpanel/tablayouter.hxx
index ff66fe367e3b..e2d46ff8b42d 100644
--- a/svtools/inc/svtools/toolpanel/tablayouter.hxx
+++ b/svtools/inc/svtools/toolpanel/tablayouter.hxx
@@ -28,6 +28,8 @@
#define TABLAYOUTER_HXX
#include "svtools/toolpanel/decklayouter.hxx"
+#include "svtools/toolpanel/toolpanelcontainer.hxx"
+#include "refbase.hxx"
#include <memory>
@@ -36,9 +38,12 @@ namespace svt
{
//........................................................................
+ class ToolPanelDeck;
+
enum TabAlignment
{
- TABS_RIGHT
+ TABS_RIGHT,
+ TABS_LEFT
};
struct TabDeckLayouter_Data;
@@ -46,14 +51,27 @@ namespace svt
//====================================================================
//= TabDeckLayouter
//====================================================================
- class TabDeckLayouter : public IDeckLayouter
+ class TabDeckLayouter :public RefBase
+ ,public IDeckLayouter
{
public:
- TabDeckLayouter( const TabAlignment i_eAlignment );
+ /** creates a new layouter
+ @param i_eAlignment
+ specifies the alignment of the panel selector
+ @param i_rPanelDeck
+ the panel deck which the layouter is responsible for. Provides access to the panels
+ container, and can and should be used as parent for any other windows which the layouter
+ needs to create.
+ */
+ TabDeckLayouter( const TabAlignment i_eAlignment, ToolPanelDeck& i_rPanelDeck );
~TabDeckLayouter();
// IDeckLayouter
virtual Rectangle Layout( const Rectangle& i_rDeckPlayground );
+ virtual void Destroy();
+
+ // IReference
+ DECLARE_IREFERENCE()
private:
::std::auto_ptr< TabDeckLayouter_Data > m_pData;
diff --git a/svtools/inc/svtools/toolpanel/toolpanel.hxx b/svtools/inc/svtools/toolpanel/toolpanel.hxx
index 4b7227f52cbd..24a166be362d 100644
--- a/svtools/inc/svtools/toolpanel/toolpanel.hxx
+++ b/svtools/inc/svtools/toolpanel/toolpanel.hxx
@@ -27,7 +27,10 @@
#ifndef TOOLPANEL_HXX
#define TOOLPANEL_HXX
-#include <boost/shared_ptr.hpp>
+#include <rtl/ustring.hxx>
+#include <vcl/image.hxx>
+
+#include <rtl/ref.hxx>
class Rectangle;
@@ -41,7 +44,7 @@ namespace svt
//====================================================================
/** abstract interface for a single tool panel
*/
- class IToolPanel
+ class IToolPanel : public ::rtl::IReference
{
public:
/// shows the panel
@@ -50,13 +53,17 @@ namespace svt
virtual void Hide() = 0;
/// sets the position of the panel
virtual void SetPosSizePixel( const Rectangle& i_rPanelPlayground ) = 0;
+ /// retrieves the display name of the panel
+ virtual ::rtl::OUString GetDisplayName() const = 0;
+ /// retrieves the image associated with the panel, if any
+ virtual Image GetImage() const = 0;
virtual ~IToolPanel()
{
}
};
- typedef ::boost::shared_ptr< IToolPanel > PToolPanel;
+ typedef ::rtl::Reference< IToolPanel > PToolPanel;
//........................................................................
} // namespace svt
diff --git a/svtools/inc/svtools/toolpanel/toolpanelcontainer.hxx b/svtools/inc/svtools/toolpanel/toolpanelcontainer.hxx
new file mode 100644
index 000000000000..c57e80e614d7
--- /dev/null
+++ b/svtools/inc/svtools/toolpanel/toolpanelcontainer.hxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+#ifndef TOOLPANELCONTAINER_HXX
+#define TOOLPANELCONTAINER_HXX
+
+#include "svtools/toolpanel/toolpanel.hxx"
+
+#include <rtl/ref.hxx>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ //====================================================================
+ //= IToolPanelContainerListener
+ //====================================================================
+ class SAL_NO_VTABLE IToolPanelContainerListener
+ {
+ public:
+ virtual void PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition ) = 0;
+ };
+
+ //====================================================================
+ //= IToolPanelContainer
+ //====================================================================
+ class IToolPanelContainer : public ::rtl::IReference
+ {
+ public:
+ /** returns the number of panels in the container
+ */
+ virtual size_t GetPanelCount() const = 0;
+
+ /** retrieves the panel with the given index. Invalid indexes will be reported via an assertion in the
+ non-product version, and silently ignored in the product version, with a NULL panel being returned.
+ */
+ virtual PToolPanel GetPanel( const size_t i_nPos ) const = 0;
+
+ /** inserts a new panel into the container. NULL panels are not allowed, as are positions greater than the
+ current panel count. Violations of this will be reported via an assertion in the non-product version, and
+ silently ignored in the product version.
+ */
+ virtual size_t InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition ) = 0;
+
+ /** adds a new listener to be notified when the container content changes. The caller is responsible
+ for life time control, i.e. removing the listener before it actually dies.
+ */
+ virtual void AddListener( IToolPanelContainerListener& i_rListener ) = 0;
+
+ /** removes a container listener previously added via addListener.
+ */
+ virtual void RemoveListener( IToolPanelContainerListener& i_rListener ) = 0;
+ };
+
+ typedef ::rtl::Reference< IToolPanelContainer > PToolPanelContainer;
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
+#endif // TOOLPANELCONTAINER_HXX
diff --git a/svtools/inc/svtools/toolpanel/toolpaneldeck.hxx b/svtools/inc/svtools/toolpanel/toolpaneldeck.hxx
index 2efde1f29e8b..42045c36b71a 100644
--- a/svtools/inc/svtools/toolpanel/toolpaneldeck.hxx
+++ b/svtools/inc/svtools/toolpanel/toolpaneldeck.hxx
@@ -28,10 +28,11 @@
#define TOOLPANELDECK_HXX
#include "svtools/toolpanel/decklayouter.hxx"
-#include "svtools/toolpanel/toolpanelcollection.hxx"
+#include "svtools/toolpanel/toolpanelcontainer.hxx"
#include <vcl/ctrl.hxx>
+#include <boost/optional.hpp>
#include <memory>
//........................................................................
@@ -43,6 +44,15 @@ namespace svt
class ToolPanelDeck_Impl;
//====================================================================
+ //= IToolPanelDeckListener
+ //====================================================================
+ class SAL_NO_VTABLE IToolPanelDeckListener
+ {
+ public:
+ virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const size_t i_nNewActive ) = 0;
+ };
+
+ //====================================================================
//= ToolPanelDeck
//====================================================================
class ToolPanelDeck : public Control
@@ -52,14 +62,17 @@ namespace svt
~ToolPanelDeck();
// attributes
- PDeckLayouter GetLayouter() const;
- void SetLayouter( const PDeckLayouter& i_pNewLayouter );
+ PDeckLayouter GetLayouter() const;
+ void SetLayouter( const PDeckLayouter& i_pNewLayouter );
+
+ PToolPanelContainer GetPanels() const;
- size_t GetActivePanel() const;
- void ActivatePanel( const size_t i_nPanel );
+ size_t GetActivePanel() const;
+ void ActivatePanel( const size_t i_nPanel );
- const ToolPanelCollection& GetPanels() const;
- ToolPanelCollection& GetPanels();
+ // listeners
+ void AddListener( IToolPanelDeckListener& i_rListener );
+ void RemoveListener( IToolPanelDeckListener& i_rListener );
protected:
// Window overridables
diff --git a/svtools/source/toolpanel/dummypanel.cxx b/svtools/source/toolpanel/dummypanel.cxx
index 52c89be24b99..405f103d9713 100644
--- a/svtools/source/toolpanel/dummypanel.cxx
+++ b/svtools/source/toolpanel/dummypanel.cxx
@@ -47,6 +47,9 @@ namespace svt
}
//--------------------------------------------------------------------
+ IMPLEMENT_IREFERENCE( DummyPanel )
+
+ //--------------------------------------------------------------------
void DummyPanel::Show()
{
}
@@ -61,6 +64,18 @@ namespace svt
{
}
+ //--------------------------------------------------------------------
+ ::rtl::OUString DummyPanel::GetDisplayName() const
+ {
+ return ::rtl::OUString();
+ }
+
+ //--------------------------------------------------------------------
+ Image DummyPanel::GetImage() const
+ {
+ return Image();
+ }
+
//........................................................................
} // namespace svt
//........................................................................
diff --git a/svtools/source/toolpanel/dummypanel.hxx b/svtools/source/toolpanel/dummypanel.hxx
index 425467641077..46b1218abe93 100644
--- a/svtools/source/toolpanel/dummypanel.hxx
+++ b/svtools/source/toolpanel/dummypanel.hxx
@@ -28,6 +28,7 @@
#define DUMMYPANEL_HXX
#include "svtools/toolpanel/toolpanel.hxx"
+#include "refbase.hxx"
//........................................................................
namespace svt
@@ -38,7 +39,8 @@ namespace svt
//= DummyPanel
//====================================================================
/// is a dummy implementation of the IToolPanel interface
- class DummyPanel : public IToolPanel
+ class DummyPanel :public RefBase
+ ,public IToolPanel
{
public:
DummyPanel();
@@ -48,6 +50,10 @@ namespace svt
virtual void Show();
virtual void Hide();
virtual void SetPosSizePixel( const Rectangle& i_rPanelPlayground );
+ virtual ::rtl::OUString GetDisplayName() const;
+ virtual Image GetImage() const;
+
+ DECLARE_IREFERENCE()
};
//........................................................................
diff --git a/svtools/source/toolpanel/makefile.mk b/svtools/source/toolpanel/makefile.mk
index 23a3186bdcef..576db7c84ee5 100644
--- a/svtools/source/toolpanel/makefile.mk
+++ b/svtools/source/toolpanel/makefile.mk
@@ -45,13 +45,12 @@ ENABLE_EXCEPTIONS=TRUE
SLOFILES=\
$(SLO)$/dummypanel.obj \
+ $(SLO)$/paneltabbar.obj \
+ $(SLO)$/refbase.obj \
$(SLO)$/tablayouter.obj \
$(SLO)$/toolpanelcollection.obj \
$(SLO)$/toolpaneldeck.obj \
-#LIB1TARGET= $(SLB)$/$(TARGET).lib
-#LIB1OBJFILES= $(SLOFILES)
-
# --- Targets ------------------------------------------------------
.INCLUDE : target.mk
diff --git a/svtools/source/toolpanel/paneltabbar.cxx b/svtools/source/toolpanel/paneltabbar.cxx
new file mode 100644
index 000000000000..0229ce664560
--- /dev/null
+++ b/svtools/source/toolpanel/paneltabbar.cxx
@@ -0,0 +1,595 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include "svtools/toolpanel/toolpaneldeck.hxx"
+#include "paneltabbar.hxx"
+
+#include <vcl/help.hxx>
+
+#include <boost/optional.hpp>
+#include <vector>
+
+// space around an item
+#define ITEM_OUTER_SPACE 2 * 3
+// distance between two items
+#define ITEM_DISTANCE_PIXEL 2
+// space between item icon and icon text
+#define ITEM_ICON_TEXT_DISTANCE 4
+// outer space (aka margin) of the complete tab bar control
+#define TAB_BAR_OUTER_SPACE 2
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ typedef sal_uInt16 ItemFlags;
+
+ #define ITEM_STATE_NORMAL 0x00
+ #define ITEM_STATE_ACTIVE 0x01
+ #define ITEM_STATE_HOVERED 0x02
+
+ //==================================================================================================================
+ //= IItemsLayout
+ //==================================================================================================================
+ class IItemsLayout
+ {
+ public:
+ /** calculates the size of the area occupied by the item representing the given tool panel
+ */
+ virtual Size CalculateItemSize( const PToolPanel& i_pPanel, const OutputDevice& i_rReferenceDevice, const bool i_bMinimum ) const = 0;
+
+ /** returns the position where the next item should start, assuming the previous item occupies a given area
+ */
+ virtual Point GetNextItemPosition( const Rectangle& i_rPreviousItemArea ) const = 0;
+
+ /** draws the item onto the given device, in the givem area
+ @param i_pPanel
+ the panel whose item representation is to be drawn
+ @param i_rTargetWindow
+ the window onto which to drawa
+ @param i_rItemRect
+ the area to paint the item into. The caller is responsible for ensuring that is has a size sufficient to
+ hold the item (which can be determined by calling CalculateItemSize beforehand).
+ @param i_nItemFlags
+ defines in which state to draw the item
+ @param i_bDrawMinimal
+ defines whether the minimal version of the item should be drawn
+ */
+ virtual void DrawItem( const PToolPanel& i_pPanel, Window& i_rTargetWindow, const Rectangle& i_rItemRect,
+ const ItemFlags i_nItemFlags, const bool i_bDrawMinimal ) = 0;
+ };
+
+ typedef ::boost::shared_ptr< IItemsLayout > PItemsLayout;
+
+ //==================================================================================================================
+ //= VerticalItemLayout
+ //==================================================================================================================
+ class VerticalItemLayout : public IItemsLayout
+ {
+ public:
+ VerticalItemLayout()
+ {
+ }
+
+ // IItemsLayout overridables
+ virtual Size CalculateItemSize( const PToolPanel& i_pPanel, const OutputDevice& i_rReferenceDevice, const bool i_bMinimum ) const;
+ virtual Point GetNextItemPosition( const Rectangle& i_rPreviousItemArea ) const;
+ virtual void DrawItem( const PToolPanel& i_pPanel, Window& i_rTargetWindow, const Rectangle& i_rItemRect,
+ const ItemFlags i_nItemFlags, const bool i_bDrawMinimal );
+ };
+
+ //------------------------------------------------------------------------------------------------------------------
+ Size VerticalItemLayout::CalculateItemSize( const PToolPanel& i_pPanel, const OutputDevice& i_rReferenceDevice, const bool i_bMinimum ) const
+ {
+ const Image aImage( i_pPanel->GetImage() );
+ const ::rtl::OUString sItemText( i_pPanel->GetDisplayName() );
+
+ // for the moment, we display the icons only
+ Size aItemSize;
+ if ( !!aImage )
+ {
+ aItemSize = aImage.GetSizePixel();
+ }
+
+ if ( !i_bMinimum && sItemText.getLength() )
+ {
+ if ( !!aImage )
+ aItemSize.Height() += ITEM_ICON_TEXT_DISTANCE;
+
+ // add space for vertical text
+ const Size aTextSize( i_rReferenceDevice.GetCtrlTextWidth( sItemText ), i_rReferenceDevice.GetTextHeight() );
+ aItemSize.Height() += aTextSize.Width();
+ aItemSize.Width() = ::std::max( aItemSize.Width(), aTextSize.Height() );
+ }
+
+ aItemSize.Width() += 2 * ITEM_OUTER_SPACE;
+ aItemSize.Height() += 2 * ITEM_OUTER_SPACE;
+
+ return aItemSize;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Point VerticalItemLayout::GetNextItemPosition( const Rectangle& i_rPreviousItemArea ) const
+ {
+ Point aNewPos( i_rPreviousItemArea.BottomLeft() );
+ aNewPos.Y() += ITEM_DISTANCE_PIXEL;
+ return aNewPos;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void VerticalItemLayout::DrawItem( const PToolPanel& i_pPanel, Window& i_rTargetWindow, const Rectangle& i_rItemRect,
+ const ItemFlags i_nItemFlags, const bool i_bDrawMinimal )
+ {
+ const Size aItemSize( CalculateItemSize( i_pPanel, i_rTargetWindow, i_bDrawMinimal ) );
+
+ Point aDrawPos( i_rItemRect.TopLeft() );
+ aDrawPos.Y() += ITEM_OUTER_SPACE;
+
+ // draw the image
+ const Image aItemImage( i_pPanel->GetImage() );
+ if ( !!aItemImage )
+ {
+ const Size aImageSize( aItemImage.GetSizePixel() );
+ i_rTargetWindow.DrawImage(
+ Point( aDrawPos.X() + ( aItemSize.Width() - aImageSize.Width() ) / 2, aDrawPos.Y() ),
+ aItemImage
+ );
+ aDrawPos.Y() += aImageSize.Height() + ITEM_ICON_TEXT_DISTANCE;
+ }
+
+ if ( !i_bDrawMinimal )
+ {
+ // draw the text
+ i_rTargetWindow.Push( PUSH_FONT );
+
+ Font aFont( i_rTargetWindow.GetFont() );
+ aFont.SetOrientation( 2700 );
+ aFont.SetVertical( TRUE );
+ i_rTargetWindow.SetFont( aFont );
+
+ const ::rtl::OUString sItemText( i_pPanel->GetDisplayName() );
+ const Size aTextSize( i_rTargetWindow.GetCtrlTextWidth( sItemText ), i_rTargetWindow.GetTextHeight() );
+
+ Point aTextPos( aDrawPos );
+ aTextPos.X() += aTextSize.Height();
+ aTextPos.X() += ( i_rItemRect.GetWidth() - aTextSize.Height() ) / 2;
+
+ i_rTargetWindow.DrawText( aTextPos, sItemText );
+
+ i_rTargetWindow.Pop();
+ }
+
+ const bool bActive = ( ( i_nItemFlags & ITEM_STATE_ACTIVE ) != 0 );
+ const bool bHovered = ( ( i_nItemFlags & ITEM_STATE_HOVERED ) != 0 );
+ if ( bActive || bHovered )
+ {
+ Rectangle aSelectionRect( i_rItemRect );
+ aSelectionRect.Left() += ITEM_OUTER_SPACE / 2;
+ aSelectionRect.Top() += ITEM_OUTER_SPACE / 2;
+ aSelectionRect.Right() -= ITEM_OUTER_SPACE / 2;
+ aSelectionRect.Bottom() -= ITEM_OUTER_SPACE / 2;
+ i_rTargetWindow.DrawSelectionBackground(
+ aSelectionRect,
+ bHovered ? ( bActive ? 1 : 2 ) : 0 /* hilight */,
+ FALSE /* check */,
+ TRUE /* border */,
+ FALSE /* ext border only */,
+ 0 /* corner radius */,
+ NULL,
+ NULL
+ );
+ }
+ }
+
+ //==================================================================================================================
+ //= ItemDescriptor
+ //==================================================================================================================
+ struct ItemDescriptor
+ {
+ PToolPanel pPanel;
+ Rectangle aMinArea;
+ Rectangle aPrefArea;
+ bool bUseMinimal;
+
+ ItemDescriptor()
+ :pPanel()
+ ,aMinArea()
+ ,aPrefArea()
+ ,bUseMinimal( false )
+ {
+ }
+
+ const Rectangle& GetCurrentRect() const
+ {
+ return bUseMinimal ? aMinArea : aPrefArea;
+ }
+ };
+
+ typedef ::std::vector< ItemDescriptor > ItemDescriptors;
+
+ //==================================================================================================================
+ //= PanelTabBar_Data
+ //==================================================================================================================
+ class PanelTabBar_Data :public IToolPanelContainerListener
+ ,public IToolPanelDeckListener
+ {
+ public:
+ PanelTabBar_Data( PanelTabBar& i_rTabBar )
+ :rTabBar( i_rTabBar )
+ ,rPanelDeck( dynamic_cast< ToolPanelDeck& >( *i_rTabBar.GetParent() ) )
+ ,pLayout( new VerticalItemLayout )
+ ,aHoveredItem()
+ ,bMouseButtonDown( false )
+ ,aItems()
+ ,bItemsDirty( true )
+ {
+ rPanelDeck.AddListener( *this );
+ rPanelDeck.GetPanels()->AddListener( *this );
+ }
+
+ ~PanelTabBar_Data()
+ {
+ rPanelDeck.GetPanels()->RemoveListener( *this );
+ rPanelDeck.RemoveListener( *this );
+ }
+
+ // IToolPanelContainerListener
+ virtual void PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition )
+ {
+ bItemsDirty = true;
+ }
+
+ // IToolPanelDeckListener
+ virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const size_t i_nNewActive );
+
+ public:
+ PanelTabBar& rTabBar;
+ ToolPanelDeck& rPanelDeck;
+ const PItemsLayout pLayout;
+ ::boost::optional< size_t > aHoveredItem;
+ bool bMouseButtonDown;
+
+ ItemDescriptors aItems;
+ bool bItemsDirty;
+ };
+
+ //==================================================================================================================
+ //= helper
+ //==================================================================================================================
+ namespace
+ {
+ //--------------------------------------------------------------------------------------------------------------
+ #if OSL_DEBUG_LEVEL > 0
+ static void lcl_checkConsistency( const PanelTabBar_Data& i_rData )
+ {
+ if ( !i_rData.rPanelDeck.GetPanels().get() )
+ {
+ OSL_ENSURE( false, "lcl_checkConsistency: NULL panels?!" );
+ return;
+ }
+ if ( !i_rData.bItemsDirty )
+ {
+ if ( i_rData.rPanelDeck.GetPanels()->GetPanelCount() != i_rData.aItems.size() )
+ {
+ OSL_ENSURE( false, "lcl_checkConsistency: inconsistent array sizes!" );
+ return;
+ }
+ for ( size_t i = 0; i < i_rData.rPanelDeck.GetPanels()->GetPanelCount(); ++i )
+ {
+ if ( i_rData.rPanelDeck.GetPanels()->GetPanel( i ).get() != i_rData.aItems[i].pPanel.get() )
+ {
+ OSL_ENSURE( false, "lcl_checkConsistency: array elements are inconsistent!" );
+ return;
+ }
+ }
+ }
+ }
+
+ #define DBG_CHECK( data ) \
+ lcl_checkConsistency( data );
+ #else
+ #define DBG_CHECK( data ) \
+ (void)data;
+ #endif
+
+ //--------------------------------------------------------------------------------------------------------------
+ static void lcl_calcItemRects( PanelTabBar_Data& io_rData, const OutputDevice& i_rReferenceDevice )
+ {
+ io_rData.aItems.resize(0);
+
+ Point aMinItemPos( TAB_BAR_OUTER_SPACE, TAB_BAR_OUTER_SPACE );
+ Point aPrefItemPos( TAB_BAR_OUTER_SPACE, TAB_BAR_OUTER_SPACE );
+
+ for ( size_t i = 0;
+ i < io_rData.rPanelDeck.GetPanels()->GetPanelCount();
+ ++i
+ )
+ {
+ PToolPanel pPanel( io_rData.rPanelDeck.GetPanels()->GetPanel( i ) );
+
+ ItemDescriptor aItem;
+ aItem.pPanel = pPanel;
+
+ const Size aMinItemSize = io_rData.pLayout->CalculateItemSize( pPanel, i_rReferenceDevice, true );
+ const Size aPrefItemSize = io_rData.pLayout->CalculateItemSize( pPanel, i_rReferenceDevice, false );
+ // TODO: have one method calculating both sizes
+
+ aItem.aMinArea = Rectangle( aMinItemPos, aMinItemSize );
+ aItem.aPrefArea = Rectangle( aPrefItemPos, aPrefItemSize );
+
+ io_rData.aItems.push_back( aItem );
+
+ aMinItemPos = io_rData.pLayout->GetNextItemPosition( aItem.aMinArea );
+ aPrefItemPos = io_rData.pLayout->GetNextItemPosition( aItem.aPrefArea );
+ }
+
+ io_rData.bItemsDirty = false;
+ }
+
+ //--------------------------------------------------------------------------------------------------------------
+ static void lcl_ensureItemsCache( PanelTabBar_Data& io_rData, const OutputDevice& i_rReferenceDevice )
+ {
+ if ( io_rData.bItemsDirty == false )
+ {
+ DBG_CHECK( io_rData );
+ return;
+ }
+ lcl_calcItemRects( io_rData, i_rReferenceDevice );
+ OSL_POSTCOND( io_rData.bItemsDirty == false, "lcl_ensureItemsCache: cache still dirty!" );
+ DBG_CHECK( io_rData );
+ }
+
+ //--------------------------------------------------------------------------------------------------------------
+ static ::boost::optional< size_t > lcl_findItemForPoint( const PanelTabBar_Data& i_rData, const Point& i_rPoint )
+ {
+ size_t i=0;
+ for ( ItemDescriptors::const_iterator item = i_rData.aItems.begin();
+ item != i_rData.aItems.end();
+ ++item, ++i
+ )
+ {
+ const Rectangle& rItemRect( item->GetCurrentRect() );
+ if ( rItemRect.IsInside( i_rPoint ) )
+ {
+ return ::boost::optional< size_t >( i );
+ }
+ }
+ return ::boost::optional< size_t >();
+ }
+
+ //--------------------------------------------------------------------------------------------------------------
+ static void lcl_drawItem( const PanelTabBar_Data& i_rData, const size_t i_nItemIndex )
+ {
+ const ItemDescriptor& rItem( i_rData.aItems[ i_nItemIndex ] );
+
+ ItemFlags nItemFlags( ITEM_STATE_NORMAL );
+ if ( i_rData.aHoveredItem == i_nItemIndex )
+ {
+ nItemFlags |= ITEM_STATE_HOVERED;
+ if ( i_rData.bMouseButtonDown )
+ nItemFlags |= ITEM_STATE_ACTIVE;
+ }
+
+ if ( i_rData.rPanelDeck.GetActivePanel() == i_nItemIndex )
+ nItemFlags |= ITEM_STATE_ACTIVE;
+
+ i_rData.rTabBar.DrawRect( rItem.GetCurrentRect() );
+ i_rData.pLayout->DrawItem( rItem.pPanel, i_rData.rTabBar, rItem.GetCurrentRect(), nItemFlags, rItem.bUseMinimal );
+ }
+
+ //--------------------------------------------------------------------------------------------------------------
+ static void lcl_drawItems( const PanelTabBar_Data& i_rData, PanelTabBar& i_rTabBar, const Rectangle& i_rTargetArea )
+ {
+ size_t i=0;
+ for ( ItemDescriptors::const_iterator item = i_rData.aItems.begin();
+ item != i_rData.aItems.end();
+ ++item, ++i
+ )
+ {
+ const Rectangle& rItemRect( item->GetCurrentRect() );
+ if ( rItemRect.IsOver( i_rTargetArea ) )
+ {
+ lcl_drawItem( i_rData, i );
+ }
+ }
+ }
+ }
+
+ //==================================================================================================================
+ //= PanelTabBar_Data
+ //==================================================================================================================
+ void PanelTabBar_Data::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const size_t i_nNewActive )
+ {
+ lcl_ensureItemsCache( *this, rTabBar );
+
+ if ( !!i_rOldActive )
+ lcl_drawItem( *this, *i_rOldActive );
+ lcl_drawItem( *this, i_nNewActive );
+ }
+
+ //==================================================================================================================
+ //= PanelTabBar
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ PanelTabBar::PanelTabBar( ToolPanelDeck& i_rPanelDeck )
+ :Control( &i_rPanelDeck, 0 )
+ ,m_pData( new PanelTabBar_Data( *this ) )
+ {
+ DBG_CHECK( *m_pData );
+
+ SetLineColor();
+ SetFillColor( GetSettings().GetStyleSettings().GetDialogColor() );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ PanelTabBar::~PanelTabBar()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Size PanelTabBar::GetOptimalSize( WindowSizeType i_eType ) const
+ {
+ lcl_ensureItemsCache( *m_pData, *this );
+
+ if ( m_pData->aItems.empty() )
+ return Size( 2 * TAB_BAR_OUTER_SPACE, 2 * TAB_BAR_OUTER_SPACE );
+
+ const bool nMinimalSize = ( i_eType == WINDOWSIZE_MINIMUM );
+ // the rect of the last item
+ const Rectangle& rLastItemRect( nMinimalSize ? m_pData->aItems.rbegin()->aMinArea : m_pData->aItems.rbegin()->aPrefArea );
+ const Point aBottomRight( rLastItemRect.BottomRight() );
+ return Size( aBottomRight.X() + TAB_BAR_OUTER_SPACE, aBottomRight.Y() + TAB_BAR_OUTER_SPACE );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::Resize()
+ {
+ Control::Resize();
+
+ // decide whether we should use the minimal or the prefered version of the items
+ const Size aPreferredSize( GetOptimalSize( WINDOWSIZE_PREFERRED ) );
+ const Size aOutputSize( GetOutputSizePixel() );
+ const bool bDrawMinimal( aPreferredSize.Height() >= aOutputSize.Height() );
+
+ for ( ItemDescriptors::iterator item = m_pData->aItems.begin();
+ item != m_pData->aItems.end();
+ ++item
+ )
+ {
+ item->bUseMinimal = bDrawMinimal;
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::Paint( const Rectangle& i_rRect )
+ {
+ lcl_ensureItemsCache( *m_pData, *this );
+
+ // background
+ DrawRect( Rectangle( Point(), GetOutputSizePixel() ) );
+
+ // items
+ lcl_drawItems( *m_pData, *this, i_rRect );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::MouseMove( const MouseEvent& i_rMouseEvent )
+ {
+ lcl_ensureItemsCache( *m_pData, *this );
+
+ ::boost::optional< size_t > aOldItem( m_pData->aHoveredItem );
+ ::boost::optional< size_t > aNewItem( lcl_findItemForPoint( *m_pData, i_rMouseEvent.GetPosPixel() ) );
+
+ if ( i_rMouseEvent.IsLeaveWindow() )
+ aNewItem.reset();
+
+ if ( aOldItem != aNewItem )
+ {
+ m_pData->aHoveredItem = aNewItem;
+
+ if ( !!aOldItem )
+ {
+ lcl_drawItem( *m_pData, *aOldItem );
+ }
+
+ if ( !!aNewItem )
+ {
+ lcl_drawItem( *m_pData, *aNewItem );
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::MouseButtonDown( const MouseEvent& i_rMouseEvent )
+ {
+ Control::MouseButtonDown( i_rMouseEvent );
+
+ if ( !i_rMouseEvent.IsLeft() )
+ return;
+
+ lcl_ensureItemsCache( *m_pData, *this );
+
+ ::boost::optional< size_t > aHitItem( lcl_findItemForPoint( *m_pData, i_rMouseEvent.GetPosPixel() ) );
+ if ( !aHitItem )
+ return;
+
+ CaptureMouse();
+ m_pData->bMouseButtonDown = true;
+
+ lcl_drawItem( *m_pData, *aHitItem );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::MouseButtonUp( const MouseEvent& i_rMouseEvent )
+ {
+ Control::MouseButtonUp( i_rMouseEvent );
+
+ if ( m_pData->bMouseButtonDown )
+ {
+ OSL_ENSURE( IsMouseCaptured(), "PanelTabBar::MouseButtonUp: inconsistency!" );
+ if ( IsMouseCaptured() )
+ ReleaseMouse();
+ m_pData->bMouseButtonDown = false;
+
+ ::boost::optional< size_t > aHitItem( lcl_findItemForPoint( *m_pData, i_rMouseEvent.GetPosPixel() ) );
+ if ( !!aHitItem )
+ {
+ // re-draw that item now that we're not in mouse-down mode anymore
+ lcl_drawItem( *m_pData, *aHitItem );
+ // activate the respective panel
+ m_pData->rPanelDeck.ActivatePanel( *aHitItem );
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void PanelTabBar::RequestHelp( const HelpEvent& i_rHelpEvent )
+ {
+ lcl_ensureItemsCache( *m_pData, *this );
+
+ ::boost::optional< size_t > aHelpItem( lcl_findItemForPoint( *m_pData, ScreenToOutputPixel( i_rHelpEvent.GetMousePosPixel() ) ) );
+ if ( !aHelpItem )
+ return;
+
+ const ItemDescriptor& rItem( m_pData->aItems[ *aHelpItem ] );
+ if ( !rItem.bUseMinimal )
+ // if we do not use the minimal representation of the item, then the text is completely drawn - no
+ // need to show it as tooltip, too
+ return;
+
+ const ::rtl::OUString sItemText( rItem.pPanel->GetDisplayName() );
+ if ( i_rHelpEvent.GetMode() == HELPMODE_BALLOON )
+ Help::ShowBalloon( this, OutputToScreenPixel( rItem.GetCurrentRect().Center() ), rItem.GetCurrentRect(), sItemText );
+ else
+ Help::ShowQuickHelp( this, rItem.GetCurrentRect(), sItemText );
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
diff --git a/svtools/source/toolpanel/paneltabbar.hxx b/svtools/source/toolpanel/paneltabbar.hxx
new file mode 100644
index 000000000000..abbc82173c57
--- /dev/null
+++ b/svtools/source/toolpanel/paneltabbar.hxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+#ifndef PANELTABBAR_HXX
+#define PANELTABBAR_HXX
+
+#include "svtools/toolpanel/toolpanelcontainer.hxx"
+
+#include <vcl/ctrl.hxx>
+
+#include <memory>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ class ToolPanelDeck;
+ class PanelTabBar_Data;
+
+ //====================================================================
+ //= PanelTabBar
+ //====================================================================
+ /** a tab bar for selecting panels
+
+ At the moment, this control aligns the tabs vertically, this might be extended to also support a horizontal
+ layout in the future.
+ */
+ class PanelTabBar : public Control
+ {
+ public:
+ PanelTabBar( ToolPanelDeck& i_rParent );
+ ~PanelTabBar();
+
+ // Window overridables
+ virtual Size GetOptimalSize( WindowSizeType i_eType ) const;
+ virtual void Paint( const Rectangle& i_rRect );
+ virtual void Resize();
+ virtual void MouseMove( const MouseEvent& i_rMouseEvent );
+ virtual void MouseButtonDown( const MouseEvent& i_rMouseEvent );
+ virtual void MouseButtonUp( const MouseEvent& i_rMouseEvent );
+ virtual void RequestHelp( const HelpEvent& i_rHelpEvent );
+
+ private:
+ ::std::auto_ptr< PanelTabBar_Data > m_pData;
+ };
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
+#endif // PANELTABBAR_HXX
+
diff --git a/svtools/source/toolpanel/refbase.cxx b/svtools/source/toolpanel/refbase.cxx
new file mode 100644
index 000000000000..cd4433045b33
--- /dev/null
+++ b/svtools/source/toolpanel/refbase.cxx
@@ -0,0 +1,56 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+#include "precompiled_svtools.hxx"
+
+#include "refbase.hxx"
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ //====================================================================
+ //= RefBase
+ //====================================================================
+ //--------------------------------------------------------------------
+ oslInterlockedCount SAL_CALL RefBase::acquire()
+ {
+ return osl_incrementInterlockedCount( &m_refCount );
+ }
+
+ //--------------------------------------------------------------------
+ oslInterlockedCount SAL_CALL RefBase::release()
+ {
+ oslInterlockedCount newCount = osl_decrementInterlockedCount( &m_refCount );
+ if ( 0 == newCount )
+ delete this;
+ return newCount;
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
diff --git a/svtools/source/toolpanel/refbase.hxx b/svtools/source/toolpanel/refbase.hxx
new file mode 100644
index 000000000000..4cbcc41ffd2a
--- /dev/null
+++ b/svtools/source/toolpanel/refbase.hxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+#ifndef REFBASE_HXX
+#define REFBASE_HXX
+
+#include <osl/interlck.h>
+
+//........................................................................
+namespace svt
+{
+//........................................................................
+
+ //====================================================================
+ //= RefBase
+ //====================================================================
+ class RefBase
+ {
+ protected:
+ RefBase()
+ :m_refCount( 0 )
+ {
+ }
+
+ virtual ~RefBase()
+ {
+ }
+
+ virtual oslInterlockedCount SAL_CALL acquire();
+ virtual oslInterlockedCount SAL_CALL release();
+
+ private:
+ oslInterlockedCount m_refCount;
+ };
+
+#define DECLARE_IREFERENCE() \
+ virtual oslInterlockedCount SAL_CALL acquire(); \
+ virtual oslInterlockedCount SAL_CALL release();
+
+
+#define IMPLEMENT_IREFERENCE( classname ) \
+ oslInterlockedCount classname::acquire() \
+ { \
+ return RefBase::acquire(); \
+ } \
+ oslInterlockedCount classname::release() \
+ { \
+ return RefBase::release(); \
+ }
+
+//........................................................................
+} // namespace svt
+//........................................................................
+
+#endif // REFBASE_HXX
diff --git a/svtools/source/toolpanel/tablayouter.cxx b/svtools/source/toolpanel/tablayouter.cxx
index 3f6f57453356..7b237e8f09f6 100644
--- a/svtools/source/toolpanel/tablayouter.cxx
+++ b/svtools/source/toolpanel/tablayouter.cxx
@@ -27,6 +27,8 @@
#include "precompiled_svtools.hxx"
#include "svtools/toolpanel/tablayouter.hxx"
+#include "svtools/toolpanel/toolpaneldeck.hxx"
+#include "paneltabbar.hxx"
#include <tools/gen.hxx>
@@ -40,17 +42,39 @@ namespace svt
//====================================================================
struct TabDeckLayouter_Data
{
- TabAlignment eAlignment;
+ TabAlignment eAlignment;
+ PToolPanelContainer pPanels;
+ ::std::auto_ptr< PanelTabBar >
+ pTabBar;
+
+ TabDeckLayouter_Data( const TabAlignment i_eAlignment, ToolPanelDeck& i_rPanelDeck )
+ :eAlignment( i_eAlignment )
+ ,pPanels( i_rPanelDeck.GetPanels() )
+ ,pTabBar( new PanelTabBar( i_rPanelDeck ) )
+ {
+ pTabBar->Show();
+ }
};
//====================================================================
+ //= helper
+ //====================================================================
+ namespace
+ {
+ static bool lcl_isVerticalTabBar( const TabAlignment i_eAlignment )
+ {
+ return ( i_eAlignment == TABS_RIGHT )
+ || ( i_eAlignment == TABS_LEFT );
+ }
+ }
+
+ //====================================================================
//= TabDeckLayouter
//====================================================================
//--------------------------------------------------------------------
- TabDeckLayouter::TabDeckLayouter( const TabAlignment i_eAlignment )
- :m_pData( new TabDeckLayouter_Data )
+ TabDeckLayouter::TabDeckLayouter( const TabAlignment i_eAlignment, ToolPanelDeck& i_rPanelDeck )
+ :m_pData( new TabDeckLayouter_Data( i_eAlignment, i_rPanelDeck ) )
{
- m_pData->eAlignment = i_eAlignment;
}
//--------------------------------------------------------------------
@@ -59,12 +83,55 @@ namespace svt
}
//--------------------------------------------------------------------
+ IMPLEMENT_IREFERENCE( TabDeckLayouter )
+
+ //--------------------------------------------------------------------
Rectangle TabDeckLayouter::Layout( const Rectangle& i_rDeckPlayground )
{
- // TODO
+ if ( !m_pData->pTabBar.get() )
+ {
+ OSL_ENSURE( false, "TabDeckLayouter::Layout: disposed!" );
+ return i_rDeckPlayground;
+ }
+
+ if ( lcl_isVerticalTabBar( m_pData->eAlignment ) )
+ {
+ const Size aPreferredSize( m_pData->pTabBar->GetOptimalSize( WINDOWSIZE_PREFERRED ) );
+ Size aTabBarSize = ( aPreferredSize.Width() < i_rDeckPlayground.GetWidth() )
+ ? aPreferredSize
+ : m_pData->pTabBar->GetOptimalSize( WINDOWSIZE_MINIMUM );
+ aTabBarSize.Height() = i_rDeckPlayground.GetHeight();
+
+ Rectangle aPanelRect( i_rDeckPlayground );
+ if ( m_pData->eAlignment == TABS_RIGHT )
+ {
+ aPanelRect.Right() -= aTabBarSize.Width();
+ Point aTabBarTopLeft( aPanelRect.TopRight() );
+ aTabBarTopLeft.X() += 1;
+ m_pData->pTabBar->SetPosSizePixel( aTabBarTopLeft, aTabBarSize );
+ }
+ else
+ {
+ m_pData->pTabBar->SetPosSizePixel( aPanelRect.TopLeft(), aTabBarSize );
+ aPanelRect.Left() += aTabBarSize.Width();
+ }
+ if ( aPanelRect.Left() >= aPanelRect.Right() )
+ aPanelRect = Rectangle();
+
+ return aPanelRect;
+ }
+
+ OSL_ENSURE( false, "TabDeckLayouter::Layout: unreachable!" );
+ // currently there do not even exist enum values for other alignments ...
return i_rDeckPlayground;
}
+ //--------------------------------------------------------------------
+ void TabDeckLayouter::Destroy()
+ {
+ m_pData->pTabBar.reset();
+ }
+
//........................................................................
} // namespace svt
//........................................................................
diff --git a/svtools/source/toolpanel/toolpanelcollection.cxx b/svtools/source/toolpanel/toolpanelcollection.cxx
index ff274075f108..b0a2571fc71e 100644
--- a/svtools/source/toolpanel/toolpanelcollection.cxx
+++ b/svtools/source/toolpanel/toolpanelcollection.cxx
@@ -26,7 +26,7 @@
#include "precompiled_svtools.hxx"
-#include "svtools/toolpanel/toolpanelcollection.hxx"
+#include "toolpanelcollection.hxx"
#include <tools/diagnose_ex.h>
@@ -42,7 +42,8 @@ namespace svt
//====================================================================
struct ToolPanelCollection_Data
{
- ::std::vector< PToolPanel > aPanels;
+ ::std::vector< PToolPanel > aPanels;
+ ::std::vector< IToolPanelContainerListener* > aListeners;
};
//====================================================================
@@ -60,6 +61,9 @@ namespace svt
}
//--------------------------------------------------------------------
+ IMPLEMENT_IREFERENCE( ToolPanelCollection )
+
+ //--------------------------------------------------------------------
size_t ToolPanelCollection::GetPanelCount() const
{
return m_pData->aPanels.size();
@@ -75,20 +79,49 @@ namespace svt
}
//--------------------------------------------------------------------
- size_t ToolPanelCollection::InsertPanel( const PToolPanel& i_pPanel, const size_t i_pPosition )
+ size_t ToolPanelCollection::InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition )
{
OSL_ENSURE( i_pPanel.get(), "ToolPanelCollection::InsertPanel: illegal panel!" );
if ( !i_pPanel.get() )
return 0;
- const size_t position = i_pPosition < m_pData->aPanels.size() ? i_pPosition : m_pData->aPanels.size();
+ const size_t position = i_nPosition < m_pData->aPanels.size() ? i_nPosition : m_pData->aPanels.size();
m_pData->aPanels.insert( m_pData->aPanels.begin() + position, i_pPanel );
- // TODO: notification. The tool panel deck which owns us is certainly interested in this event ...
+ // notifications
+ for ( ::std::vector< IToolPanelContainerListener* >::const_iterator loop = m_pData->aListeners.begin();
+ loop != m_pData->aListeners.end();
+ ++loop
+ )
+ {
+ (*loop)->PanelInserted( i_pPanel, i_nPosition );
+ }
return position;
}
+ //--------------------------------------------------------------------
+ void ToolPanelCollection::AddListener( IToolPanelContainerListener& i_rListener )
+ {
+ m_pData->aListeners.push_back( &i_rListener );
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelCollection::RemoveListener( IToolPanelContainerListener& i_rListener )
+ {
+ for ( ::std::vector< IToolPanelContainerListener* >::iterator lookup = m_pData->aListeners.begin();
+ lookup != m_pData->aListeners.end();
+ ++lookup
+ )
+ {
+ if ( *lookup == &i_rListener )
+ {
+ m_pData->aListeners.erase( lookup );
+ return;
+ }
+ }
+ }
+
//........................................................................
} // namespace svt
//........................................................................
diff --git a/svtools/inc/svtools/toolpanel/toolpanelcollection.hxx b/svtools/source/toolpanel/toolpanelcollection.hxx
index a0257fc5c91e..3eb5ea7fb44e 100644
--- a/svtools/inc/svtools/toolpanel/toolpanelcollection.hxx
+++ b/svtools/source/toolpanel/toolpanelcollection.hxx
@@ -27,7 +27,8 @@
#ifndef TOOLPANELCOLLECTION_HXX
#define TOOLPANELCOLLECTION_HXX
-#include "svtools/toolpanel/toolpanel.hxx"
+#include "svtools/toolpanel/toolpanelcontainer.hxx"
+#include "refbase.hxx"
#include <memory>
@@ -41,16 +42,22 @@ namespace svt
//====================================================================
//= ToolPanelCollection
//====================================================================
- class ToolPanelCollection
+ class ToolPanelCollection :public RefBase
+ ,public IToolPanelContainer
{
public:
ToolPanelCollection();
~ToolPanelCollection();
- // panel access
- size_t GetPanelCount() const;
- PToolPanel GetPanel( const size_t i_nPos ) const;
- size_t InsertPanel( const PToolPanel& i_pPanel, const size_t i_pPosition );
+ // IToolPanelContainer
+ virtual size_t GetPanelCount() const;
+ virtual PToolPanel GetPanel( const size_t i_nPos ) const;
+ virtual size_t InsertPanel( const PToolPanel& i_pPanel, const size_t i_pPosition );
+ virtual void AddListener( IToolPanelContainerListener& i_rListener );
+ virtual void RemoveListener( IToolPanelContainerListener& i_rListener );
+
+ // IReference
+ DECLARE_IREFERENCE()
private:
::std::auto_ptr< ToolPanelCollection_Data > m_pData;
diff --git a/svtools/source/toolpanel/toolpaneldeck.cxx b/svtools/source/toolpanel/toolpaneldeck.cxx
index 12f85794576e..8bd521689a8a 100644
--- a/svtools/source/toolpanel/toolpaneldeck.cxx
+++ b/svtools/source/toolpanel/toolpaneldeck.cxx
@@ -27,6 +27,7 @@
#include "precompiled_svtools.hxx"
#include "dummypanel.hxx"
+#include "toolpanelcollection.hxx"
#include "svtools/toolpanel/toolpaneldeck.hxx"
#include "svtools/toolpanel/tablayouter.hxx"
@@ -46,28 +47,26 @@ namespace svt
public:
ToolPanelDeck_Impl( ToolPanelDeck& i_rDeck )
:m_rDeck( i_rDeck )
- ,m_aPanels()
+ ,m_pPanels( new( ToolPanelCollection ) )
,m_pDummyPanel( new DummyPanel )
,m_aActivePanel()
,m_pLayouter()
,m_aPanelPlayground()
{
- // use a default layouter
- m_pLayouter.reset( new TabDeckLayouter( TABS_RIGHT ) );
-
- // add as listener to the panels collection - we're interested in panels
- // being added and removed
- // TODO
+ // TODO: add as listener to the panels collection - we're interested in panels
+ // being added and removed, as we need to re-layout then
}
- const ToolPanelCollection& GetPanels() const { return m_aPanels; }
- ToolPanelCollection& GetPanels() { return m_aPanels; }
+ PToolPanelContainer GetPanels() const { return m_pPanels; }
+
+ size_t GetActivePanel() const;
+ void ActivatePanel( const size_t i_nPanel );
- size_t GetActivePanel() const;
- void ActivatePanel( const size_t i_nPanel );
+ PDeckLayouter GetLayouter() const { return m_pLayouter; }
+ void SetLayouter( const PDeckLayouter& i_pNewLayouter );
- PDeckLayouter GetLayouter() const { return m_pLayouter; }
- void SetLayouter( const PDeckLayouter& i_pNewLayouter );
+ void AddListener( IToolPanelDeckListener& i_rListener );
+ void RemoveListener( IToolPanelDeckListener& i_rListener );
/// re-layouts everything
void LayoutAll() { ImplDoLayout(); }
@@ -81,13 +80,16 @@ namespace svt
private:
ToolPanelDeck& m_rDeck;
- ToolPanelCollection m_aPanels;
+ PToolPanelContainer m_pPanels;
PToolPanel m_pDummyPanel;
::boost::optional< size_t >
m_aActivePanel;
PDeckLayouter m_pLayouter;
Rectangle m_aPanelPlayground;
+
+ ::std::vector< IToolPanelDeckListener* >
+ m_aListeners;
};
//--------------------------------------------------------------------
@@ -95,7 +97,7 @@ namespace svt
{
if ( !m_aActivePanel )
return m_pDummyPanel;
- return m_aPanels.GetPanel( *m_aActivePanel );
+ return m_pPanels->GetPanel( *m_aActivePanel );
}
//--------------------------------------------------------------------
@@ -121,17 +123,18 @@ namespace svt
//--------------------------------------------------------------------
void ToolPanelDeck_Impl::ActivatePanel( const size_t i_nPanel )
{
- OSL_ENSURE( i_nPanel < m_aPanels.GetPanelCount(), "ToolPanelDeck_Impl::ActivatePanel: illegal panel no.!" );
- if ( i_nPanel >= m_aPanels.GetPanelCount() )
+ OSL_ENSURE( i_nPanel < m_pPanels->GetPanelCount(), "ToolPanelDeck_Impl::ActivatePanel: illegal panel no.!" );
+ if ( i_nPanel >= m_pPanels->GetPanelCount() )
return;
- if ( !!m_aActivePanel && ( *m_aActivePanel == i_nPanel ) )
+ if ( m_aActivePanel == i_nPanel )
return;
// hide the old panel
const PToolPanel pOldActive( GetActiveOrDummyPanel_Impl() );
pOldActive->Hide();
+ const ::boost::optional< size_t > aOldPanel( m_aActivePanel );
m_aActivePanel = i_nPanel;
// position and show the new panel
@@ -139,8 +142,14 @@ namespace svt
pNewActive->SetPosSizePixel( m_aPanelPlayground );
pNewActive->Show();
- // tell the layouter - it might need to adjust its visuals to the new situation
- // TODO
+ // notify listeners
+ for ( ::std::vector< IToolPanelDeckListener* >::iterator loop = m_aListeners.begin();
+ loop != m_aListeners.end();
+ ++loop
+ )
+ {
+ (*loop)->ActivePanelChanged( aOldPanel, *m_aActivePanel );
+ }
}
//--------------------------------------------------------------------
@@ -159,6 +168,28 @@ namespace svt
pActive->SetPosSizePixel( m_aPanelPlayground );
}
+ //--------------------------------------------------------------------
+ void ToolPanelDeck_Impl::AddListener( IToolPanelDeckListener& i_rListener )
+ {
+ m_aListeners.push_back( &i_rListener );
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck_Impl::RemoveListener( IToolPanelDeckListener& i_rListener )
+ {
+ for ( ::std::vector< IToolPanelDeckListener* >::iterator lookup = m_aListeners.begin();
+ lookup != m_aListeners.end();
+ ++lookup
+ )
+ {
+ if ( *lookup == &i_rListener )
+ {
+ m_aListeners.erase( lookup );
+ return;
+ }
+ }
+ }
+
//====================================================================
//= ToolPanelDeck
//====================================================================
@@ -167,11 +198,14 @@ namespace svt
:Control( &i_rParent, i_nStyle )
,m_pImpl( new ToolPanelDeck_Impl( *this ) )
{
+ // use a default layouter
+ SetLayouter( PDeckLayouter( new TabDeckLayouter( TABS_RIGHT, *this ) ) );
}
//--------------------------------------------------------------------
ToolPanelDeck::~ToolPanelDeck()
{
+ GetLayouter()->Destroy();
}
//--------------------------------------------------------------------
@@ -199,15 +233,21 @@ namespace svt
}
//--------------------------------------------------------------------
- const ToolPanelCollection& ToolPanelDeck::GetPanels() const
+ PToolPanelContainer ToolPanelDeck::GetPanels() const
{
return m_pImpl->GetPanels();
}
//--------------------------------------------------------------------
- ToolPanelCollection& ToolPanelDeck::GetPanels()
+ void ToolPanelDeck::AddListener( IToolPanelDeckListener& i_rListener )
{
- return m_pImpl->GetPanels();
+ m_pImpl->AddListener( i_rListener );
+ }
+
+ //--------------------------------------------------------------------
+ void ToolPanelDeck::RemoveListener( IToolPanelDeckListener& i_rListener )
+ {
+ m_pImpl->RemoveListener( i_rListener );
}
//--------------------------------------------------------------------
diff --git a/svtools/workben/toolpanel/toolpaneltest.cxx b/svtools/workben/toolpanel/toolpaneltest.cxx
index 6b02208fbdfe..d717ed9a3fd6 100644
--- a/svtools/workben/toolpanel/toolpaneltest.cxx
+++ b/svtools/workben/toolpanel/toolpaneltest.cxx
@@ -35,6 +35,7 @@
#include <cppuhelper/bootstrap.hxx>
#include <cppuhelper/servicefactory.hxx>
#include <tools/diagnose_ex.h>
+#include <vcl/help.hxx>
#include <vcl/svapp.hxx>
#include <vcl/wrkwin.hxx>
@@ -82,25 +83,40 @@ public:
class ColoredPanel : public IToolPanel
{
public:
- ColoredPanel( Window& i_rParent, const Color& i_rColor );
+ ColoredPanel( Window& i_rParent, const Color& i_rColor, const sal_Char* i_pAsciiPanelName );
~ColoredPanel();
// IToolPanel
virtual void Show();
virtual void Hide();
virtual void SetPosSizePixel( const Rectangle& i_rPanelPlayground );
+ virtual ::rtl::OUString GetDisplayName() const;
+ virtual Image GetImage() const;
+
+ // IReference
+ virtual oslInterlockedCount SAL_CALL acquire();
+ virtual oslInterlockedCount SAL_CALL release();
private:
+ oslInterlockedCount m_refCount;
ColoredPanelWindow m_aWindow;
+ ::rtl::OUString m_aPanelName;
+ BitmapEx m_aPanelIcon;
};
//=============================================================================
//= ColoredPanel
//=============================================================================
//-----------------------------------------------------------------------------
-ColoredPanel::ColoredPanel( Window& i_rParent, const Color& i_rColor )
- :m_aWindow( i_rParent, i_rColor )
+ColoredPanel::ColoredPanel( Window& i_rParent, const Color& i_rColor, const sal_Char* i_pAsciiPanelName )
+ :m_refCount(0)
+ ,m_aWindow( i_rParent, i_rColor )
+ ,m_aPanelName( ::rtl::OUString::createFromAscii( i_pAsciiPanelName ) )
+ ,m_aPanelIcon()
{
+ Bitmap aBitmap( Size( 16, 16 ), 8 );
+ m_aPanelIcon = BitmapEx( aBitmap );
+ m_aPanelIcon.Erase( i_rColor );
}
//-----------------------------------------------------------------------------
@@ -109,6 +125,21 @@ ColoredPanel::~ColoredPanel()
}
//-----------------------------------------------------------------------------
+oslInterlockedCount SAL_CALL ColoredPanel::acquire()
+{
+ return osl_incrementInterlockedCount( &m_refCount );
+}
+
+//-----------------------------------------------------------------------------
+oslInterlockedCount SAL_CALL ColoredPanel::release()
+{
+ oslInterlockedCount newCount = osl_decrementInterlockedCount( &m_refCount );
+ if ( 0 == newCount )
+ delete this;
+ return newCount;
+}
+
+//-----------------------------------------------------------------------------
void ColoredPanel::Show()
{
m_aWindow.Show();
@@ -126,6 +157,18 @@ void ColoredPanel::SetPosSizePixel( const Rectangle& i_rPanelPlayground )
m_aWindow.SetPosSizePixel( i_rPanelPlayground.TopLeft(), i_rPanelPlayground.GetSize() );
}
+//-----------------------------------------------------------------------------
+::rtl::OUString ColoredPanel::GetDisplayName() const
+{
+ return m_aPanelName;
+}
+
+//-----------------------------------------------------------------------------
+Image ColoredPanel::GetImage() const
+{
+ return Image( m_aPanelIcon );
+}
+
//=============================================================================
//= PanelDemoMainWindow
//=============================================================================
@@ -155,16 +198,20 @@ PanelDemoMainWindow::PanelDemoMainWindow()
m_aToolPanelDeck.SetPosSizePixel( Point( 20, 20 ), Size( 500, 300 ) );
m_aToolPanelDeck.SetBorderStyle( WINDOW_BORDER_MONO );
- ToolPanelCollection& rPanels = m_aToolPanelDeck.GetPanels();
- const size_t nFirstPanelPosition = rPanels.InsertPanel( PToolPanel( new ColoredPanel( m_aToolPanelDeck, Color( COL_RED ) ) ), rPanels.GetPanelCount() );
- m_aToolPanelDeck.ActivatePanel( nFirstPanelPosition );
+ PToolPanelContainer pPanels( m_aToolPanelDeck.GetPanels() );
+ pPanels->InsertPanel( PToolPanel( new ColoredPanel( m_aToolPanelDeck, Color( COL_RED ), "Red" ) ), pPanels->GetPanelCount() );
+ pPanels->InsertPanel( PToolPanel( new ColoredPanel( m_aToolPanelDeck, Color( COL_GREEN ), "Some flavor of Green" ) ), pPanels->GetPanelCount() );
+ pPanels->InsertPanel( PToolPanel( new ColoredPanel( m_aToolPanelDeck, RGB_COLORDATA( 255, 255, 0 ), "Yellow is ugly" ) ), pPanels->GetPanelCount() );
+ m_aToolPanelDeck.ActivatePanel( 0 );
m_aToolPanelDeck.Show();
SetBackground( Color( COL_LIGHTGRAY ) );
SetText( String::CreateFromAscii( "ToolPanelDeck Demo Application" ) );
Show();
+
+ Help::EnableQuickHelp();
}
//-----------------------------------------------------------------------------