]> git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/mainframe.cpp
reformat code! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / radiant / mainframe.cpp
index 00b5bad73170d332f085d282b4c82cc786c547e4..36794f83af2ffcc06da90e65ffba3cc97a7f567f 100644 (file)
@@ -1,23 +1,23 @@
 /*
-Copyright (C) 1999-2006 Id Software, Inc. and contributors.
-For a list of contributors, see the accompanying CONTRIBUTORS file.
+   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.
+   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 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.
+   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
-*/
+   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
+ */
 
 //
 // Main Window for Q3Radiant
@@ -26,14 +26,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
 #include "mainframe.h"
+#include "globaldefs.h"
 
-#include "debugging/debugging.h"
-#include "version.h"
+#include <gtk/gtk.h>
 
 #include "ifilesystem.h"
 #include "iundo.h"
-#include "ifilter.h"
-#include "itoolbar.h"
 #include "editable.h"
 #include "ientity.h"
 #include "ishaders.h"
@@ -43,20 +41,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include <ctime>
 
 #include <gdk/gdkkeysyms.h>
-#include <gtk/gtkhbox.h>
-#include <gtk/gtkvbox.h>
-#include <gtk/gtkframe.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkhpaned.h>
-#include <gtk/gtkvpaned.h>
-#include <gtk/gtktoolbar.h>
-#include <gtk/gtkmenubar.h>
-#include <gtk/gtkimage.h>
-#include <gtk/gtktable.h>
 
 
 #include "cmdlib.h"
-#include "scenelib.h"
 #include "stream/stringstream.h"
 #include "signal/isignal.h"
 #include "os/path.h"
@@ -65,14 +52,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include "moduleobservers.h"
 
 #include "gtkutil/clipboard.h"
-#include "gtkutil/container.h"
 #include "gtkutil/frame.h"
-#include "gtkutil/glfont.h"
 #include "gtkutil/glwidget.h"
 #include "gtkutil/image.h"
 #include "gtkutil/menu.h"
 #include "gtkutil/paned.h"
-#include "gtkutil/widget.h"
 
 #include "autosave.h"
 #include "build.h"
@@ -101,7 +85,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include "pluginmanager.h"
 #include "pluginmenu.h"
 #include "plugintoolbar.h"
-#include "points.h"
 #include "preferences.h"
 #include "qe3.h"
 #include "qgl.h"
@@ -116,30 +99,29 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include "renderstate.h"
 #include "feedback.h"
 #include "referencecache.h"
+#include "texwindow.h"
 
 
-
-struct layout_globals_t
-{
-  WindowPosition m_position;
+struct layout_globals_t {
+    WindowPosition m_position;
 
 
-  int nXYHeight;
-  int nXYWidth;
-  int nCamWidth;
-  int nCamHeight;
-  int nState;
+    int nXYHeight;
+    int nXYWidth;
+    int nCamWidth;
+    int nCamHeight;
+    int nState;
 
-  layout_globals_t() :
-    m_position(-1, -1, 640, 480),
+    layout_globals_t() :
+            m_position(-1, -1, 640, 480),
 
-    nXYHeight(300),
-    nXYWidth(300),
-    nCamWidth(200),
-    nCamHeight(200),
-    nState(GDK_WINDOW_STATE_MAXIMIZED)
-  {
-  }
+            nXYHeight(300),
+            nXYWidth(300),
+            nCamWidth(200),
+            nCamHeight(200),
+            nState(GDK_WINDOW_STATE_MAXIMIZED)
+    {
+    }
 };
 
 layout_globals_t g_layout_globals;
@@ -147,28 +129,54 @@ glwindow_globals_t g_glwindow_globals;
 
 
 // VFS
-class VFSModuleObserver : public ModuleObserver
+
+bool g_vfsInitialized = false;
+
+void VFS_Init()
 {
-  std::size_t m_unrealised;
+    if (g_vfsInitialized) { return; }
+    QE_InitVFS();
+    GlobalFileSystem().initialise();
+    g_vfsInitialized = true;
+}
+
+void VFS_Shutdown()
+{
+    if (!g_vfsInitialized) { return; }
+    GlobalFileSystem().shutdown();
+    g_vfsInitialized = false;
+}
+
+void VFS_Refresh()
+{
+    if (!g_vfsInitialized) { return; }
+    GlobalFileSystem().clear();
+    QE_InitVFS();
+    GlobalFileSystem().refresh();
+    g_vfsInitialized = true;
+    // also refresg models
+    RefreshReferences();
+    // also refresh texture browser
+    TextureBrowser_RefreshShaders();
+}
+
+void VFS_Restart()
+{
+    VFS_Shutdown();
+    VFS_Init();
+}
+
+class VFSModuleObserver : public ModuleObserver {
 public:
-  VFSModuleObserver() : m_unrealised(1)
-  {
-  }
-  void realise()
-  {
-    if(--m_unrealised == 0)
+    void realise()
     {
-      QE_InitVFS();
-      GlobalFileSystem().initialise();
+        VFS_Init();
     }
-  }
-  void unrealise()
-  {
-    if(++m_unrealised == 1)
+
+    void unrealise()
     {
-      GlobalFileSystem().shutdown();
+        VFS_Shutdown();
     }
-  }
 };
 
 VFSModuleObserver g_VFSModuleObserver;
@@ -177,6 +185,7 @@ void VFS_Construct()
 {
     Radiant_attachHomePathsObserver(g_VFSModuleObserver);
 }
+
 void VFS_Destroy()
 {
     Radiant_detachHomePathsObserver(g_VFSModuleObserver);
@@ -184,130 +193,129 @@ void VFS_Destroy()
 
 // Home Paths
 
-#ifdef WIN32
-#include <shlobj.h>
+#if GDEF_OS_WINDOWS
+                                                                                                                        #include <shlobj.h>
+#include <objbase.h>
 const GUID qFOLDERID_SavedGames = {0x4C5C32FF, 0xBB9D, 0x43b0, {0xB5, 0xB4, 0x2D, 0x72, 0xE5, 0x4E, 0xAA, 0xA4}};
 #define qREFKNOWNFOLDERID GUID
 #define qKF_FLAG_CREATE 0x8000
 #define qKF_FLAG_NO_ALIAS 0x1000
-static HRESULT (WINAPI *qSHGetKnownFolderPath) (qREFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath);
+typedef HRESULT ( WINAPI qSHGetKnownFolderPath_t )( qREFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath );
+static qSHGetKnownFolderPath_t *qSHGetKnownFolderPath;
 #endif
+
 void HomePaths_Realise()
 {
-  do
-  {
-    const char* prefix = g_pGameDescription->getKeyValue("prefix");
-    if(!string_empty(prefix))
-    {
-      StringOutputStream path(256);
-
-#if defined(__APPLE__)
-      path.clear();
-      path << DirectoryCleaned(g_get_home_dir()) << "Library/Application Support" << (prefix+1) << "/";
-      if(file_is_directory(path.c_str()))
-      {
-        g_qeglobals.m_userEnginePath = path.c_str();
-        break;
-      }
+    do {
+        const char *prefix = g_pGameDescription->getKeyValue("prefix");
+        if (!string_empty(prefix)) {
+            StringOutputStream path(256);
+
+#if GDEF_OS_MACOS
+                                                                                                                                    path.clear();
+                       path << DirectoryCleaned( g_get_home_dir() ) << "Library/Application Support" << ( prefix + 1 ) << "/";
+                       if ( file_is_directory( path.c_str() ) ) {
+                               g_qeglobals.m_userEnginePath = path.c_str();
+                               break;
+                       }
+                       path.clear();
+                       path << DirectoryCleaned( g_get_home_dir() ) << prefix << "/";
 #endif
 
-#if defined(WIN32)
-      TCHAR mydocsdir[MAX_PATH + 1];
-      wchar_t *mydocsdirw;
-      HMODULE shfolder = LoadLibrary("shfolder.dll");
-      if(shfolder)
-        qSHGetKnownFolderPath = GetProcAddress(shfolder, "SHGetKnownFolderPath");
-      else
-        qSHGetKnownFolderPath = NULL;
-      CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
-      if(qSHGetKnownFolderPath && qSHGetKnownFolderPath(&qFOLDERID_SavedGames, qKF_FLAG_CREATE | qKF_FLAG_NO_ALIAS, NULL, &mydocsdirw) == S_OK)
-      {
-        memset(mydocsdir, 0, sizeof(mydocsdir));
-        wctombs(mydocsdir, mydocsdirw, sizeof(mydocsdir)-1);
-        CoTaskMemFree(mydocsdirw);
-        path.clear();
-        path << DirectoryCleaned(mydocsdir) << (prefix+1) << "/";
-        if(file_is_directory(path.c_str()))
-        {
-          g_qeglobals.m_userEnginePath = path.c_str();
-          CoUninitialize();
-          FreeLibrary(shfolder);
-          break;
-        }
-      }
-      CoUninitialize();
-      if(shfolder)
-        FreeLibrary(shfolder);
-      if(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, mydocsdir))
-      {
-        path.clear();
-        path << DirectoryCleaned(mydocsdir) << "My Games/" << (prefix+1) << "/";
-        // win32: only add it if it already exists
-        if(file_is_directory(path.c_str()))
-        {
-          g_qeglobals.m_userEnginePath = path.c_str();
-          break;
-        }
-      }
+#if GDEF_OS_WINDOWS
+                                                                                                                                    TCHAR mydocsdir[MAX_PATH + 1];
+                       wchar_t *mydocsdirw;
+                       HMODULE shfolder = LoadLibrary( "shfolder.dll" );
+                       if ( shfolder ) {
+                               qSHGetKnownFolderPath = (qSHGetKnownFolderPath_t *) GetProcAddress( shfolder, "SHGetKnownFolderPath" );
+                       }
+                       else{
+                               qSHGetKnownFolderPath = NULL;
+                       }
+                       CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
+                       if ( qSHGetKnownFolderPath && qSHGetKnownFolderPath( qFOLDERID_SavedGames, qKF_FLAG_CREATE | qKF_FLAG_NO_ALIAS, NULL, &mydocsdirw ) == S_OK ) {
+                               memset( mydocsdir, 0, sizeof( mydocsdir ) );
+                               wcstombs( mydocsdir, mydocsdirw, sizeof( mydocsdir ) - 1 );
+                               CoTaskMemFree( mydocsdirw );
+                               path.clear();
+                               path << DirectoryCleaned( mydocsdir ) << ( prefix + 1 ) << "/";
+                               if ( file_is_directory( path.c_str() ) ) {
+                                       g_qeglobals.m_userEnginePath = path.c_str();
+                                       CoUninitialize();
+                                       FreeLibrary( shfolder );
+                                       break;
+                               }
+                       }
+                       CoUninitialize();
+                       if ( shfolder ) {
+                               FreeLibrary( shfolder );
+                       }
+                       if ( SHGetFolderPath( NULL, CSIDL_PERSONAL, NULL, 0, mydocsdir ) ) {
+                               path.clear();
+                               path << DirectoryCleaned( mydocsdir ) << "My Games/" << ( prefix + 1 ) << "/";
+                               // win32: only add it if it already exists
+                               if ( file_is_directory( path.c_str() ) ) {
+                                       g_qeglobals.m_userEnginePath = path.c_str();
+                                       break;
+                               }
+                       }
 #endif
 
-#if defined(POSIX)
-      path.clear();
-      path << DirectoryCleaned(g_get_home_dir()) << prefix << "/";
-      g_qeglobals.m_userEnginePath = path.c_str();
-      break;
+#if GDEF_OS_POSIX
+            path.clear();
+            path << DirectoryCleaned(g_get_home_dir()) << prefix << "/";
+            g_qeglobals.m_userEnginePath = path.c_str();
+            break;
 #endif
-    }
+        }
 
-    g_qeglobals.m_userEnginePath = EnginePath_get();
-  }
-  while(0);
+        g_qeglobals.m_userEnginePath = EnginePath_get();
+    } while (0);
 
-  Q_mkdir(g_qeglobals.m_userEnginePath.c_str());
+    Q_mkdir(g_qeglobals.m_userEnginePath.c_str());
 
-  {
-    StringOutputStream path(256);
-    path << g_qeglobals.m_userEnginePath.c_str() << gamename_get() << '/';
-    g_qeglobals.m_userGamePath = path.c_str();
-  }
-  ASSERT_MESSAGE(!string_empty(g_qeglobals.m_userGamePath.c_str()), "HomePaths_Realise: user-game-path is empty");
-  Q_mkdir(g_qeglobals.m_userGamePath.c_str());
+    {
+        StringOutputStream path(256);
+        path << g_qeglobals.m_userEnginePath.c_str() << gamename_get() << '/';
+        g_qeglobals.m_userGamePath = path.c_str();
+    }
+    ASSERT_MESSAGE(!string_empty(g_qeglobals.m_userGamePath.c_str()), "HomePaths_Realise: user-game-path is empty");
+    Q_mkdir(g_qeglobals.m_userGamePath.c_str());
 }
 
 ModuleObservers g_homePathObservers;
 
-void Radiant_attachHomePathsObserver(ModuleObserverobserver)
+void Radiant_attachHomePathsObserver(ModuleObserver &observer)
 {
-  g_homePathObservers.attach(observer);
+    g_homePathObservers.attach(observer);
 }
 
-void Radiant_detachHomePathsObserver(ModuleObserverobserver)
+void Radiant_detachHomePathsObserver(ModuleObserver &observer)
 {
-  g_homePathObservers.detach(observer);
+    g_homePathObservers.detach(observer);
 }
 
-class HomePathsModuleObserver : public ModuleObserver
-{
-  std::size_t m_unrealised;
+class HomePathsModuleObserver : public ModuleObserver {
+    std::size_t m_unrealised;
 public:
-  HomePathsModuleObserver() : m_unrealised(1)
-  {
-  }
-  void realise()
-  {
-    if(--m_unrealised == 0)
+    HomePathsModuleObserver() : m_unrealised(1)
+    {
+    }
+
+    void realise()
     {
-      HomePaths_Realise();
-      g_homePathObservers.realise();
+        if (--m_unrealised == 0) {
+            HomePaths_Realise();
+            g_homePathObservers.realise();
+        }
     }
-  }
-  void unrealise()
-  {
-    if(++m_unrealised == 1)
+
+    void unrealise()
     {
-      g_homePathObservers.unrealise();
+        if (++m_unrealised == 1) {
+            g_homePathObservers.unrealise();
+        }
     }
-  }
 };
 
 HomePathsModuleObserver g_HomePathsModuleObserver;
@@ -316,6 +324,7 @@ void HomePaths_Construct()
 {
     Radiant_attachEnginePathObserver(g_HomePathsModuleObserver);
 }
+
 void HomePaths_Destroy()
 {
     Radiant_detachEnginePathObserver(g_HomePathsModuleObserver);
@@ -328,69 +337,124 @@ CopiedString g_strEnginePath;
 ModuleObservers g_enginePathObservers;
 std::size_t g_enginepath_unrealised = 1;
 
-void Radiant_attachEnginePathObserver(ModuleObserverobserver)
+void Radiant_attachEnginePathObserver(ModuleObserver &observer)
 {
-  g_enginePathObservers.attach(observer);
+    g_enginePathObservers.attach(observer);
 }
 
-void Radiant_detachEnginePathObserver(ModuleObserverobserver)
+void Radiant_detachEnginePathObserver(ModuleObserver &observer)
 {
-  g_enginePathObservers.detach(observer);
+    g_enginePathObservers.detach(observer);
 }
 
 
 void EnginePath_Realise()
 {
-  if(--g_enginepath_unrealised == 0)
-  {
-    g_enginePathObservers.realise();
-  }
+    if (--g_enginepath_unrealised == 0) {
+        g_enginePathObservers.realise();
+    }
 }
 
 
-const charEnginePath_get()
+const char *EnginePath_get()
 {
-  ASSERT_MESSAGE(g_enginepath_unrealised == 0, "EnginePath_get: engine path not realised");
-  return g_strEnginePath.c_str();
+    ASSERT_MESSAGE(g_enginepath_unrealised == 0, "EnginePath_get: engine path not realised");
+    return g_strEnginePath.c_str();
 }
 
 void EnginePath_Unrealise()
 {
-  if(++g_enginepath_unrealised == 1)
-  {
-    g_enginePathObservers.unrealise();
-  }
+    if (++g_enginepath_unrealised == 1) {
+        g_enginePathObservers.unrealise();
+    }
 }
 
-void setEnginePath(const charpath)
+void setEnginePath(const char *path)
 {
-  StringOutputStream buffer(256);
-  buffer << DirectoryCleaned(path);
-  if(!path_equal(buffer.c_str(), g_strEnginePath.c_str()))
-  {
+    StringOutputStream buffer(256);
+    buffer << DirectoryCleaned(path);
+    if (!path_equal(buffer.c_str(), g_strEnginePath.c_str())) {
 #if 0
-    while(!ConfirmModified("Paths Changed"))
-    {
-      if(Map_Unnamed(g_map))
-      {
-        Map_SaveAs();
-      }
-      else
-      {
-        Map_Save();
-      }
-    }
-    Map_RegionOff();
+                                                                                                                                while ( !ConfirmModified( "Paths Changed" ) )
+               {
+                       if ( Map_Unnamed( g_map ) ) {
+                               Map_SaveAs();
+                       }
+                       else
+                       {
+                               Map_Save();
+                       }
+               }
+               Map_RegionOff();
 #endif
 
-    ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Changing Engine Path");
+        ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Changing Engine Path");
 
-    EnginePath_Unrealise();
+        EnginePath_Unrealise();
 
-    g_strEnginePath = buffer.c_str();
+        g_strEnginePath = buffer.c_str();
 
-    EnginePath_Realise();
-  }
+        EnginePath_Realise();
+    }
+}
+
+// Pak Path
+
+CopiedString g_strPakPath[g_pakPathCount] = {"", "", "", "", ""};
+ModuleObservers g_pakPathObservers[g_pakPathCount];
+std::size_t g_pakpath_unrealised[g_pakPathCount] = {1, 1, 1, 1, 1};
+
+void Radiant_attachPakPathObserver(int num, ModuleObserver &observer)
+{
+    g_pakPathObservers[num].attach(observer);
+}
+
+void Radiant_detachPakPathObserver(int num, ModuleObserver &observer)
+{
+    g_pakPathObservers[num].detach(observer);
+}
+
+
+void PakPath_Realise(int num)
+{
+    if (--g_pakpath_unrealised[num] == 0) {
+        g_pakPathObservers[num].realise();
+    }
+}
+
+const char *PakPath_get(int num)
+{
+    std::string message = "PakPath_get: pak path " + std::to_string(num) + " not realised";
+    ASSERT_MESSAGE(g_pakpath_unrealised[num] == 0, message.c_str());
+    return g_strPakPath[num].c_str();
+}
+
+void PakPath_Unrealise(int num)
+{
+    if (++g_pakpath_unrealised[num] == 1) {
+        g_pakPathObservers[num].unrealise();
+    }
+}
+
+void setPakPath(int num, const char *path)
+{
+    if (!g_strcmp0(path, "")) {
+        g_strPakPath[num] = "";
+        return;
+    }
+
+    StringOutputStream buffer(256);
+    buffer << DirectoryCleaned(path);
+    if (!path_equal(buffer.c_str(), g_strPakPath[num].c_str())) {
+        std::string message = "Changing Pak Path " + std::to_string(num);
+        ScopeDisableScreenUpdates disableScreenUpdates("Processing...", message.c_str());
+
+        PakPath_Unrealise(num);
+
+        g_strPakPath[num] = buffer.c_str();
+
+        PakPath_Realise(num);
+    }
 }
 
 
@@ -398,253 +462,336 @@ void setEnginePath(const char* path)
 
 CopiedString g_strAppPath;                 ///< holds the full path of the executable
 
-const charAppPath_get()
+const char *AppPath_get()
 {
-  return g_strAppPath.c_str();
+    return g_strAppPath.c_str();
 }
 
 /// the path to the local rc-dir
-const charLocalRcPath_get(void)
+const char *LocalRcPath_get(void)
 {
-  static CopiedString rc_path;
-  if(rc_path.empty())
-  {
-    StringOutputStream stream(256);
-       stream << GlobalRadiant().getSettingsPath() << g_pGameDescription->mGameFile.c_str() << "/";
-       rc_path = stream.c_str();
-  }
-  return rc_path.c_str();
+    static CopiedString rc_path;
+    if (rc_path.empty()) {
+        StringOutputStream stream(256);
+        stream << GlobalRadiant().getSettingsPath() << g_pGameDescription->mGameFile.c_str() << "/";
+        rc_path = stream.c_str();
+    }
+    return rc_path.c_str();
 }
 
 /// directory for temp files
 /// NOTE: on *nix this is were we check for .pid
 CopiedString g_strSettingsPath;
-const char* SettingsPath_get()
+
+const char *SettingsPath_get()
 {
-  return g_strSettingsPath.c_str();
+    return g_strSettingsPath.c_str();
 }
 
 
 /*!
-points to the game tools directory, for instance
-C:/Program Files/Quake III Arena/GtkRadiant
-(or other games)
-this is one of the main variables that are configured by the game selection on startup
-[GameToolsPath]/plugins
-[GameToolsPath]/modules
-and also q3map, bspc
-*/
+   points to the game tools directory, for instance
+   C:/Program Files/Quake III Arena/GtkRadiant
+   (or other games)
+   this is one of the main variables that are configured by the game selection on startup
+   [GameToolsPath]/plugins
+   [GameToolsPath]/modules
+   and also q3map, bspc
+ */
 CopiedString g_strGameToolsPath;           ///< this is set by g_GamesDialog
 
-const charGameToolsPath_get()
+const char *GameToolsPath_get()
 {
-  return g_strGameToolsPath.c_str();
+    return g_strGameToolsPath.c_str();
 }
 
-void EnginePathImport(CopiedString& self, const char* value)
-{
-  setEnginePath(value);
-}
-typedef ReferenceCaller1<CopiedString, const char*, EnginePathImport> EnginePathImportCaller;
+struct EnginePath {
+    static void Export(const CopiedString &self, const Callback<void(const char *)> &returnz)
+    {
+        returnz(self.c_str());
+    }
+
+    static void Import(CopiedString &self, const char *value)
+    {
+        setEnginePath(value);
+    }
+};
 
-void Paths_constructPreferences(PreferencesPage& page)
+struct PakPath0 {
+    static void Export(const CopiedString &self, const Callback<void(const char *)> &returnz)
+    {
+        returnz(self.c_str());
+    }
+
+    static void Import(CopiedString &self, const char *value)
+    {
+        setPakPath(0, value);
+    }
+};
+
+struct PakPath1 {
+    static void Export(const CopiedString &self, const Callback<void(const char *)> &returnz)
+    {
+        returnz(self.c_str());
+    }
+
+    static void Import(CopiedString &self, const char *value)
+    {
+        setPakPath(1, value);
+    }
+};
+
+struct PakPath2 {
+    static void Export(const CopiedString &self, const Callback<void(const char *)> &returnz)
+    {
+        returnz(self.c_str());
+    }
+
+    static void Import(CopiedString &self, const char *value)
+    {
+        setPakPath(2, value);
+    }
+};
+
+struct PakPath3 {
+    static void Export(const CopiedString &self, const Callback<void(const char *)> &returnz)
+    {
+        returnz(self.c_str());
+    }
+
+    static void Import(CopiedString &self, const char *value)
+    {
+        setPakPath(3, value);
+    }
+};
+
+struct PakPath4 {
+    static void Export(const CopiedString &self, const Callback<void(const char *)> &returnz)
+    {
+        returnz(self.c_str());
+    }
+
+    static void Import(CopiedString &self, const char *value)
+    {
+        setPakPath(4, value);
+    }
+};
+
+bool g_disableEnginePath = false;
+bool g_disableHomePath = false;
+
+void Paths_constructPreferences(PreferencesPage &page)
 {
-  page.appendPathEntry("Engine Path", true,
-    StringImportCallback(EnginePathImportCaller(g_strEnginePath)),
-    StringExportCallback(StringExportCaller(g_strEnginePath))
-  );
+    page.appendPathEntry("Engine Path", true, make_property<EnginePath>(g_strEnginePath));
+
+    page.appendCheckBox(
+            "", "Do not use Engine Path",
+            g_disableEnginePath
+    );
+
+    page.appendCheckBox(
+            "", "Do not use Home Path",
+            g_disableHomePath
+    );
+
+    for (int i = 0; i < g_pakPathCount; i++) {
+        std::string label = "Pak Path " + std::to_string(i);
+        switch (i) {
+            case 0:
+                page.appendPathEntry(label.c_str(), true, make_property<PakPath0>(g_strPakPath[i]));
+                break;
+            case 1:
+                page.appendPathEntry(label.c_str(), true, make_property<PakPath1>(g_strPakPath[i]));
+                break;
+            case 2:
+                page.appendPathEntry(label.c_str(), true, make_property<PakPath2>(g_strPakPath[i]));
+                break;
+            case 3:
+                page.appendPathEntry(label.c_str(), true, make_property<PakPath3>(g_strPakPath[i]));
+                break;
+            case 4:
+                page.appendPathEntry(label.c_str(), true, make_property<PakPath4>(g_strPakPath[i]));
+                break;
+        }
+    }
 }
-void Paths_constructPage(PreferenceGroup& group)
+
+void Paths_constructPage(PreferenceGroup &group)
 {
-  PreferencesPage page(group.createPage("Paths", "Path Settings"));
-  Paths_constructPreferences(page);
+    PreferencesPage page(group.createPage("Paths", "Path Settings"));
+    Paths_constructPreferences(page);
 }
+
 void Paths_registerPreferencesPage()
 {
-  PreferencesDialog_addSettingsPage(FreeCaller1<PreferenceGroup&, Paths_constructPage>());
+    PreferencesDialog_addSettingsPage(makeCallbackF(Paths_constructPage));
 }
 
 
-class PathsDialog : public Dialog
-{
+class PathsDialog : public Dialog {
 public:
-  GtkWindow* BuildDialog()
-  {
-    GtkFrame* frame = create_dialog_frame("Path settings", GTK_SHADOW_ETCHED_IN);
+    ui::Window BuildDialog()
+    {
+        auto frame = create_dialog_frame("Path settings", ui::Shadow::ETCHED_IN);
 
-    GtkVBox* vbox2 = create_dialog_vbox(0, 4);
-    gtk_container_add(GTK_CONTAINER(frame), GTK_WIDGET(vbox2));
+        auto vbox2 = create_dialog_vbox(0, 4);
+        frame.add(vbox2);
 
-    {
-      PreferencesPage preferencesPage(*this, GTK_WIDGET(vbox2));
-      Paths_constructPreferences(preferencesPage);
-    }
+        {
+            PreferencesPage preferencesPage(*this, vbox2);
+            Paths_constructPreferences(preferencesPage);
+        }
 
-    return create_simple_modal_dialog_window("Engine Path Not Found", m_modal, GTK_WIDGET(frame));
-  }
+        return ui::Window(create_simple_modal_dialog_window("Engine Path Not Found", m_modal, frame));
+    }
 };
 
 PathsDialog g_PathsDialog;
 
 void EnginePath_verify()
 {
-  if(!file_exists(g_strEnginePath.c_str()))
-  {
-    g_PathsDialog.Create();
-    g_PathsDialog.DoModal();
-    g_PathsDialog.Destroy();
-  }
+    if (!file_exists(g_strEnginePath.c_str())) {
+        g_PathsDialog.Create();
+        g_PathsDialog.DoModal();
+        g_PathsDialog.Destroy();
+    }
 }
 
-namespace
-{
-  CopiedString g_gamename;
-  CopiedString g_gamemode;
-  ModuleObservers g_gameNameObservers;
-  ModuleObservers g_gameModeObservers;
+namespace {
+    CopiedString g_gamename;
+    CopiedString g_gamemode;
+    ModuleObservers g_gameNameObservers;
+    ModuleObservers g_gameModeObservers;
 }
 
-void Radiant_attachGameNameObserver(ModuleObserverobserver)
+void Radiant_attachGameNameObserver(ModuleObserver &observer)
 {
-  g_gameNameObservers.attach(observer);
+    g_gameNameObservers.attach(observer);
 }
 
-void Radiant_detachGameNameObserver(ModuleObserverobserver)
+void Radiant_detachGameNameObserver(ModuleObserver &observer)
 {
-  g_gameNameObservers.detach(observer);
+    g_gameNameObservers.detach(observer);
 }
 
-const charbasegame_get()
+const char *basegame_get()
 {
-  return g_pGameDescription->getRequiredKeyValue("basegame");
+    return g_pGameDescription->getRequiredKeyValue("basegame");
 }
 
-const chargamename_get()
+const char *gamename_get()
 {
-  const char* gamename = g_gamename.c_str();
-  if(string_empty(gamename))
-  {
-    return basegame_get();
-  }
-  return gamename;
+    const char *gamename = g_gamename.c_str();
+    if (string_empty(gamename)) {
+        return basegame_get();
+    }
+    return gamename;
 }
 
-void gamename_set(const chargamename)
+void gamename_set(const char *gamename)
 {
-  if(!string_equal(gamename, g_gamename.c_str()))
-  {
-    g_gameNameObservers.unrealise();
-    g_gamename = gamename;
-    g_gameNameObservers.realise();
-  }
+    if (!string_equal(gamename, g_gamename.c_str())) {
+        g_gameNameObservers.unrealise();
+        g_gamename = gamename;
+        g_gameNameObservers.realise();
+    }
 }
 
-void Radiant_attachGameModeObserver(ModuleObserverobserver)
+void Radiant_attachGameModeObserver(ModuleObserver &observer)
 {
-  g_gameModeObservers.attach(observer);
+    g_gameModeObservers.attach(observer);
 }
 
-void Radiant_detachGameModeObserver(ModuleObserverobserver)
+void Radiant_detachGameModeObserver(ModuleObserver &observer)
 {
-  g_gameModeObservers.detach(observer);
+    g_gameModeObservers.detach(observer);
 }
 
-const chargamemode_get()
+const char *gamemode_get()
 {
-  return g_gamemode.c_str();
+    return g_gamemode.c_str();
 }
 
-void gamemode_set(const chargamemode)
+void gamemode_set(const char *gamemode)
 {
-  if(!string_equal(gamemode, g_gamemode.c_str()))
-  {
-    g_gameModeObservers.unrealise();
-    g_gamemode = gamemode;
-    g_gameModeObservers.realise();
-  }
+    if (!string_equal(gamemode, g_gamemode.c_str())) {
+        g_gameModeObservers.unrealise();
+        g_gamemode = gamemode;
+        g_gameModeObservers.realise();
+    }
 }
 
-#include "os/dir.h"
 
-class CLoadModule
-{
-  const char* m_path;
-public:
-  CLoadModule(const char* path) : m_path(path)
-  {
-  }
-  void operator()(const char* name) const
-  {
-    char fullname[1024];
-    ASSERT_MESSAGE(strlen(m_path) + strlen(name) < 1024, "");
-    strcpy(fullname, m_path);
-    strcat(fullname, name);
-    globalOutputStream() << "Found '" << fullname << "'\n";
-    GlobalModuleServer_loadModule(fullname);
-  }
-};
+#include "os/dir.h"
 
-const char* const c_library_extension =
-#if defined(WIN32)
-"dll"
-#elif defined (__APPLE__)
-"dylib"
-#elif defined(__linux__) || defined (__FreeBSD__)
-"so"
+const char *const c_library_extension =
+#if defined( CMAKE_SHARED_MODULE_SUFFIX )
+        CMAKE_SHARED_MODULE_SUFFIX
+#elif GDEF_OS_WINDOWS
+                                                                                                                        "dll"
+#elif GDEF_OS_MACOS
+       "dylib"
+#elif GDEF_OS_LINUX || GDEF_OS_BSD
+       "so"
 #endif
 ;
 
-void Radiant_loadModules(const charpath)
+void Radiant_loadModules(const char *path)
 {
-  Directory_forEach(path, MatchFileExtension<CLoadModule>(c_library_extension, CLoadModule(path)));
+    Directory_forEach(path, matchFileExtension(c_library_extension, [&](const char *name) {
+        char fullname[1024];
+        ASSERT_MESSAGE(strlen(path) + strlen(name) < 1024, "");
+        strcpy(fullname, path);
+        strcat(fullname, name);
+        globalOutputStream() << "Found '" << fullname << "'\n";
+        GlobalModuleServer_loadModule(fullname);
+    }));
 }
 
-void Radiant_loadModulesFromRoot(const chardirectory)
+void Radiant_loadModulesFromRoot(const char *directory)
 {
-  {
-    StringOutputStream path(256);
-    path << directory << g_pluginsDir;
-    Radiant_loadModules(path.c_str());
-  }
+    {
+        StringOutputStream path(256);
+        path << directory << g_pluginsDir;
+        Radiant_loadModules(path.c_str());
+    }
 
-  if(!string_equal(g_pluginsDir, g_modulesDir))
-  {
-    StringOutputStream path(256);
-    path << directory << g_modulesDir;
-    Radiant_loadModules(path.c_str());
-  }
+    if (!string_equal(g_pluginsDir, g_modulesDir)) {
+        StringOutputStream path(256);
+        path << directory << g_modulesDir;
+        Radiant_loadModules(path.c_str());
+    }
 }
 
 //! Make COLOR_BRUSHES override worldspawn eclass colour.
-void SetWorldspawnColour(const Vector3colour)
+void SetWorldspawnColour(const Vector3 &colour)
 {
-  EntityClass* worldspawn = GlobalEntityClassManager().findOrInsert("worldspawn", true);
-  eclass_release_state(worldspawn);
-  worldspawn->color = colour;
-  eclass_capture_state(worldspawn);
+    EntityClass *worldspawn = GlobalEntityClassManager().findOrInsert("worldspawn", true);
+    eclass_release_state(worldspawn);
+    worldspawn->color = colour;
+    eclass_capture_state(worldspawn);
 }
 
 
-class WorldspawnColourEntityClassObserver : public ModuleObserver
-{
-  std::size_t m_unrealised;
+class WorldspawnColourEntityClassObserver : public ModuleObserver {
+    std::size_t m_unrealised;
 public:
-  WorldspawnColourEntityClassObserver() : m_unrealised(1)
-  {
-  }
-  void realise()
-  {
-    if(--m_unrealised == 0)
+    WorldspawnColourEntityClassObserver() : m_unrealised(1)
+    {
+    }
+
+    void realise()
     {
-      SetWorldspawnColour(g_xywindow_globals.color_brushes);
+        if (--m_unrealised == 0) {
+            SetWorldspawnColour(g_xywindow_globals.color_brushes);
+        }
     }
-  }
-  void unrealise()
-  {
-    if(++m_unrealised == 1)
+
+    void unrealise()
     {
+        if (++m_unrealised == 1) {
+        }
     }
-  }
 };
 
 WorldspawnColourEntityClassObserver g_WorldspawnColourEntityClassObserver;
@@ -652,1227 +799,1157 @@ WorldspawnColourEntityClassObserver g_WorldspawnColourEntityClassObserver;
 
 ModuleObservers g_gameToolsPathObservers;
 
-void Radiant_attachGameToolsPathObserver(ModuleObserverobserver)
+void Radiant_attachGameToolsPathObserver(ModuleObserver &observer)
 {
-  g_gameToolsPathObservers.attach(observer);
+    g_gameToolsPathObservers.attach(observer);
 }
 
-void Radiant_detachGameToolsPathObserver(ModuleObserverobserver)
+void Radiant_detachGameToolsPathObserver(ModuleObserver &observer)
 {
-  g_gameToolsPathObservers.detach(observer);
+    g_gameToolsPathObservers.detach(observer);
 }
 
 void Radiant_Initialise()
 {
-  GlobalModuleServer_Initialise();
+    GlobalModuleServer_Initialise();
 
-  Radiant_loadModulesFromRoot(AppPath_get());
+    Radiant_loadModulesFromRoot(AppPath_get());
 
-  Preferences_Load();
+    Preferences_Load();
 
-  bool success = Radiant_Construct(GlobalModuleServer_get());
-  ASSERT_MESSAGE(success, "module system failed to initialise - see radiant.log for error messages");
+    bool success = Radiant_Construct(GlobalModuleServer_get());
+    ASSERT_MESSAGE(success, "module system failed to initialise - see radiant.log for error messages");
 
-  g_gameToolsPathObservers.realise();
-  g_gameModeObservers.realise();
-  g_gameNameObservers.realise();
+    g_gameToolsPathObservers.realise();
+    g_gameModeObservers.realise();
+    g_gameNameObservers.realise();
 }
 
 void Radiant_Shutdown()
 {
-  g_gameNameObservers.unrealise();
-  g_gameModeObservers.unrealise();
-  g_gameToolsPathObservers.unrealise();
+    g_gameNameObservers.unrealise();
+    g_gameModeObservers.unrealise();
+    g_gameToolsPathObservers.unrealise();
 
-  if (!g_preferences_globals.disable_ini)
-  {
-    globalOutputStream() << "Start writing prefs\n";
-    Preferences_Save();
-    globalOutputStream() << "Done prefs\n";
-  }
+    if (!g_preferences_globals.disable_ini) {
+        globalOutputStream() << "Start writing prefs\n";
+        Preferences_Save();
+        globalOutputStream() << "Done prefs\n";
+    }
 
-  Radiant_Destroy();
+    Radiant_Destroy();
 
-  GlobalModuleServer_Shutdown();
+    GlobalModuleServer_Shutdown();
 }
 
 void Exit()
 {
-  if(ConfirmModified("Exit Radiant"))
-  {
-    gtk_main_quit();
-  }
+    if (ConfirmModified("Exit Radiant")) {
+        gtk_main_quit();
+    }
 }
 
 
 void Undo()
 {
-  GlobalUndoSystem().undo();
-  SceneChangeNotify();
+    GlobalUndoSystem().undo();
+    SceneChangeNotify();
 }
 
 void Redo()
 {
-  GlobalUndoSystem().redo();
-  SceneChangeNotify();
+    GlobalUndoSystem().redo();
+    SceneChangeNotify();
 }
 
 void deleteSelection()
 {
-  UndoableCommand undo("deleteSelected");
-  Select_Delete();
+    UndoableCommand undo("deleteSelected");
+    Select_Delete();
 }
 
-void Map_ExportSelected(TextOutputStreamostream)
+void Map_ExportSelected(TextOutputStream &ostream)
 {
-  Map_ExportSelected(ostream, Map_getFormat(g_map));
+    Map_ExportSelected(ostream, Map_getFormat(g_map));
 }
 
-void Map_ImportSelected(TextInputStreamistream)
+void Map_ImportSelected(TextInputStream &istream)
 {
-  Map_ImportSelected(istream, Map_getFormat(g_map));
+    Map_ImportSelected(istream, Map_getFormat(g_map));
 }
 
 void Selection_Copy()
 {
-  clipboard_copy(Map_ExportSelected);
+    clipboard_copy(Map_ExportSelected);
 }
 
 void Selection_Paste()
 {
-  clipboard_paste(Map_ImportSelected);
+    clipboard_paste(Map_ImportSelected);
 }
 
 void Copy()
 {
-  if(SelectedFaces_empty())
-  {
-    Selection_Copy();
-  }
-  else
-  {
-    SelectedFaces_copyTexture();
-  }
+    if (SelectedFaces_empty()) {
+        Selection_Copy();
+    } else {
+        SelectedFaces_copyTexture();
+    }
 }
 
 void Paste()
 {
-  if(SelectedFaces_empty())
-  {
-    UndoableCommand undo("paste");
+    if (SelectedFaces_empty()) {
+        UndoableCommand undo("paste");
 
-    GlobalSelectionSystem().setSelectedAll(false);
-    Selection_Paste();
-  }
-  else
-  {
-    SelectedFaces_pasteTexture();
-  }
+        GlobalSelectionSystem().setSelectedAll(false);
+        Selection_Paste();
+    } else {
+        SelectedFaces_pasteTexture();
+    }
 }
 
 void PasteToCamera()
 {
-  CamWnd& camwnd = *g_pParentWnd->GetCamWnd();
-  GlobalSelectionSystem().setSelectedAll(false);
+    CamWnd &camwnd = *g_pParentWnd->GetCamWnd();
+    GlobalSelectionSystem().setSelectedAll(false);
 
-  UndoableCommand undo("pasteToCamera");
+    UndoableCommand undo("pasteToCamera");
 
-  Selection_Paste();
+    Selection_Paste();
 
-  // Work out the delta
-  Vector3 mid;
-  Select_GetMid(mid);
-  Vector3 delta = vector3_subtracted(vector3_snapped(Camera_getOrigin(camwnd), GetSnapGridSize()), mid);
+    // Work out the delta
+    Vector3 mid;
+    Select_GetMid(mid);
+    Vector3 delta = vector3_subtracted(vector3_snapped(Camera_getOrigin(camwnd), GetSnapGridSize()), mid);
 
-  // Move to camera
-  GlobalSelectionSystem().translateSelected(delta);
+    // Move to camera
+    GlobalSelectionSystem().translateSelected(delta);
 }
 
 
 void ColorScheme_Original()
 {
-  TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f));
+    TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f));
 
-  g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f);
-  g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f);
-  CamWnd_Update(*g_pParentWnd->GetCamWnd());
+    g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f);
+    g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f);
+    CamWnd_Update(*g_pParentWnd->GetCamWnd());
 
