GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / svtools / source / toolpanel / toolpaneldeck.cxx
blob81b6dacfdb8efcb7411c09eca6569a0bee839f84
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "dummypanel.hxx"
22 #include "toolpanelcollection.hxx"
23 #include "paneldecklisteners.hxx"
24 #include "toolpaneldeckpeer.hxx"
25 #include "svtools/toolpanel/toolpaneldeck.hxx"
26 #include "svtools/toolpanel/tablayouter.hxx"
27 #include "svtools/toolpanel/drawerlayouter.hxx"
29 #include <com/sun/star/accessibility/XAccessible.hpp>
30 #include <com/sun/star/accessibility/AccessibleRole.hpp>
32 #include <tools/diagnose_ex.h>
34 #include <boost/optional.hpp>
36 //........................................................................
37 namespace svt
39 //........................................................................
41 using ::com::sun::star::uno::Reference;
42 using ::com::sun::star::accessibility::XAccessible;
43 using ::com::sun::star::awt::XWindowPeer;
44 using ::com::sun::star::uno::UNO_SET_THROW;
46 namespace AccessibleRole = ::com::sun::star::accessibility::AccessibleRole;
48 enum DeckAction
50 /// activates the first panel
51 ACTION_ACTIVATE_FIRST,
52 // activates the panel after the currently active panel
53 ACTION_ACTIVATE_NEXT,
54 // activates the panel before the currently active panel
55 ACTION_ACTIVATE_PREV,
56 // activates the last panel
57 ACTION_ACTIVATE_LAST,
59 // toggles the focus between the active panel and the panel selector
60 ACTION_TOGGLE_FOCUS,
63 //====================================================================
64 //= ToolPanelDeck_Impl
65 //====================================================================
66 class ToolPanelDeck_Impl : public IToolPanelDeckListener
68 public:
69 ToolPanelDeck_Impl( ToolPanelDeck& i_rDeck )
70 :m_rDeck( i_rDeck )
71 ,m_aPanelAnchor( &i_rDeck, WB_DIALOGCONTROL | WB_CHILDDLGCTRL )
72 ,m_aPanels()
73 ,m_pDummyPanel( new DummyPanel )
74 ,m_pLayouter()
75 ,m_bInDtor( false )
76 ,m_pAccessibleParent( NULL )
78 m_aPanels.AddListener( *this );
79 m_aPanelAnchor.Show();
80 m_aPanelAnchor.SetAccessibleRole( AccessibleRole::PANEL );
83 virtual ~ToolPanelDeck_Impl()
85 m_bInDtor = true;
88 PDeckLayouter GetLayouter() const { return m_pLayouter; }
89 void SetLayouter( const PDeckLayouter& i_pNewLayouter );
91 Window& GetPanelWindowAnchor() { return m_aPanelAnchor; }
92 const Window& GetPanelWindowAnchor() const { return m_aPanelAnchor; }
94 bool IsDead() const { return m_bInDtor; }
96 /// notifies our listeners that we're going to die. Only to be called from with our anti-impl's destructor
97 void NotifyDying()
99 m_aPanels.RemoveListener( *this );
100 m_aListeners.Dying();
103 // IToolPanelDeck equivalents
104 size_t GetPanelCount() const;
105 PToolPanel GetPanel( const size_t i_nPos ) const;
106 ::boost::optional< size_t >
107 GetActivePanel() const;
108 void ActivatePanel( const ::boost::optional< size_t >& i_rPanel );
109 size_t InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition );
110 PToolPanel RemovePanel( const size_t i_nPosition );
111 void AddListener( IToolPanelDeckListener& i_rListener );
112 void RemoveListener( IToolPanelDeckListener& i_rListener );
114 /// re-layouts everything
115 void LayoutAll() { ImplDoLayout(); }
117 void DoAction( const DeckAction i_eAction );
119 bool FocusActivePanel();
121 void SetAccessibleParentWindow( Window* i_pAccessibleParent );
122 Window* GetAccessibleParentWindow() const { return m_pAccessibleParent; }
124 protected:
125 // IToolPanelDeckListener
126 virtual void PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition );
127 virtual void PanelRemoved( const size_t i_nPosition );
128 virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive );
129 virtual void LayouterChanged( const PDeckLayouter& i_rNewLayouter );
130 virtual void Dying();
132 private:
133 void ImplDoLayout();
134 PToolPanel GetActiveOrDummyPanel_Impl();
136 private:
137 ToolPanelDeck& m_rDeck;
138 Window m_aPanelAnchor;
139 ToolPanelCollection m_aPanels;
140 PToolPanel m_pDummyPanel;
141 PanelDeckListeners m_aListeners;
142 PDeckLayouter m_pLayouter;
143 bool m_bInDtor;
144 Window* m_pAccessibleParent;
147 //--------------------------------------------------------------------
148 PToolPanel ToolPanelDeck_Impl::GetActiveOrDummyPanel_Impl()
150 ::boost::optional< size_t > aActivePanel( m_aPanels.GetActivePanel() );
151 if ( !aActivePanel )
152 return m_pDummyPanel;
153 return m_aPanels.GetPanel( *aActivePanel );
156 //--------------------------------------------------------------------
157 void ToolPanelDeck_Impl::SetLayouter( const PDeckLayouter& i_pNewLayouter )
159 ENSURE_OR_RETURN_VOID( i_pNewLayouter.get(), "invalid layouter" );
161 if ( m_pLayouter.get() )
162 m_pLayouter->Destroy();
164 m_pLayouter = i_pNewLayouter;
166 ImplDoLayout();
168 m_aListeners.LayouterChanged( m_pLayouter );
171 //--------------------------------------------------------------------
172 size_t ToolPanelDeck_Impl::GetPanelCount() const
174 return m_aPanels.GetPanelCount();
177 //--------------------------------------------------------------------
178 PToolPanel ToolPanelDeck_Impl::GetPanel( const size_t i_nPos ) const
180 return m_aPanels.GetPanel( i_nPos );
183 //--------------------------------------------------------------------
184 ::boost::optional< size_t > ToolPanelDeck_Impl::GetActivePanel() const
186 return m_aPanels.GetActivePanel();
189 //--------------------------------------------------------------------
190 void ToolPanelDeck_Impl::ActivatePanel( const ::boost::optional< size_t >& i_rPanel )
192 m_aPanels.ActivatePanel( i_rPanel );
195 //--------------------------------------------------------------------
196 size_t ToolPanelDeck_Impl::InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition )
198 return m_aPanels.InsertPanel( i_pPanel, i_nPosition );
201 //--------------------------------------------------------------------
202 PToolPanel ToolPanelDeck_Impl::RemovePanel( const size_t i_nPosition )
204 return m_aPanels.RemovePanel( i_nPosition );
207 //--------------------------------------------------------------------
208 void ToolPanelDeck_Impl::ImplDoLayout()
210 const Rectangle aDeckPlayground( Point(), m_rDeck.GetOutputSizePixel() );
212 // ask the layouter what is left for our panel, and position the panel container window appropriately
213 Rectangle aPlaygroundArea( aDeckPlayground );
214 OSL_ENSURE( m_pLayouter.get(), "ToolPanelDeck_Impl::ImplDoLayout: no layouter!" );
215 if ( m_pLayouter.get() )
217 aPlaygroundArea = m_pLayouter->Layout( aDeckPlayground );
219 m_aPanelAnchor.SetPosSizePixel( aPlaygroundArea.TopLeft(), aPlaygroundArea.GetSize() );
221 // position the active panel
222 const PToolPanel pActive( GetActiveOrDummyPanel_Impl() );
223 pActive->SetSizePixel( m_aPanelAnchor.GetOutputSizePixel() );
226 //--------------------------------------------------------------------
227 void ToolPanelDeck_Impl::AddListener( IToolPanelDeckListener& i_rListener )
229 m_aListeners.AddListener( i_rListener );
232 //--------------------------------------------------------------------
233 void ToolPanelDeck_Impl::RemoveListener( IToolPanelDeckListener& i_rListener )
235 m_aListeners.RemoveListener( i_rListener );
238 //--------------------------------------------------------------------
239 void ToolPanelDeck_Impl::DoAction( const DeckAction i_eAction )
241 const size_t nPanelCount( m_aPanels.GetPanelCount() );
242 ::boost::optional< size_t > aActivatePanel;
243 ::boost::optional< size_t > aCurrentPanel( GetActivePanel() );
245 switch ( i_eAction )
247 case ACTION_ACTIVATE_FIRST:
248 if ( nPanelCount > 0 )
249 aActivatePanel = 0;
250 break;
251 case ACTION_ACTIVATE_PREV:
252 if ( !aCurrentPanel && ( nPanelCount > 0 ) )
253 aActivatePanel = nPanelCount - 1;
254 else if ( !!aCurrentPanel && ( *aCurrentPanel > 0 ) )
255 aActivatePanel = *aCurrentPanel - 1;
256 break;
257 case ACTION_ACTIVATE_NEXT:
258 if ( !aCurrentPanel && ( nPanelCount > 0 ) )
259 aActivatePanel = 0;
260 else if ( !!aCurrentPanel && ( *aCurrentPanel < nPanelCount - 1 ) )
261 aActivatePanel = *aCurrentPanel + 1;
262 break;
263 case ACTION_ACTIVATE_LAST:
264 if ( nPanelCount > 0 )
265 aActivatePanel = nPanelCount - 1;
266 break;
267 case ACTION_TOGGLE_FOCUS:
269 PToolPanel pActivePanel( GetActiveOrDummyPanel_Impl() );
270 if ( !m_aPanelAnchor.HasChildPathFocus() )
271 pActivePanel->GrabFocus();
272 else
273 GetLayouter()->SetFocusToPanelSelector();
275 break;
278 if ( !!aActivatePanel )
280 ActivatePanel( aActivatePanel );
284 //--------------------------------------------------------------------
285 bool ToolPanelDeck_Impl::FocusActivePanel()
287 ::boost::optional< size_t > aActivePanel( m_aPanels.GetActivePanel() );
288 if ( !aActivePanel )
289 return false;
291 PToolPanel pActivePanel( m_aPanels.GetPanel( *aActivePanel ) );
292 pActivePanel->GrabFocus();
293 return true;
296 //--------------------------------------------------------------------
297 void ToolPanelDeck_Impl::PanelInserted( const PToolPanel& i_pPanel, const size_t i_nPosition )
299 // multiplex to our own listeners
300 m_aListeners.PanelInserted( i_pPanel, i_nPosition );
303 //--------------------------------------------------------------------
304 void ToolPanelDeck_Impl::PanelRemoved( const size_t i_nPosition )
306 // multiplex to our own listeners
307 m_aListeners.PanelRemoved( i_nPosition );
310 //--------------------------------------------------------------------
311 void ToolPanelDeck_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive )
313 // hide the old panel
314 if ( !!i_rOldActive )
316 const PToolPanel pOldActive( m_aPanels.GetPanel( *i_rOldActive ) );
317 pOldActive->Deactivate();
320 // position and show the new panel
321 const PToolPanel pNewActive( !i_rNewActive ? m_pDummyPanel : m_aPanels.GetPanel( *i_rNewActive ) );
322 pNewActive->Activate( m_aPanelAnchor );
323 pNewActive->GrabFocus();
325 // resize the panel (cannot guarantee it has ever been resized before
326 pNewActive->SetSizePixel( m_aPanelAnchor.GetOutputSizePixel() );
328 // multiplex to our own listeners
329 m_aListeners.ActivePanelChanged( i_rOldActive, i_rNewActive );
332 //--------------------------------------------------------------------
333 void ToolPanelDeck_Impl::LayouterChanged( const PDeckLayouter& i_rNewLayouter )
335 // not interested in
336 (void)i_rNewLayouter;
339 //--------------------------------------------------------------------
340 void ToolPanelDeck_Impl::Dying()
342 // not interested in. Since the ToolPanelCollection is our member, this just means we ourself
343 // are dying, and we already sent this notification in our dtor.
346 //--------------------------------------------------------------------
347 void ToolPanelDeck_Impl::SetAccessibleParentWindow( Window* i_pAccessibleParent )
349 m_pAccessibleParent = i_pAccessibleParent;
352 //====================================================================
353 //= ToolPanelDeck
354 //====================================================================
355 //--------------------------------------------------------------------
356 ToolPanelDeck::ToolPanelDeck( Window& i_rParent, const WinBits i_nStyle )
357 :Control( &i_rParent, i_nStyle )
358 ,m_pImpl( new ToolPanelDeck_Impl( *this ) )
360 // use a default layouter
361 // SetLayouter( PDeckLayouter( new TabDeckLayouter( *this, *this, TABS_RIGHT, TABITEM_IMAGE_AND_TEXT ) ) );
362 SetLayouter( PDeckLayouter( new DrawerDeckLayouter( *this, *this ) ) );
365 //--------------------------------------------------------------------
366 ToolPanelDeck::~ToolPanelDeck()
368 m_pImpl->NotifyDying();
369 GetLayouter()->Destroy();
371 Hide();
372 for ( size_t i=0; i<GetPanelCount(); ++i )
374 PToolPanel pPanel( GetPanel( i ) );
375 pPanel->Dispose();
379 //--------------------------------------------------------------------
380 size_t ToolPanelDeck::GetPanelCount() const
382 return m_pImpl->GetPanelCount();
385 //--------------------------------------------------------------------
386 PToolPanel ToolPanelDeck::GetPanel( const size_t i_nPos ) const
388 return m_pImpl->GetPanel( i_nPos );
391 //--------------------------------------------------------------------
392 ::boost::optional< size_t > ToolPanelDeck::GetActivePanel() const
394 return m_pImpl->GetActivePanel();
397 //--------------------------------------------------------------------
398 void ToolPanelDeck::ActivatePanel( const ::boost::optional< size_t >& i_rPanel )
400 m_pImpl->ActivatePanel( i_rPanel );
403 //--------------------------------------------------------------------
404 size_t ToolPanelDeck::InsertPanel( const PToolPanel& i_pPanel, const size_t i_nPosition )
406 return m_pImpl->InsertPanel( i_pPanel, i_nPosition );
409 //--------------------------------------------------------------------
410 PToolPanel ToolPanelDeck::RemovePanel( const size_t i_nPosition )
412 return m_pImpl->RemovePanel( i_nPosition );
415 //--------------------------------------------------------------------
416 PDeckLayouter ToolPanelDeck::GetLayouter() const
418 return m_pImpl->GetLayouter();
421 //--------------------------------------------------------------------
422 void ToolPanelDeck::SetLayouter( const PDeckLayouter& i_pNewLayouter )
424 return m_pImpl->SetLayouter( i_pNewLayouter );
427 //--------------------------------------------------------------------
428 void ToolPanelDeck::AddListener( IToolPanelDeckListener& i_rListener )
430 m_pImpl->AddListener( i_rListener );
433 //--------------------------------------------------------------------
434 void ToolPanelDeck::RemoveListener( IToolPanelDeckListener& i_rListener )
436 m_pImpl->RemoveListener( i_rListener );
439 //--------------------------------------------------------------------
440 Window& ToolPanelDeck::GetPanelWindowAnchor()
442 return m_pImpl->GetPanelWindowAnchor();
445 //--------------------------------------------------------------------
446 const Window& ToolPanelDeck::GetPanelWindowAnchor() const
448 return m_pImpl->GetPanelWindowAnchor();
451 //--------------------------------------------------------------------
452 void ToolPanelDeck::Resize()
454 Control::Resize();
455 m_pImpl->LayoutAll();
458 //--------------------------------------------------------------------
459 long ToolPanelDeck::Notify( NotifyEvent& i_rNotifyEvent )
461 bool bHandled = false;
462 if ( i_rNotifyEvent.GetType() == EVENT_KEYINPUT )
464 const KeyEvent* pEvent = i_rNotifyEvent.GetKeyEvent();
465 const KeyCode& rKeyCode = pEvent->GetKeyCode();
466 if ( rKeyCode.GetModifier() == KEY_MOD1 )
468 bHandled = true;
469 switch ( rKeyCode.GetCode() )
471 case KEY_HOME:
472 m_pImpl->DoAction( ACTION_ACTIVATE_FIRST );
473 break;
474 case KEY_PAGEUP:
475 m_pImpl->DoAction( ACTION_ACTIVATE_PREV );
476 break;
477 case KEY_PAGEDOWN:
478 m_pImpl->DoAction( ACTION_ACTIVATE_NEXT );
479 break;
480 case KEY_END:
481 m_pImpl->DoAction( ACTION_ACTIVATE_LAST );
482 break;
483 default:
484 bHandled = false;
485 break;
488 else if ( rKeyCode.GetModifier() == ( KEY_MOD1 | KEY_SHIFT ) )
490 if ( rKeyCode.GetCode() == KEY_E )
492 m_pImpl->DoAction( ACTION_TOGGLE_FOCUS );
493 bHandled = true;
498 if ( bHandled )
499 return 1;
501 return Control::Notify( i_rNotifyEvent );
504 //--------------------------------------------------------------------
505 void ToolPanelDeck::GetFocus()
507 Control::GetFocus();
508 if ( m_pImpl->IsDead() )
509 return;
510 if ( !m_pImpl->FocusActivePanel() )
512 PDeckLayouter pLayouter( GetLayouter() );
513 ENSURE_OR_RETURN_VOID( pLayouter.get(), "ToolPanelDeck::GetFocus: no layouter?!" );
514 pLayouter->SetFocusToPanelSelector();
518 //--------------------------------------------------------------------
519 void ToolPanelDeck::SetAccessibleParentWindow( Window* i_pAccessibleParent )
521 m_pImpl->SetAccessibleParentWindow( i_pAccessibleParent );
524 //--------------------------------------------------------------------
525 Window* ToolPanelDeck::GetAccessibleParentWindow() const
527 Window* pAccessibleParent( m_pImpl->GetAccessibleParentWindow() );
528 if ( !pAccessibleParent )
529 pAccessibleParent = Window::GetAccessibleParentWindow();
530 return pAccessibleParent;
533 //--------------------------------------------------------------------
534 Reference< XWindowPeer > ToolPanelDeck::GetComponentInterface( sal_Bool i_bCreate )
536 Reference< XWindowPeer > xWindowPeer( Control::GetComponentInterface( sal_False ) );
537 if ( !xWindowPeer.is() && i_bCreate )
539 xWindowPeer.set( new ToolPanelDeckPeer( *this ) );
540 SetComponentInterface( xWindowPeer );
542 return xWindowPeer;
545 //........................................................................
546 } // namespace svt
547 //........................................................................
549 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */