/* Miscellaneous utility functions for the calendar view widgets
*
* Copyright (C) 1998 The Free Software Foundation
*
* Authors: Federico Mena <quartic@gimp.org>
* Miguel de Icaza <miguel@kernel.org>
*/
#include <string.h>
#include "view-utils.h"
#include <libgnomeui/gnome-icon-text.h>
int am_pm_flag = 0;
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);
else
strftime (buf, sizeof (buf), "%l%p", tm);
} else {
if (tm->tm_min)
strftime (buf, sizeof (buf), "%k:%M", tm);
else
strftime (buf, sizeof (buf), "%k", tm);
}
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 y, max_y, items, i, need_more, nlines, base, extra;
GList *list;
line_info_t *lines;
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);
/*
* Layout all the lines, measure the space needs
*/
for (i = 0, list = events; list; list = list->next, i++){
CalendarObject *co = list->data;
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);
strcpy (buf, nicetime (&tm_start));
if (flags & VIEW_UTILS_DRAW_END){
strcat (buf, "-");
strcat (buf, nicetime (&tm_end));
}
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;
}
}
/*
* Free resources.
*/
for (i = 0; i < items; i++)
gnome_icon_text_info_free (lines [i].layout);
g_free (lines);
}
void
view_utils_draw_textured_frame (GtkWidget *widget, GdkWindow *window, GdkRectangle *rect, GtkShadowType shadow)
{
int x, y;
int xthick, ythick;
GdkGC *light_gc, *dark_gc;
gdk_draw_rectangle (window,
widget->style->bg_gc[GTK_STATE_NORMAL],
TRUE,
rect->x, rect->y,
rect->width, rect->height);
light_gc = widget->style->light_gc[GTK_STATE_NORMAL];
dark_gc = widget->style->dark_gc[GTK_STATE_NORMAL];
xthick = widget->style->klass->xthickness;
ythick = widget->style->klass->ythickness;
gdk_gc_set_clip_rectangle (light_gc, rect);
gdk_gc_set_clip_rectangle (dark_gc, rect);
for (y = rect->y + ythick; y < (rect->y + rect->height - ythick); y += 3)
for (x = rect->x + xthick; x < (rect->x + rect->width - xthick); x += 6) {
gdk_draw_point (window, light_gc, x, y);
gdk_draw_point (window, dark_gc, x + 1, y + 1);
gdk_draw_point (window, light_gc, x + 3, y + 1);
gdk_draw_point (window, dark_gc, x + 4, y + 2);
}
gdk_gc_set_clip_rectangle (light_gc, NULL);
gdk_gc_set_clip_rectangle (dark_gc, NULL);
gtk_draw_shadow (widget->style, window,
GTK_STATE_NORMAL, shadow,
rect->x, rect->y,
rect->width, rect->height);
}