tdf#124148 add configurable margin for the listbox pop-up list

This is needed to increase the area of lisbox entries in the
pop-up list so it is easier to select with touch.

Change-Id: Iedb910508de26c903dc3f50f645f567d4c988940
Reviewed-on: https://gerrit.libreoffice.org/69889
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
diff --git a/vcl/inc/listbox.hxx b/vcl/inc/listbox.hxx
index 52a9ab9..1ee1244 100644
--- a/vcl/inc/listbox.hxx
+++ b/vcl/inc/listbox.hxx
@@ -54,6 +54,8 @@
    ListBoxEntryFlags mnFlags;
    long        mnHeight;

    long getHeightWithMargin() const;

    ImplEntryType( const OUString& rStr, const Image& rImage ) :
        maStr( rStr ),
        maImage( rImage ),
@@ -336,6 +338,7 @@
    tools::Rectangle       GetBoundingRectangle( sal_Int32  nItem ) const;

    long            GetEntryHeight() const              { return mnMaxHeight; }
    long            GetEntryHeightWithMargin() const;
    long            GetMaxEntryWidth() const            { return mnMaxWidth; }

    void            SetScrollHdl( const Link<ImplListBoxWindow*,void>& rLink ) { maScrollHdl = rLink; }
@@ -472,6 +475,7 @@

    Size            CalcSize( sal_Int32  nMaxLines ) const              { return maLBWindow->CalcSize( nMaxLines ); }
    long            GetEntryHeight() const          { return maLBWindow->GetEntryHeight(); }
    long            GetEntryHeightWithMargin() const{ return maLBWindow->GetEntryHeightWithMargin(); }
    long            GetMaxEntryWidth() const        { return maLBWindow->GetMaxEntryWidth(); }

    void            SetScrollHdl( const Link<ImplListBox*,void>& rLink ) { maScrollHdl = rLink; }
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index c5b3482..714c7c5 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -309,6 +309,8 @@
    // floating toolbars that can be redocked because there's no way to track
    // that the toolbar is over a dockable area.
    bool                    mbCanDetermineWindowPosition = true;

    int mnListBoxEntryMargin = 0;
};

struct BlendFrameCache
diff --git a/vcl/source/control/imp_listbox.cxx b/vcl/source/control/imp_listbox.cxx
index 5e72bcf..35c2ee7 100644
--- a/vcl/source/control/imp_listbox.cxx
+++ b/vcl/source/control/imp_listbox.cxx
@@ -310,7 +310,7 @@
        sal_Int32 nIndex = nStart;
        while( nIndex != LISTBOX_ENTRY_NOTFOUND && nIndex < nStop )
        {
            long nPosHeight = GetEntryPtr( nIndex )->mnHeight;
            long nPosHeight = GetEntryPtr( nIndex )->getHeightWithMargin();
            if (nHeight > ::std::numeric_limits<long>::max() - nPosHeight)
            {
                SAL_WARN( "vcl", "ImplEntryList::GetAddedHeight: truncated");
@@ -328,7 +328,7 @@
long ImplEntryList::GetEntryHeight( sal_Int32 nPos ) const
{
    ImplEntryType* pImplEntry = GetEntry( nPos );
    return pImplEntry ? pImplEntry->mnHeight : 0;
    return pImplEntry ? pImplEntry->getHeightWithMargin() : 0;
}

OUString ImplEntryList::GetEntryText( sal_Int32 nPos ) const
@@ -561,7 +561,7 @@

    if( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND )
    {
        Size aSz( GetOutputSizePixel().Width(), mpEntryList->GetEntryPtr( mnCurrentPos )->mnHeight );
        Size aSz( GetOutputSizePixel().Width(), mpEntryList->GetEntryPtr( mnCurrentPos )->getHeightWithMargin() );
        maFocusRect.SetSize( aSz );
    }
}
@@ -604,6 +604,11 @@
    long    nImgHeight;
};

long ImplEntryType::getHeightWithMargin() const
{
    return mnHeight + ImplGetSVData()->maNWFData.mnListBoxEntryMargin;
}

SalLayoutGlyphs* ImplEntryType::GetTextGlyphs(const OutputDevice* pOutputDevice)
{
    if (maStrGlyphs.IsValid())
@@ -805,9 +810,10 @@

    sal_Int32 nSelect = mnTop;
    const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nSelect );
    while( pEntry && rPoint.Y() > pEntry->mnHeight + nY )
    long nEntryHeight = pEntry->getHeightWithMargin();
    while( pEntry && rPoint.Y() > nEntryHeight + nY )
    {
        nY += pEntry->mnHeight;
        nY += nEntryHeight;
        pEntry = mpEntryList->GetEntryPtr( ++nSelect );
    }
    if( pEntry == nullptr )
