diff options
author | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2020-11-11 16:17:44 +0100 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2020-11-12 08:41:22 +0100 |
commit | 941b5a0bb597285737b4796106974468ac357b17 (patch) | |
tree | 2cedd15bb7d3bfd0d2d5db1dba880e9faf30dc40 | |
parent | loplugin:nullptr (macOS) (diff) | |
download | core-941b5a0bb597285737b4796106974468ac357b17.tar.gz core-941b5a0bb597285737b4796106974468ac357b17.zip |
Permit scrollable AWT tab pages a la scrolled Dialog
UNO dialogs since LibreOffice 4.0 permitted setting HScroll /
VScroll properties to enable scrolling for too large a content.
Conceptually clone this code over to TabPage as well, and register
necessary UNO properties in the toolkit UNO wrappers.
Add missing API documentation also to UnoControlDialogModel,
plus the new properties to the UnoControlTabPageModel
Layout code really doesn't like any extra controls it didn't create
itself - so create scrollbars only on demand.
Change-Id: I67894597ac104320e67ad7989ebf9a7955d99103
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105573
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
-rw-r--r-- | include/vcl/tabpage.hxx | 24 | ||||
-rw-r--r-- | offapi/com/sun/star/awt/UnoControlDialogModel.idl | 30 | ||||
-rw-r--r-- | offapi/com/sun/star/awt/tab/UnoControlTabPageModel.idl | 43 | ||||
-rw-r--r-- | toolkit/source/awt/vclxcontainer.cxx | 16 | ||||
-rw-r--r-- | toolkit/source/awt/vclxtoolkit.cxx | 3 | ||||
-rw-r--r-- | toolkit/source/controls/tabpagemodel.cxx | 6 | ||||
-rw-r--r-- | vcl/source/window/tabpage.cxx | 129 |
7 files changed, 245 insertions, 6 deletions
diff --git a/include/vcl/tabpage.hxx b/include/vcl/tabpage.hxx index bd308a96a355..1a66bab9eabd 100644 --- a/include/vcl/tabpage.hxx +++ b/include/vcl/tabpage.hxx @@ -24,6 +24,9 @@ #include <vcl/window.hxx> #include <vcl/IContext.hxx> +class ScrollBar; +class ScrollBarBox; + class VCL_DLLPUBLIC TabPage : public vcl::Window , public vcl::IContext @@ -32,10 +35,22 @@ private: using Window::ImplInit; SAL_DLLPRIVATE void ImplInit( vcl::Window* pParent, WinBits nStyle ); SAL_DLLPRIVATE void ImplInitSettings(); + void lcl_Scroll( tools::Long nX, tools::Long nY ); + DECL_LINK( ScrollBarHdl, ScrollBar*, void ); + + VclPtr<ScrollBar> m_pVScroll; + VclPtr<ScrollBar> m_pHScroll; + VclPtr<ScrollBarBox> m_aScrollBarBox; + Size maScrollArea; + bool mbHasHoriBar; + bool mbHasVertBar; + Point mnScrollPos; + tools::Long mnScrWidth; public: explicit TabPage( vcl::Window* pParent, WinBits nStyle = 0 ); virtual ~TabPage() override; + virtual void dispose() override; virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override; virtual void Draw( OutputDevice* pDev, const Point& rPos, DrawFlags nFlags ) override; @@ -48,6 +63,15 @@ public: virtual void SetPosPixel(const Point& rNewPos) override; virtual void SetSizePixel(const Size& rNewSize) override; virtual Size GetOptimalSize() const override; + + // for scrollable tabpage + virtual void Resize() override; + + void SetScrollWidth( tools::Long nWidth ); + void SetScrollHeight( tools::Long nHeight ); + void SetScrollLeft( tools::Long nLeft ); + void SetScrollTop( tools::Long Top ); + void ResetScrollBars(); }; #endif // INCLUDED_VCL_TABPAGE_HXX diff --git a/offapi/com/sun/star/awt/UnoControlDialogModel.idl b/offapi/com/sun/star/awt/UnoControlDialogModel.idl index b45545b272aa..428ef7352441 100644 --- a/offapi/com/sun/star/awt/UnoControlDialogModel.idl +++ b/offapi/com/sun/star/awt/UnoControlDialogModel.idl @@ -145,6 +145,36 @@ published service UnoControlDialogModel */ [optional, property, transient] com::sun::star::graphic::XGraphic Graphic; + /** specifies that a horizontal scrollbar should be added to the dialog + @since LibreOffice 4.0 + */ + [optional, property] boolean HScroll; + + /** specifies that a vertical scrollbar should be added to the dialog + @since LibreOffice 4.0 + */ + [optional, property] boolean VScroll; + + /** specifies the horizontal position of the scrolled dialog content + @since LibreOffice 4.0 + */ + [optional, property] long ScrollLeft; + + /** specifies the vertical position of the scrolled dialog content + @since LibreOffice 4.0 + */ + [optional, property] long ScrollTop; + + /** specifies the total width of the scrollable dialog content + @since LibreOffice 4.0 + */ + [optional, property] long ScrollWidth; + + /** specifies the total height of the scrollable dialog content + @since LibreOffice 4.0 + */ + [optional, property] long ScrollHeight; + }; diff --git a/offapi/com/sun/star/awt/tab/UnoControlTabPageModel.idl b/offapi/com/sun/star/awt/tab/UnoControlTabPageModel.idl index e4efdc605b13..0c32f231f2ec 100644 --- a/offapi/com/sun/star/awt/tab/UnoControlTabPageModel.idl +++ b/offapi/com/sun/star/awt/tab/UnoControlTabPageModel.idl @@ -30,6 +30,49 @@ module com { module sun { module star { module awt { module tab { published service UnoControlTabPageModel { interface XTabPageModel; + + /** specifies the text that is displayed in the caption bar of the dialog. + */ + [optional, property] string Title; + + /** specifies the help text of the dialog. + */ + [optional, property] string HelpText; + + /** specifies the help URL of the dialog. + */ + [optional, property] string HelpURL; + + /** specifies that a horizontal scrollbar should be added to the dialog + @since LibreOffice 7.1 + */ + [optional, property] boolean HScroll; + + /** specifies that a vertical scrollbar should be added to the dialog + @since LibreOffice 7.1 + */ + [optional, property] boolean VScroll; + + /** specifies the horizontal position of the scrolled dialog content + @since LibreOffice 7.1 + */ + [optional, property] long ScrollLeft; + + /** specifies the vertical position of the scrolled dialog content + @since LibreOffice 7.1 + */ + [optional, property] long ScrollTop; + + /** specifies the total width of the scrollable dialog content + @since LibreOffice 7.1 + */ + [optional, property] long ScrollWidth; + + /** specifies the total height of the scrollable dialog content + @since LibreOffice 7.1 + */ + [optional, property] long ScrollHeight; + }; diff --git a/toolkit/source/awt/vclxcontainer.cxx b/toolkit/source/awt/vclxcontainer.cxx index 541a9913440c..44f0844f6965 100644 --- a/toolkit/source/awt/vclxcontainer.cxx +++ b/toolkit/source/awt/vclxcontainer.cxx @@ -26,6 +26,7 @@ #include <vcl/svapp.hxx> #include <vcl/window.hxx> +#include <vcl/tabpage.hxx> #include <tools/debug.hxx> #include <helper/scrollabledialog.hxx> #include <toolkit/helper/property.hxx> @@ -251,7 +252,8 @@ void SAL_CALL VCLXContainer::setProperty( VclPtr<vcl::Window> pWindow = GetWindow(); MapMode aMode( MapUnit::MapAppFont ); toolkit::ScrollableDialog* pScrollable = dynamic_cast< toolkit::ScrollableDialog* >( pWindow.get() ); - if ( pWindow && pScrollable ) + TabPage* pScrollTabPage = dynamic_cast< TabPage* >( pWindow.get() ); + if ( pWindow && (pScrollable || pScrollTabPage) ) { OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( getGraphics() ); if ( !pDev ) @@ -265,16 +267,20 @@ void SAL_CALL VCLXContainer::setProperty( switch ( nPropType ) { case BASEPROPERTY_SCROLLHEIGHT: - pScrollable->SetScrollHeight( aSize.Height() ); + pScrollable ? pScrollable->SetScrollHeight( aSize.Height() ) : (void)0; + pScrollTabPage ? pScrollTabPage->SetScrollHeight( aSize.Height() ) : (void)0; break; case BASEPROPERTY_SCROLLWIDTH: - pScrollable->SetScrollWidth( aSize.Width() ); + pScrollable ? pScrollable->SetScrollWidth( aSize.Width() ) : (void)0; + pScrollTabPage ? pScrollTabPage->SetScrollWidth( aSize.Width() ) : (void)0; break; case BASEPROPERTY_SCROLLTOP: - pScrollable->SetScrollTop( aSize.Height() ); + pScrollable ? pScrollable->SetScrollTop( aSize.Height() ) : (void)0; + pScrollTabPage ? pScrollTabPage->SetScrollTop( aSize.Height() ) : (void)0; break; case BASEPROPERTY_SCROLLLEFT: - pScrollable->SetScrollLeft( aSize.Width() ); + pScrollable ? pScrollable->SetScrollLeft( aSize.Width() ) : (void)0; + pScrollTabPage ? pScrollTabPage->SetScrollLeft( aSize.Width() ) : (void)0; break; default: break; diff --git a/toolkit/source/awt/vclxtoolkit.cxx b/toolkit/source/awt/vclxtoolkit.cxx index 12fb64bee90b..8d7cff46e7d8 100644 --- a/toolkit/source/awt/vclxtoolkit.cxx +++ b/toolkit/source/awt/vclxtoolkit.cxx @@ -664,7 +664,8 @@ std::pair<WinBits,MessBoxStyle> ImplGetWinBits( sal_uInt32 nComponentAttribs, Wi if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_NO ) nStyle |= MessBoxStyle::DefaultNo; } - if ( nCompType == WindowType::MULTILINEEDIT || nCompType == WindowType::DIALOG || nCompType == WindowType::GROUPBOX ) + if ( nCompType == WindowType::MULTILINEEDIT || nCompType == WindowType::DIALOG + || nCompType == WindowType::GROUPBOX || nCompType == WindowType::TABPAGE ) { if( nComponentAttribs & css::awt::VclWindowPeerAttribute::AUTOHSCROLL ) nWinBits |= WB_AUTOHSCROLL; diff --git a/toolkit/source/controls/tabpagemodel.cxx b/toolkit/source/controls/tabpagemodel.cxx index 8a0856f2d08a..30f45d9258bd 100644 --- a/toolkit/source/controls/tabpagemodel.cxx +++ b/toolkit/source/controls/tabpagemodel.cxx @@ -46,6 +46,12 @@ UnoControlTabPageModel::UnoControlTabPageModel( Reference< XComponentContext > c ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); ImplRegisterProperty( BASEPROPERTY_HELPURL ); ImplRegisterProperty( BASEPROPERTY_USERFORMCONTAINEES ); + ImplRegisterProperty( BASEPROPERTY_HSCROLL ); + ImplRegisterProperty( BASEPROPERTY_VSCROLL ); + ImplRegisterProperty( BASEPROPERTY_SCROLLWIDTH ); + ImplRegisterProperty( BASEPROPERTY_SCROLLHEIGHT ); + ImplRegisterProperty( BASEPROPERTY_SCROLLTOP ); + ImplRegisterProperty( BASEPROPERTY_SCROLLLEFT ); } OUString SAL_CALL UnoControlTabPageModel::getImplementationName() diff --git a/vcl/source/window/tabpage.cxx b/vcl/source/window/tabpage.cxx index 827fbc35cd24..259b0085f12d 100644 --- a/vcl/source/window/tabpage.cxx +++ b/vcl/source/window/tabpage.cxx @@ -23,6 +23,7 @@ #include <vcl/tabpage.hxx> #include <vcl/bitmapex.hxx> #include <vcl/settings.hxx> +#include <vcl/scrbar.hxx> void TabPage::ImplInit( vcl::Window* pParent, WinBits nStyle ) { @@ -31,6 +32,40 @@ void TabPage::ImplInit( vcl::Window* pParent, WinBits nStyle ) Window::ImplInit( pParent, nStyle, nullptr ); + mbHasHoriBar = false; + mbHasVertBar = false; + + Link<ScrollBar*,void> aLink( LINK( this, TabPage, ScrollBarHdl ) ); + + if ( nStyle & ( WB_AUTOHSCROLL | WB_AUTOVSCROLL ) ) + { + if ( nStyle & WB_AUTOHSCROLL ) + { + mbHasHoriBar = true; + m_pHScroll.set(VclPtr<ScrollBar>::Create(this, (WB_HSCROLL | WB_DRAG))); + m_pHScroll->Show(); + m_pHScroll->SetScrollHdl(aLink); + } + if ( nStyle & WB_AUTOVSCROLL ) + { + mbHasVertBar = true; + m_pVScroll.set(VclPtr<ScrollBar>::Create(this, (WB_VSCROLL | WB_DRAG))); + m_pVScroll->Show(); + m_pVScroll->SetScrollHdl(aLink); + } + } + + if ( mbHasHoriBar || mbHasVertBar ) + { + m_aScrollBarBox.set( + VclPtr<ScrollBarBox>::Create(this, + ((nStyle & (WB_VSCROLL|WB_HSCROLL)) ? WB_HIDE : 0))); + m_aScrollBarBox->Show(); + SetStyle( GetStyle() | WB_CLIPCHILDREN ); + } + + mnScrWidth = Application::GetSettings().GetStyleSettings().GetScrollBarSize(); + ImplInitSettings(); // if the tabpage is drawn (ie filled) by a native widget, make sure all controls will have transparent background @@ -74,6 +109,14 @@ TabPage::~TabPage() disposeOnce(); } +void TabPage::dispose() +{ + m_pVScroll.disposeAndClear(); + m_pHScroll.disposeAndClear(); + m_aScrollBarBox.disposeAndClear(); + vcl::Window::dispose(); +} + void TabPage::StateChanged( StateChangedType nType ) { Window::StateChanged( nType ); @@ -182,4 +225,90 @@ void TabPage::SetPosPixel(const Point& rAllocPos) } } +void TabPage::lcl_Scroll( tools::Long nX, tools::Long nY ) +{ + tools::Long nXScroll = mnScrollPos.X() - nX; + tools::Long nYScroll = mnScrollPos.Y() - nY; + mnScrollPos = Point( nX, nY ); + + tools::Rectangle aScrollableArea( 0, 0, maScrollArea.Width(), maScrollArea.Height() ); + Scroll(nXScroll, nYScroll, aScrollableArea ); + // Manually scroll all children ( except the scrollbars ) + for ( int index = 0; index < GetChildCount(); ++index ) + { + vcl::Window* pChild = GetChild( index ); + if ( pChild && pChild != m_pVScroll.get() && pChild != m_pHScroll.get() ) + { + Point aPos = pChild->GetPosPixel(); + aPos += Point( nXScroll, nYScroll ); + pChild->SetPosPixel( aPos ); + } + } +} + +IMPL_LINK( TabPage, ScrollBarHdl, ScrollBar*, pSB, void ) +{ + sal_uInt16 nPos = static_cast<sal_uInt16>(pSB->GetThumbPos()); + if( pSB == m_pVScroll.get() ) + lcl_Scroll(mnScrollPos.X(), nPos ); + else if( pSB == m_pHScroll.get() ) + lcl_Scroll(nPos, mnScrollPos.Y() ); +} + +void TabPage::SetScrollTop( tools::Long nTop ) +{ + Point aOld = mnScrollPos; + lcl_Scroll( mnScrollPos.X() , mnScrollPos.Y() - nTop ); + m_pHScroll->SetThumbPos( 0 ); + // new pos is 0,0 + mnScrollPos = aOld; +} +void TabPage::SetScrollLeft( tools::Long nLeft ) +{ + Point aOld = mnScrollPos; + lcl_Scroll( mnScrollPos.X() - nLeft , mnScrollPos.Y() ); + m_pVScroll->SetThumbPos( 0 ); + // new pos is 0,0 + mnScrollPos = aOld; +} + +void TabPage::SetScrollWidth( tools::Long nWidth ) +{ + maScrollArea.setWidth( nWidth ); + ResetScrollBars(); +} + +void TabPage::SetScrollHeight( tools::Long nHeight ) +{ + maScrollArea.setHeight( nHeight ); + ResetScrollBars(); +} + +void TabPage::Resize() +{ + ResetScrollBars(); +} + +void TabPage::ResetScrollBars() +{ + Size aOutSz = GetOutputSizePixel(); + + Point aVPos( aOutSz.Width() - mnScrWidth, 0 ); + Point aHPos( 0, aOutSz.Height() - mnScrWidth ); + + if( m_pVScroll ) + { + m_pVScroll->SetPosSizePixel( aVPos, Size( mnScrWidth, GetSizePixel().Height() - mnScrWidth ) ); + m_pVScroll->SetRangeMax( maScrollArea.Height() + mnScrWidth ); + m_pVScroll->SetVisibleSize( GetSizePixel().Height() ); + } + + if( m_pHScroll ) + { + m_pHScroll->SetPosSizePixel( aHPos, Size( GetSizePixel().Width() - mnScrWidth, mnScrWidth ) ); + m_pHScroll->SetRangeMax( maScrollArea.Width() + mnScrWidth ); + m_pHScroll->SetVisibleSize( GetSizePixel().Width() ); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |