diff options
-rw-r--r-- | svtools/inc/svtools/toolpanel/decklayouter.hxx | 7 | ||||
-rw-r--r-- | svtools/inc/svtools/toolpanel/refbase.hxx (renamed from svtools/source/toolpanel/refbase.hxx) | 0 | ||||
-rw-r--r-- | svtools/inc/svtools/toolpanel/tablayouter.hxx | 7 | ||||
-rw-r--r-- | svtools/inc/svtools/toolpanel/toolpanel.hxx | 26 | ||||
-rw-r--r-- | svtools/inc/svtools/toolpanel/toolpaneldeck.hxx | 2 | ||||
-rw-r--r-- | svtools/source/toolpanel/dummypanel.cxx | 11 | ||||
-rw-r--r-- | svtools/source/toolpanel/dummypanel.hxx | 8 | ||||
-rw-r--r-- | svtools/source/toolpanel/paneltabbar.cxx | 202 | ||||
-rw-r--r-- | svtools/source/toolpanel/paneltabbar.hxx | 4 | ||||
-rw-r--r-- | svtools/source/toolpanel/refbase.cxx | 2 | ||||
-rw-r--r-- | svtools/source/toolpanel/tablayouter.cxx | 11 | ||||
-rw-r--r-- | svtools/source/toolpanel/toolpanelcollection.hxx | 2 | ||||
-rw-r--r-- | svtools/source/toolpanel/toolpaneldeck.cxx | 145 | ||||
-rw-r--r-- | svtools/workben/toolpanel/makefile.mk | 1 | ||||
-rw-r--r-- | svtools/workben/toolpanel/toolpaneltest.cxx | 209 |
15 files changed, 570 insertions, 67 deletions
diff --git a/svtools/inc/svtools/toolpanel/decklayouter.hxx b/svtools/inc/svtools/toolpanel/decklayouter.hxx index 6ee858e482c6..6050a0955715 100644 --- a/svtools/inc/svtools/toolpanel/decklayouter.hxx +++ b/svtools/inc/svtools/toolpanel/decklayouter.hxx @@ -57,10 +57,15 @@ namespace svt 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. + but non-functional. */ virtual void Destroy() = 0; + /** assuming that a layouter neesds to provide some kind of panel selector control, this method + requests to set the focus to this control. + */ + virtual void SetFocusToPanelSelector() = 0; + virtual ~IDeckLayouter() { } diff --git a/svtools/source/toolpanel/refbase.hxx b/svtools/inc/svtools/toolpanel/refbase.hxx index 4cbcc41ffd2a..4cbcc41ffd2a 100644 --- a/svtools/source/toolpanel/refbase.hxx +++ b/svtools/inc/svtools/toolpanel/refbase.hxx diff --git a/svtools/inc/svtools/toolpanel/tablayouter.hxx b/svtools/inc/svtools/toolpanel/tablayouter.hxx index e2d46ff8b42d..cf901d2e57b3 100644 --- a/svtools/inc/svtools/toolpanel/tablayouter.hxx +++ b/svtools/inc/svtools/toolpanel/tablayouter.hxx @@ -29,7 +29,7 @@ #include "svtools/toolpanel/decklayouter.hxx" #include "svtools/toolpanel/toolpanelcontainer.hxx" -#include "refbase.hxx" +#include "svtools/toolpanel/refbase.hxx" #include <memory> @@ -42,8 +42,8 @@ namespace svt enum TabAlignment { - TABS_RIGHT, - TABS_LEFT + TABS_LEFT, + TABS_RIGHT }; struct TabDeckLayouter_Data; @@ -69,6 +69,7 @@ namespace svt // IDeckLayouter virtual Rectangle Layout( const Rectangle& i_rDeckPlayground ); virtual void Destroy(); + virtual void SetFocusToPanelSelector(); // IReference DECLARE_IREFERENCE() diff --git a/svtools/inc/svtools/toolpanel/toolpanel.hxx b/svtools/inc/svtools/toolpanel/toolpanel.hxx index 24a166be362d..760b59f40255 100644 --- a/svtools/inc/svtools/toolpanel/toolpanel.hxx +++ b/svtools/inc/svtools/toolpanel/toolpanel.hxx @@ -47,17 +47,31 @@ namespace svt class IToolPanel : public ::rtl::IReference { public: - /// shows the panel - virtual void Show() = 0; - /// hides the panel - 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; + /// shows the panel window + virtual void Show() = 0; + + /// hides the panel window + virtual void Hide() = 0; + + /// sets the position of the panel window + virtual void SetPosSizePixel( const Rectangle& i_rPanelPlayground ) = 0; + + /// sets the focus to the panel window + virtual void GrabFocus() = 0; + + /** determines whether the panel window, or any of its children, currently has the focus + + Effectively, an implementation simply needs to redelegate this to its panel window's HasChildPathFocus + method. + */ + virtual bool HasFocus() const = 0; + virtual ~IToolPanel() { } diff --git a/svtools/inc/svtools/toolpanel/toolpaneldeck.hxx b/svtools/inc/svtools/toolpanel/toolpaneldeck.hxx index 42045c36b71a..573248235957 100644 --- a/svtools/inc/svtools/toolpanel/toolpaneldeck.hxx +++ b/svtools/inc/svtools/toolpanel/toolpaneldeck.hxx @@ -77,6 +77,8 @@ namespace svt protected: // Window overridables virtual void Resize(); + virtual long Notify( NotifyEvent& i_rNotifyEvent ); + virtual void GetFocus(); private: ::std::auto_ptr< ToolPanelDeck_Impl > m_pImpl; diff --git a/svtools/source/toolpanel/dummypanel.cxx b/svtools/source/toolpanel/dummypanel.cxx index 405f103d9713..6bf1fb6ea60e 100644 --- a/svtools/source/toolpanel/dummypanel.cxx +++ b/svtools/source/toolpanel/dummypanel.cxx @@ -76,6 +76,17 @@ namespace svt return Image(); } + //-------------------------------------------------------------------- + void DummyPanel::GrabFocus() + { + } + + //-------------------------------------------------------------------- + bool DummyPanel::HasFocus() const + { + return false; + } + //........................................................................ } // namespace svt //........................................................................ diff --git a/svtools/source/toolpanel/dummypanel.hxx b/svtools/source/toolpanel/dummypanel.hxx index 46b1218abe93..41afe1ad51e2 100644 --- a/svtools/source/toolpanel/dummypanel.hxx +++ b/svtools/source/toolpanel/dummypanel.hxx @@ -28,7 +28,7 @@ #define DUMMYPANEL_HXX #include "svtools/toolpanel/toolpanel.hxx" -#include "refbase.hxx" +#include "svtools/toolpanel/refbase.hxx" //........................................................................ namespace svt @@ -47,11 +47,13 @@ namespace svt ~DummyPanel(); // IToolPanel + virtual ::rtl::OUString GetDisplayName() const; + virtual Image GetImage() const; virtual void Show(); virtual void Hide(); virtual void SetPosSizePixel( const Rectangle& i_rPanelPlayground ); - virtual ::rtl::OUString GetDisplayName() const; - virtual Image GetImage() const; + virtual void GrabFocus(); + virtual bool HasFocus() const; DECLARE_IREFERENCE() }; diff --git a/svtools/source/toolpanel/paneltabbar.cxx b/svtools/source/toolpanel/paneltabbar.cxx index e65477fca693..fcca3585d618 100644 --- a/svtools/source/toolpanel/paneltabbar.cxx +++ b/svtools/source/toolpanel/paneltabbar.cxx @@ -35,7 +35,9 @@ #include <vector> // space around an item -#define ITEM_OUTER_SPACE 2 * 3 +#define ITEM_OUTER_SPACE 2 * 2 +// spacing before and after (in writing direction, whether this is horizontal or vertical) an item's text +#define ITEM_TEXT_FLOW_SPACE 2 // distance between two items #define ITEM_DISTANCE_PIXEL 2 // space between item icon and icon text @@ -53,6 +55,33 @@ namespace svt #define ITEM_STATE_NORMAL 0x00 #define ITEM_STATE_ACTIVE 0x01 #define ITEM_STATE_HOVERED 0x02 + #define ITEM_STATE_FOCUSED 0x04 + + //================================================================================================================== + //= 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; //================================================================================================================== //= IItemsLayout @@ -83,6 +112,11 @@ namespace svt */ virtual void DrawItem( const PToolPanel& i_pPanel, Window& i_rTargetWindow, const Rectangle& i_rItemRect, const ItemFlags i_nItemFlags, const bool i_bDrawMinimal ) = 0; + + /** updates the given items to use their minimal or optimal size, so they fit (if possible) into the given + area. + */ + virtual void FitItemRects( ItemDescriptors& i_rItems, const Rectangle& i_rFitInto ) = 0; }; typedef ::boost::shared_ptr< IItemsLayout > PItemsLayout; @@ -102,6 +136,7 @@ namespace svt 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 ); + virtual void FitItemRects( ItemDescriptors& i_rItems, const Rectangle& i_rFitInto ); }; //------------------------------------------------------------------------------------------------------------------ @@ -126,6 +161,8 @@ namespace svt const Size aTextSize( i_rReferenceDevice.GetCtrlTextWidth( sItemText ), i_rReferenceDevice.GetTextHeight() ); aItemSize.Height() += aTextSize.Width(); aItemSize.Width() = ::std::max( aItemSize.Width(), aTextSize.Height() ); + + aItemSize.Height() += 2 * ITEM_TEXT_FLOW_SPACE; } aItemSize.Width() += 2 * ITEM_OUTER_SPACE; @@ -165,6 +202,8 @@ namespace svt if ( !i_bDrawMinimal ) { + aDrawPos.Y() += ITEM_TEXT_FLOW_SPACE; + // draw the text i_rTargetWindow.Push( PUSH_FONT ); @@ -187,7 +226,8 @@ namespace svt const bool bActive = ( ( i_nItemFlags & ITEM_STATE_ACTIVE ) != 0 ); const bool bHovered = ( ( i_nItemFlags & ITEM_STATE_HOVERED ) != 0 ); - if ( bActive || bHovered ) + const bool bFocused = ( ( i_nItemFlags & ITEM_STATE_FOCUSED ) != 0 ); + if ( bActive || bHovered || bFocused ) { Rectangle aSelectionRect( i_rItemRect ); aSelectionRect.Left() += ITEM_OUTER_SPACE / 2; @@ -196,8 +236,8 @@ namespace svt aSelectionRect.Bottom() -= ITEM_OUTER_SPACE / 2; i_rTargetWindow.DrawSelectionBackground( aSelectionRect, - bHovered ? ( bActive ? 1 : 2 ) : 0 /* hilight */, - FALSE /* check */, + ( bHovered || bFocused ) ? ( bActive ? 1 : 2 ) : 0 /* hilight */, + bActive /* check */, TRUE /* border */, FALSE /* ext border only */, 0 /* corner radius */, @@ -207,31 +247,24 @@ namespace svt } } - //================================================================================================================== - //= ItemDescriptor - //================================================================================================================== - struct ItemDescriptor + //------------------------------------------------------------------------------------------------------------------ + void VerticalItemLayout::FitItemRects( ItemDescriptors& i_rItems, const Rectangle& i_rFitInto ) { - PToolPanel pPanel; - Rectangle aMinArea; - Rectangle aPrefArea; - bool bUseMinimal; - - ItemDescriptor() - :pPanel() - ,aMinArea() - ,aPrefArea() - ,bUseMinimal( false ) - { - } + if ( i_rItems.empty() ) + // nothing to do + return; - const Rectangle& GetCurrentRect() const + // use the minimal sizes if and only if the preferred sizes do not fit + const Point aBottomRight( i_rItems.rbegin()->aPrefArea.BottomRight() ); + bool bUseMinimal = ( aBottomRight.Y() >= i_rFitInto.Bottom() ); + for ( ItemDescriptors::iterator item = i_rItems.begin(); + item != i_rItems.end(); + ++item + ) { - return bUseMinimal ? aMinArea : aPrefArea; + item->bUseMinimal = bUseMinimal; } - }; - - typedef ::std::vector< ItemDescriptor > ItemDescriptors; + } //================================================================================================================== //= PanelTabBar_Data @@ -245,6 +278,7 @@ namespace svt ,rPanelDeck( dynamic_cast< ToolPanelDeck& >( *i_rTabBar.GetParent() ) ) ,pLayout( new VerticalItemLayout ) ,aHoveredItem() + ,aFocusedItem() ,bMouseButtonDown( false ) ,aItems() ,bItemsDirty( true ) @@ -265,6 +299,7 @@ namespace svt (void)i_pPanel; (void)i_nPosition; bItemsDirty = true; + rTabBar.Invalidate(); } // IToolPanelDeckListener @@ -275,6 +310,7 @@ namespace svt ToolPanelDeck& rPanelDeck; const PItemsLayout pLayout; ::boost::optional< size_t > aHoveredItem; + ::boost::optional< size_t > aFocusedItem; bool bMouseButtonDown; ItemDescriptors aItems; @@ -401,6 +437,9 @@ namespace svt if ( i_rData.rPanelDeck.GetActivePanel() == i_nItemIndex ) nItemFlags |= ITEM_STATE_ACTIVE; + if ( i_rData.aFocusedItem == i_nItemIndex ) + nItemFlags |= ITEM_STATE_FOCUSED; + i_rData.rTabBar.DrawRect( rItem.GetCurrentRect() ); i_rData.pLayout->DrawItem( rItem.pPanel, i_rData.rTabBar, rItem.GetCurrentRect(), nItemFlags, rItem.bUseMinimal ); } @@ -475,17 +514,14 @@ namespace svt 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; - } + // the available size + Size aOutputSize( GetOutputSizePixel() ); + // shrunk by the outer space + aOutputSize.Width() -= TAB_BAR_OUTER_SPACE; + aOutputSize.Height() -= TAB_BAR_OUTER_SPACE; + // let the layouter decide + m_pData->pLayout->FitItemRects( m_pData->aItems, Rectangle( Point(), aOutputSize ) ); } //------------------------------------------------------------------------------------------------------------------ @@ -592,6 +628,102 @@ namespace svt Help::ShowQuickHelp( this, rItem.GetCurrentRect(), sItemText ); } + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::GetFocus() + { + Control::GetFocus(); + if ( m_pData->rPanelDeck.GetPanels()->GetPanelCount() ) + { + m_pData->aFocusedItem.reset( m_pData->rPanelDeck.GetActivePanel() ); + lcl_drawItem( *m_pData, *m_pData->aFocusedItem ); + } + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::LoseFocus() + { + Control::LoseFocus(); + + ::boost::optional< size_t > aPreviouslyFocused( m_pData->aFocusedItem ); + m_pData->aFocusedItem.reset(); + if ( !!aPreviouslyFocused ) + lcl_drawItem( *m_pData, *aPreviouslyFocused ); + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::KeyInput( const KeyEvent& i_rKeyEvent ) + { + Control::KeyInput( i_rKeyEvent ); + + const KeyCode& rKeyCode( i_rKeyEvent.GetKeyCode() ); + if ( rKeyCode.GetModifier() != 0 ) + // only interested in mere key presses + return; + + // if there are less than 2 panels, we cannot travel them ... + const size_t nPanelCount( m_pData->rPanelDeck.GetPanels()->GetPanelCount() ); + if ( nPanelCount < 2 ) + return; + + OSL_PRECOND( !!m_pData->aFocusedItem, "PanelTabBar::KeyInput: we should have a focused item here!" ); + // if we get KeyInput events, we should have the focus. In this case, aFocusedItem should not be empty, + // except if there are no panels, but then we bail out of this method here earlier ... + + bool bFocusNext = false; + bool bFocusPrev = false; + + switch ( rKeyCode.GetCode() ) + { + case KEY_UP: bFocusPrev = true; break; + case KEY_DOWN: bFocusNext = true; break; + case KEY_LEFT: + if ( IsRTLEnabled() ) + bFocusNext = true; + else + bFocusPrev = true; + break; + case KEY_RIGHT: + if ( IsRTLEnabled() ) + bFocusPrev = true; + else + bFocusNext = true; + break; + case KEY_RETURN: + m_pData->rPanelDeck.ActivatePanel( *m_pData->aFocusedItem ); + break; + } + + if ( !bFocusNext && !bFocusPrev ) + return; + + const size_t nOldFocus = *m_pData->aFocusedItem; + if ( bFocusNext ) + { + m_pData->aFocusedItem.reset( ( *m_pData->aFocusedItem + 1 ) % nPanelCount ); + } + else + { + m_pData->aFocusedItem.reset( ( *m_pData->aFocusedItem + nPanelCount - 1 ) % nPanelCount ); + } + + lcl_drawItem( *m_pData, nOldFocus ); + lcl_drawItem( *m_pData, *m_pData->aFocusedItem ); + } + + //------------------------------------------------------------------------------------------------------------------ + void PanelTabBar::DataChanged( const DataChangedEvent& i_rDataChanedEvent ) + { + Control::DataChanged( i_rDataChanedEvent ); + + if ( ( i_rDataChanedEvent.GetType() == DATACHANGED_SETTINGS ) + && ( ( i_rDataChanedEvent.GetFlags() & SETTINGS_STYLE ) != 0 ) + ) + { + SetFillColor( GetSettings().GetStyleSettings().GetDialogColor() ); + Invalidate(); + } + } + //........................................................................ } // namespace svt //........................................................................ diff --git a/svtools/source/toolpanel/paneltabbar.hxx b/svtools/source/toolpanel/paneltabbar.hxx index abbc82173c57..e718619dbc4f 100644 --- a/svtools/source/toolpanel/paneltabbar.hxx +++ b/svtools/source/toolpanel/paneltabbar.hxx @@ -62,6 +62,10 @@ namespace svt virtual void MouseButtonDown( const MouseEvent& i_rMouseEvent ); virtual void MouseButtonUp( const MouseEvent& i_rMouseEvent ); virtual void RequestHelp( const HelpEvent& i_rHelpEvent ); + virtual void GetFocus(); + virtual void LoseFocus(); + virtual void KeyInput( const KeyEvent& i_rKeyEvent ); + virtual void DataChanged( const DataChangedEvent& i_rDataChanedEvent ); private: ::std::auto_ptr< PanelTabBar_Data > m_pData; diff --git a/svtools/source/toolpanel/refbase.cxx b/svtools/source/toolpanel/refbase.cxx index cd4433045b33..f41aa2d9bb9c 100644 --- a/svtools/source/toolpanel/refbase.cxx +++ b/svtools/source/toolpanel/refbase.cxx @@ -26,7 +26,7 @@ #include "precompiled_svtools.hxx" -#include "refbase.hxx" +#include "svtools/toolpanel/refbase.hxx" //........................................................................ namespace svt diff --git a/svtools/source/toolpanel/tablayouter.cxx b/svtools/source/toolpanel/tablayouter.cxx index 7b237e8f09f6..269a6a1c4acd 100644 --- a/svtools/source/toolpanel/tablayouter.cxx +++ b/svtools/source/toolpanel/tablayouter.cxx @@ -132,6 +132,17 @@ namespace svt m_pData->pTabBar.reset(); } + //-------------------------------------------------------------------- + void TabDeckLayouter::SetFocusToPanelSelector() + { + if ( !m_pData->pTabBar.get() ) + { + OSL_ENSURE( false, "TabDeckLayouter::SetFocusToPanelSelector: already disposed!" ); + return; + } + m_pData->pTabBar->GrabFocus(); + } + //........................................................................ } // namespace svt //........................................................................ diff --git a/svtools/source/toolpanel/toolpanelcollection.hxx b/svtools/source/toolpanel/toolpanelcollection.hxx index 3eb5ea7fb44e..0fb377fafaa2 100644 --- a/svtools/source/toolpanel/toolpanelcollection.hxx +++ b/svtools/source/toolpanel/toolpanelcollection.hxx @@ -28,7 +28,7 @@ #define TOOLPANELCOLLECTION_HXX #include "svtools/toolpanel/toolpanelcontainer.hxx" -#include "refbase.hxx" +#include "svtools/toolpanel/refbase.hxx" #include <memory> diff --git a/svtools/source/toolpanel/toolpaneldeck.cxx b/svtools/source/toolpanel/toolpaneldeck.cxx index 8bd521689a8a..f6ae7993b8ec 100644 --- a/svtools/source/toolpanel/toolpaneldeck.cxx +++ b/svtools/source/toolpanel/toolpaneldeck.cxx @@ -39,10 +39,25 @@ namespace svt { //........................................................................ + enum DeckAction + { + /// activates the first panel + ACTION_ACTIVATE_FIRST, + // activates the panel after the currently active panel + ACTION_ACTIVATE_NEXT, + // activates the panel before the currently active panel + ACTION_ACTIVATE_PREV, + // activates the last panel + ACTION_ACTIVATE_LAST, + + // toggles the focus between the active panel and the panel selector + ACTION_TOGGLE_FOCUS, + }; + //==================================================================== //= ToolPanelDeck_Impl //==================================================================== - class ToolPanelDeck_Impl + class ToolPanelDeck_Impl : public IToolPanelContainerListener { public: ToolPanelDeck_Impl( ToolPanelDeck& i_rDeck ) @@ -53,8 +68,7 @@ namespace svt ,m_pLayouter() ,m_aPanelPlayground() { - // TODO: add as listener to the panels collection - we're interested in panels - // being added and removed, as we need to re-layout then + m_pPanels->AddListener( *this ); } PToolPanelContainer GetPanels() const { return m_pPanels; } @@ -71,11 +85,17 @@ namespace svt /// re-layouts everything void LayoutAll() { ImplDoLayout(); } - private: - void ImplDoLayout(); + void DoAction( const DeckAction i_eAction ); + + void FocusActivePanel(); + + protected: + // IToolPanelContainerListener + virtual void PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition ); private: - PToolPanel GetActiveOrDummyPanel_Impl(); + void ImplDoLayout(); + PToolPanel GetActiveOrDummyPanel_Impl(); private: ToolPanelDeck& m_rDeck; @@ -141,6 +161,7 @@ namespace svt const PToolPanel pNewActive( GetActiveOrDummyPanel_Impl() ); pNewActive->SetPosSizePixel( m_aPanelPlayground ); pNewActive->Show(); + pNewActive->GrabFocus(); // notify listeners for ( ::std::vector< IToolPanelDeckListener* >::iterator loop = m_aListeners.begin(); @@ -190,6 +211,65 @@ namespace svt } } + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::DoAction( const DeckAction i_eAction ) + { + ::boost::optional< size_t > aActivatePanel; + const size_t nPanelCount( GetPanels()->GetPanelCount() ); + const size_t nActivePanel( GetActivePanel() ); + + switch ( i_eAction ) + { + case ACTION_ACTIVATE_FIRST: + if ( nPanelCount > 0 ) + aActivatePanel = 0; + break; + case ACTION_ACTIVATE_PREV: + if ( nActivePanel > 0 ) + aActivatePanel = nActivePanel - 1; + break; + case ACTION_ACTIVATE_NEXT: + if ( nActivePanel < nPanelCount - 1 ) + aActivatePanel = nActivePanel + 1; + break; + case ACTION_ACTIVATE_LAST: + if ( nPanelCount > 0 ) + aActivatePanel = nPanelCount - 1; + break; + case ACTION_TOGGLE_FOCUS: + { + PToolPanel pActivePanel( GetActiveOrDummyPanel_Impl() ); + if ( !pActivePanel->HasFocus() ) + pActivePanel->GrabFocus(); + else + GetLayouter()->SetFocusToPanelSelector(); + } + break; + } + + if ( !!aActivatePanel ) + { + ActivatePanel( *aActivatePanel ); + } + } + + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::FocusActivePanel() + { + PToolPanel pActivePanel( GetActiveOrDummyPanel_Impl() ); + pActivePanel->GrabFocus(); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck_Impl::PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition ) + { + if ( !!m_aActivePanel ) + { + if ( i_nPosition <= *m_aActivePanel ) + ++*m_aActivePanel; + } + } + //==================================================================== //= ToolPanelDeck //==================================================================== @@ -257,6 +337,59 @@ namespace svt m_pImpl->LayoutAll(); } + //-------------------------------------------------------------------- + long ToolPanelDeck::Notify( NotifyEvent& i_rNotifyEvent ) + { + bool bHandled = false; + if ( i_rNotifyEvent.GetType() == EVENT_KEYINPUT ) + { + const KeyEvent* pEvent = i_rNotifyEvent.GetKeyEvent(); + const KeyCode& rKeyCode = pEvent->GetKeyCode(); + if ( rKeyCode.GetModifier() == KEY_MOD1 ) + { + bHandled = true; + switch ( rKeyCode.GetCode() ) + { + case KEY_HOME: + m_pImpl->DoAction( ACTION_ACTIVATE_FIRST ); + break; + case KEY_PAGEUP: + m_pImpl->DoAction( ACTION_ACTIVATE_PREV ); + break; + case KEY_PAGEDOWN: + m_pImpl->DoAction( ACTION_ACTIVATE_NEXT ); + break; + case KEY_END: + m_pImpl->DoAction( ACTION_ACTIVATE_LAST ); + break; + default: + bHandled = false; + break; + } + } + else if ( rKeyCode.GetModifier() == ( KEY_MOD1 | KEY_SHIFT ) ) + { + if ( rKeyCode.GetCode() == KEY_E ) + { + m_pImpl->DoAction( ACTION_TOGGLE_FOCUS ); + bHandled = true; + } + } + } + + if ( bHandled ) + return 1; + + return Control::Notify( i_rNotifyEvent ); + } + + //-------------------------------------------------------------------- + void ToolPanelDeck::GetFocus() + { + Control::GetFocus(); + m_pImpl->FocusActivePanel(); + } + //........................................................................ } // namespace svt //........................................................................ diff --git a/svtools/workben/toolpanel/makefile.mk b/svtools/workben/toolpanel/makefile.mk index 8572ccaa3607..88f1117e48b3 100644 --- a/svtools/workben/toolpanel/makefile.mk +++ b/svtools/workben/toolpanel/makefile.mk @@ -53,6 +53,7 @@ APP1OBJS= $(OBJFILES) APP1LIBS= $(SLB)/toolpanel.lib APP1STDLIBS=\ $(VCLLIB) \ + $(UCBHELPERLIB) \ $(SALLIB) \ $(TOOLSLIB) \ $(COMPHELPERLIB) \ diff --git a/svtools/workben/toolpanel/toolpaneltest.cxx b/svtools/workben/toolpanel/toolpaneltest.cxx index d717ed9a3fd6..44c03fb1e661 100644 --- a/svtools/workben/toolpanel/toolpaneltest.cxx +++ b/svtools/workben/toolpanel/toolpaneltest.cxx @@ -27,6 +27,7 @@ #include "precompiled_svtools.hxx" #include "svtools/toolpanel/toolpaneldeck.hxx" +#include "svtools/toolpanel/tablayouter.hxx" #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/uno/XComponentContext.hpp> @@ -35,14 +36,20 @@ #include <cppuhelper/bootstrap.hxx> #include <cppuhelper/servicefactory.hxx> #include <tools/diagnose_ex.h> +#include <ucbhelper/contentbroker.hxx> +#include <vcl/button.hxx> +#include <vcl/edit.hxx> #include <vcl/help.hxx> #include <vcl/svapp.hxx> +#include <vcl/taskpanelist.hxx> #include <vcl/wrkwin.hxx> namespace svt { namespace toolpanel { using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; using ::com::sun::star::lang::XMultiServiceFactory; using ::com::sun::star::uno::XComponentContext; @@ -66,15 +73,35 @@ class ColoredPanelWindow : public Window public: ColoredPanelWindow( Window& i_rParent, const Color& i_rColor ) :Window( &i_rParent ) + ,m_aEdit( this, WB_BORDER ) { SetLineColor(); SetFillColor( i_rColor ); + + m_aEdit.Show(); } virtual void Paint( const Rectangle& i_rRect ) { DrawRect( i_rRect ); } + + virtual void GetFocus() + { + m_aEdit.GrabFocus(); + } + + virtual void Resize() + { + const Size aOutputSize( GetOutputSizePixel() ); + m_aEdit.SetPosSizePixel( + Point( 20, 20 ), + Size( aOutputSize.Width() - 40, 20 ) + ); + } + +private: + Edit m_aEdit; }; //============================================================================= @@ -87,11 +114,13 @@ public: ~ColoredPanel(); // IToolPanel + virtual ::rtl::OUString GetDisplayName() const; + virtual Image GetImage() const; virtual void Show(); virtual void Hide(); virtual void SetPosSizePixel( const Rectangle& i_rPanelPlayground ); - virtual ::rtl::OUString GetDisplayName() const; - virtual Image GetImage() const; + virtual void GrabFocus(); + virtual bool HasFocus() const; // IReference virtual oslInterlockedCount SAL_CALL acquire(); @@ -158,6 +187,18 @@ void ColoredPanel::SetPosSizePixel( const Rectangle& i_rPanelPlayground ) } //----------------------------------------------------------------------------- +void ColoredPanel::GrabFocus() +{ + m_aWindow.GrabFocus(); +} + +//----------------------------------------------------------------------------- +bool ColoredPanel::HasFocus() const +{ + return m_aWindow.HasChildPathFocus(); +} + +//----------------------------------------------------------------------------- ::rtl::OUString ColoredPanel::GetDisplayName() const { return m_aPanelName; @@ -170,31 +211,153 @@ Image ColoredPanel::GetImage() const } //============================================================================= -//= PanelDemoMainWindow +//= OptionsWindow //============================================================================= -class PanelDemoMainWindow : public WorkWindow +class PanelDemoMainWindow; +class OptionsWindow : public Window { +public: + OptionsWindow( PanelDemoMainWindow& i_rParent ); + + virtual void Resize(); + virtual void GetFocus(); + private: - ToolPanelDeck m_aToolPanelDeck; + DECL_LINK( OnAlignmentChanged, void* ); -protected: - virtual void GetFocus(); +private: + RadioButton m_aAlignLeft; + RadioButton m_aAlignRight; +}; +//============================================================================= +//= PanelDemoMainWindow +//============================================================================= +class PanelDemoMainWindow : public WorkWindow +{ public: PanelDemoMainWindow(); ~PanelDemoMainWindow(); + // window overridables virtual void Resize(); + +public: + // operations + void AlignTabs( const ::svt::TabAlignment i_eAlignment ); + +protected: + virtual void GetFocus(); + +private: + ToolPanelDeck m_aToolPanelDeck; + OptionsWindow m_aDemoOptions; }; //============================================================================= -//= PanelDemoMainWindow +//= PanelDemoMainWindow - implementation +//============================================================================= +//----------------------------------------------------------------------------- +OptionsWindow::OptionsWindow( PanelDemoMainWindow& i_rParent ) + :Window( &i_rParent, WB_BORDER | WB_DIALOGCONTROL ) + ,m_aAlignLeft( this, WB_GROUP ) + ,m_aAlignRight( this, 0 ) +{ + SetBorderStyle( WINDOW_BORDER_MONO ); + const Color aFaceColor( GetSettings().GetStyleSettings().GetFaceColor() ); + SetBackground( aFaceColor ); + + RadioButton* pRadios[] = + { + &m_aAlignLeft, &m_aAlignRight + }; + const sal_Char* pTexts[] = + { + "Left", "Right" + }; + for ( size_t i=0; i < sizeof( pRadios ) / sizeof( pRadios[0] ); ++i ) + { + pRadios[i]->SetText( String::CreateFromAscii( pTexts[i] ) ); + pRadios[i]->SetControlBackground( aFaceColor ); + pRadios[i]->Show(); + pRadios[i]->SetToggleHdl( LINK( this, OptionsWindow, OnAlignmentChanged ) ); + } + + m_aAlignRight.Check(); + + Show(); +} + +//----------------------------------------------------------------------------- +void OptionsWindow::GetFocus() +{ + Window::GetFocus(); + RadioButton* pRadios[] = + { + &m_aAlignLeft, &m_aAlignRight + }; + for ( size_t i=0; i < sizeof( pRadios ) / sizeof( pRadios[0] ); ++i ) + { + if ( pRadios[i]->IsChecked() ) + { + pRadios[i]->GrabFocus(); + break; + } + } +} + +//----------------------------------------------------------------------------- +void OptionsWindow::Resize() +{ + Window::Resize(); + + const Size aSpacing( LogicToPixel( Size( 3, 3 ), MAP_APPFONT ) ); + const Size aOutputSize( GetOutputSizePixel() ); + + const Size aRadioSize( + aOutputSize.Width() - 2 * aSpacing.Width(), + LogicToPixel( Size( 0, 8 ), MAP_APPFONT ).Height() + ); + + Point aRadioPos( aSpacing.Width(), aSpacing.Height() ); + RadioButton* pRadios[] = + { + &m_aAlignLeft, &m_aAlignRight + }; + for ( size_t i=0; i < sizeof( pRadios ) / sizeof( pRadios[0] ); ++i ) + { + pRadios[i]->SetPosSizePixel( aRadioPos, aRadioSize ); + aRadioPos.Move( 0, aRadioSize.Height() + aSpacing.Height() ); + } +} + +//----------------------------------------------------------------------------- +IMPL_LINK( OptionsWindow, OnAlignmentChanged, void*, /**/ ) +{ + PanelDemoMainWindow& rController( dynamic_cast< PanelDemoMainWindow& >( *GetParent() ) ); + if ( m_aAlignLeft.IsChecked() ) + { + rController.AlignTabs( TABS_LEFT ); + } + else if ( m_aAlignRight.IsChecked() ) + { + rController.AlignTabs( TABS_RIGHT ); + } + return 0L; +} +//============================================================================= +//= PanelDemoMainWindow - implementation //============================================================================= //----------------------------------------------------------------------------- PanelDemoMainWindow::PanelDemoMainWindow() :WorkWindow( NULL, WB_APP | WB_STDWORK | WB_CLIPCHILDREN ) ,m_aToolPanelDeck( *this, WB_BORDER ) + ,m_aDemoOptions( *this ) { + const Color aFaceColor( GetSettings().GetStyleSettings().GetFaceColor() ); + + SetBackground( aFaceColor ); + m_aToolPanelDeck.SetPosSizePixel( Point( 20, 20 ), Size( 500, 300 ) ); m_aToolPanelDeck.SetBorderStyle( WINDOW_BORDER_MONO ); @@ -206,17 +369,22 @@ PanelDemoMainWindow::PanelDemoMainWindow() m_aToolPanelDeck.ActivatePanel( 0 ); m_aToolPanelDeck.Show(); - SetBackground( Color( COL_LIGHTGRAY ) ); - SetText( String::CreateFromAscii( "ToolPanelDeck Demo Application" ) ); Show(); + AlignTabs( TABS_RIGHT ); + Help::EnableQuickHelp(); + + GetSystemWindow()->GetTaskPaneList()->AddWindow( &m_aToolPanelDeck ); + GetSystemWindow()->GetTaskPaneList()->AddWindow( &m_aDemoOptions ); } //----------------------------------------------------------------------------- PanelDemoMainWindow::~PanelDemoMainWindow() { + GetSystemWindow()->GetTaskPaneList()->RemoveWindow( &m_aDemoOptions ); + GetSystemWindow()->GetTaskPaneList()->RemoveWindow( &m_aToolPanelDeck ); } //----------------------------------------------------------------------------- @@ -231,9 +399,20 @@ void PanelDemoMainWindow::Resize() { WorkWindow::Resize(); Size aSize( GetOutputSizePixel() ); - aSize.Width() -= 40; + aSize.Width() -= 140; aSize.Height() -= 40; m_aToolPanelDeck.SetPosSizePixel( Point( 20, 20 ), aSize ); + + m_aDemoOptions.SetPosSizePixel( + Point( 20 + aSize.Width(), 20 ), + Size( 100, aSize.Height() ) + ); +} + +//----------------------------------------------------------------------------- +void PanelDemoMainWindow::AlignTabs( const ::svt::TabAlignment i_eAlignment ) +{ + m_aToolPanelDeck.SetLayouter( PDeckLayouter( new TabDeckLayouter( i_eAlignment, m_aToolPanelDeck ) ) ); } //============================================================================= @@ -260,9 +439,17 @@ Reference< XMultiServiceFactory > PanelDemo::createApplicationServiceManager() //----------------------------------------------------------------------------- void __EXPORT PanelDemo::Main() { + // create service factory Reference< XMultiServiceFactory > xSMgr = createApplicationServiceManager(); ::comphelper::setProcessServiceFactory( xSMgr ); + // initialize the UCB + Sequence< Any > aArgs(2); + aArgs[0] <<= rtl::OUString::createFromAscii( "Local" ); + aArgs[1] <<= rtl::OUString::createFromAscii( "Office" ); + ::ucbhelper::ContentBroker::initialize( xSMgr, aArgs ); + + // run the application PanelDemoMainWindow aWindow; Execute(); } |