static gboolean
gtk_notification_draw (GtkWidget *widget, cairo_t *cr)
{
  GtkNotification *notification = GTK_NOTIFICATION (widget);
  GtkNotificationPrivate *priv = notification->priv;
  GtkStyleContext *context;
  GdkRectangle rect;
  int inner_radius;

  if (gtk_cairo_should_draw_window (cr, priv->bin_window))
    {
      gtk_widget_get_allocation (widget, &rect);

      context = gtk_widget_get_style_context(widget);

      inner_radius = 5;
      draw_shadow_box (cr, rect, SHADOW_OFFSET_X + inner_radius, SHADOW_OFFSET_X + inner_radius,
                       SHADOW_OFFSET_Y + inner_radius, 0.8);

      gtk_style_context_save (context);
      gtk_render_background (context,  cr,
                             SHADOW_OFFSET_X, 0,
                             gtk_widget_get_allocated_width (widget) - 2 *SHADOW_OFFSET_X,
                             gtk_widget_get_allocated_height (widget) - SHADOW_OFFSET_Y);
      gtk_render_frame (context,cr,
                        SHADOW_OFFSET_X, 0,
                        gtk_widget_get_allocated_width (widget) - 2 *SHADOW_OFFSET_X,
                        gtk_widget_get_allocated_height (widget) - SHADOW_OFFSET_Y);

      gtk_style_context_restore (context);

      if (GTK_WIDGET_CLASS (gtk_notification_parent_class)->draw)
        GTK_WIDGET_CLASS (gtk_notification_parent_class)->draw(widget, cr);
    }

  return FALSE;
}
Exemple #2
0
static void
draw_horizontal_scrollbar (GtkWidget     *widget,
                           cairo_t       *cr,
                           gint           x,
                           gint           y,
                           gint           width,
                           gint           height,
                           gint           position,
                           GtkStateFlags  state)
{
  GtkStyleContext *scrollbar_context;
  GtkStyleContext *trough_context;
  GtkStyleContext *slider_context;

  /* This information is taken from the GtkScrollbar docs, see "CSS nodes" */
  const char *path[3] = {
    "scrollbar.horizontal",
    "trough",
    "slider"
  };

  scrollbar_context = get_style (NULL, path[0]);
  trough_context = get_style (scrollbar_context, path[1]);
  slider_context = get_style (trough_context, path[2]);

  gtk_style_context_set_state (scrollbar_context, state);
  gtk_style_context_set_state (trough_context, state);
  gtk_style_context_set_state (slider_context, state);

  gtk_render_background (trough_context, cr, x, y, width, height);
  gtk_render_frame (trough_context, cr, x, y, width, height);
  gtk_render_slider (slider_context, cr, x + position, y + 1, 30, height - 2, GTK_ORIENTATION_HORIZONTAL);

  g_object_unref (slider_context);
  g_object_unref (trough_context);
  g_object_unref (scrollbar_context);
}
Exemple #3
0
static void
gtk_do_render_handle (GtkStyleContext *context,
                      cairo_t         *cr,
                      gdouble          x,
                      gdouble          y,
                      gdouble          width,
                      gdouble          height)
{
  GtkCssImageBuiltinType type;

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

  if (gtk_style_context_has_class (context, GTK_STYLE_CLASS_PANE_SEPARATOR))
    {
      type = GTK_CSS_IMAGE_BUILTIN_PANE_SEPARATOR;
    }
  else
    {
      type = GTK_CSS_IMAGE_BUILTIN_HANDLE;
    }

  gtk_css_style_render_icon (gtk_style_context_lookup_style (context), cr, x, y, width, height, type);
}
static gboolean
draw_arrow_cb (GtkWidget *widget, cairo_t *cr, gpointer data)
{
    GncItemEdit *item_edit = GNC_ITEM_EDIT (data);
    GtkStyleContext *context = gtk_widget_get_style_context (widget);
    gint width = gtk_widget_get_allocated_width (widget);
    gint height = gtk_widget_get_allocated_height (widget);
    gint size;

    gtk_render_background (context, cr, 0, 0, width, height);

    gtk_style_context_add_class (context, GTK_STYLE_CLASS_ARROW);

    size = MIN(width / 2, height / 2);

    if (item_edit->popup_toggle.arrow_down == 0)
        gtk_render_arrow (context, cr, 0,
                         (width - size)/2, (height - size)/2, size);
    else
        gtk_render_arrow (context, cr, G_PI,
                         (width - size)/2, (height - size)/2, size);

    return FALSE;
}
Exemple #5
0
/**
 * gd_create_symbolic_icon:
 * @name:
 *
 * Returns: (transfer full):
 */
GIcon *
gd_create_symbolic_icon (const gchar *name,
                         gint base_size)
{
  gchar *symbolic_name;
  GIcon *icon, *retval = NULL;
  cairo_surface_t *surface;
  cairo_t *cr;
  GtkStyleContext *style;
  GtkWidgetPath *path;
  GdkPixbuf *pixbuf;
  GtkIconTheme *theme;
  GtkIconInfo *info;
  gint bg_size;
  gint emblem_size;
  gint total_size;

  total_size = base_size / 2;
  bg_size = MAX (total_size / 2, _BG_MIN_SIZE);
  emblem_size = MAX (bg_size - 8, _EMBLEM_MIN_SIZE);

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, total_size, total_size);
  cr = cairo_create (surface);

  style = gtk_style_context_new ();

  path = gtk_widget_path_new ();
  gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);
  gtk_style_context_set_path (style, path);
  gtk_widget_path_unref (path);

  gtk_style_context_add_class (style, "documents-icon-bg");

  gtk_render_background (style, cr, (total_size - bg_size) / 2, (total_size - bg_size) / 2, bg_size, bg_size);

  symbolic_name = g_strconcat (name, "-symbolic", NULL);
  icon = g_themed_icon_new_with_default_fallbacks (symbolic_name);
  g_free (symbolic_name);

  theme = gtk_icon_theme_get_default();
  info = gtk_icon_theme_lookup_by_gicon (theme, icon, emblem_size,
                                         GTK_ICON_LOOKUP_FORCE_SIZE);
  g_object_unref (icon);

  if (info == NULL)
    goto out;

  pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL);
  gtk_icon_info_free (info);

  if (pixbuf == NULL)
    goto out;

  gtk_render_icon (style, cr, pixbuf, (total_size - emblem_size) / 2,  (total_size - emblem_size) / 2);
  g_object_unref (pixbuf);

  retval = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, total_size, total_size));

 out:
  g_object_unref (style);
  cairo_surface_destroy (surface);
  cairo_destroy (cr);

  return retval;
}
Exemple #6
0
/**
 * gd_create_collection_icon:
 * @base_size:
 * @pixbufs: (element-type GdkPixbuf):
 *
 * Returns: (transfer full):
 */
