2 Copyright (C) 2003 Reed Mideke.
4 This file is part of GtkRadiant.
6 GtkRadiant is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 GtkRadiant is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GtkRadiant; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 // bkgrnd2d Plugin dialog
24 // Code by reyalP aka Reed Mideke
26 // Based on various other plugins
34 // spaces to make label nice and big
35 #define NO_FILE_MSG " (no file loaded) "
37 static ui::Window pDialogWnd{ui::null};
38 static GtkWidget *pNotebook;
39 static GtkTooltips *pTooltips;
41 class CBackgroundDialogPage {
44 GtkWidget *m_pTabLabel;
45 ui::Label m_pFileLabel;
46 GtkWidget *m_pPosLabel;
51 CBackgroundImage *m_pImage;
53 CBackgroundDialogPage(VIEWTYPE vt);
55 void Append(GtkWidget *notebook);
62 // ~BackgroundDialogPage();
66 // dialog page callbacks
67 static void browse_callback(GtkWidget *widget, gpointer data)
69 ((CBackgroundDialogPage *) data)->Browse();
72 static void reload_callback(GtkWidget *widget, gpointer data)
74 ((CBackgroundDialogPage *) data)->Reload();
77 static void size_sel_callback(GtkWidget *widget, gpointer data)
79 CBackgroundDialogPage *pPage = (CBackgroundDialogPage *) data;
80 if (pPage->m_pImage->SetExtentsSel()) {
85 static void size_mm_callback(GtkWidget *widget, gpointer data)
87 CBackgroundDialogPage *pPage = (CBackgroundDialogPage *) data;
88 if (pPage->m_pImage->SetExtentsMM()) {
93 static void alpha_adjust_callback(GtkWidget *widget, gpointer data)
95 CBackgroundDialogPage *pPage = (CBackgroundDialogPage *) data;
96 pPage->m_pImage->m_alpha = (float) gtk_range_get_value(GTK_RANGE(widget));
97 g_FuncTable.m_pfnSysUpdateWindows(W_XY);
100 void CBackgroundDialogPage::Reload()
103 m_pImage->Load(gtk_label_get_text(GTK_LABEL(m_pFileLabel)));
107 void CBackgroundDialogPage::Browse()
109 char browsedir[PATH_MAX];
114 //TODO GetMapName saves the map. eeep!
115 //also with no map, returns unnamed.map, otherwise returns full path
116 // Syn_Printf(MSG_PREFIX "GetMapName() %s\n",
117 // g_FuncTable.m_pfnGetMapName());
119 ct = g_FuncTable.m_pfnReadProjectKey("basepath");
120 // TODO shouldn't need this stuff
121 if (!ct || !strlen(ct)) {
122 Syn_Printf(MSG_PREFIX "basepath = NULL or empty\n");
125 Syn_Printf(MSG_PREFIX "basepath: %s\n", ct);
126 if (strlen(ct) >= PATH_MAX) {
127 Syn_Printf(MSG_PREFIX "base game dir too long\n");
131 strcpy(browsedir, ct);
132 // make sure we have a trailing /
133 if (browsedir[strlen(browsedir) - 1] != '/') {
134 strcat(browsedir, "/");
137 //if we dont have a file yet, don't try to use it for default dir
139 // filename should always be a nice clean unix style relative path
140 ct = gtk_label_get_text(GTK_LABEL(m_pFileLabel));
141 strcat(browsedir, ct);
142 Syn_Printf(MSG_PREFIX "full path: %s\n", browsedir);
144 // lop off the file part
145 t = browsedir + strlen(browsedir) - 1;
146 while (t != browsedir && *t != '/') {
151 Syn_Printf(MSG_PREFIX "browse directory %s\n", browsedir);
153 //does NOT need freeing contrary to include/qerplugin.h comments
154 //TODO bug/patch for comments
155 //TODO patern gets fucked up sometimes if empty
156 //http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=915
157 newfile = g_FuncTable.m_pfnFileDialog(pDialogWnd, TRUE,
158 "Load Background Image", browsedir, FILETYPE_KEY);
160 Syn_Printf(MSG_PREFIX "newfile = NULL\n");
163 Syn_Printf(MSG_PREFIX "newfile: %s\n", newfile);
164 newfile = g_FileSystemTable.m_pfnExtractRelativePath(newfile);
167 Syn_Printf(MSG_PREFIX "newfile = NULL\n");
170 Syn_Printf(MSG_PREFIX "newfile: %s\n", newfile);
172 if (m_pImage->Load(newfile)) {
174 m_pFileLabel.text(newfile);
178 void CBackgroundDialogPage::SetPosLabel()
181 // TODO no snprintf ?
182 sprintf(s, "Size/Position (%d,%d) (%d,%d)", (int) (m_pImage->m_xmin),
183 (int) (m_pImage->m_ymin), (int) (m_pImage->m_xmax), (int) (m_pImage->m_ymax));
187 CBackgroundDialogPage::CBackgroundDialogPage(VIEWTYPE vt)
193 m_bValidFile = false;
197 m_pTabLabel = ui::Label("X/Y");
198 m_pImage = &backgroundXY;
201 m_pTabLabel = ui::Label("X/Z");
202 m_pImage = &backgroundXZ;
205 m_pTabLabel = ui::Label("Y/Z");
206 m_pImage = &backgroundYZ;
209 // A vbox to hold everything
210 m_pWidget = ui::VBox(FALSE, 0);
211 // Frame for file row
212 auto frame = ui::Frame("File");
213 m_pWidget.pack_start(frame, FALSE, FALSE, 2);
215 // hbox for first row
216 auto hbox = ui::HBox(FALSE, 5);
217 gtk_container_set_border_width(GTK_CONTAINER(hbox), 4);
220 // label to display filename
221 m_pFileLabel = ui::Label(NO_FILE_MSG);
222 gtk_label_set_selectable(GTK_LABEL(m_pFileLabel), TRUE);
223 //TODO set min size ? done with spaces right now
224 hbox.pack_start(m_pFileLabel, TRUE, TRUE, 5);
228 w = ui::Button("Browse...");
229 w.connect("clicked", G_CALLBACK(browse_callback), (gpointer) this );
230 hbox.pack_start(w, FALSE, FALSE, 5);
231 gtk_tooltips_set_tip(pTooltips, w, "Select a file", NULL);
234 w = ui::Button("Reload");
235 w.connect("clicked", G_CALLBACK(reload_callback), (gpointer) this );
236 // TODO disable until we have file
237 // gtk_widget_set_sensitive(w,FALSE);
238 gtk_tooltips_set_tip(pTooltips, w, "Reload current file", NULL);
239 hbox.pack_start(w, FALSE, FALSE, 5);
245 // second row (rendering options)
246 frame = ui::Frame("Rendering");
247 m_pWidget.pack_start(frame, FALSE, FALSE, 2);
249 hbox = ui::HBox(FALSE, 5);
250 gtk_container_set_border_width(GTK_CONTAINER(hbox), 4);
253 w = ui::Label("Vertex alpha:");
254 hbox.pack_start(w, FALSE, FALSE, 5);
257 w = ui::HScale(0.0, 1.0, 0.01);
258 gtk_range_set_value(GTK_RANGE(w), 0.5);
259 gtk_scale_set_value_pos(GTK_SCALE(w), GTK_POS_LEFT);
260 w.connect("value-changed", G_CALLBACK(alpha_adjust_callback), (gpointer) this );
261 hbox.pack_start(w, TRUE, TRUE, 5);
262 gtk_tooltips_set_tip(pTooltips, w, "Set image transparancy", NULL);
267 // Third row (size and position)
268 frame = ui::Frame("Size/Position (undefined)");
269 m_pPosLabel = gtk_frame_get_label_widget(GTK_FRAME(frame));
270 m_pWidget.pack_start(frame, FALSE, FALSE, 2);
272 hbox = ui::HBox(FALSE, 5);
274 gtk_container_set_border_width(GTK_CONTAINER(hbox), 4);
276 w = ui::Button("from selection");
277 hbox.pack_start(w, TRUE, FALSE, 5);
278 w.connect("clicked", G_CALLBACK(size_sel_callback), (gpointer) this );
279 gtk_tooltips_set_tip(pTooltips, w,
280 "Set the size of the image to the bounding rectangle of all selected brushes and entities",
285 w = ui::Button("from map mins/maxs");
286 hbox.pack_start(w, TRUE, FALSE, 2);
287 w.connect("clicked", G_CALLBACK(size_mm_callback), (gpointer) this );
288 gtk_tooltips_set_tip(pTooltips, w,
289 "Set the size of the image using the mapcoordsmins and mapcoordsmaxs keys of the worldspawn entity",
300 void CBackgroundDialogPage::Append(GtkWidget *notebook)
302 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), m_pWidget, m_pTabLabel);
305 // dialog global callbacks
307 static gint expose_callback( GtkWidget *widget, gpointer data )
313 static void response_callback(GtkWidget *widget, gint response, gpointer data)
315 if (response == GTK_RESPONSE_CLOSE) {
316 gtk_widget_hide(pDialogWnd);
320 static gint close_callback(GtkWidget *widget, gpointer data)
322 gtk_widget_hide(pDialogWnd);
326 void InitBackgroundDialog()
328 CBackgroundDialogPage *pPage;
330 pDialogWnd = gtk_dialog_new_with_buttons("Background Images",
332 (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT),
333 // TODO dialog with no buttons
335 // GTK_RESPONSE_CLOSE,
337 pDialogWnd.connect("delete_event", G_CALLBACK(close_callback), NULL);
338 pDialogWnd.connect("response", G_CALLBACK(response_callback), NULL);
339 // pDialogWnd.connect( "expose_event", G_CALLBACK( ci_expose ), NULL );
341 pTooltips = gtk_tooltips_new();
343 pNotebook = gtk_notebook_new();
344 pPage = new CBackgroundDialogPage(XY);
345 pPage->Append(pNotebook);
346 pPage = new CBackgroundDialogPage(XZ);
347 pPage->Append(pNotebook);
348 pPage = new CBackgroundDialogPage(YZ);
349 pPage->Append(pNotebook);
351 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pDialogWnd)->vbox), pNotebook, TRUE, TRUE, 0);
355 gtk_widget_realize(pDialogWnd);
358 void ShowBackgroundDialog()
360 gtk_window_present(pDialogWnd);
363 void ShowBackgroundDialogPG(int page)
365 gtk_notebook_set_current_page(GTK_NOTEBOOK(pNotebook), page);
366 ShowBackgroundDialog();