diff options
-rw-r--r-- | include/svtools/tabbar.hxx | 10 | ||||
-rw-r--r-- | include/vcl/weldutils.hxx | 5 | ||||
-rw-r--r-- | solenv/sanitizers/ui/svt.suppr | 10 | ||||
-rw-r--r-- | svtools/UIConfig_svt.mk | 2 | ||||
-rw-r--r-- | svtools/source/control/tabbar.cxx | 325 | ||||
-rw-r--r-- | svtools/uiconfig/ui/tabbuttons.ui | 139 | ||||
-rw-r--r-- | svtools/uiconfig/ui/tabbuttonsmirrored.ui | 139 | ||||
-rw-r--r-- | vcl/source/app/weldutils.cxx | 11 |
8 files changed, 449 insertions, 192 deletions
diff --git a/include/svtools/tabbar.hxx b/include/svtools/tabbar.hxx index 2a9d8a43eba3..8735e0728599 100644 --- a/include/svtools/tabbar.hxx +++ b/include/svtools/tabbar.hxx @@ -267,7 +267,9 @@ carried out over an item resp. over which item the mouse click has been carried out. */ +namespace weld { class Button; +} #define WB_RANGESELECT (WinBits(0x00200000)) #define WB_MULTISELECT (WinBits(0x00400000)) @@ -308,7 +310,6 @@ struct TabBar_Impl; class SVT_DLLPUBLIC TabBar : public vcl::Window { - friend class ImplTabButton; friend class ImplTabSizer; private: @@ -363,9 +364,10 @@ private: SVT_DLLPRIVATE void ImplPrePaint(); SVT_DLLPRIVATE ImplTabBarItem* ImplGetLastTabBarItem( sal_uInt16 nItemCount ); - DECL_DLLPRIVATE_LINK(ImplClickHdl, Button*, void); - - DECL_DLLPRIVATE_LINK(ImplAddClickHandler, Button*, void); + DECL_DLLPRIVATE_LINK(ImplClickHdl, weld::Button&, void); + DECL_DLLPRIVATE_LINK(ImplAddClickHandler, weld::Button&, void); + DECL_DLLPRIVATE_LINK(MousePressHdl, const MouseEvent&, bool); + DECL_DLLPRIVATE_LINK(ContextMenuHdl, const CommandEvent&, void); ImplTabBarItem* seek( size_t i ); ImplTabBarItem* prev(); diff --git a/include/vcl/weldutils.hxx b/include/vcl/weldutils.hxx index d956849a3292..ddd34d1ed787 100644 --- a/include/vcl/weldutils.hxx +++ b/include/vcl/weldutils.hxx @@ -397,6 +397,7 @@ private: weld::Button& m_rButton; AutoTimer m_aRepeat; const Link<Button&, void> m_aLink; + const Link<const CommandEvent&, void> m_aContextLink; bool m_bModKey; DECL_LINK(MousePressHdl, const MouseEvent&, bool); @@ -404,7 +405,9 @@ private: DECL_LINK(RepeatTimerHdl, Timer*, void); public: - ButtonPressRepeater(weld::Button& rButton, const Link<Button&, void>& rLink); + ButtonPressRepeater(weld::Button& rButton, const Link<Button&, void>& rLink, + const Link<const CommandEvent&, void>& rContextLink + = Link<const CommandEvent&, void>()); void Stop() { m_aRepeat.Stop(); } bool IsModKeyPressed() const { return m_bModKey; } }; diff --git a/solenv/sanitizers/ui/svt.suppr b/solenv/sanitizers/ui/svt.suppr index 2ee563213663..40c22f896163 100644 --- a/solenv/sanitizers/ui/svt.suppr +++ b/solenv/sanitizers/ui/svt.suppr @@ -26,5 +26,15 @@ svtools/uiconfig/ui/restartdialog.ui://GtkLabel[@id='reason_skia'] orphan-label svtools/uiconfig/ui/restartdialog.ui://GtkLabel[@id='label'] orphan-label svtools/uiconfig/ui/spinfieldcontrol.ui://GtkSpinButton[@id='spinbutton'] no-labelled-by svtools/uiconfig/ui/tabbaredit.ui://GtkEntry[@id='entry'] no-labelled-by +svtools/uiconfig/ui/tabbuttons.ui://GtkButton[@id='first'] button-no-label +svtools/uiconfig/ui/tabbuttons.ui://GtkButton[@id='next'] button-no-label +svtools/uiconfig/ui/tabbuttons.ui://GtkButton[@id='prev'] button-no-label +svtools/uiconfig/ui/tabbuttons.ui://GtkButton[@id='last'] button-no-label +svtools/uiconfig/ui/tabbuttons.ui://GtkButton[@id='add'] button-no-label +svtools/uiconfig/ui/tabbuttonsmirrored.ui://GtkButton[@id='first'] button-no-label +svtools/uiconfig/ui/tabbuttonsmirrored.ui://GtkButton[@id='next'] button-no-label +svtools/uiconfig/ui/tabbuttonsmirrored.ui://GtkButton[@id='prev'] button-no-label +svtools/uiconfig/ui/tabbuttonsmirrored.ui://GtkButton[@id='last'] button-no-label +svtools/uiconfig/ui/tabbuttonsmirrored.ui://GtkButton[@id='add'] button-no-label svtools/uiconfig/ui/thineditcontrol.ui://GtkEntry[@id='entry'] no-labelled-by svtools/uiconfig/ui/thineditcontrol.ui://GtkSpinButton[@id='spinbutton'] no-labelled-by diff --git a/svtools/UIConfig_svt.mk b/svtools/UIConfig_svt.mk index 4414ba31f55b..5df446e6970e 100644 --- a/svtools/UIConfig_svt.mk +++ b/svtools/UIConfig_svt.mk @@ -30,6 +30,8 @@ $(eval $(call gb_UIConfig_add_uifiles,svt,\ svtools/uiconfig/ui/querydeletedialog \ svtools/uiconfig/ui/restartdialog \ svtools/uiconfig/ui/spinfieldcontrol \ + svtools/uiconfig/ui/tabbuttons \ + svtools/uiconfig/ui/tabbuttonsmirrored \ svtools/uiconfig/ui/tabbaredit \ svtools/uiconfig/ui/textviewcontrol \ svtools/uiconfig/ui/thineditcontrol \ diff --git a/svtools/source/control/tabbar.cxx b/svtools/source/control/tabbar.cxx index e41696c0b56d..d44dd06d86c0 100644 --- a/svtools/source/control/tabbar.cxx +++ b/svtools/source/control/tabbar.cxx @@ -22,16 +22,17 @@ #include <tools/time.hxx> #include <tools/poly.hxx> #include <vcl/InterimItemWindow.hxx> +#include <vcl/bitmapex.hxx> #include <vcl/svapp.hxx> #include <vcl/help.hxx> #include <vcl/decoview.hxx> -#include <vcl/button.hxx> #include <vcl/event.hxx> #include <vcl/settings.hxx> #include <vcl/commandevent.hxx> #include <vcl/svtaccessiblefactory.hxx> #include <vcl/accessiblefactory.hxx> #include <vcl/ptrstyle.hxx> +#include <vcl/weldutils.hxx> #include <svtools/svtresid.hxx> #include <svtools/strings.hrc> #include <limits> @@ -48,7 +49,6 @@ constexpr sal_uInt16 TABBAR_DRAG_SCROLLOFF = 5; constexpr sal_uInt16 TABBAR_MINSIZE = 5; constexpr sal_uInt16 ADDNEWPAGE_AREAWIDTH = 10; -constexpr sal_uInt16 BUTTON_MARGIN = 6; class TabDrawer { @@ -233,68 +233,6 @@ struct ImplTabBarItem } }; -class ImplTabButton : public PushButton -{ - bool mbModKey : 1; - -public: - ImplTabButton(TabBar* pParent, WinBits nWinStyle = 0) - : PushButton(pParent, nWinStyle | WB_FLATBUTTON | WB_RECTSTYLE | WB_SMALLSTYLE | WB_NOLIGHTBORDER | WB_NOPOINTERFOCUS) - , mbModKey(false) - {} - - TabBar* GetParent() const - { - return static_cast<TabBar*>(Window::GetParent()); - } - - bool isModKeyPressed() const - { - return mbModKey; - } - - virtual bool PreNotify(NotifyEvent& rNotifyEvent) override; - virtual void MouseButtonDown(const MouseEvent& rMouseEvent) override; - virtual void MouseButtonUp(const MouseEvent& rMouseEvent) override; - virtual void Command(const CommandEvent& rCommandEvent) override; -}; - -void ImplTabButton::MouseButtonDown(const MouseEvent& rMouseEvent) -{ - mbModKey = rMouseEvent.IsMod1(); - PushButton::MouseButtonDown(rMouseEvent); -} - -void ImplTabButton::MouseButtonUp(const MouseEvent& rMouseEvent) -{ - mbModKey = false; - PushButton::MouseButtonUp(rMouseEvent); -} - -void ImplTabButton::Command(const CommandEvent& rCommandEvent) -{ - if (rCommandEvent.GetCommand() == CommandEventId::ContextMenu) - { - TabBar* pParent = GetParent(); - pParent->maScrollAreaContextHdl.Call(rCommandEvent); - } - PushButton::Command(rCommandEvent); -} - -bool ImplTabButton::PreNotify(NotifyEvent& rNotifyEvent) -{ - if (rNotifyEvent.GetType() == MouseNotifyEvent::MOUSEBUTTONDOWN) - { - if (GetParent()->IsInEditMode()) - { - GetParent()->EndEditMode(); - return true; - } - } - - return PushButton::PreNotify(rNotifyEvent); -} - class ImplTabSizer : public vcl::Window { public: @@ -471,14 +409,74 @@ IMPL_LINK_NOARG(TabBarEdit, ImplEndTimerHdl, Timer *, void) GetParent()->EndEditMode( true ); } +namespace { + +class TabButtons final : public InterimItemWindow +{ +public: + std::unique_ptr<weld::Button> m_xFirstButton; + std::unique_ptr<weld::Button> m_xPrevButton; + std::unique_ptr<weld::Button> m_xNextButton; + std::unique_ptr<weld::Button> m_xLastButton; + std::unique_ptr<weld::Button> m_xAddButton; + std::unique_ptr<weld::ButtonPressRepeater> m_xAddRepeater; + std::unique_ptr<weld::ButtonPressRepeater> m_xPrevRepeater; + std::unique_ptr<weld::ButtonPressRepeater> m_xNextRepeater; + + TabButtons(TabBar* pParent) + : InterimItemWindow(pParent, + pParent->IsMirrored() ? OUString("svt/ui/tabbuttonsmirrored.ui") + : OUString("svt/ui/tabbuttons.ui"), + "TabButtons") + , m_xFirstButton(m_xBuilder->weld_button("first")) + , m_xPrevButton(m_xBuilder->weld_button("prev")) + , m_xNextButton(m_xBuilder->weld_button("next")) + , m_xLastButton(m_xBuilder->weld_button("last")) + , m_xAddButton(m_xBuilder->weld_button("add")) + { + const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); + SetPaintTransparent(false); + SetBackground(rStyleSettings.GetFaceColor()); + + m_xFirstButton->set_accessible_name(SvtResId(STR_TABBAR_PUSHBUTTON_MOVET0HOME)); + m_xPrevButton->set_accessible_name(SvtResId(STR_TABBAR_PUSHBUTTON_MOVELEFT)); + m_xNextButton->set_accessible_name(SvtResId(STR_TABBAR_PUSHBUTTON_MOVERIGHT)); + m_xLastButton->set_accessible_name(SvtResId(STR_TABBAR_PUSHBUTTON_MOVETOEND)); + m_xAddButton->set_accessible_name(SvtResId(STR_TABBAR_PUSHBUTTON_ADDTAB)); + } + + void AdaptToHeight(int nHeight) + { + if (m_xFirstButton->get_preferred_size() == Size(nHeight, nHeight)) + return; + m_xFirstButton->set_size_request(nHeight, nHeight); + m_xPrevButton->set_size_request(nHeight, nHeight); + m_xNextButton->set_size_request(nHeight, nHeight); + m_xLastButton->set_size_request(nHeight, nHeight); + m_xAddButton->set_size_request(nHeight, nHeight); + InvalidateChildSizeCache(); + } + + virtual void dispose() override + { + m_xNextRepeater.reset(); + m_xPrevRepeater.reset(); + m_xAddRepeater.reset(); + m_xAddButton.reset(); + m_xLastButton.reset(); + m_xNextButton.reset(); + m_xPrevButton.reset(); + m_xFirstButton.reset(); + InterimItemWindow::dispose(); + } +}; + +} + struct TabBar_Impl { ScopedVclPtr<ImplTabSizer> mpSizer; - ScopedVclPtr<ImplTabButton> mpFirstButton; - ScopedVclPtr<ImplTabButton> mpPrevButton; - ScopedVclPtr<ImplTabButton> mpNextButton; - ScopedVclPtr<ImplTabButton> mpLastButton; - ScopedVclPtr<ImplTabButton> mpAddButton; + ScopedVclPtr<TabButtons> mxButtonBox; ScopedVclPtr<TabBarEdit> mxEdit; std::vector<std::unique_ptr<ImplTabBarItem>> mpItemList; @@ -541,18 +539,6 @@ void TabBar::ImplInit( WinBits nWinStyle ) ImplInitControls(); - if (mpImpl->mpFirstButton) - mpImpl->mpFirstButton->SetAccessibleName(SvtResId(STR_TABBAR_PUSHBUTTON_MOVET0HOME)); - if (mpImpl->mpPrevButton) - mpImpl->mpPrevButton->SetAccessibleName(SvtResId(STR_TABBAR_PUSHBUTTON_MOVELEFT)); - if (mpImpl->mpNextButton) - mpImpl->mpNextButton->SetAccessibleName(SvtResId(STR_TABBAR_PUSHBUTTON_MOVERIGHT)); - if (mpImpl->mpLastButton) - mpImpl->mpLastButton->SetAccessibleName(SvtResId(STR_TABBAR_PUSHBUTTON_MOVETOEND)); - - if (mpImpl->mpAddButton) - mpImpl->mpAddButton->SetAccessibleName(SvtResId(STR_TABBAR_PUSHBUTTON_ADDTAB)); - SetSizePixel( Size( 100, CalcWindowSizePixel().Height() ) ); ImplInitSettings( true, true ); } @@ -753,6 +739,18 @@ sal_uInt16 TabBar::ImplGetLastFirstPos() return nLastFirstPos; } +IMPL_LINK(TabBar, ContextMenuHdl, const CommandEvent&, rCommandEvent, void) +{ + maScrollAreaContextHdl.Call(rCommandEvent); +} + +IMPL_LINK(TabBar, MousePressHdl, const MouseEvent&, rMouseEvent, bool) +{ + if (rMouseEvent.IsRight()) + ContextMenuHdl(CommandEvent(rMouseEvent.GetPosPixel(), CommandEventId::ContextMenu, true)); + return false; +} + void TabBar::ImplInitControls() { if (mnWinStyle & WB_SIZEABLE) @@ -768,65 +766,43 @@ void TabBar::ImplInitControls() mpImpl->mpSizer.disposeAndClear(); } - if ((mnWinStyle & WB_INSERTTAB) && !mpImpl->mpAddButton) + mpImpl->mxButtonBox.disposeAndReset(VclPtr<TabButtons>::Create(this)); + + Link<const CommandEvent&, void> aContextLink = LINK( this, TabBar, ContextMenuHdl ); + + if (mnWinStyle & WB_INSERTTAB) { - Link<Button*,void> aLink = LINK(this, TabBar, ImplAddClickHandler); - mpImpl->mpAddButton.disposeAndReset(VclPtr<ImplTabButton>::Create(this, WB_REPEAT)); - mpImpl->mpAddButton->SetClickHdl(aLink); - mpImpl->mpAddButton->SetSymbol(SymbolType::PLUS); - mpImpl->mpAddButton->Show(); + Link<weld::Button&,void> aLink = LINK(this, TabBar, ImplAddClickHandler); + mpImpl->mxButtonBox->m_xAddRepeater.reset(new weld::ButtonPressRepeater( + *mpImpl->mxButtonBox->m_xAddButton, aLink, aContextLink)); + mpImpl->mxButtonBox->m_xAddButton->show(); } - - Link<Button*,void> aLink = LINK( this, TabBar, ImplClickHdl ); + Link<weld::Button&,void> aLink = LINK( this, TabBar, ImplClickHdl ); if (mnWinStyle & (WB_MINSCROLL | WB_SCROLL)) { - if (!mpImpl->mpPrevButton) - { - mpImpl->mpPrevButton.disposeAndReset(VclPtr<ImplTabButton>::Create(this, WB_REPEAT)); - mpImpl->mpPrevButton->SetClickHdl(aLink); - } - mpImpl->mpPrevButton->SetSymbol(mbMirrored ? SymbolType::NEXT : SymbolType::PREV); - mpImpl->mpPrevButton->Show(); - - if (!mpImpl->mpNextButton) - { - mpImpl->mpNextButton.disposeAndReset(VclPtr<ImplTabButton>::Create(this, WB_REPEAT)); - mpImpl->mpNextButton->SetClickHdl(aLink); - } - mpImpl->mpNextButton->SetSymbol(mbMirrored ? SymbolType::PREV : SymbolType::NEXT); - mpImpl->mpNextButton->Show(); - } - else - { - mpImpl->mpPrevButton.disposeAndClear(); - mpImpl->mpNextButton.disposeAndClear(); + mpImpl->mxButtonBox->m_xPrevRepeater.reset(new weld::ButtonPressRepeater( + *mpImpl->mxButtonBox->m_xPrevButton, aLink, aContextLink)); + mpImpl->mxButtonBox->m_xPrevButton->show(); + mpImpl->mxButtonBox->m_xNextRepeater.reset(new weld::ButtonPressRepeater( + *mpImpl->mxButtonBox->m_xNextButton, aLink, aContextLink)); + mpImpl->mxButtonBox->m_xNextButton->show(); } if (mnWinStyle & WB_SCROLL) { - if (!mpImpl->mpFirstButton) - { - mpImpl->mpFirstButton.disposeAndReset(VclPtr<ImplTabButton>::Create(this)); - mpImpl->mpFirstButton->SetClickHdl(aLink); - } - mpImpl->mpFirstButton->SetSymbol(mbMirrored ? SymbolType::LAST : SymbolType::FIRST); - mpImpl->mpFirstButton->Show(); + Link<const MouseEvent&, bool> aBtnContextLink = LINK(this, TabBar, MousePressHdl); - if (!mpImpl->mpLastButton) - { - mpImpl->mpLastButton.disposeAndReset(VclPtr<ImplTabButton>::Create(this)); - mpImpl->mpLastButton->SetClickHdl(aLink); - } - mpImpl->mpLastButton->SetSymbol(mbMirrored ? SymbolType::FIRST : SymbolType::LAST); - mpImpl->mpLastButton->Show(); - } - else - { - mpImpl->mpFirstButton.disposeAndClear(); - mpImpl->mpLastButton.disposeAndClear(); + mpImpl->mxButtonBox->m_xFirstButton->connect_clicked(aLink); + mpImpl->mxButtonBox->m_xFirstButton->connect_mouse_press(aBtnContextLink); + mpImpl->mxButtonBox->m_xFirstButton->show(); + mpImpl->mxButtonBox->m_xLastButton->connect_clicked(aLink); + mpImpl->mxButtonBox->m_xLastButton->connect_mouse_press(aBtnContextLink); + mpImpl->mxButtonBox->m_xLastButton->show(); } + + mpImpl->mxButtonBox->Show(); } void TabBar::ImplEnableControls() @@ -836,16 +812,15 @@ void TabBar::ImplEnableControls() // enable/disable buttons bool bEnableBtn = mbScrollAlwaysEnabled || mnFirstPos > 0; - if (mpImpl->mpFirstButton) - mpImpl->mpFirstButton->Enable(bEnableBtn); - if (mpImpl->mpPrevButton) - mpImpl->mpPrevButton->Enable(bEnableBtn); - + mpImpl->mxButtonBox->m_xFirstButton->set_sensitive(bEnableBtn); + mpImpl->mxButtonBox->m_xPrevButton->set_sensitive(bEnableBtn); + if (!bEnableBtn && mpImpl->mxButtonBox->m_xPrevRepeater) + mpImpl->mxButtonBox->m_xPrevRepeater->Stop(); bEnableBtn = mbScrollAlwaysEnabled || mnFirstPos < ImplGetLastFirstPos(); - if (mpImpl->mpNextButton) - mpImpl->mpNextButton->Enable(bEnableBtn); - if (mpImpl->mpLastButton) - mpImpl->mpLastButton->Enable(bEnableBtn); + mpImpl->mxButtonBox->m_xLastButton->set_sensitive(bEnableBtn); + mpImpl->mxButtonBox->m_xNextButton->set_sensitive(bEnableBtn); + if (!bEnableBtn && mpImpl->mxButtonBox->m_xNextRepeater) + mpImpl->mxButtonBox->m_xNextRepeater->Stop(); } void TabBar::SetScrollAlwaysEnabled(bool bScrollAlwaysEnabled) @@ -878,29 +853,30 @@ void TabBar::ImplShowPage( sal_uInt16 nPos ) } } -IMPL_LINK( TabBar, ImplClickHdl, Button*, pButton, void ) +IMPL_LINK( TabBar, ImplClickHdl, weld::Button&, rBtn, void ) { - ImplTabButton* pBtn = static_cast<ImplTabButton*>(pButton); EndEditMode(); sal_uInt16 nNewPos = mnFirstPos; - if (pBtn == mpImpl->mpFirstButton.get() || (pBtn == mpImpl->mpPrevButton.get() && pBtn->isModKeyPressed())) + if (&rBtn == mpImpl->mxButtonBox->m_xFirstButton.get() || (&rBtn == mpImpl->mxButtonBox->m_xPrevButton.get() && + mpImpl->mxButtonBox->m_xPrevRepeater->IsModKeyPressed())) { nNewPos = 0; } - else if (pBtn == mpImpl->mpLastButton.get() || (pBtn == mpImpl->mpNextButton.get() && pBtn->isModKeyPressed())) + else if (&rBtn == mpImpl->mxButtonBox->m_xLastButton.get() || (&rBtn == mpImpl->mxButtonBox->m_xNextButton.get() && + mpImpl->mxButtonBox->m_xNextRepeater->IsModKeyPressed())) { sal_uInt16 nCount = GetPageCount(); if (nCount) nNewPos = nCount - 1; } - else if (pBtn == mpImpl->mpPrevButton.get()) + else if (&rBtn == mpImpl->mxButtonBox->m_xPrevButton.get()) { if (mnFirstPos) nNewPos = mnFirstPos - 1; } - else if (pBtn == mpImpl->mpNextButton.get()) + else if (&rBtn == mpImpl->mxButtonBox->m_xNextButton.get()) { sal_uInt16 nCount = GetPageCount(); if (mnFirstPos < nCount) @@ -915,8 +891,9 @@ IMPL_LINK( TabBar, ImplClickHdl, Button*, pButton, void ) SetFirstPageId(GetPageId(nNewPos)); } -IMPL_LINK_NOARG(TabBar, ImplAddClickHandler, Button*, void) +IMPL_LINK_NOARG(TabBar, ImplAddClickHandler, weld::Button&, void) { + EndEditMode(); AddTabClick(); } @@ -1242,7 +1219,6 @@ void TabBar::Resize() Size aNewSize = GetOutputSizePixel(); tools::Long nSizerWidth = 0; - tools::Long nButtonWidth = 0; // order the Sizer if ( mpImpl->mpSizer ) @@ -1259,35 +1235,11 @@ void TabBar::Resize() // adapt font height? ImplInitSettings( true, false ); - tools::Long nButtonMargin = BUTTON_MARGIN * GetDPIScaleFactor(); - - tools::Long nX = mbMirrored ? (aNewSize.Width() - nHeight - nButtonMargin) : nButtonMargin; - tools::Long const nXDiff = mbMirrored ? -nHeight : nHeight; - - nButtonWidth += nButtonMargin; - - Size const aBtnSize( nHeight, nHeight ); - auto setButton = [aBtnSize, nXDiff, nHeight, &nX, &nButtonWidth]( - ScopedVclPtr<ImplTabButton> const & button) - { - if (button) { - button->SetPosSizePixel(Point(nX, 0), aBtnSize); - nX += nXDiff; - nButtonWidth += nHeight; - } - }; - - setButton(mpImpl->mpFirstButton); - setButton(mpImpl->mpPrevButton); - setButton(mpImpl->mpNextButton); - setButton(mpImpl->mpLastButton); - - nButtonWidth += nButtonMargin; - nX += mbMirrored ? -nButtonMargin : nButtonMargin; - - setButton(mpImpl->mpAddButton); - - nButtonWidth += nButtonMargin; + mpImpl->mxButtonBox->AdaptToHeight(nHeight); + Size const aBtnsSize(mpImpl->mxButtonBox->get_preferred_size().Width(), nHeight); + Point aPos(mbMirrored ? (aNewSize.Width() - aBtnsSize.Width()) : 0, 0); + mpImpl->mxButtonBox->SetPosSizePixel(aPos, aBtnsSize); + auto nButtonWidth = aBtnsSize.Width(); // store size maWinSize = aNewSize; @@ -1433,23 +1385,22 @@ void TabBar::StateChanged(StateChangedType nType) } else if (nType == StateChangedType::Mirroring) { + bool bIsRTLEnabled = IsRTLEnabled(); // reacts on calls of EnableRTL, have to mirror all child controls - if (mpImpl->mpFirstButton) - mpImpl->mpFirstButton->EnableRTL(IsRTLEnabled()); - if (mpImpl->mpPrevButton) - mpImpl->mpPrevButton->EnableRTL(IsRTLEnabled()); - if (mpImpl->mpNextButton) - mpImpl->mpNextButton->EnableRTL(IsRTLEnabled()); - if (mpImpl->mpLastButton) - mpImpl->mpLastButton->EnableRTL(IsRTLEnabled()); if (mpImpl->mpSizer) - mpImpl->mpSizer->EnableRTL(IsRTLEnabled()); - if (mpImpl->mpAddButton) - mpImpl->mpAddButton->EnableRTL(IsRTLEnabled()); + mpImpl->mpSizer->EnableRTL(bIsRTLEnabled); + if (mpImpl->mxButtonBox) + { + mpImpl->mxButtonBox->m_xFirstButton->set_direction(bIsRTLEnabled); + mpImpl->mxButtonBox->m_xPrevButton->set_direction(bIsRTLEnabled); + mpImpl->mxButtonBox->m_xNextButton->set_direction(bIsRTLEnabled); + mpImpl->mxButtonBox->m_xLastButton->set_direction(bIsRTLEnabled); + mpImpl->mxButtonBox->m_xAddButton->set_direction(bIsRTLEnabled); + } if (mpImpl->mxEdit) { weld::Entry& rEntry = mpImpl->mxEdit->get_widget(); - rEntry.set_direction(IsRTLEnabled()); + rEntry.set_direction(bIsRTLEnabled); } } } @@ -2491,6 +2442,8 @@ void TabBar::EndSwitchPage() void TabBar::SetStyle(WinBits nStyle) { + if (mnWinStyle == nStyle) + return; mnWinStyle = nStyle; ImplInitControls(); // order possible controls diff --git a/svtools/uiconfig/ui/tabbuttons.ui b/svtools/uiconfig/ui/tabbuttons.ui new file mode 100644 index 000000000000..ae6c6fa16cb4 --- /dev/null +++ b/svtools/uiconfig/ui/tabbuttons.ui @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.38.1 --> +<interface domain="svt"> + <requires lib="gtk+" version="3.20"/> + <object class="GtkImage" id="image1"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="stock">gtk-new</property> + <property name="icon_size">1</property> + </object> + <object class="GtkImage" id="image2"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="stock">gtk-media-previous</property> + <property name="icon_size">1</property> + </object> + <object class="GtkImage" id="image3"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="stock">gtk-media-next</property> + <property name="icon_size">1</property> + </object> + <object class="GtkImage" id="image4"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="stock">gtk-goto-first</property> + <property name="icon_size">1</property> + </object> + <object class="GtkImage" id="image5"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="stock">gtk-goto-last</property> + <property name="icon_size">1</property> + </object> + <object class="GtkBox" id="TabButtons"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="margin-left">6</property> + <property name="margin-right">6</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <child> + <object class="GtkButton" id="first"> + <property name="can-focus">True</property> + <property name="focus-on-click">False</property> + <property name="receives-default">True</property> + <property name="no-show-all">True</property> + <property name="image">image4</property> + <property name="relief">none</property> + <property name="always-show-image">True</property> + <style> + <class name="small-button"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="prev"> + <property name="can-focus">True</property> + <property name="focus-on-click">False</property> + <property name="receives-default">True</property> + <property name="no-show-all">True</property> + <property name="image">image2</property> + <property name="relief">none</property> + <property name="always-show-image">True</property> + <style> + <class name="small-button"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="next"> + <property name="can-focus">True</property> + <property name="focus-on-click">False</property> + <property name="receives-default">True</property> + <property name="no-show-all">True</property> + <property name="image">image3</property> + <property name="relief">none</property> + <property name="always-show-image">True</property> + <style> + <class name="small-button"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkButton" id="last"> + <property name="can-focus">True</property> + <property name="focus-on-click">False</property> + <property name="receives-default">True</property> + <property name="no-show-all">True</property> + <property name="image">image5</property> + <property name="relief">none</property> + <property name="always-show-image">True</property> + <style> + <class name="small-button"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">3</property> + </packing> + </child> + <child> + <object class="GtkButton" id="add"> + <property name="can-focus">True</property> + <property name="focus-on-click">False</property> + <property name="receives-default">True</property> + <property name="no-show-all">True</property> + <property name="margin-left">6</property> + <property name="image">image1</property> + <property name="relief">none</property> + <property name="always-show-image">True</property> + <style> + <class name="small-button"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">4</property> + </packing> + </child> + </object> +</interface> diff --git a/svtools/uiconfig/ui/tabbuttonsmirrored.ui b/svtools/uiconfig/ui/tabbuttonsmirrored.ui new file mode 100644 index 000000000000..abec1f56c165 --- /dev/null +++ b/svtools/uiconfig/ui/tabbuttonsmirrored.ui @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.38.1 --> +<interface domain="svt"> + <requires lib="gtk+" version="3.20"/> + <object class="GtkImage" id="image1"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="stock">gtk-new</property> + <property name="icon_size">1</property> + </object> + <object class="GtkImage" id="image2"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="stock">gtk-media-previous</property> + <property name="icon_size">1</property> + </object> + <object class="GtkImage" id="image3"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="stock">gtk-media-next</property> + <property name="icon_size">1</property> + </object> + <object class="GtkImage" id="image4"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="stock">gtk-goto-first</property> + <property name="icon_size">1</property> + </object> + <object class="GtkImage" id="image5"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="stock">gtk-goto-last</property> + <property name="icon_size">1</property> + </object> + <object class="GtkBox" id="TabButtons"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="margin-left">6</property> + <property name="margin-right">6</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <child> + <object class="GtkButton" id="add"> + <property name="can-focus">True</property> + <property name="focus-on-click">False</property> + <property name="receives-default">True</property> + <property name="no-show-all">True</property> + <property name="margin-right">6</property> + <property name="image">image1</property> + <property name="relief">none</property> + <property name="always-show-image">True</property> + <style> + <class name="small-button"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="last"> + <property name="can-focus">True</property> + <property name="focus-on-click">False</property> + <property name="receives-default">True</property> + <property name="no-show-all">True</property> + <property name="image">image4</property> + <property name="relief">none</property> + <property name="always-show-image">True</property> + <style> + <class name="small-button"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="next"> + <property name="can-focus">True</property> + <property name="focus-on-click">False</property> + <property name="receives-default">True</property> + <property name="no-show-all">True</property> + <property name="image">image2</property> + <property name="relief">none</property> + <property name="always-show-image">True</property> + <style> + <class name="small-button"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkButton" id="prev"> + <property name="can-focus">True</property> + <property name="focus-on-click">False</property> + <property name="receives-default">True</property> + <property name="no-show-all">True</property> + <property name="image">image3</property> + <property name="relief">none</property> + <property name="always-show-image">True</property> + <style> + <class name="small-button"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">3</property> + </packing> + </child> + <child> + <object class="GtkButton" id="first"> + <property name="can-focus">True</property> + <property name="focus-on-click">False</property> + <property name="receives-default">True</property> + <property name="no-show-all">True</property> + <property name="image">image5</property> + <property name="relief">none</property> + <property name="always-show-image">True</property> + <style> + <class name="small-button"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">4</property> + </packing> + </child> + </object> +</interface> diff --git a/vcl/source/app/weldutils.cxx b/vcl/source/app/weldutils.cxx index 76e887c67644..837220447063 100644 --- a/vcl/source/app/weldutils.cxx +++ b/vcl/source/app/weldutils.cxx @@ -13,6 +13,7 @@ #include <svl/zforlist.hxx> #include <svl/zformat.hxx> #include <vcl/builderpage.hxx> +#include <vcl/commandevent.hxx> #include <vcl/commandinfoprovider.hxx> #include <vcl/event.hxx> #include <vcl/settings.hxx> @@ -548,9 +549,11 @@ void WidgetStatusListener::dispose() mWidget = nullptr; } -ButtonPressRepeater::ButtonPressRepeater(weld::Button& rButton, const Link<Button&, void>& rLink) +ButtonPressRepeater::ButtonPressRepeater(weld::Button& rButton, const Link<Button&, void>& rLink, + const Link<const CommandEvent&, void>& rContextLink) : m_rButton(rButton) , m_aLink(rLink) + , m_aContextLink(rContextLink) , m_bModKey(false) { // instead of connect_clicked because we want a button held down to @@ -563,6 +566,12 @@ ButtonPressRepeater::ButtonPressRepeater(weld::Button& rButton, const Link<Butto IMPL_LINK(ButtonPressRepeater, MousePressHdl, const MouseEvent&, rMouseEvent, bool) { + if (rMouseEvent.IsRight()) + { + m_aContextLink.Call( + CommandEvent(rMouseEvent.GetPosPixel(), CommandEventId::ContextMenu, true)); + return false; + } m_bModKey = rMouseEvent.IsMod1(); if (!m_rButton.get_sensitive()) return false; |