GIcon *
gd_create_collection_icon (gint base_size,
                           GList *pixbufs)
{
  cairo_surface_t *surface;
  GIcon *retval;
  cairo_t *cr;
  GtkStyleContext *context;
  GtkWidgetPath *path;
  gint padding, tile_size, scale_size;
  gint pix_width, pix_height;
  gint idx, cur_x, cur_y;
  GList *l;
  GdkPixbuf *pix;

  /* TODO: do not hardcode 4, but scale to another layout if more
   * pixbufs are provided.
   */

  padding = MAX (floor (base_size / 10), 4);
  tile_size = (base_size - (3 * padding)) / 2;

  context = gtk_style_context_new ();
  gtk_style_context_add_class (context, "documents-collection-icon");

  path = gtk_widget_path_new ();
  gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);
  gtk_style_context_set_path (context, path);
  gtk_widget_path_unref (path);

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, base_size, base_size);
  cr = cairo_create (surface);

  gtk_render_background (context, cr,
                         0, 0, base_size, base_size);

  l = pixbufs;
  idx = 0;
  cur_x = padding;
  cur_y = padding;

  while (l != NULL && idx < 4)
    {
      pix = l->data;
      pix_width = gdk_pixbuf_get_width (pix);
      pix_height = gdk_pixbuf_get_height (pix);

      scale_size = MIN (pix_width, pix_height);

      cairo_save (cr);

      cairo_translate (cr, cur_x, cur_y);

      cairo_rectangle (cr, 0, 0,
                       tile_size, tile_size);
      cairo_clip (cr);

      cairo_scale (cr, (gdouble) tile_size / (gdouble) scale_size, (gdouble) tile_size / (gdouble) scale_size);
      gdk_cairo_set_source_pixbuf (cr, pix, 0, 0);

      cairo_paint (cr);
      cairo_restore (cr);

      if ((idx % 2) == 0)
        {
          cur_x += tile_size + padding;
        }
      else
        {
          cur_x = padding;
          cur_y += tile_size + padding;
        }

      idx++;
      l = l->next;
    }

  retval = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, base_size, base_size));

  cairo_surface_destroy (surface);
  cairo_destroy (cr);
  g_object_unref (context);

  return retval;
}
Exemple #7
0
GIcon *
photos_utils_create_collection_icon (gint base_size, GList *pixbufs)
{
  cairo_surface_t *surface; /* TODO: use g_autoptr */
  cairo_t *cr; /* TODO: use g_autoptr */
  GdkPixbuf *pix;
  GIcon *ret_val;
  GList *l;
  g_autoptr (GtkStyleContext) context = NULL;
  g_autoptr (GtkWidgetPath) path = NULL;
  gint cur_x;
  gint cur_y;
  gint padding;
  gint pix_height;
  gint pix_width;
  gint scale_size;
  gint tile_size;
  guint idx;
  guint n_grid;
  guint n_pixbufs;
  guint n_tiles;

  n_pixbufs = g_list_length (pixbufs);
  if (n_pixbufs < 3)
    {
      n_grid = 1;
      n_tiles = 1;
    }
  else
    {
      n_grid = 2;
      n_tiles = 4;
    }

  padding = MAX (base_size / 10, 4);
  tile_size = (base_size - ((n_grid + 1) * padding)) / n_grid;

  context = gtk_style_context_new ();
  gtk_style_context_add_class (context, "photos-collection-icon");

  path = gtk_widget_path_new ();
  gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);
  gtk_style_context_set_path (context, path);

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, base_size, base_size);
  cr = cairo_create (surface);

  gtk_render_background (context, cr, 0, 0, base_size, base_size);

  l = pixbufs;
  idx = 0;
  cur_x = padding;
  cur_y = padding;

  while (l != NULL && idx < n_tiles)
    {
      pix = l->data;
      pix_width = gdk_pixbuf_get_width (pix);
      pix_height = gdk_pixbuf_get_height (pix);

      scale_size = MIN (pix_width, pix_height);

      cairo_save (cr);

      cairo_translate (cr, cur_x, cur_y);

      cairo_rectangle (cr, 0, 0,
                       tile_size, tile_size);
      cairo_clip (cr);

      cairo_scale (cr, (gdouble) tile_size / (gdouble) scale_size, (gdouble) tile_size / (gdouble) scale_size);
      gdk_cairo_set_source_pixbuf (cr, pix, 0, 0);

      cairo_paint (cr);
      cairo_restore (cr);

      idx++;
      l = l->next;

      if ((idx % n_grid) == 0)
        {
          cur_x = padding;
          cur_y += tile_size + padding;
        }
      else
        {
          cur_x += tile_size + padding;
        }
    }

  ret_val = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, base_size, base_size));

  cairo_surface_destroy (surface);
  cairo_destroy (cr);

  return ret_val;
}
static gboolean
gstyle_color_widget_draw (GtkWidget *widget,
                          cairo_t   *cr)
{
  GstyleColorWidget *self = (GstyleColorWidget *)widget;
  GtkStyleContext *style_context;
  GdkRectangle margin_box;
  GdkRectangle border_box;
  cairo_matrix_t matrix;
  GdkRGBA bg_color = {0};
  gint radius;

  g_assert (GSTYLE_IS_COLOR_WIDGET (self));
  g_assert (cr != NULL);

  style_context = gtk_widget_get_style_context (GTK_WIDGET (self));
  gtk_widget_get_allocation (widget, &margin_box);
  margin_box.x = margin_box.y = 0;

  gstyle_utils_get_rect_resized_box (margin_box, &margin_box, &self->cached_margin);
  gstyle_utils_get_rect_resized_box (margin_box, &border_box, &self->cached_border);
  cairo_save (cr);

  if (self->color != NULL)
    {
      gtk_style_context_get (style_context,
                            gtk_style_context_get_state (style_context),
                            "border-radius", &radius,
                            NULL);

      gstyle_color_fill_rgba (self->color, &bg_color);
      if (self->filter_func != NULL)
        self->filter_func (&bg_color, &bg_color, self->filter_user_data);

      cairo_new_path (cr);
      draw_cairo_round_box (cr, border_box, radius, radius, radius, radius);
    }
  else
    cairo_rectangle (cr, border_box.x, border_box.y, border_box.width, border_box.height);

  cairo_clip_preserve (cr);

  cairo_set_source_rgb (cr, 0.20, 0.20, 0.20);
  cairo_paint (cr);
  cairo_set_source_rgb (cr, 0.80, 0.80, 0.80);

  cairo_matrix_init_scale (&matrix, 0.1, 0.1);
  cairo_matrix_translate (&matrix, -border_box.x, -border_box.y);
  cairo_pattern_set_matrix (self->checkered_pattern, &matrix);
  cairo_mask (cr, self->checkered_pattern);

  if (self->color != NULL)
    {
      gdk_cairo_set_source_rgba (cr, &bg_color);
      cairo_fill (cr);
    }
  else
    gtk_render_background (style_context, cr, border_box.x, border_box.y, border_box.width, border_box.height);

  cairo_restore (cr);
  gtk_render_frame (gtk_widget_get_style_context (widget), cr,
                    margin_box.x, margin_box.y, margin_box.width, margin_box.height);

  return GTK_WIDGET_CLASS (gstyle_color_widget_parent_class)->draw (widget, cr);
}
static void
gnc_header_draw_offscreen (GncHeader *header)
{
    SheetBlockStyle *style = header->style;
    Table *table = header->sheet->table;
    VirtualLocation virt_loc;
    VirtualCell *vcell;
    guint32 color_type;
    GtkStyleContext *stylectxt = gtk_widget_get_style_context (GTK_WIDGET(header));
    GdkRGBA color;
    int row_offset;
    CellBlock *cb;
    int i;
    cairo_t *cr;

    virt_loc.vcell_loc.virt_row = 0;
    virt_loc.vcell_loc.virt_col = 0;
    virt_loc.phys_row_offset = 0;
    virt_loc.phys_col_offset = 0;

    gtk_style_context_save (stylectxt);

    // Get the background color type and apply the css class
    color_type = gnc_table_get_bg_color (table, virt_loc, NULL);
    gnucash_get_style_classes (header->sheet, stylectxt, color_type);

    if (header->surface)
        cairo_surface_destroy (header->surface);
    header->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                                header->width,
                                                header->height);

    cr = cairo_create (header->surface);

    // Fill background color of header
    gtk_render_background (stylectxt, cr, 0, 0, header->width, header->height);

    gdk_rgba_parse (&color, "black");
    cairo_set_source_rgb (cr, color.red, color.green, color.blue);
    cairo_rectangle (cr, 0.5, 0.5, header->width - 1.0, header->height - 1.0);
    cairo_set_line_width (cr, 1.0);
    cairo_stroke (cr);

    // Draw bottom horizontal line, makes bottom line thicker
    cairo_move_to (cr, 0.5, header->height - 1.5);
    cairo_line_to (cr, header->width - 1.0, header->height - 1.5);
    cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
    cairo_set_line_width (cr, 1.0);
    cairo_stroke (cr);

    /*font = gnucash_register_font;*/

    vcell = gnc_table_get_virtual_cell
            (table, table->current_cursor_loc.vcell_loc);
    cb = vcell ? vcell->cellblock : NULL;
    row_offset = 0;

    for (i = 0; i < style->nrows; i++)
    {
        int col_offset = 0;
        int h = 0, j;
        virt_loc.phys_row_offset = i;

        /* TODO: This routine is duplicated in several places.
           Can we abstract at least the cell drawing routine?
           That way we'll be sure everything is drawn
           consistently, and cut down on maintenance issues. */

        for (j = 0; j < style->ncols; j++)
        {
            CellDimensions *cd;
            double text_x, text_y, text_w, text_h;
            BasicCell *cell;
            const char *text;
            int w;
            PangoLayout *layout;

            virt_loc.phys_col_offset = j;

            cd = gnucash_style_get_cell_dimensions (style, i, j);
            h = cd->pixel_height;
            if (header->in_resize && (j == header->resize_col))
                w = header->resize_col_width;
            else
                w = cd->pixel_width;

            cell = gnc_cellblock_get_cell (cb, i, j);
            if (!cell || !cell->cell_name)
            {
                col_offset += w;
                continue;
            }

            cairo_rectangle (cr, col_offset - 0.5, row_offset + 0.5, w, h);
            cairo_set_line_width (cr, 1.0);
            cairo_stroke (cr);

            virt_loc.vcell_loc =
                table->current_cursor_loc.vcell_loc;
            text = gnc_table_get_label (table, virt_loc);
            if (!text)
                text = "";

            layout = gtk_widget_create_pango_layout (GTK_WIDGET (header->sheet), text);
            switch (gnc_table_get_align (table, virt_loc))
            {
            default:
            case CELL_ALIGN_LEFT:
                pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
                break;

            case CELL_ALIGN_RIGHT:
                pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
                break;

            case CELL_ALIGN_CENTER:
                pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
                break;
            }

            text_x = col_offset + CELL_HPADDING;
            text_y = row_offset + 1;
            text_w = MAX (0, w - (2 * CELL_HPADDING));
            text_h = h - 2;
            cairo_save (cr);
            cairo_rectangle (cr, text_x, text_y, text_w, text_h);
            cairo_clip (cr);

            gtk_render_layout (stylectxt, cr, text_x, text_y, layout);

            cairo_restore (cr);
            g_object_unref (layout);

            col_offset += w;
        }
        row_offset += h;
    }
    gtk_style_context_restore (stylectxt);

    cairo_destroy (cr);
}
Exemple #10
0
static gboolean dt_iop_zonesystem_preview_draw(GtkWidget *widget, cairo_t *crf, dt_iop_module_t *self)
{
  const int inset = DT_PIXEL_APPLY_DPI(2);
  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  int width = allocation.width, height = allocation.height;

  dt_iop_zonesystem_gui_data_t *g = (dt_iop_zonesystem_gui_data_t *)self->gui_data;
  dt_iop_zonesystem_params_t *p = (dt_iop_zonesystem_params_t *)self->params;

  cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  cairo_t *cr = cairo_create(cst);

  /* clear background */
  GtkStyleContext *context = gtk_widget_get_style_context(self->expander);
  gtk_render_background(context, cr, 0, 0, allocation.width, allocation.height);

  width -= 2 * inset;
  height -= 2 * inset;
  cairo_translate(cr, inset, inset);

  dt_pthread_mutex_lock(&g->lock);
  if(g->in_preview_buffer && g->out_preview_buffer && self->enabled)
  {
    /* calculate the zonemap */
    float zonemap[MAX_ZONE_SYSTEM_SIZE] = { -1 };
    _iop_zonesystem_calculate_zonemap(p, zonemap);

    /* let's generate a pixbuf from pixel zone buffer */
    guchar *image = g_malloc_n((size_t)4 * g->preview_width * g->preview_height, sizeof(guchar));
    guchar *buffer = g->mouse_over_output_zones ? g->out_preview_buffer : g->in_preview_buffer;
    for(int k = 0; k < g->preview_width * g->preview_height; k++)
    {
      int zone = 255 * CLIP(((1.0 / (p->size - 1)) * buffer[k]));
      image[4 * k + 2] = (g->hilite_zone && buffer[k] == g->zone_under_mouse) ? 255 : zone;
      image[4 * k + 1] = (g->hilite_zone && buffer[k] == g->zone_under_mouse) ? 255 : zone;
      image[4 * k + 0] = (g->hilite_zone && buffer[k] == g->zone_under_mouse) ? 0 : zone;
    }
    dt_pthread_mutex_unlock(&g->lock);

    const int wd = g->preview_width, ht = g->preview_height;
    const float scale = fminf(width / (float)wd, height / (float)ht);
    const int stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, wd);
    cairo_surface_t *surface = cairo_image_surface_create_for_data(image, CAIRO_FORMAT_RGB24, wd, ht, stride);
    cairo_translate(cr, width / 2.0, height / 2.0f);
    cairo_scale(cr, scale, scale);
    cairo_translate(cr, -.5f * wd, -.5f * ht);

    cairo_rectangle(cr, DT_PIXEL_APPLY_DPI(1), DT_PIXEL_APPLY_DPI(1), wd - DT_PIXEL_APPLY_DPI(2),
                    ht - DT_PIXEL_APPLY_DPI(2));
    cairo_set_source_surface(cr, surface, 0, 0);
    cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_GOOD);
    cairo_fill_preserve(cr);
    cairo_surface_destroy(surface);

    cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.0));
    cairo_set_source_rgb(cr, .1, .1, .1);
    cairo_stroke(cr);

    g_free(image);
  }
  else
  {
    dt_pthread_mutex_unlock(&g->lock);
    // draw a big, subdued dt logo
    if(g->image)
    {
      GdkRGBA *color;
      gtk_style_context_get(context, gtk_widget_get_state_flags(self->expander), "background-color", &color,
                            NULL);

      cairo_set_source_surface(cr, g->image, (width - g->image_width) * 0.5, (height - g->image_height) * 0.5);
      cairo_rectangle(cr, 0, 0, width, height);
      cairo_set_operator(cr, CAIRO_OPERATOR_HSL_LUMINOSITY);
      cairo_fill_preserve(cr);
      cairo_set_operator(cr, CAIRO_OPERATOR_DARKEN);
      cairo_set_source_rgb(cr, color->red + 0.02, color->green + 0.02, color->blue + 0.02);
      cairo_fill_preserve(cr);
      cairo_set_operator(cr, CAIRO_OPERATOR_LIGHTEN);
      cairo_set_source_rgb(cr, color->red - 0.02, color->green - 0.02, color->blue - 0.02);
      cairo_fill(cr);

      gdk_rgba_free(color);
    }
  }

  cairo_destroy(cr);
  cairo_set_source_surface(crf, cst, 0, 0);
  cairo_paint(crf);
  cairo_surface_destroy(cst);

  return TRUE;
}
Exemple #11
0
static gboolean digital_clock_draw(GtkWidget * w, cairo_t * cr)
{
    DigitalClock *dclock = DIGITAL_CLOCK(w);
    DigitalClockPriv*priv=dclock->priv;

    struct timeval tv;
    if (gettimeofday(&tv, NULL) == -1) {
	g_critical("gettimeofday() failed!");
    }

    time_t now = tv.tv_sec;
//  time_t now = time (NULL);
    struct tm *now_tm = localtime(&now);


    double width, height, fontsiz;
    width = (double) priv->width;
    height = (double)priv->height;
    fontsiz = (double) priv->fsiz;

    static gboolean draw_colon;
    static int now_sec = -1;
    static int last_msec=-1;


//    cairo_scale(cr,width,height);
//  cairo_set_source_rgb (cr, 1, 1, 1);
//  cairo_paint (cr);

    gtk_render_background(gtk_widget_get_style_context(w), cr, 0, 0,
			  priv->width, priv->height);

    if (priv->sensitive || time_val_is_null(priv->time_val)) {

        if(!priv->blink||last_msec<=500)//||now_sec!=now_tm->tm_sec)
            draw_colon=TRUE;
        else
            draw_colon=FALSE;

	if (priv->show_sec) {
	    if (draw_colon)
		sprintf(priv->time_val, "%02d:%02d:%02d", now_tm->tm_hour,
			now_tm->tm_min, now_tm->tm_sec);
	    else
		sprintf(priv->time_val, "%02d %02d %02d", now_tm->tm_hour,
			now_tm->tm_min, now_tm->tm_sec);

	    if (priv->show_msec) {
		sprintf(priv->time_val+ 8, ".%d",
			(int) (tv.tv_usec / 1000.0 + 0.5));
	    }
	} else {
	    if (draw_colon)
		sprintf(priv->time_val, "%02d:%02d", now_tm->tm_hour,
			now_tm->tm_min);
	    else
		sprintf(priv->time_val, "%02d %02d", now_tm->tm_hour,
			now_tm->tm_min);
	}
//	now_sec = now_tm->tm_sec;
    }

	last_msec=(int) (tv.tv_usec / 1000.0 + 0.5);
//    printf("Time::[%s].%03u %06u\n", TimeStr,last_msec,tv.tv_usec);

    cairo_select_font_face(cr, priv->font, CAIRO_FONT_SLANT_NORMAL,CAIRO_FONT_WEIGHT_NORMAL);
    cairo_set_font_size(cr, fontsiz);

    cairo_text_extents_t extents;
    if (priv->show_sec) {
	cairo_text_extents(cr, "00:00:00", &extents);
	if (priv->show_msec)
	    cairo_text_extents(cr, "00:00:00.000", &extents);
    } else
	cairo_text_extents(cr, "00:00", &extents);


    double x = width / 2 - extents.width / 2 - extents.x_bearing;
    double y = height / 2 - extents.height / 2 - extents.y_bearing;

    cairo_set_source_rgb(cr, 0, 0, 0);

    cairo_move_to(cr, x, y);
    cairo_show_text(cr, priv->time_val);

    return TRUE;
}
Exemple #12
0
static gboolean
swatch_draw (GtkWidget *widget,
             cairo_t   *cr)
{
  GtkColorSwatch *swatch = (GtkColorSwatch*)widget;
  gdouble width, height;
  GtkStyleContext *context;
  GtkStateFlags state;
  GtkIconTheme *theme;
  GtkBorder border, padding;
  GdkRectangle rect;
  GtkIconInfo *icon_info = NULL;

  theme = gtk_icon_theme_get_default ();
  context = gtk_widget_get_style_context (widget);
  state = gtk_style_context_get_state (context);
  width = gtk_widget_get_allocated_width (widget);
  height = gtk_widget_get_allocated_height (widget);

  gtk_render_background (context, cr, 0, 0, width, height);

  if (swatch->priv->has_color)
    {
      cairo_pattern_t *pattern;
      cairo_matrix_t matrix;

      gtk_render_content_path (context, cr, 0, 0, width, height);

      if (swatch->priv->use_alpha)
        {
          cairo_save (cr);

          cairo_clip_preserve (cr);

          cairo_set_source_rgb (cr, 0.33, 0.33, 0.33);
          cairo_fill_preserve (cr);

          pattern = _gtk_color_chooser_get_checkered_pattern ();
          cairo_matrix_init_scale (&matrix, 0.125, 0.125);
          cairo_pattern_set_matrix (pattern, &matrix);

          cairo_set_source_rgb (cr, 0.66, 0.66, 0.66);
          cairo_mask (cr, pattern);
          cairo_pattern_destroy (pattern);

          cairo_restore (cr);

          gdk_cairo_set_source_rgba (cr, &swatch->priv->color);
        }
      else
        {
          cairo_set_source_rgb (cr,
                                swatch->priv->color.red,
                                swatch->priv->color.green,
                                swatch->priv->color.blue);
        }

      cairo_fill (cr);
    }

  gtk_render_frame (context, cr, 0, 0, width, height);

  if (swatch->priv->icon)
    {
      icon_info = gtk_icon_theme_lookup_icon (theme, swatch->priv->icon, PIXBUF_SIZE,
                                              GTK_ICON_LOOKUP_GENERIC_FALLBACK
                                              | GTK_ICON_LOOKUP_USE_BUILTIN);
    }
  else if ((state & GTK_STATE_FLAG_SELECTED) != 0)
    {
      GIcon *gicon;

      gicon = g_themed_icon_new ("object-select-symbolic");
      /* fallback for themes that don't have object-select-symbolic */
      g_themed_icon_append_name (G_THEMED_ICON (gicon), "gtk-apply");

      icon_info = gtk_icon_theme_lookup_by_gicon (theme, gicon, PIXBUF_SIZE,
                                                  GTK_ICON_LOOKUP_GENERIC_FALLBACK
                                                  | GTK_ICON_LOOKUP_USE_BUILTIN);
      g_object_unref (gicon);
    }

  /* now draw the overlay image */
  gtk_style_context_get_border (context, state, &border);
  gtk_style_context_get_padding (context, state, &padding);
  rect.width = width - (border.left + border.right + padding.left + padding.right);
  rect.height = height - (border.top + border.bottom + padding.top + padding.bottom);
  rect.x = border.left + padding.left;
  rect.y = border.top + padding.top;

  gtk_style_context_save (context);
  gtk_style_context_add_class (context, "overlay");
  
  gtk_render_background (context, cr, rect.x, rect.y, rect.width, rect.height);
  gtk_render_frame (context, cr, rect.x, rect.y, rect.width, rect.height);

  if (icon_info != NULL)
    {
      GdkPixbuf *pixbuf;

      pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, context,
                                                        NULL, NULL);

      if (pixbuf != NULL)
        {
          gtk_render_icon (context, cr, pixbuf,
                           rect.x + (rect.width - gdk_pixbuf_get_width (pixbuf)) / 2,
                           rect.y + (rect.height - gdk_pixbuf_get_height (pixbuf)) / 2);
          g_object_unref (pixbuf);
        }

      g_object_unref (icon_info);
    }

  if (gtk_widget_has_visible_focus (widget))
    {
      gtk_render_focus (context, cr, 0, 0, width, height);
    }

  gtk_style_context_restore (context);

  return FALSE;
}
Exemple #13
0
static void
gtk_level_bar_draw_fill_discrete (GtkLevelBar           *self,
                                  cairo_t               *cr,
                                  cairo_rectangle_int_t *fill_area)
{
  GtkWidget *widget = GTK_WIDGET (self);
  GtkStyleContext *context;
  gint num_blocks, i;
  gint block_width, block_height;
  gint block_draw_width, block_draw_height;
  GtkBorder block_margin;
  cairo_rectangle_int_t block_area;

  context = gtk_widget_get_style_context (widget);
  gtk_level_bar_get_min_block_size (self, &block_width, &block_height);

  block_area = *fill_area;
  num_blocks = (gint) round (self->priv->max_value) - (gint) round (self->priv->min_value);

  if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
    block_width = MAX (block_width, (gint) floor (block_area.width / num_blocks));
  else
    block_height = MAX (block_height, (gint) floor (block_area.height / num_blocks));

  gtk_style_context_save_to_node (context, self->priv->block_node[0]);
  gtk_style_context_get_margin (context, gtk_style_context_get_state (context), &block_margin);
  gtk_style_context_restore (context);

  block_draw_width = block_width - block_margin.left - block_margin.right;
  block_draw_height = block_height - block_margin.top - block_margin.bottom;

  if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
    {
      block_draw_height = MAX (block_draw_height, block_area.height - block_margin.top - block_margin.bottom);
      block_area.y += block_margin.top;
    }
  else
    {
      block_draw_width = MAX (block_draw_width, block_area.width - block_margin.left - block_margin.right);
      block_area.x += block_margin.left;
    }

  for (i = 0; i < num_blocks; i++)
    {
      if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
        block_area.x += block_margin.left;
      else
        block_area.y += block_margin.top;

      gtk_style_context_save_to_node (context, self->priv->block_node[i]);

      gtk_render_background (context, cr,
                             block_area.x, block_area.y,
                             block_draw_width, block_draw_height);
      gtk_render_frame (context, cr,
                        block_area.x, block_area.y,
                        block_draw_width, block_draw_height);

      gtk_style_context_restore (context);

      if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
        block_area.x += block_draw_width + block_margin.right;
      else
        block_area.y += block_draw_height + block_margin.bottom;
    }
}
Exemple #14
0
static void
gtk_level_bar_draw_fill_continuous (GtkLevelBar           *self,
                                    cairo_t               *cr,
                                    cairo_rectangle_int_t *fill_area)
{
  GtkWidget *widget = GTK_WIDGET (self);
  GtkStyleContext *context;
  cairo_rectangle_int_t base_area, block_area;
  GtkBorder block_margin;
  gdouble fill_percentage;
  gboolean inverted;

  inverted = self->priv->inverted;
  if (gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL)
    {
      if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
        inverted = !inverted;
    }

  context = gtk_widget_get_style_context (widget);

  /* render the empty (unfilled) part */
  gtk_style_context_save_to_node (context, self->priv->block_node[inverted ? 0 : 1]);
  gtk_style_context_get_margin (context, gtk_style_context_get_state (context), &block_margin);

  base_area = *fill_area;
  base_area.x += block_margin.left;
  base_area.y += block_margin.top;
  base_area.width -= block_margin.left + block_margin.right;
  base_area.height -= block_margin.top + block_margin.bottom;

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

  gtk_style_context_restore (context);

  /* now render the filled part on top of it */

  block_area = base_area;

  fill_percentage = (self->priv->cur_value - self->priv->min_value) /
    (self->priv->max_value - self->priv->min_value);

  if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
    {
      block_area.width = (gint) floor (block_area.width * fill_percentage);

      if (inverted)
        block_area.x += base_area.width - block_area.width;
    }
  else
    {
      block_area.height = (gint) floor (block_area.height * fill_percentage);

      if (inverted)
        block_area.y += base_area.height - block_area.height;
    }

  gtk_style_context_save_to_node (context, self->priv->block_node[inverted ? 1 : 0]);

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

  gtk_style_context_restore (context);
}
static gboolean _togglebutton_draw(GtkWidget *widget, cairo_t *cr)
{
  g_return_val_if_fail(widget != NULL, FALSE);
  g_return_val_if_fail(DTGTK_IS_TOGGLEBUTTON(widget), FALSE);

  GtkDarktableToggleButton *button = DTGTK_TOGGLEBUTTON(widget);

  GtkStateFlags state = gtk_widget_get_state_flags(widget);

  GdkRGBA bg_color, fg_color;
  GtkStyleContext *context = gtk_widget_get_style_context(widget);
  if(button->icon_flags & CPF_CUSTOM_BG)
    bg_color = button->bg;
  else
    gtk_style_context_get_background_color(context, state, &bg_color);
  if(button->icon_flags & CPF_CUSTOM_FG)
    fg_color = button->fg;
  else
    gtk_style_context_get_color(context, state, &fg_color);

  /* fetch flags */
  int flags = DTGTK_TOGGLEBUTTON(widget)->icon_flags;

  /* set inner border */
  int border = DT_PIXEL_APPLY_DPI((flags & CPF_DO_NOT_USE_BORDER) ? 2 : 6);

  /* update active state paint flag */
  gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
  if(active)
    flags |= CPF_ACTIVE;
  else
    flags &= ~(CPF_ACTIVE);

  /* prelight */
  if(state & GTK_STATE_FLAG_PRELIGHT)
    flags |= CPF_PRELIGHT;
  else
    flags &= ~CPF_PRELIGHT;

  /* begin cairo drawing */
  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  int width = allocation.width;
  int height = allocation.height;

  /* draw standard button background if not transparent nor flat styled */
  if((flags & CPF_STYLE_FLAT))
  {
    if(flags & CPF_PRELIGHT || flags & CPF_ACTIVE)
    {
      cairo_rectangle(cr, 0, 0, width, height);
      gdk_cairo_set_source_rgba(cr, &bg_color);
      cairo_fill(cr);
    }
  }
  else if(!(flags & CPF_BG_TRANSPARENT))
  {
    /* draw default boxed button */
    gtk_render_background(context, cr, 0, 0, width, height);
    if(!(flags & CPF_DO_NOT_USE_BORDER))
      gtk_render_frame(context, cr, 0, 0, width, height);
  }


  /* create pango text settings if label exists */
  PangoLayout *layout = NULL;
  int pw = 0, ph = 0;
  const gchar *text = gtk_button_get_label(GTK_BUTTON(widget));
  if(text)
  {
    layout = pango_cairo_create_layout(cr);
    pango_layout_set_font_description(layout, darktable.bauhaus->pango_font_desc);
    pango_cairo_context_set_resolution(pango_layout_get_context(layout), darktable.gui->dpi);
    pango_layout_set_text(layout, text, -1);
    pango_layout_get_pixel_size(layout, &pw, &ph);
  }

  gdk_cairo_set_source_rgba(cr, &fg_color);

  /* draw icon */
  if(DTGTK_TOGGLEBUTTON(widget)->icon)
  {
    //     if (flags & CPF_IGNORE_FG_STATE)
    //       state = GTK_STATE_NORMAL;

    int icon_width = text ? height - (border * 2) : width - (border * 2);
    int icon_height = height - (border * 2);

    if(icon_width > 0 && icon_height > 0)
    {
      if(text)
        DTGTK_TOGGLEBUTTON(widget)
            ->icon(cr, border, border, height - (border * 2), height - (border * 2), flags);
      else
        DTGTK_TOGGLEBUTTON(widget)
            ->icon(cr, border, border, width - (border * 2), height - (border * 2), flags);
    }
  }


  /* draw label */
  if(text)
  {
    int lx = DT_PIXEL_APPLY_DPI(2), ly = ((height / 2.0) - (ph / 2.0));
    // if (DTGTK_TOGGLEBUTTON (widget)->icon) lx += width;
    // GdkRectangle t={x,y,x+width,y+height};
    // gtk_paint_layout(style,gtk_widget_get_window(widget),
    // state,TRUE,&t,widget,"togglebutton",lx,ly,layout);
    cairo_translate(cr, lx, ly);
    pango_cairo_show_layout(cr, layout);
    g_object_unref(layout);
  }

  return FALSE;
}
Exemple #16
0
/**
 * gd_create_collection_icon:
 * @base_size:
 * @pixbufs: (element-type GdkPixbuf):
 *
 * Returns: (transfer full):
 */
