Added create-event overlay.
Added new-event mark to month-view. Added navigation arrows to month-view. Initially moved edit-event to a dialog.
This commit is contained in:
@@ -74,3 +74,6 @@ Debug*
|
||||
data/org.gnome.calendar.enums.xml
|
||||
src/gcal-enum-types.c
|
||||
src/gcal-enum-types.h
|
||||
src/gcal-marshalers.c
|
||||
src/gcal-marshalers.h
|
||||
src/stamp-gcal-marshalers.h
|
||||
|
||||
@@ -108,10 +108,9 @@ GtkOverlay > GtkButton {
|
||||
|
||||
.new-event-view {
|
||||
padding: 18px;
|
||||
border-radius: 3px;
|
||||
border: darkblue 1px solid;
|
||||
color: @theme_fg_color;
|
||||
border: darker(@borders) 1px solid;
|
||||
color: @theme_fg_color;
|
||||
background-color: @theme_bg_color;
|
||||
-GcalArrowContainer-arrow-size: 12px;
|
||||
-GcalArrowContainer-shadow-span: 6px;
|
||||
-GcalArrowContainer-shadow-span: 3px;
|
||||
}
|
||||
|
||||
+7
-6
@@ -1,16 +1,17 @@
|
||||
# List of source files containing translatable strings.
|
||||
|
||||
src/main.c
|
||||
src/gcal-application.c
|
||||
src/gcal-window.c
|
||||
src/gcal-toolbar.c
|
||||
src/gcal-month-view.c
|
||||
src/gcal-week-view.c
|
||||
src/gcal-event-view.c
|
||||
src/gcal-editable-date.c
|
||||
src/gcal-editable-reminder.c
|
||||
src/gcal-event-overlay.c
|
||||
src/gcal-event-view.c
|
||||
src/gcal-manager.c
|
||||
src/gcal-month-view.c
|
||||
src/gcal-toolbar.c
|
||||
src/gcal-utils.c
|
||||
src/gcal-week-view.c
|
||||
src/gcal-window.c
|
||||
src/main.c
|
||||
|
||||
data/gnome-calendar.desktop.in.in
|
||||
data/org.gnome.calendar.gschema.xml.in
|
||||
|
||||
@@ -25,6 +25,8 @@ gnome_calendar_SOURCES = \
|
||||
main.c \
|
||||
gcal-application.h \
|
||||
gcal-application.c \
|
||||
gcal-arrow-container.c \
|
||||
gcal-arrow-container.h \
|
||||
gcal-floating-container.c \
|
||||
gcal-floating-container.h \
|
||||
gcal-toolbar.h \
|
||||
@@ -41,6 +43,8 @@ gnome_calendar_SOURCES = \
|
||||
gcal-event-widget.h \
|
||||
gcal-event-view.c \
|
||||
gcal-event-view.h \
|
||||
gcal-event-overlay.c \
|
||||
gcal-event-overlay.h \
|
||||
gcal-editable.c \
|
||||
gcal-editable.h \
|
||||
gcal-editable-entry.c \
|
||||
|
||||
@@ -0,0 +1,744 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* gcal-arrow-container.c
|
||||
* Copyright (C) 2012 Erick Pérez Castellanos <erickpc@gnome.org>
|
||||
*
|
||||
* gnome-calendar is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* gnome-calendar is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "gcal-arrow-container.h"
|
||||
#include <math.h>
|
||||
|
||||
struct _GcalArrowContainerPrivate
|
||||
{
|
||||
guint arrow_size;
|
||||
};
|
||||
|
||||
static void gcal_arrow_container_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_width,
|
||||
gint *natural_width);
|
||||
|
||||
static void gcal_arrow_container_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height);
|
||||
|
||||
static void gcal_arrow_container_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_height,
|
||||
gint *natural_height);
|
||||
|
||||
static void gcal_arrow_container_get_preferred_width_for_height (GtkWidget *widget,
|
||||
gint height,
|
||||
gint *minimum_width,
|
||||
gint *natural_width);
|
||||
|
||||
static void gcal_arrow_container_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
|
||||
static gboolean gcal_arrow_container_draw (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
|
||||
static void gcal_arrow_container_draw_arrow (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
|
||||
static void gcal_arrow_container_draw_shadow (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
|
||||
static void gcal_arrow_container_get_padding_and_border (GtkWidget *widget,
|
||||
GtkBorder *border,
|
||||
guint *border_width,
|
||||
guint *arrow_size,
|
||||
guint *shadow);
|
||||
|
||||
G_DEFINE_TYPE(GcalArrowContainer, gcal_arrow_container, GTK_TYPE_BIN)
|
||||
|
||||
static void
|
||||
gcal_arrow_container_class_init (GcalArrowContainerClass *klass)
|
||||
{
|
||||
GtkWidgetClass* widget_class;
|
||||
|
||||
widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
widget_class->get_preferred_width =
|
||||
gcal_arrow_container_get_preferred_width;
|
||||
widget_class->get_preferred_height_for_width =
|
||||
gcal_arrow_container_get_preferred_height_for_width;
|
||||
widget_class->get_preferred_height =
|
||||
gcal_arrow_container_get_preferred_height;
|
||||
widget_class->get_preferred_width_for_height =
|
||||
gcal_arrow_container_get_preferred_width_for_height;
|
||||
widget_class->size_allocate = gcal_arrow_container_size_allocate;
|
||||
widget_class->draw = gcal_arrow_container_draw;
|
||||
|
||||
/* Style properties */
|
||||
gtk_widget_class_install_style_property (
|
||||
widget_class,
|
||||
g_param_spec_uint ("arrow-size",
|
||||
"Arrow width and height",
|
||||
"The width and height of the arrow",
|
||||
0,
|
||||
G_MAXUINT32,
|
||||
0,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
gtk_widget_class_install_style_property (
|
||||
widget_class,
|
||||
g_param_spec_uint ("shadow-span",
|
||||
"Shadow span",
|
||||
"Shadow span",
|
||||
0,
|
||||
G_MAXUINT32,
|
||||
0,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_type_class_add_private ((gpointer)klass, sizeof(GcalArrowContainerPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_arrow_container_init (GcalArrowContainer *self)
|
||||
{
|
||||
gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
|
||||
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
||||
GCAL_TYPE_ARROW_CONTAINER,
|
||||
GcalArrowContainerPrivate);
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_arrow_container_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_width,
|
||||
gint *natural_width)
|
||||
{
|
||||
gint child_min, child_nat;
|
||||
GtkWidget *child;
|
||||
GtkBorder padding;
|
||||
gint minimum, natural;
|
||||
guint shadow;
|
||||
|
||||
gcal_arrow_container_get_padding_and_border (widget,
|
||||
&padding,
|
||||
NULL,
|
||||
NULL,
|
||||
&shadow);
|
||||
|
||||
minimum = 0;
|
||||
natural = 0;
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (widget));
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
{
|
||||
gtk_widget_get_preferred_width (child,
|
||||
&child_min, &child_nat);
|
||||
minimum += child_min;
|
||||
natural += child_nat;
|
||||
}
|
||||
|
||||
minimum += padding.left + padding.right + 2 * shadow;
|
||||
natural += padding.left + padding.right + 2 * shadow;
|
||||
|
||||
if (minimum_width)
|
||||
*minimum_width = minimum;
|
||||
|
||||
if (natural_width)
|
||||
*natural_width = natural;
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_arrow_container_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height)
|
||||
{
|
||||
gint child_min, child_nat, child_width;
|
||||
GtkWidget *child;
|
||||
GtkBorder padding;
|
||||
guint shadow;
|
||||
guint arrow_size;
|
||||
gint minimum;
|
||||
gint natural;
|
||||
|
||||
gcal_arrow_container_get_padding_and_border (widget,
|
||||
&padding,
|
||||
NULL,
|
||||
&arrow_size,
|
||||
&shadow);
|
||||
|
||||
minimum = 0;
|
||||
natural = 0;
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (widget));
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
{
|
||||
child_width = width - padding.left - padding.top - 2 * shadow;
|
||||
|
||||
gtk_widget_get_preferred_height_for_width (child, child_width,
|
||||
&child_min, &child_nat);
|
||||
minimum = MAX (minimum, child_min);
|
||||
natural = MAX (natural, child_nat);
|
||||
}
|
||||
|
||||
minimum += padding.top + padding.bottom + arrow_size + 2 * shadow;
|
||||
natural += padding.top + padding.bottom + arrow_size + 2 * shadow;
|
||||
|
||||
if (minimum_height)
|
||||
*minimum_height = minimum;
|
||||
|
||||
if (natural_height)
|
||||
*natural_height = natural;
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_arrow_container_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_height,
|
||||
gint *natural_height)
|
||||
{
|
||||
gint child_min, child_nat;
|
||||
GtkWidget *child;
|
||||
GtkBorder padding;
|
||||
guint shadow;
|
||||
guint arrow_size;
|
||||
gint minimum;
|
||||
gint natural;
|
||||
|
||||
gcal_arrow_container_get_padding_and_border (widget,
|
||||
&padding,
|
||||
NULL,
|
||||
&arrow_size,
|
||||
&shadow);
|
||||
|
||||
minimum = 0;
|
||||
natural = 0;
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (widget));
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
{
|
||||
gtk_widget_get_preferred_height (child,
|
||||
&child_min, &child_nat);
|
||||
minimum = child_min;
|
||||
natural = child_nat;
|
||||
}
|
||||
|
||||
minimum += padding.top + padding.bottom + arrow_size + 2 * shadow;
|
||||
natural += padding.top + padding.bottom + arrow_size + 2 * shadow;
|
||||
|
||||
if (minimum_height)
|
||||
*minimum_height = minimum;
|
||||
|
||||
if (natural_height)
|
||||
*natural_height = natural;
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_arrow_container_get_preferred_width_for_height (GtkWidget *widget,
|
||||
gint height,
|
||||
gint *minimum_width,
|
||||
gint *natural_width)
|
||||
{
|
||||
gint child_min, child_nat, child_height;
|
||||
GtkWidget *child;
|
||||
GtkBorder padding;
|
||||
guint shadow;
|
||||
gint minimum;
|
||||
gint natural;
|
||||
|
||||
gcal_arrow_container_get_padding_and_border (widget,
|
||||
&padding,
|
||||
NULL,
|
||||
NULL,
|
||||
&shadow);
|
||||
|
||||
minimum = 0;
|
||||
natural = 0;
|
||||
|
||||
child_height = height - padding.top - padding.bottom - 2 * shadow;
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (widget));
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
{
|
||||
gtk_widget_get_preferred_width_for_height (child, child_height,
|
||||
&child_min, &child_nat);
|
||||
minimum += child_min;
|
||||
natural += child_nat;
|
||||
}
|
||||
|
||||
minimum += padding.left + padding.right + 2 * shadow;
|
||||
natural += padding.left + padding.right + 2 * shadow;
|
||||
|
||||
if (minimum_width)
|
||||
*minimum_width = minimum;
|
||||
|
||||
if (natural_width)
|
||||
*natural_width = natural;
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_arrow_container_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
GtkAllocation child_allocation;
|
||||
GtkBorder padding;
|
||||
GtkWidget *child;
|
||||
guint arrow_size;
|
||||
guint shadow;
|
||||
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
|
||||
gcal_arrow_container_get_padding_and_border (widget,
|
||||
&padding,
|
||||
NULL,
|
||||
&arrow_size,
|
||||
&shadow);
|
||||
|
||||
if (gtk_widget_get_realized (widget))
|
||||
{
|
||||
gdk_window_move_resize (gtk_widget_get_window (widget),
|
||||
allocation->x,
|
||||
allocation->y,
|
||||
allocation->width,
|
||||
allocation->height);
|
||||
}
|
||||
|
||||
child_allocation.x = padding.left + shadow;
|
||||
child_allocation.y = padding.top + shadow;
|
||||
child_allocation.height =
|
||||
MAX (1,
|
||||
allocation->height - padding.top - padding.bottom - 2 * shadow - arrow_size);
|
||||
|
||||
child_allocation.width =
|
||||
MAX (1,
|
||||
allocation->width - padding.left - padding.right - 2 * shadow);
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (widget));
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
gtk_widget_size_allocate (child, &child_allocation);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gcal_arrow_container_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GtkBorder border;
|
||||
guint border_width;
|
||||
guint width;
|
||||
guint height;
|
||||
guint arrow_size;
|
||||
guint shadow;
|
||||
|
||||
gtk_style_context_get_border (
|
||||
gtk_widget_get_style_context (widget),
|
||||
gtk_widget_get_state_flags (widget),
|
||||
&border);
|
||||
|
||||
gcal_arrow_container_get_padding_and_border (widget,
|
||||
NULL,
|
||||
&border_width,
|
||||
&arrow_size,
|
||||
&shadow);
|
||||
|
||||
width = gtk_widget_get_allocated_width (widget) - 2 * border_width - 2 * shadow;
|
||||
height = gtk_widget_get_allocated_height (widget) - 2 * border_width - arrow_size - 2 * shadow;
|
||||
|
||||
gcal_arrow_container_draw_shadow (widget, cr);
|
||||
|
||||
gtk_render_background (gtk_widget_get_style_context (widget),
|
||||
cr,
|
||||
border_width + shadow, border_width + shadow,
|
||||
width, height);
|
||||
gtk_render_frame_gap (gtk_widget_get_style_context (widget),
|
||||
cr,
|
||||
border_width + shadow, border_width + shadow,
|
||||
width, height,
|
||||
GTK_POS_BOTTOM,
|
||||
width / 2 - arrow_size - border.bottom,
|
||||
width / 2 + arrow_size + border.bottom);
|
||||
|
||||
gcal_arrow_container_draw_arrow (widget, cr);
|
||||
|
||||
GTK_WIDGET_CLASS (gcal_arrow_container_parent_class)->draw (widget, cr);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_arrow_container_draw_arrow (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GdkRGBA color;
|
||||
GtkBorder border;
|
||||
guint arrow_size;
|
||||
guint border_width;
|
||||
guint shadow;
|
||||
guint width;
|
||||
guint height;
|
||||
|
||||
gtk_style_context_get_border (
|
||||
gtk_widget_get_style_context (widget),
|
||||
gtk_widget_get_state_flags (widget),
|
||||
&border);
|
||||
|
||||
gcal_arrow_container_get_padding_and_border (widget,
|
||||
NULL,
|
||||
&border_width,
|
||||
&arrow_size,
|
||||
&shadow);
|
||||
|
||||
width = gtk_widget_get_allocated_width (widget) - 2 * border_width - 2 * shadow;
|
||||
height = gtk_widget_get_allocated_height (widget) - 2 * border_width - arrow_size - 2 * shadow;
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_move_to (cr,
|
||||
border_width + shadow + width / 2 - arrow_size,
|
||||
border_width + shadow + height - border.bottom);
|
||||
cairo_rel_line_to (cr, 0, border.bottom);
|
||||
cairo_rel_line_to (cr, arrow_size, arrow_size);
|
||||
cairo_rel_line_to (cr, arrow_size, - arrow_size);
|
||||
cairo_rel_line_to (cr, 0, - border.bottom);
|
||||
|
||||
gtk_style_context_get_background_color (
|
||||
gtk_widget_get_style_context (widget),
|
||||
gtk_widget_get_state_flags (widget),
|
||||
&color);
|
||||
cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_set_line_width (cr, border.bottom);
|
||||
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
|
||||
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
|
||||
cairo_move_to (cr,
|
||||
border_width + shadow + width / 2 - arrow_size,
|
||||
border_width + shadow + height);
|
||||
cairo_rel_line_to (cr, arrow_size, arrow_size);
|
||||
cairo_rel_line_to (cr, arrow_size, - arrow_size);
|
||||
|
||||
gtk_style_context_get_border_color (
|
||||
gtk_widget_get_style_context (widget),
|
||||
gtk_widget_get_state_flags (widget),
|
||||
&color);
|
||||
cairo_set_source_rgb (cr, color.red, color.green, color.blue);
|
||||
cairo_stroke (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_arrow_container_draw_shadow (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
gdouble inner_alpha;
|
||||
gint width;
|
||||
gint height;
|
||||
guint arrow_size;
|
||||
guint shadow_span;
|
||||
guint border_width;
|
||||
gdouble shadow_span_tan;
|
||||
|
||||
gcal_arrow_container_get_padding_and_border (widget,
|
||||
NULL,
|
||||
&border_width,
|
||||
&arrow_size,
|
||||
&shadow_span);
|
||||
|
||||
width = gtk_widget_get_allocated_width (widget);
|
||||
height = gtk_widget_get_allocated_height (widget);
|
||||
shadow_span_tan = shadow_span / tan (G_PI_4 / 2 + G_PI_4);
|
||||
|
||||
inner_alpha = 0.8;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
/* Top border */
|
||||
pattern = cairo_pattern_create_linear (0, border_width,
|
||||
0, border_width + 3 * shadow_span);
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0, 0, 0, 0.0);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0, 0, 0, inner_alpha);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
border_width + shadow_span, border_width,
|
||||
width - 2 * border_width - 2 * shadow_span, shadow_span);
|
||||
cairo_fill (cr);
|
||||
|
||||
/* Left border */
|
||||
pattern = cairo_pattern_create_linear (border_width, 0,
|
||||
border_width + 3 * shadow_span, 0);
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0, 0, 0, 0.0);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0, 0, 0, inner_alpha);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
border_width, border_width + shadow_span,
|
||||
shadow_span, height - 2 * border_width - 2 * shadow_span - arrow_size);
|
||||
cairo_fill (cr);
|
||||
|
||||
/* Right border */
|
||||
pattern = cairo_pattern_create_linear (width - (border_width + 3 * shadow_span), 0,
|
||||
width - border_width, 0);
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0, 0, 0, inner_alpha);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0, 0, 0, 0.0);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
width - (border_width + shadow_span), border_width + shadow_span,
|
||||
shadow_span, height - 2 * border_width - 2 * shadow_span - arrow_size);
|
||||
cairo_fill (cr);
|
||||
|
||||
/* Bottom border */
|
||||
pattern = cairo_pattern_create_linear (0, height - border_width - 3 * shadow_span - arrow_size,
|
||||
0, height - border_width - arrow_size);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0, 0, 0, inner_alpha);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0, 0, 0, 0.0);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
border_width + shadow_span, height - border_width - shadow_span - arrow_size,
|
||||
width / 2 - arrow_size - border_width - shadow_span - shadow_span_tan, shadow_span);
|
||||
cairo_rectangle (cr,
|
||||
width / 2 + arrow_size + shadow_span_tan, height - border_width - shadow_span - arrow_size,
|
||||
width / 2 - arrow_size - border_width - shadow_span - shadow_span_tan, shadow_span);
|
||||
cairo_fill (cr);
|
||||
|
||||
/* NW corner */
|
||||
pattern = cairo_pattern_create_radial (
|
||||
border_width + shadow_span, border_width + shadow_span, 0,
|
||||
border_width + shadow_span, border_width + shadow_span, shadow_span);
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0, 0, 0, inner_alpha / 3);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0, 0, 0, 0.0);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
border_width, border_width,
|
||||
shadow_span, shadow_span);
|
||||
cairo_fill (cr);
|
||||
|
||||
/* SE corner */
|
||||
pattern = cairo_pattern_create_radial (
|
||||
border_width + shadow_span, height - border_width - shadow_span - arrow_size, 0,
|
||||
border_width + shadow_span, height - border_width - shadow_span - arrow_size, shadow_span);
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0, 0, 0, inner_alpha / 3);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0, 0, 0, 0.0);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
border_width, height - border_width - shadow_span - arrow_size,
|
||||
shadow_span, shadow_span);
|
||||
cairo_fill (cr);
|
||||
|
||||
/* SW corner */
|
||||
pattern = cairo_pattern_create_radial (
|
||||
width - border_width - shadow_span, height - border_width - shadow_span - arrow_size, 0,
|
||||
width - border_width - shadow_span, height - border_width - shadow_span - arrow_size, shadow_span);
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0, 0, 0, inner_alpha / 3);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0, 0, 0, 0.0);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
width - border_width - shadow_span, height - border_width - shadow_span - arrow_size,
|
||||
shadow_span, shadow_span);
|
||||
cairo_fill (cr);
|
||||
|
||||
/* Arrow left joint */
|
||||
pattern = cairo_pattern_create_radial (
|
||||
width / 2 - arrow_size - shadow_span_tan, height - border_width - arrow_size, 0,
|
||||
width / 2 - arrow_size - shadow_span_tan, height - border_width - arrow_size, shadow_span);
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0, 0, 0, 0.0);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0, 0, 0, inner_alpha / 3);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_move_to (cr,
|
||||
width / 2 - arrow_size - shadow_span_tan,
|
||||
height - border_width - arrow_size);
|
||||
cairo_arc (cr,
|
||||
width / 2 - arrow_size - shadow_span_tan,
|
||||
height - border_width - arrow_size,
|
||||
shadow_span + 2,
|
||||
G_PI_2 + G_PI,
|
||||
2 * G_PI - G_PI_4);
|
||||
|
||||
cairo_fill (cr);
|
||||
|
||||
/* Arrow right joint */
|
||||
pattern = cairo_pattern_create_radial (
|
||||
width / 2 + arrow_size + shadow_span_tan, height - border_width - arrow_size, 0,
|
||||
width / 2 + arrow_size + shadow_span_tan, height - border_width - arrow_size, shadow_span);
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0, 0, 0, 0.0);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0, 0, 0, inner_alpha / 3);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_move_to (cr,
|
||||
width / 2 + arrow_size + shadow_span_tan,
|
||||
height - border_width - arrow_size);
|
||||
cairo_arc (cr,
|
||||
width / 2 + arrow_size + shadow_span_tan,
|
||||
height - border_width - arrow_size,
|
||||
shadow_span + 2,
|
||||
G_PI_4 + G_PI,
|
||||
G_PI + G_PI_2);
|
||||
|
||||
cairo_fill (cr);
|
||||
|
||||
/* Arrow left side */
|
||||
cairo_save (cr);
|
||||
cairo_translate (cr,
|
||||
width / 2 - arrow_size,
|
||||
height - border_width - shadow_span - arrow_size);
|
||||
cairo_rotate(cr, G_PI_4);
|
||||
|
||||
pattern = cairo_pattern_create_linear (
|
||||
0, 0,
|
||||
0, shadow_span);
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0, 0, 0, inner_alpha / 3);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0, 0, 0, 0.0);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
shadow_span_tan, 0,
|
||||
arrow_size * G_SQRT2 - shadow_span_tan, shadow_span);
|
||||
|
||||
cairo_fill (cr);
|
||||
cairo_restore (cr);
|
||||
|
||||
/* Arrow right side */
|
||||
cairo_save (cr);
|
||||
cairo_translate (cr,
|
||||
width / 2,
|
||||
height - border_width - shadow_span);
|
||||
cairo_rotate (cr, - G_PI_4);
|
||||
|
||||
pattern = cairo_pattern_create_linear (
|
||||
0, 0,
|
||||
0, shadow_span);
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0, 0, 0, inner_alpha / 3);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0, 0, 0, 0.0);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
0,
|
||||
0,
|
||||
arrow_size * G_SQRT2 - shadow_span_tan,
|
||||
shadow_span);
|
||||
|
||||
cairo_fill (cr);
|
||||
cairo_restore (cr);
|
||||
|
||||
/* Arrow point */
|
||||
pattern = cairo_pattern_create_radial (
|
||||
width / 2, height - border_width - shadow_span, 0,
|
||||
width / 2, height - border_width - shadow_span, shadow_span);
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0, 0, 0, inner_alpha / 3);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0, 0, 0, 0.0);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_move_to (cr,
|
||||
width / 2,
|
||||
height - border_width - shadow_span);
|
||||
cairo_arc (cr,
|
||||
width / 2,
|
||||
height - border_width - shadow_span,
|
||||
shadow_span,
|
||||
G_PI_4,
|
||||
G_PI_2 + G_PI_4);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_arrow_container_get_padding_and_border (GtkWidget *widget,
|
||||
GtkBorder *border,
|
||||
guint *border_width,
|
||||
guint *arrow_size,
|
||||
guint *shadow)
|
||||
{
|
||||
GtkBorder tmp;
|
||||
guint bd_width;
|
||||
|
||||
bd_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
|
||||
if (border != NULL)
|
||||
{
|
||||
gtk_style_context_get_padding (
|
||||
gtk_widget_get_style_context (widget),
|
||||
gtk_widget_get_state_flags (widget),
|
||||
border);
|
||||
|
||||
gtk_style_context_get_border (
|
||||
gtk_widget_get_style_context (widget),
|
||||
gtk_widget_get_state_flags (widget),
|
||||
&tmp);
|
||||
|
||||
border->top += tmp.top + bd_width;
|
||||
border->right += tmp.right + bd_width;
|
||||
border->bottom += tmp.bottom + bd_width;
|
||||
border->left += tmp.left + bd_width;
|
||||
}
|
||||
|
||||
if (arrow_size != NULL)
|
||||
{
|
||||
gtk_style_context_get_style (
|
||||
gtk_widget_get_style_context (widget),
|
||||
"arrow-size", arrow_size,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (border_width != NULL)
|
||||
*border_width = bd_width;
|
||||
|
||||
if (shadow != NULL)
|
||||
{
|
||||
gtk_style_context_get_style (
|
||||
gtk_widget_get_style_context (widget),
|
||||
"shadow-span", shadow,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget*
|
||||
gcal_arrow_container_new (void)
|
||||
{
|
||||
return g_object_new (GCAL_TYPE_ARROW_CONTAINER, NULL);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* gcal-arrow-container.h
|
||||
* Copyright (C) 2012 Erick Pérez Castellanos <erickpc@gnome.org>
|
||||
*
|
||||
* gnome-calendar is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* gnome-calendar is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GCAL_ARROW_CONTAINER_H__
|
||||
#define __GCAL_ARROW_CONTAINER_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define GCAL_TYPE_ARROW_CONTAINER (gcal_arrow_container_get_type ())
|
||||
#define GCAL_ARROW_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GCAL_TYPE_ARROW_CONTAINER, GcalArrowContainer))
|
||||
#define GCAL_ARROW_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GCAL_TYPE_ARROW_CONTAINER, GcalArrowContainerClass))
|
||||
#define GCAL_IS_ARROW_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GCAL_TYPE_ARROW_CONTAINER))
|
||||
#define GCAL_IS_ARROW_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GCAL_TYPE_ARROW_CONTAINER))
|
||||
#define GCAL_ARROW_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GCAL_TYPE_ARROW_CONTAINER, GcalArrowContainerClass))
|
||||
|
||||
typedef struct _GcalArrowContainer GcalArrowContainer;
|
||||
typedef struct _GcalArrowContainerClass GcalArrowContainerClass;
|
||||
typedef struct _GcalArrowContainerPrivate GcalArrowContainerPrivate;
|
||||
|
||||
struct _GcalArrowContainer
|
||||
{
|
||||
GtkBin parent;
|
||||
/* add your public declarations here */
|
||||
|
||||
GcalArrowContainerPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GcalArrowContainerClass
|
||||
{
|
||||
GtkBinClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GType gcal_arrow_container_get_type (void);
|
||||
GtkWidget* gcal_arrow_container_new (void);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GCAL_ARROW_CONTAINER_H__ */
|
||||
@@ -0,0 +1,562 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* gcal-event-overlay.c
|
||||
* Copyright (C) 2012 Erick Pérez Castellanos <erickpc@gnome.org>
|
||||
*
|
||||
* gnome-calendar is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* gnome-calendar is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "gcal-event-overlay.h"
|
||||
#include "gcal-arrow-container.h"
|
||||
#include "gcal-utils.h"
|
||||
#include "gcal-marshalers.h"
|
||||
|
||||
#include <libecal/libecal.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#define CLOSE_IMAGE_FILE UI_DATA_DIR "/close-window.svg"
|
||||
|
||||
struct _GcalEventOverlayPrivate
|
||||
{
|
||||
GtkWidget *container;
|
||||
GtkWidget *title_label;
|
||||
GtkWidget *what_entry;
|
||||
GtkWidget *calendar_button;
|
||||
|
||||
GtkListStore *sources_model;
|
||||
GtkTreeIter *active_iter;
|
||||
|
||||
icaltimetype *start_span;
|
||||
icaltimetype *end_span;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CANCELLED = 1,
|
||||
CREATED,
|
||||
NUM_SIGNALS
|
||||
};
|
||||
|
||||
static guint signals[NUM_SIGNALS] = { 0, };
|
||||
|
||||
static void gcal_event_overlay_constructed (GObject *object);
|
||||
|
||||
static void gcal_event_overlay_set_calendars_menu (GcalEventOverlay *widget);
|
||||
|
||||
static gboolean gcal_event_overlay_gather_data (GcalEventOverlay *widget,
|
||||
GcalNewEventData **new_data);
|
||||
|
||||
static void gcal_event_overlay_create_button_clicked (GtkWidget *widget,
|
||||
gpointer user_data);
|
||||
|
||||
static void gcal_event_overlay_close_button_clicked (GtkWidget *widget,
|
||||
gpointer user_data);
|
||||
|
||||
static void gcal_event_overlay_calendar_selected (GtkWidget *menu_item,
|
||||
gpointer user_data);
|
||||
|
||||
static GdkPixbuf* gcal_event_overlay_get_pixbuf_for_color (GdkColor *color);
|
||||
|
||||
G_DEFINE_TYPE(GcalEventOverlay, gcal_event_overlay, GTK_CLUTTER_TYPE_ACTOR)
|
||||
|
||||
static void
|
||||
gcal_event_overlay_class_init (GcalEventOverlayClass *klass)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
object_class = G_OBJECT_CLASS (klass);
|
||||
object_class->constructed = gcal_event_overlay_constructed;
|
||||
|
||||
signals[CANCELLED] = g_signal_new ("cancelled",
|
||||
GCAL_TYPE_EVENT_OVERLAY,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GcalEventOverlayClass,
|
||||
cancelled),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
|
||||
signals[CREATED] = g_signal_new ("created",
|
||||
GCAL_TYPE_EVENT_OVERLAY,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GcalEventOverlayClass,
|
||||
created),
|
||||
NULL, NULL,
|
||||
_gcal_marshal_VOID__POINTER_BOOLEAN,
|
||||
G_TYPE_NONE,
|
||||
2,
|
||||
G_TYPE_POINTER,
|
||||
G_TYPE_BOOLEAN);
|
||||
|
||||
g_type_class_add_private ((gpointer)klass, sizeof(GcalEventOverlayPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_event_overlay_init (GcalEventOverlay *self)
|
||||
{
|
||||
GcalEventOverlayPrivate *priv;
|
||||
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
||||
GCAL_TYPE_EVENT_OVERLAY,
|
||||
GcalEventOverlayPrivate);
|
||||
priv = self->priv;
|
||||
|
||||
priv->active_iter = NULL;
|
||||
priv->start_span = NULL;
|
||||
priv->end_span = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_event_overlay_constructed (GObject* object)
|
||||
{
|
||||
GcalEventOverlayPrivate *priv;
|
||||
GtkWidget *main_grid;
|
||||
GtkWidget *row_grid;
|
||||
GtkWidget *overlay;
|
||||
GtkWidget *create_button;
|
||||
GtkWidget *details_button;
|
||||
GtkWidget *close_image;
|
||||
GtkWidget *close_button;
|
||||
GtkWidget *calendar_image;
|
||||
|
||||
priv = GCAL_EVENT_OVERLAY (object)->priv;
|
||||
|
||||
/* chaining up */
|
||||
G_OBJECT_CLASS (gcal_event_overlay_parent_class)->constructed (object);
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
|
||||
priv->container = gcal_arrow_container_new ();
|
||||
gtk_container_set_border_width (GTK_CONTAINER (priv->container), 14);
|
||||
gtk_style_context_add_class (
|
||||
gtk_widget_get_style_context (priv->container),
|
||||
"new-event-view");
|
||||
gtk_container_add (GTK_CONTAINER (overlay), priv->container);
|
||||
|
||||
main_grid = gtk_grid_new ();
|
||||
g_object_set (main_grid,
|
||||
"row-spacing", 18,
|
||||
"column-spacing", 12,
|
||||
"column-homogeneous", TRUE,
|
||||
NULL);
|
||||
|
||||
priv->title_label = gtk_label_new (_("New Event"));
|
||||
gtk_grid_attach (GTK_GRID (main_grid),
|
||||
priv->title_label,
|
||||
0, 0,
|
||||
2, 1);
|
||||
row_grid = gtk_grid_new ();
|
||||
gtk_grid_attach (GTK_GRID (main_grid),
|
||||
row_grid,
|
||||
0, 1,
|
||||
2, 1);
|
||||
create_button = gtk_button_new_with_label (_("Create"));
|
||||
g_object_set_data (G_OBJECT (create_button), "open-details", GUINT_TO_POINTER (0));
|
||||
gtk_style_context_add_class (
|
||||
gtk_widget_get_style_context (create_button),
|
||||
"suggested-action");
|
||||
gtk_grid_attach (GTK_GRID (main_grid),
|
||||
create_button,
|
||||
0, 2,
|
||||
1, 1);
|
||||
details_button = gtk_button_new_with_label (_("More details"));
|
||||
g_object_set_data (G_OBJECT (details_button), "open-details", GUINT_TO_POINTER (1));
|
||||
gtk_grid_attach (GTK_GRID (main_grid),
|
||||
details_button,
|
||||
1, 2,
|
||||
1, 1);
|
||||
|
||||
g_object_set (row_grid,
|
||||
"orientation", GTK_ORIENTATION_HORIZONTAL,
|
||||
"column-spacing", 6,
|
||||
NULL);
|
||||
priv->what_entry = gtk_entry_new ();
|
||||
g_object_set_data (G_OBJECT (priv->what_entry), "open-details", GUINT_TO_POINTER (0));
|
||||
gtk_entry_set_placeholder_text (GTK_ENTRY (priv->what_entry),
|
||||
_("What (e.g. Alien Invasion)"));
|
||||
g_object_set (priv->what_entry,
|
||||
"valign", GTK_ALIGN_CENTER,
|
||||
"expand", TRUE,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (row_grid),
|
||||
priv->what_entry);
|
||||
|
||||
priv->calendar_button = gtk_menu_button_new ();
|
||||
calendar_image = gtk_image_new_from_icon_name ("x-office-calendar-symbolic",
|
||||
GTK_ICON_SIZE_MENU);
|
||||
g_object_set (priv->calendar_button,
|
||||
"vexpand", TRUE,
|
||||
"always-show-image", TRUE,
|
||||
"image", calendar_image,
|
||||
"menu", gtk_menu_new (),
|
||||
NULL);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (row_grid),
|
||||
priv->calendar_button);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (priv->container),
|
||||
main_grid);
|
||||
|
||||
close_button = gtk_button_new ();
|
||||
close_image = gtk_image_new_from_file (CLOSE_IMAGE_FILE);
|
||||
gtk_container_add (GTK_CONTAINER (close_button), close_image);
|
||||
g_object_set (close_button,
|
||||
"relief", GTK_RELIEF_NONE,
|
||||
"focus-on-click", FALSE,
|
||||
"halign", GTK_ALIGN_END,
|
||||
"valign", GTK_ALIGN_START,
|
||||
NULL);
|
||||
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), close_button);
|
||||
|
||||
gtk_widget_show_all (overlay);
|
||||
gtk_container_add (
|
||||
GTK_CONTAINER (gtk_clutter_actor_get_widget (GTK_CLUTTER_ACTOR (object))),
|
||||
overlay);
|
||||
|
||||
/* Hooking signals */
|
||||
g_signal_connect (priv->what_entry,
|
||||
"activate",
|
||||
G_CALLBACK (gcal_event_overlay_create_button_clicked),
|
||||
object);
|
||||
|
||||
g_signal_connect (create_button,
|
||||
"clicked",
|
||||
G_CALLBACK (gcal_event_overlay_create_button_clicked),
|
||||
object);
|
||||
|
||||
g_signal_connect (details_button,
|
||||
"clicked",
|
||||
G_CALLBACK (gcal_event_overlay_create_button_clicked),
|
||||
object);
|
||||
|
||||
g_signal_connect (close_button,
|
||||
"clicked",
|
||||
G_CALLBACK (gcal_event_overlay_close_button_clicked),
|
||||
object);
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_event_overlay_set_calendars_menu (GcalEventOverlay *widget)
|
||||
{
|
||||
GcalEventOverlayPrivate *priv;
|
||||
GtkMenu *menu;
|
||||
GtkWidget *item;
|
||||
GList *children;
|
||||
|
||||
gboolean valid;
|
||||
GtkTreeIter iter;
|
||||
|
||||
priv = widget->priv;
|
||||
|
||||
valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->sources_model),
|
||||
&iter);
|
||||
if (! valid)
|
||||
return;
|
||||
|
||||
menu = gtk_menu_button_get_menu (GTK_MENU_BUTTON (priv->calendar_button));
|
||||
children = gtk_container_get_children (GTK_CONTAINER (menu));
|
||||
g_list_foreach (children, (GFunc) gtk_widget_destroy, NULL);
|
||||
|
||||
while (valid)
|
||||
{
|
||||
/* Walk through the list, reading each row */
|
||||
gchar *name;
|
||||
GdkColor *color;
|
||||
GtkWidget *cal_image;
|
||||
GdkPixbuf *pix;
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (priv->sources_model), &iter,
|
||||
1, &name,
|
||||
3, &color,
|
||||
-1);
|
||||
|
||||
item = gtk_image_menu_item_new ();
|
||||
g_object_set_data_full (G_OBJECT (item),
|
||||
"sources-iter",
|
||||
gtk_tree_iter_copy (&iter),
|
||||
(GDestroyNotify) gtk_tree_iter_free);
|
||||
g_signal_connect (item,
|
||||
"activate",
|
||||
G_CALLBACK (gcal_event_overlay_calendar_selected),
|
||||
widget);
|
||||
|
||||
pix = gcal_event_overlay_get_pixbuf_for_color (color);
|
||||
|
||||
cal_image = gtk_image_new_from_pixbuf (pix);
|
||||
g_object_set (item,
|
||||
"always-show-image", TRUE,
|
||||
"image", cal_image,
|
||||
"label", name,
|
||||
NULL);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
|
||||
g_object_unref (pix);
|
||||
g_free (name);
|
||||
gdk_color_free (color);
|
||||
|
||||
valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->sources_model),
|
||||
&iter);
|
||||
}
|
||||
|
||||
gtk_widget_show_all (GTK_WIDGET (menu));
|
||||
/*
|
||||
if (! had_menu)
|
||||
{
|
||||
gtk_menu_button_set_menu (GTK_MENU_BUTTON (priv->calendar_button),
|
||||
menu);
|
||||
}*/
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gcal_event_overlay_gather_data (GcalEventOverlay *widget,
|
||||
GcalNewEventData **new_data)
|
||||
{
|
||||
GcalEventOverlayPrivate *priv;
|
||||
GcalNewEventData *data;
|
||||
gchar *uid;
|
||||
|
||||
priv = widget->priv;
|
||||
if (priv->active_iter == NULL)
|
||||
return FALSE;
|
||||
if (g_strcmp0 (gtk_entry_get_text (GTK_ENTRY (priv->what_entry)), "") == 0)
|
||||
return FALSE;
|
||||
|
||||
data = g_new0 (GcalNewEventData, 1);
|
||||
data->summary = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->what_entry)));
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (priv->sources_model), priv->active_iter,
|
||||
0, &uid,
|
||||
-1);
|
||||
data->calendar_uid = uid;
|
||||
data->start_date = priv->start_span;
|
||||
data->end_date = priv->end_span;
|
||||
|
||||
*new_data = data;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_event_overlay_create_button_clicked (GtkWidget *widget,
|
||||
gpointer user_data)
|
||||
{
|
||||
GcalNewEventData *data;
|
||||
guint open_details;
|
||||
|
||||
open_details = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (widget),
|
||||
"open-details"));
|
||||
|
||||
/* Maybe some kind of notification */
|
||||
if (! gcal_event_overlay_gather_data (GCAL_EVENT_OVERLAY (user_data), &data))
|
||||
return;
|
||||
|
||||
g_signal_emit (GCAL_EVENT_OVERLAY (user_data),
|
||||
signals[CREATED],
|
||||
0,
|
||||
data, open_details == 1);
|
||||
|
||||
g_free (data->calendar_uid);
|
||||
g_free (data->summary);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_event_overlay_close_button_clicked (GtkWidget *widget,
|
||||
gpointer user_data)
|
||||
{
|
||||
GcalEventOverlay *self;
|
||||
self = GCAL_EVENT_OVERLAY (user_data);
|
||||
|
||||
g_signal_emit (self, signals[CANCELLED], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_event_overlay_calendar_selected (GtkWidget *menu_item,
|
||||
gpointer user_data)
|
||||
{
|
||||
GcalEventOverlayPrivate *priv;
|
||||
GtkTreeIter *iter;
|
||||
GdkColor *color;
|
||||
|
||||
GdkPixbuf *pix;
|
||||
GtkWidget *cal_image;
|
||||
|
||||
priv = GCAL_EVENT_OVERLAY (user_data)->priv;
|
||||
iter = g_object_get_data (G_OBJECT (menu_item), "sources-iter");
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (priv->sources_model), iter,
|
||||
3, &color,
|
||||
-1);
|
||||
|
||||
if (priv->active_iter != NULL)
|
||||
gtk_tree_iter_free (priv->active_iter);
|
||||
priv->active_iter = gtk_tree_iter_copy (iter);
|
||||
|
||||
pix = gcal_event_overlay_get_pixbuf_for_color (color);
|
||||
cal_image = gtk_image_new_from_pixbuf (pix);
|
||||
gtk_button_set_image (GTK_BUTTON (priv->calendar_button), cal_image);
|
||||
|
||||
gdk_color_free (color);
|
||||
g_object_unref (pix);
|
||||
}
|
||||
|
||||
static GdkPixbuf*
|
||||
gcal_event_overlay_get_pixbuf_for_color (GdkColor *color)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
gint width, height;
|
||||
GdkPixbuf *pix;
|
||||
|
||||
/* TODO: review size here, maybe not hardcoded */
|
||||
width = height = 10;
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
|
||||
cr = cairo_create (surface);
|
||||
|
||||
cairo_set_source_rgb (cr,
|
||||
color->red / 65535.0,
|
||||
color->green / 65535.0,
|
||||
color->blue / 65535.0);
|
||||
cairo_rectangle (cr, 0, 0, width, height);
|
||||
cairo_fill (cr);
|
||||
cairo_destroy (cr);
|
||||
pix = gdk_pixbuf_get_from_surface (surface,
|
||||
0, 0,
|
||||
width, height);
|
||||
cairo_surface_destroy (surface);
|
||||
return pix;
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
ClutterActor*
|
||||
gcal_event_overlay_new (void)
|
||||
{
|
||||
return g_object_new (GCAL_TYPE_EVENT_OVERLAY, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gcal_event_overlay_reset (GcalEventOverlay *widget)
|
||||
{
|
||||
GcalEventOverlayPrivate *priv;
|
||||
|
||||
g_return_if_fail (GCAL_IS_EVENT_OVERLAY (widget));
|
||||
priv = widget->priv;
|
||||
|
||||
if (priv->active_iter != NULL)
|
||||
{
|
||||
gtk_tree_iter_free (priv->active_iter);
|
||||
priv->active_iter = NULL;
|
||||
}
|
||||
if (priv->start_span != NULL)
|
||||
{
|
||||
g_free (priv->start_span);
|
||||
priv->start_span = NULL;
|
||||
}
|
||||
if (priv->end_span != NULL)
|
||||
{
|
||||
g_free (priv->end_span);
|
||||
priv->end_span = NULL;
|
||||
}
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (priv->title_label), _("New Event"));
|
||||
gtk_entry_set_text (GTK_ENTRY (priv->what_entry), "");
|
||||
|
||||
gtk_button_set_image (GTK_BUTTON (priv->calendar_button),
|
||||
gtk_image_new_from_icon_name ("x-office-calendar-symbolic",
|
||||
GTK_ICON_SIZE_MENU));
|
||||
}
|
||||
|
||||
/**
|
||||
* gcal_event_overlay_set_span:
|
||||
*
|
||||
* @widget: self
|
||||
* @start_date: The initial date
|
||||
* @end_date: The end date or NULL if the date is the same as the initial
|
||||
*/
|
||||
void
|
||||
gcal_event_overlay_set_span (GcalEventOverlay *widget,
|
||||
icaltimetype *start_date,
|
||||
icaltimetype *end_date)
|
||||
{
|
||||
GcalEventOverlayPrivate *priv;
|
||||
struct tm tm_date;
|
||||
gchar start[64];
|
||||
gchar end[64];
|
||||
gchar *title_date;
|
||||
icaltimetype *real_end_date;
|
||||
|
||||
g_return_if_fail (GCAL_IS_EVENT_OVERLAY (widget));
|
||||
priv = widget->priv;
|
||||
|
||||
if (priv->start_span == NULL)
|
||||
priv->start_span = gcal_dup_icaltime (start_date);
|
||||
else
|
||||
*(priv->start_span) = *start_date;
|
||||
|
||||
real_end_date = end_date == NULL ? start_date : end_date;
|
||||
if (priv->end_span == NULL)
|
||||
priv->end_span = gcal_dup_icaltime (real_end_date);
|
||||
else
|
||||
*(priv->end_span) = *real_end_date;
|
||||
|
||||
/* Updating labels */
|
||||
/* TODO: add as many posibles fixes for cases here, since this is when we
|
||||
* format the dates for the label */
|
||||
tm_date = icaltimetype_to_tm (start_date);
|
||||
e_utf8_strftime_fix_am_pm (start, 64, "%B %d", &tm_date);
|
||||
|
||||
if (end_date == NULL)
|
||||
{
|
||||
title_date = g_strdup_printf (_("New Event on %s"), start);
|
||||
}
|
||||
else
|
||||
{
|
||||
tm_date = icaltimetype_to_tm (real_end_date);
|
||||
|
||||
/* Fix 1: Not repeating the month */
|
||||
if (start_date->month == end_date->month &&
|
||||
start_date->year == end_date->year)
|
||||
{
|
||||
e_utf8_strftime_fix_am_pm (end, 64, "%d", &tm_date);
|
||||
}
|
||||
else
|
||||
{
|
||||
e_utf8_strftime_fix_am_pm (end, 64, "%B %d", &tm_date);
|
||||
}
|
||||
|
||||
title_date = g_strdup_printf (_("New Event from %s to %s"),
|
||||
start,
|
||||
end);
|
||||
}
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (priv->title_label), title_date);
|
||||
g_free (title_date);
|
||||
}
|
||||
|
||||
void
|
||||
gcal_event_overlay_set_sources_model (GcalEventOverlay *widget,
|
||||
GtkListStore *sources_model)
|
||||
{
|
||||
GcalEventOverlayPrivate *priv;
|
||||
|
||||
g_return_if_fail (GCAL_IS_EVENT_OVERLAY (widget));
|
||||
g_return_if_fail (GTK_IS_LIST_STORE (sources_model));
|
||||
priv = widget->priv;
|
||||
|
||||
priv->sources_model = sources_model;
|
||||
|
||||
gcal_event_overlay_set_calendars_menu (widget);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* gcal-event-overlay.h
|
||||
* Copyright (C) 2012 Erick Pérez Castellanos <erickpc@gnome.org>
|
||||
*
|
||||
* gnome-calendar is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* gnome-calendar is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GCAL_EVENT_OVERLAY_H__
|
||||
#define __GCAL_EVENT_OVERLAY_H__
|
||||
|
||||
#include <clutter-gtk/clutter-gtk.h>
|
||||
#include <icaltime.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GcalNewEventData GcalNewEventData;
|
||||
|
||||
struct _GcalNewEventData
|
||||
{
|
||||
icaltimetype *start_date;
|
||||
icaltimetype *end_date;
|
||||
gchar *calendar_uid;
|
||||
gchar *summary;
|
||||
};
|
||||
|
||||
#define GCAL_TYPE_EVENT_OVERLAY (gcal_event_overlay_get_type ())
|
||||
#define GCAL_EVENT_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GCAL_TYPE_EVENT_OVERLAY, GcalEventOverlay))
|
||||
#define GCAL_EVENT_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GCAL_TYPE_EVENT_OVERLAY, GcalEventOverlayClass))
|
||||
#define GCAL_IS_EVENT_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GCAL_TYPE_EVENT_OVERLAY))
|
||||
#define GCAL_IS_EVENT_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GCAL_TYPE_EVENT_OVERLAY))
|
||||
#define GCAL_EVENT_OVERLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GCAL_TYPE_EVENT_OVERLAY, GcalEventOverlayClass))
|
||||
|
||||
typedef struct _GcalEventOverlay GcalEventOverlay;
|
||||
typedef struct _GcalEventOverlayClass GcalEventOverlayClass;
|
||||
typedef struct _GcalEventOverlayPrivate GcalEventOverlayPrivate;
|
||||
|
||||
struct _GcalEventOverlay
|
||||
{
|
||||
GtkClutterActor parent;
|
||||
|
||||
GcalEventOverlayPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GcalEventOverlayClass
|
||||
{
|
||||
GtkClutterActorClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
void (*cancelled) (GcalEventOverlay *widget);
|
||||
void (*created) (GcalEventOverlay *widget, GcalNewEventData *new_data, gboolean open_details);
|
||||
};
|
||||
|
||||
|
||||
GType gcal_event_overlay_get_type (void);
|
||||
|
||||
ClutterActor* gcal_event_overlay_new (void);
|
||||
|
||||
void gcal_event_overlay_reset (GcalEventOverlay *widget);
|
||||
|
||||
void gcal_event_overlay_set_span (GcalEventOverlay *widget,
|
||||
icaltimetype *start_date,
|
||||
icaltimetype *end_date);
|
||||
|
||||
void gcal_event_overlay_set_sources_model (GcalEventOverlay *widget,
|
||||
GtkListStore *sources_model);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GCAL_EVENT_OVERLAY_H__ */
|
||||
@@ -1 +1,2 @@
|
||||
VOID:POINTER,POINTER,DOUBLE,DOUBLE
|
||||
VOID:POINTER,BOOLEAN
|
||||
|
||||
+364
-89
@@ -27,12 +27,6 @@
|
||||
|
||||
#include <libecal/libecal.h>
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_DATE //active-date inherited property
|
||||
};
|
||||
|
||||
struct _GcalViewChild
|
||||
{
|
||||
GtkWidget *widget;
|
||||
@@ -55,12 +49,26 @@ struct _GcalMonthViewPrivate
|
||||
|
||||
gint clicked_cell;
|
||||
|
||||
gint selected_cell;
|
||||
gint start_mark_cell;
|
||||
gint end_mark_cell;
|
||||
|
||||
gint actual_day_cell;
|
||||
gint days_delay;
|
||||
|
||||
/* property */
|
||||
icaltimetype *date;
|
||||
|
||||
/* helpers */
|
||||
GdkRectangle *prev_rectangle;
|
||||
GdkRectangle *next_rectangle;
|
||||
gboolean clicked_prev;
|
||||
gboolean clicked_next;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_DATE //active-date inherited property
|
||||
};
|
||||
|
||||
static void gcal_view_interface_init (GcalViewIface *iface);
|
||||
@@ -94,6 +102,9 @@ static gboolean gcal_month_view_draw (GtkWidget *wid
|
||||
static gboolean gcal_month_view_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event);
|
||||
|
||||
static gboolean gcal_month_view_motion_notify_event (GtkWidget *widget,
|
||||
GdkEventMotion *event);
|
||||
|
||||
static gboolean gcal_month_view_button_release (GtkWidget *widget,
|
||||
GdkEventButton *event);
|
||||
|
||||
@@ -136,6 +147,8 @@ static void gcal_month_view_remove_by_uuid (GcalView *vie
|
||||
static GtkWidget* gcal_month_view_get_by_uuid (GcalView *view,
|
||||
const gchar *uuid);
|
||||
|
||||
static void gcal_month_view_clear_selection (GcalView *view);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GcalMonthView,
|
||||
gcal_month_view,
|
||||
GTK_TYPE_CONTAINER,
|
||||
@@ -163,6 +176,7 @@ gcal_month_view_class_init (GcalMonthViewClass *klass)
|
||||
widget_class->size_allocate = gcal_month_view_size_allocate;
|
||||
widget_class->draw = gcal_month_view_draw;
|
||||
widget_class->button_press_event = gcal_month_view_button_press;
|
||||
widget_class->motion_notify_event = gcal_month_view_motion_notify_event;
|
||||
widget_class->button_release_event = gcal_month_view_button_release;
|
||||
|
||||
object_class = G_OBJECT_CLASS (klass);
|
||||
@@ -190,6 +204,17 @@ gcal_month_view_init (GcalMonthView *self)
|
||||
GcalMonthViewPrivate);
|
||||
priv = self->priv;
|
||||
|
||||
priv->clicked_cell = -1;
|
||||
|
||||
priv->start_mark_cell = -1;
|
||||
priv->end_mark_cell = -1;
|
||||
|
||||
priv->prev_rectangle = NULL;
|
||||
priv->next_rectangle = NULL;
|
||||
|
||||
priv->clicked_prev = FALSE;
|
||||
priv->clicked_next = FALSE;
|
||||
|
||||
for (i = 0; i < 35; i++)
|
||||
{
|
||||
priv->days[i] = NULL;
|
||||
@@ -209,6 +234,8 @@ gcal_view_interface_init (GcalViewIface *iface)
|
||||
iface->contains = gcal_month_view_contains;
|
||||
iface->remove_by_uuid = gcal_month_view_remove_by_uuid;
|
||||
iface->get_by_uuid = gcal_month_view_get_by_uuid;
|
||||
|
||||
iface->clear_selection = gcal_month_view_clear_selection;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -261,6 +288,11 @@ gcal_month_view_finalize (GObject *object)
|
||||
if (priv->date != NULL)
|
||||
g_free (priv->date);
|
||||
|
||||
if (priv->prev_rectangle != NULL)
|
||||
g_free (priv->prev_rectangle);
|
||||
if (priv->next_rectangle != NULL)
|
||||
g_free (priv->next_rectangle);
|
||||
|
||||
/* Chain up to parent's finalize() method. */
|
||||
G_OBJECT_CLASS (gcal_month_view_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -468,38 +500,97 @@ gcal_month_view_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
GcalMonthViewPrivate *priv;
|
||||
GtkStyleContext *context;
|
||||
GtkStateFlags state;
|
||||
GtkBorder padding;
|
||||
gint x, y;
|
||||
gdouble x, y;
|
||||
gint width, height;
|
||||
gdouble start_grid_y;
|
||||
|
||||
priv = GCAL_MONTH_VIEW (widget)->priv;
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
state = gtk_widget_get_state_flags (widget);
|
||||
gtk_style_context_get_padding (context, state, &padding);
|
||||
|
||||
x = event->x;
|
||||
y = event->y;
|
||||
if (event->window != priv->event_window)
|
||||
{
|
||||
gpointer source_widget;
|
||||
gdk_window_get_user_data (event->window, &source_widget);
|
||||
gtk_widget_translate_coordinates (GTK_WIDGET (source_widget),
|
||||
widget,
|
||||
event->x,
|
||||
event->y,
|
||||
&x,
|
||||
&y);
|
||||
}
|
||||
|
||||
//FIXME calculations for clicks, if needed
|
||||
width = gtk_widget_get_allocated_width (widget);
|
||||
height = gtk_widget_get_allocated_height (widget);
|
||||
start_grid_y = gcal_month_view_get_start_grid_y (widget);
|
||||
|
||||
if (y - start_grid_y < 0)
|
||||
{
|
||||
if (priv->prev_rectangle->x < x &&
|
||||
x < priv->prev_rectangle->x + priv->prev_rectangle->width &&
|
||||
priv->prev_rectangle->y < y &&
|
||||
y < priv->prev_rectangle->y + priv->prev_rectangle->height)
|
||||
{
|
||||
priv->clicked_prev = TRUE;
|
||||
}
|
||||
else if (priv->next_rectangle->x < x &&
|
||||
x < priv->next_rectangle->x + priv->next_rectangle->width &&
|
||||
priv->next_rectangle->y < y &&
|
||||
y < priv->next_rectangle->y + priv->next_rectangle->height)
|
||||
{
|
||||
priv->clicked_next = TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
y = y - start_grid_y;
|
||||
|
||||
priv->clicked_cell = 7 * ( (gint ) ( y / ((height - start_grid_y) / 5) )) + ((gint) ( x / (width / 7) ));
|
||||
priv->start_mark_cell = priv->clicked_cell;
|
||||
|
||||
if (event->type == GDK_2BUTTON_PRESS)
|
||||
{
|
||||
icaltimetype *start_date;
|
||||
|
||||
priv->end_mark_cell = priv->start_mark_cell;
|
||||
x = (width / 7) * (( priv->start_mark_cell % 7) + 0.5);
|
||||
y = start_grid_y + ((height - start_grid_y) / 5) * (( priv->start_mark_cell / 7) + 0.5);
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
start_date = gcal_dup_icaltime (priv->date);
|
||||
start_date->day = priv->start_mark_cell + priv->days_delay;
|
||||
|
||||
g_signal_emit_by_name (GCAL_VIEW (widget),
|
||||
"create-event",
|
||||
start_date, NULL,
|
||||
x, y);
|
||||
g_free (start_date);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gcal_month_view_motion_notify_event (GtkWidget *widget,
|
||||
GdkEventMotion *event)
|
||||
{
|
||||
GcalMonthViewPrivate *priv;
|
||||
gint width, height;
|
||||
gint y;
|
||||
gdouble start_grid_y;
|
||||
|
||||
priv = GCAL_MONTH_VIEW (widget)->priv;
|
||||
|
||||
if (priv->clicked_cell == -1)
|
||||
return FALSE;
|
||||
|
||||
width = gtk_widget_get_allocated_width (widget);
|
||||
height = gtk_widget_get_allocated_height (widget);
|
||||
start_grid_y = gcal_month_view_get_start_grid_y (widget);
|
||||
|
||||
y = event->y - start_grid_y;
|
||||
if (y < 0)
|
||||
return FALSE;
|
||||
|
||||
priv->end_mark_cell = 7 * ( (gint ) ( y / ((height - start_grid_y) / 5) )) + ((gint) ( event->x / (width / 7) ));
|
||||
if (priv->end_mark_cell == priv->start_mark_cell)
|
||||
{
|
||||
priv->end_mark_cell = -1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -509,54 +600,93 @@ gcal_month_view_button_release (GtkWidget *widget,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
GcalMonthViewPrivate *priv;
|
||||
GtkStyleContext *context;
|
||||
GtkStateFlags state;
|
||||
GtkBorder padding;
|
||||
gint x, y;
|
||||
gdouble x, y;
|
||||
gint width, height;
|
||||
gdouble start_grid_y;
|
||||
gint released;
|
||||
|
||||
icaltimetype *new_date;
|
||||
|
||||
priv = GCAL_MONTH_VIEW (widget)->priv;
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
state = gtk_widget_get_state_flags (widget);
|
||||
|
||||
gtk_style_context_get_padding (context, state, &padding);
|
||||
|
||||
x = event->x;
|
||||
y = event->y;
|
||||
if (event->window != priv->event_window)
|
||||
{
|
||||
gpointer source_widget;
|
||||
gdk_window_get_user_data (event->window, &source_widget);
|
||||
gtk_widget_translate_coordinates (GTK_WIDGET (source_widget),
|
||||
widget,
|
||||
event->x,
|
||||
event->y,
|
||||
&x,
|
||||
&y);
|
||||
}
|
||||
|
||||
//FIXME calculations for clicks, if needed
|
||||
width = gtk_widget_get_allocated_width (widget);
|
||||
height = gtk_widget_get_allocated_height (widget);
|
||||
start_grid_y = gcal_month_view_get_start_grid_y (widget);
|
||||
|
||||
if (y - start_grid_y < 0)
|
||||
{
|
||||
if (priv->prev_rectangle->x < x &&
|
||||
x < priv->prev_rectangle->x + priv->prev_rectangle->width &&
|
||||
priv->prev_rectangle->y < y &&
|
||||
y < priv->prev_rectangle->y + priv->prev_rectangle->height &&
|
||||
priv->clicked_prev)
|
||||
{
|
||||
icaltimetype *prev_month;
|
||||
prev_month = gcal_view_get_date (GCAL_VIEW (widget));
|
||||
icaltime_adjust (prev_month,
|
||||
- icaltime_days_in_month (prev_month->month,
|
||||
prev_month->year),
|
||||
0, 0, 0);
|
||||
|
||||
g_signal_emit_by_name (GCAL_VIEW (widget), "updated", prev_month);
|
||||
|
||||
g_free (prev_month);
|
||||
}
|
||||
else if (priv->next_rectangle->x < x &&
|
||||
x < priv->next_rectangle->x + priv->next_rectangle->width &&
|
||||
priv->next_rectangle->y < y &&
|
||||
y < priv->next_rectangle->y + priv->next_rectangle->height &&
|
||||
priv->clicked_next)
|
||||
{
|
||||
icaltimetype *next_month;
|
||||
next_month = gcal_view_get_date (GCAL_VIEW (widget));
|
||||
|
||||
icaltime_adjust (next_month,
|
||||
icaltime_days_in_month (next_month->month,
|
||||
next_month->year),
|
||||
0, 0, 0);
|
||||
|
||||
g_signal_emit_by_name (GCAL_VIEW (widget), "updated", next_month);
|
||||
|
||||
g_free (next_month);
|
||||
}
|
||||
|
||||
priv->clicked_cell = -1;
|
||||
priv->clicked_prev = FALSE;
|
||||
priv->clicked_next = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
y = y - start_grid_y;
|
||||
|
||||
released = 7 * ( (gint ) ( y / ((height - start_grid_y) / 5) )) + ((gint) ( x / (width / 7) ));
|
||||
|
||||
if (priv->clicked_cell == released)
|
||||
if (priv->clicked_cell != released)
|
||||
{
|
||||
priv->selected_cell = priv->clicked_cell;
|
||||
priv->clicked_cell = -1;
|
||||
gtk_widget_queue_resize (widget);
|
||||
icaltimetype *start_date;
|
||||
icaltimetype *end_date;
|
||||
|
||||
new_date = gcal_dup_icaltime (priv->date);
|
||||
new_date->day = priv->selected_cell + priv->days_delay;
|
||||
gcal_view_set_date (GCAL_VIEW (widget), new_date);
|
||||
g_free (new_date);
|
||||
x = (width / 7) * (( priv->end_mark_cell % 7) + 0.5);
|
||||
y = start_grid_y + ((height - start_grid_y) / 5) * (( priv->end_mark_cell / 7) + 0.5);
|
||||
|
||||
start_date = gcal_dup_icaltime (priv->date);
|
||||
start_date->day = priv->start_mark_cell + priv->days_delay;
|
||||
|
||||
end_date = gcal_dup_icaltime (priv->date);
|
||||
end_date->day = priv->end_mark_cell + priv->days_delay;
|
||||
|
||||
g_signal_emit_by_name (GCAL_VIEW (widget),
|
||||
"create-event",
|
||||
start_date, end_date,
|
||||
x, y);
|
||||
g_free (start_date);
|
||||
g_free (end_date);
|
||||
}
|
||||
|
||||
priv->clicked_cell = -1;
|
||||
priv->clicked_prev = FALSE;
|
||||
priv->clicked_next = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -610,28 +740,28 @@ gcal_month_view_remove (GtkContainer *container,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GcalMonthViewPrivate *priv;
|
||||
icaltimetype *date;
|
||||
gint day;
|
||||
gint i;
|
||||
GList *l;
|
||||
|
||||
g_return_if_fail (GCAL_IS_MONTH_VIEW (container));
|
||||
g_return_if_fail (gtk_widget_get_parent (widget) == GTK_WIDGET (container));
|
||||
priv = GCAL_MONTH_VIEW (container)->priv;
|
||||
|
||||
date = gcal_event_widget_get_date (GCAL_EVENT_WIDGET (widget));
|
||||
day = date->day + ( - priv->days_delay);
|
||||
g_free (date);
|
||||
|
||||
for (l = priv->days[day]; l != NULL; l = l->next)
|
||||
for (i = 0; i < 35; i++)
|
||||
{
|
||||
GcalViewChild *child;
|
||||
|
||||
child = (GcalViewChild*) l->data;
|
||||
if (child->widget == widget)
|
||||
for (l = priv->days[i]; l != NULL; l = l->next)
|
||||
{
|
||||
priv->days[day] = g_list_remove (priv->days[day], child);
|
||||
g_free (child);
|
||||
break;
|
||||
GcalViewChild *child;
|
||||
|
||||
child = (GcalViewChild*) l->data;
|
||||
if (child->widget == widget)
|
||||
{
|
||||
priv->days[i] = g_list_remove (priv->days[i], child);
|
||||
g_free (child);
|
||||
|
||||
i = 36;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
gtk_widget_unparent (widget);
|
||||
@@ -690,13 +820,13 @@ gcal_month_view_set_date (GcalMonthView *view,
|
||||
g_free (first_of_month);
|
||||
|
||||
/* if have_selection: yes this one have */
|
||||
priv->selected_cell = priv->date->day - priv->days_delay;
|
||||
priv->actual_day_cell = priv->date->day - priv->days_delay;
|
||||
|
||||
if (will_resize)
|
||||
{
|
||||
to_remove = NULL;
|
||||
|
||||
for (i = 0; i < 34; i++)
|
||||
for (i = 0; i < 35; i++)
|
||||
{
|
||||
for (l = priv->days[i]; l != NULL; l = l->next)
|
||||
{
|
||||
@@ -713,6 +843,7 @@ gcal_month_view_set_date (GcalMonthView *view,
|
||||
g_list_foreach (to_remove, (GFunc) gtk_widget_destroy, NULL);
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (view));
|
||||
gtk_widget_queue_draw (GTK_WIDGET (view));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -726,9 +857,12 @@ gcal_month_view_draw_header (GcalMonthView *view,
|
||||
GtkStyleContext *context;
|
||||
GtkStateFlags state;
|
||||
GdkRGBA color;
|
||||
GtkBorder header_padding;
|
||||
|
||||
PangoLayout *layout;
|
||||
gint layout_width;
|
||||
gint header_width;
|
||||
gint layout_height;
|
||||
|
||||
gchar *left_header;
|
||||
gchar *right_header;
|
||||
@@ -736,6 +870,9 @@ gcal_month_view_draw_header (GcalMonthView *view,
|
||||
|
||||
struct tm tm_date;
|
||||
|
||||
GtkIconTheme *icon_theme;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
g_return_if_fail (GCAL_IS_MONTH_VIEW (view));
|
||||
priv = view->priv;
|
||||
|
||||
@@ -745,6 +882,8 @@ gcal_month_view_draw_header (GcalMonthView *view,
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_region (context, "header", 0);
|
||||
|
||||
gtk_style_context_get_padding (context, state, &header_padding);
|
||||
|
||||
gtk_style_context_get_color (context, state, &color);
|
||||
cairo_set_source_rgb (cr, color.red, color.green, color.blue);
|
||||
|
||||
@@ -752,9 +891,14 @@ gcal_month_view_draw_header (GcalMonthView *view,
|
||||
pango_layout_set_font_description (layout,
|
||||
gtk_style_context_get_font (context,
|
||||
state));
|
||||
gtk_style_context_remove_region (context, "header");
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
/* Here translators should put the widgest letter in their alphabet, this
|
||||
* taken to make it align with week-view header */
|
||||
pango_layout_set_text (layout, _("WWW 99 - WWW 99"), -1);
|
||||
pango_cairo_update_layout (cr, layout);
|
||||
pango_layout_get_pixel_size (layout, &layout_width, &layout_height);
|
||||
|
||||
tm_date = icaltimetype_to_tm (priv->date);
|
||||
e_utf8_strftime_fix_am_pm (str_date, 64, "%B", &tm_date);
|
||||
|
||||
@@ -763,10 +907,56 @@ gcal_month_view_draw_header (GcalMonthView *view,
|
||||
|
||||
pango_layout_set_text (layout, left_header, -1);
|
||||
pango_cairo_update_layout (cr, layout);
|
||||
pango_layout_get_pixel_size (layout, &header_width, NULL);
|
||||
|
||||
cairo_move_to (cr, alloc->x + padding->left, alloc->y + padding->top);
|
||||
cairo_move_to (cr,
|
||||
alloc->x + header_padding.left + ((layout_width - header_width) / 2),
|
||||
alloc->y + header_padding.top);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
|
||||
/* Drawing arrows */
|
||||
icon_theme = gtk_icon_theme_get_default ();
|
||||
pixbuf = gtk_icon_theme_load_icon (icon_theme,
|
||||
"go-previous-symbolic",
|
||||
layout_height,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
gdk_cairo_set_source_pixbuf (cr,
|
||||
pixbuf,
|
||||
alloc->x + layout_width + 2 * header_padding.left,
|
||||
alloc->y + header_padding.top);
|
||||
g_object_unref (pixbuf);
|
||||
cairo_paint (cr);
|
||||
|
||||
pixbuf = gtk_icon_theme_load_icon (icon_theme,
|
||||
"go-next-symbolic",
|
||||
layout_height,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
gdk_cairo_set_source_pixbuf (cr,
|
||||
pixbuf,
|
||||
alloc->x + layout_width + 2 * header_padding.left + layout_height,
|
||||
alloc->y + header_padding.top);
|
||||
g_object_unref (pixbuf);
|
||||
cairo_paint (cr);
|
||||
|
||||
/* allocating rects */
|
||||
if (priv->prev_rectangle == NULL)
|
||||
priv->prev_rectangle = g_new0 (GdkRectangle, 1);
|
||||
priv->prev_rectangle->x = alloc->x + layout_width + 2 * header_padding.left;
|
||||
priv->prev_rectangle->y = alloc->y + header_padding.top;
|
||||
priv->prev_rectangle->width = layout_height;
|
||||
priv->prev_rectangle->height = layout_height;
|
||||
|
||||
if (priv->next_rectangle == NULL)
|
||||
priv->next_rectangle = g_new0 (GdkRectangle, 1);
|
||||
priv->next_rectangle->x = alloc->x + layout_width + 2 * header_padding.left + layout_height;
|
||||
priv->next_rectangle->y = alloc->y + header_padding.top;
|
||||
priv->next_rectangle->width = layout_height;
|
||||
priv->next_rectangle->height = layout_height;
|
||||
|
||||
gtk_style_context_get_color (context,
|
||||
state | GTK_STATE_FLAG_INSENSITIVE,
|
||||
&color);
|
||||
@@ -777,8 +967,8 @@ gcal_month_view_draw_header (GcalMonthView *view,
|
||||
pango_layout_get_pixel_size (layout, &layout_width, NULL);
|
||||
|
||||
cairo_move_to (cr,
|
||||
alloc->width - padding->right - layout_width,
|
||||
alloc->y + padding->top);
|
||||
alloc->width - header_padding.right - layout_width,
|
||||
alloc->y + header_padding.top);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
|
||||
g_free (left_header);
|
||||
@@ -800,6 +990,8 @@ gcal_month_view_draw_grid (GcalMonthView *view,
|
||||
GdkRGBA color;
|
||||
GdkRGBA ligther_color;
|
||||
GdkRGBA selected_color;
|
||||
GdkRGBA background_selected_color;
|
||||
GtkBorder header_padding;
|
||||
|
||||
gint i, j;
|
||||
gint font_width;
|
||||
@@ -829,6 +1021,10 @@ gcal_month_view_draw_grid (GcalMonthView *view,
|
||||
&selected_color);
|
||||
selected_font = gtk_style_context_get_font (context, state);
|
||||
|
||||
gtk_style_context_get_background_color (context,
|
||||
state | GTK_STATE_FLAG_SELECTED,
|
||||
&background_selected_color);
|
||||
|
||||
gtk_style_context_get_color (context,
|
||||
state | GTK_STATE_FLAG_INSENSITIVE,
|
||||
&ligther_color);
|
||||
@@ -841,6 +1037,69 @@ gcal_month_view_draw_grid (GcalMonthView *view,
|
||||
n_days_in_month = icaltime_days_in_month (priv->date->month,
|
||||
priv->date->year);
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_region (context, "header", 0);
|
||||
|
||||
gtk_style_context_get_padding (context, state, &header_padding);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
/* drawing new-event mark */
|
||||
if (priv->start_mark_cell != -1 &&
|
||||
priv->end_mark_cell != -1)
|
||||
{
|
||||
gint first_cell;
|
||||
gint last_cell;
|
||||
gint rows;
|
||||
|
||||
cairo_save (cr);
|
||||
if (priv->start_mark_cell < priv->end_mark_cell)
|
||||
{
|
||||
first_cell = priv->start_mark_cell;
|
||||
last_cell = priv->end_mark_cell;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_cell = priv->end_mark_cell;
|
||||
last_cell = priv->start_mark_cell;
|
||||
}
|
||||
|
||||
cairo_set_source_rgba (cr,
|
||||
background_selected_color.red,
|
||||
background_selected_color.green,
|
||||
background_selected_color.blue,
|
||||
background_selected_color.alpha);
|
||||
|
||||
for (rows = 0; rows < (last_cell / 7) - (first_cell / 7) + 1; rows++)
|
||||
{
|
||||
gint first_point;
|
||||
gint last_point;
|
||||
|
||||
first_point = (rows == 0) ? first_cell : ((first_cell / 7) + rows) * 7;
|
||||
cairo_move_to (
|
||||
cr,
|
||||
(alloc->width / 7) * ( first_point % 7),
|
||||
start_grid_y + ((alloc->height - start_grid_y) / 5) * ( first_point / 7) + 1);
|
||||
|
||||
last_point = (rows == (last_cell / 7 - first_cell / 7)) ? last_cell : ((first_cell / 7) + rows) * 7 + 6;
|
||||
cairo_rel_line_to (cr,
|
||||
(alloc->width / 7) * (last_point - first_point + 1),
|
||||
0);
|
||||
cairo_rel_line_to (cr,
|
||||
0,
|
||||
(alloc->height - start_grid_y) / 5);
|
||||
cairo_rel_line_to (cr,
|
||||
- (alloc->width / 7) * (last_point - first_point + 1),
|
||||
0);
|
||||
cairo_rel_line_to (cr,
|
||||
0,
|
||||
- (alloc->height - start_grid_y) / 5);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
/* drawing grid text */
|
||||
bold_font = pango_font_description_copy (font);
|
||||
pango_font_description_set_weight (bold_font, PANGO_WEIGHT_SEMIBOLD);
|
||||
@@ -853,9 +1112,8 @@ gcal_month_view_draw_grid (GcalMonthView *view,
|
||||
pango_cairo_update_layout (cr, layout);
|
||||
pango_layout_get_pixel_size (layout, &font_width, &font_height);
|
||||
|
||||
/* 6: is padding around the grid-header */
|
||||
cairo_move_to (cr,
|
||||
(alloc->width / 7) * i + padding->left,
|
||||
(alloc->width / 7) * i + header_padding.left,
|
||||
start_grid_y - padding->bottom - font_height);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
|
||||
@@ -873,7 +1131,7 @@ gcal_month_view_draw_grid (GcalMonthView *view,
|
||||
continue;
|
||||
|
||||
/* drawing selected_day */
|
||||
if (priv->selected_cell == n_day - 1)
|
||||
if (priv->actual_day_cell == n_day - priv->days_delay)
|
||||
{
|
||||
cairo_set_source_rgb (cr,
|
||||
selected_color.red,
|
||||
@@ -888,12 +1146,12 @@ gcal_month_view_draw_grid (GcalMonthView *view,
|
||||
pango_layout_get_pixel_size (layout, &font_width, NULL);
|
||||
cairo_move_to (
|
||||
cr,
|
||||
(alloc->width / 7) * i + padding->left,
|
||||
(alloc->width / 7) * i + header_padding.left,
|
||||
start_grid_y + ((alloc->height - start_grid_y) / 5) * j + padding->top);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
|
||||
/* unsetting selected flag */
|
||||
if (priv->selected_cell == n_day - 1)
|
||||
if (priv->actual_day_cell == n_day - priv->days_delay)
|
||||
{
|
||||
cairo_set_source_rgb (cr,
|
||||
ligther_color.red,
|
||||
@@ -931,7 +1189,7 @@ gcal_month_view_draw_grid (GcalMonthView *view,
|
||||
|
||||
cairo_stroke (cr);
|
||||
|
||||
/* drawing selected_cell */
|
||||
/* drawing actual_day_cell */
|
||||
//FIXME: What to do when the selected date isn't on the in the month
|
||||
cairo_set_source_rgb (cr,
|
||||
selected_color.red,
|
||||
@@ -941,10 +1199,11 @@ gcal_month_view_draw_grid (GcalMonthView *view,
|
||||
/* Two pixel line on the selected day cell */
|
||||
cairo_set_line_width (cr, 2.0);
|
||||
cairo_move_to (cr,
|
||||
(alloc->width / 7) * ( priv->selected_cell % 7),
|
||||
start_grid_y + ((alloc->height - start_grid_y) / 5) * ( priv->selected_cell / 7) + 1);
|
||||
(alloc->width / 7) * ( priv->actual_day_cell % 7),
|
||||
start_grid_y + ((alloc->height - start_grid_y) / 5) * ( priv->actual_day_cell / 7) + 1);
|
||||
cairo_rel_line_to (cr, (alloc->width / 7), 0);
|
||||
cairo_stroke (cr);
|
||||
|
||||
}
|
||||
|
||||
static gdouble
|
||||
@@ -952,6 +1211,7 @@ gcal_month_view_get_start_grid_y (GtkWidget *widget)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GtkBorder padding;
|
||||
GtkBorder header_padding;
|
||||
|
||||
PangoLayout *layout;
|
||||
gint font_height;
|
||||
@@ -964,6 +1224,10 @@ gcal_month_view_get_start_grid_y (GtkWidget *widget)
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_region (context, "header", 0);
|
||||
|
||||
gtk_style_context_get_padding (gtk_widget_get_style_context (widget),
|
||||
gtk_widget_get_state_flags (widget),
|
||||
&header_padding);
|
||||
|
||||
pango_layout_set_font_description (
|
||||
layout,
|
||||
gtk_style_context_get_font (context,
|
||||
@@ -971,8 +1235,7 @@ gcal_month_view_get_start_grid_y (GtkWidget *widget)
|
||||
pango_layout_get_pixel_size (layout, NULL, &font_height);
|
||||
|
||||
/* 6: is padding around the header */
|
||||
start_grid_y = font_height;
|
||||
gtk_style_context_remove_region (context, "header");
|
||||
start_grid_y = header_padding.top + font_height + header_padding.bottom;
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
/* init grid values */
|
||||
@@ -986,7 +1249,7 @@ gcal_month_view_get_start_grid_y (GtkWidget *widget)
|
||||
gtk_widget_get_state_flags (widget),
|
||||
&padding);
|
||||
|
||||
start_grid_y += 3 * padding.top + font_height;
|
||||
start_grid_y += padding.top + font_height;
|
||||
g_object_unref (layout);
|
||||
return start_grid_y;
|
||||
}
|
||||
@@ -1046,8 +1309,8 @@ gcal_month_view_contains (GcalView *view,
|
||||
|
||||
if (priv->date == NULL)
|
||||
return FALSE;
|
||||
if (priv->date->month == date->month
|
||||
|| priv->date->year == date->year)
|
||||
if (priv->date->month == date->month &&
|
||||
priv->date->year == date->year)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1114,6 +1377,18 @@ gcal_month_view_get_by_uuid (GcalView *view,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_month_view_clear_selection (GcalView *view)
|
||||
{
|
||||
GcalMonthViewPrivate *priv;
|
||||
|
||||
priv = GCAL_MONTH_VIEW (view)->priv;
|
||||
|
||||
priv->start_mark_cell = -1;
|
||||
priv->end_mark_cell = -1;
|
||||
gtk_widget_queue_draw (GTK_WIDGET (view));
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
/**
|
||||
* gcal_month_view_new:
|
||||
|
||||
@@ -48,6 +48,9 @@ struct _GcalMonthView
|
||||
struct _GcalMonthViewClass
|
||||
{
|
||||
GtkContainerClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (*new_event) (gint new_day);
|
||||
};
|
||||
|
||||
GType gcal_month_view_get_type (void);
|
||||
|
||||
+246
-88
@@ -28,6 +28,7 @@
|
||||
#include "gcal-event-view.h"
|
||||
#include "gcal-enum-types.h"
|
||||
#include "gtk-notification.h"
|
||||
#include "gcal-event-overlay.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <clutter/clutter.h>
|
||||
@@ -45,10 +46,13 @@ struct _GcalWindowPrivate
|
||||
ClutterActor *sources_actor;
|
||||
ClutterActor *notification_actor;
|
||||
|
||||
ClutterActor *new_event_actor;
|
||||
|
||||
GtkWidget *notebook;
|
||||
GtkWidget *sources_view;
|
||||
GtkWidget *views [5];
|
||||
GtkWidget *add_view;
|
||||
GtkWidget *edit_dialog;
|
||||
GtkWidget *edit_widget;
|
||||
|
||||
GcalWindowViewType active_view;
|
||||
icaltimetype *active_date;
|
||||
@@ -85,7 +89,7 @@ static void gcal_window_set_active_view (GcalWindow *w
|
||||
|
||||
static void gcal_window_set_sources_view (GcalWindow *window);
|
||||
|
||||
static void gcal_window_init_event_view (GcalWindow *window);
|
||||
static void gcal_window_init_edit_dialog (GcalWindow *window);
|
||||
|
||||
static void gcal_window_view_changed (GcalToolbar *main_toolbar,
|
||||
GcalWindowViewType view_type,
|
||||
@@ -101,12 +105,6 @@ static void gcal_window_add_event (GcalToolbar *m
|
||||
static void gcal_window_back_last_view (GtkWidget *widget,
|
||||
gpointer user_data);
|
||||
|
||||
static void gcal_window_edit_event (GcalToolbar *main_toolbar,
|
||||
gpointer user_data);
|
||||
|
||||
static void gcal_window_done_edit_event (GcalToolbar *main_toolbar,
|
||||
gpointer user_data);
|
||||
|
||||
static void gcal_window_sources_row_activated (GtkTreeView *tree_view,
|
||||
GtkTreePath *path,
|
||||
GtkTreeViewColumn *column,
|
||||
@@ -133,6 +131,30 @@ static void gcal_window_remove_event (GtkNotification *n
|
||||
static void gcal_window_undo_remove_event (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
static void gcal_window_view_updated (GcalView *view,
|
||||
gpointer date,
|
||||
gpointer user_data);
|
||||
|
||||
static void gcal_window_event_overlay_shown (GcalView *view,
|
||||
gpointer start_span,
|
||||
gpointer end_span,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gpointer user_data);
|
||||
|
||||
static void gcal_window_event_overlay_closed (GcalEventOverlay *widget,
|
||||
gpointer user_data);
|
||||
|
||||
static void gcal_window_create_event (GcalEventOverlay *widget,
|
||||
GcalNewEventData *new_data,
|
||||
gboolean open_details,
|
||||
gpointer user_data);
|
||||
|
||||
static void gcal_window_show_hide_actor_cb (ClutterActor *actor,
|
||||
gchar *name,
|
||||
gboolean is_finished,
|
||||
gpointer user_data);
|
||||
|
||||
G_DEFINE_TYPE(GcalWindow, gcal_window, GTK_TYPE_APPLICATION_WINDOW)
|
||||
|
||||
static void
|
||||
@@ -195,10 +217,10 @@ gcal_window_constructed (GObject *object)
|
||||
|
||||
priv = GCAL_WINDOW (object)->priv;
|
||||
|
||||
/* internal data init*/
|
||||
/* internal data init */
|
||||
priv->event_to_delete = NULL;
|
||||
|
||||
/* FIXME: here read the data from somewehere */
|
||||
/* FIXME: here read the initial date from somewehere */
|
||||
priv->active_date = g_new (icaltimetype, 1);
|
||||
*(priv->active_date) = icaltime_from_timet (time (NULL), 0);
|
||||
|
||||
@@ -315,10 +337,13 @@ gcal_window_constructed (GObject *object)
|
||||
|
||||
/* notifications manager */
|
||||
priv->notification_actor = gtk_clutter_actor_new ();
|
||||
clutter_bin_layout_add (CLUTTER_BIN_LAYOUT (contents_layout_manager),
|
||||
priv->notification_actor,
|
||||
CLUTTER_BIN_ALIGNMENT_CENTER,
|
||||
CLUTTER_BIN_ALIGNMENT_START);
|
||||
g_object_set (priv->notification_actor,
|
||||
"x-expand", TRUE,
|
||||
"y-expand", TRUE,
|
||||
"x-align", CLUTTER_ACTOR_ALIGN_CENTER,
|
||||
"y-align", CLUTTER_ACTOR_ALIGN_START,
|
||||
NULL);
|
||||
clutter_actor_add_child (priv->contents_actor, priv->notification_actor);
|
||||
|
||||
context =
|
||||
gtk_widget_get_style_context (
|
||||
@@ -327,6 +352,23 @@ gcal_window_constructed (GObject *object)
|
||||
gtk_style_context_add_class (context, "overlay");
|
||||
clutter_actor_hide (priv->notification_actor);
|
||||
|
||||
/* event-overlay */
|
||||
priv->new_event_actor = gcal_event_overlay_new ();
|
||||
g_object_set (priv->new_event_actor,
|
||||
"opacity", 0,
|
||||
"x-align", CLUTTER_ACTOR_ALIGN_FILL,
|
||||
"y-align", CLUTTER_ACTOR_ALIGN_FILL,
|
||||
NULL);
|
||||
|
||||
context =
|
||||
gtk_widget_get_style_context (
|
||||
gtk_clutter_actor_get_widget (
|
||||
GTK_CLUTTER_ACTOR (priv->new_event_actor)));
|
||||
gtk_style_context_add_class (context, "overlay");
|
||||
|
||||
clutter_actor_add_child (priv->contents_actor, priv->new_event_actor);
|
||||
clutter_actor_hide (priv->new_event_actor);
|
||||
|
||||
/* signals connection/handling */
|
||||
g_signal_connect (priv->main_toolbar,
|
||||
"view-changed",
|
||||
@@ -346,13 +388,14 @@ gcal_window_constructed (GObject *object)
|
||||
G_CALLBACK (gcal_window_back_last_view),
|
||||
object);
|
||||
|
||||
g_signal_connect (priv->main_toolbar,
|
||||
"edit-event",
|
||||
G_CALLBACK (gcal_window_edit_event),
|
||||
g_signal_connect (priv->new_event_actor,
|
||||
"cancelled",
|
||||
G_CALLBACK (gcal_window_event_overlay_closed),
|
||||
object);
|
||||
g_signal_connect (priv->main_toolbar,
|
||||
"done-edit",
|
||||
G_CALLBACK (gcal_window_done_edit_event),
|
||||
|
||||
g_signal_connect (priv->new_event_actor,
|
||||
"created",
|
||||
G_CALLBACK (gcal_window_create_event),
|
||||
object);
|
||||
|
||||
gtk_widget_show (embed);
|
||||
@@ -466,10 +509,22 @@ gcal_window_set_active_view (GcalWindow *window,
|
||||
g_debug ("Unimplemented view yet");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Bindings properties and signals */
|
||||
g_object_bind_property (priv->views[view_type], "active-date",
|
||||
window, "active-date",
|
||||
G_BINDING_DEFAULT);
|
||||
|
||||
g_signal_connect (priv->views[view_type],
|
||||
"create-event",
|
||||
G_CALLBACK (gcal_window_event_overlay_shown),
|
||||
window);
|
||||
|
||||
g_signal_connect (priv->views[view_type],
|
||||
"updated",
|
||||
G_CALLBACK (gcal_window_view_updated),
|
||||
window);
|
||||
|
||||
priv->active_view = view_type;
|
||||
|
||||
gtk_widget_show (priv->views[priv->active_view]);
|
||||
@@ -485,7 +540,8 @@ gcal_window_set_active_view (GcalWindow *window,
|
||||
update_range = ! gcal_view_contains (GCAL_VIEW (priv->views[priv->active_view]),
|
||||
priv->active_date);
|
||||
|
||||
gcal_view_set_date (GCAL_VIEW (priv->views[priv->active_view]), priv->active_date);
|
||||
gcal_view_set_date (GCAL_VIEW (priv->views[priv->active_view]),
|
||||
priv->active_date);
|
||||
if (update_range)
|
||||
{
|
||||
first_day = gcal_view_get_initial_date (
|
||||
@@ -570,32 +626,46 @@ gcal_window_set_sources_view (GcalWindow *window)
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_window_init_event_view (GcalWindow *window)
|
||||
gcal_window_init_edit_dialog (GcalWindow *window)
|
||||
{
|
||||
GcalWindowPrivate *priv;
|
||||
GcalManager *manager;
|
||||
|
||||
GtkWidget *content_area;
|
||||
GtkWidget *action_area;
|
||||
|
||||
g_return_if_fail (GCAL_IS_WINDOW (window));
|
||||
priv = window->priv;
|
||||
|
||||
priv->add_view = gcal_event_view_new_with_manager (
|
||||
gcal_window_get_manager (window));
|
||||
g_object_set (priv->add_view,
|
||||
"hexpand", TRUE,
|
||||
"vexpand", TRUE,
|
||||
"margin-top", 10,
|
||||
"margin-left", 20,
|
||||
"margin-right", 20,
|
||||
NULL);
|
||||
priv->edit_dialog = gtk_dialog_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (priv->edit_dialog), _("Edit Event"));
|
||||
gtk_window_set_modal (GTK_WINDOW (priv->edit_dialog), TRUE);
|
||||
gtk_window_set_destroy_with_parent (GTK_WINDOW (priv->edit_dialog), TRUE);
|
||||
gtk_window_set_resizable (GTK_WINDOW (priv->edit_dialog), FALSE);
|
||||
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (priv->edit_dialog));
|
||||
manager = gcal_window_get_manager (window);
|
||||
|
||||
priv->edit_widget = gcal_event_view_new_with_manager (manager);
|
||||
gtk_container_add (GTK_CONTAINER (content_area),
|
||||
priv->edit_widget);
|
||||
|
||||
gtk_widget_show_all (content_area);
|
||||
|
||||
gtk_dialog_add_button (GTK_DIALOG (priv->edit_dialog),
|
||||
GTK_STOCK_CANCEL,
|
||||
GTK_RESPONSE_REJECT);
|
||||
gtk_dialog_add_button (GTK_DIALOG (priv->edit_dialog),
|
||||
_("Done"),
|
||||
GTK_RESPONSE_ACCEPT);
|
||||
action_area = gtk_dialog_get_action_area (GTK_DIALOG (priv->edit_dialog));
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (action_area), GTK_BUTTONBOX_EDGE);
|
||||
gtk_widget_show_all (action_area);
|
||||
/* FIXME: hook delete signal
|
||||
g_signal_connect (priv->add_view,
|
||||
"will-delete",
|
||||
G_CALLBACK (gcal_window_will_remove_event),
|
||||
window);
|
||||
|
||||
gtk_widget_show (priv->add_view);
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook),
|
||||
priv->add_view,
|
||||
NULL);
|
||||
window);*/
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -646,18 +716,11 @@ gcal_window_add_event (GcalToolbar *main_toolbar,
|
||||
GcalWindowPrivate *priv;
|
||||
|
||||
priv = GCAL_WINDOW (user_data)->priv;
|
||||
if (priv->add_view == NULL)
|
||||
gcal_window_init_event_view (GCAL_WINDOW (user_data));
|
||||
if (priv->edit_dialog == NULL)
|
||||
gcal_window_init_edit_dialog (GCAL_WINDOW (user_data));
|
||||
|
||||
//TODO: Reload/clean/reinitialize status
|
||||
gtk_notebook_set_current_page (
|
||||
GTK_NOTEBOOK (priv->notebook),
|
||||
gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), priv->add_view));
|
||||
|
||||
gcal_toolbar_set_mode (GCAL_TOOLBAR (priv->main_toolbar),
|
||||
GCAL_TOOLBAR_VIEW_EVENT);
|
||||
|
||||
gcal_event_view_load_new (GCAL_EVENT_VIEW (priv->add_view));
|
||||
/* FIXME: load
|
||||
gcal_event_view_load_new (GCAL_EVENT_VIEW (priv->add_view));*/
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -685,39 +748,11 @@ gcal_window_back_last_view (GtkWidget *widget,
|
||||
}
|
||||
else
|
||||
{
|
||||
//FIXME: there's something that needs to be done here.
|
||||
/* FIXME: there's something that needs to be done here. */
|
||||
g_warning ("Your app has gone crazy");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_window_edit_event (GcalToolbar *main_toolbar,
|
||||
gpointer user_data)
|
||||
{
|
||||
GcalWindowPrivate *priv;
|
||||
|
||||
priv = GCAL_WINDOW (user_data)->priv;
|
||||
if (priv->add_view == NULL)
|
||||
gcal_window_init_event_view (GCAL_WINDOW (user_data));
|
||||
|
||||
//FIXME: check here, maybe this isn't need since edit-event
|
||||
//can be triggered only from add_view
|
||||
gtk_notebook_set_current_page (
|
||||
GTK_NOTEBOOK (priv->notebook),
|
||||
gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), priv->add_view));
|
||||
gcal_event_view_enter_edit_mode (GCAL_EVENT_VIEW (priv->add_view));
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_window_done_edit_event (GcalToolbar *main_toolbar,
|
||||
gpointer user_data)
|
||||
{
|
||||
GcalWindowPrivate *priv;
|
||||
|
||||
priv = GCAL_WINDOW (user_data)->priv;
|
||||
gcal_event_view_leave_edit_mode (GCAL_EVENT_VIEW (priv->add_view));
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_window_sources_row_activated (GtkTreeView *tree_view,
|
||||
GtkTreePath *path,
|
||||
@@ -801,7 +836,8 @@ gcal_window_events_added (GcalManager *manager,
|
||||
event_uid));
|
||||
gtk_widget_show (event);
|
||||
|
||||
//FIXME: add event to every instantiated view
|
||||
/* FIXME: add event-widget to every instantiated view, not pretty sure
|
||||
* about this. */
|
||||
gtk_container_add (
|
||||
GTK_CONTAINER (priv->views[priv->active_view]),
|
||||
event);
|
||||
@@ -856,18 +892,14 @@ gcal_window_event_activated (GcalEventWidget *event_widget,
|
||||
g_return_if_fail (GCAL_IS_WINDOW (user_data));
|
||||
priv = GCAL_WINDOW (user_data)->priv;
|
||||
|
||||
if (priv->add_view == NULL)
|
||||
gcal_window_init_event_view (GCAL_WINDOW (user_data));
|
||||
if (priv->edit_dialog == NULL)
|
||||
gcal_window_init_edit_dialog (GCAL_WINDOW (user_data));
|
||||
|
||||
gtk_notebook_set_current_page (
|
||||
GTK_NOTEBOOK (priv->notebook),
|
||||
gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), priv->add_view));
|
||||
|
||||
gcal_event_view_load_event (GCAL_EVENT_VIEW (priv->add_view),
|
||||
gcal_event_view_load_event (GCAL_EVENT_VIEW (priv->edit_widget),
|
||||
gcal_event_widget_peek_uuid (event_widget));
|
||||
|
||||
gcal_toolbar_set_mode (GCAL_TOOLBAR (priv->main_toolbar),
|
||||
GCAL_TOOLBAR_VIEW_EVENT);
|
||||
gtk_dialog_run (GTK_DIALOG (priv->edit_dialog));
|
||||
gtk_widget_hide (priv->edit_dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -898,7 +930,7 @@ gcal_window_will_remove_event (GcalEventView *view,
|
||||
}
|
||||
else
|
||||
{
|
||||
//FIXME: there's something that needs to be done here.
|
||||
/* FIXME: there's something that needs to be done here. */
|
||||
g_warning ("Your app has gone crazy");
|
||||
}
|
||||
|
||||
@@ -983,6 +1015,132 @@ gcal_window_undo_remove_event (GtkButton *button,
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_window_view_updated (GcalView *view,
|
||||
gpointer date,
|
||||
gpointer user_data)
|
||||
{
|
||||
GcalWindowPrivate *priv;
|
||||
icaltimetype *first_day;
|
||||
icaltimetype *last_day;
|
||||
|
||||
priv = GCAL_WINDOW (user_data)->priv;
|
||||
|
||||
gcal_view_set_date (GCAL_VIEW (priv->views[priv->active_view]),
|
||||
date);
|
||||
|
||||
first_day = gcal_view_get_initial_date (
|
||||
GCAL_VIEW (priv->views[priv->active_view]));
|
||||
last_day = gcal_view_get_final_date (
|
||||
GCAL_VIEW (priv->views[priv->active_view]));
|
||||
|
||||
gcal_manager_set_new_range (
|
||||
gcal_window_get_manager (GCAL_WINDOW (user_data)),
|
||||
first_day,
|
||||
last_day);
|
||||
|
||||
g_free (first_day);
|
||||
g_free (last_day);
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_window_event_overlay_shown (GcalView *view,
|
||||
gpointer start_span,
|
||||
gpointer end_span,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gpointer user_data)
|
||||
{
|
||||
GcalWindowPrivate *priv;
|
||||
GcalManager *manager;
|
||||
gint width, height;
|
||||
|
||||
g_return_if_fail (user_data);
|
||||
priv = GCAL_WINDOW (user_data)->priv;
|
||||
|
||||
manager = gcal_window_get_manager (GCAL_WINDOW (user_data));
|
||||
/* squeezed in here, reload on every show */
|
||||
gcal_event_overlay_set_sources_model (
|
||||
GCAL_EVENT_OVERLAY (priv->new_event_actor),
|
||||
gcal_manager_get_sources_model (manager));
|
||||
|
||||
if (start_span != NULL)
|
||||
{
|
||||
gcal_event_overlay_set_span (GCAL_EVENT_OVERLAY (priv->new_event_actor),
|
||||
(icaltimetype*) start_span,
|
||||
(icaltimetype*) end_span);
|
||||
}
|
||||
|
||||
clutter_actor_show (priv->new_event_actor);
|
||||
|
||||
width = clutter_actor_get_width (priv->new_event_actor);
|
||||
height = clutter_actor_get_height (priv->new_event_actor);
|
||||
|
||||
x = x - width / 2;
|
||||
y = y - height;
|
||||
|
||||
clutter_actor_set_x (priv->new_event_actor, x);
|
||||
clutter_actor_set_y (priv->new_event_actor, y);
|
||||
|
||||
clutter_actor_save_easing_state (priv->new_event_actor);
|
||||
clutter_actor_set_opacity (priv->new_event_actor, 255);
|
||||
clutter_actor_restore_easing_state (priv->new_event_actor);
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_window_event_overlay_closed (GcalEventOverlay *widget,
|
||||
gpointer user_data)
|
||||
{
|
||||
GcalWindowPrivate *priv;
|
||||
|
||||
g_return_if_fail (user_data);
|
||||
priv = GCAL_WINDOW (user_data)->priv;
|
||||
|
||||
/* reset and hide */
|
||||
gcal_view_clear_selection (GCAL_VIEW (priv->views[priv->active_view]));
|
||||
gcal_event_overlay_reset (GCAL_EVENT_OVERLAY (priv->new_event_actor));
|
||||
|
||||
clutter_actor_save_easing_state (priv->new_event_actor);
|
||||
clutter_actor_set_opacity (priv->new_event_actor, 0);
|
||||
clutter_actor_restore_easing_state (priv->new_event_actor);
|
||||
|
||||
g_signal_connect (priv->new_event_actor,
|
||||
"transition-stopped::opacity",
|
||||
G_CALLBACK (gcal_window_show_hide_actor_cb),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_window_create_event (GcalEventOverlay *widget,
|
||||
GcalNewEventData *new_data,
|
||||
gboolean open_details,
|
||||
gpointer user_data)
|
||||
{
|
||||
GcalWindowPrivate *priv;
|
||||
|
||||
g_return_if_fail (user_data);
|
||||
priv = GCAL_WINDOW (user_data)->priv;
|
||||
|
||||
/* reset and hide */
|
||||
gcal_window_event_overlay_closed (widget, user_data);
|
||||
|
||||
/* create the event */
|
||||
g_debug ("NOW CREATE THE EVENT");
|
||||
if (open_details)
|
||||
g_debug ("Opening details window NOW");
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_window_show_hide_actor_cb (ClutterActor *actor,
|
||||
gchar *name,
|
||||
gboolean is_finished,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (actor) &&
|
||||
clutter_actor_get_opacity (actor) == 0)
|
||||
clutter_actor_hide (actor);
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
GtkWidget*
|
||||
gcal_window_new_with_view (GcalApplication *app,
|
||||
|
||||
Reference in New Issue
Block a user