2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 // Leonardo Zide (leo@lokigames.com)
28 #include <gdk/gdkkeysyms.h>
30 #include "patchdialog.h"
32 PatchDialog g_PatchDialog;
33 // is the patch inspector currently displayed/active?
34 bool l_bIsActive = false;
35 // the increment we are using for the patch inspector (this is saved in the prefs)
36 texdef_t *l_pPIIncrement = &g_qeglobals.d_savedinfo.m_PIIncrement;
38 // =============================================================================
41 static void OnDone (GtkWidget *widget, gpointer data)
43 g_PatchDialog.m_Patch = NULL;
44 g_PatchDialog.HideDlg ();
47 // memorize the current state (that is don't try to undo our do before changing something else)
48 static void OnApply (GtkWidget *widget, gpointer data)
50 g_PatchDialog.UpdateData(TRUE);
51 if (g_PatchDialog.m_Patch != NULL)
53 int r = g_PatchDialog.m_nRow;
54 int c = g_PatchDialog.m_nCol;
55 if (r >= 0 && r < g_PatchDialog.m_Patch->height && c >= 0 && c < g_PatchDialog.m_Patch->width)
57 if (g_PatchDialog.m_Patch->pShader)
58 g_PatchDialog.m_Patch->pShader->DecRef();
59 if (g_PatchDialog.m_strName.Find(' ') >= 0)
61 Sys_FPrintf(SYS_WRN, "WARNING: spaces in shader names are not allowed, dropping '%s'\n", g_PatchDialog.m_strName.GetBuffer());
62 g_PatchDialog.m_strName = SHADER_NOT_FOUND;
64 g_PatchDialog.m_Patch->pShader = QERApp_Shader_ForName(g_PatchDialog.m_strName);
65 g_PatchDialog.m_Patch->d_texture = g_PatchDialog.m_Patch->pShader->getTexture();
66 g_PatchDialog.m_Patch->ctrl[c][r].xyz[0] = g_PatchDialog.m_fX;
67 g_PatchDialog.m_Patch->ctrl[c][r].xyz[1] = g_PatchDialog.m_fY;
68 g_PatchDialog.m_Patch->ctrl[c][r].xyz[2] = g_PatchDialog.m_fZ;
69 g_PatchDialog.m_Patch->ctrl[c][r].st[0] = g_PatchDialog.m_fS;
70 g_PatchDialog.m_Patch->ctrl[c][r].st[1] = g_PatchDialog.m_fT;
71 g_PatchDialog.m_Patch->bDirty = true;
72 Sys_UpdateWindows(W_ALL);
77 static void OnSelchangeComboColRow (GtkWidget *widget, gpointer data)
79 if (!g_PatchDialog.m_bListenChanged)
82 Sys_Printf("OnSelchangeComboColRow\n");
84 // retrieve the current m_nRow and m_nCol, other params are not relevant
85 // (NOTE: UpdateData has a mechanism to avoid inifinite looping)
86 g_PatchDialog.UpdateData(TRUE);
87 // read the changed values ourselves
88 g_PatchDialog.UpdateRowColInfo();
89 // now reflect our changes
90 g_PatchDialog.UpdateData(FALSE);
93 static void OnBtnPatchdetails (GtkWidget *widget, gpointer data)
95 Patch_NaturalizeSelected(true);
96 Sys_UpdateWindows(W_ALL);
99 static void OnBtnPatchfit (GtkWidget *widget, gpointer data)
101 Patch_ResetTexturing(1.0, 1.0);
102 Sys_UpdateWindows(W_ALL);
105 static void OnBtnPatchnatural (GtkWidget *widget, gpointer data)
107 Patch_NaturalizeSelected();
108 Sys_UpdateWindows(W_ALL);
111 static void OnBtnPatchreset (GtkWidget *widget, gpointer data)
114 if (DoTextureLayout (&fx, &fy) == IDOK)
116 Patch_ResetTexturing(fx, fy);
118 Sys_UpdateWindows(W_ALL);
121 static void OnSpinChanged (GtkAdjustment *adj, gpointer data)
126 td.scale[0] = td.scale[1] = 0;
127 td.shift[0] = td.shift[1] = 0;
135 if (adj == g_object_get_data (G_OBJECT (g_PatchDialog.GetWidget ()), "hshift_adj"))
137 l_pPIIncrement->shift[0] = atof (gtk_entry_get_text (GTK_ENTRY (data)));
140 td.shift[0] = l_pPIIncrement->shift[0];
142 td.shift[0] = -l_pPIIncrement->shift[0];
144 else if (adj == g_object_get_data (G_OBJECT (g_PatchDialog.GetWidget ()), "vshift_adj"))
146 l_pPIIncrement->shift[1] = atof (gtk_entry_get_text (GTK_ENTRY (data)));
149 td.shift[1] = l_pPIIncrement->shift[1];
151 td.shift[1] = -l_pPIIncrement->shift[1];
153 else if (adj == g_object_get_data (G_OBJECT (g_PatchDialog.GetWidget ()), "hscale_adj"))
155 l_pPIIncrement->scale[0] = atof (gtk_entry_get_text (GTK_ENTRY (data)));
156 if (l_pPIIncrement->scale[0] == 0.0f)
158 // make sure scale factor is always >1 for increases and <1 for decreases
161 if (l_pPIIncrement->scale[0] < 1)
162 td.scale[0] = l_pPIIncrement->scale[0];
164 td.scale[0] = 1.0f / l_pPIIncrement->scale[0];
168 if (l_pPIIncrement->scale[0] < 1)
169 td.scale[0] = 1.0f / l_pPIIncrement->scale[0];
171 td.scale[0] = l_pPIIncrement->scale[0];
174 else if (adj == g_object_get_data (G_OBJECT (g_PatchDialog.GetWidget ()), "vscale_adj"))
176 l_pPIIncrement->scale[1] = atof (gtk_entry_get_text (GTK_ENTRY (data)));
177 if (l_pPIIncrement->scale[1] == 0.0f)
179 // make sure scale factor is always >1 for increases and <1 for decreases
182 if (l_pPIIncrement->scale[1] < 1)
183 td.scale[1] = l_pPIIncrement->scale[1];
185 td.scale[1] = 1.0f / l_pPIIncrement->scale[1];
189 if (l_pPIIncrement->scale[1] < 1)
190 td.scale[1] = 1.0f / l_pPIIncrement->scale[1];
192 td.scale[1] = l_pPIIncrement->scale[1];
195 else if (adj == g_object_get_data (G_OBJECT (g_PatchDialog.GetWidget ()), "rotate_adj"))
197 l_pPIIncrement->rotate = atof (gtk_entry_get_text (GTK_ENTRY (data)));
200 td.rotate = l_pPIIncrement->rotate;
202 td.rotate = -l_pPIIncrement->rotate;
208 Sys_Printf("Patch_SetTextureInfo: %g %g %g %g %g\n", td.shift[0], td.shift[1],td.scale[0],td.scale[1],td.rotate );
210 // will scale shift rotate the patch accordingly
211 Patch_SetTextureInfo (&td);
212 // update the point-by-point view
213 OnSelchangeComboColRow(NULL,NULL);
214 Sys_UpdateWindows (W_CAMERA);
217 static gint OnDialogKey (GtkWidget* widget, GdkEventKey* event, gpointer data)
220 Sys_Printf("OnDialogKey\n");
222 if (event->keyval == GDK_Return)
224 OnApply (NULL, NULL);
227 else if (event->keyval == GDK_Escape)
235 // =============================================================================
238 void DoPatchInspector()
240 // do we need to create the dialog?
241 if (g_PatchDialog.GetWidget() == NULL)
243 g_PatchDialog.Create();
244 g_PatchDialog.UpdateData (FALSE);
246 g_PatchDialog.GetPatchInfo();
248 g_PatchDialog.ShowDlg ();
251 void UpdatePatchInspector()
254 g_PatchDialog.GetPatchInfo();
257 void TogglePatchInspector()
265 // =============================================================================
268 PatchDialog::PatchDialog ()
279 m_bListenChanged = true;
282 void PatchDialog::InitDefaultIncrement(texdef_t *tex)
284 tex->SetName(SHADER_NOT_FOUND);
285 tex->scale[0] = 0.5f;
286 tex->scale[1] = 0.5f;
288 tex->shift[0] = 8.0f;
289 tex->shift[1] = 8.0f;
292 // we plug into HideDlg and ShowDlg to maintain the l_bIsActive flag
293 void PatchDialog::HideDlg()
299 void PatchDialog::ShowDlg()
305 void PatchDialog::BuildDialog ()
307 GtkWidget *dlg, *vbox, *vbox2, *hbox, *hbox2, *frame, *table, *label;
308 GtkWidget *button, *entry, *spin, *combo;
314 load_window_pos (dlg, g_PrefsDlg.mWindowInfo.posPatchWnd);
316 gtk_window_set_title (GTK_WINDOW (dlg), "Patch Properties");
317 gtk_signal_connect (GTK_OBJECT (dlg), "delete_event", GTK_SIGNAL_FUNC (OnDone), NULL);
318 // catch 'Esc' and 'Enter'
319 gtk_signal_connect (GTK_OBJECT (dlg), "key_press_event", GTK_SIGNAL_FUNC (OnDialogKey), NULL);
320 gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (g_pParentWnd->m_pWidget));
323 vbox = gtk_vbox_new (FALSE, 5);
324 gtk_widget_show (vbox);
325 gtk_container_add (GTK_CONTAINER (dlg), vbox);
326 gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
328 hbox = gtk_hbox_new (FALSE, 5);
329 gtk_widget_show (hbox);
330 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
332 frame = gtk_frame_new ("Details");
333 gtk_widget_show (frame);
334 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
336 vbox2 = gtk_vbox_new (FALSE, 5);
337 gtk_widget_show (vbox2);
338 gtk_container_add (GTK_CONTAINER (frame), vbox2);
339 gtk_container_set_border_width (GTK_CONTAINER (vbox2), 5);
341 table = gtk_table_new (2, 2, FALSE);
342 gtk_widget_show (table);
343 gtk_box_pack_start (GTK_BOX (vbox2), table, TRUE, TRUE, 0);
344 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
345 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
347 label = gtk_label_new ("Row:");
348 gtk_widget_show (label);
349 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
350 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
351 (GtkAttachOptions) (0), 0, 0);
353 label = gtk_label_new ("Column:");
354 gtk_widget_show (label);
355 gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1,
356 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
357 (GtkAttachOptions) (0), 0, 0);
359 combo = gtk_combo_new ();
360 gtk_widget_show (combo);
361 gtk_table_attach (GTK_TABLE (table), combo, 0, 1, 1, 2,
362 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
363 (GtkAttachOptions) (0), 0, 0);
364 gtk_widget_set_usize (combo, 60, -1);
365 gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
366 gtk_signal_connect (GTK_OBJECT (GTK_COMBO (combo)->entry), "changed",
367 GTK_SIGNAL_FUNC (OnSelchangeComboColRow), this);
368 AddDialogData (combo, &m_nRow, DLG_COMBO_INT);
371 combo = gtk_combo_new ();
372 gtk_widget_show (combo);
373 gtk_table_attach (GTK_TABLE (table), combo, 1, 2, 1, 2,
374 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
375 (GtkAttachOptions) (0), 0, 0);
376 gtk_widget_set_usize (combo, 60, -1);
377 gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
378 gtk_signal_connect (GTK_OBJECT (GTK_COMBO (combo)->entry), "changed",
379 GTK_SIGNAL_FUNC (OnSelchangeComboColRow), this);
380 AddDialogData (combo, &m_nCol, DLG_COMBO_INT);
383 table = gtk_table_new (5, 2, FALSE);
384 gtk_widget_show (table);
385 gtk_box_pack_start (GTK_BOX (vbox2), table, TRUE, TRUE, 0);
386 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
387 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
389 label = gtk_label_new ("X:");
390 gtk_widget_show (label);
391 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
392 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
393 (GtkAttachOptions) (0), 0, 0);
395 label = gtk_label_new ("Y:");
396 gtk_widget_show (label);
397 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
398 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
399 (GtkAttachOptions) (0), 0, 0);
401 label = gtk_label_new ("Z:");
402 gtk_widget_show (label);
403 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
404 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
405 (GtkAttachOptions) (0), 0, 0);
407 label = gtk_label_new ("S:");
408 gtk_widget_show (label);
409 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,
410 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
411 (GtkAttachOptions) (0), 0, 0);
413 label = gtk_label_new ("T:");
414 gtk_widget_show (label);
415 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5,
416 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
417 (GtkAttachOptions) (0), 0, 0);
419 entry = gtk_entry_new ();
420 gtk_widget_show (entry);
421 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
422 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
423 (GtkAttachOptions) (0), 0, 0);
424 AddDialogData (entry, &m_fX, DLG_ENTRY_FLOAT);
426 entry = gtk_entry_new ();
427 gtk_widget_show (entry);
428 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2,
429 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
430 (GtkAttachOptions) (0), 0, 0);
431 AddDialogData (entry, &m_fY, DLG_ENTRY_FLOAT);
433 entry = gtk_entry_new ();
434 gtk_widget_show (entry);
435 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 2, 3,
436 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
437 (GtkAttachOptions) (0), 0, 0);
438 AddDialogData (entry, &m_fZ, DLG_ENTRY_FLOAT);
440 entry = gtk_entry_new ();
441 gtk_widget_show (entry);
442 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 3, 4,
443 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
444 (GtkAttachOptions) (0), 0, 0);
445 AddDialogData (entry, &m_fS, DLG_ENTRY_FLOAT);
447 entry = gtk_entry_new ();
448 gtk_widget_show (entry);
449 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 4, 5,
450 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
451 (GtkAttachOptions) (0), 0, 0);
452 AddDialogData (entry, &m_fT, DLG_ENTRY_FLOAT);
454 frame = gtk_frame_new ("Texturing");
455 gtk_widget_show (frame);
456 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
458 vbox2 = gtk_vbox_new (FALSE, 5);
459 gtk_widget_show (vbox2);
460 gtk_container_add (GTK_CONTAINER (frame), vbox2);
461 gtk_container_set_border_width (GTK_CONTAINER (vbox2), 5);
463 label = gtk_label_new ("Name:");
464 gtk_widget_show (label);
465 gtk_box_pack_start (GTK_BOX (vbox2), label, TRUE, TRUE, 0);
466 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
467 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
469 entry = gtk_entry_new ();
470 // gtk_entry_set_editable (GTK_ENTRY (entry), false);
471 gtk_widget_show (entry);
472 gtk_box_pack_start (GTK_BOX (vbox2), entry, TRUE, TRUE, 0);
473 AddDialogData (entry, &m_strName, DLG_ENTRY_TEXT);
475 table = gtk_table_new (5, 3, FALSE);
476 gtk_widget_show (table);
477 gtk_box_pack_start (GTK_BOX (vbox2), table, TRUE, TRUE, 0);
478 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
479 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
481 label = gtk_label_new ("Horizontal Shift Step");
482 gtk_widget_show (label);
483 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
484 (GtkAttachOptions) (GTK_FILL),
485 (GtkAttachOptions) (0), 0, 0);
486 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
488 label = gtk_label_new ("Vertical Shift Step");
489 gtk_widget_show (label);
490 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 1, 2,
491 (GtkAttachOptions) (GTK_FILL),
492 (GtkAttachOptions) (0), 0, 0);
493 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
495 label = gtk_label_new ("Horizontal Stretch Step");
496 gtk_widget_show (label);
497 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 2, 3,
498 (GtkAttachOptions) (GTK_FILL),
499 (GtkAttachOptions) (0), 0, 0);
500 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
502 label = gtk_label_new ("Vertical Stretch Step");
503 gtk_widget_show (label);
504 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 3, 4,
505 (GtkAttachOptions) (GTK_FILL),
506 (GtkAttachOptions) (0), 0, 0);
507 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
509 label = gtk_label_new ("Rotate Step");
510 gtk_widget_show (label);
511 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 4, 5,
512 (GtkAttachOptions) (GTK_FILL),
513 (GtkAttachOptions) (0), 0, 0);
514 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
516 entry = gtk_entry_new ();
517 gtk_widget_show (entry);
518 gtk_table_attach (GTK_TABLE (table), entry, 0, 1, 0, 1,
519 (GtkAttachOptions) (GTK_FILL),
520 (GtkAttachOptions) (0), 0, 0);
521 gtk_widget_set_usize (entry, 50, -2);
522 g_object_set_data (G_OBJECT (m_pWidget), "hshift_entry", entry);
523 // we fill in this data, if no patch is selected the widgets are unmodified when the inspector is raised
524 // so we need to have at least one initialisation somewhere
525 sprintf (buf, "%g", l_pPIIncrement->shift[0]);
526 gtk_entry_set_text (GTK_ENTRY (entry), buf);
528 adj = gtk_adjustment_new (0, -8192, 8192, 1, 1, 1);
529 gtk_signal_connect (adj, "value_changed", GTK_SIGNAL_FUNC (OnSpinChanged), entry);
530 g_object_set_data (G_OBJECT (m_pWidget), "hshift_adj", adj);
532 spin = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
533 gtk_widget_show (spin);
534 gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 0, 1,
535 (GtkAttachOptions) (0),
536 (GtkAttachOptions) (0), 0, 0);
537 gtk_widget_set_usize (spin, 10, -2);
539 entry = gtk_entry_new ();
540 gtk_widget_show (entry);
541 gtk_table_attach (GTK_TABLE (table), entry, 0, 1, 1, 2,
542 (GtkAttachOptions) (GTK_FILL),
543 (GtkAttachOptions) (0), 0, 0);
544 gtk_widget_set_usize (entry, 50, -2);
545 sprintf (buf, "%g", l_pPIIncrement->shift[1]);
546 gtk_entry_set_text (GTK_ENTRY (entry), buf);
548 adj = gtk_adjustment_new (0, -8192, 8192, 1, 1, 1);
549 gtk_signal_connect (adj, "value_changed", GTK_SIGNAL_FUNC (OnSpinChanged), entry);
550 g_object_set_data (G_OBJECT (m_pWidget), "vshift_adj", adj);
552 spin = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
553 gtk_widget_show (spin);
554 gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 1, 2,
555 (GtkAttachOptions) (0),
556 (GtkAttachOptions) (0), 0, 0);
557 gtk_widget_set_usize (spin, 10, -2);
559 entry = gtk_entry_new ();
560 gtk_widget_show (entry);
561 gtk_table_attach (GTK_TABLE (table), entry, 0, 1, 2, 3,
562 (GtkAttachOptions) (GTK_FILL),
563 (GtkAttachOptions) (0), 0, 0);
564 gtk_widget_set_usize (entry, 50, -2);
565 sprintf (buf, "%g", l_pPIIncrement->scale[0]);
566 gtk_entry_set_text (GTK_ENTRY (entry), buf);
568 adj = gtk_adjustment_new (0, -1000, 1000, 1, 1, 1);
569 gtk_signal_connect (adj, "value_changed", GTK_SIGNAL_FUNC (OnSpinChanged), entry);
570 g_object_set_data (G_OBJECT (m_pWidget), "hscale_adj", adj);
572 spin = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
573 gtk_widget_show (spin);
574 gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 2, 3,
575 (GtkAttachOptions) (0),
576 (GtkAttachOptions) (0), 0, 0);
577 gtk_widget_set_usize (spin, 10, -2);
579 entry = gtk_entry_new ();
580 gtk_widget_show (entry);
581 gtk_table_attach (GTK_TABLE (table), entry, 0, 1, 3, 4,
582 (GtkAttachOptions) (GTK_FILL),
583 (GtkAttachOptions) (0), 0, 0);
584 gtk_widget_set_usize (entry, 50, -2);
585 sprintf (buf, "%g", l_pPIIncrement->scale[1]);
586 gtk_entry_set_text (GTK_ENTRY (entry), buf);
588 adj = gtk_adjustment_new (0, -1000, 1000, 1, 1, 1);
589 gtk_signal_connect (adj, "value_changed", GTK_SIGNAL_FUNC (OnSpinChanged), entry);
590 g_object_set_data (G_OBJECT (m_pWidget), "vscale_adj", adj);
592 spin = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
593 gtk_widget_show (spin);
594 gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 3, 4,
595 (GtkAttachOptions) (0),
596 (GtkAttachOptions) (0), 0, 0);
597 gtk_widget_set_usize (spin, 10, -2);
599 entry = gtk_entry_new ();
600 gtk_widget_show (entry);
601 gtk_table_attach (GTK_TABLE (table), entry, 0, 1, 4, 5,
602 (GtkAttachOptions) (GTK_FILL),
603 (GtkAttachOptions) (0), 0, 0);
604 gtk_widget_set_usize (entry, 50, -2);
605 sprintf (buf, "%g", l_pPIIncrement->rotate);
606 gtk_entry_set_text (GTK_ENTRY (entry), buf);
608 adj = gtk_adjustment_new (0, -1000, 1000, 1, 1, 1); // NOTE: Arnout - this really should be 360 but can't change it anymore as it could break existing maps
609 gtk_signal_connect (adj, "value_changed", GTK_SIGNAL_FUNC (OnSpinChanged), entry);
610 g_object_set_data (G_OBJECT (m_pWidget), "rotate_adj", adj);
612 spin = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
613 gtk_widget_show (spin);
614 gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 4, 5,
615 (GtkAttachOptions) (0),
616 (GtkAttachOptions) (0), 0, 0);
617 gtk_widget_set_usize (spin, 10, -2);
619 hbox2 = gtk_hbox_new (TRUE, 5);
620 gtk_widget_show (hbox2);
621 gtk_box_pack_start (GTK_BOX (vbox2), hbox2, TRUE, FALSE, 0);
623 button = gtk_button_new_with_label ("CAP");
624 gtk_widget_show (button);
625 gtk_box_pack_end (GTK_BOX (hbox2), button, TRUE, FALSE, 0);
626 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnPatchdetails), NULL);
627 gtk_widget_set_usize (button, 60, -1);
629 button = gtk_button_new_with_label ("Set...");
630 gtk_widget_show (button);
631 gtk_box_pack_end (GTK_BOX (hbox2), button, TRUE, FALSE, 0);
632 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnPatchreset), NULL);
633 gtk_widget_set_usize (button, 60, -1);
635 button = gtk_button_new_with_label ("Natural");
636 gtk_widget_show (button);
637 gtk_box_pack_end (GTK_BOX (hbox2), button, TRUE, FALSE, 0);
638 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnPatchnatural), NULL);
639 gtk_widget_set_usize (button, 60, -1);
641 button = gtk_button_new_with_label ("Fit");
642 gtk_widget_show (button);
643 gtk_box_pack_end (GTK_BOX (hbox2), button, TRUE, FALSE, 0);
644 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnPatchfit), NULL);
645 gtk_widget_set_usize (button, 60, -1);
647 hbox = gtk_hbox_new (FALSE, 5);
648 gtk_widget_show (hbox);
649 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, FALSE, 0);
651 button = gtk_button_new_with_label ("Done");
652 gtk_widget_show (button);
653 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
654 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnDone), NULL);
655 gtk_widget_set_usize (button, 60, -1);
657 button = gtk_button_new_with_label ("Apply");
658 gtk_widget_show (button);
659 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
660 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnApply), NULL);
661 gtk_widget_set_usize (button, 60, -1);
664 // sync the dialog our internal data structures
665 void PatchDialog::UpdateData (bool retrieve)
667 if (m_pWidget == NULL)
670 m_bListenChanged = false;
671 Dialog::UpdateData (retrieve);
672 m_bListenChanged = true;
675 // read the map and feed in the stuff to the dialog box
676 void PatchDialog::GetPatchInfo()
678 m_Patch = SinglePatchSelected();
681 m_strName = m_Patch->pShader->getName();
683 GList *combo_list = NULL;
686 // fill in the numbers for Row / Col selection
687 m_bListenChanged = false;
689 for (i = 0; i < m_Patch->height; i++)
690 combo_list = g_list_append (combo_list, g_strdup_printf ("%i", i)); // NOTE: leaving the g_strdup cause we free with g_free later on
691 gtk_combo_set_popdown_strings (GTK_COMBO (m_pRowCombo), combo_list);
692 gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (m_pRowCombo)->entry), "0");
696 g_free (combo_list->data);
697 combo_list = g_list_remove (combo_list, combo_list->data);
700 for (i = 0; i < m_Patch->width; i++)
701 combo_list = g_list_append (combo_list, g_strdup_printf ("%i", i));
702 gtk_combo_set_popdown_strings (GTK_COMBO (m_pColCombo), combo_list);
703 gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (m_pColCombo)->entry), "0");
707 g_free (combo_list->data);
708 combo_list = g_list_remove (combo_list, combo_list->data);
711 m_bListenChanged = true;
715 Sys_Printf("WARNING: no patch\n");
716 // fill in our internal structs
717 m_nRow = 0; m_nCol = 0;
719 // now update the dialog box
723 // read the current patch on map and initialize m_fX m_fY accordingly
724 // NOTE: don't call UpdateData in there, it's not meant for
725 void PatchDialog::UpdateRowColInfo()
727 m_fX = m_fY = m_fZ = m_fS = m_fT = 0.0;
731 // we rely on whatever active row/column has been set before we get called
734 if (r >= 0 && r < m_Patch->height && c >= 0 && c < m_Patch->width)
736 m_fX = m_Patch->ctrl[c][r].xyz[0];
737 m_fY = m_Patch->ctrl[c][r].xyz[1];
738 m_fZ = m_Patch->ctrl[c][r].xyz[2];
739 m_fS = m_Patch->ctrl[c][r].st[0];
740 m_fT = m_Patch->ctrl[c][r].st[1];