@@ -832,6 +838,12 @@
    return bRet;
}

long ImplListBoxWindow::GetEntryHeightWithMargin() const
{
    long nMargin = ImplGetSVData()->maNWFData.mnListBoxEntryMargin;
    return mnMaxHeight + nMargin;
}

sal_Int32 ImplListBoxWindow::GetLastVisibleEntry() const
{
    sal_Int32 nPos = mnTop;
@@ -1714,7 +1726,7 @@

    long nWidth = GetOutputSizePixel().Width();
    long nY = mpEntryList->GetAddedHeight(nPos, mnTop);
    tools::Rectangle aRect(Point(0, nY), Size(nWidth, pEntry->mnHeight));
    tools::Rectangle aRect(Point(0, nY), Size(nWidth, pEntry->getHeightWithMargin()));

    if (mpEntryList->IsEntryPosSelected(nPos))
    {
@@ -1760,6 +1772,8 @@
    if (!pEntry)
        return;

    long nEntryHeight = pEntry->getHeightWithMargin();

    // when changing this function don't forget to adjust ImplWin::DrawEntry()

    if (mbInUserDraw)
@@ -1774,7 +1788,7 @@
        if (!!aImage)
        {
            aImgSz = aImage.GetSizePixel();
            Point aPtImg(gnBorder - mnLeft, nY + ((pEntry->mnHeight - aImgSz.Height()) / 2));
            Point aPtImg(gnBorder - mnLeft, nY + ((nEntryHeight - aImgSz.Height()) / 2));

            // pb: #106948# explicit mirroring for calc
            if (mbMirroring)
@@ -1821,7 +1835,7 @@
                nMaxWidth = GetOutputSizePixel().Width() - 2 * gnBorder;

            tools::Rectangle aTextRect(Point(gnBorder - mnLeft, nY),
                                Size(nMaxWidth, pEntry->mnHeight));
                                Size(nMaxWidth, nEntryHeight));

            if (!bDrawTextAtImagePos && (mpEntryList->HasEntryImage(nPos) || IsUserDrawEnabled()))
            {
@@ -1854,7 +1868,7 @@
        rRenderContext.SetLineColor((GetBackground().GetColor() != COL_LIGHTGRAY) ? COL_LIGHTGRAY : COL_GRAY);
        Point aStartPos(0, nY);
        if (isSeparator(nPos))
            aStartPos.AdjustY(pEntry->mnHeight - 1 );
            aStartPos.AdjustY(pEntry->getHeightWithMargin() - 1 );
        Point aEndPos(aStartPos);
        aEndPos.setX( GetOutputSizePixel().Width() );
        rRenderContext.DrawLine(aStartPos, aEndPos);
@@ -1882,12 +1896,13 @@
    for (sal_Int32 i = mnTop; i < nCount && nY < nHeight + mnMaxHeight; i++)
    {
        const ImplEntryType* pEntry = mpEntryList->GetEntryPtr(i);
        if (nY + pEntry->mnHeight >= rRect.Top() &&
        long nEntryHeight = pEntry->getHeightWithMargin();
        if (nY + nEntryHeight >= rRect.Top() &&
            nY <= rRect.Bottom() + mnMaxHeight)
        {
            ImplPaint(rRenderContext, i);
        }
        nY += pEntry->mnHeight;
        nY += nEntryHeight;
    }

    long nHeightDiff = mpEntryList->GetAddedHeight(mnCurrentPos, mnTop);
@@ -1966,7 +1981,7 @@
    if( nTop > nLastEntry )
        nTop = nLastEntry;
    const ImplEntryType* pLast = mpEntryList->GetEntryPtr( nLastEntry );
    while( nTop > 0 && mpEntryList->GetAddedHeight( nLastEntry, nTop-1 ) + pLast->mnHeight <= nWHeight )
    while( nTop > 0 && mpEntryList->GetAddedHeight( nLastEntry, nTop-1 ) + pLast->getHeightWithMargin() <= nWHeight )
        nTop--;

    if ( nTop != mnTop )
@@ -2061,7 +2076,7 @@
    // FIXME: ListBoxEntryFlags::MultiLine

    Size aSz;
    aSz.setHeight(  nMaxLines * mnMaxHeight );
    aSz.setHeight(nMaxLines * GetEntryHeightWithMargin());
    aSz.setWidth( mnMaxWidth + 2*gnBorder );
    return aSz;
}
@@ -2069,8 +2084,8 @@
tools::Rectangle ImplListBoxWindow::GetBoundingRectangle( sal_Int32 nItem ) const
{
    const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nItem );
    Size aSz( GetSizePixel().Width(), pEntry ? pEntry->mnHeight : GetEntryHeight() );
    long nY = mpEntryList->GetAddedHeight( nItem, GetTopEntry() ) + GetEntryList()->GetMRUCount()*GetEntryHeight();
    Size aSz( GetSizePixel().Width(), pEntry ? pEntry->getHeightWithMargin() : GetEntryHeightWithMargin() );
    long nY = mpEntryList->GetAddedHeight( nItem, GetTopEntry() ) + GetEntryList()->GetMRUCount()*GetEntryHeightWithMargin();
    tools::Rectangle aRect( Point( 0, nY ), aSz );
    return aRect;
}
@@ -2283,7 +2298,7 @@

    Size aOutSz = GetOutputSizePixel();
    sal_Int32 nEntries = GetEntryList()->GetEntryCount();
    sal_uInt16 nMaxVisEntries = static_cast<sal_uInt16>(aOutSz.Height() / GetEntryHeight());
    sal_uInt16 nMaxVisEntries = static_cast<sal_uInt16>(aOutSz.Height() / GetEntryHeightWithMargin());

    // vertical ScrollBar
    if( nEntries > nMaxVisEntries )
@@ -2323,7 +2338,7 @@

            if ( !mbVScroll )   // maybe we do need one now
            {
                nMaxVisEntries = static_cast<sal_uInt16>( ( aOutSz.Height() - mpHScrollBar->GetSizePixel().Height() ) / GetEntryHeight() );
                nMaxVisEntries = static_cast<sal_uInt16>( ( aOutSz.Height() - mpHScrollBar->GetSizePixel().Height() ) / GetEntryHeightWithMargin() );
                if( nEntries > nMaxVisEntries )
                {
                    bArrange = true;
@@ -2365,7 +2380,7 @@
    if ( mbVScroll )
    {
        sal_Int32 nEntries = GetEntryList()->GetEntryCount();
        sal_uInt16 nVisEntries = static_cast<sal_uInt16>(aOutSz.Height() / GetEntryHeight());
        sal_uInt16 nVisEntries = static_cast<sal_uInt16>(aOutSz.Height() / GetEntryHeightWithMargin());
        mpVScrollBar->SetRangeMax( nEntries );
        mpVScrollBar->SetVisibleSize( nVisEntries );
        mpVScrollBar->SetPageSize( nVisEntries - 1 );
@@ -3056,7 +3071,7 @@

    // align height to entries...
    long nInnerHeight = aFloatSz.Height() - nTop - nBottom;
    long nEntryHeight = mpImplLB->GetEntryHeight();
    long nEntryHeight = mpImplLB->GetEntryHeightWithMargin();
    if ( nInnerHeight % nEntryHeight )
    {
        nInnerHeight /= nEntryHeight;
diff --git a/vcl/source/control/listbox.cxx b/vcl/source/control/listbox.cxx
index 06d02ff..dc332b3 100644
--- a/vcl/source/control/listbox.cxx
+++ b/vcl/source/control/listbox.cxx
@@ -1224,7 +1224,7 @@
        aSz = mpImplLB->CalcSize (mnLineCount ? mnLineCount : mpImplLB->GetEntryList()->GetEntryCount());
    else
    {
        aSz.setHeight( mpImplLB->CalcSize( 1 ).Height() );
        aSz.setHeight( mpImplLB->GetEntryHeight() );
        // Size to maxmimum entry width
        aSz.setWidth( mpImplLB->GetMaxEntryWidth() );

@@ -1318,7 +1318,7 @@
    {
        Size aOutSz = mpImplLB->GetMainWindow()->GetOutputSizePixel();
        rnCols = static_cast<sal_uInt16>(aOutSz.Width()/nCharWidth);
        rnLines = static_cast<sal_uInt16>(aOutSz.Height()/mpImplLB->GetEntryHeight());
        rnLines = static_cast<sal_uInt16>(aOutSz.Height()/mpImplLB->GetEntryHeightWithMargin());
    }
    else
    {
diff --git a/vcl/source/gdi/FileDefinitionWidgetDraw.cxx b/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
index 210e502..e365817 100644
--- a/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
+++ b/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
@@ -77,6 +77,7 @@
    pSVData->maNWFData.mbProgressNeedsErase = true;
    pSVData->maNWFData.mnStatusBarLowerRightOffset = 10;
    pSVData->maNWFData.mbCanDrawWidgetAnySize = true;
    pSVData->maNWFData.mnListBoxEntryMargin = 20;
}

bool FileDefinitionWidgetDraw::isNativeControlSupported(ControlType eType, ControlPart ePart)