-  g_xywindow_globals.color_gridback = Vector3(1.0f, 1.0f, 1.0f);
-  g_xywindow_globals.color_gridminor = Vector3(0.75f, 0.75f, 0.75f);
-  g_xywindow_globals.color_gridmajor = Vector3(0.5f, 0.5f, 0.5f);
-  g_xywindow_globals.color_gridminor_alt = Vector3(0.5f, 0.0f, 0.0f);
-  g_xywindow_globals.color_gridmajor_alt = Vector3(1.0f, 0.0f, 0.0f);
-  g_xywindow_globals.color_gridblock = Vector3(0.0f, 0.0f, 1.0f);
-  g_xywindow_globals.color_gridtext = Vector3(0.0f, 0.0f, 0.0f);
-  g_xywindow_globals.color_selbrushes = Vector3(1.0f, 0.0f, 0.0f);
-  g_xywindow_globals.color_clipper = Vector3(0.0f, 0.0f, 1.0f);
-  g_xywindow_globals.color_brushes = Vector3(0.0f, 0.0f, 0.0f);
-  SetWorldspawnColour(g_xywindow_globals.color_brushes);
-  g_xywindow_globals.color_viewname = Vector3(0.5f, 0.0f, 0.75f);
-  XY_UpdateAllWindows();
+    g_xywindow_globals.color_gridback = Vector3(1.0f, 1.0f, 1.0f);
+    g_xywindow_globals.color_gridminor = Vector3(0.75f, 0.75f, 0.75f);
+    g_xywindow_globals.color_gridmajor = Vector3(0.5f, 0.5f, 0.5f);
+    g_xywindow_globals.color_gridminor_alt = Vector3(0.5f, 0.0f, 0.0f);
+    g_xywindow_globals.color_gridmajor_alt = Vector3(1.0f, 0.0f, 0.0f);
+    g_xywindow_globals.color_gridblock = Vector3(0.0f, 0.0f, 1.0f);
+    g_xywindow_globals.color_gridtext = Vector3(0.0f, 0.0f, 0.0f);
+    g_xywindow_globals.color_selbrushes = Vector3(1.0f, 0.0f, 0.0f);
+    g_xywindow_globals.color_clipper = Vector3(0.0f, 0.0f, 1.0f);
+    g_xywindow_globals.color_brushes = Vector3(0.0f, 0.0f, 0.0f);
+    SetWorldspawnColour(g_xywindow_globals.color_brushes);
+    g_xywindow_globals.color_viewname = Vector3(0.5f, 0.0f, 0.75f);
+    XY_UpdateAllWindows();
 }
 
 void ColorScheme_QER()
 {
-  TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f));
+    TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f));
 
-  g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f);
-  g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f);
-  CamWnd_Update(*g_pParentWnd->GetCamWnd());
+    g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f);
+    g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f);
+    CamWnd_Update(*g_pParentWnd->GetCamWnd());
 
-  g_xywindow_globals.color_gridback = Vector3(1.0f, 1.0f, 1.0f);
-  g_xywindow_globals.color_gridminor = Vector3(1.0f, 1.0f, 1.0f);
-  g_xywindow_globals.color_gridmajor = Vector3(0.5f, 0.5f, 0.5f);
-  g_xywindow_globals.color_gridblock = Vector3(0.0f, 0.0f, 1.0f);
-  g_xywindow_globals.color_gridtext = Vector3(0.0f, 0.0f, 0.0f);
-  g_xywindow_globals.color_selbrushes = Vector3(1.0f, 0.0f, 0.0f);
-  g_xywindow_globals.color_clipper = Vector3(0.0f, 0.0f, 1.0f);
-  g_xywindow_globals.color_brushes = Vector3(0.0f, 0.0f, 0.0f);
-  SetWorldspawnColour(g_xywindow_globals.color_brushes);
-  g_xywindow_globals.color_viewname = Vector3(0.5f, 0.0f, 0.75f);
-  XY_UpdateAllWindows();
+    g_xywindow_globals.color_gridback = Vector3(1.0f, 1.0f, 1.0f);
+    g_xywindow_globals.color_gridminor = Vector3(1.0f, 1.0f, 1.0f);
+    g_xywindow_globals.color_gridmajor = Vector3(0.5f, 0.5f, 0.5f);
+    g_xywindow_globals.color_gridblock = Vector3(0.0f, 0.0f, 1.0f);
+    g_xywindow_globals.color_gridtext = Vector3(0.0f, 0.0f, 0.0f);
+    g_xywindow_globals.color_selbrushes = Vector3(1.0f, 0.0f, 0.0f);
+    g_xywindow_globals.color_clipper = Vector3(0.0f, 0.0f, 1.0f);
+    g_xywindow_globals.color_brushes = Vector3(0.0f, 0.0f, 0.0f);
+    SetWorldspawnColour(g_xywindow_globals.color_brushes);
+    g_xywindow_globals.color_viewname = Vector3(0.5f, 0.0f, 0.75f);
+    XY_UpdateAllWindows();
 }
 
 void ColorScheme_Black()
 {
-  TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f));
+    TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f));
 
-  g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f);
-  g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f);
-  CamWnd_Update(*g_pParentWnd->GetCamWnd());
+    g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f);
+    g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f);
+    CamWnd_Update(*g_pParentWnd->GetCamWnd());
 
-  g_xywindow_globals.color_gridback = Vector3(0.0f, 0.0f, 0.0f);
-  g_xywindow_globals.color_gridminor = Vector3(0.2f, 0.2f, 0.2f);
-  g_xywindow_globals.color_gridmajor = Vector3(0.3f, 0.5f, 0.5f);
-  g_xywindow_globals.color_gridblock = Vector3(0.0f, 0.0f, 1.0f);
-  g_xywindow_globals.color_gridtext = Vector3(1.0f, 1.0f, 1.0f);
-  g_xywindow_globals.color_selbrushes = Vector3(1.0f, 0.0f, 0.0f);
-  g_xywindow_globals.color_clipper = Vector3(0.0f, 0.0f, 1.0f);
-  g_xywindow_globals.color_brushes = Vector3(1.0f, 1.0f, 1.0f);
-  SetWorldspawnColour(g_xywindow_globals.color_brushes);
-  g_xywindow_globals.color_viewname = Vector3(0.7f, 0.7f, 0.0f);
-  XY_UpdateAllWindows();
+    g_xywindow_globals.color_gridback = Vector3(0.0f, 0.0f, 0.0f);
+    g_xywindow_globals.color_gridminor = Vector3(0.2f, 0.2f, 0.2f);
+    g_xywindow_globals.color_gridmajor = Vector3(0.3f, 0.5f, 0.5f);
+    g_xywindow_globals.color_gridblock = Vector3(0.0f, 0.0f, 1.0f);
+    g_xywindow_globals.color_gridtext = Vector3(1.0f, 1.0f, 1.0f);
+    g_xywindow_globals.color_selbrushes = Vector3(1.0f, 0.0f, 0.0f);
+    g_xywindow_globals.color_clipper = Vector3(0.0f, 0.0f, 1.0f);
+    g_xywindow_globals.color_brushes = Vector3(1.0f, 1.0f, 1.0f);
+    SetWorldspawnColour(g_xywindow_globals.color_brushes);
+    g_xywindow_globals.color_viewname = Vector3(0.7f, 0.7f, 0.0f);
+    XY_UpdateAllWindows();
 }
 
 /* ydnar: to emulate maya/max/lightwave color schemes */
 void ColorScheme_Ydnar()
 {
-  TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f));
-
-  g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f);
-  g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f);
-  CamWnd_Update(*g_pParentWnd->GetCamWnd());
-
-  g_xywindow_globals.color_gridback = Vector3(0.77f, 0.77f, 0.77f);
-  g_xywindow_globals.color_gridminor = Vector3(0.83f, 0.83f, 0.83f);
-  g_xywindow_globals.color_gridmajor = Vector3(0.89f, 0.89f, 0.89f);
-  g_xywindow_globals.color_gridblock = Vector3(1.0f, 1.0f, 1.0f);
-  g_xywindow_globals.color_gridtext = Vector3(0.0f, 0.0f, 0.0f);
-  g_xywindow_globals.color_selbrushes = Vector3(1.0f, 0.0f, 0.0f);
-  g_xywindow_globals.color_clipper = Vector3(0.0f, 0.0f, 1.0f);
-  g_xywindow_globals.color_brushes = Vector3(0.0f, 0.0f, 0.0f);
-  SetWorldspawnColour(g_xywindow_globals.color_brushes);
-  g_xywindow_globals.color_viewname = Vector3(0.5f, 0.0f, 0.75f);
-  XY_UpdateAllWindows();
-}
+    TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f));
 
-typedef Callback1<Vector3&> GetColourCallback;
-typedef Callback1<const Vector3&> SetColourCallback;
+    g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f);
+    g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f);
+    CamWnd_Update(*g_pParentWnd->GetCamWnd());
 
-class ChooseColour
-{
-  GetColourCallback m_get;
-  SetColourCallback m_set;
+    g_xywindow_globals.color_gridback = Vector3(0.77f, 0.77f, 0.77f);
+    g_xywindow_globals.color_gridminor = Vector3(0.83f, 0.83f, 0.83f);
+    g_xywindow_globals.color_gridmajor = Vector3(0.89f, 0.89f, 0.89f);
+    g_xywindow_globals.color_gridblock = Vector3(1.0f, 1.0f, 1.0f);
+    g_xywindow_globals.color_gridtext = Vector3(0.0f, 0.0f, 0.0f);
+    g_xywindow_globals.color_selbrushes = Vector3(1.0f, 0.0f, 0.0f);
+    g_xywindow_globals.color_clipper = Vector3(0.0f, 0.0f, 1.0f);
+    g_xywindow_globals.color_brushes = Vector3(0.0f, 0.0f, 0.0f);
+    SetWorldspawnColour(g_xywindow_globals.color_brushes);
+    g_xywindow_globals.color_viewname = Vector3(0.5f, 0.0f, 0.75f);
+    XY_UpdateAllWindows();
+}
+
+typedef Callback<void(Vector3 &)> GetColourCallback;
+typedef Callback<void(const Vector3 &)> SetColourCallback;
+
+class ChooseColour {
+    GetColourCallback m_get;
+    SetColourCallback m_set;
 public:
-  ChooseColour(const GetColourCallback& get, const SetColourCallback& set)
-    : m_get(get), m_set(set)
-  {
-  }
-  void operator()()
-  {
-    Vector3 colour;
-    m_get(colour);
-    color_dialog(GTK_WIDGET(MainFrame_getWindow()), colour);
-    m_set(colour);
-  }
-};
+    ChooseColour(const GetColourCallback &get, const SetColourCallback &set)
+            : m_get(get), m_set(set)
+    {
+    }
 
+    void operator()()
+    {
+        Vector3 colour;
+        m_get(colour);
+        color_dialog(MainFrame_getWindow(), colour);
+        m_set(colour);
+    }
+};
 
 
-void Colour_get(const Vector3& colour, Vector3& other)
+void Colour_get(const Vector3 &colour, Vector3 &other)
 {
-  other = colour;
+    other = colour;
 }
-typedef ConstReferenceCaller1<Vector3, Vector3&, Colour_get> ColourGetCaller;
 
-void Colour_set(Vector3& colour, const Vector3& other)
+typedef ConstReferenceCaller<Vector3, void(Vector3 &), Colour_get> ColourGetCaller;
+
+void Colour_set(Vector3 &colour, const Vector3 &other)
 {
-  colour = other;
-  SceneChangeNotify();
+    colour = other;
+    SceneChangeNotify();
 }
-typedef ReferenceCaller1<Vector3, const Vector3&, Colour_set> ColourSetCaller;
 
-void BrushColour_set(const Vector3& other)
+typedef ReferenceCaller<Vector3, void(const Vector3 &), Colour_set> ColourSetCaller;
+
+void BrushColour_set(const Vector3 &other)
 {
-  g_xywindow_globals.color_brushes = other;
-  SetWorldspawnColour(g_xywindow_globals.color_brushes);
-  SceneChangeNotify();
+    g_xywindow_globals.color_brushes = other;
+    SetWorldspawnColour(g_xywindow_globals.color_brushes);
+    SceneChangeNotify();
 }
-typedef FreeCaller1<const Vector3&, BrushColour_set> BrushColourSetCaller;
 
-void ClipperColour_set(const Vector3& other)
+typedef FreeCaller<void(const Vector3 &), BrushColour_set> BrushColourSetCaller;
+
+void ClipperColour_set(const Vector3 &other)
 {
-  g_xywindow_globals.color_clipper = other;
-  Brush_clipperColourChanged();
-  SceneChangeNotify();
+    g_xywindow_globals.color_clipper = other;
+    Brush_clipperColourChanged();
+    SceneChangeNotify();
 }
-typedef FreeCaller1<const Vector3&, ClipperColour_set> ClipperColourSetCaller;
 
-void TextureBrowserColour_get(Vector3& other)
+typedef FreeCaller<void(const Vector3 &), ClipperColour_set> ClipperColourSetCaller;
+
+void TextureBrowserColour_get(Vector3 &other)
 {
-  other = TextureBrowser_getBackgroundColour(GlobalTextureBrowser());
+    other = TextureBrowser_getBackgroundColour(GlobalTextureBrowser());
 }
-typedef FreeCaller1<Vector3&, TextureBrowserColour_get> TextureBrowserColourGetCaller;
 
-void TextureBrowserColour_set(const Vector3& other)
+typedef FreeCaller<void(Vector3 &), TextureBrowserColour_get> TextureBrowserColourGetCaller;
+
+void TextureBrowserColour_set(const Vector3 &other)
 {
-  TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), other);
+    TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), other);
 }
-typedef FreeCaller1<const Vector3&, TextureBrowserColour_set> TextureBrowserColourSetCaller;
 
+typedef FreeCaller<void(const Vector3 &), TextureBrowserColour_set> TextureBrowserColourSetCaller;
 
-class ColoursMenu
-{
+
+class ColoursMenu {
 public:
-  ChooseColour m_textureback;
-  ChooseColour m_xyback;
-  ChooseColour m_gridmajor;
-  ChooseColour m_gridminor;
-  ChooseColour m_gridmajor_alt;
-  ChooseColour m_gridminor_alt;
-  ChooseColour m_gridtext;
-  ChooseColour m_gridblock;
-  ChooseColour m_cameraback;
-  ChooseColour m_brush;
-  ChooseColour m_selectedbrush;
-  ChooseColour m_selectedbrush3d;
-  ChooseColour m_clipper;
-  ChooseColour m_viewname;
-
-  ColoursMenu() :
-    m_textureback(TextureBrowserColourGetCaller(), TextureBrowserColourSetCaller()),
-    m_xyback(ColourGetCaller(g_xywindow_globals.color_gridback), ColourSetCaller(g_xywindow_globals.color_gridback)),
-    m_gridmajor(ColourGetCaller(g_xywindow_globals.color_gridmajor), ColourSetCaller(g_xywindow_globals.color_gridmajor)),
-    m_gridminor(ColourGetCaller(g_xywindow_globals.color_gridminor), ColourSetCaller(g_xywindow_globals.color_gridminor)),
-    m_gridmajor_alt(ColourGetCaller(g_xywindow_globals.color_gridmajor_alt), ColourSetCaller(g_xywindow_globals.color_gridmajor_alt)),
-    m_gridminor_alt(ColourGetCaller(g_xywindow_globals.color_gridminor_alt), ColourSetCaller(g_xywindow_globals.color_gridminor_alt)),
-    m_gridtext(ColourGetCaller(g_xywindow_globals.color_gridtext), ColourSetCaller(g_xywindow_globals.color_gridtext)),
-    m_gridblock(ColourGetCaller(g_xywindow_globals.color_gridblock), ColourSetCaller(g_xywindow_globals.color_gridblock)),
-    m_cameraback(ColourGetCaller(g_camwindow_globals.color_cameraback), ColourSetCaller(g_camwindow_globals.color_cameraback)),
-    m_brush(ColourGetCaller(g_xywindow_globals.color_brushes), BrushColourSetCaller()),
-    m_selectedbrush(ColourGetCaller(g_xywindow_globals.color_selbrushes), ColourSetCaller(g_xywindow_globals.color_selbrushes)),
-    m_selectedbrush3d(ColourGetCaller(g_camwindow_globals.color_selbrushes3d), ColourSetCaller(g_camwindow_globals.color_selbrushes3d)),
-    m_clipper(ColourGetCaller(g_xywindow_globals.color_clipper), ClipperColourSetCaller()),
-    m_viewname(ColourGetCaller(g_xywindow_globals.color_viewname), ColourSetCaller(g_xywindow_globals.color_viewname))
-  {
-  }
+    ChooseColour m_textureback;
+    ChooseColour m_xyback;
+    ChooseColour m_gridmajor;
+    ChooseColour m_gridminor;
+    ChooseColour m_gridmajor_alt;
+    ChooseColour m_gridminor_alt;
+    ChooseColour m_gridtext;
+    ChooseColour m_gridblock;
+    ChooseColour m_cameraback;
+    ChooseColour m_brush;
+    ChooseColour m_selectedbrush;
+    ChooseColour m_selectedbrush3d;
+    ChooseColour m_clipper;
+    ChooseColour m_viewname;
+
+    ColoursMenu() :
+            m_textureback(TextureBrowserColourGetCaller(), TextureBrowserColourSetCaller()),
+            m_xyback(ColourGetCaller(g_xywindow_globals.color_gridback),
+                     ColourSetCaller(g_xywindow_globals.color_gridback)),
+            m_gridmajor(ColourGetCaller(g_xywindow_globals.color_gridmajor),
+                        ColourSetCaller(g_xywindow_globals.color_gridmajor)),
+            m_gridminor(ColourGetCaller(g_xywindow_globals.color_gridminor),
+                        ColourSetCaller(g_xywindow_globals.color_gridminor)),
+            m_gridmajor_alt(ColourGetCaller(g_xywindow_globals.color_gridmajor_alt),
+                            ColourSetCaller(g_xywindow_globals.color_gridmajor_alt)),
+            m_gridminor_alt(ColourGetCaller(g_xywindow_globals.color_gridminor_alt),
+                            ColourSetCaller(g_xywindow_globals.color_gridminor_alt)),
+            m_gridtext(ColourGetCaller(g_xywindow_globals.color_gridtext),
+                       ColourSetCaller(g_xywindow_globals.color_gridtext)),
+            m_gridblock(ColourGetCaller(g_xywindow_globals.color_gridblock),
+                        ColourSetCaller(g_xywindow_globals.color_gridblock)),
+            m_cameraback(ColourGetCaller(g_camwindow_globals.color_cameraback),
+                         ColourSetCaller(g_camwindow_globals.color_cameraback)),
+            m_brush(ColourGetCaller(g_xywindow_globals.color_brushes), BrushColourSetCaller()),
+            m_selectedbrush(ColourGetCaller(g_xywindow_globals.color_selbrushes),
+                            ColourSetCaller(g_xywindow_globals.color_selbrushes)),
+            m_selectedbrush3d(ColourGetCaller(g_camwindow_globals.color_selbrushes3d),
+                              ColourSetCaller(g_camwindow_globals.color_selbrushes3d)),
+            m_clipper(ColourGetCaller(g_xywindow_globals.color_clipper), ClipperColourSetCaller()),
+            m_viewname(ColourGetCaller(g_xywindow_globals.color_viewname),
+                       ColourSetCaller(g_xywindow_globals.color_viewname))
+    {
+    }
 };
 
 ColoursMenu g_ColoursMenu;
 
-GtkMenuItem* create_colours_menu()
+ui::MenuItem create_colours_menu()
 {
-  GtkMenuItem* colours_menu_item = new_sub_menu_item_with_mnemonic("Colors");
-  GtkMenu* menu_in_menu = GTK_MENU(gtk_menu_item_get_submenu(colours_menu_item));
-  if (g_Layout_enableDetachableMenus.m_value)
-    menu_tearoff (menu_in_menu);
+    auto colours_menu_item = new_sub_menu_item_with_mnemonic("Colors");
+    auto menu_in_menu = ui::Menu::from(gtk_menu_item_get_submenu(colours_menu_item));
+    if (g_Layout_enableDetachableMenus.m_value) {
+        menu_tearoff(menu_in_menu);
+    }
 
-  GtkMenu* menu_3 = create_sub_menu_with_mnemonic(menu_in_menu, "Themes");
-  if (g_Layout_enableDetachableMenus.m_value)
-    menu_tearoff (menu_3);
+    auto menu_3 = create_sub_menu_with_mnemonic(menu_in_menu, "Themes");
+    if (g_Layout_enableDetachableMenus.m_value) {
+        menu_tearoff(menu_3);
+    }
 
-  create_menu_item_with_mnemonic(menu_3, "QE4 Original", "ColorSchemeOriginal");
-  create_menu_item_with_mnemonic(menu_3, "Q3Radiant Original", "ColorSchemeQER");
-  create_menu_item_with_mnemonic(menu_3, "Black and Green", "ColorSchemeBlackAndGreen");
-  create_menu_item_with_mnemonic(menu_3, "Maya/Max/Lightwave Emulation", "ColorSchemeYdnar");
+    create_menu_item_with_mnemonic(menu_3, "QE4 Original", "ColorSchemeOriginal");
+    create_menu_item_with_mnemonic(menu_3, "Q3Radiant Original", "ColorSchemeQER");
+    create_menu_item_with_mnemonic(menu_3, "Black and Green", "ColorSchemeBlackAndGreen");
+    create_menu_item_with_mnemonic(menu_3, "Maya/Max/Lightwave Emulation", "ColorSchemeYdnar");
 
-  menu_separator(menu_in_menu);
+    menu_separator(menu_in_menu);
 
-  create_menu_item_with_mnemonic(menu_in_menu, "_Texture Background...", "ChooseTextureBackgroundColor");
-  create_menu_item_with_mnemonic(menu_in_menu, "Grid Background...", "ChooseGridBackgroundColor");
-  create_menu_item_with_mnemonic(menu_in_menu, "Grid Major...", "ChooseGridMajorColor");
-  create_menu_item_with_mnemonic(menu_in_menu, "Grid Minor...", "ChooseGridMinorColor");
-  create_menu_item_with_mnemonic(menu_in_menu, "Grid Major Small...", "ChooseSmallGridMajorColor");
-  create_menu_item_with_mnemonic(menu_in_menu, "Grid Minor Small...", "ChooseSmallGridMinorColor");
-  create_menu_item_with_mnemonic(menu_in_menu, "Grid Text...", "ChooseGridTextColor");
-  create_menu_item_with_mnemonic(menu_in_menu, "Grid Block...", "ChooseGridBlockColor");
-  create_menu_item_with_mnemonic(menu_in_menu, "Default Brush...", "ChooseBrushColor");
-  create_menu_item_with_mnemonic(menu_in_menu, "Camera Background...", "ChooseCameraBackgroundColor");
-  create_menu_item_with_mnemonic(menu_in_menu, "Selected Brush...", "ChooseSelectedBrushColor");
-  create_menu_item_with_mnemonic(menu_in_menu, "Selected Brush (Camera)...", "ChooseCameraSelectedBrushColor");
-  create_menu_item_with_mnemonic(menu_in_menu, "Clipper...", "ChooseClipperColor");
-  create_menu_item_with_mnemonic(menu_in_menu, "Active View name...", "ChooseOrthoViewNameColor");
+    create_menu_item_with_mnemonic(menu_in_menu, "_Texture Background...", "ChooseTextureBackgroundColor");
+    create_menu_item_with_mnemonic(menu_in_menu, "Grid Background...", "ChooseGridBackgroundColor");
+    create_menu_item_with_mnemonic(menu_in_menu, "Grid Major...", "ChooseGridMajorColor");
+    create_menu_item_with_mnemonic(menu_in_menu, "Grid Minor...", "ChooseGridMinorColor");
+    create_menu_item_with_mnemonic(menu_in_menu, "Grid Major Small...", "ChooseSmallGridMajorColor");
+    create_menu_item_with_mnemonic(menu_in_menu, "Grid Minor Small...", "ChooseSmallGridMinorColor");
+    create_menu_item_with_mnemonic(menu_in_menu, "Grid Text...", "ChooseGridTextColor");
+    create_menu_item_with_mnemonic(menu_in_menu, "Grid Block...", "ChooseGridBlockColor");
+    create_menu_item_with_mnemonic(menu_in_menu, "Default Brush...", "ChooseBrushColor");
+    create_menu_item_with_mnemonic(menu_in_menu, "Camera Background...", "ChooseCameraBackgroundColor");
+    create_menu_item_with_mnemonic(menu_in_menu, "Selected Brush...", "ChooseSelectedBrushColor");
+    create_menu_item_with_mnemonic(menu_in_menu, "Selected Brush (Camera)...", "ChooseCameraSelectedBrushColor");
+    create_menu_item_with_mnemonic(menu_in_menu, "Clipper...", "ChooseClipperColor");
+    create_menu_item_with_mnemonic(menu_in_menu, "Active View name...", "ChooseOrthoViewNameColor");
 
-  return colours_menu_item;
+    return colours_menu_item;
 }
 
 
 void Restart()
 {
-  PluginsMenu_clear();
-  PluginToolbar_clear();
+    PluginsMenu_clear();
+    PluginToolbar_clear();
 
-  Radiant_Shutdown();
-  Radiant_Initialise();
+    Radiant_Shutdown();
+    Radiant_Initialise();
 
-  PluginsMenu_populate();
+    PluginsMenu_populate();
 
-  PluginToolbar_populate();
+    PluginToolbar_populate();
 }
 
 
 void thunk_OnSleep()
 {
-  g_pParentWnd->OnSleep();
+    g_pParentWnd->OnSleep();
 }
 
-void OpenUpdateURL()
-{
-  // build the URL
-  StringOutputStream URL(256);
-  URL << "http://www.icculus.org/netradiant/?cmd=update&data=dlupdate&query_dlup=1";
-#ifdef WIN32
-  URL << "&OS_dlup=1";
-#elif defined(__APPLE__)
-  URL << "&OS_dlup=2";
-#else
-  URL << "&OS_dlup=3";
-#endif
-  URL << "&Version_dlup=" RADIANT_VERSION;
-  g_GamesDialog.AddPacksURL(URL);
-  OpenURL(URL.c_str());
-}
-
-// open the Q3Rad manual
 void OpenHelpURL()
 {
-  // at least on win32, AppPath + "docs/index.html"
-  StringOutputStream help(256);
-  help << AppPath_get() << "docs/index.html";
-  OpenURL(help.c_str());
+    OpenURL("https://gitlab.com/xonotic/xonotic/wikis/Mapping");
 }
 
 void OpenBugReportURL()
 {
-  OpenURL("http://www.icculus.org/netradiant/?cmd=bugs");
+    OpenURL("https://gitlab.com/xonotic/netradiant/issues");
 }
 
 
-GtkWidget* g_page_console;
+ui::Widget g_page_console{ui::null};
 
 void Console_ToggleShow()
 {
-  GroupDialog_showPage(g_page_console);
+    GroupDialog_showPage(g_page_console);
 }
 
-GtkWidget* g_page_entity;
+ui::Widget g_page_entity{ui::null};
 
 void EntityInspector_ToggleShow()
 {
-  GroupDialog_showPage(g_page_entity);
+    GroupDialog_showPage(g_page_entity);
 }
 
 
-
 void SetClipMode(bool enable);
+
 void ModeChangeNotify();
 
-typedef void(*ToolMode)();
+typedef void ( *ToolMode )();
+
 ToolMode g_currentToolMode = 0;
 bool g_currentToolModeSupportsComponentEditing = false;
 ToolMode g_defaultToolMode = 0;
 
 
-
 void SelectionSystem_DefaultMode()
 {
-  GlobalSelectionSystem().SetMode(SelectionSystem::ePrimitive);
-  GlobalSelectionSystem().SetComponentMode(SelectionSystem::eDefault);
-  ModeChangeNotify();
+    GlobalSelectionSystem().SetMode(SelectionSystem::ePrimitive);
+    GlobalSelectionSystem().SetComponentMode(SelectionSystem::eDefault);
+    ModeChangeNotify();
 }
 
 
 bool EdgeMode()
 {
-  return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent
-    && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eEdge;
+    return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent
+           && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eEdge;
 }
 
 bool VertexMode()
 {
-  return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent
-    && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eVertex;
+    return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent
+           && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eVertex;
 }
 
 bool FaceMode()
 {
-  return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent
-    && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace;
+    return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent
+           && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace;
 }
 
-template<bool (*BoolFunction)()>
-class BoolFunctionExport
-{
+template<bool( *BoolFunction )()>
+class BoolFunctionExport {
 public:
-  static void apply(const BoolImportCallback& importCallback)
-  {
-    importCallback(BoolFunction());
-  }
+    static void apply(const Callback<void(bool)> &importCallback)
+    {
+        importCallback(BoolFunction());
+    }
 };
 
-typedef FreeCaller1<const BoolImportCallback&, &BoolFunctionExport<EdgeMode>::apply> EdgeModeApplyCaller;
+typedef FreeCaller<void(const Callback<void(bool)> &), &BoolFunctionExport<EdgeMode>::apply> EdgeModeApplyCaller;
 EdgeModeApplyCaller g_edgeMode_button_caller;
-BoolExportCallback g_edgeMode_button_callback(g_edgeMode_button_caller);
+Callback<void(const Callback<void(bool)> &)> g_edgeMode_button_callback(g_edgeMode_button_caller);
 ToggleItem g_edgeMode_button(g_edgeMode_button_callback);
 
-typedef FreeCaller1<const BoolImportCallback&, &BoolFunctionExport<VertexMode>::apply> VertexModeApplyCaller;
+typedef FreeCaller<void(const Callback<void(bool)> &), &BoolFunctionExport<VertexMode>::apply> VertexModeApplyCaller;
 VertexModeApplyCaller g_vertexMode_button_caller;
-BoolExportCallback g_vertexMode_button_callback(g_vertexMode_button_caller);
+Callback<void(const Callback<void(bool)> &)> g_vertexMode_button_callback(g_vertexMode_button_caller);
 ToggleItem g_vertexMode_button(g_vertexMode_button_callback);
 
-typedef FreeCaller1<const BoolImportCallback&, &BoolFunctionExport<FaceMode>::apply> FaceModeApplyCaller;
+typedef FreeCaller<void(const Callback<void(bool)> &), &BoolFunctionExport<FaceMode>::apply> FaceModeApplyCaller;
 FaceModeApplyCaller g_faceMode_button_caller;
-BoolExportCallback g_faceMode_button_callback(g_faceMode_button_caller);
+Callback<void(const Callback<void(bool)> &)> g_faceMode_button_callback(g_faceMode_button_caller);
 ToggleItem g_faceMode_button(g_faceMode_button_callback);
 
 void ComponentModeChanged()
 {
-  g_edgeMode_button.update();
-  g_vertexMode_button.update();
-  g_faceMode_button.update();
+    g_edgeMode_button.update();
+    g_vertexMode_button.update();
+    g_faceMode_button.update();
 }
 
-void ComponentMode_SelectionChanged(const Selectableselectable)
+void ComponentMode_SelectionChanged(const Selectable &selectable)
 {
-  if(GlobalSelectionSystem().Mode() == SelectionSystem::eComponent
-    && GlobalSelectionSystem().countSelected() == 0)
-  {
-    SelectionSystem_DefaultMode();
-    ComponentModeChanged();
-  }
+    if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent
+        && GlobalSelectionSystem().countSelected() == 0) {
+        SelectionSystem_DefaultMode();
+        ComponentModeChanged();
+    }
 }
 
 void SelectEdgeMode()
 {
 #if 0
-  if(GlobalSelectionSystem().Mode() == SelectionSystem::eComponent)
-  {
-    GlobalSelectionSystem().Select(false);
-  }
+                                                                                                                            if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) {
+               GlobalSelectionSystem().Select( false );
+       }
 #endif
 
-  if(EdgeMode())
-  {
-    SelectionSystem_DefaultMode();
-  }
-  else if(GlobalSelectionSystem().countSelected() != 0)
-  {
-    if(!g_currentToolModeSupportsComponentEditing)
-    {
-      g_defaultToolMode();
-    }
+    if (EdgeMode()) {
+        SelectionSystem_DefaultMode();
+    } else if (GlobalSelectionSystem().countSelected() != 0) {
+        if (!g_currentToolModeSupportsComponentEditing) {
+            g_defaultToolMode();
+        }
 
-    GlobalSelectionSystem().SetMode(SelectionSystem::eComponent);
-    GlobalSelectionSystem().SetComponentMode(SelectionSystem::eEdge);
-  }
+        GlobalSelectionSystem().SetMode(SelectionSystem::eComponent);
+        GlobalSelectionSystem().SetComponentMode(SelectionSystem::eEdge);
+    }
 
-  ComponentModeChanged();
+    ComponentModeChanged();
 
-  ModeChangeNotify();
+    ModeChangeNotify();
 }
 
 void SelectVertexMode()
 {
 #if 0
-  if(GlobalSelectionSystem().Mode() == SelectionSystem::eComponent)
-  {
-    GlobalSelectionSystem().Select(false);
-  }
+                                                                                                                            if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) {
+               GlobalSelectionSystem().Select( false );
+       }
 #endif
 
