[Libreoffice-commits] .: Branch 'feature/cmclayouttrans' - vcl/inc vcl/qa vcl/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Thu Aug 23 03:55:52 PDT 2012


 vcl/inc/vcl/button.hxx         |    1 
 vcl/inc/vcl/dialog.hxx         |    1 
 vcl/inc/vcl/layout.hxx         |   29 ++++++++-
 vcl/qa/cppunit/builder/demo.ui |  114 +++++++++++++++++++++++++++++++++++
 vcl/source/control/button.cxx  |    5 +
 vcl/source/window/builder.cxx  |    2 
 vcl/source/window/dialog.cxx   |   59 +++++++++---------
 vcl/source/window/layout.cxx   |  131 ++++++++++++++++++++++++++++++++++++++++-
 8 files changed, 310 insertions(+), 32 deletions(-)

New commits:
commit 9ccf0191fed208acfd43b49638ab11138db104c8
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Aug 23 11:54:40 2012 +0100

    Implement a VclExpander equivalent of GtkExpander
    
    Change-Id: I539d8d313a35509cf603f18e5f074eab331f2480

diff --git a/vcl/inc/vcl/button.hxx b/vcl/inc/vcl/button.hxx
index 6edfe7e..5a73e0a 100644
--- a/vcl/inc/vcl/button.hxx
+++ b/vcl/inc/vcl/button.hxx
@@ -560,6 +560,7 @@ class VCL_DLLPUBLIC DisclosureButton : public CheckBox
 protected:
     SAL_DLLPRIVATE virtual void ImplDrawCheckBoxState();
 public:
+    DisclosureButton( Window* pParent, WinBits nStyle = 0 );
     DisclosureButton( Window* pParent, const ResId& rResId );
 
     virtual void    KeyInput( const KeyEvent& rKEvt );
diff --git a/vcl/inc/vcl/dialog.hxx b/vcl/inc/vcl/dialog.hxx
index 8b6dc0f..5f24ee8 100644
--- a/vcl/inc/vcl/dialog.hxx
+++ b/vcl/inc/vcl/dialog.hxx
@@ -101,6 +101,7 @@ public:
     virtual Size    GetOptimalSize(WindowSizeType eType) const;
     virtual void    Resize();
     bool            isLayoutEnabled() const;
+    void            setInitialLayoutSize();
     virtual bool set_property(const rtl::OString &rKey, const rtl::OString &rValue);
 
     void set_border_width(int nBorderWidth)
diff --git a/vcl/inc/vcl/layout.hxx b/vcl/inc/vcl/layout.hxx
index ca6d50f..42071ce 100644
--- a/vcl/inc/vcl/layout.hxx
+++ b/vcl/inc/vcl/layout.hxx
@@ -29,6 +29,7 @@
 #define _VCLLAYOUT_HXX
 
 #include <vcl/dllapi.h>
+#include <vcl/button.hxx>
 #include <vcl/window.hxx>
 #include <boost/multi_array.hpp>
 
@@ -377,8 +378,8 @@ class VCL_DLLPUBLIC VclBin : public VclContainer
 {
 public:
     VclBin(Window *pParent) : VclContainer(pParent) {}
-    Window *get_child();
-    const Window *get_child() const;
+    virtual Window *get_child();
+    virtual const Window *get_child() const;
     virtual Size calculateRequisition() const;
     virtual void setAllocation(const Size &rAllocation);
 };
@@ -422,6 +423,30 @@ private:
     float m_fYScale;
 };
 
+class VCL_DLLPUBLIC VclExpander : public VclBin
+{
+public:
+    VclExpander(Window *pParent)
+        : VclBin(pParent)
+        , m_bResizeTopLevel(true)
+        , m_aDisclosureButton(this)
+    {
+        m_aDisclosureButton.SetToggleHdl(LINK(this, VclExpander, ClickHdl));
+        m_aDisclosureButton.Show();
+    }
+    virtual Window *get_child();
+    virtual const Window *get_child() const;
+    virtual bool set_property(const rtl::OString &rKey, const rtl::OString &rValue);
+protected:
+    virtual Size calculateRequisition() const;
+    virtual void setAllocation(const Size &rAllocation);
+private:
+    bool m_bResizeTopLevel;
+    DisclosureButton m_aDisclosureButton;
+    DECL_DLLPRIVATE_LINK(ClickHdl, DisclosureButton* pBtn);
+};
+
+
 /*
  * @return true if rValue is "True", "true", "1", etc.
  */
