[gtkmm-documentation] Modified the custom_container and custom_widget examples.



commit 072979e91b074145cbf81c7fce14ba6de191dc13
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Sun Jan 23 19:03:46 2011 +0100

    Modified the custom_container and custom_widget examples.
    
    * docs/tutorial/C/gtkmm-tutorial-in.xml: Updated the Custom Widgets chapter.
    * examples/book/custom/custom_container/examplewindow.[h|cc]: Renamed
    m_Button_Two to m_Label_Two. Removed some calls to show().
    * examples/book/custom/custom_container/mycontainer.[h|cc]: Replaced
    on_size_request() by get_request_mode_vfunc() and get_preferred_xxx_vfunc().
    Modified on_size_allocate().
    * examples/book/custom/custom_widget/custom_gtkrc:
    * examples/book/custom/custom_widget/custom_gtk.css: Renamed custom_gtkrc
    to custom_gtk.css. Modified it to suit Gtk::CssProvider.
    * examples/book/custom/custom_widget/mywidget.[h|cc]: Replaced
    on_size_request() by get_request_mode_vfunc() and get_preferred_xxx_vfunc().
    In on_realize(), removed calls to functions that no longer exist in gtkmm 3.
    Bug 639073.

 ChangeLog                                          |   18 ++
 docs/tutorial/C/gtkmm-tutorial-in.xml              |   94 ++++++++--
 .../book/custom/custom_container/examplewindow.cc  |   10 +-
 .../book/custom/custom_container/examplewindow.h   |    2 +-
 .../book/custom/custom_container/mycontainer.cc    |  188 +++++++++++++++-----
 .../book/custom/custom_container/mycontainer.h     |    6 +-
 examples/book/custom/custom_widget/custom_gtk.css  |   10 +
 examples/book/custom/custom_widget/custom_gtkrc    |    6 -
 examples/book/custom/custom_widget/mywidget.cc     |   71 ++++++--
 examples/book/custom/custom_widget/mywidget.h      |    6 +-
 10 files changed, 315 insertions(+), 96 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index a002628..734e978 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2011-01-23  Kjell Ahlstedt <kjell ahlstedt bredband net>
+
+	Modified the custom_container and custom_widget examples.
+    
+	* docs/tutorial/C/gtkmm-tutorial-in.xml: Updated the Custom Widgets chapter.
+	* examples/book/custom/custom_container/examplewindow.[h|cc]: Renamed
+	m_Button_Two to m_Label_Two. Removed some calls to show().
+	* examples/book/custom/custom_container/mycontainer.[h|cc]: Replaced
+	on_size_request() by get_request_mode_vfunc() and get_preferred_xxx_vfunc().
+	Modified on_size_allocate().
+	* examples/book/custom/custom_widget/custom_gtkrc:
+	* examples/book/custom/custom_widget/custom_gtk.css: Renamed custom_gtkrc
+	to custom_gtk.css. Modified it to suit Gtk::CssProvider.
+	* examples/book/custom/custom_widget/mywidget.[h|cc]: Replaced
+	on_size_request() by get_request_mode_vfunc() and get_preferred_xxx_vfunc().
+	In on_realize(), removed calls to functions that no longer exist in gtkmm 3.
+	Bug 639073.
+
 2011-01-19  Murray Cumming  <murrayc murrayc com>
 
 	Base example: Try to use Gtk::Application instead of Gtk::Main.
diff --git a/docs/tutorial/C/gtkmm-tutorial-in.xml b/docs/tutorial/C/gtkmm-tutorial-in.xml
index 2c1f656..5be5f3c 100644
--- a/docs/tutorial/C/gtkmm-tutorial-in.xml
+++ b/docs/tutorial/C/gtkmm-tutorial-in.xml
@@ -6842,50 +6842,79 @@ instance, you cannot use the copyright sign (&copy;).
 <chapter id="chapter-customwidgets">
     <title>Custom Widgets</title>
 