-  if(VertexMode())
-  {
-    SelectionSystem_DefaultMode();
-  }
-  else if(GlobalSelectionSystem().countSelected() != 0)
-  {
-    if(!g_currentToolModeSupportsComponentEditing)
-    {
-      g_defaultToolMode();
-    }
+    if (VertexMode()) {
+        SelectionSystem_DefaultMode();
+    } else if (GlobalSelectionSystem().countSelected() != 0) {
+        if (!g_currentToolModeSupportsComponentEditing) {
+            g_defaultToolMode();
+        }
 
-    GlobalSelectionSystem().SetMode(SelectionSystem::eComponent);
-    GlobalSelectionSystem().SetComponentMode(SelectionSystem::eVertex);
-  }
+        GlobalSelectionSystem().SetMode(SelectionSystem::eComponent);
+        GlobalSelectionSystem().SetComponentMode(SelectionSystem::eVertex);
+    }
 
-  ComponentModeChanged();
+    ComponentModeChanged();
 
-  ModeChangeNotify();
+    ModeChangeNotify();
 }
 
 void SelectFaceMode()
 {
 #if 0
-  if(GlobalSelectionSystem().Mode() == SelectionSystem::eComponent)
-  {
-    GlobalSelectionSystem().Select(false);
-  }
+                                                                                                                            if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) {
+               GlobalSelectionSystem().Select( false );
+       }
 #endif
 
-  if(FaceMode())
-  {
-    SelectionSystem_DefaultMode();
-  }
-  else if(GlobalSelectionSystem().countSelected() != 0)
-  {
-    if(!g_currentToolModeSupportsComponentEditing)
-    {
-      g_defaultToolMode();
-    }
+    if (FaceMode()) {
+        SelectionSystem_DefaultMode();
+    } else if (GlobalSelectionSystem().countSelected() != 0) {
+        if (!g_currentToolModeSupportsComponentEditing) {
+            g_defaultToolMode();
+        }
 
-    GlobalSelectionSystem().SetMode(SelectionSystem::eComponent);
-    GlobalSelectionSystem().SetComponentMode(SelectionSystem::eFace);
-  }
+        GlobalSelectionSystem().SetMode(SelectionSystem::eComponent);
+        GlobalSelectionSystem().SetComponentMode(SelectionSystem::eFace);
+    }
 
-  ComponentModeChanged();
+    ComponentModeChanged();
 
-  ModeChangeNotify();
+    ModeChangeNotify();
 }
 
 
-class CloneSelected : public scene::Graph::Walker
-{
-  bool doMakeUnique;
-  NodeSmartReference worldspawn;
+class CloneSelected : public scene::Graph::Walker {
+    bool doMakeUnique;
+    NodeSmartReference worldspawn;
 public:
-  CloneSelected(bool d): doMakeUnique(d), worldspawn(Map_FindOrInsertWorldspawn(g_map))
-  {
-  }
-  bool pre(const scene::Path& path, scene::Instance& instance) const
-  {
-    if(path.size() == 1)
-      return true;
-
-    // ignore worldspawn, but keep checking children
-    NodeSmartReference me(path.top().get());
-    if(me == worldspawn)
-           return true;
-
-    if(!path.top().get().isRoot())
+    CloneSelected(bool d) : doMakeUnique(d), worldspawn(Map_FindOrInsertWorldspawn(g_map))
     {
-      Selectable* selectable = Instance_getSelectable(instance);
-      if(selectable != 0
-        && selectable->isSelected())
-      {
-        return false;
-      }
     }
 
-    return true;
-  }
-  void post(const scene::Path& path, scene::Instance& instance) const
-  {
-    if(path.size() == 1)
-      return;
+    bool pre(const scene::Path &path, scene::Instance &instance) const
+    {
+        if (path.size() == 1) {
+            return true;
+        }
+
+        // ignore worldspawn, but keep checking children
+        NodeSmartReference me(path.top().get());
+        if (me == worldspawn) {
+            return true;
+        }
+
+        if (!path.top().get().isRoot()) {
+            Selectable *selectable = Instance_getSelectable(instance);
+            if (selectable != 0
+                && selectable->isSelected()) {
+                return false;
+            }
+        }
 
-    // ignore worldspawn, but keep checking children
-    NodeSmartReference me(path.top().get());
-    if(me == worldspawn)
-           return;
+        return true;
+    }
 
-    if(!path.top().get().isRoot())
+    void post(const scene::Path &path, scene::Instance &instance) const
     {
-      Selectable* selectable = Instance_getSelectable(instance);
-      if(selectable != 0
-        && selectable->isSelected())
-      {
-        NodeSmartReference clone(Node_Clone(path.top()));
-               if(doMakeUnique)
-                       Map_gatherNamespaced(clone);
-        Node_getTraversable(path.parent().get())->insert(clone);
-      }
-    }
-  }
+        if (path.size() == 1) {
+            return;
+        }
+
+        // ignore worldspawn, but keep checking children
+        NodeSmartReference me(path.top().get());
+        if (me == worldspawn) {
+            return;
+        }
+
+        if (!path.top().get().isRoot()) {
+            Selectable *selectable = Instance_getSelectable(instance);
+            if (selectable != 0
+                && selectable->isSelected()) {
+                NodeSmartReference clone(Node_Clone(path.top()));
+                if (doMakeUnique) {
+                    Map_gatherNamespaced(clone);
+                }
+                Node_getTraversable(path.parent().get())->insert(clone);
+            }
+        }
+    }
 };
 
-void Scene_Clone_Selected(scene::Graphgraph, bool doMakeUnique)
+void Scene_Clone_Selected(scene::Graph &graph, bool doMakeUnique)
 {
-  graph.traverse(CloneSelected(doMakeUnique));
+    graph.traverse(CloneSelected(doMakeUnique));
 
-  Map_mergeClonedNames();
+    Map_mergeClonedNames();
 }
 
-enum ENudgeDirection
-{
-  eNudgeUp = 1,
-  eNudgeDown = 3,
-  eNudgeLeft = 0,
-  eNudgeRight = 2,
+enum ENudgeDirection {
+    eNudgeUp = 1,
+    eNudgeDown = 3,
+    eNudgeLeft = 0,
+    eNudgeRight = 2,
 };
 
-struct AxisBase
-{
-  Vector3 x;
-  Vector3 y;
-  Vector3 z;
-  AxisBase(const Vector3& x_, const Vector3& y_, const Vector3& z_)
-    : x(x_), y(y_), z(z_)
-  {
-  }
+struct AxisBase {
+    Vector3 x;
+    Vector3 y;
+    Vector3 z;
+
+    AxisBase(const Vector3 &x_, const Vector3 &y_, const Vector3 &z_)
+            : x(x_), y(y_), z(z_)
+    {
+    }
 };
 
 AxisBase AxisBase_forViewType(VIEWTYPE viewtype)
 {
-  switch(viewtype)
-  {
-  case XY:
-    return AxisBase(g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z);
-  case XZ:
-    return AxisBase(g_vector3_axis_x, g_vector3_axis_z, g_vector3_axis_y);
-  case YZ:
-    return AxisBase(g_vector3_axis_y, g_vector3_axis_z, g_vector3_axis_x);
-  }
+    switch (viewtype) {
+        case XY:
+            return AxisBase(g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z);
+        case XZ:
+            return AxisBase(g_vector3_axis_x, g_vector3_axis_z, g_vector3_axis_y);
+        case YZ:
+            return AxisBase(g_vector3_axis_y, g_vector3_axis_z, g_vector3_axis_x);
+    }
 
-  ERROR_MESSAGE("invalid viewtype");
-  return AxisBase(Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(0, 0, 0));
+    ERROR_MESSAGE("invalid viewtype");
+    return AxisBase(Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(0, 0, 0));
 }
 
-Vector3 AxisBase_axisForDirection(const AxisBaseaxes, ENudgeDirection direction)
+Vector3 AxisBase_axisForDirection(const AxisBase &axes, ENudgeDirection direction)
 {
-  switch (direction)
-  {
-  case eNudgeLeft:
-    return vector3_negated(axes.x);
-  case eNudgeUp:
-    return axes.y;
-  case eNudgeRight:
-    return axes.x;
-  case eNudgeDown:
-    return vector3_negated(axes.y);
-  }
+    switch (direction) {
+        case eNudgeLeft:
+            return vector3_negated(axes.x);
+        case eNudgeUp:
+            return axes.y;
+        case eNudgeRight:
+            return axes.x;
+        case eNudgeDown:
+            return vector3_negated(axes.y);
+    }
 
-  ERROR_MESSAGE("invalid direction");
-  return Vector3(0, 0, 0);
+    ERROR_MESSAGE("invalid direction");
+    return Vector3(0, 0, 0);
 }
 
 void NudgeSelection(ENudgeDirection direction, float fAmount, VIEWTYPE viewtype)
 {
-  AxisBase axes(AxisBase_forViewType(viewtype));
-  Vector3 view_direction(vector3_negated(axes.z));
-  Vector3 nudge(vector3_scaled(AxisBase_axisForDirection(axes, direction), fAmount));
-  GlobalSelectionSystem().NudgeManipulator(nudge, view_direction);
+    AxisBase axes(AxisBase_forViewType(viewtype));
+    Vector3 view_direction(vector3_negated(axes.z));
+    Vector3 nudge(vector3_scaled(AxisBase_axisForDirection(axes, direction), fAmount));
+    GlobalSelectionSystem().NudgeManipulator(nudge, view_direction);
 }
 
 void Selection_Clone()
 {
-  if(GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive)
-  {
-    UndoableCommand undo("cloneSelected");
+    if (GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive) {
+        UndoableCommand undo("cloneSelected");
 
-    Scene_Clone_Selected(GlobalSceneGraph(), false);
+        Scene_Clone_Selected(GlobalSceneGraph(), false);
 
-    //NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType());
-    //NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType());
-  }
+        //NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType());
+        //NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType());
+    }
 }
 
 void Selection_Clone_MakeUnique()
 {
-  if(GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive)
-  {
-    UndoableCommand undo("cloneSelectedMakeUnique");
+    if (GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive) {
+        UndoableCommand undo("cloneSelectedMakeUnique");
 
-    Scene_Clone_Selected(GlobalSceneGraph(), true);
+        Scene_Clone_Selected(GlobalSceneGraph(), true);
 
-    //NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType());
-    //NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType());
-  }
+        //NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType());
+        //NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType());
+    }
 }
 
 // called when the escape key is used (either on the main window or on an inspector)
 void Selection_Deselect()
-{
-  if(GlobalSelectionSystem().Mode() == SelectionSystem::eComponent)
-  {
-    if(GlobalSelectionSystem().countSelectedComponents() != 0)
-    {
-      GlobalSelectionSystem().setSelectedAllComponents(false);
-    }
-    else
-    {
-      SelectionSystem_DefaultMode();
-      ComponentModeChanged();
-    }
-  }
-  else
-  {
-    if(GlobalSelectionSystem().countSelectedComponents() != 0)
-    {
-      GlobalSelectionSystem().setSelectedAllComponents(false);
-    }
-    else
-    {
-      GlobalSelectionSystem().setSelectedAll(false);
+{
+    if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent) {
+        if (GlobalSelectionSystem().countSelectedComponents() != 0) {
+            GlobalSelectionSystem().setSelectedAllComponents(false);
+        } else {
+            SelectionSystem_DefaultMode();
+            ComponentModeChanged();
+        }
+    } else {
+        if (GlobalSelectionSystem().countSelectedComponents() != 0) {
+            GlobalSelectionSystem().setSelectedAllComponents(false);
+        } else {
+            GlobalSelectionSystem().setSelectedAll(false);
+        }
     }
-  }
 }
 
 
 void Selection_NudgeUp()
 {
-  UndoableCommand undo("nudgeSelectedUp");
-  NudgeSelection(eNudgeUp, GetGridSize(), GlobalXYWnd_getCurrentViewType());
+    UndoableCommand undo("nudgeSelectedUp");
+    NudgeSelection(eNudgeUp, GetGridSize(), GlobalXYWnd_getCurrentViewType());
 }
 
 void Selection_NudgeDown()
 {
-  UndoableCommand undo("nudgeSelectedDown");
-  NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType());
+    UndoableCommand undo("nudgeSelectedDown");
+    NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType());
 }
 
 void Selection_NudgeLeft()
 {
-  UndoableCommand undo("nudgeSelectedLeft");
-  NudgeSelection(eNudgeLeft, GetGridSize(), GlobalXYWnd_getCurrentViewType());
+    UndoableCommand undo("nudgeSelectedLeft");
+    NudgeSelection(eNudgeLeft, GetGridSize(), GlobalXYWnd_getCurrentViewType());
 }
 
 void Selection_NudgeRight()
 {
-  UndoableCommand undo("nudgeSelectedRight");
-  NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType());
+    UndoableCommand undo("nudgeSelectedRight");
+    NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType());
 }
 
 
-void TranslateToolExport(const BoolImportCallback& importCallback)
+void TranslateToolExport(const Callback<void(bool)> &importCallback)
 {
-  importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eTranslate);
+    importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eTranslate);
 }
 
-void RotateToolExport(const BoolImportCallback& importCallback)
+void RotateToolExport(const Callback<void(bool)> &importCallback)
 {
-  importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eRotate);
+    importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eRotate);
 }
 
-void ScaleToolExport(const BoolImportCallback& importCallback)
+void ScaleToolExport(const Callback<void(bool)> &importCallback)
 {
-  importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eScale);
+    importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eScale);
 }
 
-void DragToolExport(const BoolImportCallback& importCallback)
+void DragToolExport(const Callback<void(bool)> &importCallback)
 {
-  importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eDrag);
+    importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eDrag);
 }
 
-void ClipperToolExport(const BoolImportCallback& importCallback)
+void ClipperToolExport(const Callback<void(bool)> &importCallback)
 {
-  importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip);
+    importCallback(GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip);
 }
 
-FreeCaller1<const BoolImportCallback&, TranslateToolExport> g_translatemode_button_caller;
-BoolExportCallback g_translatemode_button_callback(g_translatemode_button_caller);
+FreeCaller<void(const Callback<void(bool)> &), TranslateToolExport> g_translatemode_button_caller;
+Callback<void(const Callback<void(bool)> &)> g_translatemode_button_callback(g_translatemode_button_caller);
 ToggleItem g_translatemode_button(g_translatemode_button_callback);
 
-FreeCaller1<const BoolImportCallback&, RotateToolExport> g_rotatemode_button_caller;
-BoolExportCallback g_rotatemode_button_callback(g_rotatemode_button_caller);
+FreeCaller<void(const Callback<void(bool)> &), RotateToolExport> g_rotatemode_button_caller;
+Callback<void(const Callback<void(bool)> &)> g_rotatemode_button_callback(g_rotatemode_button_caller);
 ToggleItem g_rotatemode_button(g_rotatemode_button_callback);
 
-FreeCaller1<const BoolImportCallback&, ScaleToolExport> g_scalemode_button_caller;
-BoolExportCallback g_scalemode_button_callback(g_scalemode_button_caller);
+FreeCaller<void(const Callback<void(bool)> &), ScaleToolExport> g_scalemode_button_caller;
+Callback<void(const Callback<void(bool)> &)> g_scalemode_button_callback(g_scalemode_button_caller);
 ToggleItem g_scalemode_button(g_scalemode_button_callback);
 
-FreeCaller1<const BoolImportCallback&, DragToolExport> g_dragmode_button_caller;
-BoolExportCallback g_dragmode_button_callback(g_dragmode_button_caller);
+FreeCaller<void(const Callback<void(bool)> &), DragToolExport> g_dragmode_button_caller;
+Callback<void(const Callback<void(bool)> &)> g_dragmode_button_callback(g_dragmode_button_caller);
 ToggleItem g_dragmode_button(g_dragmode_button_callback);
 
-FreeCaller1<const BoolImportCallback&, ClipperToolExport> g_clipper_button_caller;
-BoolExportCallback g_clipper_button_callback(g_clipper_button_caller);
+FreeCaller<void(const Callback<void(bool)> &), ClipperToolExport> g_clipper_button_caller;
+Callback<void(const Callback<void(bool)> &)> g_clipper_button_callback(g_clipper_button_caller);
 ToggleItem g_clipper_button(g_clipper_button_callback);
 
 void ToolChanged()
 {
-  g_translatemode_button.update();
-  g_rotatemode_button.update();
-  g_scalemode_button.update();
-  g_dragmode_button.update();
-  g_clipper_button.update();
+    g_translatemode_button.update();
+    g_rotatemode_button.update();
+    g_scalemode_button.update();
+    g_dragmode_button.update();
+    g_clipper_button.update();
 }
 
-const charconst c_ResizeMode_status = "QE4 Drag Tool: move and resize objects";
+const char *const c_ResizeMode_status = "QE4 Drag Tool: move and resize objects";
 
 void DragMode()
 {
-  if(g_currentToolMode == DragMode && g_defaultToolMode != DragMode)
-  {
-    g_defaultToolMode();
-  }
-  else
-  {
-    g_currentToolMode = DragMode;
-    g_currentToolModeSupportsComponentEditing = true;
+    if (g_currentToolMode == DragMode && g_defaultToolMode != DragMode) {
+        g_defaultToolMode();
+    } else {
+        g_currentToolMode = DragMode;
+        g_currentToolModeSupportsComponentEditing = true;
 
-    OnClipMode(false);
+        OnClipMode(false);
 
-    Sys_Status(c_ResizeMode_status);
-    GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eDrag);
-    ToolChanged();
-    ModeChangeNotify();
-  }
+        Sys_Status(c_ResizeMode_status);
+        GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eDrag);
+        ToolChanged();
+        ModeChangeNotify();
+    }
 }
 
 
-const charconst c_TranslateMode_status = "Translate Tool: translate objects and components";
+const char *const c_TranslateMode_status = "Translate Tool: translate objects and components";
 
 void TranslateMode()
 {
-  if(g_currentToolMode == TranslateMode && g_defaultToolMode != TranslateMode)
-  {
-    g_defaultToolMode();
-  }
-  else
-  {
-    g_currentToolMode = TranslateMode;
-    g_currentToolModeSupportsComponentEditing = true;
+    if (g_currentToolMode == TranslateMode && g_defaultToolMode != TranslateMode) {
+        g_defaultToolMode();
+    } else {
+        g_currentToolMode = TranslateMode;
+        g_currentToolModeSupportsComponentEditing = true;
 
-    OnClipMode(false);
+        OnClipMode(false);
 
-    Sys_Status(c_TranslateMode_status);
-    GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eTranslate);
-    ToolChanged();
-    ModeChangeNotify();
-  }
+        Sys_Status(c_TranslateMode_status);
+        GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eTranslate);
+        ToolChanged();
+        ModeChangeNotify();
+    }
 }
 
-const charconst c_RotateMode_status = "Rotate Tool: rotate objects and components";
+const char *const c_RotateMode_status = "Rotate Tool: rotate objects and components";
 
 void RotateMode()
 {
-  if(g_currentToolMode == RotateMode && g_defaultToolMode != RotateMode)
-  {
-    g_defaultToolMode();
-  }
-  else
-  {
-    g_currentToolMode = RotateMode;
-    g_currentToolModeSupportsComponentEditing = true;
+    if (g_currentToolMode == RotateMode && g_defaultToolMode != RotateMode) {
+        g_defaultToolMode();
+    } else {
+        g_currentToolMode = RotateMode;
+        g_currentToolModeSupportsComponentEditing = true;
 
-    OnClipMode(false);
+        OnClipMode(false);
 
-    Sys_Status(c_RotateMode_status);
-    GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eRotate);
-    ToolChanged();
-    ModeChangeNotify();
-  }
+        Sys_Status(c_RotateMode_status);
+        GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eRotate);
+        ToolChanged();
+        ModeChangeNotify();
+    }
 }
 
-const charconst c_ScaleMode_status = "Scale Tool: scale objects and components";
+const char *const c_ScaleMode_status = "Scale Tool: scale objects and components";
 
 void ScaleMode()
 {
-  if(g_currentToolMode == ScaleMode && g_defaultToolMode != ScaleMode)
-  {
-    g_defaultToolMode();
-  }
-  else
-  {
-    g_currentToolMode = ScaleMode;
-    g_currentToolModeSupportsComponentEditing = true;
+    if (g_currentToolMode == ScaleMode && g_defaultToolMode != ScaleMode) {
+        g_defaultToolMode();
+    } else {
+        g_currentToolMode = ScaleMode;
+        g_currentToolModeSupportsComponentEditing = true;
 
-    OnClipMode(false);
+        OnClipMode(false);
 
-    Sys_Status(c_ScaleMode_status);
-    GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eScale);
-    ToolChanged();
-    ModeChangeNotify();
-  }
+        Sys_Status(c_ScaleMode_status);
+        GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eScale);
+        ToolChanged();
+        ModeChangeNotify();
+    }
 }
 
 
-const charconst c_ClipperMode_status = "Clipper Tool: apply clip planes to objects";
+const char *const c_ClipperMode_status = "Clipper Tool: apply clip planes to objects";
 
 
 void ClipperMode()
 {
-  if(g_currentToolMode == ClipperMode && g_defaultToolMode != ClipperMode)
-  {
-    g_defaultToolMode();
-  }
-  else
-  {
-    g_currentToolMode = ClipperMode;
-    g_currentToolModeSupportsComponentEditing = false;
+    if (g_currentToolMode == ClipperMode && g_defaultToolMode != ClipperMode) {
+        g_defaultToolMode();
+    } else {
+        g_currentToolMode = ClipperMode;
+        g_currentToolModeSupportsComponentEditing = false;
 
-    SelectionSystem_DefaultMode();
+        SelectionSystem_DefaultMode();
 
-    OnClipMode(true);
+        OnClipMode(true);
 
-    Sys_Status(c_ClipperMode_status);
-    GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eClip);
-    ToolChanged();
-    ModeChangeNotify();
-  }
+        Sys_Status(c_ClipperMode_status);
+        GlobalSelectionSystem().SetManipulatorMode(SelectionSystem::eClip);
+        ToolChanged();
+        ModeChangeNotify();
+    }
 }
 
 
 void Texdef_Rotate(float angle)
 {
-  StringOutputStream command;
-  command << "brushRotateTexture -angle " << angle;
-  UndoableCommand undo(command.c_str());
-  Select_RotateTexture(angle);
+    StringOutputStream command;
+    command << "brushRotateTexture -angle " << angle;
+    UndoableCommand undo(command.c_str());
+    Select_RotateTexture(angle);
 }
 
 void Texdef_RotateClockwise()
 {
-  Texdef_Rotate(static_cast<float>(fabs(g_si_globals.rotate)));
+    Texdef_Rotate(static_cast<float>( fabs(g_si_globals.rotate)));
 }
 
 void Texdef_RotateAntiClockwise()
 {
-  Texdef_Rotate(static_cast<float>(-fabs(g_si_globals.rotate)));
+    Texdef_Rotate(static_cast<float>( -fabs(g_si_globals.rotate)));
 }
 
 void Texdef_Scale(float x, float y)
 {
-  StringOutputStream command;
-  command << "brushScaleTexture -x " << x << " -y " << y;
-  UndoableCommand undo(command.c_str());
-  Select_ScaleTexture(x, y);
+    StringOutputStream command;
+    command << "brushScaleTexture -x " << x << " -y " << y;
+    UndoableCommand undo(command.c_str());
+    Select_ScaleTexture(x, y);
 }
 
 void Texdef_ScaleUp()
 {
-  Texdef_Scale(0, g_si_globals.scale[1]);
+    Texdef_Scale(0, g_si_globals.scale[1]);
 }
 
 void Texdef_ScaleDown()
 {
-  Texdef_Scale(0, -g_si_globals.scale[1]);
+    Texdef_Scale(0, -g_si_globals.scale[1]);
 }
 
 void Texdef_ScaleLeft()
 {
-  Texdef_Scale(-g_si_globals.scale[0],0);
+    Texdef_Scale(-g_si_globals.scale[0], 0);
 }
 
 void Texdef_ScaleRight()
 {
-  Texdef_Scale(g_si_globals.scale[0],0);
+    Texdef_Scale(g_si_globals.scale[0], 0);
 }
 
 void Texdef_Shift(float x, float y)
 {
-  StringOutputStream command;
-  command << "brushShiftTexture -x " << x << " -y " << y;
-  UndoableCommand undo(command.c_str());
-  Select_ShiftTexture(x, y);
+    StringOutputStream command;
+    command << "brushShiftTexture -x " << x << " -y " << y;
+    UndoableCommand undo(command.c_str());
+    Select_ShiftTexture(x, y);
 }
 
 void Texdef_ShiftLeft()
 {
-  Texdef_Shift(-g_si_globals.shift[0], 0);
+    Texdef_Shift(-g_si_globals.shift[0], 0);
 }
 
 void Texdef_ShiftRight()
 {
-  Texdef_Shift(g_si_globals.shift[0], 0);
+    Texdef_Shift(g_si_globals.shift[0], 0);
 }
 
 void Texdef_ShiftUp()
 {
-  Texdef_Shift(0, g_si_globals.shift[1]);
+    Texdef_Shift(0, g_si_globals.shift[1]);
 }
 
 void Texdef_ShiftDown()
 {
-  Texdef_Shift(0, -g_si_globals.shift[1]);
+    Texdef_Shift(0, -g_si_globals.shift[1]);
 }
 
 
