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 // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=467
60 if (g_PatchDialog.m_strName.Find(' ') >= 0)
62 Sys_FPrintf(SYS_WRN, "WARNING: spaces in shader names are not allowed, dropping '%s'\n", g_PatchDialog.m_strName.GetBuffer());
63 g_PatchDialog.m_strName = SHADER_NOT_FOUND;
65 g_PatchDialog.m_Patch->pShader = QERApp_Shader_ForName(g_PatchDialog.m_strName);
66 g_PatchDialog.m_Patch->d_texture = g_PatchDialog.m_Patch->pShader->getTexture();
67 g_PatchDialog.m_Patch->ctrl[c][r].xyz[0] = g_PatchDialog.m_fX;
68 g_PatchDialog.m_Patch->ctrl[c][r].xyz[1] = g_PatchDialog.m_fY;
69 g_PatchDialog.m_Patch->ctrl[c][r].xyz[2] = g_PatchDialog.m_fZ;
70 g_PatchDialog.m_Patch->ctrl[c][r].st[0] = g_PatchDialog.m_fS;
71 g_PatchDialog.m_Patch->ctrl[c][r].st[1] = g_PatchDialog.m_fT;
72 g_PatchDialog.m_Patch->bDirty = true;
73 Sys_UpdateWindows(W_ALL);
78 static void OnSelchangeComboColRow (GtkWidget *widget, gpointer data)
80 if (!g_PatchDialog.m_bListenChanged)
83 Sys_Printf("OnSelchangeComboColRow\n");
85 // retrieve the current m_nRow and m_nCol, other params are not relevant
86 // (NOTE: UpdateData has a mechanism to avoid inifinite looping)
87 g_PatchDialog.UpdateData(TRUE);
88 // read the changed values ourselves
89 g_PatchDialog.UpdateRowColInfo();
90 // now reflect our changes
91 g_PatchDialog.UpdateData(FALSE);
94 static void OnBtnPatchdetails (GtkWidget *widget, gpointer data)
96 Patch_NaturalizeSelected(true);
97 Sys_UpdateWindows(W_ALL);
100 static void OnBtnPatchfit (GtkWidget *widget, gpointer data)
102 Patch_ResetTexturing(1.0, 1.0);
103 Sys_UpdateWindows(W_ALL);
106 static void OnBtnPatchnatural (GtkWidget *widget, gpointer data)
108 Patch_NaturalizeSelected();
109 Sys_UpdateWindows(W_ALL);
112 static void OnBtnPatchreset (GtkWidget *widget, gpointer data)
115 if (DoTextureLayout (&fx, &fy) == IDOK)
117 Patch_ResetTexturing(fx, fy);
119 Sys_UpdateWindows(W_ALL);
122 static void OnSpinChanged (GtkAdjustment *adj, gpointer data)
127 td.scale[0] = td.scale[1] = 0;
128 td.shift[0] = td.shift[1] = 0;
136 if (adj == g_object_get_data (G_OBJECT (g_PatchDialog.GetWidget ()), "hshift_adj"))
138 l_pPIIncrement->shift[0] = atof (gtk_entry_get_text (GTK_ENTRY (data)));
141 td.shift[0] = l_pPIIncrement->shift[0];
143 td.shift[0] = -l_pPIIncrement->shift[0];
145 else if (adj == g_object_get_data (G_OBJECT (g_PatchDialog.GetWidget ()), "vshift_adj"))
147 l_pPIIncrement->shift[1] = atof (gtk_entry_get_text (GTK_ENTRY (data)));
150 td.shift[1] = l_pPIIncrement->shift[1];
152 td.shift[1] = -l_pPIIncrement->shift[1];
154 else if (adj == g_object_get_data (G_OBJECT (g_PatchDialog.GetWidget ()), "hscale_adj"))
156 l_pPIIncrement->scale[0] = atof (gtk_entry_get_text (GTK_ENTRY (data)));
157 if (l_pPIIncrement->scale[0] == 0.0f)
159 // make sure scale factor is always >1 for increases and <1 for decreases
162 if (l_pPIIncrement->scale[0] < 1)
163 td.scale[0] = l_pPIIncrement->scale[0];
165 td.scale[0] = 1.0f / l_pPIIncrement->scale[0];
169 if (l_pPIIncrement->scale[0] < 1)
170 td.scale[0] = 1.0f / l_pPIIncrement->scale[0];
172 td.scale[0] = l_pPIIncrement->scale[0];
175 else if (adj == g_object_get_data (G_OBJECT (g_PatchDialog.GetWidget ()), "vscale_adj"))
177 l_pPIIncrement->scale[1] = atof (gtk_entry_get_text (GTK_ENTRY (data)));
178 if (l_pPIIncrement->scale[1] == 0.0f)
180 // make sure scale factor is always >1 for increases and <1 for decreases
183 if (l_pPIIncrement->scale[1] < 1)
184 td.scale[1] = l_pPIIncrement->scale[1];
186 td.scale[1] = 1.0f / l_pPIIncrement->scale[1];
190 if (l_pPIIncrement->scale[1] < 1)
191 td.scale[1] = 1.0f / l_pPIIncrement->scale[1];
193 td.scale[1] = l_pPIIncrement->scale[1];
196 else if (adj == g_object_get_data (G_OBJECT (g_PatchDialog.GetWidget ()), "rotate_adj"))
198 l_pPIIncrement->rotate = atof (gtk_entry_get_text (GTK_ENTRY (data)));
201 td.rotate = l_pPIIncrement->rotate;
203 td.rotate = -l_pPIIncrement->rotate;
209 Sys_Printf("Patch_SetTextureInfo: %g %g %g %g %g\n", td.shift[0], td.shift[1],td.scale[0],td.scale[1],td.rotate );
211 // will scale shift rotate the patch accordingly
212 Patch_SetTextureInfo (&td);
213 // update the point-by-point view
214 OnSelchangeComboColRow(NULL,NULL);
215 Sys_UpdateWindows (W_CAMERA);
218 static gint OnDialogKey (GtkWidget* widget, GdkEventKey* event, gpointer data)
221 Sys_Printf("OnDialogKey\n");
223 if (event->keyval == GDK_Return)
225 OnApply (NULL, NULL);
228 else if (event->keyval == GDK_Escape)
236 // =============================================================================
239 void DoPatchInspector()
241 // do we need to create the dialog?
242 if (g_PatchDialog.GetWidget() == NULL)
244 g_PatchDialog.Create();
245 g_PatchDialog.UpdateData (FALSE);
247 g_PatchDialog.GetPatchInfo();
249 g_PatchDialog.ShowDlg ();
252 void UpdatePatchInspector()
255 g_PatchDialog.GetPatchInfo();
258 void TogglePatchInspector()
266 // =============================================================================
269 PatchDialog::PatchDialog ()
280 m_bListenChanged = true;
283 void PatchDialog::InitDefaultIncrement(texdef_t *tex)
285 tex->SetName(SHADER_NOT_FOUND);
286 tex->scale[0] = 0.5f;
287 tex->scale[1] = 0.5f;
289 tex->shift[0] = 8.0f;
290 tex->shift[1] = 8.0f;
293 // we plug into HideDlg and ShowDlg to maintain the l_bIsActive flag
294 void PatchDialog::HideDlg()
300 void PatchDialog::ShowDlg()
306 void PatchDialog::BuildDialog ()
308 GtkWidget *dlg, *vbox, *vbox2, *hbox, *hbox2, *frame, *table, *label;
309 GtkWidget *button, *entry, *spin, *combo;
315 load_window_pos (dlg, g_PrefsDlg.mWindowInfo.posPatchWnd);
317 gtk_window_set_title (GTK_WINDOW (dlg), "Patch Properties");
318 gtk_signal_connect (GTK_OBJECT (dlg), "delete_event", GTK_SIGNAL_FUNC (OnDone), NULL);
319 // catch 'Esc' and 'Enter'
320 gtk_signal_connect (GTK_OBJECT (dlg), "key_press_event", GTK_SIGNAL_FUNC (OnDialogKey), NULL);
321 gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (g_pParentWnd->m_pWidget));
324 vbox = gtk_vbox_new (FALSE, 5);
325 gtk_widget_show (vbox);
326 gtk_container_add (GTK_CONTAINER (dlg), vbox);
327 gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
329 hbox = gtk_hbox_new (FALSE, 5);
330 gtk_widget_show (hbox);
331 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
333 frame = gtk_frame_new ("Details");
334 gtk_widget_show (frame);
335 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
337 vbox2 = gtk_vbox_new (FALSE, 5);
338 gtk_widget_show (vbox2);
339 gtk_container_add (GTK_CONTAINER (frame), vbox2);
340 gtk_container_set_border_width (GTK_CONTAINER (vbox2), 5);
342 table = gtk_table_new (2, 2, FALSE);
343 gtk_widget_show (table);
344 gtk_box_pack_start (GTK_BOX (vbox2), table, TRUE, TRUE, 0);
345 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
346 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
348 label = gtk_label_new ("Row:");
349 gtk_widget_show (label);
350 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
351 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
352 (GtkAttachOptions) (0), 0, 0);
354 label = gtk_label_new ("Column:");
355 gtk_widget_show (label);
356 gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1,
357 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
358 (GtkAttachOptions) (0), 0, 0);
360 combo = gtk_combo_new ();
361 gtk_widget_show (combo);
362 gtk_table_attach (GTK_TABLE (table), combo, 0, 1, 1, 2,
363 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
364 (GtkAttachOptions) (0), 0, 0);
365 gtk_widget_set_usize (combo, 60, -1);
366 gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
367 gtk_signal_connect (GTK_OBJECT (GTK_COMBO (combo)->entry), "changed",
368 GTK_SIGNAL_FUNC (OnSelchangeComboColRow), this);
369 AddDialogData (combo, &m_nRow, DLG_COMBO_INT);
372 combo = gtk_combo_new ();
373 gtk_widget_show (combo);
374 gtk_table_attach (GTK_TABLE (table), combo, 1, 2, 1, 2,
375 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
376 (GtkAttachOptions) (0), 0, 0);
377 gtk_widget_set_usize (combo, 60, -1);
378 gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
379 gtk_signal_connect (GTK_OBJECT (GTK_COMBO (combo)->entry), "changed",
380 GTK_SIGNAL_FUNC (OnSelchangeComboColRow), this);
381 AddDialogData (combo, &m_nCol, DLG_COMBO_INT);
384 table = gtk_table_new (5, 2, FALSE);
385 gtk_widget_show (table);
386 gtk_box_pack_start (GTK_BOX (vbox2), table, TRUE, TRUE, 0);
387 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
388 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
390 label = gtk_label_new ("X:");
391 gtk_widget_show (label);
392 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
393 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
394 (GtkAttachOptions) (0), 0, 0);
396 label = gtk_label_new ("Y:");
397 gtk_widget_show (label);
398 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
399 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
400 (GtkAttachOptions) (0), 0, 0);
402 label = gtk_label_new ("Z:");
403 gtk_widget_show (label);
404 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
405 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
406 (GtkAttachOptions) (0), 0, 0);
408 label = gtk_label_new ("S:");
409 gtk_widget_show (label);
410 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,
411 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
412 (GtkAttachOptions) (0), 0, 0);
414 label = gtk_label_new ("T:");
415 gtk_widget_show (label);
416 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5,
417 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
418 (GtkAttachOptions) (0), 0, 0);
420 entry = gtk_entry_new ();
421 gtk_widget_show (entry);
422 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
423 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
424 (GtkAttachOptions) (0), 0, 0);
425 AddDialogData (entry, &m_fX, DLG_ENTRY_FLOAT);
427 entry = gtk_entry_new ();
428 gtk_widget_show (entry);
429 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2,
430 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
431 (GtkAttachOptions) (0), 0, 0);
432 AddDialogData (entry, &m_fY, DLG_ENTRY_FLOAT);
434 entry = gtk_entry_new ();
435 gtk_widget_show (entry);
436 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 2, 3,
437 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
438 (GtkAttachOptions) (0), 0, 0);
439 AddDialogData (entry, &m_fZ, DLG_ENTRY_FLOAT);
441 entry = gtk_entry_new ();
442 gtk_widget_show (entry);
443 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 3, 4,
444 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
445 (GtkAttachOptions) (0), 0, 0);
446 AddDialogData (entry, &m_fS, DLG_ENTRY_FLOAT);
448 entry = gtk_entry_new ();
449 gtk_widget_show (entry);
450 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 4, 5,
451 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
452 (GtkAttachOptions) (0), 0, 0);
453 AddDialogData (entry, &m_fT, DLG_ENTRY_FLOAT);
455 frame = gtk_frame_new ("Texturing");
456 gtk_widget_show (frame);
457 gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
459 vbox2 = gtk_vbox_new (FALSE, 5);
460 gtk_widget_show (vbox2);
461 gtk_container_add (GTK_CONTAINER (frame), vbox2);
462 gtk_container_set_border_width (GTK_CONTAINER (vbox2), 5);
464 label = gtk_label_new ("Name:");
465 gtk_widget_show (label);
466 gtk_box_pack_start (GTK_BOX (vbox2), label, TRUE, TRUE, 0);
467 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
468 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
470 entry = gtk_entry_new ();
471 // gtk_entry_set_editable (GTK_ENTRY (entry), false);
472 gtk_widget_show (entry);
473 gtk_box_pack_start (GTK_BOX (vbox2), entry, TRUE, TRUE, 0);
474 AddDialogData (entry, &m_strName, DLG_ENTRY_TEXT);
476 table = gtk_table_new (5, 3, FALSE);
477 gtk_widget_show (table);
478 gtk_box_pack_start (GTK_BOX (vbox2), table, TRUE, TRUE, 0);
479 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
480 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
482 label = gtk_label_new ("Horizontal Shift Step");
483 gtk_widget_show (label);
484 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
485 (GtkAttachOptions) (GTK_FILL),
486 (GtkAttachOptions) (0), 0, 0);
487 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
489 label = gtk_label_new ("Vertical Shift Step");
490 gtk_widget_show (label);
491 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 1, 2,
492 (GtkAttachOptions) (GTK_FILL),
493 (GtkAttachOptions) (0), 0, 0);
494 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
496 label = gtk_label_new ("Horizontal Stretch Step");
497 gtk_widget_show (label);
498 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 2, 3,
499 (GtkAttachOptions) (GTK_FILL),
500 (GtkAttachOptions) (0), 0, 0);
501 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
503 label = gtk_label_new ("Vertical Stretch Step");
504 gtk_widget_show (label);
505 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 3, 4,
506 (GtkAttachOptions) (GTK_FILL),
507 (GtkAttachOptions) (0), 0, 0);
508 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
510 label = gtk_label_new ("Rotate Step");
511 gtk_widget_show (label);
512 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 4, 5,
513 (GtkAttachOptions) (GTK_FILL),
514 (GtkAttachOptions) (0), 0, 0);
515 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
517 entry = gtk_entry_new ();
518 gtk_widget_show (entry);
519 gtk_table_attach (GTK_TABLE (table), entry, 0, 1, 0, 1,
520 (GtkAttachOptions) (GTK_FILL),
521 (GtkAttachOptions) (0), 0, 0);
522 gtk_widget_set_usize (entry, 50, -2);
523 g_object_set_data (G_OBJECT (m_pWidget), "hshift_entry", entry);
524 // we fill in this data, if no patch is selected the widgets are unmodified when the inspector is raised
525 // so we need to have at least one initialisation somewhere
526 sprintf (buf, "%g", l_pPIIncrement->shift[0]);
527 gtk_entry_set_text (GTK_ENTRY (entry), buf);
529 adj = gtk_adjustment_new (0, -8192, 8192, 1, 1, 1);
530 gtk_signal_connect (adj, "value_changed", GTK_SIGNAL_FUNC (OnSpinChanged), entry);
531 g_object_set_data (G_OBJECT (m_pWidget), "hshift_adj", adj);
533 spin = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
534 gtk_widget_show (spin);
535 gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 0, 1,
536 (GtkAttachOptions) (0),
537 (GtkAttachOptions) (0), 0, 0);
538 gtk_widget_set_usize (spin, 10, -2);
540 entry = gtk_entry_new ();
541 gtk_widget_show (entry);
542 gtk_table_attach (GTK_TABLE (table), entry, 0, 1, 1, 2,
543 (GtkAttachOptions) (GTK_FILL),
544 (GtkAttachOptions) (0), 0, 0);
545 gtk_widget_set_usize (entry, 50, -2);
546 sprintf (buf, "%g", l_pPIIncrement->shift[1]);
547 gtk_entry_set_text (GTK_ENTRY (entry), buf);
549 adj = gtk_adjustment_new (0, -8192, 8192, 1, 1, 1);
550 gtk_signal_connect (adj, "value_changed", GTK_SIGNAL_FUNC (OnSpinChanged), entry);
551 g_object_set_data (G_OBJECT (m_pWidget), "vshift_adj", adj);
553 spin = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
554 gtk_widget_show (spin);
555 gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 1, 2,
556 (GtkAttachOptions) (0),
557 (GtkAttachOptions) (0), 0, 0);
558 gtk_widget_set_usize (spin, 10, -2);
560 entry = gtk_entry_new ();
561 gtk_widget_show (entry);
562 gtk_table_attach (GTK_TABLE (table), entry, 0, 1, 2, 3,
563 (GtkAttachOptions) (GTK_FILL),
564 (GtkAttachOptions) (0), 0, 0);
565 gtk_widget_set_usize (entry, 50, -2);
566 sprintf (buf, "%g", l_pPIIncrement->scale[0]);
567 gtk_entry_set_text (GTK_ENTRY (entry), buf);
569 adj = gtk_adjustment_new (0, -1000, 1000, 1, 1, 1);
570 gtk_signal_connect (adj, "value_changed", GTK_SIGNAL_FUNC (OnSpinChanged), entry);
571 g_object_set_data (G_OBJECT (m_pWidget), "hscale_adj", adj);
573 spin = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
574 gtk_widget_show (spin);
575 gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 2, 3,
576 (GtkAttachOptions) (0),
577 (GtkAttachOptions) (0), 0, 0);
578 gtk_widget_set_usize (spin, 10, -2);
580 entry = gtk_entry_new ();
581 gtk_widget_show (entry);
582 gtk_table_attach (GTK_TABLE (table), entry, 0, 1, 3, 4,
583 (GtkAttachOptions) (GTK_FILL),
584 (GtkAttachOptions) (0), 0, 0);
585 gtk_widget_set_usize (entry, 50, -2);
586 sprintf (buf, "%g", l_pPIIncrement->scale[1]);
587 gtk_entry_set_text (GTK_ENTRY (entry), buf);
589 adj = gtk_adjustment_new (0, -1000, 1000, 1, 1, 1);
590 gtk_signal_connect (adj, "value_changed", GTK_SIGNAL_FUNC (OnSpinChanged), entry);
591 g_object_set_data (G_OBJECT (m_pWidget), "vscale_adj", adj);
593 spin = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
594 gtk_widget_show (spin);
595 gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 3, 4,
596 (GtkAttachOptions) (0),
597 (GtkAttachOptions) (0), 0, 0);
598 gtk_widget_set_usize (spin, 10, -2);
600 entry = gtk_entry_new ();
601 gtk_widget_show (entry);
602 gtk_table_attach (GTK_TABLE (table), entry, 0, 1, 4, 5,
603 (GtkAttachOptions) (GTK_FILL),
604 (GtkAttachOptions) (0), 0, 0);
605 gtk_widget_set_usize (entry, 50, -2);
606 sprintf (buf, "%g", l_pPIIncrement->rotate);
607 gtk_entry_set_text (GTK_ENTRY (entry), buf);
609 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
610 gtk_signal_connect (adj, "value_changed", GTK_SIGNAL_FUNC (OnSpinChanged), entry);
611 g_object_set_data (G_OBJECT (m_pWidget), "rotate_adj", adj);
613 spin = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
614 gtk_widget_show (spin);
615 gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 4, 5,
616 (GtkAttachOptions) (0),
617 (GtkAttachOptions) (0), 0, 0);
618 gtk_widget_set_usize (spin, 10, -2);
620 hbox2 = gtk_hbox_new (TRUE, 5);
621 gtk_widget_show (hbox2);
622 gtk_box_pack_start (GTK_BOX (vbox2), hbox2, TRUE, FALSE, 0);
624 button = gtk_button_new_with_label ("CAP");
625 gtk_widget_show (button);
626 gtk_box_pack_end (GTK_BOX (hbox2), button, TRUE, FALSE, 0);
627 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnPatchdetails), NULL);
628 gtk_widget_set_usize (button, 60, -1);
630 button = gtk_button_new_with_label ("Set...");
631 gtk_widget_show (button);
632 gtk_box_pack_end (GTK_BOX (hbox2), button, TRUE, FALSE, 0);
633 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnPatchreset), NULL);
634 gtk_widget_set_usize (button, 60, -1);
636 button = gtk_button_new_with_label ("Natural");
637 gtk_widget_show (button);
638 gtk_box_pack_end (GTK_BOX (hbox2), button, TRUE, FALSE, 0);
639 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnPatchnatural), NULL);
640 gtk_widget_set_usize (button, 60, -1);
642 button = gtk_button_new_with_label ("Fit");
643 gtk_widget_show (button);
644 gtk_box_pack_end (GTK_BOX (hbox2), button, TRUE, FALSE, 0);
645 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnPatchfit), NULL);
646 gtk_widget_set_usize (button, 60, -1);
648 hbox = gtk_hbox_new (FALSE, 5);
649 gtk_widget_show (hbox);
650 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, FALSE, 0);
652 button = gtk_button_new_with_label ("Done");
653 gtk_widget_show (button);
654 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
655 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnDone), NULL);
656 gtk_widget_set_usize (button, 60, -1);
658 button = gtk_button_new_with_label ("Apply");
659 gtk_widget_show (button);
660 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
661 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnApply), NULL);
662 gtk_widget_set_usize (button, 60, -1);
665 // sync the dialog our internal data structures
666 void PatchDialog::UpdateData (bool retrieve)
668 if (m_pWidget == NULL)
671 m_bListenChanged = false;
672 Dialog::UpdateData (retrieve);
673 m_bListenChanged = true;
676 // read the map and feed in the stuff to the dialog box
677 void PatchDialog::GetPatchInfo()
679 m_Patch = SinglePatchSelected();
682 m_strName = m_Patch->pShader->getName();
684 GList *combo_list = NULL;
687 // fill in the numbers for Row / Col selection
688 m_bListenChanged = false;
690 for (i = 0; i < m_Patch->height; i++)
691 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
692 gtk_combo_set_popdown_strings (GTK_COMBO (m_pRowCombo), combo_list);
693 gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (m_pRowCombo)->entry), "0");
697 g_free (combo_list->data);
698 combo_list = g_list_remove (combo_list, combo_list->data);
701 for (i = 0; i < m_Patch->width; i++)
702 combo_list = g_list_append (combo_list, g_strdup_printf ("%i", i));
703 gtk_combo_set_popdown_strings (GTK_COMBO (m_pColCombo), combo_list);
704 gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (m_pColCombo)->entry), "0");
708 g_free (combo_list->data);
709 combo_list = g_list_remove (combo_list, combo_list->data);
712 m_bListenChanged = true;
716 Sys_Printf("WARNING: no patch\n");
717 // fill in our internal structs
718 m_nRow = 0; m_nCol = 0;
720 // now update the dialog box
724 // read the current patch on map and initialize m_fX m_fY accordingly
725 // NOTE: don't call UpdateData in there, it's not meant for
726 void PatchDialog::UpdateRowColInfo()
728 m_fX = m_fY = m_fZ = m_fS = m_fT = 0.0;
732 // we rely on whatever active row/column has been set before we get called
735 if (r >= 0 && r < m_Patch->height && c >= 0 && c < m_Patch->width)
737 m_fX = m_Patch->ctrl[c][r].xyz[0];
738 m_fY = m_Patch->ctrl[c][r].xyz[1];
739 m_fZ = m_Patch->ctrl[c][r].xyz[2];
740 m_fS = m_Patch->ctrl[c][r].st[0];
741 m_fT = m_Patch->ctrl[c][r].st[1];