static void he_check_button_init (HeCheckButton *self) { HeCheckButtonPrivate *priv = HE_CHECK_BUTTON_GET_PRIVATE (self); /* Store private part */ self->priv = priv; priv->title = GTK_LABEL (gtk_label_new (NULL)); priv->value = GTK_LABEL (gtk_label_new (NULL)); priv->alignment = gtk_alignment_new (0.5, 0.5, 0, 0); priv->toggle_renderer = GTK_CELL_RENDERER_TOGGLE (gtk_cell_renderer_toggle_new ()); priv->cell_view = gtk_cell_view_new (); priv->hbox = NULL; priv->label_box = NULL; priv->style = HE_CHECK_BUTTON_STYLE_NORMAL; priv->setting_style = FALSE; /* Setup the cell renderer */ /* We need to set the correct style from the gtkrc file. Otherwise the check box * does not look like a check box on a HildonCheckButton. */ GtkStyle *style = gtk_rc_get_style_by_paths(gtk_widget_get_settings(GTK_WIDGET(self)), NULL, "*.HildonCheckButton.GtkAlignment.GtkHBox.GtkCellView", G_TYPE_NONE); gtk_widget_set_style(priv->cell_view, style); /* Make sure that the check box is always shown, no matter the value of gtk-button-images */ g_signal_connect (priv->cell_view, "notify::visible", G_CALLBACK (gtk_widget_show), NULL); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->cell_view), GTK_CELL_RENDERER (priv->toggle_renderer), TRUE); /* Get checkbox-size style property of HildonCheckButton from theme */ style = gtk_rc_get_style_by_paths (gtk_widget_get_settings (GTK_WIDGET(self)), NULL, "*.HildonCheckButton", HILDON_TYPE_CHECK_BUTTON); glong checkbox_size = get_style_property_long (style, HILDON_TYPE_CHECK_BUTTON, "checkbox-size"); /* Set the indicator to the right size (the size of the pixmap) */ g_object_set (priv->toggle_renderer, "indicator-size", checkbox_size, NULL); /* Setup the labels */ gtk_widget_set_name (GTK_WIDGET (priv->title), "hildon-button-title"); gtk_widget_set_name (GTK_WIDGET (priv->value), "hildon-button-value"); he_check_button_set_style (self, HE_CHECK_BUTTON_STYLE_NORMAL); gtk_misc_set_alignment (GTK_MISC (priv->title), 0, 0.5); gtk_misc_set_alignment (GTK_MISC (priv->value), 0, 0.5); g_object_ref_sink (priv->alignment); /* The labels are not shown automatically, see he_check_button_set_(title|value) */ gtk_widget_set_no_show_all (GTK_WIDGET (priv->title), TRUE); gtk_widget_set_no_show_all (GTK_WIDGET (priv->value), TRUE); gtk_button_set_focus_on_click (GTK_BUTTON (self), FALSE); }
/** * static applet config functions */ static void matekbd_indicator_config_load_font (MatekbdIndicatorConfig * ind_config) { ind_config->font_family = g_settings_get_string (ind_config->settings, MATEKBD_INDICATOR_CONFIG_KEY_FONT_FAMILY); if (ind_config->font_family == NULL || ind_config->font_family[0] == '\0') { PangoFontDescription *fd = NULL; GtkStyle *style = gtk_rc_get_style_by_paths (gtk_settings_get_default (), GTK_STYLE_PATH, GTK_STYLE_PATH, GTK_TYPE_LABEL); if (style != NULL) fd = style->font_desc; if (fd != NULL) { ind_config->font_family = g_strdup (pango_font_description_to_string(fd)); } } xkl_debug (150, "font: [%s]\n", ind_config->font_family); }
/**************************************************************************** Update a font option which is not attached to a widget. ****************************************************************************/ void gui_update_font_full(const char *font_name, const char *font_value, GtkStyle **pstyle) { GtkSettings *settings; GdkScreen *screen; GtkStyle *style; char buf[64]; gui_update_font(font_name, font_value); screen = gdk_screen_get_default(); settings = gtk_settings_get_for_screen(screen); fc_snprintf(buf, sizeof(buf), "Freeciv*.%s", font_name); style = gtk_rc_get_style_by_paths(settings, buf, NULL, G_TYPE_NONE); if (style) { g_object_ref(style); } else { style = gtk_style_new(); } if (*pstyle) { g_object_unref(*pstyle); } *pstyle = style; }
static VALUE rg_m_get_style_by_paths(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self) { VALUE settings, widget_path, class_path, klass; GtkStyle* style; GType gtype; const gchar* name; rb_scan_args(argc, argv, "13", &settings, &widget_path, &class_path, &klass); style = gtk_rc_get_style_by_paths(GTK_SETTINGS(RVAL2GOBJ(settings)), NIL_P(widget_path) ? NULL : RVAL2CSTR(widget_path), NIL_P(class_path) ? NULL : RVAL2CSTR(class_path), NIL_P(klass) ? G_TYPE_NONE : CLASS2GTYPE(klass)); if (style){ gtype = G_OBJECT_TYPE(style); name = G_OBJECT_TYPE_NAME(style); if (! rb_const_defined_at(mGtk, rb_intern(name))){ G_DEF_CLASS(gtype, (gchar*)name, mGtk); } return GOBJ2RVAL(style); } return Qnil; }
/** * he_helper_get_logical_font_desc: * @name: The logical font name (see he-helper.h for possible values) * * Returns a newly-allocated string that contains the string representation * of the Pango font description for the given logical string. This can be * used in the font_desc attribute of span elements in Pango markup. * * This function should be used to get the font desc for Pango markup in * special use cases (e.g. GtkTreeView, mixed-content GtkLabel). If you * want to set a logical font directly on a widget, you can use * #hildon_helper_set_logical_font (from Hildon 2.2) for this. * * The return value should be freed with g_free() after use. **/ gchar * he_helper_get_logical_font_desc (const gchar *name) { GtkSettings *settings = gtk_settings_get_default(); GtkStyle *style = gtk_rc_get_style_by_paths(settings, name, NULL, G_TYPE_NONE); return pango_font_description_to_string(style->font_desc); }
static gboolean _lib_ratings_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_ratings_t *d = (dt_lib_ratings_t *)self->data; if(!darktable.control->running) return TRUE; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width, height = allocation.height; /* get current style */ GtkStyle *style = gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL, "GtkWidget", GTK_TYPE_WIDGET); if(!style) style = gtk_rc_get_style(widget); cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); /* fill background */ cairo_set_source_rgb(cr, style->bg[0].red / 65535.0, style->bg[0].green / 65535.0, style->bg[0].blue / 65535.0); cairo_paint(cr); /* lets draw stars */ int x = 0; cairo_set_line_width(cr, 1.5); cairo_set_source_rgba(cr, style->fg[0].red / 65535.0, style->fg[0].green / 65535.0, style->fg[0].blue / 65535.0, 0.8); d->current = 0; for(int k = 0; k < 5; k++) { /* outline star */ dt_draw_star(cr, STAR_SIZE / 2.0 + x, STAR_SIZE / 2.0, STAR_SIZE / 2.0, STAR_SIZE / 4.0); if(x < d->pointerx) { cairo_fill_preserve(cr); cairo_set_source_rgba(cr, style->fg[0].red / 65535.0, style->fg[0].green / 65535.0, style->fg[0].blue / 65535.0, 0.5); cairo_stroke(cr); cairo_set_source_rgba(cr, style->fg[0].red / 65535.0, style->fg[0].green / 65535.0, style->fg[0].blue / 65535.0, 0.8); if((k + 1) > d->current) d->current = (k + 1); } else cairo_stroke(cr); x += STAR_SIZE + STAR_SPACING; } /* blit memsurface onto widget*/ cairo_destroy(cr); cairo_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_surface(cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return TRUE; }
static void he_check_button_style_set (GtkWidget *widget, GtkStyle *previous_style) { guint horizontal_spacing, vertical_spacing, image_spacing; HeCheckButtonPrivate *priv = HE_CHECK_BUTTON_GET_PRIVATE (widget); if (GTK_WIDGET_CLASS (he_check_button_parent_class)->style_set) GTK_WIDGET_CLASS (he_check_button_parent_class)->style_set (widget, previous_style); /* Prevent infinite recursion when calling set_logical_font() and * set_logical_color() */ if (priv->setting_style) return; /* Get horizontal-spacing style property from ourself */ gtk_widget_style_get (widget, "horizontal-spacing", &horizontal_spacing, NULL); /* Get vertical-spacing style property of HildonButton from theme */ GtkStyle *style = gtk_rc_get_style_by_paths (gtk_widget_get_settings (widget), "*.*Button-finger", NULL, HILDON_TYPE_BUTTON); vertical_spacing = get_style_property_long (style, HILDON_TYPE_BUTTON, "vertical-spacing"); /* Get image-spacing style property of HildonCheckButton from theme */ style = gtk_rc_get_style_by_paths (gtk_widget_get_settings (widget), NULL, "*.HildonCheckButton", HILDON_TYPE_CHECK_BUTTON); image_spacing = get_style_property_long (style, GTK_TYPE_BUTTON, "image-spacing"); /* Setting values we got from above */ if (GTK_IS_HBOX (priv->label_box)) { gtk_box_set_spacing (GTK_BOX (priv->label_box), horizontal_spacing); } else { gtk_box_set_spacing (GTK_BOX (priv->label_box), vertical_spacing); } if (GTK_IS_BOX (priv->hbox)) { gtk_box_set_spacing (priv->hbox, image_spacing); } set_logical_font (widget); set_logical_color (widget); }
static void matekbd_indicator_config_load_colors (MatekbdIndicatorConfig * ind_config) { GError *gerror = NULL; ind_config->foreground_color = mateconf_client_get_string (ind_config->conf_client, MATEKBD_INDICATOR_CONFIG_KEY_FOREGROUND_COLOR, &gerror); if (gerror != NULL) { g_warning ("Error reading configuration:%s\n", gerror->message); g_error_free (gerror); gerror = NULL; } if (ind_config->foreground_color == NULL || ind_config->foreground_color[0] == '\0') { GtkStyle *style = gtk_rc_get_style_by_paths (gtk_settings_get_default (), GTK_STYLE_PATH, GTK_STYLE_PATH, GTK_TYPE_LABEL); if (style != NULL) { ind_config->foreground_color = g_strdup_printf ("%g %g %g", ((double) style-> fg [GTK_STATE_NORMAL].red) / 0x10000, ((double) style-> fg [GTK_STATE_NORMAL].green) / 0x10000, ((double) style-> fg [GTK_STATE_NORMAL].blue) / 0x10000); } } ind_config->background_color = mateconf_client_get_string (ind_config->conf_client, MATEKBD_INDICATOR_CONFIG_KEY_BACKGROUND_COLOR, &gerror); if (gerror != NULL) { g_warning ("Error reading configuration:%s\n", gerror->message); g_error_free (gerror); gerror = NULL; } }
static void matekbd_indicator_config_load_font (MatekbdIndicatorConfig * ind_config) { GError *gerror = NULL; ind_config->font_family = mateconf_client_get_string (ind_config->conf_client, MATEKBD_INDICATOR_CONFIG_KEY_FONT_FAMILY, &gerror); if (gerror != NULL) { g_warning ("Error reading configuration:%s\n", gerror->message); ind_config->font_family = g_strdup ("Helvetica"); g_error_free (gerror); gerror = NULL; } ind_config->font_size = mateconf_client_get_int (ind_config->conf_client, MATEKBD_INDICATOR_CONFIG_KEY_FONT_SIZE, &gerror); if (gerror != NULL) { g_warning ("Error reading configuration:%s\n", gerror->message); ind_config->font_size = 10; g_error_free (gerror); gerror = NULL; } if (ind_config->font_family == NULL || ind_config->font_family[0] == '\0') { PangoFontDescription *fd = NULL; GtkStyle *style = gtk_rc_get_style_by_paths (gtk_settings_get_default (), GTK_STYLE_PATH, GTK_STYLE_PATH, GTK_TYPE_LABEL); if (style != NULL) fd = style->font_desc; if (fd != NULL) { ind_config->font_family = g_strdup (pango_font_description_get_family (fd)); ind_config->font_size = pango_font_description_get_size (fd) / PANGO_SCALE; } } xkl_debug (150, "font: [%s], size %d\n", ind_config->font_family, ind_config->font_size); }
static GtkStyle* get_attached_style (GtkStyle *fallback, GdkWindow *window, const gchar *path, GType type) { GtkSettings *settings = gtk_settings_get_default (); GtkStyle *style; style = gtk_rc_get_style_by_paths (settings, path, path, type); if (!style) style = g_object_ref (fallback); else g_object_ref (style); return gtk_style_attach (style, window); }
/** * he_helper_get_logical_font_color: * @name: The logical font color (see he-helper.h for possible values) * * Returns a newly-allocated string that contains the color value for the * requested logical color. This can be used in the foreground attribute of * span elements in Pango markup. * * This function should be used to get the font color for Pango markup in * special use cases (e.g. GtkTreeView, mixed-content GtkLabel). If you * want to set a logical color directly on a widget, you can use * #hildon_helper_set_logical_color (from Hildon 2.2) for this. * * The return value should be freed with g_free() after use. **/ gchar * he_helper_get_logical_font_color (const gchar *name) { GdkColor color; GtkSettings *settings = gtk_settings_get_default(); GtkStyle *style = gtk_rc_get_style_by_paths(settings, "GtkButton", "osso-logical-colors", GTK_TYPE_BUTTON); if (gtk_style_lookup_color(style, name, &color)) { return gdk_color_to_string(&color); } else { return NULL; } }
static gboolean _lib_darktable_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_darktable_t *d = (dt_lib_darktable_t *)self->data; /* get the current style */ GtkStyle *style=gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL,"GtkWidget", GTK_TYPE_WIDGET); if(!style) style = gtk_rc_get_style(widget); cairo_t *cr = gdk_cairo_create(widget->window); /* fill background */ cairo_set_source_rgb(cr, style->bg[0].red/65535.0, style->bg[0].green/65535.0, style->bg[0].blue/65535.0); cairo_paint(cr); /* paint icon image */ cairo_set_source_surface(cr, d->image, 0, 7); cairo_rectangle(cr,0,0,48,48); cairo_fill(cr); /* create a pango layout and print fancy name/version string */ PangoLayout *layout; layout = gtk_widget_create_pango_layout (widget,NULL); pango_font_description_set_weight (style->font_desc, PANGO_WEIGHT_BOLD); pango_font_description_set_absolute_size (style->font_desc, 25 * PANGO_SCALE); pango_layout_set_font_description (layout,style->font_desc); pango_layout_set_text (layout,PACKAGE_NAME,-1); cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.5); cairo_move_to (cr, 42.0, 5.0); pango_cairo_show_layout (cr, layout); /* print version */ pango_font_description_set_absolute_size (style->font_desc, 10 * PANGO_SCALE); pango_layout_set_font_description (layout,style->font_desc); pango_layout_set_text (layout,PACKAGE_VERSION,-1); cairo_move_to (cr, 44.0, 30.0); cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.3); pango_cairo_show_layout (cr, layout); /* cleanup */ g_object_unref (layout); cairo_destroy(cr); return TRUE; }
static void set_logical_font (GtkWidget *button) { HeCheckButtonPrivate *priv = HE_CHECK_BUTTON_GET_PRIVATE (button); /* In buttons with vertical arrangement, the 'value' label uses a * different font */ if (GTK_IS_VBOX (priv->label_box)) { GtkStyle *style = gtk_rc_get_style_by_paths ( gtk_settings_get_default (), "SmallSystemFont", NULL, G_TYPE_NONE); if (style != NULL) { PangoFontDescription *font_desc = style->font_desc; if (font_desc != NULL) { priv->setting_style = TRUE; gtk_widget_modify_font (GTK_WIDGET (priv->value), font_desc); priv->setting_style = FALSE; } } } }
static void matekbd_indicator_config_load_colors (MatekbdIndicatorConfig * ind_config) { ind_config->foreground_color = g_settings_get_string (ind_config->settings, MATEKBD_INDICATOR_CONFIG_KEY_FOREGROUND_COLOR); if (ind_config->foreground_color == NULL || ind_config->foreground_color[0] == '\0') { GtkStyle *style = gtk_rc_get_style_by_paths (gtk_settings_get_default (), GTK_STYLE_PATH, GTK_STYLE_PATH, GTK_TYPE_LABEL); if (style != NULL) { ind_config->foreground_color = g_strdup_printf ("%g %g %g", ((double) style-> fg [GTK_STATE_NORMAL].red) / 0x10000, ((double) style-> fg [GTK_STATE_NORMAL].green) / 0x10000, ((double) style-> fg [GTK_STATE_NORMAL].blue) / 0x10000); } } ind_config->background_color = g_settings_get_string (ind_config->settings, MATEKBD_INDICATOR_CONFIG_KEY_BACKGROUND_COLOR); }
static gboolean _lib_navigation_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { const int inset = DT_NAVIGATION_INSET; int width = widget->allocation.width, height = widget->allocation.height; dt_develop_t *dev = darktable.develop; if (dev->preview_dirty) return FALSE; /* get the current style */ GtkStyle *style=gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL,"GtkWidget", GTK_TYPE_WIDGET); if(!style) style = gtk_rc_get_style(widget); cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); /* fill background */ cairo_set_source_rgb(cr, style->bg[0].red/65535.0, style->bg[0].green/65535.0, style->bg[0].blue/65535.0); cairo_paint(cr); width -= 2*inset; height -= 2*inset; cairo_translate(cr, inset, inset); /* draw navigation image if available */ if(dev->preview_pipe->backbuf && !dev->preview_dirty) { dt_pthread_mutex_t *mutex = &dev->preview_pipe->backbuf_mutex; dt_pthread_mutex_lock(mutex); const int wd = dev->preview_pipe->backbuf_width; const int ht = dev->preview_pipe->backbuf_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 (dev->preview_pipe->backbuf, 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); dt_pthread_mutex_unlock(mutex); // draw box where we are dt_dev_zoom_t zoom; int closeup; float zoom_x, zoom_y; DT_CTL_GET_GLOBAL(zoom, dev_zoom); DT_CTL_GET_GLOBAL(closeup, dev_closeup); DT_CTL_GET_GLOBAL(zoom_x, dev_zoom_x); DT_CTL_GET_GLOBAL(zoom_y, 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: if(cur_scale > min_scale+0.001) { 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, 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); } } /* blit memsurface into widget */ cairo_destroy(cr); cairo_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_surface (cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return TRUE; }
static void hildon_change_style_recursive_from_list (GtkWidget *widget, GtkStyle *prev_style, GSList *list) { g_assert (GTK_IS_WIDGET (widget)); /* Change the style for child widgets */ if (GTK_IS_CONTAINER (widget)) { GList *iterator, *children; children = gtk_container_get_children (GTK_CONTAINER (widget)); for (iterator = children; iterator != NULL; iterator = g_list_next (iterator)) hildon_change_style_recursive_from_list (GTK_WIDGET (iterator->data), prev_style, list); g_list_free (children); } /* gtk_widget_modify_*() emit "style_set" signals, so if we got here from "style_set" signal, we need to block this function from being called again or we get into inifinite loop. FIXME: Compiling with gcc > 3.3 and -pedantic won't allow conversion between function and object pointers. GLib API however requires an object pointer for a function, so we have to work around this. See http://bugzilla.gnome.org/show_bug.cgi?id=310175 */ G_GNUC_EXTENSION g_signal_handlers_block_matched (G_OBJECT (widget), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC, g_signal_lookup ("style_set", G_TYPE_FROM_INSTANCE (widget)), 0, NULL, (gpointer) hildon_change_style_recursive_from_list, NULL); /* We iterate over all list elements and apply each style * specification. */ GSList *iterator = list; while (iterator) { HildonLogicalElement *element = (HildonLogicalElement *) iterator->data; if (element->is_color == TRUE) { /* Changing logical color */ GdkColor color; gtk_widget_ensure_style (widget); if (gtk_style_lookup_color (widget->style, element->logical_color_name, &color) == TRUE) { switch (element->rc_flags) { case GTK_RC_FG: gtk_widget_modify_fg (widget, element->state, &color); break; case GTK_RC_BG: gtk_widget_modify_bg (widget, element->state, &color); break; case GTK_RC_TEXT: gtk_widget_modify_text (widget, element->state, &color); break; case GTK_RC_BASE: gtk_widget_modify_base (widget, element->state, &color); break; } } } else { /* Changing logical font */ GtkStyle *font_style = gtk_rc_get_style_by_paths (gtk_settings_get_default (), element->logical_font_name, NULL, G_TYPE_NONE); if (font_style != NULL) { PangoFontDescription *font_desc = font_style->font_desc; if (font_desc != NULL) gtk_widget_modify_font (widget, font_desc); } } iterator = iterator->next; } /* FIXME: Compilation workaround for gcc > 3.3 + -pedantic again */ G_GNUC_EXTENSION g_signal_handlers_unblock_matched (G_OBJECT (widget), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC, g_signal_lookup ("style_set", G_TYPE_FROM_INSTANCE (widget)), 0, NULL, (gpointer) hildon_change_style_recursive_from_list, NULL); }
static gboolean _gradient_slider_expose(GtkWidget *widget, GdkEventExpose *event) { GtkDarktableGradientSlider *gslider=DTGTK_GRADIENT_SLIDER(widget); assert(gslider->position > 0); g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(DTGTK_IS_GRADIENT_SLIDER(widget), FALSE); g_return_val_if_fail(event != NULL, FALSE); GtkStyle *style=gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL,"GtkButton", GTK_TYPE_BUTTON); if(!style) style = gtk_rc_get_style(widget); int state = gtk_widget_get_state(widget); /*int x = widget->allocation.x; int y = widget->allocation.y;*/ int width = widget->allocation.width; int height = widget->allocation.height; int margins = gslider->margins; // Begin cairo drawing cairo_t *cr; cr = gdk_cairo_create(widget->window); // First build the cairo gradient and then fill the gradient float gheight=height/2.0; float gwidth=width-2*margins; GList *current=NULL; cairo_pattern_t *gradient=NULL; if((current=g_list_first(gslider->colors)) != NULL) { gradient=cairo_pattern_create_linear(0,0,gwidth,gheight); do { _gradient_slider_stop_t *stop=(_gradient_slider_stop_t *)current->data; cairo_pattern_add_color_stop_rgb(gradient,stop->position,stop->color.red/65535.0,stop->color.green/65535.0,stop->color.blue/65535.0); } while((current=g_list_next(current))!=NULL); } if(gradient!=NULL) // Do we got a gradient, lets draw it { cairo_set_line_width(cr,0.1); cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND); cairo_set_source(cr,gradient); cairo_rectangle(cr,margins,(height-gheight)/2.0,gwidth,gheight); cairo_fill(cr); cairo_stroke(cr); } // Lets draw position arrows cairo_set_source_rgba(cr, style->fg[state].red/65535.0, style->fg[state].green/65535.0, style->fg[state].blue/65535.0, 1.0 ); // do we have a picker value to draw? gdouble *picker = gslider->picker; if(picker[0] >= 0.0 && picker[0] <= 1.0) { int vx_min=_scale_to_screen(widget, picker[1]); int vx_max=_scale_to_screen(widget, picker[2]); int vx_avg=_scale_to_screen(widget, picker[0]); cairo_set_source_rgba(cr, style->fg[state].red/65535.0, style->fg[state].green/65535.0, style->fg[state].blue/65535.0, 0.33 ); cairo_rectangle(cr,vx_min,(height-gheight)/2.0,fmax((float)vx_max-vx_min, 0.0f),gheight); cairo_fill(cr); cairo_set_source_rgba(cr, style->fg[state].red/65535.0, style->fg[state].green/65535.0, style->fg[state].blue/65535.0, 1.0 ); cairo_move_to(cr,vx_avg,(height-gheight)/2.0); cairo_line_to(cr,vx_avg,(height+gheight)/2.0); cairo_set_antialias(cr,CAIRO_ANTIALIAS_NONE); cairo_set_line_width(cr,1.0); cairo_stroke(cr); } int indirect[GRADIENT_SLIDER_MAX_POSITIONS]; for(int k=0; k<gslider->positions; k++) indirect[k] = gslider->selected == -1 ? k : (gslider->selected + 1 + k) % gslider->positions; for(int k=0; k<gslider->positions; k++) { int l = indirect[k]; int vx=_scale_to_screen(widget, gslider->position[l]); int mk=gslider->marker[l]; int sz=(mk & (1<<3)) ? 13 : 10; // big or small marker? if(l == gslider->selected && (gslider->is_entered == TRUE || gslider->is_dragging == TRUE)) { cairo_set_source_rgba(cr, style->fg[state].red/65535.0, style->fg[state].green/65535.0, style->fg[state].blue/65535.0 * 0.5, 1.0 ); } else { cairo_set_source_rgba(cr, style->fg[state].red/65535.0*0.8, style->fg[state].green/65535.0*0.8, style->fg[state].blue/65535.0*0.8, 1.0 ); } #if 0 if(sz < 10) { // supporting line for small markers cairo_move_to(cr,vx,2); cairo_line_to(cr,vx,height-2); cairo_set_antialias(cr,CAIRO_ANTIALIAS_NONE); cairo_set_line_width(cr,1.0); cairo_stroke(cr); } #endif cairo_set_antialias(cr,CAIRO_ANTIALIAS_DEFAULT); if(mk & 0x04) /* upper arrow */ { if (mk & 0x01) /* filled */ dtgtk_cairo_paint_solid_triangle(cr, vx-sz/2, sz < 10 ? 1 : -2,sz,sz,CPF_DIRECTION_DOWN); else dtgtk_cairo_paint_triangle(cr, vx-sz/2, sz < 10 ? 1 : -2,sz,sz,CPF_DIRECTION_DOWN); } if(mk & 0x02) /* lower arrow */ { if (mk & 0x01) /* filled */ dtgtk_cairo_paint_solid_triangle(cr, vx-sz/2,sz < 10 ? height-6 : height-11,sz,sz,CPF_DIRECTION_UP); else dtgtk_cairo_paint_triangle(cr, vx-sz/2,sz < 10 ? height-6 : height-11,sz,sz,CPF_DIRECTION_UP); } } cairo_destroy(cr); return FALSE; }
void nsLookAndFeel::InitLookAndFeel() { GtkStyle *style; // tooltip foreground and background style = gtk_rc_get_style_by_paths(gtk_settings_get_default(), "gtk-tooltips", "GtkWindow", GTK_TYPE_WINDOW); if (style) { sInfoBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]); sInfoText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]); } // menu foreground & menu background GtkWidget *accel_label = gtk_accel_label_new("M"); GtkWidget *menuitem = gtk_menu_item_new(); GtkWidget *menu = gtk_menu_new(); g_object_ref_sink(menu); gtk_container_add(GTK_CONTAINER(menuitem), accel_label); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); gtk_widget_set_style(accel_label, NULL); gtk_widget_set_style(menu, NULL); gtk_widget_realize(menu); gtk_widget_realize(accel_label); style = gtk_widget_get_style(accel_label); if (style) { sMenuText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]); } style = gtk_widget_get_style(menu); if (style) { sMenuBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]); } style = gtk_widget_get_style(menuitem); if (style) { sMenuHover = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_PRELIGHT]); sMenuHoverText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_PRELIGHT]); } g_object_unref(menu); // button styles GtkWidget *parent = gtk_fixed_new(); GtkWidget *button = gtk_button_new(); GtkWidget *label = gtk_label_new("M"); GtkWidget *combobox = gtk_combo_box_new(); GtkWidget *comboboxLabel = gtk_label_new("M"); GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP); GtkWidget *treeView = gtk_tree_view_new(); GtkWidget *linkButton = gtk_link_button_new("http://example.com/"); GtkWidget *menuBar = gtk_menu_bar_new(); GtkWidget *entry = gtk_entry_new(); gtk_container_add(GTK_CONTAINER(button), label); gtk_container_add(GTK_CONTAINER(combobox), comboboxLabel); gtk_container_add(GTK_CONTAINER(parent), button); gtk_container_add(GTK_CONTAINER(parent), treeView); gtk_container_add(GTK_CONTAINER(parent), linkButton); gtk_container_add(GTK_CONTAINER(parent), combobox); gtk_container_add(GTK_CONTAINER(parent), menuBar); gtk_container_add(GTK_CONTAINER(window), parent); gtk_container_add(GTK_CONTAINER(parent), entry); gtk_widget_set_style(button, NULL); gtk_widget_set_style(label, NULL); gtk_widget_set_style(treeView, NULL); gtk_widget_set_style(linkButton, NULL); gtk_widget_set_style(combobox, NULL); gtk_widget_set_style(comboboxLabel, NULL); gtk_widget_set_style(menuBar, NULL); gtk_widget_set_style(entry, NULL); gtk_widget_realize(button); gtk_widget_realize(label); gtk_widget_realize(treeView); gtk_widget_realize(linkButton); gtk_widget_realize(combobox); gtk_widget_realize(comboboxLabel); gtk_widget_realize(menuBar); gtk_widget_realize(entry); style = gtk_widget_get_style(label); if (style) { sButtonText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]); } style = gtk_widget_get_style(comboboxLabel); if (style) { sComboBoxText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]); } style = gtk_widget_get_style(combobox); if (style) { sComboBoxBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]); } style = gtk_widget_get_style(menuBar); if (style) { sMenuBarText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]); sMenuBarHoverText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_SELECTED]); } // Some themes have a unified menu bar, and support window dragging on it gboolean supports_menubar_drag = FALSE; GParamSpec *param_spec = gtk_widget_class_find_style_property(GTK_WIDGET_GET_CLASS(menuBar), "window-dragging"); if (param_spec) { if (g_type_is_a(G_PARAM_SPEC_VALUE_TYPE(param_spec), G_TYPE_BOOLEAN)) { gtk_widget_style_get(menuBar, "window-dragging", &supports_menubar_drag, NULL); } } sMenuSupportsDrag = supports_menubar_drag; // GTK's guide to fancy odd row background colors: // 1) Check if a theme explicitly defines an odd row color // 2) If not, check if it defines an even row color, and darken it // slightly by a hardcoded value (gtkstyle.c) // 3) If neither are defined, take the base background color and // darken that by a hardcoded value GdkColor colorValue; GdkColor *colorValuePtr = NULL; gtk_widget_style_get(treeView, "odd-row-color", &colorValuePtr, NULL); if (colorValuePtr) { colorValue = *colorValuePtr; } else { gtk_widget_style_get(treeView, "even-row-color", &colorValuePtr, NULL); if (colorValuePtr) darken_gdk_color(colorValuePtr, &colorValue); else darken_gdk_color(&treeView->style->base[GTK_STATE_NORMAL], &colorValue); } sOddCellBackground = GDK_COLOR_TO_NS_RGB(colorValue); if (colorValuePtr) gdk_color_free(colorValuePtr); style = gtk_widget_get_style(button); if (style) { sButtonBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]); sButtonOuterLightBorder = GDK_COLOR_TO_NS_RGB(style->light[GTK_STATE_NORMAL]); sButtonInnerDarkBorder = GDK_COLOR_TO_NS_RGB(style->dark[GTK_STATE_NORMAL]); } colorValuePtr = NULL; gtk_widget_style_get(linkButton, "link-color", &colorValuePtr, NULL); if (colorValuePtr) { colorValue = *colorValuePtr; // we can't pass deref pointers to GDK_COLOR_TO_NS_RGB sNativeHyperLinkText = GDK_COLOR_TO_NS_RGB(colorValue); gdk_color_free(colorValuePtr); } else { sNativeHyperLinkText = NS_RGB(0x00,0x00,0xEE); } // invisible character styles guint value; g_object_get (entry, "invisible-char", &value, NULL); sInvisibleCharacter = PRUnichar(value); // caret styles gtk_widget_style_get(entry, "cursor-aspect-ratio", &sCaretRatio, NULL); gtk_widget_destroy(window); }
static gboolean _lib_histogram_expose_callback(GtkWidget *widget, GdkEventExpose *event, 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; float *hist = dev->histogram; float hist_max = dev->histogram_max; const int inset = DT_HIST_INSET; int width = widget->allocation.width, height = widget->allocation.height; cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); GtkStyle *style=gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL,"GtkWidget", GTK_TYPE_WIDGET); if(!style) style = gtk_rc_get_style(widget); cairo_set_source_rgb(cr, style->bg[0].red/65535.0, style->bg[0].green/65535.0, style->bg[0].blue/65535.0); cairo_paint(cr); cairo_translate(cr, 4*inset, inset); width -= 2*4*inset; height -= 2*inset; #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); dt_draw_grid(cr, 4, 0, 0, width, height); if(hist_max > 0) { cairo_save(cr); // 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.); cairo_set_source_rgba(cr, 1., 0., 0., 0.2); dt_draw_histogram_8(cr, hist, 0); cairo_set_source_rgba(cr, 0., 1., 0., 0.2); dt_draw_histogram_8(cr, hist, 1); cairo_set_source_rgba(cr, 0., 0., 1., 0.2); dt_draw_histogram_8(cr, hist, 2); 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_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, .1*height); char exifline[50]; cairo_move_to (cr, .02*width, .98*height); dt_image_print_exif(&dev->image_storage, exifline, 50); cairo_show_text(cr, exifline); /*cairo_text_path(cr, exifline); cairo_fill_preserve(cr); cairo_set_line_width(cr, 1.0); cairo_set_source_rgb(cr, 0.3, 0.3, 0.3); cairo_stroke(cr);*/ cairo_destroy(cr); cairo_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_surface (cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return TRUE; }
static gboolean _lib_histogram_expose_callback(GtkWidget *widget, GdkEventExpose *event, 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; float *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; int width = widget->allocation.width, height = widget->allocation.height; cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); GtkStyle *style=gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL,"GtkWidget", GTK_TYPE_WIDGET); if(!style) style = gtk_rc_get_style(widget); cairo_set_source_rgb(cr, style->bg[0].red/65535.0, style->bg[0].green/65535.0, style->bg[0].blue/65535.0); cairo_paint(cr); 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) { 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); } if(d->green) { cairo_set_source_rgba(cr, 0., 1., 0., 0.2); dt_draw_histogram_8(cr, hist, 1, dev->histogram_type); } if(d->blue) { cairo_set_source_rgba(cr, 0., 0., 1., 0.2); dt_draw_histogram_8(cr, hist, 2, dev->histogram_type); } 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_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, .1*height); char exifline[50]; cairo_move_to (cr, .02*width, .98*height); dt_image_print_exif(&dev->image_storage, exifline, 50); cairo_save(cr); // cairo_show_text(cr, exifline); cairo_set_line_width(cr, 2.0); cairo_set_source_rgba(cr, 1, 1, 1, 0.3); cairo_text_path(cr, exifline); 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_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_surface (cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return TRUE; }
static gboolean _lib_navigation_expose_callback(GtkWidget *widget, GdkEventExpose *event, 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; if(dev->preview_status != DT_DEV_PIXELPIPE_VALID) return FALSE; /* get the current style */ GtkStyle *style = gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL, "GtkWidget", GTK_TYPE_WIDGET); if(!style) style = gtk_rc_get_style(widget); cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); /* fill background */ cairo_set_source_rgb(cr, style->bg[0].red / 65535.0, style->bg[0].green / 65535.0, style->bg[0].blue / 65535.0); cairo_paint(cr); width -= 2 * inset; height -= 2 * inset; cairo_translate(cr, inset, inset); /* draw navigation image if available */ if(dev->preview_pipe->backbuf && (dev->preview_status == DT_DEV_PIXELPIPE_VALID)) { dt_pthread_mutex_t *mutex = &dev->preview_pipe->backbuf_mutex; dt_pthread_mutex_lock(mutex); const int wd = dev->preview_pipe->backbuf_width; const int ht = dev->preview_pipe->backbuf_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(dev->preview_pipe->backbuf, 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); dt_pthread_mutex_unlock(mutex); // 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, 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); } if(fabsf(cur_scale - min_scale) > 0.001f) { /* Zoom % */ cairo_identity_matrix(cr); cairo_translate(cr, 0, height); cairo_set_source_rgba(cr, 1., 1., 1., 0.5); cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, DT_PIXEL_APPLY_DPI(11)); char zoomline[5]; snprintf(zoomline, sizeof(zoomline), "%.0f%%", cur_scale * 100); cairo_text_extents_t ext; cairo_text_extents(cr, zoomline, &ext); h = d->zoom_h = ext.height; w = d->zoom_w = ext.width; cairo_move_to(cr, width - w - h * 1.1, 0); cairo_save(cr); cairo_set_line_width(cr, 2.0); cairo_set_source_rgb(cr, style->bg[0].red / 65535.0, style->bg[0].green / 65535.0, style->bg[0].blue / 65535.0); cairo_text_path(cr, zoomline); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_fill(cr); cairo_restore(cr); } else { // draw the zoom-to-fit icon cairo_identity_matrix(cr); cairo_translate(cr, 0, height); cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_text_extents_t ext; cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, DT_PIXEL_APPLY_DPI(11)); cairo_text_extents(cr, "100%", &ext); // dummy text, just to get the height h = d->zoom_h = ext.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_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_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_surface(cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return TRUE; }
static gboolean _label_expose(GtkWidget *widget, GdkEventExpose *event) { g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(DTGTK_IS_LABEL(widget), FALSE); g_return_val_if_fail(event != NULL, FALSE); GtkStyle *style=gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL,"GtkButton", GTK_TYPE_BUTTON); if(!style) style = gtk_rc_get_style(widget); // uninitialized? if(style->depth == -1) return FALSE; int state = gtk_widget_get_state(widget); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int x = allocation.x; int y = allocation.y; int width = allocation.width; int height = allocation.height; // Formating the display of text and draw it... PangoLayout *layout; layout = gtk_widget_create_pango_layout(widget,NULL); pango_layout_set_font_description(layout,style->font_desc); const gchar *text=gtk_label_get_text(GTK_LABEL(widget)); pango_layout_set_text(layout,text,-1); GdkRectangle t= {x,y,x+width,y+height}; int pw,ph; pango_layout_get_pixel_size(layout,&pw,&ph); // Begin cairo drawing cairo_t *cr; cr = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_rgba(cr, /* style->fg[state].red/65535.0, style->fg[state].green/65535.0, style->fg[state].blue/65535.0,*/ 1,1,1, 0.10 ); cairo_set_antialias(cr,CAIRO_ANTIALIAS_NONE); cairo_set_line_width(cr,1.0); cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND); if( DTGTK_LABEL(widget)->flags&DARKTABLE_LABEL_UNDERLINED ) { cairo_move_to(cr,x,y+height-2); cairo_line_to(cr,x+width,y+height-2); cairo_stroke(cr); } else if( DTGTK_LABEL(widget)->flags&DARKTABLE_LABEL_BACKFILLED ) { cairo_rectangle(cr,x,y,width,height); cairo_fill(cr); } else if( DTGTK_LABEL(widget)->flags&DARKTABLE_LABEL_TAB ) { int rx=x,rw=pw+2; if( DTGTK_LABEL(widget)->flags&DARKTABLE_LABEL_ALIGN_RIGHT ) rx=x+width-pw-8; cairo_rectangle(cr,rx,y,rw+4,height-1); cairo_fill(cr); if( DTGTK_LABEL(widget)->flags&DARKTABLE_LABEL_ALIGN_RIGHT ) { // /| cairo_move_to(cr,x+width-rw-6,y); cairo_line_to(cr,x+width-rw-6-15,y+height-2); cairo_line_to(cr,x+width-rw-6,y+height-2); cairo_fill(cr); // hline cairo_move_to(cr,x,y+height-1); cairo_line_to(cr,x+width-rw-6,y+height-1); cairo_stroke(cr); } else { // | cairo_move_to(cr,x+rw+4,y); cairo_line_to(cr,x+rw+4+15,y+height-2); cairo_line_to(cr,x+rw+4,y+height-2); cairo_fill(cr); // hline cairo_move_to(cr,x+rw+4,y+height-1); cairo_line_to(cr,x+width,y+height-1); cairo_stroke(cr); } } cairo_set_antialias(cr,CAIRO_ANTIALIAS_DEFAULT); cairo_destroy(cr); // draw text int lx=x+4, ly=y+((height/2.0)-(ph/2.0)); if( DTGTK_LABEL(widget)->flags&DARKTABLE_LABEL_ALIGN_RIGHT ) lx=x+width-pw-6; else if( DTGTK_LABEL(widget)->flags&DARKTABLE_LABEL_ALIGN_CENTER ) lx=(width/2.0)-(pw/2.0); gtk_paint_layout(style, gtk_widget_get_window(widget), state,TRUE,&t,widget,"label",lx,ly,layout); return FALSE; }
static gboolean _slider_expose(GtkWidget *widget, GdkEventExpose *event) { g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(DTGTK_IS_SLIDER(widget), FALSE); g_return_val_if_fail(event != NULL, FALSE); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); if (allocation.width<=1) return FALSE; GtkStyle *style=gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL,"GtkButton", GTK_TYPE_BUTTON); if(!style) style = gtk_rc_get_style(widget); GtkDarktableSlider *slider=DTGTK_SLIDER(widget); int state = gtk_widget_get_state(widget); int width = allocation.width; int height = allocation.height; /* get value fill rectangle constraints*/ GdkRectangle vr; _slider_get_value_area(widget,&vr); /* create cairo context */ cairo_t *cr; cr = gdk_cairo_create(gtk_widget_get_window(widget)); /* hardcode state for the rest of control */ state = GTK_STATE_NORMAL; /* fill value rect */ gfloat value = gtk_adjustment_get_value(slider->adjustment); /* convert scale value to range 0.0-1.0*/ gfloat vscale = (value - gtk_adjustment_get_lower(slider->adjustment)) / (gtk_adjustment_get_upper(slider->adjustment) - gtk_adjustment_get_lower(slider->adjustment) ); cairo_set_source_rgba(cr, (style->fg[state].red/65535.0)*1.7, (style->fg[state].green/65535.0)*1.7, (style->fg[state].blue/65535.0)*1.7, 0.2 ); _slider_draw_rounded_rect(cr,vr.x,vr.y,vr.width*vscale,vr.height,3,1); /* setup font using family from style */ const gchar *font_family = pango_font_description_get_family(style->font_desc); cairo_select_font_face (cr, font_family, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_text_extents_t ext; /* Draw label */ cairo_set_source_rgba(cr, (style->text[state].red/65535.0)*1.7, (style->text[state].green/65535.0)*1.7, (style->text[state].blue/65535.0)*1.7, 0.8); gchar *label = (gchar *)g_object_get_data(G_OBJECT(widget),DTGTK_SLIDER_LABEL_KEY); if (label) { cairo_set_font_size(cr,vr.height*0.5); cairo_text_extents(cr, "j`", &ext); cairo_move_to(cr, vr.x+(DTGTK_SLIDER_BORDER_WIDTH*2),vr.y+ext.height); cairo_show_text(cr, label); /* store the size of the label. doing it in dtgtk_slider_set_label doesn't work as the widget isn't created yet. */ if(slider->labelwidth == 0 && slider->labelheight == 0) { cairo_text_extents(cr, label, &ext); slider->labelwidth = vr.x+(DTGTK_SLIDER_BORDER_WIDTH*2)+ext.width+(DTGTK_SLIDER_BORDER_WIDTH*2); slider->labelheight = vr.y+ext.height+(DTGTK_SLIDER_BORDER_WIDTH*2); } } /* Draw value unit */ gchar *unit = (gchar *)g_object_get_data (G_OBJECT(slider),DTGTK_SLIDER_VALUE_UNIT_KEY); cairo_set_font_size(cr,vr.height*0.45); cairo_text_extents(cr, "%%", &ext); int unitwidth = ext.width; if(unit) { cairo_move_to(cr, vr.x+vr.width-ext.width - (DTGTK_SLIDER_BORDER_WIDTH) ,vr.y+vr.height-(DTGTK_SLIDER_BORDER_WIDTH*2)); cairo_show_text(cr, unit); } /* Draw text value */ cairo_select_font_face (cr, font_family, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); char sv[32]= {0}; if (slider->force_sign) sprintf(sv,"%+.*f",slider->digits,value); else sprintf(sv,"%.*f",slider->digits,value); cairo_set_font_size(cr,vr.height*0.5); cairo_text_extents(cr, sv, &ext); cairo_move_to(cr, vr.x+vr.width-ext.width - unitwidth -(DTGTK_SLIDER_BORDER_WIDTH*3) ,vr.y+vr.height-(DTGTK_SLIDER_BORDER_WIDTH*2)); cairo_show_text(cr, sv); /* draw up/down arrows */ dtgtk_cairo_paint_arrow(cr, width-DTGTK_SLIDER_ADJUST_BUTTON_WIDTH-DTGTK_SLIDER_BORDER_WIDTH, DTGTK_SLIDER_BORDER_WIDTH*2, DTGTK_SLIDER_ADJUST_BUTTON_WIDTH, DTGTK_SLIDER_ADJUST_BUTTON_WIDTH-4, CPF_DIRECTION_UP); dtgtk_cairo_paint_arrow(cr, width-DTGTK_SLIDER_ADJUST_BUTTON_WIDTH-DTGTK_SLIDER_BORDER_WIDTH, height-DTGTK_SLIDER_ADJUST_BUTTON_WIDTH+4-DTGTK_SLIDER_BORDER_WIDTH*2, DTGTK_SLIDER_ADJUST_BUTTON_WIDTH, DTGTK_SLIDER_ADJUST_BUTTON_WIDTH-4, CPF_DIRECTION_DOWN); cairo_destroy(cr); return TRUE; }