]> www.fi.muni.cz Git - evince.git/commitdiff
Start of content-area widget.
authorOwen Taylor <otaylor@redhat.com>
Wed, 22 Dec 2004 02:19:48 +0000 (02:19 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Wed, 22 Dec 2004 02:19:48 +0000 (02:19 +0000)
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.

ChangeLog
shell/.cvsignore
shell/Makefile.am
shell/ev-marshal.list [new file with mode: 0644]
shell/ev-view.c [new file with mode: 0644]
shell/ev-view.h [new file with mode: 0644]
shell/ev-window.c

index 182e3828622e1fd516c137a330c75757bafab505..b77e0ead1cf296d627a737038125ff971cc41406 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+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.
+
 Tue Dec 21 20:28:11 2004  Jonathan Blandford  <jrb@redhat.com>
 
        * Makefile.am (SUBDIRS): move shell.
index 48971d0830902bdc94010e302d360a3b94331a59..eb9b1076f2264e6815b3456f2b427e357d4aea6f 100644 (file)
@@ -1,3 +1,4 @@
 Makefile
 Makefile.in
 evince
+ev-marshal.[ch]
index 891eadb7a8a8625b8783da0049ec1db6e2de6f63..e764e3a0ad0b5781019c6937f80e4f331fd751a6 100644 (file)
@@ -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 (file)
index 0000000..38076d6
--- /dev/null
@@ -0,0 +1 @@
+VOID:OBJECT,OBJECT
diff --git a/shell/ev-view.c b/shell/ev-view.c
new file mode 100644 (file)
index 0000000..70b50e0
--- /dev/null
@@ -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 (file)
index 0000000..bb958f3
--- /dev/null
@@ -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__ */
index a6097ce4b19e0e2043594525a1a4b8a2343e56b2..d04dd9102ac20b5aeec315919b2f009683a4353c 100644 (file)
@@ -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);