diff options
Diffstat (limited to 'calendar')
-rw-r--r-- | calendar/ChangeLog | 6 | ||||
-rw-r--r-- | calendar/gncal-full-day.c | 143 | ||||
-rw-r--r-- | calendar/gui/gncal-full-day.c | 143 | ||||
-rw-r--r-- | calendar/gui/test.vcf | 8 | ||||
-rw-r--r-- | calendar/test.vcf | 8 |
5 files changed, 234 insertions, 74 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index d8f0e9c7f2..cd5a1c5bfa 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,9 @@ +1998-04-11 Federico Mena Quintero <federico@nuclecu.unam.mx> + + * gncal-full-day.c (recompute_motion): Now we support selecting a + range in the main window (by clicking+dragging). It flickers + horribly and is not perfect, but it is a start. + 1998-04-09 Federico Mena Quintero <federico@nuclecu.unam.mx> * gncal-full-day.c: #include <string.h> diff --git a/calendar/gncal-full-day.c b/calendar/gncal-full-day.c index a03d0a0811..acf937f14f 100644 --- a/calendar/gncal-full-day.c +++ b/calendar/gncal-full-day.c @@ -16,6 +16,7 @@ #define HANDLE_SIZE 3 #define MIN_WIDTH 200 #define XOR_RECT_WIDTH 2 +#define UNSELECT_TIMEOUT 150 /* ms */ typedef struct { @@ -46,6 +47,7 @@ struct drag_info { Child *child; int start_row; int rows_used; + guint32 click_time; }; @@ -750,7 +752,8 @@ static void paint_back (GncalFullDay *fullday, GdkRectangle *area) { GtkWidget *widget; - GdkRectangle rect, dest; + GdkRectangle rect, dest, aarea; + struct drag_info *di; int x1, y1, width, height; int labels_width, division_x; int rows, row_height; @@ -760,6 +763,15 @@ paint_back (GncalFullDay *fullday, GdkRectangle *area) widget = GTK_WIDGET (fullday); + if (!area) { + area = &aarea; + + area->x = 0; + area->y = 0; + area->width = widget->allocation.width; + area->height = widget->allocation.height; + } + x1 = widget->style->klass->xthickness; y1 = widget->style->klass->ythickness; width = widget->allocation.width - 2 * x1; @@ -787,6 +799,28 @@ paint_back (GncalFullDay *fullday, GdkRectangle *area) dest.x, dest.y, dest.width, dest.height); + /* Selected region */ + + di = fullday->drag_info; + + get_tm_range (fullday, fullday->lower, fullday->upper, &tm, NULL, NULL, &rows); + + row_height = calc_row_height (fullday); + + if (di->rows_used != 0) { + rect.x = x1; + rect.y = y1 + row_height * di->start_row; + rect.width = width; + rect.height = row_height * di->rows_used; + + if (gdk_rectangle_intersect (&rect, area, &dest)) + gdk_draw_rectangle (widget->window, + widget->style->bg_gc[GTK_STATE_SELECTED], + TRUE, + dest.x, dest.y, + dest.width, dest.height); + } + /* Vertical division */ division_x = x1 + 2 * TEXT_BORDER + labels_width; @@ -799,10 +833,6 @@ paint_back (GncalFullDay *fullday, GdkRectangle *area) /* Horizontal divisions */ - get_tm_range (fullday, fullday->lower, fullday->upper, &tm, NULL, NULL, &rows); - - row_height = calc_row_height (fullday); - y = y1 + row_height - 1; for (i = 1; i < rows; i++) { @@ -818,6 +848,9 @@ paint_back (GncalFullDay *fullday, GdkRectangle *area) y = y1 + ((row_height - 1) - (widget->style->font->ascent + widget->style->font->descent)) / 2; + rect.x = x1; + rect.y = y1; + rect.width = 2 * TEXT_BORDER + labels_width; rect.height = row_height - 1; for (i = 0; i < rows; i++) { @@ -973,12 +1006,15 @@ draw_xor_rect (GncalFullDay *fullday) struct drag_info *di; int i; int row_height; + int ythickness; widget = GTK_WIDGET (fullday); gdk_gc_set_function (widget->style->white_gc, GDK_INVERT); gdk_gc_set_subwindow (widget->style->white_gc, GDK_INCLUDE_INFERIORS); + ythickness = widget->style->klass->ythickness; + di = fullday->drag_info; row_height = calc_row_height (fullday); @@ -988,7 +1024,7 @@ draw_xor_rect (GncalFullDay *fullday) widget->style->white_gc, FALSE, di->child->x + i, - di->start_row * row_height + i, + di->start_row * row_height + ythickness + i, di->child->width - 2 * i - 1, di->rows_used * row_height - 2 * i - 2); @@ -1037,9 +1073,6 @@ gncal_full_day_button_press (GtkWidget *widget, GdkEventButton *event) Child *child; struct drag_info *di; gint y; - int xthickness, ythickness; - int width, height; - int xpos, ypos; int row_height; g_return_val_if_fail (widget != NULL, FALSE); @@ -1054,24 +1087,26 @@ gncal_full_day_button_press (GtkWidget *widget, GdkEventButton *event) if (!GTK_WIDGET_HAS_FOCUS (widget)) gtk_widget_grab_focus (widget); - xthickness = widget->style->klass->xthickness; - ythickness = widget->style->klass->ythickness; + /* Prepare for drag */ - width = widget->allocation.width; - height = widget->allocation.height; + di = fullday->drag_info; - xpos = event->x - xthickness; - ypos = event->y - ythickness; + di->drag_mode = DRAG_SELECT; - if (!((xpos >= 0) && (xpos < (width - 2 * xthickness)) - && (ypos >= 0) && (ypos < (height - 2 * ythickness)))) - return FALSE; + di->start_row = get_row_from_y (fullday, event->y, FALSE); + di->rows_used = 1; - /* Prepare for drag */ + di->click_time = event->time; - di = fullday->drag_info; + gdk_pointer_grab (widget->window, FALSE, + (GDK_BUTTON_MOTION_MASK + | GDK_POINTER_MOTION_HINT_MASK + | GDK_BUTTON_RELEASE_MASK), + NULL, + NULL, + event->time); - + paint_back (fullday, NULL); } else { /* Clicked on a child? */ @@ -1209,17 +1244,44 @@ gncal_full_day_button_release (GtkWidget *widget, GdkEventButton *event) di = fullday->drag_info; - if (!di->child || (event->window != di->child->window)) + gtk_widget_get_pointer (widget, NULL, &y); + + switch (di->drag_mode) { + case DRAG_NONE: return FALSE; - gtk_widget_get_pointer (widget, NULL, &y); + case DRAG_SELECT: + if ((event->time - di->click_time) < UNSELECT_TIMEOUT) + di->rows_used = 0; + else + recompute_motion (fullday, y); + + gdk_pointer_ungrab (event->time); + + paint_back (fullday, NULL); + + break; + + case DRAG_MOVE: + case DRAG_SIZE: + draw_xor_rect (fullday); + recompute_motion (fullday, y); + gdk_pointer_ungrab (event->time); + + update_from_drag_info (fullday); + + di->rows_used = 0; + + break; - draw_xor_rect (fullday); - recompute_motion (fullday, y); - gdk_pointer_ungrab (event->time); + default: + g_assert_not_reached (); + } - update_from_drag_info (fullday); + if (!di->child || (event->window != di->child->window)) + return FALSE; + di->drag_mode = DRAG_NONE; di->child = NULL; return FALSE; @@ -1239,14 +1301,29 @@ gncal_full_day_motion (GtkWidget *widget, GdkEventMotion *event) fullday = GNCAL_FULL_DAY (widget); di = fullday->drag_info; - if (!di->child || (event->window != di->child->window)) - return FALSE; - gtk_widget_get_pointer (widget, NULL, &y); - draw_xor_rect (fullday); - recompute_motion (fullday, y); - draw_xor_rect (fullday); + switch (di->drag_mode) { + case DRAG_NONE: + break; + + case DRAG_SELECT: + recompute_motion (fullday, y); + paint_back (fullday, NULL); + + break; + + case DRAG_MOVE: + case DRAG_SIZE: + draw_xor_rect (fullday); + recompute_motion (fullday, y); + draw_xor_rect (fullday); + + break; + + default: + g_assert_not_reached (); + } return FALSE; } diff --git a/calendar/gui/gncal-full-day.c b/calendar/gui/gncal-full-day.c index a03d0a0811..acf937f14f 100644 --- a/calendar/gui/gncal-full-day.c +++ b/calendar/gui/gncal-full-day.c @@ -16,6 +16,7 @@ #define HANDLE_SIZE 3 #define MIN_WIDTH 200 #define XOR_RECT_WIDTH 2 +#define UNSELECT_TIMEOUT 150 /* ms */ typedef struct { @@ -46,6 +47,7 @@ struct drag_info { Child *child; int start_row; int rows_used; + guint32 click_time; }; @@ -750,7 +752,8 @@ static void paint_back (GncalFullDay *fullday, GdkRectangle *area) { GtkWidget *widget; - GdkRectangle rect, dest; + GdkRectangle rect, dest, aarea; + struct drag_info *di; int x1, y1, width, height; int labels_width, division_x; int rows, row_height; @@ -760,6 +763,15 @@ paint_back (GncalFullDay *fullday, GdkRectangle *area) widget = GTK_WIDGET (fullday); + if (!area) { + area = &aarea; + + area->x = 0; + area->y = 0; + area->width = widget->allocation.width; + area->height = widget->allocation.height; + } + x1 = widget->style->klass->xthickness; y1 = widget->style->klass->ythickness; width = widget->allocation.width - 2 * x1; @@ -787,6 +799,28 @@ paint_back (GncalFullDay *fullday, GdkRectangle *area) dest.x, dest.y, dest.width, dest.height); + /* Selected region */ + + di = fullday->drag_info; + + get_tm_range (fullday, fullday->lower, fullday->upper, &tm, NULL, NULL, &rows); + + row_height = calc_row_height (fullday); + + if (di->rows_used != 0) { + rect.x = x1; + rect.y = y1 + row_height * di->start_row; + rect.width = width; + rect.height = row_height * di->rows_used; + + if (gdk_rectangle_intersect (&rect, area, &dest)) + gdk_draw_rectangle (widget->window, + widget->style->bg_gc[GTK_STATE_SELECTED], + TRUE, + dest.x, dest.y, + dest.width, dest.height); + } + /* Vertical division */ division_x = x1 + 2 * TEXT_BORDER + labels_width; @@ -799,10 +833,6 @@ paint_back (GncalFullDay *fullday, GdkRectangle *area) /* Horizontal divisions */ - get_tm_range (fullday, fullday->lower, fullday->upper, &tm, NULL, NULL, &rows); - - row_height = calc_row_height (fullday); - y = y1 + row_height - 1; for (i = 1; i < rows; i++) { @@ -818,6 +848,9 @@ paint_back (GncalFullDay *fullday, GdkRectangle *area) y = y1 + ((row_height - 1) - (widget->style->font->ascent + widget->style->font->descent)) / 2; + rect.x = x1; + rect.y = y1; + rect.width = 2 * TEXT_BORDER + labels_width; rect.height = row_height - 1; for (i = 0; i < rows; i++) { @@ -973,12 +1006,15 @@ draw_xor_rect (GncalFullDay *fullday) struct drag_info *di; int i; int row_height; + int ythickness; widget = GTK_WIDGET (fullday); gdk_gc_set_function (widget->style->white_gc, GDK_INVERT); gdk_gc_set_subwindow (widget->style->white_gc, GDK_INCLUDE_INFERIORS); + ythickness = widget->style->klass->ythickness; + di = fullday->drag_info; row_height = calc_row_height (fullday); @@ -988,7 +1024,7 @@ draw_xor_rect (GncalFullDay *fullday) widget->style->white_gc, FALSE, di->child->x + i, - di->start_row * row_height + i, + di->start_row * row_height + ythickness + i, di->child->width - 2 * i - 1, di->rows_used * row_height - 2 * i - 2); @@ -1037,9 +1073,6 @@ gncal_full_day_button_press (GtkWidget *widget, GdkEventButton *event) Child *child; struct drag_info *di; gint y; - int xthickness, ythickness; - int width, height; - int xpos, ypos; int row_height; g_return_val_if_fail (widget != NULL, FALSE); @@ -1054,24 +1087,26 @@ gncal_full_day_button_press (GtkWidget *widget, GdkEventButton *event) if (!GTK_WIDGET_HAS_FOCUS (widget)) gtk_widget_grab_focus (widget); - xthickness = widget->style->klass->xthickness; - ythickness = widget->style->klass->ythickness; + /* Prepare for drag */ - width = widget->allocation.width; - height = widget->allocation.height; + di = fullday->drag_info; - xpos = event->x - xthickness; - ypos = event->y - ythickness; + di->drag_mode = DRAG_SELECT; - if (!((xpos >= 0) && (xpos < (width - 2 * xthickness)) - && (ypos >= 0) && (ypos < (height - 2 * ythickness)))) - return FALSE; + di->start_row = get_row_from_y (fullday, event->y, FALSE); + di->rows_used = 1; - /* Prepare for drag */ + di->click_time = event->time; - di = fullday->drag_info; + gdk_pointer_grab (widget->window, FALSE, + (GDK_BUTTON_MOTION_MASK + | GDK_POINTER_MOTION_HINT_MASK + | GDK_BUTTON_RELEASE_MASK), + NULL, + NULL, + event->time); - + paint_back (fullday, NULL); } else { /* Clicked on a child? */ @@ -1209,17 +1244,44 @@ gncal_full_day_button_release (GtkWidget *widget, GdkEventButton *event) di = fullday->drag_info; - if (!di->child || (event->window != di->child->window)) + gtk_widget_get_pointer (widget, NULL, &y); + + switch (di->drag_mode) { + case DRAG_NONE: return FALSE; - gtk_widget_get_pointer (widget, NULL, &y); + case DRAG_SELECT: + if ((event->time - di->click_time) < UNSELECT_TIMEOUT) + di->rows_used = 0; + else + recompute_motion (fullday, y); + + gdk_pointer_ungrab (event->time); + + paint_back (fullday, NULL); + + break; + + case DRAG_MOVE: + case DRAG_SIZE: + draw_xor_rect (fullday); + recompute_motion (fullday, y); + gdk_pointer_ungrab (event->time); + + update_from_drag_info (fullday); + + di->rows_used = 0; + + break; - draw_xor_rect (fullday); - recompute_motion (fullday, y); - gdk_pointer_ungrab (event->time); + default: + g_assert_not_reached (); + } - update_from_drag_info (fullday); + if (!di->child || (event->window != di->child->window)) + return FALSE; + di->drag_mode = DRAG_NONE; di->child = NULL; return FALSE; @@ -1239,14 +1301,29 @@ gncal_full_day_motion (GtkWidget *widget, GdkEventMotion *event) fullday = GNCAL_FULL_DAY (widget); di = fullday->drag_info; - if (!di->child || (event->window != di->child->window)) - return FALSE; - gtk_widget_get_pointer (widget, NULL, &y); - draw_xor_rect (fullday); - recompute_motion (fullday, y); - draw_xor_rect (fullday); + switch (di->drag_mode) { + case DRAG_NONE: + break; + + case DRAG_SELECT: + recompute_motion (fullday, y); + paint_back (fullday, NULL); + + break; + + case DRAG_MOVE: + case DRAG_SIZE: + draw_xor_rect (fullday); + recompute_motion (fullday, y); + draw_xor_rect (fullday); + + break; + + default: + g_assert_not_reached (); + } return FALSE; } diff --git a/calendar/gui/test.vcf b/calendar/gui/test.vcf index c85355b494..2217537486 100644 --- a/calendar/gui/test.vcf +++ b/calendar/gui/test.vcf @@ -8,8 +8,8 @@ DCREATED:19980402T023552 UID:KOrganizer - 1804289383 SEQUENCE:1 LAST-MODIFIED:19980330T225948 -DTSTART:19980409T003000 -DTEND:19980409T010000 +DTSTART:19980411T003000 +DTEND:19980411T010000 SUMMARY:asdfasdfasfasdfasdf STATUS:NEEDS ACTION CLASS:PUBLIC @@ -25,8 +25,8 @@ DCREATED:19980402T023558 UID:KOrganizer - 846930886 SEQUENCE:1 LAST-MODIFIED:19980402T023558 -DTSTART:19980409T140000 -DTEND:19980409T160000 +DTSTART:19980411T140000 +DTEND:19980411T160000 SUMMARY:asdfasfdasfasdfasfd STATUS:NEEDS ACTION CLASS:PUBLIC diff --git a/calendar/test.vcf b/calendar/test.vcf index c85355b494..2217537486 100644 --- a/calendar/test.vcf +++ b/calendar/test.vcf @@ -8,8 +8,8 @@ DCREATED:19980402T023552 UID:KOrganizer - 1804289383 SEQUENCE:1 LAST-MODIFIED:19980330T225948 -DTSTART:19980409T003000 -DTEND:19980409T010000 +DTSTART:19980411T003000 +DTEND:19980411T010000 SUMMARY:asdfasdfasfasdfasdf STATUS:NEEDS ACTION CLASS:PUBLIC @@ -25,8 +25,8 @@ DCREATED:19980402T023558 UID:KOrganizer - 846930886 SEQUENCE:1 LAST-MODIFIED:19980402T023558 -DTSTART:19980409T140000 -DTEND:19980409T160000 +DTSTART:19980411T140000 +DTEND:19980411T160000 SUMMARY:asdfasfdasfasdfasfd STATUS:NEEDS ACTION CLASS:PUBLIC |