-    <para>&gtkmm; makes it very easy to derive new widgets by inheriting from an existing widget class, either by deriving from a container and adding child widgets, or by deriving from a single-item widget, and changing its behaviour. But you might occasionally find that no suitable starting point already exists. In this case, you can implement a widget from scratch.</para>
+    <para>&gtkmm; makes it very easy to derive new widgets by inheriting from an
+      existing widget class, either by deriving from a container and adding child
+      widgets, or by deriving from a single-item widget, and changing its behaviour.
+      But you might occasionally find that no suitable starting point already exists.
+      In this case, you can implement a widget from scratch.</para>
+
     <sect1 id="sec-custom-containers">
     <title>Custom Containers</title>
     <para>When deriving from <classname>Gtk::Container</classname>, you should override the following virtual methods:
     <itemizedlist>
-      <listitem><para><methodname>on_size_request()</methodname>: Calculate the minimum height and width needed by the container.</para></listitem>
+      <listitem><para><methodname>get_request_mode_vfunc()</methodname>: Return what <literal>Gtk::SizeRequestMode</literal> is preferred by the container.</para></listitem>
+      <listitem><para><methodname>get_preferred_width_vfunc()</methodname>: Calculate the minimum and natural width of the container.</para></listitem>
+      <listitem><para><methodname>get_preferred_height_vfunc()</methodname>: Calculate the minimum and natural height of the container.</para></listitem>
+      <listitem><para><methodname>get_preferred_width_for_height_vfunc()</methodname>: Calculate the minimum and natural width of the container, if it would be given the specified height.</para></listitem>
+      <listitem><para><methodname>get_preferred_height_for_width_vfunc()</methodname>: Calculate the minimum and natural height of the container, if it would be given the specified width.</para></listitem>
       <listitem><para><methodname>on_size_allocate()</methodname>: Position the child widgets, given the height and width that the container has actually been given.</para></listitem>
       <listitem><para><methodname>forall_vfunc()</methodname>: Call the same callback for each of the children.</para></listitem>
-      <listitem><para><methodname>on_add()</methodname>: </para></listitem>
-      <listitem><para><methodname>on_remove()</methodname>: </para></listitem>
+      <listitem><para><methodname>on_add()</methodname>: Add a child widget to the container.</para></listitem>
+      <listitem><para><methodname>on_remove()</methodname>: Remove a child widget from the container.</para></listitem>
       <listitem><para><methodname>child_type_vfunc()</methodname>: Return what type of child can be added.</para></listitem>
     </itemizedlist>
     </para>
 
-    <para>The <methodname>on_size_request()</methodname> and
+    <para>The <methodname>get_request_mode_vfunc()</methodname>,
+        <methodname>get_preferred_width_vfunc()</methodname>,
+        <methodname>get_preferred_height_vfunc()</methodname>,
+        <methodname>get_preferred_width_for_height_vfunc()</methodname>,
+        <methodname>get_preferred_height_for_width_vfunc()</methodname>, and
         <methodname>on_size_allocate()</methodname> virtual methods control the
         layout of the child widgets. For instance, if your container has 2
         child widgets, with one below the other, your
-        <methodname>on_size_request()</methodname> might report the maximum of
-        their widths and the sum of their heights. If you want padding between
+        <methodname>get_request_mode_vfunc()</methodname> might request
+        height-for-width layout. Then your
+        <methodname>get_preferred_width_vfunc()</methodname>
+        might report the maximum of the widths of the child widgets, and
+        <methodname>get_preferred_height_for_width_vfunc()</methodname>
+        might report the sum of their heights. If you want padding between
         the child widgets then you would add that to the width and height too.
         Your widget's container will use this result to ensure that your widget
         gets enough space, and not less. By examining each widget's parent, and
         its parent, this logic will eventually decide the size of the top-level
         window.</para>
 
