sp-color-slider.cpp revision 57d4715f4806f2a8caac4bca519d878381a3356c
0N/A#define __SP_COLOR_SLIDER_C__
0N/A
0N/A/*
0N/A * A slider with colored background
0N/A *
0N/A * Author:
0N/A * Lauris Kaplinski <lauris@kaplinski.com>
0N/A * bulia byak <buliabyak@users.sf.net>
0N/A *
0N/A * Copyright (C) 2001-2002 Lauris Kaplinski
0N/A *
0N/A * This code is in public domain
0N/A */
0N/A
0N/A#include <gtk/gtkversion.h>
0N/A#include <gtk/gtksignal.h>
0N/A#include "sp-color-scales.h"
0N/A
0N/A#define SLIDER_WIDTH 96
0N/A#define SLIDER_HEIGHT 8
0N/A#define ARROW_SIZE 7
0N/A
0N/Aenum {
0N/A GRABBED,
763N/A DRAGGED,
0N/A RELEASED,
0N/A CHANGED,
0N/A LAST_SIGNAL
0N/A};
0N/A
0N/Astatic void sp_color_slider_class_init (SPColorSliderClass *klass);
204N/Astatic void sp_color_slider_init (SPColorSlider *slider);
204N/Astatic void sp_color_slider_destroy (GtkObject *object);
0N/A
0N/Astatic void sp_color_slider_realize (GtkWidget *widget);
0N/Astatic void sp_color_slider_size_request (GtkWidget *widget, GtkRequisition *requisition);
0N/Astatic void sp_color_slider_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
0N/A/* static void sp_color_slider_draw (GtkWidget *widget, GdkRectangle *area); */
112N/A/* static void sp_color_slider_draw_focus (GtkWidget *widget); */
0N/A/* static void sp_color_slider_draw_default (GtkWidget *widget); */
0N/A
0N/Astatic gint sp_color_slider_expose (GtkWidget *widget, GdkEventExpose *event);
0N/Astatic gint sp_color_slider_button_press (GtkWidget *widget, GdkEventButton *event);
0N/Astatic gint sp_color_slider_button_release (GtkWidget *widget, GdkEventButton *event);
763N/Astatic gint sp_color_slider_motion_notify (GtkWidget *widget, GdkEventMotion *event);
0N/A
0N/Astatic void sp_color_slider_adjustment_changed (GtkAdjustment *adjustment, SPColorSlider *slider);
0N/Astatic void sp_color_slider_adjustment_value_changed (GtkAdjustment *adjustment, SPColorSlider *slider);
0N/A
0N/Astatic void sp_color_slider_paint (SPColorSlider *slider, GdkRectangle *area);
0N/Astatic const guchar *sp_color_slider_render_gradient (gint x0, gint y0, gint width, gint height,
0N/A gint c[], gint dc[], guint b0, guint b1, guint mask);
0N/Astatic const guchar *sp_color_slider_render_map (gint x0, gint y0, gint width, gint height,
0N/A guchar *map, gint start, gint step, guint b0, guint b1, guint mask);
0N/A
0N/Astatic GtkWidgetClass *parent_class;
0N/Astatic guint slider_signals[LAST_SIGNAL] = {0};
0N/A
0N/AGtkType
0N/Asp_color_slider_get_type (void)
0N/A{
0N/A static GtkType type = 0;
0N/A if (!type) {
0N/A GtkTypeInfo info = {
0N/A (gchar*) "SPColorSlider",
0N/A sizeof (SPColorSlider),
0N/A sizeof (SPColorSliderClass),
0N/A (GtkClassInitFunc) sp_color_slider_class_init,
0N/A (GtkObjectInitFunc) sp_color_slider_init,
0N/A NULL, NULL, NULL
204N/A };
868N/A type = gtk_type_unique (GTK_TYPE_WIDGET, &info);
0N/A }
868N/A return type;
868N/A}
0N/A
0N/Astatic void
0N/Asp_color_slider_class_init (SPColorSliderClass *klass)
0N/A{
0N/A GtkObjectClass *object_class;
0N/A GtkWidgetClass *widget_class;
0N/A
0N/A object_class = (GtkObjectClass *) klass;
0N/A widget_class = (GtkWidgetClass *) klass;
0N/A
0N/A parent_class = (GtkWidgetClass*)gtk_type_class (GTK_TYPE_WIDGET);
0N/A
0N/A slider_signals[GRABBED] = gtk_signal_new ("grabbed",
0N/A (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
0N/A GTK_CLASS_TYPE(object_class),
0N/A GTK_SIGNAL_OFFSET (SPColorSliderClass, grabbed),
0N/A gtk_marshal_NONE__NONE,
868N/A GTK_TYPE_NONE, 0);
0N/A slider_signals[DRAGGED] = gtk_signal_new ("dragged",
0N/A (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
0N/A GTK_CLASS_TYPE(object_class),
112N/A GTK_SIGNAL_OFFSET (SPColorSliderClass, dragged),
112N/A gtk_marshal_NONE__NONE,
763N/A GTK_TYPE_NONE, 0);
763N/A slider_signals[RELEASED] = gtk_signal_new ("released",
763N/A (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
112N/A GTK_CLASS_TYPE(object_class),
112N/A GTK_SIGNAL_OFFSET (SPColorSliderClass, released),
112N/A gtk_marshal_NONE__NONE,
204N/A GTK_TYPE_NONE, 0);
204N/A slider_signals[CHANGED] = gtk_signal_new ("changed",
204N/A (GtkSignalRunType)(GTK_RUN_FIRST | GTK_RUN_NO_RECURSE),
204N/A GTK_CLASS_TYPE(object_class),
204N/A GTK_SIGNAL_OFFSET (SPColorSliderClass, changed),
204N/A gtk_marshal_NONE__NONE,
112N/A GTK_TYPE_NONE, 0);
112N/A
0N/A object_class->destroy = sp_color_slider_destroy;
0N/A
0N/A widget_class->realize = sp_color_slider_realize;
112N/A widget_class->size_request = sp_color_slider_size_request;
204N/A widget_class->size_allocate = sp_color_slider_size_allocate;
204N/A/* widget_class->draw = sp_color_slider_draw; */
0N/A/* widget_class->draw_focus = sp_color_slider_draw_focus; */
204N/A/* widget_class->draw_default = sp_color_slider_draw_default; */
204N/A
0N/A widget_class->expose_event = sp_color_slider_expose;
112N/A widget_class->button_press_event = sp_color_slider_button_press;
204N/A widget_class->button_release_event = sp_color_slider_button_release;
204N/A widget_class->motion_notify_event = sp_color_slider_motion_notify;
763N/A}
0N/A
0N/Astatic void
0N/Asp_color_slider_init (SPColorSlider *slider)
0N/A{
0N/A /* We are widget with window */
0N/A GTK_WIDGET_UNSET_FLAGS (slider, GTK_NO_WINDOW);
0N/A
0N/A slider->dragging = FALSE;
0N/A
0N/A slider->adjustment = NULL;
0N/A slider->value = 0.0;
0N/A
0N/A slider->c0[0] = 0x00;
556N/A slider->c0[1] = 0x00;
556N/A slider->c0[2] = 0x00;
556N/A slider->c0[3] = 0xff;
556N/A
0N/A slider->cm[0] = 0xff;
0N/A slider->cm[1] = 0x00;
0N/A slider->cm[2] = 0x00;
0N/A slider->cm[3] = 0xff;
0N/A
556N/A slider->c1[0] = 0xff;
556N/A slider->c1[1] = 0xff;
556N/A slider->c1[2] = 0xff;
556N/A slider->c1[3] = 0xff;
556N/A
0N/A slider->b0 = 0x5f;
0N/A slider->b1 = 0xa0;
556N/A slider->bmask = 0x08;
556N/A
0N/A slider->map = NULL;
0N/A}
0N/A
0N/Astatic void
0N/Asp_color_slider_destroy (GtkObject *object)
0N/A{
0N/A SPColorSlider *slider;
0N/A
0N/A slider = SP_COLOR_SLIDER (object);
0N/A
0N/A if (slider->adjustment) {
797N/A gtk_signal_disconnect_by_data (GTK_OBJECT (slider->adjustment), slider);
0N/A gtk_object_unref (GTK_OBJECT (slider->adjustment));
797N/A slider->adjustment = NULL;
797N/A }
797N/A
797N/A if (((GtkObjectClass *) (parent_class))->destroy)
797N/A (* ((GtkObjectClass *) (parent_class))->destroy) (object);
797N/A}
797N/A
0N/Astatic void
797N/Asp_color_slider_realize (GtkWidget *widget)
797N/A{
797N/A SPColorSlider *slider;
797N/A GdkWindowAttr attributes;
797N/A gint attributes_mask;
797N/A
797N/A slider = SP_COLOR_SLIDER (widget);
797N/A
797N/A GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
0N/A
0N/A attributes.window_type = GDK_WINDOW_CHILD;
797N/A attributes.x = widget->allocation.x;
797N/A attributes.y = widget->allocation.y;
797N/A attributes.width = widget->allocation.width;
797N/A attributes.height = widget->allocation.height;
797N/A attributes.wclass = GDK_INPUT_OUTPUT;
0N/A attributes.visual = gdk_rgb_get_visual ();
797N/A attributes.colormap = gdk_rgb_get_cmap ();
0N/A attributes.event_mask = gtk_widget_get_events (widget);
797N/A attributes.event_mask |= (GDK_EXPOSURE_MASK |
0N/A GDK_BUTTON_PRESS_MASK |
797N/A GDK_BUTTON_RELEASE_MASK |
797N/A GDK_POINTER_MOTION_MASK |
797N/A GDK_ENTER_NOTIFY_MASK |
797N/A GDK_LEAVE_NOTIFY_MASK);
797N/A attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
797N/A
797N/A widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
797N/A gdk_window_set_user_data (widget->window, widget);
0N/A
797N/A widget->style = gtk_style_attach (widget->style, widget->window);
797N/A}
0N/A
797N/Astatic void
797N/Asp_color_slider_size_request (GtkWidget *widget, GtkRequisition *requisition)
797N/A{
797N/A SPColorSlider *slider;
797N/A
797N/A slider = SP_COLOR_SLIDER (widget);
797N/A
797N/A requisition->width = SLIDER_WIDTH + widget->style->xthickness * 2;
797N/A requisition->height = SLIDER_HEIGHT + widget->style->ythickness * 2;
797N/A}
797N/A
797N/Astatic void
0N/Asp_color_slider_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
797N/A{
536N/A SPColorSlider *slider;
797N/A
0N/A slider = SP_COLOR_SLIDER (widget);
800N/A
797N/A widget->allocation = *allocation;
797N/A
800N/A if (GTK_WIDGET_REALIZED (widget)) {
797N/A /* Resize GdkWindow */
0N/A gdk_window_move_resize (widget->window, allocation->x, allocation->y, allocation->width, allocation->height);
0N/A }
797N/A}
0N/A
797N/Astatic gint
536N/Asp_color_slider_expose (GtkWidget *widget, GdkEventExpose *event)
797N/A{
797N/A SPColorSlider *slider;
797N/A
797N/A slider = SP_COLOR_SLIDER (widget);
797N/A
797N/A if (GTK_WIDGET_DRAWABLE (widget)) {
797N/A gint width, height;
797N/A width = widget->allocation.width;
797N/A height = widget->allocation.height;
797N/A sp_color_slider_paint (slider, &event->area);
797N/A }
0N/A
797N/A return FALSE;
797N/A}
797N/A
797N/Astatic gint
797N/Asp_color_slider_button_press (GtkWidget *widget, GdkEventButton *event)
797N/A{
797N/A SPColorSlider *slider;
797N/A
797N/A slider = SP_COLOR_SLIDER (widget);
797N/A
797N/A if (event->button == 1) {
797N/A gint cx, cw;
797N/A cx = widget->style->xthickness;
797N/A cw = widget->allocation.width - 2 * cx;
797N/A gtk_signal_emit (GTK_OBJECT (slider), slider_signals[GRABBED]);
797N/A slider->dragging = TRUE;
797N/A slider->oldvalue = slider->value;
797N/A ColorScales::setScaled( slider->adjustment, CLAMP ((gfloat) (event->x - cx) / cw, 0.0, 1.0) );
797N/A gtk_signal_emit (GTK_OBJECT (slider), slider_signals[DRAGGED]);
800N/A gdk_pointer_grab (widget->window, FALSE,
800N/A (GdkEventMask)(GDK_POINTER_MOTION_MASK |
797N/A GDK_BUTTON_RELEASE_MASK),
797N/A NULL, NULL, event->time);
0N/A }
0N/A
797N/A return FALSE;
797N/A}
0N/A
797N/Astatic gint
797N/Asp_color_slider_button_release (GtkWidget *widget, GdkEventButton *event)
797N/A{
797N/A SPColorSlider *slider;
797N/A
797N/A slider = SP_COLOR_SLIDER (widget);
797N/A
797N/A if (event->button == 1) {
0N/A gdk_pointer_ungrab (event->time);
797N/A slider->dragging = FALSE;
797N/A gtk_signal_emit (GTK_OBJECT (slider), slider_signals[RELEASED]);
797N/A if (slider->value != slider->oldvalue) gtk_signal_emit (GTK_OBJECT (slider), slider_signals[CHANGED]);
797N/A }
797N/A
0N/A return FALSE;
797N/A}
797N/A
797N/Astatic gint
797N/Asp_color_slider_motion_notify (GtkWidget *widget, GdkEventMotion *event)
797N/A{
763N/A SPColorSlider *slider;
797N/A
797N/A slider = SP_COLOR_SLIDER (widget);
797N/A
797N/A if (slider->dragging) {
797N/A gint cx, cw;
797N/A cx = widget->style->xthickness;
797N/A cw = widget->allocation.width - 2 * cx;
797N/A ColorScales::setScaled( slider->adjustment, CLAMP ((gfloat) (event->x - cx) / cw, 0.0, 1.0) );
0N/A gtk_signal_emit (GTK_OBJECT (slider), slider_signals[DRAGGED]);
797N/A }
0N/A
797N/A return FALSE;
797N/A}
797N/A
797N/AGtkWidget *
797N/Asp_color_slider_new (GtkAdjustment *adjustment)
797N/A{
0N/A SPColorSlider *slider;
797N/A
797N/A slider = (SPColorSlider*)gtk_type_new (SP_TYPE_COLOR_SLIDER);
797N/A
797N/A sp_color_slider_set_adjustment (slider, adjustment);
797N/A
0N/A return GTK_WIDGET (slider);
797N/A}
0N/A
797N/Avoid
797N/Asp_color_slider_set_adjustment (SPColorSlider *slider, GtkAdjustment *adjustment)
868N/A{
868N/A g_return_if_fail (slider != NULL);
868N/A g_return_if_fail (SP_IS_COLOR_SLIDER (slider));
868N/A
797N/A if (!adjustment) {
797N/A adjustment = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, 1.0, 0.01, 0.0, 0.0);
0N/A }
0N/A#if GTK_CHECK_VERSION (2,14,0)
556N/A else {
556N/A gtk_adjustment_set_page_increment(adjustment, 0.0);
556N/A gtk_adjustment_set_page_size(adjustment, 0.0);
556N/A }
556N/A#endif
556N/A
556N/A if (slider->adjustment != adjustment) {
556N/A if (slider->adjustment) {
556N/A gtk_signal_disconnect_by_data (GTK_OBJECT (slider->adjustment), slider);
0N/A gtk_object_unref (GTK_OBJECT (slider->adjustment));
0N/A }
0N/A
0N/A slider->adjustment = adjustment;
0N/A gtk_object_ref (GTK_OBJECT (adjustment));
0N/A gtk_object_sink (GTK_OBJECT (adjustment));
0N/A
0N/A gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
0N/A GTK_SIGNAL_FUNC (sp_color_slider_adjustment_changed), slider);
0N/A gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
0N/A GTK_SIGNAL_FUNC (sp_color_slider_adjustment_value_changed), slider);
0N/A
0N/A slider->value = ColorScales::getScaled( adjustment );
0N/A
0N/A sp_color_slider_adjustment_changed (adjustment, slider);
0N/A }
0N/A}
0N/A
0N/Avoid
0N/Asp_color_slider_set_colors (SPColorSlider *slider, guint32 start, guint32 mid, guint32 end)
0N/A{
0N/A g_return_if_fail (slider != NULL);
0N/A g_return_if_fail (SP_IS_COLOR_SLIDER (slider));
0N/A
0N/A // Remove any map, if set
0N/A slider->map = 0;
0N/A
0N/A slider->c0[0] = start >> 24;
0N/A slider->c0[1] = (start >> 16) & 0xff;
0N/A slider->c0[2] = (start >> 8) & 0xff;
0N/A slider->c0[3] = start & 0xff;
0N/A
0N/A slider->cm[0] = mid >> 24;
0N/A slider->cm[1] = (mid >> 16) & 0xff;
0N/A slider->cm[2] = (mid >> 8) & 0xff;
0N/A slider->cm[3] = mid & 0xff;
0N/A
0N/A slider->c1[0] = end >> 24;
0N/A slider->c1[1] = (end >> 16) & 0xff;
0N/A slider->c1[2] = (end >> 8) & 0xff;
0N/A slider->c1[3] = end & 0xff;
0N/A
0N/A gtk_widget_queue_draw (GTK_WIDGET (slider));
0N/A}
0N/A
0N/Avoid
0N/Asp_color_slider_set_map (SPColorSlider *slider, const guchar *map)
0N/A{
0N/A g_return_if_fail (slider != NULL);
0N/A g_return_if_fail (SP_IS_COLOR_SLIDER (slider));
0N/A
0N/A slider->map = (guchar *) map;
0N/A
0N/A gtk_widget_queue_draw (GTK_WIDGET (slider));
0N/A}
0N/A
0N/Avoid
0N/Asp_color_slider_set_background (SPColorSlider *slider, guint dark, guint light, guint size)
0N/A{
0N/A g_return_if_fail (slider != NULL);
0N/A g_return_if_fail (SP_IS_COLOR_SLIDER (slider));
0N/A
0N/A slider->b0 = dark;
0N/A slider->b1 = light;
0N/A slider->bmask = size;
0N/A
0N/A gtk_widget_queue_draw (GTK_WIDGET (slider));
0N/A}
0N/A
0N/Astatic void
0N/Asp_color_slider_adjustment_changed (GtkAdjustment */*adjustment*/, SPColorSlider *slider)
0N/A{
0N/A gtk_widget_queue_draw (GTK_WIDGET (slider));
0N/A}
0N/A
0N/Astatic void
0N/Asp_color_slider_adjustment_value_changed (GtkAdjustment *adjustment, SPColorSlider *slider)
0N/A{
0N/A GtkWidget *widget;
0N/A
0N/A widget = GTK_WIDGET (slider);
0N/A
0N/A if (slider->value != ColorScales::getScaled( adjustment )) {
0N/A gint cx, cy, cw, ch;
0N/A cx = widget->style->xthickness;
0N/A cy = widget->style->ythickness;
0N/A cw = widget->allocation.width - 2 * cx;
0N/A ch = widget->allocation.height - 2 * cy;
0N/A if ((gint) (ColorScales::getScaled( adjustment ) * cw) != (gint) (slider->value * cw)) {
0N/A gint ax, ay;
0N/A gfloat value;
0N/A value = slider->value;
0N/A slider->value = ColorScales::getScaled( adjustment );
0N/A ax = (int)(cx + value * cw - ARROW_SIZE / 2 - 2);
0N/A ay = cy;
0N/A gtk_widget_queue_draw_area (widget, ax, ay, ARROW_SIZE + 4, ch);
0N/A ax = (int)(cx + slider->value * cw - ARROW_SIZE / 2 - 2);
0N/A ay = cy;
0N/A gtk_widget_queue_draw_area (widget, ax, ay, ARROW_SIZE + 4, ch);
0N/A } else {
0N/A slider->value = ColorScales::getScaled( adjustment );
0N/A }
0N/A }
0N/A}
0N/A
0N/Astatic void
0N/Asp_color_slider_paint (SPColorSlider *slider, GdkRectangle *area)
0N/A{
0N/A GtkWidget *widget;
0N/A GdkRectangle warea, carea, aarea;
0N/A GdkRectangle wpaint, cpaint, apaint;
0N/A const guchar *b;
0N/A gint w, x, y1, y2;
0N/A
0N/A widget = GTK_WIDGET (slider);
0N/A
0N/A /* Widget area */
0N/A warea.x = 0;
0N/A warea.y = 0;
0N/A warea.width = widget->allocation.width;
0N/A warea.height = widget->allocation.height;
0N/A
0N/A /* Color gradient area */
0N/A carea.x = widget->style->xthickness;
0N/A carea.y = widget->style->ythickness;
0N/A carea.width = widget->allocation.width - 2 * carea.x;
0N/A carea.height = widget->allocation.height - 2 * carea.y;
0N/A
0N/A /* Arrow area */
0N/A aarea.x = (int)(slider->value * (carea.width - 1) - ARROW_SIZE / 2 + carea.x);
0N/A aarea.width = ARROW_SIZE;
0N/A aarea.y = carea.y;
0N/A aarea.height = carea.height;
0N/A
763N/A /* Actual paintable area */
763N/A if (!gdk_rectangle_intersect (area, &warea, &wpaint)) return;
763N/A
763N/A b = NULL;
763N/A
763N/A /* Paintable part of color gradient area */
763N/A if (gdk_rectangle_intersect (area, &carea, &cpaint)) {
763N/A if (slider->map) {
763N/A gint s, d;
763N/A /* Render map pixelstore */
763N/A d = (1024 << 16) / carea.width;
763N/A s = (cpaint.x - carea.x) * d;
0N/A b = sp_color_slider_render_map (cpaint.x - carea.x, cpaint.y - carea.y, cpaint.width, cpaint.height,
0N/A slider->map, s, d,
0N/A slider->b0, slider->b1, slider->bmask);
0N/A if (b != NULL) {
0N/A gdk_draw_rgb_image (widget->window, widget->style->black_gc,
0N/A cpaint.x, cpaint.y,
0N/A cpaint.width, cpaint.height,
204N/A GDK_RGB_DITHER_MAX,
0N/A (guchar *) b, cpaint.width * 3);
0N/A }
0N/A
0N/A } else {
0N/A gint c[4], dc[4];
0N/A gint i;
0N/A /* Render gradient */
0N/A
0N/A // part 1: from c0 to cm
0N/A if ((cpaint.x - carea.x) <= carea.width/2) {
0N/A for (i = 0; i < 4; i++) {
0N/A c[i] = slider->c0[i] << 16;
0N/A dc[i] = ((slider->cm[i] << 16) - c[i]) / (carea.width/2);
0N/A c[i] += (cpaint.x - carea.x) * dc[i];
0N/A }
0N/A guint wi = MIN(cpaint.x - carea.x + cpaint.width, carea.width/2) - (cpaint.x - carea.x);
0N/A b = sp_color_slider_render_gradient (cpaint.x - carea.x, cpaint.y - carea.y, wi, cpaint.height,
0N/A c, dc,
204N/A slider->b0, slider->b1, slider->bmask);
204N/A
204N/A /* Draw pixelstore */
204N/A if (b != NULL) {
204N/A gdk_draw_rgb_image (widget->window, widget->style->black_gc,
204N/A cpaint.x, cpaint.y,
204N/A wi, cpaint.height,
204N/A GDK_RGB_DITHER_MAX,
204N/A (guchar *) b, wi * 3);
204N/A }
204N/A }
204N/A
204N/A // part 2: from cm to c1
204N/A if ((cpaint.x - carea.x + cpaint.width) > carea.width/2) {
204N/A for (i = 0; i < 4; i++) {
204N/A c[i] = slider->cm[i] << 16;
204N/A dc[i] = ((slider->c1[i] << 16) - c[i]) / (carea.width/2);
204N/A if ((cpaint.x - carea.x) > carea.width/2)
204N/A c[i] += (cpaint.x - carea.x - carea.width/2) * dc[i];
204N/A }
204N/A guint wi = cpaint.width - MAX(0, (carea.width/2 - (cpaint.x - carea.x)));
204N/A b = sp_color_slider_render_gradient (MAX(cpaint.x - carea.x, carea.width/2), cpaint.y - carea.y, wi, cpaint.height,
204N/A c, dc,
204N/A slider->b0, slider->b1, slider->bmask);
204N/A
204N/A /* Draw pixelstore */
204N/A if (b != NULL) {
204N/A gdk_draw_rgb_image (widget->window, widget->style->black_gc,
204N/A MAX(cpaint.x, carea.width/2 + carea.x), cpaint.y,
204N/A wi, cpaint.height,
204N/A GDK_RGB_DITHER_MAX,
204N/A (guchar *) b, wi * 3);
204N/A }
204N/A }
204N/A }
204N/A }
204N/A
204N/A /* Draw shadow */
204N/A gtk_paint_shadow (widget->style, widget->window,
204N/A (GtkStateType)widget->state, GTK_SHADOW_IN,
204N/A area, widget, "colorslider",
204N/A 0, 0,
204N/A warea.width, warea.height);
0N/A
0N/A
0N/A if (gdk_rectangle_intersect (area, &aarea, &apaint)) {
0N/A /* Draw arrow */
0N/A gdk_rectangle_intersect (&carea, &apaint, &apaint);
0N/A gdk_gc_set_clip_rectangle (widget->style->white_gc, &apaint);
536N/A gdk_gc_set_clip_rectangle (widget->style->black_gc, &apaint);
556N/A
536N/A x = aarea.x;
536N/A y1 = carea.y;
536N/A y2 = aarea.y + aarea.height - 1;
536N/A w = aarea.width;
536N/A while ( w > 0 )
536N/A {
536N/A gdk_draw_line (widget->window, widget->style->white_gc, x, y1, x + w - 1, y1 );
536N/A gdk_draw_line (widget->window, widget->style->white_gc, x, y2, x + w - 1, y2 );
536N/A w -=2;
536N/A x++;
536N/A if ( w > 0 )
536N/A {
536N/A gdk_draw_line (widget->window, widget->style->black_gc, x, y1, x + w - 1, y1 );
536N/A gdk_draw_line (widget->window, widget->style->black_gc, x, y2, x + w - 1, y2 );
536N/A }
763N/A y1++;
536N/A y2--;
536N/A }
536N/A
536N/A gdk_gc_set_clip_rectangle (widget->style->white_gc, NULL);
536N/A gdk_gc_set_clip_rectangle (widget->style->black_gc, NULL);
536N/A }
536N/A}
867N/A
536N/A/* Colors are << 16 */
536N/A
536N/Astatic const guchar *
536N/Asp_color_slider_render_gradient (gint x0, gint y0, gint width, gint height,
536N/A gint c[], gint dc[], guint b0, guint b1, guint mask)
536N/A{
536N/A static guchar *buf = NULL;
536N/A static gint bs = 0;
536N/A guchar *dp;
536N/A gint x, y;
536N/A guint r, g, b, a;
536N/A
536N/A if (buf && (bs < width * height)) {
536N/A g_free (buf);
0N/A buf = NULL;
0N/A }
0N/A if (!buf) {
536N/A buf = g_new (guchar, width * height * 3);
536N/A bs = width * height;
536N/A }
0N/A
0N/A dp = buf;
0N/A r = c[0];
0N/A g = c[1];
536N/A b = c[2];
536N/A a = c[3];
536N/A for (x = x0; x < x0 + width; x++) {
536N/A gint cr, cg, cb, ca;
536N/A guchar *d;
536N/A cr = r >> 16;
536N/A cg = g >> 16;
536N/A cb = b >> 16;
536N/A ca = a >> 16;
536N/A d = dp;
536N/A for (y = y0; y < y0 + height; y++) {
536N/A guint bg, fc;
536N/A /* Background value */
536N/A bg = ((x & mask) ^ (y & mask)) ? b0 : b1;
536N/A fc = (cr - bg) * ca;
536N/A d[0] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
536N/A fc = (cg - bg) * ca;
536N/A d[1] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
536N/A fc = (cb - bg) * ca;
536N/A d[2] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
536N/A d += 3 * width;
536N/A }
536N/A r += dc[0];
536N/A g += dc[1];
536N/A b += dc[2];
536N/A a += dc[3];
536N/A dp += 3;
536N/A }
536N/A
536N/A return buf;
536N/A}
536N/A
536N/A/* Positions are << 16 */
536N/A
536N/Astatic const guchar *
536N/Asp_color_slider_render_map (gint x0, gint y0, gint width, gint height,
536N/A guchar *map, gint start, gint step, guint b0, guint b1, guint mask)
536N/A{
536N/A static guchar *buf = NULL;
536N/A static gint bs = 0;
536N/A guchar *dp, *sp;
536N/A gint x, y;
536N/A
536N/A if (buf && (bs < width * height)) {
536N/A g_free (buf);
536N/A buf = NULL;
536N/A }
536N/A if (!buf) {
536N/A buf = g_new (guchar, width * height * 3);
536N/A bs = width * height;
536N/A }
536N/A
536N/A dp = buf;
536N/A for (x = x0; x < x0 + width; x++) {
551N/A gint cr, cg, cb, ca;
536N/A guchar *d;
536N/A sp = map + 4 * (start >> 16);
536N/A cr = *sp++;
536N/A cg = *sp++;
0N/A cb = *sp++;
0N/A ca = *sp++;
0N/A d = dp;
536N/A for (y = y0; y < y0 + height; y++) {
0N/A guint bg, fc;
0N/A /* Background value */
0N/A bg = ((x & mask) ^ (y & mask)) ? b0 : b1;
0N/A fc = (cr - bg) * ca;
0N/A d[0] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
536N/A fc = (cg - bg) * ca;
0N/A d[1] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
0N/A fc = (cb - bg) * ca;
0N/A d[2] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
0N/A d += 3 * width;
0N/A }
536N/A dp += 3;
536N/A start += step;
536N/A }
536N/A
536N/A return buf;
536N/A}
536N/A
536N/A