//*****************************************************************************************
// Truevision - a 3d modeler for povray
//
// glview.h
//
// Vincent LE PRINCE <vincentleprince@users.sourceforge.net>
// Copyright (C) 2000-2005 Vincent LE PRINCE
// This file is part of the TRUEVISION Package
// 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
//*******************************************************************************************
#ifndef GLVIEW_H
#define GLVIEW_H
using namespace std;
#include "main.h"
#include <gtk/gtkgl.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "tvwidgets.h"
#include "rotation.h"
#include "dlgutils.h"
#include <vector>
// Wireframe line width
// Should be somewhere else
#define LINE_WIDTH 0.2
#define POINT_SIZE 4
class glview;
//*******************************************
// View types
// TOP, FRONT, RIGHT -> 2D views ( glview2d object , in glview2d.h )
// 3D -> generic perspective ( glview3d object, in glview3d.h )
// CAMERA -> camera view ( glviewcamera object, in glview3d.h )
//*******************************************
enum viewtype {
TV_VIEW_TOP=0,
TV_VIEW_FRONT,
TV_VIEW_RIGHT,
TV_VIEW_3D,
TV_VIEW_CAMERA
};
typedef viewtype ViewType;
//*******************************************
// Drag & drop infos structure
//*******************************************
struct drag_info {
bool first_click; // Is it the first time
int current_x; // Current mouse position
int current_y;
int previous_x; // Mouse position at previous motion callback
int previous_y;
int origin_x; // Mouse postion at fist click
int origin_y;
int center_x; // Center of the edited object
int center_y;
glview *view; // Focused view
bool shift; // Shift key modifier flag
bool control; // Control key modifier flag
Rotation *rotation;
GdkRectangle *gdkview;
};
//*******************************************
// Classe de base
//*******************************************
class glview {
#define SENDER ((glview*)data)
// OpenGL callback functions
friend void initgl( GtkWidget *wid, gpointer data ) { SENDER->init_view(); }
friend gint display( GtkWidget *wid, GdkEventExpose *ev, gpointer data ) { SENDER->display_view(ev); return FALSE; }
friend gint reshape( GtkWidget *wid, GdkEventConfigure *ev, gpointer data ) { SENDER->reshape_view(NULL); return FALSE; }
// OpenGL variables toggle callbacks
friend void sign_toggle_lighting( GtkWidget *wid, gpointer data ) { SENDER->gl_lighting->toggle(); SENDER->gl_variables_refresh(); }
friend void sign_toggle_solid( GtkWidget *wid, gpointer data ) { SENDER->gl_solid->toggle(); SENDER->gl_variables_refresh(); }
friend void sign_toggle_smooth( GtkWidget *wid, gpointer data ) { SENDER->gl_smooth->toggle(); SENDER->gl_variables_refresh(); }
// Mouse callbacks
friend void sign_mouse_button_pressed( GtkWidget *wid, GdkEventButton *ev, gpointer data ) { SENDER->click(ev); }
friend void sign_mouse_moved( GtkWidget *wid, GdkEventMotion *ev, gpointer data ) { SENDER->mouse_moved(ev); }
friend void sign_mouse_scroll( GtkWidget *wid, GdkEventScroll *ev, gpointer data ) { SENDER->mouse_scrolled(ev); }
// Menu popup callbacks
friend void popup_detacher( GtkWidget *wid, GtkMenu *men ) {}
friend void sign_view_refresh( GtkWidget *wid, gpointer data ) { SENDER->force_refresh(); }
friend void sign_view_home( GtkWidget *wid, gpointer data ) { SENDER->reset_home(); }
friend void sign_toggle_axis( GtkWidget *wid, gpointer data ) { SENDER->axis->toggle(); }
friend void sign_change_view_type( GtkWidget *wid, gpointer data ) { SENDER->mutate( wid ); }
// Title bar buttons callbacks
friend void sign_maximize( GtkWidget *wid, gpointer data ) { SENDER->MaximizeRestore(); }
friend void sign_roll( GtkWidget *wid, gpointer data ) { SENDER->RollUp(); }
friend void sign_pop_menu( GtkWidget *wid, gpointer data ) { SENDER->show_menu(); }
// Title bar widget callbaks
friend void sign_glview_tbar_expose( GtkWidget *wid, GdkEventExpose *ev, gpointer data ) { SENDER->tbar_expose(ev); }
friend void sign_glview_tbar_configure( GtkWidget *wid, GdkEventConfigure *ev, gpointer data ) { SENDER->tbar_configure(); }
friend void sign_glview_tbar_mouse_click( GtkWidget *wid, GdkEventButton *ev, gpointer data ) { SENDER->tbar_mouse_click(ev); }
friend void sign_glview_tbar_focus_in( GtkWidget *wid, GdkEventFocus *ev, gpointer data ) { SENDER->select(); }
friend void sign_glview_tbar_focus_out( GtkWidget *wid, GdkEventFocus *ev, gpointer data ) { SENDER->unselect(); }
friend void sign_glview_tbar_key_press( GtkWidget *wid, GdkEventKey *ev, gpointer data ) { SENDER->key_press(ev); }
#undef SENDER
public:
static const int buttons_num = 3; // Number of buttons in the title bar
static const int but_pixmaps_num = 5;
static const int view_type_num = 5; // Number of view types
private:
// Widgets used to create the view
GtkWidget *tbar, *frame, *tframe, *container, *tbbox;
// Buttons
GtkWidget *buttons_widget[buttons_num]; // Title bar buttons widgets
GtkWidget *buttons_gpix[buttons_num]; // Title bar buttons pixmaps
GtkTooltips *buttons_tooltips[buttons_num]; // Title bar buttons tooltips
static GdkGC *tbar_gc; // Titlebar graphic context ( changed when getting focus, ie color )
static char *but_pixmaps_fnames[but_pixmaps_num];
bool tbar_focus; // Do we have the focus
char *tbar_str; // Title bar title string
// Create a new button in the title bar
GtkWidget *title_bar_button_new( GtkWidget *hbox, int but, int pix, const gchar *ttip, GtkSignalFunc func );
// Title bar widget managing functions
void tbar_expose( GdkEventExpose *ev );
void tbar_configure();
void tbar_mouse_click( GdkEventButton *ev );
void tbar_redraw();
protected:
ViewType type; // The view type
static app_objs *app_ref; // Pointer to global objects reference structure
GtkWidget *area; // The GtkGlArea
TvWidget_color *background; // Background color for this view
vector<TvWidget*> tv_widgets; // View TvWidgets list
static drag_info drag; // Drag & drop infos
Rotation rotate; // Camera rotation infos
// Lookat
// Point the camera for this OpenGL view is pointed at ( != pov camera )
// the common one is used if views are linked
TvWidget_point *local_lookat;
static TvWidget_point *common_lookat;
TvWidget_point *lookat;
// View parameters ( internal use )
bool tooltips;
TvWidget_bool *maximized;
TvWidget_bool *rolled_up;
bool visible;
// View variables
// saved & loaded in scene file
TvWidget_bool *gl_solid;
TvWidget_bool *gl_smooth;
TvWidget_bool *gl_lighting;
TvWidget_bool *axis;
TvWidget_bool *label;
TvWidget_float *grid_scale;
// not yet implemented
//TvWidget_bool *gl_antialias;
//TvWidget_bool *gl_depthcue;
//TvWidget_bool *gl_alphablending;
// Widgets used for popup menu
GtkWidget *popup;
GtkWidget *menu_axis;
GtkWidget *menu_view_types[view_type_num];
GtkWidget *mi_dtypes[2];
GtkWidget *menu_gl_lighting;
GtkWidget *menu_gl_smooth;
GtkWidget *menu_gl_solid;
// Display lists for axis & grid
static GlDisplayList axis_list;
static GlDisplayList grid_lists[3];
static GdkGLContext *glcontext;
static GdkGLConfig *glconfig;
// common drawing function for 2d & 3d views
void draw_grid( int mode );
void draw_grid( int mode, float zoom );
// Grid Stuff
TvWidget_int *grid_major;
float old_zoom;
protected:
// Area widget functions
virtual void init_view();
virtual void display_view( GdkEventExpose *ev );
virtual void reshape_view( GdkEventConfigure *ev );
virtual void set_viewport() {}
// OpenGL settings functions
virtual void set_gl_variables();
void gl_variables_refresh() { set_gl_variables(); refresh(); }
// Mouse interaction functions
virtual void click( GdkEventButton *ev );
virtual void mouse_moved( GdkEventMotion *ev ) {}
virtual void mouse_scrolled( GdkEventScroll *ev ) {}
// Keyboard shortcuts functions
virtual void key_press( GdkEventKey *ev ) {}
// OpenGL picking function
virtual void pick_object( GdkEventButton *ev );
virtual void pick_object_param( GdkEventButton *ev );
// Menu manipulation function
virtual void add_menu() {}
virtual void set_menus() {}
void show_menu() { gtk_menu_popup( GTK_MENU(popup), NULL, NULL, NULL, NULL, 1, 0 ); }
void attach_popup();
void add_menu_item_bool( GtkWidget **wid, const gchar *text, GtkSignalFunc func, bool state );
// Utlities
void mutate( GtkWidget *sender ); // Change view type
virtual void reset_view( int type ) {}
void draw_axis(); // Draw axis
public:
glview( app_objs *appref, GtkWidget *box, GtkWidget *aframe, GtkWidget *tframe );
virtual ~glview();
GtkWidget *shared() { return area; } // return shared area widget for other views
virtual void pref_changed(); // Preferences change notification
// Refresh the view
virtual void refresh();
virtual void force_refresh();
void invalidate();
// Utilities
ViewType get_type() { return type; } // Return the view type
void change_type( ViewType new_type ); // Change the view type
void set_title( const char *title ) { tbar_str = (char*)title; tbar_redraw(); } // Set the view title
void Hide(); // Hide the view ( when other is maximized )
void Show(); // Show the view
void MaximizeRestore(); // Toggle maximize
void RollUp(); // Toggle rollup
virtual void reset_home() {}; // Set Lookat to defaults ( 0,0,0 )
bool project_point( float *point2d, float *point3d );
bool handle_base_key_press( GdkEventKey *ev ); // Common shortcuts for 2d & 3d views handling function
virtual void save( ofstream & file ) {} // Save ( in scene file )
virtual bool load( ifstream & file, char *tag ) { return false; } // Load
void save_basics( ofstream & file ); // Save 2d & 3d common params
bool load_basics( ifstream & file, char *type ); // Load commons
virtual void clear( ViewType cltype ); // Reset defaults
void select() { tbar_focus = true; tbar_redraw(); } // View focus
void unselect() { if ( ! tbar_focus ) return; tbar_focus = false; tbar_redraw(); } // View unfocus
GdkGLDrawable *get_drawable() { return gtk_widget_get_gl_drawable( area ); }
GdkGLContext *get_context() { return gtk_widget_get_gl_context( area ); }
};
#endif