-
-class SnappableSnapToGridSelected : public scene::Graph::Walker
-{
-  float m_snap;
+class SnappableSnapToGridSelected : public scene::Graph::Walker {
+    float m_snap;
 public:
-  SnappableSnapToGridSelected(float snap)
-    : m_snap(snap)
-  {
-  }
-  bool pre(const scene::Path& path, scene::Instance& instance) const
-  {
-    if(path.top().get().visible())
+    SnappableSnapToGridSelected(float snap)
+            : m_snap(snap)
     {
-      Snappable* snappable = Node_getSnappable(path.top());
-      if(snappable != 0
-        && Instance_getSelectable(instance)->isSelected())
-      {
-        snappable->snapto(m_snap);
-      }
-    }
-    return true;
-  }
+    }
+
+    bool pre(const scene::Path &path, scene::Instance &instance) const
+    {
+        if (path.top().get().visible()) {
+            Snappable *snappable = Node_getSnappable(path.top());
+            if (snappable != 0
+                && Instance_getSelectable(instance)->isSelected()) {
+                snappable->snapto(m_snap);
+            }
+        }
+        return true;
+    }
 };
 
-void Scene_SnapToGrid_Selected(scene::Graphgraph, float snap)
+void Scene_SnapToGrid_Selected(scene::Graph &graph, float snap)
 {
-  graph.traverse(SnappableSnapToGridSelected(snap));
+    graph.traverse(SnappableSnapToGridSelected(snap));
 }
 
-class ComponentSnappableSnapToGridSelected : public scene::Graph::Walker
-{
-  float m_snap;
+class ComponentSnappableSnapToGridSelected : public scene::Graph::Walker {
+    float m_snap;
 public:
-  ComponentSnappableSnapToGridSelected(float snap)
-    : m_snap(snap)
-  {
-  }
-  bool pre(const scene::Path& path, scene::Instance& instance) const
-  {
-    if(path.top().get().visible())
+    ComponentSnappableSnapToGridSelected(float snap)
+            : m_snap(snap)
+    {
+    }
+
+    bool pre(const scene::Path &path, scene::Instance &instance) const
     {
-      ComponentSnappable* componentSnappable = Instance_getComponentSnappable(instance);
-      if(componentSnappable != 0
-        && Instance_getSelectable(instance)->isSelected())
-      {
-        componentSnappable->snapComponents(m_snap);
-      }
-    }
-    return true;
-  }
+        if (path.top().get().visible()) {
+            ComponentSnappable *componentSnappable = Instance_getComponentSnappable(instance);
+            if (componentSnappable != 0
+                && Instance_getSelectable(instance)->isSelected()) {
+                componentSnappable->snapComponents(m_snap);
+            }
+        }
+        return true;
+    }
 };
 
-void Scene_SnapToGrid_Component_Selected(scene::Graphgraph, float snap)
+void Scene_SnapToGrid_Component_Selected(scene::Graph &graph, float snap)
 {
-  graph.traverse(ComponentSnappableSnapToGridSelected(snap));
+    graph.traverse(ComponentSnappableSnapToGridSelected(snap));
 }
 
 void Selection_SnapToGrid()
 {
-  StringOutputStream command;
-  command << "snapSelected -grid " << GetGridSize();
-  UndoableCommand undo(command.c_str());
+    StringOutputStream command;
+    command << "snapSelected -grid " << GetGridSize();
+    UndoableCommand undo(command.c_str());
 
-  if(GlobalSelectionSystem().Mode() == SelectionSystem::eComponent)
-  {
-    Scene_SnapToGrid_Component_Selected(GlobalSceneGraph(), GetGridSize());
-  }
-  else
-  {
-    Scene_SnapToGrid_Selected(GlobalSceneGraph(), GetGridSize());
-  }
+    if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent) {
+        Scene_SnapToGrid_Component_Selected(GlobalSceneGraph(), GetGridSize());
+    } else {
+        Scene_SnapToGrid_Selected(GlobalSceneGraph(), GetGridSize());
+    }
 }
 
 
 static gint qe_every_second(gpointer data)
 {
-  GdkModifierType mask;
+    GdkModifierType mask;
 
-  gdk_window_get_pointer (0, 0, 0, &mask);
+    gdk_window_get_pointer(0, 0, 0, &mask);
 
-  if ((mask & (GDK_BUTTON1_MASK|GDK_BUTTON2_MASK|GDK_BUTTON3_MASK)) == 0)
-  {
-    QE_CheckAutoSave();
-  }
+    if ((mask & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) == 0) {
+        QE_CheckAutoSave();
+    }
 
-  return TRUE;
+    return TRUE;
 }
 
 guint s_qe_every_second_id = 0;
 
 void EverySecondTimer_enable()
 {
-  if(s_qe_every_second_id == 0)
-  {
-    s_qe_every_second_id = gtk_timeout_add(1000, qe_every_second, 0);
-  }
+    if (s_qe_every_second_id == 0) {
+        s_qe_every_second_id = g_timeout_add(1000, qe_every_second, 0);
+    }
 }
 
 void EverySecondTimer_disable()
 {
-  if(s_qe_every_second_id != 0)
-  {
-    gtk_timeout_remove(s_qe_every_second_id);
-    s_qe_every_second_id = 0;
-  }
+    if (s_qe_every_second_id != 0) {
+        g_source_remove(s_qe_every_second_id);
+        s_qe_every_second_id = 0;
+    }
 }
 
-gint window_realize_remove_decoration(GtkWidget* widget, gpointer data)
+gint window_realize_remove_decoration(ui::Widget widget, gpointer data)
 {
-  gdk_window_set_decorations(widget->window, (GdkWMDecoration)(GDK_DECOR_ALL|GDK_DECOR_MENU|GDK_DECOR_MINIMIZE|GDK_DECOR_MAXIMIZE));
-  return FALSE;
+    gdk_window_set_decorations(gtk_widget_get_window(widget),
+                               (GdkWMDecoration) (GDK_DECOR_ALL | GDK_DECOR_MENU | GDK_DECOR_MINIMIZE |
+                                                  GDK_DECOR_MAXIMIZE));
+    return FALSE;
 }
 