-   <para><methodname>on_size_allocate()</methodname>, however, receives the actual
+    <para>You are not guaranteed to get the <literal>Gtk::SizeRequestMode</literal>
+        that you request. Therefore all four of the
+        <methodname>get_preferred_xxx_vfunc()</methodname> methods must return
+        sensible values.</para>
+
+   <para><methodname>on_size_allocate()</methodname> receives the actual
        height and width that the parent container has decided to give to your
-       widget. This might be more than the minimum, for instance if the
+       widget. This might be more than the minimum, or even more than the natural
+       size, for instance if the
        top-level window has been expanded. You might choose to ignore the extra
        space and leave a blank area, or you might choose to expand your child
        widgets to fill the space, or you might choose to expand the padding
-       between your widgets. Its your container, so you decide. Don't forget to
+       between your widgets. It's your container, so you decide. Don't forget to
        call <methodname>set_allocation()</methodname> inside your
        <methodname>on_size_allocate()</methodname> implementation to actually use the
        allocated space that has been offered by the parent container.</para>
 
   <para>Unless your container is a top-level window that derives from
-      <classname>Gtk::Window</classname>, you should also call
-      <methodname>Gtk::Container::set_flags(Gtk::NO_WINDOW)</methodname> in your
-      constructor. Otherwise, your container will appear in its own window,
-      regardless of what container you put it in. And unless your container
-      draws directly onto the underlying <classname>Gdk::Window</classname>,
-      you should probably call
+      <classname>Gtk::Window</classname>, you should probably also call
+      <methodname>Gtk::Widget::set_has_window(false)</methodname> in your
+      constructor. This means that your container does not create its own
+      <classname>Gdk::Window</classname>, but uses its parent's
+      window. (Note the difference between <classname>Gtk::Window</classname>
+      and <classname>Gdk::Window</classname>.) If your container does need
+      its own <classname>Gdk::Window</classname>, and does not derive from
+      <classname>Gtk::Window</classname>, you must also override the
+      <methodname>on_realize()</methodname> method as described in the
+      <link linkend="sec-custom-widgets">Custom Widgets</link> section.
+      And unless your container draws directly onto the underlying
+      <classname>Gdk::Window</classname>, you should probably call
       <methodname>set_redraw_on_allocate(false)</methodname> to improve
       performance.</para>
 
@@ -6936,6 +6965,39 @@ instance, you cannot use the copyright sign (&copy;).
         the text of the label, but does not do this by using other
         widgets.</para>
 
+    <para>When deriving from <classname>Gtk::Widget</classname>, you should
+        override the following virtual methods. The methods marked (optional)
+        need not be overridden in all custom widgets. The base class's methods
+        may be appropriate.
+    <itemizedlist>
+      <listitem><para><methodname>get_request_mode_vfunc()</methodname>: (optional) Return what <literal>Gtk::SizeRequestMode</literal> is preferred by the widget.</para></listitem>
+      <listitem><para><methodname>get_preferred_width_vfunc()</methodname>: Calculate the minimum and natural width of the widget.</para></listitem>
+      <listitem><para><methodname>get_preferred_height_vfunc()</methodname>: Calculate the minimum and natural height of the widget.</para></listitem>
+      <listitem><para><methodname>get_preferred_width_for_height_vfunc()</methodname>: Calculate the minimum and natural width of the widget, if it would be given the specified height.</para></listitem>
+      <listitem><para><methodname>get_preferred_height_for_width_vfunc()</methodname>: Calculate the minimum and natural height of the widget, if it would be given the specified width.</para></listitem>
+      <listitem><para><methodname>on_size_allocate()</methodname>: Position the widget, given the height and width that it has actually been given.</para></listitem>
+      <listitem><para><methodname>on_realize()</methodname>: Associate a <classname>Gdk::Window</classname> with the widget.</para></listitem>
+      <listitem><para><methodname>on_unrealize()</methodname>: (optional) Break the association with the <classname>Gdk::Window</classname>. </para></listitem>
+      <listitem><para><methodname>on_map()</methodname>: (optional)</para></listitem>
+      <listitem><para><methodname>on_unmap()</methodname>: (optional)</para></listitem>
+      <listitem><para><methodname>on_draw()</methodname>: Draw on the supplied <classname>Cairo::Context</classname>.</para></listitem>
+    </itemizedlist>
+    </para>
+
+    <para>The first 6 methods in the previous table are also overridden in custom
+        containers. They are briefly described in the
+        <link linkend="sec-custom-containers">Custom Containers</link> section.
+    </para>
+
+    <para>Most custom widgets need their own <classname>Gdk::Window</classname>
+      to draw on. Then you can call
+      <methodname>Gtk::Widget::set_has_window(true)</methodname> in your
+      constructor. (This is the default value.) If you do not call
+      <methodname>set_has_window(false)</methodname>, you must override
+      <methodname>on_realize()</methodname> and call
+      <methodname>Gtk::Widget::set_realized()</methodname> and
+      <methodname>Gtk::Widget::set_window()</methodname> from there.</para>
+
 <sect2 id="custom-widget-example"><title>Example</title>
 
 <para>This example implements a widget which draws a Penrose triangle.</para>