GIcon *
gd_create_collection_icon (gint base_size,
                           GList *pixbufs)
{
  cairo_surface_t *surface;
  GIcon *retval;
  cairo_t *cr;
  GtkStyleContext *context;
  GtkWidgetPath *path;
  GtkBorder tile_border;
  gint padding, tile_size;
  gint idx, cur_x, cur_y;
  GList *l;

  context = gtk_style_context_new ();
  gtk_style_context_add_class (context, "documents-collection-icon");

  path = gtk_widget_path_new ();
  gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);
  gtk_style_context_set_path (context, path);
  gtk_widget_path_unref (path);

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, base_size, base_size);
  cr = cairo_create (surface);

  /* Render the thumbnail itself */
  gtk_render_background (context, cr,
                         0, 0, base_size, base_size);
  gtk_render_frame (context, cr,
                    0, 0, base_size, base_size);

  /* Now, render the tiles inside */
  gtk_style_context_remove_class (context, "documents-collection-icon");
  gtk_style_context_add_class (context, "documents-collection-icon-tile");

  /* TODO: do not hardcode 4, but scale to another layout if more
   * pixbufs are provided.
   */
  padding = MAX (floor (base_size / 10), 4);
  gtk_style_context_get_border (context, GTK_STATE_FLAG_NORMAL, &tile_border);
  tile_size = (base_size - (3 * padding)) / 2 -
    MAX (tile_border.left + tile_border.right, tile_border.top + tile_border.bottom);

  l = pixbufs;
  idx = 0;
  cur_x = padding;
  cur_y = padding;

  while (l != NULL && idx < 4)
    {
      GdkPixbuf *pix;
      gboolean is_thumbnail;
      gint pix_width, pix_height, scale_size;

      pix = l->data;
      is_thumbnail = (gdk_pixbuf_get_option (pix, "-documents-has-thumb") != NULL);

      /* Only draw a box for thumbnails */
      if (is_thumbnail)
        {
          gtk_render_background (context, cr,
                                 cur_x, cur_y,
                                 tile_size + tile_border.left + tile_border.right,
                                 tile_size + tile_border.top + tile_border.bottom);
          gtk_render_frame (context, cr,
                            cur_x, cur_y,
                            tile_size + tile_border.left + tile_border.right,
                            tile_size + tile_border.top + tile_border.bottom);
        }

      pix_width = gdk_pixbuf_get_width (pix);
      pix_height = gdk_pixbuf_get_height (pix);
      scale_size = MIN (pix_width, pix_height);

      cairo_save (cr);

      cairo_translate (cr, cur_x + tile_border.left, cur_y + tile_border.top);
      cairo_rectangle (cr, 0, 0, tile_size, tile_size);
      cairo_clip (cr);

      cairo_scale (cr, (gdouble) tile_size / (gdouble) scale_size, (gdouble) tile_size / (gdouble) scale_size);
      gdk_cairo_set_source_pixbuf (cr, pix, 0, 0);
      cairo_paint (cr);

      cairo_restore (cr);

      if ((idx % 2) == 0)
        {
          cur_x += tile_size + padding + tile_border.left + tile_border.right;
        }
      else
        {
          cur_x = padding;
          cur_y += tile_size + padding + tile_border.top + tile_border.bottom;
        }

      idx++;
      l = l->next;
    }

  retval = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, base_size, base_size));

  cairo_surface_destroy (surface);
  cairo_destroy (cr);
  g_object_unref (context);

  return retval;
}
Exemple #17
0
static gboolean
gtk_tearoff_menu_item_draw (GtkWidget *widget,
                            cairo_t   *cr)
{
    GtkMenuItem *menu_item;
    GtkStateFlags state;
    GtkStyleContext *context;
    GtkBorder padding;
    gint x, y, width, height;
    gint right_max;
    guint border_width;
    GtkTextDirection direction;
    GtkWidget *parent;
    gdouble angle;

    menu_item = GTK_MENU_ITEM (widget);
    context = gtk_widget_get_style_context (widget);
    direction = gtk_widget_get_direction (widget);
    state = gtk_widget_get_state_flags (widget);

    border_width = gtk_container_get_border_width (GTK_CONTAINER (menu_item));
    x = border_width;
    y = border_width;
    width = gtk_widget_get_allocated_width (widget) - border_width * 2;
    height = gtk_widget_get_allocated_height (widget) - border_width * 2;
    right_max = x + width;

    gtk_style_context_save (context);
    gtk_style_context_set_state (context, state);
    gtk_style_context_get_padding (context, state, &padding);

    if (state & GTK_STATE_FLAG_PRELIGHT)
    {
        gtk_render_background (context, cr, x, y, width, height);
        gtk_render_frame (context, cr, x, y, width, height);
    }

    parent = gtk_widget_get_parent (widget);
    if (GTK_IS_MENU (parent) && gtk_menu_get_tearoff_state (GTK_MENU (parent)))
    {
        gint arrow_x;

        if (menu_item->priv->toggle_size > ARROW_SIZE)
        {
            if (direction == GTK_TEXT_DIR_LTR)
            {
                arrow_x = x + (menu_item->priv->toggle_size - ARROW_SIZE)/2;
                angle = (3 * G_PI) / 2;
            }
            else
            {
                arrow_x = x + width - menu_item->priv->toggle_size + (menu_item->priv->toggle_size - ARROW_SIZE)/2;
                angle = G_PI / 2;
            }
            x += menu_item->priv->toggle_size + BORDER_SPACING;
        }
        else
        {
            if (direction == GTK_TEXT_DIR_LTR)
            {
                arrow_x = ARROW_SIZE / 2;
                angle = (3 * G_PI) / 2;
            }
            else
            {
                arrow_x = x + width - 2 * ARROW_SIZE + ARROW_SIZE / 2;
                angle = G_PI / 2;
            }
            x += 2 * ARROW_SIZE;
        }

        gtk_render_arrow (context, cr, angle,
                          arrow_x, height / 2 - 5,
                          ARROW_SIZE);
    }

    while (x < right_max)
    {
        gint x1, x2;

        if (direction == GTK_TEXT_DIR_LTR)
        {
            x1 = x;
            x2 = MIN (x + TEAR_LENGTH, right_max);
        }
        else
        {
            x1 = right_max - x;
            x2 = MAX (right_max - x - TEAR_LENGTH, 0);
        }

        gtk_render_line (context, cr,
                         x1, y + (height - padding.bottom) / 2,
                         x2, y + (height - padding.bottom) / 2);
        x += 2 * TEAR_LENGTH;
    }

    gtk_style_context_restore (context);

    return FALSE;
}
Exemple #18
0
static gboolean
sushi_font_widget_draw (GtkWidget *drawing_area,
                        cairo_t *cr)
{
  SushiFontWidget *self = SUSHI_FONT_WIDGET (drawing_area);
  SushiFontWidgetPrivate *priv = self->priv;
  gint *sizes = NULL, n_sizes, alpha_size, title_size, pos_y = 0, i;
  cairo_font_face_t *font;
  FT_Face face = priv->face;
  GtkStyleContext *context;
  GdkRGBA color;
  GtkBorder padding;
  GtkStateFlags state;
  gint allocated_width, allocated_height;

  if (face == NULL)
    goto end;

  context = gtk_widget_get_style_context (drawing_area);
  state = gtk_style_context_get_state (context);

  allocated_width = gtk_widget_get_allocated_width (drawing_area);
  allocated_height = gtk_widget_get_allocated_height (drawing_area);

  gtk_render_background (context, cr,
                         0, 0, allocated_width, allocated_height);

  gtk_style_context_get_color (context, state, &color);
  gtk_style_context_get_padding (context, state, &padding);

  gdk_cairo_set_source_rgba (cr, &color);

  sizes = build_sizes_table (face, &n_sizes, &alpha_size, &title_size);

  font = cairo_ft_font_face_create_for_ft_face (face, 0);
  cairo_set_font_face (cr, font);
  cairo_font_face_destroy (font);

  /* draw text */

  if (self->priv->font_name != NULL) {
    cairo_set_font_size (cr, title_size);
    draw_string (self, cr, padding, self->priv->font_name, &pos_y);
  }

  if (pos_y > allocated_height)
    goto end;

  pos_y += SECTION_SPACING / 2;
  cairo_set_font_size (cr, alpha_size);

  if (self->priv->lowercase_text != NULL)
    draw_string (self, cr, padding, self->priv->lowercase_text, &pos_y);
  if (pos_y > allocated_height)
    goto end;

  if (self->priv->uppercase_text != NULL)
    draw_string (self, cr, padding, self->priv->uppercase_text, &pos_y);
  if (pos_y > allocated_height)
    goto end;

  if (self->priv->punctuation_text != NULL)
    draw_string (self, cr, padding, self->priv->punctuation_text, &pos_y);
  if (pos_y > allocated_height)
    goto end;

  pos_y += SECTION_SPACING;

  for (i = 0; i < n_sizes; i++) {
    cairo_set_font_size (cr, sizes[i]);
    if (self->priv->sample_string !=  NULL)
      draw_string (self, cr, padding, self->priv->sample_string, &pos_y);
    if (pos_y > allocated_height)
      break;
  }

 end:
  g_free (sizes);

  return FALSE;
}
Exemple #19
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;
}
Exemple #20
0
GIcon *
photos_utils_create_symbolic_icon_for_scale (const gchar *name, gint base_size, gint scale)
{
  g_autoptr (GIcon) icon = NULL;
  GIcon *ret_val = NULL;
  g_autoptr (GdkPixbuf) pixbuf = NULL;
  g_autoptr (GtkIconInfo) info = NULL;
  GtkIconTheme *theme;
  g_autoptr (GtkStyleContext) style = NULL;
  g_autoptr (GtkWidgetPath) path = NULL;
  cairo_surface_t *icon_surface = NULL; /* TODO: use g_autoptr */
  cairo_surface_t *surface; /* TODO: use g_autoptr */
  cairo_t *cr; /* TODO: use g_autoptr */
  g_autofree gchar *symbolic_name = NULL;
  const gint bg_size = 24;
  const gint emblem_margin = 4;
  gint emblem_pos;
  gint emblem_size;
  gint total_size;
  gint total_size_scaled;

  total_size = base_size / 2;
  total_size_scaled = total_size * scale;
  emblem_size = bg_size - emblem_margin * 2;

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, total_size_scaled, total_size_scaled);
  cairo_surface_set_device_scale (surface, (gdouble) scale, (gdouble) scale);
  cr = cairo_create (surface);

  style = gtk_style_context_new ();

  path = gtk_widget_path_new ();
  gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);
  gtk_style_context_set_path (style, path);

  gtk_style_context_add_class (style, "photos-icon-bg");

  gtk_render_background (style, cr, total_size - bg_size, total_size - bg_size, bg_size, bg_size);

  symbolic_name = g_strconcat (name, "-symbolic", NULL);
  icon = g_themed_icon_new_with_default_fallbacks (symbolic_name);

  theme = gtk_icon_theme_get_default();
  info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, icon, emblem_size, scale, GTK_ICON_LOOKUP_FORCE_SIZE);
  if (info == NULL)
    goto out;

  pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL);
  if (pixbuf == NULL)
    goto out;

  icon_surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL);

  emblem_pos = total_size - emblem_size - emblem_margin;
  gtk_render_icon_surface (style, cr, icon_surface, emblem_pos, emblem_pos);

  ret_val = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, total_size_scaled, total_size_scaled));

 out:
  cairo_surface_destroy (icon_surface);
  cairo_surface_destroy (surface);
  cairo_destroy (cr);

  return ret_val;
}
static gboolean budgie_popover_draw(GtkWidget *widget,
                                    cairo_t *cr,
                                    gboolean draw)
{
        BudgiePopover *self = BUDGIE_POPOVER(widget);
        GtkStyleContext *style;
        GtkAllocation alloc;
        GtkPositionType gap_side;
        GdkRGBA color;
        gdouble x, y, tail_height, gap_width;
        gdouble margin, width, height, gap1, gap2;

        x = 0;
        y = 0;
        tail_height = 12;
        gap_width = 24;
        margin = 11;

        x += margin;
        y += margin;

        style = gtk_widget_get_style_context(widget);
        gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME);

        gtk_widget_get_allocation(widget, &alloc);
        /* Have parent class do drawing, so we gain shadows */
        ((GtkWidgetClass*)budgie_popover_parent_class)->draw(widget, cr);

        /* Remove height of tail, and margin, from our rendered size */
        width = alloc.width;
        height = alloc.height - tail_height;
        height -= margin;
        width -= margin*2;

        cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
        gap1 = (alloc.width/2)-(gap_width/2);
        gap1 = self->widg_x;
        gap2 = gap1 + gap_width;
        gap2 -= margin;
        gap_side = self->top == TRUE ? GTK_POS_TOP : GTK_POS_BOTTOM;

        /* Render a gap in the bottom center for our arrow */
        gtk_render_frame_gap(style, cr, x, y, width, height,
                gap_side, gap1, gap2);
        /* Fill in the background (pre-clip) */
        gtk_render_background(style, cr, x, y, width, height);

        /* Clip to the tail, fill in the arrow background */
        cairo_save(cr);
        if (self->top)
                budgie_tail_path(cr, gap1, gap_width, y-margin, tail_height, self->top);
        else
                budgie_tail_path(cr, gap1, gap_width, height+margin, tail_height, self->top);
        cairo_clip(cr);
        if (self->top)
                gtk_render_background(style, cr, x, y-tail_height, alloc.width, alloc.height);
        else
                gtk_render_background(style, cr, x, y, alloc.width, alloc.height);
        cairo_restore(cr);

        /* Draw in the border */
        gtk_style_context_get_border_color(style, gtk_widget_get_state_flags(widget), &color);
        gdk_cairo_set_source_rgba(cr, &color);
        cairo_set_line_width(cr, 1);
        if (self->top)
                budgie_tail_path(cr, gap1, gap_width, y-margin, tail_height, self->top);
        else
                budgie_tail_path(cr, gap1, gap_width, height+margin, tail_height, self->top);
        cairo_stroke(cr);

        /* Draw children */
        gtk_container_propagate_draw(GTK_CONTAINER(widget),
                gtk_bin_get_child(GTK_BIN(widget)),
                cr);

        return TRUE;
}
Exemple #22
0
static gboolean
gtk_bubble_window_draw (GtkWidget *widget,
                        cairo_t   *cr)
{
  GtkStyleContext *context;
  GtkAllocation allocation;
  GtkWidget *child;
  GtkBorder border;
  GdkRGBA border_color;
  gint rect_x1, rect_x2, rect_y1, rect_y2;
  gint initial_x, initial_y, final_x, final_y;
  gint gap_start, gap_end;
  GtkPositionType gap_side;
  GtkStateFlags state;

  context = gtk_widget_get_style_context (widget);
  state = gtk_widget_get_state_flags (widget);
  gtk_widget_get_allocation (widget, &allocation);

  if (gtk_widget_is_composited (widget))
    {
      cairo_save (cr);
      cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
      cairo_set_source_rgba (cr, 0, 0, 0, 0);
      cairo_paint (cr);
      cairo_restore (cr);
    }

  gtk_bubble_window_get_rect_coords (GTK_BUBBLE_WINDOW (widget),
                                     &rect_x1, &rect_y1,
                                     &rect_x2, &rect_y2);

  /* Render the rect background */
  gtk_render_background (context, cr,
                         rect_x1, rect_y1,
                         rect_x2 - rect_x1, rect_y2 - rect_y1);

  gtk_bubble_window_get_gap_coords (GTK_BUBBLE_WINDOW (widget),
                                    &initial_x, &initial_y,
                                    NULL, NULL,
                                    &final_x, &final_y,
                                    &gap_side);

  if (POS_IS_VERTICAL (gap_side))
    {
      gap_start = initial_x;
      gap_end = final_x;
    }
  else
    {
      gap_start = initial_y;
      gap_end = final_y;
    }

  /* Now render the frame, without the gap for the arrow tip */
  gtk_render_frame_gap (context, cr,
                        rect_x1, rect_y1,
                        rect_x2 - rect_x1, rect_y2 - rect_y1,
                        gap_side,
                        gap_start, gap_end);

  /* Clip to the arrow shape */
  cairo_save (cr);

  gtk_bubble_window_apply_tail_path (GTK_BUBBLE_WINDOW (widget), cr);
  cairo_clip (cr);

  /* Render the arrow background */
  gtk_render_background (context, cr,
                         0, 0,
                         allocation.width, allocation.height);

  /* Render the border of the arrow tip */
  gtk_style_context_get_border (context, state, &border);

  if (border.bottom > 0)
    {
      gtk_style_context_get_border_color (context, state, &border_color);
      gtk_bubble_window_apply_tail_path (GTK_BUBBLE_WINDOW (widget), cr);
      gdk_cairo_set_source_rgba (cr, &border_color);

      cairo_set_line_width (cr, border.bottom);
      cairo_stroke (cr);
    }

  /* We're done */
  cairo_restore (cr);

  child = gtk_bin_get_child (GTK_BIN (widget));

  if (child)
    gtk_container_propagate_draw (GTK_CONTAINER (widget), child, cr);

  return TRUE;
}
Exemple #23
0
static void
draw_month_grid (GcalYearView *year_view,
                 GtkWidget    *widget,
                 cairo_t      *cr,
                 gint          month_nr,
                 gint         *weeks_counter)
{
  GcalYearViewPrivate *priv = year_view->priv;

  GtkStyleContext *context;
  GtkStateFlags state_flags;

  PangoLayout *layout, *slayout;
  PangoFontDescription *font_desc, *sfont_desc;

  GdkRGBA color;
  gint layout_width, layout_height, i, j, sw;
  gint x, y, column, row, box_side, box_padding_top, box_padding_start;
  gint days_delay, days, shown_rows, sunday_idx;
  gchar *str, *nr_day, *nr_week;
  gboolean selected_day;

  cairo_save (cr);
  context = gtk_widget_get_style_context (widget);
  state_flags = gtk_widget_get_state_flags (widget);
  sw = 1 - 2 * priv->k;
  box_side = priv->navigator_grid->box_side;
  x = priv->navigator_grid->coordinates[month_nr].x;
  y = priv->navigator_grid->coordinates[month_nr].y;

  gtk_style_context_get (context, state_flags | GTK_STATE_FLAG_SELECTED, "font", &sfont_desc, NULL);
  slayout = gtk_widget_create_pango_layout (widget, NULL);
  pango_layout_set_font_description (slayout, sfont_desc);

  /* header */
  gtk_style_context_save (context);
  gtk_style_context_add_class (context, "header");

  str = g_strdup (gcal_get_month_name (month_nr));
  gtk_style_context_get (context, state_flags, "font", &font_desc, NULL);

  layout = gtk_widget_create_pango_layout (widget, str);
  pango_layout_set_font_description (layout, font_desc);
  pango_layout_get_pixel_size (layout, &layout_width, &layout_height);
  gtk_render_layout (context, cr, x + (box_side * 8 - layout_width) / 2, y + (box_side - layout_height) / 2,
                     layout);

  gtk_render_background (context, cr,
                         x + (box_side * 8 - layout_width) / 2, y + (box_side - layout_height) / 2,
                         layout_width, layout_width);

  pango_font_description_free (font_desc);
  g_free (str);
  gtk_style_context_restore (context);

  /* separator line */
  gtk_style_context_save (context);
  gtk_style_context_add_class (context, "lines");

  gtk_style_context_get_color (context, state_flags, &color);
  cairo_set_line_width (cr, 0.2);
  gdk_cairo_set_source_rgba (cr, &color);
  cairo_move_to (cr, x + box_side / 2, y + box_side + 0.4);
  cairo_rel_line_to (cr, 7 * box_side, 0);
  cairo_stroke (cr);

  gtk_style_context_restore (context);

  /* days */
  gtk_style_context_save (context);
  gtk_style_context_add_class (context, "days");

  gtk_style_context_get (context, state_flags, "font", &font_desc, NULL);
  pango_layout_set_font_description (layout, font_desc);

  days_delay = (time_day_of_week (1, month_nr, priv->date->year) - priv->first_weekday + 7) % 7;
  days = days_delay + icaltime_days_in_month (month_nr + 1, priv->date->year);
  shown_rows = ceil (days / 7.0);
  sunday_idx = priv->k * 6 + sw * ((7 - priv->first_weekday) % 7);

  for (i = 0; i < 7 * shown_rows; i++)
    {
      column = i % 7;
      row = i / 7;

      j = 7 * ((i + 7 * priv->k) / 7) + sw * (i % 7) + (1 - priv->k);
      if (j <= days_delay)
        continue;
      else if (j > days)
        continue;
      j -= days_delay;

      nr_day = g_strdup_printf ("%d", j);
      pango_layout_set_text (layout, nr_day, -1);
      pango_layout_get_pixel_size (layout, &layout_width, &layout_height);
      box_padding_top = (box_side - layout_height) / 2 > 0 ? (box_side - layout_height) / 2 : 0;
      box_padding_start = (box_side - layout_width) / 2 > 0 ? (box_side - layout_width) / 2 : 0;

      selected_day = FALSE;
      if (priv->selected_data->start_day != 0)
        {
          ButtonData selected_data = *(priv->selected_data);
          order_selected_data (&selected_data);
          if (month_nr > selected_data.start_month && month_nr < selected_data.end_month)
            {
              selected_day = TRUE;
            }
          else if (month_nr == selected_data.start_month && month_nr == selected_data.end_month)
            {
              selected_day = j >= selected_data.start_day && j <= selected_data.end_day;
            }
          else if (month_nr == selected_data.start_month && j >= selected_data.start_day)
            {
              selected_day = TRUE;
            }
          else if (month_nr == selected_data.end_month && j <= selected_data.end_day)
            {
              selected_day = TRUE;
            }
        }

      if (priv->date->year == priv->current_date->year && month_nr + 1 == priv->current_date->month &&
          j == priv->current_date->day)
        {
          PangoLayout *clayout;
          PangoFontDescription *cfont_desc;

          gtk_style_context_save (context);
          gtk_style_context_add_class (context, "current");

          clayout = gtk_widget_create_pango_layout (widget, nr_day);
          gtk_style_context_get (context, state_flags, "font", &cfont_desc, NULL);
          pango_layout_set_font_description (clayout, cfont_desc);
          pango_layout_get_pixel_size (clayout, &layout_width, &layout_height);
          box_padding_top = (box_side - layout_height) / 2 > 0 ? (box_side - layout_height) / 2 : 0;
          box_padding_start = (box_side - layout_width) / 2 > 0 ? (box_side - layout_width) / 2 : 0;

          /* FIXME: hardcoded padding of the number background */
          gtk_render_background (context, cr,
                                 box_side * (column + 0.5 + priv->k) + x + sw * box_padding_start - priv->k * layout_width - 2.0,
                                 box_side * (row + 1) + y + box_padding_top - 1.0,
                                 layout_width + 4.0, layout_height + 2.0);
          gtk_render_layout (context, cr,
                             box_side * (column + 0.5 + priv->k) + x + sw * box_padding_start - priv->k * layout_width,
                             box_side * (row + 1) + y + box_padding_top,
                             clayout);

          gtk_style_context_restore (context);
          pango_font_description_free (cfont_desc);
          g_object_unref (clayout);
        }
      else if (selected_day)
        {
          gtk_style_context_set_state (context, state_flags | GTK_STATE_FLAG_SELECTED);

          pango_layout_set_text (slayout, nr_day, -1);
          pango_layout_get_pixel_size (slayout, &layout_width, &layout_height);
          box_padding_top = (box_side - layout_height) / 2 > 0 ? (box_side - layout_height) / 2 : 0;
          box_padding_start = (box_side - layout_width) / 2 > 0 ? (box_side - layout_width) / 2 : 0;

          gtk_render_layout (context, cr,
                             box_side * (column + 0.5 + priv->k) + x + sw * box_padding_start - priv->k * layout_width,
                             box_side * (row + 1) + y + box_padding_top,
                             slayout);

          gtk_style_context_set_state (context, state_flags);
        }
      else if (column == sunday_idx)
        {
          gtk_style_context_save (context);
          gtk_style_context_add_class (context, "sunday");
          gtk_render_layout (context, cr,
                             box_side * (column + 0.5 + priv->k) + x + sw * box_padding_start - priv->k * layout_width,
                             box_side * (row + 1) + y + box_padding_top,
                             layout);
          gtk_style_context_restore (context);
        }
      else
        {
          gtk_render_layout (context, cr,
                             box_side * (column + 0.5 + priv->k) + x + sw * box_padding_start - priv->k * layout_width,
                             box_side * (row + 1) + y + box_padding_top,
                             layout);
        }

      g_free (nr_day);
    }
  pango_font_description_free (font_desc);
  gtk_style_context_restore (context);

  /* week numbers */
  gtk_style_context_save (context);
  gtk_style_context_add_class (context, "week-numbers");

  gtk_style_context_get (context, state_flags, "font", &font_desc, NULL);
  pango_layout_set_font_description (layout, font_desc);

  for (i = 0; i < shown_rows; i++)
    {
      if (i == 0)
        {
          if (days_delay == 0)
            *weeks_counter = *weeks_counter + 1;
        }
      else
        *weeks_counter = *weeks_counter + 1;

      nr_week = g_strdup_printf ("%d", *weeks_counter);

      pango_layout_set_text (layout, nr_week, -1);
      pango_layout_get_pixel_size (layout, &layout_width, &layout_height);
      box_padding_top = (box_side - layout_height) / 2 > 0 ? (box_side - layout_height) / 2 : 0;
      box_padding_start = ((box_side / 2) - layout_width) / 2 > 0 ? ((box_side / 2) - layout_width) / 2 : 0;

      gtk_render_layout (context, cr,
                         x + sw * box_padding_start + priv->k * (8 * box_side - layout_width),
                         box_side * (i + 1) + y + box_padding_top,
                         layout);

      g_free (nr_week);
    }
  gtk_style_context_restore (context);

  pango_font_description_free (sfont_desc);
  g_object_unref (slayout);

  pango_font_description_free (font_desc);
  g_object_unref (layout);
  cairo_restore (cr);
}
Exemple #24
0
static gboolean _lib_histogram_draw_callback(GtkWidget *widget, cairo_t *crf, gpointer user_data)
{
  dt_lib_module_t *self = (dt_lib_module_t *)user_data;
  dt_lib_histogram_t *d = (dt_lib_histogram_t *)self->data;

  dt_develop_t *dev = darktable.develop;
  uint32_t *hist = dev->histogram;
  float hist_max = dev->histogram_type == DT_DEV_HISTOGRAM_LINEAR ? dev->histogram_max
                                                                  : logf(1.0 + dev->histogram_max);
  const int inset = DT_HIST_INSET;
  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  int width = allocation.width, height = allocation.height;
  cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  cairo_t *cr = cairo_create(cst);

  gtk_render_background(gtk_widget_get_style_context(widget), cr, 0, 0, allocation.width, allocation.height);

  cairo_translate(cr, 4 * inset, inset);
  width -= 2 * 4 * inset;
  height -= 2 * inset;

  if(d->mode_x == 0)
  {
    d->color_w = 0.06 * width;
    d->button_spacing = 0.01 * width;
    d->button_h = 0.06 * width;
    d->button_y = d->button_spacing;
    d->mode_w = d->color_w;
    d->mode_x = width - 3 * (d->color_w + d->button_spacing) - (d->mode_w + d->button_spacing);
    d->red_x = width - 3 * (d->color_w + d->button_spacing);
    d->green_x = width - 2 * (d->color_w + d->button_spacing);
    d->blue_x = width - (d->color_w + d->button_spacing);
  }

  // TODO: probably this should move to the configure-event callback! That would be future proof if we ever
  // (again) allow to resize the side panels.
  const gint stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);

  // this code assumes that the first expose comes before the first (preview) pipe is processed and that the
  // size of the widget doesn't change!
  if(dev->histogram_waveform_width == 0)
  {
    dev->histogram_waveform = (uint32_t *)calloc(height * stride / 4, sizeof(uint32_t));
    dev->histogram_waveform_stride = stride;
    dev->histogram_waveform_height = height;
    dev->histogram_waveform_width = width;
    //     return TRUE; // there are enough expose events following ...
  }

