X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=src%2Fui%2Fgui%2Fpsppire-output-window.c;h=af47d3be51079a1e63c344824e74df20e4d5d322;hb=ef1c533e8f71be42b019cdbf4c5791b6bcd2d476;hp=08e9f1d9c58701f7df0e02efa1a6a704aa17264c;hpb=1075412b79b988d931209188fe9c0ab0c1b2fe94;p=pspp-builds.git diff --git a/src/ui/gui/psppire-output-window.c b/src/ui/gui/psppire-output-window.c index 08e9f1d9..af47d3be 100644 --- a/src/ui/gui/psppire-output-window.c +++ b/src/ui/gui/psppire-output-window.c @@ -20,11 +20,11 @@ #include #include "helper.h" +#include #include #include -#include -#include -#include +#include +#include #include #include "about.h" @@ -45,6 +45,7 @@ enum { COL_TITLE, /* Table title. */ + COL_Y, /* Y position of top of title. */ N_COLS }; @@ -117,132 +118,105 @@ psppire_output_window_base_finalize (PsppireOutputWindowClass *class, /* Output driver class. */ -static PsppireOutputWindow *the_output_viewer = NULL; +struct psppire_output_driver + { + struct output_driver driver; + PsppireOutputWindow *viewer; + struct xr_driver *xr; + }; + +static struct output_driver_class psppire_output_class; + +static struct psppire_output_driver * +psppire_output_cast (struct output_driver *driver) +{ + assert (driver->class == &psppire_output_class); + return UP_CAST (driver, struct psppire_output_driver, driver); +} static gboolean expose_event_callback (GtkWidget *widget, GdkEventExpose *event, gpointer data) { - struct som_entity *entity = g_object_get_data (G_OBJECT (widget), "entity"); - GdkWindow *window = widget->window; - cairo_t *cairo = gdk_cairo_create (GDK_DRAWABLE (window)); - struct outp_driver *driver = xr_create_driver (cairo); /* XXX can fail */ - struct tab_table *t = entity->ext; - void *rendering; - - rendering = entity->class->render_init (entity, driver, tab_l (t), - tab_r (t), tab_t (t), tab_b (t)); - - entity->class->title (rendering, 0, 0, - entity->table_num, entity->subtable_num, - entity->command_name); - entity->class->render (rendering, tab_l (t), tab_t (t), - tab_nc (t) - tab_r (t), - tab_nr (t) - tab_b (t)); - - entity->class->render_free (rendering); - driver->class->close_driver (driver); - outp_free_driver (driver); + struct xr_rendering *r = g_object_get_data (G_OBJECT (widget), "rendering"); + cairo_t *cr; + + cr = gdk_cairo_create (widget->window); + xr_rendering_draw (r, cr); + cairo_destroy (cr); + return TRUE; } static void -psppire_output_submit (struct outp_driver *this, struct som_entity *entity) +psppire_output_submit (struct output_driver *this, + const struct output_item *item) { - if (the_output_viewer == NULL) - { - the_output_viewer = PSPPIRE_OUTPUT_WINDOW (psppire_output_window_new ()); - gtk_widget_show_all (GTK_WIDGET (the_output_viewer)); - } + struct psppire_output_driver *pod = psppire_output_cast (this); + GtkWidget *drawing_area; + struct xr_rendering *r; + cairo_t *cr; + int tw, th; - if (entity->type == SOM_TABLE) + if (pod->viewer == NULL) { - GdkWindow *window = GTK_WIDGET (the_output_viewer)->window; - cairo_t *cairo = gdk_cairo_create (GDK_DRAWABLE (window)); - struct outp_driver *driver = xr_create_driver (cairo); /* XXX can fail */ - struct tab_table *t = entity->ext; - GtkTreeStore *store; - GtkTreeIter item; - GtkTreePath *path; - GtkWidget *drawing_area; - void *rendering; - int tw, th; - - tab_ref (t); - rendering = entity->class->render_init (entity, driver, tab_l (t), - tab_r (t), tab_t (t), tab_b (t)); - entity->class->area (rendering, &tw, &th); - - drawing_area = gtk_drawing_area_new (); - gtk_widget_modify_bg (GTK_WIDGET (drawing_area), GTK_STATE_NORMAL, - >k_widget_get_style (drawing_area)->base[GTK_STATE_NORMAL]); - g_object_set_data (G_OBJECT (drawing_area), - "entity", som_entity_clone (entity)); - gtk_widget_set_size_request (drawing_area, tw / 1024, th / 1024); - gtk_layout_put (the_output_viewer->output, drawing_area, - 0, the_output_viewer->y); - gtk_widget_show (drawing_area); - g_signal_connect (G_OBJECT (drawing_area), "expose_event", - G_CALLBACK (expose_event_callback), NULL); - - entity->class->render_free (rendering); - driver->class->close_driver (driver); - outp_free_driver (driver); - - if (tw / 1024 > the_output_viewer->max_width) - the_output_viewer->max_width = tw / 1024; - the_output_viewer->y += th / 1024; - - gtk_layout_set_size (the_output_viewer->output, - the_output_viewer->max_width, the_output_viewer->y); - - store = GTK_TREE_STORE (gtk_tree_view_get_model ( - the_output_viewer->overview)); - if (entity->table_num != the_output_viewer->last_table_num) - { - gtk_tree_store_append (store, &item, NULL); - gtk_tree_store_set (store, &item, COL_TITLE, entity->command_name, - -1); - - /* XXX shouldn't save a GtkTreeIter */ - the_output_viewer->last_table_num = entity->table_num; - the_output_viewer->last_top_level = item; - } - gtk_tree_store_append (store, &item, - &the_output_viewer->last_top_level); - gtk_tree_store_set (store, &item, COL_TITLE, - t->title ? t->title : "(unnamed)", -1); - - path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), - &the_output_viewer->last_top_level); - gtk_tree_view_expand_row (the_output_viewer->overview, path, TRUE); - gtk_tree_path_free (path); + pod->viewer = PSPPIRE_OUTPUT_WINDOW (psppire_output_window_new ()); + gtk_widget_show_all (GTK_WIDGET (pod->viewer)); + pod->viewer->driver = pod; } - gtk_window_set_urgency_hint (GTK_WINDOW (the_output_viewer), TRUE); + cr = gdk_cairo_create (GTK_WIDGET (pod->viewer)->window); + if (pod->xr == NULL) + pod->xr = xr_create_driver (cr); + + r = xr_rendering_create (pod->xr, item, cr); + if (r == NULL) + goto done; + + xr_rendering_measure (r, &tw, &th); + + drawing_area = gtk_drawing_area_new (); + gtk_widget_modify_bg ( + GTK_WIDGET (drawing_area), GTK_STATE_NORMAL, + >k_widget_get_style (drawing_area)->base[GTK_STATE_NORMAL]); + g_object_set_data (G_OBJECT (drawing_area), "rendering", r); + gtk_widget_set_size_request (drawing_area, tw, th); + gtk_layout_put (pod->viewer->output, drawing_area, 0, pod->viewer->y); + gtk_widget_show (drawing_area); + g_signal_connect (G_OBJECT (drawing_area), "expose_event", + G_CALLBACK (expose_event_callback), NULL); + + if (pod->viewer->max_width < tw) + pod->viewer->max_width = tw; + pod->viewer->y += th; + + gtk_layout_set_size (pod->viewer->output, + pod->viewer->max_width, pod->viewer->y); + + gtk_window_set_urgency_hint (GTK_WINDOW (pod->viewer), TRUE); + +done: + cairo_destroy (cr); } -static struct outp_class psppire_output_class = +static struct output_driver_class psppire_output_class = { "PSPPIRE", /* name */ - true, /* special */ - NULL, /* open_driver */ - NULL, /* close_driver */ - NULL, /* open_page */ - NULL, /* close_page */ - NULL, /* flush */ + NULL, /* create */ + NULL, /* destroy */ psppire_output_submit, /* submit */ - NULL, /* line */ - NULL, /* text_metrics */ - NULL, /* text_draw */ - NULL, /* initialise_chart */ - NULL, /* finalise_chart */ + NULL, /* flush */ }; void psppire_output_window_setup (void) { - outp_register_driver (outp_allocate_driver (&psppire_output_class, - "PSPPIRE", 0)); + struct psppire_output_driver *pod; + struct output_driver *d; + + pod = xzalloc (sizeof *pod); + d = &pod->driver; + output_driver_init (d, &psppire_output_class, "PSPPIRE", 0); + output_driver_register (d); } int viewer_length = 16; @@ -257,7 +231,7 @@ on_delete (GtkWidget *w, GdkEvent *event, gpointer user_data) gtk_widget_destroy (GTK_WIDGET (ow)); - the_output_viewer = NULL; + ow->driver->viewer = NULL; return FALSE; } @@ -270,6 +244,35 @@ cancel_urgency (GtkWindow *window, gpointer data) gtk_window_set_urgency_hint (window, FALSE); } +static void +on_row_activate (GtkTreeView *overview, + GtkTreePath *path, + GtkTreeViewColumn *column, + PsppireOutputWindow *window) +{ + GtkTreeModel *model; + GtkTreeIter iter; + GtkAdjustment *vadj; + GValue value = {0}; + double y, min, max; + + model = gtk_tree_view_get_model (overview); + if (!gtk_tree_model_get_iter (model, &iter, path)) + return; + + gtk_tree_model_get_value (model, &iter, COL_Y, &value); + y = g_value_get_long (&value); + g_value_unset (&value); + + vadj = gtk_layout_get_vadjustment (window->output); + min = vadj->lower; + max = vadj->upper - vadj->page_size; + if (y < min) + y = min; + else if (y > max) + y = max; + gtk_adjustment_set_value (vadj, y); +} static void psppire_output_window_init (PsppireOutputWindow *window) @@ -289,7 +292,8 @@ psppire_output_window_init (PsppireOutputWindow *window) gtk_tree_view_set_model (window->overview, GTK_TREE_MODEL (gtk_tree_store_new ( N_COLS, - G_TYPE_STRING))); /* COL_TITLE */ + G_TYPE_STRING, /* COL_TITLE */ + G_TYPE_LONG))); /* COL_Y */ window->last_table_num = -1; column = gtk_tree_view_column_new (); @@ -298,6 +302,9 @@ psppire_output_window_init (PsppireOutputWindow *window) gtk_tree_view_column_pack_start (column, renderer, TRUE); gtk_tree_view_column_add_attribute (column, renderer, "text", COL_TITLE); + g_signal_connect (GTK_TREE_VIEW (window->overview), + "row-activated", G_CALLBACK (on_row_activate), window); + gtk_widget_modify_bg (GTK_WIDGET (window->output), GTK_STATE_NORMAL, >k_widget_get_style (GTK_WIDGET (window->output))->base[GTK_STATE_NORMAL]);