diff options
author | Maxim Monastirsky <momonasmon@gmail.com> | 2017-02-12 22:14:48 +0200 |
---|---|---|
committer | Maxim Monastirsky <momonasmon@gmail.com> | 2017-02-12 21:56:29 +0000 |
commit | 81d4fbc0daa54889ccb09e6a3fadff9c70d99448 (patch) | |
tree | e76c9281a295dda0e1b25316efc77640ad3dc3bf /vcl | |
parent | e5aa7a5b5753c57969fc2e17fb334781bb2a0481 (diff) |
tdf#42029 Use a floating toolbar to show clipped items
Change-Id: I6b366f115258ef8497807163179d3e08ab3d5e6f
Reviewed-on: https://gerrit.libreoffice.org/34180
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Maxim Monastirsky <momonasmon@gmail.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/toolbox.h | 1 | ||||
-rw-r--r-- | vcl/source/window/floatwin.cxx | 14 | ||||
-rw-r--r-- | vcl/source/window/toolbox.cxx | 20 | ||||
-rw-r--r-- | vcl/source/window/toolbox2.cxx | 48 |
4 files changed, 47 insertions, 36 deletions
diff --git a/vcl/inc/toolbox.h b/vcl/inc/toolbox.h index 7be02bf73cab..5ea8b50a4415 100644 --- a/vcl/inc/toolbox.h +++ b/vcl/inc/toolbox.h @@ -128,6 +128,7 @@ struct ImplToolBoxPrivateData // the optional custom menu VclPtr<PopupMenu> mpMenu; + Rectangle maMenuRect; ToolBoxMenuType maMenuType; ImplSVEvent * mnEventId; diff --git a/vcl/source/window/floatwin.cxx b/vcl/source/window/floatwin.cxx index 3e9cd967edf1..41e12ea67aea 100644 --- a/vcl/source/window/floatwin.cxx +++ b/vcl/source/window/floatwin.cxx @@ -708,16 +708,16 @@ void FloatingWindow::StartPopupMode( const Rectangle& rRect, FloatWinPopupFlags void FloatingWindow::StartPopupMode( ToolBox* pBox, FloatWinPopupFlags nFlags ) { + mpImplData->mpBox = pBox; + // get selected button sal_uInt16 nItemId = pBox->GetDownItemId(); - if ( !nItemId ) - return; - mpImplData->mpBox = pBox; - pBox->ImplFloatControl( true, this ); + if ( nItemId ) + pBox->ImplFloatControl( true, this ); // retrieve some data from the ToolBox - Rectangle aRect = pBox->GetItemRect( nItemId ); + Rectangle aRect = nItemId ? pBox->GetItemRect( nItemId ) : pBox->GetOverflowRect(); Point aPos; // convert to parent's screen coordinates aPos = GetParent()->OutputToScreenPixel( GetParent()->AbsoluteScreenToOutputPixel( pBox->OutputToAbsoluteScreenPixel( aRect.TopLeft() ) ) ); @@ -793,6 +793,10 @@ void FloatingWindow::ImplEndPopupMode( FloatWinPopupEndFlags nFlags, const VclPt if (mpImplData && mpImplData->mpBox) { mpImplData->mpBox->ImplFloatControl( false, this ); + // if the parent ToolBox is in popup mode, it should be closed too. + if ( GetDockingManager()->IsInPopupMode( mpImplData->mpBox ) ) + nFlags |= FloatWinPopupEndFlags::CloseAll; + mpImplData->mpBox = nullptr; } diff --git a/vcl/source/window/toolbox.cxx b/vcl/source/window/toolbox.cxx index 6cf2f6a89c93..a6e3d5640e6f 100644 --- a/vcl/source/window/toolbox.cxx +++ b/vcl/source/window/toolbox.cxx @@ -3947,7 +3947,10 @@ void ToolBox::MouseButtonDown( const MouseEvent& rMEvt ) // menu button hit ? if( mpData->maMenubuttonItem.maRect.IsInside( aMousePos ) && ImplHasClippedItems() ) { - ExecuteCustomMenu(); + if ( maMenuButtonHdl.IsSet() ) + maMenuButtonHdl.Call( this ); + else + ExecuteCustomMenu( mpData->maMenubuttonItem.maRect ); return; } @@ -4405,8 +4408,6 @@ bool ToolBox::EventNotify( NotifyEvent& rNEvt ) void ToolBox::Command( const CommandEvent& rCEvt ) { - maCommandHandler.Call( &rCEvt ); - // depict StartDrag on MouseButton/Left/Alt if ( (rCEvt.GetCommand() == CommandEventId::StartDrag) && rCEvt.IsMouseEvent() && mbCustomize && !mbDragging && !mbDrag && !mbSelection && @@ -4462,6 +4463,11 @@ void ToolBox::Command( const CommandEvent& rCEvt ) } } } + else if ( rCEvt.GetCommand() == CommandEventId::ContextMenu ) + { + ExecuteCustomMenu( Rectangle( rCEvt.GetMousePosPixel(), rCEvt.GetMousePosPixel() ) ); + return; + } DockingWindow::Command( rCEvt ); } @@ -5052,13 +5058,15 @@ bool ToolBox::ImplOpenItem( vcl::KeyCode aKeyCode ) || ((nCode == KEY_UP || nCode == KEY_DOWN) && !IsHorizontal()) ) return false; - if( IsMenuEnabled() && mpData->mbMenubuttonSelected ) + if( mpData->mbMenubuttonSelected ) { if( ImplCloseLastPopup( GetParent() ) ) return bRet; - UpdateCustomMenu(); - mpData->mnEventId = Application::PostUserEvent( LINK( this, ToolBox, ImplCallExecuteCustomMenu ), nullptr, true ); + if ( maMenuButtonHdl.IsSet() ) + maMenuButtonHdl.Call( this ); + else + ExecuteCustomMenu( mpData->maMenubuttonItem.maRect ); } else if( mnHighItemId && ImplGetItem( mnHighItemId ) && (ImplGetItem( mnHighItemId )->mnBits & ToolBoxItemBits::DROPDOWN) ) diff --git a/vcl/source/window/toolbox2.cxx b/vcl/source/window/toolbox2.cxx index 10cede7eeeac..ec58bbd8c415 100644 --- a/vcl/source/window/toolbox2.cxx +++ b/vcl/source/window/toolbox2.cxx @@ -873,6 +873,11 @@ Rectangle ToolBox::GetItemPosRect( sal_uInt16 nPos ) const return Rectangle(); } +Rectangle ToolBox::GetOverflowRect() const +{ + return mpData->maMenubuttonItem.maRect; +} + bool ToolBox::ImplHasExternalMenubutton() { // check if the borderwindow (i.e. the decoration) provides the menu button @@ -1317,6 +1322,16 @@ void ToolBox::ShowItem( sal_uInt16 nItemId, bool bVisible ) } } +bool ToolBox::IsItemClipped( sal_uInt16 nItemId ) const +{ + ImplToolItem* pItem = ImplGetItem( nItemId ); + + if ( pItem ) + return pItem->IsClipped(); + else + return false; +} + bool ToolBox::IsItemVisible( sal_uInt16 nItemId ) const { ImplToolItem* pItem = ImplGetItem( nItemId ); @@ -1564,7 +1579,7 @@ PopupMenu* ToolBox::GetMenu() const return mpData == nullptr ? nullptr : mpData->mpMenu; } -void ToolBox::SetMenuButtonHdl( const Link<ToolBox *, void>& rLink ) +void ToolBox::SetMenuExecuteHdl( const Link<ToolBox *, void>& rLink ) { mpData->maMenuButtonHdl = rLink; } @@ -1604,19 +1619,7 @@ void ToolBox::UpdateCustomMenu() return; PopupMenu *pMenu = GetMenu(); - - sal_uInt16 i = 0; - // remove old entries - while( i < pMenu->GetItemCount() ) - { - if( pMenu->GetItemId( i ) >= TOOLBOX_MENUITEM_START ) - { - pMenu->RemoveItem( i ); - i = 0; - } - else - i++; - } + pMenu->Clear(); // add menu items: first the overflow items, then hidden items, both in the // order they would usually appear in the toolbar. Separators that would be @@ -1680,13 +1683,6 @@ IMPL_LINK_NOARG(ToolBox, ImplCallExecuteCustomMenu, void*, void) // call button handler to allow for menu customization mpData->maMenuButtonHdl.Call( this ); - // We specifically only register this event listener when executing our - // overflow menu (and remove it directly afterwards), as the same menu - // is reused for both the overflow menu (as managed here in ToolBox), - // but also by ToolBarManager for its context menu. If we leave event - // listeners alive beyond when the menu is showing in the desired mode - // then duplicate events can happen as the context menu "duplicates" - // items from the overflow menu, which both listeners would then act on. GetMenu()->AddEventListener( LINK( this, ToolBox, ImplCustomMenuListener ) ); // make sure all disabled entries will be shown @@ -1697,9 +1693,10 @@ IMPL_LINK_NOARG(ToolBox, ImplCallExecuteCustomMenu, void*, void) bool bBorderDel = false; VclPtr<vcl::Window> pWin = this; - Rectangle aMenuRect = mpData->maMenubuttonItem.maRect; + Rectangle aMenuRect = mpData->maMenuRect; + mpData->maMenuRect.SetEmpty(); VclPtr<ImplBorderWindow> pBorderWin; - if( IsFloatingMode() ) + if( aMenuRect.IsEmpty() && IsFloatingMode() ) { // custom menu is placed in the decoration pBorderWin = dynamic_cast<ImplBorderWindow*>( GetWindow( GetWindowType::Border ) ); @@ -1732,13 +1729,14 @@ IMPL_LINK_NOARG(ToolBox, ImplCallExecuteCustomMenu, void*, void) } } -void ToolBox::ExecuteCustomMenu() +void ToolBox::ExecuteCustomMenu( const Rectangle& rRect ) { if( IsMenuEnabled() ) { + UpdateCustomMenu(); // handle custom menu asynchronously // to avoid problems if the toolbox is closed during menu execute - UpdateCustomMenu(); + mpData->maMenuRect = rRect; mpData->mnEventId = Application::PostUserEvent( LINK( this, ToolBox, ImplCallExecuteCustomMenu ), nullptr, true ); } } |