2007-11-04 03:51:54 +00:00
|
|
|
/*
|
|
|
|
Copyright (C) 1999-2007 id Software, Inc. and contributors.
|
|
|
|
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
|
|
|
|
|
|
|
This file is part of GtkRadiant.
|
|
|
|
|
|
|
|
GtkRadiant is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
GtkRadiant is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with GtkRadiant; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
//
|
|
|
|
// Floating dialog that contains a notebook with at least Entities and Group tabs
|
|
|
|
// I merged the 2 MS Windows dialogs in a single class
|
|
|
|
//
|
|
|
|
// Leonardo Zide (leo@lokigames.com)
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef _WIN32
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
#include <gdk/gdkkeysyms.h>
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "groupdialog.h"
|
|
|
|
|
|
|
|
GtkWidget* EntWidgets[EntLast];
|
|
|
|
GtkListStore* g_entlist_store;
|
|
|
|
GtkListStore* g_entprops_store;
|
|
|
|
int inspector_mode; // W_TEXTURE, W_ENTITY, or W_CONSOLE
|
|
|
|
qboolean multiple_entities;
|
|
|
|
// http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=17
|
|
|
|
qboolean disable_spawn_get = false;
|
|
|
|
entity_t *edit_entity;
|
|
|
|
/*
|
|
|
|
static GdkPixmap *tree_pixmaps[7];
|
|
|
|
static GdkBitmap *tree_masks[7];
|
|
|
|
*/
|
|
|
|
#define IMG_PATCH 0
|
|
|
|
#define IMG_BRUSH 1
|
|
|
|
#define IMG_GROUP 2
|
|
|
|
#define IMG_ENTITY 3
|
|
|
|
#define IMG_ENTITYGROUP 4
|
|
|
|
#define IMG_MODEL 5
|
|
|
|
#define IMG_SCRIPT 6
|
|
|
|
|
|
|
|
// misc group support
|
|
|
|
#define MAX_GROUPS 4096
|
|
|
|
#define GROUP_DELIMETER '@'
|
|
|
|
#define GROUPNAME "QER_Group_%i"
|
|
|
|
|
|
|
|
GroupDlg g_wndGroup;
|
|
|
|
GroupDlg *g_pGroupDlg = &g_wndGroup;
|
|
|
|
|
|
|
|
// group_t are loaded / saved through "group_info" entities
|
|
|
|
// they hold epairs for group settings and additionnal access info (tree nodes)
|
|
|
|
group_t *g_pGroups = NULL;
|
|
|
|
|
|
|
|
// the number of active spawnflags
|
|
|
|
static int spawnflag_count;
|
|
|
|
// table: index, match spawnflag item to the spawnflag index (i.e. which bit)
|
|
|
|
static int spawn_table[MAX_FLAGS];
|
|
|
|
// we change the layout depending on how many spawn flags we need to display
|
|
|
|
// the table is a 4x4 in which we need to put the comment box EntWidgets[EntComment] and the spawn flags..
|
|
|
|
static GtkWidget *LayoutTable;
|
|
|
|
// 0: none of them are hooked
|
|
|
|
// 1: only the text, 2: text and four checks, 3: text and 8 checks
|
|
|
|
static int widget_state = 0;
|
|
|
|
|
|
|
|
static void entity_check (GtkWidget *widget, gpointer data);
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
// Global functions
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============================================================
|
|
|
|
|
|
|
|
ENTITY WINDOW
|
|
|
|
|
|
|
|
===============================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
void FillClassList ()
|
|
|
|
{
|
|
|
|
GtkListStore* store = g_entlist_store;
|
|
|
|
|
|
|
|
gtk_list_store_clear(store);
|
|
|
|
|
|
|
|
for (eclass_t* e = eclass ; e ; e = e->next)
|
|
|
|
{
|
|
|
|
GtkTreeIter iter;
|
|
|
|
gtk_list_store_append(store, &iter);
|
|
|
|
gtk_list_store_set(store, &iter, 0, e->name, 1, e, -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetKeyValuePairs
|
|
|
|
//
|
|
|
|
// Reset the key/value (aka property) listbox and fill it with the
|
|
|
|
// k/v pairs from the entity being edited.
|
|
|
|
//
|
|
|
|
|
|
|
|
void SetKeyValuePairs (bool bClearMD3)
|
|
|
|
{
|
|
|
|
GtkListStore* store = g_entprops_store;
|
|
|
|
|
|
|
|
gtk_list_store_clear(store);
|
|
|
|
|
|
|
|
if (edit_entity == NULL)
|
|
|
|
{
|
|
|
|
// if there's no entity, then display no key/values
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// save current key/val pair around filling epair box
|
|
|
|
// row_select wipes it and sets to first in list
|
|
|
|
Str strKey = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntKeyField]));
|
|
|
|
Str strVal = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntValueField]));
|
|
|
|
|
|
|
|
|
|
|
|
// Walk through list and add pairs
|
|
|
|
for(epair_t* epair = edit_entity->epairs ; epair ; epair = epair->next)
|
|
|
|
{
|
|
|
|
GtkTreeIter iter;
|
|
|
|
gtk_list_store_append(store, &iter);
|
|
|
|
gtk_list_store_set(store, &iter, 0, epair->key, 1, epair->value, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntKeyField]), strKey.GetBuffer());
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), strVal.GetBuffer());
|
|
|
|
|
|
|
|
Sys_UpdateWindows(W_CAMERA | W_XY);
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetSpawnFlags
|
|
|
|
//
|
|
|
|
// Update the checkboxes to reflect the flag state of the entity
|
|
|
|
//
|
|
|
|
void SetSpawnFlags(void)
|
|
|
|
{
|
|
|
|
int f, i, v;
|
|
|
|
|
|
|
|
disable_spawn_get = true;
|
|
|
|
|
|
|
|
f = atoi(ValueForKey (edit_entity, "spawnflags"));
|
|
|
|
for (i=0 ; i<spawnflag_count ; i++)
|
|
|
|
{
|
|
|
|
v = !!(f&(1<<spawn_table[i]));
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (EntWidgets[EntCheck1+i]), v);
|
|
|
|
}
|
|
|
|
// take care of the remaining ones
|
|
|
|
for (i=spawnflag_count ; i<MAX_FLAGS ; i++)
|
|
|
|
{
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (EntWidgets[EntCheck1+i]), FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
disable_spawn_get = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetSpawnFlags
|
|
|
|
//
|
|
|
|
// Update the entity flags to reflect the state of the checkboxes
|
|
|
|
//
|
|
|
|
// NOTE: this function had a tendency to add "spawnflags" "0" on most entities
|
|
|
|
// if this wants to set spawnflags to zero, remove the key
|
|
|
|
|
|
|
|
void GetSpawnFlags(void)
|
|
|
|
{
|
|
|
|
int f, i, v;
|
|
|
|
char sz[32];
|
|
|
|
|
|
|
|
f = 0;
|
|
|
|
for (i=0 ; i<spawnflag_count ; i++)
|
|
|
|
{
|
|
|
|
v = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (EntWidgets[EntCheck1+i]));
|
|
|
|
f |= v<<spawn_table[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (f==0)
|
|
|
|
{
|
|
|
|
// remove all "spawnflags" keys
|
|
|
|
if (multiple_entities)
|
|
|
|
{
|
|
|
|
brush_t *b;
|
|
|
|
|
|
|
|
for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
|
|
|
|
DeleteKey (b->owner, "spawnflags");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
DeleteKey (edit_entity, "spawnflags");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sprintf (sz, "%i", f);
|
|
|
|
if (multiple_entities)
|
|
|
|
{
|
|
|
|
brush_t *b;
|
|
|
|
|
|
|
|
for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
|
|
|
|
SetKeyValue(b->owner, "spawnflags", sz);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetKeyValue (edit_entity, "spawnflags", sz);
|
|
|
|
}
|
|
|
|
SetKeyValuePairs ();
|
|
|
|
}
|
|
|
|
|
|
|
|
//#define DBG_UPDATESEL
|
|
|
|
|
|
|
|
// UpdateSel
|
|
|
|
//
|
|
|
|
// Update the listbox, checkboxes and k/v pairs to reflect the new selection
|
|
|
|
// iIndex is the index in the list box with the class name, -1 if not found
|
|
|
|
bool UpdateSel(int iIndex, eclass_t *pec)
|
|
|
|
{
|
|
|
|
int i, next_state;
|
|
|
|
brush_t *b;
|
|
|
|
|
|
|
|
// syndrom of crappy code, we may get into stack overflowing crap with this function and Gtk
|
|
|
|
// if we play with the list of entity classes
|
|
|
|
// using a static flag to prevent recursion
|
|
|
|
static bool bBlockUpdate = false;
|
|
|
|
|
|
|
|
if (bBlockUpdate)
|
|
|
|
return FALSE; // NOTE TTimo wtf is the return value for anyway?
|
|
|
|
|
|
|
|
#ifdef DBG_UPDATESEL
|
|
|
|
Sys_FPrintf(SYS_WRN, "UpdateSel\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (selected_brushes.next == &selected_brushes)
|
|
|
|
{
|
|
|
|
edit_entity = world_entity;
|
|
|
|
multiple_entities = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
edit_entity = selected_brushes.next->owner;
|
|
|
|
for (b=selected_brushes.next->next ; b != &selected_brushes ; b=b->next)
|
|
|
|
{
|
|
|
|
if (b->owner != edit_entity)
|
|
|
|
{
|
|
|
|
multiple_entities = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (iIndex != -1)
|
|
|
|
{
|
|
|
|
#ifdef DBG_UPDATESEL
|
|
|
|
Sys_FPrintf(SYS_WRN,"Setting focus_row to %d\n", iIndex);
|
|
|
|
#endif
|
|
|
|
bBlockUpdate = true;
|
|
|
|
|
|
|
|
GtkTreeView* view = GTK_TREE_VIEW(EntWidgets[EntList]);
|
|
|
|
GtkTreePath* path = gtk_tree_path_new();
|
|
|
|
gtk_tree_path_append_index(path, iIndex);
|
|
|
|
gtk_tree_selection_select_path(gtk_tree_view_get_selection(view), path);
|
|
|
|
gtk_tree_view_scroll_to_cell(view, path, NULL, FALSE, 0, 0);
|
|
|
|
gtk_tree_path_free(path);
|
|
|
|
|
|
|
|
bBlockUpdate = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pec == NULL)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
// Set up the description
|
|
|
|
{
|
|
|
|
GtkTextBuffer* buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(EntWidgets[EntComment]));
|
|
|
|
gtk_text_buffer_set_text (buffer, pec->comments, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
spawnflag_count = 0;
|
|
|
|
|
|
|
|
// do a first pass to count the spawn flags, don't touch the widgets, we don't know in what state they are
|
|
|
|
for (i=0 ; i<MAX_FLAGS ; i++)
|
|
|
|
{
|
|
|
|
if (pec->flagnames[i] && pec->flagnames[i][0] != 0 && strcmp(pec->flagnames[i],"-"))
|
|
|
|
{
|
|
|
|
spawn_table[spawnflag_count] = i;
|
|
|
|
spawnflag_count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// what's new widget state
|
|
|
|
if (spawnflag_count==0)
|
|
|
|
next_state = 1;
|
|
|
|
else if (spawnflag_count<=4)
|
|
|
|
next_state = 2;
|
|
|
|
else if (spawnflag_count<=8)
|
|
|
|
next_state = 3;
|
|
|
|
else if (spawnflag_count<=12)
|
|
|
|
next_state = 4;
|
|
|
|
else
|
|
|
|
next_state = 5;
|
|
|
|
widget_state = next_state;
|
|
|
|
static int last_count = 0;
|
|
|
|
|
|
|
|
// disable all remaining boxes
|
|
|
|
// NOTE: these boxes might not even be on display
|
|
|
|
for (i = 0; i < last_count; i++)
|
|
|
|
{
|
|
|
|
GtkWidget* widget = EntWidgets[EntCheck1+i];
|
|
|
|
gtk_label_set_text (GTK_LABEL (GTK_BIN (widget)->child), " ");
|
|
|
|
gtk_widget_hide (widget);
|
|
|
|
gtk_widget_ref (widget);
|
|
|
|
gtk_container_remove (GTK_CONTAINER (LayoutTable), widget);
|
|
|
|
}
|
|
|
|
last_count = spawnflag_count;
|
|
|
|
|
|
|
|
for (i=0 ; i<spawnflag_count ; i++)
|
|
|
|
{
|
|
|
|
GtkWidget* widget = EntWidgets[EntCheck1+i];
|
|
|
|
gtk_widget_show (widget);
|
|
|
|
|
|
|
|
Str str;
|
|
|
|
str = pec->flagnames[spawn_table[i]];
|
|
|
|
str.MakeLower ();
|
|
|
|
|
|
|
|
// gtk_table_attach (GTK_TABLE (LayoutTable), widget, i%4, i%4+1, i/4, i/4+1,
|
|
|
|
gtk_table_attach (GTK_TABLE (LayoutTable), widget, i%4, i%4+1, i/4, i/4+1,
|
|
|
|
(GtkAttachOptions) (GTK_FILL),
|
|
|
|
(GtkAttachOptions) (GTK_FILL), 0, 0);
|
|
|
|
gtk_widget_unref (widget);
|
|
|
|
|
|
|
|
gtk_label_set_text (GTK_LABEL (GTK_BIN (widget)->child), str.GetBuffer ());
|
|
|
|
}
|
|
|
|
|
|
|
|
SetSpawnFlags();
|
|
|
|
|
|
|
|
SetKeyValuePairs();
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UpdateEntitySel(eclass_t *pec)
|
|
|
|
{
|
|
|
|
#ifdef DBG_UPDATESEL
|
|
|
|
Sys_FPrintf(SYS_WRN, "UpdateEntitySel\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
GtkTreeModel* model = GTK_TREE_MODEL(g_entlist_store);
|
|
|
|
GtkTreeIter iter;
|
|
|
|
unsigned int i = 0;
|
|
|
|
for(gboolean good = gtk_tree_model_get_iter_first(model, &iter); good != FALSE; good = gtk_tree_model_iter_next(model, &iter))
|
|
|
|
{
|
|
|
|
char* text;
|
|
|
|
gtk_tree_model_get(model, &iter, 0, &text, -1);
|
|
|
|
if (strcmp (text, pec->name) == 0)
|
|
|
|
{
|
|
|
|
#ifdef DBG_UPDATESEL
|
|
|
|
Sys_FPrintf(SYS_WRN, "found a match: %d %s\n", i, pec->name);
|
|
|
|
#endif
|
|
|
|
return UpdateSel (i, pec);
|
|
|
|
}
|
|
|
|
g_free(text);
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
return UpdateSel (-1, pec);
|
|
|
|
}
|
|
|
|
|
|
|
|
// CreateEntity
|
|
|
|
//
|
|
|
|
// Creates a new entity based on the currently selected brush and entity type.
|
|
|
|
//
|
|
|
|
|
|
|
|
void CreateEntity(void)
|
|
|
|
{
|
|
|
|
GtkTreeView* view = GTK_TREE_VIEW(EntWidgets[EntList]);
|
|
|
|
|
|
|
|
// check to make sure we have a brush
|
|
|
|
if (selected_brushes.next == &selected_brushes)
|
|
|
|
{
|
|
|
|
gtk_MessageBox(g_pParentWnd->m_pWidget, "You must have a selected brush to create an entity", "info");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// find out what type of entity we are trying to create
|
|
|
|
GtkTreeModel* model;
|
|
|
|
GtkTreeIter iter;
|
|
|
|
if(gtk_tree_selection_get_selected(gtk_tree_view_get_selection(view), &model, &iter) == FALSE)
|
|
|
|
{
|
|
|
|
gtk_MessageBox (g_pParentWnd->m_pWidget, "You must have a selected class to create an entity", "info");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* text;
|
|
|
|
gtk_tree_model_get(model, &iter, 0, &text, -1);
|
|
|
|
CreateEntityFromName(text, vec3_origin);
|
|
|
|
g_free(text);
|
|
|
|
|
|
|
|
if (selected_brushes.next == &selected_brushes)
|
|
|
|
edit_entity = world_entity;
|
|
|
|
else
|
|
|
|
edit_entity = selected_brushes.next->owner;
|
|
|
|
|
|
|
|
SetKeyValuePairs();
|
|
|
|
Select_Deselect ();
|
|
|
|
Select_Brush (edit_entity->brushes.onext);
|
|
|
|
Sys_UpdateWindows(W_ALL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============
|
|
|
|
AddProp
|
|
|
|
|
|
|
|
===============
|
|
|
|
*/
|
|
|
|
void AddProp()
|
|
|
|
{
|
|
|
|
if (edit_entity == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Get current selection text
|
|
|
|
const char* key = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntKeyField]));
|
|
|
|
const char* value = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntValueField]));
|
|
|
|
|
|
|
|
|
|
|
|
// TTimo: if you change the classname to worldspawn you won't merge back in the structural brushes but create a parasite entity
|
|
|
|
if (!strcmp(key, "classname") && !strcmp(value, "worldspawn"))
|
|
|
|
{
|
|
|
|
gtk_MessageBox(g_pParentWnd->m_pWidget, "Cannot change \"classname\" key back to worldspawn.", NULL, MB_OK );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// RR2DO2: we don't want spaces in entity keys
|
|
|
|
if (strstr( key, " " ))
|
|
|
|
{
|
|
|
|
gtk_MessageBox(g_pParentWnd->m_pWidget, "No spaces are allowed in entity keys.", NULL, MB_OK );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (multiple_entities)
|
|
|
|
{
|
|
|
|
brush_t *b;
|
|
|
|
|
|
|
|
for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
|
|
|
|
SetKeyValue(b->owner, key, value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetKeyValue(edit_entity, key, value);
|
|
|
|
|
|
|
|
// refresh the prop listbox
|
|
|
|
SetKeyValuePairs();
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef USEPLUGINENTITIES
|
|
|
|
// if it's a plugin entity, perhaps we need to update some drawing parameters
|
|
|
|
// NOTE: perhaps moving this code to a seperate func would help if we need it in other places
|
|
|
|
// TODO: we need to call some update func in the IPluginEntity in case model name changes etc.
|
|
|
|
// ( for the moment only bounding brush is updated ), see UpdateModelBrush in Ritual's Q3Radiant
|
|
|
|
if (edit_entity->eclass->nShowFlags & ECLASS_PLUGINENTITY)
|
|
|
|
{
|
|
|
|
vec3_t mins, maxs;
|
|
|
|
edit_entity->pPlugEnt->GetBounds( mins, maxs );
|
|
|
|
// replace old bounding brush by newly computed one
|
|
|
|
// NOTE: this part is similar to Entity_BuildModelBrush in Ritual's Q3Radiant, it can be
|
|
|
|
// usefull moved into a seperate func
|
|
|
|
brush_t *b,*oldbrush;
|
|
|
|
if (edit_entity->brushes.onext != &edit_entity->brushes)
|
|
|
|
oldbrush = edit_entity->brushes.onext;
|
|
|
|
b = Brush_Create (mins, maxs, &edit_entity->eclass->texdef);
|
|
|
|
Entity_LinkBrush (edit_entity, b);
|
|
|
|
Brush_Build( b, true );
|
|
|
|
Select_Deselect();
|
|
|
|
Brush_AddToList (edit_entity->brushes.onext, &selected_brushes);
|
|
|
|
if (oldbrush)
|
|
|
|
Brush_Free( oldbrush );
|
|
|
|
}
|
|
|
|
#endif // USEPLUGINENTITIES
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============
|
|
|
|
DelProp
|
|
|
|
|
|
|
|
===============
|
|
|
|
*/
|
|
|
|
void DelProp(void)
|
|
|
|
{
|
|
|
|
if (edit_entity == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Get current selection text
|
|
|
|
const char* key = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntKeyField]));
|
|
|
|
|
|
|
|
if (multiple_entities)
|
|
|
|
{
|
|
|
|
brush_t *b;
|
|
|
|
|
|
|
|
for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
|
|
|
|
DeleteKey(b->owner, key);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
DeleteKey(edit_entity, key);
|
|
|
|
|
|
|
|
// refresh the prop listbox
|
|
|
|
SetKeyValuePairs();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ResetEntity ()
|
|
|
|
{
|
|
|
|
epair_t *pep;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (edit_entity == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (multiple_entities)
|
|
|
|
{
|
|
|
|
brush_t *b;
|
|
|
|
|
|
|
|
for (b=selected_brushes.next; b != &selected_brushes; b=b->next)
|
|
|
|
for (pep = b->owner->epairs; pep; )
|
|
|
|
{
|
|
|
|
if (strcmp (pep->key, "classname") != 0)
|
|
|
|
{
|
|
|
|
DeleteKey (b->owner, pep->key);
|
|
|
|
pep = b->owner->epairs;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pep = pep->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
for (pep = edit_entity->epairs; pep; )
|
|
|
|
{
|
|
|
|
if (strcmp (pep->key, "classname") != 0)
|
|
|
|
{
|
|
|
|
DeleteKey (edit_entity, pep->key);
|
|
|
|
pep = edit_entity->epairs;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pep = pep->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
// refresh the dialog
|
|
|
|
SetKeyValuePairs ();
|
|
|
|
for (i = EntCheck1; i <= EntCheck16; i++)
|
|
|
|
gtk_signal_handler_block_by_func (GTK_OBJECT (EntWidgets[i]), GTK_SIGNAL_FUNC (entity_check), NULL);
|
|
|
|
SetSpawnFlags ();
|
|
|
|
for (i = EntCheck1; i <= EntCheck16; i++)
|
|
|
|
gtk_signal_handler_unblock_by_func (GTK_OBJECT (EntWidgets[i]), GTK_SIGNAL_FUNC (entity_check), NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetSelectAllCriteria(CString &strKey, CString &strVal)
|
|
|
|
{
|
|
|
|
GtkTreeModel* model;
|
|
|
|
GtkTreeIter iter;
|
|
|
|
if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(EntWidgets[EntProps])), &model, &iter)
|
|
|
|
&& (inspector_mode == W_ENTITY)
|
|
|
|
&& GTK_WIDGET_VISIBLE (g_pGroupDlg->m_pWidget))
|
|
|
|
{
|
|
|
|
strKey = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntKeyField]));
|
|
|
|
strVal = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntValueField]));
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AssignSound()
|
|
|
|
{
|
|
|
|
char buffer[NAME_MAX];
|
|
|
|
|
|
|
|
strcpy (buffer, g_qeglobals.m_strHomeMaps.GetBuffer());
|
|
|
|
strcat (buffer, "sound/");
|
|
|
|
|
|
|
|
if( access(buffer, R_OK) != 0 )
|
|
|
|
{
|
|
|
|
// just go to fsmain
|
|
|
|
strcpy (buffer, g_qeglobals.m_strHomeMaps.GetBuffer());
|
|
|
|
strcat (buffer, "/");
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *filename = file_dialog (g_pGroupDlg->m_pWidget, TRUE, "Open Wav File", buffer, "sound");
|
|
|
|
if (filename != NULL)
|
|
|
|
{
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntKeyField]), "noise");
|
|
|
|
char *aux = vfsExtractRelativePath (filename);
|
|
|
|
CString str;
|
|
|
|
if (aux)
|
|
|
|
str = aux;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Sys_FPrintf (SYS_WRN, "WARNING: could not extract the relative path, using full path instead\n");
|
|
|
|
str = filename;
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), str.GetBuffer());
|
|
|
|
AddProp();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AssignModel()
|
|
|
|
{
|
|
|
|
char buffer[NAME_MAX];
|
|
|
|
|
|
|
|
strcpy (buffer, g_qeglobals.m_strHomeMaps.GetBuffer());
|
|
|
|
strcat (buffer, "models/");
|
|
|
|
|
|
|
|
if( access(buffer, R_OK) != 0 )
|
|
|
|
{
|
|
|
|
// just go to fsmain
|
|
|
|
strcpy (buffer, g_qeglobals.m_strHomeMaps.GetBuffer());
|
|
|
|
strcat (buffer, "/");
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *filename = file_dialog (g_pGroupDlg->m_pWidget, TRUE, "Open Model", buffer, MODEL_MAJOR);
|
|
|
|
if (filename != NULL)
|
|
|
|
{
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntKeyField]), "model");
|
|
|
|
// use VFS to get the correct relative path
|
|
|
|
char *aux = vfsExtractRelativePath (filename);
|
|
|
|
CString str;
|
|
|
|
if (aux)
|
|
|
|
str = aux;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Sys_FPrintf (SYS_WRN, "WARNING: could not extract the relative path, using full path instead\n");
|
|
|
|
str = filename;
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), str.GetBuffer());
|
|
|
|
AddProp();
|
|
|
|
edit_entity->brushes.onext->bModelFailed = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
==============
|
|
|
|
SetInspectorMode
|
|
|
|
==============
|
|
|
|
*/
|
|
|
|
void SetInspectorMode(int iType)
|
|
|
|
{
|
|
|
|
if (iType == W_GROUP)
|
|
|
|
gtk_MessageBox(g_pParentWnd->m_pWidget, "Brush grouping is not functional yet", NULL, MB_OK | MB_ICONWARNING );
|
|
|
|
|
|
|
|
if (!g_pParentWnd->FloatingGroupDialog() &&
|
|
|
|
(iType == W_TEXTURE || iType == W_CONSOLE))
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Is the caller asking us to cycle to the next window?
|
|
|
|
if (iType == -1)
|
|
|
|
{
|
|
|
|
if (inspector_mode == W_ENTITY)
|
|
|
|
iType = W_TEXTURE;
|
|
|
|
else if (inspector_mode == W_TEXTURE)
|
|
|
|
iType = W_CONSOLE;
|
|
|
|
else if (inspector_mode == W_CONSOLE)
|
|
|
|
iType = W_GROUP;
|
|
|
|
else
|
|
|
|
iType = W_ENTITY;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(iType)
|
|
|
|
{
|
|
|
|
case W_ENTITY:
|
|
|
|
// entity is always first in the inspector
|
|
|
|
gtk_window_set_title (GTK_WINDOW (g_qeglobals_gui.d_entity), "Entities");
|
|
|
|
gtk_notebook_set_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), 0);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case W_TEXTURE:
|
|
|
|
g_pParentWnd->GetTexWnd()->FocusEdit();
|
|
|
|
gtk_window_set_title (GTK_WINDOW (g_qeglobals_gui.d_entity), "Textures");
|
|
|
|
if (g_pParentWnd->FloatingGroupDialog())
|
|
|
|
gtk_notebook_set_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), 1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case W_CONSOLE:
|
|
|
|
gtk_window_set_title (GTK_WINDOW (g_qeglobals_gui.d_entity), "Console");
|
|
|
|
if (g_pParentWnd->FloatingGroupDialog())
|
|
|
|
gtk_notebook_set_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), 2);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case W_GROUP:
|
|
|
|
if (g_pParentWnd->FloatingGroupDialog())
|
|
|
|
gtk_notebook_set_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), 3);
|
|
|
|
else
|
|
|
|
gtk_notebook_set_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), 1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Group_Add(entity_t *e)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
group_t *g = (group_t*)qmalloc(sizeof(group_t));
|
|
|
|
g->epairs = e->epairs;
|
|
|
|
g->next = NULL;
|
|
|
|
e->epairs = NULL;
|
|
|
|
|
|
|
|
// create a new group node
|
|
|
|
char *text = ValueForKey(g->epairs, "group");
|
|
|
|
g->itemOwner = gtk_ctree_insert_node (GTK_CTREE (g_wndGroup.m_pTree), g_wndGroup.m_hWorld, NULL, &text, 0,
|
|
|
|
tree_pixmaps[IMG_GROUP], tree_masks[IMG_GROUP],
|
|
|
|
tree_pixmaps[IMG_GROUP], tree_masks[IMG_GROUP], TRUE, TRUE);
|
|
|
|
g->next = g_pGroups;
|
|
|
|
g_pGroups = g;
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
group_t* Group_Alloc(char *name)
|
|
|
|
{
|
|
|
|
group_t *g = (group_t*)qmalloc(sizeof(group_t));
|
|
|
|
SetKeyValue( g->epairs, "group", name );
|
|
|
|
return g;
|
|
|
|
}
|
|
|
|
|
|
|
|
group_t* Group_ForName(const char * name)
|
|
|
|
{
|
|
|
|
group_t *g = g_pGroups;
|
|
|
|
while (g != NULL)
|
|
|
|
{
|
|
|
|
if (strcmp( ValueForKey(g->epairs,"group"), name ) == 0)
|
|
|
|
break;
|
|
|
|
g = g->next;
|
|
|
|
}
|
|
|
|
return g;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Group_AddToItem(brush_t *b, GtkCTreeNode* item)
|
|
|
|
{
|
|
|
|
int nImage = IMG_BRUSH;
|
|
|
|
if (!g_qeglobals.m_bBrushPrimitMode)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const char *pName = NULL;
|
|
|
|
// const char *pNamed = Brush_GetKeyValue(b, "name");
|
|
|
|
|
|
|
|
if (!b->owner || (b->owner == world_entity))
|
|
|
|
{
|
|
|
|
if (b->patchBrush)
|
|
|
|
{
|
|
|
|
pName = "Generic Patch";
|
|
|
|
nImage = IMG_PATCH;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pName = "Generic Brush";
|
|
|
|
nImage = IMG_BRUSH;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pName = b->owner->eclass->name;
|
|
|
|
if (b->owner->eclass->fixedsize)
|
|
|
|
{
|
|
|
|
nImage = IMG_ENTITY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nImage = IMG_ENTITYGROUP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GtkCTreeNode *newItem;
|
|
|
|
int i = (b->patchBrush) ? IMG_PATCH : IMG_BRUSH;
|
|
|
|
newItem = gtk_ctree_insert_node (GTK_CTREE (g_wndGroup.m_pTree), item, NULL, (gchar**)&pName, 0,
|
|
|
|
tree_pixmaps[i], tree_masks[i], tree_pixmaps[i],
|
|
|
|
tree_masks[i], TRUE, TRUE);
|
|
|
|
gtk_ctree_node_set_row_data (GTK_CTREE (g_wndGroup.m_pTree), newItem, b);
|
|
|
|
b->itemOwner = newItem;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
void Group_RemoveBrush(brush_t *b)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
if (!g_qeglobals.m_bBrushPrimitMode)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (b->itemOwner)
|
|
|
|
{
|
|
|
|
gtk_ctree_remove_node (GTK_CTREE (g_pGroupDlg->m_pTree), b->itemOwner);
|
|
|
|
b->itemOwner = NULL;
|
|
|
|
}
|
|
|
|
DeleteKey(b->epairs, "group");
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
void Group_AddToWorld(brush_t *b)
|
|
|
|
{
|
|
|
|
if (!g_qeglobals.m_bBrushPrimitMode)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
GtkCTreeNode *parent = gtk_ctree_node_nth (GTK_CTREE (g_pGroupDlg->m_pTree), 0);
|
|
|
|
Group_AddToItem(b, parent);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
void Group_AddToProperGroup(brush_t *b)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
if (!g_qeglobals.m_bBrushPrimitMode)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: we do a local copy of the "group" key because it gets erased by Group_RemoveBrush
|
|
|
|
const char *pGroup = Brush_GetKeyValue(b, "group");
|
|
|
|
// remove the entry in the tree if there's one
|
|
|
|
if (b->itemOwner)
|
|
|
|
{
|
|
|
|
gtk_ctree_remove_node (GTK_CTREE (g_pGroupDlg->m_pTree), b->itemOwner);
|
|
|
|
b->itemOwner = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*pGroup != 0)
|
|
|
|
{
|
|
|
|
// find the item
|
|
|
|
group_t *g = Group_ForName(pGroup);
|
|
|
|
if (g)
|
|
|
|
Group_AddToItem(b, g->itemOwner);
|
|
|
|
#ifdef _DEBUG
|
|
|
|
else
|
|
|
|
Sys_Printf("WARNING: unexpected Group_ForName not found in Group_AddToProperGroup\n");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Group_AddToWorld(b);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
void Group_AddToSelected(brush_t *b)
|
|
|
|
{
|
|
|
|
if (!g_qeglobals.m_bBrushPrimitMode)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
GtkCTreeNode *item;
|
|
|
|
item = gtk_ctree_node_nth (GTK_CTREE (g_pGroupDlg->m_pTree), GTK_CLIST (g_pGroupDlg->m_pTree)->focus_row);
|
|
|
|
if (item == NULL)
|
|
|
|
{
|
|
|
|
item = gtk_ctree_node_nth (GTK_CTREE (g_pGroupDlg->m_pTree), 0);
|
|
|
|
}
|
|
|
|
Group_AddToItem(b, item);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
void Group_Save(FILE *f)
|
|
|
|
{
|
|
|
|
group_t *g = g_pGroups;
|
|
|
|
while (g)
|
|
|
|
{
|
|
|
|
fprintf(f,"{\n\"classname\" \"group_info\"\n\"group\" \"%s\"\n}\n", ValueForKey( g->epairs, "group" ));
|
|
|
|
g = g->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
void Group_Init()
|
|
|
|
{
|
|
|
|
if (!g_qeglobals.m_bBrushPrimitMode)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// start by cleaning everything
|
|
|
|
// clean the groups
|
|
|
|
//++timo FIXME: we leak, delete the groups on the way (I don't have time to do it now)
|
|
|
|
#ifdef _DEBUG
|
|
|
|
Sys_Printf("TODO: fix leak in Group_Init\n");
|
|
|
|
#endif
|
|
|
|
group_t *g = g_pGroups;
|
|
|
|
while (g)
|
|
|
|
{
|
|
|
|
epair_t *ep,*enext;
|
|
|
|
for (ep = g->epairs ; ep ; ep=enext )
|
|
|
|
{
|
|
|
|
enext = ep->next;
|
|
|
|
free (ep->key);
|
|
|
|
free (ep->value);
|
|
|
|
free (ep);
|
|
|
|
}
|
|
|
|
g = g->next;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
GtkCTreeNode *world;
|
|
|
|
char *text = "World";
|
|
|
|
g_pGroups = NULL;
|
|
|
|
gtk_clist_clear (GTK_CLIST (g_wndGroup.m_pTree));
|
|
|
|
world = gtk_ctree_insert_node (GTK_CTREE (g_wndGroup.m_pTree), NULL, NULL, &text, 0,
|
|
|
|
tree_pixmaps[IMG_GROUP], tree_masks[IMG_GROUP], tree_pixmaps[IMG_GROUP],
|
|
|
|
tree_masks[IMG_GROUP], FALSE, TRUE);
|
|
|
|
*/
|
|
|
|
// walk through all the brushes, remove the itemOwner key and add them back where they belong
|
|
|
|
brush_t *b;
|
|
|
|
for (b = active_brushes.next; b != &active_brushes; b = b->next)
|
|
|
|
{
|
|
|
|
b->itemOwner = NULL;
|
|
|
|
Group_AddToProperGroup(b);
|
|
|
|
}
|
|
|
|
for (b = selected_brushes.next ; b != &selected_brushes ; b = b->next)
|
|
|
|
{
|
|
|
|
b->itemOwner = NULL;
|
|
|
|
Group_AddToProperGroup(b);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
// scan through world_entity for groups in this map?
|
|
|
|
// we use GROUPNAME "QER_group_%i" to look for existing groups and their naming
|
|
|
|
//++timo FIXME: is this actually needed for anything?
|
|
|
|
void Group_GetListFromWorld(GSList **pArray)
|
|
|
|
{
|
|
|
|
if (!g_qeglobals.m_bBrushPrimitMode)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (world_entity == NULL)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
char cBuff[1024];
|
|
|
|
for (int i =0; i < MAX_GROUPS; i++)
|
|
|
|
{
|
|
|
|
sprintf(cBuff, GROUPNAME, i);
|
|
|
|
char *pGroup = ValueForKey(world_entity, cBuff);
|
|
|
|
if (pGroup && strlen(pGroup) > 0)
|
|
|
|
{
|
|
|
|
*pArray = g_slist_append (*pArray, g_strdup (pGroup));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Group_RemoveListFromWorld()
|
|
|
|
{
|
|
|
|
if (!g_qeglobals.m_bBrushPrimitMode)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
GSList* array = NULL;
|
|
|
|
Group_GetListFromWorld(&array);
|
|
|
|
|
|
|
|
while (array)
|
|
|
|
{
|
|
|
|
DeleteKey(world_entity, (char*)array->data);
|
|
|
|
g_free (array->data);
|
|
|
|
array = g_slist_remove (array, array->data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int CountChar(const char *p, char c)
|
|
|
|
{
|
|
|
|
int nCount = 0;
|
|
|
|
int nLen = strlen(p)-1;
|
|
|
|
while (nLen-- >= 0)
|
|
|
|
{
|
|
|
|
if (p[nLen] == c)
|
|
|
|
{
|
|
|
|
nCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nCount;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
// =============================================================================
|
|
|
|
// callbacks
|
|
|
|
|
|
|
|
static void eclasslist_selection_changed(GtkTreeSelection* selection, gpointer data)
|
|
|
|
{
|
|
|
|
GtkTreeModel* model;
|
|
|
|
GtkTreeIter selected;
|
|
|
|
// no world entity, we are not ready yet
|
|
|
|
// http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=917
|
|
|
|
if( !world_entity ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(gtk_tree_selection_get_selected(selection, &model, &selected))
|
|
|
|
{
|
|
|
|
eclass_t* eclass;
|
|
|
|
gtk_tree_model_get(model, &selected, 1, &eclass, -1);
|
|
|
|
if(eclass != NULL)
|
|
|
|
{
|
|
|
|
GtkTreePath* path = gtk_tree_model_get_path(model, &selected);
|
|
|
|
UpdateSel(gtk_tree_path_get_indices(path)[0], eclass);
|
|
|
|
gtk_tree_path_free(path);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint eclasslist_button_press (GtkWidget *widget, GdkEventButton *event, gpointer data)
|
|
|
|
{
|
|
|
|
if (event->type == GDK_2BUTTON_PRESS)
|
|
|
|
{
|
|
|
|
CreateEntity ();
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint eclasslist_keypress (GtkWidget* widget, GdkEventKey* event, gpointer data)
|
|
|
|
{
|
|
|
|
unsigned int code = gdk_keyval_to_upper (event->keyval);
|
|
|
|
|
|
|
|
if (event->keyval == GDK_Return)
|
|
|
|
{
|
|
|
|
CreateEntity ();
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// select the entity that starts with the key pressed
|
|
|
|
if (code <= 'Z' && code >= 'A')
|
|
|
|
{
|
|
|
|
GtkTreeView* view = GTK_TREE_VIEW(EntWidgets[EntList]);
|
|
|
|
GtkTreeModel* model;
|
|
|
|
GtkTreeIter iter;
|
|
|
|
if(gtk_tree_selection_get_selected(gtk_tree_view_get_selection(view), &model, &iter) == FALSE
|
|
|
|
|| gtk_tree_model_iter_next(model, &iter) == FALSE)
|
|
|
|
{
|
|
|
|
gtk_tree_model_get_iter_first(model, &iter);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(unsigned int count = gtk_tree_model_iter_n_children(model, NULL); count > 0; --count)
|
|
|
|
{
|
|
|
|
char* text;
|
|
|
|
gtk_tree_model_get(model, &iter, 0, &text, -1);
|
|
|
|
|
|
|
|
if (toupper (text[0]) == (int)code)
|
|
|
|
{
|
|
|
|
GtkTreePath* path = gtk_tree_model_get_path(model, &iter);
|
|
|
|
gtk_tree_selection_select_path(gtk_tree_view_get_selection(view), path);
|
|
|
|
gtk_tree_view_scroll_to_cell(view, path, NULL, FALSE, 0, 0);
|
|
|
|
gtk_tree_path_free(path);
|
|
|
|
count = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(text);
|
|
|
|
|
|
|
|
if(gtk_tree_model_iter_next(model, &iter) == FALSE)
|
|
|
|
gtk_tree_model_get_iter_first(model, &iter);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void proplist_selection_changed(GtkTreeSelection* selection, gpointer data)
|
|
|
|
{
|
|
|
|
// find out what type of entity we are trying to create
|
|
|
|
GtkTreeModel* model;
|
|
|
|
GtkTreeIter iter;
|
|
|
|
if(gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* key;
|
|
|
|
char* val;
|
|
|
|
gtk_tree_model_get(model, &iter, 0, &key, 1, &val, -1);
|
|
|
|
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntKeyField]), key);
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), val);
|
|
|
|
|
|
|
|
g_free(key);
|
|
|
|
g_free(val);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void entity_check (GtkWidget *widget, gpointer data)
|
|
|
|
{
|
|
|
|
if( !disable_spawn_get )
|
|
|
|
GetSpawnFlags();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void entitylist_angle (GtkWidget *widget, gpointer data)
|
|
|
|
{
|
|
|
|
SetKeyValue (edit_entity, "angle", (char*)data);
|
|
|
|
SetKeyValuePairs ();
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint entityentry_keypress (GtkWidget* widget, GdkEventKey* event, gpointer data)
|
|
|
|
{
|
|
|
|
if (event->keyval == GDK_Tab)
|
|
|
|
{
|
|
|
|
if (widget == EntWidgets[EntKeyField])
|
|
|
|
{
|
|
|
|
//gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), "");
|
|
|
|
gtk_window_set_focus (GTK_WINDOW (g_pGroupDlg->m_pWidget), EntWidgets[EntValueField]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gtk_window_set_focus (GTK_WINDOW (g_pGroupDlg->m_pWidget), EntWidgets[EntKeyField]);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else if (event->keyval == GDK_Return)
|
|
|
|
{
|
|
|
|
if (widget == EntWidgets[EntKeyField])
|
|
|
|
{
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), "");
|
|
|
|
gtk_window_set_focus (GTK_WINDOW (g_pGroupDlg->m_pWidget), EntWidgets[EntValueField]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
AddProp ();
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
// add a new group, put all selected brushes into the group
|
|
|
|
static void groupdlg_add (GtkWidget *widget, gpointer data)
|
|
|
|
{
|
|
|
|
char* name = DoNameDlg ("New Group");
|
|
|
|
|
|
|
|
if (name != NULL)
|
|
|
|
{
|
|
|
|
// create a new group node
|
|
|
|
GtkCTreeNode *item;
|
|
|
|
item = gtk_ctree_insert_node (GTK_CTREE (g_wndGroup.m_pTree), g_pGroupDlg->m_hWorld, NULL, &name, 0,
|
|
|
|
tree_pixmaps[IMG_GROUP], tree_masks[IMG_GROUP],
|
|
|
|
tree_pixmaps[IMG_GROUP], tree_masks[IMG_GROUP], FALSE, TRUE);
|
|
|
|
|
|
|
|
// create a new group
|
|
|
|
group_t *g = Group_Alloc (name);
|
|
|
|
g->itemOwner = item;
|
|
|
|
g->next = g_pGroups;
|
|
|
|
g_pGroups = g;
|
|
|
|
|
|
|
|
// now add the selected brushes
|
|
|
|
// NOTE: it would be much faster to give the group_t for adding
|
|
|
|
// but Select_AddToGroup is the standard way for all other cases
|
|
|
|
Select_AddToGroup (name);
|
|
|
|
g_free (name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
static void switch_page (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer data)
|
|
|
|
{
|
|
|
|
char *text;
|
|
|
|
gtk_label_get(GTK_LABEL(gtk_notebook_get_tab_label(notebook, gtk_notebook_get_nth_page(notebook, page_num))), &text);
|
|
|
|
gtk_window_set_title (GTK_WINDOW (data), text);
|
|
|
|
|
|
|
|
gpointer item = g_object_get_data (G_OBJECT (g_pParentWnd->m_pWidget), "menu_misc_selectentitycolor");
|
|
|
|
|
|
|
|
if (g_pParentWnd->FloatingGroupDialog())
|
|
|
|
{
|
|
|
|
switch (page_num)
|
|
|
|
{
|
|
|
|
case 0: inspector_mode = W_ENTITY; break;
|
|
|
|
case 1: inspector_mode = W_TEXTURE; break;
|
|
|
|
case 2: inspector_mode = W_CONSOLE; break;
|
|
|
|
default: inspector_mode = W_GROUP; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (page_num == 0)
|
|
|
|
inspector_mode = W_ENTITY;
|
|
|
|
else
|
|
|
|
inspector_mode = W_GROUP;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (inspector_mode == W_ENTITY)
|
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (item), TRUE);
|
|
|
|
else
|
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
// GroupDlg class
|
|
|
|
|
|
|
|
// NOTE: when a key is hit with group window focused, we catch in this handler but it gets propagated to mainframe too
|
|
|
|
// therefore the message will be intercepted and used as a ID_SELECTION_DESELECT
|
|
|
|
static gint OnDialogKey (GtkWidget* widget, GdkEventKey* event, gpointer data)
|
|
|
|
{
|
|
|
|
#ifdef DBG_PI
|
|
|
|
Sys_Printf("OnDialogKey\n");
|
|
|
|
#endif
|
|
|
|
if ((event->keyval == GDK_Escape) && (g_pParentWnd->CurrentStyle() != MainFrame::eFloating))
|
|
|
|
{
|
|
|
|
// toggle off the group view (whatever part of it is currently displayed)
|
|
|
|
// this used to be done with a g_pParentWnd->OnViewEntity(); but it had bad consequences
|
|
|
|
// http://fenris.lokigames.com/show_bug.cgi?id=2773
|
|
|
|
widget_delete_hide (g_qeglobals_gui.d_entity);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
GroupDlg::GroupDlg ()
|
|
|
|
{
|
|
|
|
m_pWidget = NULL;
|
|
|
|
m_hWorld = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
extern void PositionWindowOnPrimaryScreen(window_position_t& position);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void GroupDlg::Create ()
|
|
|
|
{
|
|
|
|
if (m_pWidget != NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
GtkWidget* dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
if( g_PrefsDlg.m_bStartOnPrimMon ) {
|
|
|
|
PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.posEntityWnd );
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
load_window_pos (dlg, g_PrefsDlg.mWindowInfo.posEntityWnd);
|
|
|
|
|
|
|
|
gtk_window_set_title (GTK_WINDOW (dlg), "Entities");
|
|
|
|
gtk_signal_connect (GTK_OBJECT (dlg), "delete_event", GTK_SIGNAL_FUNC (widget_delete_hide), NULL);
|
|
|
|
// catch 'Esc'
|
|
|
|
gtk_signal_connect (GTK_OBJECT (dlg), "key_press_event", GTK_SIGNAL_FUNC (OnDialogKey), NULL);
|
|
|
|
gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (g_pParentWnd->m_pWidget));
|
|
|
|
g_qeglobals_gui.d_entity = dlg;
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* notebook = gtk_notebook_new ();
|
|
|
|
gtk_widget_show (notebook);
|
|
|
|
gtk_container_add (GTK_CONTAINER (dlg), notebook);
|
|
|
|
gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_BOTTOM);
|
|
|
|
m_pNotebook = notebook;
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* vbox = gtk_vbox_new (FALSE, 2);
|
|
|
|
gtk_widget_show (vbox);
|
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* label = gtk_label_new ("Entities");
|
|
|
|
gtk_widget_show (label);
|
|
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, label);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* split1 = gtk_vpaned_new ();
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), split1, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show (split1);
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* split2 = gtk_vpaned_new ();
|
|
|
|
gtk_paned_add1 (GTK_PANED (split1), split2);
|
|
|
|
gtk_widget_show (split2);
|
|
|
|
|
|
|
|
g_object_set_data (G_OBJECT (dlg), "split1", split1);
|
|
|
|
g_object_set_data (G_OBJECT (dlg), "split2", split2);
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* vbox2 = gtk_vbox_new (FALSE, 2);
|
|
|
|
gtk_widget_show (vbox2);
|
|
|
|
gtk_paned_pack2 (GTK_PANED (split1), vbox2, FALSE, FALSE);
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* scr = gtk_scrolled_window_new (NULL, NULL);
|
|
|
|
gtk_widget_show (scr);
|
|
|
|
gtk_paned_add1 (GTK_PANED (split2), scr);
|
|
|
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
|
|
|
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkListStore* store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
|
|
|
|
|
|
|
|
GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
|
|
|
|
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
|
|
|
|
g_signal_connect(G_OBJECT(view), "button_press_event", G_CALLBACK(eclasslist_button_press), NULL);
|
|
|
|
g_signal_connect(G_OBJECT(view), "key_press_event", G_CALLBACK(eclasslist_keypress), this);
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
|
|
|
|
GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("Key", renderer, "text", 0, NULL);
|
|
|
|
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
|
|
|
|
g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(eclasslist_selection_changed), dlg);
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_widget_show(view);
|
|
|
|
|
|
|
|
gtk_container_add(GTK_CONTAINER (scr), view);
|
|
|
|
|
|
|
|
g_object_unref(G_OBJECT(store));
|
|
|
|
EntWidgets[EntList] = view;
|
|
|
|
g_entlist_store = store;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* scr = gtk_scrolled_window_new (NULL, NULL);
|
|
|
|
gtk_widget_show (scr);
|
|
|
|
gtk_paned_add2 (GTK_PANED (split2), scr);
|
|
|
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
|
|
|
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* text = gtk_text_view_new();
|
|
|
|
gtk_widget_set_size_request(text, 0, -1); // allow shrinking
|
|
|
|
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
|
|
|
|
gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
|
|
|
|
gtk_widget_show (text);
|
|
|
|
gtk_container_add (GTK_CONTAINER (scr), text);
|
|
|
|
EntWidgets[EntComment] = text;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
// Spawnflags (4 colums wide max, or window gets too wide.)
|
|
|
|
GtkWidget* table = LayoutTable = gtk_table_new (4, 4, FALSE);
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox2), LayoutTable, FALSE, TRUE, 0);
|
|
|
|
gtk_widget_show(LayoutTable);
|
|
|
|
|
|
|
|
for (int i = 0; i < MAX_FLAGS; i++)
|
|
|
|
{
|
|
|
|
GtkWidget* check = gtk_check_button_new_with_label ("");
|
|
|
|
gtk_widget_ref (check);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (check), "toggled", GTK_SIGNAL_FUNC (entity_check), NULL);
|
|
|
|
EntWidgets[EntCheck1+i] = check;
|
|
|
|
}
|
|
|
|
|
|
|
|
//++timo cleanme: these flags where Q2 stuff
|
|
|
|
/*
|
|
|
|
check = gtk_check_button_new_with_label ("!Easy");
|
|
|
|
gtk_widget_show (check);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (check), "toggled", GTK_SIGNAL_FUNC (entity_check), NULL);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), check, 2, 3, 0, 1,
|
|
|
|
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
|
|
|
|
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
|
|
|
|
EntWidgets[EntCheck17] = check;
|
|
|
|
|
|
|
|
check = gtk_check_button_new_with_label ("!Medium");
|
|
|
|
gtk_widget_show (check);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (check), "toggled", GTK_SIGNAL_FUNC (entity_check), NULL);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), check, 2, 3, 1, 2,
|
|
|
|
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
|
|
|
|
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
|
|
|
|
EntWidgets[EntCheck18] = check;
|
|
|
|
|
|
|
|
check = gtk_check_button_new_with_label ("!Hard");
|
|
|
|
gtk_widget_show (check);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (check), "toggled", GTK_SIGNAL_FUNC (entity_check), NULL);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), check, 2, 3, 2, 3,
|
|
|
|
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
|
|
|
|
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
|
|
|
|
EntWidgets[EntCheck19] = check;
|
|
|
|
|
|
|
|
check = gtk_check_button_new_with_label ("!DeathMatch");
|
|
|
|
gtk_widget_show (check);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (check), "toggled", GTK_SIGNAL_FUNC (entity_check), NULL);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), check, 2, 3, 3, 4,
|
|
|
|
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
|
|
|
|
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
|
|
|
|
EntWidgets[EntCheck20] = check;
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* scr = gtk_scrolled_window_new (NULL, NULL);
|
|
|
|
gtk_widget_show (scr);
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox2), scr, TRUE, TRUE, 0);
|
|
|
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
|
|
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkListStore* store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
|
|
|
|
|
|
|
|
GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
|
|
|
|
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
|
|
|
|
GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
|
|
|
|
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
|
|
|
|
GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 1, NULL);
|
|
|
|
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
|
|
|
|
g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(proplist_selection_changed), dlg);
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_widget_show(view);
|
|
|
|
|
|
|
|
gtk_container_add(GTK_CONTAINER (scr), view);
|
|
|
|
|
|
|
|
g_object_unref(G_OBJECT(store));
|
|
|
|
|
|
|
|
EntWidgets[EntProps] = view;
|
|
|
|
g_entprops_store = store;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int x = g_PrefsDlg.mWindowInfo.nEntitySplit1;
|
|
|
|
if (x != -1)
|
|
|
|
{
|
|
|
|
gtk_paned_set_position (GTK_PANED (split1), x);
|
|
|
|
|
|
|
|
while (gtk_events_pending ()) gtk_main_iteration ();
|
|
|
|
x = g_PrefsDlg.mWindowInfo.nEntitySplit2;
|
|
|
|
|
|
|
|
if (x != -1)
|
|
|
|
gtk_paned_set_position (GTK_PANED (split2), x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* table = gtk_table_new (2, 2, FALSE);
|
|
|
|
gtk_widget_show (table);
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
|
|
|
|
gtk_table_set_row_spacings (GTK_TABLE (table), 3);
|
|
|
|
gtk_table_set_col_spacings (GTK_TABLE (table), 5);
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* entry = gtk_entry_new ();
|
|
|
|
gtk_widget_show (entry);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
|
|
|
|
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
|
|
|
|
(GtkAttachOptions) (0), 0, 0);
|
|
|
|
gtk_widget_set_events (entry, GDK_KEY_PRESS_MASK);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (entry), "key_press_event",
|
|
|
|
GTK_SIGNAL_FUNC (entityentry_keypress), this);
|
|
|
|
EntWidgets[EntKeyField] = entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* entry = gtk_entry_new ();
|
|
|
|
gtk_widget_show (entry);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2,
|
|
|
|
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
|
|
|
|
(GtkAttachOptions) (0), 0, 0);
|
|
|
|
gtk_widget_set_events (entry, GDK_KEY_PRESS_MASK);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (entry), "key_press_event",
|
|
|
|
GTK_SIGNAL_FUNC (entityentry_keypress), this);
|
|
|
|
EntWidgets[EntValueField] = entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* label = gtk_label_new ("Value");
|
|
|
|
gtk_widget_show (label);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
|
|
|
|
(GtkAttachOptions) (GTK_FILL),
|
|
|
|
(GtkAttachOptions) (0), 0, 0);
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* label = gtk_label_new ("Key");
|
|
|
|
gtk_widget_show (label);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
|
|
|
|
(GtkAttachOptions) (GTK_FILL),
|
|
|
|
(GtkAttachOptions) (0), 0, 0);
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* hbox = gtk_hbox_new (FALSE, 5);
|
|
|
|
gtk_widget_show (hbox);
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* table = gtk_table_new (3, 3, TRUE);
|
|
|
|
gtk_widget_show (table);
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), table, FALSE, TRUE, 0);
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* button = gtk_button_new_with_label ("360");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"360");
|
|
|
|
gtk_table_attach (GTK_TABLE (table), button, 2, 3, 1, 2,
|
|
|
|
(GtkAttachOptions) (GTK_FILL),
|
|
|
|
(GtkAttachOptions) (GTK_FILL), 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* button = gtk_button_new_with_label ("45");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"45");
|
|
|
|
gtk_table_attach (GTK_TABLE (table), button, 2, 3, 0, 1,
|
|
|
|
(GtkAttachOptions) (GTK_FILL),
|
|
|
|
(GtkAttachOptions) (GTK_FILL), 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* button = gtk_button_new_with_label ("90");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"90");
|
|
|
|
gtk_table_attach (GTK_TABLE (table), button, 1, 2, 0, 1,
|
|
|
|
(GtkAttachOptions) (GTK_FILL),
|
|
|
|
(GtkAttachOptions) (GTK_FILL), 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* button = gtk_button_new_with_label ("135");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"135");
|
|
|
|
gtk_table_attach (GTK_TABLE (table), button, 0, 1, 0, 1,
|
|
|
|
(GtkAttachOptions) (GTK_FILL),
|
|
|
|
(GtkAttachOptions) (GTK_FILL), 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* button = gtk_button_new_with_label ("180");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"180");
|
|
|
|
gtk_table_attach (GTK_TABLE (table), button, 0, 1, 1, 2,
|
|
|
|
(GtkAttachOptions) (GTK_FILL),
|
|
|
|
(GtkAttachOptions) (GTK_FILL), 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* button = gtk_button_new_with_label ("225");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"225");
|
|
|
|
gtk_table_attach (GTK_TABLE (table), button, 0, 1, 2, 3,
|
|
|
|
(GtkAttachOptions) (GTK_FILL),
|
|
|
|
(GtkAttachOptions) (GTK_FILL), 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* button = gtk_button_new_with_label ("270");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"270");
|
|
|
|
gtk_table_attach (GTK_TABLE (table), button, 1, 2, 2, 3,
|
|
|
|
(GtkAttachOptions) (GTK_FILL),
|
|
|
|
(GtkAttachOptions) (GTK_FILL), 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* button = gtk_button_new_with_label ("315");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"315");
|
|
|
|
gtk_table_attach (GTK_TABLE (table), button, 2, 3, 2, 3,
|
|
|
|
(GtkAttachOptions) (GTK_FILL),
|
|
|
|
(GtkAttachOptions) (GTK_FILL), 0, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* vbox2 = gtk_vbox_new (FALSE, 0);
|
|
|
|
gtk_widget_show (vbox2);
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* button = gtk_button_new_with_label ("Reset");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (ResetEntity), NULL);
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* button = gtk_button_new_with_label ("Up");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"-1");
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* button = gtk_button_new_with_label ("Dn");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"-2");
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* vbox2 = gtk_vbox_new (FALSE, 0);
|
|
|
|
gtk_widget_show (vbox2);
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* button = gtk_button_new_with_label ("Del Key/Pair");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (DelProp), NULL);
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* button = gtk_button_new_with_label ("Sound...");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (AssignSound), NULL);
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* button = gtk_button_new_with_label ("Model...");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (AssignModel), NULL);
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_pParentWnd->FloatingGroupDialog())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
GtkWidget* scr = gtk_scrolled_window_new (NULL, NULL);
|
|
|
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
|
|
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);
|
|
|
|
gtk_widget_show (scr);
|
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (scr), 3);
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* text = gtk_text_view_new ();
|
|
|
|
gtk_widget_set_size_request(text, 0, -1); // allow shrinking
|
|
|
|
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
|
|
|
|
gtk_text_view_set_editable (GTK_TEXT_VIEW(text), FALSE);
|
|
|
|
gtk_container_add (GTK_CONTAINER (scr), text);
|
|
|
|
gtk_widget_show (text);
|
|
|
|
g_qeglobals_gui.d_edit = text;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
GtkWidget* label = gtk_label_new ("Console");
|
|
|
|
gtk_widget_show (label);
|
|
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scr, label);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++timo NOTE: this part for grouping code, don't remove! (we'll put it back in sometime soon)
|
|
|
|
|
|
|
|
/*
|
|
|
|
vbox = gtk_vbox_new (FALSE, 5);
|
|
|
|
gtk_widget_show (vbox);
|
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (vbox), 3);
|
|
|
|
|
|
|
|
scr = gtk_scrolled_window_new (NULL, NULL);
|
|
|
|
gtk_widget_show (scr);
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), scr, TRUE, TRUE, 0);
|
|
|
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
|
|
|
|
|
|
|
ctree = gtk_ctree_new (1, 0);
|
|
|
|
gtk_widget_show (ctree);
|
|
|
|
gtk_container_add (GTK_CONTAINER (scr), ctree);
|
|
|
|
gtk_clist_column_titles_hide (GTK_CLIST (ctree));
|
|
|
|
m_pTree = ctree;
|
|
|
|
|
|
|
|
hbox = gtk_hbox_new (FALSE, 5);
|
|
|
|
gtk_widget_show (hbox);
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
|
|
|
|
|
|
|
|
button = gtk_button_new_with_label ("Add...");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (groupdlg_add), NULL);
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_set_usize (button, 60, -2);
|
|
|
|
|
|
|
|
button = gtk_button_new_with_label ("Edit...");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_set_usize (button, 60, -2);
|
|
|
|
|
|
|
|
button = gtk_button_new_with_label ("Delete");
|
|
|
|
gtk_widget_show (button);
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_set_usize (button, 60, -2);
|
|
|
|
|
|
|
|
label = gtk_label_new ("Groups");
|
|
|
|
gtk_widget_show (label);
|
|
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, label);
|
|
|
|
*/
|
|
|
|
inspector_mode = W_ENTITY;
|
|
|
|
// gtk_window_set_title (GTK_WINDOW (dlg), "Entities");
|
|
|
|
m_pWidget = dlg;
|
|
|
|
/*
|
|
|
|
load_pixmap ("grouptree1.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[0], &tree_masks[0]);
|
|
|
|
load_pixmap ("grouptree2.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[1], &tree_masks[1]);
|
|
|
|
load_pixmap ("grouptree3.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[2], &tree_masks[2]);
|
|
|
|
load_pixmap ("grouptree4.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[3], &tree_masks[3]);
|
|
|
|
load_pixmap ("grouptree5.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[4], &tree_masks[4]);
|
|
|
|
load_pixmap ("grouptree6.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[5], &tree_masks[5]);
|
|
|
|
load_pixmap ("grouptree7.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[6], &tree_masks[6]);
|
|
|
|
|
|
|
|
Group_Init();
|
|
|
|
*/
|
|
|
|
g_signal_connect (G_OBJECT (notebook), "switch_page", G_CALLBACK (switch_page), dlg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|