aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calendar/ChangeLog10
-rw-r--r--calendar/gncal-day-view.c42
-rw-r--r--calendar/gncal-full-day.c1
-rw-r--r--calendar/gui/gncal-day-view.c42
-rw-r--r--calendar/gui/gncal-full-day.c1
-rw-r--r--calendar/gui/view-utils.c139
-rw-r--r--calendar/view-utils.c139
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