summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorMaxim Monastirsky <momonasmon@gmail.com>2017-02-12 22:14:48 +0200
committerMaxim Monastirsky <momonasmon@gmail.com>2017-02-12 21:56:29 +0000
commit81d4fbc0daa54889ccb09e6a3fadff9c70d99448 (patch)
treee76c9281a295dda0e1b25316efc77640ad3dc3bf /vcl
parente5aa7a5b5753c57969fc2e17fb334781bb2a0481 (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.h1
-rw-r--r--vcl/source/window/floatwin.cxx14
-rw-r--r--vcl/source/window/toolbox.cxx20
-rw-r--r--vcl/source/window/toolbox2.cxx48
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 );
}
}