Example #1
0
static gboolean
gtk_switch_draw (GtkWidget *widget,
                 cairo_t   *cr)
{
  GtkSwitchPrivate *priv = GTK_SWITCH (widget)->priv;
  GtkStyleContext *context;
  GdkRectangle handle;
  PangoLayout *layout;
  PangoFontDescription *desc;
  const PangoFontDescription *style_desc;
  PangoRectangle rect;
  gint label_x, label_y;
  GtkStateFlags state;
  GtkBorder padding;
  gint focus_width, focus_pad;
  gint x, y, width, height;
  gint font_size, style_font_size;

  gtk_widget_style_get (widget,
                        "focus-line-width", &focus_width,
                        "focus-padding", &focus_pad,
                        NULL);

  context = gtk_widget_get_style_context (widget);
  state = gtk_widget_get_state_flags (widget);

  if (priv->is_active)
    state |= GTK_STATE_FLAG_ACTIVE;

  gtk_style_context_save (context);

  gtk_style_context_set_state (context, state);
  gtk_style_context_add_class (context, GTK_STYLE_CLASS_SLIDER);

  gtk_style_context_get_padding (context, state, &padding);

  gtk_style_context_restore (context);

  x = 0;
  y = 0;
  width = gtk_widget_get_allocated_width (widget);
  height = gtk_widget_get_allocated_height (widget);

  if (gtk_widget_has_focus (widget))
    gtk_render_focus (context, cr, x, y, width, height);

  x += focus_width + focus_pad;
  y += focus_width + focus_pad;
  width -= 2 * (focus_width + focus_pad);
  height -= 2 * (focus_width + focus_pad);

  gtk_style_context_save (context);
  gtk_style_context_add_class (context, GTK_STYLE_CLASS_TROUGH);
  gtk_style_context_set_state (context, state);

  gtk_render_background (context, cr, x, y, width, height);
  gtk_render_frame (context, cr, x, y, width, height);

  width -= padding.left + padding.right;
  height -= padding.top + padding.bottom;

  x += padding.left;
  y += padding.top;

  handle.y = y;
  handle.width = width / 2;
  handle.height = height;

  /* Translators: if the "on" state label requires more than three
   * glyphs then use MEDIUM VERTICAL BAR (U+2759) as the text for
   * the state
   */
  layout = gtk_widget_create_pango_layout (widget, C_("switch", "ON"));

  /* FIXME: this should be really done in the theme, but overriding font size
   * from it doesn't currently work. So we have to hardcode this here and
   * below for the "OFF" label.
   */
  desc = pango_font_description_new ();

  style_desc = gtk_style_context_get_font (context, state);
  style_font_size = pango_font_description_get_size (style_desc);
  font_size = MAX (style_font_size - 1 * PANGO_SCALE, ceil (style_font_size * PANGO_SCALE_SMALL));

  pango_font_description_set_size (desc, font_size);

  pango_layout_set_font_description (layout, desc);

  pango_layout_get_extents (layout, NULL, &rect);
  pango_extents_to_pixels (&rect, NULL);

  label_x = x +  ((width / 2) - rect.width) / 2;
  label_y = y + (height - rect.height) / 2;

  gtk_render_layout (context, cr, label_x, label_y, layout);

  g_object_unref (layout);

  /* Translators: if the "off" state label requires more than three
   * glyphs then use WHITE CIRCLE (U+25CB) as the text for the state
   */
  layout = gtk_widget_create_pango_layout (widget, C_("switch", "OFF"));
  pango_layout_set_font_description (layout, desc);

  pango_layout_get_extents (layout, NULL, &rect);
  pango_extents_to_pixels (&rect, NULL);

  label_x = x +  (width / 2) + ((width / 2) - rect.width) / 2;
  label_y = y + (height - rect.height) / 2;

  gtk_render_layout (context, cr, label_x, label_y, layout);

  g_object_unref (layout);

  if (priv->is_dragging)
    handle.x = x + priv->handle_x;
  else if (priv->is_active)
    handle.x = x + width - handle.width;
  else
    handle.x = x;

  gtk_style_context_restore (context);

  gtk_switch_paint_handle (widget, cr, &handle);

  pango_font_description_free (desc);

  return FALSE;
}
Example #2
0
static gboolean
gtk_switch_draw (GtkWidget *widget,
                 cairo_t   *cr)
{
  GtkSwitchPrivate *priv = GTK_SWITCH (widget)->priv;
  GtkStyleContext *context;
  GdkRectangle handle;
  PangoLayout *layout;
  PangoRectangle rect;
  gint label_x, label_y;
  GtkBorder padding;
  GtkStateFlags state;
  gint x, y, width, height;

  context = gtk_widget_get_style_context (widget);
  state = gtk_widget_get_state_flags (widget);

  gtk_style_context_save (context);

  gtk_style_context_add_class (context, GTK_STYLE_CLASS_SLIDER);

  gtk_style_context_get_padding (context, state, &padding);

  gtk_style_context_restore (context);

  x = 0;
  y = 0;
  width = gtk_widget_get_allocated_width (widget);
  height = gtk_widget_get_allocated_height (widget);

  gtk_style_context_save (context);
  gtk_style_context_add_class (context, GTK_STYLE_CLASS_TROUGH);

  gtk_render_background (context, cr, x, y, width, height);
  gtk_render_frame (context, cr, x, y, width, height);

  width -= padding.left + padding.right;
  height -= padding.top + padding.bottom;

  x += padding.left;
  y += padding.top;

  handle.y = y;
  handle.width = width / 2;
  handle.height = height;

  /* Translators: if the "on" state label requires more than three
   * glyphs then use MEDIUM VERTICAL BAR (U+2759) as the text for
   * the state
   */
  layout = gtk_widget_create_pango_layout (widget, C_("switch", "ON"));

  pango_layout_get_extents (layout, NULL, &rect);
  pango_extents_to_pixels (&rect, NULL);

  label_x = x +  ((width / 2) - rect.width) / 2;
  label_y = y + (height - rect.height) / 2;

  gtk_render_layout (context, cr, label_x, label_y, layout);

  g_object_unref (layout);

  /* Translators: if the "off" state label requires more than three
   * glyphs then use WHITE CIRCLE (U+25CB) as the text for the state
   */
  layout = gtk_widget_create_pango_layout (widget, C_("switch", "OFF"));

  pango_layout_get_extents (layout, NULL, &rect);
  pango_extents_to_pixels (&rect, NULL);

  label_x = x +  (width / 2) + ((width / 2) - rect.width) / 2;
  label_y = y + (height - rect.height) / 2;

  gtk_render_layout (context, cr, label_x, label_y, layout);

  g_object_unref (layout);

  if (priv->is_dragging)
    handle.x = x + priv->handle_x;
  else if (priv->is_active)
    handle.x = x + width - handle.width;
  else
    handle.x = x;

  gtk_style_context_restore (context);

  gtk_switch_paint_handle (widget, cr, &handle);

  if (gtk_widget_has_visible_focus (widget))
    {
      gint focus_width, focus_pad, pad;

      gtk_widget_style_get (widget,
                            "focus-line-width", &focus_width,
                            "focus-padding", &focus_pad,
                            NULL);

      pad = focus_pad + focus_width;

      gtk_render_focus (context, cr,
                        handle.x + pad, handle.y + pad,
                        handle.width - pad*2, handle.height - pad*2);
    }

  return FALSE;
}
Example #3
0
File: gtkswitch.c Project: BYC/gtk
static gboolean
gtk_switch_draw (GtkWidget *widget,
                 cairo_t   *cr)
{
  GtkSwitchPrivate *priv = GTK_SWITCH (widget)->priv;
  GtkStyleContext *context;
  GdkRectangle handle;
  PangoLayout *layout;
  PangoRectangle rect;
  gint label_x, label_y;
  GtkStateFlags state;
  GtkBorder padding;
  gint focus_width, focus_pad;
  gint x, y, width, height;

  gtk_widget_style_get (widget,
                        "focus-line-width", &focus_width,
                        "focus-padding", &focus_pad,
                        NULL);

  context = gtk_widget_get_style_context (widget);
  state = gtk_widget_get_state_flags (widget);

  if (priv->is_active)
    state |= GTK_STATE_FLAG_ACTIVE;

  gtk_style_context_get_padding (context, state, &padding);

  x = 0;
  y = 0;
  width = gtk_widget_get_allocated_width (widget);
  height = gtk_widget_get_allocated_height (widget);

  if (gtk_widget_has_focus (widget))
    gtk_render_focus (context, cr, x, y, width, height);

  gtk_style_context_save (context);
  gtk_style_context_set_state (context, state);

  x += focus_width + focus_pad;
  y += focus_width + focus_pad;
  width -= 2 * (focus_width + focus_pad);
  height -= 2 * (focus_width + focus_pad);

  gtk_style_context_add_class (context, GTK_STYLE_CLASS_TROUGH);

  gtk_render_background (context, cr, x, y, width, height);
  gtk_render_frame (context, cr, x, y, width, height);

  /* XXX the +1/-1 it's pixel wriggling after checking with the default
   * theme and xmag
   */
  handle.y = y + padding.top + 1;
  handle.width = (width - padding.left - padding.right) / 2;
  handle.height = (height - padding.top - padding.bottom) - 1;

  /* Translators: if the "on" state label requires more than three
   * glyphs then use MEDIUM VERTICAL BAR (U+2759) as the text for
   * the state
   */
  layout = gtk_widget_create_pango_layout (widget, C_("switch", "ON"));
  pango_layout_get_extents (layout, NULL, &rect);
  pango_extents_to_pixels (&rect, NULL);

  label_x = x + padding.left
          + ((width / 2) - rect.width - padding.left - padding.right) / 2;
  label_y = y + padding.top
          + (height - rect.height - padding.top - padding.bottom) / 2;

  gtk_render_layout (context, cr, label_x, label_y, layout);

  g_object_unref (layout);

  /* Translators: if the "off" state label requires more than three
   * glyphs then use WHITE CIRCLE (U+25CB) as the text for the state
   */
  layout = gtk_widget_create_pango_layout (widget, C_("switch", "OFF"));
  pango_layout_get_extents (layout, NULL, &rect);
  pango_extents_to_pixels (&rect, NULL);

  label_x = x + padding.left
          + (width / 2)
          + ((width / 2) - rect.width - padding.left - padding.right) / 2;
  label_y = y + padding.top
          + (height - rect.height - padding.top - padding.bottom) / 2;

  gtk_render_layout (context, cr, label_x, label_y, layout);

  g_object_unref (layout);

  if (priv->is_dragging)
    handle.x = x + priv->handle_x;
  else if (priv->is_active)
    handle.x = x + width - handle.width - padding.right;
  else
    handle.x = x + padding.left;

  gtk_style_context_restore (context);

  gtk_switch_paint_handle (widget, cr, &handle);

  return FALSE;
}