//***************************************************************************************** // Truevision - a 3d modeler for gnome and povray // // glview.h // // Vincent LE PRINCE // 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 #include #include #include "tvwidgets.h" #include "rotation.h" #include "dlgutils.h" #include // 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; }; // declarations to avoid friend injection problems void initgl( GtkWidget *wid, gpointer data ); void display( GtkWidget *wid, GdkEventExpose *ev, gpointer data ); void reshape( GtkWidget *wid, GdkEventConfigure *ev, gpointer data ); void sign_mouse_button_pressed( GtkWidget *wid, GdkEventButton *ev, gpointer data ); void sign_mouse_moved( GtkWidget *wid, GdkEventMotion *ev, gpointer data ); void sign_mouse_scroll( GtkWidget *wid, GdkEventScroll *ev, gpointer data ); void sign_toggle_lighting( GtkWidget *wid, gpointer data ); void sign_toggle_solid( GtkWidget *wid, gpointer data ); void sign_toggle_smooth( GtkWidget *wid, gpointer data ); void popup_detacher( GtkWidget *wid, GtkMenu *men ); void sign_view_refresh( GtkWidget *wid, gpointer data ); void sign_view_home( GtkWidget *wid, gpointer data ); void sign_toggle_axis( GtkWidget *wid, gpointer data ); void sign_change_view_type( GtkWidget *wid, gpointer data ); void sign_maximize( GtkWidget *wid, gpointer data ); void sign_roll( GtkWidget *wid, gpointer data ); void sign_pop_menu( GtkWidget *wid, gpointer data ); void sign_glview_tbar_expose( GtkWidget *wid, GdkEventExpose *ev, gpointer data ); void sign_glview_tbar_configure( GtkWidget *wid, GdkEventConfigure *ev, gpointer data ); void sign_glview_tbar_mouse_click( GtkWidget *wid, GdkEventButton *ev, gpointer data ); void sign_glview_tbar_focus_in( GtkWidget *wid, GdkEventFocus *ev, gpointer data ); void sign_glview_tbar_focus_out( GtkWidget *wid, GdkEventFocus *ev, gpointer data ); void sign_glview_tbar_key_press( GtkWidget *wid, GdkEventKey *ev, gpointer data ); //******************************************* // Classe de base //******************************************* class glview { #define SENDER ((glview*)data) // OpenGL callback functions friend void initgl( GtkWidget *wid, gpointer data ) { SENDER->init_view(); } friend void display( GtkWidget *wid, GdkEventExpose *ev, gpointer data ) { SENDER->display_view(ev); } friend void reshape( GtkWidget *wid, GdkEventConfigure *ev, gpointer data ) { SENDER->reshape_view(NULL); } // 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 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 ); // 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