-class WaitDialog
-{
+class WaitDialog {
 public:
-  GtkWindow* m_window;
-  GtkLabel* m_label;
+    ui::Window m_window{ui::null};
+    ui::Label m_label{ui::null};
 };
 
-WaitDialog create_wait_dialog(const char* title, const char* text)
+WaitDialog create_wait_dialog(const char *title, const char *text)
 {
-  WaitDialog dialog;
+    WaitDialog dialog;
 
-  dialog.m_window = create_floating_window(title, MainFrame_getWindow());
-  gtk_window_set_resizable(dialog.m_window, FALSE);
-  gtk_container_set_border_width(GTK_CONTAINER(dialog.m_window), 0);
-  gtk_window_set_position(dialog.m_window, GTK_WIN_POS_CENTER_ON_PARENT);
+    dialog.m_window = MainFrame_getWindow().create_floating_window(title);
+    gtk_window_set_resizable(dialog.m_window, FALSE);
+    gtk_container_set_border_width(GTK_CONTAINER(dialog.m_window), 0);
+    gtk_window_set_position(dialog.m_window, GTK_WIN_POS_CENTER_ON_PARENT);
 
-  g_signal_connect(G_OBJECT(dialog.m_window), "realize", G_CALLBACK(window_realize_remove_decoration), 0);
+    dialog.m_window.connect("realize", G_CALLBACK(window_realize_remove_decoration), 0);
 
-  {
-    dialog.m_label = GTK_LABEL(gtk_label_new(text));
-    gtk_misc_set_alignment(GTK_MISC(dialog.m_label), 0.0, 0.5);
-    gtk_label_set_justify(dialog.m_label, GTK_JUSTIFY_LEFT);
-    gtk_widget_show(GTK_WIDGET(dialog.m_label));
-    gtk_widget_set_size_request(GTK_WIDGET(dialog.m_label), 200, -1);
+    {
+        dialog.m_label = ui::Label(text);
+        gtk_misc_set_alignment(GTK_MISC(dialog.m_label), 0.0, 0.5);
+        gtk_label_set_justify(dialog.m_label, GTK_JUSTIFY_LEFT);
+        dialog.m_label.show();
+        dialog.m_label.dimensions(200, -1);
 
-    gtk_container_add(GTK_CONTAINER(dialog.m_window), GTK_WIDGET(dialog.m_label));
-  }
-  return dialog;
+        dialog.m_window.add(dialog.m_label);
+    }
+    return dialog;
 }
 
-namespace
-{
-  clock_t g_lastRedrawTime = 0;
-  const clock_t c_redrawInterval = clock_t(CLOCKS_PER_SEC / 10);
+namespace {
+    clock_t g_lastRedrawTime = 0;
+    const clock_t c_redrawInterval = clock_t(CLOCKS_PER_SEC / 10);
 
-  bool redrawRequired()
-  {
-    clock_t currentTime = std::clock();
-    if(currentTime - g_lastRedrawTime >= c_redrawInterval)
+    bool redrawRequired()
     {
-      g_lastRedrawTime = currentTime;
-      return true;
+        clock_t currentTime = std::clock();
+        if (currentTime - g_lastRedrawTime >= c_redrawInterval) {
+            g_lastRedrawTime = currentTime;
+            return true;
+        }
+        return false;
     }
-    return false;
-  }
 }
 
 bool MainFrame_isActiveApp()
 {
-  //globalOutputStream() << "listing\n";
-  GList* list = gtk_window_list_toplevels();
-  for(GList* i = list; i != 0; i = g_list_next(i))
-  {
-    //globalOutputStream() << "toplevel.. ";
-    if(gtk_window_is_active(GTK_WINDOW(i->data)))
-    {
-      //globalOutputStream() << "is active\n";
-      return true;
+    //globalOutputStream() << "listing\n";
+    GList *list = gtk_window_list_toplevels();
+    for (GList *i = list; i != 0; i = g_list_next(i)) {
+        //globalOutputStream() << "toplevel.. ";
+        if (gtk_window_is_active(ui::Window::from(i->data))) {
+            //globalOutputStream() << "is active\n";
+            return true;
+        }
+        //globalOutputStream() << "not active\n";
     }
-    //globalOutputStream() << "not active\n";
-  }
-  return false;
+    return false;
 }
 
 typedef std::list<CopiedString> StringStack;
@@ -1881,1078 +1958,1080 @@ WaitDialog g_wait;
 
 bool ScreenUpdates_Enabled()
 {
-  return g_wait_stack.empty();
+    return g_wait_stack.empty();
 }
 
 void ScreenUpdates_process()
 {
-  if(redrawRequired() && GTK_WIDGET_VISIBLE(g_wait.m_window))
-  {
-    process_gui();
-  }
+    if (redrawRequired() && g_wait.m_window.visible()) {
+        ui::process();
+    }
 }
 
 
-void ScreenUpdates_Disable(const char* message, const char* title)
+void ScreenUpdates_Disable(const char *message, const char *title)
 {
-  if(g_wait_stack.empty())
-  {
-    EverySecondTimer_disable();
+    if (g_wait_stack.empty()) {
+        EverySecondTimer_disable();
 
-    process_gui();
+        ui::process();
 
-    bool isActiveApp = MainFrame_isActiveApp();
+        bool isActiveApp = MainFrame_isActiveApp();
 
-    g_wait = create_wait_dialog(title, message);
-    gtk_grab_add(GTK_WIDGET(g_wait.m_window));
+        g_wait = create_wait_dialog(title, message);
+        gtk_grab_add(g_wait.m_window);
 
-    if(isActiveApp)
-    {
-      gtk_widget_show(GTK_WIDGET(g_wait.m_window));
-      ScreenUpdates_process();
+        if (isActiveApp) {
+            g_wait.m_window.show();
+            ScreenUpdates_process();
+        }
+    } else if (g_wait.m_window.visible()) {
+        g_wait.m_label.text(message);
+        ScreenUpdates_process();
     }
-  }
-  else if(GTK_WIDGET_VISIBLE(g_wait.m_window))
-  {
-    gtk_label_set_text(g_wait.m_label, message);
-    ScreenUpdates_process();
-  }
-  g_wait_stack.push_back(message);
+    g_wait_stack.push_back(message);
 }
 
 void ScreenUpdates_Enable()
 {
-  ASSERT_MESSAGE(!ScreenUpdates_Enabled(), "screen updates already enabled");
-  g_wait_stack.pop_back();
-  if(g_wait_stack.empty())
-  {
-    EverySecondTimer_enable();
-    //gtk_widget_set_sensitive(GTK_WIDGET(MainFrame_getWindow()), TRUE);
+    ASSERT_MESSAGE(!ScreenUpdates_Enabled(), "screen updates already enabled");
+    g_wait_stack.pop_back();
+    if (g_wait_stack.empty()) {
+        EverySecondTimer_enable();
+        //gtk_widget_set_sensitive(MainFrame_getWindow(), TRUE);
 
-    gtk_grab_remove(GTK_WIDGET(g_wait.m_window));
-    destroy_floating_window(g_wait.m_window);
-    g_wait.m_window = 0;
+        gtk_grab_remove(g_wait.m_window);
+        destroy_floating_window(g_wait.m_window);
+        g_wait.m_window = ui::Window{ui::null};
 
-    //gtk_window_present(MainFrame_getWindow());
-  }
-  else if(GTK_WIDGET_VISIBLE(g_wait.m_window))
-  {
-    gtk_label_set_text(g_wait.m_label, g_wait_stack.back().c_str());
-    ScreenUpdates_process();
-  }
+        //gtk_window_present(MainFrame_getWindow());
+    } else if (g_wait.m_window.visible()) {
+        g_wait.m_label.text(g_wait_stack.back().c_str());
+        ScreenUpdates_process();
+    }
 }
 
 
-
 void GlobalCamera_UpdateWindow()
 {
-  if(g_pParentWnd != 0)
-  {
-    CamWnd_Update(*g_pParentWnd->GetCamWnd());
-  }
+    if (g_pParentWnd != 0) {
+        CamWnd_Update(*g_pParentWnd->GetCamWnd());
+    }
 }
 
-void XY_UpdateWindow(MainFramemainframe)
+void XY_UpdateWindow(MainFrame &mainframe)
 {
-  if(mainframe.GetXYWnd() != 0)
-  {
-    XYWnd_Update(*mainframe.GetXYWnd());
-  }
+    if (mainframe.GetXYWnd() != 0) {
+        XYWnd_Update(*mainframe.GetXYWnd());
+    }
 }
 
-void XZ_UpdateWindow(MainFramemainframe)
+void XZ_UpdateWindow(MainFrame &mainframe)
 {
-  if(mainframe.GetXZWnd() != 0)
-  {
-    XYWnd_Update(*mainframe.GetXZWnd());
-  }
+    if (mainframe.GetXZWnd() != 0) {
+        XYWnd_Update(*mainframe.GetXZWnd());
+    }
 }
 
-void YZ_UpdateWindow(MainFramemainframe)
+void YZ_UpdateWindow(MainFrame &mainframe)
 {
-  if(mainframe.GetYZWnd() != 0)
-  {
-    XYWnd_Update(*mainframe.GetYZWnd());
-  }
+    if (mainframe.GetYZWnd() != 0) {
+        XYWnd_Update(*mainframe.GetYZWnd());
+    }
 }
 
-void XY_UpdateAllWindows(MainFramemainframe)
+void XY_UpdateAllWindows(MainFrame &mainframe)
 {
-  XY_UpdateWindow(mainframe);
-  XZ_UpdateWindow(mainframe);
-  YZ_UpdateWindow(mainframe);
+    XY_UpdateWindow(mainframe);
+    XZ_UpdateWindow(mainframe);
+    YZ_UpdateWindow(mainframe);
 }
 
 void XY_UpdateAllWindows()
 {
-  if(g_pParentWnd != 0)
-  {
-    XY_UpdateAllWindows(*g_pParentWnd);
-  }
+    if (g_pParentWnd != 0) {
+        XY_UpdateAllWindows(*g_pParentWnd);
+    }
 }
 
 void UpdateAllWindows()
 {
-  GlobalCamera_UpdateWindow();
-  XY_UpdateAllWindows();
+    GlobalCamera_UpdateWindow();
+    XY_UpdateAllWindows();
 }
 
 
 void ModeChangeNotify()
 {
-  SceneChangeNotify();
+    SceneChangeNotify();
 }
 
 void ClipperChangeNotify()
 {
-  GlobalCamera_UpdateWindow();
-  XY_UpdateAllWindows();
+    GlobalCamera_UpdateWindow();
+    XY_UpdateAllWindows();
 }
 
 
-LatchedInt g_Layout_viewStyle(0, "Window Layout");
-LatchedBool g_Layout_enableDetachableMenus(true, "Detachable Menus");
-LatchedBool g_Layout_enablePatchToolbar(true, "Patch Toolbar");
-LatchedBool g_Layout_enablePluginToolbar(true, "Plugin Toolbar");
-
+LatchedValue<int> g_Layout_viewStyle(0, "Window Layout");
+LatchedValue<bool> g_Layout_enableDetachableMenus(true, "Detachable Menus");
+LatchedValue<bool> g_Layout_enablePatchToolbar(true, "Patch Toolbar");
+LatchedValue<bool> g_Layout_enablePluginToolbar(true, "Plugin Toolbar");
 
 
-GtkMenuItem* create_file_menu()
+ui::MenuItem create_file_menu()
 {
-  // File menu
-  GtkMenuItem* file_menu_item = new_sub_menu_item_with_mnemonic("_File");
-  GtkMenu* menu = GTK_MENU(gtk_menu_item_get_submenu(file_menu_item));
-  if (g_Layout_enableDetachableMenus.m_value)
-    menu_tearoff (menu);
+    // File menu
+    auto file_menu_item = new_sub_menu_item_with_mnemonic("_File");
+    auto menu = ui::Menu::from(gtk_menu_item_get_submenu(file_menu_item));
+    if (g_Layout_enableDetachableMenus.m_value) {
+        menu_tearoff(menu);
+    }
 
-  create_menu_item_with_mnemonic(menu, "_New Map", "NewMap");
-  menu_separator(menu);
+    create_menu_item_with_mnemonic(menu, "_New Map", "NewMap");
+    menu_separator(menu);
 
 #if 0
-  //++timo temporary experimental stuff for sleep mode..
-  create_menu_item_with_mnemonic(menu, "_Sleep", "Sleep");
-  menu_separator(menu);
-  // end experimental
+                                                                                                                            //++timo temporary experimental stuff for sleep mode..
+       create_menu_item_with_mnemonic( menu, "_Sleep", "Sleep" );
+       menu_separator( menu );
+       // end experimental
 #endif
 
-  create_menu_item_with_mnemonic(menu, "_Open...", "OpenMap");
+    create_menu_item_with_mnemonic(menu, "_Open...", "OpenMap");
+
+    create_menu_item_with_mnemonic(menu, "_Import...", "ImportMap");
+    create_menu_item_with_mnemonic(menu, "_Save", "SaveMap");
+    create_menu_item_with_mnemonic(menu, "Save _as...", "SaveMapAs");
+    create_menu_item_with_mnemonic(menu, "_Export selected...", "ExportSelected");
+    menu_separator(menu);
+    create_menu_item_with_mnemonic(menu, "Save re_gion...", "SaveRegion");
+    menu_separator(menu);
+    create_menu_item_with_mnemonic(menu, "_Refresh models", "RefreshReferences");
+    menu_separator(menu);
+    create_menu_item_with_mnemonic(menu, "Pro_ject settings...", "ProjectSettings");
+    menu_separator(menu);
+    create_menu_item_with_mnemonic(menu, "_Pointfile...", "TogglePointfile");
+    menu_separator(menu);
+    MRU_constructMenu(menu);
+    menu_separator(menu);
+    create_menu_item_with_mnemonic(menu, "E_xit", "Exit");
+
+    return file_menu_item;
+}
+
+ui::MenuItem create_edit_menu()
+{
+    // Edit menu
+    auto edit_menu_item = new_sub_menu_item_with_mnemonic("_Edit");
+    auto menu = ui::Menu::from(gtk_menu_item_get_submenu(edit_menu_item));
+    if (g_Layout_enableDetachableMenus.m_value) {
+        menu_tearoff(menu);
+    }
+    create_menu_item_with_mnemonic(menu, "_Undo", "Undo");
+    create_menu_item_with_mnemonic(menu, "_Redo", "Redo");
+    menu_separator(menu);
+    create_menu_item_with_mnemonic(menu, "_Copy", "Copy");
+    create_menu_item_with_mnemonic(menu, "_Paste", "Paste");
+    create_menu_item_with_mnemonic(menu, "P_aste To Camera", "PasteToCamera");
+    menu_separator(menu);
+    create_menu_item_with_mnemonic(menu, "_Duplicate", "CloneSelection");
+    create_menu_item_with_mnemonic(menu, "Duplicate, make uni_que", "CloneSelectionAndMakeUnique");
+    create_menu_item_with_mnemonic(menu, "D_elete", "DeleteSelection");
+    menu_separator(menu);
+    create_menu_item_with_mnemonic(menu, "Pa_rent", "ParentSelection");
+    menu_separator(menu);
+    create_menu_item_with_mnemonic(menu, "C_lear Selection", "UnSelectSelection");
+    create_menu_item_with_mnemonic(menu, "_Invert Selection", "InvertSelection");
+    create_menu_item_with_mnemonic(menu, "Select i_nside", "SelectInside");
+    create_menu_item_with_mnemonic(menu, "Select _touching", "SelectTouching");
+
+    auto convert_menu = create_sub_menu_with_mnemonic(menu, "E_xpand Selection");
+    if (g_Layout_enableDetachableMenus.m_value) {
+        menu_tearoff(convert_menu);
+    }
+    create_menu_item_with_mnemonic(convert_menu, "To Whole _Entities", "ExpandSelectionToEntities");
+
+    menu_separator(menu);
+    create_menu_item_with_mnemonic(menu, "Pre_ferences...", "Preferences");
+
+    return edit_menu_item;
+}
+
+void fill_view_xy_top_menu(ui::Menu menu)
+{
+    create_check_menu_item_with_mnemonic(menu, "XY (Top) View", "ToggleView");
+}
+
+
+void fill_view_yz_side_menu(ui::Menu menu)
+{
+    create_check_menu_item_with_mnemonic(menu, "YZ (Side) View", "ToggleSideView");
+}
+
+
+void fill_view_xz_front_menu(ui::Menu menu)
+{
+    create_check_menu_item_with_mnemonic(menu, "XZ (Front) View", "ToggleFrontView");
+}
+
+
+ui::Widget g_toggle_z_item{ui::null};
+ui::Widget g_toggle_console_item{ui::null};
+ui::Widget g_toggle_entity_item{ui::null};
+ui::Widget g_toggle_entitylist_item{ui::null};
+
+ui::MenuItem create_view_menu(MainFrame::EViewStyle style)
+{
+    // View menu
+    auto view_menu_item = new_sub_menu_item_with_mnemonic("Vie_w");
+    auto menu = ui::Menu::from(gtk_menu_item_get_submenu(view_menu_item));
+    if (g_Layout_enableDetachableMenus.m_value) {
+        menu_tearoff(menu);
+    }
+
+    if (style == MainFrame::eFloating) {
+        fill_view_camera_menu(menu);
+        fill_view_xy_top_menu(menu);
+        fill_view_yz_side_menu(menu);
+        fill_view_xz_front_menu(menu);
+    }
+    if (style == MainFrame::eFloating || style == MainFrame::eSplit) {
+        create_menu_item_with_mnemonic(menu, "Console View", "ToggleConsole");
+        create_menu_item_with_mnemonic(menu, "Texture Browser", "ToggleTextures");
+        create_menu_item_with_mnemonic(menu, "Entity Inspector", "ToggleEntityInspector");
+    } else {
+        create_menu_item_with_mnemonic(menu, "Entity Inspector", "ViewEntityInfo");
+    }
+    create_menu_item_with_mnemonic(menu, "_Surface Inspector", "SurfaceInspector");
+    create_menu_item_with_mnemonic(menu, "Entity List", "EntityList");
+
+    menu_separator(menu);
+    {
+        auto camera_menu = create_sub_menu_with_mnemonic(menu, "Camera");
+        if (g_Layout_enableDetachableMenus.m_value) {
+            menu_tearoff(camera_menu);
+        }
+        create_menu_item_with_mnemonic(camera_menu, "_Center", "CenterView");
+        create_menu_item_with_mnemonic(camera_menu, "_Up Floor", "UpFloor");
+        create_menu_item_with_mnemonic(camera_menu, "_Down Floor", "DownFloor");
+        menu_separator(camera_menu);
+        create_menu_item_with_mnemonic(camera_menu, "Far Clip Plane In", "CubicClipZoomIn");
+        create_menu_item_with_mnemonic(camera_menu, "Far Clip Plane Out", "CubicClipZoomOut");
+        menu_separator(camera_menu);
+        create_menu_item_with_mnemonic(camera_menu, "Next leak spot", "NextLeakSpot");
+        create_menu_item_with_mnemonic(camera_menu, "Previous leak spot", "PrevLeakSpot");
+        menu_separator(camera_menu);
+        create_menu_item_with_mnemonic(camera_menu, "Look Through Selected", "LookThroughSelected");
+        create_menu_item_with_mnemonic(camera_menu, "Look Through Camera", "LookThroughCamera");
+    }
+    menu_separator(menu);
+    {
+        auto orthographic_menu = create_sub_menu_with_mnemonic(menu, "Orthographic");
+        if (g_Layout_enableDetachableMenus.m_value) {
+            menu_tearoff(orthographic_menu);
+        }
+        if (style == MainFrame::eRegular || style == MainFrame::eRegularLeft || style == MainFrame::eFloating) {
+            create_menu_item_with_mnemonic(orthographic_menu, "_Next (XY, YZ, XY)", "NextView");
+            create_menu_item_with_mnemonic(orthographic_menu, "XY (Top)", "ViewTop");
+            create_menu_item_with_mnemonic(orthographic_menu, "YZ", "ViewSide");
+            create_menu_item_with_mnemonic(orthographic_menu, "XZ", "ViewFront");
+            menu_separator(orthographic_menu);
+        }
+
+        create_menu_item_with_mnemonic(orthographic_menu, "_XY 100%", "Zoom100");
+        create_menu_item_with_mnemonic(orthographic_menu, "XY Zoom _In", "ZoomIn");
+        create_menu_item_with_mnemonic(orthographic_menu, "XY Zoom _Out", "ZoomOut");
+    }
+
+    menu_separator(menu);
+
+    {
+        auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Show");
+        if (g_Layout_enableDetachableMenus.m_value) {
+            menu_tearoff(menu_in_menu);
+        }
+        create_check_menu_item_with_mnemonic(menu_in_menu, "Show _Angles", "ShowAngles");
+        create_check_menu_item_with_mnemonic(menu_in_menu, "Show _Names", "ShowNames");
+        create_check_menu_item_with_mnemonic(menu_in_menu, "Show Blocks", "ShowBlocks");
+        create_check_menu_item_with_mnemonic(menu_in_menu, "Show C_oordinates", "ShowCoordinates");
+        create_check_menu_item_with_mnemonic(menu_in_menu, "Show Window Outline", "ShowWindowOutline");
+        create_check_menu_item_with_mnemonic(menu_in_menu, "Show Axes", "ShowAxes");
+        create_check_menu_item_with_mnemonic(menu_in_menu, "Show Workzone", "ShowWorkzone");
+        create_check_menu_item_with_mnemonic(menu_in_menu, "Show Stats", "ShowStats");
+    }
+
+    {
+        auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Filter");
+        if (g_Layout_enableDetachableMenus.m_value) {
+            menu_tearoff(menu_in_menu);
+        }
+        Filters_constructMenu(menu_in_menu);
+    }
+    menu_separator(menu);
+    {
+        auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Hide/Show");
+        if (g_Layout_enableDetachableMenus.m_value) {
+            menu_tearoff(menu_in_menu);
+        }
+        create_menu_item_with_mnemonic(menu_in_menu, "Hide Selected", "HideSelected");
+        create_menu_item_with_mnemonic(menu_in_menu, "Show Hidden", "ShowHidden");
+    }
+    menu_separator(menu);
+    {
+        auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Region");
+        if (g_Layout_enableDetachableMenus.m_value) {
+            menu_tearoff(menu_in_menu);
+        }
+        create_menu_item_with_mnemonic(menu_in_menu, "_Off", "RegionOff");
+        create_menu_item_with_mnemonic(menu_in_menu, "_Set XY", "RegionSetXY");
+        create_menu_item_with_mnemonic(menu_in_menu, "Set _Brush", "RegionSetBrush");
+        create_menu_item_with_mnemonic(menu_in_menu, "Set Se_lected Brushes", "RegionSetSelection");
+    }
+
+    command_connect_accelerator("CenterXYView");
+
+    return view_menu_item;
+}
+
+ui::MenuItem create_selection_menu()
+{
+    // Selection menu
+    auto selection_menu_item = new_sub_menu_item_with_mnemonic("M_odify");
+    auto menu = ui::Menu::from(gtk_menu_item_get_submenu(selection_menu_item));
+    if (g_Layout_enableDetachableMenus.m_value) {
+        menu_tearoff(menu);
+    }
+
+    {
+        auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Components");
+        if (g_Layout_enableDetachableMenus.m_value) {
+            menu_tearoff(menu_in_menu);
+        }
+        create_check_menu_item_with_mnemonic(menu_in_menu, "_Edges", "DragEdges");
+        create_check_menu_item_with_mnemonic(menu_in_menu, "_Vertices", "DragVertices");
+        create_check_menu_item_with_mnemonic(menu_in_menu, "_Faces", "DragFaces");
+    }
+
+    menu_separator(menu);
 
-  create_menu_item_with_mnemonic(menu, "_Import...", "ImportMap");
-  create_menu_item_with_mnemonic(menu, "_Save", "SaveMap");
-  create_menu_item_with_mnemonic(menu, "Save _as...", "SaveMapAs");
-  create_menu_item_with_mnemonic(menu, "Save s_elected...", "SaveSelected");
-  menu_separator(menu);
-  create_menu_item_with_mnemonic(menu, "Save re_gion...", "SaveRegion");
-  menu_separator(menu);
-  create_menu_item_with_mnemonic(menu, "_Refresh models", "RefreshReferences");
-  menu_separator(menu);
-  create_menu_item_with_mnemonic(menu, "Pro_ject settings...", "ProjectSettings");
-  menu_separator(menu);
-  create_menu_item_with_mnemonic(menu, "_Pointfile...", "TogglePointfile");
-  menu_separator(menu);
-  MRU_constructMenu(menu);
-  menu_separator(menu);
-  create_menu_item_with_mnemonic(menu, "Check for NetRadiant update (web)", "CheckForUpdate"); // FIXME
-  create_menu_item_with_mnemonic(menu, "E_xit", "Exit");
-
-  return file_menu_item;
-}
-
-GtkMenuItem* create_edit_menu()
-{
-  // Edit menu
-  GtkMenuItem* edit_menu_item = new_sub_menu_item_with_mnemonic("_Edit");
-  GtkMenu* menu = GTK_MENU(gtk_menu_item_get_submenu(edit_menu_item));
-  if (g_Layout_enableDetachableMenus.m_value)
-    menu_tearoff (menu);
-  create_menu_item_with_mnemonic(menu, "_Undo", "Undo");
-  create_menu_item_with_mnemonic(menu, "_Redo", "Redo");
-  menu_separator(menu);
-  create_menu_item_with_mnemonic(menu, "_Copy", "Copy");
-  create_menu_item_with_mnemonic(menu, "_Paste", "Paste");
-  create_menu_item_with_mnemonic(menu, "P_aste To Camera", "PasteToCamera");
-  menu_separator(menu);
-  create_menu_item_with_mnemonic(menu, "_Duplicate", "CloneSelection");
-  create_menu_item_with_mnemonic(menu, "Duplicate, make uni_que", "CloneSelectionAndMakeUnique");
-  create_menu_item_with_mnemonic(menu, "D_elete", "DeleteSelection");
-  menu_separator(menu);
-  create_menu_item_with_mnemonic(menu, "Pa_rent", "ParentSelection");
-  menu_separator(menu);
-  create_menu_item_with_mnemonic(menu, "C_lear Selection", "UnSelectSelection");
-  create_menu_item_with_mnemonic(menu, "_Invert Selection", "InvertSelection");
-  create_menu_item_with_mnemonic(menu, "Select i_nside", "SelectInside");
-  create_menu_item_with_mnemonic(menu, "Select _touching", "SelectTouching");
-
-  GtkMenu* convert_menu = create_sub_menu_with_mnemonic(menu, "E_xpand Selection");
-  if (g_Layout_enableDetachableMenus.m_value)
-    menu_tearoff (convert_menu);
-  create_menu_item_with_mnemonic(convert_menu, "To Whole _Entities", "ExpandSelectionToEntities");
-
-  menu_separator(menu);
-  create_menu_item_with_mnemonic(menu, "Pre_ferences...", "Preferences");
-
-  return edit_menu_item;
-}
-
-void fill_view_xy_top_menu(GtkMenu* menu)
-{
-  create_check_menu_item_with_mnemonic(menu, "XY (Top) View", "ToggleView");
-}
-
-
-void fill_view_yz_side_menu(GtkMenu* menu)
-{
-  create_check_menu_item_with_mnemonic(menu, "YZ (Side) View", "ToggleSideView");
-}
-
-
-void fill_view_xz_front_menu(GtkMenu* menu)
-{
-  create_check_menu_item_with_mnemonic(menu, "XZ (Front) View", "ToggleFrontView");
-}
-
-
-GtkWidget* g_toggle_z_item = 0;
-GtkWidget* g_toggle_console_item = 0;
-GtkWidget* g_toggle_entity_item = 0;
-GtkWidget* g_toggle_entitylist_item = 0;
-
-GtkMenuItem* create_view_menu(MainFrame::EViewStyle style)
-{
-  // View menu
-  GtkMenuItem* view_menu_item = new_sub_menu_item_with_mnemonic("Vie_w");
-  GtkMenu* menu = GTK_MENU(gtk_menu_item_get_submenu(view_menu_item));
-  if (g_Layout_enableDetachableMenus.m_value)
-    menu_tearoff (menu);
-
-  if(style == MainFrame::eFloating)
-  {
-    fill_view_camera_menu(menu);
-    fill_view_xy_top_menu(menu);
-    fill_view_yz_side_menu(menu);
-    fill_view_xz_front_menu(menu);
-  }
-  if(style == MainFrame::eFloating || style == MainFrame::eSplit)
-  {
-    create_menu_item_with_mnemonic(menu, "Console View", "ToggleConsole");
-    create_menu_item_with_mnemonic(menu, "Texture Browser", "ToggleTextures");
-    create_menu_item_with_mnemonic(menu, "Entity Inspector", "ToggleEntityInspector");
-  }
-  else
-  {
-    create_menu_item_with_mnemonic(menu, "Entity Inspector", "ViewEntityInfo");
-  }
-  create_menu_item_with_mnemonic(menu, "_Surface Inspector", "SurfaceInspector");
-  create_menu_item_with_mnemonic(menu, "Entity List", "EntityList");
-
-  menu_separator(menu);
-  {
-    GtkMenu* camera_menu = create_sub_menu_with_mnemonic (menu, "Camera");
-    if (g_Layout_enableDetachableMenus.m_value)
-      menu_tearoff (camera_menu);
-    create_menu_item_with_mnemonic(camera_menu, "_Center", "CenterView");
-    create_menu_item_with_mnemonic(camera_menu, "_Up Floor", "UpFloor");
-    create_menu_item_with_mnemonic(camera_menu, "_Down Floor", "DownFloor");
-    menu_separator(camera_menu);
-    create_menu_item_with_mnemonic(camera_menu, "Far Clip Plane In", "CubicClipZoomIn");
-    create_menu_item_with_mnemonic(camera_menu, "Far Clip Plane Out", "CubicClipZoomOut");
-    menu_separator(camera_menu);
-    create_menu_item_with_mnemonic(camera_menu, "Next leak spot", "NextLeakSpot");
-    create_menu_item_with_mnemonic(camera_menu, "Previous leak spot", "PrevLeakSpot");
-    menu_separator(camera_menu);
-    create_menu_item_with_mnemonic(camera_menu, "Look Through Selected", "LookThroughSelected");
-    create_menu_item_with_mnemonic(camera_menu, "Look Through Camera", "LookThroughCamera");
-  }
-  menu_separator(menu);
-  {
-    GtkMenu* orthographic_menu = create_sub_menu_with_mnemonic(menu, "Orthographic");
-    if (g_Layout_enableDetachableMenus.m_value)
-      menu_tearoff (orthographic_menu);
-    if(style == MainFrame::eRegular || style == MainFrame::eRegularLeft || style == MainFrame::eFloating)
     {
-      create_menu_item_with_mnemonic(orthographic_menu, "_Next (XY, YZ, XY)", "NextView");
-      create_menu_item_with_mnemonic(orthographic_menu, "XY (Top)", "ViewTop");
-      create_menu_item_with_mnemonic(orthographic_menu, "YZ", "ViewSide");
-      create_menu_item_with_mnemonic(orthographic_menu, "XZ", "ViewFront");
-      menu_separator(orthographic_menu);
-    }
-
-    create_menu_item_with_mnemonic(orthographic_menu, "_XY 100%", "Zoom100");
-    create_menu_item_with_mnemonic(orthographic_menu, "XY Zoom _In", "ZoomIn");
-    create_menu_item_with_mnemonic(orthographic_menu, "XY Zoom _Out", "ZoomOut");
-  }
-
-  menu_separator(menu);
-
-  {
-    GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic (menu, "Show");
-    if (g_Layout_enableDetachableMenus.m_value)
-      menu_tearoff (menu_in_menu);
-    create_check_menu_item_with_mnemonic(menu_in_menu, "Show _Angles", "ShowAngles");
-    create_check_menu_item_with_mnemonic(menu_in_menu, "Show _Names", "ShowNames");
-    create_check_menu_item_with_mnemonic(menu_in_menu, "Show Blocks", "ShowBlocks");
-    create_check_menu_item_with_mnemonic(menu_in_menu, "Show C_oordinates", "ShowCoordinates");
-    create_check_menu_item_with_mnemonic(menu_in_menu, "Show Window Outline", "ShowWindowOutline");
-    create_check_menu_item_with_mnemonic(menu_in_menu, "Show Axes", "ShowAxes");
-    create_check_menu_item_with_mnemonic(menu_in_menu, "Show Workzone", "ShowWorkzone");
-    create_check_menu_item_with_mnemonic(menu_in_menu, "Show Stats", "ShowStats");
-  }
-
-  {
-    GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic (menu, "Filter");
-    if (g_Layout_enableDetachableMenus.m_value)
-      menu_tearoff (menu_in_menu);
-    Filters_constructMenu(menu_in_menu);
-  }
-  menu_separator(menu);
-  {
-    GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic (menu, "Hide/Show");
-    if (g_Layout_enableDetachableMenus.m_value)
-      menu_tearoff (menu_in_menu);
-    create_menu_item_with_mnemonic(menu_in_menu, "Hide Selected", "HideSelected");
-    create_menu_item_with_mnemonic(menu_in_menu, "Show Hidden", "ShowHidden");
-  }
-  menu_separator(menu);
-  {
-    GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic (menu, "Region");
-    if (g_Layout_enableDetachableMenus.m_value)
-      menu_tearoff (menu_in_menu);
-    create_menu_item_with_mnemonic(menu_in_menu, "_Off", "RegionOff");
-    create_menu_item_with_mnemonic(menu_in_menu, "_Set XY", "RegionSetXY");
-    create_menu_item_with_mnemonic(menu_in_menu, "Set _Brush", "RegionSetBrush");
-    create_menu_item_with_mnemonic(menu_in_menu, "Set Se_lected Brushes", "RegionSetSelection");
-  }
-
-  command_connect_accelerator("CenterXYView");
-
-  return view_menu_item;
-}
-
-GtkMenuItem* create_selection_menu()
-{
-  // Selection menu
-  GtkMenuItem* selection_menu_item = new_sub_menu_item_with_mnemonic("M_odify");
-  GtkMenu* menu = GTK_MENU(gtk_menu_item_get_submenu(selection_menu_item));
-  if (g_Layout_enableDetachableMenus.m_value)
-    menu_tearoff (menu);
-
-  {
-    GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic (menu, "Components");
-    if (g_Layout_enableDetachableMenus.m_value)
-      menu_tearoff (menu_in_menu);
-    create_check_menu_item_with_mnemonic(menu_in_menu, "_Edges", "DragEdges");
-    create_check_menu_item_with_mnemonic(menu_in_menu, "_Vertices", "DragVertices");
-    create_check_menu_item_with_mnemonic(menu_in_menu, "_Faces", "DragFaces");
-  }
-
-  menu_separator(menu);
-
-  {
-    GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic(menu, "Nudge");
-    if (g_Layout_enableDetachableMenus.m_value)
-      menu_tearoff (menu_in_menu);
-    create_menu_item_with_mnemonic(menu_in_menu, "Nudge Left", "SelectNudgeLeft");
-    create_menu_item_with_mnemonic(menu_in_menu, "Nudge Right", "SelectNudgeRight");
-    create_menu_item_with_mnemonic(menu_in_menu, "Nudge Up", "SelectNudgeUp");
-    create_menu_item_with_mnemonic(menu_in_menu, "Nudge Down", "SelectNudgeDown");
-  }
-  {
-    GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic (menu, "Rotate");
-    if (g_Layout_enableDetachableMenus.m_value)
-      menu_tearoff (menu_in_menu);
-    create_menu_item_with_mnemonic(menu_in_menu, "Rotate X", "RotateSelectionX");
-    create_menu_item_with_mnemonic(menu_in_menu, "Rotate Y", "RotateSelectionY");
-    create_menu_item_with_mnemonic(menu_in_menu, "Rotate Z", "RotateSelectionZ");
-  }
-  {
-    GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic (menu, "Flip");
-    if (g_Layout_enableDetachableMenus.m_value)
-      menu_tearoff (menu_in_menu);
-    create_menu_item_with_mnemonic(menu_in_menu, "Flip _X", "MirrorSelectionX");
-    create_menu_item_with_mnemonic(menu_in_menu, "Flip _Y", "MirrorSelectionY");
-    create_menu_item_with_mnemonic(menu_in_menu, "Flip _Z", "MirrorSelectionZ");
-  }
-  menu_separator(menu);
-  create_menu_item_with_mnemonic(menu, "Arbitrary rotation...", "ArbitraryRotation");
-  create_menu_item_with_mnemonic(menu, "Arbitrary scale...", "ArbitraryScale");
-
-  return selection_menu_item;
-}
-
-GtkMenuItem* create_bsp_menu()
-{
-  // BSP menu
-  GtkMenuItem* bsp_menu_item = new_sub_menu_item_with_mnemonic("_Build");
-  GtkMenu* menu = GTK_MENU(gtk_menu_item_get_submenu(bsp_menu_item));
-
-  if (g_Layout_enableDetachableMenus.m_value)
-  {
-    menu_tearoff(menu);
-  }
-
-  create_menu_item_with_mnemonic(menu, "Customize...", "BuildMenuCustomize");
-
-  menu_separator(menu);
-
-  Build_constructMenu(menu);
-
-  g_bsp_menu = menu;
-
-  return bsp_menu_item;
-}
-
-GtkMenuItem* create_grid_menu()
-{
-  // Grid menu
-  GtkMenuItem* grid_menu_item = new_sub_menu_item_with_mnemonic("_Grid");
-  GtkMenu* menu = GTK_MENU(gtk_menu_item_get_submenu(grid_menu_item));
-  if (g_Layout_enableDetachableMenus.m_value)
-    menu_tearoff (menu);
-
-  Grid_constructMenu(menu);
-
-  return grid_menu_item;
+        auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Nudge");
+        if (g_Layout_enableDetachableMenus.m_value) {
+            menu_tearoff(menu_in_menu);
+        }
+        create_menu_item_with_mnemonic(menu_in_menu, "Nudge Left", "SelectNudgeLeft");
+        create_menu_item_with_mnemonic(menu_in_menu, "Nudge Right", "SelectNudgeRight");
+        create_menu_item_with_mnemonic(menu_in_menu, "Nudge Up", "SelectNudgeUp");
+        create_menu_item_with_mnemonic(menu_in_menu, "Nudge Down", "SelectNudgeDown");
+    }
+    {
+        auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Rotate");
+        if (g_Layout_enableDetachableMenus.m_value) {
+            menu_tearoff(menu_in_menu);
+        }
+        create_menu_item_with_mnemonic(menu_in_menu, "Rotate X", "RotateSelectionX");
+        create_menu_item_with_mnemonic(menu_in_menu, "Rotate Y", "RotateSelectionY");
+        create_menu_item_with_mnemonic(menu_in_menu, "Rotate Z", "RotateSelectionZ");
+    }
+    {
+        auto menu_in_menu = create_sub_menu_with_mnemonic(menu, "Flip");
+        if (g_Layout_enableDetachableMenus.m_value) {
+            menu_tearoff(menu_in_menu);
+        }
+        create_menu_item_with_mnemonic(menu_in_menu, "Flip _X", "MirrorSelectionX");
+        create_menu_item_with_mnemonic(menu_in_menu, "Flip _Y", "MirrorSelectionY");
+        create_menu_item_with_mnemonic(menu_in_menu, "Flip _Z", "MirrorSelectionZ");
+    }
+    menu_separator(menu);
+    create_menu_item_with_mnemonic(menu, "Arbitrary rotation...", "ArbitraryRotation");
+    create_menu_item_with_mnemonic(menu, "Arbitrary scale...", "ArbitraryScale");
+
+    return selection_menu_item;
+}
+
+ui::MenuItem create_bsp_menu()
+{
+    // BSP menu
+    auto bsp_menu_item = new_sub_menu_item_with_mnemonic("_Build");
+    auto menu = ui::Menu::from(gtk_menu_item_get_submenu(bsp_menu_item));
+
+    if (g_Layout_enableDetachableMenus.m_value) {
+        menu_tearoff(menu);
+    }
+
+    create_menu_item_with_mnemonic(menu, "Customize...", "BuildMenuCustomize");
+
+    menu_separator(menu);
+
+    Build_constructMenu(menu);
+
+    g_bsp_menu = menu;
+
+    return bsp_menu_item;
+}
+
+ui::MenuItem create_grid_menu()
+{
+    // Grid menu
+    auto grid_menu_item = new_sub_menu_item_with_mnemonic("_Grid");
+    auto menu = ui::Menu::from(gtk_menu_item_get_submenu(grid_menu_item));
+    if (g_Layout_enableDetachableMenus.m_value) {
+        menu_tearoff(menu);
+    }
+
+    Grid_constructMenu(menu);
+
+    return grid_menu_item;
 }
 
-GtkMenuItem* create_misc_menu()
+ui::MenuItem create_misc_menu()
 {
-  // Misc menu
-  GtkMenuItem* misc_menu_item = new_sub_menu_item_with_mnemonic("M_isc");
-  GtkMenu* menu = GTK_MENU(gtk_menu_item_get_submenu(misc_menu_item));
-  if (g_Layout_enableDetachableMenus.m_value)
-    menu_tearoff (menu);
+    // Misc menu
+    auto misc_menu_item = new_sub_menu_item_with_mnemonic("M_isc");
+    auto menu = ui::Menu::from(gtk_menu_item_get_submenu(misc_menu_item));
+    if (g_Layout_enableDetachableMenus.m_value) {
+        menu_tearoff(menu);
+    }
 
 #if 0
-  create_menu_item_with_mnemonic(menu, "_Benchmark", FreeCaller<GlobalCamera_Benchmark>());
+    create_menu_item_with_mnemonic( menu, "_Benchmark", makeCallbackF(GlobalCamera_Benchmark) );
 #endif
-  gtk_container_add(GTK_CONTAINER(menu), GTK_WIDGET(create_colours_menu()));
+    menu.add(create_colours_menu());
 
-  create_menu_item_with_mnemonic(menu, "Find brush...", "FindBrush");
-  create_menu_item_with_mnemonic(menu, "Map Info...", "MapInfo");
-  // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=394
-//  create_menu_item_with_mnemonic(menu, "_Print XY View", FreeCaller<WXY_Print>());
-  create_menu_item_with_mnemonic(menu, "_Background select", FreeCaller<WXY_BackgroundSelect>());
-  return misc_menu_item;
+    create_menu_item_with_mnemonic(menu, "Find brush...", "FindBrush");
+    create_menu_item_with_mnemonic(menu, "Map Info...", "MapInfo");
+    // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=394
+//  create_menu_item_with_mnemonic(menu, "_Print XY View", FreeCaller<void(), WXY_Print>());
+    create_menu_item_with_mnemonic(menu, "_Background select", makeCallbackF(WXY_BackgroundSelect));
+    return misc_menu_item;
 }
 
-GtkMenuItem* create_entity_menu()
+ui::MenuItem create_entity_menu()
 {
-  // Brush menu
-  GtkMenuItem* entity_menu_item = new_sub_menu_item_with_mnemonic("E_ntity");
-  GtkMenu* menu = GTK_MENU(gtk_menu_item_get_submenu(entity_menu_item));
-  if (g_Layout_enableDetachableMenus.m_value)
-    menu_tearoff (menu);
+    // Brush menu
+    auto entity_menu_item = new_sub_menu_item_with_mnemonic("E_ntity");
+    auto menu = ui::Menu::from(gtk_menu_item_get_submenu(entity_menu_item));
+    if (g_Layout_enableDetachableMenus.m_value) {
+        menu_tearoff(menu);
+    }
 
-  Entity_constructMenu(menu);
+    Entity_constructMenu(menu);
 
-  return entity_menu_item;
+    return entity_menu_item;
 }
 
-GtkMenuItem* create_brush_menu()
+ui::MenuItem create_brush_menu()
 {
-  // Brush menu
-  GtkMenuItem* brush_menu_item = new_sub_menu_item_with_mnemonic("B_rush");
-  GtkMenu* menu = GTK_MENU(gtk_menu_item_get_submenu(brush_menu_item));
-  if (g_Layout_enableDetachableMenus.m_value)
-    menu_tearoff (menu);
+    // Brush menu
+    auto brush_menu_item = new_sub_menu_item_with_mnemonic("B_rush");
+    auto menu = ui::Menu::from(gtk_menu_item_get_submenu(brush_menu_item));
+    if (g_Layout_enableDetachableMenus.m_value) {
+        menu_tearoff(menu);
+    }
 
-  Brush_constructMenu(menu);
+    Brush_constructMenu(menu);
 
-  return brush_menu_item;
+    return brush_menu_item;
 }
 
-GtkMenuItem* create_patch_menu()
+ui::MenuItem create_patch_menu()
 {
-  // Curve menu
-  GtkMenuItem* patch_menu_item = new_sub_menu_item_with_mnemonic("_Curve");
-  GtkMenu* menu = GTK_MENU(gtk_menu_item_get_submenu(patch_menu_item));
-  if (g_Layout_enableDetachableMenus.m_value)
-  {
-    menu_tearoff(menu);
-  }
+    // Curve menu
+    auto patch_menu_item = new_sub_menu_item_with_mnemonic("_Curve");
+    auto menu = ui::Menu::from(gtk_menu_item_get_submenu(patch_menu_item));
+    if (g_Layout_enableDetachableMenus.m_value) {
+        menu_tearoff(menu);
+    }
 
-  Patch_constructMenu(menu);
+    Patch_constructMenu(menu);
 
-  return patch_menu_item;
+    return patch_menu_item;
 }
 
-GtkMenuItem* create_help_menu()
+ui::MenuItem create_help_menu()
 {
-  // Help menu
-  GtkMenuItem* help_menu_item = new_sub_menu_item_with_mnemonic("_Help");
-  GtkMenu* menu = GTK_MENU(gtk_menu_item_get_submenu(help_menu_item));
-  if (g_Layout_enableDetachableMenus.m_value)
-    menu_tearoff (menu);
+    // Help menu
+    auto help_menu_item = new_sub_menu_item_with_mnemonic("_Help");
+    auto menu = ui::Menu::from(gtk_menu_item_get_submenu(help_menu_item));
+    if (g_Layout_enableDetachableMenus.m_value) {
+        menu_tearoff(menu);
+    }
 
-  create_menu_item_with_mnemonic(menu, "Manual", "OpenManual");
+    create_menu_item_with_mnemonic(menu, "Manual", "OpenManual");
 
-  // this creates all the per-game drop downs for the game pack helps
-  // it will take care of hooking the Sys_OpenURL calls etc.
-  create_game_help_menu(menu);
+    // this creates all the per-game drop downs for the game pack helps
+    // it will take care of hooking the Sys_OpenURL calls etc.
+    create_game_help_menu(menu);
 
-  create_menu_item_with_mnemonic(menu, "Bug report", FreeCaller<OpenBugReportURL>());
-  create_menu_item_with_mnemonic(menu, "Shortcuts list", FreeCaller<DoCommandListDlg>());
-  create_menu_item_with_mnemonic(menu, "_About", FreeCaller<DoAbout>());
+    create_menu_item_with_mnemonic(menu, "Bug report", makeCallbackF(OpenBugReportURL));
+    create_menu_item_with_mnemonic(menu, "Shortcuts list", makeCallbackF(DoCommandListDlg));
+    create_menu_item_with_mnemonic(menu, "_About", makeCallbackF(DoAbout));
 
-  return help_menu_item;
+    return help_menu_item;
 }
 
-GtkMenuBar* create_main_menu(MainFrame::EViewStyle style)
+ui::MenuBar create_main_menu(MainFrame::EViewStyle style)
 {
-  GtkMenuBar* menu_bar = GTK_MENU_BAR(gtk_menu_bar_new());
-  gtk_widget_show(GTK_WIDGET(menu_bar));
+    auto menu_bar = ui::MenuBar::from(gtk_menu_bar_new());
+    menu_bar.show();
 
-  gtk_container_add(GTK_CONTAINER(menu_bar), GTK_WIDGET(create_file_menu()));
-  gtk_container_add(GTK_CONTAINER(menu_bar), GTK_WIDGET(create_edit_menu()));
-  gtk_container_add(GTK_CONTAINER(menu_bar), GTK_WIDGET(create_view_menu(style)));
-  gtk_container_add(GTK_CONTAINER(menu_bar), GTK_WIDGET(create_selection_menu()));
-  gtk_container_add(GTK_CONTAINER(menu_bar), GTK_WIDGET(create_bsp_menu()));
-  gtk_container_add(GTK_CONTAINER(menu_bar), GTK_WIDGET(create_grid_menu()));
-  gtk_container_add(GTK_CONTAINER(menu_bar), GTK_WIDGET(create_misc_menu()));
-  gtk_container_add(GTK_CONTAINER(menu_bar), GTK_WIDGET(create_entity_menu()));
-  gtk_container_add(GTK_CONTAINER(menu_bar), GTK_WIDGET(create_brush_menu()));
-  gtk_container_add(GTK_CONTAINER(menu_bar), GTK_WIDGET(create_patch_menu()));
-  gtk_container_add(GTK_CONTAINER(menu_bar), GTK_WIDGET(create_plugins_menu()));
-  gtk_container_add(GTK_CONTAINER(menu_bar), GTK_WIDGET(create_help_menu()));
+    menu_bar.add(create_file_menu());
+    menu_bar.add(create_edit_menu());
+    menu_bar.add(create_view_menu(style));
+    menu_bar.add(create_selection_menu());
+    menu_bar.add(create_bsp_menu());
+    menu_bar.add(create_grid_menu());
+    menu_bar.add(create_misc_menu());
+    menu_bar.add(create_entity_menu());
+    menu_bar.add(create_brush_menu());
+    menu_bar.add(create_patch_menu());
+    menu_bar.add(create_plugins_menu());
+    menu_bar.add(create_help_menu());
 
-  return menu_bar;
+    return menu_bar;
 }
 
 
 void PatchInspector_registerShortcuts()
 {
-  command_connect_accelerator("PatchInspector");
+    command_connect_accelerator("PatchInspector");
 }
 
 void Patch_registerShortcuts()
 {
-  command_connect_accelerator("InvertCurveTextureX");
-  command_connect_accelerator("InvertCurveTextureY");
-  command_connect_accelerator("IncPatchColumn");
-  command_connect_accelerator("IncPatchRow");
-  command_connect_accelerator("DecPatchColumn");
-  command_connect_accelerator("DecPatchRow");
-  command_connect_accelerator("NaturalizePatch");
-  //command_connect_accelerator("CapCurrentCurve");
+    command_connect_accelerator("InvertCurveTextureX");
+    command_connect_accelerator("InvertCurveTextureY");
+    command_connect_accelerator("PatchInsertInsertColumn");
+    command_connect_accelerator("PatchInsertInsertRow");
+    command_connect_accelerator("PatchDeleteLastColumn");
+    command_connect_accelerator("PatchDeleteLastRow");
+    command_connect_accelerator("NaturalizePatch");
+    //command_connect_accelerator("CapCurrentCurve");
 }
 
 void Manipulators_registerShortcuts()
 {
-  toggle_add_accelerator("MouseRotate");
-  toggle_add_accelerator("MouseTranslate");
-  toggle_add_accelerator("MouseScale");
-  toggle_add_accelerator("MouseDrag");
-  toggle_add_accelerator("ToggleClipper");
+    toggle_add_accelerator("MouseRotate");
+    toggle_add_accelerator("MouseTranslate");
+    toggle_add_accelerator("MouseScale");
+    toggle_add_accelerator("MouseDrag");
+    toggle_add_accelerator("ToggleClipper");
 }
 
 void TexdefNudge_registerShortcuts()
 {
-  command_connect_accelerator("TexRotateClock");
-  command_connect_accelerator("TexRotateCounter");
-  command_connect_accelerator("TexScaleUp");
-  command_connect_accelerator("TexScaleDown");
-  command_connect_accelerator("TexScaleLeft");
-  command_connect_accelerator("TexScaleRight");
-  command_connect_accelerator("TexShiftUp");
-  command_connect_accelerator("TexShiftDown");
-  command_connect_accelerator("TexShiftLeft");
-  command_connect_accelerator("TexShiftRight");
+    command_connect_accelerator("TexRotateClock");
+    command_connect_accelerator("TexRotateCounter");
+    command_connect_accelerator("TexScaleUp");
+    command_connect_accelerator("TexScaleDown");
+    command_connect_accelerator("TexScaleLeft");
+    command_connect_accelerator("TexScaleRight");
+    command_connect_accelerator("TexShiftUp");
+    command_connect_accelerator("TexShiftDown");
+    command_connect_accelerator("TexShiftLeft");
+    command_connect_accelerator("TexShiftRight");
 }
 
 void SelectNudge_registerShortcuts()
 {
-  command_connect_accelerator("MoveSelectionDOWN");
-  command_connect_accelerator("MoveSelectionUP");
-  //command_connect_accelerator("SelectNudgeLeft");
-  //command_connect_accelerator("SelectNudgeRight");
-  //command_connect_accelerator("SelectNudgeUp");
-  //command_connect_accelerator("SelectNudgeDown");
+    command_connect_accelerator("MoveSelectionDOWN");
+    command_connect_accelerator("MoveSelectionUP");
+    //command_connect_accelerator("SelectNudgeLeft");
+    //command_connect_accelerator("SelectNudgeRight");
+    //command_connect_accelerator("SelectNudgeUp");
+    //command_connect_accelerator("SelectNudgeDown");
 }
 
 void SnapToGrid_registerShortcuts()
 {
-  command_connect_accelerator("SnapToGrid");
+    command_connect_accelerator("SnapToGrid");
 }
 
 void SelectByType_registerShortcuts()
 {
-  command_connect_accelerator("SelectAllOfType");
+    command_connect_accelerator("SelectAllOfType");
 }
 
 void SurfaceInspector_registerShortcuts()
 {
-  command_connect_accelerator("FitTexture");
+    command_connect_accelerator("FitTexture");
 }
 
 
 void register_shortcuts()
 {
-  PatchInspector_registerShortcuts();
-  Patch_registerShortcuts();
-  Grid_registerShortcuts();
-  XYWnd_registerShortcuts();
-  CamWnd_registerShortcuts();
-  Manipulators_registerShortcuts();
-  SurfaceInspector_registerShortcuts();
-  TexdefNudge_registerShortcuts();
-  SelectNudge_registerShortcuts();
-  SnapToGrid_registerShortcuts();
-  SelectByType_registerShortcuts();
+    PatchInspector_registerShortcuts();
+    Patch_registerShortcuts();
+    Grid_registerShortcuts();
+    XYWnd_registerShortcuts();
+    CamWnd_registerShortcuts();
+    Manipulators_registerShortcuts();
+    SurfaceInspector_registerShortcuts();
+    TexdefNudge_registerShortcuts();
+    SelectNudge_registerShortcuts();
+    SnapToGrid_registerShortcuts();
+    SelectByType_registerShortcuts();
 }
 
-void File_constructToolbar(GtkToolbar* toolbar)
+void File_constructToolbar(ui::Toolbar toolbar)
 {
-  toolbar_append_button(toolbar, "Open an existing map (CTRL + O)", "file_open.bmp", "OpenMap");
-  toolbar_append_button(toolbar, "Save the active map (CTRL + S)", "file_save.bmp", "SaveMap");
+    toolbar_append_button(toolbar, "Open an existing map (CTRL + O)", "file_open.png", "OpenMap");
+    toolbar_append_button(toolbar, "Save the active map (CTRL + S)", "file_save.png", "SaveMap");
 }
 
-void UndoRedo_constructToolbar(GtkToolbar* toolbar)
+void UndoRedo_constructToolbar(ui::Toolbar toolbar)
 {
-  toolbar_append_button(toolbar, "Undo (CTRL + Z)", "undo.bmp", "Undo");
-  toolbar_append_button(toolbar, "Redo (CTRL + Y)", "redo.bmp", "Redo");
+    toolbar_append_button(toolbar, "Undo (CTRL + Z)", "undo.png", "Undo");
+    toolbar_append_button(toolbar, "Redo (CTRL + Y)", "redo.png", "Redo");
 }
 
-void RotateFlip_constructToolbar(GtkToolbar* toolbar)
+void RotateFlip_constructToolbar(ui::Toolbar toolbar)
 {
-  toolbar_append_button(toolbar, "x-axis Flip", "brush_flipx.bmp", "MirrorSelectionX");
-  toolbar_append_button(toolbar, "x-axis Rotate", "brush_rotatex.bmp", "RotateSelectionX");
-  toolbar_append_button(toolbar, "y-axis Flip", "brush_flipy.bmp", "MirrorSelectionY");
-  toolbar_append_button(toolbar, "y-axis Rotate", "brush_rotatey.bmp", "RotateSelectionY");
-  toolbar_append_button(toolbar, "z-axis Flip", "brush_flipz.bmp", "MirrorSelectionZ");
-  toolbar_append_button(toolbar, "z-axis Rotate", "brush_rotatez.bmp", "RotateSelectionZ");
+    toolbar_append_button(toolbar, "x-axis Flip", "brush_flipx.png", "MirrorSelectionX");
+    toolbar_append_button(toolbar, "x-axis Rotate", "brush_rotatex.png", "RotateSelectionX");
+    toolbar_append_button(toolbar, "y-axis Flip", "brush_flipy.png", "MirrorSelectionY");
+    toolbar_append_button(toolbar, "y-axis Rotate", "brush_rotatey.png", "RotateSelectionY");
+    toolbar_append_button(toolbar, "z-axis Flip", "brush_flipz.png", "MirrorSelectionZ");
+    toolbar_append_button(toolbar, "z-axis Rotate", "brush_rotatez.png", "RotateSelectionZ");
 }
 
-void Select_constructToolbar(GtkToolbar* toolbar)
+void Select_constructToolbar(ui::Toolbar toolbar)
 {
-  toolbar_append_button(toolbar, "Select touching", "selection_selecttouching.bmp", "SelectTouching");
-  toolbar_append_button(toolbar, "Select inside", "selection_selectinside.bmp", "SelectInside");
+    toolbar_append_button(toolbar, "Select touching", "selection_selecttouching.png", "SelectTouching");
+    toolbar_append_button(toolbar, "Select inside", "selection_selectinside.png", "SelectInside");
 }
 
-void CSG_constructToolbar(GtkToolbar* toolbar)
+void CSG_constructToolbar(ui::Toolbar toolbar)
 {
-  toolbar_append_button(toolbar, "CSG Subtract (SHIFT + U)", "selection_csgsubtract.bmp", "CSGSubtract");
-  toolbar_append_button(toolbar, "CSG Merge (CTRL + U)", "selection_csgmerge.bmp", "CSGMerge");
-  toolbar_append_button(toolbar, "Hollow", "selection_makehollow.bmp", "CSGHollow");
+    toolbar_append_button(toolbar, "CSG Subtract (SHIFT + U)", "selection_csgsubtract.png", "CSGSubtract");
+    toolbar_append_button(toolbar, "CSG Merge (CTRL + U)", "selection_csgmerge.png", "CSGMerge");
+    toolbar_append_button(toolbar, "Hollow", "selection_makehollow.png", "CSGHollow");
 }
 
-void ComponentModes_constructToolbar(GtkToolbar* toolbar)
+void ComponentModes_constructToolbar(ui::Toolbar toolbar)
 {
-  toolbar_append_toggle_button(toolbar, "Select Vertices (V)", "modify_vertices.bmp", "DragVertices");
-  toolbar_append_toggle_button(toolbar, "Select Edges (E)", "modify_edges.bmp", "DragEdges");
-  toolbar_append_toggle_button(toolbar, "Select Faces (F)", "modify_faces.bmp", "DragFaces");
+    toolbar_append_toggle_button(toolbar, "Select Vertices (V)", "modify_vertices.png", "DragVertices");
+    toolbar_append_toggle_button(toolbar, "Select Edges (E)", "modify_edges.png", "DragEdges");
+    toolbar_append_toggle_button(toolbar, "Select Faces (F)", "modify_faces.png", "DragFaces");
 }
 
-void Clipper_constructToolbar(GtkToolbar* toolbar)
+void Clipper_constructToolbar(ui::Toolbar toolbar)
 {
 
-  toolbar_append_toggle_button(toolbar, "Clipper (X)", "view_clipper.bmp", "ToggleClipper");
+    toolbar_append_toggle_button(toolbar, "Clipper (X)", "view_clipper.png", "ToggleClipper");
 }
 
-void XYWnd_constructToolbar(GtkToolbar* toolbar)
+void XYWnd_constructToolbar(ui::Toolbar toolbar)
 {
-  toolbar_append_button(toolbar, "Change views", "view_change.bmp", "NextView");
+    toolbar_append_button(toolbar, "Change views", "view_change.png", "NextView");
 }
 
-void Manipulators_constructToolbar(GtkToolbar* toolbar)
+void Manipulators_constructToolbar(ui::Toolbar toolbar)
 {
-  toolbar_append_toggle_button(toolbar, "Translate (W)", "select_mousetranslate.bmp", "MouseTranslate");
-  toolbar_append_toggle_button(toolbar, "Rotate (R)", "select_mouserotate.bmp", "MouseRotate");
-  toolbar_append_toggle_button(toolbar, "Scale", "select_mousescale.bmp", "MouseScale");
-  toolbar_append_toggle_button(toolbar, "Resize (Q)", "select_mouseresize.bmp", "MouseDrag");
+    toolbar_append_toggle_button(toolbar, "Translate (W)", "select_mousetranslate.png", "MouseTranslate");
+    toolbar_append_toggle_button(toolbar, "Rotate (R)", "select_mouserotate.png", "MouseRotate");
+    toolbar_append_toggle_button(toolbar, "Scale", "select_mousescale.png", "MouseScale");
+    toolbar_append_toggle_button(toolbar, "Resize (Q)", "select_mouseresize.png", "MouseDrag");
 
-  Clipper_constructToolbar(toolbar);
+    Clipper_constructToolbar(toolbar);
 }
 
-GtkToolbar* create_main_toolbar(MainFrame::EViewStyle style)
+ui::Toolbar create_main_toolbar(MainFrame::EViewStyle style)
 {
-  GtkToolbar* toolbar = GTK_TOOLBAR(gtk_toolbar_new());
-  gtk_toolbar_set_orientation(toolbar, GTK_ORIENTATION_HORIZONTAL);
-  gtk_toolbar_set_style(toolbar, GTK_TOOLBAR_ICONS);
+    auto toolbar = ui::Toolbar::from(gtk_toolbar_new());
+    gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_HORIZONTAL);
+    gtk_toolbar_set_style(toolbar, GTK_TOOLBAR_ICONS);
 
-  gtk_widget_show(GTK_WIDGET(toolbar));
+    toolbar.show();
 
-  File_constructToolbar(toolbar);
+    auto space = [&]() {
+        auto btn = ui::ToolItem::from(gtk_separator_tool_item_new());
+        btn.show();
+        toolbar.add(btn);
+    };
 
-  gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+    File_constructToolbar(toolbar);
 
-  UndoRedo_constructToolbar(toolbar);
+    space();
 
-  gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+    UndoRedo_constructToolbar(toolbar);
 
-  RotateFlip_constructToolbar(toolbar);
+    space();
 
-  gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+    RotateFlip_constructToolbar(toolbar);
 
-  Select_constructToolbar(toolbar);
+    space();
 
-  gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+    Select_constructToolbar(toolbar);
 
-  CSG_constructToolbar(toolbar);
+    space();
 
-  gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+    CSG_constructToolbar(toolbar);
 
-  ComponentModes_constructToolbar(toolbar);
+    space();
 
-  if(style == MainFrame::eRegular || style == MainFrame::eRegularLeft || style == MainFrame::eFloating)
-  {
-    gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+    ComponentModes_constructToolbar(toolbar);
 
-    XYWnd_constructToolbar(toolbar);
-  }
+    if (style == MainFrame::eRegular || style == MainFrame::eRegularLeft || style == MainFrame::eFloating) {
+        space();
+
+        XYWnd_constructToolbar(toolbar);
+    }
 
-  gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+    space();
 
-  CamWnd_constructToolbar(toolbar);
+    CamWnd_constructToolbar(toolbar);
 
-  gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+    space();
 
-  Manipulators_constructToolbar(toolbar);
+    Manipulators_constructToolbar(toolbar);
 
-  if (g_Layout_enablePatchToolbar.m_value)
-  {
-    gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+    if (g_Layout_enablePatchToolbar.m_value) {
+        space();
 
-    Patch_constructToolbar(toolbar);
-  }
+        Patch_constructToolbar(toolbar);
+    }
 
-  gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+    space();
 
-  toolbar_append_toggle_button(toolbar, "Texture Lock (SHIFT +T)", "texture_lock.bmp", "TogTexLock");
+    toolbar_append_toggle_button(toolbar, "Texture Lock (SHIFT +T)", "texture_lock.png", "TogTexLock");
 
-  gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+    space();
 
-  GtkButton* g_view_entities_button = toolbar_append_button(toolbar, "Entities (N)", "entities.bmp", "ToggleEntityInspector");
-  GtkButton* g_view_console_button = toolbar_append_button(toolbar, "Console (O)", "console.bmp", "ToggleConsole");
-  GtkButton* g_view_textures_button = toolbar_append_button(toolbar, "Texture Browser (T)", "texture_browser.bmp", "ToggleTextures");
-  // TODO: call light inspector
-  //GtkButton* g_view_lightinspector_button = toolbar_append_button(toolbar, "Light Inspector", "lightinspector.bmp", "ToggleLightInspector");
+    /*auto g_view_entities_button =*/ toolbar_append_button(toolbar, "Entities (N)", "entities.png",
+                                                            "ToggleEntityInspector");
+    auto g_view_console_button = toolbar_append_button(toolbar, "Console (O)", "console.png", "ToggleConsole");
+    auto g_view_textures_button = toolbar_append_button(toolbar, "Texture Browser (T)", "texture_browser.png",
+                                                        "ToggleTextures");
+    // TODO: call light inspector
+    //GtkButton* g_view_lightinspector_button = toolbar_append_button(toolbar, "Light Inspector", "lightinspector.png", "ToggleLightInspector");
 
-  gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
-  GtkButton* g_refresh_models_button = toolbar_append_button(toolbar, "Refresh Models", "refresh_models.bmp", "RefreshReferences");
+    space();
+    /*auto g_refresh_models_button =*/ toolbar_append_button(toolbar, "Refresh Models", "refresh_models.png",
+                                                             "RefreshReferences");
 
 
-  // disable the console and texture button in the regular layouts
-  if(style == MainFrame::eRegular || style == MainFrame::eRegularLeft)
-  {
-    gtk_widget_set_sensitive(GTK_WIDGET(g_view_console_button), FALSE);
-       gtk_widget_set_sensitive(GTK_WIDGET(g_view_textures_button), FALSE);
-  }
+    // disable the console and texture button in the regular layouts
+    if (style == MainFrame::eRegular || style == MainFrame::eRegularLeft) {
+        gtk_widget_set_sensitive(g_view_console_button, FALSE);
+        gtk_widget_set_sensitive(g_view_textures_button, FALSE);
+    }
 
-  return toolbar;
+    return toolbar;
 }
 
-GtkWidget* create_main_statusbar(GtkWidget *pStatusLabel[c_count_status])
+ui::Widget create_main_statusbar(ui::Widget pStatusLabel[c_count_status])
 {
-  GtkTable* table = GTK_TABLE(gtk_table_new(1, c_count_status, FALSE));
-  gtk_widget_show(GTK_WIDGET(table));
+    auto table = ui::Table(1, c_count_status, FALSE);
+    table.show();
 
-  {
-    GtkLabel* label = GTK_LABEL(gtk_label_new ("Label"));
-    gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-    gtk_misc_set_padding(GTK_MISC(label), 4, 2);
-    gtk_widget_show(GTK_WIDGET(label));
-    gtk_table_attach_defaults(table, GTK_WIDGET(label), 0, 1, 0, 1);
-    pStatusLabel[c_command_status] = GTK_WIDGET(label);
-  }
-
-  for(int i = 1; i < c_count_status; ++i)
-  {
-    GtkFrame* frame = GTK_FRAME(gtk_frame_new(0));
-    gtk_widget_show(GTK_WIDGET(frame));
-    gtk_table_attach_defaults(table, GTK_WIDGET(frame), i, i + 1, 0, 1);
-    gtk_frame_set_shadow_type(frame, GTK_SHADOW_IN);
+    {
+        auto label = ui::Label("Label");
+        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+        gtk_misc_set_padding(GTK_MISC(label), 4, 2);
+        label.show();
+        table.attach(label, {0, 1, 0, 1});
+        pStatusLabel[c_command_status] = ui::Widget(label);
+    }
 
-    GtkLabel* label = GTK_LABEL(gtk_label_new ("Label"));
-       gtk_label_set_ellipsize( label, PANGO_ELLIPSIZE_END);
-    gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-    gtk_misc_set_padding(GTK_MISC(label), 4, 2);
-    gtk_widget_show(GTK_WIDGET(label));
-    gtk_container_add(GTK_CONTAINER(frame), GTK_WIDGET(label));
-    pStatusLabel[i] = GTK_WIDGET(label);
-  }
+    for (unsigned int i = 1; (int) i < c_count_status; ++i) {
+        auto frame = ui::Frame();
+        frame.show();
+        table.attach(frame, {i, i + 1, 0, 1});
+        gtk_frame_set_shadow_type(frame, GTK_SHADOW_IN);
+
+        auto label = ui::Label("Label");
+        gtk_label_set_ellipsize(label, PANGO_ELLIPSIZE_END);
+        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+        gtk_misc_set_padding(GTK_MISC(label), 4, 2);
+        label.show();
+        frame.add(label);
+        pStatusLabel[i] = ui::Widget(label);
+    }
 
-  return GTK_WIDGET(table);
+    return ui::Widget(table);
 }
 
 #if 0
 
 
-WidgetFocusPrinter g_mainframeWidgetFocusPrinter("mainframe");
+                                                                                                                        WidgetFocusPrinter g_mainframeWidgetFocusPrinter( "mainframe" );
 
 class WindowFocusPrinter
 {
-  const char* m_name;
+const char* m_name;
 
-  static gboolean frame_event(GtkWidget *widget, GdkEvent* event, WindowFocusPrinter* self)
-  {
-    globalOutputStream() << self->m_name << " frame_event\n";
-    return FALSE;
-  }
-  static gboolean keys_changed(GtkWidget *widget, WindowFocusPrinter* self)
-  {
-    globalOutputStream() << self->m_name << " keys_changed\n";
-    return FALSE;
-  }
-  static gboolean notify(GtkWindow* window, gpointer dummy, WindowFocusPrinter* self)
-  {
-    if(gtk_window_is_active(window))
-    {
-      globalOutputStream() << self->m_name << " takes toplevel focus\n";
-    }
-    else
-    {
-      globalOutputStream() << self->m_name << " loses toplevel focus\n";
-    }
-    return FALSE;
-  }
+static gboolean frame_event( ui::Widget widget, GdkEvent* event, WindowFocusPrinter* self ){
+       globalOutputStream() << self->m_name << " frame_event\n";
+       return FALSE;
+}
+static gboolean keys_changed( ui::Widget widget, WindowFocusPrinter* self ){
+       globalOutputStream() << self->m_name << " keys_changed\n";
+       return FALSE;
+}
+static gboolean notify( ui::Window window, gpointer dummy, WindowFocusPrinter* self ){
+       if ( gtk_window_is_active( window ) ) {
+               globalOutputStream() << self->m_name << " takes toplevel focus\n";
+       }
+       else
+       {
+               globalOutputStream() << self->m_name << " loses toplevel focus\n";
+       }
+       return FALSE;
+}
 public:
-  WindowFocusPrinter(const char* name) : m_name(name)
-  {
-  }
-  void connect(GtkWindow* toplevel_window)
-  {
-    g_signal_connect(G_OBJECT(toplevel_window), "notify::has_toplevel_focus", G_CALLBACK(notify), this);
-    g_signal_connect(G_OBJECT(toplevel_window), "notify::is_active", G_CALLBACK(notify), this);
-    g_signal_connect(G_OBJECT(toplevel_window), "keys_changed", G_CALLBACK(keys_changed), this);
-    g_signal_connect(G_OBJECT(toplevel_window), "frame_event", G_CALLBACK(frame_event), this);
-  }
+WindowFocusPrinter( const char* name ) : m_name( name ){
+}
+void connect( ui::Window toplevel_window ){
+       toplevel_window.connect( "notify::has_toplevel_focus", G_CALLBACK( notify ), this );
+       toplevel_window.connect( "notify::is_active", G_CALLBACK( notify ), this );
+       toplevel_window.connect( "keys_changed", G_CALLBACK( keys_changed ), this );
+       toplevel_window.connect( "frame_event", G_CALLBACK( frame_event ), this );
+}
 };
 
-WindowFocusPrinter g_mainframeFocusPrinter("mainframe");
+WindowFocusPrinter g_mainframeFocusPrinter( "mainframe" );
 
 #endif
 
-class MainWindowActive
-{
-  static gboolean notify(GtkWindow* window, gpointer dummy, MainWindowActive* self)
-  {
-    if(g_wait.m_window != 0 && gtk_window_is_active(window) && !GTK_WIDGET_VISIBLE(g_wait.m_window))
+class MainWindowActive {
+    static gboolean notify(ui::Window window, gpointer dummy, MainWindowActive *self)
     {
-      gtk_widget_show(GTK_WIDGET(g_wait.m_window));
+        if (g_wait.m_window && gtk_window_is_active(window) && !g_wait.m_window.visible()) {
+            g_wait.m_window.show();
+        }
+
+        return FALSE;
     }
 
-    return FALSE;
-  }
 public:
-  void connect(GtkWindow* toplevel_window)
-  {
-    g_signal_connect(G_OBJECT(toplevel_window), "notify::is-active", G_CALLBACK(notify), this);
-  }
+    void connect(ui::Window toplevel_window)
+    {
+        toplevel_window.connect("notify::is-active", G_CALLBACK(notify), this);
+    }
 };
 
 MainWindowActive g_MainWindowActive;
 
-SignalHandlerId XYWindowDestroyed_connect(const SignalHandlerhandler)
+SignalHandlerId XYWindowDestroyed_connect(const SignalHandler &handler)
 {
-  return g_pParentWnd->GetXYWnd()->onDestroyed.connectFirst(handler);
+    return g_pParentWnd->GetXYWnd()->onDestroyed.connectFirst(handler);
 }
 
 void XYWindowDestroyed_disconnect(SignalHandlerId id)
 {
-  g_pParentWnd->GetXYWnd()->onDestroyed.disconnect(id);
+    g_pParentWnd->GetXYWnd()->onDestroyed.disconnect(id);
 }
 
-MouseEventHandlerId XYWindowMouseDown_connect(const MouseEventHandlerhandler)
+MouseEventHandlerId XYWindowMouseDown_connect(const MouseEventHandler &handler)
 {
-  return g_pParentWnd->GetXYWnd()->onMouseDown.connectFirst(handler);
+    return g_pParentWnd->GetXYWnd()->onMouseDown.connectFirst(handler);
 }
 
 void XYWindowMouseDown_disconnect(MouseEventHandlerId id)
 {
-  g_pParentWnd->GetXYWnd()->onMouseDown.disconnect(id);
+    g_pParentWnd->GetXYWnd()->onMouseDown.disconnect(id);
 }
 
 // =============================================================================
 // MainFrame class
 
-MainFrameg_pParentWnd = 0;
+MainFrame *g_pParentWnd = 0;
 
-GtkWindow* MainFrame_getWindow()
+ui::Window MainFrame_getWindow()
 {
-  if(g_pParentWnd == 0)
-  {
-    return 0;
-  }
-  return g_pParentWnd->m_window;
+    return g_pParentWnd ? g_pParentWnd->m_window : ui::Window{ui::null};
 }
 
-std::vector<GtkWidget*> g_floating_windows;
+std::vector<ui::Widget> g_floating_windows;
 
-MainFrame::MainFrame() : m_window(0), m_idleRedrawStatusText(RedrawStatusTextCaller(*this))
+MainFrame::MainFrame() : m_idleRedrawStatusText(RedrawStatusTextCaller(*this))
 {
-  m_pXYWnd = 0;
-  m_pCamWnd = 0;
-  m_pZWnd = 0;
-  m_pYZWnd = 0;
-  m_pXZWnd = 0;
-  m_pActiveXY = 0;
+    m_pXYWnd = 0;
+    m_pCamWnd = 0;
+    m_pZWnd = 0;
+    m_pYZWnd = 0;
+    m_pXZWnd = 0;
+    m_pActiveXY = 0;
 
-  for (int n = 0;n < c_count_status;n++)
-  {
-    m_pStatusLabel[n] = 0;
-  }
+    for (auto &n : m_pStatusLabel) {
+        n = NULL;
+    }
 
-  m_bSleeping = false;
+    m_bSleeping = false;
 
-  Create();
+    Create();
 }
 
 MainFrame::~MainFrame()
 {
-  SaveWindowInfo();
+    SaveWindowInfo();
 
-  gtk_widget_hide(GTK_WIDGET(m_window));
+    m_window.hide();
 
-  Shutdown();
+    Shutdown();
 
-  for(std::vector<GtkWidget*>::iterator i = g_floating_windows.begin(); i != g_floating_windows.end(); ++i)
-  {
-    gtk_widget_destroy(*i);
-  }
+    for (std::vector<ui::Widget>::iterator i = g_floating_windows.begin(); i != g_floating_windows.end(); ++i) {
+        i->destroy();
+    }
 
-  gtk_widget_destroy(GTK_WIDGET(m_window));
+    m_window.destroy();
 }
 
-void MainFrame::SetActiveXY(XYWndp)
+void MainFrame::SetActiveXY(XYWnd *p)
 {
-  if (m_pActiveXY)
-    m_pActiveXY->SetActive(false);
+    if (m_pActiveXY) {
+        m_pActiveXY->SetActive(false);
+    }
 
-  m_pActiveXY = p;
+    m_pActiveXY = p;
 
-  if (m_pActiveXY)
-    m_pActiveXY->SetActive(true);
+    if (m_pActiveXY) {
+        m_pActiveXY->SetActive(true);
+    }
 
 }
 
 void MainFrame::ReleaseContexts()
 {
 #if 0
-  if (m_pXYWnd)
-    m_pXYWnd->DestroyContext();
-  if (m_pYZWnd)
-    m_pYZWnd->DestroyContext();
-  if (m_pXZWnd)
-    m_pXZWnd->DestroyContext();
-  if (m_pCamWnd)
-    m_pCamWnd->DestroyContext();
-  if (m_pTexWnd)
-    m_pTexWnd->DestroyContext();
-  if (m_pZWnd)
-    m_pZWnd->DestroyContext();
+                                                                                                                            if ( m_pXYWnd ) {
+               m_pXYWnd->DestroyContext();
+       }
+       if ( m_pYZWnd ) {
+               m_pYZWnd->DestroyContext();
+       }
+       if ( m_pXZWnd ) {
+               m_pXZWnd->DestroyContext();
+       }
+       if ( m_pCamWnd ) {
+               m_pCamWnd->DestroyContext();
+       }
+       if ( m_pTexWnd ) {
+               m_pTexWnd->DestroyContext();
+       }
+       if ( m_pZWnd ) {
+               m_pZWnd->DestroyContext();
+       }
 #endif
 }
 
 void MainFrame::CreateContexts()
 {
 #if 0
-  if (m_pCamWnd)
-    m_pCamWnd->CreateContext();
-  if (m_pXYWnd)
-    m_pXYWnd->CreateContext();
-  if (m_pYZWnd)
-    m_pYZWnd->CreateContext();
-  if (m_pXZWnd)
-    m_pXZWnd->CreateContext();
-  if (m_pTexWnd)
-    m_pTexWnd->CreateContext();
-  if (m_pZWnd)
-    m_pZWnd->CreateContext();
+                                                                                                                            if ( m_pCamWnd ) {
+               m_pCamWnd->CreateContext();
+       }
+       if ( m_pXYWnd ) {
+               m_pXYWnd->CreateContext();
+       }
+       if ( m_pYZWnd ) {
+               m_pYZWnd->CreateContext();
+       }
+       if ( m_pXZWnd ) {
+               m_pXZWnd->CreateContext();
+       }
+       if ( m_pTexWnd ) {
+               m_pTexWnd->CreateContext();
+       }
+       if ( m_pZWnd ) {
+               m_pZWnd->CreateContext();
+       }
 #endif
 }
 
-#ifdef _DEBUG
+#if GDEF_DEBUG
 //#define DBG_SLEEP
 #endif
 
 void MainFrame::OnSleep()
 {
 #if 0
-  m_bSleeping ^= 1;
-  if (m_bSleeping)
-  {
-    // useful when trying to debug crashes in the sleep code
-    globalOutputStream() << "Going into sleep mode..\n";
-
-    globalOutputStream() << "Dispatching sleep msg...";
-    DispatchRadiantMsg (RADIANT_SLEEP);
-    globalOutputStream() << "Done.\n";
-
-    gtk_window_iconify(m_window);
-    GlobalSelectionSystem().setSelectedAll(false);
-
-    GlobalShaderCache().unrealise();
-    Shaders_Free();
-    GlobalOpenGL_debugAssertNoErrors();
-    ScreenUpdates_Disable();
-
-    // release contexts
-    globalOutputStream() << "Releasing contexts...";
-    ReleaseContexts();
-    globalOutputStream() << "Done.\n";
-  }
-  else
-  {
-    globalOutputStream() << "Waking up\n";
-
-    gtk_window_deiconify(m_window);
-
-    // create contexts
-    globalOutputStream() << "Creating contexts...";
-    CreateContexts();
-    globalOutputStream() << "Done.\n";
-
-    globalOutputStream() << "Making current on camera...";
-    m_pCamWnd->MakeCurrent();
-    globalOutputStream() << "Done.\n";
-
-    globalOutputStream() << "Reloading shaders...";
-    Shaders_Load();
-    GlobalShaderCache().realise();
-    globalOutputStream() << "Done.\n";
-
-    ScreenUpdates_Enable();
-
-    globalOutputStream() << "Dispatching wake msg...";
-    DispatchRadiantMsg (RADIANT_WAKEUP);
-    globalOutputStream() << "Done\n";
-  }
+                                                                                                                            m_bSleeping ^= 1;
+       if ( m_bSleeping ) {
+               // useful when trying to debug crashes in the sleep code
+               globalOutputStream() << "Going into sleep mode..\n";
+
+               globalOutputStream() << "Dispatching sleep msg...";
+               DispatchRadiantMsg( RADIANT_SLEEP );
+               globalOutputStream() << "Done.\n";
+
+               gtk_window_iconify( m_window );
+               GlobalSelectionSystem().setSelectedAll( false );
+
+               GlobalShaderCache().unrealise();
+               Shaders_Free();
+               GlobalOpenGL_debugAssertNoErrors();
+               ScreenUpdates_Disable();
+
+               // release contexts
+               globalOutputStream() << "Releasing contexts...";
+               ReleaseContexts();
+               globalOutputStream() << "Done.\n";
+       }
+       else
+       {
+               globalOutputStream() << "Waking up\n";
+
+               gtk_window_deiconify( m_window );
+
+               // create contexts
+               globalOutputStream() << "Creating contexts...";
+               CreateContexts();
+               globalOutputStream() << "Done.\n";
+
+               globalOutputStream() << "Making current on camera...";
+               m_pCamWnd->MakeCurrent();
+               globalOutputStream() << "Done.\n";
+
+               globalOutputStream() << "Reloading shaders...";
+               Shaders_Load();
+               GlobalShaderCache().realise();
+               globalOutputStream() << "Done.\n";
+
+               ScreenUpdates_Enable();
+
+               globalOutputStream() << "Dispatching wake msg...";
+               DispatchRadiantMsg( RADIANT_WAKEUP );
+               globalOutputStream() << "Done\n";
+       }
 #endif
 }
 
 
-GtkWindow* create_splash()
+ui::Window create_splash()
 {
-  GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
-  gtk_window_set_decorated(window, FALSE);
-  gtk_window_set_resizable(window, FALSE);
-  gtk_window_set_modal(window, TRUE);
-  gtk_window_set_default_size(window, -1, -1);
-  gtk_window_set_position(window, GTK_WIN_POS_CENTER);
-  gtk_container_set_border_width(GTK_CONTAINER(window), 0);
+    auto window = ui::Window(ui::window_type::TOP);
+    gtk_window_set_decorated(window, false);
+    gtk_window_set_resizable(window, false);
+    gtk_window_set_modal(window, true);
+    gtk_window_set_default_size(window, -1, -1);
+    gtk_window_set_position(window, GTK_WIN_POS_CENTER);
+    gtk_container_set_border_width(window, 0);
 
-  GtkImage* image = new_local_image("splash.bmp");
-  gtk_widget_show(GTK_WIDGET(image));
-  gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(image));
+    auto image = new_local_image("splash.png");
+    image.show();
+    window.add(image);
 
-  gtk_widget_set_size_request(GTK_WIDGET(window), -1, -1);
-  gtk_widget_show(GTK_WIDGET(window));
+    window.dimensions(-1, -1);
+    window.show();
 
-  return window;
+    return window;
 }
 
-static GtkWindow *splash_screen = 0;
+static ui::Window splash_screen{ui::null};
 
 void show_splash()
 {
-  splash_screen = create_splash();
+    splash_screen = create_splash();
 
-  process_gui();
+    ui::process();
 }
 
 void hide_splash()
 {
-  gtk_widget_destroy(GTK_WIDGET(splash_screen));
+    splash_screen.destroy();
 }
 
 WindowPositionTracker g_posCamWnd;
@@ -2960,505 +3039,482 @@ WindowPositionTracker g_posXYWnd;
 WindowPositionTracker g_posXZWnd;
 WindowPositionTracker g_posYZWnd;
 
-static gint mainframe_delete (GtkWidget *widget, GdkEvent *event, gpointer data)
+static gint mainframe_delete(ui::Widget widget, GdkEvent *event, gpointer data)
 {
-  if(ConfirmModified("Exit Radiant"))
-  {
-    gtk_main_quit();
-  }
+    if (ConfirmModified("Exit Radiant")) {
+        gtk_main_quit();
+    }
 
-  return TRUE;
+    return TRUE;
 }
 
 void MainFrame::Create()
 {
-  GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
+    ui::Window window = ui::Window(ui::window_type::TOP);
 
-  GlobalWindowObservers_connectTopLevel(window);
+    GlobalWindowObservers_connectTopLevel(window);
 
-  gtk_window_set_transient_for(splash_screen, window);
+    gtk_window_set_transient_for(splash_screen, window);
 
-#if !defined(WIN32)
-  {
-    GdkPixbuf* pixbuf = pixbuf_new_from_file_with_mask("bitmaps/icon.bmp");
-    if(pixbuf != 0)
+#if !GDEF_OS_WINDOWS
     {
-      gtk_window_set_icon(window, pixbuf);
-      gdk_pixbuf_unref(pixbuf);
+        GdkPixbuf *pixbuf = pixbuf_new_from_file_with_mask("bitmaps/icon.png");
+        if (pixbuf != 0) {
+            gtk_window_set_icon(window, pixbuf);
+            g_object_unref(pixbuf);
+        }
     }
-  }
 #endif
 
-  gtk_widget_add_events(GTK_WIDGET(window), GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK);
-  g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(mainframe_delete), this);
+    gtk_widget_add_events(window, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK);
+    window.connect("delete_event", G_CALLBACK(mainframe_delete), this);
 
-  m_position_tracker.connect(window);
+    m_position_tracker.connect(window);
 
 #if 0
-  g_mainframeWidgetFocusPrinter.connect(window);
-  g_mainframeFocusPrinter.connect(window);
+                                                                                                                            g_mainframeWidgetFocusPrinter.connect( window );
+       g_mainframeFocusPrinter.connect( window );
 #endif
 
-  g_MainWindowActive.connect(window);
+    g_MainWindowActive.connect(window);
 
-  GetPlugInMgr().Init(GTK_WIDGET(window));
+    GetPlugInMgr().Init(window);
 
-  GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
-  gtk_container_add(GTK_CONTAINER(window), vbox);
-  gtk_widget_show(vbox);
+    auto vbox = ui::VBox(FALSE, 0);
+    window.add(vbox);
+    vbox.show();
 
-  global_accel_connect_window(window);
+    global_accel_connect_window(window);
 
-  m_nCurrentStyle = (EViewStyle)g_Layout_viewStyle.m_value;
+    m_nCurrentStyle = (EViewStyle) g_Layout_viewStyle.m_value;
 
-  register_shortcuts();
+    register_shortcuts();
 
-  GtkMenuBar* main_menu = create_main_menu(CurrentStyle());
-  gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(main_menu), FALSE, FALSE, 0);
+    auto main_menu = create_main_menu(CurrentStyle());
+    vbox.pack_start(main_menu, FALSE, FALSE, 0);
 
-  GtkToolbar* main_toolbar = create_main_toolbar(CurrentStyle());
-  gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(main_toolbar), FALSE, FALSE, 0);
+    auto main_toolbar = create_main_toolbar(CurrentStyle());
+    vbox.pack_start(main_toolbar, FALSE, FALSE, 0);
 
