]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtklabel.c
GtkToggleButton: Make it able to be prelight and active at the same time.
[~andy/gtk] / gtk / gtklabel.c
index 45f089a899efb01a02f8813c391666a8e628285c..55bc6c335ed8cb359495dfe325cf41f08b085425 100644 (file)
 #include "gtkimage.h"
 #include "gtkshow.h"
 #include "gtktooltip.h"
-#include "gtksizerequest.h"
 #include "gtkprivate.h"
 
+/*rint() is only available in GCC and/or C99*/
+#if (__STDC_VERSION__ < 199901L && !defined __GNUC__)
+double rint(double x)
+{
+       if (ceil(x+0.5) == floor(x+0.5))
+       {
+               int a = (int)ceil(x);
+               if (a%2 == 0)
+                       return ceil(x);
+               else
+                       return floor(x);
+       }
+       else
+               return floor(x+0.5);
+}
+#endif
+
+
 
 struct _GtkLabelPrivate
 {
@@ -198,14 +215,13 @@ static void gtk_label_get_property      (GObject          *object,
                                         guint             prop_id,
                                         GValue           *value,
                                         GParamSpec       *pspec);
-static void gtk_label_destroy           (GtkObject        *object);
 static void gtk_label_finalize          (GObject          *object);
+static void gtk_label_destroy           (GtkWidget        *widget);
 static void gtk_label_size_allocate     (GtkWidget        *widget,
                                          GtkAllocation    *allocation);
 static void gtk_label_state_changed     (GtkWidget        *widget,
                                          GtkStateType      state);
-static void gtk_label_style_set         (GtkWidget        *widget,
-                                        GtkStyle         *previous_style);
+static void gtk_label_style_updated     (GtkWidget        *widget);
 static void gtk_label_direction_changed (GtkWidget        *widget,
                                         GtkTextDirection  previous_dir);
 static gint gtk_label_draw              (GtkWidget        *widget,
@@ -331,30 +347,27 @@ static void          gtk_label_get_link_colors  (GtkWidget  *widget,
 static void          emit_activate_link         (GtkLabel     *label,
                                                  GtkLabelLink *link);
 
-static void               gtk_label_size_request_init     (GtkSizeRequestIface *iface);
-static GtkSizeRequestMode gtk_label_get_request_mode      (GtkSizeRequest      *widget);
-static void               gtk_label_get_width             (GtkSizeRequest      *widget,
-                                                          gint                *minimum_size,
-                                                          gint                *natural_size);
-static void               gtk_label_get_height            (GtkSizeRequest      *widget,
-                                                          gint                *minimum_size,
-                                                          gint                *natural_size);
-static void               gtk_label_get_width_for_height  (GtkSizeRequest      *widget,
-                                                          gint                 height,
-                                                          gint                *minimum_width,
-                                                          gint                *natural_width);
-static void               gtk_label_get_height_for_width  (GtkSizeRequest      *widget,
-                                                          gint                 width,
-                                                          gint                *minimum_height,
-                                                          gint                *natural_height);
+static GtkSizeRequestMode gtk_label_get_request_mode                (GtkWidget           *widget);
+static void               gtk_label_get_preferred_width             (GtkWidget           *widget,
+                                                                     gint                *minimum_size,
+                                                                     gint                *natural_size);
+static void               gtk_label_get_preferred_height            (GtkWidget           *widget,
+                                                                     gint                *minimum_size,
+                                                                     gint                *natural_size);
+static void               gtk_label_get_preferred_width_for_height  (GtkWidget           *widget,
+                                                                     gint                 height,
+                                                                     gint                *minimum_width,
+                                                                     gint                *natural_width);
+static void               gtk_label_get_preferred_height_for_width  (GtkWidget           *widget,
+                                                                     gint                 width,
+                                                                     gint                *minimum_height,
+                                                                     gint                *natural_height);
 
 static GtkBuildableIface *buildable_parent_iface = NULL;
 
 G_DEFINE_TYPE_WITH_CODE (GtkLabel, gtk_label, GTK_TYPE_MISC,
                         G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
-                                               gtk_label_buildable_interface_init)
-                         G_IMPLEMENT_INTERFACE (GTK_TYPE_SIZE_REQUEST,
-                                                gtk_label_size_request_init));
+                                               gtk_label_buildable_interface_init))
 
 static void
 add_move_binding (GtkBindingSet  *binding_set,
@@ -383,7 +396,6 @@ static void
 gtk_label_class_init (GtkLabelClass *class)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
-  GtkObjectClass *object_class = GTK_OBJECT_CLASS (class);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
   GtkBindingSet *binding_set;
 
@@ -391,11 +403,10 @@ gtk_label_class_init (GtkLabelClass *class)
   gobject_class->get_property = gtk_label_get_property;
   gobject_class->finalize = gtk_label_finalize;
 
-  object_class->destroy = gtk_label_destroy;
-
+  widget_class->destroy = gtk_label_destroy;
   widget_class->size_allocate = gtk_label_size_allocate;
   widget_class->state_changed = gtk_label_state_changed;
-  widget_class->style_set = gtk_label_style_set;
+  widget_class->style_updated = gtk_label_style_updated;
   widget_class->query_tooltip = gtk_label_query_tooltip;
   widget_class->direction_changed = gtk_label_direction_changed;
   widget_class->draw = gtk_label_draw;
@@ -414,6 +425,11 @@ gtk_label_class_init (GtkLabelClass *class)
   widget_class->grab_focus = gtk_label_grab_focus;
   widget_class->popup_menu = gtk_label_popup_menu;
   widget_class->focus = gtk_label_focus;
+  widget_class->get_request_mode = gtk_label_get_request_mode;
+  widget_class->get_preferred_width = gtk_label_get_preferred_width;
+  widget_class->get_preferred_height = gtk_label_get_preferred_height;
+  widget_class->get_preferred_width_for_height = gtk_label_get_preferred_width_for_height;
+  widget_class->get_preferred_height_for_width = gtk_label_get_preferred_height_for_width;
 
   class->move_cursor = gtk_label_move_cursor;
   class->copy_clipboard = gtk_label_copy_clipboard;
@@ -515,7 +531,7 @@ gtk_label_class_init (GtkLabelClass *class)
      */
     signals[ACTIVATE_CURRENT_LINK] =
       g_signal_new_class_handler ("activate-current-link",
-                                  G_TYPE_FROM_CLASS (object_class),
+                                  G_TYPE_FROM_CLASS (gobject_class),
                                   G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                                   G_CALLBACK (gtk_label_activate_current_link),
                                   NULL, NULL,
@@ -537,7 +553,7 @@ gtk_label_class_init (GtkLabelClass *class)
      */
     signals[ACTIVATE_LINK] =
       g_signal_new ("activate-link",
-                    G_TYPE_FROM_CLASS (object_class),
+                    G_TYPE_FROM_CLASS (gobject_class),
                     G_SIGNAL_RUN_LAST,
                     G_STRUCT_OFFSET (GtkLabelClass, activate_link),
                     _gtk_boolean_handled_accumulator, NULL,
@@ -900,12 +916,6 @@ gtk_label_class_init (GtkLabelClass *class)
   gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0,
                                "activate-current-link", 0);
 
-  gtk_settings_install_property (g_param_spec_boolean ("gtk-label-select-on-focus",
-                                                      P_("Select on focus"),
-                                                      P_("Whether to select the contents of a selectable label when it is focused"),
-                                                      TRUE,
-                                                      GTK_PARAM_READWRITE));
-
   g_type_class_add_private (class, sizeof (GtkLabelPrivate));
 }
 
@@ -2950,13 +2960,13 @@ gtk_label_get_line_wrap_mode (GtkLabel *label)
 }
 
 static void
