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
23 // Floating dialog that contains a notebook with at least Entities and Group tabs
24 // I merged the 2 MS Windows dialogs in a single class
26 // Leonardo Zide (leo@lokigames.com)
32 #include <gdk/gdkkeysyms.h>
34 #include "groupdialog.h"
36 GtkWidget* EntWidgets[EntLast];
37 GtkListStore* g_entlist_store;
38 GtkListStore* g_entprops_store;
39 int inspector_mode; // W_TEXTURE, W_ENTITY, or W_CONSOLE
40 qboolean multiple_entities;
41 // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=17
42 qboolean disable_spawn_get = false;
43 entity_t *edit_entity;
45 static GdkPixmap *tree_pixmaps[7];
46 static GdkBitmap *tree_masks[7];
52 #define IMG_ENTITYGROUP 4
57 #define MAX_GROUPS 4096
58 #define GROUP_DELIMETER '@'
59 #define GROUPNAME "QER_Group_%i"
62 GroupDlg *g_pGroupDlg = &g_wndGroup;
64 // group_t are loaded / saved through "group_info" entities
65 // they hold epairs for group settings and additionnal access info (tree nodes)
66 group_t *g_pGroups = NULL;
68 // the number of active spawnflags
69 static int spawnflag_count;
70 // table: index, match spawnflag item to the spawnflag index (i.e. which bit)
71 static int spawn_table[MAX_FLAGS];
72 // we change the layout depending on how many spawn flags we need to display
73 // the table is a 4x4 in which we need to put the comment box EntWidgets[EntComment] and the spawn flags..
74 static GtkWidget *LayoutTable;
75 // 0: none of them are hooked
76 // 1: only the text, 2: text and four checks, 3: text and 8 checks
77 static int widget_state = 0;
79 static void entity_check (GtkWidget *widget, gpointer data);
81 // =============================================================================
85 ===============================================================
89 ===============================================================
94 GtkListStore* store = g_entlist_store;
96 gtk_list_store_clear(store);
98 for (eclass_t* e = eclass ; e ; e = e->next)
101 gtk_list_store_append(store, &iter);
102 gtk_list_store_set(store, &iter, 0, e->name, 1, e, -1);
108 // Reset the key/value (aka property) listbox and fill it with the
109 // k/v pairs from the entity being edited.
112 void SetKeyValuePairs (bool bClearMD3)
114 GtkListStore* store = g_entprops_store;
116 gtk_list_store_clear(store);
118 if (edit_entity == NULL)
120 // if there's no entity, then display no key/values
124 // save current key/val pair around filling epair box
125 // row_select wipes it and sets to first in list
126 Str strKey = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntKeyField]));
127 Str strVal = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntValueField]));
130 // Walk through list and add pairs
131 for(epair_t* epair = edit_entity->epairs ; epair ; epair = epair->next)
134 gtk_list_store_append(store, &iter);
135 gtk_list_store_set(store, &iter, 0, epair->key, 1, epair->value, -1);
138 gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntKeyField]), strKey.GetBuffer());
139 gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), strVal.GetBuffer());
141 Sys_UpdateWindows(W_CAMERA | W_XY);
146 // Update the checkboxes to reflect the flag state of the entity
148 void SetSpawnFlags(void)
152 disable_spawn_get = true;
154 f = atoi(ValueForKey (edit_entity, "spawnflags"));
155 for (i=0 ; i<spawnflag_count ; i++)
157 v = !!(f&(1<<spawn_table[i]));
158 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (EntWidgets[EntCheck1+i]), v);
160 // take care of the remaining ones
161 for (i=spawnflag_count ; i<MAX_FLAGS ; i++)
163 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (EntWidgets[EntCheck1+i]), FALSE);
166 disable_spawn_get = false;
171 // Update the entity flags to reflect the state of the checkboxes
173 // NOTE: this function had a tendency to add "spawnflags" "0" on most entities
174 // if this wants to set spawnflags to zero, remove the key
176 void GetSpawnFlags(void)
182 for (i=0 ; i<spawnflag_count ; i++)
184 v = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (EntWidgets[EntCheck1+i]));
185 f |= v<<spawn_table[i];
190 // remove all "spawnflags" keys
191 if (multiple_entities)
195 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
196 DeleteKey (b->owner, "spawnflags");
199 DeleteKey (edit_entity, "spawnflags");
203 sprintf (sz, "%i", f);
204 if (multiple_entities)
208 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
209 SetKeyValue(b->owner, "spawnflags", sz);
212 SetKeyValue (edit_entity, "spawnflags", sz);
217 //#define DBG_UPDATESEL
221 // Update the listbox, checkboxes and k/v pairs to reflect the new selection
222 // iIndex is the index in the list box with the class name, -1 if not found
223 bool UpdateSel(int iIndex, eclass_t *pec)
228 // syndrom of crappy code, we may get into stack overflowing crap with this function and Gtk
229 // if we play with the list of entity classes
230 // using a static flag to prevent recursion
231 static bool bBlockUpdate = false;
234 return FALSE; // NOTE TTimo wtf is the return value for anyway?
237 Sys_FPrintf(SYS_WRN, "UpdateSel\n");
240 if (selected_brushes.next == &selected_brushes)
242 edit_entity = world_entity;
243 multiple_entities = false;
247 edit_entity = selected_brushes.next->owner;
248 for (b=selected_brushes.next->next ; b != &selected_brushes ; b=b->next)
250 if (b->owner != edit_entity)
252 multiple_entities = true;
261 Sys_FPrintf(SYS_WRN,"Setting focus_row to %d\n", iIndex);
265 GtkTreeView* view = GTK_TREE_VIEW(EntWidgets[EntList]);
266 GtkTreePath* path = gtk_tree_path_new();
267 gtk_tree_path_append_index(path, iIndex);
268 gtk_tree_selection_select_path(gtk_tree_view_get_selection(view), path);
269 gtk_tree_view_scroll_to_cell(view, path, NULL, FALSE, 0, 0);
270 gtk_tree_path_free(path);
272 bBlockUpdate = false;
278 // Set up the description
280 GtkTextBuffer* buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(EntWidgets[EntComment]));
281 gtk_text_buffer_set_text (buffer, pec->comments, -1);
286 // do a first pass to count the spawn flags, don't touch the widgets, we don't know in what state they are
287 for (i=0 ; i<MAX_FLAGS ; i++)
289 if (pec->flagnames[i] && pec->flagnames[i][0] != 0 && strcmp(pec->flagnames[i],"-"))
291 spawn_table[spawnflag_count] = i;
296 // what's new widget state
297 if (spawnflag_count==0)
299 else if (spawnflag_count<=4)
301 else if (spawnflag_count<=8)
303 else if (spawnflag_count<=12)
307 widget_state = next_state;
308 static int last_count = 0;
310 // disable all remaining boxes
311 // NOTE: these boxes might not even be on display
312 for (i = 0; i < last_count; i++)
314 GtkWidget* widget = EntWidgets[EntCheck1+i];
315 gtk_label_set_text (GTK_LABEL (GTK_BIN (widget)->child), " ");
316 gtk_widget_hide (widget);
317 gtk_widget_ref (widget);
318 gtk_container_remove (GTK_CONTAINER (LayoutTable), widget);
320 last_count = spawnflag_count;
322 for (i=0 ; i<spawnflag_count ; i++)
324 GtkWidget* widget = EntWidgets[EntCheck1+i];
325 gtk_widget_show (widget);
328 str = pec->flagnames[spawn_table[i]];
331 // gtk_table_attach (GTK_TABLE (LayoutTable), widget, i%4, i%4+1, i/4, i/4+1,
332 gtk_table_attach (GTK_TABLE (LayoutTable), widget, i%4, i%4+1, i/4, i/4+1,
333 (GtkAttachOptions) (GTK_FILL),
334 (GtkAttachOptions) (GTK_FILL), 0, 0);
335 gtk_widget_unref (widget);
337 gtk_label_set_text (GTK_LABEL (GTK_BIN (widget)->child), str.GetBuffer ());
347 bool UpdateEntitySel(eclass_t *pec)
350 Sys_FPrintf(SYS_WRN, "UpdateEntitySel\n");
353 GtkTreeModel* model = GTK_TREE_MODEL(g_entlist_store);
356 for(gboolean good = gtk_tree_model_get_iter_first(model, &iter); good != FALSE; good = gtk_tree_model_iter_next(model, &iter))
359 gtk_tree_model_get(model, &iter, 0, &text, -1);
360 if (strcmp (text, pec->name) == 0)
363 Sys_FPrintf(SYS_WRN, "found a match: %d %s\n", i, pec->name);
365 return UpdateSel (i, pec);
370 return UpdateSel (-1, pec);
375 // Creates a new entity based on the currently selected brush and entity type.
378 void CreateEntity(void)
380 GtkTreeView* view = GTK_TREE_VIEW(EntWidgets[EntList]);
382 // check to make sure we have a brush
383 if (selected_brushes.next == &selected_brushes)
385 gtk_MessageBox(g_pParentWnd->m_pWidget, "You must have a selected brush to create an entity", "info");
389 // find out what type of entity we are trying to create
392 if(gtk_tree_selection_get_selected(gtk_tree_view_get_selection(view), &model, &iter) == FALSE)
394 gtk_MessageBox (g_pParentWnd->m_pWidget, "You must have a selected class to create an entity", "info");
399 gtk_tree_model_get(model, &iter, 0, &text, -1);
400 CreateEntityFromName(text, vec3_origin);
403 if (selected_brushes.next == &selected_brushes)
404 edit_entity = world_entity;
406 edit_entity = selected_brushes.next->owner;
410 Select_Brush (edit_entity->brushes.onext);
411 Sys_UpdateWindows(W_ALL);
422 if (edit_entity == NULL)
425 // Get current selection text
426 const char* key = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntKeyField]));
427 const char* value = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntValueField]));
430 // TTimo: if you change the classname to worldspawn you won't merge back in the structural brushes but create a parasite entity
431 if (!strcmp(key, "classname") && !strcmp(value, "worldspawn"))
433 gtk_MessageBox(g_pParentWnd->m_pWidget, "Cannot change \"classname\" key back to worldspawn.", NULL, MB_OK );
438 // RR2DO2: we don't want spaces in entity keys
439 if (strstr( key, " " ))
441 gtk_MessageBox(g_pParentWnd->m_pWidget, "No spaces are allowed in entity keys.", NULL, MB_OK );
445 if (multiple_entities)
449 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
450 SetKeyValue(b->owner, key, value);
453 SetKeyValue(edit_entity, key, value);
455 // refresh the prop listbox
459 #ifdef USEPLUGINENTITIES
460 // if it's a plugin entity, perhaps we need to update some drawing parameters
461 // NOTE: perhaps moving this code to a seperate func would help if we need it in other places
462 // TODO: we need to call some update func in the IPluginEntity in case model name changes etc.
463 // ( for the moment only bounding brush is updated ), see UpdateModelBrush in Ritual's Q3Radiant
464 if (edit_entity->eclass->nShowFlags & ECLASS_PLUGINENTITY)
467 edit_entity->pPlugEnt->GetBounds( mins, maxs );
468 // replace old bounding brush by newly computed one
469 // NOTE: this part is similar to Entity_BuildModelBrush in Ritual's Q3Radiant, it can be
470 // usefull moved into a seperate func
471 brush_t *b,*oldbrush;
472 if (edit_entity->brushes.onext != &edit_entity->brushes)
473 oldbrush = edit_entity->brushes.onext;
474 b = Brush_Create (mins, maxs, &edit_entity->eclass->texdef);
475 Entity_LinkBrush (edit_entity, b);
476 Brush_Build( b, true );
478 Brush_AddToList (edit_entity->brushes.onext, &selected_brushes);
480 Brush_Free( oldbrush );
482 #endif // USEPLUGINENTITIES
493 if (edit_entity == NULL)
496 // Get current selection text
497 const char* key = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntKeyField]));
499 if (multiple_entities)
503 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
504 DeleteKey(b->owner, key);
507 DeleteKey(edit_entity, key);
509 // refresh the prop listbox
518 if (edit_entity == NULL)
521 if (multiple_entities)
525 for (b=selected_brushes.next; b != &selected_brushes; b=b->next)
526 for (pep = b->owner->epairs; pep; )
528 if (strcmp (pep->key, "classname") != 0)
530 DeleteKey (b->owner, pep->key);
531 pep = b->owner->epairs;
538 for (pep = edit_entity->epairs; pep; )
540 if (strcmp (pep->key, "classname") != 0)
542 DeleteKey (edit_entity, pep->key);
543 pep = edit_entity->epairs;
549 // refresh the dialog
551 for (i = EntCheck1; i <= EntCheck16; i++)
552 gtk_signal_handler_block_by_func (GTK_OBJECT (EntWidgets[i]), GTK_SIGNAL_FUNC (entity_check), NULL);
554 for (i = EntCheck1; i <= EntCheck16; i++)
555 gtk_signal_handler_unblock_by_func (GTK_OBJECT (EntWidgets[i]), GTK_SIGNAL_FUNC (entity_check), NULL);
558 bool GetSelectAllCriteria(CString &strKey, CString &strVal)
562 if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(EntWidgets[EntProps])), &model, &iter)
563 && (inspector_mode == W_ENTITY)
564 && GTK_WIDGET_VISIBLE (g_pGroupDlg->m_pWidget))
566 strKey = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntKeyField]));
567 strVal = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntValueField]));
576 char buffer[NAME_MAX];
578 strcpy (buffer, g_qeglobals.m_strHomeMaps.GetBuffer());
579 strcat (buffer, "sound/");
581 if( access(buffer, R_OK) != 0 )
584 strcpy (buffer, g_qeglobals.m_strHomeMaps.GetBuffer());
585 strcat (buffer, "/");
588 const char *filename = file_dialog (g_pGroupDlg->m_pWidget, TRUE, "Open Wav File", buffer, "sound");
589 if (filename != NULL)
591 gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntKeyField]), "noise");
592 char *aux = vfsExtractRelativePath (filename);
598 Sys_FPrintf (SYS_WRN, "WARNING: could not extract the relative path, using full path instead\n");
602 gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), str.GetBuffer());
609 char buffer[NAME_MAX];
611 strcpy (buffer, g_qeglobals.m_strHomeMaps.GetBuffer());
612 strcat (buffer, "models/");
614 if( access(buffer, R_OK) != 0 )
617 strcpy (buffer, g_qeglobals.m_strHomeMaps.GetBuffer());
618 strcat (buffer, "/");
621 const char *filename = file_dialog (g_pGroupDlg->m_pWidget, TRUE, "Open Model", buffer, MODEL_MAJOR);
622 if (filename != NULL)
624 gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntKeyField]), "model");
625 // use VFS to get the correct relative path
626 char *aux = vfsExtractRelativePath (filename);
632 Sys_FPrintf (SYS_WRN, "WARNING: could not extract the relative path, using full path instead\n");
636 gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), str.GetBuffer());
638 edit_entity->brushes.onext->bModelFailed = false;
647 void SetInspectorMode(int iType)
649 if (iType == W_GROUP)
650 gtk_MessageBox(g_pParentWnd->m_pWidget, "Brush grouping is not functional yet", NULL, MB_OK | MB_ICONWARNING );
652 if (!g_pParentWnd->FloatingGroupDialog() &&
653 (iType == W_TEXTURE || iType == W_CONSOLE))
656 // Is the caller asking us to cycle to the next window?
659 if (inspector_mode == W_ENTITY)
661 else if (inspector_mode == W_TEXTURE)
663 else if (inspector_mode == W_CONSOLE)
672 // entity is always first in the inspector
673 gtk_window_set_title (GTK_WINDOW (g_qeglobals_gui.d_entity), "Entities");
674 gtk_notebook_set_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), 0);
678 g_pParentWnd->GetTexWnd()->FocusEdit();
679 gtk_window_set_title (GTK_WINDOW (g_qeglobals_gui.d_entity), "Textures");
680 if (g_pParentWnd->FloatingGroupDialog())
681 gtk_notebook_set_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), 1);
685 gtk_window_set_title (GTK_WINDOW (g_qeglobals_gui.d_entity), "Console");
686 if (g_pParentWnd->FloatingGroupDialog())
687 gtk_notebook_set_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), 2);
691 if (g_pParentWnd->FloatingGroupDialog())
692 gtk_notebook_set_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), 3);
694 gtk_notebook_set_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), 1);
702 void Group_Add(entity_t *e)
705 group_t *g = (group_t*)qmalloc(sizeof(group_t));
706 g->epairs = e->epairs;
710 // create a new group node
711 char *text = ValueForKey(g->epairs, "group");
712 g->itemOwner = gtk_ctree_insert_node (GTK_CTREE (g_wndGroup.m_pTree), g_wndGroup.m_hWorld, NULL, &text, 0,
713 tree_pixmaps[IMG_GROUP], tree_masks[IMG_GROUP],
714 tree_pixmaps[IMG_GROUP], tree_masks[IMG_GROUP], TRUE, TRUE);
720 group_t* Group_Alloc(char *name)
722 group_t *g = (group_t*)qmalloc(sizeof(group_t));
723 SetKeyValue( g->epairs, "group", name );
727 group_t* Group_ForName(const char * name)
729 group_t *g = g_pGroups;
732 if (strcmp( ValueForKey(g->epairs,"group"), name ) == 0)
739 void Group_AddToItem(brush_t *b, GtkCTreeNode* item)
741 int nImage = IMG_BRUSH;
742 if (!g_qeglobals.m_bBrushPrimitMode)
746 const char *pName = NULL;
747 // const char *pNamed = Brush_GetKeyValue(b, "name");
749 if (!b->owner || (b->owner == world_entity))
753 pName = "Generic Patch";
758 pName = "Generic Brush";
764 pName = b->owner->eclass->name;
765 if (b->owner->eclass->fixedsize)
771 nImage = IMG_ENTITYGROUP;
775 GtkCTreeNode *newItem;
776 int i = (b->patchBrush) ? IMG_PATCH : IMG_BRUSH;
777 newItem = gtk_ctree_insert_node (GTK_CTREE (g_wndGroup.m_pTree), item, NULL, (gchar**)&pName, 0,
778 tree_pixmaps[i], tree_masks[i], tree_pixmaps[i],
779 tree_masks[i], TRUE, TRUE);
780 gtk_ctree_node_set_row_data (GTK_CTREE (g_wndGroup.m_pTree), newItem, b);
781 b->itemOwner = newItem;
784 void Group_RemoveBrush(brush_t *b)
787 if (!g_qeglobals.m_bBrushPrimitMode)
793 gtk_ctree_remove_node (GTK_CTREE (g_pGroupDlg->m_pTree), b->itemOwner);
796 DeleteKey(b->epairs, "group");
800 void Group_AddToWorld(brush_t *b)
802 if (!g_qeglobals.m_bBrushPrimitMode)
806 GtkCTreeNode *parent = gtk_ctree_node_nth (GTK_CTREE (g_pGroupDlg->m_pTree), 0);
807 Group_AddToItem(b, parent);
810 void Group_AddToProperGroup(brush_t *b)
813 if (!g_qeglobals.m_bBrushPrimitMode)
818 // NOTE: we do a local copy of the "group" key because it gets erased by Group_RemoveBrush
819 const char *pGroup = Brush_GetKeyValue(b, "group");
820 // remove the entry in the tree if there's one
823 gtk_ctree_remove_node (GTK_CTREE (g_pGroupDlg->m_pTree), b->itemOwner);
830 group_t *g = Group_ForName(pGroup);
832 Group_AddToItem(b, g->itemOwner);
835 Sys_Printf("WARNING: unexpected Group_ForName not found in Group_AddToProperGroup\n");
845 void Group_AddToSelected(brush_t *b)
847 if (!g_qeglobals.m_bBrushPrimitMode)
852 item = gtk_ctree_node_nth (GTK_CTREE (g_pGroupDlg->m_pTree), GTK_CLIST (g_pGroupDlg->m_pTree)->focus_row);
855 item = gtk_ctree_node_nth (GTK_CTREE (g_pGroupDlg->m_pTree), 0);
857 Group_AddToItem(b, item);
861 void Group_Save(FILE *f)
863 group_t *g = g_pGroups;
866 fprintf(f,"{\n\"classname\" \"group_info\"\n\"group\" \"%s\"\n}\n", ValueForKey( g->epairs, "group" ));
874 if (!g_qeglobals.m_bBrushPrimitMode)
878 // start by cleaning everything
880 //++timo FIXME: we leak, delete the groups on the way (I don't have time to do it now)
882 Sys_Printf("TODO: fix leak in Group_Init\n");
884 group_t *g = g_pGroups;
888 for (ep = g->epairs ; ep ; ep=enext )
899 char *text = "World";
901 gtk_clist_clear (GTK_CLIST (g_wndGroup.m_pTree));
902 world = gtk_ctree_insert_node (GTK_CTREE (g_wndGroup.m_pTree), NULL, NULL, &text, 0,
903 tree_pixmaps[IMG_GROUP], tree_masks[IMG_GROUP], tree_pixmaps[IMG_GROUP],
904 tree_masks[IMG_GROUP], FALSE, TRUE);
906 // walk through all the brushes, remove the itemOwner key and add them back where they belong
908 for (b = active_brushes.next; b != &active_brushes; b = b->next)
911 Group_AddToProperGroup(b);
913 for (b = selected_brushes.next ; b != &selected_brushes ; b = b->next)
916 Group_AddToProperGroup(b);
920 // scan through world_entity for groups in this map?
921 // we use GROUPNAME "QER_group_%i" to look for existing groups and their naming
922 //++timo FIXME: is this actually needed for anything?
923 void Group_GetListFromWorld(GSList **pArray)
925 if (!g_qeglobals.m_bBrushPrimitMode)
930 if (world_entity == NULL)
936 for (int i =0; i < MAX_GROUPS; i++)
938 sprintf(cBuff, GROUPNAME, i);
939 char *pGroup = ValueForKey(world_entity, cBuff);
940 if (pGroup && strlen(pGroup) > 0)
942 *pArray = g_slist_append (*pArray, g_strdup (pGroup));
951 void Group_RemoveListFromWorld()
953 if (!g_qeglobals.m_bBrushPrimitMode)
957 GSList* array = NULL;
958 Group_GetListFromWorld(&array);
962 DeleteKey(world_entity, (char*)array->data);
963 g_free (array->data);
964 array = g_slist_remove (array, array->data);
968 int CountChar(const char *p, char c)
971 int nLen = strlen(p)-1;
982 // =============================================================================
985 static void eclasslist_selection_changed(GtkTreeSelection* selection, gpointer data)
988 GtkTreeIter selected;
989 // no world entity, we are not ready yet
990 // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=917
991 if( !world_entity ) {
994 if(gtk_tree_selection_get_selected(selection, &model, &selected))
997 gtk_tree_model_get(model, &selected, 1, &eclass, -1);
1000 GtkTreePath* path = gtk_tree_model_get_path(model, &selected);
1001 UpdateSel(gtk_tree_path_get_indices(path)[0], eclass);
1002 gtk_tree_path_free(path);
1007 static gint eclasslist_button_press (GtkWidget *widget, GdkEventButton *event, gpointer data)
1009 if (event->type == GDK_2BUTTON_PRESS)
1017 static gint eclasslist_keypress (GtkWidget* widget, GdkEventKey* event, gpointer data)
1019 unsigned int code = gdk_keyval_to_upper (event->keyval);
1021 if (event->keyval == GDK_Return)
1027 // select the entity that starts with the key pressed
1028 if (code <= 'Z' && code >= 'A')
1030 GtkTreeView* view = GTK_TREE_VIEW(EntWidgets[EntList]);
1031 GtkTreeModel* model;
1033 if(gtk_tree_selection_get_selected(gtk_tree_view_get_selection(view), &model, &iter) == FALSE
1034 || gtk_tree_model_iter_next(model, &iter) == FALSE)
1036 gtk_tree_model_get_iter_first(model, &iter);
1039 for(unsigned int count = gtk_tree_model_iter_n_children(model, NULL); count > 0; --count)
1042 gtk_tree_model_get(model, &iter, 0, &text, -1);
1044 if (toupper (text[0]) == (int)code)
1046 GtkTreePath* path = gtk_tree_model_get_path(model, &iter);
1047 gtk_tree_selection_select_path(gtk_tree_view_get_selection(view), path);
1048 gtk_tree_view_scroll_to_cell(view, path, NULL, FALSE, 0, 0);
1049 gtk_tree_path_free(path);
1055 if(gtk_tree_model_iter_next(model, &iter) == FALSE)
1056 gtk_tree_model_get_iter_first(model, &iter);
1065 static void proplist_selection_changed(GtkTreeSelection* selection, gpointer data)
1067 // find out what type of entity we are trying to create
1068 GtkTreeModel* model;
1070 if(gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE)
1077 gtk_tree_model_get(model, &iter, 0, &key, 1, &val, -1);
1079 gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntKeyField]), key);
1080 gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), val);
1086 static void entity_check (GtkWidget *widget, gpointer data)
1088 if( !disable_spawn_get )
1092 static void entitylist_angle (GtkWidget *widget, gpointer data)
1094 SetKeyValue (edit_entity, "angle", (char*)data);
1095 SetKeyValuePairs ();
1098 static gint entityentry_keypress (GtkWidget* widget, GdkEventKey* event, gpointer data)
1100 if (event->keyval == GDK_Tab)
1102 if (widget == EntWidgets[EntKeyField])
1104 //gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), "");
1105 gtk_window_set_focus (GTK_WINDOW (g_pGroupDlg->m_pWidget), EntWidgets[EntValueField]);
1108 gtk_window_set_focus (GTK_WINDOW (g_pGroupDlg->m_pWidget), EntWidgets[EntKeyField]);
1112 else if (event->keyval == GDK_Return)
1114 if (widget == EntWidgets[EntKeyField])
1116 gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), "");
1117 gtk_window_set_focus (GTK_WINDOW (g_pGroupDlg->m_pWidget), EntWidgets[EntValueField]);
1129 // add a new group, put all selected brushes into the group
1130 static void groupdlg_add (GtkWidget *widget, gpointer data)
1132 char* name = DoNameDlg ("New Group");
1136 // create a new group node
1138 item = gtk_ctree_insert_node (GTK_CTREE (g_wndGroup.m_pTree), g_pGroupDlg->m_hWorld, NULL, &name, 0,
1139 tree_pixmaps[IMG_GROUP], tree_masks[IMG_GROUP],
1140 tree_pixmaps[IMG_GROUP], tree_masks[IMG_GROUP], FALSE, TRUE);
1142 // create a new group
1143 group_t *g = Group_Alloc (name);
1144 g->itemOwner = item;
1145 g->next = g_pGroups;
1148 // now add the selected brushes
1149 // NOTE: it would be much faster to give the group_t for adding
1150 // but Select_AddToGroup is the standard way for all other cases
1151 Select_AddToGroup (name);
1156 static void switch_page (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer data)
1159 gtk_label_get(GTK_LABEL(gtk_notebook_get_tab_label(notebook, gtk_notebook_get_nth_page(notebook, page_num))), &text);
1160 gtk_window_set_title (GTK_WINDOW (data), text);
1162 gpointer item = g_object_get_data (G_OBJECT (g_pParentWnd->m_pWidget), "menu_misc_selectentitycolor");
1164 if (g_pParentWnd->FloatingGroupDialog())
1168 case 0: inspector_mode = W_ENTITY; break;
1169 case 1: inspector_mode = W_TEXTURE; break;
1170 case 2: inspector_mode = W_CONSOLE; break;
1171 default: inspector_mode = W_GROUP; break;
1177 inspector_mode = W_ENTITY;
1179 inspector_mode = W_GROUP;
1182 if (inspector_mode == W_ENTITY)
1183 gtk_widget_set_sensitive (GTK_WIDGET (item), TRUE);
1185 gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
1188 // =============================================================================
1191 // NOTE: when a key is hit with group window focused, we catch in this handler but it gets propagated to mainframe too
1192 // therefore the message will be intercepted and used as a ID_SELECTION_DESELECT
1193 static gint OnDialogKey (GtkWidget* widget, GdkEventKey* event, gpointer data)
1196 Sys_Printf("OnDialogKey\n");
1198 if ((event->keyval == GDK_Escape) && (g_pParentWnd->CurrentStyle() != MainFrame::eFloating))
1200 // toggle off the group view (whatever part of it is currently displayed)
1201 // this used to be done with a g_pParentWnd->OnViewEntity(); but it had bad consequences
1202 // http://fenris.lokigames.com/show_bug.cgi?id=2773
1203 widget_delete_hide (g_qeglobals_gui.d_entity);
1209 GroupDlg::GroupDlg ()
1216 extern void PositionWindowOnPrimaryScreen(window_position_t& position);
1219 void GroupDlg::Create ()
1221 if (m_pWidget != NULL)
1224 GtkWidget* dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1227 if( g_PrefsDlg.m_bStartOnPrimMon ) {
1228 PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.posEntityWnd );
1231 load_window_pos (dlg, g_PrefsDlg.mWindowInfo.posEntityWnd);
1233 gtk_window_set_title (GTK_WINDOW (dlg), "Entities");
1234 gtk_signal_connect (GTK_OBJECT (dlg), "delete_event", GTK_SIGNAL_FUNC (widget_delete_hide), NULL);
1236 gtk_signal_connect (GTK_OBJECT (dlg), "key_press_event", GTK_SIGNAL_FUNC (OnDialogKey), NULL);
1237 gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (g_pParentWnd->m_pWidget));
1238 g_qeglobals_gui.d_entity = dlg;
1241 GtkWidget* notebook = gtk_notebook_new ();
1242 gtk_widget_show (notebook);
1243 gtk_container_add (GTK_CONTAINER (dlg), notebook);
1244 gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_BOTTOM);
1245 m_pNotebook = notebook;
1248 GtkWidget* vbox = gtk_vbox_new (FALSE, 2);
1249 gtk_widget_show (vbox);
1250 gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
1253 GtkWidget* label = gtk_label_new ("Entities");
1254 gtk_widget_show (label);
1255 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, label);
1259 GtkWidget* split1 = gtk_vpaned_new ();
1260 gtk_box_pack_start (GTK_BOX (vbox), split1, TRUE, TRUE, 0);
1261 gtk_widget_show (split1);
1264 GtkWidget* split2 = gtk_vpaned_new ();
1265 gtk_paned_add1 (GTK_PANED (split1), split2);
1266 gtk_widget_show (split2);
1268 g_object_set_data (G_OBJECT (dlg), "split1", split1);
1269 g_object_set_data (G_OBJECT (dlg), "split2", split2);
1272 GtkWidget* vbox2 = gtk_vbox_new (FALSE, 2);
1273 gtk_widget_show (vbox2);
1274 gtk_paned_pack2 (GTK_PANED (split1), vbox2, FALSE, FALSE);
1277 GtkWidget* scr = gtk_scrolled_window_new (NULL, NULL);
1278 gtk_widget_show (scr);
1279 gtk_paned_add1 (GTK_PANED (split2), scr);
1280 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
1281 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);
1284 GtkListStore* store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
1286 GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1287 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
1288 g_signal_connect(G_OBJECT(view), "button_press_event", G_CALLBACK(eclasslist_button_press), NULL);
1289 g_signal_connect(G_OBJECT(view), "key_press_event", G_CALLBACK(eclasslist_keypress), this);
1292 GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
1293 GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("Key", renderer, "text", 0, NULL);
1294 gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
1298 GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
1299 g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(eclasslist_selection_changed), dlg);
1302 gtk_widget_show(view);
1304 gtk_container_add(GTK_CONTAINER (scr), view);
1306 g_object_unref(G_OBJECT(store));
1307 EntWidgets[EntList] = view;
1308 g_entlist_store = store;
1313 GtkWidget* scr = gtk_scrolled_window_new (NULL, NULL);
1314 gtk_widget_show (scr);
1315 gtk_paned_add2 (GTK_PANED (split2), scr);
1316 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
1317 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);
1320 GtkWidget* text = gtk_text_view_new();
1321 gtk_widget_set_size_request(text, 0, -1); // allow shrinking
1322 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
1323 gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
1324 gtk_widget_show (text);
1325 gtk_container_add (GTK_CONTAINER (scr), text);
1326 EntWidgets[EntComment] = text;
1331 // Spawnflags (4 colums wide max, or window gets too wide.)
1332 GtkWidget* table = LayoutTable = gtk_table_new (4, 4, FALSE);
1333 gtk_box_pack_start (GTK_BOX (vbox2), LayoutTable, FALSE, TRUE, 0);
1334 gtk_widget_show(LayoutTable);
1336 for (int i = 0; i < MAX_FLAGS; i++)
1338 GtkWidget* check = gtk_check_button_new_with_label ("");
1339 gtk_widget_ref (check);
1340 gtk_signal_connect (GTK_OBJECT (check), "toggled", GTK_SIGNAL_FUNC (entity_check), NULL);
1341 EntWidgets[EntCheck1+i] = check;
1344 //++timo cleanme: these flags where Q2 stuff
1346 check = gtk_check_button_new_with_label ("!Easy");
1347 gtk_widget_show (check);
1348 gtk_signal_connect (GTK_OBJECT (check), "toggled", GTK_SIGNAL_FUNC (entity_check), NULL);
1349 gtk_table_attach (GTK_TABLE (table), check, 2, 3, 0, 1,
1350 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1351 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1352 EntWidgets[EntCheck17] = check;
1354 check = gtk_check_button_new_with_label ("!Medium");
1355 gtk_widget_show (check);
1356 gtk_signal_connect (GTK_OBJECT (check), "toggled", GTK_SIGNAL_FUNC (entity_check), NULL);
1357 gtk_table_attach (GTK_TABLE (table), check, 2, 3, 1, 2,
1358 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1359 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1360 EntWidgets[EntCheck18] = check;
1362 check = gtk_check_button_new_with_label ("!Hard");
1363 gtk_widget_show (check);
1364 gtk_signal_connect (GTK_OBJECT (check), "toggled", GTK_SIGNAL_FUNC (entity_check), NULL);
1365 gtk_table_attach (GTK_TABLE (table), check, 2, 3, 2, 3,
1366 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1367 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1368 EntWidgets[EntCheck19] = check;
1370 check = gtk_check_button_new_with_label ("!DeathMatch");
1371 gtk_widget_show (check);
1372 gtk_signal_connect (GTK_OBJECT (check), "toggled", GTK_SIGNAL_FUNC (entity_check), NULL);
1373 gtk_table_attach (GTK_TABLE (table), check, 2, 3, 3, 4,
1374 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1375 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1376 EntWidgets[EntCheck20] = check;
1381 GtkWidget* scr = gtk_scrolled_window_new (NULL, NULL);
1382 gtk_widget_show (scr);
1383 gtk_box_pack_start (GTK_BOX (vbox2), scr, TRUE, TRUE, 0);
1384 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1385 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);
1388 GtkListStore* store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
1390 GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1391 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
1394 GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
1395 GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
1396 gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
1400 GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
1401 GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 1, NULL);
1402 gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
1406 GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
1407 g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(proplist_selection_changed), dlg);
1410 gtk_widget_show(view);
1412 gtk_container_add(GTK_CONTAINER (scr), view);
1414 g_object_unref(G_OBJECT(store));
1416 EntWidgets[EntProps] = view;
1417 g_entprops_store = store;
1422 int x = g_PrefsDlg.mWindowInfo.nEntitySplit1;
1425 gtk_paned_set_position (GTK_PANED (split1), x);
1427 while (gtk_events_pending ()) gtk_main_iteration ();
1428 x = g_PrefsDlg.mWindowInfo.nEntitySplit2;
1431 gtk_paned_set_position (GTK_PANED (split2), x);
1437 GtkWidget* table = gtk_table_new (2, 2, FALSE);
1438 gtk_widget_show (table);
1439 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
1440 gtk_table_set_row_spacings (GTK_TABLE (table), 3);
1441 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
1444 GtkWidget* entry = gtk_entry_new ();
1445 gtk_widget_show (entry);
1446 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
1447 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1448 (GtkAttachOptions) (0), 0, 0);
1449 gtk_widget_set_events (entry, GDK_KEY_PRESS_MASK);
1450 gtk_signal_connect (GTK_OBJECT (entry), "key_press_event",
1451 GTK_SIGNAL_FUNC (entityentry_keypress), this);
1452 EntWidgets[EntKeyField] = entry;
1456 GtkWidget* entry = gtk_entry_new ();
1457 gtk_widget_show (entry);
1458 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2,
1459 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1460 (GtkAttachOptions) (0), 0, 0);
1461 gtk_widget_set_events (entry, GDK_KEY_PRESS_MASK);
1462 gtk_signal_connect (GTK_OBJECT (entry), "key_press_event",
1463 GTK_SIGNAL_FUNC (entityentry_keypress), this);
1464 EntWidgets[EntValueField] = entry;
1468 GtkWidget* label = gtk_label_new ("Value");
1469 gtk_widget_show (label);
1470 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
1471 (GtkAttachOptions) (GTK_FILL),
1472 (GtkAttachOptions) (0), 0, 0);
1473 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1477 GtkWidget* label = gtk_label_new ("Key");
1478 gtk_widget_show (label);
1479 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
1480 (GtkAttachOptions) (GTK_FILL),
1481 (GtkAttachOptions) (0), 0, 0);
1482 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1487 GtkWidget* hbox = gtk_hbox_new (FALSE, 5);
1488 gtk_widget_show (hbox);
1489 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
1492 GtkWidget* table = gtk_table_new (3, 3, TRUE);
1493 gtk_widget_show (table);
1494 gtk_box_pack_start (GTK_BOX (hbox), table, FALSE, TRUE, 0);
1497 GtkWidget* button = gtk_button_new_with_label ("360");
1498 gtk_widget_show (button);
1499 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"360");
1500 gtk_table_attach (GTK_TABLE (table), button, 2, 3, 1, 2,
1501 (GtkAttachOptions) (GTK_FILL),
1502 (GtkAttachOptions) (GTK_FILL), 0, 0);
1506 GtkWidget* button = gtk_button_new_with_label ("45");
1507 gtk_widget_show (button);
1508 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"45");
1509 gtk_table_attach (GTK_TABLE (table), button, 2, 3, 0, 1,
1510 (GtkAttachOptions) (GTK_FILL),
1511 (GtkAttachOptions) (GTK_FILL), 0, 0);
1515 GtkWidget* button = gtk_button_new_with_label ("90");
1516 gtk_widget_show (button);
1517 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"90");
1518 gtk_table_attach (GTK_TABLE (table), button, 1, 2, 0, 1,
1519 (GtkAttachOptions) (GTK_FILL),
1520 (GtkAttachOptions) (GTK_FILL), 0, 0);
1525 GtkWidget* button = gtk_button_new_with_label ("135");
1526 gtk_widget_show (button);
1527 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"135");
1528 gtk_table_attach (GTK_TABLE (table), button, 0, 1, 0, 1,
1529 (GtkAttachOptions) (GTK_FILL),
1530 (GtkAttachOptions) (GTK_FILL), 0, 0);
1534 GtkWidget* button = gtk_button_new_with_label ("180");
1535 gtk_widget_show (button);
1536 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"180");
1537 gtk_table_attach (GTK_TABLE (table), button, 0, 1, 1, 2,
1538 (GtkAttachOptions) (GTK_FILL),
1539 (GtkAttachOptions) (GTK_FILL), 0, 0);
1543 GtkWidget* button = gtk_button_new_with_label ("225");
1544 gtk_widget_show (button);
1545 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"225");
1546 gtk_table_attach (GTK_TABLE (table), button, 0, 1, 2, 3,
1547 (GtkAttachOptions) (GTK_FILL),
1548 (GtkAttachOptions) (GTK_FILL), 0, 0);
1552 GtkWidget* button = gtk_button_new_with_label ("270");
1553 gtk_widget_show (button);
1554 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"270");
1555 gtk_table_attach (GTK_TABLE (table), button, 1, 2, 2, 3,
1556 (GtkAttachOptions) (GTK_FILL),
1557 (GtkAttachOptions) (GTK_FILL), 0, 0);
1561 GtkWidget* button = gtk_button_new_with_label ("315");
1562 gtk_widget_show (button);
1563 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"315");
1564 gtk_table_attach (GTK_TABLE (table), button, 2, 3, 2, 3,
1565 (GtkAttachOptions) (GTK_FILL),
1566 (GtkAttachOptions) (GTK_FILL), 0, 0);
1571 GtkWidget* vbox2 = gtk_vbox_new (FALSE, 0);
1572 gtk_widget_show (vbox2);
1573 gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
1576 GtkWidget* button = gtk_button_new_with_label ("Reset");
1577 gtk_widget_show (button);
1578 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (ResetEntity), NULL);
1579 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
1583 GtkWidget* button = gtk_button_new_with_label ("Up");
1584 gtk_widget_show (button);
1585 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"-1");
1586 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
1590 GtkWidget* button = gtk_button_new_with_label ("Dn");
1591 gtk_widget_show (button);
1592 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"-2");
1593 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
1598 GtkWidget* vbox2 = gtk_vbox_new (FALSE, 0);
1599 gtk_widget_show (vbox2);
1600 gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
1603 GtkWidget* button = gtk_button_new_with_label ("Del Key/Pair");
1604 gtk_widget_show (button);
1605 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (DelProp), NULL);
1606 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
1610 GtkWidget* button = gtk_button_new_with_label ("Sound...");
1611 gtk_widget_show (button);
1612 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (AssignSound), NULL);
1613 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
1617 GtkWidget* button = gtk_button_new_with_label ("Model...");
1618 gtk_widget_show (button);
1619 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (AssignModel), NULL);
1620 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
1626 if (g_pParentWnd->FloatingGroupDialog())
1629 GtkWidget* scr = gtk_scrolled_window_new (NULL, NULL);
1630 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1631 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);
1632 gtk_widget_show (scr);
1633 gtk_container_set_border_width (GTK_CONTAINER (scr), 3);
1636 GtkWidget* text = gtk_text_view_new ();
1637 gtk_widget_set_size_request(text, 0, -1); // allow shrinking
1638 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
1639 gtk_text_view_set_editable (GTK_TEXT_VIEW(text), FALSE);
1640 gtk_container_add (GTK_CONTAINER (scr), text);
1641 gtk_widget_show (text);
1642 g_qeglobals_gui.d_edit = text;
1646 GtkWidget* label = gtk_label_new ("Console");
1647 gtk_widget_show (label);
1648 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scr, label);
1654 //++timo NOTE: this part for grouping code, don't remove! (we'll put it back in sometime soon)
1657 vbox = gtk_vbox_new (FALSE, 5);
1658 gtk_widget_show (vbox);
1659 gtk_container_set_border_width (GTK_CONTAINER (vbox), 3);
1661 scr = gtk_scrolled_window_new (NULL, NULL);
1662 gtk_widget_show (scr);
1663 gtk_box_pack_start (GTK_BOX (vbox), scr, TRUE, TRUE, 0);
1664 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1666 ctree = gtk_ctree_new (1, 0);
1667 gtk_widget_show (ctree);
1668 gtk_container_add (GTK_CONTAINER (scr), ctree);
1669 gtk_clist_column_titles_hide (GTK_CLIST (ctree));
1672 hbox = gtk_hbox_new (FALSE, 5);
1673 gtk_widget_show (hbox);
1674 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
1676 button = gtk_button_new_with_label ("Add...");
1677 gtk_widget_show (button);
1678 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (groupdlg_add), NULL);
1679 gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1680 gtk_widget_set_usize (button, 60, -2);
1682 button = gtk_button_new_with_label ("Edit...");
1683 gtk_widget_show (button);
1684 gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1685 gtk_widget_set_usize (button, 60, -2);
1687 button = gtk_button_new_with_label ("Delete");
1688 gtk_widget_show (button);
1689 gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1690 gtk_widget_set_usize (button, 60, -2);
1692 label = gtk_label_new ("Groups");
1693 gtk_widget_show (label);
1694 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, label);
1696 inspector_mode = W_ENTITY;
1697 // gtk_window_set_title (GTK_WINDOW (dlg), "Entities");
1700 load_pixmap ("grouptree1.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[0], &tree_masks[0]);
1701 load_pixmap ("grouptree2.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[1], &tree_masks[1]);
1702 load_pixmap ("grouptree3.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[2], &tree_masks[2]);
1703 load_pixmap ("grouptree4.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[3], &tree_masks[3]);
1704 load_pixmap ("grouptree5.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[4], &tree_masks[4]);
1705 load_pixmap ("grouptree6.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[5], &tree_masks[5]);
1706 load_pixmap ("grouptree7.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[6], &tree_masks[6]);
1710 g_signal_connect (G_OBJECT (notebook), "switch_page", G_CALLBACK (switch_page), dlg);