Re: Notebooks in Gtk+ v1.2.x



I am developing a CAD program.  What I am trying to do is have 
multiple drawing areas (OpenGL) available via a
notebook.  Each drawing area needs access to the toolbar and menus, 
but should have diffrent scale factors and viewing angles, among 
other things.  It is not known how many possible drawing areas will 
be open at any given time.

I have been able to create the notebook and a couple of windows, but 
can not figure out how to get them to respond to menu commands 
independently.

Jim,

I think you are in the right track.

If I understand well, you have a master window
with a notebook controlling multiple slave windows,
each one with an independent drawing area.

Generally speaking, each window must know all the information
about itself, in a structure (object) and the master must know 
the address of all the windows, in a list (of course this
is a over simplification).

My app has multiple (unlimited) top windows, each one 
with its own OpenGL drawing area, which in turn draws
multiple (unlimited) layers, each one with its own
set of objects, lights, OpenGL parameters, etc.

My architecture is slightly different from yours,
because all my top_windows are masters, while you
chose a master-slave design, but the general principles
are the same.

The function directly connected to the "expose event" signal
------------------------------------------------
gint gamgi_mesa_expose_gl_area (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
GtkGLArea *gl_area = GTK_GL_AREA (widget);
gamgi_window *window = GAMGI_CAST_WINDOW data;

/* Draw only last expose. */
if (event->count > 0) return TRUE;

glClear (GL_COLOR_BUFFER_BIT);

if (gtk_gl_area_make_current(gl_area))
  {
  gamgi_mesa_draw_window (window);
  glFlush(); /* redundant, I know */
  gtk_gl_area_swapbuffers (gl_area);
  glGetError ();
  }
return TRUE;
}
------------------------------------------------------
gtk_signal_connect (GTK_OBJECT (gl_area), "expose_event",
GTK_SIGNAL_FUNC (gamgi_mesa_expose_gl_area), window);
-----------------------------------------------------

The two lines above redraw a drawing area automatically.
The line below redraw a specified drawing area manually.

-----------------------------------------------------
gtk_widget_queue_draw (window->gl_area);
---------------------------------------


function called to redraw a window:
---------------------------------------
void gamgi_mesa_draw_window (gamgi_window *window)
{
gamgi_dlist *dlist;
gamgi_layer *layer;

/************************
 * restart color buffer *
 ************************/

glClearColor (window->layer->red, window->layer->green, window->layer->blue, 1.0);
glClear (GL_COLOR_BUFFER_BIT);

/***************************
 * draw non-current layers *
 ***************************/

if (window->layer->visibility_out != GAMGI_MESA_OPAQUE)
  {
  dlist = window->layer_start;
  while (dlist != NULL)
    {
    layer = GAMGI_CAST_LAYER dlist->data;

    if (layer != window->layer && layer->visibility_in != GAMGI_MESA_OPAQUE)
      gamgi_mesa_draw_layer (layer, window);

    dlist = dlist->next;
    }
  }

/**********************
 * draw current layer *
 **********************/

gamgi_mesa_draw_layer (window->layer, window);
}

redraw all windows:
-------------------------------------------
void gamgi_mesa_draw_gamgi (void)
{
gamgi_window *window = gamgi->window_start;

/********************
 * draw all windows *
 ********************/

while (window != NULL)
  {
  gtk_widget_queue_draw (window->gl_area);
  window = window->next;
  }
}
--------------------------------------------
In all the code above, window is a structure
that contains pointers to the list of layers,
plus relevant info, for example window->window
is the gtk window and window->window->window
is the gdk window. In gamgi->window_start,
gamgi can be a global variable or can be
stored in each window structure. The important
thing is, from >gamgi< you can address everything, 
from >window< you can address everything only
for that window, from >layer< you can address
everything only for that layer, etc. Connecting
signals and passing the window as the gpointer 
data parameter, changes automatically go to
the right window and you know exactly which
window that is.

Look at these code fragments and think about it,
I am sure there are many different ways of doing
this, of course a CAD program needs a solid, powerfull 
architecture, anyway I think you are on the right 
track.

(in case you want to look at my thing in more
detail, the (GPL) code is at www.gamgi.org)

Carlos



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]