-  GtkToolbar* plugin_toolbar = create_plugin_toolbar();
-  if (!g_Layout_enablePluginToolbar.m_value)
-  {
-    gtk_widget_hide(GTK_WIDGET(plugin_toolbar));
-  }
-  gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(plugin_toolbar), FALSE, FALSE, 0);
+    auto plugin_toolbar = create_plugin_toolbar();
+    if (!g_Layout_enablePluginToolbar.m_value) {
+        plugin_toolbar.hide();
+    }
+    vbox.pack_start(plugin_toolbar, FALSE, FALSE, 0);
 
-  GtkWidget* main_statusbar = create_main_statusbar(m_pStatusLabel);
-  gtk_box_pack_end(GTK_BOX(vbox), main_statusbar, FALSE, TRUE, 2);
+    ui::Widget main_statusbar = create_main_statusbar(reinterpret_cast<ui::Widget *>(m_pStatusLabel));
+    vbox.pack_end(main_statusbar, FALSE, TRUE, 2);
 
-  GroupDialog_constructWindow(window);
-  g_page_entity = GroupDialog_addPage("Entities", EntityInspector_constructWindow(GroupDialog_getWindow()), RawStringExportCaller("Entities"));
+    GroupDialog_constructWindow(window);
+    g_page_entity = GroupDialog_addPage("Entities", EntityInspector_constructWindow(GroupDialog_getWindow()),
+                                        RawStringExportCaller("Entities"));
 
