GTK: wrap GTK_WIDGET
[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         dlg.show();
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( ui::Widget::from(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( ui::Widget::from( 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( ui::Widget::from( 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( ui::Widget::from( 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         int loop = 1, ret = IDCANCEL;
239
240         auto dlg = ui::Window( ui::window_type::TOP );
241         gtk_window_set_title( GTK_WINDOW( dlg ), "Portal Viewer Configuration" );
242         dlg.connect( "delete_event",
243                                                 G_CALLBACK( dialog_delete_callback ), NULL );
244         dlg.connect( "destroy",
245                                                 G_CALLBACK( gtk_widget_destroy ), NULL );
246         g_object_set_data( G_OBJECT( dlg ), "loop", &loop );
247         g_object_set_data( G_OBJECT( dlg ), "ret", &ret );
248
249         auto vbox = ui::VBox( FALSE, 5 );
250         vbox.show();
251         dlg.add(vbox);
252         gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
253
254         auto frame = ui::Frame( "3D View" );
255         frame.show();
256         vbox.pack_start( frame, TRUE, TRUE, 0 );
257
258         auto vbox2 = ui::VBox( FALSE, 5 );
259         vbox2.show();
260         frame.add(vbox2);
261         gtk_container_set_border_width( GTK_CONTAINER( vbox2 ), 5 );
262
263         auto hbox = ui::HBox( FALSE, 5 );
264         hbox.show();
265         vbox2.pack_start( hbox, TRUE, TRUE, 0 );
266
267         auto adj = ui::Adjustment( portals.width_3d, 2, 40, 1, 1, 0 );
268         auto lw3slider = ui::HScale( adj );
269         lw3slider.show();
270         hbox.pack_start( lw3slider, TRUE, TRUE, 0 );
271         gtk_scale_set_draw_value( GTK_SCALE( lw3slider ), FALSE );
272
273         auto lw3label = ui::Label( "" );
274         lw3label.show();
275         hbox.pack_start( lw3label, FALSE, TRUE, 0 );
276         adj.connect( "value_changed", G_CALLBACK( OnScroll3d ), lw3label );
277
278         auto table = ui::Table( 2, 4, FALSE );
279         table.show();
280         vbox2.pack_start( table, TRUE, TRUE, 0 );
281         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
282         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
283
284         auto button = ui::Button( "Color" );
285         button.show();
286         gtk_table_attach( GTK_TABLE( table ), button, 0, 1, 0, 1,
287                                           (GtkAttachOptions) ( GTK_FILL ),
288                                           (GtkAttachOptions) ( 0 ), 0, 0 );
289         button.connect( "clicked", G_CALLBACK( OnColor3d ), NULL );
290
291         button = ui::Button( "Depth Color" );
292         button.show();
293         gtk_table_attach( GTK_TABLE( table ), button, 0, 1, 1, 2,
294                                           (GtkAttachOptions) ( GTK_FILL ),
295                                           (GtkAttachOptions) ( 0 ), 0, 0 );
296         button.connect( "clicked", G_CALLBACK( OnColorFog ), NULL );
297
298         auto aa3check = ui::CheckButton( "Anti-Alias (May not work on some video cards)" );
299         aa3check.show();
300         gtk_table_attach( GTK_TABLE( table ), aa3check, 1, 4, 0, 1,
301                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
302                                           (GtkAttachOptions) ( 0 ), 0, 0 );
303         aa3check.connect( "toggled", G_CALLBACK( OnAntiAlias3d ), NULL );
304
305         auto depthcheck = ui::CheckButton( "Depth Cue" );
306         depthcheck.show();
307         gtk_table_attach( GTK_TABLE( table ), depthcheck, 1, 2, 1, 2,
308                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
309                                           (GtkAttachOptions) ( 0 ), 0, 0 );
310         depthcheck.connect( "toggled", G_CALLBACK( OnFog ), NULL );
311
312         auto linescheck = ui::CheckButton( "Lines" );
313         linescheck.show();
314         gtk_table_attach( GTK_TABLE( table ), linescheck, 2, 3, 1, 2,
315                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
316                                           (GtkAttachOptions) ( 0 ), 0, 0 );
317         linescheck.connect( "toggled", G_CALLBACK( OnLines ), NULL );
318
319         auto polyscheck = ui::CheckButton( "Polygons" );
320         polyscheck.show();
321         gtk_table_attach( GTK_TABLE( table ), polyscheck, 3, 4, 1, 2,
322                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
323                                           (GtkAttachOptions) ( 0 ), 0, 0 );
324         polyscheck.connect( "toggled", G_CALLBACK( OnPoly ), NULL );
325
326         auto zlist = ui::ComboBoxText(ui::New);
327         zlist.show();
328         vbox2.pack_start( zlist, TRUE, FALSE, 0 );
329
330         gtk_combo_box_text_append_text(zlist, "Z-Buffer Test and Write (recommended for solid or no polygons)");
331         gtk_combo_box_text_append_text(zlist, "Z-Buffer Test Only (recommended for transparent polygons)");
332         gtk_combo_box_text_append_text(zlist, "Z-Buffer Off");
333
334         zlist.connect("changed", G_CALLBACK(+[](ui::ComboBox self, void *) {
335                 OnSelchangeZbuffer(self, GINT_TO_POINTER(gtk_combo_box_get_active(self)));
336         }), nullptr);
337
338         table = ui::Table( 2, 2, FALSE );
339         table.show();
340         vbox2.pack_start( table, TRUE, TRUE, 0 );
341         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
342         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
343
344         adj = ui::Adjustment( portals.trans_3d, 0, 100, 1, 1, 0 );
345         auto transslider = ui::HScale( adj );
346         transslider.show();
347         gtk_table_attach( GTK_TABLE( table ), transslider, 0, 1, 0, 1,
348                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
349                                           (GtkAttachOptions) ( 0 ), 0, 0 );
350         gtk_scale_set_draw_value( GTK_SCALE( transslider ), FALSE );
351
352         auto translabel = ui::Label( "" );
353         translabel.show();
354         gtk_table_attach( GTK_TABLE( table ), translabel, 1, 2, 0, 1,
355                                           (GtkAttachOptions) ( GTK_FILL ),
356                                           (GtkAttachOptions) ( 0 ), 0, 0 );
357         gtk_misc_set_alignment( GTK_MISC( translabel ), 0.0, 0.0 );
358         adj.connect( "value_changed", G_CALLBACK( OnScrollTrans ), translabel );
359
360         adj = ui::Adjustment( portals.clip_range, 1, 128, 1, 1, 0 );
361         auto clipslider = ui::HScale( adj );
362         clipslider.show();
363         gtk_table_attach( GTK_TABLE( table ), clipslider, 0, 1, 1, 2,
364                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
365                                           (GtkAttachOptions) ( 0 ), 0, 0 );
366         gtk_scale_set_draw_value( GTK_SCALE( clipslider ), FALSE );
367
368         auto cliplabel = ui::Label( "" );
369         cliplabel.show();
370         gtk_table_attach( GTK_TABLE( table ), cliplabel, 1, 2, 1, 2,
371                                           (GtkAttachOptions) ( GTK_FILL ),
372                                           (GtkAttachOptions) ( 0 ), 0, 0 );
373         gtk_misc_set_alignment( GTK_MISC( cliplabel ), 0.0, 0.0 );
374         adj.connect( "value_changed", G_CALLBACK( OnScrollClip ), cliplabel );
375
376         hbox = ui::HBox( TRUE, 5 );
377         hbox.show();
378         vbox2.pack_start( hbox, TRUE, FALSE, 0 );
379
380         auto show3check = ui::CheckButton( "Show" );
381         show3check.show();
382         hbox.pack_start( show3check, TRUE, TRUE, 0 );
383         show3check.connect( "toggled", G_CALLBACK( OnConfig3d ), NULL );
384
385         auto portalcheck = ui::CheckButton( "Portal cubic clipper" );
386         portalcheck.show();
387         hbox.pack_start( portalcheck, TRUE, TRUE, 0 );
388         portalcheck.connect( "toggled", G_CALLBACK( OnClip ), NULL );
389
390         frame = ui::Frame( "2D View" );
391         frame.show();
392         vbox.pack_start( frame, TRUE, TRUE, 0 );
393
394         vbox2 = ui::VBox( FALSE, 5 );
395         vbox2.show();
396         frame.add(vbox2);
397         gtk_container_set_border_width( GTK_CONTAINER( vbox2 ), 5 );
398
399         hbox = ui::HBox( FALSE, 5 );
400         hbox.show();
401         vbox2.pack_start( hbox, TRUE, FALSE, 0 );
402
403         adj = ui::Adjustment( portals.width_2d, 2, 40, 1, 1, 0 );
404         auto lw2slider = ui::HScale( adj );
405         lw2slider.show();
406         hbox.pack_start( lw2slider, TRUE, TRUE, 0 );
407         gtk_scale_set_draw_value( GTK_SCALE( lw2slider ), FALSE );
408
409         auto lw2label = ui::Label( "" );
410         lw2label.show();
411         hbox.pack_start( lw2label, FALSE, TRUE, 0 );
412         adj.connect( "value_changed", G_CALLBACK( OnScroll2d ), lw2label );
413
414         hbox = ui::HBox( FALSE, 5 );
415         hbox.show();
416         vbox2.pack_start( hbox, TRUE, FALSE, 0 );
417
418         button = ui::Button( "Color" );
419         button.show();
420         hbox.pack_start( button, FALSE, FALSE, 0 );
421         button.connect( "clicked", G_CALLBACK( OnColor2d ), NULL );
422         gtk_widget_set_size_request( button, 60, -1 );
423
424         auto aa2check = ui::CheckButton( "Anti-Alias (May not work on some video cards)" );
425         aa2check.show();
426         hbox.pack_start( aa2check, TRUE, TRUE, 0 );
427         aa2check.connect( "toggled", G_CALLBACK( OnAntiAlias2d ), NULL );
428
429         hbox = ui::HBox( FALSE, 5 );
430         hbox.show();
431         vbox2.pack_start( hbox, TRUE, FALSE, 0 );
432
433         auto show2check = ui::CheckButton( "Show" );
434         show2check.show();
435         hbox.pack_start( show2check, FALSE, FALSE, 0 );
436         show2check.connect( "toggled", G_CALLBACK( OnConfig2d ), NULL );
437
438         hbox = ui::HBox( FALSE, 5 );
439         hbox.show();
440         vbox.pack_start( hbox, FALSE, FALSE, 0 );
441
442         button = ui::Button( "OK" );
443         button.show();
444         hbox.pack_end(button, FALSE, FALSE, 0);
445         button.connect( "clicked",
446                                                 G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
447         gtk_widget_set_size_request( button, 60, -1 );
448
449         // initialize dialog
450         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( show2check ), portals.show_2d );
451         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( aa2check ), portals.aa_2d );
452         Set2DText( lw2label );
453
454         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( show3check ), portals.show_3d );
455         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( depthcheck ), portals.fog );
456         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( polyscheck ), portals.polygons );
457         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( linescheck ), portals.lines );
458         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( aa3check ), portals.aa_3d );
459         gtk_combo_box_set_active(zlist, portals.zbuffer);
460         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( portalcheck ), portals.clip );
461
462         Set3DText( lw3label );
463         Set3DTransText( translabel );
464         SetClipText( cliplabel );
465
466         gtk_grab_add( dlg );
467         dlg.show();
468
469         while ( loop )
470                 gtk_main_iteration();
471
472         gtk_grab_remove( dlg );
473         dlg.destroy();
474 }