X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkcolorscale.c;h=88e4459b59441b8886d0cb51f86ec27670d5d674;hb=b2340254109d8599244c875fe7bc5e234f64da08;hp=7cfa5a03bced928fb80c1774f953ed36bc34b984;hpb=19da38b8117ced88999f20af74a270c8afa163e6;p=~andy%2Fgtk diff --git a/gtk/gtkcolorscale.c b/gtk/gtkcolorscale.c index 7cfa5a03b..88e4459b5 100644 --- a/gtk/gtkcolorscale.c +++ b/gtk/gtkcolorscale.c @@ -12,9 +12,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ #include "config.h" @@ -26,15 +24,20 @@ #include "gtkorientable.h" #include "gtkstylecontext.h" #include "gtkaccessible.h" +#include "gtkpressandholdprivate.h" #include "gtkprivate.h" #include "gtkintl.h" +#include + struct _GtkColorScalePrivate { cairo_surface_t *surface; gint width, height; GdkRGBA color; GtkColorScaleType type; + + GtkPressAndHold *press_and_hold; }; enum @@ -45,6 +48,57 @@ enum G_DEFINE_TYPE (GtkColorScale, gtk_color_scale, GTK_TYPE_SCALE) +static void +gtk_color_scale_get_trough_size (GtkColorScale *scale, + gint *x_offset_out, + gint *y_offset_out, + gint *width_out, + gint *height_out) +{ + GtkWidget *widget = GTK_WIDGET (scale); + gint width, height, focus_line_width, focus_padding; + gint x_offset, y_offset; + gint slider_width, slider_height; + + gtk_widget_style_get (widget, + "focus-line-width", &focus_line_width, + "focus-padding", &focus_padding, + "slider-width", &slider_width, + "slider-length", &slider_height, + NULL); + + width = gtk_widget_get_allocated_width (widget) - 2 * (focus_line_width + focus_padding); + height = gtk_widget_get_allocated_height (widget) - 2 * (focus_line_width + focus_padding); + + x_offset = focus_line_width + focus_padding; + y_offset = focus_line_width + focus_padding; + + /* if the slider has a vertical shape, draw the trough asymmetric */ + if (slider_width > slider_height) + { + if (gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)) == GTK_ORIENTATION_VERTICAL) + { + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) + x_offset += (gint) floor (slider_width / 2.0); + + width = (gint) floor (slider_width / 2.0); + } + else + { + height = (gint) floor (slider_width / 2.0); + } + } + + if (width_out) + *width_out = width; + if (height_out) + *height_out = height; + if (x_offset_out) + *x_offset_out = x_offset; + if (y_offset_out) + *y_offset_out = y_offset; +} + static void create_surface (GtkColorScale *scale) { @@ -55,8 +109,9 @@ create_surface (GtkColorScale *scale) if (!gtk_widget_get_realized (widget)) return; - width = gtk_widget_get_allocated_width (widget); - height = gtk_widget_get_allocated_height (widget); + gtk_color_scale_get_trough_size (scale, + NULL, NULL, + &width, &height); if (!scale->priv->surface || width != scale->priv->width || @@ -151,54 +206,23 @@ create_surface (GtkColorScale *scale) } } -static gboolean -scale_has_asymmetric_thumb (GtkWidget *widget) -{ - gchar *theme; - gboolean res; - - g_object_get (gtk_widget_get_settings (widget), - "gtk-theme-name", &theme, - NULL); - res = strcmp ("Adwaita", theme) == 0; - g_free (theme); - - return res; -} - static gboolean scale_draw (GtkWidget *widget, cairo_t *cr) { GtkColorScale *scale = GTK_COLOR_SCALE (widget); - gint width, height; + gint width, height, x_offset, y_offset; cairo_pattern_t *pattern; - width = gtk_widget_get_allocated_width (widget); - height = gtk_widget_get_allocated_height (widget); - create_surface (scale); + gtk_color_scale_get_trough_size (scale, + &x_offset, &y_offset, + &width, &height); cairo_save (cr); + cairo_translate (cr, x_offset, y_offset); + cairo_rectangle (cr, 0, 0, width, height); - if (scale_has_asymmetric_thumb (widget)) - { - if (gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)) == GTK_ORIENTATION_VERTICAL) - { - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - cairo_rectangle (cr, 1, 1, width / 2 - 1, height - 2); - else - cairo_rectangle (cr, width / 2, 1, width / 2 - 1, height - 2); - } - else - { - cairo_rectangle (cr, 1, 1, width - 2, height / 2); - } - } - else - cairo_rectangle (cr, 1, 1, width - 2, height - 2); - - cairo_clip (cr); pattern = cairo_pattern_create_for_surface (scale->priv->surface); if (gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)) == GTK_ORIENTATION_HORIZONTAL && gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) @@ -210,7 +234,7 @@ scale_draw (GtkWidget *widget, cairo_pattern_set_matrix (pattern, &matrix); } cairo_set_source (cr, pattern); - cairo_paint (cr); + cairo_fill (cr); cairo_pattern_destroy (pattern); @@ -227,6 +251,7 @@ gtk_color_scale_init (GtkColorScale *scale) scale->priv = G_TYPE_INSTANCE_GET_PRIVATE (scale, GTK_TYPE_COLOR_SCALE, GtkColorScalePrivate); + gtk_widget_add_events (GTK_WIDGET (scale), GDK_TOUCH_MASK); } static void @@ -237,6 +262,8 @@ scale_finalize (GObject *object) if (scale->priv->surface) cairo_surface_destroy (scale->priv->surface); + g_clear_object (&scale->priv->press_and_hold); + G_OBJECT_CLASS (gtk_color_scale_parent_class)->finalize (object); } @@ -297,6 +324,48 @@ scale_set_property (GObject *object, } } +static void +hold_action (GtkPressAndHold *pah, + gint x, + gint y, + GtkColorScale *scale) +{ + gboolean handled; + + g_signal_emit_by_name (scale, "popup-menu", &handled); +} + +static gboolean +scale_touch (GtkWidget *widget, + GdkEventTouch *event) +{ + GtkColorScale *scale = GTK_COLOR_SCALE (widget); + + if (!scale->priv->press_and_hold) + { + gint drag_threshold; + + g_object_get (gtk_widget_get_settings (widget), + "gtk-dnd-drag-threshold", &drag_threshold, + NULL); + + scale->priv->press_and_hold = gtk_press_and_hold_new (); + + g_object_set (scale->priv->press_and_hold, + "drag-threshold", drag_threshold, + "hold-time", 1000, + NULL); + + g_signal_connect (scale->priv->press_and_hold, "hold", + G_CALLBACK (hold_action), scale); + } + + gtk_press_and_hold_process_event (scale->priv->press_and_hold, (GdkEvent *)event); + + return GTK_WIDGET_CLASS (gtk_color_scale_parent_class)->touch_event (widget, event); +} + + static void gtk_color_scale_class_init (GtkColorScaleClass *class) { @@ -308,6 +377,7 @@ gtk_color_scale_class_init (GtkColorScaleClass *class) object_class->set_property = scale_set_property; widget_class->draw = scale_draw; + widget_class->touch_event = scale_touch; g_object_class_install_property (object_class, PROP_SCALE_TYPE, g_param_spec_int ("scale-type", P_("Scale type"), P_("Scale type"),