//***************************************************************************************** // Truevision - a 3d modeler for gnome and povray // // objparam.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/objparam.h" #include "include/viewmanager.h" #include "include/preferences.h" #include "include/objectlist.h" #include "include/matlist.h" #include "include/tvio.h" #include "include/undo.h" const float sensitivity = 2.1; const float control_sensitivity = 15; //********************************************* // Base //********************************************* void ObjParam::flush( app_objs *app_ref ) { chgd = true; if ( refresh ) { VMAN_DEF vmanager->refresh(); } } void ObjParam::grab_pointer( GdkCursorType cursor, app_objs *app_ref ) { OBJLIST_DEF if ( objlist->get_current_param() == this ) return; pmode_change = true; VMAN_DEF vmanager->set_custom_pointer_mode( cursor ); pmode_change = false; objlist->set_current_param( this ); } //********************************************* // Option combo //********************************************* void ObjParam_option_combo::get_widget( GtkWidget *box, bool tt ) { TvWidget_option_combo::get_widget( box, tt ); gtk_signal_connect( GTK_OBJECT(combo), "changed", GTK_SIGNAL_FUNC(sign_option_combo_flush), this ); } void ObjParam_option_combo::get_widget( GtkWidget *tab, bool tt, int row ) { TvWidget_option_combo::get_widget( tab, tt, row ); gtk_signal_connect( GTK_OBJECT(combo), "changed", GTK_SIGNAL_FUNC(sign_option_combo_flush), this ); } void ObjParam_option_combo::flush() { if ( in_update ) return; if ( send_undo ) { UNDO_DEF ObjParam_option_combo *copy = new ObjParam_option_combo( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } TvWidget_option_combo::flush(); ObjParam::flush( app_ref ); } void ObjParam_option_combo::swap_data( ObjParam *param ) { ObjParam_option_combo *src = (ObjParam_option_combo*)param; int swap = data; data = src->data; src->data = swap; update_widget(); ObjParam::flush( app_ref ); } //********************************************* // Int //********************************************* void ObjParam_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_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(sign_int_flush), this ); TvWidget::pack_widget( box, tt, spin ); } void ObjParam_int::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, 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_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(sign_int_flush), this ); set_tooltip( label ); } void ObjParam_int::flush() { if ( in_update ) return; if ( send_undo ) { UNDO_DEF ObjParam_int *copy = new ObjParam_int( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } TvWidget_int::flush(); ObjParam::flush( app_ref ); } void ObjParam_int::swap_data( ObjParam *param ) { ObjParam_int *src = (ObjParam_int*)param; int swap = data; data = src->data; src->data = swap; update_widget(); ObjParam::flush( app_ref ); } //********************************************* // Float //********************************************* void ObjParam_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 ); GtkObject *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_widget_set_usize( spin, 20, -1 ); gtk_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(sign_float_flush), this ); TvWidget::pack_widget( box, tt, spin ); } void ObjParam_float::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 ); GtkObject *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_widget_set_usize( spin, 20, -1 ); gtk_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(sign_float_flush), this ); set_tooltip( label ); } void ObjParam_float::get_widget( GtkWidget *box, bool tt, void(*func)(GtkWidget*, gpointer ), gpointer dat ) { widget = gtk_hbox_new( FALSE, 0 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_box_pack_start( GTK_BOX(widget), label, FALSE, FALSE, 4 ); GtkObject *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_widget_set_usize( spin, 20, -1 ); gtk_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(func), dat ); TvWidget::pack_widget( box, tt, spin ); } void ObjParam_float::flush() { if ( in_update ) return; if ( send_undo ) { UNDO_DEF ObjParam_float *copy = new ObjParam_float( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } TvWidget_float::flush(); ObjParam::flush( app_ref ); } void ObjParam_float::swap_data( ObjParam *param ) { ObjParam_float *src = (ObjParam_float*)param; double swap = data; data = src->data; src->data = swap; update_widget(); ObjParam::flush( app_ref ); } //********************************************* // Float angle //********************************************* void ObjParam_float_angle::get_widget( GtkWidget *box, bool tt ) { widget = gtk_hbox_new( FALSE, 0 ); button = gtk_toggle_button_new(); gtk_container_set_border_width( GTK_CONTAINER(button), 1 ); GtkWidget *label = gtk_label_new(_( name) ); gtk_misc_set_padding( GTK_MISC(label), 5, 0 ); gtk_container_add( GTK_CONTAINER(button), label ); gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sign_float_angle_clicked), this ); gtk_box_pack_start( GTK_BOX(widget), button, FALSE, TRUE, 1 ); GtkObject *adj = gtk_adjustment_new( data, down, up, rate, rate*10, 0 ); spin = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 0, 6 ); gtk_spin_button_set_wrap( GTK_SPIN_BUTTON(spin), TRUE ); gtk_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(sign_float_angle_flush), this ); gtk_box_pack_start( GTK_BOX(widget), spin, TRUE, TRUE, 0 ); pack_widget( box, tt, button ); undo_data = data; } void ObjParam_float_angle::get_widget( GtkWidget *tab, bool tt, int row ) { widget = gtk_hbox_new( FALSE, 0 ); button = gtk_toggle_button_new(); gtk_container_set_border_width( GTK_CONTAINER(button), 1 ); GtkWidget *label = gtk_label_new(_( name) ); gtk_misc_set_padding( GTK_MISC(label), 5, 0 ); gtk_container_add( GTK_CONTAINER(button), label ); gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sign_float_angle_clicked), this ); gtk_table_attach_defaults( GTK_TABLE(tab), widget, 1, 5, row-1, row ); gtk_table_attach_defaults( GTK_TABLE(tab), button, 0, 1, row-1, row ); GtkObject *adj = gtk_adjustment_new( data, down, up, rate, rate*10, 0 ); spin = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 0, 6 ); gtk_spin_button_set_wrap( GTK_SPIN_BUTTON(spin), TRUE ); gtk_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(sign_float_angle_flush), this ); gtk_box_pack_start( GTK_BOX(widget), spin, TRUE, TRUE, 0 ); set_tooltip( button ); undo_data = data; } void ObjParam_float_angle::mouse_drag( struct drag_info *drag ) { if ( drag->first_click ) { if ( send_undo ) { UNDO_DEF ObjParam_float_angle *copy = new ObjParam_float_angle( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } drag->first_click = false; reversible_change = true; } else reversible_change = false; if ( drag->previous_x == drag->origin_x || drag->current_x == drag->origin_x ) return; double temp1 = drag->previous_x - drag->origin_x; double temp2 = drag->current_x - drag->origin_x; double up = (drag->origin_y - drag->previous_y)/temp1 - (drag->origin_y - drag->current_y) / temp2; up *= temp1 * - temp2; double down = drag->origin_y * ( drag->current_y + drag->previous_y - drag->origin_y ); down += drag->origin_x * ( drag->current_x + drag->previous_x - drag->origin_x ); down -= drag->previous_y * drag->current_y + drag->previous_x * drag->current_x; if ( down == 0 ) return; double phi = atan( up/ down ); if ( drag->control ) phi /= control_sensitivity; changing = true; undo_data = data; data -= phi*180/3.14159; if ( data > 360 ) data -= 360; if ( data < 0 ) data += 360; gtk_spin_button_set_value( GTK_SPIN_BUTTON(spin), data ); changing = false; ObjParam::flush( app_ref ); } //********************************************* // Bool //********************************************* void ObjParam_bool::get_widget( GtkWidget *box, bool tt ) { TvWidget_bool::get_widget( box, tt ); gtk_signal_connect( GTK_OBJECT(widget), "clicked", GTK_SIGNAL_FUNC(sign_bool_flush), this ); } void ObjParam_bool::get_widget( GtkWidget *tab, bool tt, int row ) { TvWidget_bool::get_widget( tab, tt, row ); gtk_signal_connect( GTK_OBJECT(widget), "clicked", GTK_SIGNAL_FUNC(sign_bool_flush), this ); } void ObjParam_bool::flush() { if ( in_update ) return; if ( send_undo ) { UNDO_DEF ObjParam_bool *copy = new ObjParam_bool( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } TvWidget_bool::flush(); ObjParam::flush( app_ref ); } void ObjParam_bool::swap_data( ObjParam *param ) { ObjParam_bool *src = (ObjParam_bool*)param; bool swap = data; data = src->data; src->data = swap; update_widget(); ObjParam::flush( app_ref ); } //********************************************* // Bool activator //********************************************* void ObjParam_bool_activator::get_widget( GtkWidget *box, bool tt ) { TvWidget_bool::get_widget( box, tt ); gtk_signal_connect( GTK_OBJECT(widget), "clicked", GTK_SIGNAL_FUNC(sign_bool_activator_flush), this ); toggle(); } void ObjParam_bool_activator::get_widget( GtkWidget *tab, bool tt, int row ) { TvWidget_bool::get_widget( tab, tt, row ); gtk_signal_connect( GTK_OBJECT(widget), "clicked", GTK_SIGNAL_FUNC(sign_bool_activator_flush), this ); toggle(); } void ObjParam_bool_activator::flush() { if ( in_update ) return; if ( send_undo ) { UNDO_DEF ObjParam_bool_activator *copy = new ObjParam_bool_activator( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } TvWidget_bool::flush(); TvWidget_bool_activator::toggle(); ObjParam::flush( app_ref ); } void ObjParam_bool_activator::swap_data( ObjParam *param ) { ObjParam_bool_activator *src = (ObjParam_bool_activator*)param; bool swap = data; data = src->data; src->data = swap; update_widget(); ObjParam::flush( app_ref ); } //********************************************* // Color //********************************************* void ObjParam_color::get_widget( GtkWidget *box, bool tt ) { TvWidget_color::get_widget( box, tt ); memcpy( undo_data, data, sizeof(double)*4 ); gtk_signal_connect( GTK_OBJECT(picker), "color_set", GTK_SIGNAL_FUNC(sign_color_flush), this ); } void ObjParam_color::get_widget( GtkWidget *tab, bool tt, int row ) { TvWidget_color::get_widget( tab, tt, row ); memcpy( undo_data, data, sizeof(double)*4 ); gtk_signal_connect( GTK_OBJECT(picker), "color_set", GTK_SIGNAL_FUNC(sign_color_flush), this ); } void ObjParam_color::flush() { if ( in_update ) return; if ( send_undo ) { UNDO_DEF ObjParam_color *copy = new ObjParam_color( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } TvWidget_color::flush(); ObjParam::flush( app_ref ); } void ObjParam_color::swap_data( ObjParam *param ) { ObjParam_color *src = (ObjParam_color*)param; double swap; for ( int i = 0 ; i < 4 ; i++ ) { swap = data[i]; data[i] = src->data[i]; src->data[i] = swap; } update_widget(); ObjParam::flush( app_ref ); } //********************************************* // Point //********************************************* void ObjParam_point::get_widget( GtkWidget *box, bool tt ) { widget = gtk_hbox_new( FALSE, 0 ); obj = NULL; button = gtk_toggle_button_new(); gtk_container_set_border_width( GTK_CONTAINER(button), 1 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_misc_set_padding( GTK_MISC(label), 5, 0 ); gtk_container_add( GTK_CONTAINER(button), label ); gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sign_point_clicked), this ); gtk_box_pack_start( GTK_BOX(widget), button, FALSE, TRUE, 1 ); 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_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(sign_point_flush), this ); gtk_box_pack_start( GTK_BOX(widget), spins[i], TRUE, TRUE, 0 ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); gtk_widget_set_usize( spins[i], 10, -1 ); } pack_widget( box, tt, button ); memcpy( undo_data, data, sizeof(float)*3 ); } void ObjParam_point::get_widget( GtkWidget *tab, bool tt, int row ) { widget = gtk_hbox_new( FALSE, 0 ); obj = NULL; gtk_table_attach_defaults( GTK_TABLE(tab), widget, 1, 5, row-1, row ); button = gtk_toggle_button_new(); gtk_container_set_border_width( GTK_CONTAINER(button), 1 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_misc_set_padding( GTK_MISC(label), 5, 0 ); gtk_container_add( GTK_CONTAINER(button), label ); gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sign_point_clicked), this ); gtk_table_attach( GTK_TABLE(tab), button, 0, 1, row-1, row, GTK_FILL, (GtkAttachOptions)0, 0, 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_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(sign_point_flush), this ); gtk_box_pack_start( GTK_BOX(widget), spins[i], TRUE, TRUE, 0 ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); gtk_widget_set_usize( spins[i], 10, -1 ); } memcpy( undo_data, data, sizeof(float)*3 ); set_tooltip( button ); } void ObjParam_point::get_widget( GtkWidget *box, bool tt, void(*func)(GtkWidget*, gpointer ), gpointer dat ) { widget = gtk_hbox_new( FALSE, 0 ); callback = func; obj = dat; button = gtk_toggle_button_new(); gtk_container_set_border_width( GTK_CONTAINER(button), 1 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_misc_set_padding( GTK_MISC(label), 5, 0 ); gtk_container_add( GTK_CONTAINER(button), label ); gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sign_point_clicked), this ); gtk_box_pack_start( GTK_BOX(widget), button, FALSE, TRUE, 1 ); 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_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(func), dat ); gtk_box_pack_start( GTK_BOX(widget), spins[i], TRUE, TRUE, 0 ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); gtk_widget_set_usize( spins[i], 10, -1 ); } pack_widget( box, tt, button ); memcpy( undo_data, data, sizeof(float)*3 ); } void ObjParam_point::get_widget( GtkWidget *tab, bool tt, int row, void(*func)(GtkWidget*, gpointer ), gpointer dat ) { widget = gtk_hbox_new( FALSE, 0 ); callback = func; obj = dat; gtk_table_attach_defaults( GTK_TABLE(tab), widget, 1, 5, row-1, row ); button = gtk_toggle_button_new(); gtk_container_set_border_width( GTK_CONTAINER(button), 1 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_misc_set_padding( GTK_MISC(label), 5, 0 ); gtk_container_add( GTK_CONTAINER(button), label ); gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sign_point_clicked), this ); //gtk_box_pack_start( GTK_BOX(widget), button, FALSE, TRUE, 1 ); gtk_table_attach_defaults( GTK_TABLE(tab), button, 0, 1, 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_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(func), dat ); gtk_box_pack_start( GTK_BOX(widget), spins[i], TRUE, TRUE, 0 ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); gtk_widget_set_usize( spins[i], 10, -1 ); } memcpy( undo_data, data, sizeof(float)*3 ); } void ObjParam_point::get_widget_no_button( 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, TRUE, 1 ); 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_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(sign_point_flush), this ); 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, button ); memcpy( undo_data, data, sizeof(float)*3 ); } void ObjParam_point::get_widget_no_button( GtkWidget *tab, bool tt, int row ) { widget = gtk_hbox_new( FALSE, 0 ); gtk_table_attach_defaults( GTK_TABLE(tab), widget, 1, 5, row-1, row ); GtkWidget *label = gtk_label_new( _(name) ); gtk_misc_set_alignment( GTK_MISC(label), 0, 0.5 ); gtk_table_attach( GTK_TABLE(tab), label, 0, 1, row-1, row, (GtkAttachOptions)(GTK_EXPAND|GTK_FILL), (GtkAttachOptions)0, 0, 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_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(sign_point_flush), this ); gtk_box_pack_start( GTK_BOX(widget), spins[i], TRUE, TRUE, 0 ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); } memcpy( undo_data, data, sizeof(float)*3 ); } void ObjParam_point::mouse_drag( struct drag_info *drag ) { if ( drag->first_click ) { UNDO_DEF ObjParam_point *copy = new ObjParam_point( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); drag->first_click = false; reversible_change = true; } else reversible_change = false; float point[3]; double view_scale = ( drag->gdkview->height + drag->gdkview->width ) / 2 / sensitivity; if ( drag->control ) { view_scale *= control_sensitivity; } double xoffset = (double)( drag->current_x - drag->previous_x ) / view_scale; double yoffset = (double)( drag->current_y - drag->previous_y ) / -view_scale; drag->rotation->rotate_vector( point, xoffset, yoffset, 0.0 ); changing = true; memcpy( undo_data, data, sizeof(float) * 3 ); TvWidget_point::add( point ); TvWidget_point::update_widget(); changing = false; ObjParam::flush( app_ref ); if ( obj != NULL ) callback( widget, obj ); } void ObjParam_point::flush() { if ( in_update ) return; if ( changing ) return; if ( send_undo ) { UNDO_DEF ObjParam_point *copy = new ObjParam_point( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } for ( register int i = 0 ; i < 3 ; i ++ ) if ( spins[i] != NULL ) gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); TvWidget_point::flush(); ObjParam::flush( app_ref ); } void ObjParam_point::swap_data( ObjParam *param ) { ObjParam_point *src = (ObjParam_point*)param; double swap = 0; for ( register int i = 0 ; i < 3 ; i++ ) { swap = data[i]; data[i] = src->data[i]; src->data[i] = swap; } update_widget(); ObjParam::flush( app_ref ); } //********************************************* // Point virtual //********************************************* void ObjParam_point_virtual::display( glview *view ) { //cout << "\nDisplay point !"; cout.flush(); glColor3f( 1.0, 0, 0 ); glPointSize( 4 ); glBegin( GL_POINTS ); glVertex3f( (GLfloat)data[0], (GLfloat)data[1], (GLfloat)data[2] ); glEnd(); } //********************************************* // Vector4 //********************************************* void ObjParam_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, TRUE, 1 ); 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_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(sign_vector4_flush), this ); 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, button ); memcpy( undo_data, data, sizeof(float)*3 ); } void ObjParam_vector4::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 ); 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_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(sign_vector4_flush), this ); gtk_box_pack_start( GTK_BOX(widget), spins[i], TRUE, TRUE, 0 ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); } memcpy( undo_data, data, sizeof(float)*3 ); } void ObjParam_vector4::flush() { if ( in_update ) return; if ( changing ) return; if ( send_undo ) { UNDO_DEF ObjParam_vector4*copy = new ObjParam_vector4( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } for ( register int i = 0 ; i < 4 ; i ++ ) if ( spins[i] != NULL ) gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); TvWidget_vector4::flush(); ObjParam::flush( app_ref ); } void ObjParam_vector4::swap_data( ObjParam *param ) { ObjParam_vector4 *src = (ObjParam_vector4*)param; double swap = 0; for ( register int i = 0 ; i < 4 ; i++ ) { swap = data[i]; data[i] = src->data[i]; src->data[i] = swap; } update_widget(); ObjParam::flush( app_ref ); } //***************************************************************** // Point 2D //**************************************************************** void ObjParam_point_2d::get_widget( GtkWidget *box, bool tt, void(*func)(GtkWidget*, gpointer ), gpointer dat ) { callback = func; obj = dat; widget = gtk_hbox_new( FALSE, 0 ); button = gtk_toggle_button_new(); gtk_container_set_border_width( GTK_CONTAINER(button), 1 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_misc_set_padding( GTK_MISC(label), 5, 0 ); gtk_container_add( GTK_CONTAINER(button), label ); gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sign_point_clicked), this ); gtk_box_pack_start( GTK_BOX(widget), button, FALSE, TRUE, 1 ); GtkObject *adj; for ( int i = 0 ; i < 2 ; 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_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(func), dat ); gtk_box_pack_start( GTK_BOX(widget), spins[i], TRUE, TRUE, 0 ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); gtk_widget_set_usize( spins[i], 10, -1 ); } pack_widget( box, tt, button ); memcpy( undo_data, data, sizeof(float)*3 ); } void ObjParam_point_2d::update_widget() { if ( !GTK_IS_WIDGET(widget) ) return; in_update = true; for ( int i = 0 ; i < 2 ; 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 ObjParam_point_2d::flush() { //cout << "\n\tflushing"; cout.flush(); if ( !GTK_IS_WIDGET(widget) ) return; if ( changing ) return; TvWidget::flush(); reversible_change = true; if ( send_undo == true ) { UNDO_DEF ObjParam_point *copy = new ObjParam_point( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } for ( int i = 0 ; i < 2 ; 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 ); } reversible_change = false; } void ObjParam_point_2d::mouse_drag( struct drag_info *drag ) { in_drag = true; if ( drag->first_click ) { if ( send_undo == true ) { UNDO_DEF ObjParam_point *copy = new ObjParam_point( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } drag->first_click = false; reversible_change = true; } else reversible_change = false; float point[3]; double view_scale = ( drag->gdkview->height + drag->gdkview->width ) / 2 / sensitivity; if ( drag->control ) { view_scale *= control_sensitivity; } double xoffset = (double)( drag->current_x - drag->previous_x ) / view_scale; double yoffset = (double)( drag->current_y - drag->previous_y ) / view_scale; if ( for_lathe ) drag->rotation->rotate_vector( point, xoffset, -yoffset, 0.0 ); else drag->rotation->rotate_vector( point, xoffset, 0, yoffset ); changing = true; memcpy( undo_data, data, sizeof(float) * 3 ); TvWidget_point::add( point ); update_widget(); changing = false; callback( widget, obj ); in_drag = false; } //********************************************* // Scale //********************************************* void ObjParam_scale::mouse_drag( struct drag_info *drag ) { if ( drag->first_click ) { if ( send_undo ) { UNDO_DEF ObjParam_scale *copy = new ObjParam_scale( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } drag->first_click = false; reversible_change = true; } reversible_change = false; float vector[3]; double view_scale = ( drag->gdkview->height + drag->gdkview->width ) / 2 / sensitivity; if ( drag->control ) view_scale *= control_sensitivity; if ( drag->shift ) { double xoffset = (double)( drag->previous_x - drag->center_x ) / view_scale; double yoffset = (double)( drag->previous_y - drag->center_y ) / view_scale; double dp = sqrt( xoffset*xoffset + yoffset*yoffset ); xoffset = (double)( drag->current_x - drag->center_x ) / view_scale; yoffset = (double)( drag->current_y - drag->center_y ) / view_scale; double dc = sqrt( xoffset*xoffset + yoffset*yoffset ); vector[0] = vector[1] = vector[2] = dc - dp; } else { double xoffset = (double)( drag->current_x - drag->previous_x ) / view_scale; double yoffset = (double)( drag->current_y - drag->previous_y ) / view_scale; float point[3]; if ( drag->origin_x < drag->center_x ) xoffset = -xoffset; if ( drag->origin_y < drag->center_y ) yoffset = -yoffset; drag->rotation->rotate_vector( point, xoffset, yoffset, 0.0 ); point[2] = -point[2]; OBJLIST_DEF Rotation *rot = objlist->get_current()->get_rotation(); if ( rot == NULL ) return; rot->rotate_vector_inverse( vector, (double)point[0], (double)point[1], (double)point[2] ); } changing = true; memcpy( undo_data, data, sizeof(float) * 3 ); TvWidget_point::add( vector ); TvWidget_point::update_widget(); changing = false; ObjParam::flush( app_ref ); } //********************************************* // Rotation //********************************************* ObjParam_rotation::ObjParam_rotation( ObjParam_rotation & ref ) : ObjParam( ref ), TvWidget( ref ) { changing = false; for ( int i = 0 ; i < 3 ; i++ ) data[i] = ref.data[i]; rotate.set_from_euler( data ); } void ObjParam_rotation::get_widget( GtkWidget *box, bool tt ) { widget = gtk_hbox_new( FALSE, 0 ); button = gtk_toggle_button_new(); gtk_container_set_border_width( GTK_CONTAINER(button), 1 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_misc_set_padding( GTK_MISC(label), 5, 0 ); gtk_container_add( GTK_CONTAINER(button), label ); gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sign_rotation_clicked), this ); gtk_box_pack_start( GTK_BOX(widget), button, FALSE, TRUE, 1 ); GtkObject *adj; for ( int i = 0 ; i < 3 ; i++ ) { adj = gtk_adjustment_new( data[i], 0, 359, 1, 10, 0 ); spins[i] = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 0, 4 ); gtk_spin_button_set_wrap( GTK_SPIN_BUTTON(spins[i]), TRUE ); gtk_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(sign_rotation_flush), this ); 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, button ); memcpy( undo_data, data, sizeof(double)*3 ); } void ObjParam_rotation::get_widget( GtkWidget *tab, bool tt, int row ) { widget = gtk_hbox_new( FALSE, 0 ); gtk_table_attach_defaults( GTK_TABLE(tab), widget, 1, 5, row-1, row ); button = gtk_toggle_button_new(); gtk_container_set_border_width( GTK_CONTAINER(button), 1 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_misc_set_padding( GTK_MISC(label), 5, 0 ); gtk_container_add( GTK_CONTAINER(button), label ); gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sign_rotation_clicked), this ); //gtk_box_pack_start( GTK_BOX(widget), button, FALSE, TRUE, 1 ); gtk_table_attach_defaults( GTK_TABLE(tab), button, 0, 1, row-1, row ); GtkObject *adj; for ( int i = 0 ; i < 3 ; i++ ) { adj = gtk_adjustment_new( data[i], 0, 359, 1, 10, 0 ); spins[i] = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 0, 4 ); gtk_spin_button_set_wrap( GTK_SPIN_BUTTON(spins[i]), TRUE ); gtk_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(sign_rotation_flush), this ); 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, button ); memcpy( undo_data, data, sizeof(double)*3 ); } void ObjParam_rotation::mouse_drag( struct drag_info *drag ) { if ( drag->first_click ) { if ( send_undo ) { UNDO_DEF ObjParam_rotation *copy = new ObjParam_rotation( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } drag->first_click = false; reversible_change = true; } reversible_change = false; if ( drag->previous_x == drag->center_x || drag->current_x == drag->center_x ) return; double temp1 = drag->previous_x - drag->center_x; double temp2 = drag->current_x - drag->center_x; double up = (drag->center_y - drag->previous_y)/temp1 - (drag->center_y - drag->current_y) / temp2; up *= temp1 * - temp2; double down = drag->center_y * ( drag->current_y + drag->previous_y - drag->center_y ); down += drag->center_x * ( drag->current_x + drag->previous_x - drag->center_x ); down -= drag->previous_y * drag->current_y + drag->previous_x * drag->current_x; if ( down == 0 ) return; double phi = atan( up/ down ); if ( drag->control ) phi /= control_sensitivity; double axis[3]; drag->rotation->rotate_z( axis ); changing = true; rotate.add( axis, phi ); memcpy( undo_data, data, sizeof(double)*3 ); rotate.get_as_euler( data ); for ( int i = 0 ; i < 3 ; i++ ) { gtk_spin_button_set_value( GTK_SPIN_BUTTON(spins[i]), data[i] ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); } changing = false; ObjParam::flush( app_ref ); } void ObjParam_rotation::flush() { if ( changing ) return; if ( in_update ) return; if ( !GTK_IS_WIDGET(widget) ) return; UNDO_DEF ObjParam_rotation *copy = new ObjParam_rotation( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); //memcpy( undo_data, data, sizeof(double) * 3 ); for ( int i = 0 ; i < 3 ; i++ ) { data[i] = gtk_spin_button_get_value_as_float( GTK_SPIN_BUTTON(spins[i]) ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); } rotate.set_from_euler( data ); TvWidget::flush(); ObjParam::flush( app_ref ); } void ObjParam_rotation::swap_data( ObjParam *param ) { ObjParam_rotation *src = (ObjParam_rotation*)param; double swap = 0; for ( register int i = 0 ; i < 3 ; i++ ) { swap = data[i]; data[i] = src->data[i]; src->data[i] = swap; } rotate.set_from_euler( data ); in_update = true; for ( int i = 0 ; i < 3 ; i++ ) gtk_spin_button_set_value( GTK_SPIN_BUTTON(spins[i]), data[i] ); in_update = false; ObjParam::flush( app_ref ); } void ObjParam_rotation::save( ofstream & file ) { TvWidget::save( file ); file << "X=" << data[0] << " Y=" << data[1] << " Z=" << data[2]; file << "} "; } bool ObjParam_rotation::load( ifstream & file, char *tag ) { if ( strcmp( sname, tag ) ) return false; char * val = NULL; do { val = tvio_get_next_val( file ); if ( val == NULL ) break; 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; } } while ( val != NULL ); rotate.set_from_euler( data ); return true; } //********************************************* // Texture reference //********************************************* ObjParam_texref::ObjParam_texref( const char *name, const char *sname, const char *tooltip, app_objs *appref, bool refr ) : ObjParam( refr ), TvWidget( name, sname, tooltip, appref) { tex_link = new TvWidget_option_combo( N_("Material"), "MAT", NULL, app_ref ); current = NULL; in_update = false; } ObjParam_texref::ObjParam_texref( ObjParam_texref & ref ) : ObjParam( ref ), TvWidget( ref ) { tex_link = new TvWidget_option_combo( *ref.tex_link ); current = ref.current; in_update = false; } void ObjParam_texref::get_widget( GtkWidget *box, bool tt ) { MATLIST_DEF const char **ref_list = (const char**)matlist->get_mat_name_list(); int ref_num = matlist->get_mat_name_list_size(); int current_index = matlist->get_index_by_pointer( current ) + 1; tex_link->set_list( ref_list, ref_num, current_index ); matlist->set_current_ref( this ); tex_link->get_widget( box, tt ); tex_link->connect_signal( GTK_SIGNAL_FUNC(sign_ref_changed), this ); GtkWidget *button = gtk_button_new(); gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sign_texref_edit), this ); GtkWidget *pix = gtk_image_new_from_stock( GTK_STOCK_EDIT, GTK_ICON_SIZE_BUTTON ); gtk_container_add( GTK_CONTAINER( button), pix ); gtk_button_set_relief( GTK_BUTTON(button), GTK_RELIEF_NONE ); GTK_WIDGET_UNSET_FLAGS( button, GTK_CAN_FOCUS ); gtk_box_pack_start( GTK_BOX(tex_link->get_gtk_widget()), button, FALSE, FALSE, 4 ); } void ObjParam_texref::get_widget( GtkWidget *tab, bool tt, int row ) { MATLIST_DEF const char **ref_list = (const char**)matlist->get_mat_name_list(); int ref_num = matlist->get_mat_name_list_size(); int current_index = matlist->get_index_by_pointer( current ) + 1; tex_link->set_list( ref_list, ref_num, current_index ); matlist->set_current_ref( this ); tex_link->get_widget( tab, tt, row ); tex_link->connect_signal( GTK_SIGNAL_FUNC(sign_ref_changed), this ); GtkWidget *button = gtk_button_new(); gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sign_texref_edit), this ); GtkWidget *pix = gtk_image_new_from_stock( GTK_STOCK_EDIT, GTK_ICON_SIZE_BUTTON ); gtk_container_add( GTK_CONTAINER( button), pix ); gtk_button_set_relief( GTK_BUTTON(button), GTK_RELIEF_NONE ); GTK_WIDGET_UNSET_FLAGS( button, GTK_CAN_FOCUS ); gtk_box_pack_start( GTK_BOX(tex_link->get_gtk_widget()), button, FALSE, FALSE, 4 ); } void ObjParam_texref::edit_material() { if ( current == NULL ) return; MATLIST_DEF matlist->raise_texeditor( current ); } void ObjParam_texref::update_ref_list() { MATLIST_DEF const char **ref_list = (const char**)matlist->get_mat_name_list(); int ref_num = matlist->get_mat_name_list_size(); int current_index = matlist->get_index_by_pointer( current ) + 1; if ( current_index == 0 ) current = NULL; tex_link->set_list( ref_list, ref_num, current_index ); in_update = true; tex_link->update_widget(); in_update = false; } void ObjParam_texref::flush() { if ( in_update ) return; if ( send_undo ) { UNDO_DEF ObjParam_texref *copy = new ObjParam_texref( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } MATLIST_DEF tex_link->flush(); if ( tex_link->value() > 0 ) current = matlist->get_pointer_by_index( tex_link->value()-1 ); else current = NULL; ObjParam::flush( app_ref ); } void ObjParam_texref::swap_data( ObjParam *param ) { ObjParam_texref *src = (ObjParam_texref*)param; int swap = tex_link->value(); tex_link->set( src->tex_link->value() ); src->tex_link ->set( swap ); MATLIST_DEF current = matlist->get_pointer_by_index( tex_link->value()-1 ); in_update = true; tex_link->update_widget(); in_update = false; ObjParam::flush( app_ref ); } void ObjParam_texref::clear_widget() { widget = NULL; tex_link->clear_widget(); MATLIST_DEF matlist->set_current_ref( NULL ); } void ObjParam_texref::output_to_povray( ofstream & file ) { MATLIST_DEF int current_index = matlist->get_index_by_pointer( current ) + 1; if ( current_index == 0 ) current = NULL; if ( current == NULL ) { return; } if ( !current->is_used() ) { return; } file << "\tmaterial { "; current->get_underscore_name( file ); file << " }"; } void ObjParam_texref::save( ofstream & file ) { MATLIST_DEF int current_index = matlist->get_index_by_pointer( current ) + 1; if ( current_index == 0 ) current = NULL; TvWidget::save( file ); file << "VALUE=\"" << (( current == NULL || !current->is_used() ) ? "NONE" : current->get_name()) << '\"'; file << "} "; } bool ObjParam_texref::load( ifstream & file, char *tag ) { if ( strcmp( sname, tag ) ) return false; char * val = NULL; char *res = NULL; do { val = tvio_get_next_val( file ); if ( val == NULL ) break; if ( ! strcmp( val, "VALUE" ) ) { res= tvio_get_value_as_string( file ); MATLIST_DEF if ( res == NULL || ! strcmp( res, "NONE" ) ) current = NULL; else current = matlist->get_pointer_by_name( res ); continue; } } while ( val != NULL ); return true; } void ObjParam_texref::get_material( vector & mlist ) { MATLIST_DEF int current_index = matlist->get_index_by_pointer( current ) + 1; if ( current_index == 0 ) current = NULL; if ( current == NULL ) return; for ( unsigned int i = 0 ; i < mlist.size() ; i ++ ) if ( mlist[i] == current ) return; mlist.push_back( current ); } //********************************************* // Object reference //********************************************* ObjParam_objref::ObjParam_objref( const char *name, const char *sname, const char *tooltip, app_objs *appref, bool refr ) : ObjParam( refr ), TvWidget( name, sname, tooltip, appref) { obj_link = new TvWidget_option_combo( name, "OBJR", NULL, app_ref ); current = NULL; in_update = false; } ObjParam_objref::ObjParam_objref( ObjParam_objref & ref ) : ObjParam( ref ), TvWidget( ref ) { obj_link = new TvWidget_option_combo( *ref.obj_link ); current = ref.current; in_update = false; } void ObjParam_objref::get_widget( GtkWidget *box, bool tt ) { OBJLIST_DEF const char **ref_list = (const char**)objlist->get_obj_name_list(); int ref_num = objlist->get_obj_name_list_size(); int current_index = objlist->get_index_by_pointer( current )+1; obj_link->set_list( ref_list, ref_num, current_index ); objlist->set_current_ref( this ); obj_link->get_widget( box, tt ); obj_link->connect_signal( GTK_SIGNAL_FUNC(sign_ref_changed), this ); } void ObjParam_objref::get_widget( GtkWidget *tab, bool tt, int row ) { OBJLIST_DEF const char **ref_list = (const char**)objlist->get_obj_name_list(); int ref_num = objlist->get_obj_name_list_size(); int current_index = objlist->get_index_by_pointer( current )+1; obj_link->set_list( ref_list, ref_num, current_index ); objlist->set_current_ref( this ); obj_link->get_widget( tab, tt, row ); obj_link->connect_signal( GTK_SIGNAL_FUNC(sign_ref_changed), this ); } void ObjParam_objref::update_ref_list() { OBJLIST_DEF const char **ref_list = (const char**)objlist->get_obj_name_list(); int ref_num = objlist->get_obj_name_list_size(); int current_index = objlist->get_index_by_pointer( current ) + 1; if ( current_index == 0 ) current = NULL; obj_link->set_list( ref_list, ref_num, current_index ); in_update = true; obj_link->update_widget(); in_update = false; } void ObjParam_objref::flush() { if ( in_update ) return; if ( send_undo ) { UNDO_DEF ObjParam_objref *copy = new ObjParam_objref( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } OBJLIST_DEF obj_link->flush(); if ( obj_link->value() > 0 ) current = objlist->get_pointer_by_index( obj_link->value()-1 ); else current = NULL; ObjParam::flush( app_ref ); } void ObjParam_objref::swap_data( ObjParam *param ) { ObjParam_objref *src = (ObjParam_objref*)param; int swap = obj_link->value(); obj_link->set( src->obj_link->value() ); src->obj_link ->set( swap ); OBJLIST_DEF current = objlist->get_pointer_by_index( obj_link->value()-1 ); in_update = true; obj_link->update_widget(); in_update = false; ObjParam::flush( app_ref ); } void ObjParam_objref::clear_widget() { widget = NULL; obj_link->clear_widget(); OBJLIST_DEF objlist->set_current_ref( NULL ); } void ObjParam_objref::save( ofstream & file ) { TvWidget::save( file ); file << "VALUE=\"" << (( current == NULL ) ? "NONE" : current->get_name()) << '\"'; file << "} "; } bool ObjParam_objref::load( ifstream & file, char *tag ) { if ( strcmp( sname, tag ) ) return false; char * val = NULL; char *res = NULL; do { val = tvio_get_next_val( file ); if ( val == NULL ) break; if ( ! strcmp( val, "VALUE" ) ) { res= tvio_get_value_as_string( file ); OBJLIST_DEF if ( res == NULL || ! strcmp( res, "NONE" ) ) current = NULL; else current = objlist->get_pointer_by_name( res ); continue; } } while ( val != NULL ); return true; } //********************************************* // entry //********************************************* void ObjParam_entry::get_widget( GtkWidget *box, bool tt ) { TvWidget_entry::get_widget( box, tt ); gtk_signal_connect( GTK_OBJECT(entry), "changed", GTK_SIGNAL_FUNC(sign_objparam_entry_flush), this ); } void ObjParam_entry::get_widget( GtkWidget *tab, bool tt, int row ) { TvWidget_entry::get_widget( tab, tt, row ); gtk_signal_connect( GTK_OBJECT(entry), "changed", GTK_SIGNAL_FUNC(sign_objparam_entry_flush), this ); } void ObjParam_entry::flush() { if ( in_update ) return; if ( send_undo ) { UNDO_DEF ObjParam_entry *copy = new ObjParam_entry( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } TvWidget_entry::flush(); ObjParam::flush( app_ref ); } void ObjParam_entry::swap_data( ObjParam *param ) { ObjParam_entry *src = (ObjParam_entry*)param; char *swap = data; data = src->data; src->data = swap; update_widget(); ObjParam::flush( app_ref ); } //********************************************* // path //********************************************* void ObjParam_path::get_widget( GtkWidget *box, bool tt ) { TvWidget_path::get_widget( box, tt ); connect_signal( GTK_SIGNAL_FUNC(sign_objparam_path_flush), this ); //gtk_signal_connect( GTK_OBJECT(fentry), "selection-changed",GTK_SIGNAL_FUNC(sign_objparam_path_flush), this ); } void ObjParam_path::get_widget( GtkWidget *tab, bool tt, int row ) { TvWidget_path::get_widget( tab, tt, row ); connect_signal( GTK_SIGNAL_FUNC(sign_objparam_path_flush), this ); //gtk_signal_connect( GTK_OBJECT(fentry), "selection-changed",GTK_SIGNAL_FUNC(sign_objparam_path_flush), this ); } void ObjParam_path::flush() { if ( in_update ) return; if ( send_undo ) { UNDO_DEF ObjParam_path *copy = new ObjParam_path( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } TvWidget_path::flush(); ObjParam::flush( app_ref ); } void ObjParam_path::swap_data( ObjParam *param ) { ObjParam_path *src = (ObjParam_path*)param; char *swap = data; data = src->data; src->data = swap; update_widget(); ObjParam::flush( app_ref ); } //********************************************* // file //********************************************* void ObjParam_file::get_widget( GtkWidget *box, bool tt ) { TvWidget_file::get_widget( box, tt ); connect_signal( GTK_SIGNAL_FUNC(sign_objparam_file_flush), this ); } void ObjParam_file::get_widget( GtkWidget *box, bool tt, int row ) { TvWidget_file::get_widget( box, tt, row ); connect_signal( GTK_SIGNAL_FUNC(sign_objparam_file_flush), this ); } void ObjParam_file::flush() { if ( in_update ) return; if ( send_undo ) { UNDO_DEF ObjParam_file *copy = new ObjParam_file( *this ); undoman->push( TV_UNDO_PARAM_CHANGED, this, copy ); } //TvWidget_file::flush(); ObjParam::flush( app_ref ); } void ObjParam_file::swap_data( ObjParam *param ) { //ObjParam_file *src = (ObjParam_file*)param; TvWidget_file::swap_data( (TvWidget_file*)param ); update_widget(); ObjParam::flush( app_ref ); }