Wrap more GTK
[xonotic/netradiant.git] / contrib / prtview / ConfigDialog.cpp
1 /*
2    PrtView plugin for GtkRadiant
3    Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #include "ConfigDialog.h"
21 #include <stdio.h>
22 #include <gtk/gtk.h>
23 #include <uilib/uilib.h>
24 #include "gtkutil/pointer.h"
25
26 #include "iscenegraph.h"
27
28 #include "prtview.h"
29 #include "portals.h"
30
31 static void dialog_button_callback( GtkWidget *widget, gpointer data ){
32         GtkWidget *parent;
33         int *loop, *ret;
34
35         parent = gtk_widget_get_toplevel( widget );
36         loop = (int*)g_object_get_data( G_OBJECT( parent ), "loop" );
37         ret = (int*)g_object_get_data( G_OBJECT( parent ), "ret" );
38
39         *loop = 0;
40         *ret = gpointer_to_int( data );
41 }
42
43 static gint dialog_delete_callback( ui::Widget widget, GdkEvent* event, gpointer data ){
44         widget.hide();
45         int *loop = (int *) g_object_get_data(G_OBJECT(widget), "loop");
46         *loop = 0;
47         return TRUE;
48 }
49
50 // =============================================================================
51 // Color selection dialog
52
53 static int DoColor( PackedColour *c ){
54         GdkColor clr;
55         int loop = 1, ret = IDCANCEL;
56
57         clr.red = (guint16) (GetRValue(*c) * (65535 / 255));
58         clr.blue = (guint16) (GetGValue(*c) * (65535 / 255));
59         clr.green = (guint16) (GetBValue(*c) * (65535 / 255));
60
61         auto dlg = ui::Widget(gtk_color_selection_dialog_new( "Choose Color" ));
62         gtk_color_selection_set_current_color( GTK_COLOR_SELECTION( gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dlg)) ), &clr );
63         dlg.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
64         dlg.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
65
66         GtkWidget *ok_button, *cancel_button;
67         g_object_get(dlg, "ok-button", &ok_button, "cancel-button", &cancel_button, nullptr);
68
69         ui::Widget(ok_button).connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
70         ui::Widget(cancel_button).connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) );
71         g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
72         g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
73
74         gtk_widget_show( dlg );
75         gtk_grab_add( dlg );
76
77         while ( loop )
78                 gtk_main_iteration();
79
80         gtk_color_selection_get_current_color( GTK_COLOR_SELECTION( gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dlg)) ), &clr );
81
82         gtk_grab_remove( dlg );
83         dlg.destroy();
84
85         if ( ret == IDOK ) {
86                 *c = RGB( clr.red / (65535 / 255), clr.green / (65535 / 255), clr.blue / (65535 / 255));
87         }
88
89         return ret;
90 }
91
92 static void Set2DText( GtkWidget* label ){
93         char s[40];
94
95         sprintf( s, "Line Width = %6.3f", portals.width_2d * 0.5f );
96
97         gtk_label_set_text( GTK_LABEL( label ), s );
98 }
99
100 static void Set3DText( GtkWidget* label ){
101         char s[40];
102
103         sprintf( s, "Line Width = %6.3f", portals.width_3d * 0.5f );
104
105         gtk_label_set_text( GTK_LABEL( label ), s );
106 }
107
108 static void Set3DTransText( GtkWidget* label ){
109         char s[40];
110
111         sprintf( s, "Polygon transparency = %d%%", (int)portals.trans_3d );
112
113         gtk_label_set_text( GTK_LABEL( label ), s );
114 }
115
116 static void SetClipText( GtkWidget* label ){
117         char s[40];
118
119         sprintf( s, "Cubic clip range = %d", (int)portals.clip_range * 64 );
120
121         gtk_label_set_text( GTK_LABEL( label ), s );
122 }
123
124 static void OnScroll2d( GtkAdjustment *adj, gpointer data ){
125         portals.width_2d = static_cast<float>( gtk_adjustment_get_value(adj) );
126         Set2DText( GTK_WIDGET( data ) );
127
128         Portals_shadersChanged();
129         SceneChangeNotify();
130 }
131
132 static void OnScroll3d( GtkAdjustment *adj, gpointer data ){
133         portals.width_3d = static_cast<float>( gtk_adjustment_get_value(adj) );
134         Set3DText( GTK_WIDGET( data ) );
135
136         SceneChangeNotify();
137 }
138
139 static void OnScrollTrans( GtkAdjustment *adj, gpointer data ){
140         portals.trans_3d = static_cast<float>( gtk_adjustment_get_value(adj) );
141         Set3DTransText( GTK_WIDGET( data ) );
142
143         SceneChangeNotify();
144 }
145
146 static void OnScrollClip( GtkAdjustment *adj, gpointer data ){
147         portals.clip_range = static_cast<float>( gtk_adjustment_get_value(adj) );
148         SetClipText( GTK_WIDGET( data ) );
149
150         SceneChangeNotify();
151 }
152
153 static void OnAntiAlias2d( GtkWidget *widget, gpointer data ){
154         portals.aa_2d = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ) ? true : false;
155
156         Portals_shadersChanged();
157
158         SceneChangeNotify();
159 }
160
161 static void OnConfig2d( GtkWidget *widget, gpointer data ){
162         portals.show_2d = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ) ? true : false;
163
164         SceneChangeNotify();
165 }
166
167 static void OnColor2d( GtkWidget *widget, gpointer data ){
168         if ( DoColor( &portals.color_2d ) == IDOK ) {
169                 Portals_shadersChanged();
170
171                 SceneChangeNotify();
172         }
173 }
174
175 static void OnConfig3d( GtkWidget *widget, gpointer data ){
176         portals.show_3d = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ) ? true : false;
177
178         SceneChangeNotify();
179 }
180
181
182 static void OnAntiAlias3d( GtkWidget *widget, gpointer data ){
183         portals.aa_3d = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ) ? true : false;
184
185         Portals_shadersChanged();
186         SceneChangeNotify();
187 }
188
189 static void OnColor3d( GtkWidget *widget, gpointer data ){
190         if ( DoColor( &portals.color_3d ) == IDOK ) {
191                 Portals_shadersChanged();
192
193                 SceneChangeNotify();
194         }
195 }
196
197 static void OnColorFog( GtkWidget *widget, gpointer data ){
198         if ( DoColor( &portals.color_fog ) == IDOK ) {
199                 Portals_shadersChanged();
200
201                 SceneChangeNotify();
202         }
203 }
204
205 static void OnFog( GtkWidget *widget, gpointer data ){
206         portals.fog = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ) ? true : false;
207
208         Portals_shadersChanged();
209         SceneChangeNotify();
210 }
211
212 static void OnSelchangeZbuffer( GtkWidget *widget, gpointer data ){
213         portals.zbuffer = gpointer_to_int( data );
214
215         Portals_shadersChanged();
216         SceneChangeNotify();
217 }
218
219 static void OnPoly( GtkWidget *widget, gpointer data ){
220         portals.polygons = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) );
221
222         SceneChangeNotify();
223 }
224
225 static void OnLines( GtkWidget *widget, gpointer data ){
226         portals.lines = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) );
227
228         SceneChangeNotify();
229 }
230
231 static void OnClip( GtkWidget *widget, gpointer data ){
232         portals.clip = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ) ? true : false;
233
234         SceneChangeNotify();
235 }
236
237 void DoConfigDialog(){
238         GtkWidget *hbox, *table;
239         GtkWidget *lw3slider, *lw3label, *lw2slider, *lw2label, *item;
240         GtkWidget *transslider, *translabel, *clipslider, *cliplabel;
241         int loop = 1, ret = IDCANCEL;
242
243         auto dlg = ui::Window( ui::window_type::TOP );
244         gtk_window_set_title( GTK_WINDOW( dlg ), "Portal Viewer Configuration" );
245         dlg.connect( "delete_event",
246                                                 G_CALLBACK( dialog_delete_callback ), NULL );
247         dlg.connect( "destroy",
248                                                 G_CALLBACK( gtk_widget_destroy ), NULL );
249         g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
250         g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
251
252         auto vbox = ui::VBox( FALSE, 5 );
253         vbox.show();
254         dlg.add(vbox);
255         gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
256
257         auto frame = ui::Frame( "3D View" );
258         frame.show();
259         gtk_box_pack_start( GTK_BOX( vbox ), frame, TRUE, TRUE, 0 );
260
261         auto vbox2 = ui::VBox( FALSE, 5 );
262         vbox2.show();
263         frame.add(vbox2);
264         gtk_container_set_border_width( GTK_CONTAINER( vbox2 ), 5 );
265
266         hbox = ui::HBox( FALSE, 5 );
267         gtk_widget_show( hbox );
268         gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, TRUE, 0 );
269
270         auto adj = ui::Adjustment( portals.width_3d, 2, 40, 1, 1, 0 );
271         lw3slider = ui::HScale( adj );
272         gtk_widget_show( lw3slider );
273         gtk_box_pack_start( GTK_BOX( hbox ), lw3slider, TRUE, TRUE, 0 );
274         gtk_scale_set_draw_value( GTK_SCALE( lw3slider ), FALSE );
275
276         lw3label = ui::Label( "" );
277         gtk_widget_show( lw3label );
278         gtk_box_pack_start( GTK_BOX( hbox ), lw3label, FALSE, TRUE, 0 );
279         adj.connect( "value_changed", G_CALLBACK( OnScroll3d ), lw3label );
280
281         table = ui::Table( 2, 4, FALSE );
282         gtk_widget_show( table );
283         gtk_box_pack_start( GTK_BOX( vbox2 ), table, TRUE, TRUE, 0 );
284         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
285         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
286
287         auto button = ui::Button( "Color" );
288         gtk_widget_show( button );
289         gtk_table_attach( GTK_TABLE( table ), button, 0, 1, 0, 1,
290                                           (GtkAttachOptions) ( GTK_FILL ),
291                                           (GtkAttachOptions) ( 0 ), 0, 0 );
292         button.connect( "clicked", G_CALLBACK( OnColor3d ), NULL );
293
294         button = ui::Button( "Depth Color" );
295         gtk_widget_show( button );
296         gtk_table_attach( GTK_TABLE( table ), button, 0, 1, 1, 2,
297                                           (GtkAttachOptions) ( GTK_FILL ),
298                                           (GtkAttachOptions) ( 0 ), 0, 0 );
299         button.connect( "clicked", G_CALLBACK( OnColorFog ), NULL );
300
301         auto aa3check = ui::CheckButton( "Anti-Alias (May not work on some video cards)" );
302         gtk_widget_show( aa3check );
303         gtk_table_attach( GTK_TABLE( table ), aa3check, 1, 4, 0, 1,
304                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
305                                           (GtkAttachOptions) ( 0 ), 0, 0 );
306         aa3check.connect( "toggled", G_CALLBACK( OnAntiAlias3d ), NULL );
307
308         auto depthcheck = ui::CheckButton( "Depth Cue" );
309         gtk_widget_show( depthcheck );
310         gtk_table_attach( GTK_TABLE( table ), depthcheck, 1, 2, 1, 2,
311                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
312                                           (GtkAttachOptions) ( 0 ), 0, 0 );
313         depthcheck.connect( "toggled", G_CALLBACK( OnFog ), NULL );
314
315         auto linescheck = ui::CheckButton( "Lines" );
316         gtk_widget_show( linescheck );
317         gtk_table_attach( GTK_TABLE( table ), linescheck, 2, 3, 1, 2,
318                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
319                                           (GtkAttachOptions) ( 0 ), 0, 0 );
320         linescheck.connect( "toggled", G_CALLBACK( OnLines ), NULL );
321
322         auto polyscheck = ui::CheckButton( "Polygons" );
323         gtk_widget_show( polyscheck );
324         gtk_table_attach( GTK_TABLE( table ), polyscheck, 3, 4, 1, 2,
325                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
326                                           (GtkAttachOptions) ( 0 ), 0, 0 );
327         polyscheck.connect( "toggled", G_CALLBACK( OnPoly ), NULL );
328
329         auto zlist = ui::ComboBoxText(ui::New);
330         gtk_widget_show( zlist );
331         gtk_box_pack_start( GTK_BOX( vbox2 ), zlist, TRUE, FALSE, 0 );
332
333         gtk_combo_box_text_append_text(zlist, "Z-Buffer Test and Write (recommended for solid or no polygons)");
334         gtk_combo_box_text_append_text(zlist, "Z-Buffer Test Only (recommended for transparent polygons)");
335         gtk_combo_box_text_append_text(zlist, "Z-Buffer Off");
336
337         zlist.connect("changed", G_CALLBACK(+[](GtkComboBox *self, void *) {
338                 OnSelchangeZbuffer(GTK_WIDGET(self), GINT_TO_POINTER(gtk_combo_box_get_active(self)));
339         }), nullptr);
340
341         table = ui::Table( 2, 2, FALSE );
342         gtk_widget_show( table );
343         gtk_box_pack_start( GTK_BOX( vbox2 ), table, TRUE, TRUE, 0 );
344         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
345         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
346
347         adj = ui::Adjustment( portals.trans_3d, 0, 100, 1, 1, 0 );
348         transslider = ui::HScale( adj );
349         gtk_widget_show( transslider );
350         gtk_table_attach( GTK_TABLE( table ), transslider, 0, 1, 0, 1,
351                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
352                                           (GtkAttachOptions) ( 0 ), 0, 0 );
353         gtk_scale_set_draw_value( GTK_SCALE( transslider ), FALSE );
354
355         translabel = ui::Label( "" );
356         gtk_widget_show( translabel );
357         gtk_table_attach( GTK_TABLE( table ), translabel, 1, 2, 0, 1,
358                                           (GtkAttachOptions) ( GTK_FILL ),
359                                           (GtkAttachOptions) ( 0 ), 0, 0 );
360         gtk_misc_set_alignment( GTK_MISC( translabel ), 0.0, 0.0 );
361         adj.connect( "value_changed", G_CALLBACK( OnScrollTrans ), translabel );
362
363         adj = ui::Adjustment( portals.clip_range, 1, 128, 1, 1, 0 );
364         clipslider = ui::HScale( adj );
365         gtk_widget_show( clipslider );
366         gtk_table_attach( GTK_TABLE( table ), clipslider, 0, 1, 1, 2,
367                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
368                                           (GtkAttachOptions) ( 0 ), 0, 0 );
369         gtk_scale_set_draw_value( GTK_SCALE( clipslider ), FALSE );
370
371         cliplabel = ui::Label( "" );
372         gtk_widget_show( cliplabel );
373         gtk_table_attach( GTK_TABLE( table ), cliplabel, 1, 2, 1, 2,
374                                           (GtkAttachOptions) ( GTK_FILL ),
375                                           (GtkAttachOptions) ( 0 ), 0, 0 );
376         gtk_misc_set_alignment( GTK_MISC( cliplabel ), 0.0, 0.0 );
377         adj.connect( "value_changed", G_CALLBACK( OnScrollClip ), cliplabel );
378
379         hbox = ui::HBox( TRUE, 5 );
380         gtk_widget_show( hbox );
381         gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, FALSE, 0 );
382
383         auto show3check = ui::CheckButton( "Show" );
384         gtk_widget_show( show3check );
385         gtk_box_pack_start( GTK_BOX( hbox ), show3check, TRUE, TRUE, 0 );
386         show3check.connect( "toggled", G_CALLBACK( OnConfig3d ), NULL );
387
388         auto portalcheck = ui::CheckButton( "Portal cubic clipper" );
389         gtk_widget_show( portalcheck );
390         gtk_box_pack_start( GTK_BOX( hbox ), portalcheck, TRUE, TRUE, 0 );
391         portalcheck.connect( "toggled", G_CALLBACK( OnClip ), NULL );
392
393         frame = ui::Frame( "2D View" );
394         gtk_widget_show( frame );
395         gtk_box_pack_start( GTK_BOX( vbox ), frame, TRUE, TRUE, 0 );
396
397         vbox2 = ui::VBox( FALSE, 5 );
398         vbox2.show();
399         frame.add(vbox2);
400         gtk_container_set_border_width( GTK_CONTAINER( vbox2 ), 5 );
401
402         hbox = ui::HBox( FALSE, 5 );
403         gtk_widget_show( hbox );
404         gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, FALSE, 0 );
405
406         adj = ui::Adjustment( portals.width_2d, 2, 40, 1, 1, 0 );
407         lw2slider = ui::HScale( adj );
408         gtk_widget_show( lw2slider );
409         gtk_box_pack_start( GTK_BOX( hbox ), lw2slider, TRUE, TRUE, 0 );
410         gtk_scale_set_draw_value( GTK_SCALE( lw2slider ), FALSE );
411
412         lw2label = ui::Label( "" );
413         gtk_widget_show( lw2label );
414         gtk_box_pack_start( GTK_BOX( hbox ), lw2label, FALSE, TRUE, 0 );
415         adj.connect( "value_changed", G_CALLBACK( OnScroll2d ), lw2label );
416
417         hbox = ui::HBox( FALSE, 5 );
418         gtk_widget_show( hbox );
419         gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, FALSE, 0 );
420
421         button = ui::Button( "Color" );
422         gtk_widget_show( button );
423         gtk_box_pack_start( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
424         button.connect( "clicked", G_CALLBACK( OnColor2d ), NULL );
425         gtk_widget_set_size_request( button, 60, -1 );
426
427         auto aa2check = ui::CheckButton( "Anti-Alias (May not work on some video cards)" );
428         gtk_widget_show( aa2check );
429         gtk_box_pack_start( GTK_BOX( hbox ), aa2check, TRUE, TRUE, 0 );
430         aa2check.connect( "toggled", G_CALLBACK( OnAntiAlias2d ), NULL );
431
432         hbox = ui::HBox( FALSE, 5 );
433         gtk_widget_show( hbox );
434         gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, FALSE, 0 );
435
436         auto show2check = ui::CheckButton( "Show" );
437         gtk_widget_show( show2check );
438         gtk_box_pack_start( GTK_BOX( hbox ), show2check, FALSE, FALSE, 0 );
439         show2check.connect( "toggled", G_CALLBACK( OnConfig2d ), NULL );
440
441         hbox = ui::HBox( FALSE, 5 );
442         gtk_widget_show( hbox );
443         gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
444
445         button = ui::Button( "OK" );
446         gtk_widget_show( button );
447         gtk_box_pack_end( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
448         button.connect( "clicked",
449                                                 G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
450         gtk_widget_set_size_request( button, 60, -1 );
451
452         // initialize dialog
453         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( show2check ), portals.show_2d );
454         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( aa2check ), portals.aa_2d );
455         Set2DText( lw2label );
456
457         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( show3check ), portals.show_3d );
458         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( depthcheck ), portals.fog );
459         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( polyscheck ), portals.polygons );
460         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( linescheck ), portals.lines );
461         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( aa3check ), portals.aa_3d );
462         gtk_combo_box_set_active(zlist, portals.zbuffer);
463         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( portalcheck ), portals.clip );
464
465         Set3DText( lw3label );
466         Set3DTransText( translabel );
467         SetClipText( cliplabel );
468
469         gtk_grab_add( dlg );
470         gtk_widget_show( dlg );
471
472         while ( loop )
473                 gtk_main_iteration();
474
475         gtk_grab_remove( dlg );
476         dlg.destroy();
477 }