#if 1
  // draw shadow around
  float alpha = 1.0f;
  cairo_set_line_width(cr, 0.2);
  for(int k = 0; k < inset; k++)
  {
    cairo_rectangle(cr, -k, -k, width + 2 * k, height + 2 * k);
    cairo_set_source_rgba(cr, 0, 0, 0, alpha);
    alpha *= 0.5f;
    cairo_fill(cr);
  }
  cairo_set_line_width(cr, 1.0);
#else
  cairo_set_line_width(cr, 1.0);
  cairo_set_source_rgb(cr, .1, .1, .1);
  cairo_rectangle(cr, 0, 0, width, height);
  cairo_stroke(cr);
#endif

  cairo_rectangle(cr, 0, 0, width, height);
  cairo_clip(cr);

  cairo_set_source_rgb(cr, .3, .3, .3);
  cairo_rectangle(cr, 0, 0, width, height);
  cairo_fill(cr);
  if(d->highlight == 1)
  {
    cairo_set_source_rgb(cr, .5, .5, .5);
    cairo_rectangle(cr, 0, 0, .2 * width, height);
    cairo_fill(cr);
  }
  else if(d->highlight == 2)
  {
    cairo_set_source_rgb(cr, .5, .5, .5);
    cairo_rectangle(cr, 0.2 * width, 0, width, height);
    cairo_fill(cr);
  }

  // draw grid
  cairo_set_line_width(cr, .4);
  cairo_set_source_rgb(cr, .1, .1, .1);
  if(dev->histogram_type == DT_DEV_HISTOGRAM_WAVEFORM)
    dt_draw_waveform_lines(cr, 0, 0, width, height);
  else
    dt_draw_grid(cr, 4, 0, 0, width, height);

  if(hist_max > 0.0f)
  {
    cairo_save(cr);
    if(dev->histogram_type == DT_DEV_HISTOGRAM_WAVEFORM)
    {
      // make the color channel selector work:
      uint8_t *buf = (uint8_t *)malloc(sizeof(uint8_t) * height * stride);
      uint8_t mask[3] = { d->blue, d->green, d->red };
      memcpy(buf, dev->histogram_waveform, sizeof(uint8_t) * height * stride);
      for(int y = 0; y < height; y++)
        for(int x = 0; x < width; x++)
          for(int k = 0; k < 3; k++)
          {
            buf[y * stride + x * 4 + k] *= mask[k];
          }

      cairo_surface_t *source
          = cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_ARGB32, width, height, stride);

      cairo_set_source_surface(cr, source, 0.0, 0.0);
      cairo_set_operator(cr, CAIRO_OPERATOR_ADD);
      cairo_paint(cr);
      cairo_surface_destroy(source);
      free(buf);
    }
    else
    {
      // cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
      cairo_translate(cr, 0, height);
      cairo_scale(cr, width / 63.0, -(height - 10) / hist_max);
      cairo_set_operator(cr, CAIRO_OPERATOR_ADD);
      // cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
      cairo_set_line_width(cr, 1.);
      if(d->red)
      {
        cairo_set_source_rgba(cr, 1., 0., 0., 0.2);
        dt_draw_histogram_8(cr, hist, 0, dev->histogram_type == DT_DEV_HISTOGRAM_LINEAR);
      }
      if(d->green)
      {
        cairo_set_source_rgba(cr, 0., 1., 0., 0.2);
        dt_draw_histogram_8(cr, hist, 1, dev->histogram_type == DT_DEV_HISTOGRAM_LINEAR);
      }
      if(d->blue)
      {
        cairo_set_source_rgba(cr, 0., 0., 1., 0.2);
        dt_draw_histogram_8(cr, hist, 2, dev->histogram_type == DT_DEV_HISTOGRAM_LINEAR);
      }
      cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
      // cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
    }
    cairo_restore(cr);
  }

  cairo_set_source_rgb(cr, .25, .25, .25);
  cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
  PangoLayout *layout;
  PangoRectangle ink;
  PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc);
  pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
  layout = pango_cairo_create_layout(cr);
  pango_font_description_set_absolute_size(desc, .1 * height * PANGO_SCALE);
  pango_layout_set_font_description(layout, desc);

  char exifline[50];
  dt_image_print_exif(&dev->image_storage, exifline, 50);
  pango_layout_set_text(layout, exifline, -1);
  pango_layout_get_pixel_extents(layout, &ink, NULL);
  cairo_move_to(cr, .02 * width, .98 * height - ink.height - ink.y);
  cairo_save(cr);
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.0));
  cairo_set_source_rgba(cr, 1, 1, 1, 0.3);
  pango_cairo_layout_path(cr, layout);
  cairo_stroke_preserve(cr);
  cairo_set_source_rgb(cr, .25, .25, .25);
  cairo_fill(cr);
  cairo_restore(cr);

  // buttons to control the display of the histogram: linear/log, r, g, b
  if(d->highlight != 0)
  {
    _draw_mode_toggle(cr, d->mode_x, d->button_y, d->mode_w, d->button_h, dev->histogram_type);
    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.4);
    _draw_color_toggle(cr, d->red_x, d->button_y, d->color_w, d->button_h, d->red);
    cairo_set_source_rgba(cr, 0.0, 1.0, 0.0, 0.4);
    _draw_color_toggle(cr, d->green_x, d->button_y, d->color_w, d->button_h, d->green);
    cairo_set_source_rgba(cr, 0.0, 0.0, 1.0, 0.4);
    _draw_color_toggle(cr, d->blue_x, d->button_y, d->color_w, d->button_h, d->blue);
  }

  cairo_destroy(cr);
  cairo_set_source_surface(crf, cst, 0, 0);
  cairo_paint(crf);
  cairo_surface_destroy(cst);
  pango_font_description_free(desc);
  g_object_unref(layout);
  return TRUE;
}
static void
ag_chart_renderer_render(GtkCellRenderer      *renderer,
                         cairo_t              *cr,
                         GtkWidget            *widget,
                         const GdkRectangle   *background_area,
                         const GdkRectangle   *cell_area,
                         GtkCellRendererState flags)
{
    AgChartRendererPrivate *priv = ag_chart_renderer_get_instance_private(
            AG_CHART_RENDERER(renderer)
        );
    int             margin;
    GtkStyleContext *context = gtk_widget_get_style_context(widget);
    GdkPixbuf       *pixbuf;

    gtk_style_context_save(context);
    gtk_style_context_add_class(context, "ag-chart-renderer");

    if (priv->css_class) {
        gtk_style_context_add_class(context, priv->css_class);
    }

    cairo_save(cr);
    gdk_cairo_rectangle(cr, cell_area);
    cairo_clip(cr);

    cairo_translate(cr, cell_area->x, cell_area->y);

    margin = MAX(
            AG_CHART_RENDERER_TILE_MARGIN,
            (int)((cell_area->width - AG_CHART_RENDERER_TILE_SIZE) / 2)
        );

    g_object_get(renderer, "pixbuf", &pixbuf, NULL);

    if (pixbuf != NULL) {
        GdkRectangle area = {
                margin,
                margin,
                AG_CHART_RENDERER_TILE_SIZE,
                AG_CHART_RENDERER_TILE_SIZE
            };

        GTK_CELL_RENDERER_CLASS(ag_chart_renderer_parent_class)->render(
                renderer,
                cr,
                widget,
                &area,
                &area,
                flags
            );
    } else {
        gtk_render_frame(
                context,
                cr,
                margin,
                margin,
                AG_CHART_RENDERER_TILE_SIZE,
                AG_CHART_RENDERER_TILE_SIZE
            );
        gtk_render_background(
                context,
                cr,
                margin,
                margin,
                AG_CHART_RENDERER_TILE_SIZE,
                AG_CHART_RENDERER_TILE_SIZE
            );
    }

    gtk_style_context_restore(context);

    if (priv->toggle_visible) {
        gint xpad,
             ypad,
             x_offset,
             check_x,
             check_y;

        gtk_cell_renderer_get_padding(
                GTK_CELL_RENDERER(renderer),
                &xpad, &ypad
            );

        if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL) {
            x_offset = xpad;
        } else {
            x_offset = cell_area->width
                - AG_CHART_RENDERER_CHECK_ICON_SIZE
                - xpad;
        }

        check_x = x_offset;
        check_y = cell_area->height - AG_CHART_RENDERER_CHECK_ICON_SIZE - ypad;

        gtk_style_context_save(context);
        gtk_style_context_add_class(context, GTK_STYLE_CLASS_CHECK);

        if (priv->checked) {
            gtk_style_context_set_state(context, GTK_STATE_FLAG_CHECKED);
        }

        gtk_render_background(
                context,
                cr,
                check_x,
                check_y,
                AG_CHART_RENDERER_CHECK_ICON_SIZE,
                AG_CHART_RENDERER_CHECK_ICON_SIZE
            );
        gtk_render_frame(
                context,
                cr,
                check_x,
                check_y,
                AG_CHART_RENDERER_CHECK_ICON_SIZE,
                AG_CHART_RENDERER_CHECK_ICON_SIZE
            );
        gtk_render_check(
                context,
                cr,
                check_x,
                check_y,
                AG_CHART_RENDERER_CHECK_ICON_SIZE,
                AG_CHART_RENDERER_CHECK_ICON_SIZE
            );

        gtk_style_context_restore(context);
    }

    cairo_restore(cr);
}
Exemple #26
0
static void
gtk_level_bar_draw_fill_discrete (GtkLevelBar           *self,
                                  cairo_t               *cr,
                                  gboolean               inverted,
                                  cairo_rectangle_int_t *fill_area)
{
  GtkWidget *widget = GTK_WIDGET (self);
  GtkStyleContext *context = gtk_widget_get_style_context (widget);
  GtkStateFlags flags = gtk_widget_get_state_flags (widget);
  gint num_blocks, num_filled, idx;
  gint block_width, block_height;
  gint block_draw_width, block_draw_height;
  GtkBorder block_margin;
  cairo_rectangle_int_t block_area;

  gtk_level_bar_get_min_block_size (self, &block_width, &block_height);

  block_area = *fill_area;
  num_blocks = gtk_level_bar_get_num_blocks (self);
  num_filled = (gint) round (self->priv->cur_value) - (gint) round (self->priv->min_value);

  if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
    block_width = MAX (block_width, (gint) floor (block_area.width / num_blocks));
  else
    block_height = MAX (block_height, (gint) floor (block_area.height / num_blocks));

  gtk_style_context_save (context);
  gtk_style_context_add_class (context, STYLE_CLASS_FILL_BLOCK);
  gtk_style_context_get_margin (context, flags, &block_margin);

  block_draw_width = block_width - block_margin.left - block_margin.right;
  block_draw_height = block_height - block_margin.top - block_margin.bottom;

  if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
    {
      block_draw_height = MAX (block_draw_height, block_area.height - block_margin.top - block_margin.bottom);
      block_area.y += block_margin.top;

      if (inverted)
        block_area.x += block_area.width - block_draw_width;
    }
  else
    {
      block_draw_width = MAX (block_draw_width, block_area.width - block_margin.left - block_margin.right);
      block_area.x += block_margin.left;

      if (inverted)
        block_area.y += block_area.height - block_draw_height;
    }

  for (idx = 0; idx < num_blocks; idx++)
    {
      if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
        {
          if (inverted)
            block_area.x -= block_margin.right;
          else
            block_area.x += block_margin.left;
        }
      else
        {
          if (inverted)
            block_area.y -= block_margin.bottom;
          else
            block_area.y += block_margin.top;
        }

      if (idx > num_filled - 1)
        gtk_style_context_add_class (context, STYLE_CLASS_EMPTY_FILL_BLOCK);

      gtk_render_background (context, cr,
                             block_area.x, block_area.y,
                             block_draw_width, block_draw_height);
      gtk_render_frame (context, cr,
                        block_area.x, block_area.y,
                        block_draw_width, block_draw_height);

      if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
        {
          if (inverted)
            block_area.x -= block_draw_width + block_margin.left;
          else
            block_area.x += block_draw_width + block_margin.right;
        }
      else
        {
          if (inverted)
            block_area.y -= block_draw_height + block_margin.top;
          else
            block_area.y += block_draw_height + block_margin.bottom;
        }
    }

  gtk_style_context_restore (context);
}
Exemple #27
0
static void
gtk_level_bar_draw_fill_continuous (GtkLevelBar           *self,
                                    cairo_t               *cr,
                                    gboolean               inverted,
                                    cairo_rectangle_int_t *fill_area)
{
  GtkWidget *widget = GTK_WIDGET (self);
  GtkStyleContext *context = gtk_widget_get_style_context (widget);
  GtkStateFlags flags = gtk_widget_get_state_flags (widget);
  cairo_rectangle_int_t base_area, block_area;
  GtkBorder block_margin;
  gdouble fill_percentage;

  gtk_style_context_save (context);
  gtk_style_context_add_class (context, STYLE_CLASS_FILL_BLOCK);
  gtk_style_context_get_margin (context, flags, &block_margin);

  /* render the empty (unfilled) part */
  base_area = *fill_area;
  base_area.x += block_margin.left;
  base_area.y += block_margin.top;
  base_area.width -= block_margin.left + block_margin.right;
  base_area.height -= block_margin.top + block_margin.bottom;

  gtk_style_context_add_class (context, STYLE_CLASS_EMPTY_FILL_BLOCK);

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

  gtk_style_context_remove_class (context, STYLE_CLASS_EMPTY_FILL_BLOCK);

  /* now render the filled part on top of it */
  block_area = base_area;

  fill_percentage = (self->priv->cur_value - self->priv->min_value) /
    (self->priv->max_value - self->priv->min_value);

  if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
    {
      block_area.width = (gint) floor (block_area.width * fill_percentage);

      if (inverted)
        block_area.x += base_area.width - block_area.width;
    }
  else
    {
      block_area.height = (gint) floor (block_area.height * fill_percentage);

      if (inverted)
        block_area.y += base_area.height - block_area.height;
    }

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

  gtk_style_context_restore (context);
}
Exemple #28
0
/* This code was originally rendering anti-aliased using X primitives, and
 * now has been switched to draw anti-aliased using cairo. In general, the
 * closest correspondence between X rendering and cairo rendering is given
 * by offsetting the geometry by 0.5 pixels in both directions before rendering
 * with cairo. This is because X samples at the upper left corner of the
 * pixel while cairo averages over the entire pixel. However, in the cases
 * where the X rendering was an exact rectangle with no "jaggies"
 * we need to be a bit careful about applying the offset. We want to produce
 * the exact same pixel-aligned rectangle, rather than a rectangle with
 * fuzz around the edges.
 */
