cui/uiconfig/ui/hyperlinkdialog.ui | 1 vcl/inc/verticaltabctrl.hxx | 2 - vcl/source/control/imivctl.hxx | 2 - vcl/source/control/imivctl1.cxx | 67 +++++++++++++++++-------------------- vcl/source/control/ivctrl.cxx | 4 +- vcl/source/window/builder.cxx | 14 +++++++ 6 files changed, 50 insertions(+), 40 deletions(-)
New commits: commit b64751ba28fd69fb2a93a21b10a92b68f4dd2097 Author: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> AuthorDate: Fri Apr 26 10:47:00 2024 +0200 Commit: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> CommitDate: Mon Apr 29 07:52:27 2024 +0200 tdf#99528 Properly layout vertical tabs without icons Implement a proper list mode for VerticalTabControl. Before this was only used in the Hyperlink dialog with large icons. Change-Id: I227643392ef4840a705555b379734e2993db0f13 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166702 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> diff --git a/cui/uiconfig/ui/hyperlinkdialog.ui b/cui/uiconfig/ui/hyperlinkdialog.ui index b8819f74d31a..c0eb4f085906 100644 --- a/cui/uiconfig/ui/hyperlinkdialog.ui +++ b/cui/uiconfig/ui/hyperlinkdialog.ui @@ -123,6 +123,7 @@ <property name="hexpand">True</property> <property name="vexpand">True</property> <property name="tab-pos">left</property> + <property name="group-name">icons</property> <child> <!-- n-columns=1 n-rows=1 --> <object class="GtkGrid"> diff --git a/vcl/inc/verticaltabctrl.hxx b/vcl/inc/verticaltabctrl.hxx index c5942799b381..666bef474172 100644 --- a/vcl/inc/verticaltabctrl.hxx +++ b/vcl/inc/verticaltabctrl.hxx @@ -49,7 +49,7 @@ class VerticalTabControl final : public VclHBox VerticalTabPageData* GetPageData(const SvxIconChoiceCtrlEntry* pEntry) const; public: - VerticalTabControl(vcl::Window* pParent); + VerticalTabControl(vcl::Window* pParent, bool bWithIcons); virtual ~VerticalTabControl() override; virtual void dispose() override; diff --git a/vcl/source/control/imivctl.hxx b/vcl/source/control/imivctl.hxx index 5a052c083efa..c29068442728 100644 --- a/vcl/source/control/imivctl.hxx +++ b/vcl/source/control/imivctl.hxx @@ -303,7 +303,7 @@ public: SvxIconChoiceCtrlEntry* GetCurEntry() const { return pCursor; } void SetCursor( SvxIconChoiceCtrlEntry* ); - SvxIconChoiceCtrlEntry* GetEntry( const Point& rDocPos, bool bHit = false ); + SvxIconChoiceCtrlEntry* GetEntry( const Point& rDocPos ); void MakeEntryVisible( SvxIconChoiceCtrlEntry* pEntry, bool bBound = true ); diff --git a/vcl/source/control/imivctl1.cxx b/vcl/source/control/imivctl1.cxx index 1364dc4f44d0..6508c4fe12c3 100644 --- a/vcl/source/control/imivctl1.cxx +++ b/vcl/source/control/imivctl1.cxx @@ -92,7 +92,7 @@ SvxIconChoiceCtrl_Impl::SvxIconChoiceCtrl_Impl( aVisRectChangedIdle.SetInvokeHandler(LINK(this,SvxIconChoiceCtrl_Impl,VisRectChangedHdl)); Clear( true ); - Size gridSize(100,70); + Size gridSize((nWinStyle & WB_DETAILS) ? 200 : 100, (nWinStyle & WB_DETAILS) ? 20 : 70); if(pView->GetDPIScaleFactor() > 1) { gridSize.setHeight( gridSize.Height() * ( pView->GetDPIScaleFactor()) ); @@ -157,11 +157,6 @@ void SvxIconChoiceCtrl_Impl::SetStyle( WinBits nWinStyle ) eSelectionMode = SelectionMode::NONE; if( !(nWinStyle & (WB_ALIGN_TOP | WB_ALIGN_LEFT))) nWinBits |= WB_ALIGN_LEFT; - if( nWinStyle & WB_DETAILS ) - { - if (!m_pColumns) - SetColumn( 0, SvxIconChoiceCtrlColumnInfo() ); - } } IMPL_LINK( SvxIconChoiceCtrl_Impl, ScrollUpDownHdl, ScrollBar*, pScrollBar, void ) @@ -608,7 +603,7 @@ bool SvxIconChoiceCtrl_Impl::MouseButtonDown( const MouseEvent& rMEvt) if(aDocPos.X()>=aOutputSize.Width() || aDocPos.Y()>=aOutputSize.Height()) return false; ToDocPos( aDocPos ); - SvxIconChoiceCtrlEntry* pEntry = GetEntry( aDocPos, true ); + SvxIconChoiceCtrlEntry* pEntry = GetEntry( aDocPos ); if( pEntry ) MakeEntryVisible( pEntry, false ); @@ -785,7 +780,7 @@ bool SvxIconChoiceCtrl_Impl::MouseMove( const MouseEvent& rMEvt ) return false; else if( nWinBits & WB_HIGHLIGHTFRAME ) { - SvxIconChoiceCtrlEntry* pEntry = GetEntry( aDocPos, true ); + SvxIconChoiceCtrlEntry* pEntry = GetEntry( aDocPos ); SetEntryHighlightFrame( pEntry, false ); } else @@ -1513,7 +1508,7 @@ void SvxIconChoiceCtrl_Impl::SetNoSelection() } } -SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GetEntry( const Point& rDocPos, bool bHit ) +SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GetEntry( const Point& rDocPos ) { CheckBoundingRects(); // search through z-order list from the end @@ -1522,24 +1517,9 @@ SvxIconChoiceCtrlEntry* SvxIconChoiceCtrl_Impl::GetEntry( const Point& rDocPos, { nCount--; SvxIconChoiceCtrlEntry* pEntry = maZOrderList[ nCount ]; - if( pEntry->aRect.Contains( rDocPos ) ) - { - if( bHit ) - { - tools::Rectangle aRect = CalcBmpRect( pEntry ); - aRect.AdjustTop( -3 ); - aRect.AdjustBottom(3 ); - aRect.AdjustLeft( -3 ); - aRect.AdjustRight(3 ); - if( aRect.Contains( rDocPos ) ) - return pEntry; - aRect = CalcTextRect( pEntry ); - if( aRect.Contains( rDocPos ) ) - return pEntry; - } - else - return pEntry; - } + tools::Rectangle aBoundingRect(GetEntryBoundRect(pEntry)); + if( aBoundingRect.Contains( rDocPos ) ) + return pEntry; } return nullptr; } @@ -1585,8 +1565,9 @@ tools::Rectangle SvxIconChoiceCtrl_Impl::CalcBmpRect( SvxIconChoiceCtrlEntry* pE return tools::Rectangle( aPos, aImageSize ); } - case WB_SMALLICON: case WB_DETAILS: + return tools::Rectangle(aPos, Size(0,0)); + case WB_SMALLICON: aPos.AdjustY(( aBound.GetHeight() - aImageSize.Height() ) / 2 ); //TODO: determine horizontal distance to bounding rectangle return tools::Rectangle( aPos, aImageSize ); @@ -1627,8 +1608,10 @@ tools::Rectangle SvxIconChoiceCtrl_Impl::CalcTextRect( SvxIconChoiceCtrlEntry* p aPos.AdjustX((nBoundWidth - aTextSize.Width()) / 2 ); break; - case WB_SMALLICON: case WB_DETAILS: + break; + + case WB_SMALLICON: aPos.AdjustX(aImageSize.Width() ); aPos.AdjustX(HOR_DIST_BMP_STRING ); aPos.AdjustY((nBoundHeight - aTextSize.Height()) / 2 ); @@ -1649,8 +1632,11 @@ tools::Long SvxIconChoiceCtrl_Impl::CalcBoundingWidth() const nWidth = std::max( nStringWidth, aImageSize.Width() ); break; - case WB_SMALLICON: case WB_DETAILS: + nWidth = nStringWidth; + break; + + case WB_SMALLICON: nWidth = aImageSize.Width(); nWidth += HOR_DIST_BMP_STRING; nWidth += nStringWidth; @@ -1672,8 +1658,11 @@ tools::Long SvxIconChoiceCtrl_Impl::CalcBoundingHeight() const nHeight += nStringHeight; break; - case WB_SMALLICON: case WB_DETAILS: + nHeight = nStringHeight; + break; + + case WB_SMALLICON: nHeight = std::max( aImageSize.Height(), nStringHeight ); break; } @@ -2053,10 +2042,13 @@ void SvxIconChoiceCtrl_Impl::DeselectAllBut( SvxIconChoiceCtrlEntry const * pThi Size SvxIconChoiceCtrl_Impl::GetMinGrid() const { + Size aTextSize( pView->GetTextWidth( "XXX" ), pView->GetTextHeight() ); + if (nWinBits & WB_DETAILS) + return Size(aTextSize.Width(), aTextSize.Height()); + Size aMinSize( aImageSize ); aMinSize.AdjustWidth(2 * LROFFS_BOUND ); aMinSize.AdjustHeight(TBOFFS_BOUND ); // single offset is enough (FileDlg) - Size aTextSize( pView->GetTextWidth( "XXX" ), pView->GetTextHeight() ); if( nWinBits & WB_ICON ) { aMinSize.AdjustHeight(VER_DIST_BMP_STRING ); @@ -2122,7 +2114,7 @@ tools::Rectangle SvxIconChoiceCtrl_Impl::CalcMaxTextRect( const SvxIconChoiceCtr if( pEntry->GetTextMode() == SvxIconChoiceCtrlTextMode::Full ) aBoundRect.SetBottom( LONG_MAX ); } - else + else if (nWinBits & WB_SMALLICON) { aBoundRect.SetLeft( aBmpRect.Right() ); aBoundRect.AdjustLeft(HOR_DIST_BMP_STRING ); @@ -2207,9 +2199,14 @@ tools::Rectangle SvxIconChoiceCtrl_Impl::CalcFocusRect( SvxIconChoiceCtrlEntry* { tools::Rectangle aTextRect( CalcTextRect( pEntry ) ); tools::Rectangle aBoundRect( GetEntryBoundRect( pEntry ) ); + + // Remove left margin + if (nWinBits & WB_DETAILS) + aBoundRect.SetPos(Point(0, aBoundRect.GetPos().Y())); + return tools::Rectangle( aBoundRect.Left(), aBoundRect.Top() - 1, aBoundRect.Right() - 1, - aTextRect.Bottom() + 1); + aTextRect.Bottom()); } // the hot spot is the inner 50% of the rectangle @@ -2774,7 +2771,7 @@ bool SvxIconChoiceCtrl_Impl::RequestHelp( const HelpEvent& rHEvt ) Point aPos( pView->ScreenToOutputPixel(rHEvt.GetMousePosPixel() ) ); aPos -= pView->GetMapMode().GetOrigin(); - SvxIconChoiceCtrlEntry* pEntry = GetEntry( aPos, true ); + SvxIconChoiceCtrlEntry* pEntry = GetEntry( aPos ); if ( !pEntry ) return false; diff --git a/vcl/source/control/ivctrl.cxx b/vcl/source/control/ivctrl.cxx index a2f502ff81dc..14e0ec44938b 100644 --- a/vcl/source/control/ivctrl.cxx +++ b/vcl/source/control/ivctrl.cxx @@ -435,9 +435,9 @@ struct VerticalTabPageData VclPtr<vcl::Window> xPage; ///< the TabPage itself }; -VerticalTabControl::VerticalTabControl(vcl::Window* pParent) +VerticalTabControl::VerticalTabControl(vcl::Window* pParent, bool bWithIcons) : VclHBox(pParent) - , m_xChooser(VclPtr<SvtIconChoiceCtrl>::Create(this, WB_3DLOOK | WB_ICON | WB_BORDER | + , m_xChooser(VclPtr<SvtIconChoiceCtrl>::Create(this, WB_3DLOOK | (bWithIcons ? WB_ICON : WB_DETAILS) | WB_BORDER | WB_NOCOLUMNHEADER | WB_HIGHLIGHTFRAME | WB_NODRAGSELECTION | WB_TABSTOP | WB_CLIPCHILDREN | WB_ALIGN_LEFT | WB_NOHSCROLL)) diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx index fcb3a21fee30..f2b0d381c7fa 100644 --- a/vcl/source/window/builder.cxx +++ b/vcl/source/window/builder.cxx @@ -985,6 +985,18 @@ namespace return bVertical; } + bool extractVerticalTabsWithIcons(VclBuilder::stringmap &rMap) + { + bool bWithIcons = false; + VclBuilder::stringmap::iterator aFind = rMap.find("group-name"); + if (aFind != rMap.end()) + { + bWithIcons = aFind->second.equalsIgnoreAsciiCase("icons"); + rMap.erase(aFind); + } + return bWithIcons; + } + bool extractInconsistent(VclBuilder::stringmap &rMap) { bool bInconsistent = false; @@ -2061,7 +2073,7 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OUString if (!extractVerticalTabPos(rMap)) xWindow = VclPtr<TabControl>::Create(pParent, WB_STDTABCONTROL|WB_3DLOOK); else - xWindow = VclPtr<VerticalTabControl>::Create(pParent); + xWindow = VclPtr<VerticalTabControl>::Create(pParent, extractVerticalTabsWithIcons(rMap)); } else if (name == "GtkDrawingArea") {