+ui::Window SurfaceInspector::BuildDialog(){
+ ui::Window window = ui::Window(create_floating_window( "Surface Inspector", m_parent ));
+
+ m_positionTracker.connect( window );
+
+ global_accel_connect_window( window );
+
+ window_connect_focus_in_clear_focus_widget( window );
+
+
+ {
+ // replaced by only the vbox:
+ ui::Widget vbox = ui::VBox( FALSE, 5 );
+ gtk_widget_show( vbox );
+ gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox ) );
+ gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
+
+ {
+ ui::Widget hbox2 = ui::HBox( FALSE, 5 );
+ gtk_widget_show( hbox2 );
+ gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox2 ), FALSE, FALSE, 0 );
+
+ {
+ ui::Widget label = ui::Label( "Texture" );
+ gtk_widget_show( label );
+ gtk_box_pack_start( GTK_BOX( hbox2 ), label, FALSE, TRUE, 0 );
+ }
+ {
+ auto entry = ui::Entry();
+ gtk_widget_show( GTK_WIDGET( entry ) );
+ gtk_box_pack_start( GTK_BOX( hbox2 ), GTK_WIDGET( entry ), TRUE, TRUE, 0 );
+ m_texture = entry;
+ m_textureEntry.connect( entry );
+ GlobalTextureEntryCompletion::instance().connect( entry );
+ }
+ }
+
+
+ {
+ ui::Widget table = ui::Table( 6, 4, FALSE );
+ gtk_widget_show( table );
+ gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( table ), FALSE, FALSE, 0 );
+ gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
+ gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
+ {
+ ui::Widget label = ui::Label( "Horizontal shift" );
+ gtk_widget_show( label );
+ gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 );
+ gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ }
+ {
+ GtkSpinButton* spin = ui::SpinButton( ui::Adjustment( 0, -8192, 8192, 2, 8, 0 ), 0, 2 );
+ m_hshiftIncrement.m_spin = spin;
+ m_hshiftSpinner.connect( spin );
+ gtk_widget_show( GTK_WIDGET( spin ) );
+ gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( spin ), 1, 2, 0, 1,
+ (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ gtk_widget_set_size_request( GTK_WIDGET( spin ), 60, -1 );
+ }
+ {
+ ui::Widget label = ui::Label( "Step" );
+ gtk_widget_show( label );
+ gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 );
+ gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 0, 1,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ }
+ {
+ auto entry = ui::Entry();
+ gtk_widget_show( GTK_WIDGET( entry ) );
+ gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( entry ), 3, 4, 0, 1,
+ (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 );
+ m_hshiftIncrement.m_entry = entry;
+ m_hshiftEntry.connect( entry );
+ }
+ {
+ ui::Widget label = ui::Label( "Vertical shift" );
+ gtk_widget_show( label );
+ gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 );
+ gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ }
+ {
+ GtkSpinButton* spin = ui::SpinButton( ui::Adjustment( 0, -8192, 8192, 2, 8, 0 ), 0, 2 );
+ m_vshiftIncrement.m_spin = spin;
+ m_vshiftSpinner.connect( spin );
+ gtk_widget_show( GTK_WIDGET( spin ) );
+ gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( spin ), 1, 2, 1, 2,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ gtk_widget_set_size_request( GTK_WIDGET( spin ), 60, -1 );
+ }
+ {
+ ui::Widget label = ui::Label( "Step" );
+ gtk_widget_show( label );
+ gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 );
+ gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 1, 2,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ }
+ {
+ auto entry = ui::Entry();
+ gtk_widget_show( GTK_WIDGET( entry ) );
+ gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( entry ), 3, 4, 1, 2,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 );
+ m_vshiftIncrement.m_entry = entry;
+ m_vshiftEntry.connect( entry );
+ }
+ {
+ ui::Widget label = ui::Label( "Horizontal stretch" );
+ gtk_widget_show( label );
+ gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 );
+ gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ }
+ {
+ GtkSpinButton* spin = ui::SpinButton( ui::Adjustment( 0, -8192, 8192, 2, 8, 0 ), 0, 5 );
+ m_hscaleIncrement.m_spin = spin;
+ m_hscaleSpinner.connect( spin );
+ gtk_widget_show( GTK_WIDGET( spin ) );
+ gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( spin ), 1, 2, 2, 3,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ gtk_widget_set_size_request( GTK_WIDGET( spin ), 60, -1 );
+ }
+ {
+ ui::Widget label = ui::Label( "Step" );
+ gtk_widget_show( label );
+ gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 );
+ gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 2, 3,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 2, 3 );
+ }
+ {
+ auto entry = ui::Entry();
+ gtk_widget_show( GTK_WIDGET( entry ) );
+ gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( entry ), 3, 4, 2, 3,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 2, 3 );
+ gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 );
+ m_hscaleIncrement.m_entry = entry;
+ m_hscaleEntry.connect( entry );
+ }
+ {
+ ui::Widget label = ui::Label( "Vertical stretch" );
+ gtk_widget_show( label );
+ gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 );
+ gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 3, 4,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ }
+ {
+ GtkSpinButton* spin = ui::SpinButton( ui::Adjustment( 0, -8192, 8192, 2, 8, 0 ), 0, 5 );
+ m_vscaleIncrement.m_spin = spin;
+ m_vscaleSpinner.connect( spin );
+ gtk_widget_show( GTK_WIDGET( spin ) );
+ gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( spin ), 1, 2, 3, 4,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ gtk_widget_set_size_request( GTK_WIDGET( spin ), 60, -1 );
+ }
+ {
+ ui::Widget label = ui::Label( "Step" );
+ gtk_widget_show( label );
+ gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 );
+ gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 3, 4,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ }
+ {
+ auto entry = ui::Entry();
+ gtk_widget_show( GTK_WIDGET( entry ) );
+ gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( entry ), 3, 4, 3, 4,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 );
+ m_vscaleIncrement.m_entry = entry;
+ m_vscaleEntry.connect( entry );
+ }
+ {
+ ui::Widget label = ui::Label( "Rotate" );
+ gtk_widget_show( label );
+ gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 );
+ gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 4, 5,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ }
+ {
+ GtkSpinButton* spin = ui::SpinButton( ui::Adjustment( 0, -8192, 8192, 2, 8, 0 ), 0, 2 );
+ m_rotateIncrement.m_spin = spin;
+ m_rotateSpinner.connect( spin );
+ gtk_widget_show( GTK_WIDGET( spin ) );
+ gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( spin ), 1, 2, 4, 5,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ gtk_widget_set_size_request( GTK_WIDGET( spin ), 60, -1 );
+ gtk_spin_button_set_wrap( spin, TRUE );
+ }
+ {
+ ui::Widget label = ui::Label( "Step" );
+ gtk_widget_show( label );
+ gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 );
+ gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 4, 5,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ }
+ {
+ auto entry = ui::Entry();
+ gtk_widget_show( GTK_WIDGET( entry ) );
+ gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( entry ), 3, 4, 4, 5,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 );
+ m_rotateIncrement.m_entry = entry;
+ m_rotateEntry.connect( entry );
+ }
+ {
+ // match grid button
+ ui::Widget button = ui::Button( "Match Grid" );
+ gtk_widget_show( button );
+ gtk_table_attach( GTK_TABLE( table ), button, 2, 4, 5, 6,
+ (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( OnBtnMatchGrid ), 0 );
+ }
+ }
+
+ {
+ ui::Widget frame = ui::Frame( "Texturing" );
+ gtk_widget_show( frame );
+ gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( frame ), FALSE, FALSE, 0 );
+ {
+ ui::Widget table = ui::Table( 4, 4, FALSE );
+ gtk_widget_show( table );
+ gtk_container_add( GTK_CONTAINER( frame ), table );
+ gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
+ gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
+ gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
+ {
+ ui::Widget label = ui::Label( "Brush" );
+ gtk_widget_show( label );
+ gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ }
+ {
+ ui::Widget label = ui::Label( "Patch" );
+ gtk_widget_show( label );
+ gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ }
+ {
+ ui::Widget label = ui::Label( "Width" );
+ gtk_widget_show( label );
+ gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 0, 1,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ }
+ {
+ ui::Widget label = ui::Label( "Height" );
+ gtk_widget_show( label );
+ gtk_table_attach( GTK_TABLE( table ), label, 3, 4, 0, 1,
+ (GtkAttachOptions) ( GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ }
+ {
+ ui::Widget button = ui::Button( "Axial" );
+ gtk_widget_show( button );
+ gtk_table_attach( GTK_TABLE( table ), button, 0, 1, 1, 2,
+ (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ g_signal_connect( G_OBJECT( button ), "clicked",
+ G_CALLBACK( OnBtnAxial ), 0 );
+ gtk_widget_set_size_request( button, 60, -1 );
+ }
+ {
+ ui::Widget button = ui::Button( "Fit" );
+ gtk_widget_show( button );
+ gtk_table_attach( GTK_TABLE( table ), button, 1, 2, 1, 2,
+ (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ g_signal_connect( G_OBJECT( button ), "clicked",
+ G_CALLBACK( OnBtnFaceFit ), 0 );
+ gtk_widget_set_size_request( button, 60, -1 );
+ }
+ {
+ ui::Widget button = ui::Button( "CAP" );
+ gtk_widget_show( button );
+ gtk_table_attach( GTK_TABLE( table ), button, 0, 1, 3, 4,
+ (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ g_signal_connect( G_OBJECT( button ), "clicked",
+ G_CALLBACK( OnBtnPatchdetails ), 0 );
+ gtk_widget_set_size_request( button, 60, -1 );
+ }
+ {
+ ui::Widget button = ui::Button( "Set..." );
+ gtk_widget_show( button );
+ gtk_table_attach( GTK_TABLE( table ), button, 1, 2, 3, 4,
+ (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ g_signal_connect( G_OBJECT( button ), "clicked",
+ G_CALLBACK( OnBtnPatchreset ), 0 );
+ gtk_widget_set_size_request( button, 60, -1 );
+ }
+ {
+ ui::Widget button = ui::Button( "Natural" );
+ gtk_widget_show( button );
+ gtk_table_attach( GTK_TABLE( table ), button, 2, 3, 3, 4,
+ (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ g_signal_connect( G_OBJECT( button ), "clicked",
+ G_CALLBACK( OnBtnPatchnatural ), 0 );
+ gtk_widget_set_size_request( button, 60, -1 );
+ }
+ {
+ ui::Widget button = ui::Button( "Fit" );
+ gtk_widget_show( button );
+ gtk_table_attach( GTK_TABLE( table ), button, 3, 4, 3, 4,
+ (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ g_signal_connect( G_OBJECT( button ), "clicked",
+ G_CALLBACK( OnBtnPatchFit ), 0 );
+ gtk_widget_set_size_request( button, 60, -1 );
+ }
+ {
+ ui::Widget spin = ui::SpinButton( ui::Adjustment( 1, 0, 1 << 16, 1, 10, 0 ), 0, 6 );
+ gtk_widget_show( spin );
+ gtk_table_attach( GTK_TABLE( table ), spin, 2, 3, 1, 2,
+ (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ gtk_widget_set_size_request( spin, 60, -1 );
+ AddDialogData( *GTK_SPIN_BUTTON( spin ), m_fitHorizontal );
+ }
+ {
+ ui::Widget spin = ui::SpinButton( ui::Adjustment( 1, 0, 1 << 16, 1, 10, 0 ), 0, 6 );
+ gtk_widget_show( spin );
+ gtk_table_attach( GTK_TABLE( table ), spin, 3, 4, 1, 2,
+ (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+ (GtkAttachOptions) ( 0 ), 0, 0 );
+ gtk_widget_set_size_request( spin, 60, -1 );
+ AddDialogData( *GTK_SPIN_BUTTON( spin ), m_fitVertical );
+ }
+ }
+ }
+ if ( !string_empty( g_pGameDescription->getKeyValue( "si_flags" ) ) ) {
+ {
+ GtkFrame* frame = ui::Frame( "Surface Flags" );
+ gtk_widget_show( GTK_WIDGET( frame ) );
+ gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( frame ), TRUE, TRUE, 0 );
+ {
+ GtkVBox* vbox3 = ui::VBox( FALSE, 4 );
+ //gtk_container_set_border_width(GTK_CONTAINER(vbox3), 4);
+ gtk_widget_show( GTK_WIDGET( vbox3 ) );
+ gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( vbox3 ) );
+ {
+ GtkTable* table = ui::Table( 8, 4, FALSE );
+ gtk_widget_show( GTK_WIDGET( table ) );
+ gtk_box_pack_start( GTK_BOX( vbox3 ), GTK_WIDGET( table ), TRUE, TRUE, 0 );
+ gtk_table_set_row_spacings( table, 0 );
+ gtk_table_set_col_spacings( table, 0 );
+
+ GtkCheckButton** p = m_surfaceFlags;
+
+ for ( int c = 0; c != 4; ++c )
+ {
+ for ( int r = 0; r != 8; ++r )
+ {
+ GtkCheckButton* check = ui::CheckButton( getSurfaceFlagName( c * 8 + r ) );
+ gtk_widget_show( GTK_WIDGET( check ) );
+ gtk_table_attach( table, GTK_WIDGET( check ), c, c + 1, r, r + 1,
+ (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ),
+ (GtkAttachOptions)( 0 ), 0, 0 );
+ *p++ = check;
+ guint handler_id = togglebutton_connect_toggled( GTK_TOGGLE_BUTTON( check ), ApplyFlagsCaller( *this ) );
+ g_object_set_data( G_OBJECT( check ), "handler", gint_to_pointer( handler_id ) );
+ }
+ }
+ }
+ }
+ }
+ {
+ GtkFrame* frame = ui::Frame( "Content Flags" );
+ gtk_widget_show( GTK_WIDGET( frame ) );
+ gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( frame ), TRUE, TRUE, 0 );
+ {
+ GtkVBox* vbox3 = ui::VBox( FALSE, 4 );
+ //gtk_container_set_border_width(GTK_CONTAINER(vbox3), 4);
+ gtk_widget_show( GTK_WIDGET( vbox3 ) );
+ gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( vbox3 ) );
+ {
+
+ GtkTable* table = ui::Table( 8, 4, FALSE );
+ gtk_widget_show( GTK_WIDGET( table ) );
+ gtk_box_pack_start( GTK_BOX( vbox3 ), GTK_WIDGET( table ), TRUE, TRUE, 0 );
+ gtk_table_set_row_spacings( table, 0 );
+ gtk_table_set_col_spacings( table, 0 );
+
+ GtkCheckButton** p = m_contentFlags;
+
+ for ( int c = 0; c != 4; ++c )
+ {
+ for ( int r = 0; r != 8; ++r )
+ {
+ GtkCheckButton* check = ui::CheckButton( getContentFlagName( c * 8 + r ) );
+ gtk_widget_show( GTK_WIDGET( check ) );
+ gtk_table_attach( table, GTK_WIDGET( check ), c, c + 1, r, r + 1,
+ (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ),
+ (GtkAttachOptions)( 0 ), 0, 0 );
+ *p++ = check;
+ guint handler_id = togglebutton_connect_toggled( GTK_TOGGLE_BUTTON( check ), ApplyFlagsCaller( *this ) );
+ g_object_set_data( G_OBJECT( check ), "handler", gint_to_pointer( handler_id ) );
+ }
+ }
+
+ // not allowed to modify detail flag using Surface Inspector
+ gtk_widget_set_sensitive( GTK_WIDGET( m_contentFlags[BRUSH_DETAIL_FLAG] ), FALSE );
+ }
+ }
+ }
+ {
+ GtkFrame* frame = ui::Frame( "Value" );
+ gtk_widget_show( GTK_WIDGET( frame ) );
+ gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( frame ), TRUE, TRUE, 0 );
+ {
+ GtkVBox* vbox3 = ui::VBox( FALSE, 4 );
+ gtk_container_set_border_width( GTK_CONTAINER( vbox3 ), 4 );
+ gtk_widget_show( GTK_WIDGET( vbox3 ) );
+ gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( vbox3 ) );
+
+ {
+ auto entry = ui::Entry();
+ gtk_widget_show( GTK_WIDGET( entry ) );
+ gtk_box_pack_start( GTK_BOX( vbox3 ), GTK_WIDGET( entry ), TRUE, TRUE, 0 );
+ m_valueEntryWidget = entry;
+ m_valueEntry.connect( entry );
+ }
+ }
+ }
+ }
+
+#if TEXTOOL_ENABLED
+ if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES ) {
+// Shamus: Textool goodies...
+ ui::Widget frame = ui::Frame( "Textool" );
+ gtk_widget_show( frame );
+ gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( frame ), FALSE, FALSE, 0 );
+ {
+ //Prolly should make this a member or global var, so the SI can draw on it...
+ TexTool::g_textoolWin = glwidget_new( FALSE );
+ // --> Dunno, but this stuff may be necessary... (Looks like it!)
+ g_object_ref( TexTool::g_textoolWin );
+ gtk_widget_set_events( TexTool::g_textoolWin, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK );
+ gtk_widget_set_can_focus( TexTool::g_textoolWin, true );
+ // <-- end stuff...
+ gtk_widget_show( TexTool::g_textoolWin );
+ gtk_widget_set_size_request( TexTool::g_textoolWin, -1, 240 ); //Yeah!
+ gtk_container_add( GTK_CONTAINER( frame ), TexTool::g_textoolWin );
+
+ g_signal_connect( G_OBJECT( TexTool::g_textoolWin ), "size_allocate", G_CALLBACK( TexTool::size_allocate ), NULL );
+ g_signal_connect( G_OBJECT( TexTool::g_textoolWin ), "expose_event", G_CALLBACK( TexTool::expose ), NULL );
+ g_signal_connect( G_OBJECT( TexTool::g_textoolWin ), "button_press_event", G_CALLBACK( TexTool::button_press ), NULL );
+ g_signal_connect( G_OBJECT( TexTool::g_textoolWin ), "button_release_event", G_CALLBACK( TexTool::button_release ), NULL );
+ g_signal_connect( G_OBJECT( TexTool::g_textoolWin ), "motion_notify_event", G_CALLBACK( TexTool::motion ), NULL );
+ }
+ {
+ ui::Widget hbox = ui::HBox( FALSE, 5 );
+ gtk_widget_show( hbox );
+ gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox ), FALSE, FALSE, 0 );
+ // Checkboxes go here... (Flip X/Y)
+ ui::Widget flipX = ui::CheckButton( "Flip X axis" );
+ ui::Widget flipY = ui::CheckButton( "Flip Y axis" );
+ gtk_widget_show( flipX );
+ gtk_widget_show( flipY );
+ gtk_box_pack_start( GTK_BOX( hbox ), flipX, FALSE, FALSE, 0 );
+ gtk_box_pack_start( GTK_BOX( hbox ), flipY, FALSE, FALSE, 0 );
+
+//Instead of this, we probably need to create a vbox to put into the frame, then the
+//window, then the hbox. !!! FIX !!!
+// gtk_container_add(GTK_CONTAINER(frame), hbox);
+
+//Hmm. Do we really need g_object_set_data? Mebbe not... And we don't! :-)
+// g_object_set_data(G_OBJECT(flipX), "handler", gint_to_pointer(g_signal_connect(G_OBJECT(flipX), "toggled", G_CALLBACK(TexTool::flipX), 0)));
+// g_object_set_data(G_OBJECT(flipY), "handler", gint_to_pointer(g_signal_connect(G_OBJECT(flipY), "toggled", G_CALLBACK(TexTool::flipY), 0)));
+//Instead, just do:
+ g_signal_connect( G_OBJECT( flipX ), "toggled", G_CALLBACK( TexTool::flipX ), NULL );
+ g_signal_connect( G_OBJECT( flipY ), "toggled", G_CALLBACK( TexTool::flipY ), NULL );
+ }
+ }
+#endif
+ }
+
+ return window;
+}
+
+/*
+ ==============
+ Update
+
+ Set the fields to the current texdef (i.e. map/texdef -> dialog widgets)
+ if faces selected (instead of brushes) -> will read this face texdef, else current texdef
+ if only patches selected, will read the patch texdef
+ ===============
+ */
+
+void spin_button_set_value_no_signal( GtkSpinButton* spin, gdouble value ){
+ guint handler_id = gpointer_to_int( g_object_get_data( G_OBJECT( spin ), "handler" ) );
+ g_signal_handler_block( G_OBJECT( gtk_spin_button_get_adjustment( spin ) ), handler_id );
+ gtk_spin_button_set_value( spin, value );
+ g_signal_handler_unblock( G_OBJECT( gtk_spin_button_get_adjustment( spin ) ), handler_id );
+}
+
+void spin_button_set_step_increment( GtkSpinButton* spin, gdouble value ){
+ GtkAdjustment* adjust = gtk_spin_button_get_adjustment( spin );
+ gtk_adjustment_set_step_increment(adjust, value);
+}
+
+void SurfaceInspector::Update(){
+ const char * name = SurfaceInspector_GetSelectedShader();
+
+ if ( shader_is_texture( name ) ) {
+ gtk_entry_set_text( m_texture, shader_get_textureName( name ) );
+ }
+ else
+ {
+ gtk_entry_set_text( m_texture, "" );
+ }
+
+ texdef_t shiftScaleRotate;
+//Shamus: This is where we get into trouble--the BP code tries to convert to a "faked"
+//shift, rotate & scale values from the brush face, which seems to screw up for some reason.
+//!!! FIX !!!
+/*globalOutputStream() << "--> SI::Update. About to do ShiftScaleRotate_fromFace()...\n";
+ SurfaceInspector_GetSelectedBPTexdef();
+ globalOutputStream() << "BP: (" << g_selectedBrushPrimitTexdef.coords[0][0] << ", " << g_selectedBrushPrimitTexdef.coords[0][1] << ")("
+ << g_selectedBrushPrimitTexdef.coords[1][0] << ", " << g_selectedBrushPrimitTexdef.coords[1][1] << ")("
+ << g_selectedBrushPrimitTexdef.coords[0][2] << ", " << g_selectedBrushPrimitTexdef.coords[1][2] << ") SurfaceInspector::Update\n";//*/
+//Ok, it's screwed up *before* we get here...
+ ShiftScaleRotate_fromFace( shiftScaleRotate, SurfaceInspector_GetSelectedTexdef() );
+
+ // normalize again to hide the ridiculously high scale values that get created when using texlock
+ shiftScaleRotate.shift[0] = float_mod( shiftScaleRotate.shift[0], (float)g_selectedShaderSize[0] );
+ shiftScaleRotate.shift[1] = float_mod( shiftScaleRotate.shift[1], (float)g_selectedShaderSize[1] );
+
+ {
+ spin_button_set_value_no_signal( m_hshiftIncrement.m_spin, shiftScaleRotate.shift[0] );
+ spin_button_set_step_increment( m_hshiftIncrement.m_spin, g_si_globals.shift[0] );
+ entry_set_float( m_hshiftIncrement.m_entry, g_si_globals.shift[0] );
+ }
+
+ {
+ spin_button_set_value_no_signal( m_vshiftIncrement.m_spin, shiftScaleRotate.shift[1] );
+ spin_button_set_step_increment( m_vshiftIncrement.m_spin, g_si_globals.shift[1] );
+ entry_set_float( m_vshiftIncrement.m_entry, g_si_globals.shift[1] );
+ }
+
+ {
+ spin_button_set_value_no_signal( m_hscaleIncrement.m_spin, shiftScaleRotate.scale[0] );
+ spin_button_set_step_increment( m_hscaleIncrement.m_spin, g_si_globals.scale[0] );
+ entry_set_float( m_hscaleIncrement.m_entry, g_si_globals.scale[0] );
+ }
+
+ {
+ spin_button_set_value_no_signal( m_vscaleIncrement.m_spin, shiftScaleRotate.scale[1] );
+ spin_button_set_step_increment( m_vscaleIncrement.m_spin, g_si_globals.scale[1] );
+ entry_set_float( m_vscaleIncrement.m_entry, g_si_globals.scale[1] );
+ }
+
+ {
+ spin_button_set_value_no_signal( m_rotateIncrement.m_spin, shiftScaleRotate.rotate );
+ spin_button_set_step_increment( m_rotateIncrement.m_spin, g_si_globals.rotate );
+ entry_set_float( m_rotateIncrement.m_entry, g_si_globals.rotate );
+ }
+
+ if ( !string_empty( g_pGameDescription->getKeyValue( "si_flags" ) ) ) {
+ ContentsFlagsValue flags( SurfaceInspector_GetSelectedFlags() );
+
+ entry_set_int( m_valueEntryWidget, flags.m_value );
+
+ for ( GtkCheckButton** p = m_surfaceFlags; p != m_surfaceFlags + 32; ++p )
+ {
+ toggle_button_set_active_no_signal( ui::CheckButton( *p ), flags.m_surfaceFlags & ( 1 << ( p - m_surfaceFlags ) ) );
+ }
+
+ for ( GtkCheckButton** p = m_contentFlags; p != m_contentFlags + 32; ++p )
+ {
+ toggle_button_set_active_no_signal( ui::CheckButton( *p ), flags.m_contentFlags & ( 1 << ( p - m_contentFlags ) ) );
+ }
+ }
+}
+
+/*
+ ==============
+ Apply
+
+ Reads the fields to get the current texdef (i.e. widgets -> MAP)
+ in brush primitive mode, grab the fake shift scale rot and compute a new texture matrix
+ ===============
+ */
+void SurfaceInspector::ApplyShader(){
+ StringOutputStream name( 256 );
+ name << GlobalTexturePrefix_get() << gtk_entry_get_text( m_texture );
+
+ // TTimo: detect and refuse invalid texture names (at least the ones with spaces)
+ if ( !texdef_name_valid( name.c_str() ) ) {
+ globalErrorStream() << "invalid texture name '" << name.c_str() << "'\n";
+ SurfaceInspector_queueDraw();
+ return;
+ }
+
+ UndoableCommand undo( "textureNameSetSelected" );
+ Select_SetShader( name.c_str() );
+}
+
+void SurfaceInspector::ApplyTexdef(){
+ texdef_t shiftScaleRotate;
+
+ shiftScaleRotate.shift[0] = static_cast<float>( gtk_spin_button_get_value( m_hshiftIncrement.m_spin ) );
+ shiftScaleRotate.shift[1] = static_cast<float>( gtk_spin_button_get_value( m_vshiftIncrement.m_spin ) );
+ shiftScaleRotate.scale[0] = static_cast<float>( gtk_spin_button_get_value( m_hscaleIncrement.m_spin ) );
+ shiftScaleRotate.scale[1] = static_cast<float>( gtk_spin_button_get_value( m_vscaleIncrement.m_spin ) );
+ shiftScaleRotate.rotate = static_cast<float>( gtk_spin_button_get_value( m_rotateIncrement.m_spin ) );
+
+ TextureProjection projection;
+//Shamus: This is the other place that screws up, it seems, since it doesn't seem to do the
+//conversion from the face (I think) and so bogus values end up in the thing... !!! FIX !!!
+//This is actually OK. :-P
+ ShiftScaleRotate_toFace( shiftScaleRotate, projection );
+
+ UndoableCommand undo( "textureProjectionSetSelected" );
+ Select_SetTexdef( projection );
+}
+
+void SurfaceInspector::ApplyFlags(){
+ unsigned int surfaceflags = 0;
+ for ( GtkCheckButton** p = m_surfaceFlags; p != m_surfaceFlags + 32; ++p )
+ {
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( *p ) ) ) {
+ surfaceflags |= ( 1 << ( p - m_surfaceFlags ) );
+ }
+ }
+
+ unsigned int contentflags = 0;
+ for ( GtkCheckButton** p = m_contentFlags; p != m_contentFlags + 32; ++p )
+ {
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( *p ) ) ) {
+ contentflags |= ( 1 << ( p - m_contentFlags ) );
+ }
+ }
+
+ int value = entry_get_int( m_valueEntryWidget );
+
+ UndoableCommand undo( "flagsSetSelected" );
+ Select_SetFlags( ContentsFlagsValue( surfaceflags, contentflags, value, true ) );
+}
+
+
+void Face_getTexture( Face& face, CopiedString& shader, TextureProjection& projection, ContentsFlagsValue& flags ){
+ shader = face.GetShader();
+ face.GetTexdef( projection );
+ flags = face.getShader().m_flags;
+}
+typedef Function4<Face&, CopiedString&, TextureProjection&, ContentsFlagsValue&, void, Face_getTexture> FaceGetTexture;
+
+void Face_setTexture( Face& face, const char* shader, const TextureProjection& projection, const ContentsFlagsValue& flags ){
+ face.SetShader( shader );
+ face.SetTexdef( projection );
+ face.SetFlags( flags );