]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/preferences.h
Wrap more GTK
[xonotic/netradiant.git] / radiant / preferences.h
index 7abd86ebd751ae95142083fab30faae895d99e3f..0f6804f794f410975ae0035283534407d5bb2360 100644 (file)
-/*\r
-Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
-For a list of contributors, see the accompanying CONTRIBUTORS file.\r
-\r
-This file is part of GtkRadiant.\r
-\r
-GtkRadiant is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-GtkRadiant is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with GtkRadiant; if not, write to the Free Software\r
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
-*/\r
-\r
-#ifndef _PREFERENCES_H_\r
-#define _PREFERENCES_H_\r
-\r
-#include "dialog.h"\r
-#include "gtkr_list.h"\r
-//#include "profile.h"\r
-\r
-#define MAX_TEXTURE_QUALITY 3\r
-\r
-enum PrefTypes_t\r
-{\r
-  PREF_STR,\r
-  PREF_INT,\r
-  PREF_BOOL,\r
-  PREF_FLOAT,\r
-  PREF_VEC3,\r
-  PREF_WNDPOS,\r
-};\r
-\r
-/*!\r
-a preference assignment, name, type and pointer to value\r
-we don't store the xmlNodePtr because the document itself can be thrown away upon any LoadPref\r
-(see CGameDialog::UpdatePrefTree)\r
-*/\r
-class CPrefAssignment\r
-{\r
-public:\r
-  Str mName;\r
-  PrefTypes_t mType;\r
-  void *mVal;\r
-\r
-  CPrefAssignment(char *name, PrefTypes_t Type, void *Val)\r
-  {\r
-    mName = name; mType = Type; mVal = Val;\r
-  }\r
-  CPrefAssignment() { mVal = NULL; }\r
-  CPrefAssignment(const CPrefAssignment& ass);\r
-  virtual ~CPrefAssignment() { }\r
-  virtual CPrefAssignment& operator =(const CPrefAssignment& ass);\r
-};\r
-\r
-\r
-/*!\r
-generic preferences storage class, using xml files\r
-*/\r
-class CXMLPropertyBag\r
-{\r
-private:\r
-  /*!\r
-  local prefs file\r
-  */\r
-  xmlDocPtr mpDoc;\r
-  xmlNodePtr mpDocNode;\r
-\r
-  /*!\r
-  prefs assignments (what pref name, what type, what variable)\r
-  */\r
-  list<CPrefAssignment> mPrefAssignments;\r
-\r
-  /*!\r
-  name of file to load/save as\r
-  */\r
-  Str mStrFilename;\r
-\r
-  /*!\r
-  store assignment in the property list if not already there\r
-  */\r
-  void PushAssignment(char *name, PrefTypes_t type, void *pV);\r
-\r
-  /*!\r
-  find the xmlnode relating to the epair name\r
-  */\r
-  xmlNodePtr EpairForName(const char *name);\r
-\r
-public:\r
-  CXMLPropertyBag();\r
-  virtual ~CXMLPropertyBag() \r
-  {\r
-    if (InUse())\r
-      Clear();\r
-  };\r
-\r
-  /*!\r
-  read a pref setting, if doesn't exist, will add it to the xml tree (using default value provided)\r
-  \arg name the name of the pref\r
-  \arg pV pointer to the value\r
-  \arg V default value\r
-  those functions will fill in the list of preferences assignments\r
-    (name, type and pointer to value)\r
-    this is used in UpdatePrefTree\r
-  */\r
-  void GetPref(char *name, Str *pV, char *V);\r
-  void GetPref(char *name, int *pV, int V);\r
-  void GetPref(char *name, bool *pV, bool V);\r
-  void GetPref(char *name, float *pV, float V);\r
-  void GetPref(char *name, float *pV, float* V);\r
-  void GetPref(char *name, window_position_t* pV, window_position_t V);\r
-\r
-  /*!\r
-  returns whether or not the property bag is already open\r
-  */\r
-  qboolean InUse() { return (mpDoc != NULL); };\r
-\r
-  /*!\r
-  unload the xml doc, and free the tree\r
-  */\r
-  void Clear();\r
-\r
-  /*|\r
-  read data from our XML file\r
-  */\r
-  void ReadXMLFile(const char* pFilename);\r
-\r
-  /*|\r
-  write out the property bag to an XML data file\r
-  return is success/fail\r
-  */\r
-  qboolean WriteXMLFile(const char* pFilename);\r
-\r
-  /*!\r
-  update the xml tree with data form the property list, usually in preparation for a write\r
-  */\r
-  void UpdatePrefTree();\r
-\r
-  /*!\r
-  did the file have any data or not?\r
-  */\r
-  qboolean mbEmpty;\r
-};\r
-\r
-/*!\r
-holds information for a given game\r
-I'm a bit unclear on that still\r
-it holds game specific configuration stuff\r
-such as base names, engine names, some game specific features to activate in the various modules\r
-it is not strictly a prefs thing since the user is not supposed to edit that (unless he is hacking\r
-support for a new game)\r
-\r
-what we do now is fully generate the information for this during the setup. We might want to\r
-generate a piece that just says "the game pack is there", but put the rest of the config somwhere\r
-else (i.e. not generated, copied over during setup .. for instance in the game tools directory)\r
-*/\r
-class CGameDescription\r
-{\r
-public:\r
-  xmlDocPtr mpDoc; ///< the game description xml tree\r
-  Str mGameToolsPath; ///< the explicit path to the game-dependent modules\r
-  Str mGameName; ///< name of the game used in dialogs\r
-  Str mGameFile; ///< the .game file that describes this game\r
-  Str mBaseGame; ///< basegame directory\r
-  Str mEnginePath; ///< path to the engine\r
-  Str mEngine; ///< engine name\r
-#if defined (__linux__) || defined (__APPLE__)\r
-  Str mUserPathPrefix; ///< prefix for ~/.q3a ~/.wolf init, only on *nix\r
-#endif\r
-  Str mShaderPath; ///< the path in which to look for shaders\r
-  Str mShaderlist; ///< shaderlist file\r
-  float mTextureDefaultScale; ///< default scale (0.5 in q3, 1.0 in q1/q2, 0.25 in JK2 ..)\r
-  bool mEClassSingleLoad; ///< only load a single eclass definition file\r
-  bool mNoPatch; ///< this game doesn't support patch technology\r
-  Str mCaulkShader; ///< the shader to use for caulking\r
-\r
-  CGameDescription() { mpDoc = NULL; }\r
-  /*!\r
-  \todo parse basic info from the node\r
-  user-friendly name of the game\r
-  essential parameters (such as the start dir)\r
-  */\r
-  CGameDescription(xmlDocPtr pDoc, const Str &GameFile);\r
-  virtual ~CGameDescription() { xmlFreeDoc(mpDoc); }\r
-\r
-  void Dump();\r
-};\r
-\r
-/*!\r
-standalone dialog for games selection, and more generally global settings\r
-*/\r
-class CGameDialog : public Dialog\r
-{\r
-  GtkWidget *mFrame; ///< this is built on-demand first time it's used\r
-  GtkWidget *mTopBox; ///< top level box used to store the dialog frame, must unhook after modal use\r
-\r
-\r
-  /*!\r
-  global prefs storage\r
-  */\r
-  CXMLPropertyBag mGlobalPrefs;\r
-\r
-#ifdef _WIN32\r
-  /*!\r
-  run from a network share\r
-  this one is not being saved out in prefs, since we need to know before we load prefs\r
-  we use a dummy file NETRUN_FILENAME as flag\r
-  all done with static stuff\r
-  */\r
-  static bool m_bNetRun;\r
-#endif\r
-\r
-protected:\r
-  \r
-  int m_nComboSelect; ///< intermediate int value for combo in dialog box\r
-\r
-public:\r
-\r
-  /*! \r
-  those settings are saved in the global prefs file \r
-  I'm too lazy to wrap behind protected access, not sure this needs to be public\r
-  NOTE: those are preference settings. if you change them it is likely that you would\r
-  have to restart the editor for them to take effect\r
-  */\r
-  /*@{*/\r
-  /*!\r
-  what game has been selected\r
-  this is the name of the .game file\r
-  */\r
-  Str m_sGameFile;\r
-  /*!\r
-  auto-load the game on startup\r
-  this is linked to auto-load checkbox\r
-  */\r
-  bool m_bAutoLoadGame;\r
-  /*!\r
-  log console to radiant.log\r
-  m_bForceLogConsole is an obscure forced latching situation\r
-  */\r
-  bool m_bLogConsole;\r
-  bool m_bForceLogConsole;\r
-  /*@}*/\r
-\r
-  /*!\r
-  points somewhere in mGames, set once at startup\r
-  */\r
-  CGameDescription *m_pCurrentGameDescription;\r
-\r
-  /*!\r
-  the list of game descriptions we scanned from the game/ dir\r
-  */\r
-  list<CGameDescription *> mGames;\r
-\r
-  CGameDialog() { mFrame = NULL; m_pCurrentGameDescription = NULL; m_bLogConsole = false; m_bForceLogConsole = false; }\r
-  virtual ~CGameDialog(); \r
-\r
-  void AddPacksURL(Str &s);  \r
-    \r
-  /*!\r
-  intialize the game dialog, called at CPrefsDlg::Init\r
-  will scan for games, load prefs, and do game selection dialog if needed\r
-  */\r
-  void Init();\r
-\r
-  /*!\r
-  reset the global settings by removing the file\r
-  */\r
-  void Reset();\r
-\r
-  /*!\r
-  run the dialog UI for the list of games \r
-  */\r
-  void DoGameDialog();\r
-\r
-  /*!\r
-  Dialog API\r
-  this is only called when the dialog is built at startup for main engine select\r
-  */\r
-  void BuildDialog ();\r
-  void UpdateData (bool retrieve);\r
-\r
-  /*!\r
-  construction of the dialog frame\r
-  this is the part to be re-used in prefs dialog\r
-  for the standalone dialog, we include this in a modal box\r
-  for prefs, we hook the frame in the main notebook\r
-  build the frame on-demand (only once)\r
-  */\r
-  GtkWidget *GetGlobalFrame();\r
-\r
-  /*!\r
-  global preferences subsystem\r
-  XML-based this time, hopefully this will generalize to other prefs\r
-  LoadPrefs has hardcoded defaults\r
-  NOTE: it may not be strictly 'CGameDialog' to put the global prefs here\r
-    could have named the class differently I guess\r
-  */\r
-  /*@{*/\r
-  void LoadPrefs(); ///< load from file into variables\r
-  void SavePrefs(); ///< save pref variables to file\r
-  /*@}*/\r
-\r
-  /*!\r
-  read or set netrun (check file)\r
-  \param retrieve \r
-    if false, will check if netrun file is present and will set m_bNetRun\r
-    if true, will create/erase the netrun file depending on m_bNetRun\r
-    NOTE: this is not backwards, 'retrieve' means 'retrieve from settings dialog' - in terms of UI\r
-  */\r
-  static void UpdateNetrun(bool retrieve);\r
-  /*!\r
-  get current netrun setting\r
-  */\r
-  static bool GetNetrun();\r
-\r
-private:\r
-  /*!\r
-  scan for .game files, load them\r
-  */\r
-  void ScanForGames();\r
-\r
-  /*!\r
-  inits g_PrefsDlg.m_global_rc_path\r
-  */\r
-  void InitGlobalPrefPath();\r
-\r
-  /*!\r
-  uses m_nComboItem to find the right mGames\r
-  */\r
-  CGameDescription *GameDescriptionForComboItem();\r
-};\r
-\r
-typedef struct {\r
-  int nEntitySplit1;\r
-  int nEntitySplit2;\r
-  \r
-  window_position_t position;\r
-\r
-  window_position_t posEntityWnd;\r
-  window_position_t posMapInfoWnd;\r
-  window_position_t posCamWnd;\r
-  window_position_t posZWnd;\r
-  window_position_t posXYWnd;\r
-  window_position_t posXZWnd;\r
-  window_position_t posYZWnd;\r
-  window_position_t posPatchWnd;\r
-  window_position_t posSurfaceWnd;\r
-  window_position_t posEntityInfoWnd;\r
-\r
-  int nXYHeight;\r
-  int nZWidth;\r
-  int nXYWidth;\r
-  int nCamWidth;\r
-  int nCamHeight;\r
-  int nZFloatWidth;\r
-  int nState;\r
-} windowPosInfo_t;\r
-\r
-class PrefsDlg : public Dialog\r
-{\r
-  \r
-public:\r
-  /*!\r
-  local prefs file\r
-  */\r
-  CXMLPropertyBag mLocalPrefs;\r
-\r
-  // will enable/disable stuff according to the situation\r
-  void DoSensitivity();\r
-  void PreModal() { DoSensitivity(); }\r
-  \r
-  // enable/disable custom editor entry\r
-  void DoEditorSensitivity();\r
-  \r
-  /*!\r
-  this holds global level preferences\r
-  */\r
-  CGameDialog mGamesDialog;\r
-protected:\r
-  // warning about old project files\r
-  bool m_bWarn;\r
-  list<CGameDescription *> mGames;\r
-  \r
-public:\r
-  // last light intensity used in the CLightPrompt dialog, stored in registry\r
-  int m_iLastLightIntensity;\r
-  // these mirror what goes in the combo box\r
-  // see PrefDlg::m_nShader, tells wether to load NONE / COMMON or ALL shaders at parsing stage\r
-  enum {SHADER_NONE = 0, SHADER_COMMON, SHADER_ALL};\r
-\r
-  // Gef: updated preferences dialog\r
-  /*! Preference notebook page numbers */\r
-  enum {PTAB_FRONT = 0, PTAB_GAME_SETTINGS, PTAB_2D, PTAB_CAMERA, PTAB_TEXTURE, PTAB_LAYOUT, PTAB_MOUSE,\r
-        PTAB_EDITING, PTAB_STARTUP, PTAB_PATHS, PTAB_MISC, PTAB_BSPMONITOR} pref_tabs;\r
-  \r
-  GtkWidget *notebook;\r
-       \r
-  void UpdateTextureCompression();\r
-\r
-#ifdef ATIHACK_812\r
-  void UpdateATIHack();\r
-#endif\r
-        \r
-  void LoadPrefs();\r
-  void SavePrefs();\r
-  void LoadTexdefPref(texdef_t* pTexdef, char* pName);\r
-\r
-  PrefsDlg ();\r
-  virtual ~PrefsDlg ()\r
-  {\r
-    g_string_free (m_rc_path, true );\r
-    g_string_free (m_inipath, true );\r
-  }\r
-\r
-  /*!\r
-  path for global settings\r
-  win32: g_strAppPath\r
-  linux: ~/.radiant/<version>/\r
-  */\r
-  GString *m_global_rc_path;\r
-\r
-  /*!\r
-  path to per-game settings\r
-  used for various game dependant storage\r
-  win32: g_strGameToolsPath\r
-  linux: ~/.radiant/<version>/<gamename>/\r
-  */\r
-  GString *m_rc_path;\r
-\r
-  /*!\r
-  holds per-game settings\r
-  m_rc_path+"local.pref"\r
-  \todo FIXME at some point this should become XML property bag code too\r
-  */\r
-  GString *m_inipath;\r
-\r
-  // initialize the above paths\r
-  void Init();\r
-\r
-#if 0\r
-  // DEPRECATED: use engine path from the current game description instead\r
-       // path to the top-level installation\r
-       Str     m_strEnginePath;\r
-  // name of executable\r
-  // quake2 quake3 etc\r
-       Str     m_strEngine;\r
-  // we use this Str to store the full path to the engine: m_strEnginePath + m_strEngine\r
-  // it's not stored in the registry or anything, just ued for display in prefs\r
-  Str   m_strPrefsDlgEngine;\r
-#endif\r
-\r
-  // Dialog Data\r
-  int   m_nMouse;\r
-  MainFrame::EViewStyle m_nView;\r
-  bool  m_bTextureLock;\r
-  bool  m_bLoadLast;\r
-       // path to the project loaded at startup\r
-       // if g_PrefsDlg can't find the information in the ini file\r
-       // it will try to guess and eventually ask the user\r
-  Str   m_strLastProject;  \r
-  /*!\r
-  version of last loaded project file\r
-  says -1 if there's no version loaded\r
-  if it's a manually constructed project file, will be 0\r
-  otherwise the actual 'version' epair\r
-  */\r
-  int   m_nLastProjectVer;\r
-  Str   m_strLastMap;\r
-  bool  m_bInternalBSP;\r
-  bool  m_bRightClick;\r
-  bool  m_bSetGame;\r
-  bool  m_bAutoSave;\r
-  bool  m_bLoadLastMap;\r
-  bool  m_bTextureWindow;\r
-  bool  m_bSnapShots;\r
-  float m_fTinySize;\r
-  bool  m_bCleanTiny;\r
-  bool  m_bCamXYUpdate;\r
-  int   m_nCamDragMultiSelect;\r
-  bool  m_bCamDragMultiSelect;\r
-  bool  m_bCamFreeLook;\r
-  bool  m_bCamFreeLookStrafe;\r
-  bool m_bCamInverseMouse;\r
-  bool m_bCamDiscrete;\r
-  bool  m_bNewLightDraw;\r
-  Str   m_strPrefabPath;\r
-  int   m_nWhatGame;\r
-  bool  m_bALTEdge;\r
-  bool  m_bFaceColors;\r
-  bool  m_bXZVis;\r
-  bool  m_bYZVis;\r
-  bool  m_bZVis;\r
-  bool  m_bSizePaint;\r
-  bool  m_bDLLEntities;\r
-  bool  m_bRotateLock;\r
-  bool  m_bDetachableMenus;\r
-  bool  m_bPatchToolbar;\r
-  bool  m_bWideToolbar;\r
-  bool  m_bPluginToolbar;\r
-  bool  m_bNoClamp;\r
-       //++timo this is most likely broken, I don't know what it's supposed to do\r
-  Str   m_strUserPath;\r
-  int   m_nRotation;\r
-  bool  m_bChaseMouse;\r
-  bool  m_bTextureScrollbar;\r
-  bool  m_bDisplayLists;\r
-  bool m_bAntialiasedPointsAndLines; // Fishman - Add antialiazed points and lines support. 09/03/00\r
-  bool  m_bShowShaders;\r
-  int   m_nShader;\r
-  bool  m_bNoStipple;\r
-  int   m_nUndoLevels;\r
-  bool  m_bVertexSplit;\r
-\r
-  int   m_nMouseButtons;\r
-  int   m_nAngleSpeed;\r
-  int   m_nMoveSpeed;\r
-  int   m_nAutoSave;\r
-  bool  m_bCubicClipping;\r
-  int   m_nCubicScale;\r
-  bool  m_bSelectCurves;\r
-  bool  m_bSelectModels;\r
-  int   m_nEntityShowState;\r
-  int   m_nTextureScale;\r
-  bool  m_bNormalizeColors;\r
-  bool  m_bSwitchClip;\r
-  bool  m_bSelectWholeEntities;\r
-  int   m_nTextureQuality;\r
-  bool  m_bGLLighting;\r
-  bool  m_bTexturesShaderlistOnly;\r
-  int   m_nSubdivisions;\r
-  bool  m_bFloatingZ;\r
-  bool  m_bLatchedFloatingZ;\r
-  // Gef: Kyro GL_POINT workaround\r
-  bool m_bGlPtWorkaround;\r
-\r
-  // how many menus in the texture thing before we split?\r
-  int   m_nTextureMenuSplit;\r
-\r
-  // watch the BSP process through network connections\r
-  // true: trigger the BSP steps one by one and monitor them through the network\r
-  // false: create a BAT / .sh file and execute it. don't bother monitoring it.\r
-  bool  m_bWatchBSP;\r
-  // do we stop the compilation process if we come accross a leak?\r
-  bool  m_bLeakStop;\r
-  // timeout when beginning a step (in seconds)\r
-  // if we don't get a connection quick enough we assume something failed and go back to idling\r
-  int   m_iTimeout;\r
-  bool  m_bRunQuake;\r
-  // store prefs setting for automatic sleep mode activation\r
-  bool  m_bDoSleep;\r
-  \r
-  bool m_bClipCaulk;\r
-\r
-  // make the texture increments match the grid changes\r
-  bool m_bSnapTToGrid;\r
-\r
-  // try to fix the target/targetname conflicts when importing a map (default true)\r
-  bool m_bDoTargetFix;\r
-\r
-  // the increment step we use against the wheel mouse\r
-  int m_nWheelInc;\r
-\r
-#ifdef _WIN32\r
-  // use the file associations to open files instead of builtin Gtk editor\r
-  bool m_bUseWin32Editor;\r
-#else\r
-  // custom shader editor\r
-  bool m_bUseCustomEditor;\r
-  Str  m_strEditorCommand;  // this is the command executed\r
-#endif\r
-\r
-#ifdef _WIN32\r
-  bool m_bNativeGUI;\r
-  bool m_bStartOnPrimMon;\r
-#endif\r
-\r
-  bool m_bPatchBBoxSelect;\r
-\r
-  // RR2DO2: latched data, for settings that require a restart. We don't want to set\r
-  // these directly in case users set them under preferences and then continue working\r
-  // with the editor.\r
-  MainFrame::EViewStyle m_nLatchedView;\r
-  int m_nMRUCount;\r
-  Str m_strMRUFiles[4];\r
-\r
-  windowPosInfo_t mWindowInfo;\r
-\r
-  bool  m_bLatchedDetachableMenus;\r
-  bool  m_bLatchedPatchToolbar;\r
-  bool  m_bLatchedWideToolbar;\r
-  bool  m_bLatchedPluginToolbar;\r
-  int   m_nLatchedShader;\r
-  int   m_nLatchedTextureQuality;\r
-\r
-  // RIANT\r
-  // texture compression format\r
-  int m_nTextureCompressionFormat;\r
-\r
-  int m_nLightRadiuses;\r
-  \r
-  bool m_bQ3Map2Texturing;\r
-\r
-#ifdef ATIHACK_812\r
-       bool m_bGlATIHack;\r
-#endif\r
-\r
-  void UpdateData (bool retrieve);\r
-\r
-  /*! Utility function for swapping notebook pages for tree list selections */\r
-  void showPrefPage(int prefpage);\r
-\r
-protected:\r
-  /*! Scan for game description files and build a list */\r
-  void ScanForGames();\r
-\r
-  /*! Dialog API */\r
-  void BuildDialog ();\r
-  void PostModal (int code);\r
-};\r
-\r
-#endif // _PREFERENCES_H_\r
+/*
+   Copyright (C) 1999-2006 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
+ */
+
+/*
+   The following source code is licensed by Id Software and subject to the terms of
+   its LIMITED USE SOFTWARE LICENSE AGREEMENT, a copy of which is included with
+   GtkRadiant. If you did not receive a LIMITED USE SOFTWARE LICENSE AGREEMENT,
+   please contact Id Software immediately at info@idsoftware.com.
+ */
+
+#if !defined( INCLUDED_PREFERENCES_H )
+#define INCLUDED_PREFERENCES_H
+
+#include "libxml/parser.h"
+#include "dialog.h"
+#include <list>
+#include <map>
+
+void Widget_connectToggleDependency( ui::Widget self, ui::Widget toggleButton );
+
+class PreferencesPage
+{
+Dialog& m_dialog;
+ui::Widget m_vbox;
+public:
+PreferencesPage( Dialog& dialog, ui::Widget vbox ) : m_dialog( dialog ), m_vbox( vbox ){
+}
+ui::CheckButton appendCheckBox( const char* name, const char* flag, bool& data ){
+       return m_dialog.addCheckBox( m_vbox, name, flag, data );
+}
+ui::CheckButton appendCheckBox( const char* name, const char* flag, const BoolImportCallback& importCallback, const BoolExportCallback& exportCallback ){
+       return m_dialog.addCheckBox( m_vbox, name, flag, importCallback, exportCallback );
+}
+void appendCombo( const char* name, StringArrayRange values, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){
+       m_dialog.addCombo( m_vbox, name, values, importCallback, exportCallback );
+}
+void appendCombo( const char* name, int& data, StringArrayRange values ){
+       m_dialog.addCombo( m_vbox, name, data, values );
+}
+void appendSlider( const char* name, int& data, gboolean draw_value, const char* low, const char* high, double value, double lower, double upper, double step_increment, double page_increment ){
+       m_dialog.addSlider( m_vbox, name, data, draw_value, low, high, value, lower, upper, step_increment, page_increment );
+}
+void appendRadio( const char* name, StringArrayRange names, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){
+       m_dialog.addRadio( m_vbox, name, names, importCallback, exportCallback );
+}
+void appendRadio( const char* name, int& data, StringArrayRange names ){
+       m_dialog.addRadio( m_vbox, name, data, names );
+}
+void appendRadioIcons( const char* name, StringArrayRange icons, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){
+       m_dialog.addRadioIcons( m_vbox, name, icons, importCallback, exportCallback );
+}
+void appendRadioIcons( const char* name, int& data, StringArrayRange icons ){
+       m_dialog.addRadioIcons( m_vbox, name, data, icons );
+}
+ui::Widget appendEntry( const char* name, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){
+       return m_dialog.addIntEntry( m_vbox, name, importCallback, exportCallback );
+}
+ui::Widget appendEntry( const char* name, int& data ){
+       return m_dialog.addEntry( m_vbox, name, data );
+}
+ui::Widget appendEntry( const char* name, const SizeImportCallback& importCallback, const SizeExportCallback& exportCallback ){
+       return m_dialog.addSizeEntry( m_vbox, name, importCallback, exportCallback );
+}
+ui::Widget appendEntry( const char* name, std::size_t& data ){
+       return m_dialog.addEntry( m_vbox, name, data );
+}
+ui::Widget appendEntry( const char* name, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ){
+       return m_dialog.addFloatEntry( m_vbox, name, importCallback, exportCallback );
+}
+ui::Widget appendEntry( const char* name, float& data ){
+       return m_dialog.addEntry( m_vbox, name, data );
+}
+ui::Widget appendPathEntry( const char* name, bool browse_directory, const StringImportCallback& importCallback, const StringExportCallback& exportCallback ){
+       return m_dialog.addPathEntry( m_vbox, name, browse_directory, importCallback, exportCallback );
+}
+ui::Widget appendPathEntry( const char* name, CopiedString& data, bool directory ){
+       return m_dialog.addPathEntry( m_vbox, name, data, directory );
+}
+ui::SpinButton appendSpinner( const char* name, int& data, double value, double lower, double upper ){
+       return m_dialog.addSpinner( m_vbox, name, data, value, lower, upper );
+}
+ui::SpinButton appendSpinner( const char* name, double value, double lower, double upper, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){
+       return m_dialog.addSpinner( m_vbox, name, value, lower, upper, importCallback, exportCallback );
+}
+ui::SpinButton appendSpinner( const char* name, double value, double lower, double upper, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ){
+       return m_dialog.addSpinner( m_vbox, name, value, lower, upper, importCallback, exportCallback );
+}
+};
+
+typedef Callback1<PreferencesPage&> PreferencesPageCallback;
+
+class PreferenceGroup
+{
+public:
+virtual PreferencesPage createPage( const char* treeName, const char* frameName ) = 0;
+};
+
+typedef Callback1<PreferenceGroup&> PreferenceGroupCallback;
+
+void PreferencesDialog_addInterfacePreferences( const PreferencesPageCallback& callback );
+void PreferencesDialog_addInterfacePage( const PreferenceGroupCallback& callback );
+void PreferencesDialog_addDisplayPreferences( const PreferencesPageCallback& callback );
+void PreferencesDialog_addDisplayPage( const PreferenceGroupCallback& callback );
+void PreferencesDialog_addSettingsPreferences( const PreferencesPageCallback& callback );
+void PreferencesDialog_addSettingsPage( const PreferenceGroupCallback& callback );
+
+void PreferencesDialog_restartRequired( const char* staticName );
+
+template<typename Value>
+class LatchedValue
+{
+public:
+Value m_value;
+Value m_latched;
+const char* m_description;
+
+LatchedValue( Value value, const char* description ) : m_latched( value ), m_description( description ){
+}
+void useLatched(){
+       m_value = m_latched;
+}
+void import( Value value ){
+       m_latched = value;
+       if ( m_latched != m_value ) {
+               PreferencesDialog_restartRequired( m_description );
+       }
+}
+};
+
+typedef LatchedValue<bool> LatchedBool;
+typedef MemberCaller1<LatchedBool, bool, &LatchedBool::import> LatchedBoolImportCaller;
+
+typedef LatchedValue<int> LatchedInt;
+typedef MemberCaller1<LatchedInt, int, &LatchedInt::import> LatchedIntImportCaller;
+
+/*!
+   holds information for a given game
+   I'm a bit unclear on that still
+   it holds game specific configuration stuff
+   such as base names, engine names, some game specific features to activate in the various modules
+   it is not strictly a prefs thing since the user is not supposed to edit that (unless he is hacking
+   support for a new game)
+
+   what we do now is fully generate the information for this during the setup. We might want to
+   generate a piece that just says "the game pack is there", but put the rest of the config somwhere
+   else (i.e. not generated, copied over during setup .. for instance in the game tools directory)
+ */
+class CGameDescription
+{
+typedef std::map<CopiedString, CopiedString> GameDescription;
+
+public:
+CopiedString mGameFile;   ///< the .game file that describes this game
+GameDescription m_gameDescription;
+
+CopiedString mGameToolsPath;   ///< the explicit path to the game-dependent modules
+CopiedString mGameType;   ///< the type of the engine
+
+const char* getKeyValue( const char* key ) const {
+       GameDescription::const_iterator i = m_gameDescription.find( key );
+       if ( i != m_gameDescription.end() ) {
+               return ( *i ).second.c_str();
+       }
+       return "";
+}
+const char* getRequiredKeyValue( const char* key ) const {
+       GameDescription::const_iterator i = m_gameDescription.find( key );
+       if ( i != m_gameDescription.end() ) {
+               return ( *i ).second.c_str();
+       }
+       ERROR_MESSAGE( "game attribute " << makeQuoted( key ) << " not found in " << makeQuoted( mGameFile.c_str() ) );
+       return "";
+}
+
+CGameDescription( xmlDocPtr pDoc, const CopiedString &GameFile );
+
+void Dump();
+};
+
+extern CGameDescription *g_pGameDescription;
+
+class PrefsDlg;
+
+class PreferencesPage;
+
+class StringOutputStream;
+
+/*!
+   standalone dialog for games selection, and more generally global settings
+ */
+class CGameDialog : public Dialog
+{
+protected:
+
+mutable int m_nComboSelect;   ///< intermediate int value for combo in dialog box
+
+public:
+
+/*!
+   those settings are saved in the global prefs file
+   I'm too lazy to wrap behind protected access, not sure this needs to be public
+   NOTE: those are preference settings. if you change them it is likely that you would
+   have to restart the editor for them to take effect
+ */
+/*@{*/
+/*!
+   what game has been selected
+   this is the name of the .game file
+ */
+CopiedString m_sGameFile;
+/*!
+   prompt which game to load on startup
+ */
+bool m_bGamePrompt;
+/*!
+   log console to radiant.log
+   m_bForceLogConsole is an obscure forced latching situation
+ */
+bool m_bForceLogConsole;
+/*@}*/
+
+/*!
+   the list of game descriptions we scanned from the game/ dir
+ */
+std::list<CGameDescription*> mGames;
+
+CGameDialog() :
+       m_sGameFile( "" ),
+       m_bGamePrompt( true ),
+       m_bForceLogConsole( false ){
+}
+virtual ~CGameDialog();
+
+/*!
+   intialize the game dialog, called at CPrefsDlg::Init
+   will scan for games, load prefs, and do game selection dialog if needed
+ */
+void Init();
+
+/*!
+   reset the global settings by removing the file
+ */
+void Reset();
+
+/*!
+   run the dialog UI for the list of games
+ */
+void DoGameDialog();
+
+/*!
+   Dialog API
+   this is only called when the dialog is built at startup for main engine select
+ */
+ui::Window BuildDialog();
+
+void GameFileImport( int value );
+void GameFileExport( const IntImportCallback& importCallback ) const;
+
+/*!
+   construction of the dialog frame
+   this is the part to be re-used in prefs dialog
+   for the standalone dialog, we include this in a modal box
+   for prefs, we hook the frame in the main notebook
+   build the frame on-demand (only once)
+ */
+void CreateGlobalFrame( PreferencesPage& page );
+
+/*!
+   global preferences subsystem
+   XML-based this time, hopefully this will generalize to other prefs
+   LoadPrefs has hardcoded defaults
+   NOTE: it may not be strictly 'CGameDialog' to put the global prefs here
+   could have named the class differently I guess
+ */
+/*@{*/
+void LoadPrefs();   ///< load from file into variables
+void SavePrefs();   ///< save pref variables to file
+/*@}*/
+
+private:
+/*!
+   scan for .game files, load them
+ */
+void ScanForGames();
+
+/*!
+   inits g_Preferences.m_global_rc_path
+ */
+void InitGlobalPrefPath();
+
+/*!
+   uses m_nComboItem to find the right mGames
+ */
+CGameDescription *GameDescriptionForComboItem();
+};
+
+/*!
+   this holds global level preferences
+ */
+extern CGameDialog g_GamesDialog;
+
+
+class texdef_t;
+
+class PrefsDlg : public Dialog
+{
+public:
+protected:
+std::list<CGameDescription *> mGames;
+
+public:
+
+ui::Widget m_notebook{ui::null};
+
+virtual ~PrefsDlg(){
+       g_string_free( m_rc_path, true );
+       g_string_free( m_inipath, true );
+}
+
+/*!
+   path for global settings
+   win32: AppPath
+   linux: ~/.radiant/[version]/
+ */
+GString *m_global_rc_path;
+
+/*!
+   path to per-game settings
+   used for various game dependant storage
+   win32: GameToolsPath
+   linux: ~/.radiant/[version]/[gamename]/
+ */
+GString *m_rc_path;
+
+/*!
+   holds per-game settings
+   m_rc_path+"local.pref"
+   \todo FIXME at some point this should become XML property bag code too
+ */
+GString *m_inipath;
+
+// initialize the above paths
+void Init();
+
+/*! Utility function for swapping notebook pages for tree list selections */
+void showPrefPage( ui::Widget prefpage );
+
+protected:
+
+/*! Dialog API */
+ui::Window BuildDialog();
+void PostModal( EMessageBoxReturn code );
+};
+
+extern PrefsDlg g_Preferences;
+
+struct preferences_globals_t
+{
+       // disabled all INI / registry read write .. used when shutting down after registry cleanup
+       bool disable_ini;
+       preferences_globals_t() : disable_ini( false ){
+       }
+};
+extern preferences_globals_t g_preferences_globals;
+
+void PreferencesDialog_constructWindow( ui::Window main_window );
+void PreferencesDialog_destroyWindow();
+
+void PreferencesDialog_showDialog();
+
+void GlobalPreferences_Init();
+void Preferences_Init();
+
+void Preferences_Load();
+void Preferences_Save();
+
+void Preferences_Reset();
+
+
+#endif