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")
     {

Reply via email to