]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkexpander.c
gdk/gdkwindow.c, gtk/gtkwidget.c: Include fallback-c89.c
[~andy/gtk] / gtk / gtkexpander.c
index 0370c1226a32ef56247c522fd7c00d4b386035f6..6f6a196a6f4da67b286e615180a7d6a203a4dc39 100644 (file)
@@ -13,9 +13,7 @@
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  *
  * Authors:
  *      Mark McLoughlin <mark@skynet.ie>
 #include "gtkintl.h"
 #include "gtkprivate.h"
 #include "gtkdnd.h"
+#include "a11y/gtkexpanderaccessible.h"
 
 
 #define DEFAULT_EXPANDER_SIZE 10
@@ -128,7 +127,8 @@ enum
   PROP_USE_MARKUP,
   PROP_SPACING,
   PROP_LABEL_WIDGET,
-  PROP_LABEL_FILL
+  PROP_LABEL_FILL,
+  PROP_RESIZE_TOPLEVEL
 };
 
 struct _GtkExpanderPrivate
@@ -145,6 +145,7 @@ struct _GtkExpanderPrivate
   guint             button_down : 1;
   guint             prelight : 1;
   guint             label_fill : 1;
+  guint             resize_toplevel : 1;
 };
 
 static void gtk_expander_set_property (GObject          *object,
@@ -331,6 +332,22 @@ gtk_expander_class_init (GtkExpanderClass *klass)
                                                          FALSE,
                                                          GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
+  /**
+   * GtkExpander:resize-toplevel:
+   *
+   * When this property is %TRUE, the expander will resize the toplevel
+   * widget containing the expander upon expanding and collapsing.
+   *
+   * Since: 3.2
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_RESIZE_TOPLEVEL,
+                                   g_param_spec_boolean ("resize-toplevel",
+                                                         P_("Resize toplevel"),
+                                                         P_("Whether the expander will resize the toplevel window upon expanding and collapsing"),
+                                                         FALSE,
+                                                         GTK_PARAM_READWRITE));
+
   gtk_widget_class_install_style_property (widget_class,
                                            g_param_spec_int ("expander-size",
                                                              P_("Expander Size"),
@@ -357,6 +374,8 @@ gtk_expander_class_init (GtkExpanderClass *klass)
                   NULL, NULL,
                   _gtk_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
+
+  gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_EXPANDER_ACCESSIBLE);
 }
 
 static void
@@ -382,6 +401,7 @@ gtk_expander_init (GtkExpander *expander)
   priv->prelight = FALSE;
   priv->label_fill = FALSE;
   priv->expand_timer = 0;
+  priv->resize_toplevel = 0;
 
   gtk_drag_dest_set (GTK_WIDGET (expander), 0, NULL, 0, 0);
   gtk_drag_dest_set_track_motion (GTK_WIDGET (expander), TRUE);
@@ -438,6 +458,9 @@ gtk_expander_set_property (GObject      *object,
     case PROP_LABEL_FILL:
       gtk_expander_set_label_fill (expander, g_value_get_boolean (value));
       break;
+    case PROP_RESIZE_TOPLEVEL:
+      gtk_expander_set_resize_toplevel (expander, g_value_get_boolean (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -478,6 +501,9 @@ gtk_expander_get_property (GObject    *object,
     case PROP_LABEL_FILL:
       g_value_set_boolean (value, priv->label_fill);
       break;
+    case PROP_RESIZE_TOPLEVEL:
+      g_value_set_boolean (value, gtk_expander_get_resize_toplevel (expander));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -551,7 +577,7 @@ gtk_expander_realize (GtkWidget *widget)
 
   priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
                                        &attributes, attributes_mask);
-  gdk_window_set_user_data (priv->event_window, widget);
+  gtk_widget_register_window (widget, priv->event_window);
 }
 
 static void
@@ -561,7 +587,7 @@ gtk_expander_unrealize (GtkWidget *widget)
 
   if (priv->event_window)
     {
-      gdk_window_set_user_data (priv->event_window, NULL);
+      gtk_widget_unregister_window (widget, priv->event_window);
       gdk_window_destroy (priv->event_window);
       priv->event_window = NULL;
     }
@@ -859,39 +885,37 @@ gtk_expander_paint (GtkExpander *expander,
 
   widget = GTK_WIDGET (expander);
   context = gtk_widget_get_style_context (widget);
+  state = gtk_widget_get_state_flags (widget);
 
   get_expander_bounds (expander, &clip);
   gtk_widget_get_allocation (widget, &allocation);
 
   gtk_style_context_save (context);
 
+  state &= ~(GTK_STATE_FLAG_PRELIGHT);
   if (expander->priv->prelight)
     {
-      state = GTK_STATE_FLAG_PRELIGHT;
+      state |= GTK_STATE_FLAG_PRELIGHT;
       gtk_style_context_set_state (context, state);
       gtk_expander_paint_prelight (expander, cr);
     }
 
   gtk_widget_style_get (widget, "expander-size", &size, NULL);
 
-  state = gtk_style_context_get_state (context);
-
   /* Set active flag as per the expanded state */
   if (priv->expanded)
     state |= GTK_STATE_FLAG_ACTIVE;
+  else
+    state &= ~(GTK_STATE_FLAG_ACTIVE);
 
   gtk_style_context_set_state (context, state);
   gtk_style_context_add_class (context, GTK_STYLE_CLASS_EXPANDER);
 
-  /* The expander is the only animatable region */
-  gtk_style_context_push_animatable_region (context, GUINT_TO_POINTER (1));
-
   gtk_render_expander (context, cr,
                        clip.x - allocation.x,
                        clip.y - allocation.y,
                        size, size);
 
-  gtk_style_context_pop_animatable_region (context);
   gtk_style_context_restore (context);
 }
 
