diff options
author | Caolán McNamara <caolanm@redhat.com> | 2012-06-11 12:48:24 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2012-09-28 08:48:26 +0100 |
commit | 839acd1be4d158e285d98527ed48c64628fdc2d7 (patch) | |
tree | a3cf294910882075dd4abd43de1ec47f090caea5 /vcl | |
parent | c17c1b2ae7a6a00dce6d2018b5f3cce1d3eb3193 (diff) |
implement widget alignment within gtkgrid
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/vcl/vclenum.hxx | 8 | ||||
-rw-r--r-- | vcl/inc/vcl/window.hxx | 47 | ||||
-rw-r--r-- | vcl/inc/window.h | 8 | ||||
-rw-r--r-- | vcl/qa/cppunit/builder/demo.ui | 349 | ||||
-rw-r--r-- | vcl/source/window/layout.cxx | 79 | ||||
-rw-r--r-- | vcl/source/window/window.cxx | 76 |
6 files changed, 507 insertions, 60 deletions
diff --git a/vcl/inc/vcl/vclenum.hxx b/vcl/inc/vcl/vclenum.hxx index 95510e8414f0..e497fc410514 100644 --- a/vcl/inc/vcl/vclenum.hxx +++ b/vcl/inc/vcl/vclenum.hxx @@ -192,6 +192,14 @@ inline bool operator !=(const ItalicMatrix& a, const ItalicMatrix& b) return a.xx != b.xx || a.xy != b.xy || a.yx != b.yx || a.yy != b.yy; } +enum VclAlign +{ + VCL_ALIGN_FILL, + VCL_ALIGN_START, + VCL_ALIGN_END, + VCL_ALIGN_CENTER +}; + #endif // _VCL_VCLENUM_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/vcl/window.hxx b/vcl/inc/vcl/window.hxx index aec700c579c6..312f8122ef39 100644 --- a/vcl/inc/vcl/window.hxx +++ b/vcl/inc/vcl/window.hxx @@ -329,7 +329,8 @@ typedef sal_uInt16 StateChangedType; #define DLGWINDOW_NEXT 1 #define DLGWINDOW_FIRST 2 -enum WindowSizeType { +enum WindowSizeType +{ WINDOWSIZE_MINIMUM, WINDOWSIZE_PREFERRED, WINDOWSIZE_MAXIMUM @@ -1119,6 +1120,50 @@ public: Size get_preferred_size() const; /* + * Gets the value of the "halign" property. + */ + VclAlign get_halign() const; + + /* + * Sets the horizontal alignment of widget. See the "halign" property. + */ + void set_halign(VclAlign eAlign); + + /* + * Gets the value of the "valign" property. + */ + VclAlign get_valign() const; + + /* + * Sets the horizontal alignment of widget. See the "valign" property. + */ + void set_valign(VclAlign eAlign); + + /* + * Gets whether the widget would like to use any available extra horizontal + * space. + */ + bool get_hexpand() const; + + /* + * Sets whether the widget would like to use any available extra horizontal + * space. + */ + void set_hexpand(bool bExpand); + + /* + * Gets whether the widget would like to use any available extra vertical + * space. + */ + bool get_vexpand() const; + + /* + * Sets whether the widget would like to use any available extra vertical + * space. + */ + void set_vexpand(bool bExpand); + + /* * Sets a widget property * * @return false if property is unknown diff --git a/vcl/inc/window.h b/vcl/inc/window.h index 7e7d0461f9f6..af7443cbe613 100644 --- a/vcl/inc/window.h +++ b/vcl/inc/window.h @@ -315,7 +315,9 @@ public: sal_uInt16 mnDlgCtrlFlags; sal_uInt16 mnLockCount; AlwaysInputMode meAlwaysInputMode; - sal_Bool mbFrame:1, + VclAlign meHalign; + VclAlign meValign; + sal_uInt8 mbFrame:1, mbBorderWin:1, mbOverlapWin:1, mbSysWin:1, @@ -388,7 +390,9 @@ public: mbDisableAccessibleLabelForRelation:1, mbDisableAccessibleLabeledByRelation:1, mbHelpTextDynamic:1, - mbFakeFocusSet:1; + mbFakeFocusSet:1, + mbHexpand:1, + mbVexpand:1; ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > mxDNDListenerContainer; }; diff --git a/vcl/qa/cppunit/builder/demo.ui b/vcl/qa/cppunit/builder/demo.ui index 39754e402349..681212e97c03 100644 --- a/vcl/qa/cppunit/builder/demo.ui +++ b/vcl/qa/cppunit/builder/demo.ui @@ -1,47 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <interface> <!-- interface-requires gtk+ 3.0 --> - <object class="GtkListStore" id="liststore2"> - <columns> - <!-- column-name gchararray1 --> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes">1</col> - </row> - <row> - <col id="0" translatable="yes">2</col> - </row> - <row> - <col id="0" translatable="yes">3</col> - </row> - <row> - <col id="0" translatable="yes">4</col> - </row> - <row> - <col id="0" translatable="yes">5</col> - </row> - <row> - <col id="0" translatable="yes">6</col> - </row> - <row> - <col id="0" translatable="yes">7</col> - </row> - <row> - <col id="0" translatable="yes">8</col> - </row> - <row> - <col id="0" translatable="yes">9</col> - </row> - <row> - <col id="0" translatable="yes">10</col> - </row> - <row> - <col id="0" translatable="yes">1 - 10</col> - </row> - </data> - </object> <object class="GtkDialog" id="dialog1"> <property name="can_focus">False</property> <property name="border_width">5</property> @@ -1655,9 +1614,274 @@ <property name="tab_fill">False</property> </packing> </child> + <child> + <object class="GtkBox" id="box21"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">10</property> + <property name="margin_right">10</property> + <child> + <object class="GtkFrame" id="frame10"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkAlignment" id="alignment13"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> + <child> + <object class="GtkTreeView" id="treeview2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="model">liststore2</property> + <property name="headers_visible">False</property> + <property name="search_column">0</property> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection4"/> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="label26"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Level</property> + <property name="use_markup">True</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkFrame" id="frame11"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkAlignment" id="alignment14"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> + <child> + <object class="GtkGrid" id="grid4"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="row_spacing">10</property> + <property name="column_spacing">10</property> + <child> + <object class="GtkLabel" id="label27"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Numbering followed by</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="label28"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Numbering Alignment</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="label29"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Aligned at</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">3</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label30"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Indent at</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">4</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox5"> + <property name="visible">True</property> + <property name="can_focus">False</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> + <child> + <object class="GtkSpinButton" id="spinbutton4"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">●</property> + <property name="invisible_char_set">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">4</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label31"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">at</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="GtkSpinButton" id="spinbutton5"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">●</property> + <property name="invisible_char_set">True</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="GtkSpinButton" id="spinbutton6"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">●</property> + <property name="invisible_char_set">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">3</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox6"> + <property name="visible">True</property> + <property name="can_focus">False</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="GtkDrawingArea" id="drawingarea2"> + <property name="width_request">300</property> + <property name="height_request">150</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">5</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="button6"> + <property name="label" translatable="yes">Default</property> + <property name="use_action_appearance">False</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="valign">end</property> + <property name="use_action_appearance">False</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">5</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="label32"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Position and spacing</property> + <property name="use_markup">True</property> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="position">5</property> + </packing> + </child> + <child type="tab"> + <object class="GtkLabel" id="label25"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">page 6</property> + </object> + <packing> + <property name="position">5</property> + <property name="tab_fill">False</property> + </packing> + </child> </object> <packing> - <property name="expand">False</property> + <property name="expand">True</property> <property name="fill">True</property> <property name="position">1</property> </packing> @@ -1683,4 +1907,45 @@ </row> </data> </object> + <object class="GtkListStore" id="liststore2"> + <columns> + <!-- column-name gchararray1 --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0" translatable="yes">1</col> + </row> + <row> + <col id="0" translatable="yes">2</col> + </row> + <row> + <col id="0" translatable="yes">3</col> + </row> + <row> + <col id="0" translatable="yes">4</col> + </row> + <row> + <col id="0" translatable="yes">5</col> + </row> + <row> + <col id="0" translatable="yes">6</col> + </row> + <row> + <col id="0" translatable="yes">7</col> + </row> + <row> + <col id="0" translatable="yes">8</col> + </row> + <row> + <col id="0" translatable="yes">9</col> + </row> + <row> + <col id="0" translatable="yes">10</col> + </row> + <row> + <col id="0" translatable="yes">1 - 10</col> + </row> + </data> + </object> </interface> diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx index bfcf73ec96da..79c63fe7d330 100644 --- a/vcl/source/window/layout.cxx +++ b/vcl/source/window/layout.cxx @@ -259,8 +259,6 @@ Size VclButtonBox::calculateRequisition() const long nSecondaryDimension = getSecondaryDimension(aSize); setSecondaryDimension(aSize, nSecondaryDimension); - fprintf(stderr, "button box asked for %ld %ld\n", aSize.Width(), aSize.Height()); - return aSize; } @@ -292,8 +290,6 @@ bool VclButtonBox::set_property(const rtl::OString &rKey, const rtl::OString &rV void VclButtonBox::setAllocation(const Size &rAllocation) { - fprintf(stderr, "button box got %ld %ld\n", rAllocation.Width(), rAllocation.Height()); - sal_uInt16 nVisibleChildren = 0; for (Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT)) { @@ -506,7 +502,7 @@ void VclGrid::setAllocation(const Size& rAllocation) rtl::OString sWidth(RTL_CONSTASCII_STRINGPARAM("width")); rtl::OString sHeight(RTL_CONSTASCII_STRINGPARAM("height")); - Point aPosition(0, 0); + Point aAllocPos(0, 0); for (sal_Int32 x = 0; x < nMaxX; ++x) { for (sal_Int32 y = 0; y < nMaxY; ++y) @@ -514,24 +510,77 @@ void VclGrid::setAllocation(const Size& rAllocation) Window *pChild = A[x][y]; if (pChild) { - Size aChildSize(0, 0); + Size aChildAlloc(0, 0); sal_Int32 nWidth = pChild->getWidgetProperty<sal_Int32>(sWidth, 1); for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX) - aChildSize.Width() += aWidths[x+nSpanX]; - aChildSize.Width() += get_column_spacing()*(nWidth-1); + aChildAlloc.Width() += aWidths[x+nSpanX]; + aChildAlloc.Width() += get_column_spacing()*(nWidth-1); sal_Int32 nHeight = pChild->getWidgetProperty<sal_Int32>(sHeight, 1); for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY) - aChildSize.Height() += aHeights[y+nSpanY]; - aChildSize.Height() += get_row_spacing()*(nHeight-1); - - pChild->SetPosSizePixel(aPosition, aChildSize); + aChildAlloc.Height() += aHeights[y+nSpanY]; + aChildAlloc.Height() += get_row_spacing()*(nHeight-1); + + Point aChildPos(aAllocPos); + Size aChildSize(aChildAlloc); + + VclAlign eHalign = pChild->get_halign(); + VclAlign eValign = pChild->get_valign(); + + Size aChildPreferredSize; + + if (eHalign != VCL_ALIGN_FILL || eValign != VCL_ALIGN_FILL) + aChildPreferredSize = pChild->GetOptimalSize(WINDOWSIZE_PREFERRED); + + switch (eHalign) + { + case VCL_ALIGN_FILL: + break; + case VCL_ALIGN_START: + if (aChildPreferredSize.Width() < aChildAlloc.Width()) + aChildSize.Width() = aChildPreferredSize.Width(); + break; + case VCL_ALIGN_END: + if (aChildPreferredSize.Width() < aChildAlloc.Width()) + aChildSize.Width() = aChildPreferredSize.Width(); + aChildPos.X() += aChildAlloc.Width(); + aChildPos.X() -= aChildSize.Width(); + break; + case VCL_ALIGN_CENTER: + if (aChildPreferredSize.Width() < aChildSize.Width()) + aChildSize.Width() = aChildPreferredSize.Width(); + aChildPos.X() += (aChildAlloc.Width() - aChildSize.Width()) / 2; + break; + } + + switch (eValign) + { + case VCL_ALIGN_FILL: + break; + case VCL_ALIGN_START: + if (aChildPreferredSize.Height() < aChildAlloc.Height()) + aChildSize.Height() = aChildPreferredSize.Height(); + break; + case VCL_ALIGN_END: + if (aChildPreferredSize.Height() < aChildAlloc.Height()) + aChildSize.Height() = aChildPreferredSize.Height(); + aChildPos.Y() += aChildAlloc.Height(); + aChildPos.Y() -= aChildSize.Height(); + break; + case VCL_ALIGN_CENTER: + if (aChildPreferredSize.Height() < aChildSize.Height()) + aChildSize.Height() = aChildPreferredSize.Height(); + aChildPos.Y() += (aChildAlloc.Height() - aChildSize.Height()) / 2; + break; + } + + pChild->SetPosSizePixel(aChildPos, aChildSize); } - aPosition.Y() += aHeights[y] + get_row_spacing(); + aAllocPos.Y() += aHeights[y] + get_row_spacing(); } - aPosition.X() += aWidths[x] + get_column_spacing(); - aPosition.Y() = 0; + aAllocPos.X() += aWidths[x] + get_column_spacing(); + aAllocPos.Y() = 0; } } diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index 8538512b0165..2a2c574c5dca 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -710,6 +710,11 @@ void Window::ImplInitWindowData( WindowType nType ) mpWindowImpl->mbDisableAccessibleLabeledByRelation = sal_False; // sal_True: do not set LabeledBy relation on accessible objects mpWindowImpl->mbHelpTextDynamic = sal_False; // sal_True: append help id in HELP_DEBUG case mpWindowImpl->mbFakeFocusSet = sal_False; // sal_True: pretend as if the window has focus. + mpWindowImpl->mbHexpand = false; + mpWindowImpl->mbVexpand = false; + mpWindowImpl->meHalign = VCL_ALIGN_FILL; + mpWindowImpl->meValign = VCL_ALIGN_FILL; + mbEnableRTL = Application::GetSettings().GetLayoutRTL(); // sal_True: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active } @@ -9799,6 +9804,11 @@ void Window::take_properties(Window &rOther) mpWindowImpl->mbHelpTextDynamic = pWindowImpl->mbHelpTextDynamic; mpWindowImpl->mbFakeFocusSet = pWindowImpl->mbFakeFocusSet; mpWindowImpl->mbInterceptChildWindowKeyDown = pWindowImpl->mbInterceptChildWindowKeyDown; + mpWindowImpl->mbHexpand = pWindowImpl->mbHexpand; + mpWindowImpl->mbVexpand = pWindowImpl->mbVexpand; + mpWindowImpl->meHalign = pWindowImpl->meHalign; + mpWindowImpl->meValign = pWindowImpl->meValign; + std::swap(m_aWidgetProperties, rOther.m_aWidgetProperties); @@ -9811,6 +9821,24 @@ void Window::take_properties(Window &rOther) mpWindowImpl->mpBorderWindow->take_properties(*pWindowImpl->mpBorderWindow); } +namespace +{ + VclAlign toAlign(const rtl::OString &rValue) + { + VclAlign eRet = VCL_ALIGN_FILL; + + if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("fill"))) + eRet = VCL_ALIGN_FILL; + else if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("start"))) + eRet = VCL_ALIGN_START; + else if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("end"))) + eRet = VCL_ALIGN_END; + else if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("center"))) + eRet = VCL_ALIGN_CENTER; + return eRet; + } +} + bool Window::set_property(const rtl::OString &rKey, const rtl::OString &rValue) { if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("label"))) @@ -9863,6 +9891,14 @@ bool Window::set_property(const rtl::OString &rKey, const rtl::OString &rValue) set_height_request(rValue.toInt32()); else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("width-request"))) set_width_request(rValue.toInt32()); + else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("hexpand"))) + set_hexpand(toBool(rValue)); + else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("vexpand"))) + set_vexpand(toBool(rValue)); + else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("halign"))) + set_halign(toAlign(rValue)); + else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("valign"))) + set_valign(toAlign(rValue)); else { fprintf(stderr, "unhandled property %s\n", rKey.getStr()); @@ -9871,4 +9907,44 @@ bool Window::set_property(const rtl::OString &rKey, const rtl::OString &rValue) return true; } +VclAlign Window::get_halign() const +{ + return mpWindowImpl->meHalign; +} + +void Window::set_halign(VclAlign eAlign) +{ + mpWindowImpl->meHalign = eAlign; +} + +VclAlign Window::get_valign() const +{ + return mpWindowImpl->meValign; +} + +void Window::set_valign(VclAlign eAlign) +{ + mpWindowImpl->meValign = eAlign; +} + +bool Window::get_hexpand() const +{ + return mpWindowImpl->mbHexpand; +} + +void Window::set_hexpand(bool bExpand) +{ + mpWindowImpl->mbHexpand = bExpand; +} + +bool Window::get_vexpand() const +{ + return mpWindowImpl->mbVexpand; +} + +void Window::set_vexpand(bool bExpand) +{ + mpWindowImpl->mbVexpand = bExpand; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |