//***************************************************************************************** // Truevision - a 3d modeler for gnome and povray // // tvwidgets2.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" //********************************************************* // Classe rotation //********************************************************* TvWidget_rotation::TvWidget_rotation( TvWidget_rotation & ref ) : TvWidget( ref ) { memcpy( data, ref.data, sizeof(float)*3 ); for ( int i = 0 ; i < 3 ; i++ ) spins[i] = NULL; } void TvWidget_rotation::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], -360, 360, 1, 10, 2 ); spins[i] = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 0, 4 ); gtk_spin_button_set_wrap( GTK_SPIN_BUTTON(spins[i]), TRUE ); 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_rotation::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 ); GtkObject *adj; for ( int i = 0 ; i < 3 ; i++ ) { adj = gtk_adjustment_new( data[i], -360, 360, 1, 10, 2 ); spins[i] = gtk_spin_button_new( GTK_ADJUSTMENT(adj), 0, 4 ); gtk_spin_button_set_wrap( GTK_SPIN_BUTTON(spins[i]), TRUE ); gtk_box_pack_start( GTK_BOX(widget), spins[i], TRUE, TRUE, 0 ); gtk_editable_set_position( GTK_EDITABLE(spins[i] ), 0 ); } 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( widget ); } void TvWidget_rotation::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_rotation::flush() { if ( !GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); 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 ); } } void TvWidget_rotation::gl_rotate() { glRotatef( data[0], 1, 0, 0 ); glRotatef( data[1], 0, 1, 0 ); glRotatef( data[2], 0, 0, 1 ); } void TvWidget_rotation::save( ofstream & file ) { TvWidget::save( file ); file << "X=" << data[0] << " Y=" << data[1] << " Z=" << data[2]; file << "} "; } bool TvWidget_rotation::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 transformation //********************************************************* TvWidget_transformation::TvWidget_transformation( const char *name, const char *sname, const char *tooltip, app_objs *appref ) : TvWidget( name, sname, tooltip, appref ) { transfo = new TvWidget_bool_activator( N_("Use transformation"), "USED", NULL, app_ref, false ); scale = new TvWidget_point( N_("Scale"), "SCALE", NULL, app_ref ); scale->set( 1, 1, 1 ); translate = new TvWidget_point( N_("Translate"), "TRANSL", NULL, app_ref ); translate->set( 0, 0, 0 ); rotate = new TvWidget_rotation( N_("Rotate"), "ROT", NULL, app_ref ); rotate->set( 0, 0, 0 ); } TvWidget_transformation::TvWidget_transformation( TvWidget_transformation & ref ) : TvWidget( ref ) { transfo = new TvWidget_bool_activator( *ref.transfo ); scale = new TvWidget_point( *ref.scale ); translate = new TvWidget_point( *ref.translate ); rotate = new TvWidget_rotation( *ref.rotate ); } TvWidget_transformation::~TvWidget_transformation() { delete transfo; delete scale; delete translate; delete rotate; } void TvWidget_transformation::get_widget_wnframe( GtkWidget *box, bool tt, bool frame ) { if ( frame ) widget = dlg_simple_box_frame( _(name), box ); else { widget = gtk_vbox_new( FALSE, 0 ); gtk_box_pack_start( GTK_BOX(box), widget, FALSE, TRUE, 2 ); } transfo->get_widget_no_toggle( widget, tt ); GtkWidget *tbox = new_table_no_frame( widget, 3 ); transfo->set_target( tbox ); translate->get_widget( tbox, tt, 1 ); translate->reduce_size(); scale->get_widget( tbox, tt, 2 ); scale->reduce_size(); rotate->get_widget( tbox, tt, 3 ); rotate->reduce_size(); transfo->update_widget(); } void TvWidget_transformation::clear_widget() { TvWidget::clear_widget(); transfo->clear_widget(); scale->clear_widget(); translate->clear_widget(); rotate->clear_widget(); } void TvWidget_transformation::flush() { if ( widget == NULL ) return; TvWidget::flush(); transfo->flush(); scale->flush(); translate->flush(); rotate->flush(); } void TvWidget_transformation::output_to_povray( ofstream & file ) { if ( !transfo->value() ) return; file << " translate "; translate->output_to_povray( file ); file << " scale "; scale->output_to_povray( file ); file << " rotate "; rotate->output_to_povray( file ); } void TvWidget_transformation::save( ofstream & file ) { if ( !transfo->value() ) return; TvWidget::save( file ); rotate->save( file ); scale->save( file ); translate->save( file ); file << "} "; } bool TvWidget_transformation::load( ifstream & file, char * ltag ) { if ( strcmp( sname, ltag ) ) return false; char * tag = NULL; transfo->set( true ); do { tag = tvio_get_next_tag( file ); if ( tag == NULL ) break; if ( rotate->load( file , tag ) ) continue; if ( scale->load( file , tag ) ) continue; if ( translate->load( file , tag ) ) continue; tvio_skip_section( file ); } while( tag != NULL ); return true; } //********************************************************* // Classe axis //********************************************************* const int axis_num = 3; const char *axis_list[axis_num] = { "x", "y", "z" }; TvWidget_axis::TvWidget_axis( const char *name, const char *sname, const char *tooltip, app_objs *appref ) : TvWidget( name, sname, tooltip, appref ) { axis = new TvWidget_option_combo( name, "DIR", NULL, app_ref ); axis->set_list( axis_list, axis_num, 0 ); offset = new TvWidget_float( N_("Value"), "VAL", NULL, app_ref, 2.0 ); } TvWidget_axis::TvWidget_axis( TvWidget_axis & ref ) : TvWidget( ref ) { axis = new TvWidget_option_combo( *ref.axis ); offset = new TvWidget_float( *ref.offset ); } TvWidget_axis::~TvWidget_axis() { delete axis; delete offset; } void TvWidget_axis::get_widget( GtkWidget *box, bool tt ) { widget = gtk_vbox_new( FALSE, 0 ); axis->get_widget( widget, tt ); offset->get_widget( widget, tt ); pack_widget( box, tt ); } void TvWidget_axis::get_widget( GtkWidget *tab, bool tt, int row ) { axis->get_widget( tab, tt, row ); offset->get_widget( tab, tt, row+1 ); } void TvWidget_axis::clear_widget() { TvWidget::clear_widget(); axis->clear_widget(); offset->clear_widget(); } void TvWidget_axis::flush() { if ( ! GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); axis->flush(); offset->flush(); } void TvWidget_axis::output_to_povray( ofstream & file ) { file << axis_list[axis->value()] << "*"; offset->output_to_povray( file ); } void TvWidget_axis::save( ofstream & file ) { TvWidget::save( file ); axis->save( file ); offset->save( file ); file << "} "; } bool TvWidget_axis::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 ( axis->load( file , tag ) ) continue; if ( offset->load( file , tag ) ) continue; tvio_skip_section( file ); } while( tag != NULL ); return true; } //********************************************************* // Classe blockpattern //********************************************************* const int blockpattern_type_num = 3; const char *blockpattern_type_list[blockpattern_type_num] = { N_("Brick"), N_("Checker"), N_("Hexagon") }; const char *blockpattern_output[blockpattern_type_num] = { "brick", "checker", "hexagon" }; TvWidget_blockpattern::TvWidget_blockpattern( const char *name, const char *sname, const char *tooltip, app_objs *appref ) : TvWidget( name, sname, tooltip, appref ) { type = new TvWidget_option_combo( N_("Type"), "TYPE", NULL, app_ref ); type->set_list( blockpattern_type_list, blockpattern_type_num, 0 ); bricksize = new TvWidget_point( N_("Brick size"), "BSIZE", NULL, app_ref ); bricksize->set( 8, 3, 4.5 ); mortar = new TvWidget_float( N_("Mortar"), "MORTAR", NULL, app_ref, 0.5 ); mortar->set_range( 200, 0, 0.1, 5 ); func = NULL; } TvWidget_blockpattern::TvWidget_blockpattern( TvWidget_blockpattern & ref ) : TvWidget( ref ) { type = new TvWidget_option_combo( *ref.type ); bricksize = new TvWidget_point( *ref.bricksize ); mortar = new TvWidget_float( *ref.mortar ); func = NULL; data = NULL; } TvWidget_blockpattern::~TvWidget_blockpattern() { delete type; delete bricksize; delete mortar; } void TvWidget_blockpattern::get_widget( GtkWidget *box, bool tt ) { func = NULL; widget = dlg_simple_box_frame( _(name), box ); type->get_widget( widget, tt ); bricksize->get_widget( widget, tt ); mortar->get_widget( widget, tt ); type_changed(); type->connect_signal( GTK_SIGNAL_FUNC(sign_blockp_type_changed), this ); } void TvWidget_blockpattern::type_changed() { if ( widget == NULL ) return; type->flush(); if ( type->value() == 0 ) { bricksize->set_widget_active(); mortar->set_widget_active(); } else { bricksize->set_widget_inactive(); mortar->set_widget_inactive(); } if ( func != NULL ) (*func)( data ); } void TvWidget_blockpattern::clear_widget() { widget = NULL; func = NULL; type->clear_widget(); bricksize->clear_widget(); mortar->clear_widget(); } void TvWidget_blockpattern::flush() { if ( ! GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); type->flush(); bricksize->flush(); mortar->flush(); } void TvWidget_blockpattern::output_to_povray( ofstream & file ) { file << blockpattern_output[type->value()]; } void TvWidget_blockpattern::output_to_povray_options( ofstream & file ) { if ( type->value() != 0 ) return; file << "\n\t\t\tbrick_size "; bricksize->output_to_povray( file ); file << "\n\t\t\tmortar "; mortar->output_to_povray( file ); } void TvWidget_blockpattern::save( ofstream & file ) { TvWidget::save( file ); type->save( file ); bricksize->save( file ); mortar->save( file ); file << "} "; } bool TvWidget_blockpattern::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 ( type->load( file , tag ) ) continue; if ( bricksize->load( file , tag ) ) continue; if ( mortar->load( file , tag ) ) continue; tvio_skip_section( file ); } while( tag != NULL ); return true; } //********************************************************* // Classe noise //********************************************************* TvWidget_noise::TvWidget_noise( const char *name, const char *sname, const char *tooltip, app_objs *appref ) : TvWidget( name, sname, tooltip, appref ) { use = new TvWidget_bool_activator( N_("Add noise"), "USED", NULL, app_ref, false ); turbulence = new TvWidget_point( N_("Turbulence"), "TURB", NULL, app_ref ); turbulence->set( 0, 0, 0 ); octaves = new TvWidget_int( N_("Octaves"), "OCT", NULL, app_ref, 6 ); octaves->set_range( 10, 0, 1 ); omega = new TvWidget_float( N_("Omega"), "OMEG", NULL, app_ref, 0.5 ); omega->set_range( 20, 0, 0.1, 3 ); lambda = new TvWidget_float( N_("Lambda"), "LAMB", NULL, app_ref, 2.0 ); lambda->set_range( 20, 0, 0.1, 3 ); noisegen = new TvWidget_noise_generator( N_("Noise generator"), "NOISEGEN", NULL, app_ref ); } TvWidget_noise::TvWidget_noise( TvWidget_noise & ref ) : TvWidget( ref ) { use = new TvWidget_bool_activator( *ref.use ); turbulence = new TvWidget_point( *ref.turbulence ); octaves = new TvWidget_int( *ref.octaves ); octaves->set_range( 10, 0, 1 ); omega = new TvWidget_float( *ref.omega ); lambda = new TvWidget_float( *ref.lambda ); noisegen = new TvWidget_noise_generator( *ref.noisegen ); } TvWidget_noise::~TvWidget_noise() { delete use; delete turbulence; delete octaves; delete omega; delete lambda; delete noisegen; } void TvWidget_noise::get_widget_wnframe( GtkWidget *box, bool tt, bool frame ) { if ( frame ) widget = dlg_simple_box_frame( _(name), box ); else { widget = gtk_vbox_new( FALSE, 0 ); gtk_box_pack_start( GTK_BOX(box), widget, FALSE, TRUE, 2 ); } use->get_widget_no_toggle( widget, tt ); GtkWidget *tbox = new_table_no_frame( widget, 5 ); use->set_target( tbox ); turbulence->get_widget( tbox, tt, 1 ); turbulence->reduce_size(); octaves->get_widget( tbox, tt, 2 ); lambda->get_widget( tbox, tt, 3 ); omega->get_widget( tbox, tt, 4 ); noisegen->get_widget( tbox, tt, 5 ); use->update_widget(); } void TvWidget_noise::clear_widget() { TvWidget::clear_widget(); use->clear_widget(); turbulence->clear_widget(); octaves->clear_widget(); lambda->clear_widget(); omega->clear_widget(); noisegen->clear_widget(); } void TvWidget_noise::flush() { if ( ! GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); use->flush(); turbulence->flush(); octaves->flush(); lambda->flush(); omega->flush(); noisegen->flush(); } void TvWidget_noise::output_to_povray( ofstream & file ) { if ( !use->value() ) return; file << "\n\t\t turbulence "; turbulence->output_to_povray( file ); file << "\n\t\t octaves "; octaves->output_to_povray( file ); file << "\n\t\t lambda "; lambda->output_to_povray( file ); file << "\n\t\t omega "; omega->output_to_povray( file ); noisegen->output_to_povray( file ); } void TvWidget_noise::save( ofstream & file ) { if ( !use->value() ) return; TvWidget::save( file ); turbulence->save( file ); octaves->save( file ); lambda->save( file ); omega->save( file ); noisegen->save( file ); file << "} "; } bool TvWidget_noise::load( ifstream & file, char * ltag ) { if ( strcmp( sname, ltag ) ) return false; char * tag = NULL; use->set( true ); do { tag = tvio_get_next_tag( file ); if ( tag == NULL ) break; if ( turbulence->load( file , tag ) ) continue; if ( octaves->load( file , tag ) ) continue; if ( lambda->load( file , tag ) ) continue; if ( omega->load( file , tag ) ) continue; if ( noisegen->load( file , tag ) ) continue; tvio_skip_section( file ); } while( tag != NULL ); return true; } //********************************************************* // Classe warp //********************************************************* const int warp_num = 7; const char *warp_list[warp_num] = { N_("Black hole warp"), N_("Repeat warp"), N_("Turbulence warp"), N_("Cylindrical"), N_("Spherical"), N_("Toroidal"), N_("Planar") }; TvWidget_warp::TvWidget_warp( const char *name, const char *sname, const char *tooltip, app_objs *appref ) : TvWidget( name, sname, tooltip, appref ) { changing_box = NULL; use = new TvWidget_bool_activator( N_("Use warp"), "USED", NULL, app_ref, false ); type = new TvWidget_option_combo( N_("Type"), "TYPE", NULL, app_ref ); type->set_list( warp_list, warp_num, 0 ); center = new TvWidget_point( N_("Center"), "CENTER", NULL, app_ref ); center->set( 0, 0, 0 ); repeat = new TvWidget_point( N_("Repeat"), "REPEAT", NULL, app_ref ); repeat->set( 0, 0, 0 ); radius = new TvWidget_float( N_("Radius"), "RADIUS", NULL, app_ref, 0.5 ); strength = new TvWidget_float( N_("Strength"), "STRENGTH", NULL, app_ref, 1.0 ); falloff = new TvWidget_float( N_("Falloff"), "FALLOFF", NULL, app_ref, 1.0 ); inverse = new TvWidget_bool( N_("Inverse"), "INVERSE", NULL, app_ref, false ); repeat_axis = new TvWidget_axis( N_("Direction"), "DIR", NULL, app_ref ); offset = new TvWidget_point( N_("Offset"), "OFFSET", NULL, app_ref ); offset->set( 0, 0, 0 ); flip = new TvWidget_point( N_("Flip"), "FLIP", NULL, app_ref ); flip->set( 0, 0, 0 ); turbulence = new TvWidget_point( N_("Turbulence"), "TURB", NULL, app_ref ); turbulence->set( 0, 0, 0 ); octaves = new TvWidget_int( N_("Octaves"), "OCT", NULL, app_ref, 6 ); omega = new TvWidget_float( N_("Omega"), "OMEG", NULL, app_ref, .05 ); lambda = new TvWidget_float( N_("Lambda"), "LAMB", NULL, app_ref, 2.0 ); dist_exp = new TvWidget_int( N_("Distance exponant"), "DISTEXP", NULL, app_ref, 0 ); dist_exp->set_range( 10, 0, 1 ); major_radius = new TvWidget_float( N_("Major radius"), "MRAD", NULL, app_ref, 1 ); major_radius->set_range( 10, 0, 0.1, 2 ); direction = new TvWidget_point( N_("Orientation"), "ORIENT", NULL, app_ref ); direction->set( 0, 0, 1 ); normal = new TvWidget_point( N_("Normal"), "NORMAL", NULL, app_ref ); normal->set( 0, 0, 1 ); distance = new TvWidget_float( N_("Distance"), "DISTANCE", NULL, app_ref, 0 ); distance->set_range( 30, -30, 0.1, 2 ); } TvWidget_warp::TvWidget_warp( TvWidget_warp & ref ) : TvWidget( ref ) { changing_box = NULL; use = new TvWidget_bool_activator( *ref.use ); type = new TvWidget_option_combo( *ref.type ); center = new TvWidget_point( *ref.center ); repeat = new TvWidget_point( *ref.repeat ); radius = new TvWidget_float( *ref.radius ); strength = new TvWidget_float( *ref.strength ); falloff = new TvWidget_float( *ref.falloff ); inverse = new TvWidget_bool( *ref.inverse ); repeat_axis = new TvWidget_axis( *ref.repeat_axis ); offset = new TvWidget_point( *ref.offset ); flip = new TvWidget_point( *ref.flip ); turbulence = new TvWidget_point( *ref.turbulence ); octaves = new TvWidget_int( *ref.octaves ); omega = new TvWidget_float( *ref.omega ); lambda = new TvWidget_float( *ref.lambda ); direction = new TvWidget_point( *ref.direction ); dist_exp = new TvWidget_int( *ref.dist_exp ); major_radius = new TvWidget_float( *ref.major_radius ); normal = new TvWidget_point( *ref.normal ); distance = new TvWidget_float( *ref.distance ); } void TvWidget_warp::copy( TvWidget *wo ) { TvWidget_warp *wr = (TvWidget_warp*)wo; use->copy( wr->use ); type->copy( wr->type ); center->copy( wr->center ); repeat->copy( wr->repeat ); radius->copy( wr->radius ); strength->copy( wr->strength ); falloff->copy( wr->falloff ); inverse->copy( wr->inverse ); repeat_axis->copy( wr->repeat_axis ); offset->copy( wr->offset ); flip->copy( wr->flip ); turbulence->copy( wr->turbulence ); octaves->copy( wr->octaves ); omega->copy( wr->omega ); lambda->copy( wr->lambda ); direction->copy( wr->direction ); dist_exp->copy( wr->dist_exp ); major_radius->copy( wr->major_radius ) ; normal->copy( wr->normal ); distance->copy( wr->distance ); } TvWidget_warp::~TvWidget_warp() { delete use; delete type; delete center; delete repeat; delete radius; delete strength; delete falloff; delete inverse; delete repeat_axis; delete offset; delete flip; delete turbulence; delete octaves; delete omega; delete lambda; delete direction; delete dist_exp; delete major_radius; delete normal; delete distance; } void TvWidget_warp::get_widget_wnframe( GtkWidget *box, bool tt, bool frame ) { changing_box = NULL; if ( frame ) widget = dlg_simple_box_frame( _(name), box ); else { widget = gtk_vbox_new( FALSE, 0 ); gtk_box_pack_start( GTK_BOX(box), widget, FALSE, TRUE, 2 ); } use->get_widget_no_toggle( widget, tt ); activated_box = gtk_vbox_new( FALSE, 0 ); gtk_box_pack_start( GTK_BOX(widget), activated_box, FALSE, FALSE, 0 ); use->set_target( activated_box ); type->get_widget( activated_box, tt ); type->connect_signal( GTK_SIGNAL_FUNC(sign_warptype_changed), this ); type_changed(); use->update_widget(); } void TvWidget_warp::type_changed() { bool tt = true; type->flush(); if ( changing_box != NULL ) { gtk_widget_destroy( changing_box ); center->clear_widget(); repeat->clear_widget(); radius ->clear_widget(); strength->clear_widget(); falloff->clear_widget(); inverse->clear_widget(); offset->clear_widget(); flip->clear_widget(); turbulence->clear_widget(); octaves->clear_widget(); lambda->clear_widget(); omega->clear_widget(); direction->clear_widget(); dist_exp->clear_widget(); major_radius->clear_widget(); normal->clear_widget(); distance->clear_widget(); } changing_box = gtk_vbox_new( FALSE, 0 ); gtk_box_pack_start( GTK_BOX(activated_box), changing_box, FALSE, FALSE, 0 ); GtkWidget *table; switch( type->value() ) { case 0: table = new_table_no_frame( changing_box, 7 ); center->get_widget( table, tt, 1 ); center->reduce_size(); radius->get_widget( table, tt, 2 ); falloff->get_widget( table, tt, 3 ); strength->get_widget( table, tt, 4 ); repeat->get_widget( table, tt, 5 ); repeat->reduce_size(); turbulence->get_widget( table, tt, 6 ); turbulence->reduce_size(); inverse->get_widget( table, tt, 7 ); break; case 1: table = new_table_no_frame( changing_box, 4 ); repeat_axis->get_widget( table, tt, 1 ); offset->get_widget( table, tt, 3 ); offset->reduce_size(); flip->get_widget( table, tt, 4 ); flip->reduce_size(); break; case 2: table = new_table_no_frame( changing_box, 4 ); turbulence->get_widget( table, tt, 1 ); turbulence->reduce_size(); octaves->get_widget( table, tt, 2 ); lambda->get_widget( table, tt, 3 ); omega->get_widget( table, tt, 4 ); break; case 3: case 4: table = new_table_no_frame( changing_box, 2 ); direction->get_widget( table, tt, 1 ); direction->reduce_size(); dist_exp->get_widget( table, tt, 2 ); break; case 5: table = new_table_no_frame( changing_box, 3 ); direction->get_widget( table, tt, 1 ); direction->reduce_size(); dist_exp->get_widget( table, tt, 2 ); major_radius->get_widget( table, tt, 3 ); break; case 6: table = new_table_no_frame( changing_box, 2 ); normal->get_widget( table, tt, 1 ); normal->reduce_size(); distance->get_widget( table, tt, 2 ); break; default: break; } gtk_widget_show_all( changing_box ); } void TvWidget_warp::clear_widget() { widget = NULL; use->clear_widget(); type->clear_widget(); center->clear_widget(); repeat->clear_widget(); radius ->clear_widget(); strength->clear_widget(); falloff->clear_widget(); inverse->clear_widget(); repeat_axis->clear_widget(); offset->clear_widget(); flip->clear_widget(); turbulence->clear_widget(); octaves->clear_widget(); lambda->clear_widget(); omega->clear_widget(); direction->clear_widget(); dist_exp->clear_widget(); major_radius->clear_widget(); normal->clear_widget(); distance->clear_widget(); } void TvWidget_warp::flush() { if ( widget == NULL ) return; TvWidget::flush(); use->flush(); center->flush(); repeat->flush(); radius ->flush(); strength->flush(); falloff->flush(); type->flush(); inverse->flush(); repeat_axis->flush(); offset->flush(); flip->flush(); turbulence->flush(); octaves->flush(); lambda->flush(); omega->flush(); direction->flush(); dist_exp->flush(); major_radius->flush(); normal->flush(); distance->flush(); } void TvWidget_warp::output_to_povray( ofstream & file ) { if ( !use->value() ) return; file << "\n\t\t warp {"; switch( type->value() ) { case 0: file << "\n\t\t\tblack_hole "; center->output_to_povray( file ); file << " , "; radius->output_to_povray( file ); file << "\n\t\t\tfalloff "; falloff->output_to_povray( file ); file << "\n\t\t\tstrength "; strength->output_to_povray( file ); file << "\n\t\t\trepeat "; repeat->output_to_povray( file ); file << "\n\t\t\tturbulence "; turbulence->output_to_povray( file ); if ( inverse->value() ) file << "\n\t\t\tinverse"; break; case 1: file << "\n\t\t\trepeat "; repeat_axis->output_to_povray( file ); file << "\n\t\t\toffset "; offset->output_to_povray( file ); file << "\n\t\t\tflip "; flip->output_to_povray( file ); break; case 2: file << "\n\t\t\tturbulence "; turbulence->output_to_povray( file ); file << "\n\t\t\toctaves "; octaves->output_to_povray( file ); file << "\n\t\t\tlambda "; lambda->output_to_povray( file ); file << "\n\t\t\tomega "; omega->output_to_povray( file ); break; case 3: file << "\n\t\tcylindrical "; file << "\n\t\t\tdist_exp "; dist_exp->output_to_povray( file ); break; case 4: file << "\n\t\tspherical "; file << "\n\t\t\tdist_exp "; dist_exp->output_to_povray( file ); break; case 5: file << "\n\t\ttoroidal "; file << "\n\t\t\tdist_exp "; dist_exp->output_to_povray( file ); break; case 6: file << "\n\t\tplanar "; normal->output_to_povray( file ); file << ","; distance->output_to_povray( file ); break; } file << "\n\t\t}"; } void TvWidget_warp::save( ofstream & file ) { if ( !use->value() ) return; TvWidget::save( file ); type->save( file ); center->save( file ); radius->save( file ); falloff->save( file ); strength->save( file ); repeat->save( file ); inverse->save( file ) ; repeat_axis->save( file ); offset->save( file ); flip->save( file ); turbulence->save( file ); octaves->save( file ); lambda->save( file ); omega->save( file ); direction->save( file ); dist_exp->save( file ); major_radius->save( file ); normal->save( file ); distance->save( file ); file << "} "; } bool TvWidget_warp::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 ( type->load( file , tag ) ) continue; if ( center->load( file , tag ) ) continue; if ( radius->load( file , tag ) ) continue; if ( falloff->load( file , tag ) ) continue; if ( strength->load( file , tag ) ) continue; if ( repeat->load( file , tag ) ) continue; if ( inverse->load( file , tag ) ) continue; if ( repeat_axis->load( file , tag ) ) continue; if ( offset->load( file , tag ) ) continue; if ( flip->load( file , tag ) ) continue; if ( turbulence->load( file , tag ) ) continue; if ( octaves->load( file , tag ) ) continue; if ( lambda->load( file , tag ) ) continue; if ( omega->load( file , tag ) ) continue; if ( direction->load( file , tag ) ) continue; if ( dist_exp->load( file , tag ) ) continue; if ( major_radius->load( file , tag ) ) continue; if ( normal->load( file , tag ) ) continue; if ( distance->load( file , tag ) ) continue; tvio_skip_section( file ); } while( tag != NULL ); return true; } //********************************************************* // Classe blendmap //********************************************************* const int blendmap_num = 25; const char *blendmap_list[blendmap_num] = { N_("Agate"), N_("Boxed"), N_("Bozo / Spotted"), N_("Bumps"), N_("Crackle"), N_("Cylindrical"), N_("Dents"), N_("Gradient"), N_("Granite"), N_("Leopard"), N_("Mandel"), N_("Marble"), N_("Onion"), N_("Planar"), N_("Quilted"), N_("Radial"), N_("Ripples"), N_("Spherical"), N_("Spiral 1"), N_("Spiral 2"), N_("Waves"), N_("Wood"), N_("Wrinckles"), N_("Density file"), N_("Average"), }; const char *blendmap_keyword[blendmap_num] = { "agate", "boxed", "bozo", "bumps", "crackle", "cylindrical", "dents", "gradient", "granite", "leopard", "mandel", "marble", "onion", "planar", "quilted", "radial", "ripples", "spherical", "spiral1", "spiral2", "waves", "wood", "wrinkles", "density_file", "average", }; const int bfiletype_num = 1; const char *bfiletype_ext[bfiletype_num] = { "df3" }; const char *bfiletype_def[bfiletype_num] = { " df3 " }; TvWidget_blendmap::TvWidget_blendmap( const char *name, const char *sname, const char *tooltip, app_objs *appref, bool is_colmap ) : TvWidget( name, sname, tooltip, appref ) { option_box = NULL; colmap_mode = is_colmap; type = new TvWidget_option_combo( N_("Type"), "TYPE", NULL, app_ref ); type->set_list( blendmap_list, colmap_mode ? blendmap_num-1 : blendmap_num , 0 ); agate_turb = new TvWidget_float( N_("Agate turbulence"), "ATURB", NULL, app_ref, 0.5 ); agate_turb->set_range( 5, 0, 0.1, 2 ); gradient_dir = new TvWidget_point( N_("Orientation"), "ORIENT", NULL, app_ref ); gradient_dir->set( 1, 1, 1 ); mandel_iterations = new TvWidget_int( N_("Mandel max iterations"), "MANDMAX", NULL, app_ref, 10 ); mandel_iterations->set_range( 256, 10, 1 ); quilted_control0 = new TvWidget_float( N_("Control 0"), "CTRL0", NULL, app_ref, 1 ); quilted_control0->set_range( 1, 0, 0.01, 3 ); quilted_control1 = new TvWidget_float( N_("Control 1"), "CTRL1", NULL, app_ref, 1 ); quilted_control1->set_range( 1, 0, 0.01, 3 ); spiral_arms = new TvWidget_int( N_("Spiral arms"), "SPIRARMS", NULL, app_ref, 4 ); spiral_arms->set_range( 20, 1, 1 ); density_file = new TvWidget_file( N_("File"), "FILE", NULL, app_ref ); density_file->set_list( bfiletype_ext, bfiletype_def, bfiletype_num ); interpolate = new TvWidget_bool( N_("Interpolate"), "INTERP", NULL, app_ref, false ); frequency = new TvWidget_float( N_("Frequency"), "FREQ", NULL, app_ref, 1.0 ); frequency->set_range( 1000, -1000, 0.1, 3 ); phase = new TvWidget_float( N_("Phase"), "PHASE", NULL, app_ref, 0 ); phase->set_range( 1000, -1000, 0.1, 3 );} TvWidget_blendmap::TvWidget_blendmap( TvWidget_blendmap & ref ) : TvWidget( ref ) { option_box = NULL; type = new TvWidget_option_combo( *ref.type ); agate_turb= new TvWidget_float( *ref.agate_turb ); gradient_dir = new TvWidget_point( *ref.gradient_dir ); mandel_iterations = new TvWidget_int( *ref.mandel_iterations ); quilted_control0 = new TvWidget_float( *ref.quilted_control0 ); quilted_control1 = new TvWidget_float( *ref.quilted_control1 ); spiral_arms = new TvWidget_int( *ref.spiral_arms ); density_file = new TvWidget_file( *ref.density_file ); interpolate = new TvWidget_bool( *ref.interpolate ); frequency = new TvWidget_float( *ref.frequency ); phase = new TvWidget_float( *ref.phase ); } void TvWidget_blendmap::copy( TvWidget *to ) { TvWidget_blendmap *tm = (TvWidget_blendmap*)to; type->copy( tm->type ); agate_turb->copy( tm->agate_turb ); gradient_dir->copy( tm->gradient_dir ); mandel_iterations->copy( tm->mandel_iterations ); quilted_control0->copy( tm->quilted_control0 ); quilted_control1->copy( tm->quilted_control1 ); spiral_arms->copy( tm->spiral_arms ); density_file->copy( tm->density_file ); interpolate->copy( tm->interpolate ); frequency->copy( tm->frequency ); phase->copy( tm->phase ); } TvWidget_blendmap::~TvWidget_blendmap() { delete type; delete agate_turb; delete gradient_dir; delete mandel_iterations; delete quilted_control0; delete quilted_control1; delete spiral_arms; delete density_file; delete interpolate; delete frequency; delete phase; } void TvWidget_blendmap::get_widget( GtkWidget *box, bool tt ) { option_box = NULL; widget = dlg_simple_box_frame( _(name), box ); type->get_widget( widget, tt ); type->connect_signal( GTK_SIGNAL_FUNC(sign_blendtype_changed), this ); type_changed(); } void TvWidget_blendmap::type_changed() { if ( option_box != NULL ) { agate_turb->clear_widget(); gradient_dir->clear_widget(); mandel_iterations->clear_widget(); quilted_control0->clear_widget(); quilted_control1->clear_widget(); spiral_arms->clear_widget(); density_file->clear_widget(); interpolate->clear_widget(); frequency->clear_widget(); phase->clear_widget(); gtk_widget_destroy( option_box ); } option_box = gtk_vbox_new( FALSE, 0 ); gtk_box_pack_start( GTK_BOX(widget), option_box, TRUE, TRUE, 0 ); type->flush(); bool tt = true; switch ( type->value() ) { case 0: agate_turb->get_widget( option_box, tt ); break; case 7: gradient_dir->get_widget( option_box, tt ); break; case 10: mandel_iterations->get_widget( option_box, tt ); break; case 14: quilted_control0->get_widget( option_box, tt ); quilted_control1->get_widget( option_box, tt ); break; case 18: case 19: spiral_arms->get_widget( option_box, tt ); break; case 23: density_file->get_widget( option_box, tt ); interpolate->get_widget( option_box, tt ); break; case 16: case 20: frequency->get_widget( option_box, tt ); phase->get_widget( option_box, tt ); break; } gtk_widget_show_all( option_box ); } void TvWidget_blendmap::clear_widget() { TvWidget::clear_widget(); type->clear_widget(); agate_turb->clear_widget(); gradient_dir->clear_widget(); mandel_iterations->clear_widget(); quilted_control0->clear_widget(); quilted_control1->clear_widget(); spiral_arms->clear_widget(); density_file->clear_widget(); interpolate->clear_widget(); frequency->clear_widget(); phase->clear_widget(); } void TvWidget_blendmap::flush() { if ( ! GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); type->flush(); agate_turb->flush(); gradient_dir->flush(); mandel_iterations->flush(); quilted_control0->flush(); quilted_control1->flush(); spiral_arms->flush(); density_file->flush(); interpolate->flush(); frequency->flush(); phase->flush(); } void TvWidget_blendmap::output_to_povray( ofstream & file ) { file << blendmap_keyword[type->value()]; switch ( type->value() ) { case 0: file << " agate_turb "; agate_turb->output_to_povray( file ); break; case 7: file << " "; gradient_dir->output_to_povray( file ); break; case 10: file << " "; mandel_iterations->output_to_povray( file ); break; case 14: file << " control0 "; quilted_control0->output_to_povray( file ); file << " control1 "; quilted_control1->output_to_povray( file ); break; case 18: case 19: file << " "; spiral_arms->output_to_povray( file ); break; case 23: //file << " df3 "; density_file->output_to_povray( file ); if ( interpolate->value() == true ) file << "\n\t\t\tinterpolate 1"; break; case 16: case 20: file << " frequency " << frequency->value(); file << " phase " << phase->value(); break; } } void TvWidget_blendmap::save( ofstream & file ) { TvWidget::save( file ); type->save( file ); agate_turb->save( file ); gradient_dir->save( file ); mandel_iterations->save( file ); quilted_control0->save( file ); quilted_control1->save( file ); spiral_arms->save( file ); density_file->save( file ); interpolate->save( file ); frequency->save( file ); phase->save( file ); file << "} "; } bool TvWidget_blendmap::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 ( type->load( file , tag ) ) continue; if ( agate_turb->load( file , tag ) ) continue; if ( gradient_dir->load( file , tag ) ) continue; if ( mandel_iterations->load( file , tag ) ) continue; if ( quilted_control0->load( file , tag ) ) continue; if ( quilted_control1->load( file , tag ) ) continue; if ( spiral_arms->load( file , tag ) ) continue; if ( density_file->load( file , tag ) ) continue; if ( interpolate->load( file , tag ) ) continue; if ( frequency->load( file , tag ) ) continue; if ( phase->load( file , tag ) ) continue; tvio_skip_section( file ); } while( tag != NULL ); return true; } //********************************************************* // Classe blendmap modifiers //********************************************************* const int blendmap_mod_num = 6; const char *blendmap_mod_list[blendmap_mod_num] = { N_("Cubic"), N_("Poly"), N_("Ramp"), N_("Scallop"), N_("Sine"), N_("Triangle") }; const char *blendmap_mod_keyword[blendmap_mod_num] = { "cubic_wave", "poly_wave", "ramp_wave", "scallop_wave", "sine_wave", "triangle_wave" }; TvWidget_blendmap_mod::TvWidget_blendmap_mod( const char *name, const char *sname, const char *tooltip, app_objs *appref ) : TvWidget( name, sname, tooltip, appref ) { use = new TvWidget_bool_activator( N_("Use modifiers"), "USED", NULL, app_ref, false ); waveform = new TvWidget_option_combo( N_("Wave"), "WAVE", NULL, app_ref ); waveform->set_list( blendmap_mod_list, blendmap_mod_num, 2 ); frequency = new TvWidget_float( N_("Frequency"), "FREQ", NULL, app_ref, 1.0 ); frequency->set_range( 1000, -1000, 0.1, 3 ); phase = new TvWidget_float( N_("Phase"), "PHASE", NULL, app_ref, 0 ); phase->set_range( 1000, -1000, 0.1, 3 ); polywave_count = new TvWidget_float( N_("Exponent"), "EXP", NULL, app_ref, 1.0 ); polywave_count->set_range( 100, 0, 0.1, 2 ); } TvWidget_blendmap_mod::TvWidget_blendmap_mod( TvWidget_blendmap_mod & ref ) : TvWidget( ref ) { use = new TvWidget_bool_activator( *ref.use ); waveform = new TvWidget_option_combo( *ref.waveform ); frequency = new TvWidget_float( *ref.frequency ); phase = new TvWidget_float( *ref.phase ); polywave_count = new TvWidget_float( *ref.polywave_count ); } void TvWidget_blendmap_mod::copy( TvWidget *bo ) { TvWidget_blendmap_mod *bm = (TvWidget_blendmap_mod*)bo; use->copy( bm->use ); waveform->copy( bm->waveform ); frequency->copy( bm->frequency ); phase->copy( bm->phase ); polywave_count->copy( bm->polywave_count ); } TvWidget_blendmap_mod::~TvWidget_blendmap_mod() { delete use; delete waveform; delete frequency; delete phase; delete polywave_count; } void TvWidget_blendmap_mod::get_widget( GtkWidget *box, bool tt ) { widget = dlg_simple_box_frame( _(name), box ); use->get_widget_no_toggle( widget, tt ); GtkWidget *activated_box = gtk_vbox_new( FALSE, 0 ); gtk_box_pack_start( GTK_BOX(widget), activated_box, FALSE, FALSE, 0 ); use->set_target( activated_box ); frequency->get_widget( activated_box, tt ); phase->get_widget( activated_box, tt ); waveform->get_widget( activated_box, tt ); polywave_count->get_widget( activated_box, tt ); waveform->connect_signal( GTK_SIGNAL_FUNC(sign_wavetype_changed), this ); wavetype_changed(); use->update_widget(); } void TvWidget_blendmap_mod::wavetype_changed() { waveform->flush(); if ( waveform->value() != 1 ) polywave_count->set_widget_inactive(); else polywave_count->set_widget_active(); } void TvWidget_blendmap_mod::clear_widget() { TvWidget::clear_widget(); use->clear_widget(); waveform->clear_widget(); polywave_count->clear_widget(); frequency->clear_widget(); phase->clear_widget(); } void TvWidget_blendmap_mod::flush() { if ( ! GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); use->flush(); waveform->flush(); polywave_count->flush(); frequency->flush(); phase->flush(); } void TvWidget_blendmap_mod::output_to_povray( ofstream & file ) { if ( !use->value() ) return; file << "frequency "; frequency->output_to_povray( file ); file << " phase "; phase->output_to_povray( file ); file << ' '; file << blendmap_mod_keyword[waveform->value()]; if ( waveform->value() == 1 ) { file << ' '; polywave_count->output_to_povray( file ); } } void TvWidget_blendmap_mod::save( ofstream & file ) { if ( !use->value() ) return; TvWidget::save( file ); frequency->save( file ); phase->save( file ); waveform->save( file ); polywave_count->save( file ); file << "} "; } bool TvWidget_blendmap_mod::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 ( frequency->load( file , tag ) ) continue; if ( phase->load( file , tag ) ) continue; if ( waveform->load( file , tag ) ) continue; if ( polywave_count->load( file , tag ) ) continue; tvio_skip_section( file ); } while( tag != NULL ); use->set( true ); return true; } //********************************************************* // Classe file //********************************************************* TvWidget_file::TvWidget_file( const char *name, const char *sname, const char *tooltip, app_objs *appref ) : TvWidget( name, sname, tooltip, appref ) { path = new TvWidget_path( name, "PATH", NULL, appref ); store = new TvWidget_bool( N_("Store"), "STORE", NULL, app_ref, false ); type = -1; loaded = false; } void TvWidget_file::set_list( const char **ext, const char **def, const int num ) { ext_list = (char**)ext; def_list = (char**)def; list_num = (int)num; } TvWidget_file::TvWidget_file( TvWidget_file & ref ) : TvWidget( ref ) { path = new TvWidget_path( *ref.path ); store = new TvWidget_bool( *ref.store ); loaded = false; type = ref.type; ext_list = (char**)ref.ext_list; def_list = (char**)ref.def_list; list_num = (int)ref.list_num; } TvWidget_file::~TvWidget_file() { if ( loaded == true ) unlink( path->value() ); delete path; delete store; } void TvWidget_file::get_widget( GtkWidget *box, bool tt ) { path->get_widget( box, tt ); path->connect_signal( GTK_SIGNAL_FUNC(sign_file_changed), this ); store->get_widget( box, tt ); } void TvWidget_file::get_widget( GtkWidget *box, bool tt, int row ) { path->get_widget( box, tt, row ); path->connect_signal( GTK_SIGNAL_FUNC(sign_file_changed), this ); store->get_widget( box, tt, row+1 ); } void TvWidget_file::file_changed() { if ( in_update == true ) return; in_update = true; char *oldptr = path->value(); char *old = NULL; if ( oldptr != NULL ) { old = new char[ strlen(oldptr) +1 ]; strcpy( old, oldptr ); } path->flush(); char *res = path->value(); if ( old != NULL && res != NULL ) if ( ! strcmp( old, res ) ) { delete old; in_update = false; return; } if ( loaded ) unlink( old ); if ( old != NULL ) delete old; loaded = false; type = -1; if ( res == NULL ) { in_update = false; return; } int res_len = strlen( res ); if ( res_len == 0 ) { in_update = false; return; } for ( register int i = 0 ; i < list_num ; i++ ) { int ext_len = strlen( ext_list[i] ); if ( !strcmp( ext_list[i], res + res_len - ext_len ) ) type = i; } in_update = false; } void TvWidget_file::clear_widget() { TvWidget::clear_widget(); path->clear_widget(); store->clear_widget(); } void TvWidget_file::flush() { TvWidget::flush(); path->flush(); store->flush(); } void TvWidget_file::output_to_povray( ofstream & file ) { //file_changed(); char *res = path->value(); file << def_list[ ( type == -1 ) ? 5 : type ]; file << " \"" << res << '\"'; } void TvWidget_file::save( ofstream & file ) { TvWidget::save( file ); int file_size = 0; char *fname = path->value(); if ( fname == NULL || strlen( fname ) == 0 ) { file << "SIZE=0 } "; return; } ifstream ifile( fname ); if ( ! ifile ) { file << "SIZE=0 } "; app_warning( "Cannot open", path->value() ); return; } ifile.seekg( 0, ios::end ); file_size = ifile.tellg(); ifile.seekg( 0, ios::beg ); file << "SIZE=" << file_size << " TYPE=" << type << " DATA="; for ( register int i = 0 ; i < file_size ; i++ ) file << (char)ifile.get(); file << " } "; } bool TvWidget_file::load( ifstream & file, char *ltag ) { if ( strcmp( sname, ltag ) ) return false; char * val = NULL; int file_size = 0; do { val = tvio_get_next_val( file ); if ( val == NULL ) return true; if ( ! strcmp( val, "SIZE" ) ) { file_size = tvio_get_value_as_int( file ); continue; } if ( ! strcmp( val, "TYPE" ) ) { type = tvio_get_value_as_int( file ); continue; } if ( ! strcmp( val, "DATA" ) ) { char *tmpfile = get_temp_filename(); path->set( tmpfile ); ofstream ifile( tmpfile ); ifile.seekp( 0, ios::beg ); for ( register int i = 0 ; i < file_size ; i++ ) ifile << (char)file.get(); ifile.close(); loaded = true; delete tmpfile; } } while( val != NULL ); return true; } void TvWidget_file::connect_signal( GtkSignalFunc funcd , gpointer datad ) { path->connect_signal( GTK_SIGNAL_FUNC(funcd) , datad ); store->connect_signal( GTK_SIGNAL_FUNC(funcd) , datad ); } void TvWidget_file::swap_data( TvWidget_file *param ) { bool swap = store->value(); store->set( param->store->value() ); param->store->set( swap ); char *swap2 = path->value(); path->set( param->path->value() ); param->path->set( swap2 ); } //********************************************************* // Classe bitmap //********************************************************* const int maptype_num = 4; const char *maptype_list[maptype_num] = { N_("Planar"), N_("Spherical"), N_("Cylindrical"), N_("Donut") }; const int maptype_def[maptype_num] = { 0, 1, 2, 5 }; const int interpolate_num = 3; const char *interpolate_list[interpolate_num] = { N_("None"), N_("Bilinear"), N_("Normalized") }; const int filetype_num = 8; const char *filetype_ext[filetype_num] = { "gif", "tga", "iff", "ppm", "pgm", "png", "jpg", "tif" }; const char *filetype_def[filetype_num] = { "gif", "tga", "iff", "ppm", "pgm", "png", "jpeg", "tiff" }; TvWidget_bitmap::TvWidget_bitmap( const char *name, const char *sname, const char *tooltip, app_objs *appref ) : TvWidget( name, sname, tooltip, appref ) { file = new TvWidget_file( N_("File"), "FILE", NULL, appref ); file->set_list( filetype_ext, filetype_def, filetype_num ); filter_all = new TvWidget_percent( N_("Filter all (%)"), "FILT", NULL, app_ref, 0 ); filter_all->set_range( 1, 0, 0.01, 4 ); transmit_all = new TvWidget_percent( N_("Transmit all(%)"), "TRANS", NULL, app_ref, 0 ); transmit_all->set_range( 1, 0, 0.01, 4 ); maptype = new TvWidget_option_combo( N_("Map type"), "TYPE", NULL, app_ref ); maptype->set_list( maptype_list, maptype_num, 0 ); interpolate = new TvWidget_option_combo( N_("Interpolate"), "INTERP", NULL, app_ref ); interpolate->set_list( interpolate_list, interpolate_num, 0 ); once = new TvWidget_bool( N_("Once"), "ONCE", NULL, app_ref, false ); } TvWidget_bitmap::TvWidget_bitmap( TvWidget_bitmap & ref ) : TvWidget( ref ) { file = new TvWidget_file( *ref.file ); filter_all = new TvWidget_percent( *ref.filter_all ); transmit_all = new TvWidget_percent( *ref.transmit_all ); maptype = new TvWidget_option_combo( *ref.maptype ); interpolate = new TvWidget_option_combo( *ref.interpolate ); once = new TvWidget_bool( *ref.once ); } TvWidget_bitmap::~TvWidget_bitmap() { delete file; delete filter_all; delete transmit_all; delete maptype; delete interpolate; delete once; } void TvWidget_bitmap::get_widget( GtkWidget *box, bool tt ) { widget = dlg_simple_box_frame( _(name), box ); file->get_widget( widget, tt ); filter_all->get_widget( widget, tt ); transmit_all->get_widget( widget, tt ); maptype->get_widget( widget, tt ); interpolate->get_widget( widget, tt ); once->get_widget( widget, tt ); } void TvWidget_bitmap::clear_widget() { TvWidget::clear_widget(); file->clear_widget(); filter_all->clear_widget(); transmit_all->clear_widget(); maptype->clear_widget(); interpolate->clear_widget(); once->clear_widget(); } void TvWidget_bitmap::flush() { if ( !GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); file->flush(); filter_all->flush(); transmit_all->flush(); maptype->flush(); interpolate->flush(); once->flush(); } void TvWidget_bitmap::output_to_povray_nodecl( ofstream & ofile ) { file->output_to_povray( ofile ); if ( once->value() ) ofile << "\n\t\t\t once"; if ( interpolate->value() != 0 ) ofile << "\n\t\t\t interpolate " << interpolate->value()*2; ofile << "\n\t\t\t map_type " << maptype_def[maptype->value()]; ofile << "\n\t\t\tfilter all " << filter_all->value(); ofile << "\n\t\t\ttransmit all " << transmit_all->value(); } void TvWidget_bitmap::output_to_povray( ofstream & ofile ) { ofile << "image_map{ "; output_to_povray_nodecl(ofile); ofile << "\n\t\t\t}"; } void TvWidget_bitmap::save( ofstream & ofile ) { TvWidget::save( ofile ); file->save( ofile ); filter_all->save( ofile ); transmit_all->save( ofile ); once->save( ofile ); interpolate->save( ofile ); maptype->save( ofile ); ofile << "} "; } bool TvWidget_bitmap::load( ifstream & ofile, char * ltag ) { if ( strcmp( sname, ltag ) ) return false; char * tag = NULL; do { tag = tvio_get_next_tag( ofile ); if ( tag == NULL ) break; if( file->load( ofile, tag ) ) continue; if( filter_all->load( ofile, tag ) ) continue; if( transmit_all->load( ofile, tag ) ) continue; if( once->load( ofile, tag ) ) continue; if( interpolate->load( ofile, tag ) ) continue; if( maptype->load( ofile, tag ) ) continue; tvio_skip_section( ofile ); } while( tag != NULL ); return true; } //*************************************** void TvWidget_bumpmap::output_to_povray( ofstream & ofile ) { ofile << "bump_map{ "; file->output_to_povray( ofile ); if ( once->value() ) ofile << "\n\t\t\t once"; if ( once->value() ) ofile << "\n\t\t\t use_color"; if ( interpolate->value() != 0 ) ofile << "\n\t\t\t interpolate " << interpolate->value()*2; ofile << "\n\t\t\t map_type " << maptype_def[maptype->value()]; ofile << "\n\t\t\t}"; } void TvWidget_bumpmap::get_widget( GtkWidget *box, bool tt ) { widget = dlg_simple_box_frame( _(name), box ); file->get_widget( widget, tt ); maptype->get_widget( widget, tt ); interpolate->get_widget( widget, tt ); once->get_widget( widget, tt ); use_color->get_widget( widget, tt ); } //********************************************************* // Classe text //********************************************************* void TvWidget_text::get_widget( GtkWidget *box, bool tt ) { widget = gtk_vbox_new( FALSE, 0 ); GtkWidget *label = gtk_label_new( _(name) ); gtk_label_set_justify( GTK_LABEL(label), GTK_JUSTIFY_LEFT ); gtk_box_pack_start( GTK_BOX(widget), label, FALSE, FALSE, 4 ); text = gtk_text_view_new(); gtk_widget_set_usize( text, -1, 40 ); gtk_text_view_set_editable( GTK_TEXT_VIEW(text), TRUE ); gtk_text_view_set_wrap_mode( GTK_TEXT_VIEW(text), GTK_WRAP_WORD ); gtk_box_pack_start( GTK_BOX(widget), text, FALSE, TRUE, 4 ); GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); if ( data != NULL ) gtk_text_buffer_set_text( buffer, data, -1 ); TvWidget::pack_widget( box, tt, text ); } void TvWidget_text::flush() { if ( ! GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); //size = gtk_text_buffer_get_length( GTK_TEXT_BUFFER(text) ); //gchar * txt = gtk_editable_get_chars( GTK_EDITABLE(text), 0, -1 ); if ( data != NULL ) { delete data; data = NULL; } //data = new char[ size + 1 ]; //data[0] = '\0'; //strncpy( data, txt, size+1 ); GtkTextIter start, end; gtk_text_buffer_get_bounds( buffer, &start, &end ); gchar *tmp = gtk_text_buffer_get_text( buffer, &start, &end, FALSE ); size = strlen( tmp ); data = new char[ size + 1 ]; data[0] = '\0'; strncpy( data, tmp, size+1 ); g_free( tmp ); } void TvWidget_text::save( ofstream & file ) { TvWidget::save( file ); file << "SIZE=" << size; file << " VALUE="; for ( register int i = 0 ; i < size ; i++ ) file << data[i]; file << "} "; } bool TvWidget_text::load( ifstream & file, char * ltag ) { if ( strcmp( sname, ltag ) ) return false; char * val = NULL; int text_size = 0; do { val = tvio_get_next_val( file ); if ( val == NULL ) break; if ( ! strcmp( val, "SIZE" ) ) { text_size = tvio_get_value_as_int( file ); if ( data != NULL ) delete data; data = NULL; if ( text_size != 0 ) data = new char[ text_size + 1 ]; continue; } if ( ! strcmp( val, "VALUE" ) ) { if ( text_size == 0 ) continue; for ( register int i = 0 ; i < text_size ; i++ ) data[i] = (char)file.get(); data[text_size] = '\0'; continue; } } while( val != NULL ); return true; } void TvWidget_text::update_widget() { if ( !GTK_IS_WIDGET(widget) ) return; in_update = true; GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); GtkTextIter start, end; gtk_text_buffer_get_bounds( buffer, &start, &end ); gtk_text_buffer_delete( buffer, &start, &end ); if ( data != NULL ) gtk_text_buffer_set_text( buffer, data, -1 ); //gtk_text_backward_delete( GTK_TEXT(text), gtk_text_get_length( GTK_TEXT(text) ) ); //if ( data != NULL ) gtk_text_insert( GTK_TEXT(text), NULL, NULL, NULL, data, -1 ); in_update = false; } //********************************************************* // Classe noise generator //********************************************************* const int noise_mode_num = 3; const gchar * noise_mode_list[noise_mode_num] = { N_("Povray 3.1"), N_("Range corrected"), N_("Perlin noise") }; TvWidget_noise_generator::TvWidget_noise_generator( const char *name, const char *sname, const char *tooltip, app_objs *appref ) : TvWidget( name, sname, tooltip, appref ) { mode = new TvWidget_option_combo( name, sname, tooltip, appref ); mode->set_list( noise_mode_list, noise_mode_num, 1 ); } //********************************************************* // Classe String List //********************************************************* TvWidget_StringList::TvWidget_StringList( const char *name, const char *sname, const char *tooltip, app_objs *appref, int asize ) : TvWidget( name, sname, tooltip, appref ) { size_max = asize; } TvWidget_StringList::~TvWidget_StringList() { Strings.clear(); } void TvWidget_StringList::push_string( char *str ) { if ( str == NULL ) return; if ( Strings.size() == size_max ) { delete Strings.back(); Strings.pop_back(); } char *text = new char[ strlen(str) + 1 ]; strcpy( text, str ); Strings.insert( Strings.begin(), text ); } bool TvWidget_StringList::pop_string( char *str ) { if ( str == NULL ) return false; for ( unsigned int i = 0 ; i < Strings.size() ; i++ ) if ( !strcmp( str, Strings[i] ) ) { delete Strings[i]; Strings.erase( Strings.begin() + i ); return true; } return false; } void TvWidget_StringList::push_string_unique( char *str ) { for ( unsigned int i = 0 ; i < Strings.size() ; i++ ) { if ( Strings[i] == NULL ) break; if ( !strcmp( str, Strings[i] ) ) return; } push_string( str ); } void TvWidget_StringList::save( ofstream & file ) { file << sname << "{SIZE=" << Strings.size(); for ( unsigned int i = 0 ; i < Strings.size() ; i++ ) if ( Strings[i] != NULL ) file << " STR=\"" << Strings[i] << "\", "; file << "}"; } bool TvWidget_StringList::load( ifstream & file, char *ltag ) { if ( strcmp( sname, ltag ) ) return false; char * val = NULL; do { val = tvio_get_next_val( file ); if ( val == NULL ) break; if ( ! strcmp( val, "SIZE" ) ) { int asize = tvio_get_value_as_int( file ); asize=+1; } // Old version if ( ! strcmp( val, "STR" ) ) { char *str = tvio_get_value_as_string( file ); char *text = new char[ strlen( str ) + 1 ]; strcpy( text, str ); Strings.push_back( text ); continue; } } while( val != NULL ); return true; }; void TvWidget_StringList::reput_on_top( int num ) { char *str = Strings[num]; Strings.erase( Strings.begin() + num ); Strings.insert( Strings.begin(), str ); } //********************************************************* // Classe fonte //********************************************************* /*TvWidget_font::TvWidget_font( TvWidget_font & ref ) : TvWidget( ref ) { set( ref.get() ); picker = NULL; } void TvWidget_font::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, 3 ); picker = gnome_font_picker_new(); gtk_box_pack_start( GTK_BOX(widget), picker, FALSE, FALSE, 10 ); pack_widget( box, tt, picker ); } void TvWidget_font::update_widget() { if ( ! GTK_IS_WIDGET(widget) ) return; in_update = true; gnome_font_picker_set_font_name( GNOME_FONT_PICKER(picker), data ); in_update = false; } void TvWidget_font::flush() { if ( !GTK_IS_WIDGET(widget) ) return; TvWidget::flush(); char *temp = (char*)gnome_font_picker_get_font_name( GNOME_FONT_PICKER(picker) ); set( temp ); } void TvWidget_font::save( ofstream & file ) { TvWidget::save( file ); file << "FNAME=" << data; file << "} "; } bool TvWidget_font::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, "FNAME" ) ) { set( tvio_get_value_as_string( file )); continue; } } return true; } void TvWidget_font ::set( char *val ) { if ( data != NULL ) delete data; data = new char[ strlen(val) + 1 ]; strcpy( data, val ); } */ //********************************************************* // Classe function //********************************************************* const gchar *tvwid_funcs[ tvwid_funcs_num ] = { "cos", "cosh", "acos", "acosh", "sin", "sinh", "asin", "asinh", "tan", "tanh", "atan", "atanh", "atan2", "degrees", "radians", "int", "ceil", "abs", "floor", "div", "mod", "min", "max", "exp", "ln", "log", "sqrt", "pow", // Objects "f_algbr_cyl1", "f_algbr_cyl2", "f_algbr_cyl3", "f_algbr_cyl4", "f_blob", "f_blob2", "f_cross_ellipsoids", "f_ellipsoid", "f_helical_torus", "f_helix1", "f_helix2", "f_hyperbolic_torus", "f_mesh1", "f_paraboloid", "f_parabolic_torus", "f_quartic_paraboloid", "f_quartic_saddle", "f_quartic_cylinder", "f_rounded_box", "f_sphere", "f_spiral", "f_strophoid", "f_strophoid_2d", "f_superellipsoid", "f_torus", "f_torus2", // Funny things "f_comma", "f_umbrella", "f_bicorn", "f_bifolia", "f_cubic_saddle", "f_heart", "f_isect_ellipsoids", "f_mitre", "f_pillow", "f_piriform", "f_piriform_2d", "f_polytubes","f_spikes", "f_spikes_2d", "f_torus_gumdrop", // Scientific "f_steiners_roman", "f_boy_surface", "f_dupin_cyclid", "f_enneper", "f_hex_x", "f_hex_y","f_hunt_surface", "f_kampyle_of_eudoxus", "f_kampyle_of_eudoxus_2d", "f_klein_bottle", "f_kummer_surface_v1", "f_kummer_surface_v2", "f_lemniscate_of_gerono", "f_lemniscate_of_gerono_2d", "f_ovals_of_cassini", "f_poly4", "f_steiners_roman", // Weird "f_crossed_through", "f_cushion", "f_devils_curve", "f_devils_curve_2d", "f_flange_cover", "f_folium_surface", "f_folium_surface_2d", "f_glob", "f_hetero_mf", "f_nodal_cubic","f_odd", "f_ph", "f_quantum", "f_r", "f_th", "f_witch_of_agnesi", "f_witch_of_agnesi_2d", }; const int tvwid_funcs_cat_num = 8; const gchar *tvwid_funcs_cat[ tvwid_funcs_cat_num ] = { N_("Trigonometry"), N_("Conversion"), N_("Arithmetic"), N_("Maths") , N_("Objects"), N_("Funny"), N_("Scientific"), N_("Weird") }; const int tvwid_funcs_cat_size[ tvwid_funcs_cat_num ] = { 13, 3, 7, 5, 24, 16, 15, 17 }; const int tvwid_funcs_arg_num[ tvwid_funcs_num ] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 8, 8, 8, 8, 8, 7, 7, 6, 13, 10,10, 5, 7, 8, 4, 6, 4, 4, 6, 7, 4, 9, 7, 10, 5, 5, 6, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4,10, 9, 8, 7, 4, 4, 5, 9, 4, 4, 6, 9, 4, 4, 7, 4, 9, 7, 8, 4, 4, 4, 4, 9, 7, 6, 9, 4, 9, 4, 4, 3, 4, 3, 3, 5, 9, }; void TvWidget_function::get_widget( GtkWidget *box, bool tt ) { widget = gtk_button_new_with_label( name ); gtk_signal_connect( GTK_OBJECT(widget), "clicked", GTK_SIGNAL_FUNC(sign_tvwid_func_open_dialog), this ); TvWidget::pack_widget( box, tt, widget ); } void TvWidget_function::get_widget( GtkWidget *tab, bool tt, int row ) { widget = gtk_button_new_with_label( name ); gtk_signal_connect( GTK_OBJECT(widget), "clicked", GTK_SIGNAL_FUNC(sign_tvwid_func_open_dialog), this ); //TvWidget::pack_widget( box, tt, widget ); gtk_table_attach_defaults( GTK_TABLE(tab), widget, 0, 5, row-1, row ); //gtk_table_attach( GTK_TABLE(tab), widget, 0, 5, row-1, row, (GtkAttachOptions)(GTK_FILL), (GtkAttachOptions)0, 0, 0 ); } void TvWidget_function::save( ofstream & file ) { TvWidget::save( file ); file << "SIZE=" << size; file << " VALUE="; for ( register int i = 0 ; i < size ; i++ ) file << data[i]; file << "} "; } bool TvWidget_function::load( ifstream & file, char * ltag ) { if ( strcmp( sname, ltag ) ) return false; char * val = NULL; int text_size = 0; do { val = tvio_get_next_val( file ); if ( val == NULL ) break; if ( ! strcmp( val, "SIZE" ) ) { text_size = tvio_get_value_as_int( file ); if ( data != NULL ) delete data; data = NULL; if ( text_size != 0 ) data = new char[ text_size + 1 ]; continue; } if ( ! strcmp( val, "VALUE" ) ) { if ( text_size == 0 ) continue; for ( register int i = 0 ; i < text_size ; i++ ) data[i] = (char)file.get(); data[text_size] = '\0'; continue; } } while( val != NULL ); if ( text_size != 0 ) func_parser.set_expression( data ); size = text_size; return true; } void TvWidget_function::open_dialog() { if ( GTK_IS_DIALOG(dialog) ) { gdk_window_raise( dialog->window ); return; } dialog = gtk_dialog_new_with_buttons( _("Function editor"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,NULL ); gtk_window_set_modal( GTK_WINDOW(dialog), TRUE ); g_signal_connect( G_OBJECT(dialog), "response", G_CALLBACK(sign_tvwid_func_dlg_click), this ); g_signal_connect( G_OBJECT(dialog), "close", G_CALLBACK(sign_tvwid_func_dlg_destroy), this ); GtkBox *vbox = GTK_BOX( ((GtkDialog*)(dialog))->vbox ); // Menus GtkWidget *menu_bar = gtk_menu_bar_new(); gtk_box_pack_start( vbox, menu_bar, FALSE, TRUE, 12 ); GtkWidget *insert_menu = gtk_menu_item_new_with_label( N_("Insert") ); gtk_menu_bar_append( menu_bar, insert_menu ); GtkWidget *sub_menu = gtk_menu_new(); gtk_menu_item_set_submenu( GTK_MENU_ITEM(insert_menu), sub_menu ); // Predefined functions int offset = 0; for ( int cat = 0 ; cat < tvwid_funcs_cat_num ; cat ++ ) { GtkWidget *menu_item = gtk_menu_item_new_with_label( tvwid_funcs_cat[cat] ); gtk_menu_append( GTK_MENU(sub_menu), menu_item ); GtkWidget *menu = gtk_menu_new(); gtk_menu_item_set_submenu( GTK_MENU_ITEM(menu_item), menu ); for ( int i = 0 ; i < tvwid_funcs_cat_size[cat] ; i++ ) { insert_menu_widgets[offset] = gtk_menu_item_new_with_label( tvwid_funcs[offset] ); gtk_menu_append( GTK_MENU(menu), insert_menu_widgets[offset] ); gtk_signal_connect( GTK_OBJECT(insert_menu_widgets[offset] ), "activate", GTK_SIGNAL_FUNC(sign_tvwid_func_insert), this ); offset++; } } // Utils GtkWidget *utils_menu = gtk_menu_item_new_with_label( N_("Utils") ); gtk_menu_bar_append( menu_bar, utils_menu ); sub_menu = gtk_menu_new(); gtk_menu_item_set_submenu( GTK_MENU_ITEM(utils_menu), sub_menu ); GtkWidget *menu_item = gtk_menu_item_new_with_label( N_("Clear") ); gtk_menu_append( sub_menu, menu_item ); gtk_signal_connect( GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(sign_tvwid_func_clear), this ); menu_item = gtk_separator_menu_item_new( ); gtk_menu_append( sub_menu, menu_item ); menu_item = gtk_menu_item_new_with_label( N_("Cut") ); gtk_menu_append( sub_menu, menu_item ); gtk_signal_connect( GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(sign_tvwid_func_cut), this ); menu_item = gtk_menu_item_new_with_label( N_("Copy") ); gtk_menu_append( sub_menu, menu_item ); gtk_signal_connect( GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(sign_tvwid_func_copy), this ); menu_item = gtk_menu_item_new_with_label( N_("Paste") ); gtk_menu_append( sub_menu, menu_item ); gtk_signal_connect( GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(sign_tvwid_func_paste), this ); // Multiline text editor GtkWidget *scroll = gtk_scrolled_window_new( NULL, NULL ); gtk_widget_set_usize( scroll, 450, 200 ); gtk_box_pack_start( vbox, scroll, TRUE, TRUE, 4 ); text = gtk_text_view_new(); gtk_text_view_set_editable( GTK_TEXT_VIEW(text), TRUE ); gtk_text_view_set_wrap_mode( GTK_TEXT_VIEW(text), GTK_WRAP_WORD ); gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scroll), text ); GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); if ( data != NULL ) gtk_text_buffer_set_text( buffer, data, -1 ); gtk_widget_show_all(dialog); } void TvWidget_function::clicked_dlg( int button ) { switch( button ) { case GTK_RESPONSE_OK: { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); if ( data != NULL ) { delete data; data = NULL; } GtkTextIter start, end; gtk_text_buffer_get_bounds( buffer, &start, &end ); gchar *tmp = gtk_text_buffer_get_text( buffer, &start, &end, FALSE ); size = strlen( tmp ); data = new char[ size + 1 ]; data[0] = '\0'; strncpy( data, tmp, size+1 ); g_free( tmp ); clicked_dlg( -1 ); func_parser.set_expression( data ); if ( func_parser.get_status() == false ) app_warning( func_parser.get_error() ); } flush(); break; // Close default: case GTK_RESPONSE_CLOSE: gtk_widget_destroy( dialog ); dialog = NULL; break; } } void TvWidget_function::insert_function( GtkWidget *sender ) { gchar *str = NULL; int arg_num = 0; for ( int i = 0 ; i < tvwid_funcs_num ; i ++ ) if ( insert_menu_widgets[i] == sender ) { str = (gchar*)tvwid_funcs[i]; arg_num = (int)tvwid_funcs_arg_num[i] - 1; } if ( str == NULL ) return; int len = strlen( str ) + 4 + arg_num*2; char *insert = new char[ len ]; strcpy( insert, str ); strcat( insert, "(" ); for ( int i = 0 ; i < arg_num ; i++ ) strcat( insert, " ," ); strcat( insert, " )" ); GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); gtk_text_buffer_insert_at_cursor( buffer, insert, len-1 ); delete insert; } void TvWidget_function::clear_editor() { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); GtkTextIter start, end; gtk_text_buffer_get_bounds( buffer, &start, &end ); gtk_text_buffer_delete( buffer, &start, &end ); } void TvWidget_function::cut() { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); GtkClipboard *clip = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ); gtk_text_buffer_cut_clipboard( buffer, clip, true ); } void TvWidget_function::copy() { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); GtkClipboard *clip = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ); gtk_text_buffer_copy_clipboard( buffer, clip ); } void TvWidget_function::paste() { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); GtkClipboard *clip = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ); gtk_text_buffer_paste_clipboard( buffer, clip, NULL, true ); } //********************************************************* // Classe Text Button //********************************************************* void TvWidget_TextButton::get_widget( GtkWidget *box, bool tt ) { widget = gtk_button_new_with_label( name ); gtk_signal_connect( GTK_OBJECT(widget), "clicked", GTK_SIGNAL_FUNC(sign_tvwid_tb_open_dialog), this ); TvWidget::pack_widget( box, tt, widget ); } void TvWidget_TextButton::save( ofstream & file ) { TvWidget::save( file ); file << "SIZE=" << size; file << " VALUE="; for ( register int i = 0 ; i < size ; i++ ) file << data[i]; file << "} "; } bool TvWidget_TextButton::load( ifstream & file, char * ltag ) { if ( strcmp( sname, ltag ) ) return false; char * val = NULL; int text_size = 0; do { val = tvio_get_next_val( file ); if ( val == NULL ) break; if ( ! strcmp( val, "SIZE" ) ) { text_size = tvio_get_value_as_int( file ); if ( data != NULL ) delete data; data = NULL; if ( text_size != 0 ) data = new char[ text_size + 1 ]; continue; } if ( ! strcmp( val, "VALUE" ) ) { if ( text_size == 0 ) continue; for ( register int i = 0 ; i < text_size ; i++ ) data[i] = (char)file.get(); data[text_size] = '\0'; continue; } } while( val != NULL ); size = text_size; return true; } void TvWidget_TextButton::open_dialog() { if ( GTK_IS_DIALOG(dialog) ) { gdk_window_raise( dialog->window ); return; } dialog = gtk_dialog_new_with_buttons( _("Script editor"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,NULL ); gtk_window_set_modal( GTK_WINDOW(dialog), TRUE ); g_signal_connect( G_OBJECT(dialog), "response", G_CALLBACK(sign_tvwid_tb_dlg_click), this ); g_signal_connect( G_OBJECT(dialog), "close", G_CALLBACK(sign_tvwid_tb_dlg_destroy), this ); GtkBox *vbox = GTK_BOX( ((GtkDialog*)(dialog))->vbox ); // Menus GtkWidget *menu_bar = gtk_menu_bar_new(); gtk_box_pack_start( vbox, menu_bar, FALSE, TRUE, 12 ); // Utils GtkWidget *utils_menu = gtk_menu_item_new_with_label( N_("Utils") ); gtk_menu_bar_append( menu_bar, utils_menu ); GtkWidget *sub_menu = gtk_menu_new(); gtk_menu_item_set_submenu( GTK_MENU_ITEM(utils_menu), sub_menu ); GtkWidget *menu_item = gtk_menu_item_new_with_label( N_("Clear") ); gtk_menu_append( sub_menu, menu_item ); gtk_signal_connect( GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(sign_tvwid_tb_clear), this ); menu_item = gtk_separator_menu_item_new( ); gtk_menu_append( sub_menu, menu_item ); menu_item = gtk_menu_item_new_with_label( N_("Cut") ); gtk_menu_append( sub_menu, menu_item ); gtk_signal_connect( GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(sign_tvwid_tb_cut), this ); menu_item = gtk_menu_item_new_with_label( N_("Copy") ); gtk_menu_append( sub_menu, menu_item ); gtk_signal_connect( GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(sign_tvwid_tb_copy), this ); menu_item = gtk_menu_item_new_with_label( N_("Paste") ); gtk_menu_append( sub_menu, menu_item ); gtk_signal_connect( GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(sign_tvwid_tb_paste), this ); // Multiline text editor GtkWidget *scroll = gtk_scrolled_window_new( NULL, NULL ); gtk_widget_set_usize( scroll, 450, 200 ); gtk_box_pack_start( vbox, scroll, TRUE, TRUE, 4 ); text = gtk_text_view_new(); gtk_text_view_set_editable( GTK_TEXT_VIEW(text), TRUE ); gtk_text_view_set_wrap_mode( GTK_TEXT_VIEW(text), GTK_WRAP_WORD ); gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scroll), text ); GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); if ( data != NULL ) gtk_text_buffer_set_text( buffer, data, -1 ); gtk_widget_show_all(dialog); } void TvWidget_TextButton::clicked_dlg( int button ) { switch( button ) { case GTK_RESPONSE_OK: { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); if ( data != NULL ) { delete data; data = NULL; } GtkTextIter start, end; gtk_text_buffer_get_bounds( buffer, &start, &end ); gchar *tmp = gtk_text_buffer_get_text( buffer, &start, &end, FALSE ); size = strlen( tmp ); data = new char[ size + 1 ]; data[0] = '\0'; strncpy( data, tmp, size+1 ); g_free( tmp ); clicked_dlg( -1 ); flush(); } break; // Close default: case GTK_RESPONSE_CLOSE: gtk_widget_destroy( dialog ); dialog = NULL; break; } } void TvWidget_TextButton::clear_editor() { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); GtkTextIter start, end; gtk_text_buffer_get_bounds( buffer, &start, &end ); gtk_text_buffer_delete( buffer, &start, &end ); } void TvWidget_TextButton::cut() { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); GtkClipboard *clip = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ); gtk_text_buffer_cut_clipboard( buffer, clip, true ); } void TvWidget_TextButton::copy() { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); GtkClipboard *clip = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ); gtk_text_buffer_copy_clipboard( buffer, clip ); } void TvWidget_TextButton::paste() { GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) ); GtkClipboard *clip = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ); gtk_text_buffer_paste_clipboard( buffer, clip, NULL, true ); }