diff --git a/vcl/qa/cppunit/builder/demo.ui b/vcl/qa/cppunit/builder/demo.ui
index 776173e..b83fd65 100644
--- a/vcl/qa/cppunit/builder/demo.ui
+++ b/vcl/qa/cppunit/builder/demo.ui
@@ -1880,6 +1880,120 @@
                 <property name="tab_fill">False</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkExpander" id="expander1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="resize_toplevel">True</property>
+                <child>
+                  <object class="GtkGrid" id="grid5">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="row_spacing">200</property>
+                    <property name="column_spacing">400</property>
+                    <child>
+                      <object class="GtkLabel" id="label34">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">label</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label35">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">label</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label36">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">label</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">2</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label37">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">label</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label38">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">label</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label39">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">label</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">2</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label40">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Details</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="position">6</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="label33">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">page 7</property>
+              </object>
+              <packing>
+                <property name="position">6</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="expand">True</property>
diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx
index 4c14d47..d806063 100644
--- a/vcl/source/control/button.cxx
+++ b/vcl/source/control/button.cxx
@@ -4168,6 +4168,11 @@ TriStateBox::~TriStateBox()
 
 // =======================================================================
 
+DisclosureButton::DisclosureButton( Window* pParent, WinBits nStyle ) :
+    CheckBox( pParent, nStyle )
+{
+}
+
 DisclosureButton::DisclosureButton( Window* pParent, const ResId& rResId ) :
     CheckBox( pParent, rResId.SetRT( RSC_CHECKBOX ) )
 {
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 2fa0f6f..7b42362 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -390,6 +390,8 @@ Window *VclBuilder::makeObject(Window *pParent, const rtl::OString &name, const
         pWindow = new VclGrid(pParent);
     else if (name.equalsL(RTL_CONSTASCII_STRINGPARAM("GtkFrame")))
         pWindow = new VclFrame(pParent);
+    else if (name.equalsL(RTL_CONSTASCII_STRINGPARAM("GtkExpander")))
+        pWindow = new VclExpander(pParent);
     else if (name.equalsL(RTL_CONSTASCII_STRINGPARAM("GtkAlignment")))
         pWindow = new VclAlignment(pParent);
     else if (name.equalsL(RTL_CONSTASCII_STRINGPARAM("GtkButton")))
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index fe41ae7..3574af1 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -649,43 +649,46 @@ long Dialog::Notify( NotifyEvent& rNEvt )
     return nRet;
 }
 
-// -----------------------------------------------------------------------
-
-void Dialog::StateChanged( StateChangedType nType )
+void Dialog::setInitialLayoutSize()
 {
-    SystemWindow::StateChanged( nType );
+    maLayoutTimer.Stop();
 
-    if ( nType == STATE_CHANGE_INITSHOW )
+    //resize dialog to fit requisition on initial show
+    VclBox *pBox = static_cast<VclBox*>(GetWindow(WINDOW_FIRSTCHILD));
+
+    const DialogStyle& rDialogStyle =
+        GetSettings().GetStyleSettings().GetDialogStyle();
+    pBox->set_border_width(rDialogStyle.content_area_border);
+    pBox->set_spacing(rDialogStyle.content_area_spacing);
+
+    VclButtonBox *pActionArea = getActionArea(this);
+    if (pActionArea)
     {
-        if (isLayoutEnabled())
-        {
-            maLayoutTimer.Stop();
+        pActionArea->set_border_width(rDialogStyle.action_area_border);
+        pActionArea->set_spacing(rDialogStyle.button_spacing);
+    }
 
-            //resize dialog to fit requisition on initial show
-            VclBox *pBox = static_cast<VclBox*>(GetWindow(WINDOW_FIRSTCHILD));
+    Size aSize = get_preferred_size();
 
-            const DialogStyle& rDialogStyle =
-                GetSettings().GetStyleSettings().GetDialogStyle();
-            pBox->set_border_width(rDialogStyle.content_area_border);
-            pBox->set_spacing(rDialogStyle.content_area_spacing);
+    Size aMax = GetOptimalSize(WINDOWSIZE_MAXIMUM);
+    aSize.Width() = std::min(aMax.Width(), aSize.Width());
+    aSize.Height() = std::min(aMax.Height(), aSize.Height());
 
-            VclButtonBox *pActionArea = getActionArea(this);
-            if (pActionArea)
-            {
-                pActionArea->set_border_width(rDialogStyle.action_area_border);
-                pActionArea->set_spacing(rDialogStyle.button_spacing);
-            }
+    SetMinOutputSizePixel(aSize);
+    SetSizePixel(aSize);
+    setPosSizeOnContainee(aSize, *pBox);
+}
 
-            Size aSize = get_preferred_size();
+// -----------------------------------------------------------------------
 
-            Size aMax = GetOptimalSize(WINDOWSIZE_MAXIMUM);
-            aSize.Width() = std::min(aMax.Width(), aSize.Width());
-            aSize.Height() = std::min(aMax.Height(), aSize.Height());
+void Dialog::StateChanged( StateChangedType nType )
+{
+    SystemWindow::StateChanged( nType );
 
-            SetMinOutputSizePixel(aSize);
-            SetSizePixel(aSize);
-            setPosSizeOnContainee(aSize, *pBox);
-        }
+    if ( nType == STATE_CHANGE_INITSHOW )
+    {
+        if (isLayoutEnabled())
+            setInitialLayoutSize();
 
         if ( GetSettings().GetStyleSettings().GetAutoMnemonic() )
             ImplWindowAutoMnemonic( this );
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index 1bc2233..67b4af8 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -26,6 +26,7 @@
  * instead of those above.
  */
 
+#include <vcl/dialog.hxx>
 #include <vcl/layout.hxx>
 #include "window.h"
 
@@ -865,8 +866,6 @@ Size VclAlignment::calculateRequisition() const
 
 void VclAlignment::setAllocation(const Size &rAllocation)
 {
-    //SetBackground( Color(0x00, 0x00, 0xFF) );
-
     Window *pChild = get_child();
     if (!pChild || !pChild->IsVisible())
         return;
@@ -903,6 +902,134 @@ bool VclAlignment::set_property(const rtl::OString &rKey, const rtl::OString &rV
     return true;
 }
 
+const Window *VclExpander::get_child() const
+{
+    const WindowImpl* pWindowImpl = ImplGetWindowImpl();
+
+    assert(pWindowImpl->mpFirstChild == &m_aDisclosureButton);
+
+    return pWindowImpl->mpFirstChild->GetWindow(WINDOW_NEXT);
+}
+
+Window *VclExpander::get_child()
+{
+    return const_cast<Window*>(const_cast<const VclExpander*>(this)->get_child());
+}
+
+Size VclExpander::calculateRequisition() const
+{
+    Size aRet(0, 0);
+
+    WindowImpl* pWindowImpl = ImplGetWindowImpl();
+
+    const Window *pChild = get_child();
+    const Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
+
+    if (pChild && pChild->IsVisible() && m_aDisclosureButton.IsChecked())
+        aRet = pChild->GetOptimalSize(WINDOWSIZE_PREFERRED);
+
+    Size aExpanderSize = m_aDisclosureButton.GetOptimalSize(WINDOWSIZE_PREFERRED);
+
+    if (pLabel && pLabel->IsVisible())
+    {
+        Size aLabelSize = pLabel->GetOptimalSize(WINDOWSIZE_PREFERRED);
+        aExpanderSize.Height() = std::max(aExpanderSize.Height(), aLabelSize.Height());
+        aExpanderSize.Width() += aLabelSize.Width();
+    }
+
+    aRet.Height() += aExpanderSize.Height();
+    aRet.Width() = std::max(aExpanderSize.Width(), aRet.Width());
+
+    const FrameStyle &rFrameStyle =
+        GetSettings().GetStyleSettings().GetFrameStyle();
+    aRet.Width() += rFrameStyle.left + rFrameStyle.right;
+    aRet.Height() += rFrameStyle.top + rFrameStyle.bottom;
+
+    return aRet;
+}
+
+void VclExpander::setAllocation(const Size &rAllocation)
+{
+    const FrameStyle &rFrameStyle =
+        GetSettings().GetStyleSettings().GetFrameStyle();
+    Size aAllocation(rAllocation.Width() - rFrameStyle.left - rFrameStyle.right,
+        rAllocation.Height() - rFrameStyle.top - rFrameStyle.bottom);
+    Point aChildPos(rFrameStyle.left, rFrameStyle.top);
+
+    WindowImpl* pWindowImpl = ImplGetWindowImpl();
+
+    //The label widget is the last (of two) children
+    Window *pChild = get_child();
+    Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
+
+    Size aButtonSize = m_aDisclosureButton.GetOptimalSize(WINDOWSIZE_PREFERRED);
+    Size aLabelSize;
+    Size aExpanderSize = aButtonSize;
+    if (pLabel && pLabel->IsVisible())
+    {
+        aLabelSize = pLabel->GetOptimalSize(WINDOWSIZE_PREFERRED);
+        aExpanderSize.Height() = std::max(aExpanderSize.Height(), aLabelSize.Height());
+        aExpanderSize.Width() += aLabelSize.Width();
+    }
+
+    aExpanderSize.Height() = std::min(aExpanderSize.Height(), aAllocation.Height());
+    aExpanderSize.Width() = std::min(aExpanderSize.Width(), aAllocation.Width());
+
+    aButtonSize.Height() = std::min(aButtonSize.Height(), aExpanderSize.Height());
+    aButtonSize.Width() = std::min(aButtonSize.Width(), aExpanderSize.Width());
+
+    long nExtraExpanderHeight = aExpanderSize.Height() - aButtonSize.Height();
+    Point aButtonPos(aChildPos.X(), aChildPos.Y() + nExtraExpanderHeight/2);
+    setPosSizePixel(m_aDisclosureButton, aButtonPos, aButtonSize);
+
+    if (pLabel && pLabel->IsVisible())
+    {
+        aLabelSize.Height() = std::min(aLabelSize.Height(), aExpanderSize.Height());
+        aLabelSize.Width() = std::min(aLabelSize.Width(),
+            aExpanderSize.Width() - aButtonSize.Width());
+
+        long nExtraLabelHeight = aExpanderSize.Height() - aLabelSize.Height();
+        Point aLabelPos(aChildPos.X() + aButtonSize.Width(), aChildPos.Y() + nExtraLabelHeight/2);
+        setPosSizePixel(*pLabel, aLabelPos, aLabelSize);
+    }
+
+    aAllocation.Height() -= aExpanderSize.Height();
+    aChildPos.Y() += aExpanderSize.Height();
+
+    if (pChild && pChild->IsVisible())
+    {
+        if (!m_aDisclosureButton.IsChecked())
+            aAllocation = Size();
+        setPosSizePixel(*pChild, aChildPos, aAllocation);
+    }
+}
+
+bool VclExpander::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
+{
+    if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("expanded")))
+        m_aDisclosureButton.Check(toBool(rValue));
+    else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("resize-toplevel")))
+        m_bResizeTopLevel = toBool(rValue);
+    else
+        return VclBin::set_property(rKey, rValue);
+    return true;
+}
+
+IMPL_LINK( VclExpander, ClickHdl, DisclosureButton*, pBtn )
+{
+    Window *pChild = get_child();
+    if (pChild)
+    {
+        pChild->Show(pBtn->IsChecked());
+        Dialog* pResizeDialog = m_bResizeTopLevel ? GetParentDialog() : NULL;
+        if (pResizeDialog)
+            pResizeDialog->setInitialLayoutSize();
+        else
+            queue_resize();
+    }
+    return 0;
+}
+
 Size getLegacyBestSizeForChildren(const Window &rWindow)
 {
     Rectangle aBounds;


More information about the Libreoffice-commits mailing list