diff --git a/examples/book/custom/custom_container/examplewindow.cc b/examples/book/custom/custom_container/examplewindow.cc
index 03aa5c5..6b57680 100644
--- a/examples/book/custom/custom_container/examplewindow.cc
+++ b/examples/book/custom/custom_container/examplewindow.cc
@@ -21,7 +21,7 @@
 
 ExampleWindow::ExampleWindow()
 : m_Button_One("Child One"),
-  m_Button_Two("Child 2"),
+  m_Label_Two("Child 2"),
   m_Button_Quit("Quit")
 {
   set_title("Custom Container example");
@@ -31,15 +31,11 @@ ExampleWindow::ExampleWindow()
   add(m_VBox);
 
   //Add the child widgets to the custom container:
-  m_MyContainer.set_child_widgets(m_Button_One, m_Button_Two);
-  m_Button_One.show();
-  m_Button_Two.show();
+  m_MyContainer.set_child_widgets(m_Button_One, m_Label_Two);
 
-  m_Button_Two.property_xalign() = 1.0f; 
+  m_Label_Two.set_alignment(1.0, 0.5);
 
   m_VBox.pack_start(m_MyContainer, Gtk::PACK_EXPAND_WIDGET);
-  m_MyContainer.show();
-
   m_VBox.pack_start(m_ButtonBox, Gtk::PACK_SHRINK);
 
   m_ButtonBox.pack_start(m_Button_Quit, Gtk::PACK_SHRINK);
diff --git a/examples/book/custom/custom_container/examplewindow.h b/examples/book/custom/custom_container/examplewindow.h
index fa9d8c9..373b5c2 100644
--- a/examples/book/custom/custom_container/examplewindow.h
+++ b/examples/book/custom/custom_container/examplewindow.h
@@ -36,7 +36,7 @@ protected:
   Gtk::VBox m_VBox;
   MyContainer m_MyContainer;
   Gtk::Button m_Button_One;
-  Gtk::Label m_Button_Two;
+  Gtk::Label m_Label_Two;
   Gtk::HButtonBox m_ButtonBox;
   Gtk::Button m_Button_Quit;
 };
diff --git a/examples/book/custom/custom_container/mycontainer.cc b/examples/book/custom/custom_container/mycontainer.cc
index 6a67631..4039a3e 100644
--- a/examples/book/custom/custom_container/mycontainer.cc
+++ b/examples/book/custom/custom_container/mycontainer.cc
@@ -17,6 +17,7 @@
  */
 
 #include <iostream>
+#include <algorithm> // std::max
 #include "mycontainer.h"
 
 MyContainer::MyContainer()
@@ -40,69 +41,169 @@ void MyContainer::set_child_widgets(Gtk::Widget& child_one,
   m_child_two->set_parent(*this);
 }
 
