diff options
author | Owen Taylor <otaylor@redhat.com> | 2005-05-11 19:16:19 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2005-05-11 19:16:19 +0000 |
commit | dda40ca71a669d7ba39261cb94d78772f5803b42 (patch) | |
tree | b85adf32e9bc73bd6c6879110e7aa73131eda622 | |
parent | 846972ba1486f694291c788cb113453a40b8104d (diff) | |
download | gtk+-dda40ca71a669d7ba39261cb94d78772f5803b42.tar.gz |
Use a GtkAlignment rather than a GtkDrawingArea to draw the swatch in to
2005-05-11 Owen Taylor <otaylor@redhat.com>
* gtk/gtkcolorbutton.c: Use a GtkAlignment rather than a GtkDrawingArea
to draw the swatch in to avoid having an extraneous window.
* gtk/gtkcolorsel.c (color_sample_draw_sample): Actually se tthe
color when !has_opacity.
2005-05-10 Owen Taylor <otaylor@redhat.com>
* gdk/gdkcairo.[ch] gdk/gdkcolor.[ch] gdk/Makefile.am: Add source
files for Cairo convenience functionality.
* gdk/gdkcairo.h (gdk_cairo_rectangle, gdk_cairo_region): Add a
convenience functions to add GdkRectangle, GdkRegion to a cairo path.
* gdk/gdkwindow.c gdk/gdkgc.c gtk/gtkcolorsel.c gtk/gtkiconview.c
gtk/gtkstyle.c: Use gdk_cairo_rectangle/region().
* gdk/gdkcairo.[ch] gdk/gdkdrawable.h gdk/gdkdraw.c: Rename
gdk_drawable_create_cairo_context() to gdk_cairo_create().
* gdk/gdkcairo.c gdk/gdkpixbuf.h gdk/gdkpixbuf-render.c:
Rename gdk_pixbuf_set_as_cairo_source() to
gdk_cairo_set_source_pixbuf().
* gdk/gdkdraw.c gdk/gdkpango.c gtk/gtkcolorsel.c gtk/gtkhruler.c
gtk/gtkhsv.c gtk/gtkiconview.c gtk/gtkstyle.c gtk/gtkvruler.c:
Adjust for renames.
* gdk/gdk.symbols: Update.
* gtk/gtkwidget.c (gtk_widget_queue_shallow_draw): Fix
coordinate system problem that was causing the wrong portions
to be invalidated.
* gtk/gtkcellrenderer.c (gtk_cell_renderer_render)
gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render)
gtk/gtkcellrendererprogress.c (gtk_cell_renderer_progress_render)
gtk/gtkcellrenderertext.c (gtk_cell_renderer_text_render)
gtk/gtkcellview.c (gtk_cell_view_expose)
gtk/gtkdnd.c (gtk_drag_highlight_expose)
gtk/gtkentry.c (gtk_entry_draw_text)
gtk/gtktextview.c (text_window_invalidate_rect): Some cairoization.
* gtk/gtkcalendar.[ch]: Beat into something roughly resembling
GTK+ style ... use instance-private data and standard names for
private structure, etc. Move function docs inline.
* gtk/gtkcalendar.[ch]: Switch to drawing everything in
expose. Switch drawing to Cairo.
* gtk/gtkcalendar.c (gtk_calendar_freeze): Deprecate
gtk_calendar_freeze/thaw
38 files changed, 2253 insertions, 2182 deletions
@@ -1,3 +1,58 @@ +2005-05-11 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkcolorbutton.c: Use a GtkAlignment rather than a GtkDrawingArea + to draw the swatch in to avoid having an extraneous window. + + * gtk/gtkcolorsel.c (color_sample_draw_sample): Actually se tthe + color when !has_opacity. + +2005-05-10 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkcairo.[ch] gdk/gdkcolor.[ch] gdk/Makefile.am: Add source + files for Cairo convenience functionality. + + * gdk/gdkcairo.h (gdk_cairo_rectangle, gdk_cairo_region): Add a + convenience functions to add GdkRectangle, GdkRegion to a cairo path. + + * gdk/gdkwindow.c gdk/gdkgc.c gtk/gtkcolorsel.c gtk/gtkiconview.c + gtk/gtkstyle.c: Use gdk_cairo_rectangle/region(). + + * gdk/gdkcairo.[ch] gdk/gdkdrawable.h gdk/gdkdraw.c: Rename + gdk_drawable_create_cairo_context() to gdk_cairo_create(). + + * gdk/gdkcairo.c gdk/gdkpixbuf.h gdk/gdkpixbuf-render.c: + Rename gdk_pixbuf_set_as_cairo_source() to + gdk_cairo_set_source_pixbuf(). + + * gdk/gdkdraw.c gdk/gdkpango.c gtk/gtkcolorsel.c gtk/gtkhruler.c + gtk/gtkhsv.c gtk/gtkiconview.c gtk/gtkstyle.c gtk/gtkvruler.c: + Adjust for renames. + + * gdk/gdk.symbols: Update. + + * gtk/gtkwidget.c (gtk_widget_queue_shallow_draw): Fix + coordinate system problem that was causing the wrong portions + to be invalidated. + + * gtk/gtkcellrenderer.c (gtk_cell_renderer_render) + gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render) + gtk/gtkcellrendererprogress.c (gtk_cell_renderer_progress_render) + gtk/gtkcellrenderertext.c (gtk_cell_renderer_text_render) + gtk/gtkcellview.c (gtk_cell_view_expose) + gtk/gtkdnd.c (gtk_drag_highlight_expose) + gtk/gtkentry.c (gtk_entry_draw_text) + gtk/gtktextview.c (text_window_invalidate_rect): Some cairoization. + + * gtk/gtkcalendar.[ch]: Beat into something roughly resembling + GTK+ style ... use instance-private data and standard names for + private structure, etc. Move function docs inline. + + * gtk/gtkcalendar.[ch]: Switch to drawing everything in + expose. Switch drawing to Cairo. + + * gtk/gtkcalendar.c (gtk_calendar_freeze): Deprecate + gtk_calendar_freeze/thaw + 2005-05-10 Tor Lillqvist <tml@novell.com> * gdk/win32/gdkproperty-win32.c (gdk_screen_get_setting): Check diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index e76a646502..9dd0685777 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,58 @@ +2005-05-11 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkcolorbutton.c: Use a GtkAlignment rather than a GtkDrawingArea + to draw the swatch in to avoid having an extraneous window. + + * gtk/gtkcolorsel.c (color_sample_draw_sample): Actually se tthe + color when !has_opacity. + +2005-05-10 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkcairo.[ch] gdk/gdkcolor.[ch] gdk/Makefile.am: Add source + files for Cairo convenience functionality. + + * gdk/gdkcairo.h (gdk_cairo_rectangle, gdk_cairo_region): Add a + convenience functions to add GdkRectangle, GdkRegion to a cairo path. + + * gdk/gdkwindow.c gdk/gdkgc.c gtk/gtkcolorsel.c gtk/gtkiconview.c + gtk/gtkstyle.c: Use gdk_cairo_rectangle/region(). + + * gdk/gdkcairo.[ch] gdk/gdkdrawable.h gdk/gdkdraw.c: Rename + gdk_drawable_create_cairo_context() to gdk_cairo_create(). + + * gdk/gdkcairo.c gdk/gdkpixbuf.h gdk/gdkpixbuf-render.c: + Rename gdk_pixbuf_set_as_cairo_source() to + gdk_cairo_set_source_pixbuf(). + + * gdk/gdkdraw.c gdk/gdkpango.c gtk/gtkcolorsel.c gtk/gtkhruler.c + gtk/gtkhsv.c gtk/gtkiconview.c gtk/gtkstyle.c gtk/gtkvruler.c: + Adjust for renames. + + * gdk/gdk.symbols: Update. + + * gtk/gtkwidget.c (gtk_widget_queue_shallow_draw): Fix + coordinate system problem that was causing the wrong portions + to be invalidated. + + * gtk/gtkcellrenderer.c (gtk_cell_renderer_render) + gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render) + gtk/gtkcellrendererprogress.c (gtk_cell_renderer_progress_render) + gtk/gtkcellrenderertext.c (gtk_cell_renderer_text_render) + gtk/gtkcellview.c (gtk_cell_view_expose) + gtk/gtkdnd.c (gtk_drag_highlight_expose) + gtk/gtkentry.c (gtk_entry_draw_text) + gtk/gtktextview.c (text_window_invalidate_rect): Some cairoization. + + * gtk/gtkcalendar.[ch]: Beat into something roughly resembling + GTK+ style ... use instance-private data and standard names for + private structure, etc. Move function docs inline. + + * gtk/gtkcalendar.[ch]: Switch to drawing everything in + expose. Switch drawing to Cairo. + + * gtk/gtkcalendar.c (gtk_calendar_freeze): Deprecate + gtk_calendar_freeze/thaw + 2005-05-10 Tor Lillqvist <tml@novell.com> * gdk/win32/gdkproperty-win32.c (gdk_screen_get_setting): Check diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index e76a646502..9dd0685777 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,58 @@ +2005-05-11 Owen Taylor <otaylor@redhat.com> + + * gtk/gtkcolorbutton.c: Use a GtkAlignment rather than a GtkDrawingArea + to draw the swatch in to avoid having an extraneous window. + + * gtk/gtkcolorsel.c (color_sample_draw_sample): Actually se tthe + color when !has_opacity. + +2005-05-10 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkcairo.[ch] gdk/gdkcolor.[ch] gdk/Makefile.am: Add source + files for Cairo convenience functionality. + + * gdk/gdkcairo.h (gdk_cairo_rectangle, gdk_cairo_region): Add a + convenience functions to add GdkRectangle, GdkRegion to a cairo path. + + * gdk/gdkwindow.c gdk/gdkgc.c gtk/gtkcolorsel.c gtk/gtkiconview.c + gtk/gtkstyle.c: Use gdk_cairo_rectangle/region(). + + * gdk/gdkcairo.[ch] gdk/gdkdrawable.h gdk/gdkdraw.c: Rename + gdk_drawable_create_cairo_context() to gdk_cairo_create(). + + * gdk/gdkcairo.c gdk/gdkpixbuf.h gdk/gdkpixbuf-render.c: + Rename gdk_pixbuf_set_as_cairo_source() to + gdk_cairo_set_source_pixbuf(). + + * gdk/gdkdraw.c gdk/gdkpango.c gtk/gtkcolorsel.c gtk/gtkhruler.c + gtk/gtkhsv.c gtk/gtkiconview.c gtk/gtkstyle.c gtk/gtkvruler.c: + Adjust for renames. + + * gdk/gdk.symbols: Update. + + * gtk/gtkwidget.c (gtk_widget_queue_shallow_draw): Fix + coordinate system problem that was causing the wrong portions + to be invalidated. + + * gtk/gtkcellrenderer.c (gtk_cell_renderer_render) + gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render) + gtk/gtkcellrendererprogress.c (gtk_cell_renderer_progress_render) + gtk/gtkcellrenderertext.c (gtk_cell_renderer_text_render) + gtk/gtkcellview.c (gtk_cell_view_expose) + gtk/gtkdnd.c (gtk_drag_highlight_expose) + gtk/gtkentry.c (gtk_entry_draw_text) + gtk/gtktextview.c (text_window_invalidate_rect): Some cairoization. + + * gtk/gtkcalendar.[ch]: Beat into something roughly resembling + GTK+ style ... use instance-private data and standard names for + private structure, etc. Move function docs inline. + + * gtk/gtkcalendar.[ch]: Switch to drawing everything in + expose. Switch drawing to Cairo. + + * gtk/gtkcalendar.c (gtk_calendar_freeze): Deprecate + gtk_calendar_freeze/thaw + 2005-05-10 Tor Lillqvist <tml@novell.com> * gdk/win32/gdkproperty-win32.c (gdk_screen_get_setting): Check diff --git a/docs/reference/gtk/tmpl/gtkcalendar.sgml b/docs/reference/gtk/tmpl/gtkcalendar.sgml index cde6a8c859..1a2727d4d1 100644 --- a/docs/reference/gtk/tmpl/gtkcalendar.sgml +++ b/docs/reference/gtk/tmpl/gtkcalendar.sgml @@ -27,11 +27,6 @@ gtk_calendar_set_display_options(). The selected date can be retrieved from a #GtkCalendar using gtk_calendar_get_date(). </para> -<para> -If performing many 'mark' operations, the calendar can be frozen to prevent -flicker, using gtk_calendar_freeze(), and 'thawed' again using -gtk_calendar_thaw(). -</para> <!-- ##### SECTION See_Also ##### --> <para> @@ -165,59 +160,52 @@ These options can be used to influence the display and behaviour of a #GtkCalend <!-- ##### FUNCTION gtk_calendar_new ##### --> <para> -Creates a new calendar, with the current date being selected. </para> -@Returns: a #GtkCalendar. +@Returns: <!-- ##### FUNCTION gtk_calendar_select_month ##### --> <para> -Shifts the calendar to a different month. </para> -@calendar: a #GtkCalendar. -@month: a month number between 0 and 11. -@year: the year the month is in. -@Returns: %TRUE. +@calendar: +@month: +@year: +@Returns: <!-- ##### FUNCTION gtk_calendar_select_day ##### --> <para> -Selects a day from the current month. </para> -@calendar: a #GtkCalendar. -@day: the day number between 1 and 31, or 0 to unselect - the currently selected day. +@calendar: +@day: <!-- ##### FUNCTION gtk_calendar_mark_day ##### --> <para> -Places a visual marker on a particular day. </para> -@calendar: a #GtkCalendar. -@day: the day number to mark between 1 and 31. -@Returns: %TRUE. +@calendar: +@day: +@Returns: <!-- ##### FUNCTION gtk_calendar_unmark_day ##### --> <para> -Removes the visual marker from a particular day. </para> -@calendar: a #GtkCalendar. -@day: the day number to unmark between 1 and 31. -@Returns: %TRUE. +@calendar: +@day: +@Returns: <!-- ##### FUNCTION gtk_calendar_clear_marks ##### --> <para> -Remove all visual markers. </para> -@calendar: a #GtkCalendar. +@calendar: <!-- ##### FUNCTION gtk_calendar_get_display_options ##### --> @@ -240,39 +228,34 @@ Remove all visual markers. <!-- ##### FUNCTION gtk_calendar_display_options ##### --> <para> -Sets display options (whether to display the heading and the month headings). </para> -@calendar: a #GtkCalendar. -@flags: the display options to set. -@Deprecated: Use gtk_calendar_set_display_options() instead +@calendar: +@flags: +@Deprecated: <!-- ##### FUNCTION gtk_calendar_get_date ##### --> <para> -Obtains the selected date from a #GtkCalendar. </para> -@calendar: a #GtkCalendar. -@year: location to store the year number. -@month: location to store the month number (between 0 and 11). -@day: location to store the day number (between 1 and 31). +@calendar: +@year: +@month: +@day: <!-- ##### FUNCTION gtk_calendar_freeze ##### --> <para> -Locks the display of the calendar until it is thawed with gtk_calendar_thaw(). </para> -@calendar: a #GtkCalendar. +@calendar: <!-- ##### FUNCTION gtk_calendar_thaw ##### --> <para> -Defrosts a calendar; all the changes made since the last -gtk_calendar_freeze() are displayed. </para> -@calendar: a #GtkCalendar. +@calendar: diff --git a/gdk/Makefile.am b/gdk/Makefile.am index a66938a7a5..0fcb35c865 100644 --- a/gdk/Makefile.am +++ b/gdk/Makefile.am @@ -50,6 +50,7 @@ LDADD = \ # gdk_public_h_sources = \ gdk.h \ + gdkcairo.h \ gdkcolor.h \ gdkcursor.h \ gdkdisplay.h \ @@ -85,6 +86,7 @@ gdk_headers = \ gdk_c_sources = \ gdk.c \ + gdkcairo.c \ gdkcolor.c \ gdkcursor.c \ gdkdisplay.c \ @@ -240,7 +242,7 @@ stamp-gdkenumtypes.h: @REBUILD@ $(gdk_public_h_sources) Makefile gdkenumtypes.c: @REBUILD@ $(gdk_public_h_sources) Makefile ( cd $(srcdir) && glib-mkenums \ --fhead "#define GDK_ENABLE_BROKEN\n#include \"gdk.h\"\n#include \"gdkalias.h\"\n" \ - --fprod "\n/* enumerations from \"@filename@\" */" \ + --fprod "\n/* enumerations from \"@filename@\" */" \ --ftail "\n#define __GDK_ENUM_TYPES_C__\n#include \"gdkaliasdef.c\"\n" \ --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \ @@ -27,6 +27,7 @@ #ifndef __GDK_H__ #define __GDK_H__ +#include <gdk/gdkcairo.h> #include <gdk/gdkcolor.h> #include <gdk/gdkcursor.h> #include <gdk/gdkdisplay.h> diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols index 93448836dc..8e70365ba0 100644 --- a/gdk/gdk.symbols +++ b/gdk/gdk.symbols @@ -288,6 +288,16 @@ gdk_fontset_load_for_display #endif #endif +#if IN_HEADER(__GDK_CAIRO_H__) +#if IN_FILE(__GDK_CAIRO_C__) +gdk_cairo_create +gdk_cairo_set_source_color +gdk_cairo_set_source_pixbuf +gdk_cairo_rectangle +gdk_cairo_region +#endif +#endif + #if IN_HEADER(__GDK_COLOR_H__) #if IN_FILE(__GDK_COLOR_C__) #ifndef GDK_DISABLE_DEPRECATED @@ -301,7 +311,6 @@ gdk_color_equal gdk_color_free gdk_color_get_type G_GNUC_CONST gdk_color_hash -gdk_cairo_set_source_color gdk_colormap_alloc_color gdk_colormap_get_system gdk_colormap_get_visual @@ -510,7 +519,6 @@ gdk_drag_get_protocol #if IN_HEADER(__GDK_DRAWABLE_H__) #if IN_FILE(__GDK_DRAW_C__) -gdk_drawable_create_cairo_context gdk_drawable_copy_to_image gdk_drawable_get_clip_region gdk_drawable_get_colormap @@ -853,7 +861,6 @@ gdk_pixbuf_get_from_image gdk_pixbuf_render_pixmap_and_mask gdk_pixbuf_render_pixmap_and_mask_for_colormap gdk_pixbuf_render_threshold_alpha -gdk_pixbuf_set_as_cairo_source #ifndef GDK_DISABLE_DEPRECATED gdk_pixbuf_render_to_drawable gdk_pixbuf_render_to_drawable_alpha diff --git a/gdk/gdkcairo.c b/gdk/gdkcairo.c new file mode 100644 index 0000000000..4e498546fa --- /dev/null +++ b/gdk/gdkcairo.c @@ -0,0 +1,221 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2005 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * 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. + */ + +#include "gdkcairo.h" +#include "gdkdrawable.h" +#include "gdkinternals.h" +#include "gdkregion-generic.h" +#include "gdkalias.h" + +/** + * gdk_cairo_create: + * @drawable: a #GdkDrawable + * + * Creates a Cairo context for drawing to @drawable. + * + * Return value: A newly created Cairo context. Free with + * cairo_destroy() when you are done drawing. + * + * Since: 2.10 + **/ +cairo_t * +gdk_cairo_create (GdkDrawable *drawable) +{ + cairo_surface_t *surface; + cairo_t *cr; + + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + surface = _gdk_drawable_ref_cairo_surface (drawable); + cr = cairo_create (surface); + cairo_surface_destroy (surface); + + return cr; +} + +/** + * gdk_cairo_set_source_color: + * @cr: a #cairo_t + * @color: a #GdkColor + * + * Sets the specified #GdkColor as the source color of @cr. + * + * Since: 2.8 + **/ +void +gdk_cairo_set_source_color (cairo_t *cr, + GdkColor *color) +{ + g_return_if_fail (cr != NULL); + g_return_if_fail (color != NULL); + + cairo_set_source_rgb (cr, + color->red / 65535., + color->green / 65535., + color->blue / 65535.); +} + +/** + * gdk_cairo_rectangle: + * @cr: a #cairo_t + * @rectangle: a #GdkRectangle + * + * Adds the given rectangle to the current path of @cr. + **/ +void +gdk_cairo_rectangle (cairo_t *cr, + GdkRectangle *rectangle) +{ + g_return_if_fail (cr != NULL); + g_return_if_fail (rectangle != NULL); + + cairo_rectangle (cr, + rectangle->x, rectangle->y, + rectangle->width, rectangle->height); +} + +/** + * gdk_cairo_region: + * @cr: a #cairo_t + * @region: a #GdkRegion + * + * Adds the given region to the current path of @cr. + **/ +void +gdk_cairo_region (cairo_t *cr, + GdkRegion *region) +{ + GdkRegionBox *boxes; + gint n_boxes, i; + + g_return_if_fail (cr != NULL); + g_return_if_fail (region != NULL); + + boxes = region->rects; + n_boxes = region->numRects; + + for (i = 0; i < n_boxes; i++) + cairo_rectangle (cr, + boxes[i].x1, + boxes[i].y1, + boxes[i].x2 - boxes[i].x1, + boxes[i].y2 - boxes[i].y1); +} + +/** + * gdk_cairo_set_source_pixbuf: + * @cr: a #Cairo context + * @pixbuf: a #GdkPixbuf + * @pixbuf_x: X coordinate of location to place upper left corner of @pixbuf + * @pixbuf_y: Y coordinate of location to place upper left corner of @pixbuf + * + * Sets the given pixbuf as the source pattern for the Cairo context. + * The pattern has an extend mode of %CAIRO_EXTEND_NONE and is aligned + * so that the origin of @pixbuf is @pixbuf_x, @pixbuf_y + **/ +void +gdk_cairo_set_source_pixbuf (cairo_t *cr, + GdkPixbuf *pixbuf, + double pixbuf_x, + double pixbuf_y) +{ + gint width = gdk_pixbuf_get_width (pixbuf); + gint height = gdk_pixbuf_get_height (pixbuf); + guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf); + int gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf); + int n_channels = gdk_pixbuf_get_n_channels (pixbuf); + guchar *cairo_pixels; + cairo_format_t format; + cairo_surface_t *surface; + static const cairo_user_data_key_t key; + int j; + + if (n_channels == 3) + format = CAIRO_FORMAT_RGB24; + else + format = CAIRO_FORMAT_ARGB32; + + cairo_pixels = g_malloc (4 * width * height); + surface = cairo_image_surface_create_for_data ((unsigned char *)cairo_pixels, + format, + width, height, 4 * width); + cairo_surface_set_user_data (surface, &key, + cairo_pixels, (cairo_destroy_func_t)g_free); + + for (j = height; j; j--) + { + guchar *p = gdk_pixels; + guchar *q = cairo_pixels; + + if (n_channels == 3) + { + guchar *end = p + 3 * width; + + while (p < end) + { +#if G_BYTE_ORDER == GDK_LSB_FIRST + q[0] = p[2]; + q[1] = p[1]; + q[2] = p[2]; +#else + q[0] = p[0]; + q[1] = p[1]; + q[2] = p[2]; +#endif + p += 3; + q += 4; + } + } + else + { + guchar *end = p + 4 * width; + guint t1,t2,t3; + +#define MULT(d,c,a,t) G_STMT_START { t = c * a; d = ((t >> 8) + t) >> 8; } G_STMT_END + + while (p < end) + { +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + MULT(q[0], p[2], p[3], t1); + MULT(q[1], p[1], p[3], t2); + MULT(q[2], p[0], p[3], t3); + q[3] = p[3]; +#else + q[0] = p[3]; + MULT(q[1], p[0], p[3], t1); + MULT(q[2], p[1], p[3], t2); + MULT(q[3], p[2], p[3], t3); +#endif + + p += 4; + q += 4; + } + +#undef MULT + } + + gdk_pixels += gdk_rowstride; + cairo_pixels += 4 * width; + } + + cairo_set_source_surface (cr, surface, pixbuf_x, pixbuf_y); +} + +#define __GDK_CAIRO_C__ +#include "gdkaliasdef.c" diff --git a/gdk/gdkcairo.h b/gdk/gdkcairo.h new file mode 100644 index 0000000000..3918f2381e --- /dev/null +++ b/gdk/gdkcairo.h @@ -0,0 +1,45 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2005 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * 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. + */ + +#ifndef __GDK_CAIRO_H__ +#define __GDK_CAIRO_H__ + +#include <gdk/gdkcolor.h> +#include <gdk/gdkpixbuf.h> +#include <pango/pangocairo.h> + +G_BEGIN_DECLS + +cairo_t *gdk_cairo_create (GdkDrawable *drawable); + +void gdk_cairo_set_source_color (cairo_t *cr, + GdkColor *color); +void gdk_cairo_set_source_pixbuf (cairo_t *cr, + GdkPixbuf *pixbuf, + double pixbuf_x, + double pixbuf_y); + +void gdk_cairo_rectangle (cairo_t *cr, + GdkRectangle *rectangle); +void gdk_cairo_region (cairo_t *cr, + GdkRegion *region); + +G_END_DECLS + +#endif /* __GDK_CAIRO_H__ */ diff --git a/gdk/gdkcolor.c b/gdk/gdkcolor.c index 27bdf19460..d2a4a55cab 100644 --- a/gdk/gdkcolor.c +++ b/gdk/gdkcolor.c @@ -371,25 +371,5 @@ gdk_colormap_get_system (void) return gdk_screen_get_system_colormap (gdk_screen_get_default ()); } -/** - * gdk_cairo_set_source_color: - * @cr: a #cairo_t - * @color: a #GdkColor - * - * Convenience function to set the specified GdkColor as the - * source color of the given Cairo context. - * - * Since: 2.8 - **/ -void -gdk_cairo_set_source_color (cairo_t *cr, - GdkColor *color) -{ - cairo_set_source_rgb (cr, - color->red / 65535., - color->green / 65535., - color->blue / 65535.); -} - #define __GDK_COLOR_C__ #include "gdkaliasdef.c" diff --git a/gdk/gdkcolor.h b/gdk/gdkcolor.h index bbf7bd83f4..4d8a7e6df2 100644 --- a/gdk/gdkcolor.h +++ b/gdk/gdkcolor.h @@ -111,9 +111,6 @@ gboolean gdk_color_equal (const GdkColor *colora, GType gdk_color_get_type (void) G_GNUC_CONST; -void gdk_cairo_set_source_color (cairo_t *cr, - GdkColor *color); - /* The following functions are deprecated */ #ifndef GDK_DISABLE_DEPRECATED void gdk_colors_store (GdkColormap *colormap, diff --git a/gdk/gdkdraw.c b/gdk/gdkdraw.c index f956a5bedd..93e3e9f8f3 100644 --- a/gdk/gdkdraw.c +++ b/gdk/gdkdraw.c @@ -879,7 +879,7 @@ real_draw_glyphs (GdkDrawable *drawable, { cairo_t *cr; - cr = gdk_drawable_create_cairo_context (drawable); + cr = gdk_cairo_create (drawable); _gdk_gc_update_context (gc, cr, NULL, NULL); if (matrix) @@ -1003,7 +1003,7 @@ gdk_draw_trapezoids (GdkDrawable *drawable, g_return_if_fail (GDK_IS_GC (gc)); g_return_if_fail (n_trapezoids == 0 || trapezoids != NULL); - cr = gdk_drawable_create_cairo_context (drawable); + cr = gdk_cairo_create (drawable); _gdk_gc_update_context (gc, cr, NULL, NULL); for (i = 0; i < n_trapezoids; i++) @@ -1285,32 +1285,6 @@ _gdk_drawable_ref_cairo_surface (GdkDrawable *drawable) return GDK_DRAWABLE_GET_CLASS (drawable)->ref_cairo_surface (drawable); } -/** - * gdk_drawable_create_cairo_context: - * @drawable: a #GdkDrawable - * - * Creates a Cairo context for drawing to @drawable. - * - * Return value: A newly created Cairo context. Free with - * cairo_destroy() when you are done drawing. - * - * Since: 2.10 - **/ -cairo_t * -gdk_drawable_create_cairo_context (GdkDrawable *drawable) -{ - cairo_surface_t *surface; - cairo_t *cr; - - g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); - - surface = _gdk_drawable_ref_cairo_surface (drawable); - cr = cairo_create (surface); - cairo_surface_destroy (surface); - - return cr; -} - static void composite (guchar *src_buf, gint src_rowstride, diff --git a/gdk/gdkdrawable.h b/gdk/gdkdrawable.h index 19344954f1..1e9194e4d1 100644 --- a/gdk/gdkdrawable.h +++ b/gdk/gdkdrawable.h @@ -391,8 +391,6 @@ GdkImage *gdk_drawable_copy_to_image (GdkDrawable *drawable, GdkRegion *gdk_drawable_get_clip_region (GdkDrawable *drawable); GdkRegion *gdk_drawable_get_visible_region (GdkDrawable *drawable); -cairo_t *gdk_drawable_create_cairo_context (GdkDrawable *drawable); - #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gdk/gdkgc.c b/gdk/gdkgc.c index 72115eec27..b29fecb608 100644 --- a/gdk/gdkgc.c +++ b/gdk/gdkgc.c @@ -27,10 +27,10 @@ #include <config.h> #include <string.h> +#include "gdkcairo.h" #include "gdkgc.h" #include "gdkinternals.h" #include "gdkpixmap.h" -#include "gdkregion-generic.h" #include "gdkrgb.h" #include "gdkprivate.h" #include "gdkalias.h" @@ -1225,21 +1225,13 @@ _gdk_gc_update_context (GdkGC *gc, cairo_reset_clip (cr); if (priv->clip_region) { - GdkRegionBox *boxes = priv->clip_region->rects; - gint n_boxes = priv->clip_region->numRects; - int i; - cairo_save (cr); cairo_identity_matrix (cr); - + cairo_translate (cr, gc->clip_x_origin, gc->clip_y_origin); + cairo_new_path (cr); - for (i=0; i < n_boxes; i++) - cairo_rectangle (cr, - boxes[i].x1 + gc->clip_x_origin, - boxes[i].y1 + gc->clip_y_origin, - boxes[i].x2 - boxes[i].x1, - boxes[i].y2 - boxes[i].y1); + gdk_cairo_region (cr, priv->clip_region); cairo_restore (cr); diff --git a/gdk/gdkpango.c b/gdk/gdkpango.c index 4a266762b5..a160511dc7 100644 --- a/gdk/gdkpango.c +++ b/gdk/gdkpango.c @@ -141,7 +141,7 @@ get_cairo_context (GdkPangoRenderer *gdk_renderer, { const PangoMatrix *matrix; - priv->cr = gdk_drawable_create_cairo_context (priv->drawable); + priv->cr = gdk_cairo_create (priv->drawable); matrix = pango_renderer_get_matrix (renderer); if (matrix) diff --git a/gdk/gdkpixbuf-render.c b/gdk/gdkpixbuf-render.c index d8eda5eb69..31dcb62cc8 100644 --- a/gdk/gdkpixbuf-render.c +++ b/gdk/gdkpixbuf-render.c @@ -329,105 +329,6 @@ gdk_pixbuf_render_pixmap_and_mask_for_colormap (GdkPixbuf *pixbuf, } } -/** - * gdk_pixbuf_set_as_cairo_source: - * @pixbuf: a #GdkPixbuf - * @cr: a #Cairo context - * @pixbuf_x: X coordinate of location to place upper left corner of @pixbuf - * @pixbuf_y: Y coordinate of location to place upper left corner of @pixbuf - * - * Sets the given pixbuf as the source pattern for the Cairo context. - * The pattern has an extend mode of %CAIRO_EXTEND_NONE and is aligned - * so that the origin of @pixbuf is @pixbuf_x, @pixbuf_y - **/ -void -gdk_pixbuf_set_as_cairo_source (GdkPixbuf *pixbuf, - cairo_t *cr, - double pixbuf_x, - double pixbuf_y) -{ - gint width = gdk_pixbuf_get_width (pixbuf); - gint height = gdk_pixbuf_get_height (pixbuf); - guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf); - int gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf); - int n_channels = gdk_pixbuf_get_n_channels (pixbuf); - guchar *cairo_pixels; - cairo_format_t format; - cairo_surface_t *surface; - static const cairo_user_data_key_t key; - int j; - - if (n_channels == 3) - format = CAIRO_FORMAT_RGB24; - else - format = CAIRO_FORMAT_ARGB32; - - cairo_pixels = g_malloc (4 * width * height); - surface = cairo_image_surface_create_for_data ((unsigned char *)cairo_pixels, - format, - width, height, 4 * width); - cairo_surface_set_user_data (surface, &key, - cairo_pixels, (cairo_destroy_func_t)g_free); - - for (j = height; j; j--) - { - guchar *p = gdk_pixels; - guchar *q = cairo_pixels; - - if (n_channels == 3) - { - guchar *end = p + 3 * width; - - while (p < end) - { -#if G_BYTE_ORDER == GDK_LSB_FIRST - q[0] = p[2]; - q[1] = p[1]; - q[2] = p[2]; -#else - q[0] = p[0]; - q[1] = p[1]; - q[2] = p[2]; -#endif - p += 3; - q += 4; - } - } - else - { - guchar *end = p + 4 * width; - guint t1,t2,t3; - -#define MULT(d,c,a,t) G_STMT_START { t = c * a; d = ((t >> 8) + t) >> 8; } G_STMT_END - - while (p < end) - { -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - MULT(q[0], p[2], p[3], t1); - MULT(q[1], p[1], p[3], t2); - MULT(q[2], p[0], p[3], t3); - q[3] = p[3]; -#else - q[0] = p[3]; - MULT(q[1], p[0], p[3], t1); - MULT(q[2], p[1], p[3], t2); - MULT(q[3], p[2], p[3], t3); -#endif - - p += 4; - q += 4; - } - -#undef MULT - } - - gdk_pixels += gdk_rowstride; - cairo_pixels += 4 * width; - } - - cairo_set_source_surface (cr, surface, pixbuf_x, pixbuf_y); -} - #define __GDK_PIXBUF_RENDER_C__ #include "gdkaliasdef.c" diff --git a/gdk/gdkpixbuf.h b/gdk/gdkpixbuf.h index aa5b4acba2..ed297135c7 100644 --- a/gdk/gdkpixbuf.h +++ b/gdk/gdkpixbuf.h @@ -80,11 +80,6 @@ GdkPixbuf *gdk_pixbuf_get_from_image (GdkPixbuf *dest, int width, int height); -void gdk_pixbuf_set_as_cairo_source (GdkPixbuf *pixbuf, - cairo_t *cr, - double pixbuf_x, - double pixbuf_y); - G_END_DECLS #endif /* __GDK_PIXBUF_H__ */ diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 87280a5052..85326aef65 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -1764,23 +1764,6 @@ gdk_window_set_bg_pattern (GdkWindow *window, } static void -region_path (cairo_t *cr, - GdkRegion *region) -{ - GdkRectangle *rectangles; - int n_rectangles, i; - - gdk_region_get_rectangles (region, &rectangles, &n_rectangles); - for (i = 0; i < n_rectangles; i++) - { - cairo_rectangle (cr, - rectangles[i].x, rectangles[i].y, - rectangles[i].width, rectangles[i].height); - } - g_free (rectangles); -} - -static void gdk_window_clear_backing_rect (GdkWindow *window, gint x, gint y, @@ -1801,7 +1784,7 @@ gdk_window_clear_backing_rect (GdkWindow *window, cairo_rectangle (cr, x, y, width, height); cairo_clip (cr); - region_path (cr, paint->region); + gdk_cairo_region (cr, paint->region); cairo_fill (cr); cairo_destroy (cr); diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index 52332318f8..2a069add48 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -402,11 +402,12 @@ gtk_button_set_use_underline #if IN_HEADER(__GTK_CALENDAR_H__) #if IN_FILE(__GTK_CALENDAR_C__) -gtk_calendar_clear_marks #ifndef GTK_DISABLE_DEPRECATED gtk_calendar_display_options -#endif gtk_calendar_freeze +gtk_calendar_thaw +#endif +gtk_calendar_clear_marks gtk_calendar_get_date gtk_calendar_get_display_options gtk_calendar_get_type G_GNUC_CONST @@ -415,7 +416,6 @@ gtk_calendar_new gtk_calendar_select_day gtk_calendar_select_month gtk_calendar_set_display_options -gtk_calendar_thaw gtk_calendar_unmark_day #endif #endif diff --git a/gtk/gtkcalendar.c b/gtk/gtkcalendar.c index 585fa85c4a..9c36354969 100644 --- a/gtk/gtkcalendar.c +++ b/gtk/gtkcalendar.c @@ -42,7 +42,10 @@ #include <time.h> #include <glib/gprintf.h> +#undef GTK_DISABLE_DEPRECATED #include "gtkcalendar.h" +#define GTK_DISABLE_DEPRECATED + #include "gtkdnd.h" #include "gtkintl.h" #include "gtkmain.h" @@ -234,12 +237,9 @@ enum PROP_LAST }; -static gint gtk_calendar_signals[LAST_SIGNAL] = { 0 }; - -static GtkWidgetClass *parent_class = NULL; +static guint gtk_calendar_signals[LAST_SIGNAL] = { 0 }; -typedef struct _GtkCalendarPrivateData GtkCalendarPrivateData; -struct _GtkCalendarPrivateData +struct _GtkCalendarPrivate { GdkWindow *header_win; GdkWindow *day_name_win; @@ -267,14 +267,7 @@ struct _GtkCalendarPrivateData guint max_label_char_descent; guint max_week_char_width; - guint freeze_count; - /* flags */ - guint dirty_header : 1; - guint dirty_day_names : 1; - guint dirty_main : 1; - guint dirty_week : 1; - guint year_before : 1; guint need_timer : 1; @@ -291,130 +284,94 @@ struct _GtkCalendarPrivateData gint drag_start_y; }; -#define GTK_CALENDAR_PRIVATE_DATA(widget) (((GtkCalendarPrivateData*)(GTK_CALENDAR (widget)->private_data))) - -typedef void (*GtkCalendarSignalDate) (GtkObject *object, guint arg1, guint arg2, guint arg3, gpointer data); - -static void gtk_calendar_class_init (GtkCalendarClass *class); -static void gtk_calendar_init (GtkCalendar *calendar); -static void gtk_calendar_finalize (GObject *calendar); -static void gtk_calendar_destroy (GtkObject *calendar); -static void gtk_calendar_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gtk_calendar_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void gtk_calendar_realize (GtkWidget *widget); -static void gtk_calendar_unrealize (GtkWidget *widget); -static void gtk_calendar_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void gtk_calendar_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gint gtk_calendar_expose (GtkWidget *widget, - GdkEventExpose *event); -static gint gtk_calendar_button_press (GtkWidget *widget, - GdkEventButton *event); -static gint gtk_calendar_button_release (GtkWidget *widget, - GdkEventButton *event); -static void gtk_calendar_main_button (GtkWidget *widget, - GdkEventButton *event); -static gint gtk_calendar_motion_notify (GtkWidget *widget, - GdkEventMotion *event); -static gint gtk_calendar_enter_notify (GtkWidget *widget, - GdkEventCrossing *event); -static gint gtk_calendar_leave_notify (GtkWidget *widget, - GdkEventCrossing *event); -static gint gtk_calendar_key_press (GtkWidget *widget, - GdkEventKey *event); -static gint gtk_calendar_scroll (GtkWidget *widget, - GdkEventScroll *event); -static void gtk_calendar_grab_notify (GtkWidget *widget, - gboolean was_grabbed); -static gboolean gtk_calendar_focus_out (GtkWidget *widget, - GdkEventFocus *event); -static void gtk_calendar_state_changed (GtkWidget *widget, - GtkStateType previous_state); -static void gtk_calendar_style_set (GtkWidget *widget, - GtkStyle *previous_style); -static void gtk_calendar_paint_header (GtkWidget *widget); -static void gtk_calendar_paint_day_names (GtkWidget *widget); -static void gtk_calendar_paint_week_numbers (GtkWidget *widget); -static void gtk_calendar_paint_main (GtkWidget *widget); - -static void gtk_calendar_select_and_focus_day (GtkCalendar *calendar, - guint day); - -static void gtk_calendar_paint_arrow (GtkWidget *widget, - guint arrow); -static void gtk_calendar_paint_day_num (GtkWidget *widget, - gint day); -static void gtk_calendar_paint_day (GtkWidget *widget, - gint row, - gint col); -static void gtk_calendar_compute_days (GtkCalendar *calendar); -static gint left_x_for_column (GtkCalendar *calendar, - gint column); -static gint top_y_for_row (GtkCalendar *calendar, - gint row); - -static void gtk_calendar_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time); -static void gtk_calendar_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time); -static gboolean gtk_calendar_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time); -static void gtk_calendar_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time); -static gboolean gtk_calendar_drag_drop (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time); +#define GTK_CALENDAR_GET_PRIVATE(widget) (GTK_CALENDAR (widget)->priv) + +static void gtk_calendar_finalize (GObject *calendar); +static void gtk_calendar_destroy (GtkObject *calendar); +static void gtk_calendar_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gtk_calendar_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static void gtk_calendar_realize (GtkWidget *widget); +static void gtk_calendar_unrealize (GtkWidget *widget); +static void gtk_calendar_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static void gtk_calendar_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +static gboolean gtk_calendar_expose (GtkWidget *widget, + GdkEventExpose *event); +static gboolean gtk_calendar_button_press (GtkWidget *widget, + GdkEventButton *event); +static gboolean gtk_calendar_button_release (GtkWidget *widget, + GdkEventButton *event); +static gboolean gtk_calendar_motion_notify (GtkWidget *widget, + GdkEventMotion *event); +static gboolean gtk_calendar_enter_notify (GtkWidget *widget, + GdkEventCrossing *event); +static gboolean gtk_calendar_leave_notify (GtkWidget *widget, + GdkEventCrossing *event); +static gboolean gtk_calendar_scroll (GtkWidget *widget, + GdkEventScroll *event); +static gboolean gtk_calendar_key_press (GtkWidget *widget, + GdkEventKey *event); +static gboolean gtk_calendar_focus_out (GtkWidget *widget, + GdkEventFocus *event); +static void gtk_calendar_grab_notify (GtkWidget *widget, + gboolean was_grabbed); +static void gtk_calendar_state_changed (GtkWidget *widget, + GtkStateType previous_state); +static void gtk_calendar_style_set (GtkWidget *widget, + GtkStyle *previous_style); + +static void gtk_calendar_drag_data_get (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time); +static void gtk_calendar_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time); +static gboolean gtk_calendar_drag_motion (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint time); +static void gtk_calendar_drag_leave (GtkWidget *widget, + GdkDragContext *context, + guint time); +static gboolean gtk_calendar_drag_drop (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint time); + +static void calendar_start_spinning (GtkCalendar *calendar, + gint click_child); +static void calendar_stop_spinning (GtkCalendar *calendar); + +static void calendar_invalidate_day (GtkCalendar *widget, + gint row, + gint col); +static void calendar_invalidate_day_num (GtkCalendar *widget, + gint day); +static void calendar_invalidate_arrow (GtkCalendar *widget, + guint arrow); + +static void calendar_compute_days (GtkCalendar *calendar); static char *default_abbreviated_dayname[7]; static char *default_monthname[12]; -GType -gtk_calendar_get_type (void) -{ - static GType calendar_type = 0; - - if (!calendar_type) - { - static const GTypeInfo calendar_info = - { - sizeof (GtkCalendarClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) gtk_calendar_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GtkCalendar), - 0, /* n_preallocs */ - (GInstanceInitFunc) gtk_calendar_init, - }; - - calendar_type = g_type_register_static (GTK_TYPE_WIDGET, "GtkCalendar", - &calendar_info, 0); - } - - return calendar_type; -} +G_DEFINE_TYPE (GtkCalendar, gtk_calendar, GTK_TYPE_WIDGET) static void gtk_calendar_class_init (GtkCalendarClass *class) @@ -427,8 +384,6 @@ gtk_calendar_class_init (GtkCalendarClass *class) object_class = (GtkObjectClass*) class; widget_class = (GtkWidgetClass*) class; - parent_class = g_type_class_peek_parent (class); - gobject_class->set_property = gtk_calendar_set_property; gobject_class->get_property = gtk_calendar_get_property; gobject_class->finalize = gtk_calendar_finalize; @@ -458,14 +413,6 @@ gtk_calendar_class_init (GtkCalendarClass *class) widget_class->drag_drop = gtk_calendar_drag_drop; widget_class->drag_data_received = gtk_calendar_drag_data_received; - class->month_changed = NULL; - class->day_selected = NULL; - class->day_selected_double_click = NULL; - class->prev_month = NULL; - class->next_month = NULL; - class->prev_year = NULL; - class->next_year = NULL; - g_object_class_install_property (gobject_class, PROP_YEAR, g_param_spec_int ("year", @@ -603,27 +550,29 @@ gtk_calendar_class_init (GtkCalendarClass *class) NULL, NULL, _gtk_marshal_VOID__VOID, G_TYPE_NONE, 0); + + g_type_class_add_private (gobject_class, sizeof (GtkCalendarPrivate)); } static void gtk_calendar_init (GtkCalendar *calendar) { + GtkWidget *widget = GTK_WIDGET (calendar); time_t secs; struct tm *tm; gint i; char buffer[255]; time_t tmp_time; - GtkWidget *widget; - GtkCalendarPrivateData *private_data; + GtkCalendarPrivate *priv; gchar *year_before; gchar *week_start; - widget = GTK_WIDGET (calendar); + priv = calendar->priv = G_TYPE_INSTANCE_GET_PRIVATE (calendar, + GTK_TYPE_CALENDAR, + GtkCalendarPrivate); + GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS); - calendar->private_data = g_malloc (sizeof (GtkCalendarPrivateData)); - private_data = GTK_CALENDAR_PRIVATE_DATA (calendar); - if (!default_abbreviated_dayname[0]) for (i=0; i<7; i++) { @@ -645,10 +594,11 @@ gtk_calendar_init (GtkCalendar *calendar) tm = localtime (&secs); calendar->month = tm->tm_mon; calendar->year = 1900 + tm->tm_year; - + + calendar_compute_days (calendar); + for (i=0;i<31;i++) calendar->marked_date[i] = FALSE; - calendar->num_marked_dates = 0; calendar->selected_day = tm->tm_mday; calendar->display_flags = ( GTK_CALENDAR_SHOW_HEADING | @@ -659,38 +609,30 @@ gtk_calendar_init (GtkCalendar *calendar) calendar->focus_row = -1; calendar->focus_col = -1; - calendar->xor_gc = NULL; - private_data->max_year_width = 0; - private_data->max_month_width = 0; - private_data->max_day_char_width = 0; - private_data->max_week_char_width = 0; + priv->max_year_width = 0; + priv->max_month_width = 0; + priv->max_day_char_width = 0; + priv->max_week_char_width = 0; - private_data->max_day_char_ascent = 0; - private_data->max_day_char_descent = 0; - private_data->max_label_char_ascent = 0; - private_data->max_label_char_descent = 0; + priv->max_day_char_ascent = 0; + priv->max_day_char_descent = 0; + priv->max_label_char_ascent = 0; + priv->max_label_char_descent = 0; - private_data->arrow_width = 10; + priv->arrow_width = 10; - private_data->freeze_count = 0; - - private_data->dirty_header = 0; - private_data->dirty_day_names = 0; - private_data->dirty_week = 0; - private_data->dirty_main = 0; - - private_data->need_timer = 0; - private_data->timer = 0; - private_data->click_child = -1; + priv->need_timer = 0; + priv->timer = 0; + priv->click_child = -1; - private_data->in_drag = 0; - private_data->drag_highlight = 0; + priv->in_drag = 0; + priv->drag_highlight = 0; gtk_drag_dest_set (widget, 0, NULL, 0, GDK_ACTION_COPY); gtk_drag_dest_add_text_targets (widget); - private_data->year_before = 0; + priv->year_before = 0; /* Translate to calendar:YM if you want years to be displayed * before months; otherwise translate to calendar:MY. @@ -703,13 +645,13 @@ gtk_calendar_init (GtkCalendar *calendar) */ year_before = _("calendar:MY"); if (strcmp (year_before, "calendar:YM") == 0) - private_data->year_before = 1; + priv->year_before = 1; else if (strcmp (year_before, "calendar:MY") != 0) g_warning ("Whoever translated calendar:MY did so wrongly.\n"); #ifdef HAVE__NL_TIME_FIRST_WEEKDAY week_start = nl_langinfo (_NL_TIME_FIRST_WEEKDAY); - private_data->week_start = *((unsigned char *) week_start) % 7; + priv->week_start = *((unsigned char *) week_start) % 7; #else /* Translate to calendar:week_start:0 if you want Sunday to be the * first day of the week to calendar:week_start:1 if you want Monday @@ -718,29 +660,260 @@ gtk_calendar_init (GtkCalendar *calendar) week_start = _("calendar:week_start:0"); if (strncmp (week_start, "calendar:week_start:", 20) == 0) - private_data->week_start = *(week_start + 20) - '0'; + priv->week_start = *(week_start + 20) - '0'; else - private_data->week_start = -1; + priv->week_start = -1; - if (private_data->week_start < 0 || private_data->week_start > 6) + if (priv->week_start < 0 || priv->week_start > 6) { g_warning ("Whoever translated calendar:week_start:0 did so wrongly.\n"); - private_data->week_start = 0; + priv->week_start = 0; } #endif } -GtkWidget* -gtk_calendar_new (void) + +/**************************************** + * Utility Functions * + ****************************************/ + +static void +calendar_set_month_next (GtkCalendar *calendar) { - return g_object_new (GTK_TYPE_CALENDAR, NULL); + gint month_len; + + g_return_if_fail (GTK_IS_WIDGET (calendar)); + + if (calendar->display_flags & GTK_CALENDAR_NO_MONTH_CHANGE) + return; + + + if (calendar->month == 11) + { + calendar->month = 0; + calendar->year++; + } + else + calendar->month++; + + calendar_compute_days (calendar); + g_signal_emit (calendar, + gtk_calendar_signals[NEXT_MONTH_SIGNAL], + 0); + g_signal_emit (calendar, + gtk_calendar_signals[MONTH_CHANGED_SIGNAL], + 0); + + month_len = month_length[leap (calendar->year)][calendar->month + 1]; + + if (month_len < calendar->selected_day) + { + calendar->selected_day = 0; + gtk_calendar_select_day (calendar, month_len); + } + else + gtk_calendar_select_day (calendar, calendar->selected_day); + + gtk_widget_queue_draw (GTK_WIDGET (calendar)); +} + +static void +calendar_set_year_prev (GtkCalendar *calendar) +{ + gint month_len; + + g_return_if_fail (GTK_IS_WIDGET (calendar)); + + calendar->year--; + calendar_compute_days (calendar); + g_signal_emit (calendar, + gtk_calendar_signals[PREV_YEAR_SIGNAL], + 0); + g_signal_emit (calendar, + gtk_calendar_signals[MONTH_CHANGED_SIGNAL], + 0); + + month_len = month_length[leap (calendar->year)][calendar->month + 1]; + + if (month_len < calendar->selected_day) + { + calendar->selected_day = 0; + gtk_calendar_select_day (calendar, month_len); + } + else + gtk_calendar_select_day (calendar, calendar->selected_day); + + gtk_widget_queue_draw (GTK_WIDGET (calendar)); +} + +static void +calendar_set_year_next (GtkCalendar *calendar) +{ + gint month_len; + GtkWidget *widget; + + g_return_if_fail (GTK_IS_WIDGET (calendar)); + + widget = GTK_WIDGET (calendar); + + calendar->year++; + calendar_compute_days (calendar); + g_signal_emit (calendar, + gtk_calendar_signals[NEXT_YEAR_SIGNAL], + 0); + g_signal_emit (calendar, + gtk_calendar_signals[MONTH_CHANGED_SIGNAL], + 0); + + month_len = month_length[leap (calendar->year)][calendar->month + 1]; + + if (month_len < calendar->selected_day) + { + calendar->selected_day = 0; + gtk_calendar_select_day (calendar, month_len); + } + else + gtk_calendar_select_day (calendar, calendar->selected_day); + + gtk_widget_queue_draw (GTK_WIDGET (calendar)); +} + +static void +calendar_compute_days (GtkCalendar *calendar) +{ + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (GTK_WIDGET (calendar)); + gint month; + gint year; + gint ndays_in_month; + gint ndays_in_prev_month; + gint first_day; + gint row; + gint col; + gint day; + + g_return_if_fail (GTK_IS_CALENDAR (calendar)); + + year = calendar->year; + month = calendar->month + 1; + + ndays_in_month = month_length[leap (year)][month]; + + first_day = day_of_week (year, month, 1); + first_day = (first_day + 7 - priv->week_start) % 7; + + /* Compute days of previous month */ + if (month > 1) + ndays_in_prev_month = month_length[leap (year)][month-1]; + else + ndays_in_prev_month = month_length[leap (year)][12]; + day = ndays_in_prev_month - first_day + 1; + + row = 0; + if (first_day > 0) + { + for (col = 0; col < first_day; col++) + { + calendar->day[row][col] = day; + calendar->day_month[row][col] = MONTH_PREV; + day++; + } + } + + /* Compute days of current month */ + col = first_day; + for (day = 1; day <= ndays_in_month; day++) + { + calendar->day[row][col] = day; + calendar->day_month[row][col] = MONTH_CURRENT; + + col++; + if (col == 7) + { + row++; + col = 0; + } + } + + /* Compute days of next month */ + day = 1; + for (; row <= 5; row++) + { + for (; col <= 6; col++) + { + calendar->day[row][col] = day; + calendar->day_month[row][col] = MONTH_NEXT; + day++; + } + col = 0; + } +} + +static void +calendar_select_and_focus_day (GtkCalendar *calendar, + guint day) +{ + gint old_focus_row = calendar->focus_row; + gint old_focus_col = calendar->focus_col; + gint row; + gint col; + + for (row = 0; row < 6; row ++) + for (col = 0; col < 7; col++) + { + if (calendar->day_month[row][col] == MONTH_CURRENT + && calendar->day[row][col] == day) + { + calendar->focus_row = row; + calendar->focus_col = col; + } + } + + if (old_focus_row != -1 && old_focus_col != -1) + calendar_invalidate_day (calendar, old_focus_row, old_focus_col); + + gtk_calendar_select_day (calendar, day); +} + + +/**************************************** + * Layout computation utilities * + ****************************************/ + +static gint +calendar_row_height (GtkCalendar *calendar) +{ + return (GTK_CALENDAR_GET_PRIVATE (calendar)->main_h - CALENDAR_MARGIN + - ((calendar->display_flags & GTK_CALENDAR_SHOW_DAY_NAMES) + ? CALENDAR_YSEP : CALENDAR_MARGIN)) / 6; +} + + +/* calendar_left_x_for_column: returns the x coordinate + * for the left of the column */ +static gint +calendar_left_x_for_column (GtkCalendar *calendar, + gint column) +{ + gint width; + gint x_left; + + if (gtk_widget_get_direction (GTK_WIDGET (calendar)) == GTK_TEXT_DIR_RTL) + column = 6 - column; + + width = GTK_CALENDAR_GET_PRIVATE (calendar)->day_width; + if (calendar->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS) + x_left = CALENDAR_XSEP + (width + DAY_XSEP) * column; + else + x_left = CALENDAR_MARGIN + (width + DAY_XSEP) * column; + + return x_left; } /* column_from_x: returns the column 0-6 that the * x pixel of the xwindow is in */ static gint -column_from_x (GtkCalendar *calendar, - gint event_x) +calendar_column_from_x (GtkCalendar *calendar, + gint event_x) { gint c, column; gint x_left, x_right; @@ -749,8 +922,8 @@ column_from_x (GtkCalendar *calendar, for (c = 0; c < 7; c++) { - x_left = left_x_for_column (calendar, c); - x_right = x_left + GTK_CALENDAR_PRIVATE_DATA (calendar)->day_width; + x_left = calendar_left_x_for_column (calendar, c); + x_right = x_left + GTK_CALENDAR_GET_PRIVATE (calendar)->day_width; if (event_x >= x_left && event_x < x_right) { @@ -762,31 +935,34 @@ column_from_x (GtkCalendar *calendar, return column; } +/* calendar_top_y_for_row: returns the y coordinate + * for the top of the row */ static gint -row_height (GtkCalendar *calendar) +calendar_top_y_for_row (GtkCalendar *calendar, + gint row) { - return (GTK_CALENDAR_PRIVATE_DATA (calendar)->main_h - CALENDAR_MARGIN - - ((calendar->display_flags & GTK_CALENDAR_SHOW_DAY_NAMES) - ? CALENDAR_YSEP : CALENDAR_MARGIN)) / 6; + + return (GTK_CALENDAR_GET_PRIVATE (calendar)->main_h + - (CALENDAR_MARGIN + (6 - row) + * calendar_row_height (calendar))); } - /* row_from_y: returns the row 0-5 that the * y pixel of the xwindow is in */ static gint -row_from_y (GtkCalendar *calendar, - gint event_y) +calendar_row_from_y (GtkCalendar *calendar, + gint event_y) { gint r, row; gint height; gint y_top, y_bottom; - height = row_height (calendar); + height = calendar_row_height (calendar); row = -1; for (r = 0; r < 6; r++) { - y_top = top_y_for_row (calendar, r); + y_top = calendar_top_y_for_row (calendar, r); y_bottom = y_top + height; if (event_y >= y_top && event_y < y_bottom) @@ -797,41 +973,79 @@ row_from_y (GtkCalendar *calendar, } return row; -}/* left_x_for_column: returns the x coordinate - * for the left of the column */ -static gint -left_x_for_column (GtkCalendar *calendar, - gint column) +} + +static void +calendar_arrow_rectangle (GtkCalendar *calendar, + guint arrow, + GdkRectangle *rect) { - gint width; - gint x_left; - - if (gtk_widget_get_direction (GTK_WIDGET (calendar)) == GTK_TEXT_DIR_RTL) - column = 6 - column; + GtkWidget *widget = GTK_WIDGET (calendar); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); + gboolean year_left; - width = GTK_CALENDAR_PRIVATE_DATA (calendar)->day_width; - if (calendar->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS) - x_left = CALENDAR_XSEP + (width + DAY_XSEP) * column; + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) + year_left = priv->year_before; else - x_left = CALENDAR_MARGIN + (width + DAY_XSEP) * column; + year_left = !priv->year_before; + + rect->y = 3; + rect->width = priv->arrow_width; + rect->height = priv->header_h - 7; - return x_left; + switch (arrow) + { + case ARROW_MONTH_LEFT: + if (year_left) + rect->x = (widget->allocation.width - 2 * widget->style->xthickness + - (3 + 2*priv->arrow_width + + priv->max_month_width)); + else + rect->x = 3; + break; + case ARROW_MONTH_RIGHT: + if (year_left) + rect->x = (widget->allocation.width - 2 * widget->style->xthickness + - 3 - priv->arrow_width); + else + rect->x = (priv->arrow_width + + priv->max_month_width); + break; + case ARROW_YEAR_LEFT: + if (year_left) + rect->x = 3; + else + rect->x = (widget->allocation.width - 2 * widget->style->xthickness + - (3 + 2*priv->arrow_width + + priv->max_year_width)); + break; + case ARROW_YEAR_RIGHT: + if (year_left) + rect->x = (priv->arrow_width + + priv->max_year_width); + else + rect->x = (widget->allocation.width - 2 * widget->style->xthickness + - 3 - priv->arrow_width); + break; + } } -/* top_y_for_row: returns the y coordinate - * for the top of the row */ -static gint -top_y_for_row (GtkCalendar *calendar, - gint row) +static void +calendar_day_rectangle (GtkCalendar *calendar, + gint row, + gint col, + GdkRectangle *rect) { - - return (GTK_CALENDAR_PRIVATE_DATA (calendar)->main_h - - (CALENDAR_MARGIN + (6 - row) - * row_height (calendar))); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); + + rect->x = calendar_left_x_for_column (calendar, col); + rect->y = calendar_top_y_for_row (calendar, row); + rect->height = calendar_row_height (calendar); + rect->width = priv->day_width; } static void -gtk_calendar_set_month_prev (GtkCalendar *calendar) +calendar_set_month_prev (GtkCalendar *calendar) { gint month_len; @@ -848,8 +1062,7 @@ gtk_calendar_set_month_prev (GtkCalendar *calendar) month_len = month_length[leap (calendar->year)][calendar->month + 1]; - gtk_calendar_freeze (calendar); - gtk_calendar_compute_days (calendar); + calendar_compute_days (calendar); g_signal_emit (calendar, gtk_calendar_signals[PREV_MONTH_SIGNAL], @@ -871,195 +1084,157 @@ gtk_calendar_set_month_prev (GtkCalendar *calendar) } gtk_widget_queue_draw (GTK_WIDGET (calendar)); - gtk_calendar_thaw (calendar); } + +/**************************************** + * Basic object methods * + ****************************************/ static void -gtk_calendar_set_month_next (GtkCalendar *calendar) +gtk_calendar_finalize (GObject *object) { - gint month_len; - - g_return_if_fail (GTK_IS_WIDGET (calendar)); - - if (calendar->display_flags & GTK_CALENDAR_NO_MONTH_CHANGE) - return; - - - if (calendar->month == 11) - { - calendar->month = 0; - calendar->year++; - } - else - calendar->month++; - - gtk_calendar_freeze (calendar); - gtk_calendar_compute_days (calendar); - g_signal_emit (calendar, - gtk_calendar_signals[NEXT_MONTH_SIGNAL], - 0); - g_signal_emit (calendar, - gtk_calendar_signals[MONTH_CHANGED_SIGNAL], - 0); - - month_len = month_length[leap (calendar->year)][calendar->month + 1]; - - if (month_len < calendar->selected_day) - { - calendar->selected_day = 0; - gtk_calendar_select_day (calendar, month_len); - } - else - gtk_calendar_select_day (calendar, calendar->selected_day); - - gtk_widget_queue_draw (GTK_WIDGET (calendar)); - gtk_calendar_thaw (calendar); + (* G_OBJECT_CLASS (gtk_calendar_parent_class)->finalize) (object); } static void -gtk_calendar_set_year_prev (GtkCalendar *calendar) +gtk_calendar_destroy (GtkObject *object) { - gint month_len; - - g_return_if_fail (GTK_IS_WIDGET (calendar)); + calendar_stop_spinning (GTK_CALENDAR (object)); - calendar->year--; - gtk_calendar_freeze (calendar); - gtk_calendar_compute_days (calendar); - g_signal_emit (calendar, - gtk_calendar_signals[PREV_YEAR_SIGNAL], - 0); - g_signal_emit (calendar, - gtk_calendar_signals[MONTH_CHANGED_SIGNAL], - 0); - - month_len = month_length[leap (calendar->year)][calendar->month + 1]; - - if (month_len < calendar->selected_day) - { - calendar->selected_day = 0; - gtk_calendar_select_day (calendar, month_len); - } - else - gtk_calendar_select_day (calendar, calendar->selected_day); - - gtk_widget_queue_draw (GTK_WIDGET (calendar)); - gtk_calendar_thaw (calendar); + GTK_OBJECT_CLASS (gtk_calendar_parent_class)->destroy (object); } + static void -gtk_calendar_set_year_next (GtkCalendar *calendar) +calendar_set_display_option (GtkCalendar *calendar, + GtkCalendarDisplayOptions flag, + gboolean setting) { - gint month_len; - GtkWidget *widget; - - g_return_if_fail (GTK_IS_WIDGET (calendar)); - - widget = GTK_WIDGET (calendar); - - gtk_calendar_freeze (calendar); - - calendar->year++; - gtk_calendar_compute_days (calendar); - g_signal_emit (calendar, - gtk_calendar_signals[NEXT_YEAR_SIGNAL], - 0); - g_signal_emit (calendar, - gtk_calendar_signals[MONTH_CHANGED_SIGNAL], - 0); - - month_len = month_length[leap (calendar->year)][calendar->month + 1]; - - if (month_len < calendar->selected_day) - { - calendar->selected_day = 0; - gtk_calendar_select_day (calendar, month_len); - } + GtkCalendarDisplayOptions flags; + if (setting) + flags = calendar->display_flags | flag; else - gtk_calendar_select_day (calendar, calendar->selected_day); - - gtk_widget_queue_draw (GTK_WIDGET (calendar)); - gtk_calendar_thaw (calendar); + flags = calendar->display_flags & ~flag; + gtk_calendar_display_options (calendar, flags); } -static void -gtk_calendar_main_button (GtkWidget *widget, - GdkEventButton *event) +static gboolean +calendar_get_display_option (GtkCalendar *calendar, + GtkCalendarDisplayOptions flag) +{ + return (calendar->display_flags & flag) != 0; +} + +static void +gtk_calendar_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; - gint x, y; - gint row, col; - gint day_month; - gint day; - - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - - x = (gint) (event->x); - y = (gint) (event->y); - - row = row_from_y (calendar, y); - col = column_from_x (calendar, x); - /* If row or column isn't found, just return. */ - if (row == -1 || col == -1) - return; - - day_month = calendar->day_month[row][col]; + calendar = GTK_CALENDAR (object); - if (event->type == GDK_BUTTON_PRESS) + switch (prop_id) { - day = calendar->day[row][col]; - - if (day_month == MONTH_PREV) - gtk_calendar_set_month_prev (calendar); - else if (day_month == MONTH_NEXT) - gtk_calendar_set_month_next (calendar); - - if (!GTK_WIDGET_HAS_FOCUS (widget)) - gtk_widget_grab_focus (widget); - - if (event->button == 1) - { - private_data->in_drag = 1; - private_data->drag_start_x = x; - private_data->drag_start_y = y; - } - - gtk_calendar_select_and_focus_day (calendar, day); + case PROP_YEAR: + gtk_calendar_select_month (calendar, + calendar->month, + g_value_get_int (value)); + break; + case PROP_MONTH: + gtk_calendar_select_month (calendar, + g_value_get_int (value), + calendar->year); + break; + case PROP_DAY: + gtk_calendar_select_day (calendar, + g_value_get_int (value)); + break; + case PROP_SHOW_HEADING: + calendar_set_display_option (calendar, + GTK_CALENDAR_SHOW_HEADING, + g_value_get_boolean (value)); + break; + case PROP_SHOW_DAY_NAMES: + calendar_set_display_option (calendar, + GTK_CALENDAR_SHOW_DAY_NAMES, + g_value_get_boolean (value)); + break; + case PROP_NO_MONTH_CHANGE: + calendar_set_display_option (calendar, + GTK_CALENDAR_NO_MONTH_CHANGE, + g_value_get_boolean (value)); + break; + case PROP_SHOW_WEEK_NUMBERS: + calendar_set_display_option (calendar, + GTK_CALENDAR_SHOW_WEEK_NUMBERS, + g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } - else if (event->type == GDK_2BUTTON_PRESS) +} + +static void +gtk_calendar_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkCalendar *calendar; + + calendar = GTK_CALENDAR (object); + + switch (prop_id) { - private_data->in_drag = 0; - if (day_month == MONTH_CURRENT) - g_signal_emit (calendar, - gtk_calendar_signals[DAY_SELECTED_DOUBLE_CLICK_SIGNAL], - 0); + case PROP_YEAR: + g_value_set_int (value, calendar->year); + break; + case PROP_MONTH: + g_value_set_int (value, calendar->month); + break; + case PROP_DAY: + g_value_set_int (value, calendar->selected_day); + break; + case PROP_SHOW_HEADING: + g_value_set_boolean (value, calendar_get_display_option (calendar, + GTK_CALENDAR_SHOW_HEADING)); + break; + case PROP_SHOW_DAY_NAMES: + g_value_set_boolean (value, calendar_get_display_option (calendar, + GTK_CALENDAR_SHOW_DAY_NAMES)); + break; + case PROP_NO_MONTH_CHANGE: + g_value_set_boolean (value, calendar_get_display_option (calendar, + GTK_CALENDAR_NO_MONTH_CHANGE)); + break; + case PROP_SHOW_WEEK_NUMBERS: + g_value_set_boolean (value, calendar_get_display_option (calendar, + GTK_CALENDAR_SHOW_WEEK_NUMBERS)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } } + +/**************************************** + * Realization * + ****************************************/ + static void -gtk_calendar_realize_arrows (GtkWidget *widget) +calendar_realize_arrows (GtkCalendar *calendar) { - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; + GtkWidget *widget = GTK_WIDGET (calendar); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); GdkWindowAttr attributes; gint attributes_mask; gint i; - gboolean year_left; - - g_return_if_fail (GTK_IS_CALENDAR (widget)); - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) - year_left = private_data->year_before; - else - year_left = !private_data->year_before; - /* Arrow windows ------------------------------------- */ if (! (calendar->display_flags & GTK_CALENDAR_NO_MONTH_CHANGE) && (calendar->display_flags & GTK_CALENDAR_SHOW_HEADING)) @@ -1072,79 +1247,43 @@ gtk_calendar_realize_arrows (GtkWidget *widget) | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - attributes.y = 3; - attributes.width = private_data->arrow_width; - attributes.height = private_data->header_h - 7; for (i = 0; i < 4; i++) { - switch (i) - { - case ARROW_MONTH_LEFT: - if (year_left) - attributes.x = (widget->allocation.width - 2 * widget->style->xthickness - - (3 + 2*private_data->arrow_width - + private_data->max_month_width)); - else - attributes.x = 3; - break; - case ARROW_MONTH_RIGHT: - if (year_left) - attributes.x = (widget->allocation.width - 2 * widget->style->xthickness - - 3 - private_data->arrow_width); - else - attributes.x = (private_data->arrow_width - + private_data->max_month_width); - break; - case ARROW_YEAR_LEFT: - if (year_left) - attributes.x = 3; - else - attributes.x = (widget->allocation.width - 2 * widget->style->xthickness - - (3 + 2*private_data->arrow_width - + private_data->max_year_width)); - break; - case ARROW_YEAR_RIGHT: - if (year_left) - attributes.x = (private_data->arrow_width - + private_data->max_year_width); - else - attributes.x = (widget->allocation.width - 2 * widget->style->xthickness - - 3 - private_data->arrow_width); - break; - } - private_data->arrow_win[i] = gdk_window_new (private_data->header_win, - &attributes, - attributes_mask); + GdkRectangle rect; + calendar_arrow_rectangle (calendar, i, &rect); + + attributes.x = rect.x; + attributes.y = rect.y; + attributes.width = rect.width; + attributes.height = rect.width; + priv->arrow_win[i] = gdk_window_new (priv->header_win, + &attributes, + attributes_mask); if (GTK_WIDGET_IS_SENSITIVE (widget)) - private_data->arrow_state[i] = GTK_STATE_NORMAL; + priv->arrow_state[i] = GTK_STATE_NORMAL; else - private_data->arrow_state[i] = GTK_STATE_INSENSITIVE; - gdk_window_set_background (private_data->arrow_win[i], + priv->arrow_state[i] = GTK_STATE_INSENSITIVE; + gdk_window_set_background (priv->arrow_win[i], HEADER_BG_COLOR (GTK_WIDGET (calendar))); - gdk_window_show (private_data->arrow_win[i]); - gdk_window_set_user_data (private_data->arrow_win[i], widget); + gdk_window_show (priv->arrow_win[i]); + gdk_window_set_user_data (priv->arrow_win[i], widget); } } else { for (i = 0; i < 4; i++) - private_data->arrow_win[i] = NULL; + priv->arrow_win[i] = NULL; } } static void -gtk_calendar_realize_header (GtkWidget *widget) +calendar_realize_header (GtkCalendar *calendar) { - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; + GtkWidget *widget = GTK_WIDGET (calendar); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); GdkWindowAttr attributes; gint attributes_mask; - g_return_if_fail (GTK_IS_CALENDAR (widget)); - - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - /* Header window ------------------------------------- */ if (calendar->display_flags & GTK_CALENDAR_SHOW_HEADING) { @@ -1157,36 +1296,31 @@ gtk_calendar_realize_header (GtkWidget *widget) attributes.x = widget->style->xthickness; attributes.y = widget->style->ythickness; attributes.width = widget->allocation.width - 2 * attributes.x; - attributes.height = private_data->header_h - 2 * attributes.y; - private_data->header_win = gdk_window_new (widget->window, - &attributes, attributes_mask); + attributes.height = priv->header_h - 2 * attributes.y; + priv->header_win = gdk_window_new (widget->window, + &attributes, attributes_mask); - gdk_window_set_background (private_data->header_win, + gdk_window_set_background (priv->header_win, HEADER_BG_COLOR (GTK_WIDGET (calendar))); - gdk_window_show (private_data->header_win); - gdk_window_set_user_data (private_data->header_win, widget); + gdk_window_show (priv->header_win); + gdk_window_set_user_data (priv->header_win, widget); } else { - private_data->header_win = NULL; + priv->header_win = NULL; } - gtk_calendar_realize_arrows (widget); + calendar_realize_arrows (calendar); } static void -gtk_calendar_realize_day_names (GtkWidget *widget) +calendar_realize_day_names (GtkCalendar *calendar) { - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; + GtkWidget *widget = GTK_WIDGET (calendar); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); GdkWindowAttr attributes; gint attributes_mask; - g_return_if_fail (GTK_IS_CALENDAR (widget)); - - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - /* Day names window --------------------------------- */ if ( calendar->display_flags & GTK_CALENDAR_SHOW_DAY_NAMES) { @@ -1197,39 +1331,34 @@ gtk_calendar_realize_day_names (GtkWidget *widget) attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK; attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; attributes.x = (widget->style->xthickness + INNER_BORDER); - attributes.y = private_data->header_h + (widget->style->ythickness + attributes.y = priv->header_h + (widget->style->ythickness + INNER_BORDER); attributes.width = (widget->allocation.width - (widget->style->xthickness + INNER_BORDER) * 2); - attributes.height = private_data->day_name_h; - private_data->day_name_win = gdk_window_new (widget->window, - &attributes, - attributes_mask); - gdk_window_set_background (private_data->day_name_win, + attributes.height = priv->day_name_h; + priv->day_name_win = gdk_window_new (widget->window, + &attributes, + attributes_mask); + gdk_window_set_background (priv->day_name_win, BACKGROUND_COLOR ( GTK_WIDGET ( calendar))); - gdk_window_show (private_data->day_name_win); - gdk_window_set_user_data (private_data->day_name_win, widget); + gdk_window_show (priv->day_name_win); + gdk_window_set_user_data (priv->day_name_win, widget); } else { - private_data->day_name_win = NULL; + priv->day_name_win = NULL; } } static void -gtk_calendar_realize_week_numbers (GtkWidget *widget) +calendar_realize_week_numbers (GtkCalendar *calendar) { - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; + GtkWidget *widget = GTK_WIDGET (calendar); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); GdkWindowAttr attributes; gint attributes_mask; - g_return_if_fail (GTK_IS_CALENDAR (widget)); - - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - /* Week number window -------------------------------- */ if (calendar->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS) { @@ -1241,37 +1370,32 @@ gtk_calendar_realize_week_numbers (GtkWidget *widget) attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; attributes.x = widget->style->xthickness + INNER_BORDER; - attributes.y = (private_data->header_h + private_data->day_name_h + attributes.y = (priv->header_h + priv->day_name_h + (widget->style->ythickness + INNER_BORDER)); - attributes.width = private_data->week_width; - attributes.height = private_data->main_h; - private_data->week_win = gdk_window_new (widget->window, - &attributes, attributes_mask); - gdk_window_set_background (private_data->week_win, + attributes.width = priv->week_width; + attributes.height = priv->main_h; + priv->week_win = gdk_window_new (widget->window, + &attributes, attributes_mask); + gdk_window_set_background (priv->week_win, BACKGROUND_COLOR (GTK_WIDGET (calendar))); - gdk_window_show (private_data->week_win); - gdk_window_set_user_data (private_data->week_win, widget); + gdk_window_show (priv->week_win); + gdk_window_set_user_data (priv->week_win, widget); } else { - private_data->week_win = NULL; + priv->week_win = NULL; } } static void gtk_calendar_realize (GtkWidget *widget) { - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; + GtkCalendar *calendar = GTK_CALENDAR (widget); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); GdkWindowAttr attributes; gint attributes_mask; - GdkGCValues values; - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - gtk_calendar_compute_days (calendar); attributes.x = widget->allocation.x; attributes.y = widget->allocation.y; @@ -1291,103 +1415,90 @@ gtk_calendar_realize (GtkWidget *widget) widget->style = gtk_style_attach (widget->style, widget->window); /* Header window ------------------------------------- */ - gtk_calendar_realize_header (widget); + calendar_realize_header (calendar); /* Day names window --------------------------------- */ - gtk_calendar_realize_day_names (widget); + calendar_realize_day_names (calendar); /* Week number window -------------------------------- */ - gtk_calendar_realize_week_numbers (widget); + calendar_realize_week_numbers (calendar); /* Main Window -------------------------------------- */ attributes.event_mask = (gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK); - attributes.x = private_data->week_width + (widget->style->ythickness + INNER_BORDER); - attributes.y = (private_data->header_h + private_data->day_name_h + attributes.x = priv->week_width + (widget->style->ythickness + INNER_BORDER); + attributes.y = (priv->header_h + priv->day_name_h + (widget->style->ythickness + INNER_BORDER)); attributes.width = (widget->allocation.width - attributes.x - (widget->style->xthickness + INNER_BORDER)); - attributes.height = private_data->main_h; - private_data->main_win = gdk_window_new (widget->window, - &attributes, attributes_mask); - gdk_window_set_background (private_data->main_win, + attributes.height = priv->main_h; + priv->main_win = gdk_window_new (widget->window, + &attributes, attributes_mask); + gdk_window_set_background (priv->main_win, BACKGROUND_COLOR ( GTK_WIDGET ( calendar))); - gdk_window_show (private_data->main_win); - gdk_window_set_user_data (private_data->main_win, widget); + gdk_window_show (priv->main_win); + gdk_window_set_user_data (priv->main_win, widget); gdk_window_set_background (widget->window, BACKGROUND_COLOR (widget)); gdk_window_show (widget->window); gdk_window_set_user_data (widget->window, widget); - - /* Set widgets gc */ - calendar->gc = gdk_gc_new (widget->window); - - values.foreground = widget->style->white; - values.function = GDK_XOR; - calendar->xor_gc = gdk_gc_new_with_values (widget->window, - &values, - GDK_GC_FOREGROUND | - GDK_GC_FUNCTION); } static void gtk_calendar_unrealize (GtkWidget *widget) { - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); gint i; - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - - if (private_data->header_win) + if (priv->header_win) { for (i = 0; i < 4; i++) { - if (private_data->arrow_win[i]) + if (priv->arrow_win[i]) { - gdk_window_set_user_data (private_data->arrow_win[i], NULL); - gdk_window_destroy (private_data->arrow_win[i]); - private_data->arrow_win[i] = NULL; + gdk_window_set_user_data (priv->arrow_win[i], NULL); + gdk_window_destroy (priv->arrow_win[i]); + priv->arrow_win[i] = NULL; } } - gdk_window_set_user_data (private_data->header_win, NULL); - gdk_window_destroy (private_data->header_win); - private_data->header_win = NULL; + gdk_window_set_user_data (priv->header_win, NULL); + gdk_window_destroy (priv->header_win); + priv->header_win = NULL; } - if (private_data->week_win) + if (priv->week_win) { - gdk_window_set_user_data (private_data->week_win, NULL); - gdk_window_destroy (private_data->week_win); - private_data->week_win = NULL; + gdk_window_set_user_data (priv->week_win, NULL); + gdk_window_destroy (priv->week_win); + priv->week_win = NULL; } - if (private_data->main_win) + if (priv->main_win) { - gdk_window_set_user_data (private_data->main_win, NULL); - gdk_window_destroy (private_data->main_win); - private_data->main_win = NULL; + gdk_window_set_user_data (priv->main_win, NULL); + gdk_window_destroy (priv->main_win); + priv->main_win = NULL; } - if (private_data->day_name_win) + if (priv->day_name_win) { - gdk_window_set_user_data (private_data->day_name_win, NULL); - gdk_window_destroy (private_data->day_name_win); - private_data->day_name_win = NULL; + gdk_window_set_user_data (priv->day_name_win, NULL); + gdk_window_destroy (priv->day_name_win); + priv->day_name_win = NULL; } - if (calendar->xor_gc) - g_object_unref (calendar->xor_gc); - if (calendar->gc) - g_object_unref (calendar->gc); - if (GTK_WIDGET_CLASS (parent_class)->unrealize) - (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); + if (GTK_WIDGET_CLASS (gtk_calendar_parent_class)->unrealize) + (* GTK_WIDGET_CLASS (gtk_calendar_parent_class)->unrealize) (widget); } + +/**************************************** + * Size Request and Allocate * + ****************************************/ + static void gtk_calendar_size_request (GtkWidget *widget, GtkRequisition *requisition) { - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; + GtkCalendar *calendar = GTK_CALENDAR (widget); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); PangoLayout *layout; PangoRectangle logical_rect; @@ -1400,8 +1511,6 @@ gtk_calendar_size_request (GtkWidget *widget, gint focus_width; gint focus_padding; - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); gtk_widget_style_get (GTK_WIDGET (widget), "focus-line-width", &focus_width, "focus-padding", &focus_padding, @@ -1417,63 +1526,63 @@ gtk_calendar_size_request (GtkWidget *widget, if (calendar->display_flags & GTK_CALENDAR_SHOW_HEADING) { - private_data->max_month_width = 0; + priv->max_month_width = 0; for (i = 0; i < 12; i++) { pango_layout_set_text (layout, default_monthname[i], -1); pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - private_data->max_month_width = MAX (private_data->max_month_width, + priv->max_month_width = MAX (priv->max_month_width, logical_rect.width + 8); max_header_height = MAX (max_header_height, logical_rect.height); } - private_data->max_year_width = 0; + priv->max_year_width = 0; for (i=0; i<10; i++) { g_snprintf (buffer, sizeof (buffer), "%d%d%d%d", i,i,i,i); pango_layout_set_text (layout, buffer, -1); pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - private_data->max_year_width = MAX (private_data->max_year_width, + priv->max_year_width = MAX (priv->max_year_width, logical_rect.width + 8); max_header_height = MAX (max_header_height, logical_rect.height); } } else { - private_data->max_month_width = 0; - private_data->max_year_width = 0; + priv->max_month_width = 0; + priv->max_year_width = 0; } if (calendar->display_flags & GTK_CALENDAR_NO_MONTH_CHANGE) - header_width = (private_data->max_month_width - + private_data->max_year_width + header_width = (priv->max_month_width + + priv->max_year_width + 3 * 3); else - header_width = (private_data->max_month_width - + private_data->max_year_width - + 4 * private_data->arrow_width + 3 * 3); + header_width = (priv->max_month_width + + priv->max_year_width + + 4 * priv->arrow_width + 3 * 3); /* Mainwindow labels width */ - private_data->max_day_char_width = 0; - private_data->min_day_width = 0; - private_data->max_label_char_ascent = 0; - private_data->max_label_char_descent = 0; + priv->max_day_char_width = 0; + priv->min_day_width = 0; + priv->max_label_char_ascent = 0; + priv->max_label_char_descent = 0; for (i = 0; i < 9; i++) { g_snprintf (buffer, sizeof (buffer), "%d%d", i, i); pango_layout_set_text (layout, buffer, -1); pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - private_data->min_day_width = MAX (private_data->min_day_width, + priv->min_day_width = MAX (priv->min_day_width, logical_rect.width); - private_data->max_day_char_ascent = MAX (private_data->max_label_char_ascent, + priv->max_day_char_ascent = MAX (priv->max_label_char_ascent, PANGO_ASCENT (logical_rect)); - private_data->max_day_char_descent = MAX (private_data->max_label_char_descent, + priv->max_day_char_descent = MAX (priv->max_label_char_descent, PANGO_DESCENT (logical_rect)); } /* We add one to max_day_char_width to be able to make the marked day "bold" */ - private_data->max_day_char_width = private_data->min_day_width / 2 + 1; + priv->max_day_char_width = priv->min_day_width / 2 + 1; if (calendar->display_flags & GTK_CALENDAR_SHOW_DAY_NAMES) for (i = 0; i < 7; i++) @@ -1481,27 +1590,27 @@ gtk_calendar_size_request (GtkWidget *widget, pango_layout_set_text (layout, default_abbreviated_dayname[i], -1); pango_layout_line_get_pixel_extents (pango_layout_get_lines (layout)->data, NULL, &logical_rect); - private_data->min_day_width = MAX (private_data->min_day_width, logical_rect.width); - private_data->max_label_char_ascent = MAX (private_data->max_label_char_ascent, + priv->min_day_width = MAX (priv->min_day_width, logical_rect.width); + priv->max_label_char_ascent = MAX (priv->max_label_char_ascent, PANGO_ASCENT (logical_rect)); - private_data->max_label_char_descent = MAX (private_data->max_label_char_descent, + priv->max_label_char_descent = MAX (priv->max_label_char_descent, PANGO_DESCENT (logical_rect)); } - private_data->max_week_char_width = 0; + priv->max_week_char_width = 0; if (calendar->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS) for (i = 0; i < 9; i++) { g_snprintf (buffer, sizeof (buffer), "%d%d", i, i); pango_layout_set_text (layout, buffer, -1); pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - private_data->max_week_char_width = MAX (private_data->max_week_char_width, + priv->max_week_char_width = MAX (priv->max_week_char_width, logical_rect.width / 2); } - main_width = (7 * (private_data->min_day_width + (focus_padding + focus_width) * 2) + (DAY_XSEP * 6) + CALENDAR_MARGIN * 2 - + (private_data->max_week_char_width - ? private_data->max_week_char_width * 2 + (focus_padding + focus_width) * 2 + CALENDAR_XSEP * 2 + main_width = (7 * (priv->min_day_width + (focus_padding + focus_width) * 2) + (DAY_XSEP * 6) + CALENDAR_MARGIN * 2 + + (priv->max_week_char_width + ? priv->max_week_char_width * 2 + (focus_padding + focus_width) * 2 + CALENDAR_XSEP * 2 : 0)); @@ -1513,33 +1622,33 @@ gtk_calendar_size_request (GtkWidget *widget, if (calendar->display_flags & GTK_CALENDAR_SHOW_HEADING) { - private_data->header_h = (max_header_height + CALENDAR_YSEP * 2); + priv->header_h = (max_header_height + CALENDAR_YSEP * 2); } else { - private_data->header_h = 0; + priv->header_h = 0; } if (calendar->display_flags & GTK_CALENDAR_SHOW_DAY_NAMES) { - private_data->day_name_h = (private_data->max_label_char_ascent - + private_data->max_label_char_descent + priv->day_name_h = (priv->max_label_char_ascent + + priv->max_label_char_descent + 2 * (focus_padding + focus_width) + calendar_margin); calendar_margin = CALENDAR_YSEP; } else { - private_data->day_name_h = 0; + priv->day_name_h = 0; } - private_data->main_h = (CALENDAR_MARGIN + calendar_margin - + 6 * (private_data->max_day_char_ascent - + private_data->max_day_char_descent + priv->main_h = (CALENDAR_MARGIN + calendar_margin + + 6 * (priv->max_day_char_ascent + + priv->max_day_char_descent + 2 * (focus_padding + focus_width)) + DAY_YSEP * 5); - height = (private_data->header_h + private_data->day_name_h - + private_data->main_h); + height = (priv->header_h + priv->day_name_h + + priv->main_h); requisition->height = height + (widget->style->ythickness + INNER_BORDER) * 2; @@ -1550,39 +1659,37 @@ static void gtk_calendar_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; + GtkCalendar *calendar = GTK_CALENDAR (widget); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); gint xthickness = widget->style->xthickness; gint ythickness = widget->style->xthickness; gboolean year_left; + guint i; widget->allocation = *allocation; - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) - year_left = private_data->year_before; + year_left = priv->year_before; else - year_left = !private_data->year_before; + year_left = !priv->year_before; if (calendar->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS) { - private_data->day_width = (private_data->min_day_width - * ((allocation->width - (xthickness + INNER_BORDER) * 2 - - (CALENDAR_MARGIN * 2) - (DAY_XSEP * 6) - CALENDAR_XSEP * 2)) - / (7 * private_data->min_day_width + private_data->max_week_char_width * 2)); - private_data->week_width = ((allocation->width - (xthickness + INNER_BORDER) * 2 - - (CALENDAR_MARGIN * 2) - (DAY_XSEP * 6) - CALENDAR_XSEP * 2 ) - - private_data->day_width * 7 + CALENDAR_MARGIN + CALENDAR_XSEP); + priv->day_width = (priv->min_day_width + * ((allocation->width - (xthickness + INNER_BORDER) * 2 + - (CALENDAR_MARGIN * 2) - (DAY_XSEP * 6) - CALENDAR_XSEP * 2)) + / (7 * priv->min_day_width + priv->max_week_char_width * 2)); + priv->week_width = ((allocation->width - (xthickness + INNER_BORDER) * 2 + - (CALENDAR_MARGIN * 2) - (DAY_XSEP * 6) - CALENDAR_XSEP * 2 ) + - priv->day_width * 7 + CALENDAR_MARGIN + CALENDAR_XSEP); } else { - private_data->day_width = (allocation->width - - (xthickness + INNER_BORDER) * 2 - - (CALENDAR_MARGIN * 2) - - (DAY_XSEP * 6))/7; - private_data->week_width = 0; + priv->day_width = (allocation->width + - (xthickness + INNER_BORDER) * 2 + - (CALENDAR_MARGIN * 2) + - (DAY_XSEP * 6))/7; + priv->week_width = 0; } if (GTK_WIDGET_REALIZED (widget)) @@ -1590,203 +1697,107 @@ gtk_calendar_size_allocate (GtkWidget *widget, gdk_window_move_resize (widget->window, allocation->x, allocation->y, allocation->width, allocation->height); - if (private_data->header_win) - gdk_window_move_resize (private_data->header_win, + if (priv->header_win) + gdk_window_move_resize (priv->header_win, xthickness, ythickness, - allocation->width - 2 * xthickness, private_data->header_h); - if (private_data->arrow_win[ARROW_MONTH_LEFT]) - { - if (year_left) - gdk_window_move_resize (private_data->arrow_win[ARROW_MONTH_LEFT], - (allocation->width - 2 * xthickness - - (3 + 2*private_data->arrow_width - + private_data->max_month_width)), - 3, - private_data->arrow_width, - private_data->header_h - 7); - else - gdk_window_move_resize (private_data->arrow_win[ARROW_MONTH_LEFT], - 3, 3, - private_data->arrow_width, - private_data->header_h - 7); - } - if (private_data->arrow_win[ARROW_MONTH_RIGHT]) - { - if (year_left) - gdk_window_move_resize (private_data->arrow_win[ARROW_MONTH_RIGHT], - (allocation->width - 2 * xthickness - - 3 - private_data->arrow_width), - 3, - private_data->arrow_width, - private_data->header_h - 7); - else - gdk_window_move_resize (private_data->arrow_win[ARROW_MONTH_RIGHT], - (private_data->arrow_width - + private_data->max_month_width), - 3, - private_data->arrow_width, - private_data->header_h - 7); - } - if (private_data->arrow_win[ARROW_YEAR_LEFT]) - { - if (year_left) - gdk_window_move_resize (private_data->arrow_win[ARROW_YEAR_LEFT], - 3, 3, - private_data->arrow_width, - private_data->header_h - 7); - else - gdk_window_move_resize (private_data->arrow_win[ARROW_YEAR_LEFT], - (allocation->width - 2 * xthickness - - (3 + 2*private_data->arrow_width - + private_data->max_year_width)), - 3, - private_data->arrow_width, - private_data->header_h - 7); - } - if (private_data->arrow_win[ARROW_YEAR_RIGHT]) + allocation->width - 2 * xthickness, priv->header_h); + + for (i = 0 ; i < 4 ; i++) { - if (year_left) - gdk_window_move_resize (private_data->arrow_win[ARROW_YEAR_RIGHT], - (private_data->arrow_width - + private_data->max_year_width), - 3, - private_data->arrow_width, - private_data->header_h - 7); - else - gdk_window_move_resize (private_data->arrow_win[ARROW_YEAR_RIGHT], - (allocation->width - 2 * xthickness - - 3 - private_data->arrow_width), - 3, - private_data->arrow_width, - private_data->header_h - 7); + if (priv->arrow_win[i]) + { + GdkRectangle rect; + calendar_arrow_rectangle (calendar, i, &rect); + + gdk_window_move_resize (priv->arrow_win[i], + rect.x, rect.y, rect.width, rect.height); + } } - if (private_data->day_name_win) - gdk_window_move_resize (private_data->day_name_win, + + if (priv->day_name_win) + gdk_window_move_resize (priv->day_name_win, xthickness + INNER_BORDER, - private_data->header_h + (widget->style->ythickness + INNER_BORDER), + priv->header_h + (widget->style->ythickness + INNER_BORDER), allocation->width - (xthickness + INNER_BORDER) * 2, - private_data->day_name_h); + priv->day_name_h); if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) { - if (private_data->week_win) - gdk_window_move_resize (private_data->week_win, + if (priv->week_win) + gdk_window_move_resize (priv->week_win, (xthickness + INNER_BORDER), - private_data->header_h + private_data->day_name_h + priv->header_h + priv->day_name_h + (widget->style->ythickness + INNER_BORDER), - private_data->week_width, - private_data->main_h); - gdk_window_move_resize (private_data->main_win, - private_data->week_width + (xthickness + INNER_BORDER), - private_data->header_h + private_data->day_name_h + priv->week_width, + priv->main_h); + gdk_window_move_resize (priv->main_win, + priv->week_width + (xthickness + INNER_BORDER), + priv->header_h + priv->day_name_h + (widget->style->ythickness + INNER_BORDER), allocation->width - - private_data->week_width + - priv->week_width - (xthickness + INNER_BORDER) * 2, - private_data->main_h); + priv->main_h); } else { - gdk_window_move_resize (private_data->main_win, + gdk_window_move_resize (priv->main_win, (xthickness + INNER_BORDER), - private_data->header_h + private_data->day_name_h + priv->header_h + priv->day_name_h + (widget->style->ythickness + INNER_BORDER), allocation->width - - private_data->week_width + - priv->week_width - (xthickness + INNER_BORDER) * 2, - private_data->main_h); - if (private_data->week_win) - gdk_window_move_resize (private_data->week_win, + priv->main_h); + if (priv->week_win) + gdk_window_move_resize (priv->week_win, allocation->width - - private_data->week_width + - priv->week_width - (xthickness + INNER_BORDER), - private_data->header_h + private_data->day_name_h + priv->header_h + priv->day_name_h + (widget->style->ythickness + INNER_BORDER), - private_data->week_width, - private_data->main_h); + priv->week_width, + priv->main_h); } } } -static gboolean -gtk_calendar_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; - - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - - if (GTK_WIDGET_DRAWABLE (widget)) - { - if (event->window == private_data->main_win) - gtk_calendar_paint_main (widget); - - if (event->window == private_data->header_win) - gtk_calendar_paint_header (widget); - - if (event->window == private_data->day_name_win) - gtk_calendar_paint_day_names (widget); - - if (event->window == private_data->week_win) - gtk_calendar_paint_week_numbers (widget); - if (event->window == widget->window) - { - gtk_paint_shadow (widget->style, widget->window, GTK_WIDGET_STATE (widget), - GTK_SHADOW_IN, NULL, widget, "calendar", - 0, 0, widget->allocation.width, widget->allocation.height); - } - } - - return FALSE; -} + +/**************************************** + * Repainting * + ****************************************/ static void -gtk_calendar_paint_header (GtkWidget *widget) +calendar_paint_header (GtkCalendar *calendar) { - GtkCalendar *calendar; - GdkGC *gc; + GtkWidget *widget = GTK_WIDGET (calendar); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); + cairo_t *cr; char buffer[255]; int x, y; gint header_width, cal_height; gint max_month_width; gint max_year_width; - GtkCalendarPrivateData *private_data; PangoLayout *layout; PangoRectangle logical_rect; gboolean year_left; - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - - if (private_data->freeze_count) - { - private_data->dirty_header = 1; - return; - } - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) - year_left = private_data->year_before; + year_left = priv->year_before; else - year_left = !private_data->year_before; + year_left = !priv->year_before; - private_data->dirty_header = 0; - gc = calendar->gc; - - /* Clear window */ - gdk_window_clear (private_data->header_win); + cr = gdk_cairo_create (priv->header_win); header_width = widget->allocation.width - 2 * widget->style->xthickness; cal_height = widget->allocation.height; - max_month_width = private_data->max_month_width; - max_year_width = private_data->max_year_width; + max_month_width = priv->max_month_width; + max_year_width = priv->max_year_width; - gdk_gc_set_foreground (gc, BACKGROUND_COLOR (GTK_WIDGET (calendar))); - gtk_paint_shadow (widget->style, private_data->header_win, + gtk_paint_shadow (widget->style, priv->header_win, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, widget, "calendar", - 0, 0, header_width, private_data->header_h); + 0, 0, header_width, priv->header_h); g_snprintf (buffer, sizeof (buffer), "%d", calendar->year); @@ -1794,7 +1805,7 @@ gtk_calendar_paint_header (GtkWidget *widget) pango_layout_get_pixel_extents (layout, NULL, &logical_rect); /* Draw title */ - y = (private_data->header_h - logical_rect.height) / 2; + y = (priv->header_h - logical_rect.height) / 2; /* Draw year and its arrows */ @@ -1806,14 +1817,15 @@ gtk_calendar_paint_header (GtkWidget *widget) - (max_year_width - logical_rect.width)/2); else if (year_left) - x = 3 + private_data->arrow_width + (max_year_width - logical_rect.width)/2; + x = 3 + priv->arrow_width + (max_year_width - logical_rect.width)/2; else - x = header_width - (3 + private_data->arrow_width + max_year_width + x = header_width - (3 + priv->arrow_width + max_year_width - (max_year_width - logical_rect.width)/2); - - gdk_gc_set_foreground (gc, HEADER_FG_COLOR (GTK_WIDGET (calendar))); - gdk_draw_layout (private_data->header_win, gc, x, y, layout); + + gdk_cairo_set_source_color (cr, HEADER_FG_COLOR (GTK_WIDGET (calendar))); + cairo_move_to (cr, x, y); + pango_cairo_show_layout (cr, layout); /* Draw month */ g_snprintf (buffer, sizeof (buffer), "%s", default_monthname[calendar->month]); @@ -1828,28 +1840,24 @@ gtk_calendar_paint_header (GtkWidget *widget) x = 3 + (max_month_width - logical_rect.width) / 2; else if (year_left) - x = header_width - (3 + private_data->arrow_width + max_month_width + x = header_width - (3 + priv->arrow_width + max_month_width - (max_month_width - logical_rect.width)/2); else - x = 3 + private_data->arrow_width + (max_month_width - logical_rect.width)/2; + x = 3 + priv->arrow_width + (max_month_width - logical_rect.width)/2; - gdk_draw_layout (private_data->header_win, gc, x, y, layout); - - gdk_gc_set_foreground (gc, BACKGROUND_COLOR (GTK_WIDGET (calendar))); - - gtk_calendar_paint_arrow (widget, ARROW_MONTH_LEFT); - gtk_calendar_paint_arrow (widget, ARROW_MONTH_RIGHT); - gtk_calendar_paint_arrow (widget, ARROW_YEAR_LEFT); - gtk_calendar_paint_arrow (widget, ARROW_YEAR_RIGHT); + cairo_move_to (cr, x, y); + pango_cairo_show_layout (cr, layout); g_object_unref (layout); + cairo_destroy (cr); } static void -gtk_calendar_paint_day_names (GtkWidget *widget) +calendar_paint_day_names (GtkCalendar *calendar) { - GtkCalendar *calendar; - GdkGC *gc; + GtkWidget *widget = GTK_WIDGET (calendar); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); + cairo_t *cr; char buffer[255]; int day,i; int day_width, cal_width; @@ -1857,37 +1865,17 @@ gtk_calendar_paint_day_names (GtkWidget *widget) int day_wid_sep; PangoLayout *layout; PangoRectangle logical_rect; - GtkCalendarPrivateData *private_data; gint focus_padding; gint focus_width; - g_return_if_fail (GTK_IS_CALENDAR (widget)); - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - gc = calendar->gc; + cr = gdk_cairo_create (priv->day_name_win); gtk_widget_style_get (GTK_WIDGET (widget), "focus-line-width", &focus_width, "focus-padding", &focus_padding, NULL); - /* - * Handle freeze/thaw functionality - */ - if (private_data->freeze_count) - { - private_data->dirty_day_names = 1; - return; - } - private_data->dirty_day_names = 0; - - /* - * Clear the window - */ - - gdk_window_clear (private_data->day_name_win); - - day_width = private_data->day_width; + day_width = priv->day_width; cal_width = widget->allocation.width; cal_height = widget->allocation.height; day_wid_sep = day_width + DAY_XSEP; @@ -1895,84 +1883,74 @@ gtk_calendar_paint_day_names (GtkWidget *widget) /* * Draw rectangles as inverted background for the labels. */ - - gdk_gc_set_foreground (gc, SELECTED_BG_COLOR (widget)); - gdk_draw_rectangle (private_data->day_name_win, gc, TRUE, - CALENDAR_MARGIN, CALENDAR_MARGIN, - cal_width-CALENDAR_MARGIN * 2, - private_data->day_name_h - CALENDAR_MARGIN); + + gdk_cairo_set_source_color (cr, SELECTED_BG_COLOR (widget)); + cairo_rectangle (cr, + CALENDAR_MARGIN, CALENDAR_MARGIN, + cal_width-CALENDAR_MARGIN * 2, + priv->day_name_h - CALENDAR_MARGIN); + cairo_fill (cr); if (calendar->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS) - gdk_draw_rectangle (private_data->day_name_win, gc, TRUE, - CALENDAR_MARGIN, - private_data->day_name_h - CALENDAR_YSEP, - private_data->week_width - CALENDAR_YSEP - CALENDAR_MARGIN, - CALENDAR_YSEP); + { + cairo_rectangle (cr, + CALENDAR_MARGIN, + priv->day_name_h - CALENDAR_YSEP, + priv->week_width - CALENDAR_YSEP - CALENDAR_MARGIN, + CALENDAR_YSEP); + cairo_fill (cr); + } /* * Write the labels */ layout = gtk_widget_create_pango_layout (widget, NULL); - - gdk_gc_set_foreground (gc, SELECTED_FG_COLOR (widget)); + + gdk_cairo_set_source_color (cr, SELECTED_FG_COLOR (widget)); for (i = 0; i < 7; i++) { if (gtk_widget_get_direction (GTK_WIDGET (calendar)) == GTK_TEXT_DIR_RTL) day = 6 - i; else day = i; - day = (day + private_data->week_start) % 7; + day = (day + priv->week_start) % 7; g_snprintf (buffer, sizeof (buffer), "%s", default_abbreviated_dayname[day]); pango_layout_set_text (layout, buffer, -1); pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - gdk_draw_layout (private_data->day_name_win, gc, - (CALENDAR_MARGIN + - + (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ? - (private_data->week_width + (private_data->week_width ? CALENDAR_XSEP : 0)) - : 0) - + day_wid_sep * i - + (day_width - logical_rect.width)/2), - CALENDAR_MARGIN + focus_width + focus_padding + logical_rect.y, - layout); + cairo_move_to (cr, + (CALENDAR_MARGIN + + + (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ? + (priv->week_width + (priv->week_width ? CALENDAR_XSEP : 0)) + : 0) + + day_wid_sep * i + + (day_width - logical_rect.width)/2), + CALENDAR_MARGIN + focus_width + focus_padding + logical_rect.y); + pango_cairo_show_layout (cr, layout); } g_object_unref (layout); + cairo_destroy (cr); } static void -gtk_calendar_paint_week_numbers (GtkWidget *widget) +calendar_paint_week_numbers (GtkCalendar *calendar) { - GtkCalendar *calendar; - GdkGC *gc; + GtkWidget *widget = GTK_WIDGET (calendar); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); + cairo_t *cr; gint row, week = 0, year; gint x_loc; char buffer[3]; gint y_loc, day_height; - GtkCalendarPrivateData *private_data; PangoLayout *layout; PangoRectangle logical_rect; gint focus_padding; gint focus_width; - g_return_if_fail (GTK_IS_CALENDAR (widget)); - g_return_if_fail (widget->window != NULL); - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - gc = calendar->gc; - - /* - * Handle freeze/thaw functionality - */ - - if (private_data->freeze_count) - { - private_data->dirty_week = 1; - return; - } - private_data->dirty_week = 0; + cr = gdk_cairo_create (priv->week_win); gtk_widget_style_get (GTK_WIDGET (widget), "focus-line-width", &focus_width, @@ -1980,28 +1958,23 @@ gtk_calendar_paint_week_numbers (GtkWidget *widget) NULL); /* - * Clear the window - */ - - gdk_window_clear (private_data->week_win); - - /* * Draw a rectangle as inverted background for the labels. */ - - gdk_gc_set_foreground (gc, SELECTED_BG_COLOR (widget)); - if (private_data->day_name_win) - gdk_draw_rectangle (private_data->week_win, gc, TRUE, - CALENDAR_MARGIN, - 0, - private_data->week_width - CALENDAR_MARGIN, - private_data->main_h - CALENDAR_MARGIN); + + gdk_cairo_set_source_color (cr, SELECTED_BG_COLOR (widget)); + if (priv->day_name_win) + cairo_rectangle (cr, + CALENDAR_MARGIN, + 0, + priv->week_width - CALENDAR_MARGIN, + priv->main_h - CALENDAR_MARGIN); else - gdk_draw_rectangle (private_data->week_win, gc, TRUE, - CALENDAR_MARGIN, - CALENDAR_MARGIN, - private_data->week_width - CALENDAR_MARGIN, - private_data->main_h - 2 * CALENDAR_MARGIN); + cairo_rectangle (cr, + CALENDAR_MARGIN, + CALENDAR_MARGIN, + priv->week_width - CALENDAR_MARGIN, + priv->main_h - 2 * CALENDAR_MARGIN); + cairo_fill (cr); /* * Write the labels @@ -2009,45 +1982,45 @@ gtk_calendar_paint_week_numbers (GtkWidget *widget) layout = gtk_widget_create_pango_layout (widget, NULL); - gdk_gc_set_foreground (gc, SELECTED_FG_COLOR (widget)); - day_height = row_height (calendar); + gdk_cairo_set_source_color (cr, SELECTED_FG_COLOR (widget)); + day_height = calendar_row_height (calendar); for (row = 0; row < 6; row++) { + gboolean result; + year = calendar->year; if (calendar->day[row][6] < 15 && row > 3 && calendar->month == 11) year++; - g_return_if_fail (week_of_year (&week, &year, - ((calendar->day[row][6] < 15 && row > 3 ? 1 : 0) - + calendar->month) % 12 + 1, calendar->day[row][6])); + result = week_of_year (&week, &year, + ((calendar->day[row][6] < 15 && row > 3 ? 1 : 0) + + calendar->month) % 12 + 1, calendar->day[row][6]); + g_return_if_fail (result); g_snprintf (buffer, sizeof (buffer), "%d", week); pango_layout_set_text (layout, buffer, -1); pango_layout_get_pixel_extents (layout, NULL, &logical_rect); - y_loc = top_y_for_row (calendar, row) + (day_height - logical_rect.height) / 2; + y_loc = calendar_top_y_for_row (calendar, row) + (day_height - logical_rect.height) / 2; - x_loc = (private_data->week_width + x_loc = (priv->week_width - logical_rect.width - CALENDAR_XSEP - focus_padding - focus_width); - gdk_draw_layout (private_data->week_win, gc, x_loc, y_loc, layout); + cairo_move_to (cr, x_loc, y_loc); + pango_cairo_show_layout (cr, layout); } g_object_unref (layout); + cairo_destroy (cr); } static void -gtk_calendar_paint_day_num (GtkWidget *widget, - gint day) +calendar_invalidate_day_num (GtkCalendar *calendar, + gint day) { - GtkCalendar *calendar; gint r, c, row, col; - g_return_if_fail (GTK_IS_CALENDAR (widget)); - - calendar = GTK_CALENDAR (widget); - row = -1; col = -1; for (r = 0; r < 6; r++) @@ -2062,114 +2035,101 @@ gtk_calendar_paint_day_num (GtkWidget *widget, g_return_if_fail (row != -1); g_return_if_fail (col != -1); - gtk_calendar_paint_day (widget, row, col); + calendar_invalidate_day (calendar, row, col); } static void -gtk_calendar_paint_day (GtkWidget *widget, - gint row, - gint col) +calendar_invalidate_day (GtkCalendar *calendar, + gint row, + gint col) { - GtkCalendar *calendar; - GdkGC *gc; + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); + + if (priv->main_win) + { + GdkRectangle day_rect; + + calendar_day_rectangle (calendar, row, col, &day_rect); + gdk_window_invalidate_rect (priv->main_win, &day_rect, FALSE); + } +} + +static void +calendar_paint_day (GtkCalendar *calendar, + gint row, + gint col) +{ + GtkWidget *widget = GTK_WIDGET (calendar); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); + cairo_t *cr; + GdkColor *text_color; gchar buffer[255]; gint day; - gint day_height; - gint x_left; - gint x_loc; - gint y_top; - gint y_loc; - gint day_xspace; - gint focus_width; + gint x_loc, y_loc; + GdkRectangle day_rect; - GtkCalendarPrivateData *private_data; PangoLayout *layout; PangoRectangle logical_rect; - g_return_if_fail (GTK_IS_CALENDAR (widget)); g_return_if_fail (row < 6); g_return_if_fail (col < 7); - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - /* - * Handle freeze/thaw functionality - */ - - if (private_data->freeze_count) - { - private_data->dirty_main = 1; - return; - } - - gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL); + cr = gdk_cairo_create (priv->main_win); - day_height = row_height (calendar); - - day_xspace = private_data->day_width - private_data->max_day_char_width*2; - day = calendar->day[row][col]; - - x_left = left_x_for_column (calendar, col); - x_loc = x_left + private_data->day_width / 2 + private_data->max_day_char_width; - - y_top = top_y_for_row (calendar, row); - - gdk_window_clear_area (private_data->main_win, x_left, y_top, - private_data->day_width, day_height); - - gc = calendar->gc; + + calendar_day_rectangle (calendar, row, col, &day_rect); if (calendar->day_month[row][col] == MONTH_PREV) { - gdk_gc_set_foreground (gc, PREV_MONTH_COLOR (GTK_WIDGET (calendar))); + text_color = PREV_MONTH_COLOR (widget); } else if (calendar->day_month[row][col] == MONTH_NEXT) { - gdk_gc_set_foreground (gc, NEXT_MONTH_COLOR (GTK_WIDGET (calendar))); + text_color = NEXT_MONTH_COLOR (widget); } else { /* if (calendar->highlight_row == row && calendar->highlight_col == col) { - gdk_gc_set_foreground (gc, HIGHLIGHT_BACK_COLOR (GTK_WIDGET (calendar))); - gdk_draw_rectangle (private_data->main_win, gc, TRUE, x_left, y_top, - private_data->day_width, day_height); + cairo_set_source_color (cr, HIGHLIGHT_BG_COLOR (widget)); + gdk_cairo_rectangle (cr, &day_rect); + cairo_fill (cr); } */ if (calendar->selected_day == day) { - gdk_gc_set_foreground (gc, SELECTED_BG_COLOR (GTK_WIDGET (calendar))); - gdk_draw_rectangle (private_data->main_win, gc, TRUE, x_left, y_top, - private_data->day_width, day_height); + gdk_cairo_set_source_color (cr, SELECTED_BG_COLOR (widget)); + gdk_cairo_rectangle (cr, &day_rect); + cairo_fill (cr); } - - if (calendar->marked_date[day-1]) - gdk_gc_set_foreground (gc, MARKED_COLOR (GTK_WIDGET (calendar))); - else - gdk_gc_set_foreground (gc, NORMAL_DAY_COLOR (GTK_WIDGET (calendar))); - if (calendar->selected_day == day) - gdk_gc_set_foreground (gc, SELECTED_FG_COLOR (GTK_WIDGET (calendar))); + text_color = SELECTED_FG_COLOR (widget); + else if (calendar->marked_date[day-1]) + text_color = MARKED_COLOR (widget); else - gdk_gc_set_foreground (gc, & (GTK_WIDGET (calendar)->style->fg[GTK_WIDGET_STATE (calendar)])); + text_color = NORMAL_DAY_COLOR (widget); } - g_snprintf (buffer, sizeof (buffer), "%d", day); layout = gtk_widget_create_pango_layout (widget, buffer); pango_layout_get_pixel_extents (layout, NULL, &logical_rect); + x_loc = day_rect.x + day_rect.width / 2 + priv->max_day_char_width; x_loc -= logical_rect.width; - - y_loc = y_top + (day_height - logical_rect.height) / 2; - gdk_draw_layout (private_data->main_win, gc, - x_loc, y_loc, layout); + y_loc = day_rect.y + (day_rect.height - logical_rect.height) / 2; + + gdk_cairo_set_source_color (cr, text_color); + cairo_move_to (cr, x_loc, y_loc); + pango_cairo_show_layout (cr, layout); + if (calendar->marked_date[day-1] && calendar->day_month[row][col] == MONTH_CURRENT) - gdk_draw_layout (private_data->main_win, gc, - x_loc-1, y_loc, layout); + { + cairo_move_to (cr, x_loc - 1, y_loc); + pango_cairo_show_layout (cr, layout); + } if (GTK_WIDGET_HAS_FOCUS (calendar) && calendar->focus_row == row && calendar->focus_col == col) @@ -2182,466 +2142,135 @@ gtk_calendar_paint_day (GtkWidget *widget, state = GTK_STATE_NORMAL; gtk_paint_focus (widget->style, - private_data->main_win, + priv->main_win, (calendar->selected_day == day) ? GTK_STATE_SELECTED : GTK_STATE_NORMAL, NULL, widget, "calendar-day", - x_left, y_top, - private_data->day_width, - day_height); + day_rect.x, day_rect.y, + day_rect.width, day_rect.height); } g_object_unref (layout); + cairo_destroy (cr); } - static void -gtk_calendar_paint_main (GtkWidget *widget) +calendar_paint_main (GtkCalendar *calendar) { - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; gint row, col; - g_return_if_fail (GTK_IS_CALENDAR (widget)); - g_return_if_fail (widget->window != NULL); - - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - - if (private_data->freeze_count) - { - private_data->dirty_main = 1; - return; - } - private_data->dirty_main = 0; - gdk_window_clear (private_data->main_win); - - /* gtk_calendar_compute_days (calendar); */ /* REMOVE later */ - for (col = 0; col < 7; col++) for (row = 0; row < 6; row++) - gtk_calendar_paint_day (widget, row, col); + calendar_paint_day (calendar, row, col); } static void -gtk_calendar_compute_days (GtkCalendar *calendar) +calendar_invalidate_arrow (GtkCalendar *calendar, + guint arrow) { - GtkCalendarPrivateData *private_data; - gint month; - gint year; - gint ndays_in_month; - gint ndays_in_prev_month; - gint first_day; - gint row; - gint col; - gint day; - - g_return_if_fail (GTK_IS_CALENDAR (calendar)); - - private_data = GTK_CALENDAR_PRIVATE_DATA (GTK_WIDGET (calendar)); - - year = calendar->year; - month = calendar->month + 1; - - ndays_in_month = month_length[leap (year)][month]; - - first_day = day_of_week (year, month, 1); - first_day = (first_day + 7 - private_data->week_start) % 7; - - /* Compute days of previous month */ - if (month > 1) - ndays_in_prev_month = month_length[leap (year)][month-1]; - else - ndays_in_prev_month = month_length[leap (year)][12]; - day = ndays_in_prev_month - first_day + 1; - - row = 0; - if (first_day > 0) - { - for (col = 0; col < first_day; col++) - { - calendar->day[row][col] = day; - calendar->day_month[row][col] = MONTH_PREV; - day++; - } - } - - /* Compute days of current month */ - col = first_day; - for (day = 1; day <= ndays_in_month; day++) - { - calendar->day[row][col] = day; - calendar->day_month[row][col] = MONTH_CURRENT; - - col++; - if (col == 7) - { - row++; - col = 0; - } - } + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); + GdkWindow *window; - /* Compute days of next month */ - day = 1; - for (; row <= 5; row++) - { - for (; col <= 6; col++) - { - calendar->day[row][col] = day; - calendar->day_month[row][col] = MONTH_NEXT; - day++; - } - col = 0; - } -} - -void -gtk_calendar_display_options (GtkCalendar *calendar, - GtkCalendarDisplayOptions flags) -{ - gtk_calendar_set_display_options (calendar, flags); -} - -/** - * gtk_calendar_get_display_options: - * @calendar: a #GtkCalendar - * - * Returns the current display options of @calendar. - * - * Return value: the display options. - * - * Since: 2.4 - **/ -GtkCalendarDisplayOptions -gtk_calendar_get_display_options (GtkCalendar *calendar) -{ - g_return_val_if_fail (GTK_IS_CALENDAR (calendar), 0); - - return calendar->display_flags; + window = priv->arrow_win[arrow]; + if (window) + gdk_window_invalidate_rect (window, NULL, FALSE); } -/** - * gtk_calendar_set_display_options: - * @calendar: a #GtkCalendar - * @flags: the display options to set - * - * Sets display options (whether to display the heading and the month - * headings). - * - * Since: 2.4 - **/ -void -gtk_calendar_set_display_options (GtkCalendar *calendar, - GtkCalendarDisplayOptions flags) +static void +calendar_paint_arrow (GtkCalendar *calendar, + guint arrow) { - GtkCalendarPrivateData *private_data; - gint resize = 0; - GtkWidget *widget; - gint i; - GtkCalendarDisplayOptions old_flags; - - g_return_if_fail (GTK_IS_CALENDAR (calendar)); - - widget = GTK_WIDGET (calendar); - private_data = GTK_CALENDAR_PRIVATE_DATA (calendar); - old_flags = calendar->display_flags; + GtkWidget *widget = GTK_WIDGET (calendar); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); + GdkWindow *window; - if (GTK_WIDGET_REALIZED (widget)) + window = priv->arrow_win[arrow]; + if (window) { - if ((flags ^ calendar->display_flags) & GTK_CALENDAR_NO_MONTH_CHANGE) - { - resize ++; - if (! (flags & GTK_CALENDAR_NO_MONTH_CHANGE) - && (private_data->header_win)) - { - calendar->display_flags &= ~GTK_CALENDAR_NO_MONTH_CHANGE; - gtk_calendar_realize_arrows (widget); - } - else - { - for (i = 0; i < 4; i++) - { - if (private_data->arrow_win[i]) - { - gdk_window_set_user_data (private_data->arrow_win[i], - NULL); - gdk_window_destroy (private_data->arrow_win[i]); - private_data->arrow_win[i] = NULL; - } - } - } - } - - if ((flags ^ calendar->display_flags) & GTK_CALENDAR_SHOW_HEADING) - { - resize++; - - if (flags & GTK_CALENDAR_SHOW_HEADING) - { - calendar->display_flags |= GTK_CALENDAR_SHOW_HEADING; - gtk_calendar_realize_header (widget); - } - else - { - for (i = 0; i < 4; i++) - { - if (private_data->arrow_win[i]) - { - gdk_window_set_user_data (private_data->arrow_win[i], - NULL); - gdk_window_destroy (private_data->arrow_win[i]); - private_data->arrow_win[i] = NULL; - } - } - gdk_window_set_user_data (private_data->header_win, NULL); - gdk_window_destroy (private_data->header_win); - private_data->header_win = NULL; - } - } - - - if ((flags ^ calendar->display_flags) & GTK_CALENDAR_SHOW_DAY_NAMES) - { - resize++; - - if (flags & GTK_CALENDAR_SHOW_DAY_NAMES) - { - calendar->display_flags |= GTK_CALENDAR_SHOW_DAY_NAMES; - gtk_calendar_realize_day_names (widget); - } - else - { - gdk_window_set_user_data (private_data->day_name_win, NULL); - gdk_window_destroy (private_data->day_name_win); - private_data->day_name_win = NULL; - } - } - - if ((flags ^ calendar->display_flags) & GTK_CALENDAR_SHOW_WEEK_NUMBERS) - { - resize++; - - if (flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS) - { - calendar->display_flags |= GTK_CALENDAR_SHOW_WEEK_NUMBERS; - gtk_calendar_realize_week_numbers (widget); - } - else - { - gdk_window_set_user_data (private_data->week_win, NULL); - gdk_window_destroy (private_data->week_win); - private_data->week_win = NULL; - } - } - - if ((flags ^ calendar->display_flags) & GTK_CALENDAR_WEEK_START_MONDAY) - g_warning ("GTK_CALENDAR_WEEK_START_MONDAY is ignored; the first day of the week is determined from the locale"); - - calendar->display_flags = flags; - if (resize) - gtk_widget_queue_resize (GTK_WIDGET (calendar)); - - } - else - calendar->display_flags = flags; - - g_object_freeze_notify (G_OBJECT (calendar)); - if ((old_flags ^ calendar->display_flags) & GTK_CALENDAR_SHOW_HEADING) - g_object_notify (G_OBJECT (calendar), "show-heading"); - if ((old_flags ^ calendar->display_flags) & GTK_CALENDAR_SHOW_DAY_NAMES) - g_object_notify (G_OBJECT (calendar), "show-day-names"); - if ((old_flags ^ calendar->display_flags) & GTK_CALENDAR_NO_MONTH_CHANGE) - g_object_notify (G_OBJECT (calendar), "no-month-change"); - if ((old_flags ^ calendar->display_flags) & GTK_CALENDAR_SHOW_WEEK_NUMBERS) - g_object_notify (G_OBJECT (calendar), "show-week-numbers"); - g_object_thaw_notify (G_OBJECT (calendar)); -} - -gboolean -gtk_calendar_select_month (GtkCalendar *calendar, - guint month, - guint year) -{ - g_return_val_if_fail (GTK_IS_CALENDAR (calendar), FALSE); - g_return_val_if_fail (month <= 11, FALSE); - - calendar->month = month; - calendar->year = year; - - gtk_calendar_compute_days (calendar); - - gtk_widget_queue_draw (GTK_WIDGET (calendar)); - - g_object_freeze_notify (G_OBJECT (calendar)); - g_object_notify (G_OBJECT (calendar), "month"); - g_object_notify (G_OBJECT (calendar), "year"); - g_object_thaw_notify (G_OBJECT (calendar)); - - g_signal_emit (calendar, - gtk_calendar_signals[MONTH_CHANGED_SIGNAL], - 0); - return TRUE; -} + cairo_t *cr = gdk_cairo_create (window); + gint width, height; + gint state; + + state = priv->arrow_state[arrow]; -void -gtk_calendar_select_day (GtkCalendar *calendar, - guint day) -{ - g_return_if_fail (GTK_IS_CALENDAR (calendar)); - g_return_if_fail (day <= 31); - - /* gtk_calendar_compute_days (calendar); */ - - /* Deselect the old day */ - if (calendar->selected_day > 0) - { - gint selected_day; + gdk_cairo_set_source_color (cr, &widget->style->bg[state]); + cairo_paint (cr); - selected_day = calendar->selected_day; - calendar->selected_day = 0; - if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (calendar))) - gtk_calendar_paint_day_num (GTK_WIDGET (calendar), selected_day); - } - - calendar->selected_day = day; - - /* Select the new day */ - if (day != 0) - { - if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (calendar))) - gtk_calendar_paint_day_num (GTK_WIDGET (calendar), day); + gdk_drawable_get_size (window, &width, &height); + if (arrow == ARROW_MONTH_LEFT || arrow == ARROW_YEAR_LEFT) + gtk_paint_arrow (widget->style, window, state, + GTK_SHADOW_OUT, NULL, widget, "calendar", + GTK_ARROW_LEFT, TRUE, + width/2 - 3, height/2 - 4, 8, 8); + else + gtk_paint_arrow (widget->style, window, state, + GTK_SHADOW_OUT, NULL, widget, "calendar", + GTK_ARROW_RIGHT, TRUE, + width/2 - 2, height/2 - 4, 8, 8); } - - g_object_notify (G_OBJECT (calendar), "day"); - - g_signal_emit (calendar, - gtk_calendar_signals[DAY_SELECTED_SIGNAL], - 0); -} - -static void -gtk_calendar_select_and_focus_day (GtkCalendar *calendar, - guint day) -{ - gint old_focus_row = calendar->focus_row; - gint old_focus_col = calendar->focus_col; - gint row; - gint col; - - for (row = 0; row < 6; row ++) - for (col = 0; col < 7; col++) - { - if (calendar->day_month[row][col] == MONTH_CURRENT - && calendar->day[row][col] == day) - { - calendar->focus_row = row; - calendar->focus_col = col; - } - } - - if (old_focus_row != -1 && old_focus_col != -1) - gtk_calendar_paint_day (GTK_WIDGET (calendar), old_focus_row, old_focus_col); - - gtk_calendar_select_day (calendar, day); } -void -gtk_calendar_clear_marks (GtkCalendar *calendar) +static gboolean +gtk_calendar_expose (GtkWidget *widget, + GdkEventExpose *event) { - guint day; - - g_return_if_fail (GTK_IS_CALENDAR (calendar)); - - for (day = 0; day < 31; day++) - { - calendar->marked_date[day] = FALSE; - } - - calendar->num_marked_dates = 0; - - if (GTK_WIDGET_DRAWABLE (calendar)) - { - gtk_calendar_paint_main (GTK_WIDGET (calendar)); - } -} + GtkCalendar *calendar = GTK_CALENDAR (widget); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); + int i; -gboolean -gtk_calendar_mark_day (GtkCalendar *calendar, - guint day) -{ - g_return_val_if_fail (GTK_IS_CALENDAR (calendar), FALSE); - - if (day >= 1 && day <= 31 && calendar->marked_date[day-1] == FALSE) - { - calendar->marked_date[day - 1] = TRUE; - calendar->num_marked_dates++; - } - if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (calendar))) + if (GTK_WIDGET_DRAWABLE (widget)) { - gtk_calendar_paint_main (GTK_WIDGET (calendar)); - } - - return TRUE; -} + if (event->window == priv->main_win) + calendar_paint_main (calendar); + + if (event->window == priv->header_win) + calendar_paint_header (calendar); -gboolean -gtk_calendar_unmark_day (GtkCalendar *calendar, - guint day) -{ - g_return_val_if_fail (GTK_IS_CALENDAR (calendar), FALSE); - - if (day >= 1 && day <= 31 && calendar->marked_date[day-1] == TRUE) - { - calendar->marked_date[day - 1] = FALSE; - calendar->num_marked_dates--; - } - - if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (calendar))) - { - gtk_calendar_paint_main (GTK_WIDGET (calendar)); + for (i = 0; i < 4; i++) + if (event->window == priv->arrow_win[i]) + calendar_paint_arrow (calendar, i); + + if (event->window == priv->day_name_win) + calendar_paint_day_names (calendar); + + if (event->window == priv->week_win) + calendar_paint_week_numbers (calendar); + if (event->window == widget->window) + { + gtk_paint_shadow (widget->style, widget->window, GTK_WIDGET_STATE (widget), + GTK_SHADOW_IN, NULL, widget, "calendar", + 0, 0, widget->allocation.width, widget->allocation.height); + } } - return TRUE; + return FALSE; } -void -gtk_calendar_get_date (GtkCalendar *calendar, - guint *year, - guint *month, - guint *day) -{ - g_return_if_fail (GTK_IS_CALENDAR (calendar)); - - if (year) - *year = calendar->year; - - if (month) - *month = calendar->month; - - if (day) - *day = calendar->selected_day; -} + +/**************************************** + * Mouse handling * + ****************************************/ #define CALENDAR_INITIAL_TIMER_DELAY 200 #define CALENDAR_TIMER_DELAY 20 static void -arrow_action (GtkCalendar *calendar, - guint arrow) +calendar_arrow_action (GtkCalendar *calendar, + guint arrow) { switch (arrow) { case ARROW_YEAR_LEFT: - gtk_calendar_set_year_prev (calendar); + calendar_set_year_prev (calendar); break; case ARROW_YEAR_RIGHT: - gtk_calendar_set_year_next (calendar); + calendar_set_year_next (calendar); break; case ARROW_MONTH_LEFT: - gtk_calendar_set_month_prev (calendar); + calendar_set_month_prev (calendar); break; case ARROW_MONTH_RIGHT: - gtk_calendar_set_month_next (calendar); + calendar_set_month_next (calendar); break; default:; /* do nothing */ @@ -2652,19 +2281,19 @@ static gboolean calendar_timer (gpointer data) { GtkCalendar *calendar = data; - GtkCalendarPrivateData *private_data = GTK_CALENDAR_PRIVATE_DATA (calendar); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); gboolean retval = FALSE; GDK_THREADS_ENTER (); - if (private_data->timer) + if (priv->timer) { - arrow_action (calendar, private_data->click_child); + calendar_arrow_action (calendar, priv->click_child); - if (private_data->need_timer) + if (priv->need_timer) { - private_data->need_timer = FALSE; - private_data->timer = g_timeout_add (CALENDAR_TIMER_DELAY, + priv->need_timer = FALSE; + priv->timer = g_timeout_add (CALENDAR_TIMER_DELAY, (GSourceFunc) calendar_timer, (gpointer) calendar); } @@ -2678,97 +2307,115 @@ calendar_timer (gpointer data) } static void -start_spinning (GtkWidget *widget, - gint click_child) +calendar_start_spinning (GtkCalendar *calendar, + gint click_child) { - GtkCalendarPrivateData *private_data = GTK_CALENDAR_PRIVATE_DATA (widget); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); - private_data->click_child = click_child; + priv->click_child = click_child; - if (!private_data->timer) + if (!priv->timer) { - private_data->need_timer = TRUE; - private_data->timer = g_timeout_add (CALENDAR_INITIAL_TIMER_DELAY, - calendar_timer, - (gpointer) widget); + priv->need_timer = TRUE; + priv->timer = g_timeout_add (CALENDAR_INITIAL_TIMER_DELAY, + calendar_timer, + calendar); } } static void -stop_spinning (GtkWidget *widget) +calendar_stop_spinning (GtkCalendar *calendar) { - GtkCalendarPrivateData *private_data; - - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); - if (private_data->timer) + if (priv->timer) { - g_source_remove (private_data->timer); - private_data->timer = 0; - private_data->need_timer = FALSE; + g_source_remove (priv->timer); + priv->timer = 0; + priv->need_timer = FALSE; } } static void -gtk_calendar_destroy (GtkObject *object) +calendar_main_button_press (GtkCalendar *calendar, + GdkEventButton *event) { - stop_spinning (GTK_WIDGET (object)); + GtkWidget *widget = GTK_WIDGET (calendar); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); + gint x, y; + gint row, col; + gint day_month; + gint day; - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - -static void -gtk_calendar_grab_notify (GtkWidget *widget, - gboolean was_grabbed) -{ - if (!was_grabbed) - stop_spinning (widget); -} - -static gboolean -gtk_calendar_focus_out (GtkWidget *widget, - GdkEventFocus *event) -{ - GtkCalendarPrivateData *private_data; - - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); + x = (gint) (event->x); + y = (gint) (event->y); + + row = calendar_row_from_y (calendar, y); + col = calendar_column_from_x (calendar, x); - stop_spinning (widget); + /* If row or column isn't found, just return. */ + if (row == -1 || col == -1) + return; - private_data->in_drag = 0; + day_month = calendar->day_month[row][col]; - return FALSE; + if (event->type == GDK_BUTTON_PRESS) + { + day = calendar->day[row][col]; + + if (day_month == MONTH_PREV) + calendar_set_month_prev (calendar); + else if (day_month == MONTH_NEXT) + calendar_set_month_next (calendar); + + if (!GTK_WIDGET_HAS_FOCUS (widget)) + gtk_widget_grab_focus (widget); + + if (event->button == 1) + { + priv->in_drag = 1; + priv->drag_start_x = x; + priv->drag_start_y = y; + } + + calendar_select_and_focus_day (calendar, day); + } + else if (event->type == GDK_2BUTTON_PRESS) + { + priv->in_drag = 0; + if (day_month == MONTH_CURRENT) + g_signal_emit (calendar, + gtk_calendar_signals[DAY_SELECTED_DOUBLE_CLICK_SIGNAL], + 0); + } } static gboolean gtk_calendar_button_press (GtkWidget *widget, GdkEventButton *event) { - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; + GtkCalendar *calendar = GTK_CALENDAR (widget); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); gint arrow = -1; - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - - if (event->window == private_data->main_win) - gtk_calendar_main_button (widget, event); + if (event->window == priv->main_win) + calendar_main_button_press (calendar, event); if (!GTK_WIDGET_HAS_FOCUS (widget)) gtk_widget_grab_focus (widget); for (arrow = ARROW_YEAR_LEFT; arrow <= ARROW_MONTH_RIGHT; arrow++) { - if (event->window == private_data->arrow_win[arrow]) + if (event->window == priv->arrow_win[arrow]) { /* only call the action on single click, not double */ if (event->type == GDK_BUTTON_PRESS) { if (event->button == 1) - start_spinning (widget, arrow); + calendar_start_spinning (calendar, arrow); - arrow_action (calendar, arrow); + calendar_arrow_action (calendar, arrow); } return TRUE; @@ -2782,18 +2429,15 @@ static gboolean gtk_calendar_button_release (GtkWidget *widget, GdkEventButton *event) { - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; - - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); + GtkCalendar *calendar = GTK_CALENDAR (widget); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); if (event->button == 1) { - stop_spinning (widget); + calendar_stop_spinning (calendar); - if (private_data->in_drag) - private_data->in_drag = 0; + if (priv->in_drag) + priv->in_drag = 0; } return TRUE; @@ -2803,24 +2447,22 @@ static gboolean gtk_calendar_motion_notify (GtkWidget *widget, GdkEventMotion *event) { - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; + GtkCalendar *calendar = GTK_CALENDAR (widget); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); gint event_x, event_y; gint row, col; gint old_row, old_col; - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); event_x = (gint) (event->x); event_y = (gint) (event->y); - if (event->window == private_data->main_win) + if (event->window == priv->main_win) { - if (private_data->in_drag) + if (priv->in_drag) { if (gtk_drag_check_threshold (widget, - private_data->drag_start_x, private_data->drag_start_y, + priv->drag_start_x, priv->drag_start_y, event->x, event->y)) { GdkDragContext *context; @@ -2830,7 +2472,7 @@ gtk_calendar_motion_notify (GtkWidget *widget, 1, (GdkEvent *)event); - private_data->in_drag = 0; + priv->in_drag = 0; gtk_target_list_unref (target_list); gtk_drag_set_icon_default (context); @@ -2838,8 +2480,8 @@ gtk_calendar_motion_notify (GtkWidget *widget, } else { - row = row_from_y (calendar, event_y); - col = column_from_x (calendar, event_x); + row = calendar_row_from_y (calendar, event_y); + col = calendar_column_from_x (calendar, event_x); if (row != calendar->highlight_row || calendar->highlight_col != col) { @@ -2849,14 +2491,14 @@ gtk_calendar_motion_notify (GtkWidget *widget, { calendar->highlight_row = -1; calendar->highlight_col = -1; - gtk_calendar_paint_day (widget, old_row, old_col); + calendar_invalidate_day (calendar, old_row, old_col); } calendar->highlight_row = row; calendar->highlight_col = col; if (row > -1 && col > -1) - gtk_calendar_paint_day (widget, row, col); + calendar_invalidate_day (calendar, row, col); } } } @@ -2867,34 +2509,31 @@ static gboolean gtk_calendar_enter_notify (GtkWidget *widget, GdkEventCrossing *event) { - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; - - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); + GtkCalendar *calendar = GTK_CALENDAR (widget); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); - if (event->window == private_data->arrow_win[ARROW_MONTH_LEFT]) + if (event->window == priv->arrow_win[ARROW_MONTH_LEFT]) { - private_data->arrow_state[ARROW_MONTH_LEFT] = GTK_STATE_PRELIGHT; - gtk_calendar_paint_arrow (widget, ARROW_MONTH_LEFT); + priv->arrow_state[ARROW_MONTH_LEFT] = GTK_STATE_PRELIGHT; + calendar_invalidate_arrow (calendar, ARROW_MONTH_LEFT); } - if (event->window == private_data->arrow_win[ARROW_MONTH_RIGHT]) + if (event->window == priv->arrow_win[ARROW_MONTH_RIGHT]) { - private_data->arrow_state[ARROW_MONTH_RIGHT] = GTK_STATE_PRELIGHT; - gtk_calendar_paint_arrow (widget, ARROW_MONTH_RIGHT); + priv->arrow_state[ARROW_MONTH_RIGHT] = GTK_STATE_PRELIGHT; + calendar_invalidate_arrow (calendar, ARROW_MONTH_RIGHT); } - if (event->window == private_data->arrow_win[ARROW_YEAR_LEFT]) + if (event->window == priv->arrow_win[ARROW_YEAR_LEFT]) { - private_data->arrow_state[ARROW_YEAR_LEFT] = GTK_STATE_PRELIGHT; - gtk_calendar_paint_arrow (widget, ARROW_YEAR_LEFT); + priv->arrow_state[ARROW_YEAR_LEFT] = GTK_STATE_PRELIGHT; + calendar_invalidate_arrow (calendar, ARROW_YEAR_LEFT); } - if (event->window == private_data->arrow_win[ARROW_YEAR_RIGHT]) + if (event->window == priv->arrow_win[ARROW_YEAR_RIGHT]) { - private_data->arrow_state[ARROW_YEAR_RIGHT] = GTK_STATE_PRELIGHT; - gtk_calendar_paint_arrow (widget, ARROW_YEAR_RIGHT); + priv->arrow_state[ARROW_YEAR_RIGHT] = GTK_STATE_PRELIGHT; + calendar_invalidate_arrow (calendar, ARROW_YEAR_RIGHT); } return TRUE; @@ -2904,212 +2543,48 @@ static gboolean gtk_calendar_leave_notify (GtkWidget *widget, GdkEventCrossing *event) { - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; + GtkCalendar *calendar = GTK_CALENDAR (widget); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); gint row; gint col; - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - - if (event->window == private_data->main_win) + if (event->window == priv->main_win) { row = calendar->highlight_row; col = calendar->highlight_col; calendar->highlight_row = -1; calendar->highlight_col = -1; if (row > -1 && col > -1) - gtk_calendar_paint_day (widget, row, col); + calendar_invalidate_day (calendar, row, col); } - if (event->window == private_data->arrow_win[ARROW_MONTH_LEFT]) + if (event->window == priv->arrow_win[ARROW_MONTH_LEFT]) { - private_data->arrow_state[ARROW_MONTH_LEFT] = GTK_STATE_NORMAL; - gtk_calendar_paint_arrow (widget, ARROW_MONTH_LEFT); + priv->arrow_state[ARROW_MONTH_LEFT] = GTK_STATE_NORMAL; + calendar_invalidate_arrow (calendar, ARROW_MONTH_LEFT); } - if (event->window == private_data->arrow_win[ARROW_MONTH_RIGHT]) + if (event->window == priv->arrow_win[ARROW_MONTH_RIGHT]) { - private_data->arrow_state[ARROW_MONTH_RIGHT] = GTK_STATE_NORMAL; - gtk_calendar_paint_arrow (widget, ARROW_MONTH_RIGHT); + priv->arrow_state[ARROW_MONTH_RIGHT] = GTK_STATE_NORMAL; + calendar_invalidate_arrow (calendar, ARROW_MONTH_RIGHT); } - if (event->window == private_data->arrow_win[ARROW_YEAR_LEFT]) + if (event->window == priv->arrow_win[ARROW_YEAR_LEFT]) { - private_data->arrow_state[ARROW_YEAR_LEFT] = GTK_STATE_NORMAL; - gtk_calendar_paint_arrow (widget, ARROW_YEAR_LEFT); + priv->arrow_state[ARROW_YEAR_LEFT] = GTK_STATE_NORMAL; + calendar_invalidate_arrow (calendar, ARROW_YEAR_LEFT); } - if (event->window == private_data->arrow_win[ARROW_YEAR_RIGHT]) + if (event->window == priv->arrow_win[ARROW_YEAR_RIGHT]) { - private_data->arrow_state[ARROW_YEAR_RIGHT] = GTK_STATE_NORMAL; - gtk_calendar_paint_arrow (widget, ARROW_YEAR_RIGHT); + priv->arrow_state[ARROW_YEAR_RIGHT] = GTK_STATE_NORMAL; + calendar_invalidate_arrow (calendar, ARROW_YEAR_RIGHT); } return TRUE; } -static void -gtk_calendar_paint_arrow (GtkWidget *widget, - guint arrow) -{ - GtkCalendarPrivateData *private_data; - GdkWindow *window; - GdkGC *gc; - GtkCalendar *calendar; - gint state; - gint width, height; - - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - - if (private_data->freeze_count) - { - private_data->dirty_header = 1; - return; - } - window = private_data->arrow_win[arrow]; - if (window) - { - state = private_data->arrow_state[arrow]; - gc = calendar->gc; - - gdk_window_clear (window); - gdk_window_set_background (window, &(widget)->style->bg[state]); - gdk_drawable_get_size (window, &width, &height); - gdk_window_clear_area (window, - 0,0, - width,height); - if (arrow == ARROW_MONTH_LEFT || arrow == ARROW_YEAR_LEFT) - gtk_paint_arrow (widget->style, window, state, - GTK_SHADOW_OUT, NULL, widget, "calendar", - GTK_ARROW_LEFT, TRUE, - width/2 - 3, height/2 - 4, 8, 8); - else - gtk_paint_arrow (widget->style, window, state, - GTK_SHADOW_OUT, NULL, widget, "calendar", - GTK_ARROW_RIGHT, TRUE, - width/2 - 2, height/2 - 4, 8, 8); - } -} - -void -gtk_calendar_freeze (GtkCalendar *calendar) -{ - g_return_if_fail (GTK_IS_CALENDAR (calendar)); - - GTK_CALENDAR_PRIVATE_DATA (calendar)->freeze_count++; -} - -void -gtk_calendar_thaw (GtkCalendar *calendar) -{ - GtkCalendarPrivateData *private_data; - - g_return_if_fail (GTK_IS_CALENDAR (calendar)); - - private_data = GTK_CALENDAR_PRIVATE_DATA (calendar); - - if (private_data->freeze_count) - if (!(--private_data->freeze_count)) - { - if (private_data->dirty_header) - if (GTK_WIDGET_DRAWABLE (calendar)) - gtk_calendar_paint_header (GTK_WIDGET (calendar)); - - if (private_data->dirty_day_names) - if (GTK_WIDGET_DRAWABLE (calendar)) - gtk_calendar_paint_day_names (GTK_WIDGET (calendar)); - - if (private_data->dirty_week) - if (GTK_WIDGET_DRAWABLE (calendar)) - gtk_calendar_paint_week_numbers (GTK_WIDGET (calendar)); - - if (private_data->dirty_main) - if (GTK_WIDGET_DRAWABLE (calendar)) - gtk_calendar_paint_main (GTK_WIDGET (calendar)); - } -} - -static void -gtk_calendar_set_background (GtkWidget *widget) -{ - GtkCalendar *calendar; - GtkCalendarPrivateData *private_data; - gint i; - - calendar = GTK_CALENDAR (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - - if (GTK_WIDGET_REALIZED (widget)) - { - for (i = 0; i < 4; i++) - { - if (private_data->arrow_win[i]) - gdk_window_set_background (private_data->arrow_win[i], - HEADER_BG_COLOR (widget)); - } - if (private_data->header_win) - gdk_window_set_background (private_data->header_win, - HEADER_BG_COLOR (widget)); - if (private_data->day_name_win) - gdk_window_set_background (private_data->day_name_win, - BACKGROUND_COLOR (widget)); - if (private_data->week_win) - gdk_window_set_background (private_data->week_win, - BACKGROUND_COLOR (widget)); - if (private_data->main_win) - gdk_window_set_background (private_data->main_win, - BACKGROUND_COLOR (widget)); - if (widget->window) - gdk_window_set_background (widget->window, - BACKGROUND_COLOR (widget)); - } -} - -static void -gtk_calendar_style_set (GtkWidget *widget, - GtkStyle *previous_style) -{ - if (previous_style && GTK_WIDGET_REALIZED (widget)) - gtk_calendar_set_background(widget); -} - -static void -gtk_calendar_state_changed (GtkWidget *widget, - GtkStateType previous_state) -{ - GtkCalendarPrivateData *private_data; - int i; - - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - - if (!GTK_WIDGET_IS_SENSITIVE (widget)) - { - private_data->in_drag = 0; - stop_spinning (widget); - } - - for (i = 0; i < 4; i++) - if (GTK_WIDGET_IS_SENSITIVE (widget)) - private_data->arrow_state[i] = GTK_STATE_NORMAL; - else - private_data->arrow_state[i] = GTK_STATE_INSENSITIVE; - - gtk_calendar_set_background (widget); -} - -static void -gtk_calendar_finalize (GObject *object) -{ - GtkCalendarPrivateData *private_data; - private_data = GTK_CALENDAR_PRIVATE_DATA (object); - - g_free (private_data); - - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - static gboolean gtk_calendar_scroll (GtkWidget *widget, GdkEventScroll *event) @@ -3120,13 +2595,13 @@ gtk_calendar_scroll (GtkWidget *widget, { if (!GTK_WIDGET_HAS_FOCUS (widget)) gtk_widget_grab_focus (widget); - gtk_calendar_set_month_prev (calendar); + calendar_set_month_prev (calendar); } else if (event->direction == GDK_SCROLL_DOWN) { if (!GTK_WIDGET_HAS_FOCUS (widget)) gtk_widget_grab_focus (widget); - gtk_calendar_set_month_next (calendar); + calendar_set_month_next (calendar); } else return FALSE; @@ -3134,9 +2609,14 @@ gtk_calendar_scroll (GtkWidget *widget, return TRUE; } + +/**************************************** + * Key handling * + ****************************************/ + static void move_focus (GtkCalendar *calendar, - gint direction) + gint direction) { GtkTextDirection text_dir = gtk_widget_get_direction (GTK_WIDGET (calendar)); @@ -3185,54 +2665,54 @@ gtk_calendar_key_press (GtkWidget *widget, case GDK_Left: return_val = TRUE; if (event->state & GDK_CONTROL_MASK) - gtk_calendar_set_month_prev (calendar); + calendar_set_month_prev (calendar); else { move_focus (calendar, -1); - gtk_calendar_paint_day (widget, old_focus_row, old_focus_col); - gtk_calendar_paint_day (widget, calendar->focus_row, - calendar->focus_col); + calendar_invalidate_day (calendar, old_focus_row, old_focus_col); + calendar_invalidate_day (calendar, calendar->focus_row, + calendar->focus_col); } break; case GDK_KP_Right: case GDK_Right: return_val = TRUE; if (event->state & GDK_CONTROL_MASK) - gtk_calendar_set_month_next (calendar); + calendar_set_month_next (calendar); else { move_focus (calendar, 1); - gtk_calendar_paint_day (widget, old_focus_row, old_focus_col); - gtk_calendar_paint_day (widget, calendar->focus_row, - calendar->focus_col); + calendar_invalidate_day (calendar, old_focus_row, old_focus_col); + calendar_invalidate_day (calendar, calendar->focus_row, + calendar->focus_col); } break; case GDK_KP_Up: case GDK_Up: return_val = TRUE; if (event->state & GDK_CONTROL_MASK) - gtk_calendar_set_year_prev (calendar); + calendar_set_year_prev (calendar); else { if (calendar->focus_row > 0) calendar->focus_row--; - gtk_calendar_paint_day (widget, old_focus_row, old_focus_col); - gtk_calendar_paint_day (widget, calendar->focus_row, - calendar->focus_col); + calendar_invalidate_day (calendar, old_focus_row, old_focus_col); + calendar_invalidate_day (calendar, calendar->focus_row, + calendar->focus_col); } break; case GDK_KP_Down: case GDK_Down: return_val = TRUE; if (event->state & GDK_CONTROL_MASK) - gtk_calendar_set_year_next (calendar); + calendar_set_year_next (calendar); else { if (calendar->focus_row < 5) calendar->focus_row++; - gtk_calendar_paint_day (widget, old_focus_row, old_focus_col); - gtk_calendar_paint_day (widget, calendar->focus_row, - calendar->focus_col); + calendar_invalidate_day (calendar, old_focus_row, old_focus_col); + calendar_invalidate_day (calendar, calendar->focus_row, + calendar->focus_col); } break; case GDK_KP_Space: @@ -3244,139 +2724,113 @@ gtk_calendar_key_press (GtkWidget *widget, if (row > -1 && col > -1) { return_val = TRUE; - gtk_calendar_freeze (calendar); if (calendar->day_month[row][col] == MONTH_PREV) - gtk_calendar_set_month_prev (calendar); + calendar_set_month_prev (calendar); else if (calendar->day_month[row][col] == MONTH_NEXT) - gtk_calendar_set_month_next (calendar); + calendar_set_month_next (calendar); - gtk_calendar_select_and_focus_day (calendar, day); - - gtk_calendar_thaw (calendar); + calendar_select_and_focus_day (calendar, day); } } return return_val; } + +/**************************************** + * Misc widget methods * + ****************************************/ + static void -gtk_calendar_set_display_option (GtkCalendar *calendar, - GtkCalendarDisplayOptions flag, - gboolean setting) +calendar_set_background (GtkWidget *widget) { - GtkCalendarDisplayOptions flags; - if (setting) - flags = calendar->display_flags | flag; - else - flags = calendar->display_flags & ~flag; - gtk_calendar_display_options (calendar, flags); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); + gint i; + + if (GTK_WIDGET_REALIZED (widget)) + { + for (i = 0; i < 4; i++) + { + if (priv->arrow_win[i]) + gdk_window_set_background (priv->arrow_win[i], + HEADER_BG_COLOR (widget)); + } + if (priv->header_win) + gdk_window_set_background (priv->header_win, + HEADER_BG_COLOR (widget)); + if (priv->day_name_win) + gdk_window_set_background (priv->day_name_win, + BACKGROUND_COLOR (widget)); + if (priv->week_win) + gdk_window_set_background (priv->week_win, + BACKGROUND_COLOR (widget)); + if (priv->main_win) + gdk_window_set_background (priv->main_win, + BACKGROUND_COLOR (widget)); + if (widget->window) + gdk_window_set_background (widget->window, + BACKGROUND_COLOR (widget)); + } } -static gboolean -gtk_calendar_get_display_option (GtkCalendar *calendar, - GtkCalendarDisplayOptions flag) +static void +gtk_calendar_style_set (GtkWidget *widget, + GtkStyle *previous_style) { - return (calendar->display_flags & flag) != 0; + if (previous_style && GTK_WIDGET_REALIZED (widget)) + calendar_set_background (widget); } - -static void -gtk_calendar_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +static void +gtk_calendar_state_changed (GtkWidget *widget, + GtkStateType previous_state) { - GtkCalendar *calendar; - - calendar = GTK_CALENDAR (object); - - switch (prop_id) + GtkCalendar *calendar = GTK_CALENDAR (widget); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); + int i; + + if (!GTK_WIDGET_IS_SENSITIVE (widget)) { - case PROP_YEAR: - gtk_calendar_select_month (calendar, - calendar->month, - g_value_get_int (value)); - break; - case PROP_MONTH: - gtk_calendar_select_month (calendar, - g_value_get_int (value), - calendar->year); - break; - case PROP_DAY: - gtk_calendar_select_day (calendar, - g_value_get_int (value)); - break; - case PROP_SHOW_HEADING: - gtk_calendar_set_display_option (calendar, - GTK_CALENDAR_SHOW_HEADING, - g_value_get_boolean (value)); - break; - case PROP_SHOW_DAY_NAMES: - gtk_calendar_set_display_option (calendar, - GTK_CALENDAR_SHOW_DAY_NAMES, - g_value_get_boolean (value)); - break; - case PROP_NO_MONTH_CHANGE: - gtk_calendar_set_display_option (calendar, - GTK_CALENDAR_NO_MONTH_CHANGE, - g_value_get_boolean (value)); - break; - case PROP_SHOW_WEEK_NUMBERS: - gtk_calendar_set_display_option (calendar, - GTK_CALENDAR_SHOW_WEEK_NUMBERS, - g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; + priv->in_drag = 0; + calendar_stop_spinning (calendar); } + + for (i = 0; i < 4; i++) + if (GTK_WIDGET_IS_SENSITIVE (widget)) + priv->arrow_state[i] = GTK_STATE_NORMAL; + else + priv->arrow_state[i] = GTK_STATE_INSENSITIVE; + + calendar_set_background (widget); } -static void -gtk_calendar_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +static void +gtk_calendar_grab_notify (GtkWidget *widget, + gboolean was_grabbed) { - GtkCalendar *calendar; + if (!was_grabbed) + calendar_stop_spinning (GTK_CALENDAR (widget)); +} - calendar = GTK_CALENDAR (object); +static gboolean +gtk_calendar_focus_out (GtkWidget *widget, + GdkEventFocus *event) +{ + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); - switch (prop_id) - { - case PROP_YEAR: - g_value_set_int (value, calendar->year); - break; - case PROP_MONTH: - g_value_set_int (value, calendar->month); - break; - case PROP_DAY: - g_value_set_int (value, calendar->selected_day); - break; - case PROP_SHOW_HEADING: - g_value_set_boolean (value, gtk_calendar_get_display_option (calendar, - GTK_CALENDAR_SHOW_HEADING)); - break; - case PROP_SHOW_DAY_NAMES: - g_value_set_boolean (value, gtk_calendar_get_display_option (calendar, - GTK_CALENDAR_SHOW_DAY_NAMES)); - break; - case PROP_NO_MONTH_CHANGE: - g_value_set_boolean (value, gtk_calendar_get_display_option (calendar, - GTK_CALENDAR_NO_MONTH_CHANGE)); - break; - case PROP_SHOW_WEEK_NUMBERS: - g_value_set_boolean (value, gtk_calendar_get_display_option (calendar, - GTK_CALENDAR_SHOW_WEEK_NUMBERS)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + calendar_stop_spinning (GTK_CALENDAR (widget)); + + priv->in_drag = 0; + return FALSE; } + +/**************************************** + * Drag and Drop * + ****************************************/ + static void gtk_calendar_drag_data_get (GtkWidget *widget, GdkDragContext *context, @@ -3417,53 +2871,51 @@ get_status_pending (GdkDragContext *context) } static void -gtk_calendar_drag_leave (GtkWidget *widget, +gtk_calendar_drag_leave (GtkWidget *widget, GdkDragContext *context, - guint time) + guint time) { - GtkCalendarPrivateData *private_data; + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - private_data->drag_highlight = 0; + priv->drag_highlight = 0; gtk_drag_unhighlight (widget); } static gboolean -gtk_calendar_drag_motion (GtkWidget *widget, +gtk_calendar_drag_motion (GtkWidget *widget, GdkDragContext *context, - gint x, - gint y, - guint time) + gint x, + gint y, + guint time) { - GtkCalendarPrivateData *private_data; + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (widget); GdkAtom target; - private_data = GTK_CALENDAR_PRIVATE_DATA (widget); - - if (!private_data->drag_highlight) + if (!priv->drag_highlight) { - private_data->drag_highlight = 1; + priv->drag_highlight = 1; gtk_drag_highlight (widget); } target = gtk_drag_dest_find_target (widget, context, NULL); if (target == GDK_NONE) gdk_drag_status (context, 0, time); - else { - set_status_pending (context, context->suggested_action); - gtk_drag_get_data (widget, context, target, time); - } + else + { + set_status_pending (context, context->suggested_action); + gtk_drag_get_data (widget, context, target, time); + } return TRUE; } static gboolean -gtk_calendar_drag_drop (GtkWidget *widget, +gtk_calendar_drag_drop (GtkWidget *widget, GdkDragContext *context, - gint x, - gint y, - guint time) + gint x, + gint y, + guint time) { GdkAtom target; @@ -3555,5 +3007,392 @@ gtk_calendar_drag_data_received (GtkWidget *widget, g_object_thaw_notify (G_OBJECT (calendar)); } + +/**************************************** + * Public API * + ****************************************/ + +/** + * gtk_calendar_new: + * + * Creates a new calendar, with the current date being selected. + * + * Return value: a newly #GtkCalendar widget + **/ +GtkWidget* +gtk_calendar_new (void) +{ + return g_object_new (GTK_TYPE_CALENDAR, NULL); +} + +/** + * gtk_calendar_display_options: + * @calendar: a #GtkCalendar. + * @flags: the display options to set. + * + * Sets display options (whether to display the heading and the month headings). + * + * Deprecated: Use gtk_calendar_set_display_options() instead + **/ +void +gtk_calendar_display_options (GtkCalendar *calendar, + GtkCalendarDisplayOptions flags) +{ + gtk_calendar_set_display_options (calendar, flags); +} + +/** + * gtk_calendar_get_display_options: + * @calendar: a #GtkCalendar + * + * Returns the current display options of @calendar. + * + * Return value: the display options. + * + * Since: 2.4 + **/ +GtkCalendarDisplayOptions +gtk_calendar_get_display_options (GtkCalendar *calendar) +{ + g_return_val_if_fail (GTK_IS_CALENDAR (calendar), 0); + + return calendar->display_flags; +} + +/** + * gtk_calendar_set_display_options: + * @calendar: a #GtkCalendar + * @flags: the display options to set + * + * Sets display options (whether to display the heading and the month + * headings). + * + * Since: 2.4 + **/ +void +gtk_calendar_set_display_options (GtkCalendar *calendar, + GtkCalendarDisplayOptions flags) +{ + GtkWidget *widget = GTK_WIDGET (calendar); + GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar); + gint resize = 0; + gint i; + GtkCalendarDisplayOptions old_flags; + + g_return_if_fail (GTK_IS_CALENDAR (calendar)); + + old_flags = calendar->display_flags; + + if (GTK_WIDGET_REALIZED (widget)) + { + if ((flags ^ calendar->display_flags) & GTK_CALENDAR_NO_MONTH_CHANGE) + { + resize ++; + if (! (flags & GTK_CALENDAR_NO_MONTH_CHANGE) + && (priv->header_win)) + { + calendar->display_flags &= ~GTK_CALENDAR_NO_MONTH_CHANGE; + calendar_realize_arrows (calendar); + } + else + { + for (i = 0; i < 4; i++) + { + if (priv->arrow_win[i]) + { + gdk_window_set_user_data (priv->arrow_win[i], + NULL); + gdk_window_destroy (priv->arrow_win[i]); + priv->arrow_win[i] = NULL; + } + } + } + } + + if ((flags ^ calendar->display_flags) & GTK_CALENDAR_SHOW_HEADING) + { + resize++; + + if (flags & GTK_CALENDAR_SHOW_HEADING) + { + calendar->display_flags |= GTK_CALENDAR_SHOW_HEADING; + calendar_realize_header (calendar); + } + else + { + for (i = 0; i < 4; i++) + { + if (priv->arrow_win[i]) + { + gdk_window_set_user_data (priv->arrow_win[i], + NULL); + gdk_window_destroy (priv->arrow_win[i]); + priv->arrow_win[i] = NULL; + } + } + gdk_window_set_user_data (priv->header_win, NULL); + gdk_window_destroy (priv->header_win); + priv->header_win = NULL; + } + } + + + if ((flags ^ calendar->display_flags) & GTK_CALENDAR_SHOW_DAY_NAMES) + { + resize++; + + if (flags & GTK_CALENDAR_SHOW_DAY_NAMES) + { + calendar->display_flags |= GTK_CALENDAR_SHOW_DAY_NAMES; + calendar_realize_day_names (calendar); + } + else + { + gdk_window_set_user_data (priv->day_name_win, NULL); + gdk_window_destroy (priv->day_name_win); + priv->day_name_win = NULL; + } + } + + if ((flags ^ calendar->display_flags) & GTK_CALENDAR_SHOW_WEEK_NUMBERS) + { + resize++; + + if (flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS) + { + calendar->display_flags |= GTK_CALENDAR_SHOW_WEEK_NUMBERS; + calendar_realize_week_numbers (calendar); + } + else + { + gdk_window_set_user_data (priv->week_win, NULL); + gdk_window_destroy (priv->week_win); + priv->week_win = NULL; + } + } + + if ((flags ^ calendar->display_flags) & GTK_CALENDAR_WEEK_START_MONDAY) + g_warning ("GTK_CALENDAR_WEEK_START_MONDAY is ignored; the first day of the week is determined from the locale"); + + calendar->display_flags = flags; + if (resize) + gtk_widget_queue_resize (GTK_WIDGET (calendar)); + + } + else + calendar->display_flags = flags; + + g_object_freeze_notify (G_OBJECT (calendar)); + if ((old_flags ^ calendar->display_flags) & GTK_CALENDAR_SHOW_HEADING) + g_object_notify (G_OBJECT (calendar), "show-heading"); + if ((old_flags ^ calendar->display_flags) & GTK_CALENDAR_SHOW_DAY_NAMES) + g_object_notify (G_OBJECT (calendar), "show-day-names"); + if ((old_flags ^ calendar->display_flags) & GTK_CALENDAR_NO_MONTH_CHANGE) + g_object_notify (G_OBJECT (calendar), "no-month-change"); + if ((old_flags ^ calendar->display_flags) & GTK_CALENDAR_SHOW_WEEK_NUMBERS) + g_object_notify (G_OBJECT (calendar), "show-week-numbers"); + g_object_thaw_notify (G_OBJECT (calendar)); +} + +/** + * gtk_calendar_select_month: + * @calendar: a #GtkCalendar + * @month: a month number between 0 and 11. + * @year: the year the month is in. + * + * Shifts the calendar to a different month. + * + * Return value: %TRUE, always + **/ +gboolean +gtk_calendar_select_month (GtkCalendar *calendar, + guint month, + guint year) +{ + g_return_val_if_fail (GTK_IS_CALENDAR (calendar), FALSE); + g_return_val_if_fail (month <= 11, FALSE); + + calendar->month = month; + calendar->year = year; + + calendar_compute_days (calendar); + + gtk_widget_queue_draw (GTK_WIDGET (calendar)); + + g_object_freeze_notify (G_OBJECT (calendar)); + g_object_notify (G_OBJECT (calendar), "month"); + g_object_notify (G_OBJECT (calendar), "year"); + g_object_thaw_notify (G_OBJECT (calendar)); + + g_signal_emit (calendar, + gtk_calendar_signals[MONTH_CHANGED_SIGNAL], + 0); + return TRUE; +} + +/** + * gtk_calendar_select_day: + * @calendar: a #GtkCalendar. + * @day: the day number between 1 and 31, or 0 to unselect + * the currently selected day. + * + * Selects a day from the current month. + **/ +void +gtk_calendar_select_day (GtkCalendar *calendar, + guint day) +{ + g_return_if_fail (GTK_IS_CALENDAR (calendar)); + g_return_if_fail (day <= 31); + + /* Deselect the old day */ + if (calendar->selected_day > 0) + { + gint selected_day; + + selected_day = calendar->selected_day; + calendar->selected_day = 0; + if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (calendar))) + calendar_invalidate_day_num (calendar, selected_day); + } + + calendar->selected_day = day; + + /* Select the new day */ + if (day != 0) + { + if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (calendar))) + calendar_invalidate_day_num (calendar, day); + } + + g_object_notify (G_OBJECT (calendar), "day"); + + g_signal_emit (calendar, + gtk_calendar_signals[DAY_SELECTED_SIGNAL], + 0); +} + +/** + * gtk_calendar_clear_marks: + * @calendar: a #GtkCalendar + * + * Remove all visual markers. + **/ +void +gtk_calendar_clear_marks (GtkCalendar *calendar) +{ + guint day; + + g_return_if_fail (GTK_IS_CALENDAR (calendar)); + + for (day = 0; day < 31; day++) + { + calendar->marked_date[day] = FALSE; + } + + gtk_widget_queue_draw (GTK_WIDGET (calendar)); +} + +/** + * gtk_calendar_mark_day: + * @calendar: a #GtkCalendar + * @day: the day number to mark between 1 and 31. + * + * Places a visual marker on a particular day. + * + * Return value: %TRUE, always + **/ +gboolean +gtk_calendar_mark_day (GtkCalendar *calendar, + guint day) +{ + g_return_val_if_fail (GTK_IS_CALENDAR (calendar), FALSE); + + if (day >= 1 && day <= 31 && calendar->marked_date[day-1] == FALSE) + { + calendar->marked_date[day - 1] = TRUE; + calendar_invalidate_day_num (calendar, day); + } + + return TRUE; +} + +/** + * gtk_calendar_unmark_day: + * @calendar: a #GtkCalendar. + * @day: the day number to unmark between 1 and 31. + * + * Removes the visual marker from a particular day. + * + * Return value: %TRUE, always + **/ +gboolean +gtk_calendar_unmark_day (GtkCalendar *calendar, + guint day) +{ + g_return_val_if_fail (GTK_IS_CALENDAR (calendar), FALSE); + + if (day >= 1 && day <= 31 && calendar->marked_date[day-1] == TRUE) + { + calendar->marked_date[day - 1] = FALSE; + calendar_invalidate_day_num (calendar, day); + } + + return TRUE; +} + +/** + * gtk_calendar_get_date: + * @calendar: a #GtkCalendar + * @year: location to store the year number, or %NULL + * @month: location to store the month number (between 0 and 11), or %NULL + * @day: location to store the day number (between 1 and 31), or %NULL + * + * Obtains the selected date from a #GtkCalendar. + **/ +void +gtk_calendar_get_date (GtkCalendar *calendar, + guint *year, + guint *month, + guint *day) +{ + g_return_if_fail (GTK_IS_CALENDAR (calendar)); + + if (year) + *year = calendar->year; + + if (month) + *month = calendar->month; + + if (day) + *day = calendar->selected_day; +} + +/** + * gtk_calendar_freeze: + * @calendar: a #GtkCalendar + * + * Does nothing. Previously locked the display of the calendar until + * it was thawed with gtk_calendar_thaw(). + **/ +void +gtk_calendar_freeze (GtkCalendar *calendar) +{ + g_return_if_fail (GTK_IS_CALENDAR (calendar)); +} + +/** + * gtk_calendar_thaw: + * @calendar: + * + * Does nothing. Previously defrosted a calendar; all the changes made + * since the last gtk_calendar_freeze() were displayed. + **/ +void +gtk_calendar_thaw (GtkCalendar *calendar) +{ + g_return_if_fail (GTK_IS_CALENDAR (calendar)); +} + #define __GTK_CALENDAR_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkcalendar.h b/gtk/gtkcalendar.h index 162d814acc..3115e0ee0a 100644 --- a/gtk/gtkcalendar.h +++ b/gtk/gtkcalendar.h @@ -49,6 +49,8 @@ G_BEGIN_DECLS typedef struct _GtkCalendar GtkCalendar; typedef struct _GtkCalendarClass GtkCalendarClass; +typedef struct _GtkCalendarPrivate GtkCalendarPrivate; + typedef enum { GTK_CALENDAR_SHOW_HEADING = 1 << 0, @@ -77,8 +79,8 @@ struct _GtkCalendar GtkCalendarDisplayOptions display_flags; GdkColor marked_date_color[31]; - GdkGC *gc; - GdkGC *xor_gc; + GdkGC *gc; /* unused */ + GdkGC *xor_gc; /* unused */ gint focus_row; gint focus_col; @@ -86,7 +88,7 @@ struct _GtkCalendar gint highlight_row; gint highlight_col; - gpointer private_data; + GtkCalendarPrivate *priv; gchar grow_space [32]; /* Padding for future expansion */ @@ -141,9 +143,10 @@ void gtk_calendar_get_date (GtkCalendar *calendar, guint *year, guint *month, guint *day); +#ifndef GTK_DISABLE_DEPRECATED void gtk_calendar_freeze (GtkCalendar *calendar); void gtk_calendar_thaw (GtkCalendar *calendar); - +#endif G_END_DECLS diff --git a/gtk/gtkcellrenderer.c b/gtk/gtkcellrenderer.c index 8c6a8df773..596f6715f7 100644 --- a/gtk/gtkcellrenderer.c +++ b/gtk/gtkcellrenderer.c @@ -580,19 +580,13 @@ gtk_cell_renderer_render (GtkCellRenderer *cell, if (cell->cell_background_set && !selected) { - GdkColor color; - GdkGC *gc; - - color.red = priv->cell_background.red; - color.green = priv->cell_background.green; - color.blue = priv->cell_background.blue; - - gc = gdk_gc_new (window); - gdk_gc_set_rgb_fg_color (gc, &color); - gdk_draw_rectangle (window, gc, TRUE, - background_area->x, background_area->y, - background_area->width, background_area->height); - g_object_unref (gc); + cairo_t *cr = gdk_cairo_create (window); + + gdk_cairo_rectangle (cr, background_area); + gdk_cairo_set_source_color (cr, &priv->cell_background); + cairo_fill (cr); + + cairo_destroy (cr); } GTK_CELL_RENDERER_GET_CLASS (cell)->render (cell, diff --git a/gtk/gtkcellrendererpixbuf.c b/gtk/gtkcellrendererpixbuf.c index f3839ea791..f19adf6216 100644 --- a/gtk/gtkcellrendererpixbuf.c +++ b/gtk/gtkcellrendererpixbuf.c @@ -508,6 +508,7 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell, GdkPixbuf *colorized = NULL; GdkRectangle pix_rect; GdkRectangle draw_rect; + cairo_t *cr; priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (cell); @@ -588,18 +589,13 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell, pixbuf = colorized; } - gdk_draw_pixbuf (window, - widget->style->black_gc, - pixbuf, - /* pixbuf 0, 0 is at pix_rect.x, pix_rect.y */ - draw_rect.x - pix_rect.x, - draw_rect.y - pix_rect.y, - draw_rect.x, - draw_rect.y, - draw_rect.width, - draw_rect.height, - GDK_RGB_DITHER_NORMAL, - 0, 0); + cr = gdk_cairo_create (window); + + gdk_cairo_set_source_pixbuf (cr, pixbuf, pix_rect.x, pix_rect.y); + gdk_cairo_rectangle (cr, &draw_rect); + cairo_fill (cr); + + cairo_destroy (cr); if (invisible) g_object_unref (invisible); diff --git a/gtk/gtkcellrendererprogress.c b/gtk/gtkcellrendererprogress.c index a5b0d95ff7..c01bbd2f17 100644 --- a/gtk/gtkcellrendererprogress.c +++ b/gtk/gtkcellrendererprogress.c @@ -318,36 +318,41 @@ gtk_cell_renderer_progress_render (GtkCellRenderer *cell, guint flags) { GtkCellRendererProgress *cellprogress = GTK_CELL_RENDERER_PROGRESS (cell); - GdkGC *gc; PangoLayout *layout; PangoRectangle logical_rect; gint x, y, w, h, perc_w, pos; GdkRectangle clip; gboolean is_rtl; + cairo_t *cr; is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL; - gc = gdk_gc_new (window); + cr = gdk_cairo_create (window); x = cell_area->x + cell->xpad; y = cell_area->y + cell->ypad; w = cell_area->width - cell->xpad * 2; h = cell_area->height - cell->ypad * 2; - - gdk_gc_set_rgb_fg_color (gc, &widget->style->fg[GTK_STATE_NORMAL]); - gdk_draw_rectangle (window, gc, TRUE, x, y, w, h); + + cairo_rectangle (cr, x, y, w, h); + gdk_cairo_set_source_color (cr, &widget->style->fg[GTK_STATE_NORMAL]); + cairo_fill (cr); x += widget->style->xthickness; y += widget->style->ythickness; w -= widget->style->xthickness * 2; h -= widget->style->ythickness * 2; - gdk_gc_set_rgb_fg_color (gc, &widget->style->bg[GTK_STATE_NORMAL]); - gdk_draw_rectangle (window, gc, TRUE, x, y, w, h); - gdk_gc_set_rgb_fg_color (gc, &widget->style->bg[GTK_STATE_SELECTED]); + cairo_rectangle (cr, x, y, w, h); + gdk_cairo_set_source_color (cr, &widget->style->bg[GTK_STATE_NORMAL]); + cairo_fill (cr); + perc_w = w * MAX (0, cellprogress->priv->value) / 100; - gdk_draw_rectangle (window, gc, TRUE, is_rtl ? (x + w - perc_w) : x, y, perc_w, h); + + cairo_rectangle (cr, is_rtl ? (x + w - perc_w) : x, y, perc_w, h); + gdk_cairo_set_source_color (cr, &widget->style->bg[GTK_STATE_SELECTED]); + cairo_fill (cr); layout = gtk_widget_create_pango_layout (widget, cellprogress->priv->label); pango_layout_get_pixel_extents (layout, NULL, &logical_rect); @@ -375,7 +380,7 @@ gtk_cell_renderer_progress_render (GtkCellRenderer *cell, layout); g_object_unref (layout); - g_object_unref (gc); + cairo_destroy (cr); } #define __GTK_CELL_RENDERER_PROGRESS_C__ diff --git a/gtk/gtkcellrenderertext.c b/gtk/gtkcellrenderertext.c index 9058c66357..343a4895fb 100644 --- a/gtk/gtkcellrenderertext.c +++ b/gtk/gtkcellrenderertext.c @@ -1626,29 +1626,22 @@ gtk_cell_renderer_text_render (GtkCellRenderer *cell, if (celltext->background_set && (flags & GTK_CELL_RENDERER_SELECTED) == 0) { - GdkColor color; - GdkGC *gc; + cairo_t *cr = gdk_cairo_create (window); + + if (expose_area) + { + gdk_cairo_rectangle (cr, expose_area); + cairo_clip (cr); + } + + gdk_cairo_rectangle (cr, background_area); + cairo_set_source_rgb (cr, + celltext->background.red / 65535., + celltext->background.green / 65535., + celltext->background.blue / 65535.); + cairo_fill (cr); - color.red = celltext->background.red; - color.green = celltext->background.green; - color.blue = celltext->background.blue; - - gc = gdk_gc_new (window); - - gdk_gc_set_rgb_fg_color (gc, &color); - - if (expose_area) - gdk_gc_set_clip_rectangle (gc, expose_area); - gdk_draw_rectangle (window, - gc, - TRUE, - background_area->x, - background_area->y, - background_area->width, - background_area->height); - if (expose_area) - gdk_gc_set_clip_rectangle (gc, NULL); - g_object_unref (gc); + cairo_destroy (cr); } if (priv->ellipsize_set) diff --git a/gtk/gtkcellview.c b/gtk/gtkcellview.c index 075c24e235..29ae5894b4 100644 --- a/gtk/gtkcellview.c +++ b/gtk/gtkcellview.c @@ -429,23 +429,16 @@ gtk_cell_view_expose (GtkWidget *widget, /* "blank" background */ if (cellview->priv->background_set) { - GdkGC *gc; + cairo_t *cr = gdk_cairo_create (GTK_WIDGET (cellview)->window); - gc = gdk_gc_new (GTK_WIDGET (cellview)->window); - gdk_gc_set_rgb_fg_color (gc, &cellview->priv->background); + gdk_cairo_rectangle (cr, &widget->allocation); + cairo_set_source_rgb (cr, + cellview->priv->background.red / 65535., + cellview->priv->background.green / 65535., + cellview->priv->background.blue / 65535.); + cairo_fill (cr); - gdk_draw_rectangle (GTK_WIDGET (cellview)->window, - gc, - TRUE, - - /*0, 0,*/ - widget->allocation.x, - widget->allocation.y, - - widget->allocation.width, - widget->allocation.height); - - g_object_unref (gc); + cairo_destroy (cr); } /* set cell data (if available) */ diff --git a/gtk/gtkcolorbutton.c b/gtk/gtkcolorbutton.c index 23f3758965..6ade7cefa0 100644 --- a/gtk/gtkcolorbutton.c +++ b/gtk/gtkcolorbutton.c @@ -59,7 +59,7 @@ struct _GtkColorButtonPrivate GdkPixbuf *pixbuf; /* Pixbuf for rendering sample */ GdkGC *gc; /* GC for drawing */ - GtkWidget *drawing_area;/* Drawing area for color sample */ + GtkWidget *draw_area; /* Widget where we draw the color sample */ GtkWidget *cs_dialog; /* Color selection dialog */ gchar *title; /* Title for the color selection window */ @@ -285,8 +285,8 @@ render (GtkColorButton *color_button) guint8 insensitive_g = 0; guint8 insensitive_b = 0; - width = color_button->priv->drawing_area->allocation.width; - height = color_button->priv->drawing_area->allocation.height; + width = color_button->priv->draw_area->allocation.width; + height = color_button->priv->draw_area->allocation.height; if (color_button->priv->pixbuf == NULL || gdk_pixbuf_get_width (color_button->priv->pixbuf) != width || gdk_pixbuf_get_height (color_button->priv->pixbuf) != height) @@ -378,8 +378,8 @@ expose_event (GtkWidget *widget, { GtkColorButton *color_button = GTK_COLOR_BUTTON (data); - gint width = color_button->priv->drawing_area->allocation.width; - gint height = color_button->priv->drawing_area->allocation.height; + gint width = color_button->priv->draw_area->allocation.width; + gint height = color_button->priv->draw_area->allocation.height; if (color_button->priv->pixbuf == NULL || width != gdk_pixbuf_get_width (color_button->priv->pixbuf) || @@ -389,15 +389,15 @@ expose_event (GtkWidget *widget, gdk_draw_pixbuf (widget->window, color_button->priv->gc, color_button->priv->pixbuf, - event->area.x, - event->area.y, + event->area.x - widget->allocation.x, + event->area.y - widget->allocation.y, event->area.x, event->area.y, event->area.width, event->area.height, GDK_RGB_DITHER_MAX, - event->area.x, - event->area.y); + event->area.x - widget->allocation.x, + event->area.y - widget->allocation.y); return FALSE; } @@ -480,7 +480,7 @@ gtk_color_button_drag_data_received (GtkWidget *widget, g_object_unref (color_button->priv->pixbuf); color_button->priv->pixbuf = NULL; - gtk_widget_queue_draw (color_button->priv->drawing_area); + gtk_widget_queue_draw (color_button->priv->draw_area); g_signal_emit (color_button, color_button_signals[COLOR_SET], 0); @@ -562,15 +562,16 @@ gtk_color_button_init (GtkColorButton *color_button) gtk_container_add (GTK_CONTAINER (alignment), frame); gtk_widget_show (frame); - color_button->priv->drawing_area = gtk_drawing_area_new (); + /* Just some widget we can hook to expose-event on */ + color_button->priv->draw_area = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); layout = gtk_widget_create_pango_layout (GTK_WIDGET (color_button), "Black"); pango_layout_get_pixel_extents (layout, NULL, &rect); - gtk_widget_set_size_request (color_button->priv->drawing_area, rect.width - 2, rect.height - 2); - g_signal_connect (color_button->priv->drawing_area, "expose_event", + gtk_widget_set_size_request (color_button->priv->draw_area, rect.width - 2, rect.height - 2); + g_signal_connect (color_button->priv->draw_area, "expose-event", G_CALLBACK (expose_event), color_button); - gtk_container_add (GTK_CONTAINER (frame), color_button->priv->drawing_area); - gtk_widget_show (color_button->priv->drawing_area); + gtk_container_add (GTK_CONTAINER (frame), color_button->priv->draw_area); + gtk_widget_show (color_button->priv->draw_area); color_button->priv->title = g_strdup (_("Pick a Color")); /* default title */ @@ -685,7 +686,7 @@ dialog_ok_clicked (GtkWidget *widget, gtk_widget_hide (color_button->priv->cs_dialog); - gtk_widget_queue_draw (color_button->priv->drawing_area); + gtk_widget_queue_draw (color_button->priv->draw_area); g_signal_emit (color_button, color_button_signals[COLOR_SET], 0); @@ -790,7 +791,7 @@ gtk_color_button_set_color (GtkColorButton *color_button, g_object_unref (color_button->priv->pixbuf); color_button->priv->pixbuf = NULL; - gtk_widget_queue_draw (color_button->priv->drawing_area); + gtk_widget_queue_draw (color_button->priv->draw_area); g_object_notify (G_OBJECT (color_button), "color"); } @@ -817,7 +818,7 @@ gtk_color_button_set_alpha (GtkColorButton *color_button, g_object_unref (color_button->priv->pixbuf); color_button->priv->pixbuf = NULL; - gtk_widget_queue_draw (color_button->priv->drawing_area); + gtk_widget_queue_draw (color_button->priv->draw_area); g_object_notify (G_OBJECT (color_button), "alpha"); } @@ -882,7 +883,7 @@ gtk_color_button_set_use_alpha (GtkColorButton *color_button, color_button->priv->use_alpha = use_alpha; render (color_button); - gtk_widget_queue_draw (color_button->priv->drawing_area); + gtk_widget_queue_draw (color_button->priv->draw_area); g_object_notify (G_OBJECT (color_button), "use-alpha"); } diff --git a/gtk/gtkcolorsel.c b/gtk/gtkcolorsel.c index c18b8afbdc..1f61d108f2 100644 --- a/gtk/gtkcolorsel.c +++ b/gtk/gtkcolorsel.c @@ -401,7 +401,7 @@ color_sample_draw_sample (GtkColorSelection *colorsel, int which) goff = priv->old_sample->allocation.width % 32; } - cr = gdk_drawable_create_cairo_context (da->window); + cr = gdk_cairo_create (da->window); wid = da->allocation.width; heig = da->allocation.height; @@ -427,23 +427,21 @@ color_sample_draw_sample (GtkColorSelection *colorsel, int which) if (which == 0) { - if (priv->has_opacity) - cairo_set_source_rgba (cr, - priv->old_color[COLORSEL_RED], - priv->old_color[COLORSEL_GREEN], - priv->old_color[COLORSEL_BLUE], - priv->has_opacity ? - priv->old_color[COLORSEL_OPACITY] : 1.0); + cairo_set_source_rgba (cr, + priv->old_color[COLORSEL_RED], + priv->old_color[COLORSEL_GREEN], + priv->old_color[COLORSEL_BLUE], + priv->has_opacity ? + priv->old_color[COLORSEL_OPACITY] : 1.0); } else { - if (priv->has_opacity) - cairo_set_source_rgba (cr, - priv->color[COLORSEL_RED], - priv->color[COLORSEL_GREEN], - priv->color[COLORSEL_BLUE], - priv->has_opacity ? - priv->color[COLORSEL_OPACITY] : 1.0); + cairo_set_source_rgba (cr, + priv->color[COLORSEL_RED], + priv->color[COLORSEL_GREEN], + priv->color[COLORSEL_BLUE], + priv->has_opacity ? + priv->color[COLORSEL_OPACITY] : 1.0); } cairo_rectangle (cr, 0, 0, wid, heig); @@ -615,11 +613,10 @@ palette_paint (GtkWidget *drawing_area, if (drawing_area->window == NULL) return; - cr = gdk_drawable_create_cairo_context (drawing_area->window); + cr = gdk_cairo_create (drawing_area->window); gdk_cairo_set_source_color (cr, &drawing_area->style->bg[GTK_STATE_NORMAL]); - cairo_rectangle (cr, - area->x, area->y, area->width, area->height); + gdk_cairo_rectangle (cr, area); cairo_fill (cr); if (GTK_WIDGET_HAS_FOCUS (drawing_area)) diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c index 18c7d13be1..dec51ecff4 100644 --- a/gtk/gtkdnd.c +++ b/gtk/gtkdnd.c @@ -774,6 +774,8 @@ gtk_drag_highlight_expose (GtkWidget *widget, if (GTK_WIDGET_DRAWABLE (widget)) { + cairo_t *cr; + if (GTK_WIDGET_NO_WINDOW (widget)) { x = widget->allocation.x; @@ -792,11 +794,15 @@ gtk_drag_highlight_expose (GtkWidget *widget, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, widget, "dnd", x, y, width, height); - - gdk_draw_rectangle (widget->window, - widget->style->black_gc, - FALSE, - x, y, width - 1, height - 1); + + cr = gdk_cairo_create (widget->window); + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */ + cairo_set_line_width (cr, 1.0); + cairo_rectangle (cr, + x + 0.5, y + 0.5, + width - 1, height - 1); + cairo_stroke (cr); + cairo_destroy (cr); } return FALSE; diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 688b2a3cb8..b7b69420f9 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -3091,6 +3091,7 @@ gtk_entry_draw_text (GtkEntry *entry) if (GTK_WIDGET_DRAWABLE (entry)) { PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE); + cairo_t *cr; gint x, y; gint start_pos, end_pos; @@ -3098,57 +3099,53 @@ gtk_entry_draw_text (GtkEntry *entry) get_layout_position (entry, &x, &y); - gdk_draw_layout (entry->text_area, widget->style->text_gc [widget->state], - x, y, - layout); - + cr = gdk_cairo_create (entry->text_area); + + cairo_move_to (cr, x, y); + gdk_cairo_set_source_color (cr, &widget->style->text [widget->state]); + pango_cairo_show_layout (cr, layout); + if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos)) { gint *ranges; gint n_ranges, i; PangoRectangle logical_rect; - GdkGC *selection_gc, *text_gc; - GdkRegion *clip_region; + GdkColor *selection_color, *text_color; pango_layout_get_pixel_extents (layout, NULL, &logical_rect); gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges); if (GTK_WIDGET_HAS_FOCUS (entry)) { - selection_gc = widget->style->base_gc [GTK_STATE_SELECTED]; - text_gc = widget->style->text_gc [GTK_STATE_SELECTED]; + selection_color = &widget->style->base [GTK_STATE_SELECTED]; + text_color = &widget->style->text [GTK_STATE_SELECTED]; } else { - selection_gc = widget->style->base_gc [GTK_STATE_ACTIVE]; - text_gc = widget->style->text_gc [GTK_STATE_ACTIVE]; + selection_color = &widget->style->base [GTK_STATE_ACTIVE]; + text_color = &widget->style->text [GTK_STATE_ACTIVE]; } - - clip_region = gdk_region_new (); - for (i = 0; i < n_ranges; ++i) - { - GdkRectangle rect; - rect.x = INNER_BORDER - entry->scroll_offset + ranges[2 * i]; - rect.y = y; - rect.width = ranges[2 * i + 1]; - rect.height = logical_rect.height; - - gdk_draw_rectangle (entry->text_area, selection_gc, TRUE, - rect.x, rect.y, rect.width, rect.height); + for (i = 0; i < n_ranges; ++i) + cairo_rectangle (cr, + INNER_BORDER - entry->scroll_offset + ranges[2 * i], + y, + ranges[2 * i + 1], + logical_rect.height); - gdk_region_union_with_rect (clip_region, &rect); - } + cairo_clip (cr); - gdk_gc_set_clip_region (text_gc, clip_region); - gdk_draw_layout (entry->text_area, text_gc, - x, y, - layout); - gdk_gc_set_clip_region (text_gc, NULL); + gdk_cairo_set_source_color (cr, selection_color); + cairo_paint (cr); + + cairo_move_to (cr, x, y); + gdk_cairo_set_source_color (cr, text_color); + pango_cairo_show_layout (cr, layout); - gdk_region_destroy (clip_region); g_free (ranges); } + + cairo_destroy (cr); } } diff --git a/gtk/gtkhruler.c b/gtk/gtkhruler.c index f88dad5f27..acbceb6f74 100644 --- a/gtk/gtkhruler.c +++ b/gtk/gtkhruler.c @@ -177,7 +177,7 @@ gtk_hruler_draw_ticks (GtkRuler *ruler) 0, 0, widget->allocation.width, widget->allocation.height); - cr = gdk_drawable_create_cairo_context (ruler->backing_store); + cr = gdk_cairo_create (ruler->backing_store); gdk_cairo_set_source_color (cr, &widget->style->fg[widget->state]); cairo_rectangle (cr, @@ -296,7 +296,7 @@ gtk_hruler_draw_pos (GtkRuler *ruler) if ((bs_width > 0) && (bs_height > 0)) { - cairo_t *cr = gdk_drawable_create_cairo_context (widget->window); + cairo_t *cr = gdk_cairo_create (widget->window); /* If a backing store exists, restore the ruler */ if (ruler->backing_store) diff --git a/gtk/gtkhsv.c b/gtk/gtkhsv.c index 20ca50c63c..b73f59d7a4 100644 --- a/gtk/gtkhsv.c +++ b/gtk/gtkhsv.c @@ -1298,7 +1298,7 @@ gtk_hsv_expose (GtkWidget *widget, if (!gdk_rectangle_intersect (&event->area, &rect, &dest)) return FALSE; - cr = gdk_drawable_create_cairo_context (widget->window); + cr = gdk_cairo_create (widget->window); cairo_translate (cr, widget->allocation.x, widget->allocation.y); paint (hsv, cr, diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c index 8bc4c74473..8494103682 100644 --- a/gtk/gtkiconview.c +++ b/gtk/gtkiconview.c @@ -1250,7 +1250,7 @@ gtk_icon_view_expose (GtkWidget *widget, if (expose->window != icon_view->priv->bin_window) return FALSE; - cr = gdk_drawable_create_cairo_context (icon_view->priv->bin_window); + cr = gdk_cairo_create (icon_view->priv->bin_window); cairo_set_line_width (cr, 1.); gtk_icon_view_get_drag_dest_item (icon_view, &path, &dest_pos); @@ -2899,7 +2899,7 @@ gtk_icon_view_paint_rubberband (GtkIconView *icon_view, fill_color_alpha / 255.); cairo_save (cr); - cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height); + gdk_cairo_rectangle (cr, &rect); cairo_clip (cr); cairo_paint (cr); @@ -6460,15 +6460,12 @@ gtk_icon_view_create_drag_icon (GtkIconView *icon_view, item->height + 2, -1); - cr = gdk_drawable_create_cairo_context (drawable); + cr = gdk_cairo_create (drawable); cairo_set_line_width (cr, 1.); - gdk_draw_rectangle (drawable, - widget->style->base_gc [GTK_WIDGET_STATE (widget)], - TRUE, - 0, 0, - item->width + 2, - item->height + 2); + gdk_cairo_set_source_color (cr, &widget->style->base_gc); + cairo_rectangle (cr, 0, 0, item->width + 2, item->height + 2); + cairo_fill (cr); area.x = 0; area.y = 0; @@ -6476,15 +6473,11 @@ gtk_icon_view_create_drag_icon (GtkIconView *icon_view, area.height = item->height; gtk_icon_view_paint_item (icon_view, cr, item, &area, - drawable, 1, 1, FALSE); + drawable, 1, 1, FALSE); - - gdk_draw_rectangle (drawable, - widget->style->black_gc, - FALSE, - 0, 0, - item->width + 1, - item->height + 1); + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */ + cairo_rectangle (cr, 0.5, 0.5, item->width + 1, item->height + 1); + cairo_stroke (cr); cairo_destroy (cr); diff --git a/gtk/gtkstyle.c b/gtk/gtkstyle.c index 7452c52e88..d2af4bf082 100644 --- a/gtk/gtkstyle.c +++ b/gtk/gtkstyle.c @@ -2900,14 +2900,13 @@ draw_arrow (GdkWindow *window, gint width, gint height) { - cairo_t *cr = gdk_drawable_create_cairo_context (window); + cairo_t *cr = gdk_cairo_create (window); gdk_cairo_set_source_color (cr, color); if (area) { - cairo_rectangle (cr, area->x, area->y, area->width, area->height); + gdk_cairo_rectangle (cr, area); cairo_clip (cr); - cairo_new_path (cr); } if (arrow_type == GTK_ARROW_DOWN) @@ -3611,7 +3610,7 @@ gtk_default_draw_check (GtkStyle *style, gint width, gint height) { - cairo_t *cr = gdk_drawable_create_cairo_context (window); + cairo_t *cr = gdk_cairo_create (window); enum { BUTTON, MENU, CELL } type = BUTTON; int exterior_size; int interior_size; @@ -3627,9 +3626,8 @@ gtk_default_draw_check (GtkStyle *style, if (area) { - cairo_rectangle (cr, area->x, area->y, area->width, area->height); + gdk_cairo_rectangle (cr, area); cairo_clip (cr); - cairo_new_path (cr); } exterior_size = MIN (width, height); @@ -3737,7 +3735,7 @@ gtk_default_draw_option (GtkStyle *style, gint width, gint height) { - cairo_t *cr = gdk_drawable_create_cairo_context (window); + cairo_t *cr = gdk_cairo_create (window); enum { BUTTON, MENU, CELL } type = BUTTON; int exterior_size; @@ -3751,9 +3749,8 @@ gtk_default_draw_option (GtkStyle *style, if (area) { - cairo_rectangle (cr, area->x, area->y, area->width, area->height); + gdk_cairo_rectangle (cr, area); cairo_clip (cr); - cairo_new_path (cr); } exterior_size = MIN (width, height); @@ -4543,7 +4540,7 @@ gtk_default_draw_focus (GtkStyle *style, sanitize_size (window, &width, &height); - cr = gdk_drawable_create_cairo_context (window); + cr = gdk_cairo_create (window); if (detail && !strcmp (detail, "colorwheel_light")) cairo_set_source_rgb (cr, 0., 0., 0.); @@ -4583,10 +4580,8 @@ gtk_default_draw_focus (GtkStyle *style, if (area) { - cairo_rectangle (cr, - area->x, area->y, area->width, area->height); + gdk_cairo_rectangle (cr, area); cairo_clip (cr); - cairo_new_path (cr); } cairo_rectangle (cr, @@ -4793,13 +4788,12 @@ gtk_default_draw_expander (GtkStyle *style, double x_double, y_double; gint degrees = 0; - cairo_t *cr = gdk_drawable_create_cairo_context (window); + cairo_t *cr = gdk_cairo_create (window); if (area) { - cairo_rectangle (cr, area->x, area->y, area->width, area->height); + gdk_cairo_rectangle (cr, area); cairo_clip (cr); - cairo_new_path (cr); } if (widget && diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index bbdf558a2c..f4d9140e32 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -7329,13 +7329,11 @@ text_window_invalidate_rect (GtkTextWindow *win, #if 0 { - GdkColor color = { 0, 65535, 0, 0 }; - GdkGC *gc = gdk_gc_new (win->bin_window); - gdk_gc_set_rgb_fg_color (gc, &color); - gdk_draw_rectangle (win->bin_window, - gc, TRUE, window_rect.x, window_rect.y, - window_rect.width, window_rect.height); - g_object_unref (gc); + cairo_t *cr = gdk_cairo_create (win->bin_window); + gdk_cairo_rectangle (cr, &window_rect); + cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); /* red */ + cairo_fill (cr); + cairo_destroy (cr); } #endif } diff --git a/gtk/gtkvruler.c b/gtk/gtkvruler.c index 648ec96143..c013aa557c 100644 --- a/gtk/gtkvruler.c +++ b/gtk/gtkvruler.c @@ -178,7 +178,7 @@ gtk_vruler_draw_ticks (GtkRuler *ruler) 0, 0, widget->allocation.width, widget->allocation.height); - cr = gdk_drawable_create_cairo_context (ruler->backing_store); + cr = gdk_cairo_create (ruler->backing_store); gdk_cairo_set_source_color (cr, &widget->style->fg[widget->state]); cairo_rectangle (cr, @@ -303,7 +303,7 @@ gtk_vruler_draw_pos (GtkRuler *ruler) if ((bs_width > 0) && (bs_height > 0)) { - cairo_t *cr = gdk_drawable_create_cairo_context (widget->window); + cairo_t *cr = gdk_cairo_create (widget->window); /* If a backing store exists, restore the ruler */ if (ruler->backing_store) diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 72b78f939c..da8bbaa5b4 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -2744,7 +2744,25 @@ gtk_widget_queue_shallow_draw (GtkWidget *widget) g_return_if_fail (GTK_IS_WIDGET (widget)); + if (!GTK_WIDGET_REALIZED (widget)) + return; + gtk_widget_get_draw_rectangle (widget, &rect); + + /* get_draw_rectangle() gives us window coordinates, we + * need to convert to the coordinates that widget->allocation + * is in. + */ + if (!GTK_WIDGET_NO_WINDOW (widget) && widget->parent) + { + int wx, wy; + + gdk_window_get_position (widget->window, &wx, &wy); + + rect.x += wx; + rect.y += wy; + } + region = gdk_region_rectangle (&rect); gtk_widget_invalidate_widget_windows (widget, region); gdk_region_destroy (region); diff --git a/tests/testcairo.c b/tests/testcairo.c index 06257cd9af..918ebff974 100644 --- a/tests/testcairo.c +++ b/tests/testcairo.c @@ -197,7 +197,7 @@ on_expose_event (GtkWidget *widget, { cairo_t *cr; - cr = gdk_drawable_create_cairo_context (widget->window); + cr = gdk_cairo_create (widget->window); draw (cr, widget->allocation.width, widget->allocation.height); |