static void
draw_op_draw_with_env (const MetaDrawOp    *op,
                       GtkStyleContext     *context,
                       cairo_t             *cr,
                       const MetaDrawInfo  *info,
                       MetaPositionExprEnv *env)
{
  GdkRGBA color;

  cairo_save (cr);

  cairo_set_line_width (cr, 1.0);

  switch (op->type)
    {
    case META_DRAW_LINE:
      {
        gdouble x1, x2, y1, y2;

        meta_color_spec_render (op->data.line.color_spec, context, &color);
        gdk_cairo_set_source_rgba (cr, &color);

        if (op->data.line.width > 0)
          cairo_set_line_width (cr, op->data.line.width);

        if (op->data.line.dash_on_length > 0 &&
            op->data.line.dash_off_length > 0)
          {
            double dash_list[2];
            dash_list[0] = op->data.line.dash_on_length;
            dash_list[1] = op->data.line.dash_off_length;
            cairo_set_dash (cr, dash_list, 2, 0);
          }

        x1 = meta_draw_spec_parse_x_position (op->data.line.x1, env);
        y1 = meta_draw_spec_parse_y_position (op->data.line.y1, env);

        if (!op->data.line.x2 && !op->data.line.y2 &&
            op->data.line.width == 0)
          {
            cairo_rectangle (cr, x1, y1, 1, 1);
            cairo_fill (cr);
          }
        else
          {
            if (op->data.line.x2)
              x2 = meta_draw_spec_parse_x_position (op->data.line.x2, env);
            else
              x2 = x1;

            if (op->data.line.y2)
              y2 = meta_draw_spec_parse_y_position (op->data.line.y2, env);
            else
              y2 = y1;

            /* This is one of the cases where we are matching the exact
             * pixel aligned rectangle produced by X; for zero-width lines
             * the generic algorithm produces the right result so we don't
             * need to handle them here.
             */
            if ((y1 == y2 || x1 == x2) && op->data.line.width != 0)
              {
                double offset = op->data.line.width % 2 ? .5 : 0;

                if (y1 == y2)
                  {
                    cairo_move_to (cr, x1, y1 + offset);
                    cairo_line_to (cr, x2, y2 + offset);
                  }
                else
                  {
                    cairo_move_to (cr, x1 + offset, y1);
                    cairo_line_to (cr, x2 + offset, y2);
                  }
              }
            else
              {
                /* zero-width lines include both end-points in X, unlike wide lines */
                if (op->data.line.width == 0)
                  cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);

                cairo_move_to (cr, x1 + .5, y1 + .5);
                cairo_line_to (cr, x2 + .5, y2 + .5);
              }
            cairo_stroke (cr);
          }
      }
      break;

    case META_DRAW_RECTANGLE:
      {
        gdouble rx, ry, rwidth, rheight;

        meta_color_spec_render (op->data.rectangle.color_spec, context, &color);
        gdk_cairo_set_source_rgba (cr, &color);

        rx = meta_draw_spec_parse_x_position (op->data.rectangle.x, env);
        ry = meta_draw_spec_parse_y_position (op->data.rectangle.y, env);
        rwidth = meta_draw_spec_parse_size (op->data.rectangle.width, env);
        rheight = meta_draw_spec_parse_size (op->data.rectangle.height, env);

        /* Filled and stroked rectangles are the other cases
         * we pixel-align to X rasterization
         */
        if (op->data.rectangle.filled)
          {
            cairo_rectangle (cr, rx, ry, rwidth, rheight);
            cairo_fill (cr);
          }
        else
          {
            cairo_rectangle (cr, rx + .5, ry + .5, rwidth, rheight);
            cairo_stroke (cr);
          }
      }
      break;

    case META_DRAW_ARC:
      {
        gdouble rx, ry, rwidth, rheight;
        double start_angle, end_angle;
        double center_x, center_y;

        meta_color_spec_render (op->data.arc.color_spec, context, &color);
        gdk_cairo_set_source_rgba (cr, &color);

        rx = meta_draw_spec_parse_x_position (op->data.arc.x, env);
        ry = meta_draw_spec_parse_y_position (op->data.arc.y, env);
        rwidth = meta_draw_spec_parse_size (op->data.arc.width, env);
        rheight = meta_draw_spec_parse_size (op->data.arc.height, env);

        start_angle = op->data.arc.start_angle * (M_PI / 180.)
                      - (.5 * M_PI); /* start at 12 instead of 3 oclock */
        end_angle = start_angle + op->data.arc.extent_angle * (M_PI / 180.);
        center_x = rx + (double)rwidth / 2. + .5;
        center_y = ry + (double)rheight / 2. + .5;

        cairo_save (cr);

        cairo_translate (cr, center_x, center_y);
        cairo_scale (cr, (double)rwidth / 2., (double)rheight / 2.);

        if (op->data.arc.extent_angle >= 0)
          cairo_arc (cr, 0, 0, 1, start_angle, end_angle);
        else
          cairo_arc_negative (cr, 0, 0, 1, start_angle, end_angle);

        cairo_restore (cr);

        if (op->data.arc.filled)
          {
            cairo_line_to (cr, center_x, center_y);
            cairo_fill (cr);
          }
        else
          cairo_stroke (cr);
      }
      break;

    case META_DRAW_CLIP:
      break;

    case META_DRAW_TINT:
      {
        gdouble rx, ry, rwidth, rheight;

        rx = meta_draw_spec_parse_x_position (op->data.tint.x, env);
        ry = meta_draw_spec_parse_y_position (op->data.tint.y, env);
        rwidth = meta_draw_spec_parse_size (op->data.tint.width, env);
        rheight = meta_draw_spec_parse_size (op->data.tint.height, env);

        meta_color_spec_render (op->data.tint.color_spec, context, &color);
        meta_alpha_gradient_spec_render (op->data.tint.alpha_spec, color, cr,
                                         rx, ry, rwidth, rheight);
      }
      break;

    case META_DRAW_GRADIENT:
      {
        gdouble rx, ry, rwidth, rheight;

        rx = meta_draw_spec_parse_x_position (op->data.gradient.x, env);
        ry = meta_draw_spec_parse_y_position (op->data.gradient.y, env);
        rwidth = meta_draw_spec_parse_size (op->data.gradient.width, env);
        rheight = meta_draw_spec_parse_size (op->data.gradient.height, env);

        meta_gradient_spec_render (op->data.gradient.gradient_spec,
                                   op->data.gradient.alpha_spec,
                                   cr, context, rx, ry, rwidth, rheight);
      }
      break;

    case META_DRAW_IMAGE:
      {
        gdouble scale;
        gdouble rx, ry, rwidth, rheight;
        cairo_surface_t *surface;

        scale = info->scale;
        cairo_scale (cr, 1.0 / scale, 1.0 / scale);

        if (op->data.image.pixbuf)
          {
            env->object_width = gdk_pixbuf_get_width (op->data.image.pixbuf);
            env->object_height = gdk_pixbuf_get_height (op->data.image.pixbuf);
          }

        rwidth = meta_draw_spec_parse_size (op->data.image.width, env) * scale;
        rheight = meta_draw_spec_parse_size (op->data.image.height, env) * scale;

        surface = draw_op_as_surface (op, context, info, rwidth, rheight);

        if (surface)
          {
            rx = meta_draw_spec_parse_x_position (op->data.image.x, env) * scale;
            ry = meta_draw_spec_parse_y_position (op->data.image.y, env) * scale;

            cairo_set_source_surface (cr, surface, rx, ry);

            if (op->data.image.alpha_spec)
              {
                cairo_pattern_t *pattern;

                cairo_translate (cr, rx, ry);
                cairo_scale (cr, rwidth, rheight);

                pattern = meta_alpha_gradient_spec_get_mask (op->data.image.alpha_spec);
                cairo_mask (cr, pattern);

                cairo_pattern_destroy (pattern);
              }
            else
              {
                cairo_paint (cr);
              }

            cairo_surface_destroy (surface);
          }
      }
      break;

    case META_DRAW_GTK_ARROW:
      {
        gdouble rx, ry, rwidth, rheight;
        double angle = 0, size;

        rx = meta_draw_spec_parse_x_position (op->data.gtk_arrow.x, env);
        ry = meta_draw_spec_parse_y_position (op->data.gtk_arrow.y, env);
        rwidth = meta_draw_spec_parse_size (op->data.gtk_arrow.width, env);
        rheight = meta_draw_spec_parse_size (op->data.gtk_arrow.height, env);

        size = MAX(rwidth, rheight);

        switch (op->data.gtk_arrow.arrow)
          {
          case GTK_ARROW_UP:
            angle = 0;
            break;
          case GTK_ARROW_RIGHT:
            angle = M_PI / 2;
            break;
          case GTK_ARROW_DOWN:
            angle = M_PI;
            break;
          case GTK_ARROW_LEFT:
            angle = 3 * M_PI / 2;
            break;
          case GTK_ARROW_NONE:
            return;
          default:
            break;
          }

        gtk_style_context_set_state (context, op->data.gtk_arrow.state);
        gtk_render_arrow (context, cr, angle, rx, ry, size);
      }
      break;

    case META_DRAW_GTK_BOX:
      {
        gdouble rx, ry, rwidth, rheight;

        rx = meta_draw_spec_parse_x_position (op->data.gtk_box.x, env);
        ry = meta_draw_spec_parse_y_position (op->data.gtk_box.y, env);
        rwidth = meta_draw_spec_parse_size (op->data.gtk_box.width, env);
        rheight = meta_draw_spec_parse_size (op->data.gtk_box.height, env);

        gtk_style_context_set_state (context, op->data.gtk_box.state);
        gtk_render_background (context, cr, rx, ry, rwidth, rheight);
        gtk_render_frame (context, cr, rx, ry, rwidth, rheight);
      }
      break;

    case META_DRAW_GTK_VLINE:
      {
        gdouble rx, ry1, ry2;

        rx = meta_draw_spec_parse_x_position (op->data.gtk_vline.x, env);
        ry1 = meta_draw_spec_parse_y_position (op->data.gtk_vline.y1, env);
        ry2 = meta_draw_spec_parse_y_position (op->data.gtk_vline.y2, env);

        gtk_style_context_set_state (context, op->data.gtk_vline.state);
        gtk_render_line (context, cr, rx, ry1, rx, ry2);
      }
      break;

    case META_DRAW_ICON:
      {
        gdouble rx, ry, rwidth, rheight;
        cairo_surface_t *surface;

        rwidth = meta_draw_spec_parse_size (op->data.icon.width, env);
        rheight = meta_draw_spec_parse_size (op->data.icon.height, env);

        surface = draw_op_as_surface (op, context, info, rwidth, rheight);

        if (surface)
          {
            rx = meta_draw_spec_parse_x_position (op->data.icon.x, env);
            ry = meta_draw_spec_parse_y_position (op->data.icon.y, env);

            cairo_set_source_surface (cr, surface, rx, ry);

            if (op->data.icon.alpha_spec)
              {
                cairo_pattern_t *pattern;

                cairo_translate (cr, rx, ry);
                cairo_scale (cr, rwidth, rheight);

                pattern = meta_alpha_gradient_spec_get_mask (op->data.icon.alpha_spec);
                cairo_mask (cr, pattern);

                cairo_pattern_destroy (pattern);
              }
            else
              {
                cairo_paint (cr);
              }

            cairo_surface_destroy (surface);
          }
      }
      break;

    case META_DRAW_TITLE:
      if (info->title_layout)
        {
          gdouble rx, ry;
          PangoRectangle ink_rect, logical_rect;

          meta_color_spec_render (op->data.title.color_spec, context, &color);
          gdk_cairo_set_source_rgba (cr, &color);

          rx = meta_draw_spec_parse_x_position (op->data.title.x, env);
          ry = meta_draw_spec_parse_y_position (op->data.title.y, env);

          if (op->data.title.ellipsize_width)
            {
              gdouble ellipsize_width;
              int right_bearing;

              ellipsize_width = meta_draw_spec_parse_x_position (op->data.title.ellipsize_width, env);
              /* HACK: meta_draw_spec_parse_x_position adds in env->rect.x, subtract out again */
              ellipsize_width -= env->rect.x;

              pango_layout_set_width (info->title_layout, -1);
              pango_layout_get_pixel_extents (info->title_layout,
                                              &ink_rect, &logical_rect);

              /* Pango's idea of ellipsization is with respect to the logical rect.
               * correct for this, by reducing the ellipsization width by the overflow
               * of the un-ellipsized text on the right... it's always the visual
               * right we want regardless of bidi, since since the X we pass in to
               * cairo_move_to() is always the left edge of the line.
               */
              right_bearing = (ink_rect.x + ink_rect.width) - (logical_rect.x + logical_rect.width);
              right_bearing = MAX (right_bearing, 0);

              ellipsize_width -= right_bearing;
              ellipsize_width = MAX (ellipsize_width, 0);

              /* Only ellipsizing when necessary is a performance optimization -
               * pango_layout_set_width() will force a relayout if it isn't the
               * same as the current width of -1.
               */
              if (ellipsize_width < logical_rect.width)
                pango_layout_set_width (info->title_layout, PANGO_SCALE * ellipsize_width);
            }
          else if (rx - env->rect.x + env->title_width >= env->rect.width)
          {
            const double alpha_margin = 30.0;
            int text_space = env->rect.x + env->rect.width -
                             (rx - env->rect.x) - env->right_width;

            double startalpha = 1.0 - (alpha_margin/((double)text_space));

            cairo_pattern_t *linpat;
            linpat = cairo_pattern_create_linear (rx, ry, text_space,
                                                  env->title_height);
            cairo_pattern_add_color_stop_rgba (linpat, 0, color.red,
                                                          color.green,
                                                          color.blue,
                                                          color.alpha);
            cairo_pattern_add_color_stop_rgba (linpat, startalpha,
                                                       color.red,
                                                       color.green,
                                                       color.blue,
                                                       color.alpha);
            cairo_pattern_add_color_stop_rgba (linpat, 1, color.red,
                                                          color.green,
                                                          color.blue, 0);
            cairo_set_source(cr, linpat);
            cairo_pattern_destroy(linpat);
          }

          cairo_move_to (cr, rx, ry);
          pango_cairo_show_layout (cr, info->title_layout);

          /* Remove any ellipsization we might have set; will short-circuit
           * if the width is already -1 */
          pango_layout_set_width (info->title_layout, -1);
        }
      break;

    case META_DRAW_OP_LIST:
      {
        MetaRectangleDouble d_rect;

        d_rect.x = meta_draw_spec_parse_x_position (op->data.op_list.x, env);
        d_rect.y = meta_draw_spec_parse_y_position (op->data.op_list.y, env);
        d_rect.width = meta_draw_spec_parse_size (op->data.op_list.width, env);
        d_rect.height = meta_draw_spec_parse_size (op->data.op_list.height, env);

        meta_draw_op_list_draw_with_style (op->data.op_list.op_list,
                                           context, cr, info, d_rect);
      }
      break;

    case META_DRAW_TILE:
      {
        gdouble rx, ry, rwidth, rheight;
        gdouble tile_xoffset, tile_yoffset;
        MetaRectangleDouble tile;

        rx = meta_draw_spec_parse_x_position (op->data.tile.x, env);
        ry = meta_draw_spec_parse_y_position (op->data.tile.y, env);
        rwidth = meta_draw_spec_parse_size (op->data.tile.width, env);
        rheight = meta_draw_spec_parse_size (op->data.tile.height, env);

        cairo_save (cr);

        cairo_rectangle (cr, rx, ry, rwidth, rheight);
        cairo_clip (cr);

        tile_xoffset = meta_draw_spec_parse_x_position (op->data.tile.tile_xoffset, env);
        tile_yoffset = meta_draw_spec_parse_y_position (op->data.tile.tile_yoffset, env);
        /* tile offset should not include x/y */
        tile_xoffset -= env->rect.x;
        tile_yoffset -= env->rect.y;

        tile.width = meta_draw_spec_parse_size (op->data.tile.tile_width, env);
        tile.height = meta_draw_spec_parse_size (op->data.tile.tile_height, env);

        tile.x = rx - tile_xoffset;

        while (tile.x < (rx + rwidth))
          {
            tile.y = ry - tile_yoffset;
            while (tile.y < (ry + rheight))
              {
                meta_draw_op_list_draw_with_style (op->data.tile.op_list,
                                                   context, cr, info, tile);

                tile.y += tile.height;
              }

            tile.x += tile.width;
          }
        cairo_restore (cr);
      }
      break;

    default:
      break;
    }

   cairo_restore (cr);
}
Exemple #29
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;
}
Exemple #30
-1
static gboolean _lib_navigation_draw_callback(GtkWidget *widget, cairo_t *crf, gpointer user_data)
{
  dt_lib_module_t *self = (dt_lib_module_t *)user_data;
  dt_lib_navigation_t *d = (dt_lib_navigation_t *)self->data;

  const int inset = DT_NAVIGATION_INSET;
  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  int width = allocation.width, height = allocation.height;

  dt_develop_t *dev = darktable.develop;

  /* double buffering of image data: only take new data if valid */
  if(dev->preview_pipe->backbuf && dev->preview_status == DT_DEV_PIXELPIPE_VALID)
  {
    /* re-allocate in case of changed image dimensions */
    if(d->buffer == NULL || dev->preview_pipe->backbuf_width != d->wd || dev->preview_pipe->backbuf_height != d->ht)
    {
      g_free(d->buffer);
      d->wd = dev->preview_pipe->backbuf_width;
      d->ht = dev->preview_pipe->backbuf_height;
      d->buffer = g_malloc0((size_t)d->wd * d->ht * 4 * sizeof(unsigned char));
    }

    /* update buffer if new data is available */
    if(d->buffer && dev->preview_pipe->input_timestamp > d->timestamp)
    {
      dt_pthread_mutex_t *mutex = &dev->preview_pipe->backbuf_mutex;
      dt_pthread_mutex_lock(mutex);
      memcpy(d->buffer, dev->preview_pipe->backbuf, (size_t)d->wd * d->ht * 4 * sizeof(unsigned char));
      d->timestamp = dev->preview_pipe->input_timestamp;
      dt_pthread_mutex_unlock(mutex);
    }
  }

  /* get the current style */
  cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  cairo_t *cr = cairo_create(cst);

  GtkStyleContext *context = gtk_widget_get_style_context(widget);
  gtk_render_background(context, cr, 0, 0, allocation.width, allocation.height);

  width -= 2 * inset;
  height -= 2 * inset;
  cairo_translate(cr, inset, inset);

  /* draw navigation image if available */
  if(d->buffer)
  {
    cairo_save(cr);
    const int wd = d->wd;
    const int ht = d->ht;
    const float scale = fminf(width / (float)wd, height / (float)ht);

    const int stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, wd);
    cairo_surface_t *surface
        = cairo_image_surface_create_for_data(d->buffer, CAIRO_FORMAT_RGB24, wd, ht, stride);
    cairo_translate(cr, width / 2.0, height / 2.0f);
    cairo_scale(cr, scale, scale);
    cairo_translate(cr, -.5f * wd, -.5f * ht);

    // draw shadow around
    float alpha = 1.0f;
    for(int k = 0; k < 4; k++)
    {
      cairo_rectangle(cr, -k / scale, -k / scale, wd + 2 * k / scale, ht + 2 * k / scale);
      cairo_set_source_rgba(cr, 0, 0, 0, alpha);
      alpha *= 0.6f;
      cairo_fill(cr);
    }

    cairo_rectangle(cr, 0, 0, wd - 2, ht - 1);
    cairo_set_source_surface(cr, surface, 0, 0);
    cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST);
    cairo_fill(cr);
    cairo_surface_destroy(surface);

    // draw box where we are
    dt_dev_zoom_t zoom = dt_control_get_dev_zoom();
    int closeup = dt_control_get_dev_closeup();
    float zoom_x = dt_control_get_dev_zoom_x();
    float zoom_y = dt_control_get_dev_zoom_y();
    const float min_scale = dt_dev_get_zoom_scale(dev, DT_ZOOM_FIT, closeup ? 2.0 : 1.0, 0);
    const float cur_scale = dt_dev_get_zoom_scale(dev, zoom, closeup ? 2.0 : 1.0, 0);
    // avoid numerical instability for small resolutions:
    double h, w;
    if(cur_scale > min_scale)
    {
      float boxw = 1, boxh = 1;
      dt_dev_check_zoom_bounds(darktable.develop, &zoom_x, &zoom_y, zoom, closeup, &boxw, &boxh);
      cairo_translate(cr, wd * (.5f + zoom_x), ht * (.5f + zoom_y));
      cairo_set_source_rgb(cr, 0., 0., 0.);
      cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.f / scale));
      boxw *= wd;
      boxh *= ht;
      cairo_rectangle(cr, -boxw / 2 - 1, -boxh / 2 - 1, boxw + 2, boxh + 2);
      cairo_stroke(cr);
      cairo_set_source_rgb(cr, 1., 1., 1.);
      cairo_rectangle(cr, -boxw / 2, -boxh / 2, boxw, boxh);
      cairo_stroke(cr);
    }
    cairo_restore(cr);
    if(fabsf(cur_scale - min_scale) > 0.001f)
    {
      /* Zoom % */
      PangoLayout *layout;
      PangoRectangle ink;
      PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc);
      pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
      layout = pango_cairo_create_layout(cr);
      const float fontsize = DT_PIXEL_APPLY_DPI(11);
      pango_font_description_set_absolute_size(desc, fontsize * PANGO_SCALE);
      pango_layout_set_font_description(layout, desc);
      cairo_translate(cr, 0, height);
      cairo_set_source_rgba(cr, 1., 1., 1., 0.5);
      cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);

      char zoomline[5];
      snprintf(zoomline, sizeof(zoomline), "%.0f%%", cur_scale * 100);

      pango_layout_set_text(layout, zoomline, -1);
      pango_layout_get_pixel_extents(layout, &ink, NULL);
      h = d->zoom_h = ink.height;
      w = d->zoom_w = ink.width;

      cairo_move_to(cr, width - w - h * 1.1 - ink.x, - fontsize);

      cairo_save(cr);
      cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.0));

      GdkRGBA *color;
      gtk_style_context_get(context, gtk_widget_get_state_flags(widget), "background-color", &color, NULL);

      gdk_cairo_set_source_rgba(cr, color);
      pango_cairo_layout_path(cr, layout);
      cairo_stroke_preserve(cr);
      cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
      cairo_fill(cr);
      cairo_restore(cr);

      gdk_rgba_free(color);
      pango_font_description_free(desc);
      g_object_unref(layout);

    }
    else
    {
      // draw the zoom-to-fit icon
      cairo_translate(cr, 0, height);
      cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);

      static int height = -1;
      if(height == -1)
      {
        PangoLayout *layout;
        PangoRectangle ink;
        PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc);
        pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
        layout = pango_cairo_create_layout(cr);
        pango_font_description_set_absolute_size(desc, DT_PIXEL_APPLY_DPI(11) * PANGO_SCALE);
        pango_layout_set_font_description(layout, desc);
        pango_layout_set_text(layout, "100%", -1); // dummy text, just to get the height
        pango_layout_get_pixel_extents(layout, &ink, NULL);
        height = ink.height;
        pango_font_description_free(desc);
        g_object_unref(layout);
      }

      h = d->zoom_h = height;
      w = h * 1.5;
      float sp = h * 0.6;
      d->zoom_w = w + sp;

      cairo_move_to(cr, width - w - h - sp, -1.0 * h);
      cairo_rectangle(cr, width - w - h - sp, -1.0 * h, w, h);
      cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);
      cairo_fill(cr);

      cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.0));

      cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
      cairo_move_to(cr, width - w * 0.8 - h - sp, -1.0 * h);
      cairo_line_to(cr, width - w - h - sp, -1.0 * h);
      cairo_line_to(cr, width - w - h - sp, -0.7 * h);
      cairo_stroke(cr);
      cairo_move_to(cr, width - w - h - sp, -0.3 * h);
      cairo_line_to(cr, width - w - h - sp, 0);
      cairo_line_to(cr, width - w * 0.8 - h - sp, 0);
      cairo_stroke(cr);
      cairo_move_to(cr, width - w * 0.2 - h - sp, 0);
      cairo_line_to(cr, width - h - sp, 0);
      cairo_line_to(cr, width - h - sp, -0.3 * h);
      cairo_stroke(cr);
      cairo_move_to(cr, width - h - sp, -0.7 * h);
      cairo_line_to(cr, width - h - sp, -1.0 * h);
      cairo_line_to(cr, width - w * 0.2 - h - sp, -1.0 * h);
      cairo_stroke(cr);
    }

    cairo_move_to(cr, width - 0.95 * h, -0.9 * h);
    cairo_line_to(cr, width - 0.05 * h, -0.9 * h);
    cairo_line_to(cr, width - 0.5 * h, -0.1 * h);
    cairo_fill(cr);
  }

  /* blit memsurface into widget */
  cairo_destroy(cr);
  cairo_set_source_surface(crf, cst, 0, 0);
  cairo_paint(crf);
  cairo_surface_destroy(cst);

  return TRUE;
}