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