-void MyContainer::on_size_request(Gtk::Requisition* requisition)
+//This example container is a simplified VBox with at most two children.
+Gtk::SizeRequestMode MyContainer::get_request_mode_vfunc() const
 {
-  //Initialize the output parameter:
-  *requisition = Gtk::Requisition();
-
-  //Discover the total amount of minimum space needed by this container widget,
-  //by examining its child widgets.  The layouts in this custom container will
-  //be arranged vertically, one above the other.
-
-   Gtk::Requisition child_requisition_one = {0, 0};
-   Gtk::Requisition child_requisition_two = {0, 0};
-   if(m_child_one && m_child_one->get_visible())
-   {
-     //TODO: Support natural-size properly:
-     Gtk::Requisition child_requisition_one_natural;
-     m_child_one->get_preferred_size(child_requisition_one, child_requisition_one_natural);
-    }
+  return Gtk::SIZE_REQUEST_HEIGHT_FOR_WIDTH;
+}
+
+//Discover the total amount of minimum space and natural space needed by
+//this container and its children.
+void MyContainer::get_preferred_width_vfunc(int* minimum_width, int* natural_width) const
+{
+  int child_minimum_width[2] = {0, 0};
+  int child_natural_width[2] = {0, 0};
+
+  if(m_child_one && m_child_one->get_visible())
+    m_child_one->get_preferred_width(child_minimum_width[0], child_natural_width[0]);
+
+  if(m_child_two && m_child_two->get_visible())
+    m_child_two->get_preferred_width(child_minimum_width[1], child_natural_width[1]);
 
-   if(m_child_two && m_child_two->get_visible())
-   {
-     //TODO: Support natural-size properly:
-     Gtk::Requisition child_requisition_two_natural;
-     m_child_two->get_preferred_size(child_requisition_two, child_requisition_two_natural);
-   }
-
-  //See which one has the most width:
-  int max_width = MAX(child_requisition_one.width,
-          child_requisition_two.width);
-
-  //Add the heights together:
-  int total_height = child_requisition_one.height +
-      child_requisition_two.height;
-
-  //Request the width for this container based on the sizes requested by its
-  //child widgets:
-  requisition->height = total_height;
-  requisition->width = max_width;
+  //Request a width equal to the width of the widest visible child.
+  if(minimum_width) 
+    *minimum_width = std::max(child_minimum_width[0], child_minimum_width[1]);
+
+  if(natural_width) 
+    *natural_width = std::max(child_natural_width[0], child_natural_width[1]);
+}
+
+void MyContainer::get_preferred_height_for_width_vfunc(int width,
+   int* minimum_height, int* natural_height) const
+{
+  int child_minimum_height[2] = {0, 0};
+  int child_natural_height[2] = {0, 0};
+  int nvis_children = 0;
+
+  if(m_child_one && m_child_one->get_visible())
+  {
+    ++nvis_children;
+    m_child_one->get_preferred_height_for_width(width, child_minimum_height[0],
+                                                child_natural_height[0]);
+  }
+
+  if(m_child_two && m_child_two->get_visible())
+  {
+    ++nvis_children;
+    m_child_two->get_preferred_height_for_width(width, child_minimum_height[1],
+                                                child_natural_height[1]);
+  }
+
+  //The allocated height will be divided equally among the visible children.
+  //Request a height equal to the number of visible children times the height
+  //of the highest child.
+  if(minimum_height) 
+    *minimum_height = nvis_children * std::max(child_minimum_height[0],
+                                               child_minimum_height[1]);
+
+  if(natural_height) 
+    *natural_height = nvis_children * std::max(child_natural_height[0],
+                                               child_natural_height[1]);
+}
+
+void MyContainer::get_preferred_height_vfunc(int* minimum_height, int* natural_height) const
+{
+  int child_minimum_height[2] = {0, 0};
+  int child_natural_height[2] = {0, 0};
+  int nvis_children = 0;
+
+  if(m_child_one && m_child_one->get_visible())
+  {
+    ++nvis_children;
+    m_child_one->get_preferred_height(child_minimum_height[0], child_natural_height[0]);
+  }
+
+  if(m_child_two && m_child_two->get_visible())
+  {
+    ++nvis_children;
+    m_child_two->get_preferred_height(child_minimum_height[1], child_natural_height[1]);
+  }
+
+  //The allocated height will be divided equally among the visible children.
+  //Request a height equal to the number of visible children times the height
+  //of the highest child.
+  if(minimum_height) 
+    *minimum_height = nvis_children * std::max(child_minimum_height[0],
+                                               child_minimum_height[1]);
+
+  if(natural_height) 
+    *natural_height = nvis_children * std::max(child_natural_height[0],
+                                               child_natural_height[1]);
+}
+
+void MyContainer::get_preferred_width_for_height_vfunc(int height,
+   int* minimum_width, int* natural_width) const
+{
+  int child_minimum_width[2] = {0, 0};
+  int child_natural_width[2] = {0, 0};
+  int nvis_children = 0;
+
+  //Get number of visible children.
+  if(m_child_one && m_child_one->get_visible())
+    ++nvis_children;
+  if(m_child_two && m_child_two->get_visible())
+    ++nvis_children;
+
+  if(nvis_children > 0)
+  {
+    //Divide the height equally among the visible children.
+    const int height_per_child = height / nvis_children;
+
+    if(m_child_one && m_child_one->get_visible())
+      m_child_one->get_preferred_width_for_height(height_per_child,
+                   child_minimum_width[0], child_natural_width[0]);
+
+    if(m_child_two && m_child_two->get_visible())
+      m_child_two->get_preferred_width_for_height(height_per_child,
+                   child_minimum_width[1], child_natural_width[1]);
+  }
+
+  //Request a width equal to the width of the widest child.
+  if(minimum_width) 
+    *minimum_width = std::max(child_minimum_width[0], child_minimum_width[1]);
+
+  if(natural_width) 
+    *natural_width = std::max(child_natural_width[0], child_natural_width[1]);
 }
 
 void MyContainer::on_size_allocate(Gtk::Allocation& allocation)
 {
   //Do something with the space that we have actually been given:
   //(We will not be given heights or widths less than we have requested, though
-  //we might get more)
+  //we might get more.)
 
   //Use the offered allocation for this container:
   set_allocation(allocation);
 
-  //Assign sign space to the child:
-  Gtk::Allocation child_allocation_one, child_allocation_two;
+  //Get number of visible children.
+  int nvis_children = 0;
+  if(m_child_one && m_child_one->get_visible())
+    ++nvis_children;
+  if(m_child_two && m_child_two->get_visible())
+    ++nvis_children;
+
+  if(nvis_children <= 0)
+    return;
+
+  //Assign space to the children:
+  Gtk::Allocation child_allocation_one;
+  Gtk::Allocation child_allocation_two;
 
-  //Place the first child at the top-left,
+  //Place the first child at the top-left:
   child_allocation_one.set_x( allocation.get_x() );
   child_allocation_one.set_y( allocation.get_y() );
 
   //Make it take up the full width available:
   child_allocation_one.set_width( allocation.get_width() );
 
-  //Make it take up half the height available:
-  child_allocation_one.set_height( allocation.get_height() / 2);
-
   if(m_child_one && m_child_one->get_visible())
+  {
+    //Divide the height equally among the visible children.
+    child_allocation_one.set_height( allocation.get_height() / nvis_children);
     m_child_one->size_allocate(child_allocation_one);
+  }
+  else
+    child_allocation_one.set_height(0);
 
   //Place the second child below the first child:
   child_allocation_two.set_x( allocation.get_x() );
@@ -112,7 +213,7 @@ void MyContainer::on_size_allocate(Gtk::Allocation& allocation)
   //Make it take up the full width available:
   child_allocation_two.set_width( allocation.get_width() );
 
-  //Make it take up half the height available:
+  //Make it take up the remaining height:
   child_allocation_two.set_height( allocation.get_height() -
           child_allocation_one.get_height());
 
@@ -139,7 +240,6 @@ void MyContainer::on_add(Gtk::Widget* child)
   else if(!m_child_two)
   {
     m_child_two = child;
-
     m_child_two->set_parent(*this);
   }
 }
