GTK: wrap gtk_widget_set_size_request
[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(table, 5);
281     gtk_table_set_col_spacings(table, 5);
282
283         auto button = ui::Button( "Color" );
284         button.show();
285     table.attach(button, {0, 1, 0, 1}, {GTK_FILL, 0});
286         button.connect( "clicked", G_CALLBACK( OnColor3d ), NULL );
287
288         button = ui::Button( "Depth Color" );
289         button.show();
290     table.attach(button, {0, 1, 1, 2}, {GTK_FILL, 0});
291         button.connect( "clicked", G_CALLBACK( OnColorFog ), NULL );
292
293         auto aa3check = ui::CheckButton( "Anti-Alias (May not work on some video cards)" );
294         aa3check.show();
295     table.attach(aa3check, {1, 4, 0, 1}, {GTK_EXPAND | GTK_FILL, 0});
296         aa3check.connect( "toggled", G_CALLBACK( OnAntiAlias3d ), NULL );
297
298         auto depthcheck = ui::CheckButton( "Depth Cue" );
299         depthcheck.show();
300     table.attach(depthcheck, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0});
301         depthcheck.connect( "toggled", G_CALLBACK( OnFog ), NULL );
302
303         auto linescheck = ui::CheckButton( "Lines" );
304         linescheck.show();
305     table.attach(linescheck, {2, 3, 1, 2}, {GTK_EXPAND | GTK_FILL, 0});
306         linescheck.connect( "toggled", G_CALLBACK( OnLines ), NULL );
307
308         auto polyscheck = ui::CheckButton( "Polygons" );
309         polyscheck.show();
310     table.attach(polyscheck, {3, 4, 1, 2}, {GTK_EXPAND | GTK_FILL, 0});
311         polyscheck.connect( "toggled", G_CALLBACK( OnPoly ), NULL );
312
313         auto zlist = ui::ComboBoxText(ui::New);
314         zlist.show();
315         vbox2.pack_start( zlist, TRUE, FALSE, 0 );
316
317         gtk_combo_box_text_append_text(zlist, "Z-Buffer Test and Write (recommended for solid or no polygons)");
318         gtk_combo_box_text_append_text(zlist, "Z-Buffer Test Only (recommended for transparent polygons)");
319         gtk_combo_box_text_append_text(zlist, "Z-Buffer Off");
320
321         zlist.connect("changed", G_CALLBACK(+[](ui::ComboBox self, void *) {
322                 OnSelchangeZbuffer(self, GINT_TO_POINTER(gtk_combo_box_get_active(self)));
323         }), nullptr);
324
325         table = ui::Table( 2, 2, FALSE );
326         table.show();
327         vbox2.pack_start( table, TRUE, TRUE, 0 );
328     gtk_table_set_row_spacings(table, 5);
329     gtk_table_set_col_spacings(table, 5);
330
331         adj = ui::Adjustment( portals.trans_3d, 0, 100, 1, 1, 0 );
332         auto transslider = ui::HScale( adj );
333         transslider.show();
334     table.attach(transslider, {0, 1, 0, 1}, {GTK_EXPAND | GTK_FILL, 0});
335         gtk_scale_set_draw_value( GTK_SCALE( transslider ), FALSE );
336
337         auto translabel = ui::Label( "" );
338         translabel.show();
339     table.attach(translabel, {1, 2, 0, 1}, {GTK_FILL, 0});
340         gtk_misc_set_alignment( GTK_MISC( translabel ), 0.0, 0.0 );
341         adj.connect( "value_changed", G_CALLBACK( OnScrollTrans ), translabel );
342
343         adj = ui::Adjustment( portals.clip_range, 1, 128, 1, 1, 0 );
344         auto clipslider = ui::HScale( adj );
345         clipslider.show();
346     table.attach(clipslider, {0, 1, 1, 2}, {GTK_EXPAND | GTK_FILL, 0});
347         gtk_scale_set_draw_value( GTK_SCALE( clipslider ), FALSE );
348
349         auto cliplabel = ui::Label( "" );
350         cliplabel.show();
351     table.attach(cliplabel, {1, 2, 1, 2}, {GTK_FILL, 0});
352         gtk_misc_set_alignment( GTK_MISC( cliplabel ), 0.0, 0.0 );
353         adj.connect( "value_changed", G_CALLBACK( OnScrollClip ), cliplabel );
354
355         hbox = ui::HBox( TRUE, 5 );
356         hbox.show();
357         vbox2.pack_start( hbox, TRUE, FALSE, 0 );
358
359         auto show3check = ui::CheckButton( "Show" );
360         show3check.show();
361         hbox.pack_start( show3check, TRUE, TRUE, 0 );
362         show3check.connect( "toggled", G_CALLBACK( OnConfig3d ), NULL );
363
364         auto portalcheck = ui::CheckButton( "Portal cubic clipper" );
365         portalcheck.show();
366         hbox.pack_start( portalcheck, TRUE, TRUE, 0 );
367         portalcheck.connect( "toggled", G_CALLBACK( OnClip ), NULL );
368
369         frame = ui::Frame( "2D View" );
370         frame.show();
371         vbox.pack_start( frame, TRUE, TRUE, 0 );
372
373         vbox2 = ui::VBox( FALSE, 5 );
374         vbox2.show();
375         frame.add(vbox2);
376         gtk_container_set_border_width( GTK_CONTAINER( vbox2 ), 5 );
377
378         hbox = ui::HBox( FALSE, 5 );
379         hbox.show();
380         vbox2.pack_start( hbox, TRUE, FALSE, 0 );
381
382         adj = ui::Adjustment( portals.width_2d, 2, 40, 1, 1, 0 );
383         auto lw2slider = ui::HScale( adj );
384         lw2slider.show();
385         hbox.pack_start( lw2slider, TRUE, TRUE, 0 );
386         gtk_scale_set_draw_value( GTK_SCALE( lw2slider ), FALSE );
387
388         auto lw2label = ui::Label( "" );
389         lw2label.show();
390         hbox.pack_start( lw2label, FALSE, TRUE, 0 );
391         adj.connect( "value_changed", G_CALLBACK( OnScroll2d ), lw2label );
392
393         hbox = ui::HBox( FALSE, 5 );
394         hbox.show();
395         vbox2.pack_start( hbox, TRUE, FALSE, 0 );
396
397         button = ui::Button( "Color" );
398         button.show();
399         hbox.pack_start( button, FALSE, FALSE, 0 );
400         button.connect( "clicked", G_CALLBACK( OnColor2d ), NULL );
401         button.dimensions(60, -1);
402
403         auto aa2check = ui::CheckButton( "Anti-Alias (May not work on some video cards)" );
404         aa2check.show();
405         hbox.pack_start( aa2check, TRUE, TRUE, 0 );
406         aa2check.connect( "toggled", G_CALLBACK( OnAntiAlias2d ), NULL );
407
408         hbox = ui::HBox( FALSE, 5 );
409         hbox.show();
410         vbox2.pack_start( hbox, TRUE, FALSE, 0 );
411
412         auto show2check = ui::CheckButton( "Show" );
413         show2check.show();
414         hbox.pack_start( show2check, FALSE, FALSE, 0 );
415         show2check.connect( "toggled", G_CALLBACK( OnConfig2d ), NULL );
416
417         hbox = ui::HBox( FALSE, 5 );
418         hbox.show();
419         vbox.pack_start( hbox, FALSE, FALSE, 0 );
420
421         button = ui::Button( "OK" );
422         button.show();
423         hbox.pack_end(button, FALSE, FALSE, 0);
424         button.connect( "clicked",
425                                                 G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDOK ) );
426         button.dimensions(60, -1);
427
428         // initialize dialog
429         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( show2check ), portals.show_2d );
430         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( aa2check ), portals.aa_2d );
431         Set2DText( lw2label );
432
433         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( show3check ), portals.show_3d );
434         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( depthcheck ), portals.fog );
435         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( polyscheck ), portals.polygons );
436         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( linescheck ), portals.lines );
437         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( aa3check ), portals.aa_3d );
438         gtk_combo_box_set_active(zlist, portals.zbuffer);
439         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( portalcheck ), portals.clip );
440
441         Set3DText( lw3label );
442         Set3DTransText( translabel );
443         SetClipText( cliplabel );
444
445         gtk_grab_add( dlg );
446         dlg.show();
447
448         while ( loop )
449                 gtk_main_iteration();
450
451         gtk_grab_remove( dlg );
452         dlg.destroy();
453 }