]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/bkgrnd2d/dialog.cpp
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / contrib / bkgrnd2d / dialog.cpp
1 /*\r
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.\r
4 \r
5 This file is part of GtkRadiant.\r
6 \r
7 GtkRadiant is free software; you can redistribute it and/or modify\r
8 it under the terms of the GNU General Public License as published by\r
9 the Free Software Foundation; either version 2 of the License, or\r
10 (at your option) any later version.\r
11 \r
12 GtkRadiant is distributed in the hope that it will be useful,\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 GNU General Public License for more details.\r
16 \r
17 You should have received a copy of the GNU General Public License\r
18 along with GtkRadiant; if not, write to the Free Software\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
20 */\r
21 \r
22 //\r
23 // bkgrnd2d Plugin dialog\r
24 //\r
25 // Code by reyalP aka Reed Mideke\r
26 //\r
27 // Based on various other plugins\r
28 //\r
29 \r
30 #include <gtk/gtk.h>\r
31 \r
32 #include "bkgrnd2d.h"\r
33 #include "dialog.h"\r
34 \r
35 // spaces to make label nice and big\r
36 #define NO_FILE_MSG "        (no file loaded)        "\r
37 \r
38 static GtkWidget *pDialogWnd;\r
39 static GtkWidget *pNotebook;\r
40 static GtkTooltips *pTooltips;\r
41 \r
42 class CBackgroundDialogPage\r
43 {\r
44 private:\r
45         GtkWidget *m_pWidget;\r
46         GtkWidget *m_pTabLabel;\r
47         GtkWidget *m_pFileLabel;\r
48         GtkWidget *m_pPosLabel;\r
49         VIEWTYPE m_vt;\r
50         bool m_bValidFile;\r
51 \r
52 public:\r
53         CBackgroundImage *m_pImage;\r
54         CBackgroundDialogPage( VIEWTYPE vt );\r
55         void Append(GtkWidget *notebook);\r
56         void Browse();\r
57         void Reload();\r
58         void SetPosLabel();\r
59 //  ~BackgroundDialogPage();\r
60 };\r
61 \r
62 \r
63 // dialog page callbacks\r
64 static void browse_callback( GtkWidget *widget, gpointer data )\r
65 {\r
66         ((CBackgroundDialogPage *)data)->Browse();\r
67 }\r
68 \r
69 static void reload_callback( GtkWidget *widget, gpointer data )\r
70 {\r
71         ((CBackgroundDialogPage *)data)->Reload();\r
72 }\r
73 \r
74 static void size_sel_callback( GtkWidget *widget, gpointer data )\r
75 {\r
76         CBackgroundDialogPage *pPage = (CBackgroundDialogPage *)data;\r
77         if (pPage->m_pImage->SetExtentsSel())\r
78                 pPage->SetPosLabel();\r
79 }\r
80 \r
81 static void size_mm_callback( GtkWidget *widget, gpointer data )\r
82 {\r
83         CBackgroundDialogPage *pPage = (CBackgroundDialogPage *)data;\r
84         if(pPage->m_pImage->SetExtentsMM())\r
85                 pPage->SetPosLabel();\r
86 }\r
87 \r
88 static void alpha_adjust_callback( GtkWidget *widget, gpointer data )\r
89 {\r
90         CBackgroundDialogPage *pPage = (CBackgroundDialogPage *)data;\r
91         pPage->m_pImage->m_alpha = (float)gtk_range_get_value (GTK_RANGE(widget));\r
92         g_FuncTable.m_pfnSysUpdateWindows(W_XY);\r
93 }\r
94 \r
95 void CBackgroundDialogPage::Reload()\r
96 {\r
97         if(m_bValidFile)\r
98                 m_pImage->Load(gtk_label_get_text(GTK_LABEL(m_pFileLabel)));\r
99 }\r
100 \r
101 void CBackgroundDialogPage::Browse()\r
102 {\r
103         char browsedir[PATH_MAX];\r
104         const char *ct;\r
105         const char *newfile;\r
106         char *t;\r
107         \r
108         //TODO GetMapName saves the map. eeep!\r
109         //also with no map, returns unnamed.map, otherwise returns full path\r
110 //      Syn_Printf(MSG_PREFIX "GetMapName() %s\n",\r
111 //                              g_FuncTable.m_pfnGetMapName());\r
112         \r
113         ct = g_FuncTable.m_pfnReadProjectKey("basepath");\r
114         // TODO shouldn't need this stuff\r
115         if(!ct || !strlen(ct)) {\r
116                 Syn_Printf(MSG_PREFIX "basepath = NULL or empty\n");\r
117                 return;\r
118         }\r
119         Syn_Printf(MSG_PREFIX "basepath: %s\n",ct);\r
120         if(strlen(ct) >= PATH_MAX) {\r
121                 Syn_Printf(MSG_PREFIX "base game dir too long\n");\r
122                 return;\r
123         }\r
124 \r
125         strcpy(browsedir,ct);\r
126         // make sure we have a trailing / \r
127         if(browsedir[strlen(browsedir) - 1] != '/')\r
128                 strcat(browsedir,"/");\r
129 \r
130         //if we dont have a file yet, don't try to use it for default dir\r
131         if(m_bValidFile) {\r
132         // filename should always be a nice clean unix style relative path\r
133                 ct = gtk_label_get_text(GTK_LABEL(m_pFileLabel));\r
134                 strcat(browsedir,ct);\r
135                 Syn_Printf(MSG_PREFIX "full path: %s\n",browsedir);\r
136 \r
137                 // lop off the file part\r
138                 t = browsedir + strlen(browsedir) - 1;\r
139                 while (t != browsedir && *t != '/') \r
140                         t--;\r
141                 *t = 0;\r
142         }\r
143         Syn_Printf(MSG_PREFIX "browse directory %s\n",browsedir);\r
144         \r
145 //does NOT need freeing contrary to include/qerplugin.h comments\r
146 //TODO bug/patch for comments\r
147 //TODO patern gets fucked up sometimes if empty\r
148 //http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=915\r
149         newfile = g_FuncTable.m_pfnFileDialog(pDialogWnd,TRUE,\r
150                                                                   "Load Background Image",browsedir,FILETYPE_KEY);\r
151         if(!newfile) {\r
152                 Syn_Printf(MSG_PREFIX "newfile = NULL\n");\r
153                 return;\r
154         }\r
155         Syn_Printf(MSG_PREFIX "newfile: %s\n",newfile);\r
156         newfile = g_FileSystemTable.m_pfnExtractRelativePath(newfile);\r
157 \r
158         if(!newfile) {\r
159                 Syn_Printf(MSG_PREFIX "newfile = NULL\n");\r
160                 return;\r
161         }\r
162         Syn_Printf(MSG_PREFIX "newfile: %s\n",newfile);\r
163 \r
164         if(m_pImage->Load(newfile)) {\r
165                 m_bValidFile = true;\r
166                 gtk_label_set_text(GTK_LABEL(m_pFileLabel),newfile);\r
167         }\r
168 }\r
169 \r
170 void CBackgroundDialogPage::SetPosLabel()\r
171 {\r
172         char s[64];\r
173         // TODO no snprintf ?\r
174         sprintf(s, "Size/Position (%d,%d) (%d,%d)",(int)(m_pImage->m_xmin),\r
175                         (int)(m_pImage->m_ymin),(int)(m_pImage->m_xmax),(int)(m_pImage->m_ymax));\r
176         gtk_label_set_text(GTK_LABEL(m_pPosLabel),s);\r
177 }\r
178 \r
179 CBackgroundDialogPage::CBackgroundDialogPage(VIEWTYPE vt )\r
180 {\r
181         GtkWidget *frame;\r
182         GtkWidget *hbox;\r
183         GtkWidget *w;\r
184 \r
185         m_vt = vt;\r
186 \r
187         m_bValidFile = false;\r
188 \r
189         switch(m_vt)\r
190         {\r
191                 case XY:\r
192                         m_pTabLabel = gtk_label_new("X/Y");\r
193                         m_pImage = &backgroundXY;\r
194                         break;\r
195                 case XZ:\r
196                         m_pTabLabel = gtk_label_new("X/Z");\r
197                         m_pImage = &backgroundXZ;\r
198                         break;\r
199                 case YZ:\r
200                         m_pTabLabel = gtk_label_new("Y/Z");\r
201                         m_pImage = &backgroundYZ;\r
202                         break;\r
203         }\r
204 // A vbox to hold everything\r
205         m_pWidget = gtk_vbox_new(FALSE,0); \r
206 // Frame for file row\r
207         frame = gtk_frame_new("File");\r
208         gtk_box_pack_start (GTK_BOX (m_pWidget),frame, FALSE, FALSE, 2);\r
209 \r
210 // hbox for first row\r
211         hbox = gtk_hbox_new(FALSE,5);\r
212         gtk_container_set_border_width(GTK_CONTAINER (hbox),4);\r
213         gtk_container_add (GTK_CONTAINER (frame), hbox);\r
214 \r
215 // label to display filename\r
216         m_pFileLabel  = gtk_label_new(NO_FILE_MSG);\r
217         gtk_label_set_selectable(GTK_LABEL(m_pFileLabel),TRUE);\r
218 //TODO set min size ? done with spaces right now\r
219         gtk_box_pack_start (GTK_BOX (hbox),m_pFileLabel, TRUE, TRUE, 5);\r
220 \r
221   gtk_widget_show (m_pFileLabel);\r
222 \r
223         w = gtk_button_new_with_label ("Browse...");\r
224         g_signal_connect (G_OBJECT (w), "clicked", G_CALLBACK (browse_callback),\r
225                                                               (gpointer)this);\r
226         gtk_box_pack_start (GTK_BOX (hbox),w, FALSE, FALSE, 5);\r
227         gtk_tooltips_set_tip (pTooltips, w, "Select a file", NULL);\r
228   gtk_widget_show (w);\r
229         \r
230         w = gtk_button_new_with_label ("Reload");\r
231         g_signal_connect (G_OBJECT (w), "clicked", G_CALLBACK (reload_callback),\r
232                                                               (gpointer)this);\r
233         // TODO disable until we have file\r
234         // gtk_widget_set_sensitive(w,FALSE);\r
235         gtk_tooltips_set_tip (pTooltips, w, "Reload current file", NULL);\r
236         gtk_box_pack_start (GTK_BOX (hbox),w, FALSE, FALSE, 5);\r
237   gtk_widget_show (w);\r
238 \r
239         gtk_widget_show (hbox);\r
240         gtk_widget_show (frame);\r
241 \r
242 // second row (rendering options)\r
243         frame = gtk_frame_new("Rendering");\r
244         gtk_box_pack_start (GTK_BOX (m_pWidget),frame, FALSE, FALSE, 2);\r
245 \r
246         hbox = gtk_hbox_new(FALSE,5);\r
247         gtk_container_set_border_width(GTK_CONTAINER (hbox),4);\r
248         gtk_container_add (GTK_CONTAINER (frame), hbox);\r
249 \r
250         w = gtk_label_new("Vertex alpha:");\r
251         gtk_box_pack_start (GTK_BOX (hbox),w, FALSE, FALSE, 5);\r
252   gtk_widget_show (w);\r
253 \r
254         w = gtk_hscale_new_with_range(0.0,1.0,0.01);\r
255         gtk_range_set_value(GTK_RANGE(w),0.5);\r
256         gtk_scale_set_value_pos(GTK_SCALE(w),GTK_POS_LEFT);\r
257         g_signal_connect (G_OBJECT (w), "value-changed",\r
258                           G_CALLBACK (alpha_adjust_callback), (gpointer)this);\r
259         gtk_box_pack_start (GTK_BOX (hbox),w, TRUE, TRUE, 5);\r
260         gtk_tooltips_set_tip (pTooltips, w, "Set image transparancy", NULL);\r
261   gtk_widget_show (w);\r
262 \r
263         gtk_widget_show (hbox);\r
264         gtk_widget_show (frame);\r
265 // Third row (size and position)\r
266         frame = gtk_frame_new("Size/Position (undefined)");\r
267         m_pPosLabel = gtk_frame_get_label_widget (GTK_FRAME(frame));\r
268         gtk_box_pack_start ( GTK_BOX (m_pWidget), frame, FALSE, FALSE, 2);\r
269 \r
270         hbox = gtk_hbox_new(FALSE,5);\r
271         gtk_container_add (GTK_CONTAINER (frame), hbox);\r
272         gtk_container_set_border_width(GTK_CONTAINER (hbox),4);\r
273 \r
274         w = gtk_button_new_with_label ("from selection");\r
275         gtk_box_pack_start (GTK_BOX (hbox),w, TRUE, FALSE, 5);\r
276         g_signal_connect (G_OBJECT (w), "clicked", G_CALLBACK (size_sel_callback),\r
277                                                                 (gpointer)this);\r
278         gtk_tooltips_set_tip (pTooltips, w, "Set the size of the image to the bounding rectangle of all selected brushes and entities", NULL);\r
279   gtk_widget_show (w);\r
280 \r
281         if(m_vt == XY) {\r
282                 w = gtk_button_new_with_label ("from map mins/maxs");\r
283                 gtk_box_pack_start ( GTK_BOX (hbox),w, TRUE, FALSE, 2);\r
284                 g_signal_connect (G_OBJECT (w), "clicked", G_CALLBACK (size_mm_callback),\r
285                                                                 (gpointer)this);\r
286                 gtk_tooltips_set_tip (pTooltips, w, "Set the size of the image using the mapcoordsmins and mapcoordsmaxs keys of the worldspawn entity", NULL);\r
287                 gtk_widget_show (w);\r
288         }\r
289 \r
290         gtk_widget_show (hbox);\r
291         gtk_widget_show (frame);\r
292 \r
293   gtk_widget_show ( m_pWidget );\r
294 }\r
295 \r
296 void CBackgroundDialogPage::Append(GtkWidget *notebook)\r
297 {\r
298         gtk_notebook_append_page( GTK_NOTEBOOK(notebook), m_pWidget, m_pTabLabel);\r
299 }\r
300 \r
301 // dialog global callbacks\r
302 /*\r
303 static gint expose_callback( GtkWidget *widget, gpointer data )\r
304 {\r
305         return FALSE;\r
306 }\r
307 */\r
308 \r
309 static void response_callback( GtkWidget *widget, gint response, gpointer data )\r
310 {\r
311         if( response == GTK_RESPONSE_CLOSE )\r
312                 gtk_widget_hide( pDialogWnd );\r
313 }\r
314 \r
315 static gint close_callback( GtkWidget *widget, gpointer data )\r
316 {\r
317         gtk_widget_hide( pDialogWnd );\r
318         return TRUE;\r
319 }\r
320 \r
321 void InitBackgroundDialog()\r
322 {\r
323         CBackgroundDialogPage *pPage;\r
324 \r
325         pDialogWnd = gtk_dialog_new_with_buttons ("Background Images",\r
326                               GTK_WINDOW(g_pMainWidget),\r
327                               (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT),\r
328         // TODO dialog with no buttons\r
329         //                                                                                GTK_STOCK_CLOSE,\r
330         //                                                                                GTK_RESPONSE_CLOSE,\r
331                               NULL);\r
332         gtk_signal_connect( GTK_OBJECT (pDialogWnd), "delete_event",\r
333                                     GTK_SIGNAL_FUNC( close_callback ), NULL );\r
334         gtk_signal_connect( GTK_OBJECT (pDialogWnd), "response",\r
335                                   GTK_SIGNAL_FUNC( response_callback ), NULL );\r
336 //      gtk_signal_connect( GTK_OBJECT (pDialogWnd), "expose_event", GTK_SIGNAL_FUNC( ci_expose ), NULL );\r
337 \r
338         pTooltips = gtk_tooltips_new();\r
339 \r
340         pNotebook = gtk_notebook_new();\r
341         pPage = new CBackgroundDialogPage(XY);\r
342         pPage->Append(pNotebook);\r
343         pPage = new CBackgroundDialogPage(XZ);\r
344         pPage->Append(pNotebook);\r
345         pPage = new CBackgroundDialogPage(YZ);\r
346         pPage->Append(pNotebook);\r
347 \r
348         gtk_box_pack_start (GTK_BOX (GTK_DIALOG(pDialogWnd)->vbox), pNotebook, TRUE, TRUE, 0);\r
349 \r
350   gtk_widget_show ( pNotebook );\r
351         \r
352         gtk_widget_realize( pDialogWnd );\r
353 }\r
354 \r
355 void ShowBackgroundDialog()\r
356 {\r
357         gtk_window_present( GTK_WINDOW(pDialogWnd) );\r
358 }\r
359 \r
360 void ShowBackgroundDialogPG(int page)\r
361 {\r
362         gtk_notebook_set_current_page(GTK_NOTEBOOK(pNotebook),page);\r
363         ShowBackgroundDialog();\r
364 }\r
365 \r