-  if(FloatingGroupDialog())
-  {
-    g_page_console = GroupDialog_addPage("Console", Console_constructWindow(GroupDialog_getWindow()), RawStringExportCaller("Console"));
-  }
+    if (FloatingGroupDialog()) {
+        g_page_console = GroupDialog_addPage("Console", Console_constructWindow(GroupDialog_getWindow()),
+                                             RawStringExportCaller("Console"));
+    }
 
-#ifdef WIN32
-  if( g_multimon_globals.m_bStartOnPrimMon )
-  {
-    PositionWindowOnPrimaryScreen(g_layout_globals.m_position);
-       window_set_position(window, g_layout_globals.m_position);
-  }
-  else
+#if GDEF_OS_WINDOWS
+                                                                                                                            if ( g_multimon_globals.m_bStartOnPrimMon ) {
+               PositionWindowOnPrimaryScreen( g_layout_globals.m_position );
+               window_set_position( window, g_layout_globals.m_position );
+       }
+       else
 #endif
-  if(g_layout_globals.nState & GDK_WINDOW_STATE_MAXIMIZED)
-  {
-    gtk_window_maximize(window);
-    WindowPosition default_position(-1, -1, 640, 480);
-    window_set_position(window, default_position);
-  }
-  else
-  {
-    window_set_position(window, g_layout_globals.m_position);
-  }
-
-  m_window = window;
-
-  gtk_widget_show(GTK_WIDGET(window));
-
-  if (CurrentStyle() == eRegular || CurrentStyle() == eRegularLeft)
-  {
-    {
-      GtkWidget* vsplit = gtk_vpaned_new();
-      m_vSplit = vsplit;
-      gtk_box_pack_start(GTK_BOX(vbox), vsplit, TRUE, TRUE, 0);
-      gtk_widget_show (vsplit);
-
-      // console
-      GtkWidget* console_window = Console_constructWindow(window);
-      gtk_paned_pack2(GTK_PANED(vsplit), console_window, FALSE, TRUE);
-
-      {
-        GtkWidget* hsplit = gtk_hpaned_new();
-        gtk_widget_show (hsplit);
-        m_hSplit = hsplit;
-        gtk_paned_add1(GTK_PANED(vsplit), hsplit);
-
-        // xy
-        m_pXYWnd = new XYWnd();
-        m_pXYWnd->SetViewType(XY);
-        GtkWidget* xy_window = GTK_WIDGET(create_framed_widget(m_pXYWnd->GetWidget()));
+    if (g_layout_globals.nState & GDK_WINDOW_STATE_MAXIMIZED) {
+        gtk_window_maximize(window);
+        WindowPosition default_position(-1, -1, 640, 480);
+        window_set_position(window, default_position);
+    } else {
+        window_set_position(window, g_layout_globals.m_position);
+    }
 
+    m_window = window;
+
+    window.show();
+
+    if (CurrentStyle() == eRegular || CurrentStyle() == eRegularLeft) {
         {
-          GtkWidget* vsplit2 = gtk_vpaned_new();
-          gtk_widget_show(vsplit2);
-          m_vSplit2 = vsplit2;
-
-          if (CurrentStyle() == eRegular)
-          {
-            gtk_paned_add1(GTK_PANED(hsplit), xy_window);
-            gtk_paned_add2(GTK_PANED(hsplit), vsplit2);
-          }
-          else
-          {
-            gtk_paned_add1(GTK_PANED(hsplit), vsplit2);
-            gtk_paned_add2(GTK_PANED(hsplit), xy_window);
-          }
-
-
-          // camera
-          m_pCamWnd = NewCamWnd();
-          GlobalCamera_setCamWnd(*m_pCamWnd);
-          CamWnd_setParent(*m_pCamWnd, window);
-          GtkFrame* camera_window = create_framed_widget(CamWnd_getWidget(*m_pCamWnd));
-
-          gtk_paned_add1(GTK_PANED(vsplit2), GTK_WIDGET(camera_window));
-
-          // textures
-          GtkFrame* texture_window = create_framed_widget(TextureBrowser_constructWindow(window));
-
-          gtk_paned_add2(GTK_PANED(vsplit2), GTK_WIDGET(texture_window));
+            ui::Widget vsplit = ui::VPaned(ui::New);
+            m_vSplit = vsplit;
+            vbox.pack_start(vsplit, TRUE, TRUE, 0);
+            vsplit.show();
+
+            // console
+            ui::Widget console_window = Console_constructWindow(window);
+            gtk_paned_pack2(GTK_PANED(vsplit), console_window, FALSE, TRUE);
+
+            {
+                ui::Widget hsplit = ui::HPaned(ui::New);
+                hsplit.show();
+                m_hSplit = hsplit;
+                gtk_paned_add1(GTK_PANED(vsplit), hsplit);
+
+                // xy
+                m_pXYWnd = new XYWnd();
+                m_pXYWnd->SetViewType(XY);
+                ui::Widget xy_window = ui::Widget(create_framed_widget(m_pXYWnd->GetWidget()));
+
+                {
+                    ui::Widget vsplit2 = ui::VPaned(ui::New);
+                    vsplit2.show();
+                    m_vSplit2 = vsplit2;
+
+                    if (CurrentStyle() == eRegular) {
+                        gtk_paned_add1(GTK_PANED(hsplit), xy_window);
+                        gtk_paned_add2(GTK_PANED(hsplit), vsplit2);
+                    } else {
+                        gtk_paned_add1(GTK_PANED(hsplit), vsplit2);
+                        gtk_paned_add2(GTK_PANED(hsplit), xy_window);
+                    }
+
+
+                    // camera
+                    m_pCamWnd = NewCamWnd();
+                    GlobalCamera_setCamWnd(*m_pCamWnd);
+                    CamWnd_setParent(*m_pCamWnd, window);
+                    auto camera_window = create_framed_widget(CamWnd_getWidget(*m_pCamWnd));
+
+                    gtk_paned_add1(GTK_PANED(vsplit2), camera_window);
+
+                    // textures
+                    auto texture_window = create_framed_widget(TextureBrowser_constructWindow(window));
+
+                    gtk_paned_add2(GTK_PANED(vsplit2), texture_window);
+                }
+            }
         }
-      }
-    }
 
-    gtk_paned_set_position(GTK_PANED(m_vSplit), g_layout_globals.nXYHeight);
+        gtk_paned_set_position(GTK_PANED(m_vSplit), g_layout_globals.nXYHeight);
 
-    if (CurrentStyle() == eRegular)
-    {
-      gtk_paned_set_position(GTK_PANED(m_hSplit), g_layout_globals.nXYWidth);
-    }
-    else
-    {
-      gtk_paned_set_position(GTK_PANED(m_hSplit), g_layout_globals.nCamWidth);
-    }
+        if (CurrentStyle() == eRegular) {
+            gtk_paned_set_position(GTK_PANED(m_hSplit), g_layout_globals.nXYWidth);
+        } else {
+            gtk_paned_set_position(GTK_PANED(m_hSplit), g_layout_globals.nCamWidth);
+        }
 
-    gtk_paned_set_position(GTK_PANED(m_vSplit2), g_layout_globals.nCamHeight);
-  }
-  else if (CurrentStyle() == eFloating)
-  {
-    {
-      GtkWindow* window = create_persistent_floating_window("Camera", m_window);
-      global_accel_connect_window(window);
-      g_posCamWnd.connect(window);
+        gtk_paned_set_position(GTK_PANED(m_vSplit2), g_layout_globals.nCamHeight);
+    } else if (CurrentStyle() == eFloating) {
+        {
+            ui::Window window = ui::Window(create_persistent_floating_window("Camera", m_window));
+            global_accel_connect_window(window);
+            g_posCamWnd.connect(window);
 
-      gtk_widget_show(GTK_WIDGET(window));
+            window.show();
 
-      m_pCamWnd = NewCamWnd();
-      GlobalCamera_setCamWnd(*m_pCamWnd);
+            m_pCamWnd = NewCamWnd();
+            GlobalCamera_setCamWnd(*m_pCamWnd);
 
-      {
-        GtkFrame* frame = create_framed_widget(CamWnd_getWidget(*m_pCamWnd));
-        gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(frame));
-      }
-      CamWnd_setParent(*m_pCamWnd, window);
+            {
+                auto frame = create_framed_widget(CamWnd_getWidget(*m_pCamWnd));
+                window.add(frame);
+            }
+            CamWnd_setParent(*m_pCamWnd, window);
 
-      g_floating_windows.push_back(GTK_WIDGET(window));
-    }
+            g_floating_windows.push_back(window);
+        }
 
-    {
-      GtkWindow* window = create_persistent_floating_window(ViewType_getTitle(XY), m_window);
-      global_accel_connect_window(window);
-      g_posXYWnd.connect(window);
+        {
+            ui::Window window = ui::Window(create_persistent_floating_window(ViewType_getTitle(XY), m_window));
+            global_accel_connect_window(window);
+            g_posXYWnd.connect(window);
 
-      m_pXYWnd = new XYWnd();
-      m_pXYWnd->m_parent = window;
-      m_pXYWnd->SetViewType(XY);
+            m_pXYWnd = new XYWnd();
+            m_pXYWnd->m_parent = window;
+            m_pXYWnd->SetViewType(XY);
 
 
-      {
-        GtkFrame* frame = create_framed_widget(m_pXYWnd->GetWidget());
-        gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(frame));
-      }
-      XY_Top_Shown_Construct(window);
+            {
+                auto frame = create_framed_widget(m_pXYWnd->GetWidget());
+                window.add(frame);
+            }
+            XY_Top_Shown_Construct(window);
 
-      g_floating_windows.push_back(GTK_WIDGET(window));
-    }
+            g_floating_windows.push_back(window);
+        }
 
-    {
-      GtkWindow* window = create_persistent_floating_window(ViewType_getTitle(XZ), m_window);
-      global_accel_connect_window(window);
-      g_posXZWnd.connect(window);
+        {
+            ui::Window window = ui::Window(create_persistent_floating_window(ViewType_getTitle(XZ), m_window));
+            global_accel_connect_window(window);
+            g_posXZWnd.connect(window);
 
-      m_pXZWnd = new XYWnd();
-      m_pXZWnd->m_parent = window;
-      m_pXZWnd->SetViewType(XZ);
+            m_pXZWnd = new XYWnd();
+            m_pXZWnd->m_parent = window;
+            m_pXZWnd->SetViewType(XZ);
 
-      {
-        GtkFrame* frame = create_framed_widget(m_pXZWnd->GetWidget());
-        gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(frame));
-      }
+            {
+                auto frame = create_framed_widget(m_pXZWnd->GetWidget());
+                window.add(frame);
+            }
 
-      XZ_Front_Shown_Construct(window);
+            XZ_Front_Shown_Construct(window);
 
-      g_floating_windows.push_back(GTK_WIDGET(window));
-    }
+            g_floating_windows.push_back(window);
+        }
 
-    {
-      GtkWindow* window = create_persistent_floating_window(ViewType_getTitle(YZ), m_window);
-      global_accel_connect_window(window);
-      g_posYZWnd.connect(window);
+        {
+            ui::Window window = ui::Window(create_persistent_floating_window(ViewType_getTitle(YZ), m_window));
+            global_accel_connect_window(window);
+            g_posYZWnd.connect(window);
 
-      m_pYZWnd = new XYWnd();
-      m_pYZWnd->m_parent = window;
-      m_pYZWnd->SetViewType(YZ);
+            m_pYZWnd = new XYWnd();
+            m_pYZWnd->m_parent = window;
+            m_pYZWnd->SetViewType(YZ);
 
-      {
-        GtkFrame* frame = create_framed_widget(m_pYZWnd->GetWidget());
-        gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(frame));
-      }
+            {
+                auto frame = create_framed_widget(m_pYZWnd->GetWidget());
+                window.add(frame);
+            }
 
-      YZ_Side_Shown_Construct(window);
+            YZ_Side_Shown_Construct(window);
 
-      g_floating_windows.push_back(GTK_WIDGET(window));
-    }
+            g_floating_windows.push_back(window);
+        }
 
-    {
-      GtkFrame* frame = create_framed_widget(TextureBrowser_constructWindow(GroupDialog_getWindow()));
-      g_page_textures = GroupDialog_addPage("Textures", GTK_WIDGET(frame), TextureBrowserExportTitleCaller());
-    }
+        {
+            auto frame = create_framed_widget(TextureBrowser_constructWindow(GroupDialog_getWindow()));
+            g_page_textures = GroupDialog_addPage("Textures", frame, TextureBrowserExportTitleCaller());
+        }
 
-    GroupDialog_show();
-  }
-  else // 4 way
-  {
-    m_pCamWnd = NewCamWnd();
-    GlobalCamera_setCamWnd(*m_pCamWnd);
-    CamWnd_setParent(*m_pCamWnd, window);
+        GroupDialog_show();
+    } else // 4 way
+    {
+        m_pCamWnd = NewCamWnd();
+        GlobalCamera_setCamWnd(*m_pCamWnd);
+        CamWnd_setParent(*m_pCamWnd, window);
 
-    GtkWidget* camera = CamWnd_getWidget(*m_pCamWnd);
+        ui::Widget camera = CamWnd_getWidget(*m_pCamWnd);
 
-    m_pYZWnd = new XYWnd();
-    m_pYZWnd->SetViewType(YZ);
+        m_pYZWnd = new XYWnd();
+        m_pYZWnd->SetViewType(YZ);
 
-    GtkWidget* yz = m_pYZWnd->GetWidget();
+        ui::Widget yz = m_pYZWnd->GetWidget();
 
-    m_pXYWnd = new XYWnd();
-    m_pXYWnd->SetViewType(XY);
+        m_pXYWnd = new XYWnd();
+        m_pXYWnd->SetViewType(XY);
 
-    GtkWidget* xy = m_pXYWnd->GetWidget();
+        ui::Widget xy = m_pXYWnd->GetWidget();
 
-    m_pXZWnd = new XYWnd();
-    m_pXZWnd->SetViewType(XZ);
+        m_pXZWnd = new XYWnd();
+        m_pXZWnd->SetViewType(XZ);
 
-    GtkWidget* xz = m_pXZWnd->GetWidget();
+        ui::Widget xz = m_pXZWnd->GetWidget();
 
-    GtkHPaned* split = create_split_views(camera, yz, xy, xz);
-    gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(split), TRUE, TRUE, 0);
+        auto split = create_split_views(camera, yz, xy, xz);
+        vbox.pack_start(split, TRUE, TRUE, 0);
 
-    {
-      GtkFrame* frame = create_framed_widget(TextureBrowser_constructWindow(window));
-      g_page_textures = GroupDialog_addPage("Textures", GTK_WIDGET(frame), TextureBrowserExportTitleCaller());
+        {
+            auto frame = create_framed_widget(TextureBrowser_constructWindow(window));
+            g_page_textures = GroupDialog_addPage("Textures", frame, TextureBrowserExportTitleCaller());
+        }
     }
-  }
 
-  EntityList_constructWindow(window);
-  PreferencesDialog_constructWindow(window);
-  FindTextureDialog_constructWindow(window);
-  SurfaceInspector_constructWindow(window);
-  PatchInspector_constructWindow(window);
+    EntityList_constructWindow(window);
+    PreferencesDialog_constructWindow(window);
+    FindTextureDialog_constructWindow(window);
+    SurfaceInspector_constructWindow(window);
+    PatchInspector_constructWindow(window);
 
-  SetActiveXY(m_pXYWnd);
+    SetActiveXY(m_pXYWnd);
 
-  AddGridChangeCallback(SetGridStatusCaller(*this));
-  AddGridChangeCallback(ReferenceCaller<MainFrame, XY_UpdateAllWindows>(*this));
+    AddGridChangeCallback(SetGridStatusCaller(*this));
+    AddGridChangeCallback(ReferenceCaller<MainFrame, void(), XY_UpdateAllWindows>(*this));
 
-  g_defaultToolMode = DragMode;
-  g_defaultToolMode();
-  SetStatusText(m_command_status, c_TranslateMode_status);
+    g_defaultToolMode = DragMode;
+    g_defaultToolMode();
+    SetStatusText(m_command_status, c_TranslateMode_status);
 
-  EverySecondTimer_enable();
+    EverySecondTimer_enable();
 
-  //GlobalShortcuts_reportUnregistered();
+    //GlobalShortcuts_reportUnregistered();
 }
 
 void MainFrame::SaveWindowInfo()
 {
-  if (!FloatingGroupDialog())
-  {
-    g_layout_globals.nXYHeight = gtk_paned_get_position(GTK_PANED(m_vSplit));
+    if (!FloatingGroupDialog()) {
+        g_layout_globals.nXYHeight = gtk_paned_get_position(GTK_PANED(m_vSplit));
 
-    if(CurrentStyle() != eRegular)
-    {
-      g_layout_globals.nCamWidth = gtk_paned_get_position(GTK_PANED(m_hSplit));
-    }
-    else
-    {
-      g_layout_globals.nXYWidth = gtk_paned_get_position(GTK_PANED(m_hSplit));
-    }
+        if (CurrentStyle() != eRegular) {
+            g_layout_globals.nCamWidth = gtk_paned_get_position(GTK_PANED(m_hSplit));
+        } else {
+            g_layout_globals.nXYWidth = gtk_paned_get_position(GTK_PANED(m_hSplit));
+        }
 
-    g_layout_globals.nCamHeight = gtk_paned_get_position(GTK_PANED(m_vSplit2));
-  }
+        g_layout_globals.nCamHeight = gtk_paned_get_position(GTK_PANED(m_vSplit2));
+    }
 
-  g_layout_globals.m_position = m_position_tracker.getPosition();
+    g_layout_globals.m_position = m_position_tracker.getPosition();
 
-  g_layout_globals.nState = gdk_window_get_state(GTK_WIDGET(m_window)->window);
+    g_layout_globals.nState = gdk_window_get_state(gtk_widget_get_window(m_window));
 }
 
 void MainFrame::Shutdown()
 {
-  EverySecondTimer_disable();
+    EverySecondTimer_disable();
 
-  EntityList_destroyWindow();
+    EntityList_destroyWindow();
 
-  delete m_pXYWnd;
-  m_pXYWnd = 0;
-  delete m_pYZWnd;
-  m_pYZWnd = 0;
-  delete m_pXZWnd;
-  m_pXZWnd = 0;
+    delete m_pXYWnd;
+    m_pXYWnd = 0;
+    delete m_pYZWnd;
+    m_pYZWnd = 0;
+    delete m_pXZWnd;
+    m_pXZWnd = 0;
 
-  TextureBrowser_destroyWindow();
+    TextureBrowser_destroyWindow();
 
-  DeleteCamWnd(m_pCamWnd);
-  m_pCamWnd = 0;
+    DeleteCamWnd(m_pCamWnd);
+    m_pCamWnd = 0;
 
-  PreferencesDialog_destroyWindow();
-  SurfaceInspector_destroyWindow();
-  FindTextureDialog_destroyWindow();
-  PatchInspector_destroyWindow();
+    PreferencesDialog_destroyWindow();
+    SurfaceInspector_destroyWindow();
+    FindTextureDialog_destroyWindow();
+    PatchInspector_destroyWindow();
 
-  g_DbgDlg.destroyWindow();
+    g_DbgDlg.destroyWindow();
 
-  // destroying group-dialog last because it may contain texture-browser
-  GroupDialog_destroyWindow();
+    // destroying group-dialog last because it may contain texture-browser
+    GroupDialog_destroyWindow();
 }
 
 void MainFrame::RedrawStatusText()
 {
-  gtk_label_set_text(GTK_LABEL(m_pStatusLabel[c_command_status]), m_command_status.c_str());
-  gtk_label_set_text(GTK_LABEL(m_pStatusLabel[c_position_status]), m_position_status.c_str());
-  gtk_label_set_text(GTK_LABEL(m_pStatusLabel[c_brushcount_status]), m_brushcount_status.c_str());
-  gtk_label_set_text(GTK_LABEL(m_pStatusLabel[c_texture_status]), m_texture_status.c_str());
-  gtk_label_set_text(GTK_LABEL(m_pStatusLabel[c_grid_status]), m_grid_status.c_str());
+    ui::Label::from(m_pStatusLabel[c_command_status]).text(m_command_status.c_str());
+    ui::Label::from(m_pStatusLabel[c_position_status]).text(m_position_status.c_str());
+    ui::Label::from(m_pStatusLabel[c_brushcount_status]).text(m_brushcount_status.c_str());
+    ui::Label::from(m_pStatusLabel[c_texture_status]).text(m_texture_status.c_str());
+    ui::Label::from(m_pStatusLabel[c_grid_status]).text(m_grid_status.c_str());
 }
 
 void MainFrame::UpdateStatusText()
 {
-  m_idleRedrawStatusText.queueDraw();
+    m_idleRedrawStatusText.queueDraw();
 }
 
-void MainFrame::SetStatusText(CopiedString& status_text, const char* pText)
+void MainFrame::SetStatusText(CopiedString &status_text, const char *pText)
 {
-  status_text = pText;
-  UpdateStatusText();
+    status_text = pText;
+    UpdateStatusText();
 }
 
-void Sys_Status(const charstatus)
+void Sys_Status(const char *status)
 {
-  if(g_pParentWnd != 0)
-  {
-    g_pParentWnd->SetStatusText (g_pParentWnd->m_command_status, status);
-  }
+    if (g_pParentWnd != 0) {
+        g_pParentWnd->SetStatusText(g_pParentWnd->m_command_status, status);
+    }
 }
 
 int getRotateIncrement()
 {
-  return static_cast<int>(g_si_globals.rotate);
+    return static_cast<int>( g_si_globals.rotate );
 }
 
 int getFarClipDistance()
 {
-  return g_camwindow_globals.m_nCubicScale;
+    return g_camwindow_globals.m_nCubicScale;
 }
 
-float (*GridStatus_getGridSize)() = GetGridSize;
-int (*GridStatus_getRotateIncrement)() = getRotateIncrement;
-int (*GridStatus_getFarClipDistance)() = getFarClipDistance;
-bool (*GridStatus_getTextureLockEnabled)();
+float ( *GridStatus_getGridSize )() = GetGridSize;
+
+int ( *GridStatus_getRotateIncrement )() = getRotateIncrement;
+
+int ( *GridStatus_getFarClipDistance )() = getFarClipDistance;
+
+bool ( *GridStatus_getTextureLockEnabled )();
 
 void MainFrame::SetGridStatus()
 {
-  StringOutputStream status(64);
-  const char* lock = (GridStatus_getTextureLockEnabled()) ? "ON" : "OFF";
-  status << (GetSnapGridSize() > 0 ? "G:" : "g:") << GridStatus_getGridSize()
-    << "  R:" << GridStatus_getRotateIncrement()
-    << "  C:" << GridStatus_getFarClipDistance()
-    << "  L:" << lock;
-  SetStatusText(m_grid_status, status.c_str());
+    StringOutputStream status(64);
+    const char *lock = (GridStatus_getTextureLockEnabled()) ? "ON" : "OFF";
+    status << (GetSnapGridSize() > 0 ? "G:" : "g:") << GridStatus_getGridSize()
+           << "  R:" << GridStatus_getRotateIncrement()
+           << "  C:" << GridStatus_getFarClipDistance()
+           << "  L:" << lock;
+    SetStatusText(m_grid_status, status.c_str());
 }
 
 void GridStatus_onTextureLockEnabledChanged()
 {
-  if(g_pParentWnd != 0)
-  {
-    g_pParentWnd->SetGridStatus();
-  }
+    if (g_pParentWnd != 0) {
+        g_pParentWnd->SetGridStatus();
+    }
 }
 
 void GlobalGL_sharedContextCreated()
 {
-  GLFont *g_font = NULL;
+    GLFont *g_font = NULL;
 
-  // report OpenGL information
-  globalOutputStream() << "GL_VENDOR: " << reinterpret_cast<const char*>(glGetString (GL_VENDOR)) << "\n";
-  globalOutputStream() << "GL_RENDERER: " << reinterpret_cast<const char*>(glGetString (GL_RENDERER)) << "\n";
-  globalOutputStream() << "GL_VERSION: " << reinterpret_cast<const char*>(glGetString (GL_VERSION)) << "\n";
-  globalOutputStream() << "GL_EXTENSIONS: " << reinterpret_cast<const char*>(glGetString (GL_EXTENSIONS)) << "\n";
+    // report OpenGL information
+    globalOutputStream() << "GL_VENDOR: " << reinterpret_cast<const char *>( glGetString(GL_VENDOR)) << "\n";
+    globalOutputStream() << "GL_RENDERER: " << reinterpret_cast<const char *>( glGetString(GL_RENDERER)) << "\n";
+    globalOutputStream() << "GL_VERSION: " << reinterpret_cast<const char *>( glGetString(GL_VERSION)) << "\n";
+    const auto extensions = reinterpret_cast<const char *>( glGetString(GL_EXTENSIONS));
+    globalOutputStream() << "GL_EXTENSIONS: " << (extensions ? extensions : "") << "\n";
 
-  QGL_sharedContextCreated(GlobalOpenGL());
+    QGL_sharedContextCreated(GlobalOpenGL());
 
-  ShaderCache_extensionsInitialised();
+    ShaderCache_extensionsInitialised();
 
-  GlobalShaderCache().realise();
-  Textures_Realise();
+    GlobalShaderCache().realise();
+    Textures_Realise();
 
-#ifdef WIN32
-  /* win32 is dodgy here, just use courier new then */
-  g_font = glfont_create("arial 9");
+#if GDEF_OS_WINDOWS
+                                                                                                                            /* win32 is dodgy here, just use courier new then */
+       g_font = glfont_create( "arial 9" );
 #else
-  GtkSettings *settings = gtk_settings_get_default();
-  gchar *fontname;
-  g_object_get(settings, "gtk-font-name", &fontname, NULL);
-  g_font = glfont_create(fontname);
+    auto settings = gtk_settings_get_default();
+    gchar *fontname;
+    g_object_get(settings, "gtk-font-name", &fontname, NULL);
+    g_font = glfont_create(fontname);
 #endif
 
-  GlobalOpenGL().m_font = g_font;
+    GlobalOpenGL().m_font = g_font;
 }
 
 void GlobalGL_sharedContextDestroyed()
 {
-  Textures_Unrealise();
-  GlobalShaderCache().unrealise();
+    Textures_Unrealise();
+    GlobalShaderCache().unrealise();
 
-  QGL_sharedContextDestroyed(GlobalOpenGL());
+    QGL_sharedContextDestroyed(GlobalOpenGL());
 }
 
 
