static void _gradient_slider_realize(GtkWidget *widget) { GdkWindowAttr attributes; guint attributes_mask; g_return_if_fail(widget != NULL); g_return_if_fail(DTGTK_IS_GRADIENT_SLIDER(widget)); GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED); attributes.window_type = GDK_WINDOW_CHILD; attributes.x = widget->allocation.x; attributes.y = widget->allocation.y; attributes.width = 100; attributes.height = 17; attributes.wclass = GDK_INPUT_OUTPUT; attributes.event_mask = gtk_widget_get_events(widget) | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_POINTER_MOTION_MASK; attributes_mask = GDK_WA_X | GDK_WA_Y; widget->window = gdk_window_new( gtk_widget_get_parent_window (widget), & attributes, attributes_mask ); gdk_window_set_user_data(widget->window, widget); widget->style = gtk_style_attach(widget->style, widget->window); gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL); }
static void _gradient_slider_size_request(GtkWidget *widget,GtkRequisition *requisition) { g_return_if_fail(widget != NULL); g_return_if_fail(DTGTK_IS_GRADIENT_SLIDER(widget)); g_return_if_fail(requisition != NULL); requisition->width = 100; requisition->height = 17; }
static void _gradient_slider_destroy(GtkObject *object) { GtkDarktableGradientSliderClass *klass; g_return_if_fail(object != NULL); g_return_if_fail(DTGTK_IS_GRADIENT_SLIDER(object)); // TODO: Free colorentries klass = gtk_type_class(gtk_widget_get_type()); if (GTK_OBJECT_CLASS(klass)->destroy) { (* GTK_OBJECT_CLASS(klass)->destroy) (object); } }
static void _gradient_slider_destroy(GtkObject *object) { GtkDarktableGradientSliderClass *klass; g_return_if_fail(object != NULL); g_return_if_fail(DTGTK_IS_GRADIENT_SLIDER(object)); if(DTGTK_GRADIENT_SLIDER(object)->timeout_handle) g_source_remove(DTGTK_GRADIENT_SLIDER(object)->timeout_handle); DTGTK_GRADIENT_SLIDER(object)->timeout_handle = 0; if(DTGTK_GRADIENT_SLIDER(object)->colors) { g_list_foreach(DTGTK_GRADIENT_SLIDER(object)->colors, (GFunc)g_free, NULL); g_list_free(DTGTK_GRADIENT_SLIDER(object)->colors); DTGTK_GRADIENT_SLIDER(object)->colors = NULL; } klass = gtk_type_class(gtk_widget_get_type()); if (GTK_OBJECT_CLASS(klass)->destroy) { (* GTK_OBJECT_CLASS(klass)->destroy) (object); } }
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; }