//***************************************************************************************** // Truevision - a 3d modeler for gnome and povray // // viewmanager.cc // // 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. */ //******************************************************************************************* #include "include/viewmanager.h" #include "include/objectlist.h" #include "include/preferences.h" #include "include/tvio.h" //*********************************************** // X Win pointers //*********************************************** GdkCursorType Pointeurs[MAX_PMODE] = { GDK_HAND1, GDK_TOP_LEFT_ARROW, GDK_SIZING, GDK_EXCHANGE, GDK_FLEUR, GDK_TCROSS, }; //*********************************************** // Constructor //*********************************************** ViewManager::ViewManager( app_objs *appref, GtkWidget *parent, GtkUIManager *ui_manager ) { // Initialisation app_ref = appref; appref->vmanager = this; PREF_DEF pointeur = NULL; pointer_mode = TV_PMODE_TRACKBALL; freezed = true; pmode_in_change = false; // Get GtkActions for each pointer mode pointer_actions[0] = gtk_ui_manager_get_action( ui_manager, "/MainToolbar/Trackball" ); pointer_actions[1] = gtk_ui_manager_get_action( ui_manager, "/MainToolbar/Select" ); pointer_actions[2] = gtk_ui_manager_get_action( ui_manager, "/MainToolbar/Scale" ); pointer_actions[3] = gtk_ui_manager_get_action( ui_manager, "/MainToolbar/Rotate" ); pointer_actions[4] = gtk_ui_manager_get_action( ui_manager, "/MainToolbar/Move" ); // Boxes for gl widgets GtkWidget *box = gtk_hbox_new( TRUE, 2 ); vbox1 = gtk_vbox_new( FALSE, 1 ); vbox2 = gtk_vbox_new( FALSE, 1 ); gtk_box_pack_start( GTK_BOX(box), vbox1, TRUE, TRUE, 0 ); gtk_box_pack_start( GTK_BOX(box), vbox2, TRUE, TRUE, 0 ); gtk_paned_add1( GTK_PANED(parent), box ); GtkWidget *boxes[4] = { vbox1, vbox1, vbox2, vbox2 }; // Create views for ( int i = 0 ; i < 4 ; i++ ) { switch ( pref->view_modes[i]->value() ) { case TV_VIEW_3D: views[i] = new glview3d( app_ref, boxes[i], NULL, NULL ); break; case TV_VIEW_CAMERA: views[i] = new glcamview( app_ref, boxes[i], NULL, NULL ); break; case TV_VIEW_TOP: case TV_VIEW_FRONT: case TV_VIEW_RIGHT: views[i] = new glview2d( app_ref, (ViewType)(pref->view_modes[i]->value()), boxes[i], NULL, NULL ); break; } } freezed = false; } //************************************************** // Set pointer mode //************************************************** // GtkAction callback void ViewManager::sign_pmode_change( GtkAction *action ) { if ( pmode_in_change ) return; for ( int i = 0 ; i < 5 ; i++ ) { if ( action == pointer_actions[i] ) //cout << "\nwe have action callback N°" << i; cout.flush(); set_pointer_mode( (PointerMode)i ); } } // Set current pointer mode // Modify active GtkAction void ViewManager::set_pointer_mode( PointerMode pmode ) { if ( pmode != -1 ) pointer_mode = pmode; if ( pointeur != NULL ) gdk_cursor_destroy( pointeur ); pointeur = gdk_cursor_new( Pointeurs[pointer_mode] ); for ( int i = 0 ; i < 4 ; i++ ) gdk_window_set_cursor( views[i]->shared()->window, pointeur ); // Change Active GtkAction pmode_in_change = true; for ( int i = 0 ; i < MAX_PMODE-1 ; i++ ) gtk_toggle_action_set_active( GTK_TOGGLE_ACTION( pointer_actions[i] ), pointer_mode == i ? TRUE : FALSE ); pmode_in_change = false; OBJLIST_DEF if ( objlist->get_current_param() != NULL ) { objlist->get_current_param()->ungrab_pointer(); objlist->clear_current_param(); } } // Set Pointer mode as custom // i.e pointer is owned by an ObjParam void ViewManager::set_custom_pointer_mode( GdkCursorType cursor ) { pointer_mode = TV_PMODE_CUSTOM; if ( pointeur != NULL ) gdk_cursor_destroy( pointeur ); pointeur = gdk_cursor_new( cursor ); for ( int i = 0 ; i < 4 ; i++ ) gdk_window_set_cursor( views[i]->shared()->window, pointeur ); // Unactivate all GtkAction relatives to pointer mode pmode_in_change = true; for ( int i = 0 ; i < MAX_PMODE-1 ; i++ ) gtk_toggle_action_set_active( GTK_TOGGLE_ACTION( pointer_actions[i] ), FALSE ); pmode_in_change = false; OBJLIST_DEF if ( objlist->get_current_param() != NULL ) { objlist->get_current_param()->ungrab_pointer(); objlist->clear_current_param(); } } // Restore 'normal' cursor for each gl preview void ViewManager::unset_cursor() { for ( int i = 0 ; i < 4 ; i++ ) gdk_window_set_cursor( views[i]->shared()->window, NULL ); } //************************************************** // Preferences Changed //************************************************** void ViewManager::pref_changed() { for ( int i = 0 ; i < 4 ; i++ ) views[i]->pref_changed(); } //************************************************** // Hide / Unhide Sisters // // Hide all preview except one //************************************************** void ViewManager::hide_sisters( glview *view, GtkWidget *container ) { for ( int i = 0 ; i < 4 ; i ++ ) if ( views[i] != view ) views[i]->Hide(); if ( container == vbox1 ) gtk_widget_hide( vbox2 ); else gtk_widget_hide( vbox1 ); } void ViewManager::unhide_sisters() { for ( int i = 0 ; i < 4 ; i ++ ) views[i]->Show(); gtk_widget_show( vbox1 ); gtk_widget_show( vbox2 ); } //************************************************** // Change view // //Create a new view of specified type and replace oldone //************************************************** void ViewManager::change_view( glview *oldone, ViewType type, GtkWidget *box, GtkWidget *area_frame, GtkWidget *tbar_frame, bool maximized ) { register int i = 0; while ( views[i++] == oldone ); int newone=0; for ( i = 0 ; i < 4 ; i ++ ) if ( views[i] == oldone ) { newone = i; break; } delete oldone; switch ( type ) { case TV_VIEW_3D: views[newone] = new glview3d( app_ref, box, area_frame, tbar_frame ); break; case TV_VIEW_CAMERA: views[newone] = new glcamview( app_ref, box, area_frame, tbar_frame ); break; case TV_VIEW_TOP: case TV_VIEW_RIGHT: case TV_VIEW_FRONT: views[newone] = new glview2d( app_ref, type, box, area_frame, tbar_frame ); break; } if ( maximized ) views[newone]->MaximizeRestore(); } //******************************************************************* // Save & Load // // In truevision scene file //****************************************************************** void ViewManager::save( ofstream & file ) { file << " \nVIEWS{\n"; for ( int i = 0 ; i < 4 ; i ++ ) views[i]->save( file ); file << "\n}"; } void ViewManager::clear() { PREF_DEF for ( int i = 0 ; i < 4 ; i ++ ) views[i]->clear( (ViewType)(pref->view_modes[i]->value()) ); refresh(); } bool ViewManager::load( ifstream & file, char *ltag ) { if ( strcmp( ltag, "VIEWS" ) ) return false; int i = 0; char * tag = NULL; do { tag = tvio_get_next_tag( file ); if ( tag == NULL || i > 4 ) break; if ( ! strcmp( tag, "GLVIEW2D" ) ) { if ( views[i]->get_type() == TV_VIEW_3D || views[i]->get_type() == TV_VIEW_CAMERA ) views[i]->change_type( TV_VIEW_FRONT ); views[i]->load( file, tag ); i++; continue; } if ( ! strcmp( tag, "GLVIEW3D" ) ) { if ( views[i]->get_type() != TV_VIEW_3D ) views[i]->change_type( TV_VIEW_3D ); views[i]->load( file, tag ); i++; continue; } if ( ! strcmp( tag, "GLCAMVIEW" ) ) { if ( views[i]->get_type() != TV_VIEW_CAMERA ) views[i]->change_type( TV_VIEW_CAMERA ); views[i]->load( file, tag ); i++; continue; } tvio_skip_section(file ); } while ( tag != NULL ); refresh(); return true; }