Consider details for size-request and expose-event. (#339540)
* gtk/gtkcalendar.c: Add gtk_calendar_get_detail and is_color_attribute functions. Change gtk_calendar_size_request and calendar_paint_day to consider and show calender details. svn path=/trunk/; revision=19261
This commit is contained in:
parent
fbc0f37062
commit
d1e8ca6c4a
@ -1,3 +1,11 @@
|
|||||||
|
2007-12-28 Mathias Hasselmann <mathias@openismus.com>
|
||||||
|
|
||||||
|
Consider details for size-request and expose-event. (#339540)
|
||||||
|
|
||||||
|
* gtk/gtkcalendar.c: Add gtk_calendar_get_detail and
|
||||||
|
is_color_attribute functions. Change gtk_calendar_size_request
|
||||||
|
and calendar_paint_day to consider and show calender details.
|
||||||
|
|
||||||
2007-12-28 Matthias Clasen <mclasen@redhat.com>
|
2007-12-28 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* gtk/gtkcombobox.c: Introduce local priv variables to
|
* gtk/gtkcombobox.c: Introduce local priv variables to
|
||||||
|
@ -255,6 +255,7 @@ struct _GtkCalendarPrivate
|
|||||||
guint arrow_width;
|
guint arrow_width;
|
||||||
guint max_month_width;
|
guint max_month_width;
|
||||||
guint max_year_width;
|
guint max_year_width;
|
||||||
|
guint max_detail_height;
|
||||||
|
|
||||||
guint day_width;
|
guint day_width;
|
||||||
guint week_width;
|
guint week_width;
|
||||||
@ -1602,6 +1603,34 @@ gtk_calendar_unrealize (GtkWidget *widget)
|
|||||||
(* GTK_WIDGET_CLASS (gtk_calendar_parent_class)->unrealize) (widget);
|
(* GTK_WIDGET_CLASS (gtk_calendar_parent_class)->unrealize) (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static G_CONST_RETURN gchar*
|
||||||
|
gtk_calendar_get_detail (GtkCalendar *calendar,
|
||||||
|
gint row,
|
||||||
|
gint column)
|
||||||
|
{
|
||||||
|
GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
|
||||||
|
gint year, month;
|
||||||
|
|
||||||
|
year = calendar->year;
|
||||||
|
month = calendar->month + calendar->day_month[row][column] - MONTH_CURRENT;
|
||||||
|
|
||||||
|
if (month < 0)
|
||||||
|
{
|
||||||
|
month += 12;
|
||||||
|
year -= 1;
|
||||||
|
}
|
||||||
|
else if (month > 11)
|
||||||
|
{
|
||||||
|
month -= 12;
|
||||||
|
year += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return priv->detail_func (calendar,
|
||||||
|
year, month,
|
||||||
|
calendar->day[row][column],
|
||||||
|
priv->detail_func_user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************
|
/****************************************
|
||||||
* Size Request and Allocate *
|
* Size Request and Allocate *
|
||||||
@ -1617,7 +1646,7 @@ gtk_calendar_size_request (GtkWidget *widget,
|
|||||||
PangoRectangle logical_rect;
|
PangoRectangle logical_rect;
|
||||||
|
|
||||||
gint height;
|
gint height;
|
||||||
gint i;
|
gint i, r, c;
|
||||||
gint calendar_margin = CALENDAR_MARGIN;
|
gint calendar_margin = CALENDAR_MARGIN;
|
||||||
gint header_width, main_width;
|
gint header_width, main_width;
|
||||||
gint max_header_height = 0;
|
gint max_header_height = 0;
|
||||||
@ -1700,8 +1729,6 @@ gtk_calendar_size_request (GtkWidget *widget,
|
|||||||
priv->max_day_char_descent = MAX (priv->max_day_char_descent,
|
priv->max_day_char_descent = MAX (priv->max_day_char_descent,
|
||||||
PANGO_DESCENT (logical_rect));
|
PANGO_DESCENT (logical_rect));
|
||||||
}
|
}
|
||||||
/* We add one to max_day_char_width to be able to make the marked day "bold" */
|
|
||||||
priv->max_day_char_width = priv->min_day_width / 2 + 1;
|
|
||||||
|
|
||||||
priv->max_label_char_ascent = 0;
|
priv->max_label_char_ascent = 0;
|
||||||
priv->max_label_char_descent = 0;
|
priv->max_label_char_descent = 0;
|
||||||
@ -1730,6 +1757,77 @@ gtk_calendar_size_request (GtkWidget *widget,
|
|||||||
logical_rect.width / 2);
|
logical_rect.width / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calculate detail extents. Do this as late as possible since
|
||||||
|
* pango_layout_set_markup is called which alters font settings. */
|
||||||
|
priv->max_detail_height = 0;
|
||||||
|
|
||||||
|
if (priv->detail_func)
|
||||||
|
{
|
||||||
|
gchar *markup, *tail;
|
||||||
|
|
||||||
|
if (priv->detail_width_chars || priv->detail_height_rows)
|
||||||
|
{
|
||||||
|
gint rows = MAX (1, priv->detail_height_rows) - 1;
|
||||||
|
gsize len = priv->detail_width_chars + rows + 16;
|
||||||
|
|
||||||
|
markup = tail = g_alloca (len);
|
||||||
|
|
||||||
|
memcpy (tail, "<small>", 7);
|
||||||
|
tail += 7;
|
||||||
|
|
||||||
|
memset (tail, 'm', priv->detail_width_chars);
|
||||||
|
tail += priv->detail_width_chars;
|
||||||
|
|
||||||
|
memset (tail, '\n', rows);
|
||||||
|
tail += rows;
|
||||||
|
|
||||||
|
memcpy (tail, "</small>", 9);
|
||||||
|
tail += 9;
|
||||||
|
|
||||||
|
g_assert (len == (tail - markup));
|
||||||
|
|
||||||
|
pango_layout_set_markup (layout, markup, -1);
|
||||||
|
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||||||
|
|
||||||
|
|
||||||
|
if (priv->detail_width_chars)
|
||||||
|
priv->min_day_width = MAX (priv->min_day_width, logical_rect.width);
|
||||||
|
if (priv->detail_height_rows)
|
||||||
|
priv->max_detail_height = MAX (priv->max_detail_height, logical_rect.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!priv->detail_width_chars || !priv->detail_height_rows)
|
||||||
|
for (r = 0; r < 6; r++)
|
||||||
|
for (c = 0; c < 7; c++)
|
||||||
|
{
|
||||||
|
const gchar *detail = gtk_calendar_get_detail (calendar, r, c);
|
||||||
|
|
||||||
|
if (detail)
|
||||||
|
{
|
||||||
|
markup = g_strconcat ("<small>", detail, "</small>", NULL);
|
||||||
|
pango_layout_set_markup (layout, markup, -1);
|
||||||
|
|
||||||
|
if (priv->detail_width_chars)
|
||||||
|
{
|
||||||
|
pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
|
||||||
|
pango_layout_set_width (layout, PANGO_SCALE * priv->min_day_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||||||
|
|
||||||
|
if (!priv->detail_width_chars)
|
||||||
|
priv->min_day_width = MAX (priv->min_day_width, logical_rect.width);
|
||||||
|
if (!priv->detail_height_rows)
|
||||||
|
priv->max_detail_height = MAX (priv->max_detail_height, logical_rect.height);
|
||||||
|
|
||||||
|
g_free (markup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We add one to max_day_char_width to be able to make the marked day "bold" */
|
||||||
|
priv->max_day_char_width = priv->min_day_width / 2 + 1;
|
||||||
|
|
||||||
main_width = (7 * (priv->min_day_width + (focus_padding + focus_width) * 2) + (DAY_XSEP * 6) + CALENDAR_MARGIN * 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
|
||||||
? priv->max_week_char_width * 2 + (focus_padding + focus_width) * 2 + CALENDAR_XSEP * 2
|
? priv->max_week_char_width * 2 + (focus_padding + focus_width) * 2 + CALENDAR_XSEP * 2
|
||||||
@ -1766,6 +1864,7 @@ gtk_calendar_size_request (GtkWidget *widget,
|
|||||||
priv->main_h = (CALENDAR_MARGIN + calendar_margin
|
priv->main_h = (CALENDAR_MARGIN + calendar_margin
|
||||||
+ 6 * (priv->max_day_char_ascent
|
+ 6 * (priv->max_day_char_ascent
|
||||||
+ priv->max_day_char_descent
|
+ priv->max_day_char_descent
|
||||||
|
+ priv->max_detail_height
|
||||||
+ 2 * (focus_padding + focus_width))
|
+ 2 * (focus_padding + focus_width))
|
||||||
+ DAY_YSEP * 5);
|
+ DAY_YSEP * 5);
|
||||||
|
|
||||||
@ -2199,6 +2298,14 @@ calendar_invalidate_day (GtkCalendar *calendar,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_color_attribute (PangoAttribute *attribute,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
return (attribute->klass->type == PANGO_ATTR_FOREGROUND ||
|
||||||
|
attribute->klass->type == PANGO_ATTR_BACKGROUND);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calendar_paint_day (GtkCalendar *calendar,
|
calendar_paint_day (GtkCalendar *calendar,
|
||||||
gint row,
|
gint row,
|
||||||
@ -2208,6 +2315,7 @@ calendar_paint_day (GtkCalendar *calendar,
|
|||||||
GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
|
GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
GdkColor *text_color;
|
GdkColor *text_color;
|
||||||
|
const gchar *detail;
|
||||||
gchar buffer[32];
|
gchar buffer[32];
|
||||||
gint day;
|
gint day;
|
||||||
gint x_loc, y_loc;
|
gint x_loc, y_loc;
|
||||||
@ -2269,12 +2377,20 @@ calendar_paint_day (GtkCalendar *calendar,
|
|||||||
* too.
|
* too.
|
||||||
*/
|
*/
|
||||||
g_snprintf (buffer, sizeof (buffer), Q_("calendar:day:digits|%d"), day);
|
g_snprintf (buffer, sizeof (buffer), Q_("calendar:day:digits|%d"), day);
|
||||||
|
|
||||||
|
/* Get extra information to show, if any: */
|
||||||
|
|
||||||
|
if (priv->detail_func)
|
||||||
|
detail = gtk_calendar_get_detail (calendar, row, col);
|
||||||
|
else
|
||||||
|
detail = NULL;
|
||||||
|
|
||||||
layout = gtk_widget_create_pango_layout (widget, buffer);
|
layout = gtk_widget_create_pango_layout (widget, buffer);
|
||||||
|
pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
|
||||||
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
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 = day_rect.x + (day_rect.width - logical_rect.width) / 2;
|
||||||
x_loc -= logical_rect.width;
|
y_loc = day_rect.y;
|
||||||
y_loc = day_rect.y + (day_rect.height - logical_rect.height) / 2;
|
|
||||||
|
|
||||||
gdk_cairo_set_source_color (cr, text_color);
|
gdk_cairo_set_source_color (cr, text_color);
|
||||||
cairo_move_to (cr, x_loc, y_loc);
|
cairo_move_to (cr, x_loc, y_loc);
|
||||||
@ -2287,6 +2403,65 @@ calendar_paint_day (GtkCalendar *calendar,
|
|||||||
pango_cairo_show_layout (cr, layout);
|
pango_cairo_show_layout (cr, layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
y_loc += priv->max_day_char_descent;
|
||||||
|
|
||||||
|
if (priv->detail_func)
|
||||||
|
{
|
||||||
|
cairo_set_line_width (cr, 1);
|
||||||
|
cairo_move_to (cr, day_rect.x + 1, y_loc + 0.5);
|
||||||
|
cairo_line_to (cr, day_rect.x + day_rect.width - 1, y_loc + 0.5);
|
||||||
|
cairo_stroke (cr);
|
||||||
|
|
||||||
|
y_loc += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (detail)
|
||||||
|
{
|
||||||
|
gint i, n_lines;
|
||||||
|
|
||||||
|
gchar *markup = g_strconcat ("<small>", detail, "</small>", NULL);
|
||||||
|
pango_layout_set_markup (layout, markup, -1);
|
||||||
|
g_free (markup);
|
||||||
|
|
||||||
|
if (day == calendar->selected_day)
|
||||||
|
{
|
||||||
|
/* Stripping colors as they conflict with selection marking. */
|
||||||
|
|
||||||
|
PangoAttrList *attrs = pango_layout_get_attributes (layout);
|
||||||
|
PangoAttrList *colors = NULL;
|
||||||
|
|
||||||
|
if (attrs)
|
||||||
|
colors = pango_attr_list_filter (attrs, is_color_attribute, NULL);
|
||||||
|
if (colors)
|
||||||
|
pango_attr_list_unref (colors);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->detail_width_chars)
|
||||||
|
{
|
||||||
|
pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
|
||||||
|
pango_layout_set_width (layout, PANGO_SCALE * priv->min_day_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
n_lines = pango_layout_get_line_count (layout);
|
||||||
|
|
||||||
|
if (priv->detail_height_rows)
|
||||||
|
n_lines = MIN (n_lines, priv->detail_height_rows);
|
||||||
|
|
||||||
|
for (i = 0; i < n_lines; ++i)
|
||||||
|
{
|
||||||
|
PangoLayoutLine *line = pango_layout_get_line_readonly (layout, i);
|
||||||
|
pango_layout_line_get_pixel_extents (line, NULL, &logical_rect);
|
||||||
|
|
||||||
|
x_loc = day_rect.x + (day_rect.width - logical_rect.width) / 2;
|
||||||
|
y_loc += PANGO_ASCENT (logical_rect);
|
||||||
|
|
||||||
|
cairo_move_to (cr, x_loc, y_loc);
|
||||||
|
pango_cairo_show_layout_line (cr, line);
|
||||||
|
|
||||||
|
y_loc += PANGO_DESCENT (logical_rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (GTK_WIDGET_HAS_FOCUS (calendar)
|
if (GTK_WIDGET_HAS_FOCUS (calendar)
|
||||||
&& calendar->focus_row == row && calendar->focus_col == col)
|
&& calendar->focus_row == row && calendar->focus_col == col)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user