/*
* Vis5d+/Gtk user interface
* Copyright (C) 2001 James P Edwards
*
* This program 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.
*
* This program 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
*
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gtkgl/gdkgl.h>
#include <gtkgl/gtkglarea.h>
#include "../src/api.h"
#include <math.h> /* for HUGE */
#include "window3D.h"
#include "w3D_interface.h"
#include "interface.h"
#include "support.h"
#include "support_cb.h"
#include "graph_labels.h"
#include "VarGraphicsControls.h"
#include "ProcedureDialog.h"
extern GtkWidget *FileSelectionDialog;
extern GtkWidget *FontSelectionDialog;
gboolean vis5d_initialized=FALSE;
GtkWidget *new_window3D(GtkWidget *oldwindow3D)
{
GtkWidget *window3D, *delete_frame;
GList *window3Dlist=NULL;
#ifdef ENABLE_NLS
bindtextdomain (PACKAGE, VIS5D_LOCALE_DIR);
textdomain (PACKAGE);
#endif
add_pixmap_directory (DATA_PREFIX "/pixmaps");
add_pixmap_directory (VIS5D_SOURCE_DIR "/pixmaps");
window3D = create_window3D();
if(oldwindow3D){
delete_frame = lookup_widget(oldwindow3D,"delete_frame1");
gtk_widget_set_sensitive(delete_frame,TRUE);
window3Dlist = (GList *) gtk_object_get_data(GTK_OBJECT(oldwindow3D),"window3Dlist");
delete_frame = lookup_widget(window3D,"delete_frame1");
gtk_widget_set_sensitive(delete_frame,TRUE);
}
printf("Start the window\n");
window3Dlist = g_list_append(window3Dlist,(gpointer) window3D);
gtk_object_set_data(GTK_OBJECT(window3D),"window3Dlist",(gpointer) window3Dlist);
if(oldwindow3D)
gtk_object_set_data(GTK_OBJECT(oldwindow3D),"window3Dlist",(gpointer) window3Dlist);
gtk_widget_set_sensitive(lookup_widget(window3D,"vars2d"),FALSE);
gtk_widget_set_sensitive(lookup_widget(window3D,"vars3d"),FALSE);
printf("Show the window\n");
gtk_widget_show (window3D);
return window3D;
}
void
on_open1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
GtkWidget *window3D;
if(FileSelectionDialog == NULL)
FileSelectionDialog = create_fileselection1();
/* This is the only window that should accept input */
gtk_grab_add(FileSelectionDialog);
gtk_window_set_title(GTK_WINDOW(FileSelectionDialog),_("Open Data File"));
if(user_data){
/* called from open in new frame or main*/
window3D=GTK_WIDGET(user_data);
}else{
window3D=lookup_widget(GTK_WIDGET (menuitem),"window3D");
}
gtk_object_set_data(GTK_OBJECT(FileSelectionDialog),"window3D" , window3D);
gtk_object_set_data(GTK_OBJECT(FileSelectionDialog),"OpenWhat" , GINT_TO_POINTER(DATA_FILE));
gtk_widget_show (FileSelectionDialog);
gtk_window_set_transient_for(GTK_WINDOW(FileSelectionDialog),GTK_WINDOW( window3D));
}
void
on_exit1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
GtkWidget *window3D;
GList *window3Dlist, *item;
v5d_info *info;
window3D = lookup_widget(GTK_WIDGET(menuitem),"window3D");
window3Dlist = g_list_first((GList *) gtk_object_get_data(GTK_OBJECT(window3D),"window3Dlist"));
item = window3Dlist;
while(item!=NULL){
info = (v5d_info*)gtk_object_get_data(GTK_OBJECT(item->data),"v5d_info");
if(info->timeout_id){
gtk_timeout_remove(info->timeout_id);
}
vis5d_destroy_display_context(info->v5d_display_context);
free(info);
gtk_widget_destroy(GTK_WIDGET(item->data));
item = g_list_next(item);
}
g_list_free(window3Dlist);
vis5d_terminate(1);
gtk_main_quit();
}
void
on_delete_frame1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
GtkWidget *window3D, *delete_frame;
GList *window3Dlist, *item;
v5d_info *info;
window3D = lookup_widget(GTK_WIDGET(menuitem),"window3D");
info = (v5d_info*)gtk_object_get_data(GTK_OBJECT(window3D),"v5d_info");
window3Dlist = g_list_first((GList *) gtk_object_get_data(GTK_OBJECT(window3D),"window3Dlist"));
window3Dlist = g_list_remove(window3Dlist,(gpointer) window3D);
if(info->timeout_id){
gtk_timeout_remove(info->timeout_id);
}
free(info);
gtk_widget_destroy(window3D);
if(g_list_last(window3Dlist) == window3Dlist){
/* only one window3D left */
window3D = GTK_WIDGET(window3Dlist->data);
delete_frame = lookup_widget(window3D,"delete_frame1");
gtk_widget_set_sensitive(delete_frame,FALSE);
}
item = window3Dlist;
/* Reset the window3Dlist pointer for each window */
while(item!=NULL){
gtk_object_set_data(GTK_OBJECT(item->data),"window3Dlist",window3Dlist);
item = item->next;
}
}
void
on_open_in_new_frame1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
GtkWidget *window3D;
window3D = new_window3D(lookup_widget(GTK_WIDGET(menuitem),"window3D"));
on_open1_activate(menuitem,(gpointer) window3D);
}
void on_option_toggle(GtkMenuItem *menuitem,gpointer user_data, int v5dwhat)
{
GtkWidget *window3D;
v5d_info *info;
window3D = lookup_widget(GTK_WIDGET(menuitem),"window3D");
info = (v5d_info *)gtk_object_get_data(GTK_OBJECT(window3D),"v5d_info");
if(info){
if( GTK_CHECK_MENU_ITEM(menuitem)->active ){
vis5d_graphics_mode(info->v5d_display_context,v5dwhat,VIS5D_ON);
}else{
vis5d_graphics_mode(info->v5d_display_context,v5dwhat,VIS5D_OFF);
}
}else{
printf("ERROR: info undefined in option_toggle\n");
}
}
void
on_map1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
on_option_toggle(menuitem,user_data,VIS5D_MAP);
}
void
on_topo1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
on_option_toggle(menuitem,user_data,VIS5D_TOPO);
}
void
on_box1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
on_option_toggle(menuitem,user_data,VIS5D_BOX);
}
void
on_clock1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
on_option_toggle(menuitem,user_data,VIS5D_CLOCK);
}
void
on_Arrow_clicked (GtkButton *button,
gpointer user_data)
{
v5d_info *info;
info = (v5d_info*)gtk_object_get_data(GTK_OBJECT(
lookup_widget(GTK_WIDGET(button),"window3D")),"v5d_info");
if(info==NULL)
return;
vis5d_get_dtx_timestep(info->v5d_display_context ,&info->timestep);
/* returns Numtimes - lasttime is one less */
vis5d_get_dtx_numtimes(info->v5d_display_context, &info->numtimes);
if(strncmp("next",user_data,4)==0)
{
info->timestep+=info->stepsize;
}
else if(strncmp("previous",user_data,8)==0)
{
info->timestep-=info->stepsize;
}
else if(strncmp("first",user_data,5)==0)
{
info->timestep=0;
}
else if(strncmp("last",user_data,4)==0)
{
info->timestep = info->numtimes-1;
}
if(info->timestep<0){
info->timestep = info->numtimes+info->timestep;
}else if(info->timestep>=info->numtimes){
info->timestep = info->timestep-info->numtimes;
}
vis5d_make_timestep_graphics(info->v5d_display_context, info->timestep);
#ifdef SINGLE_TASK
vis5d_finish_work();
#endif
vis5d_set_dtx_timestep(info->v5d_display_context ,info->timestep);
glarea_draw (info->GtkGlArea,NULL,NULL);
}
void
on_animate_toggled (GtkToggleButton *togglebutton,
gpointer user_data)
{
GtkToolbar *toolbar;
GList *item;
GtkWidget *widget;
v5d_info *info = (v5d_info*)gtk_object_get_data(GTK_OBJECT(
lookup_widget(GTK_WIDGET(togglebutton),"window3D")),"v5d_info");
if(info==NULL) return;
toolbar = GTK_TOOLBAR(lookup_widget(GTK_WIDGET(togglebutton),"toolbar1"));
if(gtk_toggle_button_get_active(togglebutton)&&info->numtimes>0){
if(user_data){
info->animate=-1; /* animate backwards */
}else{
info->animate=1;
}
/* set all other toolbar items to inactive */
item = g_list_first(toolbar->children);
while(item!=NULL){
if((widget=((GtkToolbarChild *) item->data)->widget) != GTK_WIDGET(togglebutton)
&& !GTK_IS_TOOLBAR(widget) ){
gtk_widget_set_sensitive(widget,FALSE);
}
item=g_list_next(item);
}
/* animation speed items should be active */
gtk_widget_set_sensitive(lookup_widget(GTK_WIDGET(togglebutton),"faster"),TRUE);
gtk_widget_set_sensitive(lookup_widget(GTK_WIDGET(togglebutton),"slower"),TRUE);
}else{
info->animate=0;
/* set all other toolbar items to active */
item = g_list_first(toolbar->children);
while(item!=NULL){
if((widget=((GtkToolbarChild *) item->data)->widget) != GTK_WIDGET(togglebutton)){
gtk_widget_set_sensitive(widget,TRUE);
}
item=g_list_next(item);
}
/* animation speed items should be inactive */
gtk_widget_set_sensitive(lookup_widget(GTK_WIDGET(togglebutton),"faster"),FALSE);
gtk_widget_set_sensitive(lookup_widget(GTK_WIDGET(togglebutton),"slower"),FALSE);
}
}
void
on_save_options1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_openprocedure_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
GtkWidget *window3D;
if(FileSelectionDialog == NULL)
FileSelectionDialog = create_fileselection1();
/* This is the only window that should accept input */
gtk_grab_add(FileSelectionDialog);
gtk_window_set_title(GTK_WINDOW(FileSelectionDialog),_("Open Procedure File"));
if(user_data)
window3D = GTK_WIDGET(user_data);
else
window3D=lookup_widget(GTK_WIDGET (menuitem),"window3D");
gtk_object_set_data(GTK_OBJECT(FileSelectionDialog),"window3D" , window3D);
gtk_object_set_data(GTK_OBJECT(FileSelectionDialog),"OpenWhat" , GINT_TO_POINTER(PROCEDURE_FILE));
gtk_widget_show (FileSelectionDialog);
gtk_window_set_transient_for(GTK_WINDOW(FileSelectionDialog),GTK_WINDOW( window3D));
}
void
on_topography1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
char v5dstr[V5D_MAXSTRLEN];
GtkWidget *window3D;
v5d_info *info;
window3D = lookup_widget(GTK_WIDGET(menuitem),"window3D");
if(!window3D) return;
info = (v5d_info*) gtk_object_get_data(GTK_OBJECT(window3D), "v5d_info");
if(!info) return;
if(FileSelectionDialog == NULL)
FileSelectionDialog = create_fileselection1();
gtk_window_set_title(GTK_WINDOW(FileSelectionDialog),_("Select Topography File"));
gtk_grab_add(FileSelectionDialog);
gtk_object_set_data(GTK_OBJECT(FileSelectionDialog),"OpenWhat" ,GINT_TO_POINTER(TOPO_FILE));
vis5d_get_topo(info->v5d_display_context , (char *) v5dstr);
if(v5dstr[0]=='/'){
gtk_file_selection_set_filename(GTK_FILE_SELECTION(FileSelectionDialog),v5dstr);
}else{
gtk_file_selection_set_filename(GTK_FILE_SELECTION(FileSelectionDialog),DATA_PREFIX );
}
gtk_widget_show (FileSelectionDialog);
gtk_grab_add(FileSelectionDialog);
gtk_window_set_transient_for(GTK_WINDOW(FileSelectionDialog),GTK_WINDOW(window3D));
}
void
on_map2_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
char v5dstr[V5D_MAXSTRLEN];
GtkWidget *window3D;
v5d_info *info;
window3D = lookup_widget(GTK_WIDGET(menuitem),"window3D");
if(!window3D) return;
info = (v5d_info*) gtk_object_get_data(GTK_OBJECT(window3D), "v5d_info");
if(!info) return;
if(FileSelectionDialog == NULL)
FileSelectionDialog = create_fileselection1();
gtk_window_set_title(GTK_WINDOW(FileSelectionDialog),_("Select Map File"));
gtk_grab_add(FileSelectionDialog);
gtk_object_set_data(GTK_OBJECT(FileSelectionDialog),"OpenWhat" ,GINT_TO_POINTER(MAP_FILE));
vis5d_get_map(info->v5d_display_context , (char *) v5dstr);
if(v5dstr[0]=='/'){
gtk_file_selection_set_filename(GTK_FILE_SELECTION(FileSelectionDialog),v5dstr);
}else{
gtk_file_selection_set_filename(GTK_FILE_SELECTION(FileSelectionDialog),DATA_PREFIX );
}
gtk_widget_show (FileSelectionDialog);
gtk_grab_add(FileSelectionDialog);
gtk_window_set_transient_for(GTK_WINDOW(FileSelectionDialog),GTK_WINDOW(window3D));
}
void
on_newprocedure_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
v5d_info *info;
GtkWidget *window3D = lookup_widget(GTK_WIDGET(menuitem),"window3D");
info = (v5d_info *)gtk_object_get_data(GTK_OBJECT(window3D),"v5d_info");
if(info->ProcedureDialog)
gtk_widget_destroy(info->ProcedureDialog);
info->ProcedureDialog = new_ProcedureDialog(info, NULL);
gtk_window_set_transient_for(GTK_WINDOW(info->ProcedureDialog),GTK_WINDOW(window3D));
}
void
on_setview_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
GtkLabel *label;
gchar *label_str;
label = GTK_LABEL(GTK_BIN(menuitem)->child);
gtk_label_get(label, &label_str);
printf("here %s\n",label_str);
}
/*****************************************************************************/
/* */
/* Function: create_glarea (void) */
/* */
/* This function performs the necessary operations to construct a GtkGlarea */
/* widget. These operations include creating the widget, setting the size */
/* of the widget, and registering callbacks for the widget. */
/* */
/* This is a good place to add function calls for any GtkGlarea */
/* initialization that you need to do. */
/* */
/*****************************************************************************/
GtkWidget*
create_glarea (gchar *widget_name, gchar *string1, gchar *string2,
gint int1, gint int2 )
{
GtkWidget* glarea;
/* Choose the attributes that we would like for our visual. */
/* These attributes are passed to glXChooseVisual by the */
/* gdk (see gdk_gl_choose_visual in gdkgl.c from the */
/* GtkGlarea distro). */
/* */
/* */
/* From the glXChooseVisual manpage: */
/* */
/* glXChooseVisual returns a pointer to an XVisualInfo */
/* structure describing the visual that best meets a */
/* minimum specification. */
/* */
/* Check out the manpage for a complete list of attributes */
/* and their descriptions. */
int attrlist[] = {
GDK_GL_RGBA,
GDK_GL_DOUBLEBUFFER,
GDK_GL_RED_SIZE, 1,
GDK_GL_BLUE_SIZE, 1,
GDK_GL_GREEN_SIZE, 1,
GDK_GL_DEPTH_SIZE, 1,
GDK_GL_NONE
};
/* First things first! Make sure that OpenGL is supported */
/* before trying to do OpenGL stuff! */
if(gdk_gl_query() == FALSE) {
g_print("OpenGL not supported!\n");
return NULL;
}
/* Now, create the GtkGLArea using the attribute list that */
/* we defined above. */
if ((glarea = gtk_gl_area_new(attrlist)) == NULL) {
g_print("Error creating GtkGLArea!\n");
return NULL;
}
/* Indicate which events we are interested in receiving in */
/* in the window allocated to our glarea widget. */
/* */
/* Check out gdk/gdktypes.h in your include directory for a */
/* complete list of event masks that you can use. */
gtk_widget_set_events(GTK_WIDGET(glarea),GDK_ALL_EVENTS_MASK);
/* TODO: Refine this list
GDK_EXPOSURE_MASK|
GDK_BUTTON_PRESS_MASK|
GDK_BUTTON_RELEASE_MASK|
GDK_POINTER_MOTION_MASK|
GDK_POINTER_MOTION_HINT_MASK);
*/
return (glarea);
}
/*****************************************************************************/
/* */
/* Function: glarea_button_release (GtkWidget*, GdkEventButton*) */
/* */
/* This function handles button-release events for the GtkGLArea into which */
/* we are drawing. */
/* */
/*****************************************************************************/
gboolean glarea_button_release (GtkWidget* widget, GdkEventButton* event
,gpointer user_data) {
/*
int x = event->x;
int y = event->y;
*/
if (event->button == 1) {
/* Mouse button 1 was released */
return TRUE;
}
if (event->button == 2) {
/* Mouse button 2 was released */
return TRUE;
}
return FALSE;
}
/*****************************************************************************/
/* */
/* Function: glarea_button_press (GtkWidget*, GdkEventButton*) */
/* */
/* This function handles button-press events for the GtkGLArea into which we */
/* are drawing. */
/* */
/*****************************************************************************/
gboolean glarea_button_press (GtkWidget* widget, GdkEventButton* event,
gpointer user_data) {
v5d_info *info;
int label_id;
int x = event->x;
int y = event->y;
info = (v5d_info*)gtk_object_get_data(GTK_OBJECT(lookup_widget(widget,"window3D")),"v5d_info");
if(vis5d_find_label(info->v5d_display_context, &x, &y, &label_id)==0){
graph_label_button_press(info, label_id, event->button);
return TRUE;
}
if (event->button == 1) {
/* Mouse button 1 was engaged */
return TRUE;
}
if (event->button == 2) {
/* Mouse button 2 was engaged */
return TRUE;
}
if (event->button == 3) {
/* Mouse button 3 was engaged */
return TRUE;
}
g_print("Button %d press?\n",event->button);
return FALSE;
}
/*****************************************************************************/
/* */
/* Function: glarea_motion_notify (GtkWidget*, GdkEventMotion*) */
/* */
/* This function handles motion events for the GtkGLArea into which we are */
/* drawing */
/* */
/*****************************************************************************/
gboolean glarea_motion_notify(GtkWidget *widget, GdkEventMotion *event,
gpointer user_data)
{
int x, y;
GdkRectangle area;
GdkModifierType state;
v5d_info *info = (v5d_info*)gtk_object_get_data(GTK_OBJECT(lookup_widget(widget,"window3D")),"v5d_info");
if(info==NULL)
return FALSE;
if (event->is_hint) {
/* fix this! */
#if !defined(WIN32)
gdk_window_get_pointer(event->window, &x, &y, &state);
#endif
} else {
x = event->x;
y = event->y;
state = event->state;
}
area.x = 0;
area.y = 0;
area.width = widget->allocation.width;
area.height = widget->allocation.height;
if (state & GDK_BUTTON1_MASK) {
/* drag in progress, simulate trackball */
/* in ../src/matrix.c - not part of the api */
void make_matrix( float rotx, float roty, float rotz,
float scale, float transx, float transy, float transz,
float mat[4][4] );
float xangle,yangle,view[7], matrix[4][4];
yangle = (float) (x - info->beginx) * 200.0/ (float) area.width;
xangle = (float) (y - info->beginy) * 200.0/ (float) area.height;
make_matrix(xangle, yangle, 0.0, 1.0, 0., 0., 0., matrix);
vis5d_matrix_mult(info->v5d_display_context, matrix);
glarea_draw(widget,NULL,NULL);
}
if (state & GDK_BUTTON2_MASK) {
/* translating drag */
float view[7];
vis5d_get_view(info->v5d_display_context,view,view+1,
view+2,view+3,view+4,view+5,view+6);
vis5d_set_view(info->v5d_display_context,
view[0],view[1],view[2],view[3],
view[4]+(info->beginx-x)*(-2.0/area.width),
view[5]+(info->beginy-y)*(2.0/area.height),view[6]);
glarea_draw(widget,NULL,NULL);
}
if (state & GDK_BUTTON3_MASK) {
/* zooming drag */
info->zoom += ((y - info->beginy) / area.height) ;
/* if (info->zoom < 0.5) info->zoom = 0.5;
if (info->zoom > 120) info->zoom = 120;
*/
vis5d_set_camera(info->v5d_display_context,0.0,0.0,info->zoom);
glarea_draw(widget,NULL,NULL);
}
info->beginx = x;
info->beginy = y;
return TRUE;
}
gint vis5d_do_work_gtk( gpointer data )
{
vis5d_do_work();
return 1;
}
gint _glarea_draw(gpointer infoptr)
{
int redraw;
v5d_info *info=(v5d_info *) infoptr;
/* Clear the drawing color buffer and depth buffers */
/* before drawing. */
if(info->timeout_id==0){
printf("glarea_draw \n");
return TRUE;
}
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(info->animate){
info->timestep += (info->animate*info->stepsize);
if(info->timestep<0){
info->timestep = info->numtimes+info->timestep;
}else if(info->timestep>=info->numtimes){
info->timestep = info->timestep-info->numtimes;
}
vis5d_make_timestep_graphics(info->v5d_display_context, info->timestep);
vis5d_set_dtx_timestep(info->v5d_display_context ,info->timestep);
redraw=1;
}else{
vis5d_check_redraw( info->v5d_display_context, &redraw );
}
if(redraw){
vis5d_draw_frame(info->v5d_display_context,info->animate);
/* is definitely recommended! Take a look at the red */
/* book if you don't already have an understanding of */
/* single vs. double buffered windows. */
gtk_gl_area_swapbuffers (GTK_GL_AREA(info->GtkGlArea));
}
#ifdef SINGLE_TASK
vis5d_do_work_gtk(NULL);
#endif
return TRUE;
}
/*****************************************************************************/
/* */
/* Function: glarea_draw (GtkWidget*, GdkEventExpose*) */
/* */
/* This is the function that should render your scene to the GtkGLArea. It */
/* can be used as a callback to the 'Expose' event. */
/* */
/*****************************************************************************/
gboolean glarea_draw (GtkWidget* widget, GdkEventExpose* event, gpointer user_data) {
/* Draw only on the last expose event. */
/* If event is null called from other than a callback */
v5d_info *info;
if (event && event->count > 0) {
return(TRUE);
}
info = (v5d_info *)gtk_object_get_data(GTK_OBJECT(gtk_widget_get_toplevel(widget)),"v5d_info");
if(info)
vis5d_signal_redraw(info->v5d_display_context,1);
/* gtk_gl_area_make_current MUST be called before rendering */
/* into the GtkGLArea. */
if (gtk_gl_area_make_current(GTK_GL_AREA(widget))) {
_glarea_draw(info);
}
return (TRUE);
}
/*****************************************************************************/
/* */
/* Function: glarea_reshape (GtkWidget*, GdkEventConfigure*) */
/* */
/* This function performs the operations needed to maintain the viewing area */
/* of the GtkGLArea. This should be called whenever the size of the area */
/* is changed. */
/* */
/*****************************************************************************/
gboolean glarea_reshape (GtkWidget* widget, GdkEventConfigure* event, gpointer user_data)
{
int w, h;
w = widget->allocation.width;
h = widget->allocation.height;
/* gtk_gl_area_make_current MUST be called before rendering */
/* into the GtkGLArea. */
if (gtk_gl_area_make_current (GTK_GL_AREA(widget))) {
v5d_info *info = (v5d_info *)gtk_object_get_data(GTK_OBJECT(gtk_widget_get_toplevel(widget)),"v5d_info");
if(info) {
vis5d_resize_3d_window(info->v5d_display_context,w,h);
vis5d_signal_redraw(info->v5d_display_context,1);
}
}
return (TRUE);
}
/*****************************************************************************/
/* */
/* Function: glarea_init (GtkWidget*) */
/* */
/* This function is a callback for the realization of the GtkGLArea widtget. */
/* You should do any OpenGL initialization here. */
/* */
/*****************************************************************************/
void glarea_init (GtkWidget* widget, gpointer user_data) {
/* gtk_gl_area_make_current MUST be called before rendering */
/* into the GtkGLArea. */
GLXContext glcontext;
Display *Xdisplay;
Window Xwindow;
if (gtk_gl_area_make_current (GTK_GL_AREA(widget))) {
GtkWidget *window3D;
/* set up v5d_info */
v5d_info *info ;
window3D = gtk_widget_get_toplevel(widget);
info = g_new0(v5d_info,1);
info->stepsize=1;
info->v5d_display_context=-1;
info->GtkGlArea=widget;
info->vinfo_array = g_ptr_array_new();
/* set pointers to the info structure from the glarea */
gtk_object_set_data(GTK_OBJECT(window3D), "v5d_info", info);
/* initialize vis5d */
{
/* from gdkgl.h */
typedef struct _GdkGLContextPrivate GdkGLContextPrivate;
struct _GdkGLContextPrivate {
Display *xdisplay;
GLXContext glxcontext;
guint ref_count;
};
GdkGLContext *gdkglcontext;
gdkglcontext = GTK_GL_AREA(widget)->glcontext;
glcontext = ((GdkGLContextPrivate *) gdkglcontext)->glxcontext;
Xdisplay = ((GdkGLContextPrivate *) gdkglcontext)->xdisplay;
Xwindow = GDK_WINDOW_XWINDOW(widget->window);
info->zoom = 1;
info->animate_speed=500;
if( vis5d_initialized==FALSE){
vis5d_initialize(0);
/*
vis5d_set_verbose_level(VERBOSE_DISPLAY);
*/
vis5d_noexit(1);
vis5d_initialized=TRUE;
}
info->v5d_display_context = vis5d_alloc_display_context();
vis5d_set_BigWindow(Xdisplay, Xwindow, glcontext);
vis5d_init_opengl_window(info->v5d_display_context,Xdisplay, Xwindow, glcontext);
vis5d_init_path(DATA_PREFIX);
vis5d_graphics_mode(info->v5d_display_context,VIS5D_BOX,VIS5D_ON);
vis5d_graphics_mode(info->v5d_display_context,VIS5D_CLOCK,VIS5D_ON);
vis5d_graphics_mode(info->v5d_display_context,VIS5D_MAP,VIS5D_ON);
vis5d_alpha_mode(info->v5d_display_context,VIS5D_ON );
vis5d_set_logo_size(info->v5d_display_context, 0.0);
vis5d_signal_redraw(info->v5d_display_context,3);
info->timeout_id = gtk_timeout_add(info->animate_speed, (GtkFunction) (_glarea_draw),(gpointer) info);
}
}
return ;
}
void
on_contour_label1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
GtkWidget *window3D;
v5d_info *info;
if(!FontSelectionDialog)
FontSelectionDialog = create_fontselectiondialog1();
window3D = lookup_widget(GTK_WIDGET(menuitem),"window3D");
if(!window3D) return;
info = (v5d_info*) gtk_object_get_data(GTK_OBJECT(window3D), "v5d_info");
if(!info) return;
gtk_object_set_data(GTK_OBJECT(FontSelectionDialog),"v5d_info",info);
gtk_object_set_data(GTK_OBJECT(FontSelectionDialog),"Font",GINT_TO_POINTER(CONTOUR_LABEL_FONT));
gtk_widget_show(FontSelectionDialog);
}
void
on_window_3d1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
GtkWidget *window3D;
v5d_info *info;
if(!FontSelectionDialog)
FontSelectionDialog = create_fontselectiondialog1();
window3D = lookup_widget(GTK_WIDGET(menuitem),"window3D");
if(!window3D) return;
info = (v5d_info*) gtk_object_get_data(GTK_OBJECT(window3D), "v5d_info");
if(!info) return;
gtk_object_set_data(GTK_OBJECT(FontSelectionDialog),"v5d_info",info);
gtk_object_set_data(GTK_OBJECT(FontSelectionDialog),"Font",GINT_TO_POINTER(WINDOW_3D_FONT));
gtk_widget_show(FontSelectionDialog);
}
void
on_variable_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
/* JPE This function is a callback for the variable menuitem
it may also be called from ProcedureDialog in which case menuitem==NULL
As of this time menuitem is not used, be careful if you use it.
*/
v5d_var_info *vinfo = (v5d_var_info *) user_data;
if(! vinfo->VarGraphicsDialog){
gchar title[80];
vinfo->VarGraphicsDialog = new_VarGraphicsControls();
g_snprintf(title,80,_("%s Variable Graphics Controls"),vinfo->vname);
gtk_window_set_title(GTK_WINDOW(vinfo->VarGraphicsDialog),title);
gtk_object_set_data(GTK_OBJECT(vinfo->VarGraphicsDialog),"v5d_var_info",(gpointer) vinfo);
if(vinfo->maxlevel==1){
GtkWidget *notebook;
int i;
notebook = lookup_widget(vinfo->VarGraphicsDialog,"notebook3");
/* get rid of all but the horizontal contour pages */
for(i=5;i>1;i--){
gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), i);
}
/* perhaps we want to use these for 2d variables? (lui does allow movement) */
gtk_widget_destroy(lookup_widget(vinfo->VarGraphicsDialog,"hsvbox"));
gtk_widget_destroy(lookup_widget(vinfo->VarGraphicsDialog,"chvbox"));
}else{
gtk_widget_set_sensitive(lookup_widget(vinfo->VarGraphicsDialog,"Vslicebutton"),TRUE);
gtk_widget_set_sensitive(lookup_widget(vinfo->VarGraphicsDialog,"CVslicebutton"),TRUE);
/*
gtk_widget_set_sensitive(lookup_widget(vinfo->VarGraphicsDialog,"Isosurfbutton"),TRUE);
gtk_widget_set_sensitive(lookup_widget(vinfo->VarGraphicsDialog,"Volumebutton"),TRUE);
*/
}
}
if(menuitem)
gtk_widget_show(vinfo->VarGraphicsDialog);
}
void
on_about1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
variable_menu_add_variable(GtkWidget *window3D, v5d_var_info *vinfo)
{
GtkWidget *variables_menu, *variable, *tearoff;
gpointer tmp;
if(vinfo->maxlevel == 1){
variables_menu = lookup_widget(window3D,"vars2d_menu");
gtk_widget_set_sensitive(lookup_widget(window3D,"vars2d"),TRUE);
tmp = gtk_object_get_data(GTK_OBJECT(window3D),"tearoff_2d");
if(tmp)
tearoff = GTK_WIDGET(tmp);
else{
variable = lookup_widget(window3D,"var2d");
if(variable){
gtk_widget_destroy(variable);
gtk_object_remove_data(GTK_OBJECT(window3D),"var2d");
}
tearoff = gtk_tearoff_menu_item_new();
gtk_widget_ref(tearoff);
gtk_widget_show(tearoff);
gtk_container_add (GTK_CONTAINER (variables_menu), tearoff);
gtk_object_set_data_full(GTK_OBJECT(window3D), "tearoff_2d",
tearoff, (GtkDestroyNotify) gtk_widget_unref);
}
}
else{
variables_menu = lookup_widget(window3D,"vars3d_menu");
gtk_widget_set_sensitive(lookup_widget(window3D,"vars3d"),TRUE);
tmp = gtk_object_get_data(GTK_OBJECT(window3D),"tearoff_3d");
if(tmp)
tearoff = GTK_WIDGET(tmp);
else{
variable = lookup_widget(window3D,"var3d");
if(variable){
gtk_widget_destroy(variable);
gtk_object_remove_data(GTK_OBJECT(window3D),"var3d");
}
tearoff = gtk_tearoff_menu_item_new();
gtk_widget_ref(tearoff);
gtk_widget_show(tearoff);
gtk_container_add (GTK_CONTAINER (variables_menu), tearoff);
gtk_object_set_data_full(GTK_OBJECT(window3D), "tearoff_3d",
tearoff, (GtkDestroyNotify) gtk_widget_unref);
}
}
/* get rid of the glade generated place holder and add tearoff */
/* glade cannot handle tearoffs at this time */
variable = gtk_menu_item_new_with_label (vinfo->vname);
gtk_widget_ref (variable);
gtk_widget_show (variable);
gtk_container_add (GTK_CONTAINER (variables_menu), variable);
gtk_signal_connect (GTK_OBJECT (variable), "activate",
GTK_SIGNAL_FUNC (on_variable_activate),
(gpointer) vinfo);
}
void
on_change_animate_speed (GtkButton *button,
gpointer user_data)
{
v5d_info *info;
GtkWidget *window3D;
/* user_data == 0 -> slower ; 1 -> faster */
gint faster = GPOINTER_TO_INT(user_data);
window3D = lookup_widget(GTK_WIDGET(button),"window3D");
info = gtk_object_get_data(GTK_OBJECT(window3D),"v5d_info");
if(!(info && info->timeout_id ))
return;
if(faster){
/* set a reasonable limit on speed (may not be achievable on all platforms) */
/* 16 is about 60 frames per second */
if(info->animate_speed > 16)
info->animate_speed*=0.5;
}else{
info->animate_speed*=2.0;
}
gtk_timeout_remove(info->timeout_id);
info->timeout_id = gtk_timeout_add(info->animate_speed, (GtkFunction) (_glarea_draw),(gpointer) info);
}
void
on_append1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
syntax highlighted by Code2HTML, v. 0.9.1