diff --git a/examples/book/custom/custom_container/mycontainer.h b/examples/book/custom/custom_container/mycontainer.h
index a80c18a..eac4caa 100644
--- a/examples/book/custom/custom_container/mycontainer.h
+++ b/examples/book/custom/custom_container/mycontainer.h
@@ -32,7 +32,11 @@ public:
 protected:
 
   //Overrides:
-  virtual void on_size_request(Gtk::Requisition* requisition);
+  virtual Gtk::SizeRequestMode get_request_mode_vfunc() const;
+  virtual void get_preferred_width_vfunc(int* minimum_width, int* natural_width) const;
+  virtual void get_preferred_height_for_width_vfunc(int width, int* minimum_height, int* natural_height) const;
+  virtual void get_preferred_height_vfunc(int* minimum_height, int* natural_height) const;
+  virtual void get_preferred_width_for_height_vfunc(int height, int* minimum_width, int* natural_width) const;
   virtual void on_size_allocate(Gtk::Allocation& allocation);
 
   virtual void forall_vfunc(gboolean include_internals, GtkCallback callback, gpointer callback_data);
diff --git a/examples/book/custom/custom_widget/custom_gtk.css b/examples/book/custom/custom_widget/custom_gtk.css
new file mode 100644
index 0000000..4e098f6
--- /dev/null
+++ b/examples/book/custom/custom_widget/custom_gtk.css
@@ -0,0 +1,10 @@
+/* Example of a CSS style sheet with a custom style property.
+ *
+ * The name of the style property must have its canonical form, i.e. characters
+ * other than ASCII letters, digits, and hyphens must be replaced by hyphens.
+*/
+* {
+  /* -<widget class name>-<style property canonical name>: <value>;*/
+  -gtkmm__CustomObject_mywidget-example-scale: 920;
+}
+
diff --git a/examples/book/custom/custom_widget/mywidget.cc b/examples/book/custom/custom_widget/mywidget.cc
index b5081dd..294cf25 100644
--- a/examples/book/custom/custom_widget/mywidget.cc
+++ b/examples/book/custom/custom_widget/mywidget.cc
@@ -31,15 +31,14 @@ MyWidget::MyWidget() :
 {
   set_has_window(true);
 
-  //This shows the GType name, which must be used in the RC file.
+  //This shows the GType name, which must be used in the CSS file.
   std::cout << "GType name: " << G_OBJECT_TYPE_NAME(gobj()) << std::endl;
 
-  //This show that the GType still derives from GtkWidget:
+  //This shows that the GType still derives from GtkWidget:
   //std::cout << "Gtype is a GtkWidget?:" << GTK_IS_WIDGET(gobj()) << std::endl;
 
-
-  //Install a style so that an aspect of this widget may be themed via an RC
-  //file:
+  //Install a style so that an aspect of this widget may be themed via a CSS
+  //style sheet file:
   gtk_widget_class_install_style_property(GTK_WIDGET_CLASS(
               G_OBJECT_GET_CLASS(gobj())),
       g_param_spec_int("example_scale",
@@ -50,14 +49,14 @@ MyWidget::MyWidget() :
         0,
         G_PARAM_READABLE) );
 
-  m_refStyleProvider = Gtk::CssProvider::get_default();
+  m_refStyleProvider = Gtk::CssProvider::create();
   Glib::RefPtr<Gtk::StyleContext> refStyleContext = get_style_context();
   refStyleContext->add_provider(m_refStyleProvider, 
     GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
     
   try
   {
-    m_refStyleProvider->load_from_path("custom_gtkrc");
+    m_refStyleProvider->load_from_path("custom_gtk.css");
   }
   catch(const Glib::Error& ex)
   {
@@ -69,16 +68,52 @@ MyWidget::~MyWidget()
 {
 }
 
-void MyWidget::on_size_request(Gtk::Requisition* requisition)
+Gtk::SizeRequestMode MyWidget::get_request_mode_vfunc() const
+{
+  //Accept the default value supplied by the base class.
+  return Gtk::Widget::get_request_mode_vfunc();
+}
+
+//Discover the total amount of minimum space and natural space needed by
+//this widget.
+//Let's make this simple example widget always need minimum 60 by 50 and
+//natural 100 by 70.
+void MyWidget::get_preferred_width_vfunc(int* minimum_width, int* natural_width) const
+{
+  if (minimum_width) 
+    *minimum_width = 60;
+
+  if (natural_width) 
+    *natural_width = 100;
+}
+
+void MyWidget::get_preferred_height_for_width_vfunc(int /* width */,
+   int* minimum_height, int* natural_height) const
+{
+  if (minimum_height) 
+    *minimum_height = 50;
+
+  if (natural_height) 
+    *natural_height = 70;
+}
+
+void MyWidget::get_preferred_height_vfunc(int* minimum_height, int* natural_height) const
 {
-  //Initialize the output parameter:
-  *requisition = Gtk::Requisition();
+  if (minimum_height) 
+    *minimum_height = 50;
 
-  //Discover the total amount of minimum space needed by this widget.
+  if (natural_height) 
+    *natural_height = 70;
+}
+
+void MyWidget::get_preferred_width_for_height_vfunc(int /* height */,
+   int* minimum_width, int* natural_width) const
+{
+  if (minimum_width) 
+    *minimum_width = 60;
 
-  //Let's make this simple example widget always need 50 by 50:
-  requisition->height = 50;
-  requisition->width = 50;
+  if (natural_width) 
+    *natural_width = 100;
 }
 
 void MyWidget::on_size_allocate(Gtk::Allocation& allocation)
@@ -115,11 +150,10 @@ void MyWidget::on_realize()
   //It's intended only for widgets that set_has_window(false).
 
   set_realized();
-  ensure_style();
 
-  //Get the themed style from the RC file:
+  //Get the themed style from the CSS file:
   get_style_property("example_scale", m_scale);
-  std::cout << "m_scale (example_scale from the theme/rc-file) is: "
+  std::cout << "m_scale (example_scale from the theme/css-file) is: "
       << m_scale << std::endl;
 
   if(!m_refGdkWindow)
@@ -145,9 +179,6 @@ void MyWidget::on_realize()
             GDK_WA_X | GDK_WA_Y);
     set_window(m_refGdkWindow);
 
-    //Attach this widget's style to its Gdk::Window.
-    style_attach();
-
     //set colors
     override_background_color(Gdk::RGBA("red"));
     override_color(Gdk::RGBA("blue"));
diff --git a/examples/book/custom/custom_widget/mywidget.h b/examples/book/custom/custom_widget/mywidget.h
index 70d0f2f..edf3e4f 100644
--- a/examples/book/custom/custom_widget/mywidget.h
+++ b/examples/book/custom/custom_widget/mywidget.h
@@ -31,7 +31,11 @@ public:
 protected:
 
   //Overrides:
-  virtual void on_size_request(Gtk::Requisition* requisition);
+  virtual Gtk::SizeRequestMode get_request_mode_vfunc() const;
+  virtual void get_preferred_width_vfunc(int* minimum_width, int* natural_width) const;
+  virtual void get_preferred_height_for_width_vfunc(int width, int* minimum_height, int* natural_height) const;
+  virtual void get_preferred_height_vfunc(int* minimum_height, int* natural_height) const;
+  virtual void get_preferred_width_for_height_vfunc(int height, int* minimum_width, int* natural_width) const;
   virtual void on_size_allocate(Gtk::Allocation& allocation);
   virtual void on_map();
   virtual void on_unmap();



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]