diff options
-rw-r--r-- | calendar/ChangeLog | 10 | ||||
-rw-r--r-- | calendar/gncal-day-view.c | 42 | ||||
-rw-r--r-- | calendar/gncal-full-day.c | 1 | ||||
-rw-r--r-- | calendar/gui/gncal-day-view.c | 42 | ||||
-rw-r--r-- | calendar/gui/gncal-full-day.c | 1 | ||||
-rw-r--r-- | calendar/gui/view-utils.c | 139 | ||||
-rw-r--r-- | calendar/view-utils.c | 139 |
7 files changed, 268 insertions, 106 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 78876acc1e..02a4efe075 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,13 @@ +1999-01-30 Miguel de Icaza <miguel@nuclecu.unam.mx> + + * view-utils.c (view_utils_draw_events): Improve this draw + routine. Now it can split the text in lines and fit as many + events as possible. + (nicetime): Return strings without spaces at the beginning. + + * gncal-day-view.c (gncal_day_view_expose): Move clip-clear + operation here. + 1999-01-29 Jason Tackaberry <tack@dok.org> * gncal-full-day.c (child_popup_menu): if the user clicks on an diff --git a/calendar/gncal-day-view.c b/calendar/gncal-day-view.c index 85d61292f1..1fc59c6fef 100644 --- a/calendar/gncal-day-view.c +++ b/calendar/gncal-day-view.c @@ -250,6 +250,7 @@ gncal_day_view_expose (GtkWidget *widget, GdkEventExpose *event) GdkRectangle rect, dest; GdkFont *font; int str_width; + GdkGC *gc; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GNCAL_IS_DAY_VIEW (widget), FALSE); @@ -258,6 +259,7 @@ gncal_day_view_expose (GtkWidget *widget, GdkEventExpose *event) if (!GTK_WIDGET_DRAWABLE (widget)) return FALSE; + gc = widget->style->fg_gc [GTK_STATE_NORMAL]; dview = GNCAL_DAY_VIEW (widget); x1 = widget->style->klass->xthickness; @@ -300,18 +302,16 @@ gncal_day_view_expose (GtkWidget *widget, GdkEventExpose *event) dest.width -= 2 * TEXT_BORDER; dest.height -= 2 * TEXT_BORDER; - gdk_gc_set_clip_rectangle (widget->style->fg_gc[GTK_STATE_NORMAL], &dest); + gdk_gc_set_clip_rectangle (gc, &dest); str_width = gdk_string_width (font, dview->day_str); - gdk_draw_string (widget->window, - font, - widget->style->fg_gc[GTK_STATE_NORMAL], + gdk_draw_string (widget->window, font, gc, dest.x + (dest.width - str_width) / 2, dest.y + font->ascent, dview->day_str); - gdk_gc_set_clip_rectangle (widget->style->fg_gc[GTK_STATE_NORMAL], NULL); + gdk_gc_set_clip_rectangle (gc, NULL); } /* Division line */ @@ -325,21 +325,25 @@ gncal_day_view_expose (GtkWidget *widget, GdkEventExpose *event) /* Text */ - rect.x = x1 + TEXT_BORDER; - rect.y = y1 + 3 * TEXT_BORDER + font->ascent + font->descent + widget->style->klass->ythickness; - rect.width = width - 2 * TEXT_BORDER; - rect.height = height - (rect.y - y1) - TEXT_BORDER; - - if (gdk_rectangle_intersect (&rect, &event->area, &dest)) - view_utils_draw_events (widget, - widget->window, - widget->style->fg_gc[GTK_STATE_NORMAL], - &rect, - VIEW_UTILS_DRAW_END | VIEW_UTILS_DRAW_SPLIT, - dview->events, - dview->lower, - dview->upper); + if (dview->events != NULL){ + rect.x = x1 + TEXT_BORDER; + rect.y = y1 + 3 * TEXT_BORDER + + font->ascent + font->descent + + widget->style->klass->ythickness; + rect.width = width - 2 * TEXT_BORDER; + rect.height = height - (rect.y - y1) - TEXT_BORDER; + + if (gdk_rectangle_intersect (&rect, &event->area, &dest)) + view_utils_draw_events ( + widget, widget->window, gc, + &rect, + VIEW_UTILS_DRAW_END | VIEW_UTILS_DRAW_SPLIT, + dview->events, + dview->lower, + dview->upper); + } + gdk_gc_set_clip_rectangle (gc, NULL); return FALSE; } diff --git a/calendar/gncal-full-day.c b/calendar/gncal-full-day.c index fd1b06877b..c33cb2ed31 100644 --- a/calendar/gncal-full-day.c +++ b/calendar/gncal-full-day.c @@ -750,7 +750,6 @@ child_new (GncalFullDay *fullday, time_t start, time_t end, iCalObject *ico) static void squick (GtkWidget *widget, gpointer data) { - printf ("destroyed!\n"); } static void diff --git a/calendar/gui/gncal-day-view.c b/calendar/gui/gncal-day-view.c index 85d61292f1..1fc59c6fef 100644 --- a/calendar/gui/gncal-day-view.c +++ b/calendar/gui/gncal-day-view.c @@ -250,6 +250,7 @@ gncal_day_view_expose (GtkWidget *widget, GdkEventExpose *event) GdkRectangle rect, dest; GdkFont *font; int str_width; + GdkGC *gc; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GNCAL_IS_DAY_VIEW (widget), FALSE); @@ -258,6 +259,7 @@ gncal_day_view_expose (GtkWidget *widget, GdkEventExpose *event) if (!GTK_WIDGET_DRAWABLE (widget)) return FALSE; + gc = widget->style->fg_gc [GTK_STATE_NORMAL]; dview = GNCAL_DAY_VIEW (widget); x1 = widget->style->klass->xthickness; @@ -300,18 +302,16 @@ gncal_day_view_expose (GtkWidget *widget, GdkEventExpose *event) dest.width -= 2 * TEXT_BORDER; dest.height -= 2 * TEXT_BORDER; - gdk_gc_set_clip_rectangle (widget->style->fg_gc[GTK_STATE_NORMAL], &dest); + gdk_gc_set_clip_rectangle (gc, &dest); str_width = gdk_string_width (font, dview->day_str); - gdk_draw_string (widget->window, - font, - widget->style->fg_gc[GTK_STATE_NORMAL], + gdk_draw_string (widget->window, font, gc, dest.x + (dest.width - str_width) / 2, dest.y + font->ascent, dview->day_str); - gdk_gc_set_clip_rectangle (widget->style->fg_gc[GTK_STATE_NORMAL], NULL); + gdk_gc_set_clip_rectangle (gc, NULL); } /* Division line */ @@ -325,21 +325,25 @@ gncal_day_view_expose (GtkWidget *widget, GdkEventExpose *event) /* Text */ - rect.x = x1 + TEXT_BORDER; - rect.y = y1 + 3 * TEXT_BORDER + font->ascent + font->descent + widget->style->klass->ythickness; - rect.width = width - 2 * TEXT_BORDER; - rect.height = height - (rect.y - y1) - TEXT_BORDER; - - if (gdk_rectangle_intersect (&rect, &event->area, &dest)) - view_utils_draw_events (widget, - widget->window, - widget->style->fg_gc[GTK_STATE_NORMAL], - &rect, - VIEW_UTILS_DRAW_END | VIEW_UTILS_DRAW_SPLIT, - dview->events, - dview->lower, - dview->upper); + if (dview->events != NULL){ + rect.x = x1 + TEXT_BORDER; + rect.y = y1 + 3 * TEXT_BORDER + + font->ascent + font->descent + + widget->style->klass->ythickness; + rect.width = width - 2 * TEXT_BORDER; + rect.height = height - (rect.y - y1) - TEXT_BORDER; + + if (gdk_rectangle_intersect (&rect, &event->area, &dest)) + view_utils_draw_events ( + widget, widget->window, gc, + &rect, + VIEW_UTILS_DRAW_END | VIEW_UTILS_DRAW_SPLIT, + dview->events, + dview->lower, + dview->upper); + } + gdk_gc_set_clip_rectangle (gc, NULL); return FALSE; } diff --git a/calendar/gui/gncal-full-day.c b/calendar/gui/gncal-full-day.c index fd1b06877b..c33cb2ed31 100644 --- a/calendar/gui/gncal-full-day.c +++ b/calendar/gui/gncal-full-day.c @@ -750,7 +750,6 @@ child_new (GncalFullDay *fullday, time_t start, time_t end, iCalObject *ico) static void squick (GtkWidget *widget, gpointer data) { - printf ("destroyed!\n"); } static void diff --git a/calendar/gui/view-utils.c b/calendar/gui/view-utils.c index 1571c2f31e..487bfaf973 100644 --- a/calendar/gui/view-utils.c +++ b/calendar/gui/view-utils.c @@ -8,6 +8,7 @@ #include <string.h> #include "view-utils.h" +#include <libgnomeui/gnome-icon-text.h> int am_pm_flag = 0; @@ -15,7 +16,8 @@ static char * nicetime (struct tm *tm) { static char buf [20]; - + char *p = buf; + if (am_pm_flag){ if (tm->tm_min) strftime (buf, sizeof (buf), "%l:%M%p", tm); @@ -27,34 +29,48 @@ nicetime (struct tm *tm) else strftime (buf, sizeof (buf), "%k", tm); } - return buf; + while (*p == ' ') + p++; + return p; } +typedef struct { + GnomeIconTextInfo *layout; + int lines; + int assigned_lines; +} line_info_t; + void view_utils_draw_events (GtkWidget *widget, GdkWindow *window, GdkGC *gc, GdkRectangle *area, int flags, GList *events, time_t start, time_t end) { + GdkFont *font = widget->style->font; int font_height; - int x, y, max_y; - char buf [40]; - struct tm tm_start, tm_end; - char *str; - iCalObject *ico; + int y, max_y, items, i, need_more, nlines, base, extra; GList *list; + line_info_t *lines; - gdk_gc_set_clip_rectangle (gc, area); - - font_height = widget->style->font->ascent + widget->style->font->descent; - + if (events == NULL) + return; + + items = g_list_length (events); + lines = g_new0 (line_info_t, items); + + font_height = font->ascent + font->descent; max_y = area->y + area->height - font_height * ((flags & VIEW_UTILS_DRAW_SPLIT) ? 2 : 1); - for (y = area->y, list = events; (y < max_y) && list; y += font_height, list = list->next) { + /* + * Layout all the lines, measure the space needs + */ + for (i = 0, list = events; list; list = list->next, i++){ CalendarObject *co = list->data; - ico = co->ico; + struct tm tm_start, tm_end; + iCalObject *ico = co->ico; + char buf [60]; + char *full_text; tm_start = *localtime (&co->ev_start); tm_end = *localtime (&co->ev_end); - str = ico->summary; strcpy (buf, nicetime (&tm_start)); @@ -62,27 +78,84 @@ view_utils_draw_events (GtkWidget *widget, GdkWindow *window, GdkGC *gc, GdkRect strcat (buf, "-"); strcat (buf, nicetime (&tm_end)); } - gdk_draw_string (window, - widget->style->font, - gc, - area->x, - y + widget->style->font->ascent, - buf); - - if (flags & VIEW_UTILS_DRAW_SPLIT) { + + full_text = g_strconcat (buf, ": ", ico->summary, NULL); + lines [i].layout = gnome_icon_layout_text ( + font, full_text, "\n -,.;:=#", area->width, TRUE); + lines [i].lines = g_list_length (lines [i].layout->rows); + + g_free (full_text); + } + + /* + * Compute how many lines we will give to each row + */ + nlines = 1 + max_y / font_height; + base = nlines / items; + extra = nlines % items; + need_more = 0; + + for (i = 0; i < items; i++){ + if (lines [i].lines <= base){ + extra += base - lines [i].lines; + lines [i].assigned_lines = lines [i].lines; + } else { + need_more++; + lines [i].assigned_lines = base; + } + } + + /* + * use any extra space + */ + while (need_more && extra > 0){ + need_more = 0; + + for (i = 0; i < items; i++){ + if (lines [i].lines > lines [i].assigned_lines){ + lines [i].assigned_lines++; + extra--; + } + + if (extra == 0) + break; + + if (lines [i].lines > lines [i].assigned_lines) + need_more = 1; + } + } + + /* + * Draw the information + */ + gdk_gc_set_clip_rectangle (gc, area); + y = area->y; + for (i = 0; i < items; i++){ + int line; + + list = lines [i].layout->rows; + + for (line = 0; line < lines [i].assigned_lines; line++){ + GnomeIconTextInfoRow *row = list->data; + + list = list->next; + + if (row) + gdk_draw_string ( + window, font, gc, + area->x, y + font->ascent, + row->text); y += font_height; - x = widget->style->font->ascent; /* some indentation */ - } else - x = gdk_string_width (widget->style->font, buf); - - gdk_draw_string (window, - widget->style->font, - gc, - x, - y + widget->style->font->ascent, - str); + } } - gdk_gc_set_clip_rectangle (gc, NULL); + + /* + * Free resources. + */ + + for (i = 0; i < items; i++) + gnome_icon_text_info_free (lines [i].layout); + g_free (lines); } void diff --git a/calendar/view-utils.c b/calendar/view-utils.c index 1571c2f31e..487bfaf973 100644 --- a/calendar/view-utils.c +++ b/calendar/view-utils.c @@ -8,6 +8,7 @@ #include <string.h> #include "view-utils.h" +#include <libgnomeui/gnome-icon-text.h> int am_pm_flag = 0; @@ -15,7 +16,8 @@ static char * nicetime (struct tm *tm) { static char buf [20]; - + char *p = buf; + if (am_pm_flag){ if (tm->tm_min) strftime (buf, sizeof (buf), "%l:%M%p", tm); @@ -27,34 +29,48 @@ nicetime (struct tm *tm) else strftime (buf, sizeof (buf), "%k", tm); } - return buf; + while (*p == ' ') + p++; + return p; } +typedef struct { + GnomeIconTextInfo *layout; + int lines; + int assigned_lines; +} line_info_t; + void view_utils_draw_events (GtkWidget *widget, GdkWindow *window, GdkGC *gc, GdkRectangle *area, int flags, GList *events, time_t start, time_t end) { + GdkFont *font = widget->style->font; int font_height; - int x, y, max_y; - char buf [40]; - struct tm tm_start, tm_end; - char *str; - iCalObject *ico; + int y, max_y, items, i, need_more, nlines, base, extra; GList *list; + line_info_t *lines; - gdk_gc_set_clip_rectangle (gc, area); - - font_height = widget->style->font->ascent + widget->style->font->descent; - + if (events == NULL) + return; + + items = g_list_length (events); + lines = g_new0 (line_info_t, items); + + font_height = font->ascent + font->descent; max_y = area->y + area->height - font_height * ((flags & VIEW_UTILS_DRAW_SPLIT) ? 2 : 1); - for (y = area->y, list = events; (y < max_y) && list; y += font_height, list = list->next) { + /* + * Layout all the lines, measure the space needs + */ + for (i = 0, list = events; list; list = list->next, i++){ CalendarObject *co = list->data; - ico = co->ico; + struct tm tm_start, tm_end; + iCalObject *ico = co->ico; + char buf [60]; + char *full_text; tm_start = *localtime (&co->ev_start); tm_end = *localtime (&co->ev_end); - str = ico->summary; strcpy (buf, nicetime (&tm_start)); @@ -62,27 +78,84 @@ view_utils_draw_events (GtkWidget *widget, GdkWindow *window, GdkGC *gc, GdkRect strcat (buf, "-"); strcat (buf, nicetime (&tm_end)); } - gdk_draw_string (window, - widget->style->font, - gc, - area->x, - y + widget->style->font->ascent, - buf); - - if (flags & VIEW_UTILS_DRAW_SPLIT) { + + full_text = g_strconcat (buf, ": ", ico->summary, NULL); + lines [i].layout = gnome_icon_layout_text ( + font, full_text, "\n -,.;:=#", area->width, TRUE); + lines [i].lines = g_list_length (lines [i].layout->rows); + + g_free (full_text); + } + + /* + * Compute how many lines we will give to each row + */ + nlines = 1 + max_y / font_height; + base = nlines / items; + extra = nlines % items; + need_more = 0; + + for (i = 0; i < items; i++){ + if (lines [i].lines <= base){ + extra += base - lines [i].lines; + lines [i].assigned_lines = lines [i].lines; + } else { + need_more++; + lines [i].assigned_lines = base; + } + } + + /* + * use any extra space + */ + while (need_more && extra > 0){ + need_more = 0; + + for (i = 0; i < items; i++){ + if (lines [i].lines > lines [i].assigned_lines){ + lines [i].assigned_lines++; + extra--; + } + + if (extra == 0) + break; + + if (lines [i].lines > lines [i].assigned_lines) + need_more = 1; + } + } + + /* + * Draw the information + */ + gdk_gc_set_clip_rectangle (gc, area); + y = area->y; + for (i = 0; i < items; i++){ + int line; + + list = lines [i].layout->rows; + + for (line = 0; line < lines [i].assigned_lines; line++){ + GnomeIconTextInfoRow *row = list->data; + + list = list->next; + + if (row) + gdk_draw_string ( + window, font, gc, + area->x, y + font->ascent, + row->text); y += font_height; - x = widget->style->font->ascent; /* some indentation */ - } else - x = gdk_string_width (widget->style->font, buf); - - gdk_draw_string (window, - widget->style->font, - gc, - x, - y + widget->style->font->ascent, - str); + } } - gdk_gc_set_clip_rectangle (gc, NULL); + + /* + * Free resources. + */ + + for (i = 0; i < items; i++) + gnome_icon_text_info_free (lines [i].layout); + g_free (lines); } void |