include/vcl/weld.hxx          |   26 +++++++++
 vcl/inc/salvtables.hxx        |    2 
 vcl/source/app/salvtables.cxx |   79 +++++++++++++++++++++++++++
 vcl/unx/gtk3/gtkinst.cxx      |  119 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 226 insertions(+)

New commits:
commit cadd2a9ea61464c8da3536b262a09ab50691f8d6
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Tue Aug 2 16:44:44 2022 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Wed Aug 3 12:44:59 2022 +0200

    allow welding scrollbars individually
    
    typically a full ScrolledWindow is probably preferable, but allow
    individual scrollbars to be used
    
    Change-Id: Iab290b387421d7d97d3604e31f528769d822155a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137709
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 11ecec27ee9a..2f5a76cb8bdb 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -2493,6 +2493,31 @@ public:
     void connect_menu_toggled(const Link<const OString&, void>& rLink) { 
m_aToggleMenuHdl = rLink; }
 };
 
+class VCL_DLLPUBLIC Scrollbar : virtual public Widget
+{
+protected:
+    Link<Scrollbar&, void> m_aChangeHdl;
+
+    void signal_adjustment_changed() { m_aChangeHdl.Call(*this); }
+
+public:
+    virtual void adjustment_configure(int value, int lower, int upper, int 
step_increment,
+                                      int page_increment, int page_size)
+        = 0;
+    virtual int adjustment_get_value() const = 0;
+    virtual void adjustment_set_value(int value) = 0;
+    virtual int adjustment_get_upper() const = 0;
+    virtual void adjustment_set_upper(int upper) = 0;
+    virtual int adjustment_get_page_size() const = 0;
+    virtual void adjustment_set_page_size(int size) = 0;
+    virtual void adjustment_set_page_increment(int size) = 0;
+    virtual void adjustment_set_step_increment(int size) = 0;
+    virtual int adjustment_get_lower() const = 0;
+    virtual void adjustment_set_lower(int upper) = 0;
+
+    void connect_adjustment_changed(const Link<Scrollbar&, void>& rLink) { 
m_aChangeHdl = rLink; }
+};
+
 class VCL_DLLPUBLIC SizeGroup
 {
 public:
@@ -2555,6 +2580,7 @@ public:
     virtual std::unique_ptr<Menu> weld_menu(const OString& id) = 0;
     virtual std::unique_ptr<Popover> weld_popover(const OString& id) = 0;
     virtual std::unique_ptr<Toolbar> weld_toolbar(const OString& id) = 0;
+    virtual std::unique_ptr<Scrollbar> weld_scrollbar(const OString& id) = 0;
     virtual std::unique_ptr<SizeGroup> create_size_group() = 0;
     /* return a Dialog suitable to take a screenshot of containing the 
contents of the .ui file.
 
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index 1fca22d1702b..17084200955a 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -126,6 +126,8 @@ public:
 
     virtual std::unique_ptr<weld::Toolbar> weld_toolbar(const OString& id) 
override;
 
+    virtual std::unique_ptr<weld::Scrollbar> weld_scrollbar(const OString& id) 
override;
+
     virtual std::unique_ptr<weld::SizeGroup> create_size_group() override;
 
     OString get_current_page_help_id() const;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index f3c7f8e8a7a3..2f5d542b0fc5 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -2488,6 +2488,79 @@ IMPL_LINK_NOARG(SalInstanceScrolledWindow, HscrollHdl, 
ScrollBar*, void)
         m_aOrigHScrollHdl.Call(&m_xScrolledWindow->getHorzScrollBar());
 }
 
+namespace
+{
+class SalInstanceScrollbar : public SalInstanceWidget, public virtual 
weld::Scrollbar
+{
+private:
+    VclPtr<ScrollBar> m_xScrollBar;
+    Link<ScrollBar*, void> m_aOrigScrollHdl;
+
+    DECL_LINK(ScrollHdl, ScrollBar*, void);
+
+public:
+    SalInstanceScrollbar(ScrollBar* pScrollbar, SalInstanceBuilder* pBuilder, 
bool bTakeOwnership)
+        : SalInstanceWidget(pScrollbar, pBuilder, bTakeOwnership)
+        , m_xScrollBar(pScrollbar)
+    {
+        m_aOrigScrollHdl = m_xScrollBar->GetScrollHdl();
+        m_xScrollBar->SetScrollHdl(LINK(this, SalInstanceScrollbar, 
ScrollHdl));
+    }
+
+    virtual void adjustment_configure(int value, int lower, int upper, int 
step_increment,
+                                      int page_increment, int page_size) 
override
+    {
+        m_xScrollBar->SetRangeMin(lower);
+        m_xScrollBar->SetRangeMax(upper);
+        m_xScrollBar->SetLineSize(step_increment);
+        m_xScrollBar->SetPageSize(page_increment);
+        m_xScrollBar->SetThumbPos(value);
+        m_xScrollBar->SetVisibleSize(page_size);
+    }
+
+    virtual int adjustment_get_value() const override { return 
m_xScrollBar->GetThumbPos(); }
+
+    virtual void adjustment_set_value(int value) override
+    {
+        m_xScrollBar->SetThumbPos(value);
+        m_aOrigScrollHdl.Call(m_xScrollBar.get());
+    }
+
+    virtual int adjustment_get_upper() const override { return 
m_xScrollBar->GetRangeMax(); }
+
+    virtual void adjustment_set_upper(int upper) override { 
m_xScrollBar->SetRangeMax(upper); }
+
+    virtual int adjustment_get_lower() const override { return 
m_xScrollBar->GetRangeMin(); }
+
+    virtual void adjustment_set_lower(int lower) override { 
m_xScrollBar->SetRangeMin(lower); }
+
+    virtual int adjustment_get_page_size() const override { return 
m_xScrollBar->GetVisibleSize(); }
+
+    virtual void adjustment_set_page_size(int size) override
+    {
+        return m_xScrollBar->SetVisibleSize(size);
+    }
+
+    virtual void adjustment_set_page_increment(int size) override
+    {
+        return m_xScrollBar->SetPageSize(size);
+    }
+
+    virtual void adjustment_set_step_increment(int size) override
+    {
+        return m_xScrollBar->SetLineSize(size);
+    }
+
+    virtual ~SalInstanceScrollbar() override { 
m_xScrollBar->SetScrollHdl(m_aOrigScrollHdl); }
+};
+}
+
+IMPL_LINK_NOARG(SalInstanceScrollbar, ScrollHdl, ScrollBar*, void)
+{
+    signal_adjustment_changed();
+    m_aOrigScrollHdl.Call(m_xScrollBar.get());
+}
+
 SalInstanceNotebook::SalInstanceNotebook(TabControl* pNotebook, 
SalInstanceBuilder* pBuilder,
                                          bool bTakeOwnership)
     : SalInstanceWidget(pNotebook, pBuilder, bTakeOwnership)
@@ -7355,6 +7428,12 @@ std::unique_ptr<weld::Toolbar> 
SalInstanceBuilder::weld_toolbar(const OString& i
     return pToolBox ? std::make_unique<SalInstanceToolbar>(pToolBox, this, 
false) : nullptr;
 }
 
+std::unique_ptr<weld::Scrollbar> SalInstanceBuilder::weld_scrollbar(const 
OString& id)
+{
+    ScrollBar* pScrollbar = m_xBuilder->get<ScrollBar>(id);
+    return pScrollbar ? std::make_unique<SalInstanceScrollbar>(pScrollbar, 
this, false) : nullptr;
+}
+
 std::unique_ptr<weld::SizeGroup> SalInstanceBuilder::create_size_group()
 {
     return std::make_unique<SalInstanceSizeGroup>();
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 0236f1aa9529..7412c0c0742d 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -8406,6 +8406,116 @@ public:
     }
 };
 
+class GtkInstanceScrollbar final : public GtkInstanceWidget, public virtual 
weld::Scrollbar
+{
+private:
+    GtkScrollbar* m_pScrollbar;
+    GtkAdjustment* m_pAdjustment;
+    gulong m_nAdjustChangedSignalId;
+
+    static void signalAdjustValueChanged(GtkAdjustment*, gpointer widget)
+    {
+        GtkInstanceScrollbar* pThis = 
static_cast<GtkInstanceScrollbar*>(widget);
+        SolarMutexGuard aGuard;
+        pThis->signal_adjustment_changed();
+    }
+
+public:
+    GtkInstanceScrollbar(GtkScrollbar* pScrollbar, GtkInstanceBuilder* 
pBuilder, bool bTakeOwnership)
+        : GtkInstanceWidget(GTK_WIDGET(pScrollbar), pBuilder, bTakeOwnership)
+        , m_pScrollbar(pScrollbar)
+#if GTK_CHECK_VERSION(4, 0, 0)
+        , m_pAdjustment(gtk_scrollbar_get_adjustment(m_pScrollbar))
+#else
+        , m_pAdjustment(gtk_range_get_adjustment(GTK_RANGE(m_pScrollbar)))
+#endif
+        , m_nAdjustChangedSignalId(g_signal_connect(m_pAdjustment, 
"value-changed", G_CALLBACK(signalAdjustValueChanged), this))
+    {
+    }
+
+    virtual void adjustment_configure(int value, int lower, int upper,
+                                       int step_increment, int page_increment,
+                                       int page_size) override
+    {
+        disable_notify_events();
+        gtk_adjustment_configure(m_pAdjustment, value, lower, upper, 
step_increment, page_increment, page_size);
+        enable_notify_events();
+    }
+
+    virtual int adjustment_get_value() const override
+    {
+        return gtk_adjustment_get_value(m_pAdjustment);
+    }
+
+    virtual void adjustment_set_value(int value) override
+    {
+        disable_notify_events();
+        gtk_adjustment_set_value(m_pAdjustment, value);
+        enable_notify_events();
+    }
+
+    virtual int adjustment_get_upper() const override
+    {
+         return gtk_adjustment_get_upper(m_pAdjustment);
+    }
+
+    virtual void adjustment_set_upper(int upper) override
+    {
+        disable_notify_events();
+        gtk_adjustment_set_upper(m_pAdjustment, upper);
+        enable_notify_events();
+    }
+
+    virtual int adjustment_get_lower() const override
+    {
+         return gtk_adjustment_get_lower(m_pAdjustment);
+    }
+
+    virtual void adjustment_set_lower(int lower) override
+    {
+        disable_notify_events();
+        gtk_adjustment_set_lower(m_pAdjustment, lower);
+        enable_notify_events();
+    }
+
+    virtual int adjustment_get_page_size() const override
+    {
+        return gtk_adjustment_get_page_size(m_pAdjustment);
+    }
+
+    virtual void adjustment_set_page_size(int size) override
+    {
+        gtk_adjustment_set_page_size(m_pAdjustment, size);
+    }
+
+    virtual void adjustment_set_page_increment(int size) override
+    {
+        gtk_adjustment_set_page_increment(m_pAdjustment, size);
+    }
+
+    virtual void adjustment_set_step_increment(int size) override
+    {
+        gtk_adjustment_set_step_increment(m_pAdjustment, size);
+    }
+
+    virtual void disable_notify_events() override
+    {
+        g_signal_handler_block(m_pAdjustment, m_nAdjustChangedSignalId);
+        GtkInstanceWidget::disable_notify_events();
+    }
+
+    virtual void enable_notify_events() override
+    {
+        GtkInstanceWidget::enable_notify_events();
+        g_signal_handler_unblock(m_pAdjustment, m_nAdjustChangedSignalId);
+    }
+
+    virtual ~GtkInstanceScrollbar() override
+    {
+        g_signal_handler_disconnect(m_pAdjustment, m_nAdjustChangedSignalId);
+    }
+};
+
 }
 
 namespace {
@@ -23722,6 +23832,15 @@ public:
         return std::make_unique<GtkInstanceToolbar>(pToolbar, this, false);
     }
 
+    virtual std::unique_ptr<weld::Scrollbar> weld_scrollbar(const OString &id) 
override
+    {
+        GtkScrollbar* pScrollbar = 
GTK_SCROLLBAR(gtk_builder_get_object(m_pBuilder, id.getStr()));
+        if (!pScrollbar)
+            return nullptr;
+        auto_add_parentless_widgets_to_container(GTK_WIDGET(pScrollbar));
+        return std::make_unique<GtkInstanceScrollbar>(pScrollbar, this, false);
+    }
+
     virtual std::unique_ptr<weld::SizeGroup> create_size_group() override
     {
         return std::make_unique<GtkInstanceSizeGroup>();

Reply via email to