//***************************************************************************************** // Truevision - a 3d modeler for gnome and povray // // tvwidgets.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 "math.h" #include "include/tvwidgets.h" #include "include/preferences.h" #include "include/dlgutils.h" #include "include/tvio.h" #include "include/scene.h" const float pi = 3.141592654; app_objs *TvWidget::app_ref = NULL; //********************************************************* // Classe de base //********************************************************* TvWidget::TvWidget( const char *nom, const char *snom, const char *aide, app_objs *appref ) { app_ref = appref; name = nom; sname = snom; tooltip = aide; widget = NULL; ttwidget = NULL; in_update = false; } TvWidget::TvWidget( TvWidget & ref ) { app_ref = ref.app_ref; name = ref.name; sname = ref.sname; tooltip = ref.tooltip; widget = NULL; ttwidget = NULL; in_update = false; } void TvWidget::pack_widget( GtkWidget *box, bool tt, GtkWidget *target ) { if ( tt && tooltip != NULL ) { if ( target == NULL ) target = widget; ttwidget = gtk_tooltips_new(); gtk_tooltips_set_tip( ttwidget, target, tooltip, NULL ); } gtk_box_pack_start( GTK_BOX(box), widget, FALSE, TRUE, 1 ); } void TvWidget::set_tooltip( GtkWidget *target ) { if ( !GTK_IS_WIDGET(widget) || tooltip == NULL ) return; PREF_DEF if ( pref->tooltips->value() ) { if ( !GTK_IS_TOOLTIPS(ttwidget) ) { ttwidget = gtk_tooltips_new(); gtk_tooltips_set_tip( ttwidget, target, _(tooltip), NULL ); } else gtk_tooltips_enable( ttwidget ); } else if ( GTK_IS_TOOLTIPS(ttwidget) ) gtk_tooltips_disable( ttwidget ); } void TvWidget::flush() { SCENE_DEF scene->set_modified(); } //********************************************************* // Rolling_box //********************************************************* app_objs *Rolling_box::app_ref = NULL; Rolling_box::Rolling_box( const char *titre, app_objs *appref, TvWidget *obj ) { title = titre; app_ref = appref; child_widget = obj; rolled_up = true; rolling_box = NULL; mother_box = NULL; } Rolling_box::Rolling_box( Rolling_box & ref ) { title = ref.title; child_widget = ref.child_widget; rolled_up = ref.rolled_up; rolling_box = NULL; mother_box = NULL; } void Rolling_box::copy( Rolling_box *ref ) { title = ref->title; rolled_up = ref->rolled_up; rolling_box = NULL; mother_box = NULL; } void Rolling_box::set_bar_pix() { char *pix_fname; if ( ! rolled_up ) pix_fname = tv_get_pixmap( "view_rollup.png" ); else pix_fname = tv_get_pixmap( "view_rolldown.png" ); if ( bar_pix == NULL ) bar_pix = gtk_image_new_from_file( pix_fname ); else gtk_image_set_from_file( GTK_IMAGE(bar_pix), pix_fname ); delete pix_fname; } void Rolling_box::get_widget_rb( GtkWidget *box, bool tt ) { tooltips = tt; GtkWidget *bar_frame = gtk_frame_new( NULL ); gtk_box_pack_start( GTK_BOX(box), bar_frame, FALSE, FALSE, 0 ); gtk_container_set_border_width( GTK_CONTAINER(bar_frame), 0 ); gtk_frame_set_shadow_type( GTK_FRAME(bar_frame), GTK_SHADOW_OUT ); gtk_widget_set_size_request( bar_frame, -1, 20 ); GtkWidget *bar_box = gtk_hbox_new( FALSE, 0 ); gtk_container_add( GTK_CONTAINER(bar_frame), bar_box ); GtkWidget *bar_label = gtk_label_new( title ); gtk_box_pack_start( GTK_BOX(bar_box), bar_label, TRUE, TRUE, 0 ); GtkWidget *roll_button = gtk_button_new(); gtk_button_set_relief( GTK_BUTTON(roll_button), GTK_RELIEF_NONE ); GTK_WIDGET_UNSET_FLAGS( roll_button, GTK_CAN_FOCUS ); gtk_container_set_border_width( GTK_CONTAINER(roll_button), 0 ); gtk_box_pack_start( GTK_BOX(bar_box), roll_button, FALSE, TRUE, 0 ); bar_pix = NULL; set_bar_pix(); gtk_container_add( GTK_CONTAINER(roll_button), bar_pix ); gtk_signal_connect( GTK_OBJECT(roll_button), "clicked", GTK_SIGNAL_FUNC(sign_rolling_box_clicked), this ); mother_box = gtk_vbox_new( FALSE, 0 ); gtk_box_pack_start( GTK_BOX(box), mother_box, FALSE, FALSE, 0 ); if ( rolled_up ) return; rolling_box = gtk_vbox_new( FALSE, 0 ); gtk_box_pack_start( GTK_BOX(mother_box), rolling_box, FALSE, FALSE, 0 ); child_widget->get_widget_noframe( rolling_box, tooltips ); } void Rolling_box::button_clicked() { if ( !rolled_up ) { child_widget->flush(); child_widget->clear_widget(); gtk_widget_destroy( rolling_box ); } else { rolling_box = gtk_vbox_new( FALSE, 0 ); gtk_box_pack_start( GTK_BOX(mother_box), rolling_box, FALSE, FALSE, 0 ); child_widget->get_widget_noframe( rolling_box, tooltips ); gtk_widget_show_all( mother_box ); } rolled_up = ! rolled_up; set_bar_pix(); } //********************************************************* // Classe bool //********************************************************* void TvWidget_bool::get_widget( GtkWidget *box, bool tt ) { widget = gtk_check_button_new_with_label( _(name) ); gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(widget), data ); TvWidget::pack_widget( box, tt ); } void TvWidget_bool::get_widget( GtkWidget *tab, bool tt, int row ) { widget = gtk_check_button_new_with_label( _(name) ); gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(widget), data ); gtk_table_attach_defaults( GTK_TABLE(tab), widget, 0, 2, row-1, row ); set_tooltip( widget ); } void TvWidget_bool::flush() { if ( !GTK_IS_WIDGET(widget) ) return; if ( widget == NULL ) return; TvWidget::flush(); data = GTK_TOGGLE_BUTTON(widget)->active; } void TvWidget_bool::save( ofstream & file ) { TvWidget::save( file ); file << "VALUE=" << ( data ? 'Y' : 'N' ); file << "} "; } bool TvWidget_bool::load( ifstream & file, char * tag ) { if ( strcmp( sname, tag ) ) return false; char * val = NULL; do { val = tvio_get_next_val( file ); if ( val == NULL ) return true; if ( ! strcmp( val, "VALUE" ) ) { data = tvio_get_value_as_bool( file ); continue; } } while( val != NULL ); return true; } //********************************************************* // Classe bool activator //********************************************************* void TvWidget_bool_activator::get_widget_no_toggle( GtkWidget *box, bool tt ) { TvWidget_bool::get_widget( box, tt ); gtk_signal_connect( GTK_OBJECT(widget), "clicked", GTK_SIGNAL_FUNC(sign_bool_activator_clicked), this ); } //********************************************************* // Classe int //********************************************************* TvWidget_int::TvWidget_int( TvWidget_int & ref ) : TvWidget( ref ) { data = ref.data; up = ref.data; down = ref.data; rate = ref.rate; spin = NULL; } void TvWidget_int::get_widget( GtkWidget *box, bool tt ) { widget = gtk_hbox_new( FALSE, 0 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_box_pack_start( GTK_BOX(widget), label, FALSE, FALSE, 4 ); adj = gtk_adjustment_new( data, down, up, rate, rate*10, 0 ); spin = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 0, 0 ); gtk_box_pack_start( GTK_BOX(widget), spin, TRUE, TRUE, 0 ); gtk_editable_set_position( GTK_EDITABLE(spin), 0 ); TvWidget::pack_widget( box, tt, spin ); } void TvWidget_int::get_widget( GtkWidget *tab, bool tt, int row ) { GtkWidget *label = gtk_label_new( _(name) ); gtk_misc_set_alignment( GTK_MISC(label), 0, 0.5 ); adj = gtk_adjustment_new( data, down, up, rate, rate*10, 0 ); spin = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 0, 0 ); gtk_editable_set_position( GTK_EDITABLE(spin), 0 ); gtk_table_attach_defaults( GTK_TABLE(tab), label, 0, 1, row-1, row ); gtk_table_attach_defaults( GTK_TABLE(tab), spin, 1, 5, row-1, row ); set_tooltip( widget ); widget = spin; } void TvWidget_int::flush() { if ( !GTK_IS_WIDGET(widget) ) return; if ( widget == NULL ) return; TvWidget::flush(); data = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(spin) ); gtk_editable_set_position( GTK_EDITABLE(spin), 0 ); } void TvWidget_int::update_widget() { if ( ! GTK_IS_WIDGET(widget) ) return; in_update = true; gtk_spin_button_set_value( GTK_SPIN_BUTTON(spin), data ); gtk_editable_set_position( GTK_EDITABLE(spin), 0 ); in_update = false; } void TvWidget_int::save( ofstream & file ) { TvWidget::save( file ); file << "VALUE=" << data << "} "; } bool TvWidget_int::load( ifstream & file, char * tag ) { if ( strcmp( sname, tag ) ) return false; char * val = NULL; do { val = tvio_get_next_val( file ); if ( val == NULL ) return true; if ( ! strcmp( val, "VALUE" ) ) { data = tvio_get_value_as_int( file ); continue; } } while( val != NULL ); return true; } void TvWidget_int::reset_range( int min, int max ) { in_update = true; up = max; down = min; if ( GTK_IS_WIDGET(widget) ) gtk_spin_button_set_range( GTK_SPIN_BUTTON(spin), min, max ); in_update = false; } //********************************************************* // Classe float //********************************************************* TvWidget_float::TvWidget_float( TvWidget_float & ref ) : TvWidget( ref ) { data = ref.data; up = ref.up; down = ref.down; rate = ref.rate; precision = ref.precision; spin = NULL; } void TvWidget_float::get_widget( GtkWidget *box, bool tt ) { widget = gtk_hbox_new( FALSE, 0 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_box_pack_start( GTK_BOX(widget), label, FALSE, FALSE, 4 ); adj = gtk_adjustment_new( data, down, up, rate, rate*10, 0 ); spin = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 0, precision ); gtk_spin_button_set_wrap( GTK_SPIN_BUTTON(spin), TRUE ); gtk_box_pack_start( GTK_BOX(widget), spin, TRUE, TRUE, 0 ); gtk_editable_set_position( GTK_EDITABLE(spin), 0 ); TvWidget::pack_widget( box, tt, spin ); } void TvWidget_float::get_widget( GtkWidget *tab, bool tt, int row ) { GtkWidget *label = gtk_label_new( _(name) ); gtk_misc_set_alignment( GTK_MISC(label), 0, 0.5 ); adj = gtk_adjustment_new( data, down, up, rate, rate*10, 0 ); spin = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 0, precision ); gtk_spin_button_set_wrap( GTK_SPIN_BUTTON(spin), TRUE ); gtk_editable_set_position( GTK_EDITABLE(spin), 0 ); gtk_table_attach_defaults( GTK_TABLE(tab), label, 0, 1, row-1, row ); gtk_table_attach_defaults( GTK_TABLE(tab), spin, 1, 5, row-1, row ); widget = spin; set_tooltip( widget ); } void TvWidget_float::flush() { if ( !GTK_IS_WIDGET(widget) ) return; if ( widget == NULL ) return; TvWidget::flush(); data = gtk_spin_button_get_value_as_float( GTK_SPIN_BUTTON(spin) ); gtk_editable_set_position( GTK_EDITABLE(spin), 0 ); } void TvWidget_float::update_widget() { if ( ! GTK_IS_WIDGET(widget) ) return; in_update = true; gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), data ); gtk_editable_set_position( GTK_EDITABLE(spin), 0 ); in_update = false; } void TvWidget_float::save( ofstream & file ) { TvWidget::save(file); file << "VALUE=" << data; file << "} "; } bool TvWidget_float::load( ifstream & file, char * tag ) { if ( strcmp( sname, tag ) ) return false; char * val = (char*)sname; while ( val != NULL ) { val = tvio_get_next_val( file ); if ( val == NULL ) return true; if ( ! strcmp( val, "VALUE" ) ) { data = tvio_get_value_as_float( file ); continue; } } return true; } //******************************************************** // TvWidget Percent //******************************************************** void TvWidget_percent::get_widget( GtkWidget *box, bool tt ) { widget = gtk_hbox_new( FALSE, 0 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_box_pack_start( GTK_BOX(widget), label, FALSE, FALSE, 4 ); adj = gtk_adjustment_new( data*100.0, 0, 100, 1, 10, 0 ); spin = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 0, 2 ); //gtk_spin_button_set_wrap( GTK_SPIN_BUTTON(spin), TRUE ); gtk_box_pack_start( GTK_BOX(widget), spin, TRUE, TRUE, 0 ); GtkWidget *slider = gtk_hscale_new( GTK_ADJUSTMENT(adj) ); gtk_box_pack_start( GTK_BOX(widget), slider, TRUE, TRUE, 0 ); gtk_editable_set_position( GTK_EDITABLE(spin), 0 ); TvWidget::pack_widget( box, tt, spin ); } void TvWidget_percent::get_widget( GtkWidget *tab, bool tt, int row ) { widget = gtk_hbox_new( FALSE, 0 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_misc_set_alignment( GTK_MISC(label), 0, 0.5 ); gtk_table_attach_defaults( GTK_TABLE(tab), widget, 1, 5, row-1, row ); gtk_table_attach_defaults( GTK_TABLE(tab), label, 0, 1, row-1, row ); adj = gtk_adjustment_new( data*100.0, 0, 100, 1, 10, 0 ); spin = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 0, 2 ); gtk_box_pack_start( GTK_BOX(widget), spin, FALSE, TRUE, 0 ); GtkWidget *slider = gtk_hscale_new( GTK_ADJUSTMENT(adj) ); gtk_box_pack_start( GTK_BOX(widget), slider, TRUE, TRUE, 0 ); gtk_editable_set_position( GTK_EDITABLE(spin), 0 ); set_tooltip( label ); } void TvWidget_percent::flush() { if ( !GTK_IS_WIDGET(widget) ) return; if ( widget == NULL ) return; TvWidget::flush(); data = gtk_spin_button_get_value_as_float( GTK_SPIN_BUTTON(spin) ) / 100.0; gtk_editable_set_position( GTK_EDITABLE(spin), 0 ); } void TvWidget_percent::update_widget() { if ( ! GTK_IS_WIDGET(widget) ) return; in_update = true; gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), data*100.0 ); gtk_editable_set_position( GTK_EDITABLE(spin), 0 ); in_update = false; } //********************************************************* // Classe entry //********************************************************* TvWidget_entry::~TvWidget_entry() { if ( undo_data != data && undo_data != NULL ) delete undo_data; if ( data != NULL ) delete data; } void TvWidget_entry::set( char *val ) { if ( data != NULL && data != undo_data ) delete data; if ( val == NULL ) { data = NULL; return; } data = new char[ strlen(val) + 1 ]; strcpy( data, val ); } void TvWidget_entry::store() { if ( undo_data != data && undo_data != NULL ) delete undo_data; undo_data = data; } void TvWidget_entry::restore() { if ( data == undo_data ) { undo_data = NULL; return; } delete data; data = undo_data; undo_data = NULL; } void TvWidget_entry::get_widget( GtkWidget *box, bool tt ) { widget = gtk_hbox_new( FALSE, 0 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_box_pack_start( GTK_BOX(widget), label, FALSE, FALSE, 4 ); entry = gtk_entry_new(); if ( data != NULL ) gtk_entry_set_text( GTK_ENTRY(entry), data ); gtk_box_pack_start( GTK_BOX(widget), entry, TRUE, TRUE, 0 ); TvWidget::pack_widget( box, tt, entry ); } void TvWidget_entry::get_widget( GtkWidget *tab, bool tt, int row ) { widget = gtk_hbox_new( FALSE, 0 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_misc_set_alignment( GTK_MISC(label), 0, 0.5 ); gtk_table_attach_defaults( GTK_TABLE(tab), widget, 1, 5, row-1, row ); gtk_table_attach_defaults( GTK_TABLE(tab), label, 0, 1, row-1, row ); entry = gtk_entry_new(); if ( data != NULL ) gtk_entry_set_text( GTK_ENTRY(entry), data ); gtk_box_pack_start( GTK_BOX(widget), entry, TRUE, TRUE, 0 ); set_tooltip( label ); } void TvWidget_entry::save( ofstream & file ) { if ( data == NULL ) return; TvWidget::save( file ); file << "VALUE=\"" << data << "\"} "; } bool TvWidget_entry::load( ifstream & file, char * tag ) { if ( strcmp( sname, tag ) ) return false; char * val = NULL; do { val = tvio_get_next_val( file ); if ( val == NULL ) return true; if ( ! strcmp( val, "VALUE" ) ) { set( tvio_get_value_as_string( file ) ); continue; } } while ( val != NULL ); return true; } //********************************************************* // Classe couleur //********************************************************* TvWidget_color::TvWidget_color( TvWidget_color & ref ) : TvWidget( ref ) { for ( int i = 0 ; i < 4 ; i++ ) data[i] = ref.data[i]; picker = NULL; } void TvWidget_color::get_widget( GtkWidget *box, bool tt ) { widget = gtk_hbox_new( FALSE, 0 ); picker = gtk_color_button_new(); if ( use_alpha ) gtk_color_button_set_use_alpha( GTK_COLOR_BUTTON(picker), TRUE ); gtk_color_button_set_title( GTK_COLOR_BUTTON(picker), _(name) ); gtk_box_pack_start( GTK_BOX(widget), picker, FALSE, FALSE, 3 ); GdkColor col; gdk_col( col ); gtk_color_button_set_color( GTK_COLOR_BUTTON(picker), &col ); gtk_color_button_set_alpha( GTK_COLOR_BUTTON(picker), (gushort)(data[3]*65535) ); GtkWidget *label = gtk_label_new( _(name) ); gtk_box_pack_start( GTK_BOX(widget), label, FALSE, FALSE, 10 ); pack_widget( box, tt, picker ); } void TvWidget_color::get_widget( GtkWidget *tab, bool tt, int row ) { picker = gtk_color_button_new(); if ( use_alpha ) gtk_color_button_set_use_alpha( GTK_COLOR_BUTTON(picker), TRUE ); gtk_color_button_set_title( GTK_COLOR_BUTTON(picker), _(name) ); GdkColor col; gdk_col( col ); gtk_color_button_set_color( GTK_COLOR_BUTTON(picker), &col ); gtk_color_button_set_alpha( GTK_COLOR_BUTTON(picker), (gushort)(data[3]*65535) ); GtkWidget *label = gtk_label_new( _(name) ); gtk_misc_set_alignment( GTK_MISC(label), 0, 0.5 ); gtk_table_attach_defaults( GTK_TABLE(tab), picker, 1, 5, row-1, row ); gtk_table_attach_defaults( GTK_TABLE(tab), label, 0, 1, row-1, row ); widget = picker; set_tooltip( label ); } void TvWidget_color::update_widget() { if ( ! GTK_IS_WIDGET(widget) ) return; in_update = true; GdkColor col; gdk_col( col ); gtk_color_button_set_color( GTK_COLOR_BUTTON(picker), &col ); gtk_color_button_set_alpha( GTK_COLOR_BUTTON(picker), (gushort)(data[3]*65535) ); in_update = false; } void TvWidget_color::flush() { if ( !GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); GdkColor col; gtk_color_button_get_color( GTK_COLOR_BUTTON(picker), &col ); set( col ); } void TvWidget_color::gl_set_rgb() { glColor3f( data[0], data[1], data[2] ); GLfloat color[] = { data[0], data[1], data[2], 0 }; glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color ); } void TvWidget_color::gl_set_rgb_for_wireframe() { glColor3f( data[0], data[1], data[2] ); GLfloat specular[4] = { 1, 1, 1, 1 }; GLfloat shininess[1] = { 0.9 }; GLfloat color[4] = { data[0], data[1], data[2], 1.0 }; glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, specular ); glMaterialfv( GL_FRONT_AND_BACK, GL_SHININESS, shininess ); glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color ); } void TvWidget_color::save( ofstream & file ) { TvWidget::save( file ); file << "R=" << data[0] << " G=" << data [1] << " B=" << data[2]; file << "} "; } bool TvWidget_color::load( ifstream & file, char * tag ) { if ( strcmp( sname, tag ) ) return false; char * val = (char*)sname; while ( val != NULL ) { val = tvio_get_next_val( file ); if ( val == NULL ) return true; if ( ! strcmp( val, "R" ) ) { data[0] = tvio_get_value_as_float( file ); continue; } if ( ! strcmp( val, "G" ) ) { data[1] = tvio_get_value_as_float( file ); continue; } if ( ! strcmp( val, "B" ) ) { data[2] = tvio_get_value_as_float( file ); continue; } } return true; } //********************************************************* // Classe pigment //********************************************************* TvWidget_pigment::TvWidget_pigment( const char *name, const char *sname, const char *tooltip, app_objs *appref ) : TvWidget( name, sname, tooltip, appref ) { color = new TvWidget_color( N_("RGB Color"), "RGB", NULL, app_ref ); color->set( 0, 0, 0 ); filter = new TvWidget_percent( N_("Filter(%)"), "FILT", NULL, app_ref, 0 ); filter->set_range( 1, 0, 0.01, 4 ); transmit = new TvWidget_percent( N_("Transmit(%)"), "TRANS", NULL, app_ref, 0 ); transmit->set_range( 1, 0, 0.01, 4 ); } TvWidget_pigment::TvWidget_pigment( TvWidget_pigment & ref ) : TvWidget( ref ) { color = new TvWidget_color( *ref.color ); filter = new TvWidget_percent( *ref.filter ); transmit = new TvWidget_percent( *ref.transmit ); } void TvWidget_pigment::get_widget_wnframe( GtkWidget *box, bool tt, bool frame ) { if ( frame ) widget = new_table( box, _(name), 3 ); else widget = new_table_no_frame( box, 3 ); color->get_widget( widget, tt, 1 ); filter->get_widget( widget, tt, 2 ); transmit->get_widget( widget, tt, 3 ); } void TvWidget_pigment::clear_widget() { widget = NULL; color->clear_widget(); filter->clear_widget(); transmit->clear_widget(); } void TvWidget_pigment::flush() { if ( !GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); color->flush(); filter->flush(); transmit->flush(); } void TvWidget_pigment::connect_signal( void (*fn)(gpointer), gpointer data ) { func = fn; func_data = data; color->connect_signal( GTK_SIGNAL_FUNC(sign_pigcolor_changed), this ); filter->connect_signal( GTK_SIGNAL_FUNC(sign_pigalpha_changed), this ); transmit->connect_signal( GTK_SIGNAL_FUNC(sign_pigalpha_changed), this ); } void TvWidget_pigment::output_to_povray( ofstream & file ) { file << "rgbft<" << color->get(0) << ',' << color->get(1) << ','; file << color->get(2) << ',' << filter->value() << ',' << transmit->value() << '>'; } void TvWidget_pigment::save( ofstream & file ) { TvWidget::save( file ); color->save( file ); filter->save( file ); transmit->save( file ); file << "} "; } bool TvWidget_pigment::load( ifstream & file, char * ltag ) { if ( strcmp( sname, ltag ) ) return false; char * tag = NULL; do { tag = tvio_get_next_tag( file ); if ( tag == NULL ) break; if ( color->load( file , tag ) ) continue; if ( filter->load( file , tag ) ) continue; if ( transmit->load( file , tag ) ) continue; tvio_skip_section( file ); } while( tag != NULL ); return true; } //********************************************************* // Classe option combo //********************************************************* TvWidget_option_combo::TvWidget_option_combo( TvWidget_option_combo & ref ) : TvWidget( ref ) { data = ref.data; items = ref.items; num_items = ref.num_items; combo = NULL; } void TvWidget_option_combo::get_widget( GtkWidget *box, bool tt ) { widget = gtk_hbox_new( FALSE, 0 ); GtkWidget *label = gtk_label_new( name ); gtk_box_pack_start( GTK_BOX(widget), label, FALSE, FALSE, 4 ); combo = gtk_combo_box_new_text(); gtk_box_pack_start( GTK_BOX(widget), combo, TRUE, TRUE, 0 ); for ( int i = 0 ; i < num_items ; i++ ) gtk_combo_box_append_text( GTK_COMBO_BOX(combo), items[i] ); gtk_combo_box_set_active( GTK_COMBO_BOX(combo), data ); pack_widget( box, tt, combo ); } void TvWidget_option_combo::get_widget( GtkWidget *tab, bool tt, int row ) { widget = gtk_hbox_new( FALSE, 0 ); GtkWidget *label = gtk_label_new( name ); gtk_misc_set_alignment( GTK_MISC(label), 0, 0.5 ); gtk_table_attach_defaults( GTK_TABLE(tab), label, 0, 1, row-1, row ); gtk_table_attach_defaults( GTK_TABLE(tab), widget, 1, 5, row-1, row ); combo = gtk_combo_box_new_text(); gtk_box_pack_start( GTK_BOX(widget), combo, TRUE, TRUE, 0 ); for ( int i = 0 ; i < num_items ; i++ ) gtk_combo_box_append_text( GTK_COMBO_BOX(combo), items[i] ); gtk_combo_box_set_active( GTK_COMBO_BOX(combo), data ); set_tooltip( label ); } void TvWidget_option_combo::flush() { if ( !GTK_IS_WIDGET(widget) ) return; in_update = true; TvWidget::flush(); data = gtk_combo_box_get_active( GTK_COMBO_BOX(combo) ); in_update = false; } void TvWidget_option_combo::update_widget() { if ( !GTK_IS_WIDGET(widget) ) return; in_update = true; //while ( gtk_combo_box_get_active( GTK_COMBO_BOX(combo) ) != -1 ) // gtk_combo_box_remove_text( GTK_COMBO_BOX(combo), 0 ); GtkListStore *list_store = GTK_LIST_STORE( gtk_combo_box_get_model( GTK_COMBO_BOX(combo) ) ); gtk_list_store_clear( list_store ); for ( int i = 0 ; i < num_items ; i++ ) gtk_combo_box_append_text( GTK_COMBO_BOX(combo), items[i] ); gtk_combo_box_set_active( GTK_COMBO_BOX(combo), data ); in_update = false; } void TvWidget_option_combo::reset_list ( const char **it, const int num ) { items = (char**)it; num_items = (int)num; } void TvWidget_option_combo::save( ofstream & file ) { TvWidget::save( file ); file << "VALUE=" << data; file << "} "; } bool TvWidget_option_combo::load( ifstream & file, char * tag ) { if ( strcmp( sname, tag ) ) return false; char * val = NULL; do { val = tvio_get_next_val( file ); if ( val == NULL ) return true; if ( ! strcmp( val, "VALUE" ) ) { set( tvio_get_value_as_int( file ) ); continue; } } while( val != NULL ); return true; } //********************************************************* // Classe path //********************************************************* TvWidget_path::TvWidget_path( TvWidget_path & ref ) : TvWidget( ref ) { data = undo_data = NULL; set( ref.data ); fentry = NULL; action = ref.action; } TvWidget_path::~TvWidget_path() { if ( undo_data != data && undo_data != NULL ) delete undo_data; if ( data != NULL ) delete data; } void TvWidget_path::set( char *val ) { if ( data != NULL && data != undo_data ) delete data; if ( val == NULL ) { data = NULL; return; } data = new char[ strlen(val) + 1 ]; strcpy( data, val ); } void TvWidget_path::store() { if ( undo_data != data && undo_data != NULL ) delete undo_data; undo_data = data; } void TvWidget_path::restore() { if ( data == undo_data ) { undo_data = NULL; return; } delete data; data = undo_data; undo_data = NULL; } void TvWidget_path::get_widget( GtkWidget *box, bool tt ) { widget = gtk_hbox_new( FALSE, 2 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_box_pack_start( GTK_BOX(widget), label, FALSE, TRUE, 4 ); fentry = gtk_file_chooser_button_new( name, action ); gtk_box_pack_start( GTK_BOX(widget), fentry, TRUE, TRUE, 2 ); if ( data != NULL ) gtk_file_chooser_set_filename( GTK_FILE_CHOOSER(fentry), data ); pack_widget( box, tt, label ); } void TvWidget_path::get_widget( GtkWidget *tab, bool tt, int row ) { widget = gtk_hbox_new( FALSE, 2 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_misc_set_alignment( GTK_MISC(label), 0, 0.5 ); fentry = gtk_file_chooser_button_new( name, action ); if ( data != NULL ) gtk_file_chooser_set_filename( GTK_FILE_CHOOSER(fentry), data ); gtk_box_pack_start( GTK_BOX(widget), fentry, TRUE, TRUE, 2 ); gtk_table_attach_defaults( GTK_TABLE(tab), label, 0, 1, row-1, row ); gtk_table_attach_defaults( GTK_TABLE(tab), widget, 1, 5, row-1, row ); set_tooltip( label ); } void TvWidget_path::set_default_path( char *str ) { if ( ! GTK_IS_WIDGET(fentry) ) return; if ( data != NULL ) gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(fentry), data ); } void TvWidget_path::flush() { if ( !GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); char *res = (char*)gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(fentry) ); if ( res == NULL ) { set( NULL ); return; } if ( strlen(res) > 0 ) set( res ); else set( NULL ); if ( res != NULL ) g_free( res ); } void TvWidget_path::save( ofstream & file ) { TvWidget::save( file ); file << "VALUE=\"" << data << "\"} "; } bool TvWidget_path::load( ifstream & file, char * tag ) { if ( strcmp( sname, tag ) ) return false; char * val = NULL; do { val = tvio_get_next_val( file ); if ( val == NULL ) return true; if ( ! strcmp( val, "VALUE" ) ) { set( tvio_get_value_as_string( file ) ); continue; } } while ( val != NULL ); return true; } //********************************************************* // Classe path alt - see header //********************************************************* TvWidget_path_alt::TvWidget_path_alt( TvWidget_path_alt & ref ) : TvWidget( ref ) { data = undo_data = NULL; set( ref.data ); entry = fentry = NULL; } TvWidget_path_alt::~TvWidget_path_alt() { if ( undo_data != data && undo_data != NULL ) delete undo_data; if ( data != NULL ) delete data; } void TvWidget_path_alt::set( char *val ) { if ( data != NULL && data != undo_data ) delete data; if ( val == NULL ) { data = NULL; return; } data = new char[ strlen(val) + 1 ]; strcpy( data, val ); } void TvWidget_path_alt::store() { if ( undo_data != data && undo_data != NULL ) delete undo_data; undo_data = data; } void TvWidget_path_alt::restore() { if ( data == undo_data ) { undo_data = NULL; return; } delete data; data = undo_data; undo_data = NULL; } void TvWidget_path_alt::get_widget( GtkWidget *box, bool tt ) { widget = gtk_hbox_new( FALSE, 2 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_box_pack_start( GTK_BOX(widget), label, FALSE, TRUE, 4 ); fentry = gnome_file_entry_new( NULL, name ); entry = gnome_file_entry_gtk_entry( GNOME_FILE_ENTRY(fentry) ); if ( data != NULL ) gtk_entry_set_text( GTK_ENTRY(entry), data ); gtk_box_pack_start( GTK_BOX(widget), fentry, FALSE, TRUE, 2 ); pack_widget( box, tt, entry ); } void TvWidget_path_alt::set_default_path( char *str ) { if ( ! GTK_IS_WIDGET(fentry) ) return; gnome_file_entry_set_default_path( GNOME_FILE_ENTRY(fentry), str ); } void TvWidget_path_alt::flush() { if ( !GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); char *res = (char*)gtk_entry_get_text( GTK_ENTRY(entry) ); if ( strlen(res) > 0 ) set( res ); else set( NULL ); } void TvWidget_path_alt::save( ofstream & file ) { TvWidget::save( file ); file << "VALUE=\"" << data << "\"} "; } bool TvWidget_path_alt::load( ifstream & file, char * tag ) { if ( strcmp( sname, tag ) ) return false; char * val = NULL; do { val = tvio_get_next_val( file ); if ( val == NULL ) return true; if ( ! strcmp( val, "VALUE" ) ) { set( tvio_get_value_as_string( file ) ); continue; } } while ( val != NULL ); return true; } //********************************************************* // Classe point //********************************************************* TvWidget_point::TvWidget_point( TvWidget_point & ref ) : TvWidget( ref ) { memcpy( data, ref.data, sizeof(float)*3 ); for ( int i = 0 ; i < 3 ; i++ ) spins[i] = NULL; up = ref.up; down = ref.down; rate = ref.rate; precision = ref.precision; } void TvWidget_point::get_widget( GtkWidget *box, bool tt ) { widget = gtk_hbox_new( FALSE, 0 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_box_pack_start( GTK_BOX(widget), label, FALSE, FALSE, 0 ); GtkObject *adj; for ( int i = 0 ; i < 3 ; i++ ) { adj = gtk_adjustment_new( data[i], down, up, rate, rate*10, 0 ); spins[i] = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 0, precision ); gtk_box_pack_start( GTK_BOX(widget), spins[i], TRUE, TRUE, 0 ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); } pack_widget( box, tt, spins[0] ); } void TvWidget_point::get_widget( GtkWidget *tab, bool tt, int row ) { GtkWidget *label = gtk_label_new( _(name) ); gtk_misc_set_alignment( GTK_MISC(label), 0, 0.5 ); gtk_table_attach_defaults( GTK_TABLE(tab), label, 0, 1, row-1, row ); widget = gtk_hbox_new( FALSE, 0 ); gtk_table_attach_defaults( GTK_TABLE(tab), widget, 1, 5, row-1, row ); GtkObject *adj; for ( int i = 0 ; i < 3 ; i++ ) { adj = gtk_adjustment_new( data[i], down, up, rate, rate*10, 0 ); spins[i] = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 0, precision ); gtk_box_pack_start( GTK_BOX(widget), spins[i], TRUE, TRUE, 0 ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); } set_tooltip( label ); } void TvWidget_point::reduce_size() { for ( int i = 0 ; i < 3 ; i++ ) if ( GTK_IS_WIDGET(spins[i] ) ) gtk_widget_set_size_request( spins[i], 10, -1 ); } void TvWidget_point::flush() { if ( !GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); for ( int i = 0 ; i < 3 ; i++ ) { if ( spins[i] == NULL ) break; data[i] = gtk_spin_button_get_value_as_float( GTK_SPIN_BUTTON(spins[i]) ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); } } void TvWidget_point::update_widget() { if ( !GTK_IS_WIDGET(widget) ) return; in_update = true; for ( int i = 0 ; i < 3 ; i++ ) { if ( spins[i] == NULL ) break; gtk_spin_button_set_value( GTK_SPIN_BUTTON(spins[i]), data[i] ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); } in_update = false; } void TvWidget_point::save( ofstream & file ) { TvWidget::save( file ); file << "X=" << data[0] << " Y=" << data[1] << " Z=" << data[2]; file << "} "; } bool TvWidget_point::load( ifstream & file, char * tag ) { if ( strcmp( sname, tag ) ) return false; char * val = (char*)sname; while ( val != NULL ) { val = tvio_get_next_val( file ); if ( val == NULL ) return true; if ( ! strcmp( val, "X" ) ) { data[0] = tvio_get_value_as_float( file ); continue; } if ( ! strcmp( val, "Y" ) ) { data[1] = tvio_get_value_as_float( file ); continue; } if ( ! strcmp( val, "Z" ) ) { data[2] = tvio_get_value_as_float( file ); continue; } } return true; } //********************************************************* // Classe vector4d //********************************************************* TvWidget_vector4::TvWidget_vector4( TvWidget_vector4 & ref ) : TvWidget( ref ) { memcpy( data, ref.data, sizeof(float)*4 ); for ( int i = 0 ; i < 3 ; i++ ) spins[i] = NULL; up = ref.up; down = ref.down; rate = ref.rate; precision = ref.precision; } void TvWidget_vector4::get_widget( GtkWidget *box, bool tt ) { widget = gtk_hbox_new( FALSE, 0 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_box_pack_start( GTK_BOX(widget), label, FALSE, FALSE, 0 ); GtkObject *adj; for ( int i = 0 ; i < 4 ; i++ ) { adj = gtk_adjustment_new( data[i], down, up, rate, rate*10, 0 ); spins[i] = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 0, precision ); gtk_box_pack_start( GTK_BOX(widget), spins[i], TRUE, TRUE, 0 ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); } pack_widget( box, tt, spins[0] ); } void TvWidget_vector4::reduce_size() { for ( int i = 0 ; i < 4 ; i++ ) if ( GTK_IS_WIDGET(spins[i] ) ) gtk_widget_set_size_request( spins[i], 15, -1 ); } void TvWidget_vector4::flush() { if ( !GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); for ( int i = 0 ; i < 4 ; i++ ) { if ( spins[i] == NULL ) break; data[i] = gtk_spin_button_get_value_as_float( GTK_SPIN_BUTTON(spins[i]) ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); } } void TvWidget_vector4::update_widget() { if ( !GTK_IS_WIDGET(widget) ) return; in_update = true; for ( int i = 0 ; i < 4 ; i++ ) { if ( spins[i] == NULL ) break; gtk_spin_button_set_value( GTK_SPIN_BUTTON(spins[i]), data[i] ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); } in_update = false; } void TvWidget_vector4::save( ofstream & file ) { TvWidget::save( file ); file << "X=" << data[0] << " Y=" << data[1] << " Z=" << data[2] << " W=" << data[3]; file << "} "; } bool TvWidget_vector4::load( ifstream & file, char * tag ) { if ( strcmp( sname, tag ) ) return false; char * val = (char*)sname; while ( val != NULL ) { val = tvio_get_next_val( file ); if ( val == NULL ) return true; if ( ! strcmp( val, "X" ) ) { data[0] = tvio_get_value_as_float( file ); continue; } if ( ! strcmp( val, "Y" ) ) { data[1] = tvio_get_value_as_float( file ); continue; } if ( ! strcmp( val, "Z" ) ) { data[2] = tvio_get_value_as_float( file ); continue; } if ( ! strcmp( val, "W" ) ) { data[3] = tvio_get_value_as_float( file ); continue; } } return true; } //********************************************************* // Classe gl material //********************************************************* TvWidget_glmat::TvWidget_glmat( const char *name, const char *sname, const char *tooltip, app_objs *appref ) : TvWidget( name, sname, tooltip, appref ) { //ambient = new TvWidget_color( N_("Ambient"), "AMBIENT", NULL, appref, true ); //ambient->set( .2, .2, .2, 1.0 ); diffuse = new TvWidget_color( N_("Diffuse and ambient"), "DIFFUSE", NULL, appref, true ); diffuse->set( .8, .8, .8, 1.0 ); specular = new TvWidget_color( N_("Specular"), "SPECULAR", NULL, appref, true ); specular->set( 0.0, 0.0, 0.0, 1.0 ); emission = new TvWidget_color( N_("Emission"), "EMISSION", NULL, appref, true ); emission->set( 0.0, 0.0, 0.0, 1.0 ); shininess = new TvWidget_float( N_("Shininess"), "SHINY", NULL, appref, 0 ); shininess->set_range( 1, 0, 0.01, 3 ); } TvWidget_glmat::TvWidget_glmat( TvWidget_glmat & ref ) : TvWidget( ref ) { //ambient = new TvWidget_color( *ref.ambient ); diffuse = new TvWidget_color( *ref.diffuse ); specular = new TvWidget_color( *ref.specular ); emission = new TvWidget_color( *ref.emission ); shininess = new TvWidget_float( *ref.shininess ); } TvWidget_glmat::~TvWidget_glmat() { //delete ambient; delete diffuse; delete specular; delete emission; delete shininess; } void TvWidget_glmat::get_widget( GtkWidget *box, bool tt ) { widget = new_table( box, _(name),4 ); //ambient->get_widget( widget, tt ); diffuse->get_widget( widget, tt, 1 ); specular->get_widget( widget, tt, 2 ); shininess->get_widget( widget, tt, 3 ); emission->get_widget( widget, tt, 4 ); } void TvWidget_glmat::clear_widget() { TvWidget::clear_widget(); //ambient->clear_widget(); diffuse->clear_widget(); specular->clear_widget(); emission->clear_widget(); shininess->clear_widget(); } void TvWidget_glmat::flush() { if ( !GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); //ambient->flush(); diffuse->flush(); specular->flush(); emission->flush(); shininess->flush(); } void TvWidget_glmat::gl_set_material() { flush(); //GLfloat ambient_col[4]; GLfloat diffuse_col[4]; GLfloat specular_col[4]; GLfloat emission_col[4]; GLfloat shininess_col[] = { (GLfloat)shininess->value() }; for ( register int i = 0 ; i < 4 ; i++ ) { //ambient_col[i] = (GLfloat)ambient->get(i); diffuse_col[i] = (GLfloat)diffuse->get(i); specular_col[i] = (GLfloat)specular->get(i); emission_col[i] = (GLfloat)emission->get(i); } //glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, ambient_col ); glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diffuse_col ); glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, emission_col ); glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, specular_col ); glMaterialfv( GL_FRONT_AND_BACK, GL_SHININESS, shininess_col ); glColor4fv( diffuse_col ); } void TvWidget_glmat::save( ofstream & file ) { TvWidget::save( file ); //ambient->save( file ); diffuse->save( file ); specular->save( file ); emission->save( file ); shininess->save( file ); file << "} "; } bool TvWidget_glmat::load( ifstream & file, char * ltag ) { if ( strcmp( sname, ltag ) ) return false; char * tag = NULL; do { tag = tvio_get_next_tag( file ); if ( tag == NULL ) break; //if ( ambient->load( file , tag ) ) continue; if ( diffuse->load( file , tag ) ) continue; if ( specular->load( file , tag ) ) continue; if ( emission->load( file , tag ) ) continue; if ( shininess->load( file , tag ) ) continue; tvio_skip_section( file ); } while( tag != NULL ); return true; }