-gtk_label_destroy (GtkObject *object)
+gtk_label_destroy (GtkWidget *widget)
 {
-  GtkLabel *label = GTK_LABEL (object);
+  GtkLabel *label = GTK_LABEL (widget);
 
   gtk_label_set_mnemonic_widget (label, NULL);
 
-  GTK_OBJECT_CLASS (gtk_label_parent_class)->destroy (object);
+  GTK_WIDGET_CLASS (gtk_label_parent_class)->destroy (widget);
 }
 
 static void
@@ -3353,20 +3363,10 @@ get_single_line_height (GtkWidget   *widget,
   return ascent + descent;
 }
 
-static void
-gtk_label_size_request_init (GtkSizeRequestIface *iface)
-{
-  iface->get_request_mode     = gtk_label_get_request_mode;
-  iface->get_width            = gtk_label_get_width;
-  iface->get_height           = gtk_label_get_height;
-  iface->get_width_for_height = gtk_label_get_width_for_height;
-  iface->get_height_for_width = gtk_label_get_height_for_width;
-}
-
 static GtkSizeRequestMode
-gtk_label_get_request_mode (GtkSizeRequest *layout)
+gtk_label_get_request_mode (GtkWidget *widget)
 {
-  GtkLabel *label = GTK_LABEL (layout);
+  GtkLabel *label = GTK_LABEL (widget);
   gdouble   angle = gtk_label_get_angle (label);
 
   if (angle == 90 || angle == 270)
@@ -3419,10 +3419,10 @@ get_size_for_allocation (GtkLabel        *label,
 }
 
 static void
-gtk_label_get_size (GtkSizeRequest *widget,
-                   GtkOrientation  orientation,
-                   gint           *minimum_size,
-                   gint           *natural_size)
+gtk_label_get_preferred_size (GtkWidget      *widget,
+                              GtkOrientation  orientation,
+                              gint           *minimum_size,
+                              gint           *natural_size)
 {
   GtkLabel      *label = GTK_LABEL (widget);
   GtkLabelPrivate  *priv = label->priv;
@@ -3567,26 +3567,26 @@ gtk_label_get_size (GtkSizeRequest *widget,
 
 
 static void
-gtk_label_get_width (GtkSizeRequest *widget,
-                    gint           *minimum_size,
-                    gint           *natural_size)
+gtk_label_get_preferred_width (GtkWidget *widget,
+                               gint      *minimum_size,
+                               gint      *natural_size)
 {
-  gtk_label_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
+  gtk_label_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
 }
 
 static void
-gtk_label_get_height (GtkSizeRequest *widget,
-                     gint           *minimum_size,
-                     gint           *natural_size)
+gtk_label_get_preferred_height (GtkWidget *widget,
+                                gint      *minimum_size,
+                                gint      *natural_size)
 {
-  gtk_label_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
+  gtk_label_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
 }
 
 static void
-gtk_label_get_width_for_height (GtkSizeRequest *widget,
-                                gint            height,
-                                gint           *minimum_width,
-                                gint           *natural_width)
+gtk_label_get_preferred_width_for_height (GtkWidget *widget,
+                                          gint       height,
+                                          gint      *minimum_width,
+                                          gint      *natural_width)
 {
   GtkLabel *label = GTK_LABEL (widget);
   GtkLabelPrivate *priv = label->priv;
@@ -3611,14 +3611,14 @@ gtk_label_get_width_for_height (GtkSizeRequest *widget,
         *natural_width += xpad * 2;
     }
   else
-    GTK_SIZE_REQUEST_GET_IFACE (widget)->get_width (widget, minimum_width, natural_width);
+    GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, minimum_width, natural_width);
 }
 
 static void
-gtk_label_get_height_for_width (GtkSizeRequest *widget,
-                                gint            width,
-                                gint           *minimum_height,
-                                gint           *natural_height)
+gtk_label_get_preferred_height_for_width (GtkWidget *widget,
+                                          gint       width,
+                                          gint      *minimum_height,
+                                          gint      *natural_height)
 {
   GtkLabel *label = GTK_LABEL (widget);
   GtkLabelPrivate *priv = label->priv;
@@ -3643,7 +3643,7 @@ gtk_label_get_height_for_width (GtkSizeRequest *widget,
         *natural_height += ypad * 2;
     }
   else
-    GTK_SIZE_REQUEST_GET_IFACE (widget)->get_height (widget, minimum_height, natural_height);
+    GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, minimum_height, natural_height);
 }
 
 static void
@@ -3805,8 +3805,7 @@ gtk_label_state_changed (GtkWidget   *widget,
 }
 
 static void
-gtk_label_style_set (GtkWidget *widget,
-                    GtkStyle  *previous_style)
+gtk_label_style_updated (GtkWidget *widget)
 {
   GtkLabel *label = GTK_LABEL (widget);
 
@@ -3921,7 +3920,7 @@ draw_insertion_cursor (GtkLabel      *label,
   else
     text_dir = GTK_TEXT_DIR_RTL;
 
-  gtk_cairo_draw_insertion_cursor (widget, cr, cursor_location,
+  gtk_draw_insertion_cursor (widget, cr, cursor_location,
                             is_primary, text_dir, draw_arrow);
 }
 
@@ -4064,7 +4063,8 @@ gtk_label_draw (GtkWidget *widget,
   GtkLabelPrivate *priv = label->priv;
   GtkLabelSelectionInfo *info = priv->select_info;
   GtkAllocation allocation;
-  GtkStyle *style;
+  GtkStyleContext *context;
+  GtkStateFlags state;
   GdkWindow *window;
   gint x, y;
 
@@ -4072,23 +4072,22 @@ gtk_label_draw (GtkWidget *widget,
 
   if (priv->text && (*priv->text != '\0'))
     {
+      GdkRGBA *bg_color, *fg_color;
+
       get_layout_location (label, &x, &y);
 
-      style = gtk_widget_get_style (widget);
+      context = gtk_widget_get_style_context (widget);
       window = gtk_widget_get_window (widget);
       gtk_widget_get_allocation (widget, &allocation);
 
-      x -= allocation.x;
-      y -= allocation.y;
+      cairo_translate (cr, -allocation.x, -allocation.y);
+
+      state = gtk_widget_get_state_flags (widget);
+      gtk_style_context_set_state (context, state);
 
-      gtk_paint_layout (style,
-                        cr,
-                        gtk_widget_get_state (widget),
-                       FALSE,
-                        widget,
-                        "label",
-                        x, y,
-                        priv->layout);
+      gtk_render_layout (context, cr,
+                         x, y,
+                         priv->layout);
 
       if (info &&
           (info->selection_anchor != info->selection_end))
@@ -4121,19 +4120,28 @@ gtk_label_draw (GtkWidget *widget,
           gdk_cairo_region (cr, clip);
           cairo_clip (cr);
 
-         state = GTK_STATE_SELECTED;
-         if (!gtk_widget_has_focus (widget))
-           state = GTK_STATE_ACTIVE;
+          state = GTK_STATE_FLAG_SELECTED;
+
+         if (gtk_widget_has_focus (widget))
+           state |= GTK_STATE_FLAG_FOCUSED;
 
-          gdk_cairo_set_source_color (cr, &style->base[state]);
+          gtk_style_context_get (context, state,
+                                 "background-color", &bg_color,
+                                 "color", &fg_color,
+                                 NULL);
+
+          gdk_cairo_set_source_rgba (cr, bg_color);
           cairo_paint (cr);
 
-          gdk_cairo_set_source_color (cr, &style->text[state]);
+          gdk_cairo_set_source_rgba (cr, fg_color);
           cairo_move_to (cr, x, y);
           _gtk_pango_fill_layout (cr, priv->layout);
 
           cairo_restore (cr);
           cairo_region_destroy (clip);
+
+          gdk_rgba_free (bg_color);
+          gdk_rgba_free (fg_color);
         }
       else if (info)
         {
@@ -4143,7 +4151,6 @@ gtk_label_draw (GtkWidget *widget,
           cairo_region_t *clip;
           GdkRectangle rect;
           GdkColor *text_color;
-          GdkColor *base_color;
           GdkColor *link_color;
           GdkColor *visited_link_color;
 
@@ -4156,6 +4163,8 @@ gtk_label_draw (GtkWidget *widget,
 
           if (active_link)
             {
+              GdkRGBA *bg_color;
+
               range[0] = active_link->start;
               range[1] = active_link->end;
 
@@ -4174,12 +4183,17 @@ gtk_label_draw (GtkWidget *widget,
                 text_color = visited_link_color;
               else
                 text_color = link_color;
+
               if (info->link_clicked)
-                base_color = &style->base[GTK_STATE_ACTIVE];
+                state = GTK_STATE_FLAG_ACTIVE;
               else
-                base_color = &style->base[GTK_STATE_PRELIGHT];
+                state = GTK_STATE_FLAG_PRELIGHT;
+
+              gtk_style_context_get (context, state,
+                                     "background-color", &bg_color,
+                                     NULL);
 
-              gdk_cairo_set_source_color (cr, base_color);
+              gdk_cairo_set_source_rgba (cr, bg_color);
               cairo_paint (cr);
 
               gdk_cairo_set_source_color (cr, text_color);
@@ -4188,6 +4202,7 @@ gtk_label_draw (GtkWidget *widget,
 
               gdk_color_free (link_color);
               gdk_color_free (visited_link_color);
+              gdk_rgba_free (bg_color);
 
               cairo_restore (cr);
             }
@@ -4203,9 +4218,12 @@ gtk_label_draw (GtkWidget *widget,
                                                        1);
               cairo_region_get_extents (clip, &rect);
 
-              gtk_paint_focus (style, cr, gtk_widget_get_state (widget),
-                               widget, "label",
-                               rect.x, rect.y, rect.width, rect.height);
+              state = gtk_widget_get_state_flags (widget);
+              gtk_style_context_set_state (context, state);
+
+              gtk_render_focus (context, cr,
+                                rect.x, rect.y,
+                                rect.width, rect.height);
 
               cairo_region_destroy (clip);
             }
@@ -5509,8 +5527,9 @@ gtk_label_get_selection_bounds (GtkLabel  *label,
  * Gets the #PangoLayout used to display the label.
  * The layout is useful to e.g. convert text positions to
  * pixel positions, in combination with gtk_label_get_layout_offsets().
- * The returned layout is owned by the label so need not be
- * freed by the caller.
+ * The returned layout is owned by the @label so need not be
+ * freed by the caller. The @label is free to recreate its layout at
+ * any time, so it should be considered read-only.
  *
  * Return value: (transfer none): the #PangoLayout for this label
  **/
@@ -6127,8 +6146,8 @@ popup_position_func (GtkMenu   *menu,
   *x += allocation.x;
   *y += allocation.y;
 
-  gtk_size_request_get_size (GTK_SIZE_REQUEST (menu),
-                             &req, NULL);
+  gtk_widget_get_preferred_size (GTK_WIDGET (menu),
+                                 &req, NULL);
 
   gtk_widget_get_allocation (widget, &allocation);