-void Layout_constructPreferences(PreferencesPagepage)
+void Layout_constructPreferences(PreferencesPage &page)
 {
-  {
-    const char* layouts[] = { "window1.bmp", "window2.bmp", "window3.bmp", "window4.bmp" };
-    page.appendRadioIcons(
-      "Window Layout",
-      STRING_ARRAY_RANGE(layouts),
-      LatchedIntImportCaller(g_Layout_viewStyle),
-      IntExportCaller(g_Layout_viewStyle.m_latched)
+    {
+        const char *layouts[] = {"window1.png", "window2.png", "window3.png", "window4.png"};
+        page.appendRadioIcons(
+                "Window Layout",
+                STRING_ARRAY_RANGE(layouts),
+                make_property(g_Layout_viewStyle)
+        );
+    }
+    page.appendCheckBox(
+            "", "Detachable Menus",
+            make_property(g_Layout_enableDetachableMenus)
     );
-  }
-  page.appendCheckBox(
-    "", "Detachable Menus",
-    LatchedBoolImportCaller(g_Layout_enableDetachableMenus),
-    BoolExportCaller(g_Layout_enableDetachableMenus.m_latched)
-  );
-  if (!string_empty(g_pGameDescription->getKeyValue("no_patch")))
-  {
+    if (!string_empty(g_pGameDescription->getKeyValue("no_patch"))) {
+        page.appendCheckBox(
+                "", "Patch Toolbar",
+                make_property(g_Layout_enablePatchToolbar)
+        );
+    }
     page.appendCheckBox(
-      "", "Patch Toolbar",
-      LatchedBoolImportCaller(g_Layout_enablePatchToolbar),
-      BoolExportCaller(g_Layout_enablePatchToolbar.m_latched)
+            "", "Plugin Toolbar",
+            make_property(g_Layout_enablePluginToolbar)
     );
-  }
-  page.appendCheckBox(
-    "", "Plugin Toolbar",
-    LatchedBoolImportCaller(g_Layout_enablePluginToolbar),
-    BoolExportCaller(g_Layout_enablePluginToolbar.m_latched)
-  );
 }
 
-void Layout_constructPage(PreferenceGroupgroup)
+void Layout_constructPage(PreferenceGroup &group)
 {
-  PreferencesPage page(group.createPage("Layout", "Layout Preferences"));
-  Layout_constructPreferences(page);
+    PreferencesPage page(group.createPage("Layout", "Layout Preferences"));
+    Layout_constructPreferences(page);
 }
 
 void Layout_registerPreferencesPage()
 {
-  PreferencesDialog_addInterfacePage(FreeCaller1<PreferenceGroup&, Layout_constructPage>());
+    PreferencesDialog_addInterfacePage(makeCallbackF(Layout_constructPage));
 }
 
 
@@ -3467,197 +3523,236 @@ void Layout_registerPreferencesPage()
 
 void MainFrame_Construct()
 {
-  GlobalCommands_insert("OpenManual", FreeCaller<OpenHelpURL>(), Accelerator(GDK_F1));
-
-  GlobalCommands_insert("Sleep", FreeCaller<thunk_OnSleep>(), Accelerator('P', (GdkModifierType)(GDK_SHIFT_MASK|GDK_CONTROL_MASK)));
-  GlobalCommands_insert("NewMap", FreeCaller<NewMap>());
-  GlobalCommands_insert("OpenMap", FreeCaller<OpenMap>(), Accelerator('O', (GdkModifierType)GDK_CONTROL_MASK));
-  GlobalCommands_insert("ImportMap", FreeCaller<ImportMap>());
-  GlobalCommands_insert("SaveMap", FreeCaller<SaveMap>(), Accelerator('S', (GdkModifierType)GDK_CONTROL_MASK));
-  GlobalCommands_insert("SaveMapAs", FreeCaller<SaveMapAs>());
-  GlobalCommands_insert("SaveSelected", FreeCaller<ExportMap>());
-  GlobalCommands_insert("SaveRegion", FreeCaller<SaveRegion>());
-  GlobalCommands_insert("RefreshReferences", FreeCaller<RefreshReferences>());
-  GlobalCommands_insert("ProjectSettings", FreeCaller<DoProjectSettings>());
-  GlobalCommands_insert("CheckForUpdate", FreeCaller<OpenUpdateURL>());
-  GlobalCommands_insert("Exit", FreeCaller<Exit>());
-
-  GlobalCommands_insert("Undo", FreeCaller<Undo>(), Accelerator('Z', (GdkModifierType)GDK_CONTROL_MASK));
-  GlobalCommands_insert("Redo", FreeCaller<Redo>(), Accelerator('Y', (GdkModifierType)GDK_CONTROL_MASK));
-  GlobalCommands_insert("Copy", FreeCaller<Copy>(), Accelerator('C', (GdkModifierType)GDK_CONTROL_MASK));
-  GlobalCommands_insert("Paste", FreeCaller<Paste>(), Accelerator('V', (GdkModifierType)GDK_CONTROL_MASK));
-  GlobalCommands_insert("PasteToCamera", FreeCaller<PasteToCamera>(), Accelerator('V', (GdkModifierType)GDK_MOD1_MASK));
-  GlobalCommands_insert("CloneSelection", FreeCaller<Selection_Clone>(), Accelerator(GDK_space));
-  GlobalCommands_insert("CloneSelectionAndMakeUnique", FreeCaller<Selection_Clone_MakeUnique>(), Accelerator(GDK_space, (GdkModifierType)GDK_SHIFT_MASK));
-  GlobalCommands_insert("DeleteSelection", FreeCaller<deleteSelection>(), Accelerator(GDK_BackSpace));
-  GlobalCommands_insert("ParentSelection", FreeCaller<Scene_parentSelected>());
-  GlobalCommands_insert("UnSelectSelection", FreeCaller<Selection_Deselect>(), Accelerator(GDK_Escape));
-  GlobalCommands_insert("InvertSelection", FreeCaller<Select_Invert>(), Accelerator('I'));
-  GlobalCommands_insert("SelectInside", FreeCaller<Select_Inside>());
-  GlobalCommands_insert("SelectTouching", FreeCaller<Select_Touching>());
-  GlobalCommands_insert("ExpandSelectionToEntities", FreeCaller<Scene_ExpandSelectionToEntities>(), Accelerator('E', (GdkModifierType)(GDK_MOD1_MASK|GDK_CONTROL_MASK)));
-  GlobalCommands_insert("Preferences", FreeCaller<PreferencesDialog_showDialog>(), Accelerator('P'));
-
-  GlobalCommands_insert("ToggleConsole", FreeCaller<Console_ToggleShow>(), Accelerator('O'));
-  GlobalCommands_insert("ToggleEntityInspector", FreeCaller<EntityInspector_ToggleShow>(), Accelerator('N'));
-  GlobalCommands_insert("EntityList", FreeCaller<EntityList_toggleShown>(), Accelerator('L'));
-
-  GlobalCommands_insert("ShowHidden", FreeCaller<Select_ShowAllHidden>(), Accelerator('H', (GdkModifierType)GDK_SHIFT_MASK));
-  GlobalCommands_insert("HideSelected", FreeCaller<HideSelected>(), Accelerator('H'));
-
-  GlobalToggles_insert("DragVertices", FreeCaller<SelectVertexMode>(), ToggleItem::AddCallbackCaller(g_vertexMode_button), Accelerator('V'));
-  GlobalToggles_insert("DragEdges", FreeCaller<SelectEdgeMode>(), ToggleItem::AddCallbackCaller(g_edgeMode_button), Accelerator('E'));
-  GlobalToggles_insert("DragFaces", FreeCaller<SelectFaceMode>(), ToggleItem::AddCallbackCaller(g_faceMode_button), Accelerator('F'));
-
-  GlobalCommands_insert("MirrorSelectionX", FreeCaller<Selection_Flipx>());
-  GlobalCommands_insert("RotateSelectionX", FreeCaller<Selection_Rotatex>());
-  GlobalCommands_insert("MirrorSelectionY", FreeCaller<Selection_Flipy>());
-  GlobalCommands_insert("RotateSelectionY", FreeCaller<Selection_Rotatey>());
-  GlobalCommands_insert("MirrorSelectionZ", FreeCaller<Selection_Flipz>());
-  GlobalCommands_insert("RotateSelectionZ", FreeCaller<Selection_Rotatez>());
-
-  GlobalCommands_insert("ArbitraryRotation", FreeCaller<DoRotateDlg>());
-  GlobalCommands_insert("ArbitraryScale", FreeCaller<DoScaleDlg>());
-
-  GlobalCommands_insert("BuildMenuCustomize", FreeCaller<DoBuildMenu>());
-
-  GlobalCommands_insert("FindBrush", FreeCaller<DoFind>());
-
-  GlobalCommands_insert("MapInfo", FreeCaller<DoMapInfo>(), Accelerator('M'));
-
-
-  GlobalToggles_insert("ToggleClipper", FreeCaller<ClipperMode>(), ToggleItem::AddCallbackCaller(g_clipper_button), Accelerator('X'));
-
-  GlobalToggles_insert("MouseTranslate", FreeCaller<TranslateMode>(), ToggleItem::AddCallbackCaller(g_translatemode_button), Accelerator('W'));
-  GlobalToggles_insert("MouseRotate", FreeCaller<RotateMode>(), ToggleItem::AddCallbackCaller(g_rotatemode_button), Accelerator('R'));
-  GlobalToggles_insert("MouseScale", FreeCaller<ScaleMode>(), ToggleItem::AddCallbackCaller(g_scalemode_button));
-  GlobalToggles_insert("MouseDrag", FreeCaller<DragMode>(), ToggleItem::AddCallbackCaller(g_dragmode_button), Accelerator('Q'));
-
-  GlobalCommands_insert("ColorSchemeOriginal", FreeCaller<ColorScheme_Original>());
-  GlobalCommands_insert("ColorSchemeQER", FreeCaller<ColorScheme_QER>());
-  GlobalCommands_insert("ColorSchemeBlackAndGreen", FreeCaller<ColorScheme_Black>());
-  GlobalCommands_insert("ColorSchemeYdnar", FreeCaller<ColorScheme_Ydnar>());
-  GlobalCommands_insert("ChooseTextureBackgroundColor", makeCallback(g_ColoursMenu.m_textureback));
-  GlobalCommands_insert("ChooseGridBackgroundColor", makeCallback(g_ColoursMenu.m_xyback));
-  GlobalCommands_insert("ChooseGridMajorColor", makeCallback(g_ColoursMenu.m_gridmajor));
-  GlobalCommands_insert("ChooseGridMinorColor", makeCallback(g_ColoursMenu.m_gridminor));
-  GlobalCommands_insert("ChooseSmallGridMajorColor", makeCallback(g_ColoursMenu.m_gridmajor_alt));
-  GlobalCommands_insert("ChooseSmallGridMinorColor", makeCallback(g_ColoursMenu.m_gridminor_alt));
-  GlobalCommands_insert("ChooseGridTextColor", makeCallback(g_ColoursMenu.m_gridtext));
-  GlobalCommands_insert("ChooseGridBlockColor", makeCallback(g_ColoursMenu.m_gridblock));
-  GlobalCommands_insert("ChooseBrushColor", makeCallback(g_ColoursMenu.m_brush));
-  GlobalCommands_insert("ChooseCameraBackgroundColor", makeCallback(g_ColoursMenu.m_cameraback));
-  GlobalCommands_insert("ChooseSelectedBrushColor", makeCallback(g_ColoursMenu.m_selectedbrush));
-  GlobalCommands_insert("ChooseCameraSelectedBrushColor", makeCallback(g_ColoursMenu.m_selectedbrush3d));
-  GlobalCommands_insert("ChooseClipperColor", makeCallback(g_ColoursMenu.m_clipper));
-  GlobalCommands_insert("ChooseOrthoViewNameColor", makeCallback(g_ColoursMenu.m_viewname));
-
-
-  GlobalCommands_insert("CSGSubtract", FreeCaller<CSG_Subtract>(), Accelerator('U', (GdkModifierType)GDK_SHIFT_MASK));
-  GlobalCommands_insert("CSGMerge", FreeCaller<CSG_Merge>(), Accelerator('U', (GdkModifierType)GDK_CONTROL_MASK));
-  GlobalCommands_insert("CSGHollow", FreeCaller<CSG_MakeHollow>());
-
-  Grid_registerCommands();
-
-  GlobalCommands_insert("SnapToGrid", FreeCaller<Selection_SnapToGrid>(), Accelerator('G', (GdkModifierType)GDK_CONTROL_MASK));
-
-  GlobalCommands_insert("SelectAllOfType", FreeCaller<Select_AllOfType>(), Accelerator('A', (GdkModifierType)GDK_SHIFT_MASK));
-
-  GlobalCommands_insert("TexRotateClock", FreeCaller<Texdef_RotateClockwise>(), Accelerator(GDK_Next, (GdkModifierType)GDK_SHIFT_MASK));
-  GlobalCommands_insert("TexRotateCounter", FreeCaller<Texdef_RotateAntiClockwise>(), Accelerator(GDK_Prior, (GdkModifierType)GDK_SHIFT_MASK));
-  GlobalCommands_insert("TexScaleUp", FreeCaller<Texdef_ScaleUp>(), Accelerator(GDK_Up, (GdkModifierType)GDK_CONTROL_MASK));
-  GlobalCommands_insert("TexScaleDown", FreeCaller<Texdef_ScaleDown>(), Accelerator(GDK_Down, (GdkModifierType)GDK_CONTROL_MASK));
-  GlobalCommands_insert("TexScaleLeft", FreeCaller<Texdef_ScaleLeft>(), Accelerator(GDK_Left, (GdkModifierType)GDK_CONTROL_MASK));
-  GlobalCommands_insert("TexScaleRight", FreeCaller<Texdef_ScaleRight>(), Accelerator(GDK_Right, (GdkModifierType)GDK_CONTROL_MASK));
-  GlobalCommands_insert("TexShiftUp", FreeCaller<Texdef_ShiftUp>(), Accelerator(GDK_Up, (GdkModifierType)GDK_SHIFT_MASK));
-  GlobalCommands_insert("TexShiftDown", FreeCaller<Texdef_ShiftDown>(), Accelerator(GDK_Down, (GdkModifierType)GDK_SHIFT_MASK));
-  GlobalCommands_insert("TexShiftLeft", FreeCaller<Texdef_ShiftLeft>(), Accelerator(GDK_Left, (GdkModifierType)GDK_SHIFT_MASK));
-  GlobalCommands_insert("TexShiftRight", FreeCaller<Texdef_ShiftRight>(), Accelerator(GDK_Right, (GdkModifierType)GDK_SHIFT_MASK));
-
-  GlobalCommands_insert("MoveSelectionDOWN", FreeCaller<Selection_MoveDown>(), Accelerator(GDK_KP_Subtract));
-  GlobalCommands_insert("MoveSelectionUP", FreeCaller<Selection_MoveUp>(), Accelerator(GDK_KP_Add));
-
-  GlobalCommands_insert("SelectNudgeLeft", FreeCaller<Selection_NudgeLeft>(), Accelerator(GDK_Left, (GdkModifierType)GDK_MOD1_MASK));
-  GlobalCommands_insert("SelectNudgeRight", FreeCaller<Selection_NudgeRight>(), Accelerator(GDK_Right, (GdkModifierType)GDK_MOD1_MASK));
-  GlobalCommands_insert("SelectNudgeUp", FreeCaller<Selection_NudgeUp>(), Accelerator(GDK_Up, (GdkModifierType)GDK_MOD1_MASK));
-  GlobalCommands_insert("SelectNudgeDown", FreeCaller<Selection_NudgeDown>(), Accelerator(GDK_Down, (GdkModifierType)GDK_MOD1_MASK));
-
-  Patch_registerCommands();
-  XYShow_registerCommands();
-
-  typedef FreeCaller1<const Selectable&, ComponentMode_SelectionChanged> ComponentModeSelectionChangedCaller;
-  GlobalSelectionSystem().addSelectionChangeCallback(ComponentModeSelectionChangedCaller());
-
-  GlobalPreferenceSystem().registerPreference("DetachableMenus", BoolImportStringCaller(g_Layout_enableDetachableMenus.m_latched), BoolExportStringCaller(g_Layout_enableDetachableMenus.m_latched));
-  GlobalPreferenceSystem().registerPreference("PatchToolBar", BoolImportStringCaller(g_Layout_enablePatchToolbar.m_latched), BoolExportStringCaller(g_Layout_enablePatchToolbar.m_latched));
-  GlobalPreferenceSystem().registerPreference("PluginToolBar", BoolImportStringCaller(g_Layout_enablePluginToolbar.m_latched), BoolExportStringCaller(g_Layout_enablePluginToolbar.m_latched));
-  GlobalPreferenceSystem().registerPreference("QE4StyleWindows", IntImportStringCaller(g_Layout_viewStyle.m_latched), IntExportStringCaller(g_Layout_viewStyle.m_latched));
-  GlobalPreferenceSystem().registerPreference("XYHeight", IntImportStringCaller(g_layout_globals.nXYHeight), IntExportStringCaller(g_layout_globals.nXYHeight));
-  GlobalPreferenceSystem().registerPreference("XYWidth", IntImportStringCaller(g_layout_globals.nXYWidth), IntExportStringCaller(g_layout_globals.nXYWidth));
-  GlobalPreferenceSystem().registerPreference("CamWidth", IntImportStringCaller(g_layout_globals.nCamWidth), IntExportStringCaller(g_layout_globals.nCamWidth));
-  GlobalPreferenceSystem().registerPreference("CamHeight", IntImportStringCaller(g_layout_globals.nCamHeight), IntExportStringCaller(g_layout_globals.nCamHeight));
-
-  GlobalPreferenceSystem().registerPreference("State", IntImportStringCaller(g_layout_globals.nState), IntExportStringCaller(g_layout_globals.nState));
-  GlobalPreferenceSystem().registerPreference("PositionX", IntImportStringCaller(g_layout_globals.m_position.x), IntExportStringCaller(g_layout_globals.m_position.x));
-  GlobalPreferenceSystem().registerPreference("PositionY", IntImportStringCaller(g_layout_globals.m_position.y), IntExportStringCaller(g_layout_globals.m_position.y));
-  GlobalPreferenceSystem().registerPreference("Width", IntImportStringCaller(g_layout_globals.m_position.w), IntExportStringCaller(g_layout_globals.m_position.w));
-  GlobalPreferenceSystem().registerPreference("Height", IntImportStringCaller(g_layout_globals.m_position.h), IntExportStringCaller(g_layout_globals.m_position.h));
-
-  GlobalPreferenceSystem().registerPreference("CamWnd", WindowPositionTrackerImportStringCaller(g_posCamWnd), WindowPositionTrackerExportStringCaller(g_posCamWnd));
-  GlobalPreferenceSystem().registerPreference("XYWnd", WindowPositionTrackerImportStringCaller(g_posXYWnd), WindowPositionTrackerExportStringCaller(g_posXYWnd));
-  GlobalPreferenceSystem().registerPreference("YZWnd", WindowPositionTrackerImportStringCaller(g_posYZWnd), WindowPositionTrackerExportStringCaller(g_posYZWnd));
-  GlobalPreferenceSystem().registerPreference("XZWnd", WindowPositionTrackerImportStringCaller(g_posXZWnd), WindowPositionTrackerExportStringCaller(g_posXZWnd));
-
-  {
-    const char* ENGINEPATH_ATTRIBUTE =
-#if defined(WIN32)
-      "enginepath_win32"
-#elif defined(__linux__) || defined (__FreeBSD__)
-      "enginepath_linux"
-#elif defined(__APPLE__)
-      "enginepath_macos"
+    GlobalCommands_insert("OpenManual", makeCallbackF(OpenHelpURL), Accelerator(GDK_KEY_F1));
+
+    GlobalCommands_insert("Sleep", makeCallbackF(thunk_OnSleep),
+                          Accelerator('P', (GdkModifierType) (GDK_SHIFT_MASK | GDK_CONTROL_MASK)));
+    GlobalCommands_insert("NewMap", makeCallbackF(NewMap));
+    GlobalCommands_insert("OpenMap", makeCallbackF(OpenMap), Accelerator('O', (GdkModifierType) GDK_CONTROL_MASK));
+    GlobalCommands_insert("ImportMap", makeCallbackF(ImportMap));
+    GlobalCommands_insert("SaveMap", makeCallbackF(SaveMap), Accelerator('S', (GdkModifierType) GDK_CONTROL_MASK));
+    GlobalCommands_insert("SaveMapAs", makeCallbackF(SaveMapAs));
+    GlobalCommands_insert("ExportSelected", makeCallbackF(ExportMap));
+    GlobalCommands_insert("SaveRegion", makeCallbackF(SaveRegion));
+    GlobalCommands_insert("RefreshReferences", makeCallbackF(VFS_Refresh));
+    GlobalCommands_insert("ProjectSettings", makeCallbackF(DoProjectSettings));
+    GlobalCommands_insert("Exit", makeCallbackF(Exit));
+
+    GlobalCommands_insert("Undo", makeCallbackF(Undo), Accelerator('Z', (GdkModifierType) GDK_CONTROL_MASK));
+    GlobalCommands_insert("Redo", makeCallbackF(Redo), Accelerator('Y', (GdkModifierType) GDK_CONTROL_MASK));
+    GlobalCommands_insert("Copy", makeCallbackF(Copy), Accelerator('C', (GdkModifierType) GDK_CONTROL_MASK));
+    GlobalCommands_insert("Paste", makeCallbackF(Paste), Accelerator('V', (GdkModifierType) GDK_CONTROL_MASK));
+    GlobalCommands_insert("PasteToCamera", makeCallbackF(PasteToCamera),
+                          Accelerator('V', (GdkModifierType) GDK_MOD1_MASK));
+    GlobalCommands_insert("CloneSelection", makeCallbackF(Selection_Clone), Accelerator(GDK_KEY_space));
+    GlobalCommands_insert("CloneSelectionAndMakeUnique", makeCallbackF(Selection_Clone_MakeUnique),
+                          Accelerator(GDK_KEY_space, (GdkModifierType) GDK_SHIFT_MASK));
+    GlobalCommands_insert("DeleteSelection", makeCallbackF(deleteSelection), Accelerator(GDK_KEY_BackSpace));
+    GlobalCommands_insert("ParentSelection", makeCallbackF(Scene_parentSelected));
+    GlobalCommands_insert("UnSelectSelection", makeCallbackF(Selection_Deselect), Accelerator(GDK_KEY_Escape));
+    GlobalCommands_insert("InvertSelection", makeCallbackF(Select_Invert), Accelerator('I'));
+    GlobalCommands_insert("SelectInside", makeCallbackF(Select_Inside));
+    GlobalCommands_insert("SelectTouching", makeCallbackF(Select_Touching));
+    GlobalCommands_insert("ExpandSelectionToEntities", makeCallbackF(Scene_ExpandSelectionToEntities),
+                          Accelerator('E', (GdkModifierType) (GDK_MOD1_MASK | GDK_CONTROL_MASK)));
+    GlobalCommands_insert("Preferences", makeCallbackF(PreferencesDialog_showDialog), Accelerator('P'));
+
+    GlobalCommands_insert("ToggleConsole", makeCallbackF(Console_ToggleShow), Accelerator('O'));
+    GlobalCommands_insert("ToggleEntityInspector", makeCallbackF(EntityInspector_ToggleShow), Accelerator('N'));
+    GlobalCommands_insert("EntityList", makeCallbackF(EntityList_toggleShown), Accelerator('L'));
+
+    GlobalCommands_insert("ShowHidden", makeCallbackF(Select_ShowAllHidden),
+                          Accelerator('H', (GdkModifierType) GDK_SHIFT_MASK));
+    GlobalCommands_insert("HideSelected", makeCallbackF(HideSelected), Accelerator('H'));
+
+    GlobalToggles_insert("DragVertices", makeCallbackF(SelectVertexMode),
+                         ToggleItem::AddCallbackCaller(g_vertexMode_button), Accelerator('V'));
+    GlobalToggles_insert("DragEdges", makeCallbackF(SelectEdgeMode), ToggleItem::AddCallbackCaller(g_edgeMode_button),
+                         Accelerator('E'));
+    GlobalToggles_insert("DragFaces", makeCallbackF(SelectFaceMode), ToggleItem::AddCallbackCaller(g_faceMode_button),
+                         Accelerator('F'));
+
+    GlobalCommands_insert("MirrorSelectionX", makeCallbackF(Selection_Flipx));
+    GlobalCommands_insert("RotateSelectionX", makeCallbackF(Selection_Rotatex));
+    GlobalCommands_insert("MirrorSelectionY", makeCallbackF(Selection_Flipy));
+    GlobalCommands_insert("RotateSelectionY", makeCallbackF(Selection_Rotatey));
+    GlobalCommands_insert("MirrorSelectionZ", makeCallbackF(Selection_Flipz));
+    GlobalCommands_insert("RotateSelectionZ", makeCallbackF(Selection_Rotatez));
+
+    GlobalCommands_insert("ArbitraryRotation", makeCallbackF(DoRotateDlg));
+    GlobalCommands_insert("ArbitraryScale", makeCallbackF(DoScaleDlg));
+
+    GlobalCommands_insert("BuildMenuCustomize", makeCallbackF(DoBuildMenu));
+
+    GlobalCommands_insert("FindBrush", makeCallbackF(DoFind));
+
+    GlobalCommands_insert("MapInfo", makeCallbackF(DoMapInfo), Accelerator('M'));
+
+
+    GlobalToggles_insert("ToggleClipper", makeCallbackF(ClipperMode), ToggleItem::AddCallbackCaller(g_clipper_button),
+                         Accelerator('X'));
+
+    GlobalToggles_insert("MouseTranslate", makeCallbackF(TranslateMode),
+                         ToggleItem::AddCallbackCaller(g_translatemode_button), Accelerator('W'));
+    GlobalToggles_insert("MouseRotate", makeCallbackF(RotateMode), ToggleItem::AddCallbackCaller(g_rotatemode_button),
+                         Accelerator('R'));
+    GlobalToggles_insert("MouseScale", makeCallbackF(ScaleMode), ToggleItem::AddCallbackCaller(g_scalemode_button));
+    GlobalToggles_insert("MouseDrag", makeCallbackF(DragMode), ToggleItem::AddCallbackCaller(g_dragmode_button),
+                         Accelerator('Q'));
+
+    GlobalCommands_insert("ColorSchemeOriginal", makeCallbackF(ColorScheme_Original));
+    GlobalCommands_insert("ColorSchemeQER", makeCallbackF(ColorScheme_QER));
+    GlobalCommands_insert("ColorSchemeBlackAndGreen", makeCallbackF(ColorScheme_Black));
+    GlobalCommands_insert("ColorSchemeYdnar", makeCallbackF(ColorScheme_Ydnar));
+    GlobalCommands_insert("ChooseTextureBackgroundColor", makeCallback(g_ColoursMenu.m_textureback));
+    GlobalCommands_insert("ChooseGridBackgroundColor", makeCallback(g_ColoursMenu.m_xyback));
+    GlobalCommands_insert("ChooseGridMajorColor", makeCallback(g_ColoursMenu.m_gridmajor));
+    GlobalCommands_insert("ChooseGridMinorColor", makeCallback(g_ColoursMenu.m_gridminor));
+    GlobalCommands_insert("ChooseSmallGridMajorColor", makeCallback(g_ColoursMenu.m_gridmajor_alt));
+    GlobalCommands_insert("ChooseSmallGridMinorColor", makeCallback(g_ColoursMenu.m_gridminor_alt));
+    GlobalCommands_insert("ChooseGridTextColor", makeCallback(g_ColoursMenu.m_gridtext));
+    GlobalCommands_insert("ChooseGridBlockColor", makeCallback(g_ColoursMenu.m_gridblock));
+    GlobalCommands_insert("ChooseBrushColor", makeCallback(g_ColoursMenu.m_brush));
+    GlobalCommands_insert("ChooseCameraBackgroundColor", makeCallback(g_ColoursMenu.m_cameraback));
+    GlobalCommands_insert("ChooseSelectedBrushColor", makeCallback(g_ColoursMenu.m_selectedbrush));
+    GlobalCommands_insert("ChooseCameraSelectedBrushColor", makeCallback(g_ColoursMenu.m_selectedbrush3d));
+    GlobalCommands_insert("ChooseClipperColor", makeCallback(g_ColoursMenu.m_clipper));
+    GlobalCommands_insert("ChooseOrthoViewNameColor", makeCallback(g_ColoursMenu.m_viewname));
+
+
+    GlobalCommands_insert("CSGSubtract", makeCallbackF(CSG_Subtract),
+                          Accelerator('U', (GdkModifierType) GDK_SHIFT_MASK));
+    GlobalCommands_insert("CSGMerge", makeCallbackF(CSG_Merge), Accelerator('U', (GdkModifierType) GDK_CONTROL_MASK));
+    GlobalCommands_insert("CSGHollow", makeCallbackF(CSG_MakeHollow));
+
+    Grid_registerCommands();
+
+    GlobalCommands_insert("SnapToGrid", makeCallbackF(Selection_SnapToGrid),
+                          Accelerator('G', (GdkModifierType) GDK_CONTROL_MASK));
+
+    GlobalCommands_insert("SelectAllOfType", makeCallbackF(Select_AllOfType),
+                          Accelerator('A', (GdkModifierType) GDK_SHIFT_MASK));
+
+    GlobalCommands_insert("TexRotateClock", makeCallbackF(Texdef_RotateClockwise),
+                          Accelerator(GDK_KEY_Next, (GdkModifierType) GDK_SHIFT_MASK));
+    GlobalCommands_insert("TexRotateCounter", makeCallbackF(Texdef_RotateAntiClockwise),
+                          Accelerator(GDK_KEY_Prior, (GdkModifierType) GDK_SHIFT_MASK));
+    GlobalCommands_insert("TexScaleUp", makeCallbackF(Texdef_ScaleUp),
+                          Accelerator(GDK_KEY_Up, (GdkModifierType) GDK_CONTROL_MASK));
+    GlobalCommands_insert("TexScaleDown", makeCallbackF(Texdef_ScaleDown),
+                          Accelerator(GDK_KEY_Down, (GdkModifierType) GDK_CONTROL_MASK));
+    GlobalCommands_insert("TexScaleLeft", makeCallbackF(Texdef_ScaleLeft),
+                          Accelerator(GDK_KEY_Left, (GdkModifierType) GDK_CONTROL_MASK));
+    GlobalCommands_insert("TexScaleRight", makeCallbackF(Texdef_ScaleRight),
+                          Accelerator(GDK_KEY_Right, (GdkModifierType) GDK_CONTROL_MASK));
+    GlobalCommands_insert("TexShiftUp", makeCallbackF(Texdef_ShiftUp),
+                          Accelerator(GDK_KEY_Up, (GdkModifierType) GDK_SHIFT_MASK));
+    GlobalCommands_insert("TexShiftDown", makeCallbackF(Texdef_ShiftDown),
+                          Accelerator(GDK_KEY_Down, (GdkModifierType) GDK_SHIFT_MASK));
+    GlobalCommands_insert("TexShiftLeft", makeCallbackF(Texdef_ShiftLeft),
+                          Accelerator(GDK_KEY_Left, (GdkModifierType) GDK_SHIFT_MASK));
+    GlobalCommands_insert("TexShiftRight", makeCallbackF(Texdef_ShiftRight),
+                          Accelerator(GDK_KEY_Right, (GdkModifierType) GDK_SHIFT_MASK));
+
+    GlobalCommands_insert("MoveSelectionDOWN", makeCallbackF(Selection_MoveDown), Accelerator(GDK_KEY_KP_Subtract));
+    GlobalCommands_insert("MoveSelectionUP", makeCallbackF(Selection_MoveUp), Accelerator(GDK_KEY_KP_Add));
+
+    GlobalCommands_insert("SelectNudgeLeft", makeCallbackF(Selection_NudgeLeft),
+                          Accelerator(GDK_KEY_Left, (GdkModifierType) GDK_MOD1_MASK));
+    GlobalCommands_insert("SelectNudgeRight", makeCallbackF(Selection_NudgeRight),
+                          Accelerator(GDK_KEY_Right, (GdkModifierType) GDK_MOD1_MASK));
+    GlobalCommands_insert("SelectNudgeUp", makeCallbackF(Selection_NudgeUp),
+                          Accelerator(GDK_KEY_Up, (GdkModifierType) GDK_MOD1_MASK));
+    GlobalCommands_insert("SelectNudgeDown", makeCallbackF(Selection_NudgeDown),
+                          Accelerator(GDK_KEY_Down, (GdkModifierType) GDK_MOD1_MASK));
+
+    Patch_registerCommands();
+    XYShow_registerCommands();
+
+    typedef FreeCaller<void(const Selectable &), ComponentMode_SelectionChanged> ComponentModeSelectionChangedCaller;
+    GlobalSelectionSystem().addSelectionChangeCallback(ComponentModeSelectionChangedCaller());
+
+    GlobalPreferenceSystem().registerPreference("DetachableMenus",
+                                                make_property_string(g_Layout_enableDetachableMenus.m_latched));
+    GlobalPreferenceSystem().registerPreference("PatchToolBar",
+                                                make_property_string(g_Layout_enablePatchToolbar.m_latched));
+    GlobalPreferenceSystem().registerPreference("PluginToolBar",
+                                                make_property_string(g_Layout_enablePluginToolbar.m_latched));
+    GlobalPreferenceSystem().registerPreference("QE4StyleWindows", make_property_string(g_Layout_viewStyle.m_latched));
+    GlobalPreferenceSystem().registerPreference("XYHeight", make_property_string(g_layout_globals.nXYHeight));
+    GlobalPreferenceSystem().registerPreference("XYWidth", make_property_string(g_layout_globals.nXYWidth));
+    GlobalPreferenceSystem().registerPreference("CamWidth", make_property_string(g_layout_globals.nCamWidth));
+    GlobalPreferenceSystem().registerPreference("CamHeight", make_property_string(g_layout_globals.nCamHeight));
+
+    GlobalPreferenceSystem().registerPreference("State", make_property_string(g_layout_globals.nState));
+    GlobalPreferenceSystem().registerPreference("PositionX", make_property_string(g_layout_globals.m_position.x));
+    GlobalPreferenceSystem().registerPreference("PositionY", make_property_string(g_layout_globals.m_position.y));
+    GlobalPreferenceSystem().registerPreference("Width", make_property_string(g_layout_globals.m_position.w));
+    GlobalPreferenceSystem().registerPreference("Height", make_property_string(g_layout_globals.m_position.h));
+
+    GlobalPreferenceSystem().registerPreference("CamWnd", make_property<WindowPositionTracker_String>(g_posCamWnd));
+    GlobalPreferenceSystem().registerPreference("XYWnd", make_property<WindowPositionTracker_String>(g_posXYWnd));
+    GlobalPreferenceSystem().registerPreference("YZWnd", make_property<WindowPositionTracker_String>(g_posYZWnd));
+    GlobalPreferenceSystem().registerPreference("XZWnd", make_property<WindowPositionTracker_String>(g_posXZWnd));
+
+    {
+        const char *ENGINEPATH_ATTRIBUTE =
+#if GDEF_OS_WINDOWS
+                "enginepath_win32"
+#elif GDEF_OS_MACOS
+                "enginepath_macos"
+#elif GDEF_OS_LINUX || GDEF_OS_BSD
+                "enginepath_linux"
 #else
 #error "unknown platform"
 #endif
-    ;
-    StringOutputStream path(256);
-    path << DirectoryCleaned(g_pGameDescription->getRequiredKeyValue(ENGINEPATH_ATTRIBUTE));
-    g_strEnginePath = path.c_str();
-  }
+        ;
+        StringOutputStream path(256);
+        path << DirectoryCleaned(g_pGameDescription->getRequiredKeyValue(ENGINEPATH_ATTRIBUTE));
+        g_strEnginePath = path.c_str();
+    }
+
+    GlobalPreferenceSystem().registerPreference("EnginePath", make_property_string(g_strEnginePath));
 
-  GlobalPreferenceSystem().registerPreference("EnginePath", CopiedStringImportStringCaller(g_strEnginePath), CopiedStringExportStringCaller(g_strEnginePath));
+    GlobalPreferenceSystem().registerPreference("DisableEnginePath", make_property_string(g_disableEnginePath));
+    GlobalPreferenceSystem().registerPreference("DisableHomePath", make_property_string(g_disableHomePath));
+
+    for (int i = 0; i < g_pakPathCount; i++) {
+        std::string label = "PakPath" + std::to_string(i);
+        GlobalPreferenceSystem().registerPreference(label.c_str(), make_property_string(g_strPakPath[i]));
+    }
 
-  g_Layout_viewStyle.useLatched();
-  g_Layout_enableDetachableMenus.useLatched();
-  g_Layout_enablePatchToolbar.useLatched();
-  g_Layout_enablePluginToolbar.useLatched();
+    g_Layout_viewStyle.useLatched();
+    g_Layout_enableDetachableMenus.useLatched();
+    g_Layout_enablePatchToolbar.useLatched();
+    g_Layout_enablePluginToolbar.useLatched();
 
-  Layout_registerPreferencesPage();
-  Paths_registerPreferencesPage();
+    Layout_registerPreferencesPage();
+    Paths_registerPreferencesPage();
 
-  g_brushCount.setCountChangedCallback(FreeCaller<QE_brushCountChanged>());
-  g_entityCount.setCountChangedCallback(FreeCaller<QE_entityCountChanged>());
-  GlobalEntityCreator().setCounter(&g_entityCount);
+    g_brushCount.setCountChangedCallback(makeCallbackF(QE_brushCountChanged));
+    g_entityCount.setCountChangedCallback(makeCallbackF(QE_entityCountChanged));
+    GlobalEntityCreator().setCounter(&g_entityCount);
 
-  GLWidget_sharedContextCreated = GlobalGL_sharedContextCreated;
-  GLWidget_sharedContextDestroyed = GlobalGL_sharedContextDestroyed;
+    GLWidget_sharedContextCreated = GlobalGL_sharedContextCreated;
+    GLWidget_sharedContextDestroyed = GlobalGL_sharedContextDestroyed;
 
-  GlobalEntityClassManager().attach(g_WorldspawnColourEntityClassObserver);
+    GlobalEntityClassManager().attach(g_WorldspawnColourEntityClassObserver);
 }
 
 void MainFrame_Destroy()
 {
-  GlobalEntityClassManager().detach(g_WorldspawnColourEntityClassObserver);
+    GlobalEntityClassManager().detach(g_WorldspawnColourEntityClassObserver);
 
-  GlobalEntityCreator().setCounter(0);
-  g_entityCount.setCountChangedCallback(Callback());
-  g_brushCount.setCountChangedCallback(Callback());
+    GlobalEntityCreator().setCounter(0);
+    g_entityCount.setCountChangedCallback(Callback<void()>());
+    g_brushCount.setCountChangedCallback(Callback<void()>());
 }
 
 
 void GLWindow_Construct()
 {
-  GlobalPreferenceSystem().registerPreference("MouseButtons", IntImportStringCaller(g_glwindow_globals.m_nMouseType), IntExportStringCaller(g_glwindow_globals.m_nMouseType));
+    GlobalPreferenceSystem().registerPreference("MouseButtons", make_property_string(g_glwindow_globals.m_nMouseType));
 }
 
 void GLWindow_Destroy()