@@ -988,7 +1012,7 @@ gtk_expander_draw (GtkWidget *widget,
 
   gtk_expander_paint (expander, cr);
 
-  if (gtk_widget_has_focus (widget))
+  if (gtk_widget_has_visible_focus (widget))
     gtk_expander_paint_focus (expander, cr);
 
   GTK_WIDGET_CLASS (gtk_expander_parent_class)->draw (widget, cr);
@@ -1002,7 +1026,7 @@ gtk_expander_button_press (GtkWidget      *widget,
 {
   GtkExpander *expander = GTK_EXPANDER (widget);
 
-  if (event->button == 1 && event->window == expander->priv->event_window)
+  if (event->button == GDK_BUTTON_PRIMARY && event->window == expander->priv->event_window)
     {
       expander->priv->button_down = TRUE;
       return TRUE;
@@ -1017,7 +1041,7 @@ gtk_expander_button_release (GtkWidget      *widget,
 {
   GtkExpander *expander = GTK_EXPANDER (widget);
 
-  if (event->button == 1 && expander->priv->button_down)
+  if (event->button == GDK_BUTTON_PRIMARY && expander->priv->button_down)
     {
       gtk_widget_activate (widget);
       expander->priv->button_down = FALSE;
@@ -1227,6 +1251,7 @@ get_next_site (GtkExpander      *expander,
         case GTK_DIR_RIGHT:
           return FOCUS_WIDGET;
         }
+      break;
     case FOCUS_WIDGET:
       switch (direction)
         {
@@ -1240,8 +1265,8 @@ get_next_site (GtkExpander      *expander,
           return FOCUS_LABEL;
         case GTK_DIR_RIGHT:
           return ltr ? FOCUS_LABEL : FOCUS_NONE;
-          break;
         }
+      break;
     case FOCUS_LABEL:
       switch (direction)
         {
@@ -1255,8 +1280,8 @@ get_next_site (GtkExpander      *expander,
           return FOCUS_CHILD;
         case GTK_DIR_RIGHT:
           return ltr ? FOCUS_CHILD : FOCUS_WIDGET;
-          break;
         }
+      break;
     case FOCUS_CHILD:
       switch (direction)
         {
@@ -1269,12 +1294,54 @@ get_next_site (GtkExpander      *expander,
         case GTK_DIR_RIGHT:
           return FOCUS_NONE;
         }
+      break;
     }
 
   g_assert_not_reached ();
   return FOCUS_NONE;
 }
 
+static void
+gtk_expander_resize_toplevel (GtkExpander *expander)
+{
+  GtkExpanderPrivate *priv = expander->priv;
+  GtkWidget *child = gtk_bin_get_child (GTK_BIN (expander));
+
+  if (child && priv->resize_toplevel &&
+      gtk_widget_get_realized (GTK_WIDGET (expander)))
+    {
+      GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (expander));
+
+      if (toplevel && gtk_widget_get_realized (toplevel))
+        {
+          GtkAllocation toplevel_allocation;
+
+          gtk_widget_get_allocation (toplevel, &toplevel_allocation);
+
+          if (priv->expanded)
+            {
+              GtkRequisition child_requisition;
+
+              gtk_widget_get_preferred_size (child, &child_requisition, NULL);
+
+              toplevel_allocation.height += child_requisition.height;
+            }
+          else
+            {
+              GtkAllocation child_allocation;
+
+              gtk_widget_get_allocation (child, &child_allocation);
+
+              toplevel_allocation.height -= child_allocation.height;
+            }
+
+          gtk_window_resize (GTK_WINDOW (toplevel),
+                             toplevel_allocation.width,
+                             toplevel_allocation.height);
+        }
+    }
+}
+
 static gboolean
 gtk_expander_focus (GtkWidget        *widget,
                     GtkDirectionType  direction)
@@ -1640,34 +1707,16 @@ gtk_expander_set_expanded (GtkExpander *expander,
   if (priv->expanded != expanded)
     {
       GtkWidget *widget = GTK_WIDGET (expander);
-      GtkSettings *settings = gtk_widget_get_settings (widget);
-      GtkStyleContext *context;
-      gboolean enable_animations;
 
-      context = gtk_widget_get_style_context (widget);
       priv->expanded = expanded;
 
-      g_object_get (settings, "gtk-enable-animations", &enable_animations, NULL);
-
-      if (enable_animations && gtk_widget_get_realized (widget))
-        {
-          gtk_style_context_save (context);
-          gtk_style_context_add_class (context, GTK_STYLE_CLASS_EXPANDER);
-
-          gtk_style_context_notify_state_change (context,
-                                                 gtk_widget_get_window (widget),
-                                                 GUINT_TO_POINTER (1),
-                                                 GTK_STATE_ACTIVE,
-                                                 expanded);
-          gtk_style_context_restore (context);
-        }
-
       child = gtk_bin_get_child (GTK_BIN (expander));
 
       if (child)
         {
           gtk_widget_set_child_visible (child, priv->expanded);
           gtk_widget_queue_resize (widget);
+          gtk_expander_resize_toplevel (expander);
         }
 
       g_object_notify (G_OBJECT (expander), "expanded");
@@ -1797,7 +1846,7 @@ gtk_expander_set_label (GtkExpander *expander,
  *
  * Since: 2.4
  */
-G_CONST_RETURN char *
+const char *
 gtk_expander_get_label (GtkExpander *expander)
 {
   GtkExpanderPrivate *priv;
@@ -2048,3 +2097,45 @@ gtk_expander_get_label_fill (GtkExpander *expander)
 
   return expander->priv->label_fill;
 }
+
+/**
+ * gtk_expander_set_resize_toplevel:
+ * @expander: a #GtkExpander
+ * @resize_toplevel: whether to resize the toplevel
+ *
+ * Sets whether the expander will resize the toplevel widget
+ * containing the expander upon resizing and collpasing.
+ *
+ * Since: 3.2
+ */
+void
+gtk_expander_set_resize_toplevel (GtkExpander *expander,
+                                  gboolean     resize_toplevel)
+{
+  g_return_if_fail (GTK_IS_EXPANDER (expander));
+
+  if (expander->priv->resize_toplevel != resize_toplevel)
+    {
+      expander->priv->resize_toplevel = resize_toplevel ? TRUE : FALSE;
+      g_object_notify (G_OBJECT (expander), "resize-toplevel");
+    }
+}
+
+/**
+ * gtk_expander_get_resize_toplevel:
+ * @expander: a #GtkExpander
+ *
+ * Returns whether the expander will resize the toplevel widget
+ * containing the expander upon resizing and collpasing.
+ *
+ * Return value: the "resize toplevel" setting.
+ *
+ * Since: 3.2
+ */
+gboolean
+gtk_expander_get_resize_toplevel (GtkExpander *expander)
+{
+  g_return_val_if_fail (GTK_IS_EXPANDER (expander), FALSE);
+
+  return expander->priv->resize_toplevel;
+}