Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2004-12-22 02:19:48 (GMT)
committer Owen Taylor <otaylor@src.gnome.org>2004-12-22 02:19:48 (GMT)
commitff8d0330fc705c931a40d07e28eb4060f1dd92f9 (patch)
tree386af38110a5d9e9b7f8ede9b17aa92947955971 /shell
parent1d8612cf9fa4348ad27e06b38d9c21d38d31c94a (diff)
Start of content-area widget.
Tue Dec 21 21:07:55 2004 Owen Taylor <otaylor@redhat.com> * shell/ev-view.[ch]: Start of content-area widget. * shell/ev-window.c: Create a EvView, update it as we change documents. * shell/Makefile.am shell/ev-marshal.list: Add generated marshalers.
Diffstat (limited to 'shell')
-rw-r--r--shell/.cvsignore1
-rw-r--r--shell/Makefile.am15
-rw-r--r--shell/ev-marshal.list1
-rw-r--r--shell/ev-view.c422
-rw-r--r--shell/ev-view.h45
-rw-r--r--shell/ev-window.c21
6 files changed, 500 insertions, 5 deletions
diff --git a/shell/.cvsignore b/shell/.cvsignore
index 48971d0..eb9b107 100644
--- a/shell/.cvsignore
+++ b/shell/.cvsignore
@@ -1,3 +1,4 @@
Makefile
Makefile.in
evince
+ev-marshal.[ch]
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 891eadb..e764e3a 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -17,6 +17,10 @@ evince_SOURCES= \
eggfindbar.h \
ev-application.c \
ev-application.h \
+ ev-marshal.c \
+ ev-marshal.h \
+ ev-view.c \
+ ev-view.h \
ev-window.c \
ev-window.h \
ev-sidebar.c \
@@ -29,3 +33,14 @@ evince_LDADD= \
$(top_builddir)/backend/libevbackend.la \
$(top_builddir)/pdf/xpdf/libpdfdocument.la \
$(NULL)
+
+BUILT_SOURCES = ev-marshal.h ev-marshal.c
+
+EXTRA_DIST = ev-marshal.list
+
+ev-marshal.h: ev-marshal.list
+ glib-genmarshal --prefix=ev_marshal ev-marshal.list --header > ev-marshal.h
+
+ev-marshal.c: ev-marshal.list
+ echo '#include "ev-marshal.h"' > ev-marshal.c
+ glib-genmarshal --prefix=ev_marshal ev-marshal.list --body >> ev-marshal.c
diff --git a/shell/ev-marshal.list b/shell/ev-marshal.list
new file mode 100644
index 0000000..38076d6
--- /dev/null
+++ b/shell/ev-marshal.list
@@ -0,0 +1 @@
+VOID:OBJECT,OBJECT
diff --git a/shell/ev-view.c b/shell/ev-view.c
new file mode 100644
index 0000000..70b50e0
--- /dev/null
+++ b/shell/ev-view.c
@@ -0,0 +1,422 @@
+/* this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2004 Red Hat, Inc
+ *
+ * Evince 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gtk/gtkalignment.h>
+
+#include "ev-marshal.h"
+#include "ev-view.h"
+
+#define EV_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_VIEW, EvViewClass))
+#define EV_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EV_TYPE_VIEW))
+#define EV_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EV_TYPE_VIEW, EvViewClass))
+
+struct _EvView {
+ GtkWidget parent_instance;
+
+ EvDocument *document;
+
+ GdkWindow *bin_window;
+
+ int scroll_x;
+ int scroll_y;
+
+ GtkAdjustment *hadjustment;
+ GtkAdjustment *vadjustment;
+};
+
+struct _EvViewClass {
+ GtkWidgetClass parent_class;
+
+ void (*set_scroll_adjustments) (EvView *view,
+ GtkAdjustment *hadjustment,
+ GtkAdjustment *vadjustment);
+};
+
+static void ev_view_set_scroll_adjustments (EvView *view,
+ GtkAdjustment *hadjustment,
+ GtkAdjustment *vadjustment);
+
+G_DEFINE_TYPE (EvView, ev_view, GTK_TYPE_WIDGET)
+
+/*** Helper functions ***/
+
+static void
+view_update_adjustments (EvView *view)
+{
+ int old_x = view->scroll_x;
+ int old_y = view->scroll_y;
+
+ if (view->hadjustment)
+ view->scroll_x = view->hadjustment->value;
+ else
+ view->scroll_x = 0;
+
+ if (view->vadjustment)
+ view->scroll_y = view->vadjustment->value;
+ else
+ view->scroll_y = 0;
+
+ if (GTK_WIDGET_REALIZED (view) &&
+ (view->scroll_x != old_x || view->scroll_y != old_y)) {
+ gdk_window_move (view->bin_window, - view->scroll_x, - view->scroll_y);
+ gdk_window_process_updates (view->bin_window, TRUE);
+ }
+}
+
+static void
+view_set_adjustment_values (EvView *view,
+ GtkOrientation orientation)
+{
+ GtkWidget *widget = GTK_WIDGET (view);
+ GtkAdjustment *adjustment;
+ gboolean value_changed = FALSE;
+ int requisition;
+ int allocation;
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL) {
+ requisition = widget->requisition.width;
+ allocation = widget->allocation.width;
+ adjustment = view->hadjustment;
+ } else {
+ requisition = widget->requisition.height;
+ allocation = widget->allocation.height;
+ adjustment = view->vadjustment;
+ }
+
+ if (!adjustment)
+ return;
+
+ adjustment->page_size = allocation;
+ adjustment->step_increment = allocation * 0.1;
+ adjustment->page_increment = allocation * 0.9;
+ adjustment->lower = 0;
+ adjustment->upper = MAX (allocation, requisition);
+
+ if (adjustment->value > adjustment->upper - adjustment->page_size) {
+ adjustment->value = adjustment->upper - adjustment->page_size;
+ value_changed = TRUE;
+ }
+
+ gtk_adjustment_changed (adjustment);
+ if (value_changed)
+ gtk_adjustment_value_changed (adjustment);
+}
+
+/*** Virtual function implementations ***/
+
+static void
+ev_view_finalize (GObject *object)
+{
+ EvView *view = EV_VIEW (object);
+
+ if (view->document)
+ g_object_unref (view->document);
+
+ ev_view_set_scroll_adjustments (view, NULL, NULL);
+
+ G_OBJECT_CLASS (ev_view_parent_class)->finalize (object);
+}
+
+static void
+ev_view_destroy (GtkObject *object)
+{
+ EvView *view = EV_VIEW (object);
+
+ ev_view_set_scroll_adjustments (view, NULL, NULL);
+
+ GTK_OBJECT_CLASS (ev_view_parent_class)->destroy (object);
+}
+
+static void
+ev_view_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ /* EvView *view = EV_VIEW (widget); */
+
+ requisition->width = 500;
+ requisition->height = 500;
+}
+
+static void
+ev_view_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ EvView *view = EV_VIEW (widget);
+
+ GTK_WIDGET_CLASS (ev_view_parent_class)->size_allocate (widget, allocation);
+
+ view_set_adjustment_values (view, GTK_ORIENTATION_HORIZONTAL);
+ view_set_adjustment_values (view, GTK_ORIENTATION_VERTICAL);
+
+ if (GTK_WIDGET_REALIZED (widget)) {
+ gdk_window_resize (view->bin_window,
+ MAX (widget->allocation.width, widget->requisition.width),
+ MAX (widget->allocation.height, widget->requisition.height));
+ }
+}
+
+static void
+update_window_backgrounds (EvView *view)
+{
+ GtkWidget *widget = GTK_WIDGET (view);
+
+ if (GTK_WIDGET_REALIZED (view)) {
+ gdk_window_set_background (view->bin_window,
+ &widget->style->base[GTK_WIDGET_STATE (widget)]);
+ }
+}
+
+static void
+ev_view_realize (GtkWidget *widget)
+{
+ EvView *view = EV_VIEW (widget);
+ GdkWindowAttr attributes;
+
+ GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.wclass = GDK_INPUT_OUTPUT;
+ attributes.visual = gtk_widget_get_visual (widget);
+ attributes.colormap = gtk_widget_get_colormap (widget);
+
+ attributes.x = widget->allocation.x;
+ attributes.y = widget->allocation.y;
+ attributes.width = widget->allocation.width;
+ attributes.height = widget->allocation.height;
+ attributes.event_mask = 0;
+
+ widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
+ &attributes,
+ GDK_WA_X | GDK_WA_Y |
+ GDK_WA_COLORMAP |
+ GDK_WA_VISUAL);
+ gdk_window_set_user_data (widget->window, widget);
+ widget->style = gtk_style_attach (widget->style, widget->window);
+
+ attributes.x = 0;
+ attributes.y = 0;
+ attributes.width = MAX (widget->allocation.width, widget->requisition.width);
+ attributes.height = MAX (widget->allocation.height, widget->requisition.height);
+ attributes.event_mask = GDK_EXPOSURE_MASK;
+
+ view->bin_window = gdk_window_new (widget->window,
+ &attributes,
+ GDK_WA_X | GDK_WA_Y |
+ GDK_WA_COLORMAP |
+ GDK_WA_VISUAL);
+ gdk_window_set_user_data (view->bin_window, widget);
+ gdk_window_show (view->bin_window);
+
+ attributes.event_mask = GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_MOTION_MASK | GDK_EXPOSURE_MASK;
+
+ update_window_backgrounds (view);
+}
+
+static void
+ev_view_unrealize (GtkWidget *widget)
+{
+ EvView *view = EV_VIEW (widget);
+
+ gdk_window_set_user_data (view->bin_window, NULL);
+ gdk_window_destroy (view->bin_window);
+ view->bin_window = NULL;
+
+ GTK_WIDGET_CLASS (ev_view_parent_class)->unrealize (widget);
+}
+
+static void
+ev_view_style_set (GtkWidget *widget,
+ GtkStyle *previous_style)
+{
+ update_window_backgrounds (EV_VIEW (widget));
+}
+
+static void
+ev_view_state_changed (GtkWidget *widget,
+ GtkStateType previous_state)
+{
+ update_window_backgrounds (EV_VIEW (widget));
+}
+
+static void
+expose_bin_window (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ /* EvView *view = EV_VIEW (widget); */
+}
+
+static gboolean
+ev_view_expose_event (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ EvView *view = EV_VIEW (widget);
+
+ if (event->window == view->bin_window)
+ expose_bin_window (widget, event);
+ else
+ return GTK_WIDGET_CLASS (ev_view_parent_class)->expose_event (widget, event);
+
+ return FALSE;
+
+}
+
+static gboolean
+ev_view_button_press_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ /* EvView *view = EV_VIEW (widget); */
+
+ return FALSE;
+}
+
+static gboolean
+ev_view_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event)
+{
+ /* EvView *view = EV_VIEW (widget); */
+
+ return FALSE;
+}
+
+static gboolean
+ev_view_button_release_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ /* EvView *view = EV_VIEW (widget); */
+
+ return FALSE;
+}
+
+static void
+on_adjustment_value_changed (GtkAdjustment *adjustment,
+ EvView *view)
+{
+ view_update_adjustments (view);
+}
+
+static void
+set_scroll_adjustment (EvView *view,
+ GtkOrientation orientation,
+ GtkAdjustment *adjustment)
+{
+ GtkAdjustment **to_set;
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ to_set = &view->hadjustment;
+ else
+ to_set = &view->vadjustment;
+
+ if (*to_set != adjustment) {
+ if (*to_set) {
+ g_signal_handlers_disconnect_by_func (*to_set,
+ (gpointer) on_adjustment_value_changed,
+ view);
+ g_object_unref (*to_set);
+ }
+
+ *to_set = adjustment;
+ view_set_adjustment_values (view, orientation);
+
+ if (*to_set) {
+ g_object_ref (*to_set);
+ g_signal_connect (*to_set, "value_changed",
+ G_CALLBACK (on_adjustment_value_changed), view);
+ }
+ }
+}
+
+static void
+ev_view_set_scroll_adjustments (EvView *view,
+ GtkAdjustment *hadjustment,
+ GtkAdjustment *vadjustment)
+{
+ set_scroll_adjustment (view, GTK_ORIENTATION_HORIZONTAL, hadjustment);
+ set_scroll_adjustment (view, GTK_ORIENTATION_VERTICAL, vadjustment);
+
+ view_update_adjustments (view);
+}
+
+static void
+ev_view_class_init (EvViewClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+ object_class->finalize = ev_view_finalize;
+
+ widget_class->expose_event = ev_view_expose_event;
+ widget_class->button_press_event = ev_view_button_press_event;
+ widget_class->motion_notify_event = ev_view_motion_notify_event;
+ widget_class->button_release_event = ev_view_button_release_event;
+ widget_class->size_request = ev_view_size_request;
+ widget_class->size_allocate = ev_view_size_allocate;
+ widget_class->realize = ev_view_realize;
+ widget_class->unrealize = ev_view_unrealize;
+ widget_class->style_set = ev_view_style_set;
+ widget_class->state_changed = ev_view_state_changed;
+ gtk_object_class->destroy = ev_view_destroy;
+
+ class->set_scroll_adjustments = ev_view_set_scroll_adjustments;
+
+ widget_class->set_scroll_adjustments_signal = g_signal_new ("set-scroll-adjustments",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EvViewClass, set_scroll_adjustments),
+ NULL, NULL,
+ ev_marshal_VOID__OBJECT_OBJECT,
+ G_TYPE_NONE, 2,
+ GTK_TYPE_ADJUSTMENT,
+ GTK_TYPE_ADJUSTMENT);
+}
+
+static void
+ev_view_init (EvView *view)
+{
+ static const GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
+
+ gtk_widget_modify_bg (GTK_WIDGET (view), GTK_STATE_NORMAL, &white);
+}
+
+/*** Public API ***/
+
+GtkWidget*
+ev_view_new (void)
+{
+ return g_object_new (EV_TYPE_VIEW, NULL);
+}
+
+void
+ev_view_set_document (EvView *view,
+ EvDocument *document)
+{
+ g_return_if_fail (EV_IS_VIEW (view));
+
+ if (document != view->document) {
+ if (view->document)
+ g_object_unref (view->document);
+
+ view->document = document;
+
+ if (view->document)
+ g_object_ref (view->document);
+
+ gtk_widget_queue_resize (GTK_WIDGET (view));
+ }
+}
diff --git a/shell/ev-view.h b/shell/ev-view.h
new file mode 100644
index 0000000..bb958f3
--- /dev/null
+++ b/shell/ev-view.h
@@ -0,0 +1,45 @@
+/* this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2004 Red Hat, Inc
+ *
+ * Evince 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EV_VIEW_H__
+#define __EV_VIEW_H__
+
+#include <gtk/gtkwidget.h>
+
+#include "ev-document.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_VIEW (ev_view_get_type ())
+#define EV_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_VIEW, EvView))
+#define EV_IS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_VIEW))
+
+
+typedef struct _EvView EvView;
+typedef struct _EvViewClass EvViewClass;
+
+GType ev_view_get_type (void) G_GNUC_CONST;
+GtkWidget* ev_view_new (void);
+
+void ev_view_set_document (EvView *view,
+ EvDocument *document);
+
+G_END_DECLS
+
+#endif /* __EV_VIEW_H__ */
diff --git a/shell/ev-window.c b/shell/ev-window.c
index a6097ce..d04dd91 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -28,6 +28,7 @@
#include "ev-window.h"
#include "ev-sidebar.h"
+#include "ev-view.h"
#include "eggfindbar.h"
#include "pdf-document.h"
@@ -56,6 +57,7 @@ struct _EvWindowPrivate {
GtkWidget *sidebar;
GtkWidget *find_bar;
GtkWidget *bonobo_widget;
+ GtkWidget *view;
GtkUIManager *ui_manager;
GtkWidget *statusbar;
guint help_message_cid;
@@ -158,6 +160,9 @@ ev_window_open (EvWindow *ev_window, const char *uri)
if (ev_window->priv->document)
g_object_unref (ev_window->priv->document);
ev_window->priv->document = document;
+
+ ev_view_set_document (EV_VIEW (ev_window->priv->view),
+ document);
} else {
GtkWidget *dialog;
@@ -708,9 +713,9 @@ ev_window_init (EvWindow *ev_window)
GtkActionGroup *action_group;
GtkAccelGroup *accel_group;
GError *error = NULL;
+ GtkWidget *scrolled_window;
GtkWidget *menubar;
GtkWidget *toolbar;
- GtkWidget *darea;
ev_window->priv = EV_WINDOW_GET_PRIVATE (ev_window);
@@ -769,11 +774,17 @@ ev_window_init (EvWindow *ev_window)
gtk_paned_add1 (GTK_PANED (ev_window->priv->hpaned),
ev_window->priv->sidebar);
- /* Stub widget, for now */
- darea = gtk_drawing_area_new ();
- gtk_widget_show (darea);
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_widget_show (scrolled_window);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_paned_add2 (GTK_PANED (ev_window->priv->hpaned),
- darea);
+ scrolled_window);
+
+ ev_window->priv->view = ev_view_new ();
+ gtk_widget_show (ev_window->priv->view);
+ gtk_container_add (GTK_CONTAINER (scrolled_window),
+ ev_window->priv->view);
ev_window->priv->statusbar = gtk_statusbar_new ();
gtk_widget_show (ev_window->priv->statusbar);