From 9d3d2040182af8284fe9c6fdf26950cfa738c4f2 Mon Sep 17 00:00:00 2001 From: Garux Date: Thu, 27 Oct 2022 09:10:31 +0300 Subject: [PATCH] Qt --- .github/workflows/build.yml | 6 +- COMPILING | 38 +- Makefile | 84 +- contrib/bobtoolz/DBobView.cpp | 108 +- contrib/bobtoolz/DBobView.h | 35 +- contrib/bobtoolz/DBrush.cpp | 170 +- contrib/bobtoolz/DBrush.h | 2 +- contrib/bobtoolz/DEntity.cpp | 101 +- contrib/bobtoolz/DEntity.h | 2 +- contrib/bobtoolz/DMap.cpp | 34 +- contrib/bobtoolz/DMap.h | 2 +- contrib/bobtoolz/DShape.cpp | 4 +- contrib/bobtoolz/DTrainDrawer.cpp | 6 +- contrib/bobtoolz/DVisDrawer.cpp | 14 +- contrib/bobtoolz/bobToolz-GTK.cpp | 53 +- contrib/bobtoolz/bobToolz-GTK.h | 2 +- contrib/bobtoolz/bsploader.cpp | 4 +- contrib/bobtoolz/ctfToolz-GTK.cpp | 2 +- contrib/bobtoolz/dialogs/dialogs-gtk.cpp | 2295 +++---------- contrib/bobtoolz/dialogs/dialogs-gtk.h | 40 +- contrib/bobtoolz/funchandlers-GTK.cpp | 106 +- contrib/bobtoolz/funchandlers-ctf-GTK.cpp | 2 +- contrib/bobtoolz/funchandlers.h | 8 +- contrib/bobtoolz/lists.cpp | 23 +- contrib/bobtoolz/lists.h | 4 +- contrib/bobtoolz/misc.cpp | 25 +- contrib/bobtoolz/misc.h | 3 +- contrib/bobtoolz/shapes.cpp | 2 - contrib/bobtoolz/visfind.cpp | 2 +- contrib/brushexport/callbacks.cpp | 109 +- contrib/brushexport/callbacks.h | 39 +- contrib/brushexport/export.cpp | 4 +- contrib/brushexport/interface.cpp | 282 +- contrib/brushexport/plugin.cpp | 25 +- contrib/brushexport/plugin.h | 3 +- contrib/brushexport/support.cpp | 33 - contrib/brushexport/support.h | 20 - contrib/meshtex/AllocatedMatrix.h | 5 +- contrib/meshtex/GeneralFunctionDialog.cpp | 747 ++--- contrib/meshtex/GeneralFunctionDialog.h | 24 +- contrib/meshtex/GenericDialog.cpp | 105 +- contrib/meshtex/GenericDialog.h | 68 +- contrib/meshtex/GenericMainMenu.h | 7 +- contrib/meshtex/GenericPluginUI.cpp | 162 +- contrib/meshtex/GenericPluginUI.h | 140 +- contrib/meshtex/GenericPluginUIMessages.h | 12 +- contrib/meshtex/GetInfoDialog.cpp | 157 +- contrib/meshtex/GetInfoDialog.h | 11 +- contrib/meshtex/MainMenu.h | 5 +- contrib/meshtex/MeshEntity.cpp | 24 +- contrib/meshtex/MeshEntity.h | 17 +- contrib/meshtex/MeshEntityMessages.h | 5 +- contrib/meshtex/MeshVisitor.h | 5 +- contrib/meshtex/PluginModule.cpp | 2 +- contrib/meshtex/PluginModule.h | 5 +- contrib/meshtex/PluginProperties.h | 5 +- contrib/meshtex/PluginUI.cpp | 6 +- contrib/meshtex/PluginUI.h | 5 +- contrib/meshtex/PluginUIMessages.h | 11 +- contrib/meshtex/RefCounted.h | 5 +- contrib/meshtex/SetScaleDialog.cpp | 697 ++-- contrib/meshtex/SetScaleDialog.h | 28 +- contrib/meshtex/UtilityMacros.h | 5 +- contrib/prtview/AboutDialog.cpp | 84 +- contrib/prtview/ConfigDialog.cpp | 541 +--- contrib/prtview/LoadPortalFileDialog.cpp | 146 +- contrib/prtview/LoadPortalFileDialog.h | 2 +- contrib/prtview/portals.cpp | 336 +- contrib/prtview/portals.h | 53 +- contrib/prtview/prtview.cpp | 95 +- contrib/prtview/prtview.h | 6 +- contrib/shaderplug/shaderplug.cpp | 63 +- contrib/sunplug/sunplug.cpp | 431 +-- contrib/ufoaiplug/ufoai.cpp | 20 +- contrib/ufoaiplug/ufoai_filters.cpp | 12 +- contrib/ufoaiplug/ufoai_gtk.cpp | 36 - contrib/ufoaiplug/ufoai_gtk.h | 1 - docs/shaderManual/general-directives.html | 1 - docs/shaderManual/stage-directives.html | 8 +- include/icamera.h | 1 - include/igl.h | 2860 +--------------- include/igtkgl.h | 10 - include/irender.h | 51 +- include/qerplugin.h | 53 +- include/warnings.h | 27 - install-dlls-msys2-mingw.sh | 8 +- libs/debugging/debugging.h | 1 - libs/entitylib.h | 226 +- libs/gtkutil/accelerator.cpp | 533 +-- libs/gtkutil/accelerator.h | 102 +- libs/gtkutil/accelerator_translate.h | 553 ++++ libs/gtkutil/button.cpp | 139 - libs/gtkutil/button.h | 46 - libs/gtkutil/clipboard.cpp | 127 +- libs/gtkutil/closure.cpp | 22 - libs/gtkutil/closure.h | 67 - libs/gtkutil/container.h | 37 - libs/gtkutil/cursor.cpp | 66 - libs/gtkutil/cursor.h | 304 +- libs/gtkutil/dialog.cpp | 261 +- libs/gtkutil/dialog.h | 84 +- libs/gtkutil/entry.h | 26 +- libs/gtkutil/fbo.h | 63 + libs/gtkutil/filechooser.cpp | 192 +- libs/gtkutil/filechooser.h | 10 +- libs/gtkutil/frame.cpp | 33 - libs/gtkutil/glfont.cpp | 447 ++- libs/gtkutil/glfont.h | 4 +- libs/gtkutil/glwidget.cpp | 233 +- libs/gtkutil/glwidget.h | 13 +- libs/gtkutil/guisettings.cpp | 137 + .../multimon.h => libs/gtkutil/guisettings.h | 37 +- libs/gtkutil/idledraw.h | 30 +- libs/gtkutil/image.cpp | 48 +- libs/gtkutil/image.h | 12 +- libs/gtkutil/menu.cpp | 240 +- libs/gtkutil/menu.h | 32 +- libs/gtkutil/messagebox.cpp | 201 +- libs/gtkutil/messagebox.h | 3 +- libs/gtkutil/mousepresses.h | 104 + libs/gtkutil/nonmodal.h | 176 +- libs/gtkutil/paned.cpp | 102 - libs/gtkutil/paned.h | 25 - libs/gtkutil/pointer.cpp | 22 - libs/gtkutil/spinbox.h | 118 + libs/gtkutil/toolbar.cpp | 59 +- libs/gtkutil/toolbar.h | 17 +- libs/gtkutil/widget.h | 129 +- libs/gtkutil/window.cpp | 169 - libs/gtkutil/window.h | 177 - libs/gtkutil/xorrectangle.h | 74 +- libs/maplib.h | 2 +- libs/math/aabb.h | 30 +- libs/math/frustum.h | 10 +- libs/math/matrix.h | 12 +- libs/pivot.h | 52 +- libs/render.h | 315 +- libs/scenelib.h | 1 - libs/script/scripttokeniser.h | 4 +- libs/script/scripttokenwriter.h | 2 +- libs/stream/textstream.h | 21 +- libs/string/pooledstring.h | 4 +- libs/stringio.h | 4 +- libs/timer.h | 14 + libs/transformlib.h | 6 +- libs/undolib.h | 1 - libs/xml/xmltextags.cpp | 22 +- libs/xml/xmltextags.h | 18 +- plugins/assmodel/model.cpp | 35 +- plugins/entity/curve.h | 4 +- plugins/entity/doom3group.cpp | 17 +- plugins/entity/group.cpp | 4 +- plugins/entity/light.cpp | 214 +- plugins/entity/light.h | 3 +- plugins/entity/namedentity.h | 2 +- plugins/entity/targetable.h | 18 +- plugins/image/bmp.cpp | 2 +- plugins/md3model/md5.cpp | 2 +- plugins/md3model/model.h | 43 +- plugins/model/model.cpp | 35 +- plugins/shaders/shaders.cpp | 2 - plugins/shaders/shaders.h | 3 +- plugins/vfspk3/vfs.h | 3 +- radiant/autosave.cpp | 6 +- radiant/brush.cpp | 4 +- radiant/brush.h | 96 +- radiant/brush_primit.cpp | 55 +- radiant/brush_primit.h | 5 +- radiant/brushmanip.cpp | 156 +- radiant/brushmanip.h | 18 +- radiant/brushmodule.cpp | 6 +- radiant/build.cpp | 539 ++- radiant/build.h | 5 +- radiant/camwindow.cpp | 885 +++-- radiant/camwindow.h | 28 +- radiant/clippertool.cpp | 25 +- radiant/colors.cpp | 351 ++ libs/gtkutil/pointer.h => radiant/colors.h | 20 +- radiant/commands.cpp | 532 ++- radiant/commands.h | 8 +- radiant/console.cpp | 119 +- radiant/console.h | 4 +- radiant/csg.cpp | 405 +-- radiant/csg.h | 6 +- radiant/dialog.cpp | 547 ++-- radiant/dialog.h | 125 +- radiant/entity.cpp | 44 +- radiant/entity.h | 6 +- radiant/entityinspector.cpp | 1523 +++------ radiant/entityinspector.h | 4 +- radiant/entitylist.cpp | 542 +--- radiant/entitylist.h | 3 +- radiant/error.cpp | 4 +- radiant/feedback.cpp | 147 +- radiant/feedback.h | 24 +- radiant/filterbar.cpp | 198 +- radiant/filterbar.h | 4 +- radiant/filters.cpp | 108 +- radiant/filters.h | 3 +- radiant/findtexturedialog.cpp | 195 +- radiant/findtexturedialog.h | 3 +- radiant/glwidget.cpp | 5 - radiant/grid.cpp | 24 +- radiant/grid.h | 3 +- radiant/groupdialog.cpp | 124 +- radiant/groupdialog.h | 13 +- radiant/gtkdlgs.cpp | 1060 ++---- radiant/gtkdlgs.h | 13 +- radiant/gtkmisc.cpp | 218 +- radiant/gtkmisc.h | 36 +- radiant/gtktheme.cpp | 652 ---- radiant/gtktheme.h | 11 - radiant/help.cpp | 20 +- radiant/help.h | 3 +- radiant/main.cpp | 254 +- radiant/mainframe.cpp | 2878 ++++------------- radiant/mainframe.h | 44 +- radiant/map.cpp | 390 +-- radiant/map.h | 15 +- radiant/modelwindow.cpp | 587 ++-- radiant/modelwindow.h | 7 +- radiant/mru.cpp | 67 +- radiant/mru.h | 3 +- radiant/multimon.cpp | 97 - radiant/patch.cpp | 108 +- radiant/patch.h | 88 +- radiant/patchdialog.cpp | 1035 +----- radiant/patchdialog.h | 9 +- radiant/patchmanip.cpp | 1078 +++--- radiant/patchmanip.h | 15 +- radiant/plugin.cpp | 9 +- radiant/pluginapi.cpp | 12 - radiant/pluginapi.h | 1 - radiant/pluginmanager.cpp | 14 +- radiant/pluginmanager.h | 4 +- radiant/pluginmenu.cpp | 50 +- radiant/pluginmenu.h | 5 +- radiant/plugintoolbar.cpp | 74 +- radiant/plugintoolbar.h | 6 +- radiant/points.cpp | 27 +- radiant/points.h | 3 +- radiant/preferences.cpp | 366 +-- radiant/preferences.h | 118 +- radiant/qe3.cpp | 36 +- radiant/qgl.cpp | 1363 +------- radiant/qgl.h | 2 - radiant/renderstate.cpp | 998 ++---- radiant/scenegraph.cpp | 15 +- radiant/select.cpp | 1012 ++++-- radiant/select.h | 30 +- radiant/selection.cpp | 354 +- radiant/server.cpp | 1 - radiant/server.h | 3 +- radiant/stacktrace.cpp | 2 +- radiant/stacktrace.h | 3 +- radiant/surfacedialog.cpp | 1984 +++--------- radiant/surfacedialog.h | 20 +- radiant/textureentry.h | 56 +- radiant/textures.cpp | 79 +- radiant/texwindow.cpp | 2521 ++++++--------- radiant/texwindow.h | 23 +- radiant/theme.cpp | 182 ++ libs/gtkutil/container.cpp => radiant/theme.h | 5 +- radiant/tools.cpp | 442 +++ libs/gtkutil/frame.h => radiant/tools.h | 12 +- radiant/treemodel.cpp | 1582 ++------- radiant/treemodel.h | 11 +- radiant/undo.cpp | 5 +- radiant/url.cpp | 35 +- radiant/view.h | 2 +- radiant/watchbsp.cpp | 51 +- radiant/winding.h | 2 +- radiant/windowobservers.cpp | 145 +- radiant/windowobservers.h | 32 +- radiant/xywindow.cpp | 1231 +++---- radiant/xywindow.h | 84 +- setup/data/tools/.gtkrc-2.0.win | 9 - .../data/tools/bitmaps/MyriadPro-Regular.ttf | Bin 0 -> 97260 bytes setup/data/tools/bitmaps/radiant.ico | Bin 0 -> 55465 bytes setup/data/tools/bitmaps/texbro_tags.png | Bin 283 -> 0 bytes .../data/tools/gl/lighting_DBS_XY_Z_arbfp1.cg | 92 - .../data/tools/gl/lighting_DBS_XY_Z_arbvp1.cg | 78 - setup/data/tools/gl/lighting_DBS_omni_fp.glp | 86 - setup/data/tools/gl/lighting_DBS_omni_vp.glp | 410 --- setup/data/tools/gl/utils.cg | 36 - setup/data/tools/gl/zfill_arbfp1.cg | 47 - setup/data/tools/gl/zfill_arbvp1.cg | 49 - setup/data/tools/gl/zfill_fp.glp | 19 - setup/data/tools/gl/zfill_vp.glp | 384 --- 289 files changed, 13557 insertions(+), 33481 deletions(-) delete mode 100644 contrib/brushexport/support.cpp delete mode 100644 contrib/brushexport/support.h delete mode 100644 include/warnings.h create mode 100644 libs/gtkutil/accelerator_translate.h delete mode 100644 libs/gtkutil/button.cpp delete mode 100644 libs/gtkutil/button.h delete mode 100644 libs/gtkutil/closure.cpp delete mode 100644 libs/gtkutil/closure.h delete mode 100644 libs/gtkutil/container.h delete mode 100644 libs/gtkutil/cursor.cpp create mode 100644 libs/gtkutil/fbo.h delete mode 100644 libs/gtkutil/frame.cpp create mode 100644 libs/gtkutil/guisettings.cpp rename radiant/multimon.h => libs/gtkutil/guisettings.h (50%) create mode 100644 libs/gtkutil/mousepresses.h delete mode 100644 libs/gtkutil/paned.cpp delete mode 100644 libs/gtkutil/paned.h delete mode 100644 libs/gtkutil/pointer.cpp create mode 100644 libs/gtkutil/spinbox.h delete mode 100644 libs/gtkutil/window.cpp delete mode 100644 libs/gtkutil/window.h create mode 100644 radiant/colors.cpp rename libs/gtkutil/pointer.h => radiant/colors.h (68%) delete mode 100644 radiant/gtktheme.cpp delete mode 100644 radiant/gtktheme.h delete mode 100644 radiant/multimon.cpp create mode 100644 radiant/theme.cpp rename libs/gtkutil/container.cpp => radiant/theme.h (90%) create mode 100644 radiant/tools.cpp rename libs/gtkutil/frame.h => radiant/tools.h (76%) delete mode 100644 setup/data/tools/.gtkrc-2.0.win create mode 100644 setup/data/tools/bitmaps/MyriadPro-Regular.ttf create mode 100644 setup/data/tools/bitmaps/radiant.ico delete mode 100644 setup/data/tools/bitmaps/texbro_tags.png delete mode 100644 setup/data/tools/gl/lighting_DBS_XY_Z_arbfp1.cg delete mode 100644 setup/data/tools/gl/lighting_DBS_XY_Z_arbvp1.cg delete mode 100644 setup/data/tools/gl/lighting_DBS_omni_fp.glp delete mode 100644 setup/data/tools/gl/lighting_DBS_omni_vp.glp delete mode 100644 setup/data/tools/gl/utils.cg delete mode 100644 setup/data/tools/gl/zfill_arbfp1.cg delete mode 100644 setup/data/tools/gl/zfill_arbvp1.cg delete mode 100644 setup/data/tools/gl/zfill_fp.glp delete mode 100644 setup/data/tools/gl/zfill_vp.glp diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 976ba45b..ed630e76 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: steps: - uses: msys2/setup-msys2@v2 with: - install: ${{ matrix.prefix }}-gtk2 ${{ matrix.prefix }}-gtkglext ${{ matrix.prefix }}-gtk-engines ${{ matrix.prefix }}-gtk-engine-murrine svn git + install: ${{ matrix.prefix }}-qt5-base ${{ matrix.prefix }}-libxml2 svn git msystem: ${{ matrix.msystem }} path-type: minimal release: false @@ -39,7 +39,7 @@ jobs: - name: Build run: | - make DOWNLOAD_GAMEPACKS=no MAKEFILE_CONF=msys2-Makefile.conf BUILD=release -j$(nproc) CXXFLAGS="-Wno-deprecated-declarations" 2> windows-warn-${{ matrix.arch }}.log + make DOWNLOAD_GAMEPACKS=no MAKEFILE_CONF=msys2-Makefile.conf BUILD=release -j$(nproc) 2> windows-warn-${{ matrix.arch }}.log wget https://www.dropbox.com/s/b1xpajzfa6yjlzf/netradiant-custom-extra-gamepacks.zip unzip -o netradiant-custom-extra-gamepacks.zip -d "install" wget https://www.dropbox.com/s/hcgkwzzmja3m6c0/netradiant-custom-extra-win.zip @@ -68,7 +68,7 @@ jobs: - name: Install tools run: | sudo apt-get -qq update - sudo apt-get -y install mesa-common-dev libgtk2.0-dev libpango1.0-dev libgtkglext1-dev + sudo apt-get -y install mesa-common-dev qtbase5-dev - uses: actions/checkout@v2 with: submodules: recursive diff --git a/COMPILING b/COMPILING index 215c5eef..1904f81f 100644 --- a/COMPILING +++ b/COMPILING @@ -27,8 +27,8 @@ environment: - svn >= 1.1 (some build steps use svn) dependencies: -- gtk+ >= 2.4.0 (requires glib, atk, pango, iconv, etc) -- gtkglext >= 1.0.0 (requires opengl) +- qt5 +- glib - libxml2 >= 2.0.0 - zlib >= 1.2.0 (for archivezip module) - libpng >= 1.2.0 (for imagepng module) @@ -67,7 +67,7 @@ run: Switch into the install folder, and run NetRadiant.app -Win32 (using MSYS2)(recommended) +Win32 (using MSYS2) ================== environment: @@ -75,9 +75,9 @@ environment: - from msys2_shell: pacman -S --needed base-devel 32 bit: - pacman -S --needed mingw-w64-i686-{toolchain,gtk2,gtkglext} + pacman -S --needed mingw-w64-i686-{toolchain,qt5-base,libxml2} 64 bit: - pacman -S mingw-w64-x86_64-{toolchain,gtk2,gtkglext} + pacman -S --needed mingw-w64-x86_64-{toolchain,qt5-base,libxml2} these are only strictly required for gamepacks: pacman -S --needed unzip svn git @@ -90,31 +90,3 @@ build: make MAKEFILE_CONF=msys2-Makefile.conf DEPENDENCIES_CHECK=off DOWNLOAD_GAMEPACKS=no INSTALL_DLLS=no BUILD=debug RADIANT_ABOUTMSG="NetRadiant custom dev build" -j$(nproc) run: - in the "install" directory, double click radiant.exe - - -Win32 (using MinGW) -================== - -environment: -- MinGW (http://www.mingw.org/wiki/Getting_Started) - Install this to c:\mingw, and select the components C compiler, C++ compiler - and MSYS Basic System -- Start the MSYS shell once, then exit it -- Prepackaged Radiant dependencies (Gtk and other stuff): - http://www.icculus.org/netradiant/files/netradiant-dependencies-mingw32-20101211-7z.exe - Extract this one to - c:\mingw\msys\1.0\home\username - (if you do this with 7zip, keep the "netradiant-dependencies-mingw32" folder - name of the contents) -- now download the source from the MSYS shell, if you don't already have it: - ~/netradiant-dependencies-mingw32/util/bin/git clone git://git.icculus.org/divverent/netradiant.git - -build: -- Start the MSYS shell -- Switch to the directory with NetRadiant-custom source -- make MAKEFILE_CONF=mingw-Makefile.conf - -run: -- in the "install" directory, double click radiant.exe -- if you get a DLL not found error, copy the DLL from either c:\mingw\bin or - from c:\mingw\msys\1.0\bin to the "install" directory diff --git a/Makefile b/Makefile index 0e1d754a..fcc89e45 100644 --- a/Makefile +++ b/Makefile @@ -67,15 +67,15 @@ LIBS_XML ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) li CPPFLAGS_PNG ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) libpng --cflags $(STDERR_TO_DEVNULL)) LIBS_PNG ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) libpng --libs-only-L $(STDERR_TO_DEVNULL)) \ $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) libpng --libs-only-l $(STDERR_TO_DEVNULL)) -CPPFLAGS_GTK ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) gtk+-2.0 --cflags $(STDERR_TO_DEVNULL)) -LIBS_GTK ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) gtk+-2.0 --libs-only-L $(STDERR_TO_DEVNULL)) \ - $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) gtk+-2.0 --libs-only-l $(STDERR_TO_DEVNULL)) -CPPFLAGS_PANGOFT2 ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) pangoft2 --cflags $(STDERR_TO_DEVNULL)) -LIBS_PANGOFT2 ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) pangoft2 --libs-only-L $(STDERR_TO_DEVNULL)) \ - $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) pangoft2 --libs-only-l $(STDERR_TO_DEVNULL)) -CPPFLAGS_GTKGLEXT ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) gtkglext-1.0 --cflags $(STDERR_TO_DEVNULL)) -LIBS_GTKGLEXT ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) gtkglext-1.0 --libs-only-L $(STDERR_TO_DEVNULL)) \ - $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) gtkglext-1.0 --libs-only-l $(STDERR_TO_DEVNULL)) +CPPFLAGS_QTCORE ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) Qt5Core --cflags $(STDERR_TO_DEVNULL)) -DQT_NO_KEYWORDS +LIBS_QTCORE ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) Qt5Core --libs-only-L $(STDERR_TO_DEVNULL)) \ + $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) Qt5Core --libs-only-l $(STDERR_TO_DEVNULL)) +CPPFLAGS_QTGUI ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) Qt5Gui --cflags $(STDERR_TO_DEVNULL)) +LIBS_QTGUI ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) Qt5Gui --libs-only-L $(STDERR_TO_DEVNULL)) \ + $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) Qt5Gui --libs-only-l $(STDERR_TO_DEVNULL)) +CPPFLAGS_QTWIDGETS ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) Qt5Widgets --cflags $(STDERR_TO_DEVNULL)) +LIBS_QTWIDGETS ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) Qt5Widgets --libs-only-L $(STDERR_TO_DEVNULL)) \ + $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) Qt5Widgets --libs-only-l $(STDERR_TO_DEVNULL)) CPPFLAGS_GL ?= LIBS_GL ?= -lGL # -lopengl32 on Win32 CPPFLAGS_DL ?= @@ -98,7 +98,7 @@ DEPENDENCIES_CHECK ?= quiet endif # these are used on Win32 only -GTKDIR ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) gtk+-2.0 --variable=prefix $(STDERR_TO_DEVNULL)) +GTKDIR ?= $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKGCONFIG) Qt5Widgets --variable=prefix $(STDERR_TO_DEVNULL)) WHICHDLL ?= which DLLINSTALL ?= install-dlls.sh @@ -240,7 +240,6 @@ ifeq ($(OS),Darwin) # workaround: http://developer.apple.com/qa/qa2007/qa1567.html LIBS_GL += -lX11 -dylib_file /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib - LIBS_GTKGLEXT += -lX11 -dylib_file /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib # workaround: we have no "ldd" for OS X, so... LDD = OTOOL = otool @@ -379,9 +378,9 @@ dependencies-check: checkheader libxml2-dev libxml/xpath.h xmlXPathInit "$(CPPFLAGS_XML)" "$(LIBS_XML)"; \ checkheader libpng12-dev png.h png_create_read_struct "$(CPPFLAGS_PNG)" "$(LIBS_PNG)"; \ checkheader "mesa-common-dev (or another OpenGL library)" GL/gl.h glClear "$(CPPFLAGS_GL)" "$(LIBS_GL)"; \ - checkheader libgtk2.0-dev gtk/gtkdialog.h gtk_dialog_run "$(CPPFLAGS_GTK)" "$(LIBS_GTK)"; \ - checkheader libpango1.0-dev pango/pangoft2.h pango_ft2_font_map_new "$(CPPFLAGS_PANGOFT2)" "$(LIBS_PANGOFT2)"; \ - checkheader libgtkglext1-dev gtk/gtkglwidget.h gtk_widget_get_gl_context "$(CPPFLAGS_GTKGLEXT)" "$(LIBS_GTKGLEXT)"; \ + checkheader Qt5Core QCoreApplication QCoreApplication::exec "$(CPPFLAGS_QTCORE)" "$(LIBS_QTCORE)"; \ + checkheader Qt5Gui QGuiApplication QGuiApplication::exec "$(CPPFLAGS_QTGUI)" "$(LIBS_QTGUI)"; \ + checkheader Qt5Widgets QApplication QApplication::exec "$(CPPFLAGS_QTWIDGETS)" "$(LIBS_QTWIDGETS)"; \ [ "$(OS)" != "Win32" ] && checkheader libc6-dev dlfcn.h dlopen "$(CPPFLAGS_DL)" "$(LIBS_DL)"; \ checkheader zlib1g-dev zlib.h zlibVersion "$(CPPFLAGS_ZLIB)" "$(LIBS_ZLIB)"; \ [ "$$failed" = "0" ] && $(ECHO) All required libraries have been found! @@ -830,8 +829,8 @@ libetclib.$(A): \ libs/etclib.o \ $(INSTALLDIR)/radiant.$(EXE): LDFLAGS_EXTRA := $(MWINDOWS) -$(INSTALLDIR)/radiant.$(EXE): LIBS_EXTRA := $(LIBS_GL) $(LIBS_DL) $(LIBS_XML) $(LIBS_GLIB) $(LIBS_GTK) $(LIBS_GTKGLEXT) $(LIBS_ZLIB) $(LIBS_PANGOFT2) -$(INSTALLDIR)/radiant.$(EXE): CPPFLAGS_EXTRA := $(CPPFLAGS_GL) $(CPPFLAGS_DL) $(CPPFLAGS_XML) $(CPPFLAGS_GLIB) $(CPPFLAGS_GTK) $(CPPFLAGS_GTKGLEXT) $(CPPFLAGS_PANGOFT2) -Ilibs -Iinclude +$(INSTALLDIR)/radiant.$(EXE): LIBS_EXTRA := $(LIBS_GL) $(LIBS_DL) $(LIBS_XML) $(LIBS_GLIB) $(LIBS_QTCORE) $(LIBS_QTGUI) $(LIBS_QTWIDGETS) $(LIBS_ZLIB) +$(INSTALLDIR)/radiant.$(EXE): CPPFLAGS_EXTRA := $(CPPFLAGS_GL) $(CPPFLAGS_DL) $(CPPFLAGS_XML) $(CPPFLAGS_GLIB) $(CPPFLAGS_QTCORE) $(CPPFLAGS_QTGUI) $(CPPFLAGS_QTWIDGETS) -Ilibs -Iinclude $(INSTALLDIR)/radiant.$(EXE): \ radiant/autosave.o \ radiant/brushmanip.o \ @@ -844,6 +843,7 @@ $(INSTALLDIR)/radiant.$(EXE): \ radiant/build.o \ radiant/camwindow.o \ radiant/clippertool.o \ + radiant/colors.o \ radiant/commands.o \ radiant/console.o \ radiant/csg.o \ @@ -868,14 +868,12 @@ $(INSTALLDIR)/radiant.$(EXE): \ radiant/groupdialog.o \ radiant/gtkdlgs.o \ radiant/gtkmisc.o \ - radiant/gtktheme.o \ radiant/help.o \ radiant/image.o \ radiant/mainframe.o \ radiant/main.o \ radiant/map.o \ radiant/modelwindow.o \ - $(if $(findstring Win32,$(OS)),radiant/multimon.o,) \ radiant/mru.o \ radiant/nullmodel.o \ radiant/parse.o \ @@ -906,6 +904,8 @@ $(INSTALLDIR)/radiant.$(EXE): \ radiant/texmanip.o \ radiant/textures.o \ radiant/texwindow.o \ + radiant/theme.o \ + radiant/tools.o \ radiant/treemodel.o \ radiant/undo.o \ radiant/url.o \ @@ -936,30 +936,23 @@ libprofile.$(A): \ libs/profile/file.o \ libs/profile/profile.o \ -libgtkutil.$(A): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_GTK) $(CPPFLAGS_GTKGLEXT) $(CPPFLAGS_PANGOFT2) -Ilibs -Iinclude +libgtkutil.$(A): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_QTCORE) $(CPPFLAGS_QTGUI) $(CPPFLAGS_QTWIDGETS) -Ilibs -Iinclude libgtkutil.$(A): \ libs/gtkutil/accelerator.o \ - libs/gtkutil/button.o \ libs/gtkutil/clipboard.o \ - libs/gtkutil/closure.o \ - libs/gtkutil/container.o \ - libs/gtkutil/cursor.o \ libs/gtkutil/dialog.o \ libs/gtkutil/entry.o \ libs/gtkutil/filechooser.o \ - libs/gtkutil/frame.o \ libs/gtkutil/glfont.o \ libs/gtkutil/glwidget.o \ + libs/gtkutil/guisettings.o \ libs/gtkutil/idledraw.o \ libs/gtkutil/image.o \ libs/gtkutil/menu.o \ libs/gtkutil/messagebox.o \ libs/gtkutil/nonmodal.o \ - libs/gtkutil/paned.o \ - libs/gtkutil/pointer.o \ libs/gtkutil/toolbar.o \ libs/gtkutil/widget.o \ - libs/gtkutil/window.o \ libs/gtkutil/xorrectangle.o \ libxmllib.$(A): CPPFLAGS_EXTRA := $(CPPFLAGS_XML) $(CPPFLAGS_GLIB) -Ilibs -Iinclude @@ -994,7 +987,7 @@ $(INSTALLDIR)/modules/archivepak.$(DLL): \ plugins/archivepak/pak.o \ plugins/archivepak/plugin.o \ -$(INSTALLDIR)/modules/entity.$(DLL): CPPFLAGS_EXTRA := -Ilibs -Iinclude +$(INSTALLDIR)/modules/entity.$(DLL): CPPFLAGS_EXTRA := -Ilibs -Iinclude $(CPPFLAGS_QTGUI) $(INSTALLDIR)/modules/entity.$(DLL): \ plugins/entity/angle.o \ plugins/entity/angles.o \ @@ -1065,7 +1058,7 @@ ifneq ($(OS),Win32) $(INSTALLDIR)/modules/assmodel.$(DLL): LDFLAGS_EXTRA := -Wl,-rpath '-Wl,$$ORIGIN/..' endif $(INSTALLDIR)/modules/assmodel.$(DLL): LIBS_EXTRA := -lassimp_ -L$(INSTALLDIR) -$(INSTALLDIR)/modules/assmodel.$(DLL): CPPFLAGS_EXTRA := -Ilibs -Iinclude -Ilibs/assimp/include +$(INSTALLDIR)/modules/assmodel.$(DLL): CPPFLAGS_EXTRA := -Ilibs -Iinclude -Ilibs/assimp/include $(CPPFLAGS_QTGUI) $(INSTALLDIR)/modules/assmodel.$(DLL): \ plugins/assmodel/mdlimage.o \ plugins/assmodel/model.o \ @@ -1087,8 +1080,8 @@ $(INSTALLDIR)/modules/vfspk3.$(DLL): \ plugins/vfspk3/vfspk3.o \ libfilematch.$(A) \ -$(INSTALLDIR)/plugins/bobtoolz.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_GTK) -$(INSTALLDIR)/plugins/bobtoolz.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_GTK) -Ilibs -Iinclude +$(INSTALLDIR)/plugins/bobtoolz.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_QTCORE) $(LIBS_QTGUI) $(LIBS_QTWIDGETS) +$(INSTALLDIR)/plugins/bobtoolz.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_QTCORE) $(CPPFLAGS_QTGUI) $(CPPFLAGS_QTWIDGETS) -Ilibs -Iinclude $(INSTALLDIR)/plugins/bobtoolz.$(DLL): \ contrib/bobtoolz/bobToolz-GTK.o \ contrib/bobtoolz/bsploader.o \ @@ -1117,17 +1110,16 @@ $(INSTALLDIR)/plugins/bobtoolz.$(DLL): \ libmathlib.$(A) \ libprofile.$(A) \ -$(INSTALLDIR)/plugins/brushexport.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_GTK) -$(INSTALLDIR)/plugins/brushexport.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_GTK) -Ilibs -Iinclude +$(INSTALLDIR)/plugins/brushexport.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_QTCORE) $(LIBS_QTGUI) $(LIBS_QTWIDGETS) +$(INSTALLDIR)/plugins/brushexport.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_QTCORE) $(CPPFLAGS_QTGUI) $(CPPFLAGS_QTWIDGETS) -Ilibs -Iinclude $(INSTALLDIR)/plugins/brushexport.$(DLL): \ contrib/brushexport/callbacks.o \ contrib/brushexport/export.o \ contrib/brushexport/interface.o \ contrib/brushexport/plugin.o \ - contrib/brushexport/support.o \ -$(INSTALLDIR)/plugins/prtview.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_GTK) -$(INSTALLDIR)/plugins/prtview.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_GTK) -Ilibs -Iinclude +$(INSTALLDIR)/plugins/prtview.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_QTCORE) $(LIBS_QTGUI) $(LIBS_QTWIDGETS) +$(INSTALLDIR)/plugins/prtview.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_QTCORE) $(CPPFLAGS_QTGUI) $(CPPFLAGS_QTWIDGETS) -Ilibs -Iinclude $(INSTALLDIR)/plugins/prtview.$(DLL): \ contrib/prtview/AboutDialog.o \ contrib/prtview/ConfigDialog.o \ @@ -1136,14 +1128,14 @@ $(INSTALLDIR)/plugins/prtview.$(DLL): \ contrib/prtview/prtview.o \ libprofile.$(A) \ -$(INSTALLDIR)/plugins/shaderplug.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_GTK) $(LIBS_XML) -$(INSTALLDIR)/plugins/shaderplug.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_GTK) $(CPPFLAGS_XML) -Ilibs -Iinclude +$(INSTALLDIR)/plugins/shaderplug.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_QTCORE) $(LIBS_QTGUI) $(LIBS_QTWIDGETS) $(LIBS_XML) +$(INSTALLDIR)/plugins/shaderplug.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_QTCORE) $(CPPFLAGS_QTGUI) $(CPPFLAGS_QTWIDGETS) $(CPPFLAGS_XML) -Ilibs -Iinclude $(INSTALLDIR)/plugins/shaderplug.$(DLL): \ contrib/shaderplug/shaderplug.o \ libxmllib.$(A) \ -$(INSTALLDIR)/plugins/sunplug.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_GTK) -$(INSTALLDIR)/plugins/sunplug.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_GTK) -Ilibs -Iinclude +$(INSTALLDIR)/plugins/sunplug.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_QTCORE) $(LIBS_QTGUI) $(LIBS_QTWIDGETS) +$(INSTALLDIR)/plugins/sunplug.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_QTCORE) $(CPPFLAGS_QTGUI) $(CPPFLAGS_QTWIDGETS) -Ilibs -Iinclude $(INSTALLDIR)/plugins/sunplug.$(DLL): \ contrib/sunplug/sunplug.o \ @@ -1209,16 +1201,16 @@ $(INSTALLDIR)/q2map.$(EXE): \ libl_net.$(A) \ $(if $(findstring Win32,$(OS)),icons/q2map.o,) \ -$(INSTALLDIR)/plugins/ufoaiplug.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_GTK) -$(INSTALLDIR)/plugins/ufoaiplug.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_GTK) -Ilibs -Iinclude +$(INSTALLDIR)/plugins/ufoaiplug.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_QTCORE) $(LIBS_QTGUI) $(LIBS_QTWIDGETS) +$(INSTALLDIR)/plugins/ufoaiplug.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_QTCORE) $(CPPFLAGS_QTGUI) $(CPPFLAGS_QTWIDGETS) -Ilibs -Iinclude $(INSTALLDIR)/plugins/ufoaiplug.$(DLL): \ contrib/ufoaiplug/ufoai_filters.o \ contrib/ufoaiplug/ufoai_gtk.o \ contrib/ufoaiplug/ufoai_level.o \ contrib/ufoaiplug/ufoai.o \ -$(INSTALLDIR)/plugins/meshtex.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_GTK) -$(INSTALLDIR)/plugins/meshtex.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_GTK) -Ilibs -Iinclude +$(INSTALLDIR)/plugins/meshtex.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_QTCORE) $(LIBS_QTGUI) $(LIBS_QTWIDGETS) +$(INSTALLDIR)/plugins/meshtex.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_QTCORE) $(CPPFLAGS_QTGUI) $(CPPFLAGS_QTWIDGETS) -Ilibs -Iinclude $(INSTALLDIR)/plugins/meshtex.$(DLL): \ contrib/meshtex/GeneralFunctionDialog.o \ contrib/meshtex/GenericDialog.o \ @@ -1234,8 +1226,8 @@ $(INSTALLDIR)/plugins/meshtex.$(DLL): \ contrib/meshtex/RefCounted.o \ contrib/meshtex/SetScaleDialog.o \ -$(INSTALLDIR)/plugins/bkgrnd2d.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_GTK) -$(INSTALLDIR)/plugins/bkgrnd2d.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_GTK) -Ilibs -Iinclude +$(INSTALLDIR)/plugins/bkgrnd2d.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_QTCORE) $(LIBS_QTGUI) $(LIBS_QTWIDGETS) +$(INSTALLDIR)/plugins/bkgrnd2d.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_QTCORE) $(CPPFLAGS_QTGUI) $(CPPFLAGS_QTWIDGETS) -Ilibs -Iinclude $(INSTALLDIR)/plugins/bkgrnd2d.$(DLL): \ contrib/bkgrnd2d/bkgrnd2d.o \ contrib/bkgrnd2d/dialog.o \ diff --git a/contrib/bobtoolz/DBobView.cpp b/contrib/bobtoolz/DBobView.cpp index 55dd8e4d..a6973aaf 100644 --- a/contrib/bobtoolz/DBobView.cpp +++ b/contrib/bobtoolz/DBobView.cpp @@ -44,10 +44,6 @@ DBobView::DBobView(){ nPathCount = 0; - path = NULL; - - boundingShow = BOUNDS_APEX; - constructShaders(); GlobalShaderCache().attachRenderable( *this ); } @@ -55,12 +51,7 @@ DBobView::DBobView(){ DBobView::~DBobView(){ GlobalShaderCache().detachRenderable( *this ); destroyShaders(); - - if ( path ) { - delete[] path; - } - - g_PathView = NULL; + clear(); } ////////////////////////////////////////////////////////////////////// @@ -68,12 +59,12 @@ DBobView::~DBobView(){ ////////////////////////////////////////////////////////////////////// void DBobView::render( RenderStateFlags state ) const { - glBegin( GL_LINE_STRIP ); + gl().glBegin( GL_LINE_STRIP ); for ( int i = 0; i < nPathCount; i++ ) - glVertex3fv( path[i] ); + gl().glVertex3fv( path[i] ); - glEnd(); + gl().glEnd(); } const char* DBobView_state_line = "$bobtoolz/bobview/line"; @@ -82,15 +73,16 @@ const char* DBobView_state_box = "$bobtoolz/bobview/box"; void DBobView::constructShaders(){ OpenGLState state; GlobalOpenGLStateLibrary().getDefaultState( state ); - state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_BLEND | RENDER_LINESMOOTH; - state.m_sort = OpenGLState::eSortOpaque; - state.m_linewidth = 1; + state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_DEPTHTEST; + state.m_sort = OpenGLState::eSortFullbright; + state.m_linewidth = 2; state.m_colour[0] = 1; state.m_colour[1] = 0; state.m_colour[2] = 0; state.m_colour[3] = 1; GlobalOpenGLStateLibrary().insert( DBobView_state_line, state ); + state.m_linewidth = 1; state.m_colour[0] = 0.25f; state.m_colour[1] = 0.75f; state.m_colour[2] = 0.75f; @@ -135,19 +127,11 @@ void DBobView::renderWireframe( Renderer& renderer, const VolumeTest& volume ) c renderSolid( renderer, volume ); } -void DBobView::SetPath( vec3_t *pPath ){ - if ( path ) { - delete[] path; - } - - path = pPath; -} - #define LOCAL_GRAVITY -800.0f bool DBobView::CalculateTrajectory( vec3_t start, vec3_t apex, float multiplier, int points, float varGravity ){ if ( apex[2] <= start[2] ) { - SetPath( NULL ); + path.reset(); return false; } // ----think q3a actually would allow these @@ -165,15 +149,15 @@ bool DBobView::CalculateTrajectory( vec3_t start, vec3_t apex, float multiplier, // Sys_Printf("Speed: (%.4f %.4f %.4f)\n", speed[0], speed[1], speed[2]); - vec3_t* pPath = new vec3_t[points]; + path.reset( new vec3_t[points] ); float interval = multiplier * flight_time / points; for ( int i = 0; i < points; i++ ) { float ltime = interval * i; - VectorScale( speed, ltime, pPath[i] ); - VectorAdd( pPath[i], start, pPath[i] ); + VectorScale( speed, ltime, path[i] ); + VectorAdd( path[i], start, path[i] ); // could do this all with vectors // vGrav = {0, 0, -800.0f} @@ -182,16 +166,14 @@ bool DBobView::CalculateTrajectory( vec3_t start, vec3_t apex, float multiplier, // _VectorAdd(pPath[i], start, pPath[i]) // _VectorAdd(pPath[i], vAdd, pPath[i]) - pPath[i][2] = start[2] + ( speed_z * ltime ) + ( varGravity * 0.5f * ltime * ltime ); + path[i][2] = start[2] + ( speed_z * ltime ) + ( varGravity * 0.5f * ltime * ltime ); } - SetPath( pPath ); return true; } -void DBobView::Begin( const char* trigger, const char *target, float multiplier, int points, float varGravity, bool bNoUpdate, bool bShowExtra ){ - strcpy( entTrigger, trigger ); - strcpy( entTarget, target ); +void DBobView::Begin( const char *targetName, float multiplier, int points, float varGravity, bool bShowExtra ){ + strcpy( this->targetName, targetName ); fMultiplier = multiplier; fVarGravity = varGravity; @@ -199,20 +181,19 @@ void DBobView::Begin( const char* trigger, const char *target, float multiplier, m_bShowExtra = bShowExtra; if ( !UpdatePath() ) { - globalErrorStream() << "Initialization Failure in DBobView::Begin"; - delete this; + globalErrorStream() << "Initialization Failure in DBobView::Begin\n"; + g_PathView.reset(); } - globalOutputStream() << "Initialization of Path Plotter succeeded."; + globalOutputStream() << "Initialization of Path Plotter succeeded.\n"; } bool DBobView::UpdatePath(){ vec3_t start, apex; - if ( GetEntityCentre( entTrigger, start ) ) { - if ( GetEntityCentre( entTarget, apex ) ) { - CalculateTrajectory( start, apex, fMultiplier, nPathCount, fVarGravity ); - return true; - } + if ( GetEntityCentre( targetName, true, start ) + && GetEntityCentre( targetName, false, apex ) ) { + CalculateTrajectory( start, apex, fMultiplier, nPathCount, fVarGravity ); + return true; } return false; } @@ -221,47 +202,34 @@ void DBobView_setEntity( Entity& entity, float multiplier, int points, float var DEntity trigger; trigger.LoadEPairList( &entity ); - DEPair* trigger_ep = trigger.FindEPairByKey( "targetname" ); + if ( !strcmp( trigger.m_Classname, "trigger_push" ) ) { + if ( DEPair* trigger_ep = trigger.FindEPairByKey( "target" ) ) { + const scene::Path* entTarget = FindEntityFromTargetname( trigger_ep->value ); + if ( entTarget ) { + g_PathView.reset(); // delete old at first + g_PathView.reset( new DBobView ); - if ( trigger_ep ) { - if ( !strcmp( trigger.m_Classname, "trigger_push" ) ) { - DEPair* target_ep = trigger.FindEPairByKey( "target" ); - if ( target_ep ) { - const scene::Path* entTarget = FindEntityFromTargetname( target_ep->value ); - if ( entTarget ) { - if ( g_PathView ) { - delete g_PathView; - } - g_PathView = new DBobView; - - Entity* target = Node_getEntity( entTarget->top() ); - if ( target != 0 ) { - if ( !bNoUpdate ) { - g_PathView->trigger = &entity; - entity.attach( *g_PathView ); - g_PathView->target = target; - target->attach( *g_PathView ); - } - g_PathView->Begin( trigger_ep->value, target_ep->value, multiplier, points, varGravity, bNoUpdate, bShowExtra ); - } - else{ - globalErrorStream() << "bobToolz PathPlotter: trigger_push ARGH\n"; + Entity* target = Node_getEntity( entTarget->top() ); + if ( target != 0 ) { + if ( !bNoUpdate ) { + g_PathView->target = target; + target->attach( *g_PathView ); } + g_PathView->Begin( trigger_ep->value, multiplier, points, varGravity, bShowExtra ); } else{ - globalErrorStream() << "bobToolz PathPlotter: trigger_push target could not be found..\n"; + globalErrorStream() << "bobToolz PathPlotter: trigger_push ARGH\n"; } } else{ - globalErrorStream() << "bobToolz PathPlotter: trigger_push has no target..\n"; + globalErrorStream() << "bobToolz PathPlotter: trigger_push target could not be found..\n"; } } else{ - globalErrorStream() << "bobToolz PathPlotter: You must select a 'trigger_push' entity..\n"; + globalErrorStream() << "bobToolz PathPlotter: Entity must have a target.\n"; } } else{ - globalErrorStream() << "bobToolz PathPlotter: Entity must have a targetname.\n"; + globalErrorStream() << "bobToolz PathPlotter: You must select a 'trigger_push' entity..\n"; } - return; } \ No newline at end of file diff --git a/contrib/bobtoolz/DBobView.h b/contrib/bobtoolz/DBobView.h index c8299233..ddeebdc5 100644 --- a/contrib/bobtoolz/DBobView.h +++ b/contrib/bobtoolz/DBobView.h @@ -28,12 +28,8 @@ #include "renderable.h" #include "mathlib.h" -class DListener; class Shader; -#define BOUNDS_ALL 0 -#define BOUNDS_APEX 1 - class DBobView : public Renderable, public OpenGLRenderable, public Entity::Observer { Shader* m_shader_line; @@ -43,29 +39,23 @@ public: virtual ~DBobView(); protected: - vec3_t* path; + std::unique_ptr path; public: bool m_bShowExtra; - int boundingShow; - DListener* eyes; float fVarGravity; float fMultiplier; int nPathCount; - Entity* trigger; - Entity* target; + Entity* target{}; bool UpdatePath(); - char entTarget[256]; - char entTrigger[256]; - void Begin( const char*, const char*, float, int, float, bool, bool ); + char targetName[256]; + void Begin( const char*, float, int, float, bool ); bool CalculateTrajectory( vec3_t, vec3_t, float, int, float ); - void SetPath( vec3_t* pPath ); - - void render( RenderStateFlags state ) const; - void renderSolid( Renderer& renderer, const VolumeTest& volume ) const; - void renderWireframe( Renderer& renderer, const VolumeTest& volume ) const; + void render( RenderStateFlags state ) const override; + void renderSolid( Renderer& renderer, const VolumeTest& volume ) const override; + void renderWireframe( Renderer& renderer, const VolumeTest& volume ) const override; void constructShaders(); void destroyShaders(); @@ -74,21 +64,18 @@ public: UpdatePath(); } typedef MemberCaller1 ValueChangedCaller; - void insert( const char* key, EntityKeyValue& value ){ + void insert( const char* key, EntityKeyValue& value ) override { value.attach( ValueChangedCaller( *this ) ); } - void erase( const char* key, EntityKeyValue& value ){ + void erase( const char* key, EntityKeyValue& value ) override { value.detach( ValueChangedCaller( *this ) ); } - void clear(){ - if ( trigger != 0 ) { - trigger->detach( *this ); + void clear() override { + if ( target != 0 ) { target->detach( *this ); - trigger = 0; target = 0; } } }; -class Entity; void DBobView_setEntity( Entity& entity, float multiplier, int points, float varGravity, bool bNoUpdate, bool bShowExtra ); diff --git a/contrib/bobtoolz/DBrush.cpp b/contrib/bobtoolz/DBrush.cpp index 2ea77afa..458ef790 100644 --- a/contrib/bobtoolz/DBrush.cpp +++ b/contrib/bobtoolz/DBrush.cpp @@ -143,9 +143,9 @@ void DBrush::LoadFromBrush( scene::Instance& brush, bool textured ){ int DBrush::PointPosition( vec3_t pnt ){ int state = POINT_IN_BRUSH; // if nothing happens point is inside brush - for ( std::list::const_iterator chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) + for ( DPlane *plane : faceList ) { - float dist = ( *chkPlane )->DistanceToPoint( pnt ); + float dist = plane->DistanceToPoint( pnt ); if ( dist > MAX_ROUND_ERROR ) { return POINT_OUT_BRUSH; // if point is in front of plane, it CANT be in the brush @@ -160,17 +160,17 @@ int DBrush::PointPosition( vec3_t pnt ){ } void DBrush::ClearPoints(){ - for ( std::list::const_iterator deadPoint = pointList.begin(); deadPoint != pointList.end(); deadPoint++ ) { - delete *deadPoint; + for ( DPoint *point : pointList ) { + delete point; } pointList.clear(); } void DBrush::ClearFaces(){ bBoundsBuilt = false; - for ( std::list::const_iterator deadPlane = faceList.begin(); deadPlane != faceList.end(); deadPlane++ ) + for ( DPlane *plane : faceList ) { - delete *deadPlane; + delete plane; } faceList.clear(); } @@ -182,9 +182,9 @@ void DBrush::AddPoint( vec3_t pnt ){ } bool DBrush::HasPoint( vec3_t pnt ){ - for ( std::list::const_iterator chkPoint = pointList.begin(); chkPoint != pointList.end(); chkPoint++ ) + for ( DPoint *chkPoint : pointList ) { - if ( **chkPoint == pnt ) { + if ( *chkPoint == pnt ) { return true; } } @@ -311,10 +311,10 @@ bool DBrush::BBoxCollision( DBrush* chkBrush ){ } DPlane* DBrush::HasPlane( DPlane* chkPlane ){ - for ( std::list::const_iterator brushPlane = faceList.begin(); brushPlane != faceList.end(); brushPlane++ ) + for ( DPlane *plane : faceList ) { - if ( **brushPlane == *chkPlane ) { - return *brushPlane; + if ( *plane == *chkPlane ) { + return plane; } } return NULL; @@ -374,9 +374,9 @@ scene::Node* DBrush::BuildInRadiant( bool allowDestruction, int* changeCnt, scen if ( allowDestruction ) { bool kill = true; - for ( std::list::const_iterator chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) + for ( DPlane *plane : faceList ) { - if ( ( *chkPlane )->m_bChkOk ) { + if ( plane->m_bChkOk ) { kill = false; break; } @@ -395,8 +395,8 @@ scene::Node* DBrush::BuildInRadiant( bool allowDestruction, int* changeCnt, scen NodeSmartReference node( GlobalBrushCreator().createBrush() ); - for ( std::list::const_iterator buildPlane = faceList.begin(); buildPlane != faceList.end(); buildPlane++ ) { - if ( ( *buildPlane )->AddToBrush( node ) && changeCnt ) { + for ( DPlane *plane : faceList ) { + if ( plane->AddToBrush( node ) && changeCnt ) { ( *changeCnt )++; } } @@ -424,10 +424,10 @@ void DBrush::CutByPlane( DPlane *cutPlane, DBrush **newBrush1, DBrush **newBrush DBrush* b1 = new DBrush; DBrush* b2 = new DBrush; - for ( std::list::const_iterator parsePlane = faceList.begin(); parsePlane != faceList.end(); parsePlane++ ) + for ( DPlane *plane : faceList ) { - b1->AddFace( ( *parsePlane )->points[0], ( *parsePlane )->points[1], ( *parsePlane )->points[2], NULL ); - b2->AddFace( ( *parsePlane )->points[0], ( *parsePlane )->points[1], ( *parsePlane )->points[2], NULL ); + b1->AddFace( plane->points[0], plane->points[1], plane->points[2], NULL ); + b2->AddFace( plane->points[0], plane->points[1], plane->points[2], NULL ); } b1->AddFace( cutPlane->points[0], cutPlane->points[1], cutPlane->points[2], NULL ); @@ -457,15 +457,13 @@ bool DBrush::IntersectsWith( DBrush *chkBrush ){ return false; } - std::list::const_iterator iplPlane; - - for ( iplPlane = faceList.begin(); iplPlane != faceList.end(); iplPlane++ ) + for ( DPlane *plane : faceList ) { bool allInFront = true; - for ( std::list::const_iterator iPoint = chkBrush->pointList.begin(); iPoint != chkBrush->pointList.end(); iPoint++ ) + for ( DPoint *point : chkBrush->pointList ) { - if ( ( *iplPlane )->DistanceToPoint( ( *iPoint )->_pnt ) < -MAX_ROUND_ERROR ) { + if ( plane->DistanceToPoint( point->_pnt ) < -MAX_ROUND_ERROR ) { allInFront = false; break; } @@ -475,12 +473,12 @@ bool DBrush::IntersectsWith( DBrush *chkBrush ){ } } - for ( iplPlane = chkBrush->faceList.begin(); iplPlane != chkBrush->faceList.end(); iplPlane++ ) + for ( DPlane *plane : chkBrush->faceList ) { bool allInFront = true; - for ( std::list::const_iterator iPoint = pointList.begin(); iPoint != pointList.end(); iPoint++ ) + for ( DPoint *point : pointList ) { - if ( ( *iplPlane )->DistanceToPoint( ( *iPoint )->_pnt ) < -MAX_ROUND_ERROR ) { + if ( plane->DistanceToPoint( point->_pnt ) < -MAX_ROUND_ERROR ) { allInFront = false; break; } @@ -496,15 +494,13 @@ bool DBrush::IntersectsWith( DBrush *chkBrush ){ bool DBrush::IntersectsWith( DPlane* p1, DPlane* p2, vec3_t v ) { vec3_t vDown = { 0, 0, -1 }; - std::list::const_iterator iplPlane; - for ( iplPlane = faceList.begin(); iplPlane != faceList.end(); iplPlane++ ) { - DPlane* p = ( *iplPlane ); - - vec_t d = DotProduct( p->normal, vDown ); + for ( DPlane *plane : faceList ) + { + vec_t d = DotProduct( plane->normal, vDown ); if ( d >= 0 ) { continue; } - if ( p->PlaneIntersection( p1, p2, v ) ) { + if ( plane->PlaneIntersection( p1, p2, v ) ) { if ( PointPosition( v ) != POINT_OUT_BRUSH ) { return true; } @@ -619,30 +615,30 @@ bool DBrush::BBoxTouch( DBrush *chkBrush ){ } void DBrush::ResetChecks( std::list* exclusionList ){ - for ( std::list::const_iterator resetPlane = faceList.begin(); resetPlane != faceList.end(); resetPlane++ ) + for ( DPlane *plane : faceList ) { bool set = false; if ( exclusionList ) { - for ( std::list::iterator eTexture = exclusionList->begin(); eTexture != exclusionList->end(); eTexture++ ) + for ( const Str& texture : *exclusionList ) { - if ( strstr( ( *resetPlane )->m_shader.c_str(), eTexture->GetBuffer() ) ) { + if ( strstr( plane->m_shader.c_str(), texture.GetBuffer() ) ) { set = true; break; } } } - ( *resetPlane )->m_bChkOk = set; + plane->m_bChkOk = set; } } DPlane* DBrush::HasPlaneInverted( DPlane *chkPlane ){ - for ( std::list::const_iterator brushPlane = faceList.begin(); brushPlane != faceList.end(); brushPlane++ ) + for ( DPlane *plane : faceList ) { - if ( **brushPlane != *chkPlane ) { - if ( fabs( ( *brushPlane )->_d + chkPlane->_d ) < 0.1 ) { - return ( *brushPlane ); + if ( *plane != *chkPlane ) { + if ( fabs( plane->_d + chkPlane->_d ) < 0.1 ) { + return plane; } } } @@ -650,9 +646,9 @@ DPlane* DBrush::HasPlaneInverted( DPlane *chkPlane ){ } bool DBrush::HasTexture( const char *textureName ){ - for ( std::list::const_iterator chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) + for ( const DPlane *plane : faceList ) { - if ( strstr( ( *chkPlane )->m_shader.c_str(), textureName ) ) { + if ( strstr( plane->m_shader.c_str(), textureName ) ) { return true; } @@ -661,9 +657,9 @@ bool DBrush::HasTexture( const char *textureName ){ } bool DBrush::IsDetail(){ - for ( std::list::const_iterator chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) + for ( const DPlane *plane : faceList ) { - if ( ( *chkPlane )->texInfo.contents & FACE_DETAIL ) { + if ( plane->texInfo.contents & FACE_DETAIL ) { return true; } @@ -699,18 +695,18 @@ void DBrush::BuildFromWinding( DWinding *w ){ void DBrush::SaveToFile( FILE *pFile ){ fprintf( pFile, "{\n" ); - for ( std::list::const_iterator pp = faceList.begin(); pp != faceList.end(); pp++ ) + for ( const DPlane *pp : faceList ) { char buffer[512]; sprintf( buffer, "( %.0f %.0f %.0f ) ( %.0f %.0f %.0f ) ( %.0f %.0f %.0f ) %s %.0f %.0f %f %f %.0f 0 0 0\n", - ( *pp )->points[0][0], ( *pp )->points[0][1], ( *pp )->points[0][2], - ( *pp )->points[1][0], ( *pp )->points[1][1], ( *pp )->points[1][2], - ( *pp )->points[2][0], ( *pp )->points[2][1], ( *pp )->points[2][2], - ( *pp )->m_shader.c_str(), - ( *pp )->texInfo.m_texdef.shift[0], ( *pp )->texInfo.m_texdef.shift[1], - ( *pp )->texInfo.m_texdef.scale[0], ( *pp )->texInfo.m_texdef.scale[0], - ( *pp )->texInfo.m_texdef.rotate ); + pp->points[0][0], pp->points[0][1], pp->points[0][2], + pp->points[1][0], pp->points[1][1], pp->points[1][2], + pp->points[2][0], pp->points[2][1], pp->points[2][2], + pp->m_shader.c_str(), + pp->texInfo.m_texdef.shift[0], pp->texInfo.m_texdef.shift[1], + pp->texInfo.m_texdef.scale[0], pp->texInfo.m_texdef.scale[0], + pp->texInfo.m_texdef.rotate ); fprintf( pFile, "%s", buffer ); } @@ -719,12 +715,12 @@ void DBrush::SaveToFile( FILE *pFile ){ } void DBrush::Rotate( vec3_t vOrigin, vec3_t vRotation ){ - for ( std::list::const_iterator rotPlane = faceList.begin(); rotPlane != faceList.end(); rotPlane++ ) + for ( DPlane *plane : faceList ) { for ( int i = 0; i < 3; i++ ) - VectorRotate( ( *rotPlane )->points[i], vRotation, vOrigin ); + VectorRotate( plane->points[i], vRotation, vOrigin ); - ( *rotPlane )->Rebuild(); + plane->Rebuild(); } } @@ -739,33 +735,33 @@ void DBrush::RotateAboutCentre( vec3_t vRotation ){ Rotate( centre, vRotation ); } -bool DBrush::ResetTextures( const char* textureName, float fScale[2], float fShift[2], int rotation, const char* newTextureName, - int bResetTextureName, int bResetScale[2], int bResetShift[2], int bResetRotation ){ +bool DBrush::ResetTextures( const char* textureName, float fScale[2], float fShift[2], int rotation, const char* newTextureName, + bool bResetTextureName, bool bResetScale[2], bool bResetShift[2], bool bResetRotation ){ if ( textureName ) { bool changed = false; - for ( std::list::const_iterator resetPlane = faceList.begin(); resetPlane != faceList.end(); resetPlane++ ) + for ( DPlane *plane : faceList ) { - if ( !strcmp( ( *resetPlane )->m_shader.c_str(), textureName ) ) { + if ( !strcmp( plane->m_shader.c_str(), textureName ) ) { if ( bResetTextureName ) { - ( *resetPlane )->m_shader = newTextureName; + plane->m_shader = newTextureName; } if ( bResetScale[0] ) { - ( *resetPlane )->texInfo.m_texdef.scale[0] = fScale[0]; + plane->texInfo.m_texdef.scale[0] = fScale[0]; } if ( bResetScale[1] ) { - ( *resetPlane )->texInfo.m_texdef.scale[1] = fScale[1]; + plane->texInfo.m_texdef.scale[1] = fScale[1]; } if ( bResetShift[0] ) { - ( *resetPlane )->texInfo.m_texdef.shift[0] = fShift[0]; + plane->texInfo.m_texdef.shift[0] = fShift[0]; } if ( bResetShift[1] ) { - ( *resetPlane )->texInfo.m_texdef.shift[1] = fShift[1]; + plane->texInfo.m_texdef.shift[1] = fShift[1]; } if ( bResetRotation ) { - ( *resetPlane )->texInfo.m_texdef.rotate = (float)rotation; + plane->texInfo.m_texdef.rotate = (float)rotation; } changed = true; @@ -775,28 +771,28 @@ bool DBrush::ResetTextures( const char* textureName, float fScale[2], float f } else { - for ( std::list::const_iterator resetPlane = faceList.begin(); resetPlane != faceList.end(); resetPlane++ ) + for ( DPlane *plane : faceList ) { if ( bResetTextureName ) { - ( *resetPlane )->m_shader = newTextureName; + plane->m_shader = newTextureName; } if ( bResetScale[0] ) { - ( *resetPlane )->texInfo.m_texdef.scale[0] = fScale[0]; + plane->texInfo.m_texdef.scale[0] = fScale[0]; } if ( bResetScale[1] ) { - ( *resetPlane )->texInfo.m_texdef.scale[1] = fScale[1]; + plane->texInfo.m_texdef.scale[1] = fScale[1]; } if ( bResetShift[0] ) { - ( *resetPlane )->texInfo.m_texdef.shift[0] = fShift[0]; + plane->texInfo.m_texdef.shift[0] = fShift[0]; } if ( bResetShift[1] ) { - ( *resetPlane )->texInfo.m_texdef.shift[1] = fShift[1]; + plane->texInfo.m_texdef.shift[1] = fShift[1]; } if ( bResetRotation ) { - ( *resetPlane )->texInfo.m_texdef.rotate = (float)rotation; + plane->texInfo.m_texdef.rotate = (float)rotation; } } return true; @@ -804,18 +800,16 @@ bool DBrush::ResetTextures( const char* textureName, float fScale[2], float f } bool DBrush::operator ==( DBrush* other ){ - std::list::const_iterator chkPlane; - - for ( chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) + for ( DPlane *plane : faceList ) { - if ( !other->HasPlane( ( *chkPlane ) ) ) { + if ( !other->HasPlane( plane ) ) { return false; } } - for ( chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) + for ( DPlane *plane : other->faceList ) { - if ( !HasPlane( ( *chkPlane ) ) ) { + if ( !HasPlane( plane ) ) { return false; } } @@ -834,14 +828,11 @@ DPlane* DBrush::AddFace( const vec3_t va, const vec3_t vb, const vec3_t vc, cons DPlane* DBrush::FindPlaneWithClosestNormal( vec_t* normal ) { vec_t bestDot = -2; DPlane* bestDotPlane = NULL; - std::list::const_iterator chkPlane; - for ( chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) { - DPlane* pPlane = ( *chkPlane ); - - vec_t dot = DotProduct( pPlane->normal, normal ); + for ( DPlane *plane : faceList ) { + vec_t dot = DotProduct( plane->normal, normal ); if ( dot > bestDot ) { bestDot = dot; - bestDotPlane = pPlane; + bestDotPlane = plane; } } @@ -857,9 +848,8 @@ int DBrush::FindPointsForPlane( DPlane* plane, DPoint** pnts, int maxpnts ) { BuildPoints(); - for ( std::list::const_iterator points = pointList.begin(); points != pointList.end(); points++ ) { - DPoint* point = ( *points ); - + for ( DPoint *point : pointList ) + { if ( fabs( plane->DistanceToPoint( point->_pnt ) ) < MAX_ROUND_ERROR ) { pnts[numpnts] = point; numpnts++; @@ -876,9 +866,9 @@ int DBrush::FindPointsForPlane( DPlane* plane, DPoint** pnts, int maxpnts ) { void DBrush::RemovePlane( DPlane* plane ) { bBoundsBuilt = false; - for ( std::list::const_iterator deadPlane = faceList.begin(); deadPlane != faceList.end(); deadPlane++ ) { - if ( *deadPlane == plane ) { - delete *deadPlane; + for ( DPlane *deadPlane : faceList ) { + if ( deadPlane == plane ) { + delete deadPlane; faceList.remove( plane ); } } diff --git a/contrib/bobtoolz/DBrush.h b/contrib/bobtoolz/DBrush.h index 19734e9c..2ce22348 100644 --- a/contrib/bobtoolz/DBrush.h +++ b/contrib/bobtoolz/DBrush.h @@ -56,7 +56,7 @@ public: DPlane* HasPlane( DPlane* chkPlane ); DPlane* AddFace( const vec3_t va, const vec3_t vb, const vec3_t vc, const _QERFaceData* texData ); - bool ResetTextures( const char* textureName, float fScale[2], float fShift[2], int rotation, const char* newTextureName, int bResetTextureName, int bResetScale[2], int bResetShift[2], int bResetRotation ); + bool ResetTextures( const char* textureName, float fScale[2], float fShift[2], int rotation, const char* newTextureName, bool bResetTextureName, bool bResetScale[2], bool bResetShift[2], bool bResetRotation ); bool IsDetail(); bool HasTexture( const char* textureName ); bool IntersectsWith( DBrush *chkBrush ); diff --git a/contrib/bobtoolz/DEntity.cpp b/contrib/bobtoolz/DEntity.cpp index aa94d7f5..835d5388 100644 --- a/contrib/bobtoolz/DEntity.cpp +++ b/contrib/bobtoolz/DEntity.cpp @@ -91,17 +91,17 @@ DEntity::~DEntity(){ ////////////////////////////////////////////////////////////////////// void DEntity::ClearBrushes(){ - for ( std::list::const_iterator deadBrush = brushList.begin(); deadBrush != brushList.end(); deadBrush++ ) + for ( DBrush *brush : brushList ) { - delete *deadBrush; + delete brush; } brushList.clear(); } void DEntity::ClearPatches(){ - for ( std::list::const_iterator deadPatch = patchList.begin(); deadPatch != patchList.end(); deadPatch++ ) + for ( DPatch *patch : patchList ) { - delete *deadPatch; + delete patch; } patchList.clear(); } @@ -200,10 +200,10 @@ DPlane* DEntity::AddFaceToBrush( vec3_t va, vec3_t vb, vec3_t vc, _QERFaceData* DBrush* DEntity::GetBrushForID( int ID ){ DBrush* buildBrush = NULL; - for ( std::list::const_iterator chkBrush = brushList.begin(); chkBrush != brushList.end(); chkBrush++ ) + for ( DBrush *brush : brushList ) { - if ( ( *chkBrush )->m_nBrushID == ID ) { - buildBrush = ( *chkBrush ); + if ( brush->m_nBrushID == ID ) { + buildBrush = brush; break; } } @@ -339,10 +339,10 @@ void DEntity::SelectBrushes( bool *selectList ){ scene::Path path( NodeReference( GlobalSceneGraph().root() ) ); path.push( NodeReference( *QER_Entity ) ); - for ( std::list::const_iterator pBrush = brushList.begin(); pBrush != brushList.end(); pBrush++ ) + for ( DBrush *brush : brushList ) { - if ( selectList[( *pBrush )->m_nBrushID] ) { - path.push( NodeReference( *( *pBrush )->QER_brush ) ); + if ( selectList[brush->m_nBrushID] ) { + path.push( NodeReference( *brush->QER_brush ) ); Instance_getSelectable( *GlobalSceneGraph().find( path ) )->setSelected( true ); path.pop(); } @@ -437,18 +437,18 @@ void DEntity::RemoveNonCheckBrushes( std::list* exclusionList, bool useDeta } void DEntity::ResetChecks( std::list* exclusionList ){ - for ( std::list::const_iterator resetBrush = brushList.begin(); resetBrush != brushList.end(); resetBrush++ ) + for ( DBrush *brush : brushList ) { - ( *resetBrush )->ResetChecks( exclusionList ); + brush->ResetChecks( exclusionList ); } } int DEntity::FixBrushes(){ int count = 0; - for ( std::list::const_iterator fixBrush = brushList.begin(); fixBrush != brushList.end(); fixBrush++ ) + for ( DBrush *brush : brushList ) { - count += ( *fixBrush )->RemoveRedundantPlanes(); + count += brush->RemoveRedundantPlanes(); } return count; @@ -460,28 +460,28 @@ void DEntity::BuildInRadiant( bool allowDestruction ){ if ( makeEntity ) { NodeSmartReference node( GlobalEntityCreator().createEntity( GlobalEntityClassManager().findOrInsert( m_Classname.GetBuffer(), !brushList.empty() || !patchList.empty() ) ) ); - for ( std::list::const_iterator buildEPair = epairList.begin(); buildEPair != epairList.end(); buildEPair++ ) + for ( const DEPair *epair : epairList ) { - Node_getEntity( node )->setKeyValue( ( *buildEPair )->key, ( *buildEPair )->value ); + Node_getEntity( node )->setKeyValue( epair->key, epair->value ); } Node_getTraversable( GlobalSceneGraph().root() )->insert( node ); - for ( std::list::const_iterator buildBrush = brushList.begin(); buildBrush != brushList.end(); buildBrush++ ) - ( *buildBrush )->BuildInRadiant( allowDestruction, NULL, node.get_pointer() ); + for ( DBrush *brush : brushList ) + brush->BuildInRadiant( allowDestruction, NULL, node.get_pointer() ); - for ( std::list::const_iterator buildPatch = patchList.begin(); buildPatch != patchList.end(); buildPatch++ ) - ( *buildPatch )->BuildInRadiant( node.get_pointer() ); + for ( DPatch *patch : patchList ) + patch->BuildInRadiant( node.get_pointer() ); QER_Entity = node.get_pointer(); } else { - for ( std::list::const_iterator buildBrush = brushList.begin(); buildBrush != brushList.end(); buildBrush++ ) - ( *buildBrush )->BuildInRadiant( allowDestruction, NULL ); + for ( DBrush *brush : brushList ) + brush->BuildInRadiant( allowDestruction, NULL ); - for ( std::list::const_iterator buildPatch = patchList.begin(); buildPatch != patchList.end(); buildPatch++ ) - ( *buildPatch )->BuildInRadiant(); + for ( DPatch *patch : patchList ) + patch->BuildInRadiant(); } } @@ -489,9 +489,9 @@ void DEntity::BuildInRadiant( bool allowDestruction ){ int DEntity::GetIDMax( void ) { int max = -1; - for ( std::list::const_iterator cntBrush = brushList.begin(); cntBrush != brushList.end(); cntBrush++ ) { - if ( ( *cntBrush )->m_nBrushID > max ) { - max = ( *cntBrush )->m_nBrushID; + for ( const DBrush *brush : brushList ) { + if ( brush->m_nBrushID > max ) { + max = brush->m_nBrushID; } } return max + 1; @@ -506,23 +506,23 @@ void DEntity::SaveToFile( FILE *pFile ){ fprintf( pFile, "\"classname\" \"%s\"\n", (const char *)m_Classname ); - for ( std::list::const_iterator ep = epairList.begin(); ep != epairList.end(); ep++ ) + for ( const DEPair *ep : epairList ) { - fprintf( pFile, "\"%s\" \"%s\"\n", (const char *)( *ep )->key, (const char *)( *ep )->value ); + fprintf( pFile, "\"%s\" \"%s\"\n", (const char *)ep->key, (const char *)ep->value ); } - for ( std::list::const_iterator bp = brushList.begin(); bp != brushList.end(); bp++ ) + for ( DBrush *brush : brushList ) { - ( *bp )->SaveToFile( pFile ); + brush->SaveToFile( pFile ); } fprintf( pFile, "}\n" ); } void DEntity::ClearEPairs(){ - for ( std::list::const_iterator deadEPair = epairList.begin(); deadEPair != epairList.end(); deadEPair++ ) + for ( DEPair *epair : epairList ) { - delete ( *deadEPair ); + delete epair; } epairList.clear(); } @@ -562,34 +562,31 @@ void DEntity::LoadEPairList( Entity *epl ){ epl->forEachKeyValue( load_epairs ); } -bool DEntity::ResetTextures( const char* textureName, float fScale[2], float fShift[2], int rotation, const char* newTextureName, - int bResetTextureName, int bResetScale[2], int bResetShift[2], int bResetRotation, bool rebuild ){ +bool DEntity::ResetTextures( const char* textureName, float fScale[2], float fShift[2], int rotation, const char* newTextureName, + bool bResetTextureName, bool bResetScale[2], bool bResetShift[2], bool bResetRotation, bool rebuild ){ bool reset = false; - for ( std::list::const_iterator resetBrush = brushList.begin(); resetBrush != brushList.end(); resetBrush++ ) + for ( DBrush *brush : brushList ) { - bool tmp = ( *resetBrush )->ResetTextures( textureName, fScale, fShift, rotation, newTextureName, - bResetTextureName, bResetScale, bResetShift, bResetRotation ); - + const bool tmp = brush->ResetTextures( textureName, fScale, fShift, rotation, newTextureName, + bResetTextureName, bResetScale, bResetShift, bResetRotation ); if ( tmp ) { reset = true; if ( rebuild ) { - Node_getTraversable( *( *resetBrush )->QER_entity )->erase( *( *resetBrush )->QER_brush ); - ( *resetBrush )->BuildInRadiant( false, NULL, ( *resetBrush )->QER_entity ); + Node_getTraversable( *brush->QER_entity )->erase( *brush->QER_brush ); + brush->BuildInRadiant( false, NULL, brush->QER_entity ); } } } if ( bResetTextureName ) { - for ( std::list::const_iterator resetPatch = patchList.begin(); resetPatch != patchList.end(); resetPatch++ ) + for ( DPatch *patch : patchList ) { - bool tmp = ( *resetPatch )->ResetTextures( textureName, newTextureName ); - - if ( tmp ) { + if ( patch->ResetTextures( textureName, newTextureName ) ) { reset = true; if ( rebuild ) { - Node_getTraversable( *( *resetPatch )->QER_entity )->erase( *( *resetPatch )->QER_brush ); - ( *resetPatch )->BuildInRadiant( ( *resetPatch )->QER_entity ); + Node_getTraversable( *patch->QER_entity )->erase( *patch->QER_brush ); + patch->BuildInRadiant( patch->QER_entity ); } } } @@ -599,11 +596,10 @@ bool DEntity::ResetTextures( const char* textureName, float fScale[2], float } DEPair* DEntity::FindEPairByKey( const char* keyname ){ - for ( std::list::const_iterator ep = epairList.begin(); ep != epairList.end(); ep++ ) + for ( DEPair *ep : epairList ) { - char* c = ( *ep )->key; - if ( !strcmp( c, keyname ) ) { - return *ep; + if ( !strcmp( ep->key, keyname ) ) { + return ep; } } return NULL; @@ -660,8 +656,7 @@ int DEntity::GetBrushCount( void ) { } DBrush* DEntity::FindBrushByPointer( scene::Node& brush ) { - for ( std::list::const_iterator listBrush = brushList.begin(); listBrush != brushList.end(); listBrush++ ) { - DBrush* pBrush = ( *listBrush ); + for ( DBrush* pBrush : brushList ) { if ( pBrush->QER_brush == &brush ) { return pBrush; } diff --git a/contrib/bobtoolz/DEntity.h b/contrib/bobtoolz/DEntity.h index 083bed74..2a0c7137 100644 --- a/contrib/bobtoolz/DEntity.h +++ b/contrib/bobtoolz/DEntity.h @@ -59,7 +59,7 @@ public: // --------------------------------------------- // random functions........ - bool ResetTextures( const char* textureName, float fScale[2], float fShift[2], int rotation, const char* newTextureName, int bResetTextureName, int bResetScale[2], int bResetShift[2], int bResetRotation, bool rebuild ); + bool ResetTextures( const char* textureName, float fScale[2], float fShift[2], int rotation, const char* newTextureName, bool bResetTextureName, bool bResetScale[2], bool bResetShift[2], bool bResetRotation, bool rebuild ); void SaveToFile( FILE* pFile ); void SetClassname( const char* classname ); int GetIDMax(); diff --git a/contrib/bobtoolz/DMap.cpp b/contrib/bobtoolz/DMap.cpp index 27e1f3b8..70b7e43f 100644 --- a/contrib/bobtoolz/DMap.cpp +++ b/contrib/bobtoolz/DMap.cpp @@ -75,8 +75,8 @@ DEntity* DMap::AddEntity( const char *classname, int ID ){ void DMap::ClearEntities(){ m_nNextEntity = 1; - for ( std::list::const_iterator deadEntity = entityList.begin(); deadEntity != entityList.end(); deadEntity++ ) - delete *deadEntity; + for ( DEntity *entity : entityList ) + delete entity; entityList.clear(); } @@ -84,10 +84,10 @@ void DMap::ClearEntities(){ DEntity* DMap::GetEntityForID( int ID ){ DEntity* findEntity = NULL; - for ( std::list::const_iterator chkEntity = entityList.begin(); chkEntity != entityList.end(); chkEntity++ ) + for ( DEntity *entity : entityList ) { - if ( ( *chkEntity )->m_nID == ID ) { - findEntity = ( *chkEntity ); + if ( entity->m_nID == ID ) { + findEntity = entity; break; } } @@ -105,8 +105,8 @@ DEntity* DMap::GetWorldSpawn(){ } void DMap::BuildInRadiant( bool bAllowDestruction ){ - for ( std::list::const_iterator buildEntity = entityList.begin(); buildEntity != entityList.end(); buildEntity++ ) - ( *buildEntity )->BuildInRadiant( bAllowDestruction ); + for ( DEntity *entity : entityList ) + entity->BuildInRadiant( bAllowDestruction ); } void DMap::LoadAll( bool bLoadPatches ){ @@ -136,27 +136,27 @@ void DMap::LoadAll( bool bLoadPatches ){ int DMap::FixBrushes(){ int count = 0; - for ( std::list::const_iterator fixEntity = entityList.begin(); fixEntity != entityList.end(); fixEntity++ ) + for ( DEntity *entity : entityList ) { - count += ( *fixEntity )->FixBrushes(); + count += entity->FixBrushes(); } return count; } void DMap::ResetTextures( const char* textureName, float fScale[2], float fShift[2], int rotation, const char* newTextureName, - int bResetTextureName, int bResetScale[2], int bResetShift[2], int bResetRotation ){ - for ( std::list::const_iterator texEntity = entityList.begin(); texEntity != entityList.end(); texEntity++ ) + bool bResetTextureName, bool bResetScale[2], bool bResetShift[2], bool bResetRotation ){ + for ( DEntity *entity : entityList ) { - if ( string_equal_nocase( "worldspawn", ( *texEntity )->m_Classname ) ) { - ( *texEntity )->ResetTextures( textureName, fScale, fShift, rotation, newTextureName, - bResetTextureName, bResetScale, bResetShift, bResetRotation, true ); + if ( string_equal_nocase( "worldspawn", entity->m_Classname ) ) { + entity->ResetTextures( textureName, fScale, fShift, rotation, newTextureName, + bResetTextureName, bResetScale, bResetShift, bResetRotation, true ); } else { - if ( ( *texEntity )->ResetTextures( textureName, fScale, fShift, rotation, newTextureName, - bResetTextureName, bResetScale, bResetShift, bResetRotation, false ) ) { - RebuildEntity( *texEntity ); + if ( entity->ResetTextures( textureName, fScale, fShift, rotation, newTextureName, + bResetTextureName, bResetScale, bResetShift, bResetRotation, false ) ) { + RebuildEntity( entity ); } } } diff --git a/contrib/bobtoolz/DMap.h b/contrib/bobtoolz/DMap.h index aadf8f8e..bc86567f 100644 --- a/contrib/bobtoolz/DMap.h +++ b/contrib/bobtoolz/DMap.h @@ -32,7 +32,7 @@ class DMap public: static void RebuildEntity( DEntity* ent ); - void ResetTextures( const char* textureName, float fScale[2], float fShift[2], int rotation, const char* newTextureName, int bResetTextureName, int bResetScale[2], int bResetShift[2], int bResetRotation ); + void ResetTextures( const char* textureName, float fScale[2], float fShift[2], int rotation, const char* newTextureName, bool bResetTextureName, bool bResetScale[2], bool bResetShift[2], bool bResetRotation ); void LoadAll( bool bLoadPatches = false ); void BuildInRadiant( bool bAllowDestruction ); int m_nNextEntity; diff --git a/contrib/bobtoolz/DShape.cpp b/contrib/bobtoolz/DShape.cpp index 201390b8..0a91c410 100644 --- a/contrib/bobtoolz/DShape.cpp +++ b/contrib/bobtoolz/DShape.cpp @@ -34,8 +34,6 @@ #include "DPatch.h" #include "DEntity.h" -//#include "dialogs-gtk.h" - #include "misc.h" #include "shapes.h" @@ -194,7 +192,7 @@ void DShape::BuildBorderedPrism( vec3_t min, vec3_t max, int nSides, int nBorder VectorScale( origin, 0.5f, origin ); if ( nBorder >= Min( radius[0], radius[1] ) ) { -// DoMessageBox("Border is too large", "Error", MB_OK); +// DoMessageBox("Border is too large", "Error", EMessageBoxType::Error); return; } diff --git a/contrib/bobtoolz/DTrainDrawer.cpp b/contrib/bobtoolz/DTrainDrawer.cpp index 3566e502..d363d008 100644 --- a/contrib/bobtoolz/DTrainDrawer.cpp +++ b/contrib/bobtoolz/DTrainDrawer.cpp @@ -101,11 +101,11 @@ void DTrainDrawer::render( RenderStateFlags state ) const { for ( std::list::const_iterator sp = m_splineList.begin(); sp != m_splineList.end(); sp++ ) { splinePoint_t* pSP = ( *sp ); - glBegin( GL_LINE_STRIP ); + gl().glBegin( GL_LINE_STRIP ); for ( std::list::const_iterator v = pSP->m_vertexList.begin(); v != pSP->m_vertexList.end(); v++ ) { - glVertex3fv( ( *v )._pnt ); + gl().glVertex3fv( ( *v )._pnt ); } - glEnd(); + gl().glEnd(); } } diff --git a/contrib/bobtoolz/DVisDrawer.cpp b/contrib/bobtoolz/DVisDrawer.cpp index 8ffb4aa2..b897d54f 100644 --- a/contrib/bobtoolz/DVisDrawer.cpp +++ b/contrib/bobtoolz/DVisDrawer.cpp @@ -50,8 +50,6 @@ DVisDrawer::~DVisDrawer(){ destroyShaders(); ClearPoints(); - - g_VisView = NULL; } ////////////////////////////////////////////////////////////////////// @@ -87,15 +85,15 @@ void DVisDrawer::destroyShaders(){ } void DVisDrawer::render( RenderStateFlags state ) const { - glEnable( GL_POLYGON_OFFSET_FILL ); + gl().glEnable( GL_POLYGON_OFFSET_FILL ); for( const auto surf : *m_list ){ const DMetaSurf& s = *surf; - glColor4f( s.colour[0], s.colour[1], s.colour[2], 0.5f ); - glVertexPointer( 3, GL_FLOAT, sizeof( vec3_t ), s.verts ); - glDrawElements( GL_TRIANGLES, GLsizei( s.indicesN ), GL_UNSIGNED_INT, s.indices ); + gl().glColor4f( s.colour[0], s.colour[1], s.colour[2], 0.5f ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( vec3_t ), s.verts ); + gl().glDrawElements( GL_TRIANGLES, GLsizei( s.indicesN ), GL_UNSIGNED_INT, s.indices ); } - glDisable( GL_POLYGON_OFFSET_FILL ); - glColor4f( 1, 1, 1, 1 ); + gl().glDisable( GL_POLYGON_OFFSET_FILL ); + gl().glColor4f( 1, 1, 1, 1 ); } void DVisDrawer::renderWireframe( Renderer& renderer, const VolumeTest& volume ) const { diff --git a/contrib/bobtoolz/bobToolz-GTK.cpp b/contrib/bobtoolz/bobToolz-GTK.cpp index e906608c..dfa15027 100644 --- a/contrib/bobtoolz/bobToolz-GTK.cpp +++ b/contrib/bobtoolz/bobToolz-GTK.cpp @@ -40,14 +40,8 @@ void BobToolz_construct(){ } void BobToolz_destroy(){ - if ( g_PathView ) { - delete g_PathView; - g_PathView = NULL; - } - if ( g_VisView ) { - delete g_VisView; - g_VisView = NULL; - } + g_PathView.reset(); + g_VisView.reset(); if ( g_TrainView ) { delete g_TrainView; g_TrainView = NULL; @@ -62,19 +56,44 @@ void BobToolz_destroy(){ const char* PLUGIN_NAME = "bobToolz"; // commands in the menu -static const char* PLUGIN_COMMANDS = "About...,-,Reset Textures...,PitOMatic,-,Vis Viewer,Brush Cleanup,Polygon Builder,Caulk Selection,-,Tree Planter,Drop Entity,Plot Splines,-,Merge Patches,Split patches,Split patches cols,Split patches rows,Turn edge"; +constexpr char PLUGIN_COMMANDS[] = "About...," + "-," + "Stair Builder...," + "Door Builder...," + "Intersect...," + "Make Chain...," + "Path Plotter...," + "-," + "Reset Textures...," + "PitOMatic," + "-," + "Vis Viewer," + "Brush Cleanup," + "Polygon Builder," + "Caulk Selection," + "-," + "Tree Planter," + "Drop Entity," + "Plot Splines," + "-," + "Merge Patches," + "Split patches," + "Split patches cols," + "Split patches rows," + "Turn edge" + ; // globals -GtkWidget *g_pRadiantWnd = NULL; +QWidget *g_pRadiantWnd = nullptr; -static const char *PLUGIN_ABOUT = "bobToolz for SDRadiant\n" - "by digibob (digibob@splashdamage.com)\n" - "http://www.splashdamage.com\n\n" - "Additional Contributors:\n" - "MarsMattel, RR2DO2\n"; +constexpr char PLUGIN_ABOUT[] = "bobToolz for SDRadiant
" + "by digibob (digibob@splashdamage.com)
" + "http://www.splashdamage.com

" + "Additional Contributors:
" + "MarsMattel, RR2DO2
"; extern "C" const char* QERPlug_Init( void* hApp, void* pMainWidget ) { - g_pRadiantWnd = (GtkWidget*)pMainWidget; + g_pRadiantWnd = static_cast( pMainWidget ); return "bobToolz for GTKradiant"; } @@ -148,7 +167,7 @@ extern "C" void QERPlug_Dispatch( const char *p, vec3_t vMin, vec3_t vMax, bool DoPathPlotter(); } else if ( string_equal_nocase( p, "about..." ) ) { - DoMessageBox( PLUGIN_ABOUT, "About", eMB_OK ); + DoMessageBox( PLUGIN_ABOUT, "About" ); } } diff --git a/contrib/bobtoolz/bobToolz-GTK.h b/contrib/bobtoolz/bobToolz-GTK.h index 41b89e09..994a51e6 100644 --- a/contrib/bobtoolz/bobToolz-GTK.h +++ b/contrib/bobtoolz/bobToolz-GTK.h @@ -1,4 +1,4 @@ #pragma once -extern GtkWidget *g_pRadiantWnd; +extern QWidget *g_pRadiantWnd; diff --git a/contrib/bobtoolz/bsploader.cpp b/contrib/bobtoolz/bsploader.cpp index 295e709a..fc1af3c1 100644 --- a/contrib/bobtoolz/bsploader.cpp +++ b/contrib/bobtoolz/bsploader.cpp @@ -211,12 +211,12 @@ bool LoadBSPFile( const char *filename ) { SwapBlock( (int *)header, sizeof( *header ) ); if ( header->ident != BSP_IDENT ) { - DoMessageBox( "Cant find a valid IBSP file", "Error", eMB_OK ); + DoMessageBox( "Cant find a valid IBSP file", "Error", EMessageBoxType::Error ); return false; } if ( ( header->version != Q3_BSP_VERSION ) && ( header->version != WOLF_BSP_VERSION ) ) { - DoMessageBox( "File is incorrect version", "Error", eMB_OK ); + DoMessageBox( "File is incorrect version", "Error", EMessageBoxType::Error ); return false; } diff --git a/contrib/bobtoolz/ctfToolz-GTK.cpp b/contrib/bobtoolz/ctfToolz-GTK.cpp index bfeae5c5..e5f18404 100644 --- a/contrib/bobtoolz/ctfToolz-GTK.cpp +++ b/contrib/bobtoolz/ctfToolz-GTK.cpp @@ -80,7 +80,7 @@ extern "C" void WINAPI QERPlug_Dispatch( LPCSTR p, vec3_t vMin, vec3_t vMax, boo } if ( !strcmp( p, "About..." ) ) { - DoMessageBox( PLUGIN_ABOUT, "About", IDOK ); + DoMessageBox( PLUGIN_ABOUT, "About" ); } else if ( !strcmp( p, "Colour Changer..." ) ) { DoCTFColourChanger(); diff --git a/contrib/bobtoolz/dialogs/dialogs-gtk.cpp b/contrib/bobtoolz/dialogs/dialogs-gtk.cpp index cc98f255..df64cf94 100644 --- a/contrib/bobtoolz/dialogs/dialogs-gtk.cpp +++ b/contrib/bobtoolz/dialogs/dialogs-gtk.cpp @@ -22,184 +22,28 @@ #include "str.h" #include -#include -#include "gtkutil/pointer.h" #include "../lists.h" #include "../misc.h" #include "../bobToolz-GTK.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gtkutil/spinbox.h" -/*-------------------------------- - Callback Functions - ---------------------------------*/ - -typedef struct { - GtkWidget *cbTexChange; - GtkWidget *editTexOld, *editTexNew; - - GtkWidget *cbScaleHor, *cbScaleVert; - GtkWidget *editScaleHor, *editScaleVert; - - GtkWidget *cbShiftHor, *cbShiftVert; - GtkWidget *editShiftHor, *editShiftVert; - - GtkWidget *cbRotation; - GtkWidget *editRotation; -} dlg_texReset_t; - -dlg_texReset_t dlgTexReset; - -void Update_TextureReseter(); - -static void dialog_button_callback_texreset_update( GtkWidget *widget, gpointer data ){ - Update_TextureReseter(); -} - -void Update_TextureReseter(){ - gboolean check; - - check = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbTexChange ) ); - gtk_editable_set_editable( GTK_EDITABLE( dlgTexReset.editTexNew ), check ); - gtk_editable_set_editable( GTK_EDITABLE( dlgTexReset.editTexOld ), check ); - - check = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbScaleHor ) ); - gtk_editable_set_editable( GTK_EDITABLE( dlgTexReset.editScaleHor ), check ); - - check = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbScaleVert ) ); - gtk_editable_set_editable( GTK_EDITABLE( dlgTexReset.editScaleVert ), check ); - - check = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbShiftHor ) ); - gtk_editable_set_editable( GTK_EDITABLE( dlgTexReset.editShiftHor ), check ); - - check = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbShiftVert ) ); - gtk_editable_set_editable( GTK_EDITABLE( dlgTexReset.editShiftVert ), check ); - - check = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbRotation ) ); - gtk_editable_set_editable( GTK_EDITABLE( dlgTexReset.editRotation ), check ); -} - -static void dialog_button_callback( GtkWidget *widget, gpointer data ){ - GtkWidget *parent; - int *loop; - EMessageBoxReturn *ret; - - parent = gtk_widget_get_toplevel( widget ); - loop = (int*)g_object_get_data( G_OBJECT( parent ), "loop" ); - ret = (EMessageBoxReturn*)g_object_get_data( G_OBJECT( parent ), "ret" ); - - *loop = 0; - *ret = (EMessageBoxReturn)gpointer_to_int( data ); -} - -static gint dialog_delete_callback( GtkWidget *widget, GdkEvent* event, gpointer data ){ - int *loop; - - gtk_widget_hide( widget ); - loop = (int*)g_object_get_data( G_OBJECT( widget ), "loop" ); - *loop = 0; - - *(EMessageBoxReturn*)g_object_get_data( G_OBJECT( widget ), "ret" ) = eIDCANCEL; - - return TRUE; -} - -static void dialog_button_callback_settex( GtkWidget *widget, gpointer data ){ - TwinWidget* tw = (TwinWidget*)data; - - GtkEntry* entry = GTK_ENTRY( tw->one ); - GtkComboBox* combo = GTK_COMBO_BOX( tw->two ); - - const gchar* tex = gtk_entry_get_text( GTK_ENTRY( gtk_bin_get_child( GTK_BIN( combo ) ) ) ); - gtk_entry_set_text( entry, tex ); -} - -/*-------------------------------- - Data validation Routines - ---------------------------------*/ - -bool ValidateTextFloat( const char* pData, const char* error_title, float* value ){ - if ( pData ) { - float testNum = (float)atof( pData ); - - if ( ( testNum == 0.0f ) && strcmp( pData, "0" ) ) { - DoMessageBox( "Please Enter A Floating Point Number", error_title, eMB_OK ); - return FALSE; - } - else - { - *value = testNum; - return TRUE; - } - } - - DoMessageBox( "Please Enter A Floating Point Number", error_title, eMB_OK ); - return FALSE; -} - -bool ValidateTextFloatRange( const char* pData, float min, float max, const char* error_title, float* value ){ - char error_buffer[256]; - sprintf( error_buffer, "Please Enter A Floating Point Number Between %.3f and %.3f", min, max ); - - if ( pData ) { - float testNum = (float)atof( pData ); - - if ( ( testNum < min ) || ( testNum > max ) ) { - DoMessageBox( error_buffer, error_title, eMB_OK ); - return FALSE; - } - else - { - *value = testNum; - return TRUE; - } - } - - DoMessageBox( error_buffer, error_title, eMB_OK ); - return FALSE; -} - -bool ValidateTextIntRange( const char* pData, int min, int max, const char* error_title, int* value ){ - char error_buffer[256]; - sprintf( error_buffer, "Please Enter An Integer Between %i and %i", min, max ); - - if ( pData ) { - int testNum = atoi( pData ); - - if ( ( testNum < min ) || ( testNum > max ) ) { - DoMessageBox( error_buffer, error_title, eMB_OK ); - return FALSE; - } - else - { - *value = testNum; - return TRUE; - } - } - - DoMessageBox( error_buffer, error_title, eMB_OK ); - return FALSE; -} - -bool ValidateTextInt( const char* pData, const char* error_title, int* value ){ - if ( pData ) { - int testNum = atoi( pData ); - - if ( ( testNum == 0 ) && strcmp( pData, "0" ) ) { - DoMessageBox( "Please Enter An Integer", error_title, eMB_OK ); - return FALSE; - } - else - { - *value = testNum; - return TRUE; - } - } - - DoMessageBox( "Please Enter An Integer", error_title, eMB_OK ); - return FALSE; -} /*-------------------------------- Modal Dialog Boxes @@ -213,1789 +57,504 @@ bool ValidateTextInt( const char* pData, const char* error_title, int* value ){ */ EMessageBoxReturn DoMessageBox( const char* lpText, const char* lpCaption, EMessageBoxType type ){ - GtkWidget *window, *w, *vbox, *hbox; - EMessageBoxReturn ret; - int loop = 1; + return GlobalRadiant().m_pfnMessageBox( g_pRadiantWnd, lpText, lpCaption, type, 0 ); +} - window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - gtk_window_set_transient_for( GTK_WINDOW( window ), GTK_WINDOW( g_pRadiantWnd ) ); - gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); - g_signal_connect( G_OBJECT( window ), "delete_event", - G_CALLBACK( dialog_delete_callback ), NULL ); - g_signal_connect( G_OBJECT( window ), "destroy", - G_CALLBACK( gtk_widget_destroy ), NULL ); - gtk_window_set_title( GTK_WINDOW( window ), lpCaption ); - gtk_container_set_border_width( GTK_CONTAINER( window ), 10 ); - g_object_set_data( G_OBJECT( window ), "loop", &loop ); - g_object_set_data( G_OBJECT( window ), "ret", &ret ); - gtk_widget_realize( window ); +bool DoIntersectBox( IntersectRS* rs ){ + QDialog dialog( g_pRadiantWnd, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Intersect" ); - vbox = gtk_vbox_new( FALSE, 10 ); - gtk_container_add( GTK_CONTAINER( window ), vbox ); - gtk_widget_show( vbox ); + QRadioButton *radio1, *radio2; + QCheckBox *check1, *check2; - w = gtk_label_new( lpText ); - gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 2 ); - gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT ); - gtk_widget_show( w ); - - w = gtk_hseparator_new(); - gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 2 ); - gtk_widget_show( w ); - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 2 ); - gtk_widget_show( hbox ); - - if ( type == eMB_OK ) { - w = gtk_button_new_with_label( "Ok" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", - G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) ); - gtk_widget_set_can_default( w, TRUE ); - gtk_widget_grab_default( w ); - gtk_widget_show( w ); - ret = eIDOK; - } - else if ( type == eMB_OKCANCEL ) { - w = gtk_button_new_with_label( "Ok" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", - G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) ); - gtk_widget_set_can_default( w, TRUE ); - gtk_widget_grab_default( w ); - gtk_widget_show( w ); - - w = gtk_button_new_with_label( "Cancel" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", - G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) ); - gtk_widget_show( w ); - ret = eIDCANCEL; - } - else if ( type == eMB_YESNOCANCEL ) { - w = gtk_button_new_with_label( "Yes" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", - G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDYES ) ); - gtk_widget_set_can_default( w, TRUE ); - gtk_widget_grab_default( w ); - gtk_widget_show( w ); - - w = gtk_button_new_with_label( "No" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", - G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDNO ) ); - gtk_widget_show( w ); - - w = gtk_button_new_with_label( "Cancel" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", - G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) ); - gtk_widget_show( w ); - ret = eIDCANCEL; - } - else /* if (mode == MB_YESNO) */ { - w = gtk_button_new_with_label( "Yes" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", - G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDYES ) ); - gtk_widget_set_can_default( w, TRUE ); - gtk_widget_grab_default( w ); - gtk_widget_show( w ); - - w = gtk_button_new_with_label( "No" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", - G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDNO ) ); - gtk_widget_show( w ); - ret = eIDNO; + auto vbox = new QVBoxLayout( &dialog ); + vbox->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + { + vbox->addWidget( radio1 = new QRadioButton( "Use Whole Map" ) ); + vbox->addWidget( radio2 = new QRadioButton( "Use Selected Brushes" ) ); + radio1->setChecked( true ); + } + { + auto line = new QFrame; + line->setFrameShape( QFrame::Shape::HLine ); + line->setFrameShadow( QFrame::Shadow::Raised ); + vbox->addWidget( line ); + } + { + vbox->addWidget( check1 = new QCheckBox( "Include Detail Brushes" ) ); + vbox->addWidget( check2 = new QCheckBox( "Select Duplicate Brushes Only" ) ); + } + { + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel ); + vbox->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept ); + QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject ); + } } - gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER_ON_PARENT ); - gtk_widget_show( window ); - - while ( loop ) - gtk_main_iteration(); - - gtk_widget_destroy( window ); - - return ret; -} - -EMessageBoxReturn DoIntersectBox( IntersectRS* rs ){ - GtkWidget *window, *w, *vbox, *hbox; - GtkWidget *radio1, *radio2; - GtkWidget *check1, *check2; - EMessageBoxReturn ret; - int loop = 1; - - window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - - g_signal_connect( G_OBJECT( window ), "delete_event", G_CALLBACK( dialog_delete_callback ), NULL ); - g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( gtk_widget_destroy ), NULL ); - - gtk_window_set_title( GTK_WINDOW( window ), "Intersect" ); - gtk_container_set_border_width( GTK_CONTAINER( window ), 10 ); - - g_object_set_data( G_OBJECT( window ), "loop", &loop ); - g_object_set_data( G_OBJECT( window ), "ret", &ret ); - - gtk_widget_realize( window ); - - - - vbox = gtk_vbox_new( FALSE, 10 ); - gtk_container_add( GTK_CONTAINER( window ), vbox ); - gtk_widget_show( vbox ); - - // ---- vbox ---- - - - radio1 = gtk_radio_button_new_with_label_from_widget( NULL, "Use Whole Map" ); - gtk_box_pack_start( GTK_BOX( vbox ), radio1, FALSE, FALSE, 2 ); - gtk_widget_show( radio1 ); - - radio2 = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(radio1), "Use Selected Brushes" ); - gtk_box_pack_start( GTK_BOX( vbox ), radio2, FALSE, FALSE, 2 ); - gtk_widget_show( radio2 ); - - w = gtk_hseparator_new(); - gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 2 ); - gtk_widget_show( w ); - - check1 = gtk_check_button_new_with_label( "Include Detail Brushes" ); - gtk_box_pack_start( GTK_BOX( vbox ), check1, FALSE, FALSE, 0 ); - gtk_widget_show( check1 ); - - check2 = gtk_check_button_new_with_label( "Select Duplicate Brushes Only" ); - gtk_box_pack_start( GTK_BOX( vbox ), check2, FALSE, FALSE, 0 ); - gtk_widget_show( check2 ); - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 2 ); - gtk_widget_show( hbox ); - - // ---- hbox ---- ok/cancel buttons - - w = gtk_button_new_with_label( "Ok" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) ); - - gtk_widget_set_can_default( w, TRUE ); - gtk_widget_grab_default( w ); - gtk_widget_show( w ); - - w = gtk_button_new_with_label( "Cancel" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) ); - gtk_widget_show( w ); - ret = eIDCANCEL; - - // ---- /hbox ---- - - // ---- /vbox ---- - - gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); - gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER ); - gtk_widget_show( window ); - - while ( loop ) - gtk_main_iteration(); - - if ( gtk_toggle_button_get_active( (GtkToggleButton*)radio1 ) ) { - rs->nBrushOptions = BRUSH_OPT_WHOLE_MAP; + if( dialog.exec() ){ + rs->nBrushOptions = radio1->isChecked() + ? BRUSH_OPT_WHOLE_MAP + : BRUSH_OPT_SELECTED; + rs->bUseDetail = check1->isChecked(); + rs->bDuplicateOnly = check2->isChecked(); + return true; } - else if ( gtk_toggle_button_get_active( (GtkToggleButton*)radio2 ) ) { - rs->nBrushOptions = BRUSH_OPT_SELECTED; - } - - rs->bUseDetail = gtk_toggle_button_get_active( (GtkToggleButton*)check1 ) ? true : false; - rs->bDuplicateOnly = gtk_toggle_button_get_active( (GtkToggleButton*)check2 ) ? true : false; - - gtk_widget_destroy( window ); - - return ret; + return false; } -inline GtkWidget* entry_new_with_max_length( gint max ){ - GtkWidget* entry = gtk_entry_new(); - gtk_entry_set_max_length( GTK_ENTRY( entry ), max ); - return entry; -} +bool DoPolygonBox( PolygonRS* rs ){ + QDialog dialog( g_pRadiantWnd, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Polygon Builder" ); -EMessageBoxReturn DoPolygonBox( PolygonRS* rs ){ - GtkWidget *window, *w, *vbox, *hbox, *vbox2, *hbox2; + QSpinBox *spin_sides, *spin_border; + QCheckBox *check_border, *check_inverse, *check_align; - GtkWidget *check1, *check2, *check3; - GtkWidget *text1, *text2; - - EMessageBoxReturn ret; - int loop = 1; - - window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - gtk_window_set_transient_for( GTK_WINDOW( window ), GTK_WINDOW( g_pRadiantWnd ) ); - - g_signal_connect( G_OBJECT( window ), "delete_event", G_CALLBACK( dialog_delete_callback ), NULL ); - g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( gtk_widget_destroy ), NULL ); - - gtk_window_set_title( GTK_WINDOW( window ), "Polygon Builder" ); - gtk_container_set_border_width( GTK_CONTAINER( window ), 10 ); - - g_object_set_data( G_OBJECT( window ), "loop", &loop ); - g_object_set_data( G_OBJECT( window ), "ret", &ret ); - - gtk_widget_realize( window ); - - - - vbox = gtk_vbox_new( FALSE, 10 ); - gtk_container_add( GTK_CONTAINER( window ), vbox ); - gtk_widget_show( vbox ); - - // ---- vbox ---- - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 2 ); - gtk_widget_show( hbox ); - - // ---- hbox ---- - - - vbox2 = gtk_vbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( hbox ), vbox2, FALSE, FALSE, 2 ); - gtk_widget_show( vbox2 ); - - // ---- vbox2 ---- - - hbox2 = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox2 ), hbox2, FALSE, FALSE, 2 ); - gtk_widget_show( hbox2 ); - - // ---- hbox2 ---- - - text1 = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( text1 ), "3" ); - gtk_box_pack_start( GTK_BOX( hbox2 ), text1, FALSE, FALSE, 2 ); - gtk_widget_show( text1 ); - - w = gtk_label_new( "Number Of Sides" ); - gtk_box_pack_start( GTK_BOX( hbox2 ), w, FALSE, FALSE, 2 ); - gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT ); - gtk_widget_show( w ); - - // ---- /hbox2 ---- - - hbox2 = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox2 ), hbox2, FALSE, FALSE, 2 ); - gtk_widget_show( hbox2 ); - - // ---- hbox2 ---- - - text2 = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( text2 ), "8" ); - gtk_box_pack_start( GTK_BOX( hbox2 ), text2, FALSE, FALSE, 2 ); - gtk_widget_show( text2 ); - - w = gtk_label_new( "Border Width" ); - gtk_box_pack_start( GTK_BOX( hbox2 ), w, FALSE, FALSE, 2 ); - gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT ); - gtk_widget_show( w ); - - // ---- /hbox2 ---- - - // ---- /vbox2 ---- - - - - vbox2 = gtk_vbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( hbox ), vbox2, FALSE, FALSE, 2 ); - gtk_widget_show( vbox2 ); - - // ---- vbox2 ---- - - check1 = gtk_check_button_new_with_label( "Use Border" ); - gtk_box_pack_start( GTK_BOX( vbox2 ), check1, FALSE, FALSE, 0 ); - gtk_widget_show( check1 ); - - - check2 = gtk_check_button_new_with_label( "Inverse Polygon" ); - gtk_box_pack_start( GTK_BOX( vbox2 ), check2, FALSE, FALSE, 0 ); - gtk_widget_show( check2 ); - - - check3 = gtk_check_button_new_with_label( "Align Top Edge" ); - gtk_box_pack_start( GTK_BOX( vbox2 ), check3, FALSE, FALSE, 0 ); - gtk_widget_show( check3 ); - - // ---- /vbox2 ---- - - // ---- /hbox ---- - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 2 ); - gtk_widget_show( hbox ); - - // ---- hbox ---- - - w = gtk_button_new_with_label( "Ok" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) ); - - gtk_widget_set_can_default( w, TRUE ); - gtk_widget_grab_default( w ); - gtk_widget_show( w ); - - w = gtk_button_new_with_label( "Cancel" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) ); - gtk_widget_show( w ); - ret = eIDCANCEL; - - // ---- /hbox ---- - - // ---- /vbox ---- - - gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER_ON_PARENT ); - gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); - gtk_widget_show( window ); - - bool dialogError = TRUE; - while ( dialogError ) { - loop = 1; - while ( loop ) - gtk_main_iteration(); - - dialogError = FALSE; - - if ( ret == eIDOK ) { - rs->bUseBorder = gtk_toggle_button_get_active( (GtkToggleButton*)check1 ) ? true : false; - rs->bInverse = gtk_toggle_button_get_active( (GtkToggleButton*)check2 ) ? true : false; - rs->bAlignTop = gtk_toggle_button_get_active( (GtkToggleButton*)check3 ) ? true : false; - - if ( !ValidateTextIntRange( gtk_entry_get_text( GTK_ENTRY( text1 ) ), 3, 128, "Number Of Sides", &rs->nSides ) ) { - dialogError = TRUE; + auto hbox = new QHBoxLayout( &dialog ); + hbox->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + { + auto form = new QFormLayout; + hbox->addLayout( form ); + { + auto spin = spin_sides = new SpinBox( 3, 128, 6 ); + form->addRow( new SpinBoxLabel( "Number Of Sides", spin ), spin ); } - - if ( rs->bUseBorder ) { - if ( !ValidateTextIntRange( gtk_entry_get_text( GTK_ENTRY( text2 ) ), 8, 256, "Border Width", &rs->nBorderWidth ) ) { - dialogError = TRUE; - } + { + auto spin = spin_border = new SpinBox( 8, 256, 16 ); + form->addRow( new SpinBoxLabel( "Border Width", spin ), spin ); + } + { + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel ); + form->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept ); + QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject ); + } + } + { + auto vbox = new QVBoxLayout; + hbox->addLayout( vbox ); + { + vbox->addWidget( check_border = new QCheckBox( "Use Border" ) ); + vbox->addWidget( check_inverse = new QCheckBox( "Inverse Polygon" ) ); + vbox->addWidget( check_align = new QCheckBox( "Align Top Edge" ) ); + QObject::connect( check_border, &QCheckBox::stateChanged, spin_border, &QWidget::setEnabled ); + spin_border->setEnabled( false ); + QObject::connect( check_inverse, &QCheckBox::stateChanged, [check_border]( int on ){ + if( on ) // either of border or inverse may be used + check_border->setChecked( false ); + } ); + QObject::connect( check_border, &QCheckBox::stateChanged, [check_inverse]( int on ){ + if( on ) // either of border or inverse may be used + check_inverse->setChecked( false ); + } ); } } } - gtk_widget_destroy( window ); + if( dialog.exec() ){ + rs->nSides = spin_sides->value(); + rs->nBorderWidth = spin_border->value(); - return ret; + rs->bUseBorder = check_border->isChecked(); + rs->bInverse = check_inverse->isChecked(); + rs->bAlignTop = check_align->isChecked(); + + return true; + } + return false; } // mars // for stair builder stuck as close as i could to the MFC version // obviously feel free to change it at will :) -EMessageBoxReturn DoBuildStairsBox( BuildStairsRS* rs ){ - // i made widgets for just about everything ... i think that's what i need to do dunno tho - GtkWidget *window, *w, *vbox, *hbox; - GtkWidget *textStairHeight, *textRiserTex, *textMainTex; - GtkWidget *radioNorth, *radioSouth, *radioEast, *radioWest; // i'm guessing we can't just abuse 'w' for these if we're getting a value - GtkWidget *radioOldStyle, *radioBobStyle, *radioCornerStyle; - GtkWidget *checkUseDetail; - EMessageBoxReturn ret; - int loop = 1; +bool DoBuildStairsBox( BuildStairsRS* rs ){ + QDialog dialog( g_pRadiantWnd, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Stair Builder" ); - const char *text = "Please set a value in the boxes below and press 'OK' to build the stairs"; + QSpinBox *spin_stairHeight; + QButtonGroup *group_direction, *group_style; + QCheckBox *check_detail; + QLineEdit *edit_mainTex, *edit_riserTex; - window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - - g_signal_connect( G_OBJECT( window ), "delete_event", G_CALLBACK( dialog_delete_callback ), NULL ); - g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( gtk_widget_destroy ), NULL ); - - gtk_window_set_title( GTK_WINDOW( window ), "Stair Builder" ); - - gtk_container_set_border_width( GTK_CONTAINER( window ), 10 ); - - g_object_set_data( G_OBJECT( window ), "loop", &loop ); - g_object_set_data( G_OBJECT( window ), "ret", &ret ); - - gtk_widget_realize( window ); - - // new vbox - vbox = gtk_vbox_new( FALSE, 10 ); - gtk_container_add( GTK_CONTAINER( window ), vbox ); - gtk_widget_show( vbox ); - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_container_add( GTK_CONTAINER( vbox ), hbox ); - gtk_widget_show( hbox ); - - // dunno if you want this text or not ... - w = gtk_label_new( text ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 ); // not entirely sure on all the parameters / what they do ... - gtk_widget_show( w ); - - w = gtk_hseparator_new(); - gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 ); - gtk_widget_show( w ); - - // ------------------------- // indenting == good way of keeping track of lines :) - - // new hbox - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - textStairHeight = entry_new_with_max_length( 256 ); - gtk_box_pack_start( GTK_BOX( hbox ), textStairHeight, FALSE, FALSE, 1 ); - gtk_widget_show( textStairHeight ); - - w = gtk_label_new( "Stair Height" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 1 ); - gtk_widget_show( w ); - - // ------------------------- // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - w = gtk_label_new( "Direction:" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 5 ); - gtk_widget_show( w ); - - // -------------------------- // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - // radio buttons confuse me ... - // but this _looks_ right - - // djbob: actually it looks very nice :), slightly better than the way i did it - // edit: actually it doesn't work :P, you must pass the last radio item each time, ugh - - radioNorth = gtk_radio_button_new_with_label_from_widget( NULL, "North" ); - gtk_box_pack_start( GTK_BOX( hbox ), radioNorth, FALSE, FALSE, 3 ); - gtk_widget_show( radioNorth ); - - radioSouth = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON( radioNorth ), "South" ); - gtk_box_pack_start( GTK_BOX( hbox ), radioSouth, FALSE, FALSE, 2 ); - gtk_widget_show( radioSouth ); - - radioEast = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON( radioNorth ), "East" ); - gtk_box_pack_start( GTK_BOX( hbox ), radioEast, FALSE, FALSE, 1 ); - gtk_widget_show( radioEast ); - - radioWest = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON( radioNorth ), "West" ); - gtk_box_pack_start( GTK_BOX( hbox ), radioWest, FALSE, FALSE, 0 ); - gtk_widget_show( radioWest ); - - // --------------------------- // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - w = gtk_label_new( "Style:" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 5 ); - gtk_widget_show( w ); - - // --------------------------- // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - radioOldStyle = gtk_radio_button_new_with_label_from_widget( NULL, "Original" ); - gtk_box_pack_start( GTK_BOX( hbox ), radioOldStyle, FALSE, FALSE, 0 ); - gtk_widget_show( radioOldStyle ); - - radioBobStyle = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON( radioOldStyle ), "Bob's Style" ); - gtk_box_pack_start( GTK_BOX( hbox ), radioBobStyle, FALSE, FALSE, 0 ); - gtk_widget_show( radioBobStyle ); - - radioCornerStyle = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON( radioOldStyle ), "Corner Style" ); - gtk_box_pack_start( GTK_BOX( hbox ), radioCornerStyle, FALSE, FALSE, 0 ); - gtk_widget_show( radioCornerStyle ); - - // err, the q3r has an if or something so you need bob style checked before this - // is "ungreyed out" but you'll need to do that, as i suck :) - - // djbob: er.... yeah um, im not at all sure how i'm gonna sort this - // djbob: think we need some button callback functions or smuffin - // FIXME: actually get around to doing what i suggested!!!! - - checkUseDetail = gtk_check_button_new_with_label( "Use Detail Brushes" ); - gtk_box_pack_start( GTK_BOX( hbox ), checkUseDetail, FALSE, FALSE, 0 ); - gtk_widget_show( checkUseDetail ); - - // --------------------------- // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - textMainTex = entry_new_with_max_length( 512 ); - gtk_entry_set_text( GTK_ENTRY( textMainTex ), rs->mainTexture ); - gtk_box_pack_start( GTK_BOX( hbox ), textMainTex, FALSE, FALSE, 0 ); - gtk_widget_show( textMainTex ); - - w = gtk_label_new( "Main Texture" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 1 ); - gtk_widget_show( w ); - - // -------------------------- // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - textRiserTex = entry_new_with_max_length( 512 ); - gtk_box_pack_start( GTK_BOX( hbox ), textRiserTex, FALSE, FALSE, 0 ); - gtk_widget_show( textRiserTex ); - - w = gtk_label_new( "Riser Texture" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 1 ); - gtk_widget_show( w ); - - // -------------------------- // - w = gtk_hseparator_new(); - gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 ); - gtk_widget_show( w ); - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - w = gtk_button_new_with_label( "OK" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) ); - gtk_widget_set_can_default( w, TRUE ); - gtk_widget_grab_default( w ); - gtk_widget_show( w ); - - w = gtk_button_new_with_label( "Cancel" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) ); - gtk_widget_show( w ); - - ret = eIDCANCEL; - -// +djbob: need our "little" modal loop mars :P - gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); - gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER ); - gtk_widget_show( window ); - - bool dialogError = TRUE; - while ( dialogError ) { - loop = 1; - while ( loop ) - gtk_main_iteration(); - - dialogError = FALSE; - - if ( ret == eIDOK ) { - rs->bUseDetail = gtk_toggle_button_get_active( (GtkToggleButton*)checkUseDetail ) ? true : false; - - strcpy( rs->riserTexture, gtk_entry_get_text( GTK_ENTRY( textRiserTex ) ) ); - strcpy( rs->mainTexture, gtk_entry_get_text( GTK_ENTRY( textMainTex ) ) ); - - if ( gtk_toggle_button_get_active( (GtkToggleButton*)radioNorth ) ) { - rs->direction = MOVE_NORTH; - } - else if ( gtk_toggle_button_get_active( (GtkToggleButton*)radioSouth ) ) { - rs->direction = MOVE_SOUTH; - } - else if ( gtk_toggle_button_get_active( (GtkToggleButton*)radioEast ) ) { - rs->direction = MOVE_EAST; - } - else if ( gtk_toggle_button_get_active( (GtkToggleButton*)radioWest ) ) { - rs->direction = MOVE_WEST; - } - - if ( !ValidateTextInt( gtk_entry_get_text( GTK_ENTRY( textStairHeight ) ), "Stair Height", &rs->stairHeight ) ) { - dialogError = TRUE; - } - - if ( gtk_toggle_button_get_active( (GtkToggleButton*)radioOldStyle ) ) { - rs->style = STYLE_ORIGINAL; - } - else if ( gtk_toggle_button_get_active( (GtkToggleButton*)radioBobStyle ) ) { - rs->style = STYLE_BOB; - } - else if ( gtk_toggle_button_get_active( (GtkToggleButton*)radioCornerStyle ) ) { - rs->style = STYLE_CORNER; - } + auto form = new QFormLayout( &dialog ); + form->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + { + auto spin = spin_stairHeight = new SpinBox( 1, 1024, 8 ); + form->addRow( new SpinBoxLabel( "Stair Height", spin ), spin ); + } + { + auto hbox = new QHBoxLayout; + form->addRow( "Direction:", hbox ); + group_direction = new QButtonGroup( form ); + group_direction->addButton( new QRadioButton( "North" ), MOVE_NORTH ); + group_direction->addButton( new QRadioButton( "South" ), MOVE_SOUTH ); + group_direction->addButton( new QRadioButton( "East" ), MOVE_EAST ); + group_direction->addButton( new QRadioButton( "West" ), MOVE_WEST ); + for( auto b : group_direction->buttons() ) + hbox->addWidget( b ); + group_direction->button( MOVE_NORTH )->setChecked( true ); + } + { + auto hbox = new QHBoxLayout; + form->addRow( "Style:", hbox ); + group_style = new QButtonGroup( form ); + group_style->addButton( new QRadioButton( "Original" ), STYLE_ORIGINAL ); + group_style->addButton( new QRadioButton( "Bob's Style" ), STYLE_BOB ); + group_style->addButton( new QRadioButton( "Corner Style" ), STYLE_CORNER ); + for( auto b : group_style->buttons() ) + hbox->addWidget( b ); + group_style->button( STYLE_ORIGINAL )->setChecked( true ); + } + { + form->addWidget( check_detail = new QCheckBox( "Use Detail Brushes" ) ); + QObject::connect( group_style, &QButtonGroup::idClicked, [check_detail]( int id ){ + check_detail->setEnabled( id == STYLE_BOB ); + } ); + check_detail->setEnabled( false ); + } + { + form->addRow( "Main Texture", edit_mainTex = new QLineEdit( rs->mainTexture ) ); + edit_mainTex->setMaxLength( std::size( rs->mainTexture ) - 1 ); + } + { + form->addRow( "Riser Texture", edit_riserTex = new QLineEdit ); + edit_riserTex->setMaxLength( std::size( rs->riserTexture ) - 1 ); + } + { + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel ); + form->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept ); + QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject ); } } - gtk_widget_destroy( window ); + if( dialog.exec() ) + { + rs->stairHeight = spin_stairHeight->value(); + rs->direction = group_direction->checkedId(); + rs->style = group_style->checkedId(); + rs->bUseDetail = check_detail->isChecked(); - return ret; -// -djbob + strcpy( rs->mainTexture, edit_mainTex->text().toLatin1().constData() ); + strcpy( rs->riserTexture, edit_riserTex->text().toLatin1().constData() ); - // there we go, all done ... on my end at least, not bad for a night's work + return true; + } + return false; } -EMessageBoxReturn DoDoorsBox( DoorRS* rs ){ - GtkWidget *window, *hbox, *vbox, *w; - GtkWidget *textFrontBackTex, *textTrimTex; - GtkWidget *checkScaleMainH, *checkScaleMainV, *checkScaleTrimH, *checkScaleTrimV; - GtkWidget *comboMain, *comboTrim; - GtkWidget *buttonSetMain, *buttonSetTrim; - GtkWidget *radioNS, *radioEW; - TwinWidget tw1, tw2; - EMessageBoxReturn ret; - int loop = 1; +bool DoDoorsBox( DoorRS* rs ){ + QDialog dialog( g_pRadiantWnd, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Door Builder" ); - window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); + QCheckBox *checkScaleMainH, *checkScaleMainV, *checkScaleTrimH, *checkScaleTrimV; + QComboBox *comboMain, *comboTrim; + QRadioButton *radioNS, *radioEW; - g_signal_connect( G_OBJECT( window ), "delete_event", G_CALLBACK( dialog_delete_callback ), NULL ); - g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( gtk_widget_destroy ), NULL ); - - gtk_window_set_title( GTK_WINDOW( window ), "Door Builder" ); - - gtk_container_set_border_width( GTK_CONTAINER( window ), 10 ); - - g_object_set_data( G_OBJECT( window ), "loop", &loop ); - g_object_set_data( G_OBJECT( window ), "ret", &ret ); - - gtk_widget_realize( window ); - - char buffer[256]; - GtkListStore *listMainTextures = gtk_list_store_new( 1, G_TYPE_STRING ); - GtkListStore *listTrimTextures = gtk_list_store_new( 1, G_TYPE_STRING ); - LoadListStore( GetFilename( buffer, "bt/door-tex.txt" ), listMainTextures ); - LoadListStore( GetFilename( buffer, "bt/door-tex-trim.txt" ), listTrimTextures ); - - vbox = gtk_vbox_new( FALSE, 10 ); - gtk_container_add( GTK_CONTAINER( window ), vbox ); - gtk_widget_show( vbox ); - - // -------------------------- // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - textFrontBackTex = entry_new_with_max_length( 512 ); - gtk_entry_set_text( GTK_ENTRY( textFrontBackTex ), rs->mainTexture ); - gtk_box_pack_start( GTK_BOX( hbox ), textFrontBackTex, FALSE, FALSE, 0 ); - gtk_widget_show( textFrontBackTex ); - - w = gtk_label_new( "Door Front/Back Texture" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 ); - gtk_widget_show( w ); - - // ------------------------ // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - textTrimTex = entry_new_with_max_length( 512 ); - gtk_box_pack_start( GTK_BOX( hbox ), textTrimTex, FALSE, FALSE, 0 ); - gtk_widget_show( textTrimTex ); - - w = gtk_label_new( "Door Trim Texture" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 ); - gtk_widget_show( w ); - - // ----------------------- // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - // sp: horizontally ???? - // djbob: yes mars, u can spell :] - checkScaleMainH = gtk_check_button_new_with_label( "Scale Main Texture Horizontally" ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( checkScaleMainH ), TRUE ); - gtk_box_pack_start( GTK_BOX( hbox ), checkScaleMainH, FALSE, FALSE, 0 ); - gtk_widget_show( checkScaleMainH ); - - checkScaleTrimH = gtk_check_button_new_with_label( "Scale Trim Texture Horizontally" ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( checkScaleTrimH ), TRUE ); - gtk_box_pack_start( GTK_BOX( hbox ), checkScaleTrimH, FALSE, FALSE, 0 ); - gtk_widget_show( checkScaleTrimH ); - - // ---------------------- // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - checkScaleMainV = gtk_check_button_new_with_label( "Scale Main Texture Vertically" ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( checkScaleMainV ), TRUE ); - gtk_box_pack_start( GTK_BOX( hbox ), checkScaleMainV, FALSE, FALSE, 0 ); - gtk_widget_show( checkScaleMainV ); - - checkScaleTrimV = gtk_check_button_new_with_label( "Scale Trim Texture Vertically" ); - gtk_box_pack_start( GTK_BOX( hbox ), checkScaleTrimV, FALSE, FALSE, 0 ); - gtk_widget_show( checkScaleTrimV ); - - // --------------------- // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - // djbob: lists added - - comboMain = gtk_combo_box_new_with_model_and_entry( GTK_TREE_MODEL( listMainTextures ) ); - gtk_combo_box_set_entry_text_column( GTK_COMBO_BOX( comboMain ), 0 ); - gtk_box_pack_start( GTK_BOX( hbox ), comboMain, FALSE, FALSE, 0 ); - gtk_widget_show( comboMain ); - - tw1.one = textFrontBackTex; - tw1.two = comboMain; - - buttonSetMain = gtk_button_new_with_label( "Set As Main Texture" ); - g_signal_connect( G_OBJECT( buttonSetMain ), "clicked", G_CALLBACK( dialog_button_callback_settex ), &tw1 ); - gtk_box_pack_start( GTK_BOX( hbox ), buttonSetMain, FALSE, FALSE, 0 ); - gtk_widget_show( buttonSetMain ); - - // ------------------- // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - comboTrim = gtk_combo_box_new_with_model_and_entry( GTK_TREE_MODEL( listTrimTextures ) ); - gtk_combo_box_set_entry_text_column( GTK_COMBO_BOX( comboTrim ), 0 ); - gtk_box_pack_start( GTK_BOX( hbox ), comboTrim, FALSE, FALSE, 0 ); - gtk_widget_show( comboTrim ); - - tw2.one = textTrimTex; - tw2.two = comboTrim; - - buttonSetTrim = gtk_button_new_with_label( "Set As Trim Texture" ); - g_signal_connect( G_OBJECT( buttonSetTrim ), "clicked", G_CALLBACK( dialog_button_callback_settex ), &tw2 ); - gtk_box_pack_start( GTK_BOX( hbox ), buttonSetTrim, FALSE, FALSE, 0 ); - gtk_widget_show( buttonSetTrim ); - - // ------------------ // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - w = gtk_label_new( "Orientation" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 ); - gtk_widget_show( w ); - - // argh more radio buttons! - radioNS = gtk_radio_button_new_with_label_from_widget( NULL, "North - South" ); - gtk_box_pack_start( GTK_BOX( hbox ), radioNS, FALSE, FALSE, 0 ); - gtk_widget_show( radioNS ); - - radioEW = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON( radioNS ), "East - West" ); - gtk_box_pack_start( GTK_BOX( hbox ), radioEW, FALSE, FALSE, 0 ); - gtk_widget_show( radioEW ); - - // ----------------- // - - w = gtk_hseparator_new(); - gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 ); - gtk_widget_show( w ); - - // ----------------- // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - w = gtk_button_new_with_label( "OK" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) ); - gtk_widget_set_can_default( w, TRUE ); - gtk_widget_grab_default( w ); - gtk_widget_show( w ); - - w = gtk_button_new_with_label( "Cancel" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) ); - gtk_widget_show( w ); - ret = eIDCANCEL; - - // ----------------- // - -//+djbob - gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); - gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER ); - gtk_widget_show( window ); - - while ( loop ) - gtk_main_iteration(); - - strcpy( rs->mainTexture, gtk_entry_get_text( GTK_ENTRY( textFrontBackTex ) ) ); - strcpy( rs->trimTexture, gtk_entry_get_text( GTK_ENTRY( textTrimTex ) ) ); - - rs->bScaleMainH = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( checkScaleMainH ) ) ? true : false; - rs->bScaleMainV = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( checkScaleMainV ) ) ? true : false; - rs->bScaleTrimH = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( checkScaleTrimH ) ) ? true : false; - rs->bScaleTrimV = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( checkScaleTrimV ) ) ? true : false; - - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( radioNS ) ) ) { - rs->nOrientation = DIRECTION_NS; - } - else if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( radioEW ) ) ) { - rs->nOrientation = DIRECTION_EW; + { + auto form = new QFormLayout( &dialog ); + form->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + { + form->addRow( "Door Front/Back Texture", comboMain = new QComboBox ); + char buffer[256]; + comboMain->addItems( LoadListStore( GetFilename( buffer, "bt/door-tex.txt" ) ) ); + comboMain->setEditable( true ); + comboMain->lineEdit()->setMaxLength( std::size( rs->mainTexture ) - 1 ); + comboMain->setCurrentText( rs->mainTexture ); + } + { + form->addWidget( checkScaleMainH = new QCheckBox( "Scale Main Texture Horizontally" ) ); + form->addWidget( checkScaleMainV = new QCheckBox( "Scale Main Texture Vertically" ) ); + checkScaleMainH->setChecked( true ); + checkScaleMainV->setChecked( true ); + } + { + form->addRow( "Door Trim Texture", comboTrim = new QComboBox ); + char buffer[256]; + comboTrim->addItems( LoadListStore( GetFilename( buffer, "bt/door-tex-trim.txt" ) ) ); + comboTrim->setEditable( true ); + comboTrim->lineEdit()->setMaxLength( std::size( rs->trimTexture ) - 1 ); + comboTrim->setCurrentText( QString() ); + } + { + form->addWidget( checkScaleTrimH = new QCheckBox( "Scale Trim Texture Horizontally" ) ); + form->addWidget( checkScaleTrimV = new QCheckBox( "Scale Trim Texture Vertically" ) ); + checkScaleTrimH->setChecked( true ); + } + { + form->addRow( "Orientation", radioNS = new QRadioButton( "North - South" ) ); + form->addRow( "", radioEW = new QRadioButton( "North - South" ) ); + radioNS->setChecked( true ); + } + { + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel ); + form->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept ); + QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject ); + } } - gtk_widget_destroy( window ); + if( dialog.exec() ){ + strcpy( rs->mainTexture, comboMain->currentText().toLatin1().constData() ); + strcpy( rs->trimTexture, comboTrim->currentText().toLatin1().constData() ); - return ret; -//-djbob + rs->bScaleMainH = checkScaleMainH->isChecked(); + rs->bScaleMainV = checkScaleMainV->isChecked(); + rs->bScaleTrimH = checkScaleTrimH->isChecked(); + rs->bScaleTrimV = checkScaleTrimV->isChecked(); + + rs->nOrientation = radioNS->isChecked() + ? DIRECTION_NS + : DIRECTION_EW; + return true; + } + return false; } EMessageBoxReturn DoPathPlotterBox( PathPlotterRS* rs ){ - GtkWidget *window, *w, *vbox, *hbox; + QDialog dialog( g_pRadiantWnd, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Path Plotter" ); - GtkWidget *text1, *text2, *text3; - GtkWidget *check1, *check2; + QSpinBox *spin_pts; + QDoubleSpinBox *spin_mult, *spin_grav; + QCheckBox *check1, *check2; - EMessageBoxReturn ret; - int loop = 1; + EMessageBoxReturn ret = eIDCANCEL; - window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - - g_signal_connect( G_OBJECT( window ), "delete_event", G_CALLBACK( dialog_delete_callback ), NULL ); - g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( gtk_widget_destroy ), NULL ); - - gtk_window_set_title( GTK_WINDOW( window ), "Texture Reset" ); - gtk_container_set_border_width( GTK_CONTAINER( window ), 10 ); - - g_object_set_data( G_OBJECT( window ), "loop", &loop ); - g_object_set_data( G_OBJECT( window ), "ret", &ret ); - - gtk_widget_realize( window ); - - - - vbox = gtk_vbox_new( FALSE, 10 ); - gtk_container_add( GTK_CONTAINER( window ), vbox ); - gtk_widget_show( vbox ); - - // ---- vbox ---- - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 2 ); - gtk_widget_show( hbox ); - - // ---- hbox ---- - - text1 = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( text1 ), "25" ); - gtk_box_pack_start( GTK_BOX( hbox ), text1, FALSE, FALSE, 2 ); - gtk_widget_show( text1 ); - - w = gtk_label_new( "Number Of Points" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 2 ); - gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT ); - gtk_widget_show( w ); - - // ---- /hbox ---- - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 2 ); - gtk_widget_show( hbox ); - - // ---- hbox ---- - - text2 = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( text2 ), "3" ); - gtk_box_pack_start( GTK_BOX( hbox ), text2, FALSE, FALSE, 2 ); - gtk_widget_show( text2 ); - - w = gtk_label_new( "Multipler" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 2 ); - gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT ); - gtk_widget_show( w ); - - // ---- /hbox ---- - - w = gtk_label_new( "Path Distance = dist(start -> apex) * multiplier" ); - gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 ); - gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT ); - gtk_widget_show( w ); - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 2 ); - gtk_widget_show( hbox ); - - // ---- hbox ---- - - text3 = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( text3 ), "-800" ); - gtk_box_pack_start( GTK_BOX( hbox ), text3, FALSE, FALSE, 2 ); - gtk_widget_show( text3 ); - - w = gtk_label_new( "Gravity" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 2 ); - gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT ); - gtk_widget_show( w ); - - // ---- /hbox ---- - - w = gtk_hseparator_new(); - gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 ); - gtk_widget_show( w ); - - check1 = gtk_check_button_new_with_label( "No Dynamic Update" ); - gtk_box_pack_start( GTK_BOX( vbox ), check1, FALSE, FALSE, 0 ); - gtk_widget_show( check1 ); - - check2 = gtk_check_button_new_with_label( "Show Bounding Lines" ); - gtk_box_pack_start( GTK_BOX( vbox ), check2, FALSE, FALSE, 0 ); - gtk_widget_show( check2 ); - - // ---- /vbox ---- - - - // ----------------- // - - w = gtk_hseparator_new(); - gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 ); - gtk_widget_show( w ); - - // ----------------- // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - w = gtk_button_new_with_label( "Enable" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDYES ) ); - gtk_widget_show( w ); - - gtk_widget_set_can_default( w, TRUE ); - gtk_widget_grab_default( w ); - - w = gtk_button_new_with_label( "Disable" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDNO ) ); - gtk_widget_show( w ); - - w = gtk_button_new_with_label( "Cancel" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) ); - gtk_widget_show( w ); - - ret = eIDCANCEL; - - // ----------------- // - - gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); - gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER ); - gtk_widget_show( window ); - - bool dialogError = TRUE; - while ( dialogError ) { - loop = 1; - while ( loop ) - gtk_main_iteration(); - - dialogError = FALSE; - - if ( ret == eIDYES ) { - if ( !ValidateTextIntRange( gtk_entry_get_text( GTK_ENTRY( text1 ) ), 1, 200, "Number Of Points", &rs->nPoints ) ) { - dialogError = TRUE; - } - - if ( !ValidateTextFloatRange( gtk_entry_get_text( GTK_ENTRY( text2 ) ), 1.0f, 10.0f, "Multiplier", &rs->fMultiplier ) ) { - dialogError = TRUE; - } - - if ( !ValidateTextFloatRange( gtk_entry_get_text( GTK_ENTRY( text3 ) ), -10000.0f, -1.0f, "Gravity", &rs->fGravity ) ) { - dialogError = TRUE; - } - - rs->bNoUpdate = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( check1 ) ) ? true : false; - rs->bShowExtra = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( check2 ) ) ? true : false; + auto form = new QFormLayout( &dialog ); + form->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + { + auto spin = spin_pts = new SpinBox( 1, 200, 50 ); + form->addRow( new SpinBoxLabel( "Number Of Points", spin ), spin ); + } + { + auto spin = spin_mult = new DoubleSpinBox( 1, 10, 3 ); + form->addRow( new SpinBoxLabel( "Distance Multipler", spin ), spin ); + spin->setToolTip( "Path Distance = dist(start -> apex) * multiplier" ); + } + { + auto spin = spin_grav = new DoubleSpinBox( -10000, -1, -800 ); + form->addRow( new SpinBoxLabel( "Gravity", spin ), spin ); + } + { + form->addWidget( check1 = new QCheckBox( "No Dynamic Update" ) ); + form->addWidget( check2 = new QCheckBox( "Show Bounding Lines" ) ); + } + { + auto buttons = new QDialogButtonBox; + form->addWidget( buttons ); + // rejection via dialog means will return DialogCode::Rejected (0), eID* > 0 + QObject::connect( buttons->addButton( "Enable", QDialogButtonBox::ButtonRole::AcceptRole ), + &QAbstractButton::clicked, [&dialog](){ dialog.done( eIDYES ); } ); + QObject::connect( buttons->addButton( "Disable", QDialogButtonBox::ButtonRole::NoRole ), + &QAbstractButton::clicked, [&dialog](){ dialog.done( eIDNO ); } ); + QObject::connect( buttons->addButton( QDialogButtonBox::StandardButton::Cancel ), + &QAbstractButton::clicked, &dialog, &QDialog::reject ); } } - gtk_widget_destroy( window ); + if( const int r = dialog.exec() ){ + ret = static_cast( r ); + + if ( ret == eIDYES ) { + rs->nPoints = spin_pts->value(); + rs->fMultiplier = spin_mult->value(); + rs->fGravity = spin_grav->value(); + + rs->bNoUpdate = check1->isChecked(); + rs->bShowExtra = check2->isChecked(); + } + } return ret; } EMessageBoxReturn DoCTFColourChangeBox(){ - GtkWidget *window, *w, *vbox, *hbox; - EMessageBoxReturn ret; - int loop = 1; + QDialog dialog( g_pRadiantWnd, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "CTF Colour Changer" ); - window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); + EMessageBoxReturn ret = eIDCANCEL; - g_signal_connect( G_OBJECT( window ), "delete_event", G_CALLBACK( dialog_delete_callback ), NULL ); - g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( gtk_widget_destroy ), NULL ); + { + auto buttons = new QDialogButtonBox; + // rejection via dialog means will return DialogCode::Rejected (0), eID* > 0 + QObject::connect( buttons->addButton( "Red->Blue", QDialogButtonBox::ButtonRole::AcceptRole ), + &QAbstractButton::clicked, [&dialog](){ dialog.done( eIDOK ); } ); + QObject::connect( buttons->addButton( "Blue->Red", QDialogButtonBox::ButtonRole::NoRole ), + &QAbstractButton::clicked, [&dialog](){ dialog.done( eIDYES ); } ); + QObject::connect( buttons->addButton( QDialogButtonBox::StandardButton::Cancel ), + &QAbstractButton::clicked, &dialog, &QDialog::reject ); + ( new QHBoxLayout( &dialog ) )->addWidget( buttons ); + } - gtk_window_set_title( GTK_WINDOW( window ), "CTF Colour Changer" ); - gtk_container_set_border_width( GTK_CONTAINER( window ), 10 ); - - g_object_set_data( G_OBJECT( window ), "loop", &loop ); - g_object_set_data( G_OBJECT( window ), "ret", &ret ); - - gtk_widget_realize( window ); - - - - vbox = gtk_vbox_new( FALSE, 10 ); - gtk_container_add( GTK_CONTAINER( window ), vbox ); - gtk_widget_show( vbox ); - - // ---- vbox ---- - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, TRUE, TRUE, 0 ); - gtk_widget_show( hbox ); - - // ---- hbox ---- ok/cancel buttons - - w = gtk_button_new_with_label( "Red->Blue" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) ); - - gtk_widget_set_can_default( w, TRUE ); - gtk_widget_grab_default( w ); - gtk_widget_show( w ); - - w = gtk_button_new_with_label( "Blue->Red" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDYES ) ); - gtk_widget_show( w ); - - w = gtk_button_new_with_label( "Cancel" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) ); - gtk_widget_show( w ); - ret = eIDCANCEL; - - // ---- /hbox ---- - - // ---- /vbox ---- - - gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); - gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER ); - gtk_widget_show( window ); - - while ( loop ) - gtk_main_iteration(); - - gtk_widget_destroy( window ); + if( const int r = dialog.exec() ){ + ret = static_cast( r ); + } return ret; } + EMessageBoxReturn DoResetTextureBox( ResetTextureRS* rs ){ - Str texSelected; + EMessageBoxReturn ret = eIDCANCEL; - GtkWidget *window, *w, *vbox, *hbox, *frame, *table; + QDialog dialog( g_pRadiantWnd, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Texture Reset" ); - EMessageBoxReturn ret; - int loop = 1; + QLineEdit *editTexOld, *editTexNew; + QDoubleSpinBox *spin_ScaleHor, *spin_ScaleVert; + QDoubleSpinBox *spin_ShiftHor, *spin_ShiftVert; + QDoubleSpinBox *spin_Rotation; - window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - gtk_window_set_transient_for( GTK_WINDOW( window ), GTK_WINDOW( g_pRadiantWnd ) ); - gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); - - g_signal_connect( G_OBJECT( window ), "delete_event", G_CALLBACK( dialog_delete_callback ), NULL ); - g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( gtk_widget_destroy ), NULL ); - - gtk_window_set_title( GTK_WINDOW( window ), "Texture Reset" ); - gtk_container_set_border_width( GTK_CONTAINER( window ), 10 ); - - g_object_set_data( G_OBJECT( window ), "loop", &loop ); - g_object_set_data( G_OBJECT( window ), "ret", &ret ); - - gtk_widget_realize( window ); - - vbox = gtk_vbox_new( FALSE, 10 ); - gtk_container_add( GTK_CONTAINER( window ), vbox ); - gtk_widget_show( vbox ); - - // ---- vbox ---- - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 2 ); - gtk_widget_show( hbox ); - - // ---- hbox ---- - - texSelected = "Currently Selected Texture: "; - texSelected += GetCurrentTexture(); - - w = gtk_label_new( texSelected ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 2 ); - gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT ); - gtk_widget_show( w ); - - // ---- /hbox ---- - - frame = gtk_frame_new( "Reset Texture Names" ); - gtk_widget_show( frame ); - gtk_box_pack_start( GTK_BOX( vbox ), frame, FALSE, TRUE, 0 ); - - table = gtk_table_new( 2, 3, TRUE ); - gtk_widget_show( table ); - gtk_container_add( GTK_CONTAINER( frame ), table ); - gtk_table_set_row_spacings( GTK_TABLE( table ), 5 ); - gtk_table_set_col_spacings( GTK_TABLE( table ), 5 ); - gtk_container_set_border_width( GTK_CONTAINER( table ), 5 ); - - // ---- frame ---- - - dlgTexReset.cbTexChange = gtk_check_button_new_with_label( "Enabled" ); - g_signal_connect( G_OBJECT( dlgTexReset.cbTexChange ), "toggled", G_CALLBACK( dialog_button_callback_texreset_update ), NULL ); - gtk_widget_show( dlgTexReset.cbTexChange ); - gtk_table_attach( GTK_TABLE( table ), dlgTexReset.cbTexChange, 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - w = gtk_label_new( "Old Name: " ); - gtk_table_attach( GTK_TABLE( table ), w, 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( w ); - - dlgTexReset.editTexOld = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editTexOld ), rs->textureName ); - gtk_table_attach( GTK_TABLE( table ), dlgTexReset.editTexOld, 2, 3, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( dlgTexReset.editTexOld ); - - w = gtk_label_new( "New Name: " ); - gtk_table_attach( GTK_TABLE( table ), w, 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( w ); - - dlgTexReset.editTexNew = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editTexNew ), rs->textureName ); - gtk_table_attach( GTK_TABLE( table ), dlgTexReset.editTexNew, 2, 3, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( dlgTexReset.editTexNew ); - - // ---- /frame ---- - - frame = gtk_frame_new( "Reset Scales" ); - gtk_widget_show( frame ); - gtk_box_pack_start( GTK_BOX( vbox ), frame, FALSE, TRUE, 0 ); - - table = gtk_table_new( 2, 3, TRUE ); - gtk_widget_show( table ); - gtk_container_add( GTK_CONTAINER( frame ), table ); - gtk_table_set_row_spacings( GTK_TABLE( table ), 5 ); - gtk_table_set_col_spacings( GTK_TABLE( table ), 5 ); - gtk_container_set_border_width( GTK_CONTAINER( table ), 5 ); - - // ---- frame ---- - - dlgTexReset.cbScaleHor = gtk_check_button_new_with_label( "Enabled" ); - g_signal_connect( G_OBJECT( dlgTexReset.cbScaleHor ), "toggled", G_CALLBACK( dialog_button_callback_texreset_update ), NULL ); - gtk_widget_show( dlgTexReset.cbScaleHor ); - gtk_table_attach( GTK_TABLE( table ), dlgTexReset.cbScaleHor, 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - w = gtk_label_new( "New Horizontal Scale: " ); - gtk_table_attach( GTK_TABLE( table ), w, 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( w ); - - dlgTexReset.editScaleHor = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editScaleHor ), "0.5" ); - gtk_table_attach( GTK_TABLE( table ), dlgTexReset.editScaleHor, 2, 3, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( dlgTexReset.editScaleHor ); - - - dlgTexReset.cbScaleVert = gtk_check_button_new_with_label( "Enabled" ); - g_signal_connect( G_OBJECT( dlgTexReset.cbScaleVert ), "toggled", G_CALLBACK( dialog_button_callback_texreset_update ), NULL ); - gtk_widget_show( dlgTexReset.cbScaleVert ); - gtk_table_attach( GTK_TABLE( table ), dlgTexReset.cbScaleVert, 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - w = gtk_label_new( "New Vertical Scale: " ); - gtk_table_attach( GTK_TABLE( table ), w, 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( w ); - - dlgTexReset.editScaleVert = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editScaleVert ), "0.5" ); - gtk_table_attach( GTK_TABLE( table ), dlgTexReset.editScaleVert, 2, 3, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( dlgTexReset.editScaleVert ); - - // ---- /frame ---- - - frame = gtk_frame_new( "Reset Shift" ); - gtk_widget_show( frame ); - gtk_box_pack_start( GTK_BOX( vbox ), frame, FALSE, TRUE, 0 ); - - table = gtk_table_new( 2, 3, TRUE ); - gtk_widget_show( table ); - gtk_container_add( GTK_CONTAINER( frame ), table ); - gtk_table_set_row_spacings( GTK_TABLE( table ), 5 ); - gtk_table_set_col_spacings( GTK_TABLE( table ), 5 ); - gtk_container_set_border_width( GTK_CONTAINER( table ), 5 ); - - // ---- frame ---- - - dlgTexReset.cbShiftHor = gtk_check_button_new_with_label( "Enabled" ); - g_signal_connect( G_OBJECT( dlgTexReset.cbShiftHor ), "toggled", G_CALLBACK( dialog_button_callback_texreset_update ), NULL ); - gtk_widget_show( dlgTexReset.cbShiftHor ); - gtk_table_attach( GTK_TABLE( table ), dlgTexReset.cbShiftHor, 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - w = gtk_label_new( "New Horizontal Shift: " ); - gtk_table_attach( GTK_TABLE( table ), w, 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( w ); - - dlgTexReset.editShiftHor = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editShiftHor ), "0" ); - gtk_table_attach( GTK_TABLE( table ), dlgTexReset.editShiftHor, 2, 3, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( dlgTexReset.editShiftHor ); - - - dlgTexReset.cbShiftVert = gtk_check_button_new_with_label( "Enabled" ); - g_signal_connect( G_OBJECT( dlgTexReset.cbShiftVert ), "toggled", G_CALLBACK( dialog_button_callback_texreset_update ), NULL ); - gtk_widget_show( dlgTexReset.cbShiftVert ); - gtk_table_attach( GTK_TABLE( table ), dlgTexReset.cbShiftVert, 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - w = gtk_label_new( "New Vertical Shift: " ); - gtk_table_attach( GTK_TABLE( table ), w, 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( w ); - - dlgTexReset.editShiftVert = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editShiftVert ), "0" ); - gtk_table_attach( GTK_TABLE( table ), dlgTexReset.editShiftVert, 2, 3, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( dlgTexReset.editShiftVert ); - - // ---- /frame ---- - - frame = gtk_frame_new( "Reset Rotation" ); - gtk_widget_show( frame ); - gtk_box_pack_start( GTK_BOX( vbox ), frame, FALSE, TRUE, 0 ); - - table = gtk_table_new( 1, 3, TRUE ); - gtk_widget_show( table ); - gtk_container_add( GTK_CONTAINER( frame ), table ); - gtk_table_set_row_spacings( GTK_TABLE( table ), 5 ); - gtk_table_set_col_spacings( GTK_TABLE( table ), 5 ); - gtk_container_set_border_width( GTK_CONTAINER( table ), 5 ); - - // ---- frame ---- - - dlgTexReset.cbRotation = gtk_check_button_new_with_label( "Enabled" ); - gtk_widget_show( dlgTexReset.cbRotation ); - gtk_table_attach( GTK_TABLE( table ), dlgTexReset.cbRotation, 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - w = gtk_label_new( "New Rotation Value: " ); - gtk_table_attach( GTK_TABLE( table ), w, 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( w ); - - dlgTexReset.editRotation = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editRotation ), "0" ); - gtk_table_attach( GTK_TABLE( table ), dlgTexReset.editRotation, 2, 3, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( dlgTexReset.editRotation ); - - // ---- /frame ---- - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 2 ); - gtk_widget_show( hbox ); - - // ---- hbox ---- - - w = gtk_button_new_with_label( "Use Selected Brushes" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) ); - - gtk_widget_set_can_default( w, TRUE ); - gtk_widget_grab_default( w ); - gtk_widget_show( w ); - - w = gtk_button_new_with_label( "Use All Brushes" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDYES ) ); - gtk_widget_show( w ); - - w = gtk_button_new_with_label( "Cancel" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) ); - gtk_widget_show( w ); - ret = eIDCANCEL; - - // ---- /hbox ---- - - // ---- /vbox ---- - - gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER_ON_PARENT ); - gtk_widget_show( window ); - - Update_TextureReseter(); - - bool dialogError = TRUE; - while ( dialogError ) { - loop = 1; - while ( loop ) - gtk_main_iteration(); - - dialogError = FALSE; - - if ( ret != eIDCANCEL ) { - rs->bResetRotation = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbRotation ) ); - if ( rs->bResetRotation ) { - if ( !ValidateTextInt( gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editRotation ) ), "Rotation", &rs->rotation ) ) { - dialogError = TRUE; + auto vbox = new QVBoxLayout( &dialog ); + { + vbox->addWidget( new QLabel( QString( "Currently Selected Texture: " ) + GetCurrentTexture() ) ); + } + { + auto group = new QGroupBox( "Reset Texture Names" ); + group->setCheckable( true ); + group->setChecked( false ); + vbox->addWidget( group ); + { + auto form = new QFormLayout( group ); + { + form->addRow( "Old Name: ", editTexOld = new QLineEdit( rs->textureName ) ); + editTexOld->setMaxLength( std::size( rs->textureName ) - 1 ); + } + { + form->addRow( "New Name: ", editTexNew = new QLineEdit( rs->newTextureName ) ); + editTexNew->setMaxLength( std::size( rs->newTextureName ) - 1 ); } } - - rs->bResetScale[0] = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbScaleHor ) ); - if ( rs->bResetScale[0] ) { - if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editScaleHor ) ), "Horizontal Scale", &rs->fScale[0] ) ) { - dialogError = TRUE; - } + } + { + auto group = new QGroupBox( "New Horizontal Scale" ); + group->setCheckable( true ); + group->setChecked( false ); + vbox->addWidget( group ); + { + auto spin = spin_ScaleHor = new DoubleSpinBox( -1024, 1024, .5, 3, .25 ); + ( new QFormLayout( group ) )->addWidget( spin ); } - - rs->bResetScale[1] = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbScaleVert ) ); - if ( rs->bResetScale[1] ) { - if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editScaleVert ) ), "Vertical Scale", &rs->fScale[1] ) ) { - dialogError = TRUE; - } + } + { + auto group = new QGroupBox( "New Vertical Scale" ); + group->setCheckable( true ); + group->setChecked( false ); + vbox->addWidget( group ); + { + auto spin = spin_ScaleVert = new DoubleSpinBox( -1024, 1024, .5, 3, .25 ); + ( new QFormLayout( group ) )->addWidget( spin ); } - - rs->bResetShift[0] = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbShiftHor ) ); - if ( rs->bResetShift[0] ) { - if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editShiftHor ) ), "Horizontal Shift", &rs->fShift[0] ) ) { - dialogError = TRUE; - } + } + { + auto group = new QGroupBox( "New Horizontal Shift" ); + group->setCheckable( true ); + group->setChecked( false ); + vbox->addWidget( group ); + { + auto spin = spin_ShiftHor = new DoubleSpinBox( -999999, 999999 ); + ( new QFormLayout( group ) )->addWidget( spin ); } - - rs->bResetShift[1] = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbShiftVert ) ); - if ( rs->bResetShift[1] ) { - if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editShiftVert ) ), "Vertical Shift", &rs->fShift[1] ) ) { - dialogError = TRUE; - } + } + { + auto group = new QGroupBox( "New Vertical Shift" ); + group->setCheckable( true ); + group->setChecked( false ); + vbox->addWidget( group ); + { + auto spin = spin_ShiftVert = new DoubleSpinBox( -999999, 999999 ); + ( new QFormLayout( group ) )->addWidget( spin ); } - - rs->bResetTextureName = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbTexChange ) ); - if ( rs->bResetTextureName ) { - strcpy( rs->textureName, gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editTexOld ) ) ); - strcpy( rs->newTextureName, gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editTexNew ) ) ); + } + { + auto group = new QGroupBox( "New Rotation Value" ); + group->setCheckable( true ); + group->setChecked( false ); + vbox->addWidget( group ); + { + auto spin = spin_Rotation = new DoubleSpinBox( -360, 360, 0, 2, 1, true ); + ( new QFormLayout( group ) )->addWidget( spin ); } } + + { + auto buttons = new QDialogButtonBox; + vbox->addWidget( buttons ); + // rejection via dialog means will return DialogCode::Rejected (0), eID* > 0 + QObject::connect( buttons->addButton( "Use Selected Brushes", QDialogButtonBox::ButtonRole::AcceptRole ), + &QAbstractButton::clicked, [&dialog](){ dialog.done( eIDOK ); } ); + QObject::connect( buttons->addButton( "Use All Brushes", QDialogButtonBox::ButtonRole::NoRole ), + &QAbstractButton::clicked, [&dialog](){ dialog.done( eIDYES ); } ); + QObject::connect( buttons->addButton( QDialogButtonBox::StandardButton::Cancel ), + &QAbstractButton::clicked, &dialog, &QDialog::reject ); + } } - gtk_widget_destroy( window ); + + if( const int r = dialog.exec() ){ + ret = static_cast( r ); + if ( ( rs->bResetTextureName = editTexOld->isEnabled() ) ) { + strcpy( rs->textureName, editTexOld->text().toLatin1().constData() ); + strcpy( rs->newTextureName, editTexNew->text().toLatin1().constData() ); + } + if ( ( rs->bResetScale[0] = spin_ScaleHor->isEnabled() ) ) + rs->fScale[0] = spin_ScaleHor->value(); + + if ( ( rs->bResetScale[1] = spin_ScaleVert->isEnabled() ) ) + rs->fScale[1] = spin_ScaleVert->value(); + + if ( ( rs->bResetShift[0] = spin_ShiftHor->isEnabled() ) ) + rs->fShift[0] = spin_ShiftHor->value(); + + if ( ( rs->bResetShift[1] = spin_ShiftVert->isEnabled() ) ) + rs->fShift[1] = spin_ShiftVert->value(); + + if ( ( rs->bResetRotation = spin_Rotation->isEnabled() ) ) + rs->rotation = spin_Rotation->value(); + } return ret; } -EMessageBoxReturn DoTrainThingBox( TrainThingRS* rs ){ - Str texSelected; - GtkWidget *window, *w, *vbox, *hbox, *frame, *table; - - GtkWidget *radiusX, *radiusY; - GtkWidget *angleStart, *angleEnd; - GtkWidget *heightStart, *heightEnd; - GtkWidget *numPoints; - - EMessageBoxReturn ret; - int loop = 1; - - window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - - g_signal_connect( G_OBJECT( window ), "delete_event", G_CALLBACK( dialog_delete_callback ), NULL ); - g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( gtk_widget_destroy ), NULL ); - - gtk_window_set_title( GTK_WINDOW( window ), "Train Thing" ); - gtk_container_set_border_width( GTK_CONTAINER( window ), 10 ); - - g_object_set_data( G_OBJECT( window ), "loop", &loop ); - g_object_set_data( G_OBJECT( window ), "ret", &ret ); - - gtk_widget_realize( window ); - - vbox = gtk_vbox_new( FALSE, 10 ); - gtk_container_add( GTK_CONTAINER( window ), vbox ); - gtk_widget_show( vbox ); - - // ---- vbox ---- - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 2 ); - gtk_widget_show( hbox ); - - // ---- /hbox ---- - - frame = gtk_frame_new( "Radii" ); - gtk_widget_show( frame ); - gtk_box_pack_start( GTK_BOX( vbox ), frame, FALSE, TRUE, 0 ); - - table = gtk_table_new( 2, 3, TRUE ); - gtk_widget_show( table ); - gtk_container_add( GTK_CONTAINER( frame ), table ); - gtk_table_set_row_spacings( GTK_TABLE( table ), 5 ); - gtk_table_set_col_spacings( GTK_TABLE( table ), 5 ); - gtk_container_set_border_width( GTK_CONTAINER( table ), 5 ); - - // ---- frame ---- - - w = gtk_label_new( "X: " ); - gtk_table_attach( GTK_TABLE( table ), w, 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( w ); - - radiusX = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( radiusX ), "100" ); - gtk_table_attach( GTK_TABLE( table ), radiusX, 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( radiusX ); - - - - w = gtk_label_new( "Y: " ); - gtk_table_attach( GTK_TABLE( table ), w, 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( w ); - - radiusY = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( radiusY ), "100" ); - gtk_table_attach( GTK_TABLE( table ), radiusY, 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( radiusY ); - - - - frame = gtk_frame_new( "Angles" ); - gtk_widget_show( frame ); - gtk_box_pack_start( GTK_BOX( vbox ), frame, FALSE, TRUE, 0 ); - - table = gtk_table_new( 2, 3, TRUE ); - gtk_widget_show( table ); - gtk_container_add( GTK_CONTAINER( frame ), table ); - gtk_table_set_row_spacings( GTK_TABLE( table ), 5 ); - gtk_table_set_col_spacings( GTK_TABLE( table ), 5 ); - gtk_container_set_border_width( GTK_CONTAINER( table ), 5 ); - - // ---- frame ---- - - w = gtk_label_new( "Start: " ); - gtk_table_attach( GTK_TABLE( table ), w, 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( w ); - - angleStart = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( angleStart ), "0" ); - gtk_table_attach( GTK_TABLE( table ), angleStart, 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( angleStart ); - - - - w = gtk_label_new( "End: " ); - gtk_table_attach( GTK_TABLE( table ), w, 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( w ); - - angleEnd = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( angleEnd ), "90" ); - gtk_table_attach( GTK_TABLE( table ), angleEnd, 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( angleEnd ); - - - frame = gtk_frame_new( "Height" ); - gtk_widget_show( frame ); - gtk_box_pack_start( GTK_BOX( vbox ), frame, FALSE, TRUE, 0 ); - - table = gtk_table_new( 2, 3, TRUE ); - gtk_widget_show( table ); - gtk_container_add( GTK_CONTAINER( frame ), table ); - gtk_table_set_row_spacings( GTK_TABLE( table ), 5 ); - gtk_table_set_col_spacings( GTK_TABLE( table ), 5 ); - gtk_container_set_border_width( GTK_CONTAINER( table ), 5 ); - - // ---- frame ---- - - w = gtk_label_new( "Start: " ); - gtk_table_attach( GTK_TABLE( table ), w, 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( w ); - - heightStart = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( heightStart ), "0" ); - gtk_table_attach( GTK_TABLE( table ), heightStart, 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( heightStart ); - - - - w = gtk_label_new( "End: " ); - gtk_table_attach( GTK_TABLE( table ), w, 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( w ); - - heightEnd = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( heightEnd ), "0" ); - gtk_table_attach( GTK_TABLE( table ), heightEnd, 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( heightEnd ); - - - - frame = gtk_frame_new( "Points" ); - gtk_widget_show( frame ); - gtk_box_pack_start( GTK_BOX( vbox ), frame, FALSE, TRUE, 0 ); - - table = gtk_table_new( 2, 3, TRUE ); - gtk_widget_show( table ); - gtk_container_add( GTK_CONTAINER( frame ), table ); - gtk_table_set_row_spacings( GTK_TABLE( table ), 5 ); - gtk_table_set_col_spacings( GTK_TABLE( table ), 5 ); - gtk_container_set_border_width( GTK_CONTAINER( table ), 5 ); - - // ---- frame ---- - - w = gtk_label_new( "Number: " ); - gtk_table_attach( GTK_TABLE( table ), w, 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( w ); - - numPoints = entry_new_with_max_length( 256 ); - gtk_entry_set_text( GTK_ENTRY( numPoints ), "0" ); - gtk_table_attach( GTK_TABLE( table ), numPoints, 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( numPoints ); - - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 2 ); - gtk_widget_show( hbox ); - - // ---- hbox ---- - - w = gtk_button_new_with_label( "Ok" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) ); - - gtk_widget_set_can_default( w, TRUE ); - gtk_widget_grab_default( w ); - gtk_widget_show( w ); - - w = gtk_button_new_with_label( "Cancel" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) ); - gtk_widget_show( w ); - ret = eIDCANCEL; - - // ---- /hbox ---- - - - gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); - gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER ); - gtk_widget_show( window ); - - bool dialogError = TRUE; - while ( dialogError ) - { - loop = 1; - while ( loop ) - gtk_main_iteration(); - - dialogError = FALSE; - - if ( ret != eIDCANCEL ) { - if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( radiusX ) ), "Radius (X)", &rs->fRadiusX ) ) { - dialogError = TRUE; - } - - if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( radiusY ) ), "Radius (Y)", &rs->fRadiusY ) ) { - dialogError = TRUE; - } - - if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( angleStart ) ), "Angle (Start)", &rs->fStartAngle ) ) { - dialogError = TRUE; - } - - if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( angleEnd ) ), "Angle (End)", &rs->fEndAngle ) ) { - dialogError = TRUE; - } - - if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( heightStart ) ), "Height (Start)", &rs->fStartHeight ) ) { - dialogError = TRUE; - } - - if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( heightEnd ) ), "Height (End)", &rs->fEndHeight ) ) { - dialogError = TRUE; - } - - if ( !ValidateTextInt( gtk_entry_get_text( GTK_ENTRY( numPoints ) ), "Num Points", &rs->iNumPoints ) ) { - dialogError = TRUE; - } - } - } - - gtk_widget_destroy( window ); - - return ret; -} // ailmanki // add a simple input for the MakeChain thing.. -EMessageBoxReturn DoMakeChainBox( MakeChainRS* rs ){ - GtkWidget *window, *w, *vbox, *hbox; - GtkWidget *textlinkNum, *textlinkName; - EMessageBoxReturn ret; - int loop = 1; +bool DoMakeChainBox( MakeChainRS* rs ){ + QDialog dialog( g_pRadiantWnd, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Make Chain" ); - const char *text = "Please set a value in the boxes below and press 'OK' to make a chain"; + QSpinBox *spin_linkNum; + QLineEdit *edit_linkName; - window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - - g_signal_connect( G_OBJECT( window ), "delete_event", G_CALLBACK( dialog_delete_callback ), NULL ); - g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( gtk_widget_destroy ), NULL ); - - gtk_window_set_title( GTK_WINDOW( window ), "Make Chain" ); - - gtk_container_set_border_width( GTK_CONTAINER( window ), 10 ); - - g_object_set_data( G_OBJECT( window ), "loop", &loop ); - g_object_set_data( G_OBJECT( window ), "ret", &ret ); - - gtk_widget_realize( window ); - - // new vbox - vbox = gtk_vbox_new( FALSE, 10 ); - gtk_container_add( GTK_CONTAINER( window ), vbox ); - gtk_widget_show( vbox ); - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_container_add( GTK_CONTAINER( vbox ), hbox ); - gtk_widget_show( hbox ); - - // dunno if you want this text or not ... - w = gtk_label_new( text ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 ); - gtk_widget_show( w ); - - w = gtk_hseparator_new(); - gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 ); - gtk_widget_show( w ); - - // ------------------------- // - - // new hbox - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - textlinkNum = entry_new_with_max_length( 256 ); - gtk_box_pack_start( GTK_BOX( hbox ), textlinkNum, FALSE, FALSE, 1 ); - gtk_widget_show( textlinkNum ); - - w = gtk_label_new( "Number of elements in chain" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 1 ); - gtk_widget_show( w ); - - // -------------------------- // - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - - textlinkName = entry_new_with_max_length( 256 ); - gtk_box_pack_start( GTK_BOX( hbox ), textlinkName, FALSE, FALSE, 0 ); - gtk_widget_show( textlinkName ); - - w = gtk_label_new( "Basename for chain's targetnames." ); - gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 1 ); - gtk_widget_show( w ); - - - w = gtk_button_new_with_label( "OK" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) ); - gtk_widget_set_can_default( w, TRUE ); - gtk_widget_grab_default( w ); - gtk_widget_show( w ); - - w = gtk_button_new_with_label( "Cancel" ); - gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( w ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) ); - gtk_widget_show( w ); - - ret = eIDCANCEL; - - gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); - gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER ); - gtk_widget_show( window ); - - bool dialogError = TRUE; - while ( dialogError ) { - loop = 1; - while ( loop ) - gtk_main_iteration(); - - dialogError = FALSE; - - if ( ret == eIDOK ) { - strcpy( rs->linkName, gtk_entry_get_text( GTK_ENTRY( textlinkName ) ) ); - if ( !ValidateTextInt( gtk_entry_get_text( GTK_ENTRY( textlinkNum ) ), "Elements", &rs->linkNum ) ) { - dialogError = TRUE; - } + auto form = new QFormLayout( &dialog ); + form->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + { + auto spin = spin_linkNum = new SpinBox( 1, 1000 ); + form->addRow( new SpinBoxLabel( "Number of elements in chain", spin ), spin ); + } + { + form->addRow( "Basename for chain's targetnames", edit_linkName = new QLineEdit ); + edit_linkName->setMaxLength( std::size( rs->linkName ) - 1 ); + } + { + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel ); + form->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept ); + QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject ); } } - gtk_widget_destroy( window ); - - return ret; + if( dialog.exec() ){ + rs->linkNum = spin_linkNum->value(); + strcpy( rs->linkName, edit_linkName->text().toLatin1().constData() ); + return true; + } + return false; } diff --git a/contrib/bobtoolz/dialogs/dialogs-gtk.h b/contrib/bobtoolz/dialogs/dialogs-gtk.h index ae354904..c331ab6d 100644 --- a/contrib/bobtoolz/dialogs/dialogs-gtk.h +++ b/contrib/bobtoolz/dialogs/dialogs-gtk.h @@ -17,8 +17,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#if !defined( INCLUDED_DIALOGS_GTK_H ) -#define INCLUDED_DIALOGS_GTK_H +#pragma once #include "qerplugin.h" @@ -32,27 +31,20 @@ struct BuildStairsRS { }; struct ResetTextureRS { - int bResetTextureName; + bool bResetTextureName; char textureName[256]; char newTextureName[256]; - int bResetScale[2]; + bool bResetScale[2]; float fScale[2]; - int bResetShift[2]; + bool bResetShift[2]; float fShift[2]; - int bResetRotation; + bool bResetRotation; int rotation; }; -struct TrainThingRS { - float fRadiusX, fRadiusY; - float fStartAngle, fEndAngle; - int iNumPoints; - float fStartHeight, fEndHeight; -}; - struct IntersectRS { int nBrushOptions; bool bUseDetail; @@ -90,23 +82,13 @@ struct MakeChainRS { int linkNum; }; -typedef struct _GtkWidget GtkWidget; -struct TwinWidget { - GtkWidget* one; - GtkWidget* two; -}; - -EMessageBoxReturn DoMessageBox( const char* lpText, const char* lpCaption, EMessageBoxType type ); -EMessageBoxReturn DoIntersectBox( IntersectRS* rs ); -EMessageBoxReturn DoPolygonBox( PolygonRS* rs ); +EMessageBoxReturn DoMessageBox( const char* lpText, const char* lpCaption, EMessageBoxType type = EMessageBoxType::Info ); +bool DoIntersectBox( IntersectRS* rs ); +bool DoPolygonBox( PolygonRS* rs ); EMessageBoxReturn DoResetTextureBox( ResetTextureRS* rs ); -EMessageBoxReturn DoBuildStairsBox( BuildStairsRS* rs ); -EMessageBoxReturn DoDoorsBox( DoorRS* rs ); +bool DoBuildStairsBox( BuildStairsRS* rs ); +bool DoDoorsBox( DoorRS* rs ); EMessageBoxReturn DoPathPlotterBox( PathPlotterRS* rs ); EMessageBoxReturn DoCTFColourChangeBox(); -EMessageBoxReturn DoTrainThingBox( TrainThingRS* rs ); -EMessageBoxReturn DoMakeChainBox( MakeChainRS* rs ); -//GtkWidget* GetProgressWindow(char* title, GtkProgressBar* feedback); - -#endif +bool DoMakeChainBox( MakeChainRS* rs ); diff --git a/contrib/bobtoolz/funchandlers-GTK.cpp b/contrib/bobtoolz/funchandlers-GTK.cpp index 9066315b..5fc5a2b2 100644 --- a/contrib/bobtoolz/funchandlers-GTK.cpp +++ b/contrib/bobtoolz/funchandlers-GTK.cpp @@ -61,8 +61,8 @@ bool el2Loaded = false; bool clrLst1Loaded = false; bool clrLst2Loaded = false; -DBobView* g_PathView = NULL; -DVisDrawer* g_VisView = NULL; +std::unique_ptr g_PathView; +std::unique_ptr g_VisView; DTrainDrawer* g_TrainView = NULL; DTreePlanter* g_TreePlanter = NULL; // ------------- @@ -91,13 +91,13 @@ void DoIntersect(){ UndoableCommand undo( "bobToolz.intersect" ); IntersectRS rs; - if ( DoIntersectBox( &rs ) == eIDCANCEL ) { + if ( !DoIntersectBox( &rs ) ) { return; } if ( rs.nBrushOptions == BRUSH_OPT_SELECTED ) { if ( GlobalSelectionSystem().countSelected() < 2 ) { - //DoMessageBox("Invalid number of brushes selected, choose at least 2", "Error", eMB_OK); + //DoMessageBox("Invalid number of brushes selected, choose at least 2", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz Intersect: Invalid number of brushes selected, choose at least 2.\n"; return; } @@ -143,7 +143,7 @@ void DoPolygons(){ UndoableCommand undo( "bobToolz.polygons" ); // ensure we have something selected if ( GlobalSelectionSystem().countSelected() != 1 ) { - //DoMessageBox("Invalid number of brushes selected, choose 1 only", "Error", eMB_OK); + //DoMessageBox("Invalid number of brushes selected, choose 1 only", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz Polygons: Invalid number of brushes selected, choose 1 only.\n"; return; } @@ -151,12 +151,12 @@ void DoPolygons(){ PolygonRS rs; scene::Instance& instance = GlobalSelectionSystem().ultimateSelected(); if ( !Node_isBrush( instance.path().top() ) ) { - //DoMessageBox("No brush selected, select ONLY one brush", "Error", eMB_OK); + //DoMessageBox("No brush selected, select ONLY one brush", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz Polygons: No brush selected, select ONLY one brush.\n"; return; } // ask user for type, size, etc.... - if ( DoPolygonBox( &rs ) == eIDOK ) { + if ( DoPolygonBox( &rs ) ) { DShape poly; vec3_t vMin, vMax; @@ -211,10 +211,7 @@ void DoResetTextures(){ strcpy( rs.textureName, GetCurrentTexture() ); } - EMessageBoxReturn ret; - if ( ( ret = DoResetTextureBox( &rs ) ) == eIDCANCEL ) { - return; - } + const EMessageBoxReturn ret = DoResetTextureBox( &rs ); if ( rs.bResetTextureName ) { texName = rs.textureName; @@ -226,7 +223,7 @@ void DoResetTextures(){ world.ResetTextures( texName, rs.fScale, rs.fShift, rs.rotation, rs.newTextureName, rs.bResetTextureName, rs.bResetScale, rs.bResetShift, rs.bResetRotation, true ); } - else + else if ( ret == eIDYES ) { DMap world; world.LoadAll( true ); @@ -243,13 +240,13 @@ void DoBuildStairs(){ // ensure we have something selected if ( GlobalSelectionSystem().countSelected() != 1 ) { - //DoMessageBox("Invalid number of brushes selected, choose 1 only", "Error", eMB_OK); + //DoMessageBox("Invalid number of brushes selected, choose 1 only", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz BuildStairs: Invalid number of brushes selected, choose 1 only.\n"; return; } // ask user for type, size, etc.... - if ( DoBuildStairsBox( &rs ) == eIDOK ) { + if ( DoBuildStairsBox( &rs ) ) { vec3_t vMin, vMax; { @@ -264,7 +261,7 @@ void DoBuildStairs(){ if ( ( (int)size[2] % rs.stairHeight ) != 0 ) { // stairs must fit evenly into brush - //DoMessageBox("Invalid stair height\nHeight of block must be divisable by stair height", "Error", eMB_OK); + //DoMessageBox("Invalid stair height\nHeight of block must be divisable by stair height", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz BuildStairs: Invalid stair height. Height of block must be divisable by stair height.\n"; } else @@ -331,15 +328,20 @@ void DoBuildDoors(){ UndoableCommand undo( "bobToolz.buildDoors" ); // ensure we have something selected if ( GlobalSelectionSystem().countSelected() != 1 ) { - //DoMessageBox("Invalid number of brushes selected, choose 1 only", "Error", eMB_OK); + //DoMessageBox("Invalid number of brushes selected, choose 1 only", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz BuildDoors: Invalid number of brushes selected, choose 1 only.\n"; return; } DoorRS rs; - strcpy( rs.mainTexture, GetCurrentTexture() ); + { + const char *tex = GetCurrentTexture(); + strcpy( rs.mainTexture, tex + ( string_equal_prefix_nocase( tex, "textures/" ) + ? strlen( "textures/" ) + : 0 ) ); + } - if ( DoDoorsBox( &rs ) == eIDOK ) { + if ( DoDoorsBox( &rs ) ) { vec3_t vMin, vMax; { @@ -352,7 +354,7 @@ void DoBuildDoors(){ BuildDoorsX2( vMin, vMax, rs.bScaleMainH, rs.bScaleMainV, rs.bScaleTrimH, rs.bScaleTrimV, - rs.mainTexture, rs.trimTexture, + ( std::string( "textures/" ) + rs.mainTexture ).c_str(), ( std::string( "textures/" ) + rs.trimTexture ).c_str(), rs.nOrientation ); // shapes.cpp } } @@ -365,34 +367,32 @@ void DoPathPlotter(){ return; } if ( ret == eIDNO ) { - if ( g_PathView ) { - delete g_PathView; - } + g_PathView.reset(); + SceneChangeNotify(); return; } // ensure we have something selected - /* - if( GlobalSelectionSystem().countSelected() != 1 ) - { - //DoMessageBox("Invalid number of brushes selected, choose 1 only", "Error", eMB_OK); - globalErrorStream() << "bobToolz PathPlotter: Invalid number of entities selected, choose 1 trigger_push entity only.\n"; - return; - } - */ + if( GlobalSelectionSystem().countSelected() != 1 ){ + //DoMessageBox("Invalid number of brushes selected, choose 1 only", "Error", EMessageBoxType::Error); + globalErrorStream() << "bobToolz PathPlotter: Invalid number of entities selected, choose 1 trigger_push entity only.\n"; + return; + } + Entity* entity = Node_getEntity( GlobalSelectionSystem().ultimateSelected().path().top() ); - if ( entity != 0 ) + if ( entity != 0 || ( entity = Node_getEntity( GlobalSelectionSystem().ultimateSelected().path().parent() ) ) ){ DBobView_setEntity( *entity, rs.fMultiplier, rs.nPoints, rs.fGravity, rs.bNoUpdate, rs.bShowExtra ); + SceneChangeNotify(); + } else globalErrorStream() << "bobToolz PathPlotter: No trigger_push entity selected, select 1 only (Use list to select it).\n"; - return; } void DoPitBuilder(){ UndoableCommand undo( "bobToolz.pitBuilder" ); // ensure we have something selected if ( GlobalSelectionSystem().countSelected() != 1 ) { - //DoMessageBox("Invalid number of brushes selected, choose 1 only", "Error", eMB_OK); + //DoMessageBox("Invalid number of brushes selected, choose 1 only", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz PitBuilder: Invalid number of brushes selected, choose 1 only.\n"; return; } @@ -402,7 +402,7 @@ void DoPitBuilder(){ scene::Instance& instance = GlobalSelectionSystem().ultimateSelected(); //seems it does this also with a patch with valid dimensions.. but probably better to enforce a brush. if ( !Node_isBrush( instance.path().top() ) ) { - //DoMessageBox("No brush selected, select ONLY one brush", "Error", eMB_OK); + //DoMessageBox("No brush selected, select ONLY one brush", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz PitBuilder: No brush selected, select ONLY 1 brush.\n"; return; } @@ -418,7 +418,7 @@ void DoPitBuilder(){ } else { - //DoMessageBox("Failed To Make Pit\nTry Making The Brush Bigger", "Error", eMB_OK); + //DoMessageBox("Failed To Make Pit\nTry Making The Brush Bigger", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz PitBuilder: Failed to make Pit, try making the brush bigger.\n"; } } @@ -507,7 +507,7 @@ void DoSplitPatch() { // ensure we have something selected if ( GlobalSelectionSystem().countSelected() != 1 ) { - //DoMessageBox("Invalid number of patches selected, choose 1 only", "Error", eMB_OK); + //DoMessageBox("Invalid number of patches selected, choose 1 only", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz SplitPatch: Invalid number of patches selected, choose only 1 patch.\n"; return; } @@ -515,7 +515,7 @@ void DoSplitPatch() { scene::Instance& instance = GlobalSelectionSystem().ultimateSelected(); if ( !Node_isPatch( instance.path().top() ) ) { - //DoMessageBox("No patch selected, select ONLY one patch", "Error", eMB_OK); + //DoMessageBox("No patch selected, select ONLY one patch", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz SplitPatch: No patch selected, select ONLY 1 patch.\n"; return; } @@ -536,7 +536,7 @@ void DoSplitPatchCols() { // ensure we have something selected if ( GlobalSelectionSystem().countSelected() != 1 ) { - //DoMessageBox("Invalid number of patches selected, choose 1 only", "Error", eMB_OK); + //DoMessageBox("Invalid number of patches selected, choose 1 only", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz SplitPatchCols: Invalid number of patches selected, choose 1 only.\n"; return; } @@ -544,7 +544,7 @@ void DoSplitPatchCols() { scene::Instance& instance = GlobalSelectionSystem().ultimateSelected(); if ( !Node_isPatch( instance.path().top() ) ) { - //DoMessageBox("No patch selected, select ONLY one patch", "Error", eMB_OK); + //DoMessageBox("No patch selected, select ONLY one patch", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz SplitPatchCols: No patch selected, select ONLY 1 patch.\n"; return; } @@ -565,7 +565,7 @@ void DoSplitPatchRows() { // ensure we have something selected if ( GlobalSelectionSystem().countSelected() != 1 ) { - //DoMessageBox("Invalid number of patches selected, choose 1 only", "Error", eMB_OK); + //DoMessageBox("Invalid number of patches selected, choose 1 only", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz SplitPatchRows: Invalid number of patches selected, choose 1 only.\n"; return; } @@ -573,7 +573,7 @@ void DoSplitPatchRows() { scene::Instance& instance = GlobalSelectionSystem().ultimateSelected(); if ( !Node_isPatch( instance.path().top() ) ) { - //DoMessageBox("No patch selected, select ONLY one patch", "Error", eMB_OK); + //DoMessageBox("No patch selected, select ONLY one patch", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz SplitPatchRows: No patch selected, select ONLY 1 patch.\n"; return; } @@ -590,7 +590,7 @@ void DoSplitPatchRows() { void DoVisAnalyse(){ const char* rad_filename = GlobalRadiant().getMapName(); if ( !rad_filename ) { - //DoMessageBox("An ERROR occurred while trying\n to get the map filename", "Error", eMB_OK); + //DoMessageBox("An ERROR occurred while trying\n to get the map filename", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz VisAnalyse: An ERROR occurred while trying to get the map filename.\n"; return; } @@ -603,10 +603,10 @@ void DoVisAnalyse(){ vec3_t origin; if ( GlobalSelectionSystem().countSelected() == 0 ) { - memcpy( origin, GlobalRadiant().Camera_getOrigin().data(), 3 * sizeof ( ( ( Vector3* ) ( 0 ) ) -> x() ) ); + memcpy( origin, GlobalRadiant().Camera_getOrigin().data(), 3 * sizeof( Vector3().x() ) ); } else{ - memcpy( origin, GlobalSelectionSystem().getBoundsSelected().origin.data(), 3 * sizeof ( ( ( Vector3* ) ( 0 ) ) -> x() ) ); + memcpy( origin, GlobalSelectionSystem().getBoundsSelected().origin.data(), 3 * sizeof( Vector3().x() ) ); } DMetaSurfaces* pointList = BuildTrace( filename, origin ); @@ -615,7 +615,7 @@ void DoVisAnalyse(){ globalOutputStream() << "bobToolz VisAnalyse: " << pointList->size() << " drawsurfaces loaded\n"; if ( !g_VisView ) { - g_VisView = new DVisDrawer; + g_VisView = std::make_unique(); } g_VisView->SetList( pointList ); @@ -638,8 +638,8 @@ void DoCaulkSelection() { float fScale[2] = { 0.5f, 0.5f }; float fShift[2] = { 0.0f, 0.0f }; - int bResetScale[2] = { false, false }; - int bResetShift[2] = { false, false }; + bool bResetScale[2] = { false, false }; + bool bResetShift[2] = { false, false }; world.LoadSelectedBrushes(); world.LoadSelectedPatches(); @@ -666,7 +666,7 @@ void DoDropEnts() { void DoMakeChain() { MakeChainRS rs; - if ( DoMakeChainBox( &rs ) == eIDOK ) { + if ( DoMakeChainBox( &rs ) ) { if ( rs.linkNum > 1001 ) { globalErrorStream() << "bobToolz MakeChain: " << rs.linkNum << " to many Elemets, limited to 1000.\n"; return; @@ -688,7 +688,7 @@ void DoFlipTerrain() { // ensure we have something selected if ( GlobalSelectionSystem().countSelected() != 2 ) { - //DoMessageBox("Invalid number of objects selected, choose 2 only", "Error", eMB_OK); + //DoMessageBox("Invalid number of objects selected, choose 2 only", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz FlipTerrain: Invalid number of objects selected, choose 2 only.\n"; return; } @@ -700,7 +700,7 @@ void DoFlipTerrain() { for ( i = 0; i < 2; i++ ) { if ( !Node_isBrush( brushes[i]->path().top() ) ) { - //DoMessageBox("No brushes selected, select ONLY brushes", "Error", eMB_OK); + //DoMessageBox("No brushes selected, select ONLY brushes", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz FlipTerrain: No brushes selected, select ONLY 2 brushes.\n"; return; } @@ -711,7 +711,7 @@ void DoFlipTerrain() { for ( i = 0; i < 2; i++ ) { Brushes[i].LoadFromBrush( *brushes[i], false ); if ( !( Planes[i] = Brushes[i].FindPlaneWithClosestNormal( vUp ) ) || Brushes[i].FindPointsForPlane( Planes[i], Points[i], 3 ) != 3 ) { - //DoMessageBox("Error", "Error", eMB_OK); + //DoMessageBox("Error", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz FlipTerrain: ERROR (FindPlaneWithClosestNormal/FindPointsForPlane).\n"; return; } @@ -739,7 +739,7 @@ void DoFlipTerrain() { found = false; } if ( dontmatch[0] == -1 ) { - //DoMessageBox("Error", "Error", eMB_OK); + //DoMessageBox("Error", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz FlipTerrain: ERROR (dontmatch[0]).\n"; return; } @@ -758,7 +758,7 @@ void DoFlipTerrain() { found = false; } if ( dontmatch[1] == -1 ) { - //DoMessageBox("Error", "Error", eMB_OK); + //DoMessageBox("Error", "Error", EMessageBoxType::Error); globalErrorStream() << "bobToolz FlipTerrain: ERROR (dontmatch[1]).\n"; return; } diff --git a/contrib/bobtoolz/funchandlers-ctf-GTK.cpp b/contrib/bobtoolz/funchandlers-ctf-GTK.cpp index d6cc80c0..666c5ddb 100644 --- a/contrib/bobtoolz/funchandlers-ctf-GTK.cpp +++ b/contrib/bobtoolz/funchandlers-ctf-GTK.cpp @@ -61,7 +61,7 @@ void LoadLists(){ void DoCTFColourChanger(){ if ( !clrLst1Loaded || !clrLst2Loaded ) { - DoMessageBox( "CTF texture lists not found, this function will terminate.", "Error", MB_OK ); + DoMessageBox( "CTF texture lists not found, this function will terminate.", "Error", EMessageBoxType::Error ); return; } diff --git a/contrib/bobtoolz/funchandlers.h b/contrib/bobtoolz/funchandlers.h index 34b7b402..5c55e576 100644 --- a/contrib/bobtoolz/funchandlers.h +++ b/contrib/bobtoolz/funchandlers.h @@ -19,13 +19,13 @@ #pragma once -class DBobView; -class DVisDrawer; +#include + class DTrainDrawer; class DTreePlanter; -extern DBobView* g_PathView; -extern DVisDrawer* g_VisView; +extern std::unique_ptr g_PathView; +extern std::unique_ptr g_VisView; extern DTrainDrawer* g_TrainView; extern DTreePlanter* g_TreePlanter; diff --git a/contrib/bobtoolz/lists.cpp b/contrib/bobtoolz/lists.cpp index b6c8a104..215ac94a 100644 --- a/contrib/bobtoolz/lists.cpp +++ b/contrib/bobtoolz/lists.cpp @@ -19,15 +19,12 @@ #include "lists.h" -#include - #include "misc.h" bool LoadExclusionList( char* filename, std::list* exclusionList ){ FILE* eFile = fopen( filename, "r" ); if ( eFile ) { char buffer[256]; - int cnt = 0; while ( !feof( eFile ) ) { memset( buffer, 0, 256 ); @@ -36,43 +33,37 @@ bool LoadExclusionList( char* filename, std::list* exclusionList ){ if ( strlen( buffer ) > 0 ) { exclusionList->push_back( buffer ); } - else{ - cnt++; - } } fclose( eFile ); - return TRUE; + return true; } globalErrorStream() << "Failed To Load Exclusion List: " << filename << "\n"; - return FALSE; + return false; } -bool LoadListStore( char* filename, GtkListStore* loadlist ){ +QStringList LoadListStore( char* filename ){ + QStringList list; FILE* eFile = fopen( filename, "r" ); if ( eFile ) { char buffer[256]; - int cnt = 0; while ( !feof( eFile ) ) { memset( buffer, 0, 256 ); fscanf( eFile, "%s\n", buffer ); if ( strlen( buffer ) > 0 ) { - gtk_list_store_insert_with_values( loadlist, NULL, -1, 0, buffer, -1 ); - } - else{ - cnt++; + list.append( buffer ); } } fclose( eFile ); - return TRUE; + return list; } globalErrorStream() << "Failed To Load GList: " << filename << "\n"; - return FALSE; + return list; } diff --git a/contrib/bobtoolz/lists.h b/contrib/bobtoolz/lists.h index 62e8d846..35da22ff 100644 --- a/contrib/bobtoolz/lists.h +++ b/contrib/bobtoolz/lists.h @@ -21,7 +21,7 @@ #include #include "str.h" -typedef struct _GtkListStore GtkListStore; +#include bool LoadExclusionList( char* filename, std::list* exclusionList ); -bool LoadListStore( char* filename, GtkListStore* loadlist ); +QStringList LoadListStore( char* filename ); diff --git a/contrib/bobtoolz/misc.cpp b/contrib/bobtoolz/misc.cpp index 4904f987..6f30d4f6 100644 --- a/contrib/bobtoolz/misc.cpp +++ b/contrib/bobtoolz/misc.cpp @@ -254,27 +254,32 @@ void BuildMiniPrt( std::list* exclusionList ){ StartBSP(); } -class EntityFindByTargetName +class EntityFindByKeyValue { - const char* targetname; + const char* m_key; + const char* m_value; public: mutable const scene::Path* result; - EntityFindByTargetName( const char* targetname ) - : targetname( targetname ), result( 0 ){ + EntityFindByKeyValue( const char* key, const char* value ) + : m_key( key ), m_value( value ), result( 0 ){ } void operator()( scene::Instance& instance ) const { if ( result == 0 ) { - const char* value = Node_getEntity( instance.path().top() )->getKeyValue( "targetname" ); + const char* value = Node_getEntity( instance.path().top() )->getKeyValue( m_key ); - if ( !strcmp( value, targetname ) ) { + if ( !strcmp( value, m_value ) ) { result = &instance.path(); } } } }; +const scene::Path* FindEntityFromTarget( const char* target ){ + return Scene_forEachEntity( EntityFindByKeyValue( "target", target ) ).result; +} + const scene::Path* FindEntityFromTargetname( const char* targetname ){ - return Scene_forEachEntity( EntityFindByTargetName( targetname ) ).result; + return Scene_forEachEntity( EntityFindByKeyValue( "targetname", targetname ) ).result; } void FillDefaultTexture( _QERFaceData* faceData, vec3_t va, vec3_t vb, vec3_t vc, const char* texture ){ @@ -303,8 +308,10 @@ float Determinant3x3( float a1, float a2, float a3, return a1 * ( b2 * c3 - b3 * c2 ) - a2 * ( b1 * c3 - b3 * c1 ) + a3 * ( b1 * c2 - b2 * c1 ); } -bool GetEntityCentre( const char* entity, vec3_t centre ){ - const scene::Path* ent = FindEntityFromTargetname( entity ); +bool GetEntityCentre( const char* entityKey, bool keyIsTarget, vec3_t centre ){ + const scene::Path* ent = keyIsTarget + ? FindEntityFromTarget( entityKey ) + : FindEntityFromTargetname( entityKey ); if ( !ent ) { return false; } diff --git a/contrib/bobtoolz/misc.h b/contrib/bobtoolz/misc.h index 867fdcef..dba390d2 100644 --- a/contrib/bobtoolz/misc.h +++ b/contrib/bobtoolz/misc.h @@ -39,6 +39,7 @@ void BuildMiniPrt( std::list* exclusionList ); void MoveBlock( int dir, vec3_t min, vec3_t max, float dist ); void SetInitialStairPos( int dir, vec3_t min, vec3_t max, float width ); +const scene::Path* FindEntityFromTarget( const char* target ); const scene::Path* FindEntityFromTargetname( const char* targetname ); char* UnixToDosPath( char* path ); @@ -50,5 +51,5 @@ float Determinant3x3( float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3 ); -bool GetEntityCentre( const char* entity, vec3_t centre ); +bool GetEntityCentre( const char* entityKey, bool keyIsTarget, vec3_t centre ); void MakeNormal( const vec_t* va, const vec_t* vb, const vec_t* vc, vec_t* out ); diff --git a/contrib/bobtoolz/shapes.cpp b/contrib/bobtoolz/shapes.cpp index 5cb09dc9..aa3be34e 100644 --- a/contrib/bobtoolz/shapes.cpp +++ b/contrib/bobtoolz/shapes.cpp @@ -45,8 +45,6 @@ #include "scenelib.h" #include "texturelib.h" -//#include "dialogs-gtk.h" - /************************ Cube Diagram ************************/ diff --git a/contrib/bobtoolz/visfind.cpp b/contrib/bobtoolz/visfind.cpp index 11ee3c05..f61c0df3 100644 --- a/contrib/bobtoolz/visfind.cpp +++ b/contrib/bobtoolz/visfind.cpp @@ -141,7 +141,7 @@ void AddCluster( DMetaSurfaces* pointlist, dleaf_t *cl, bool* repeatlist, con qdrawVert_t* vert = &drawVerts[surf->firstVert]; if ( surf->firstVert + surf->numVerts > numDrawVerts ) { - DoMessageBox( "Warning", "Warning", eMB_OK ); + DoMessageBox( "Warning", "Warning", EMessageBoxType::Warning ); } DMetaSurf* meta = new DMetaSurf( surf->numVerts, surf->numIndexes ); diff --git a/contrib/brushexport/callbacks.cpp b/contrib/brushexport/callbacks.cpp index 7aca1300..36a5efb0 100644 --- a/contrib/brushexport/callbacks.cpp +++ b/contrib/brushexport/callbacks.cpp @@ -1,6 +1,7 @@ -#include -#include -#include + + +#include "callbacks.h" + #include #include "qerplugin.h" @@ -8,17 +9,16 @@ #include "os/path.h" #include "os/file.h" #include "stream/stringstream.h" -#include "support.h" #include "export.h" + + namespace callbacks { static std::string s_export_path; -void OnExportClicked( GtkButton* button, gpointer choose_path ){ - GtkWidget* window = lookup_widget( GTK_WIDGET( button ), "w_plugplug2" ); - ASSERT_NOTNULL( window ); +void OnExportClicked( bool choose_path ){ if( choose_path ){ StringOutputStream buffer( 1024 ); @@ -35,7 +35,7 @@ void OnExportClicked( GtkButton* button, gpointer choose_path ){ } } - const char* cpath = GlobalRadiant().m_pfnFileDialog( window, false, "Save as Obj", buffer.c_str(), 0, false, false, true ); + const char* cpath = GlobalRadiant().m_pfnFileDialog( g_dialog.window, false, "Save as Obj", buffer.c_str(), 0, false, false, true ); if ( !cpath ) { return; } @@ -43,11 +43,9 @@ void OnExportClicked( GtkButton* button, gpointer choose_path ){ if( !string_equal_suffix_nocase( s_export_path.c_str(), ".obj" ) ) s_export_path += ".obj"; // enable button to reexport with the selected name - GtkWidget* b_export = lookup_widget( GTK_WIDGET( button ), "b_export" ); - ASSERT_NOTNULL( b_export ); - gtk_widget_set_sensitive( b_export, TRUE ); + g_dialog.b_export->setEnabled( true ); // add tooltip - gtk_widget_set_tooltip_text( b_export, ( std::string( "ReExport to " ) + s_export_path ).c_str() ); + g_dialog.b_export->setToolTip( ( std::string( "ReExport to " ) + s_export_path ).c_str() ); } else if( s_export_path.empty() ){ return; @@ -59,21 +57,9 @@ void OnExportClicked( GtkButton* button, gpointer choose_path ){ return string_less_nocase( lhs.c_str(), rhs.c_str() ); } ); - GtkTreeView* view = GTK_TREE_VIEW( lookup_widget( GTK_WIDGET( button ), "t_materialist" ) ); - GtkListStore* list = GTK_LIST_STORE( gtk_tree_view_get_model( view ) ); - - GtkTreeIter iter; - gboolean valid = gtk_tree_model_get_iter_first( GTK_TREE_MODEL( list ), &iter ); - while ( valid ) + for( int i = 0; i < g_dialog.t_materialist->count(); ++i ) { - gchar* data; - gtk_tree_model_get( GTK_TREE_MODEL( list ), &iter, 0, &data, -1 ); -#ifdef _DEBUG - globalOutputStream() << data << "\n"; -#endif - ignore.insert( std::string( data ) ); - g_free( data ); - valid = gtk_tree_model_iter_next( GTK_TREE_MODEL( list ), &iter ); + ignore.insert( g_dialog.t_materialist->item( i )->text().toStdString() ); } #ifdef _DEBUG for ( const std::string& str : ignore ) @@ -82,77 +68,46 @@ void OnExportClicked( GtkButton* button, gpointer choose_path ){ // collapse mode collapsemode mode = COLLAPSE_NONE; - GtkWidget* radio = lookup_widget( GTK_WIDGET( button ), "r_collapse" ); - ASSERT_NOTNULL( radio ); - - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( radio ) ) ) { + if ( g_dialog.r_collapse->isChecked() ) { mode = COLLAPSE_ALL; } - else - { - radio = lookup_widget( GTK_WIDGET( button ), "r_collapsebymaterial" ); - ASSERT_NOTNULL( radio ); - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( radio ) ) ) { - mode = COLLAPSE_BY_MATERIAL; - } - else - { - radio = lookup_widget( GTK_WIDGET( button ), "r_nocollapse" ); - ASSERT_NOTNULL( radio ); - ASSERT_NOTNULL( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( radio ) ) ); - mode = COLLAPSE_NONE; - } + else if ( g_dialog.r_collapsebymaterial->isChecked() ) { + mode = COLLAPSE_BY_MATERIAL; + } + else{ + ASSERT_NOTNULL( g_dialog.r_nocollapse->isChecked() ); + mode = COLLAPSE_NONE; } - GtkWidget* toggle; // export materials? - ASSERT_NOTNULL( ( toggle = lookup_widget( GTK_WIDGET( button ), "t_exportmaterials" ) ) ); - const bool exportmat = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( toggle ) ); + const bool exportmat = g_dialog.t_exportmaterials->isChecked(); // limit material names? - ASSERT_NOTNULL( ( toggle = lookup_widget( GTK_WIDGET( button ), "t_limitmatnames" ) ) ); - const bool limitMatNames = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( toggle ) ); + const bool limitMatNames = g_dialog.t_limitmatnames->isChecked(); // create objects instead of groups? - ASSERT_NOTNULL( ( toggle = lookup_widget( GTK_WIDGET( button ), "t_objects" ) ) ); - const bool objects = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( toggle ) ); + const bool objects = g_dialog.t_objects->isChecked(); - ASSERT_NOTNULL( ( toggle = lookup_widget( GTK_WIDGET( button ), "t_weld" ) ) ); - const bool weld = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( toggle ) ); + const bool weld = g_dialog.t_weld->isChecked(); // export ExportSelection( ignore, mode, exportmat, s_export_path, limitMatNames, objects, weld ); } -void OnAddMaterial( GtkButton* button, gpointer user_data ){ - GtkEntry* edit = GTK_ENTRY( lookup_widget( GTK_WIDGET( button ), "ed_materialname" ) ); - ASSERT_NOTNULL( edit ); +void OnAddMaterial(){ + const auto text = g_dialog.ed_materialname->text().toLatin1(); - const gchar* name = path_get_filename_start( gtk_entry_get_text( edit ) ); - if ( g_utf8_strlen( name, -1 ) > 0 ) { - GtkListStore* list = GTK_LIST_STORE( gtk_tree_view_get_model( GTK_TREE_VIEW( lookup_widget( GTK_WIDGET( button ), "t_materialist" ) ) ) ); - GtkTreeIter iter; - gtk_list_store_append( list, &iter ); - gtk_list_store_set( list, &iter, 0, name, -1 ); - gtk_entry_set_text( edit, "" ); + const char* name = path_get_filename_start( text.constData() ); + if ( strlen( name ) > 0 ) { + auto item = new QListWidgetItem( name ); + item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren ); + g_dialog.t_materialist->addItem( item ); } } -void OnRemoveMaterial( GtkButton* button, gpointer user_data ){ - GtkTreeView* view = GTK_TREE_VIEW( lookup_widget( GTK_WIDGET( button ), "t_materialist" ) ); - GtkListStore* list = GTK_LIST_STORE( gtk_tree_view_get_model( view ) ); - GtkTreeSelection* sel = gtk_tree_view_get_selection( view ); - - GtkTreeIter iter; - if ( gtk_tree_selection_get_selected( sel, 0, &iter ) ) { - gtk_list_store_remove( list, &iter ); - } +void OnRemoveMaterial(){ + qDeleteAll( g_dialog.t_materialist->selectedItems() ); } -gboolean OnRemoveMaterialKb( GtkWidget* widget, GdkEventKey* event, gpointer user_data ){ - if( event->keyval == GDK_KEY_Delete ) - OnRemoveMaterial( reinterpret_cast( widget ), NULL ); - return FALSE; -} } // callbacks diff --git a/contrib/brushexport/callbacks.h b/contrib/brushexport/callbacks.h index 21eb6b06..bf74bdcf 100644 --- a/contrib/brushexport/callbacks.h +++ b/contrib/brushexport/callbacks.h @@ -1,14 +1,41 @@ #pragma once -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkButton GtkButton; +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct BrushexportDialog +{ + QWidget *window; + QPushButton *b_export; + QListWidget *t_materialist; + + QRadioButton *r_collapse; + QRadioButton *r_collapsebymaterial; + QRadioButton *r_nocollapse; + + QCheckBox *t_exportmaterials; + QCheckBox *t_limitmatnames; + QCheckBox *t_objects; + QCheckBox *t_weld; + + QLineEdit *ed_materialname; +}; + +inline BrushexportDialog g_dialog{}; + namespace callbacks { -void OnExportClicked( GtkButton *, gpointer ); -void OnAddMaterial( GtkButton *, gpointer ); -void OnRemoveMaterial( GtkButton *, gpointer ); -gboolean OnRemoveMaterialKb( GtkWidget *, GdkEventKey *, gpointer ); +void OnExportClicked( bool choose_path ); +void OnAddMaterial(); +void OnRemoveMaterial(); } // callbacks diff --git a/contrib/brushexport/export.cpp b/contrib/brushexport/export.cpp index 80731b81..b61df2b8 100644 --- a/contrib/brushexport/export.cpp +++ b/contrib/brushexport/export.cpp @@ -312,7 +312,7 @@ bool ExportDataAsWavefront::WriteToFile( const std::string& path, collapsemode m } outMtl << "# Wavefront material file exported with NetRadiants brushexport plugin.\n"; - outMtl << "# Material Count: " << (Unsigned)materials.size() << "\n\n"; + outMtl << "# Material Count: " << materials.size() << "\n\n"; for ( const auto& material : materials ) { const std::string& str = material.first; @@ -380,7 +380,7 @@ bool ExportSelection( const StringSetWithLambda& ignorelist, collapsemode m, boo if( GlobalSelectionSystem().countSelected() == 0 ){ globalErrorStream() << "Nothing is selected.\n"; - GlobalRadiant().m_pfnMessageBox( g_pRadiantWnd, "Nothing is selected.", "brushexport", eMB_OK, eMB_ICONERROR ); + GlobalRadiant().m_pfnMessageBox( g_pRadiantWnd, "Nothing is selected.", "brushexport", EMessageBoxType::Error, 0 ); return false; } diff --git a/contrib/brushexport/interface.cpp b/contrib/brushexport/interface.cpp index b1b071bb..0e3c7f9e 100644 --- a/contrib/brushexport/interface.cpp +++ b/contrib/brushexport/interface.cpp @@ -1,196 +1,122 @@ -#include -#include + #include "debugging/debugging.h" #include "callbacks.h" -#include "support.h" #include "plugin.h" -#define GLADE_HOOKUP_OBJECT( component,widget,name ) \ - g_object_set_data_full( G_OBJECT( component ), name, \ - g_object_ref( (gpointer)widget ), (GDestroyNotify) g_object_unref ) +#include +inline void qt_connect_shortcut_override( QWidget *widget ){ + class Filter : public QObject + { + using QObject::QObject; + protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::ShortcutOverride ) { + event->accept(); + return true; + } + return QObject::eventFilter( obj, event ); // standard event processing + } + }; + widget->installEventFilter( new Filter( widget ) ); +} -#define GLADE_HOOKUP_OBJECT_NO_REF( component,widget,name ) \ - g_object_set_data( G_OBJECT( component ), name, widget ) +#include +class Del_QListWidget : public QListWidget +{ + using QListWidget::QListWidget; +protected: + void keyPressEvent( QKeyEvent *event ) override { + if( event->matches( QKeySequence::StandardKey::Delete ) ) + callbacks::OnRemoveMaterial(); + QListWidget::keyPressEvent( event ); + } +}; -// created by glade -GtkWidget* -create_w_plugplug2( void ){ - GtkWidget *w_plugplug2; - GtkWidget *vbox1; - GtkWidget *hbox2; - GtkWidget *vbox4; - GtkWidget *r_collapse; - GtkWidget *r_collapsebymaterial; - GtkWidget *r_nocollapse; - GtkWidget *vbox3; - GtkWidget *b_export; - GtkWidget *b_exportAs; - GtkWidget *b_close; - GtkWidget *vbox2; - GtkWidget *label1; - GtkWidget *scrolledwindow1; - GtkWidget *t_materialist; - GtkWidget *ed_materialname; - GtkWidget *hbox1; - GtkWidget *b_addmaterial; - GtkWidget *b_removematerial; - GtkWidget *t_exportmaterials; - GtkWidget *t_limitmatnames; - GtkWidget *t_objects; - GtkWidget *t_weld; - - w_plugplug2 = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - gtk_window_set_title( GTK_WINDOW( w_plugplug2 ), "BrushExport-Plugin 3.0 by namespace" ); - gtk_window_set_position( GTK_WINDOW( w_plugplug2 ), GTK_WIN_POS_CENTER_ON_PARENT ); - gtk_window_set_transient_for( GTK_WINDOW( w_plugplug2 ), GTK_WINDOW( g_pRadiantWnd ) ); - gtk_window_set_destroy_with_parent( GTK_WINDOW( w_plugplug2 ), TRUE ); - - vbox1 = gtk_vbox_new( FALSE, 0 ); - gtk_container_add( GTK_CONTAINER( w_plugplug2 ), vbox1 ); - gtk_container_set_border_width( GTK_CONTAINER( vbox1 ), 5 ); - - hbox2 = gtk_hbox_new( TRUE, 5 ); - gtk_box_pack_start( GTK_BOX( vbox1 ), hbox2, FALSE, FALSE, 0 ); - gtk_container_set_border_width( GTK_CONTAINER( hbox2 ), 5 ); - - vbox4 = gtk_vbox_new( TRUE, 0 ); - gtk_box_pack_start( GTK_BOX( hbox2 ), vbox4, TRUE, FALSE, 0 ); - - r_collapse = gtk_radio_button_new_with_label_from_widget( NULL, "Collapse mesh" ); - gtk_widget_set_tooltip_text( r_collapse, "Collapse all brushes into a single group" ); - gtk_box_pack_start( GTK_BOX( vbox4 ), r_collapse, FALSE, FALSE, 0 ); - - r_collapsebymaterial = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON( r_collapse ), "Collapse by material" ); - gtk_widget_set_tooltip_text( r_collapsebymaterial, "Collapse into groups by material" ); - gtk_box_pack_start( GTK_BOX( vbox4 ), r_collapsebymaterial, FALSE, FALSE, 0 ); - - r_nocollapse = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON( r_collapse ), "Don't collapse" ); - gtk_widget_set_tooltip_text( r_nocollapse, "Every brush is stored in its own group" ); - gtk_box_pack_start( GTK_BOX( vbox4 ), r_nocollapse, FALSE, FALSE, 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( r_nocollapse ), TRUE ); - - vbox3 = gtk_vbox_new( FALSE, 0 ); - gtk_box_pack_start( GTK_BOX( hbox2 ), vbox3, FALSE, FALSE, 0 ); - - b_export = gtk_button_new_from_stock( "gtk-save" ); - gtk_box_pack_start( GTK_BOX( vbox3 ), b_export, TRUE, FALSE, 0 ); - gtk_container_set_border_width( GTK_CONTAINER( b_export ), 5 ); - gtk_widget_set_sensitive( b_export, FALSE ); - - b_exportAs = gtk_button_new_from_stock( "gtk-save-as" ); - gtk_box_pack_start( GTK_BOX( vbox3 ), b_exportAs, TRUE, FALSE, 0 ); - gtk_container_set_border_width( GTK_CONTAINER( b_exportAs ), 5 ); - - b_close = gtk_button_new_from_stock( "gtk-cancel" ); - gtk_box_pack_start( GTK_BOX( vbox3 ), b_close, TRUE, FALSE, 0 ); - gtk_container_set_border_width( GTK_CONTAINER( b_close ), 5 ); - - vbox2 = gtk_vbox_new( FALSE, 5 ); - gtk_box_pack_start( GTK_BOX( vbox1 ), vbox2, TRUE, TRUE, 0 ); - gtk_container_set_border_width( GTK_CONTAINER( vbox2 ), 2 ); - - label1 = gtk_label_new( "Ignored materials:" ); - gtk_box_pack_start( GTK_BOX( vbox2 ), label1, FALSE, FALSE, 0 ); - - scrolledwindow1 = gtk_scrolled_window_new( NULL, NULL ); - gtk_box_pack_start( GTK_BOX( vbox2 ), scrolledwindow1, TRUE, TRUE, 0 ); - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolledwindow1 ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); - gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scrolledwindow1 ), GTK_SHADOW_IN ); +QWidget* create_w_plugplug2(){ + auto window = g_dialog.window = new QWidget( g_pRadiantWnd, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + window->setWindowTitle( "BrushExport-Plugin 3.0 by namespace" ); + qt_connect_shortcut_override( window ); { - t_materialist = gtk_tree_view_new(); - gtk_container_add( GTK_CONTAINER( scrolledwindow1 ), t_materialist ); - gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( t_materialist ), FALSE ); - gtk_tree_view_set_enable_search( GTK_TREE_VIEW( t_materialist ), FALSE ); + auto grid = new QGridLayout( window ); + { + auto r_collapse = g_dialog.r_collapse = new QRadioButton( "Collapse mesh" ); + r_collapse->setToolTip( "Collapse all brushes into a single group" ); + grid->addWidget( r_collapse, 0, 0 ); - // column & renderer - GtkTreeViewColumn* col = gtk_tree_view_column_new(); - gtk_tree_view_column_set_title( col, "materials" ); - gtk_tree_view_append_column( GTK_TREE_VIEW( t_materialist ), col ); - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_insert_column_with_attributes( GTK_TREE_VIEW( t_materialist ), -1, "", renderer, "text", 0, NULL ); + auto r_collapsebymaterial = g_dialog.r_collapsebymaterial = new QRadioButton( "Collapse by material" ); + r_collapsebymaterial->setToolTip( "Collapse into groups by material" ); + grid->addWidget( r_collapsebymaterial, 1, 0 ); - // list store - GtkListStore* ignorelist = gtk_list_store_new( 1, G_TYPE_STRING ); - gtk_tree_view_set_model( GTK_TREE_VIEW( t_materialist ), GTK_TREE_MODEL( ignorelist ) ); - g_object_unref( ignorelist ); + auto r_nocollapse = g_dialog.r_nocollapse = new QRadioButton( "Don't collapse" ); + r_nocollapse->setToolTip( "Every brush is stored in its own group" ); + grid->addWidget( r_nocollapse, 2, 0 ); + r_nocollapse->setChecked( true ); + } + { + auto b_export = g_dialog.b_export = new QPushButton( "Save" ); + grid->addWidget( b_export, 0, 1 ); + b_export->setDisabled( true ); + QObject::connect( b_export, &QAbstractButton::clicked, callbacks::OnExportClicked ); + + auto b_exportAs = new QPushButton( "Save As" ); + grid->addWidget( b_exportAs, 1, 1 ); + QObject::connect( b_exportAs, &QAbstractButton::clicked, [](){ + callbacks::OnExportClicked( true ); + } ); + + auto b_close = new QPushButton( "Cancel" ); + grid->addWidget( b_close, 2, 1 ); + QObject::connect( b_close, &QAbstractButton::clicked, window, &QWidget::hide ); + } + { + grid->addWidget( new QLabel( "Ignored materials:" ), 3, 0, 1, 2, Qt::AlignmentFlag::AlignHCenter ); + } + { + auto t_materialist = g_dialog.t_materialist = new Del_QListWidget; + grid->addWidget( t_materialist, 4, 0, 1, 2 ); + t_materialist->setEditTriggers( QAbstractItemView::EditTrigger::DoubleClicked | QAbstractItemView::EditTrigger::EditKeyPressed ); + } + { + auto ed_materialname = g_dialog.ed_materialname = new QLineEdit; + grid->addWidget( ed_materialname, 5, 0, 1, 2 ); + QObject::connect( ed_materialname, &QLineEdit::returnPressed, callbacks::OnAddMaterial ); + } + { + auto b_addmaterial = new QPushButton( "Add" ); + grid->addWidget( b_addmaterial, 6, 0 ); + QObject::connect( b_addmaterial, &QAbstractButton::clicked, callbacks::OnAddMaterial ); + + auto b_removematerial = new QPushButton( "Remove" ); + grid->addWidget( b_removematerial, 6, 1 ); + QObject::connect( b_removematerial, &QAbstractButton::clicked, callbacks::OnRemoveMaterial ); + } + { + auto t_limitmatnames = g_dialog.t_limitmatnames = new QCheckBox( "Use short material names (max. 20 chars)" ); + grid->addWidget( t_limitmatnames, 7, 0, 1, 2 ); + + auto t_objects = g_dialog.t_objects = new QCheckBox( "Create (o)bjects instead of (g)roups" ); + grid->addWidget( t_objects, 8, 0, 1, 2 ); + + auto t_weld = g_dialog.t_weld = new QCheckBox( "Weld vertices" ); + grid->addWidget( t_weld, 9, 0, 1, 2 ); + t_weld->setToolTip( "inside groups/objects" ); + t_weld->setChecked( true ); + + auto t_exportmaterials = g_dialog.t_exportmaterials = new QCheckBox( "Create material information (.mtl file)" ); + grid->addWidget( t_exportmaterials, 10, 0, 1, 2 ); + t_exportmaterials->setChecked( true ); + } } - ed_materialname = gtk_entry_new(); - gtk_box_pack_start( GTK_BOX( vbox2 ), ed_materialname, FALSE, FALSE, 0 ); - - hbox1 = gtk_hbox_new( TRUE, 0 ); - gtk_box_pack_start( GTK_BOX( vbox2 ), hbox1, FALSE, FALSE, 0 ); - - b_addmaterial = gtk_button_new_from_stock( "gtk-add" ); - gtk_box_pack_start( GTK_BOX( hbox1 ), b_addmaterial, FALSE, FALSE, 0 ); - - b_removematerial = gtk_button_new_from_stock( "gtk-remove" ); - gtk_box_pack_start( GTK_BOX( hbox1 ), b_removematerial, FALSE, FALSE, 0 ); - - t_limitmatnames = gtk_check_button_new_with_mnemonic( "Use short material names (max. 20 chars)" ); - gtk_box_pack_end( GTK_BOX( vbox2 ), t_limitmatnames, FALSE, FALSE, 0 ); - - t_objects = gtk_check_button_new_with_mnemonic( "Create (o)bjects instead of (g)roups" ); - gtk_box_pack_end( GTK_BOX( vbox2 ), t_objects, FALSE, FALSE, 0 ); - - t_weld = gtk_check_button_new_with_mnemonic( "Weld vertices" ); - gtk_widget_set_tooltip_text( t_weld, "inside groups/objects" ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( t_weld ), TRUE ); - gtk_box_pack_end( GTK_BOX( vbox2 ), t_weld, FALSE, FALSE, 0 ); - - t_exportmaterials = gtk_check_button_new_with_mnemonic( "Create material information (.mtl file)" ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( t_exportmaterials ), TRUE ); - gtk_box_pack_end( GTK_BOX( vbox2 ), t_exportmaterials, FALSE, FALSE, 0 ); - - using namespace callbacks; - g_signal_connect( G_OBJECT( w_plugplug2 ), "delete_event", G_CALLBACK( gtk_widget_hide_on_delete ), NULL ); - g_signal_connect_swapped( G_OBJECT( b_close ), "clicked", G_CALLBACK( gtk_widget_hide ), w_plugplug2 ); - - g_signal_connect( G_OBJECT( b_export ), "clicked", G_CALLBACK( OnExportClicked ), NULL ); - g_signal_connect( G_OBJECT( b_exportAs ), "clicked", G_CALLBACK( OnExportClicked ), gpointer( 1 ) ); - g_signal_connect( G_OBJECT( b_addmaterial ), "clicked", G_CALLBACK( OnAddMaterial ), NULL ); - g_signal_connect( G_OBJECT( ed_materialname ), "activate", G_CALLBACK( OnAddMaterial ), NULL ); // NB: wrong callback, but pointer casting works - g_signal_connect( G_OBJECT( b_removematerial ), "clicked", G_CALLBACK( OnRemoveMaterial ), NULL ); - g_signal_connect( G_OBJECT( t_materialist ), "key-press-event", G_CALLBACK( OnRemoveMaterialKb ), NULL ); - - - /* Store pointers to all widgets, for use by lookup_widget(). */ - GLADE_HOOKUP_OBJECT_NO_REF( w_plugplug2, w_plugplug2, "w_plugplug2" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, vbox1, "vbox1" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, hbox2, "hbox2" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, vbox4, "vbox4" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, r_collapse, "r_collapse" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, r_collapsebymaterial, "r_collapsebymaterial" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, r_nocollapse, "r_nocollapse" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, vbox3, "vbox3" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, b_export, "b_export" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, b_close, "b_close" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, vbox2, "vbox2" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, label1, "label1" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, scrolledwindow1, "scrolledwindow1" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, t_materialist, "t_materialist" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, ed_materialname, "ed_materialname" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, hbox1, "hbox1" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, b_addmaterial, "b_addmaterial" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, b_removematerial, "b_removematerial" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, t_exportmaterials, "t_exportmaterials" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, t_limitmatnames, "t_limitmatnames" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, t_objects, "t_objects" ); - GLADE_HOOKUP_OBJECT( w_plugplug2, t_weld, "t_weld" ); - - gtk_widget_show_all( w_plugplug2 ); - - return w_plugplug2; + return window; } // global main window, is 0 when not created -GtkWidget* g_brushexp_window = 0; - // spawn or unhide plugin window -void CreateWindow( void ){ - if( !g_brushexp_window ) - g_brushexp_window = create_w_plugplug2(); - gtk_widget_show( g_brushexp_window ); +void CreateWindow(){ + if( g_dialog.window == nullptr ) + g_dialog.window = create_w_plugplug2(); + g_dialog.window->show(); } diff --git a/contrib/brushexport/plugin.cpp b/contrib/brushexport/plugin.cpp index 308d510d..eff18555 100644 --- a/contrib/brushexport/plugin.cpp +++ b/contrib/brushexport/plugin.cpp @@ -23,15 +23,11 @@ #include "iplugin.h" #include "qerplugin.h" -#include - #include "debugging/debugging.h" #include "string/string.h" #include "modulesystem/singletonmodule.h" #include "stream/textfilestream.h" #include "stream/stringstream.h" -#include "gtkutil/messagebox.h" -#include "gtkutil/filechooser.h" #include "ibrush.h" #include "iscenegraph.h" @@ -39,22 +35,19 @@ #include "ifilesystem.h" #include "ifiletypes.h" -#include "support.h" - #include "typesystem.h" void CreateWindow( void ); -GtkWidget *g_pRadiantWnd = NULL; +QWidget *g_pRadiantWnd = nullptr; namespace BrushExport { -GtkWindow* g_mainwnd; +QWidget* g_mainwnd; const char* init( void* hApp, void* pMainWidget ){ - g_mainwnd = (GtkWindow*)pMainWidget; - g_pRadiantWnd = (GtkWidget*)pMainWidget; - ASSERT_NOTNULL( g_mainwnd ); + g_pRadiantWnd = static_cast( pMainWidget ); + ASSERT_NOTNULL( g_pRadiantWnd ); return ""; } const char* getName(){ @@ -69,11 +62,11 @@ const char* getCommandTitleList(){ void dispatch( const char* command, float* vMin, float* vMax, bool bSingleBrush ){ if ( string_equal( command, "About" ) ) { - GlobalRadiant().m_pfnMessageBox( GTK_WIDGET( g_mainwnd ), - "Brushexport plugin v 2.0 by namespace (www.codecreator.net)\n" - "Enjoy!\n\nSend feedback to spam@codecreator.net", "About me...", - eMB_OK, - eMB_ICONDEFAULT ); + GlobalRadiant().m_pfnMessageBox( g_pRadiantWnd, + "Brushexport plugin v 3.0 by namespace (http://www.codecreator.net)
" + "Enjoy!

" + "Send feedback to spam@codecreator.net", + "About me...", EMessageBoxType::Info, 0 ); } else if ( string_equal( command, "Export .obj" ) ) { CreateWindow(); diff --git a/contrib/brushexport/plugin.h b/contrib/brushexport/plugin.h index 44b5367d..96fad497 100644 --- a/contrib/brushexport/plugin.h +++ b/contrib/brushexport/plugin.h @@ -21,5 +21,4 @@ #pragma once -typedef struct _GtkWidget GtkWidget; -extern GtkWidget *g_pRadiantWnd; +extern class QWidget *g_pRadiantWnd; diff --git a/contrib/brushexport/support.cpp b/contrib/brushexport/support.cpp deleted file mode 100644 index 3bc57cdf..00000000 --- a/contrib/brushexport/support.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include - -#include "support.h" - -GtkWidget* -lookup_widget( GtkWidget *widget, - const gchar *widget_name ){ - GtkWidget *parent, *found_widget; - - for (;; ) - { - if ( GTK_IS_MENU( widget ) ) { - parent = gtk_menu_get_attach_widget( GTK_MENU( widget ) ); - } - else{ - parent = gtk_widget_get_parent( widget ); - } - if ( !parent ) { - parent = (GtkWidget*) g_object_get_data( G_OBJECT( widget ), "GladeParentKey" ); - } - if ( parent == NULL ) { - break; - } - widget = parent; - } - - found_widget = (GtkWidget*) g_object_get_data( G_OBJECT( widget ), - widget_name ); - if ( !found_widget ) { - g_warning( "Widget not found: %s", widget_name ); - } - return found_widget; -} diff --git a/contrib/brushexport/support.h b/contrib/brushexport/support.h deleted file mode 100644 index f02cd776..00000000 --- a/contrib/brushexport/support.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * DO NOT EDIT THIS FILE - it is generated by Glade. - */ - -#pragma once - -#include - -/* - * Public Functions. - */ - -/* - * This function returns a widget in a component created by Glade. - * Call it with the toplevel widget in the component (i.e. a window/dialog), - * or alternatively any widget in the component, and the name of the widget - * you want returned. - */ -GtkWidget* lookup_widget( GtkWidget *widget, - const gchar *widget_name ); diff --git a/contrib/meshtex/AllocatedMatrix.h b/contrib/meshtex/AllocatedMatrix.h index 3967d6c8..1f470cb4 100644 --- a/contrib/meshtex/AllocatedMatrix.h +++ b/contrib/meshtex/AllocatedMatrix.h @@ -23,8 +23,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_ALLOCATEDMATRIX_H) -#define INCLUDED_ALLOCATEDMATRIX_H +#pragma once #include "debugging/debugging.h" #include "ipatch.h" @@ -66,5 +65,3 @@ private: // private member vars */ Element *_allocated; }; - -#endif // #if !defined(INCLUDED_ALLOCATEDMATRIX_H) diff --git a/contrib/meshtex/GeneralFunctionDialog.cpp b/contrib/meshtex/GeneralFunctionDialog.cpp index cf229916..66c8eb42 100644 --- a/contrib/meshtex/GeneralFunctionDialog.cpp +++ b/contrib/meshtex/GeneralFunctionDialog.cpp @@ -23,8 +23,6 @@ * along with MeshTex. If not, see . */ -#include - #include "GenericPluginUI.h" #include "GeneralFunctionDialog.h" #include "PluginUIMessages.h" @@ -95,506 +93,203 @@ GeneralFunctionDialog::GeneralFunctionDialog(const std::string& key) : GenericDialog(key), _nullVisitor(new MeshVisitor()) { - // Enable the usual handling of the close event. - CreateWindowCloseCallback(); - // Configure the dialog window. - gtk_window_set_resizable(GTK_WINDOW(_dialog), FALSE); - gtk_window_set_title(GTK_WINDOW(_dialog), DIALOG_GEN_FUNC_TITLE); - gtk_container_set_border_width(GTK_CONTAINER(_dialog), 10); + _dialog->setWindowTitle(DIALOG_GEN_FUNC_TITLE); // Create the contained widgets. - - GtkWidget *table; - GtkWidget *entry; - GtkWidget *applybutton, *refbutton, *button; - GtkWidget *separator; - GtkWidget *label; - GtkWidget *mainvbox, *vbox, *hbox, *mainhbox; - GtkWidget *frame; - - table = gtk_table_new(6, 13, FALSE); - gtk_table_set_row_spacing(GTK_TABLE(table), 0, 5); - gtk_table_set_row_spacing(GTK_TABLE(table), 1, 10); - gtk_table_set_row_spacing(GTK_TABLE(table), 3, 15); - gtk_table_set_row_spacing(GTK_TABLE(table), 4, 15); - gtk_container_add(GTK_CONTAINER(_dialog), table); - gtk_widget_show(table); - - hbox = gtk_hbox_new(TRUE, 10); - gtk_table_attach(GTK_TABLE(table), hbox, 0, 13, 0, 1, GTK_SHRINK, GTK_EXPAND, 0, 0); - gtk_widget_show(hbox); - - // Mutually exclusive "Surface values" and "Control values" radio buttons. - - button = gtk_radio_button_new_with_label_from_widget(NULL, - DIALOG_GEN_FUNC_SURFACE_VALUES); - g_object_set_data(G_OBJECT(_dialog), "surface", button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_show(button); - - button = gtk_radio_button_new_with_label_from_widget( - GTK_RADIO_BUTTON(button), - DIALOG_GEN_FUNC_CONTROL_VALUES); - g_object_set_data(G_OBJECT(_dialog), "control", button); - gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); - - separator = gtk_hseparator_new(); - gtk_table_attach_defaults(GTK_TABLE(table), separator, 0, 13, 1, 2); - gtk_widget_show(separator); - - // Checkbox for the "S" row of factors. All the other widgets on this row - // will have a dependence registered on this checkbox; i.e. they will only - // be active when it is checked. - - applybutton = gtk_check_button_new(); - g_object_set_data(G_OBJECT(_dialog), "s_apply", applybutton); - gtk_table_attach_defaults(GTK_TABLE(table), applybutton, 0, 1, 2, 3); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(applybutton), TRUE); - gtk_widget_show(applybutton); - - label = gtk_label_new(DIALOG_GEN_FUNC_S_FUNC_LABEL); - gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 2, 3); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "s_oldval", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "1.0"); - gtk_table_attach_defaults(GTK_TABLE(table), entry, 2, 3, 2, 3); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - - label = gtk_label_new(DIALOG_GEN_FUNC_OLD_S_LABEL); - gtk_table_attach_defaults(GTK_TABLE(table), label, 3, 4, 2, 3); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "s_rowdist", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0.0"); - gtk_table_attach_defaults(GTK_TABLE(table), entry, 4, 5, 2, 3); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - - label = gtk_label_new(DIALOG_GEN_FUNC_ROW_DIST_LABEL); - gtk_table_attach_defaults(GTK_TABLE(table), label, 5, 6, 2, 3); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "s_coldist", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0.0"); - gtk_table_attach_defaults(GTK_TABLE(table), entry, 6, 7, 2, 3); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - - label = gtk_label_new(DIALOG_GEN_FUNC_COL_DIST_LABEL); - gtk_table_attach_defaults(GTK_TABLE(table), label, 7, 8, 2, 3); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "s_rownum", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0.0"); - gtk_table_attach_defaults(GTK_TABLE(table), entry, 8, 9, 2, 3); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - - label = gtk_label_new(DIALOG_GEN_FUNC_ROW_NUM_LABEL); - gtk_table_attach_defaults(GTK_TABLE(table), label, 9, 10, 2, 3); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "s_colnum", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0.0"); - gtk_table_attach_defaults(GTK_TABLE(table), entry, 10, 11, 2, 3); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - - label = gtk_label_new(DIALOG_GEN_FUNC_COL_NUM_LABEL); - gtk_table_attach_defaults(GTK_TABLE(table), label, 11, 12, 2, 3); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "s_constant", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0.0"); - gtk_table_attach_defaults(GTK_TABLE(table), entry, 12, 13, 2, 3); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - - // Checkbox for the "T" row of factors. All the other widgets on this row - // will have a dependence registered on this checkbox; i.e. they will only - // be active when it is checked. - - applybutton = gtk_check_button_new(); - g_object_set_data(G_OBJECT(_dialog), "t_apply", applybutton); - gtk_table_attach_defaults(GTK_TABLE(table), applybutton, 0, 1, 3, 4); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(applybutton), TRUE); - gtk_widget_show(applybutton); - - label = gtk_label_new(DIALOG_GEN_FUNC_T_FUNC_LABEL); - gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 3, 4); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "t_oldval", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "1.0"); - gtk_table_attach_defaults(GTK_TABLE(table), entry, 2, 3, 3, 4); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - - label = gtk_label_new(DIALOG_GEN_FUNC_OLD_T_LABEL); - gtk_table_attach_defaults(GTK_TABLE(table), label, 3, 4, 3, 4); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "t_rowdist", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0.0"); - gtk_table_attach_defaults(GTK_TABLE(table), entry, 4, 5, 3, 4); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - - label = gtk_label_new(DIALOG_GEN_FUNC_ROW_DIST_LABEL); - gtk_table_attach_defaults(GTK_TABLE(table), label, 5, 6, 3, 4); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "t_coldist", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0.0"); - gtk_table_attach_defaults(GTK_TABLE(table), entry, 6, 7, 3, 4); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - - label = gtk_label_new(DIALOG_GEN_FUNC_COL_DIST_LABEL); - gtk_table_attach_defaults(GTK_TABLE(table), label, 7, 8, 3, 4); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "t_rownum", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0.0"); - gtk_table_attach_defaults(GTK_TABLE(table), entry, 8, 9, 3, 4); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - - label = gtk_label_new(DIALOG_GEN_FUNC_ROW_NUM_LABEL); - gtk_table_attach_defaults(GTK_TABLE(table), label, 9, 10, 3, 4); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "t_colnum", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0.0"); - gtk_table_attach_defaults(GTK_TABLE(table), entry, 10, 11, 3, 4); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - - label = gtk_label_new(DIALOG_GEN_FUNC_COL_NUM_LABEL); - gtk_table_attach_defaults(GTK_TABLE(table), label, 11, 12, 3, 4); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "t_constant", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0.0"); - gtk_table_attach_defaults(GTK_TABLE(table), entry, 12, 13, 3, 4); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - - mainhbox = gtk_hbox_new(TRUE, 0); - gtk_table_attach(GTK_TABLE(table), mainhbox, 0, 13, 4, 5, GTK_SHRINK, GTK_EXPAND, 0, 0); - gtk_widget_show(mainhbox); - - mainvbox = gtk_vbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(mainhbox), mainvbox, FALSE, FALSE, 0); - gtk_widget_show(mainvbox); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(mainvbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - frame = gtk_frame_new(DIALOG_GEN_FUNC_COL_ALIGN_FRAME_LABEL); - gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 5); - gtk_widget_show(frame); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(frame), vbox); - gtk_widget_show(vbox); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - // Widgets for specifying the alignment column. - - button = gtk_radio_button_new(NULL); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_show(button); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "col_num_align", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0"); - gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 5); - gtk_widget_set_size_request(entry, 25, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(button, entry); - - button = gtk_radio_button_new_with_label_from_widget( - GTK_RADIO_BUTTON(button), - DIALOG_GEN_FUNC_MAX_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "col_max_align", button); - gtk_box_pack_end(GTK_BOX(hbox), button, TRUE, FALSE, 5); - gtk_widget_show(button); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(mainvbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - // Widgets for specifying the reference row & usage. - - refbutton = gtk_check_button_new_with_label(DIALOG_GEN_FUNC_REF_ROW_FRAME_LABEL); - g_object_set_data(G_OBJECT(_dialog), "row_ref", refbutton); - gtk_widget_show(refbutton); - - frame = gtk_frame_new(NULL); - gtk_frame_set_label_widget(GTK_FRAME(frame), refbutton); - gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 5); - gtk_widget_show(frame); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(frame), vbox); - gtk_widget_show(vbox); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - button = gtk_radio_button_new(NULL); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_set_sensitive(button, FALSE); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(refbutton, button); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "row_num_ref", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0"); - gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 5); - gtk_widget_set_size_request(entry, 25, -1); - gtk_widget_set_sensitive(entry, FALSE); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(refbutton, entry); - UIInstance().RegisterWidgetDependence(button, entry); - - button = gtk_radio_button_new_with_label_from_widget( - GTK_RADIO_BUTTON(button), - DIALOG_GEN_FUNC_MAX_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "row_max_ref", button); - gtk_box_pack_end(GTK_BOX(hbox), button, TRUE, FALSE, 5); - gtk_widget_set_sensitive(button, FALSE); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(refbutton, button); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_end(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - button = gtk_check_button_new_with_label(DIALOG_GEN_FUNC_REF_TOTAL_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "row_ref_total", button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_set_sensitive(button, FALSE); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(refbutton, button); - - mainvbox = gtk_vbox_new(FALSE, 0); - gtk_box_pack_end(GTK_BOX(mainhbox), mainvbox, FALSE, FALSE, 0); - gtk_widget_show(mainvbox); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(mainvbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - frame = gtk_frame_new(DIALOG_GEN_FUNC_ROW_ALIGN_FRAME_LABEL); - gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 5); - gtk_widget_show(frame); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(frame), vbox); - gtk_widget_show(vbox); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - // Widgets for specifying the alignment row. - - button = gtk_radio_button_new(NULL); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_show(button); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "row_num_align", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0"); - gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 5); - gtk_widget_set_size_request(entry, 25, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(button, entry); - - button = gtk_radio_button_new_with_label_from_widget( - GTK_RADIO_BUTTON(button), - DIALOG_GEN_FUNC_MAX_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "row_max_align", button); - gtk_box_pack_end(GTK_BOX(hbox), button, TRUE, FALSE, 5); - gtk_widget_show(button); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(mainvbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - // Widgets for specifying the reference column & usage. - - refbutton = gtk_check_button_new_with_label(DIALOG_GEN_FUNC_REF_COL_FRAME_LABEL); - g_object_set_data(G_OBJECT(_dialog), "col_ref", refbutton); - gtk_widget_show(refbutton); - - frame = gtk_frame_new(NULL); - gtk_frame_set_label_widget(GTK_FRAME(frame), refbutton); - gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 5); - gtk_widget_show(frame); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(frame), vbox); - gtk_widget_show(vbox); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - button = gtk_radio_button_new(NULL); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_set_sensitive(button, FALSE); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(refbutton, button); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "col_num_ref", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0"); - gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 5); - gtk_widget_set_size_request(entry, 25, -1); - gtk_widget_set_sensitive(entry, FALSE); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(refbutton, entry); - UIInstance().RegisterWidgetDependence(button, entry); - - button = gtk_radio_button_new_with_label_from_widget( - GTK_RADIO_BUTTON(button), - DIALOG_GEN_FUNC_MAX_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "col_max_ref", button); - gtk_box_pack_end(GTK_BOX(hbox), button, TRUE, FALSE, 5); - gtk_widget_set_sensitive(button, FALSE); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(refbutton, button); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_end(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - button = gtk_check_button_new_with_label(DIALOG_GEN_FUNC_REF_TOTAL_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "col_ref_total", button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_set_sensitive(button, FALSE); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(refbutton, button); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_table_attach_defaults(GTK_TABLE(table), hbox, 0, 13, 5, 6); - gtk_widget_show(hbox); - - // Create Cancel button and hook it to callback. - - button = gtk_button_new_with_label(DIALOG_CANCEL_BUTTON); - gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_widget_set_size_request(button, 60, -1); - gtk_widget_show(button); - - CreateCancelButtonCallback(button); - - // Create Apply button and hook it to callback. - - button = gtk_button_new_with_label(DIALOG_APPLY_BUTTON); - gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 10); - gtk_widget_set_size_request (button, 60, -1); - gtk_widget_show(button); - - CreateApplyButtonCallback(button); - - // Create OK button and hook it to callback. - - button = gtk_button_new_with_label(DIALOG_OK_BUTTON); - gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_widget_set_size_request (button, 60, -1); - gtk_widget_show(button); - - CreateOkButtonCallback(button); + { + auto grid = new QGridLayout( _dialog ); // 6 x 13 + grid->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + grid->setColumnStretch( 0, 1 ); + grid->setColumnStretch( 3, 1 ); + { + // Mutually exclusive "Surface values" and "Control values" radio buttons. + { + auto radio = surface = new QRadioButton( DIALOG_GEN_FUNC_SURFACE_VALUES ); + grid->addWidget( radio, 0, 1 ); + radio->setChecked( true ); + } + { + auto radio = new QRadioButton( DIALOG_GEN_FUNC_CONTROL_VALUES ); + grid->addWidget( radio, 0, 2 ); + } + { + auto line = new QFrame; + line->setFrameShape( QFrame::Shape::HLine ); + line->setFrameShadow( QFrame::Shadow::Raised ); + grid->addWidget( line, 1, 0, 1, 4 ); + } + // Checkbox for the "S" row of factors. All the other widgets on this row + // will have a dependence registered on this checkbox; i.e. they will only + // be active when it is checked. + { + auto hbox = new QHBoxLayout; + grid->addLayout( hbox, 2, 0, 1, 4 ); + + auto check = s_apply = new QCheckBox; + check->setChecked( true ); + hbox->addWidget( check ); + + auto container = new QWidget; + hbox->addWidget( container ); + UIInstance().RegisterWidgetDependence( check, container ); + + auto container_hbox = new QHBoxLayout( container ); + container_hbox->setContentsMargins( 0, 0, 0, 0 ); + { + const struct{ const char* name; QDoubleSpinBox *&spin; } data[] = { + { DIALOG_GEN_FUNC_S_FUNC_LABEL, s_oldval }, + { DIALOG_GEN_FUNC_OLD_S_LABEL, s_rowdist }, + { DIALOG_GEN_FUNC_ROW_DIST_LABEL, s_coldist }, + { DIALOG_GEN_FUNC_COL_DIST_LABEL, s_rownum }, + { DIALOG_GEN_FUNC_ROW_NUM_LABEL, s_colnum }, + { DIALOG_GEN_FUNC_COL_NUM_LABEL, s_constant }, + }; + for( auto [ name, spin ] : data ) + { + container_hbox->addWidget( new QLabel( name ) ); + container_hbox->addWidget( spin = new DoubleSpinBox( -999, 999, 0, 3, .01 ) ); + } + s_oldval->setValue( 1 ); + } + } + // Checkbox for the "T" row of factors. All the other widgets on this row + // will have a dependence registered on this checkbox; i.e. they will only + // be active when it is checked. + { + auto hbox = new QHBoxLayout; + grid->addLayout( hbox, 3, 0, 1, 4 ); + + auto check = t_apply = new QCheckBox; + check->setChecked( true ); + hbox->addWidget( check ); + + auto container = new QWidget; + hbox->addWidget( container ); + UIInstance().RegisterWidgetDependence( check, container ); + + auto container_hbox = new QHBoxLayout( container ); + container_hbox->setContentsMargins( 0, 0, 0, 0 ); + { + const struct{ const char* name; QDoubleSpinBox *&spin; } data[] = { + { DIALOG_GEN_FUNC_T_FUNC_LABEL, t_oldval }, + { DIALOG_GEN_FUNC_OLD_S_LABEL, t_rowdist }, + { DIALOG_GEN_FUNC_ROW_DIST_LABEL, t_coldist }, + { DIALOG_GEN_FUNC_COL_DIST_LABEL, t_rownum }, + { DIALOG_GEN_FUNC_ROW_NUM_LABEL, t_colnum }, + { DIALOG_GEN_FUNC_COL_NUM_LABEL, t_constant }, + }; + for( auto [ name, spin ] : data ) + { + container_hbox->addWidget( new QLabel( name ) ); + container_hbox->addWidget( spin = new DoubleSpinBox( -999, 999, 0, 3, .01 ) ); + } + t_oldval->setValue( 1 ); + } + } + { + // Widgets for specifying the alignment column. + auto group = new QGroupBox( DIALOG_GEN_FUNC_COL_ALIGN_FRAME_LABEL ); + grid->addWidget( group, 4, 1 ); + + auto grid = new QGridLayout( group ); + grid->setColumnStretch( 2, 1 ); + { + auto radio = new QRadioButton; + grid->addWidget( radio, 0, 0 ); + auto spin = col_num_align = new SpinBox( 0, 30 ); + grid->addWidget( spin, 0, 1 ); + UIInstance().RegisterWidgetDependence( radio, spin ); + radio->setChecked( true ); + } + { + auto radio = new QRadioButton( DIALOG_GEN_FUNC_MAX_OPT_LABEL ); + grid->addWidget( radio, 0, 2, Qt::AlignmentFlag::AlignRight ); + } + } + { + // Widgets for specifying the reference row & usage. + auto group = row_ref = new QGroupBox( DIALOG_GEN_FUNC_REF_ROW_FRAME_LABEL ); + group->setCheckable( true ); + group->setChecked( true ); + grid->addWidget( group, 5, 1 ); + + auto grid = new QGridLayout( group ); + grid->setColumnStretch( 2, 1 ); + { + auto radio = new QRadioButton; + grid->addWidget( radio, 0, 0 ); + auto spin = row_num_ref = new SpinBox( 0, 30 ); + grid->addWidget( spin, 0, 1 ); + UIInstance().RegisterWidgetDependence( radio, spin ); + radio->setChecked( true ); + } + { + auto radio = new QRadioButton( DIALOG_GEN_FUNC_MAX_OPT_LABEL ); + grid->addWidget( radio, 0, 2, Qt::AlignmentFlag::AlignRight ); + } + { + auto check = row_ref_total = new QCheckBox( DIALOG_GEN_FUNC_REF_TOTAL_OPT_LABEL ); + grid->addWidget( check, 1, 0, 1, 3 ); + check->setChecked( true ); + } + } + { + // Widgets for specifying the alignment row. + auto group = new QGroupBox( DIALOG_GEN_FUNC_ROW_ALIGN_FRAME_LABEL ); + grid->addWidget( group, 4, 2 ); + + auto grid = new QGridLayout( group ); + grid->setColumnStretch( 2, 1 ); + { + auto radio = new QRadioButton; + grid->addWidget( radio, 0, 0 ); + auto spin = row_num_align = new SpinBox( 0, 30 ); + grid->addWidget( spin, 0, 1 ); + UIInstance().RegisterWidgetDependence( radio, spin ); + radio->setChecked( true ); + } + { + auto radio = new QRadioButton( DIALOG_GEN_FUNC_MAX_OPT_LABEL ); + grid->addWidget( radio, 0, 2, Qt::AlignmentFlag::AlignRight ); + } + } + { + // Widgets for specifying the reference column & usage. + auto group = col_ref = new QGroupBox( DIALOG_GEN_FUNC_REF_COL_FRAME_LABEL ); + group->setCheckable( true ); + group->setChecked( true ); + grid->addWidget( group, 5, 2 ); + + auto grid = new QGridLayout( group ); + grid->setColumnStretch( 2, 1 ); + { + auto radio = new QRadioButton; + grid->addWidget( radio, 0, 0 ); + auto spin = col_num_ref = new SpinBox( 0, 30 ); + grid->addWidget( spin, 0, 1 ); + UIInstance().RegisterWidgetDependence( radio, spin ); + radio->setChecked( true ); + } + { + auto radio = new QRadioButton( DIALOG_GEN_FUNC_MAX_OPT_LABEL ); + grid->addWidget( radio, 0, 2, Qt::AlignmentFlag::AlignRight ); + } + { + auto check = col_ref_total = new QCheckBox( DIALOG_GEN_FUNC_REF_TOTAL_OPT_LABEL ); + grid->addWidget( check, 1, 0, 1, 3 ); + check->setChecked( true ); + } + } + { + auto buttons = new QDialogButtonBox; + grid->addWidget( buttons, 6, 0, 1, 4 ); + CreateOkButtonCallback( buttons->addButton( QDialogButtonBox::StandardButton::Ok ) ); + CreateApplyButtonCallback( buttons->addButton( QDialogButtonBox::StandardButton::Apply ) ); + CreateCancelButtonCallback( buttons->addButton( QDialogButtonBox::StandardButton::Cancel ) ); + } + } + } } /** @@ -625,8 +320,8 @@ GeneralFunctionDialog::Apply() } // See if we're going to be affecting the S and/or T texture axis. - bool sApply = NamedToggleWidgetActive("s_apply"); - bool tApply = NamedToggleWidgetActive("t_apply"); + const bool sApply = s_apply->isChecked(); + const bool tApply = t_apply->isChecked(); if (!sApply && !tApply) { @@ -642,50 +337,50 @@ GeneralFunctionDialog::Apply() if (sApply) { // S axis is affected, so read the S factors. - s.oldValue = (float)atof(NamedEntryWidgetText("s_oldval")); - s.rowDistance = (float)atof(NamedEntryWidgetText("s_rowdist")); - s.colDistance = (float)atof(NamedEntryWidgetText("s_coldist")); - s.rowNumber = (float)atof(NamedEntryWidgetText("s_rownum")); - s.colNumber = (float)atof(NamedEntryWidgetText("s_colnum")); - s.constant = (float)atof(NamedEntryWidgetText("s_constant")); + s.oldValue = s_oldval->value(); + s.rowDistance = s_rowdist->value(); + s.colDistance = s_coldist->value(); + s.rowNumber = s_rownum->value(); + s.colNumber = s_colnum->value(); + s.constant = s_constant->value(); sFactors = &s; } if (tApply) { // T axis is affected, so read the T factors. - t.oldValue = (float)atof(NamedEntryWidgetText("t_oldval")); - t.rowDistance = (float)atof(NamedEntryWidgetText("t_rowdist")); - t.colDistance = (float)atof(NamedEntryWidgetText("t_coldist")); - t.rowNumber = (float)atof(NamedEntryWidgetText("t_rownum")); - t.colNumber = (float)atof(NamedEntryWidgetText("t_colnum")); - t.constant = (float)atof(NamedEntryWidgetText("t_constant")); + t.oldValue = t_oldval->value(); + t.rowDistance = t_rowdist->value(); + t.colDistance = t_coldist->value(); + t.rowNumber = t_rownum->value(); + t.colNumber = t_colnum->value(); + t.constant = t_constant->value(); tFactors = &t; } MeshEntity::SliceDesignation alignRow, alignCol; - alignRow.maxSlice = NamedToggleWidgetActive("row_max_align"); - alignRow.index = atoi(NamedEntryWidgetText("row_num_align")); - alignCol.maxSlice = NamedToggleWidgetActive("col_max_align"); - alignCol.index = atoi(NamedEntryWidgetText("col_num_align")); + alignRow.maxSlice = !row_num_align->isEnabled(); + alignRow.index = row_num_align->value(); + alignCol.maxSlice = !col_num_align->isEnabled(); + alignCol.index = col_num_align->value(); MeshEntity::RefSliceDescriptor row, col; MeshEntity::RefSliceDescriptor *refRow = NULL; MeshEntity::RefSliceDescriptor *refCol = NULL; - if (NamedToggleWidgetActive("row_ref")) + if ( row_ref->isChecked() ) { // Reference row is specified, so get that info. - row.designation.maxSlice = NamedToggleWidgetActive("row_max_ref"); - row.designation.index = atoi(NamedEntryWidgetText("row_num_ref")); - row.totalLengthOnly = NamedToggleWidgetActive("row_ref_total"); + row.designation.maxSlice = !row_num_ref->isEnabled(); + row.designation.index = row_num_ref->value(); + row.totalLengthOnly = row_ref_total->isChecked(); refRow = &row; } - if (NamedToggleWidgetActive("col_ref")) + if ( col_ref->isChecked() ) { // Reference column is specified, so get that info. - col.designation.maxSlice = NamedToggleWidgetActive("col_max_ref"); - col.designation.index = atoi(NamedEntryWidgetText("col_num_ref")); - col.totalLengthOnly = NamedToggleWidgetActive("col_ref_total"); + col.designation.maxSlice = !col_num_ref->isEnabled(); + col.designation.index = col_num_ref->value(); + col.totalLengthOnly = col_ref_total->isChecked(); refCol = &col; } - bool surfaceValues = NamedToggleWidgetActive("surface"); + const bool surfaceValues = surface->isChecked(); // Let Radiant know the name of the operation responsible for the changes // that are about to happen. diff --git a/contrib/meshtex/GeneralFunctionDialog.h b/contrib/meshtex/GeneralFunctionDialog.h index 2ef23578..82627492 100644 --- a/contrib/meshtex/GeneralFunctionDialog.h +++ b/contrib/meshtex/GeneralFunctionDialog.h @@ -23,8 +23,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_GENERALFUNCTIONDIALOG_H) -#define INCLUDED_GENERALFUNCTIONDIALOG_H +#pragma once #include "GenericDialog.h" #include "MeshVisitor.h" @@ -35,7 +34,7 @@ * for setting S and T values as a linear combination of various factors. * * @image html genfunc.png - * + * * @ingroup meshtex-ui */ class GeneralFunctionDialog : public GenericDialog @@ -75,11 +74,26 @@ public: // public methods private: // private member vars + QRadioButton *surface; + + QCheckBox *s_apply; + QDoubleSpinBox *s_oldval, *s_rowdist, *s_coldist, *s_rownum, *s_colnum, *s_constant; + QCheckBox *t_apply; + QDoubleSpinBox *t_oldval, *t_rowdist, *t_coldist, *t_rownum, *t_colnum, *t_constant; + + QSpinBox *col_num_align; + QGroupBox *row_ref; + QSpinBox *row_num_ref; + QCheckBox *row_ref_total; + + QSpinBox *row_num_align; + QGroupBox *col_ref; + QSpinBox *col_num_ref; + QCheckBox *col_ref_total; + /** * Action-less mesh visitor used purely to count the number of selected mesh * entities. */ SmartPointer _nullVisitor; }; - -#endif // #if !defined(INCLUDED_GENERALFUNCTIONDIALOG_H) \ No newline at end of file diff --git a/contrib/meshtex/GenericDialog.cpp b/contrib/meshtex/GenericDialog.cpp index e4716b5d..993fe89b 100644 --- a/contrib/meshtex/GenericDialog.cpp +++ b/contrib/meshtex/GenericDialog.cpp @@ -23,14 +23,12 @@ * along with MeshTex. If not, see . */ -#include - #include "GenericDialog.h" #include "GenericPluginUI.h" /** - * Constructor. Create the GTK+ widget for the dialog window (not visible + * Constructor. Create the Qt widget for the dialog window (not visible * yet). Initialize callback IDs to zero (invalid). Note that as this is a * protected method, GenericDialog objects cannot be created directly; only * subclasses of GenericDialog can be created. @@ -38,29 +36,21 @@ * @param key Unique key to identify this dialog widget. */ GenericDialog::GenericDialog(const std::string& key) : - _dialog(gtk_window_new(GTK_WINDOW_TOPLEVEL)), - _window(NULL), + _dialog(new QDialog( nullptr, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint )), + _window(nullptr), _key(key), _okCallbackID(0), _applyCallbackID(0), _cancelCallbackID(0) { - // XXX Should we go ahead invoke CreateWindowCloseCallback here (and make it - // private) rather than leaving that to the subclass constructors? Depends on - // whether it's plausible that a dialog would ever NOT want the usual - // handling for the close event. } /** - * Virtual destructor. Destroy the GTK+ dialog widget (and therefore its - * contained widgets) if necessary. + * Virtual destructor. */ GenericDialog::~GenericDialog() { - if (_dialog != NULL) - { - gtk_widget_destroy(_dialog); - } + // destroyed by parent } /** @@ -80,14 +70,14 @@ GenericDialog::GetKey() const * @param window The parent window. */ void -GenericDialog::SetWindow(GtkWidget *window) +GenericDialog::SetWindow(QWidget *window) { // Remember the parent window. _window = window; // Mark this widget as a modal dialog for it. - if (_dialog != NULL) + if (_dialog != nullptr) { - gtk_window_set_transient_for(GTK_WINDOW(_dialog), GTK_WINDOW(_window)); + static_cast( _dialog )->setParent( _window ); } } @@ -98,9 +88,10 @@ void GenericDialog::Raise() { // Don't bother if not visible. - if (gtk_widget_get_visible(_dialog)) + if (_dialog->isVisible()) { - gdk_window_raise(gtk_widget_get_window( _dialog )); + _dialog->raise(); + _dialog->activateWindow(); } } @@ -116,9 +107,9 @@ GenericDialog::Show(const std::string& triggerCommand) // use of this information. _triggerCommand = triggerCommand; // Show the window if it is currently hidden. - if (!gtk_widget_get_visible(_dialog)) + if (!_dialog->isVisible()) { - gtk_widget_show(_dialog); + _dialog->show(); } // Raise the window to the top of the stack. Raise(); @@ -131,18 +122,10 @@ void GenericDialog::Hide() { // Bail out if the window is already invisible. - if (!gtk_widget_get_visible(_dialog)) + if (_dialog->isVisible()) { - return; + _dialog->hide(); } - // Hide the window. - gtk_widget_hide(_dialog); - // If there's a parent window, raise it to the top of the stack. - if (_window == NULL) - { - return; - } - gdk_window_raise(gtk_widget_get_window(_window)); } /** @@ -161,25 +144,6 @@ GenericDialog::Apply() return true; } -/** - * Callback for window-close event. - * - * @param widget This dialog window widget. - * @param event The event that instigated the callback. - * @param callbackID Unique numerical ID for the callback. - * - * @return TRUE as defined by glib. - */ -gint -GenericDialog::CloseEventCallback(GtkWidget *widget, - GdkEvent* event, - gpointer callbackID) -{ - // All we need to do is hide the window. - Hide(); - return TRUE; -} - /** * Callback for clicking on OK/Apply/Cancel button. * @@ -187,8 +151,7 @@ GenericDialog::CloseEventCallback(GtkWidget *widget, * @param callbackID Unique numerical ID for the callback. */ void -GenericDialog::FinalizeCallback(GtkWidget *widget, - gpointer callbackID) +GenericDialog::FinalizeCallback(QAbstractButton *callbackID) { // Assume success until we have to do something. bool success = true; @@ -204,33 +167,19 @@ GenericDialog::FinalizeCallback(GtkWidget *widget, } } -/** - * Register the callback for the close-window event. - */ -void -GenericDialog::CreateWindowCloseCallback() -{ - // The close-window event will trigger the CloseEventCallback method. - const GenericPluginUI::DialogEventCallbackMethod - closeCallback(*this); - UIInstance().RegisterDialogEventCallback(_dialog, "delete_event", closeCallback); -} - /** * Register the callback for the OK button. * * @param button The OK button widget. */ void -GenericDialog::CreateOkButtonCallback(GtkWidget *button) +GenericDialog::CreateOkButtonCallback(QAbstractButton *button) { // Clicking the OK button will trigger the FinalizeCallback method. Since // FinalizeCallback can be used for multiple buttons, we'll save the specific // callback ID associated with the OK button. - const GenericPluginUI::DialogSignalCallbackMethod - finalizeCallback(*this); - _okCallbackID = - UIInstance().RegisterDialogSignalCallback(button, "clicked", finalizeCallback); + _okCallbackID = button; + QObject::connect( button, &QAbstractButton::clicked, [this, button](){ FinalizeCallback( button ); } ); } /** @@ -239,15 +188,13 @@ GenericDialog::CreateOkButtonCallback(GtkWidget *button) * @param button The Apply button widget. */ void -GenericDialog::CreateApplyButtonCallback(GtkWidget *button) +GenericDialog::CreateApplyButtonCallback(QAbstractButton *button) { // Clicking the Apply button will trigger the FinalizeCallback method. Since // FinalizeCallback can be used for multiple buttons, we'll save the specific // callback ID associated with the Apply button. - const GenericPluginUI::DialogSignalCallbackMethod - finalizeCallback(*this); - _applyCallbackID = - UIInstance().RegisterDialogSignalCallback(button, "clicked", finalizeCallback); + _applyCallbackID = button; + QObject::connect( button, &QAbstractButton::clicked, [this, button](){ FinalizeCallback( button ); } ); } /** @@ -256,13 +203,11 @@ GenericDialog::CreateApplyButtonCallback(GtkWidget *button) * @param button The Cancel button widget. */ void -GenericDialog::CreateCancelButtonCallback(GtkWidget *button) +GenericDialog::CreateCancelButtonCallback(QAbstractButton *button) { // Clicking the Cancel button will trigger the FinalizeCallback method. Since // FinalizeCallback can be used for multiple buttons, we'll save the specific // callback ID associated with the Cancel button. - const GenericPluginUI::DialogSignalCallbackMethod - finalizeCallback(*this); - _cancelCallbackID = - UIInstance().RegisterDialogSignalCallback(button, "clicked", finalizeCallback); + _cancelCallbackID = button; + QObject::connect( button, &QAbstractButton::clicked, [this, button](){ FinalizeCallback( button ); } ); } diff --git a/contrib/meshtex/GenericDialog.h b/contrib/meshtex/GenericDialog.h index 5a085d7d..89715b84 100644 --- a/contrib/meshtex/GenericDialog.h +++ b/contrib/meshtex/GenericDialog.h @@ -23,40 +23,29 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_GENERICDIALOG_H) -#define INCLUDED_GENERICDIALOG_H +#pragma once #include -#include -#include #include "RefCounted.h" #include "qerplugin.h" -/** - * Macro to get a handle on a widget inside the dialog by name. - * - * @param widgetName Name of the contained widget to find. - */ -#define NamedWidget(widgetName) \ - (g_object_get_data(G_OBJECT(_dialog), widgetName)) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gtkutil/spinbox.h" -/** - * Macro to enable/disable a widget inside the dialog, selected by name. - * - * @param widgetName Name of the contained widget to enable/disable. - */ -#define NamedToggleWidgetActive(widgetName) \ - gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(NamedWidget(widgetName))) - -/** - * Macro to read text from a widget inside the dialog, selected by name. - * - * @param widgetName Name of the contained widget to read from. - */ -#define NamedEntryWidgetText(widgetName) \ - (gtk_entry_get_text(GTK_ENTRY(NamedWidget(widgetName)))) /** * Framework for a basic dialog window with OK/Apply/Cancel actions. @@ -93,7 +82,7 @@ public: // public methods //@} /// @name Window management //@{ - virtual void SetWindow(GtkWidget *window); + virtual void SetWindow(QWidget *window); virtual void Raise(); virtual void Show(const std::string& triggerCommand); virtual void Hide(); @@ -101,18 +90,13 @@ public: // public methods /// @name Callback implementation //@{ virtual bool Apply(); - virtual gint CloseEventCallback(GtkWidget *widget, - GdkEvent* event, - gpointer callbackID); - virtual void FinalizeCallback(GtkWidget *widget, - gpointer callbackID); + virtual void FinalizeCallback(QAbstractButton *callbackID); //@} /// @name Callback creation //@{ - void CreateWindowCloseCallback(); - void CreateOkButtonCallback(GtkWidget *button); - void CreateApplyButtonCallback(GtkWidget *button); - void CreateCancelButtonCallback(GtkWidget *button); + void CreateOkButtonCallback(QAbstractButton *button); + void CreateApplyButtonCallback(QAbstractButton *button); + void CreateCancelButtonCallback(QAbstractButton *button); //@} protected: // protected member vars @@ -120,12 +104,12 @@ protected: // protected member vars /** * This dialog widget. */ - GtkWidget *_dialog; + QDialog *_dialog; /** * Parent window. */ - GtkWidget *_window; + QWidget *_window; /** * Unique key for this dialog. @@ -140,17 +124,15 @@ protected: // protected member vars /** * Callback ID associated with an OK button; 0 if none. */ - gpointer _okCallbackID; + QAbstractButton *_okCallbackID; /** * Callback ID associated with an Apply button; 0 if none. */ - gpointer _applyCallbackID; + QAbstractButton *_applyCallbackID; /** * Callback ID associated with a Cancel button; 0 if none. */ - gpointer _cancelCallbackID; + QAbstractButton *_cancelCallbackID; }; - -#endif // #if !defined(INCLUDED_GENERICDIALOG_H) diff --git a/contrib/meshtex/GenericMainMenu.h b/contrib/meshtex/GenericMainMenu.h index af972262..999baaad 100644 --- a/contrib/meshtex/GenericMainMenu.h +++ b/contrib/meshtex/GenericMainMenu.h @@ -23,8 +23,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_GENERICMAINMENU_H) -#define INCLUDED_GENERICMAINMENU_H +#pragma once #include #include @@ -45,7 +44,7 @@ * Framework for a Radiant plugin's main menu. This object handles the menu * logic: what commands exist and how to execute them. The actual menu * display is handled by Radiant. - * + * * A subclass should handle creating the command list. * * @ingroup generic-ui @@ -152,5 +151,3 @@ private: // private member vars */ DialogMap _dialogMap; }; - -#endif // #if !defined(INCLUDED_GENERICMAINMENU_H) \ No newline at end of file diff --git a/contrib/meshtex/GenericPluginUI.cpp b/contrib/meshtex/GenericPluginUI.cpp index b73e0893..ca5833d2 100644 --- a/contrib/meshtex/GenericPluginUI.cpp +++ b/contrib/meshtex/GenericPluginUI.cpp @@ -23,8 +23,6 @@ * along with MeshTex. If not, see . */ -#include - #include "GenericPluginUI.h" @@ -36,9 +34,7 @@ */ GenericPluginUI::GenericPluginUI() : _window(NULL), - _mainMenu(NULL), - _callbackID(1), - _widgetControlCallback(*this) + _mainMenu(NULL) { } @@ -89,17 +85,16 @@ GenericPluginUI::RegisterDialog(SmartPointer& dialog) * @param window The main window. */ void -GenericPluginUI::SetWindow(GtkWidget *window) +GenericPluginUI::SetWindow(QWidget *window) { // Remember it. _window = window; // Set it as the parent for every dialog window. - DialogMap::const_iterator dialogMapIter = _dialogMap.begin(); - for (; dialogMapIter != _dialogMap.end(); ++dialogMapIter) + for ( const auto& [name, ptr] : _dialogMap ) { - if (dialogMapIter->second.get() != NULL) + if (ptr.get() != NULL) { - dialogMapIter->second->SetWindow(window); + ptr->SetWindow(window); } } } @@ -137,110 +132,6 @@ GenericPluginUI::Dialog(const std::string& key) return dialogMapIter->second; } -/** - * Generic event callback used to invoke the specific callback functions - * registered with this manager. Those specific callbacks are not themselves - * registered directly with GTK+ because they may be methods that must be - * invoked on objects. (Unlike this function, which is a static method.) - * - * @param widget The widget generating the event. - * @param event The event. - * @param data ID of the specific callback registered with this manager. - * - * @return The return value from the specific callback. - */ -gint -GenericPluginUI::DialogEventCallbackDispatch(GtkWidget *widget, - GdkEvent* event, - gpointer data) -{ - // Look up the callback ID in our registration map. - DialogEventCallbackMap::iterator dialogEventCallbackMapIter = - UIInstance()._dialogEventCallbackMap.find(data); - if (dialogEventCallbackMapIter == UIInstance()._dialogEventCallbackMap.end()) - { - // If we didn't find it, nothing to do. - return TRUE; - } - // Otherwise invoke that callback. - return dialogEventCallbackMapIter->second(widget, event, data); -} - -/** - * Generic signal callback used to invoke the specific callback functions - * registered with this manager. Those specific callbacks are not themselves - * registered directly with GTK+ because they may be methods that must be - * invoked on objects. (Unlike this function, which is a static method.) - * - * @param widget The widget generating the signal. - * @param data ID of the specific callback registered with this manager. - */ -void -GenericPluginUI::DialogSignalCallbackDispatch(GtkWidget *widget, - gpointer data) -{ - // Look up the callback ID in our registration map. - DialogSignalCallbackMap::iterator dialogSignalCallbackMapIter = - UIInstance()._dialogSignalCallbackMap.find(data); - if (dialogSignalCallbackMapIter == UIInstance()._dialogSignalCallbackMap.end()) - { - // If we didn't find it, nothing to do. - return; - } - // Otherwise invoke that callback. - dialogSignalCallbackMapIter->second(widget, data); -} - -/** - * Register a function to be invoked when a widget generates an event. - * - * @param widget The widget generating the event. - * @param name The name of the event. - * @param callback The callback function. - * - * @return The unique ID for the registered callback function. - */ -gpointer -GenericPluginUI::RegisterDialogEventCallback(GtkWidget *widget, - const gchar *name, - const DialogEventCallback& callback) -{ - // Get the next callback ID to use. - gpointer callbackID = GUINT_TO_POINTER(_callbackID++); - // Make that event on that dialog widget trigger our event dispatch. - g_signal_connect(G_OBJECT(widget), name, - G_CALLBACK(DialogEventCallbackDispatch), callbackID); - // Save the association between callback ID and function. - _dialogEventCallbackMap.insert(std::make_pair(callbackID, callback)); - // Return the generated unique callback ID. - return callbackID; -} - -/** - * Register a function to be invoked when a widget generates a signal. - * - * @param widget The widget generating the signal. - * @param name The name of the signal. - * @param callback The callback function. - * - * @return The unique ID for the registered callback function. - */ -gpointer -GenericPluginUI::RegisterDialogSignalCallback(GtkWidget *widget, - const gchar *name, - const DialogSignalCallback& callback) -{ - // Get the next callback ID to use. - gpointer callbackID = GUINT_TO_POINTER(_callbackID++); - // Make that signal on that dialog widget trigger our signal dispatch. - g_signal_connect(G_OBJECT(widget), name, - G_CALLBACK(DialogSignalCallbackDispatch), callbackID); - // Save the association between callback ID and function. - _dialogSignalCallbackMap.insert(std::make_pair(callbackID, callback)); - // Return the generated unique callback ID. - return callbackID; -} - /** * Declare that the controllee widget should be inactive when the * controller widget is inactive. The controllee will be active only @@ -250,13 +141,15 @@ GenericPluginUI::RegisterDialogSignalCallback(GtkWidget *widget, * @param controllee The controllee widget. */ void -GenericPluginUI::RegisterWidgetDependence(GtkWidget *controller, - GtkWidget *controllee) +GenericPluginUI::RegisterWidgetDependence(QAbstractButton *controller, + QWidget *controllee) { // Make sure we get a callback when the controller is toggled. if (_widgetControlMap.find(controller) == _widgetControlMap.end()) { - RegisterDialogSignalCallback(controller, "clicked", _widgetControlCallback); + QObject::connect( controller, &QAbstractButton::toggled, [this, controller]( bool checked ){ + WidgetControlCallback( controller ); + } ); } // Save the association. _widgetControlMap[controller].push_back(controllee); @@ -272,13 +165,15 @@ GenericPluginUI::RegisterWidgetDependence(GtkWidget *controller, * @param controllee The controllee widget. */ void -GenericPluginUI::RegisterWidgetAntiDependence(GtkWidget *controller, - GtkWidget *controllee) +GenericPluginUI::RegisterWidgetAntiDependence(QAbstractButton *controller, + QWidget *controllee) { // Make sure we get a callback when the controller is toggled. if (_widgetControlMap.find(controller) == _widgetControlMap.end()) { - RegisterDialogSignalCallback(controller, "clicked", _widgetControlCallback); + QObject::connect( controller, &QAbstractButton::toggled, [this, controller]( bool checked ){ + WidgetControlCallback( controller ); + } ); } // Save the association. _widgetControlMap[controller].push_back(controllee); @@ -292,42 +187,35 @@ GenericPluginUI::RegisterWidgetAntiDependence(GtkWidget *controller, * @param callbackID Unique numerical ID for the callback. */ void -GenericPluginUI::WidgetControlCallback(GtkWidget *widget, - gpointer callbackID) +GenericPluginUI::WidgetControlCallback( QAbstractButton *button ) { // Iterate over all controllees registered for this widget. - std::vector::iterator controlleeIter = - _widgetControlMap[widget].begin(); - for (; controlleeIter != _widgetControlMap[widget].end(); ++controlleeIter) + for ( QWidget *controllee : _widgetControlMap[button] ) { - GtkWidget *controllee = *controlleeIter; - std::vector::iterator controllerIter; // Start with an assumption that the controllee widget will be active. bool sensitive = true; // Look for a dependence on any widget. - controllerIter = _widgetControlledByMap[controllee].begin(); - for (; controllerIter != _widgetControlledByMap[controllee].end(); ++controllerIter) + for ( QAbstractButton *controller : _widgetControlledByMap[controllee] ) { // Dependence found; honor it. - if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(*controllerIter))) + if ( !controller->isChecked() ) { sensitive = false; break; } } // Look for an anti-dependence on any widget. - controllerIter = _widgetAntiControlledByMap[controllee].begin(); - for (; controllerIter != _widgetAntiControlledByMap[controllee].end(); ++controllerIter) + for ( QAbstractButton *controller : _widgetAntiControlledByMap[controllee] ) { // Anti-dependence found; honor it. - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(*controllerIter))) + if ( controller->isChecked() ) { sensitive = false; break; } } // Set the active state of the controllee appropriately. - gtk_widget_set_sensitive(controllee, sensitive); + controllee->setEnabled( sensitive); } } @@ -342,7 +230,7 @@ GenericPluginUI::ErrorReportDialog(const char *title, const char *message) { // Pass this operation to Radiant. - GlobalRadiant().m_pfnMessageBox(UIInstance()._window, message, title, eMB_OK, eMB_ICONERROR); + GlobalRadiant().m_pfnMessageBox(UIInstance()._window, message, title, EMessageBoxType::Error, 0); } /** @@ -356,7 +244,7 @@ GenericPluginUI::WarningReportDialog(const char *title, const char *message) { // Pass this operation to Radiant. - GlobalRadiant().m_pfnMessageBox(UIInstance()._window, message, title, eMB_OK, eMB_ICONWARNING); + GlobalRadiant().m_pfnMessageBox(UIInstance()._window, message, title, EMessageBoxType::Warning, 0); } /** @@ -370,5 +258,5 @@ GenericPluginUI::InfoReportDialog(const char *title, const char *message) { // Pass this operation to Radiant. - GlobalRadiant().m_pfnMessageBox(UIInstance()._window, message, title, eMB_OK, eMB_ICONDEFAULT); + GlobalRadiant().m_pfnMessageBox(UIInstance()._window, message, title, EMessageBoxType::Info, 0); } diff --git a/contrib/meshtex/GenericPluginUI.h b/contrib/meshtex/GenericPluginUI.h index 8b6c241d..41d1df4b 100644 --- a/contrib/meshtex/GenericPluginUI.h +++ b/contrib/meshtex/GenericPluginUI.h @@ -23,12 +23,9 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_GENERICPLUGINUI_H) -#define INCLUDED_GENERICPLUGINUI_H +#pragma once #include -#include -#include #include "GenericMainMenu.h" #include "GenericDialog.h" @@ -41,8 +38,6 @@ * responsible for: * - holding a reference on those objects for lifecycle management * - providing lookup facilities for those objects - * - mapping GTK+ event/signal callbacks into method invocations on - * the dialog objects * - providing automatic handling of widgets that should be active or * inactive based on the active state of other widgets * - providing utility functions for generating message popups @@ -69,102 +64,26 @@ private: // private methods const GenericPluginUI& operator=(const GenericPluginUI&); //@} -public: // public types - - /** - * Type for GTK+ event callbacks. The callback takes a GtkWidget* argument - * (widget generating the event), a GdkEvent* argument (the event), and a - * gpointer argument (the callback ID); it returns gint (success as TRUE or - * FALSE). - */ - typedef Callback3 DialogEventCallback; - - /** - * Type for GTK+ signal callbacks. The callback takes a GtkWidget* argument - * (widget generating the signal) and a gpointer argument (the callback data); - * it has no return value. - */ - typedef Callback2 DialogSignalCallback; - - /** - * An instance of this class can be used as a - * GenericPluginUI::DialogEventCallback, in situations where the callback is - * a method to be invoked on a target object. When invoking this constructor, - * the target object is the constructor argument, and the target object class - * and method are template parameters. The target object's method must have - * an appropriate signature for DialogEventCallback: one GtkWidget* argument, - * one GdkEvent* argument, one gpointer argument, gint return. - */ - template - class DialogEventCallbackMethod : public BindFirstOpaque3 > - { - public: - /** - * Constructor. - * - * @param object The object on which to invoke the callback method. - */ - DialogEventCallbackMethod(ObjectClass& object) : - BindFirstOpaque3 >(object) {} - }; - - /** - * An instance of this class can be used as a - * GenericPluginUI::DialogSignalCallback, in situations where the callback is - * a method to be invoked on a target object. When invoking this constructor, - * the target object is the constructor argument, and the target object class - * and method are template parameters. The target object's method must have - * an appropriate signature for DialogSignalCallback: one GtkWidget* argument, - * one gpointer argument, void return. - */ - template - class DialogSignalCallbackMethod : public BindFirstOpaque2 > - { - public: - /** - * Constructor. - * - * @param object The object on which to invoke the callback method. - */ - DialogSignalCallbackMethod(ObjectClass& object) : - BindFirstOpaque2 >(object) {} - }; - public: // public methods /// @name Setup //@{ void RegisterMainMenu(SmartPointer& mainMenu); void RegisterDialog(SmartPointer& dialog); - void SetWindow(GtkWidget *window); + void SetWindow(QWidget *window); //@} /// @name Lookup //@{ GenericMainMenu *MainMenu(); GenericDialog *Dialog(const std::string& key); //@} - /// @name Event/signal dispatch - //@{ - static gint DialogEventCallbackDispatch(GtkWidget *widget, - GdkEvent* event, - gpointer data); - static void DialogSignalCallbackDispatch(GtkWidget *widget, - gpointer data); - gpointer RegisterDialogEventCallback(GtkWidget *widget, - const gchar *name, - const DialogEventCallback& callback); - gpointer RegisterDialogSignalCallback(GtkWidget *widget, - const gchar *name, - const DialogSignalCallback& callback); - //@} /// @name Widget dependence //@{ - void RegisterWidgetDependence(GtkWidget *controller, - GtkWidget *controllee); - void RegisterWidgetAntiDependence(GtkWidget *controller, - GtkWidget *controllee); - void WidgetControlCallback(GtkWidget *widget, - gpointer callbackID); + void RegisterWidgetDependence(QAbstractButton *controller, + QWidget *controllee); + void RegisterWidgetAntiDependence(QAbstractButton *controller, + QWidget *controllee); + void WidgetControlCallback( QAbstractButton *button ); //@} /// @name Message popups //@{ @@ -183,60 +102,29 @@ private: // private types */ typedef std::map > DialogMap; - /** - * Type for a map between gpointer (for callback ID) and event callback. - */ - typedef std::map DialogEventCallbackMap; - - /** - * Type for a map between gpointer (for callback ID) and signal callback. - */ - typedef std::map DialogSignalCallbackMap; - /** * Type for a map between a widget and a vector of widgets. */ - typedef std::map > WidgetDependenceMap; + typedef std::map > WidgetDependenceMap; + typedef std::map > WidgetDependenceByMap; private: // private member vars /** * The parent window. */ - GtkWidget *_window; + QWidget *_window; /** * Pointer to a reference-counted handle on the main menu object. */ SmartPointer *_mainMenu; - /** - * Next ID to use when registering an event or signal callback. Starts at 1; - * 0 is reserved to mean invalid. - */ - unsigned _callbackID; - - /** - * Callback to implement widget-active dependences. - */ - const DialogSignalCallbackMethod - _widgetControlCallback; - /** * Associations between keys and dialog windows. */ DialogMap _dialogMap; - /** - * Associations between callback IDs and event callbacks. - */ - DialogEventCallbackMap _dialogEventCallbackMap; - - /** - * Associations between callback IDs and signal callbacks. - */ - DialogSignalCallbackMap _dialogSignalCallbackMap; - /** * Associations between controller and controllee widgets for all dependences * and anti-dependences. @@ -244,16 +132,16 @@ private: // private member vars WidgetDependenceMap _widgetControlMap; /** - * Associations between controller and controllee widgets for dependences + * Associations between controllee and controller widgets for dependences * only. */ - WidgetDependenceMap _widgetControlledByMap; + WidgetDependenceByMap _widgetControlledByMap; /** * Associations between controller and controllee widgets for anti- * dependences only. */ - WidgetDependenceMap _widgetAntiControlledByMap; + WidgetDependenceByMap _widgetAntiControlledByMap; }; @@ -272,5 +160,3 @@ private: // private member vars * @relates GenericPluginUI */ GenericPluginUI& UIInstance(); - -#endif // #if !defined(INCLUDED_GENERICPLUGINUI_H) diff --git a/contrib/meshtex/GenericPluginUIMessages.h b/contrib/meshtex/GenericPluginUIMessages.h index 0e0d0cc3..a2894066 100644 --- a/contrib/meshtex/GenericPluginUIMessages.h +++ b/contrib/meshtex/GenericPluginUIMessages.h @@ -23,8 +23,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_GENERICPLUGINUIMESSAGES_H) -#define INCLUDED_GENERICPLUGINUIMESSAGES_H +#pragma once /// @name Window titles //@{ @@ -36,12 +35,3 @@ //@{ #define DIALOG_INTERNAL_ERROR "Internal error in plugin code." //@} - -/// @name Button labels -//@{ -#define DIALOG_CANCEL_BUTTON "Cancel" -#define DIALOG_APPLY_BUTTON "Apply" -#define DIALOG_OK_BUTTON "OK" -//@} - -#endif // #if !defined(INCLUDED_GENERICPLUGINUIMESSAGES_H) diff --git a/contrib/meshtex/GetInfoDialog.cpp b/contrib/meshtex/GetInfoDialog.cpp index 6d5147d4..6c3eba05 100644 --- a/contrib/meshtex/GetInfoDialog.cpp +++ b/contrib/meshtex/GetInfoDialog.cpp @@ -23,8 +23,6 @@ * along with MeshTex. If not, see . */ -#include - #include "GenericPluginUI.h" #include "GetInfoDialog.h" #include "PluginUIMessages.h" @@ -88,111 +86,43 @@ GetInfoDialog::GetInfoDialog(const std::string& key, &SetScaleDialog::PopulateTWidgets>(*setScaleDialog)), _nullVisitor(new MeshVisitor()) { - // Enable the usual handling of the close event. - CreateWindowCloseCallback(); - // Configure the dialog window. - gtk_window_set_resizable(GTK_WINDOW(_dialog), FALSE); - gtk_window_set_title(GTK_WINDOW(_dialog), DIALOG_GET_INFO_TITLE); - gtk_container_set_border_width(GTK_CONTAINER(_dialog), 10); + _dialog->setWindowTitle(DIALOG_GET_INFO_TITLE); // Create the contained widgets. + { + auto form = new QFormLayout( _dialog ); + form->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + { + // Widgets for specifying the reference row if any. + auto check = new QCheckBox( DIALOG_GET_INFO_S_ROW_HEADER ); + check->setChecked( true ); + auto spin = s_ref_row = new SpinBox( 0, 30 ); + form->addRow( check, spin ); + UIInstance().RegisterWidgetDependence( check, spin ); + } + { + // Widgets for specifying the reference column if any. + auto check = new QCheckBox( DIALOG_GET_INFO_T_COL_HEADER ); + check->setChecked( true ); + auto spin = t_ref_col = new SpinBox( 0, 30 ); + form->addRow( check, spin ); + UIInstance().RegisterWidgetDependence( check, spin ); + } + { + // Checkbox to enable the callbacks to Set S/T Scale. + auto check = check_transfer = new QCheckBox( DIALOG_GET_INFO_XFER_OPT_LABEL ); + form->addRow( check ); + } + { + auto buttons = new QDialogButtonBox; + form->addWidget( buttons ); + CreateOkButtonCallback( buttons->addButton( QDialogButtonBox::StandardButton::Ok ) ); + CreateApplyButtonCallback( buttons->addButton( QDialogButtonBox::StandardButton::Apply ) ); + CreateCancelButtonCallback( buttons->addButton( QDialogButtonBox::StandardButton::Cancel ) ); + } - GtkWidget *table; - GtkWidget *entry; - GtkWidget *button; - GtkWidget *label; - GtkWidget *hbox; - - table = gtk_table_new(4, 3, FALSE); - gtk_table_set_row_spacing(GTK_TABLE(table), 1, 10); - gtk_table_set_row_spacing(GTK_TABLE(table), 2, 15); - gtk_container_add(GTK_CONTAINER(_dialog), table); - gtk_widget_show(table); - - // Widgets for specifying the reference row if any. - - button = gtk_check_button_new(); - g_object_set_data(G_OBJECT(_dialog), "s_apply", button); - gtk_table_attach_defaults(GTK_TABLE(table), button, 0, 1, 0, 1); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_show(button); - - label = gtk_label_new(DIALOG_GET_INFO_S_ROW_HEADER); - gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT); - gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 0, 1); - gtk_widget_show(label); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "s_ref_row", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0"); - gtk_table_attach_defaults(GTK_TABLE(table), entry, 2, 3, 0, 1); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(button, label); - UIInstance().RegisterWidgetDependence(button, entry); - - // Widgets for specifying the reference column if any. - - button = gtk_check_button_new(); - g_object_set_data(G_OBJECT(_dialog), "t_apply", button); - gtk_table_attach_defaults(GTK_TABLE(table), button, 0, 1, 1, 2); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_show(button); - - label = gtk_label_new(DIALOG_GET_INFO_T_COL_HEADER); - gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT); - gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 1, 2); - gtk_widget_show(label); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "t_ref_col", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0"); - gtk_table_attach_defaults(GTK_TABLE(table), entry, 2, 3, 1, 2); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(button, label); - UIInstance().RegisterWidgetDependence(button, entry); - - // Checkbox to enable the callbacks to Set S/T Scale. - - button = gtk_check_button_new_with_label(DIALOG_GET_INFO_XFER_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "transfer", button); - gtk_table_attach(GTK_TABLE(table), button, 0, 3, 2, 3, GTK_EXPAND, GTK_EXPAND, 0, 0); - gtk_widget_show(button); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_table_attach_defaults(GTK_TABLE(table), hbox, 0, 3, 3, 4); - gtk_widget_show(hbox); - - // Create Cancel button and hook it to callback. - - button = gtk_button_new_with_label(DIALOG_CANCEL_BUTTON); - gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_widget_set_size_request(button, 60, -1); - gtk_widget_show(button); - - CreateCancelButtonCallback(button); - - // Create Apply button and hook it to callback. - - button = gtk_button_new_with_label(DIALOG_APPLY_BUTTON); - gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 10); - gtk_widget_set_size_request (button, 60, -1); - gtk_widget_show(button); - - CreateApplyButtonCallback(button); - - // Create OK button and hook it to callback. - - button = gtk_button_new_with_label(DIALOG_OK_BUTTON); - gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_widget_set_size_request (button, 60, -1); - gtk_widget_show(button); - - CreateOkButtonCallback(button); + } } /** @@ -225,7 +155,7 @@ GetInfoDialog::Apply() // If the option to transfer info to Set S/T Scale is active, then only one // mesh may be selected. - bool transfer = NamedToggleWidgetActive("transfer"); + const bool transfer = check_transfer->isChecked(); if (transfer && _nullVisitor->GetVisitedCount() != 1) { // Multiple selected. Warn and bail out. @@ -236,18 +166,15 @@ GetInfoDialog::Apply() // OK read the remaining info from the widgets. - bool sApply = NamedToggleWidgetActive("s_apply"); - bool tApply = NamedToggleWidgetActive("t_apply"); - int row, col; - int *refRow = NULL; - int *refCol = NULL; - MeshEntity::TexInfoCallback *rowTexInfoCallback = NULL; - MeshEntity::TexInfoCallback *colTexInfoCallback = NULL; - if (sApply) + int *refRow = nullptr; + int *refCol = nullptr; + MeshEntity::TexInfoCallback *rowTexInfoCallback = nullptr; + MeshEntity::TexInfoCallback *colTexInfoCallback = nullptr; + if ( s_ref_row->isEnabled() ) { // Reference row is specified, so get that info. - row = atoi(NamedEntryWidgetText("s_ref_row")); + row = s_ref_row->value(); refRow = &row; if (transfer) { @@ -255,10 +182,10 @@ GetInfoDialog::Apply() rowTexInfoCallback = &_rowTexInfoCallback; } } - if (tApply) + if ( t_ref_col->isEnabled() ) { // Reference column is specified, so get that info. - col = atoi(NamedEntryWidgetText("t_ref_col")); + col = t_ref_col->value(); refCol = &col; if (transfer) { diff --git a/contrib/meshtex/GetInfoDialog.h b/contrib/meshtex/GetInfoDialog.h index ef266d56..1a5d180e 100644 --- a/contrib/meshtex/GetInfoDialog.h +++ b/contrib/meshtex/GetInfoDialog.h @@ -23,8 +23,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_GETINFODIALOG_H) -#define INCLUDED_GETINFODIALOG_H +#pragma once #include "GenericDialog.h" #include "SetScaleDialog.h" @@ -37,7 +36,7 @@ * the Get Info menu entry. This window allows the user to query information * about selected meshes and optionally transfer some of that information to * the Set S/T Scale dialog. - * + * * @image html getinfo.png * * @ingroup meshtex-ui @@ -74,6 +73,10 @@ public: // public methods private: // private member vars + QSpinBox *s_ref_row; + QSpinBox *t_ref_col; + QCheckBox *check_transfer; + /** * Handle on the Set S/T Scale dialog. */ @@ -95,5 +98,3 @@ private: // private member vars */ SmartPointer _nullVisitor; }; - -#endif // #if !defined(INCLUDED_GETINFODIALOG_H) \ No newline at end of file diff --git a/contrib/meshtex/MainMenu.h b/contrib/meshtex/MainMenu.h index d6e32962..1fa9ad69 100644 --- a/contrib/meshtex/MainMenu.h +++ b/contrib/meshtex/MainMenu.h @@ -23,8 +23,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_MAINMENU_H) -#define INCLUDED_MAINMENU_H +#pragma once #include "GenericMainMenu.h" #include "MeshVisitor.h" @@ -101,5 +100,3 @@ private: const CommandCallbackMethod _commandMeshVisitor; }; - -#endif // #if !defined(INCLUDED_MAINMENU_H) \ No newline at end of file diff --git a/contrib/meshtex/MeshEntity.cpp b/contrib/meshtex/MeshEntity.cpp index faac7ee3..6341a8ae 100644 --- a/contrib/meshtex/MeshEntity.cpp +++ b/contrib/meshtex/MeshEntity.cpp @@ -206,12 +206,12 @@ MeshEntity::IsValid() const /** * Get information about the patch mesh. - * + * * A message string describing general mesh information (number of rows/cols, * min/max texture coords, extent in worldspace) will be composed and sent to * the infoReportCallback that was specified when this wrapper object was * constructed. - * + * * Optionally this method can do additional reporting on a specific * "reference row" and "reference column". If a reference row and/or column * is specified, then information about the reference slice(s) will be added @@ -235,7 +235,7 @@ MeshEntity::GetInfo(const int *refRow, { // Prep a message buffer to compose the response. char messageBuffer[INFO_BUFFER_SIZE + 1]; - messageBuffer[INFO_BUFFER_SIZE] = 0; + messageBuffer[0] = 0; size_t bufferOffset = 0; // Get reference row info if requested; this will be written into the message // buffer as well as sent to the row callback (if any). @@ -350,14 +350,14 @@ MeshEntity::MinMaxAlignShrink(TextureAxisSelection axes) * Set the texture scaling along the rows or columns of the mesh. This * affects only the texture axis that is naturally associated with rows (S) * or columns (T) according to the chosen sliceType. - * + * * The scaling may be input either as a multiple of the natural scale that * Radiant would choose for this texture, or as the number of tiles of the * texture that should fit on the mesh's row/column. - * + * * Among the slices perpendicular to the direction of scaling, an alignment * slice is used to fix the position of the texture boundary. - * + * * A reference slice may optionally be chosen among the slices parallel to * the scaling direction. If a reference slice is not specified, then the * texture coordinates are independently determined for each slice. If a @@ -475,7 +475,7 @@ MeshEntity::SetScale(SliceType sliceType, * control points themselves, or to directly set the texture coordinates at * the locations on the mesh surface that correspond to each half-patch * interval. - * + * * An alignment row is used as the zero-point for any calculations of row * number or of distance along a column surface when processing the equation. * An alignment column is similarly used. (Note that the number identifying @@ -483,7 +483,7 @@ MeshEntity::SetScale(SliceType sliceType, * it's not the modified number as affected by the alignment column/row when * processing the equation. We don't want to be stuck in a chicken-and-egg * situation.) - * + * * Calculations of distance along row/col surface may optionally be affected * by a designated reference row/col. The reference row/col can be used as a * source of end-to-end distance only, in which case the proportional spacing @@ -753,7 +753,7 @@ MeshEntity::GetSliceTexScale(SliceType sliceType, // We're going to be walking patches along the mesh, choosing the patches // that surround/affect the slice we are interested in. We'll calculate // the length of the slice's surface across each patch & add those up. - + // A SlicePatchContext will contain all the necessary information to // evaluate our slice's surface length within each patch. Some aspects of // the SlicePatchContext will vary as we move from patch to patch, but we @@ -1512,7 +1512,7 @@ MeshEntity::CopyValuesFromControlTex(TextureAxis axis, /** * Generate a set of values based on surface slice lengths and some amount of * desired scaling or tiling. - * + * * This method does a great deal of the work for the SetScale public method; * refer to that method's comment header for more details about the alignment * slice and reference slice inputs. The main difference from the SetScale @@ -1549,7 +1549,7 @@ MeshEntity::GenScaledDistanceValues(SliceType sliceType, // We're going to be walking patches along the mesh, choosing the patches // that surround/affect the slice we are interested in. - + // A SlicePatchContext will contain all the necessary information to // evaluate our slice's surface length within each patch. SlicePatchContext context; @@ -1665,7 +1665,7 @@ MeshEntity::GenScaledDistanceValues(SliceType sliceType, } // Now we may adjust the distance values based on scaling/tiling input. - + // If there's a reference slice, we're going to need to know the total slice // length, so save that away. float refTotalLength; diff --git a/contrib/meshtex/MeshEntity.h b/contrib/meshtex/MeshEntity.h index 2b74d8d2..ad351b41 100644 --- a/contrib/meshtex/MeshEntity.h +++ b/contrib/meshtex/MeshEntity.h @@ -23,8 +23,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_MESHENTITY_H) -#define INCLUDED_MESHENTITY_H +#pragma once #include "AllocatedMatrix.h" @@ -62,9 +61,9 @@ public: // public types */ enum SliceType { - ROW_SLICE_TYPE = 0, ///< row - COL_SLICE_TYPE = 1, ///< column - NUM_SLICE_TYPES = 2 ///< number of kinds of slice + ROW_SLICE_TYPE = 0, ///< row + COL_SLICE_TYPE = 1, ///< column + NUM_SLICE_TYPES = 2 ///< number of kinds of slice }; /** @@ -189,7 +188,7 @@ private: // private types */ enum TextureAxis { - S_TEX_AXIS = 0, ///< S texture axis + S_TEX_AXIS = 0, ///< S texture axis T_TEX_AXIS = 1, ///< T texture axis NUM_TEX_AXES = 2 ///< number of kinds of texture axis }; @@ -199,7 +198,7 @@ private: // private types */ enum PositionAxis { - X_POS_AXIS = 0, ///< X position axis + X_POS_AXIS = 0, ///< X position axis Y_POS_AXIS = 1, ///< Y position axis Z_POS_AXIS = 2, ///< Z position axis NUM_POS_AXES = 3 ///< number of kinds of position axis @@ -270,7 +269,7 @@ private: // private template methods SliceType sliceType, int slice, int index) { - return (sliceType == ROW_SLICE_TYPE ? matrix(slice, index) : + return (sliceType == ROW_SLICE_TYPE ? matrix(slice, index) : matrix(index, slice)); } @@ -463,5 +462,3 @@ private: // private member vars */ float _posMax[NUM_POS_AXES]; }; - -#endif // #if !defined(INCLUDED_MESHENTITY_H) \ No newline at end of file diff --git a/contrib/meshtex/MeshEntityMessages.h b/contrib/meshtex/MeshEntityMessages.h index 7300c753..bb1e4597 100644 --- a/contrib/meshtex/MeshEntityMessages.h +++ b/contrib/meshtex/MeshEntityMessages.h @@ -23,8 +23,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_MESHENTITYMESSAGES_H) -#define INCLUDED_MESHENTITYMESSAGES_H +#pragma once /// @name Informational messages //@{ @@ -51,5 +50,3 @@ #define ERROR_ROW_ZEROTILES "A tile count of zero cannot be applied; the S values of the row will not be changed." #define ERROR_COL_ZEROTILES "A tile count of zero cannot be applied; the T values of the column will not be changed." //@} - -#endif // #if !defined(INCLUDED_MESHENTITYMESSAGES_H) \ No newline at end of file diff --git a/contrib/meshtex/MeshVisitor.h b/contrib/meshtex/MeshVisitor.h index 75438cf9..8dc674f7 100644 --- a/contrib/meshtex/MeshVisitor.h +++ b/contrib/meshtex/MeshVisitor.h @@ -23,8 +23,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_MESHVISITOR_H) -#define INCLUDED_MESHVISITOR_H +#pragma once #include "RefCounted.h" #include "MeshEntity.h" @@ -68,5 +67,3 @@ private: // private member vars */ mutable unsigned _visitedCount; }; - -#endif // #if !defined(INCLUDED_MESHVISITOR_H) \ No newline at end of file diff --git a/contrib/meshtex/PluginModule.cpp b/contrib/meshtex/PluginModule.cpp index cbcfa728..7c7e22a3 100644 --- a/contrib/meshtex/PluginModule.cpp +++ b/contrib/meshtex/PluginModule.cpp @@ -73,7 +73,7 @@ PluginModule::QERPluginInit(void *hApp, void *pMainWidget) { // Inform the UI of the main app window. - UIInstance().SetWindow((GtkWidget *)pMainWidget); + UIInstance().SetWindow(static_cast(pMainWidget)); // Return the plugin name. return PLUGIN_NAME; } diff --git a/contrib/meshtex/PluginModule.h b/contrib/meshtex/PluginModule.h index fc8c802b..0ec2f91c 100644 --- a/contrib/meshtex/PluginModule.h +++ b/contrib/meshtex/PluginModule.h @@ -23,8 +23,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_PLUGINMODULE_H) -#define INCLUDED_PLUGINMODULE_H +#pragma once #include "PluginProperties.h" @@ -84,5 +83,3 @@ private: // private member vars static _QERPluginTable _pluginAPI; }; - -#endif // #if !defined(INCLUDED_PLUGINMODULE_H) diff --git a/contrib/meshtex/PluginProperties.h b/contrib/meshtex/PluginProperties.h index cc80b300..9c48eb75 100644 --- a/contrib/meshtex/PluginProperties.h +++ b/contrib/meshtex/PluginProperties.h @@ -24,8 +24,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_PLUGINPROPERTIES_H) -#define INCLUDED_PLUGINPROPERTIES_H +#pragma once #include "UtilityMacros.h" //#include "CodeVersion.h" @@ -40,5 +39,3 @@ #define PLUGIN_DESCRIPTION "Align and scale textures on patch meshes" #define PLUGIN_FILE_BASENAME "meshtex" #define PLUGIN_FILE_DESCRIPTION "patch mesh texturing plugin for GtkRadiant 1.5" - -#endif // #if !defined(INCLUDED_PLUGINPROPERTIES_H) diff --git a/contrib/meshtex/PluginUI.cpp b/contrib/meshtex/PluginUI.cpp index fcbeef44..aa82d74d 100644 --- a/contrib/meshtex/PluginUI.cpp +++ b/contrib/meshtex/PluginUI.cpp @@ -83,9 +83,9 @@ PluginUI::Instance() { //static PluginUI singleton; //return singleton; - if(!singleton) - singleton = new PluginUI(); - return *singleton; + if(!singleton) + singleton = new PluginUI(); + return *singleton; } /** diff --git a/contrib/meshtex/PluginUI.h b/contrib/meshtex/PluginUI.h index 9dcb0842..6b6d28b4 100644 --- a/contrib/meshtex/PluginUI.h +++ b/contrib/meshtex/PluginUI.h @@ -23,8 +23,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_PLUGINUI_H) -#define INCLUDED_PLUGINUI_H +#pragma once #include "GenericPluginUI.h" @@ -57,5 +56,3 @@ public: // public methods static PluginUI& Instance(); }; - -#endif // #if !defined(INCLUDED_PLUGINUI_H) diff --git a/contrib/meshtex/PluginUIMessages.h b/contrib/meshtex/PluginUIMessages.h index acad961f..c7e933ac 100644 --- a/contrib/meshtex/PluginUIMessages.h +++ b/contrib/meshtex/PluginUIMessages.h @@ -23,8 +23,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_PLUGINUIMESSAGES_H) -#define INCLUDED_PLUGINUIMESSAGES_H +#pragma once #include "GenericPluginUIMessages.h" #include "PluginProperties.h" @@ -43,10 +42,10 @@ //@{ #define DIALOG_MULTIMESHES_ERROR "Must select only one patch mesh for this function." #define DIALOG_NOMESHES_MSG "No valid patch meshes selected." -#define DIALOG_ABOUT_MSG PLUGIN_NAME " " PLUGIN_VERSION "\n\n" PLUGIN_DESCRIPTION "\n\n" PLUGIN_AUTHOR " (" PLUGIN_AUTHOR_EMAIL ")" +#define DIALOG_ABOUT_MSG PLUGIN_NAME " " PLUGIN_VERSION "

" PLUGIN_DESCRIPTION "

" PLUGIN_AUTHOR " ( " PLUGIN_AUTHOR_EMAIL " )" #define DIALOG_HELP_MSG "The Set S/T Scale, Get Info, and General Function dialogs will affect patch meshes that are selected when OK or Apply is clicked. " \ - "For the other menu options, select the mesh(es) before selecting the option.\n\n" \ - "http://neogeographica.com/site/pages/tools/meshtex.html" + "For the other menu options, select the mesh(es) before selecting the option.

" \ + "http://neogeographica.com/site/pages/tools/meshtex.html" //@} /// @name Get Info @@ -90,5 +89,3 @@ #define DIALOG_GEN_FUNC_REF_COL_FRAME_LABEL DIALOG_SET_SCALE_T_REF_COL_OPT_LABEL " (for distances)" #define DIALOG_GEN_FUNC_REF_TOTAL_OPT_LABEL DIALOG_SET_SCALE_REF_TOTAL_OPT_LABEL //@} - -#endif // #if !defined(INCLUDED_PLUGINUIMESSAGES_H) diff --git a/contrib/meshtex/RefCounted.h b/contrib/meshtex/RefCounted.h index 0f108486..62f3f7a7 100644 --- a/contrib/meshtex/RefCounted.h +++ b/contrib/meshtex/RefCounted.h @@ -23,8 +23,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_REFCOUNTED_H) -#define INCLUDED_REFCOUNTED_H +#pragma once /** * A mixin for maintaining a reference count associated with an object, and @@ -58,5 +57,3 @@ private: // private member vars */ int _refCount; }; - -#endif // #if !defined(INCLUDED_REFCOUNTED_H) \ No newline at end of file diff --git a/contrib/meshtex/SetScaleDialog.cpp b/contrib/meshtex/SetScaleDialog.cpp index 93f16ec3..1014e78e 100644 --- a/contrib/meshtex/SetScaleDialog.cpp +++ b/contrib/meshtex/SetScaleDialog.cpp @@ -23,8 +23,6 @@ * along with MeshTex. If not, see . */ -#include - #include "GenericPluginUI.h" #include "SetScaleDialog.h" #include "PluginUIMessages.h" @@ -88,465 +86,185 @@ SetScaleDialog::SetScaleDialog(const std::string& key) : GenericDialog(key), _nullVisitor(new MeshVisitor()) { - // Enable the usual handling of the close event. - CreateWindowCloseCallback(); - // Configure the dialog window. - gtk_window_set_resizable(GTK_WINDOW(_dialog), FALSE); - gtk_window_set_title(GTK_WINDOW(_dialog), DIALOG_SET_SCALE_TITLE); - gtk_container_set_border_width(GTK_CONTAINER(_dialog), 10); + _dialog->setWindowTitle(DIALOG_SET_SCALE_TITLE); // Create the contained widgets. - - GtkWidget *table; - GtkWidget *entry; - GtkWidget *applybutton, *refbutton, *button; - GtkWidget *label; - GtkWidget *mainvbox, *vbox, *hbox; - GtkWidget *frame; - - table = gtk_table_new(2, 2, FALSE); - gtk_table_set_row_spacing(GTK_TABLE(table), 0, 15); - gtk_table_set_col_spacing(GTK_TABLE(table), 0, 10); - gtk_container_add(GTK_CONTAINER(_dialog), table); - gtk_widget_show(table); - - // Checkbox for the "S" grouping of widgets. All the widgets in that - // grouping will have a dependence registered on this checkbox; i.e. they - // will only be active when it is checked. - - applybutton = gtk_check_button_new_with_label(DIALOG_SET_SCALE_S_ACTIVE_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "s_apply", applybutton); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(applybutton), TRUE); - gtk_widget_show(applybutton); - - frame = gtk_frame_new(NULL); - gtk_frame_set_label_widget(GTK_FRAME(frame), applybutton); - gtk_table_attach_defaults(GTK_TABLE(table), frame, 0, 1, 0, 1); - gtk_widget_show(frame); - - mainvbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(frame), mainvbox); - gtk_widget_show(mainvbox); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(mainvbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - // Widgets for specifying S scaling. - - label = gtk_label_new(DIALOG_SET_SCALE_METHOD_FRAME_TITLE); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - frame = gtk_frame_new(NULL); - gtk_frame_set_label_widget(GTK_FRAME(frame), label); - gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 5); - gtk_widget_show(frame); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(frame), vbox); - gtk_widget_show(vbox); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_end(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - button = gtk_radio_button_new_with_label_from_widget(NULL, DIALOG_SET_SCALE_TILES_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "s_tiling", button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(applybutton, button); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "s_tiles", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "1"); - gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 5); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_set_sensitive(entry, FALSE); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - UIInstance().RegisterWidgetDependence(button, entry); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_end(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - button = gtk_radio_button_new_with_label_from_widget( - GTK_RADIO_BUTTON(button), - DIALOG_SET_SCALE_NATURAL_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "s_natural", button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(applybutton, button); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "s_scale", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "1"); - gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 5); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_set_sensitive(entry, TRUE); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - UIInstance().RegisterWidgetDependence(button, entry); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(mainvbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - // Widgets for specifying the alignment column. - - label = gtk_label_new(DIALOG_SET_SCALE_S_ALIGN_FRAME_TITLE); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - frame = gtk_frame_new(NULL); - gtk_frame_set_label_widget(GTK_FRAME(frame), label); - gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 5); - gtk_widget_show(frame); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(frame), vbox); - gtk_widget_show(vbox); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - button = gtk_radio_button_new(NULL); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(applybutton, button); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "col_num_align", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0"); - gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 5); - gtk_widget_set_size_request(entry, 25, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - UIInstance().RegisterWidgetDependence(button, entry); - - button = gtk_radio_button_new_with_label_from_widget( - GTK_RADIO_BUTTON(button), - DIALOG_SET_SCALE_MAX_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "col_max_align", button); - gtk_box_pack_end(GTK_BOX(hbox), button, TRUE, FALSE, 5); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(applybutton, button); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(mainvbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - // Widgets for specifying the reference row & usage. - - refbutton = gtk_check_button_new_with_label(DIALOG_SET_SCALE_S_REF_ROW_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "row_ref", refbutton); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(refbutton), TRUE); - gtk_widget_show(refbutton); - - UIInstance().RegisterWidgetDependence(applybutton, refbutton); - - frame = gtk_frame_new(NULL); - gtk_frame_set_label_widget(GTK_FRAME(frame), refbutton); - gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 5); - gtk_widget_show(frame); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(frame), vbox); - gtk_widget_show(vbox); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - button = gtk_radio_button_new(NULL); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(applybutton, button); - UIInstance().RegisterWidgetDependence(refbutton, button); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "row_num_ref", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0"); - gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 5); - gtk_widget_set_size_request(entry, 25, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - UIInstance().RegisterWidgetDependence(refbutton, entry); - UIInstance().RegisterWidgetDependence(button, entry); - - button = gtk_radio_button_new_with_label_from_widget( - GTK_RADIO_BUTTON(button), - DIALOG_SET_SCALE_MAX_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "row_max_ref", button); - gtk_box_pack_end(GTK_BOX(hbox), button, TRUE, FALSE, 5); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(applybutton, button); - UIInstance().RegisterWidgetDependence(refbutton, button); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_end(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - button = gtk_check_button_new_with_label(DIALOG_SET_SCALE_REF_TOTAL_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "row_ref_total", button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(applybutton, button); - UIInstance().RegisterWidgetDependence(refbutton, button); - - // Checkbox for the "T" grouping of widgets. All the widgets in that - // grouping will have a dependence registered on this checkbox; i.e. they - // will only be active when it is checked. - - applybutton = gtk_check_button_new_with_label(DIALOG_SET_SCALE_T_ACTIVE_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "t_apply", applybutton); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(applybutton), TRUE); - gtk_widget_show(applybutton); - - frame = gtk_frame_new(NULL); - gtk_frame_set_label_widget(GTK_FRAME(frame), applybutton); - gtk_table_attach_defaults(GTK_TABLE(table), frame, 1, 2, 0, 1); - gtk_widget_show(frame); - - mainvbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(frame), mainvbox); - gtk_widget_show(mainvbox); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(mainvbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - // Widgets for specifying T scaling. - - label = gtk_label_new(DIALOG_SET_SCALE_METHOD_FRAME_TITLE); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - frame = gtk_frame_new(NULL); - gtk_frame_set_label_widget(GTK_FRAME(frame), label); - gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 5); - gtk_widget_show(frame); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(frame), vbox); - gtk_widget_show(vbox); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_end(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - button = gtk_radio_button_new_with_label_from_widget(NULL, DIALOG_SET_SCALE_TILES_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "t_tiling", button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(applybutton, button); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "t_tiles", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "1"); - gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 5); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_set_sensitive(entry, FALSE); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - UIInstance().RegisterWidgetDependence(button, entry); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_end(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - button = gtk_radio_button_new_with_label_from_widget( - GTK_RADIO_BUTTON(button), - DIALOG_SET_SCALE_NATURAL_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "t_natural", button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(applybutton, button); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "t_scale", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "1"); - gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 5); - gtk_widget_set_size_request(entry, 50, -1); - gtk_widget_set_sensitive(entry, TRUE); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - UIInstance().RegisterWidgetDependence(button, entry); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(mainvbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - // Widgets for specifying the alignment row. - - label = gtk_label_new(DIALOG_SET_SCALE_T_ALIGN_FRAME_TITLE); - gtk_widget_show(label); - - UIInstance().RegisterWidgetDependence(applybutton, label); - - frame = gtk_frame_new(NULL); - gtk_frame_set_label_widget(GTK_FRAME(frame), label); - gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 5); - gtk_widget_show(frame); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(frame), vbox); - gtk_widget_show(vbox); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - button = gtk_radio_button_new(NULL); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(applybutton, button); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "row_num_align", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0"); - gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 5); - gtk_widget_set_size_request(entry, 25, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - UIInstance().RegisterWidgetDependence(button, entry); - - button = gtk_radio_button_new_with_label_from_widget( - GTK_RADIO_BUTTON(button), - DIALOG_SET_SCALE_MAX_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "row_max_align", button); - gtk_box_pack_end(GTK_BOX(hbox), button, TRUE, FALSE, 5); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(applybutton, button); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(mainvbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - // Widgets for specifying the reference column & usage. - - refbutton = gtk_check_button_new_with_label(DIALOG_SET_SCALE_T_REF_COL_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "col_ref", refbutton); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(refbutton), TRUE); - gtk_widget_show(refbutton); - - UIInstance().RegisterWidgetDependence(applybutton, refbutton); - - frame = gtk_frame_new(NULL); - gtk_frame_set_label_widget(GTK_FRAME(frame), refbutton); - gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 5); - gtk_widget_show(frame); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(frame), vbox); - gtk_widget_show(vbox); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - button = gtk_radio_button_new(NULL); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(applybutton, button); - UIInstance().RegisterWidgetDependence(refbutton, button); - - entry = gtk_entry_new(); - g_object_set_data(G_OBJECT(_dialog), "col_num_ref", entry); - gtk_entry_set_text(GTK_ENTRY(entry), "0"); - gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 5); - gtk_widget_set_size_request(entry, 25, -1); - gtk_widget_show(entry); - - UIInstance().RegisterWidgetDependence(applybutton, entry); - UIInstance().RegisterWidgetDependence(refbutton, entry); - UIInstance().RegisterWidgetDependence(button, entry); - - button = gtk_radio_button_new_with_label_from_widget( - GTK_RADIO_BUTTON(button), - DIALOG_SET_SCALE_MAX_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "col_max_ref", button); - gtk_box_pack_end(GTK_BOX(hbox), button, TRUE, FALSE, 5); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(applybutton, button); - UIInstance().RegisterWidgetDependence(refbutton, button); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_end(GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - gtk_widget_show(hbox); - - button = gtk_check_button_new_with_label(DIALOG_SET_SCALE_REF_TOTAL_OPT_LABEL); - g_object_set_data(G_OBJECT(_dialog), "col_ref_total", button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - gtk_widget_show(button); - - UIInstance().RegisterWidgetDependence(applybutton, button); - UIInstance().RegisterWidgetDependence(refbutton, button); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_table_attach_defaults(GTK_TABLE(table), hbox, 0, 2, 1, 2); - gtk_widget_show(hbox); - - // Create Cancel button and hook it to callback. - - button = gtk_button_new_with_label(DIALOG_CANCEL_BUTTON); - gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_widget_set_size_request(button, 60, -1); - gtk_widget_show(button); - - CreateCancelButtonCallback(button); - - // Create Apply button and hook it to callback. - - button = gtk_button_new_with_label(DIALOG_APPLY_BUTTON); - gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 10); - gtk_widget_set_size_request (button, 60, -1); - gtk_widget_show(button); - - CreateApplyButtonCallback(button); - - // Create OK button and hook it to callback. - - button = gtk_button_new_with_label(DIALOG_OK_BUTTON); - gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_widget_set_size_request (button, 60, -1); - gtk_widget_show(button); - - CreateOkButtonCallback(button); + { + auto dialog_grid = new QGridLayout( _dialog ); + dialog_grid->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + { + // Checkbox for the "S" grouping of widgets. All the widgets in that + // grouping will have a dependence registered on this checkbox; i.e. they + // will only be active when it is checked. + auto group = s_apply = new QGroupBox( DIALOG_SET_SCALE_S_ACTIVE_OPT_LABEL ); + dialog_grid->addWidget( group, 0, 0 ); + group->setCheckable( true ); + group->setChecked( true ); + { + auto vbox = new QVBoxLayout( group ); + { + // Widgets for specifying S scaling. + auto group = new QGroupBox( DIALOG_SET_SCALE_METHOD_FRAME_TITLE ); + vbox->addWidget( group ); + + auto grid = new QGridLayout( group ); + { + auto radio = new QRadioButton( DIALOG_SET_SCALE_NATURAL_OPT_LABEL ); + grid->addWidget( radio, 0, 0 ); + auto spin = s_scale = new DoubleSpinBox( -999, 999, 1, 3 ); + grid->addWidget( spin, 0, 1 ); + UIInstance().RegisterWidgetDependence( radio, spin ); + radio->setChecked( true ); + } + { + auto radio = new QRadioButton( DIALOG_SET_SCALE_TILES_OPT_LABEL ); + grid->addWidget( radio, 1, 0 ); + auto spin = s_tiles = new DoubleSpinBox( -999, 999, 1, 3 ); + grid->addWidget( spin, 1, 1 ); + UIInstance().RegisterWidgetDependence( radio, spin ); + spin->setEnabled( false ); + } + } + { + // Widgets for specifying the alignment column. + auto group = new QGroupBox( DIALOG_SET_SCALE_S_ALIGN_FRAME_TITLE ); + vbox->addWidget( group ); + + auto grid = new QGridLayout( group ); + grid->setColumnStretch( 2, 1 ); + { + auto radio = new QRadioButton; + grid->addWidget( radio, 0, 0 ); + auto spin = col_num_align = new SpinBox( 0, 30 ); + grid->addWidget( spin, 0, 1 ); + UIInstance().RegisterWidgetDependence( radio, spin ); + radio->setChecked( true ); + } + { + auto radio = new QRadioButton( DIALOG_SET_SCALE_MAX_OPT_LABEL ); + grid->addWidget( radio, 0, 2, Qt::AlignmentFlag::AlignRight ); + } + } + { + // Widgets for specifying the reference row & usage. + auto group = row_ref = new QGroupBox( DIALOG_SET_SCALE_S_REF_ROW_OPT_LABEL ); + group->setCheckable( true ); + group->setChecked( true ); + vbox->addWidget( group ); + + auto grid = new QGridLayout( group ); + grid->setColumnStretch( 2, 1 ); + { + auto radio = new QRadioButton; + grid->addWidget( radio, 0, 0 ); + auto spin = row_num_ref = new SpinBox( 0, 30 ); + grid->addWidget( spin, 0, 1 ); + UIInstance().RegisterWidgetDependence( radio, spin ); + radio->setChecked( true ); + } + { + auto radio = new QRadioButton( DIALOG_SET_SCALE_MAX_OPT_LABEL ); + grid->addWidget( radio, 0, 2, Qt::AlignmentFlag::AlignRight ); + } + { + auto check = row_ref_total = new QCheckBox( DIALOG_SET_SCALE_REF_TOTAL_OPT_LABEL ); + grid->addWidget( check, 1, 0, 1, 3 ); + check->setChecked( true ); + } + } + } + } + { + // Checkbox for the "T" grouping of widgets. All the widgets in that + // grouping will have a dependence registered on this checkbox; i.e. they + // will only be active when it is checked. + auto group = t_apply = new QGroupBox( DIALOG_SET_SCALE_T_ACTIVE_OPT_LABEL ); + dialog_grid->addWidget( group, 0, 1 ); + group->setCheckable( true ); + group->setChecked( true ); + { + auto vbox = new QVBoxLayout( group ); + { + // Widgets for specifying T scaling. + auto group = new QGroupBox( DIALOG_SET_SCALE_METHOD_FRAME_TITLE ); + vbox->addWidget( group ); + + auto grid = new QGridLayout( group ); + { + auto radio = new QRadioButton( DIALOG_SET_SCALE_NATURAL_OPT_LABEL ); + grid->addWidget( radio, 0, 0 ); + auto spin = t_scale = new DoubleSpinBox( -999, 999, 1, 3 ); + grid->addWidget( spin, 0, 1 ); + UIInstance().RegisterWidgetDependence( radio, spin ); + radio->setChecked( true ); + } + { + auto radio = new QRadioButton( DIALOG_SET_SCALE_TILES_OPT_LABEL ); + grid->addWidget( radio, 1, 0 ); + auto spin = t_tiles = new DoubleSpinBox( -999, 999, 1, 3 ); + grid->addWidget( spin, 1, 1 ); + UIInstance().RegisterWidgetDependence( radio, spin ); + spin->setEnabled( false ); + } + } + { + // Widgets for specifying the alignment row. + auto group = new QGroupBox( DIALOG_SET_SCALE_T_ALIGN_FRAME_TITLE ); + vbox->addWidget( group ); + + auto grid = new QGridLayout( group ); + grid->setColumnStretch( 2, 1 ); + { + auto radio = new QRadioButton; + grid->addWidget( radio, 0, 0 ); + auto spin = row_num_align = new SpinBox( 0, 30 ); + grid->addWidget( spin, 0, 1 ); + UIInstance().RegisterWidgetDependence( radio, spin ); + radio->setChecked( true ); + } + { + auto radio = new QRadioButton( DIALOG_SET_SCALE_MAX_OPT_LABEL ); + grid->addWidget( radio, 0, 2, Qt::AlignmentFlag::AlignRight ); + } + } + { + // Widgets for specifying the reference column & usage. + auto group = col_ref = new QGroupBox( DIALOG_SET_SCALE_T_REF_COL_OPT_LABEL ); + group->setCheckable( true ); + group->setChecked( true ); + vbox->addWidget( group ); + + auto grid = new QGridLayout( group ); + grid->setColumnStretch( 2, 1 ); + { + auto radio = new QRadioButton; + grid->addWidget( radio, 0, 0 ); + auto spin = col_num_ref = new SpinBox( 0, 30 ); + grid->addWidget( spin, 0, 1 ); + UIInstance().RegisterWidgetDependence( radio, spin ); + radio->setChecked( true ); + } + { + auto radio = new QRadioButton( DIALOG_SET_SCALE_MAX_OPT_LABEL ); + grid->addWidget( radio, 0, 2, Qt::AlignmentFlag::AlignRight ); + } + { + auto check = col_ref_total = new QCheckBox( DIALOG_SET_SCALE_REF_TOTAL_OPT_LABEL ); + grid->addWidget( check, 1, 0, 1, 3 ); + check->setChecked( true ); + } + } + } + } + { + auto buttons = new QDialogButtonBox; + dialog_grid->addWidget( buttons, 1, 0, 1, 2 ); + CreateOkButtonCallback( buttons->addButton( QDialogButtonBox::StandardButton::Ok ) ); + CreateApplyButtonCallback( buttons->addButton( QDialogButtonBox::StandardButton::Apply ) ); + CreateCancelButtonCallback( buttons->addButton( QDialogButtonBox::StandardButton::Cancel ) ); + } + } } /** @@ -577,8 +295,8 @@ SetScaleDialog::Apply() } // See if we're going to be affecting the S and/or T texture axis. - bool sApply = NamedToggleWidgetActive("s_apply"); - bool tApply = NamedToggleWidgetActive("t_apply"); + const bool sApply = s_apply->isChecked(); + const bool tApply = t_apply->isChecked(); if (!sApply && !tApply) { @@ -596,25 +314,25 @@ SetScaleDialog::Apply() if (sApply) { // S axis is affected, so read the S info. - row.naturalScale = NamedToggleWidgetActive("s_natural"); + row.naturalScale = s_scale->isEnabled(); if (row.naturalScale) { - row.scaleOrTiles = (float)atof(NamedEntryWidgetText("s_scale")); + row.scaleOrTiles = s_scale->value(); } else { - row.scaleOrTiles = (float)atof(NamedEntryWidgetText("s_tiles")); + row.scaleOrTiles = s_tiles->value(); } - alignCol.maxSlice = NamedToggleWidgetActive("col_max_align"); - alignCol.index = atoi(NamedEntryWidgetText("col_num_align")); + alignCol.maxSlice = !col_num_align->isEnabled(); + alignCol.index = col_num_align->value(); row.alignSlice = &alignCol; row.refSlice = NULL; - if (NamedToggleWidgetActive("row_ref")) + if ( row_ref->isChecked() ) { // Reference row is specified, so get that info. - refRow.designation.maxSlice = NamedToggleWidgetActive("row_max_ref"); - refRow.designation.index = atoi(NamedEntryWidgetText("row_num_ref")); - refRow.totalLengthOnly = NamedToggleWidgetActive("row_ref_total"); + refRow.designation.maxSlice = !row_num_ref->isEnabled(); + refRow.designation.index = row_num_ref->value(); + refRow.totalLengthOnly = row_ref_total->isChecked(); row.refSlice = &refRow; } rowArgs = &row; @@ -622,25 +340,25 @@ SetScaleDialog::Apply() if (tApply) { // T axis is affected, so read the T info. - col.naturalScale = NamedToggleWidgetActive("t_natural"); + col.naturalScale = t_scale->isEnabled(); if (col.naturalScale) { - col.scaleOrTiles = (float)atof(NamedEntryWidgetText("t_scale")); + col.scaleOrTiles = t_scale->value(); } else { - col.scaleOrTiles = (float)atof(NamedEntryWidgetText("t_tiles")); + col.scaleOrTiles = t_tiles->value(); } - alignRow.maxSlice = NamedToggleWidgetActive("row_max_align"); - alignRow.index = atoi(NamedEntryWidgetText("row_num_align")); + alignRow.maxSlice = !row_num_align->isEnabled(); + alignRow.index = row_num_align->value(); col.alignSlice = &alignRow; col.refSlice = NULL; - if (NamedToggleWidgetActive("col_ref")) + if ( col_ref->isChecked() ) { // Reference column is specified, so get that info. - refCol.designation.maxSlice = NamedToggleWidgetActive("col_max_ref"); - refCol.designation.index = atoi(NamedEntryWidgetText("col_num_ref")); - refCol.totalLengthOnly = NamedToggleWidgetActive("col_ref_total"); + refCol.designation.maxSlice = !col_num_ref->isEnabled(); + refCol.designation.index = col_num_ref->value(); + refCol.totalLengthOnly = col_ref_total->isChecked(); col.refSlice = &refCol; } colArgs = &col; @@ -669,8 +387,8 @@ SetScaleDialog::PopulateSWidgets(float scale, float tiles) { // Use the texture info to populate some of our widgets. - PopulateEntry("s_scale", scale); - PopulateEntry("s_tiles", tiles); + s_scale->setValue( scale); + s_tiles->setValue( tiles); } /** @@ -684,21 +402,6 @@ SetScaleDialog::PopulateTWidgets(float scale, float tiles) { // Use the texture info to populate some of our widgets. - PopulateEntry("t_scale", scale); - PopulateEntry("t_tiles", tiles); -} - -/** - * Populate a text widget with a floating point number. - * - * @param widgetName Name of the widget. - * @param value The number to write to the widget. - */ -void -SetScaleDialog::PopulateEntry(const char *widgetName, - float value) -{ - static char entryBuffer[ENTRY_BUFFER_SIZE + 1] = { 0 }; - snprintf(entryBuffer, ENTRY_BUFFER_SIZE, "%f", value); - gtk_entry_set_text(GTK_ENTRY(NamedWidget(widgetName)), entryBuffer); + t_scale->setValue( scale); + t_tiles->setValue( tiles); } diff --git a/contrib/meshtex/SetScaleDialog.h b/contrib/meshtex/SetScaleDialog.h index 605cf6be..5f97d83a 100644 --- a/contrib/meshtex/SetScaleDialog.h +++ b/contrib/meshtex/SetScaleDialog.h @@ -23,8 +23,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_SETSCALEDIALOG_H) -#define INCLUDED_SETSCALEDIALOG_H +#pragma once #include "GenericDialog.h" #include "MeshVisitor.h" @@ -33,7 +32,7 @@ * Subclass of GenericDialog that implements the window summoned by selecting * the Set S/T Scale menu entry. This window is used to control the scaling * of the S and/or T texture axes. - * + * * @image html setscale.png * * @ingroup meshtex-ui @@ -93,18 +92,27 @@ public: // public methods void PopulateTWidgets(float scale, float tiles); -private: // private methods - - void PopulateEntry(const char *widgetName, - float value); - private: // private member vars + QGroupBox *s_apply; + QDoubleSpinBox *s_scale; + QDoubleSpinBox *s_tiles; + QSpinBox *col_num_align; + QGroupBox *row_ref; + QSpinBox *row_num_ref; + QCheckBox *row_ref_total; + + QGroupBox *t_apply; + QDoubleSpinBox *t_scale; + QDoubleSpinBox *t_tiles; + QSpinBox *row_num_align; + QGroupBox *col_ref; + QSpinBox *col_num_ref; + QCheckBox *col_ref_total; + /** * Action-less mesh visitor used purely to count the number of selected mesh * entities. */ SmartPointer _nullVisitor; }; - -#endif // #if !defined(INCLUDED_SETSCALEDIALOG_H) \ No newline at end of file diff --git a/contrib/meshtex/UtilityMacros.h b/contrib/meshtex/UtilityMacros.h index 9f670b7c..86e6b0fe 100644 --- a/contrib/meshtex/UtilityMacros.h +++ b/contrib/meshtex/UtilityMacros.h @@ -23,8 +23,7 @@ * along with MeshTex. If not, see . */ -#if !defined(INCLUDED_UTILITYMACROS_H) -#define INCLUDED_UTILITYMACROS_H +#pragma once /** * Convert a token to a string at compile-time. @@ -39,5 +38,3 @@ * @param A The name of the macro to process. */ #define STRINGIFY_MACRO(A) STRINGIFY(A) - -#endif // #if !defined(INCLUDED_UTILITYMACROS_H) diff --git a/contrib/prtview/AboutDialog.cpp b/contrib/prtview/AboutDialog.cpp index cd3d04a2..b41f9225 100644 --- a/contrib/prtview/AboutDialog.cpp +++ b/contrib/prtview/AboutDialog.cpp @@ -18,85 +18,19 @@ */ #include "AboutDialog.h" -#include +#include "qerplugin.h" #include "version.h" -#include "gtkutil/pointer.h" #include "prtview.h" #include "ConfigDialog.h" -static void dialog_button_callback( GtkWidget *widget, gpointer data ){ - GtkWidget *parent; - int *loop, *ret; - - parent = gtk_widget_get_toplevel( widget ); - loop = (int*)g_object_get_data( G_OBJECT( parent ), "loop" ); - ret = (int*)g_object_get_data( G_OBJECT( parent ), "ret" ); - - *loop = 0; - *ret = gpointer_to_int( data ); -} - -static gint dialog_delete_callback( GtkWidget *widget, GdkEvent* event, gpointer data ){ - int *loop; - - gtk_widget_hide( widget ); - loop = (int*)g_object_get_data( G_OBJECT( widget ), "loop" ); - *loop = 0; - - return TRUE; -} - void DoAboutDlg(){ - GtkWidget *dlg, *hbox, *vbox, *button, *label; - int loop = 1, ret = IDCANCEL; - - dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - gtk_window_set_transient_for( GTK_WINDOW( dlg ), GTK_WINDOW( g_pRadiantWnd ) ); - gtk_window_set_position( GTK_WINDOW( dlg ),GTK_WIN_POS_CENTER_ON_PARENT ); - gtk_window_set_modal( GTK_WINDOW( dlg ), TRUE ); - gtk_window_set_title( GTK_WINDOW( dlg ), "About Portal Viewer" ); - g_signal_connect( G_OBJECT( dlg ), "delete_event", - G_CALLBACK( dialog_delete_callback ), NULL ); - g_signal_connect( G_OBJECT( dlg ), "destroy", - G_CALLBACK( gtk_widget_destroy ), NULL ); - g_object_set_data( G_OBJECT( dlg ), "loop", &loop ); - g_object_set_data( G_OBJECT( dlg ), "ret", &ret ); - - hbox = gtk_hbox_new( FALSE, 10 ); - gtk_widget_show( hbox ); - gtk_container_add( GTK_CONTAINER( dlg ), hbox ); - gtk_container_set_border_width( GTK_CONTAINER( hbox ), 10 ); - - label = gtk_label_new( "Version 1.000\n\n" - "Gtk port by Leonardo Zide\nleo@lokigames.com\n\n" - "Written by Geoffrey DeWan\ngdewan@prairienet.org\n\n" - "Built against NetRadiant " RADIANT_VERSION "\n" - __DATE__ - ); - gtk_widget_show( label ); - gtk_box_pack_start( GTK_BOX( hbox ), label, TRUE, TRUE, 0 ); - gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT ); - - vbox = gtk_vbox_new( FALSE, 0 ); - gtk_widget_show( vbox ); - gtk_box_pack_start( GTK_BOX( hbox ), vbox, FALSE, FALSE, 0 ); - - button = gtk_button_new_with_label( "OK" ); - gtk_widget_show( button ); - gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDOK ) ); - gtk_widget_set_size_request( button, 60, -1 ); - - gtk_widget_show( dlg ); - - while ( loop ) - gtk_main_iteration(); - - gtk_widget_destroy( dlg ); + constexpr char msg[] = "Version 1.000

" + "Gtk port by Leonardo Zide
" + "leo@lokigames.com

" + "Written by Geoffrey DeWan
" + "gdewan@prairienet.org

" + "Built against NetRadiant " RADIANT_VERSION "
" + __DATE__; + GlobalRadiant().m_pfnMessageBox( g_pRadiantWnd, msg, "About Portal Viewer", EMessageBoxType::Info, 0 ); } - - -///////////////////////////////////////////////////////////////////////////// -// CAboutDialog message handlers diff --git a/contrib/prtview/ConfigDialog.cpp b/contrib/prtview/ConfigDialog.cpp index c3ababd5..b1c12795 100644 --- a/contrib/prtview/ConfigDialog.cpp +++ b/contrib/prtview/ConfigDialog.cpp @@ -18,464 +18,143 @@ */ #include "ConfigDialog.h" -#include -#include -#include "gtkutil/pointer.h" #include "iscenegraph.h" +#include "qerplugin.h" #include "prtview.h" #include "portals.h" -static void dialog_button_callback( GtkWidget *widget, gpointer data ){ - GtkWidget *parent; - int *loop, *ret; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include - parent = gtk_widget_get_toplevel( widget ); - loop = (int*)g_object_get_data( G_OBJECT( parent ), "loop" ); - ret = (int*)g_object_get_data( G_OBJECT( parent ), "ret" ); - *loop = 0; - *ret = gpointer_to_int( data ); -} - -static gint dialog_delete_callback( GtkWidget *widget, GdkEvent* event, gpointer data ){ - int *loop; - - gtk_widget_hide( widget ); - loop = (int*)g_object_get_data( G_OBJECT( widget ), "loop" ); - *loop = 0; - - return TRUE; -} - -// ============================================================================= -// Color selection dialog - -static int DoColor( PackedColour *c ){ - GtkWidget* dlg; - GdkColor clr = { 0, guint16( GetRValue( *c ) * ( 65535 / 255 ) ), - guint16( GetGValue( *c ) * ( 65535 / 255 ) ), - guint16( GetBValue( *c ) * ( 65535 / 255 ) ) - }; - int loop = 1, ret = IDCANCEL; - - dlg = gtk_color_selection_dialog_new( "Choose Color" ); - gtk_window_set_transient_for( GTK_WINDOW( dlg ), GTK_WINDOW( g_pRadiantWnd ) ); - gtk_window_set_position( GTK_WINDOW( dlg ),GTK_WIN_POS_CENTER_ON_PARENT ); - gtk_window_set_modal( GTK_WINDOW( dlg ), TRUE ); - gtk_color_selection_set_current_color( GTK_COLOR_SELECTION( gtk_color_selection_dialog_get_color_selection( GTK_COLOR_SELECTION_DIALOG( dlg ) ) ), &clr ); - g_signal_connect( G_OBJECT( dlg ), "delete_event", G_CALLBACK( dialog_delete_callback ), NULL ); - g_signal_connect( G_OBJECT( dlg ), "destroy", G_CALLBACK( gtk_widget_destroy ), NULL ); - - GtkWidget *ok_button, *cancel_button; - g_object_get( G_OBJECT( dlg ), "ok-button", &ok_button, "cancel-button", &cancel_button, nullptr ); - - g_signal_connect( G_OBJECT( ok_button ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDOK ) ); - g_signal_connect( G_OBJECT( cancel_button ), "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) ); - g_object_set_data( G_OBJECT( dlg ), "loop", &loop ); - g_object_set_data( G_OBJECT( dlg ), "ret", &ret ); - - gtk_widget_show( dlg ); - - while ( loop ) - gtk_main_iteration(); - - gtk_color_selection_get_current_color( GTK_COLOR_SELECTION( gtk_color_selection_dialog_get_color_selection( GTK_COLOR_SELECTION_DIALOG( dlg ) ) ), &clr ); - - gtk_widget_destroy( dlg ); - - if ( ret == IDOK ) { - *c = RGB( clr.red / (65535 / 255), clr.green / (65535 / 255), clr.blue / (65535 / 255) ); - } - - return ret; -} - -static void Set2DText( GtkWidget* label ){ - char s[40]; - - sprintf( s, "Line Width = %6.3f", portals.width_2d * 0.5f ); - - gtk_label_set_text( GTK_LABEL( label ), s ); -} - -static void Set3DText( GtkWidget* label ){ - char s[40]; - - sprintf( s, "Line Width = %6.3f", portals.width_3d * 0.5f ); - - gtk_label_set_text( GTK_LABEL( label ), s ); -} - -static void Set3DTransText( GtkWidget* label ){ - char s[40]; - - sprintf( s, "Polygon transparency = %d%%", (int)portals.trans_3d ); - - gtk_label_set_text( GTK_LABEL( label ), s ); -} - -static void SetClipText( GtkWidget* label ){ - char s[40]; - - sprintf( s, "Cubic clip range = %d", (int)portals.clip_range * 64 ); - - gtk_label_set_text( GTK_LABEL( label ), s ); -} - -static void OnScroll2d( GtkAdjustment *adj, gpointer data ){ - portals.width_2d = static_cast( gtk_adjustment_get_value( adj ) ); - Set2DText( GTK_WIDGET( data ) ); - - Portals_shadersChanged(); - SceneChangeNotify(); -} - -static void OnScroll3d( GtkAdjustment *adj, gpointer data ){ - portals.width_3d = static_cast( gtk_adjustment_get_value( adj ) ); - Set3DText( GTK_WIDGET( data ) ); - - SceneChangeNotify(); -} - -static void OnScrollTrans( GtkAdjustment *adj, gpointer data ){ - portals.trans_3d = static_cast( gtk_adjustment_get_value( adj ) ); - Set3DTransText( GTK_WIDGET( data ) ); - - SceneChangeNotify(); -} - -static void OnScrollClip( GtkAdjustment *adj, gpointer data ){ - portals.clip_range = static_cast( gtk_adjustment_get_value( adj ) ); - SetClipText( GTK_WIDGET( data ) ); - - SceneChangeNotify(); -} - -static void OnAntiAlias2d( GtkWidget *widget, gpointer data ){ - portals.aa_2d = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ) ? true : false; - - Portals_shadersChanged(); - - SceneChangeNotify(); -} - -static void OnConfig2d( GtkWidget *widget, gpointer data ){ - portals.show_2d = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ) ? true : false; - - SceneChangeNotify(); -} - -static void OnColor2d( GtkWidget *widget, gpointer data ){ - if ( DoColor( &portals.color_2d ) == IDOK ) { +static void OnColor( PackedColour& clr ){ + Vector3 color( RGB_UNPACK_R( clr ) / 255.f, RGB_UNPACK_G( clr ) / 255.f, RGB_UNPACK_B( clr ) / 255.f ); + if ( GlobalRadiant().m_pfnColorDialog( g_pRadiantWnd, color, "Choose Color" ) ) + { + clr = RGB_PACK( color[0] * 255, color[1] * 255, color[2] * 255 ); Portals_shadersChanged(); - SceneChangeNotify(); } } -static void OnConfig3d( GtkWidget *widget, gpointer data ){ - portals.show_3d = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ) ? true : false; +static void form_add_color( QFormLayout *form, PackedColour& color ){ + auto button = new QPushButton( "Color" ); + QObject::connect( button, &QAbstractButton::clicked, [&color](){ OnColor( color ); } ); - SceneChangeNotify(); + auto hbox = new QHBoxLayout; + form->addRow( hbox ); + hbox->addStretch(); + hbox->addWidget( button ); } +static void form_add_slider( QFormLayout *form, int& param, int min, int max, const char *prefix, const char *suffix, bool changeShaders ){ + auto slider = new QSlider( Qt::Orientation::Horizontal ); + slider->setRange( min, max ); -static void OnAntiAlias3d( GtkWidget *widget, gpointer data ){ - portals.aa_3d = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ) ? true : false; - - Portals_shadersChanged(); - SceneChangeNotify(); -} - -static void OnColor3d( GtkWidget *widget, gpointer data ){ - if ( DoColor( &portals.color_3d ) == IDOK ) { - Portals_shadersChanged(); + auto label = new QLabel; + label->setMinimumWidth( label->fontMetrics().horizontalAdvance( QString( prefix ) + QString::number( max ) + suffix ) ); + const auto label_set_text = [label, prefix, suffix]( int value ){ + label->setText( QString( prefix ) + QString::number( value ) + suffix ); + }; + QObject::connect( slider, &QSlider::valueChanged, label_set_text ); + slider->setValue( param ); // sets label text too + QObject::connect( slider, &QAbstractSlider::valueChanged, [¶m, changeShaders]( int value ){ + param = value; + if( changeShaders ) + Portals_shadersChanged(); SceneChangeNotify(); - } + } ); + + form->addRow( label, slider ); } -static void OnColorFog( GtkWidget *widget, gpointer data ){ - if ( DoColor( &portals.color_fog ) == IDOK ) { - Portals_shadersChanged(); - +static QGroupBox* vbox_add_group( QVBoxLayout *vbox, const char *name, bool& param, bool changeShaders ){ + auto group = new QGroupBox( name ); + vbox->addWidget( group ); + group->setCheckable( true ); + group->setChecked( param ); + QObject::connect( group, &QGroupBox::toggled, [¶m, changeShaders]( bool on ){ + param = on; + if( changeShaders ) + Portals_shadersChanged(); SceneChangeNotify(); - } + } ); + + return group; } -static void OnFog( GtkWidget *widget, gpointer data ){ - portals.fog = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ) ? true : false; - - Portals_shadersChanged(); - SceneChangeNotify(); -} - -static void OnSelchangeZbuffer( GtkComboBox *comboBox, gpointer data ){ - portals.zbuffer = gtk_combo_box_get_active( comboBox ); - - Portals_shadersChanged(); - SceneChangeNotify(); -} - -static void OnPoly( GtkWidget *widget, gpointer data ){ - portals.polygons = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ); - - SceneChangeNotify(); -} - -static void OnLines( GtkWidget *widget, gpointer data ){ - portals.lines = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ); - - SceneChangeNotify(); -} - -static void OnClip( GtkWidget *widget, gpointer data ){ - portals.clip = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ) ? true : false; - - SceneChangeNotify(); +static QCheckBox* new_checkbox( const char *name, bool& param ){ + auto check = new QCheckBox( name ); + check->setChecked( param ); + QObject::connect( check, &QAbstractButton::toggled, [¶m]( bool checked ){ + param = checked; + SceneChangeNotify(); + } ); + return check; } void DoConfigDialog(){ - GtkWidget *dlg, *hbox, *vbox, *vbox2, *button, *table, *frame; - GtkWidget *lw3slider, *lw3label, *lw2slider, *lw2label, *zlist; - GtkWidget *aa2check, *aa3check, *depthcheck, *linescheck, *polyscheck; - GtkWidget *transslider, *translabel, *clipslider, *cliplabel; - GtkWidget *show2check, *show3check, *portalcheck; - int loop = 1, ret = IDCANCEL; + auto dialog = new QDialog( g_pRadiantWnd, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog->setWindowTitle( "Portal Viewer Configuration" ); + dialog->setAttribute( Qt::WidgetAttribute::WA_DeleteOnClose ); - dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - gtk_window_set_transient_for( GTK_WINDOW( dlg ), GTK_WINDOW( g_pRadiantWnd ) ); - gtk_window_set_position( GTK_WINDOW( dlg ),GTK_WIN_POS_CENTER_ON_PARENT ); - gtk_window_set_modal( GTK_WINDOW( dlg ), TRUE ); - gtk_window_set_title( GTK_WINDOW( dlg ), "Portal Viewer Configuration" ); - g_signal_connect( G_OBJECT( dlg ), "delete_event", - G_CALLBACK( dialog_delete_callback ), NULL ); - g_signal_connect( G_OBJECT( dlg ), "destroy", - G_CALLBACK( gtk_widget_destroy ), NULL ); - g_object_set_data( G_OBJECT( dlg ), "loop", &loop ); - g_object_set_data( G_OBJECT( dlg ), "ret", &ret ); + { + auto dialog_vbox = new QVBoxLayout( dialog ); + dialog_vbox->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + { + auto vbox = new QVBoxLayout( vbox_add_group( dialog_vbox, "3D View", portals.show_3d, false ) ); + { + auto form = new QFormLayout( vbox_add_group( vbox, "Lines", portals.lines, false ) ); + form_add_slider( form, portals.width_3d, 1, 10, "Width = ", "", true ); + form_add_color( form, portals.color_3d ); + } + { + auto form = new QFormLayout( vbox_add_group( vbox, "Polygons", portals.polygons, false ) ); + form_add_slider( form, portals.opacity_3d, 0, 100, "Opacity = ", "%", false ); + } + { + auto form = new QFormLayout( vbox_add_group( vbox, "Fog", portals.fog, true ) ); + form_add_color( form, portals.color_fog ); + } + { + auto form = new QFormLayout( vbox_add_group( vbox, "Cubic clipper", portals.clip, false ) ); + form_add_slider( form, portals.clip_range, 64, 8192, "Clip range = ", "", false ); + } + { + auto combo = new QComboBox; + vbox->addWidget( combo ); + combo->addItem( "Z-Buffer Test and Write (recommended for solid or no polygons)" ); + combo->addItem( "Z-Buffer Test Only (recommended for transparent polygons)" ); + combo->addItem( "Z-Buffer Off" ); + combo->setCurrentIndex( portals.zbuffer ); + QObject::connect( combo, QOverload::of( &QComboBox::currentIndexChanged ), [&zbuffer = portals.zbuffer]( int index ){ + zbuffer = index; + Portals_shadersChanged(); + SceneChangeNotify(); + } ); + } + } + { + dialog_vbox->addWidget( new_checkbox( "Draw Hint Portals", portals.draw_hints ), 0, Qt::AlignmentFlag::AlignHCenter ); + dialog_vbox->addWidget( new_checkbox( "Draw Regular Portals", portals.draw_nonhints ), 0, Qt::AlignmentFlag::AlignHCenter ); + } + { + auto form = new QFormLayout( vbox_add_group( dialog_vbox, "2D View Lines", portals.show_2d, false ) ); + form_add_slider( form, portals.width_2d, 1, 10, "Width = ", "", true ); + form_add_color( form, portals.color_2d ); + } + } - vbox = gtk_vbox_new( FALSE, 5 ); - gtk_widget_show( vbox ); - gtk_container_add( GTK_CONTAINER( dlg ), vbox ); - gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 ); - - frame = gtk_frame_new( "3D View" ); - gtk_widget_show( frame ); - gtk_box_pack_start( GTK_BOX( vbox ), frame, TRUE, TRUE, 0 ); - - vbox2 = gtk_vbox_new( FALSE, 5 ); - gtk_widget_show( vbox2 ); - gtk_container_add( GTK_CONTAINER( frame ), vbox2 ); - gtk_container_set_border_width( GTK_CONTAINER( vbox2 ), 5 ); - - hbox = gtk_hbox_new( FALSE, 5 ); - gtk_widget_show( hbox ); - gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, TRUE, 0 ); - - auto *adj = gtk_adjustment_new( portals.width_3d, 2, 40, 1, 1, 0 ); - lw3slider = gtk_hscale_new( GTK_ADJUSTMENT( adj ) ); - gtk_widget_show( lw3slider ); - gtk_box_pack_start( GTK_BOX( hbox ), lw3slider, TRUE, TRUE, 0 ); - gtk_scale_set_draw_value( GTK_SCALE( lw3slider ), FALSE ); - - lw3label = gtk_label_new( "" ); - gtk_widget_show( lw3label ); - gtk_box_pack_start( GTK_BOX( hbox ), lw3label, FALSE, TRUE, 0 ); - g_signal_connect( adj, "value_changed", G_CALLBACK( OnScroll3d ), lw3label ); - - table = gtk_table_new( 2, 4, FALSE ); - gtk_widget_show( table ); - gtk_box_pack_start( GTK_BOX( vbox2 ), table, TRUE, TRUE, 0 ); - gtk_table_set_row_spacings( GTK_TABLE( table ), 5 ); - gtk_table_set_col_spacings( GTK_TABLE( table ), 5 ); - - button = gtk_button_new_with_label( "Color" ); - gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( OnColor3d ), NULL ); - - button = gtk_button_new_with_label( "Depth Color" ); - gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( OnColorFog ), NULL ); - - aa3check = gtk_check_button_new_with_label( "Anti-Alias (May not work on some video cards)" ); - gtk_widget_show( aa3check ); - gtk_table_attach( GTK_TABLE( table ), aa3check, 1, 4, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( aa3check ), "toggled", G_CALLBACK( OnAntiAlias3d ), NULL ); - - depthcheck = gtk_check_button_new_with_label( "Depth Cue" ); - gtk_widget_show( depthcheck ); - gtk_table_attach( GTK_TABLE( table ), depthcheck, 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( depthcheck ), "toggled", G_CALLBACK( OnFog ), NULL ); - - linescheck = gtk_check_button_new_with_label( "Lines" ); - gtk_widget_show( linescheck ); - gtk_table_attach( GTK_TABLE( table ), linescheck, 2, 3, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( linescheck ), "toggled", G_CALLBACK( OnLines ), NULL ); - - polyscheck = gtk_check_button_new_with_label( "Polygons" ); - gtk_widget_show( polyscheck ); - gtk_table_attach( GTK_TABLE( table ), polyscheck, 3, 4, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( polyscheck ), "toggled", G_CALLBACK( OnPoly ), NULL ); - - zlist = gtk_combo_box_text_new(); - gtk_widget_show( zlist ); - gtk_box_pack_start( GTK_BOX( vbox2 ), zlist, TRUE, FALSE, 0 ); - - gtk_combo_box_text_append_text( GTK_COMBO_BOX_TEXT( zlist ), "Z-Buffer Test and Write (recommended for solid or no polygons)" ); - gtk_combo_box_text_append_text( GTK_COMBO_BOX_TEXT( zlist ), "Z-Buffer Test Only (recommended for transparent polygons)" ); - gtk_combo_box_text_append_text( GTK_COMBO_BOX_TEXT( zlist ), "Z-Buffer Off" ); - - g_signal_connect( G_OBJECT( zlist ), "changed", G_CALLBACK( OnSelchangeZbuffer ), nullptr ); - - table = gtk_table_new( 2, 2, FALSE ); - gtk_widget_show( table ); - gtk_box_pack_start( GTK_BOX( vbox2 ), table, TRUE, TRUE, 0 ); - gtk_table_set_row_spacings( GTK_TABLE( table ), 5 ); - gtk_table_set_col_spacings( GTK_TABLE( table ), 5 ); - - adj = gtk_adjustment_new( portals.trans_3d, 0, 100, 1, 1, 0 ); - transslider = gtk_hscale_new( GTK_ADJUSTMENT( adj ) ); - gtk_widget_show( transslider ); - gtk_table_attach( GTK_TABLE( table ), transslider, 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_scale_set_draw_value( GTK_SCALE( transslider ), FALSE ); - - translabel = gtk_label_new( "" ); - gtk_widget_show( translabel ); - gtk_table_attach( GTK_TABLE( table ), translabel, 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( translabel ), 0.0, 0.0 ); - g_signal_connect( adj, "value_changed", G_CALLBACK( OnScrollTrans ), translabel ); - - adj = gtk_adjustment_new( portals.clip_range, 1, 128, 1, 1, 0 ); - clipslider = gtk_hscale_new( GTK_ADJUSTMENT( adj ) ); - gtk_widget_show( clipslider ); - gtk_table_attach( GTK_TABLE( table ), clipslider, 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_scale_set_draw_value( GTK_SCALE( clipslider ), FALSE ); - - cliplabel = gtk_label_new( "" ); - gtk_widget_show( cliplabel ); - gtk_table_attach( GTK_TABLE( table ), cliplabel, 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( cliplabel ), 0.0, 0.0 ); - g_signal_connect( adj, "value_changed", G_CALLBACK( OnScrollClip ), cliplabel ); - - hbox = gtk_hbox_new( TRUE, 5 ); - gtk_widget_show( hbox ); - gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, FALSE, 0 ); - - show3check = gtk_check_button_new_with_label( "Show" ); - gtk_widget_show( show3check ); - gtk_box_pack_start( GTK_BOX( hbox ), show3check, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( show3check ), "toggled", G_CALLBACK( OnConfig3d ), NULL ); - - portalcheck = gtk_check_button_new_with_label( "Portal cubic clipper" ); - gtk_widget_show( portalcheck ); - gtk_box_pack_start( GTK_BOX( hbox ), portalcheck, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( portalcheck ), "toggled", G_CALLBACK( OnClip ), NULL ); - - frame = gtk_frame_new( "2D View" ); - gtk_widget_show( frame ); - gtk_box_pack_start( GTK_BOX( vbox ), frame, TRUE, TRUE, 0 ); - - vbox2 = gtk_vbox_new( FALSE, 5 ); - gtk_widget_show( vbox2 ); - gtk_container_add( GTK_CONTAINER( frame ), vbox2 ); - gtk_container_set_border_width( GTK_CONTAINER( vbox2 ), 5 ); - - hbox = gtk_hbox_new( FALSE, 5 ); - gtk_widget_show( hbox ); - gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, FALSE, 0 ); - - adj = gtk_adjustment_new( portals.width_2d, 2, 40, 1, 1, 0 ); - lw2slider = gtk_hscale_new( GTK_ADJUSTMENT( adj ) ); - gtk_widget_show( lw2slider ); - gtk_box_pack_start( GTK_BOX( hbox ), lw2slider, TRUE, TRUE, 0 ); - gtk_scale_set_draw_value( GTK_SCALE( lw2slider ), FALSE ); - - lw2label = gtk_label_new( "" ); - gtk_widget_show( lw2label ); - gtk_box_pack_start( GTK_BOX( hbox ), lw2label, FALSE, TRUE, 0 ); - g_signal_connect( adj, "value_changed", G_CALLBACK( OnScroll2d ), lw2label ); - - hbox = gtk_hbox_new( FALSE, 5 ); - gtk_widget_show( hbox ); - gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, FALSE, 0 ); - - button = gtk_button_new_with_label( "Color" ); - gtk_widget_show( button ); - gtk_box_pack_start( GTK_BOX( hbox ), button, FALSE, FALSE, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( OnColor2d ), NULL ); - gtk_widget_set_size_request( button, 60, -1 ); - - aa2check = gtk_check_button_new_with_label( "Anti-Alias (May not work on some video cards)" ); - gtk_widget_show( aa2check ); - gtk_box_pack_start( GTK_BOX( hbox ), aa2check, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( aa2check ), "toggled", G_CALLBACK( OnAntiAlias2d ), NULL ); - - hbox = gtk_hbox_new( FALSE, 5 ); - gtk_widget_show( hbox ); - gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, FALSE, 0 ); - - show2check = gtk_check_button_new_with_label( "Show" ); - gtk_widget_show( show2check ); - gtk_box_pack_start( GTK_BOX( hbox ), show2check, FALSE, FALSE, 0 ); - g_signal_connect( G_OBJECT( show2check ), "toggled", G_CALLBACK( OnConfig2d ), NULL ); - - hbox = gtk_hbox_new( FALSE, 5 ); - gtk_widget_show( hbox ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - - button = gtk_button_new_with_label( "OK" ); - gtk_widget_show( button ); - gtk_box_pack_end( GTK_BOX( hbox ), button, FALSE, FALSE, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDOK ) ); - gtk_widget_set_size_request( button, 60, -1 ); - - // initialize dialog - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( show2check ), portals.show_2d ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( aa2check ), portals.aa_2d ); - Set2DText( lw2label ); - - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( show3check ), portals.show_3d ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( depthcheck ), portals.fog ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( polyscheck ), portals.polygons ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( linescheck ), portals.lines ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( aa3check ), portals.aa_3d ); - gtk_combo_box_set_active( GTK_COMBO_BOX( zlist ), portals.zbuffer ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( portalcheck ), portals.clip ); - - Set3DText( lw3label ); - Set3DTransText( translabel ); - SetClipText( cliplabel ); - - gtk_widget_show( dlg ); - - while ( loop ) - gtk_main_iteration(); - - gtk_widget_destroy( dlg ); + dialog->show(); } diff --git a/contrib/prtview/LoadPortalFileDialog.cpp b/contrib/prtview/LoadPortalFileDialog.cpp index de93c616..00be59b2 100644 --- a/contrib/prtview/LoadPortalFileDialog.cpp +++ b/contrib/prtview/LoadPortalFileDialog.cpp @@ -22,106 +22,54 @@ #include "LoadPortalFileDialog.h" -#include #include "stream/stringstream.h" #include "convert.h" -#include "gtkutil/pointer.h" #include "qerplugin.h" #include "prtview.h" #include "portals.h" -static void dialog_button_callback( GtkWidget *widget, gpointer data ){ - GtkWidget *parent; - int *loop, *ret; +#include +#include +#include +#include +#include +#include +#include +#include - parent = gtk_widget_get_toplevel( widget ); - loop = (int*)g_object_get_data( G_OBJECT( parent ), "loop" ); - ret = (int*)g_object_get_data( G_OBJECT( parent ), "ret" ); - *loop = 0; - *ret = gpointer_to_int( data ); -} +bool DoLoadPortalFileDialog(){ + QDialog dialog( g_pRadiantWnd, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Load .prt" ); -static gint dialog_delete_callback( GtkWidget *widget, GdkEvent* event, gpointer data ){ - int *loop; + QLineEdit *line; + QCheckBox *check3d, *check2d; - gtk_widget_hide( widget ); - loop = (int*)g_object_get_data( G_OBJECT( widget ), "loop" ); - *loop = 0; - - return TRUE; -} - -static void change_clicked( GtkWidget *widget, gpointer data ){ - if ( const char* filename = GlobalRadiant().m_pfnFileDialog( g_pRadiantWnd, true, "Locate portal (.prt) file", gtk_entry_get_text( GTK_ENTRY( data ) ), 0, true, false, false ) ) { - strcpy( portals.fn, filename ); - gtk_entry_set_text( GTK_ENTRY( data ), filename ); + { + auto vbox = new QVBoxLayout( &dialog ); + { + vbox->addWidget( line = new QLineEdit ); + line->setMaxLength( std::size( portals.fn ) - 1 ); + auto button = line->addAction( QApplication::style()->standardIcon( QStyle::SP_FileDialogStart ), QLineEdit::ActionPosition::TrailingPosition ); + QObject::connect( button, &QAction::triggered, [line](){ + if ( const char* filename = GlobalRadiant().m_pfnFileDialog( g_pRadiantWnd, true, "Locate portal (.prt) file", line->text().toLatin1().constData(), 0, true, false, false ) ) + line->setText( filename ); + } ); + } + { + vbox->addWidget( check3d = new QCheckBox( "Show 3D" ) ); + vbox->addWidget( check2d = new QCheckBox( "Show 2D" ) ); + } + { + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel ); + vbox->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept ); + QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject ); + } } -} -int DoLoadPortalFileDialog(){ - GtkWidget *dlg, *vbox, *hbox, *button, *entry, *check2d, *check3d; - int loop = 1, ret = IDCANCEL; - - dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - gtk_window_set_transient_for( GTK_WINDOW( dlg ), GTK_WINDOW( g_pRadiantWnd ) ); - gtk_window_set_position( GTK_WINDOW( dlg ),GTK_WIN_POS_CENTER_ON_PARENT ); - gtk_window_set_modal( GTK_WINDOW( dlg ), TRUE ); - gtk_window_set_title( GTK_WINDOW( dlg ), "Load .prt" ); - g_signal_connect( G_OBJECT( dlg ), "delete_event", - G_CALLBACK( dialog_delete_callback ), NULL ); - g_signal_connect( G_OBJECT( dlg ), "destroy", - G_CALLBACK( gtk_widget_destroy ), NULL ); - g_object_set_data( G_OBJECT( dlg ), "loop", &loop ); - g_object_set_data( G_OBJECT( dlg ), "ret", &ret ); - - vbox = gtk_vbox_new( FALSE, 5 ); - gtk_widget_show( vbox ); - gtk_container_add( GTK_CONTAINER( dlg ), vbox ); - gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 ); - - entry = gtk_entry_new(); - gtk_widget_show( entry ); -// gtk_editable_set_editable( GTK_EDITABLE( entry ), FALSE ); - gtk_box_pack_start( GTK_BOX( vbox ), entry, FALSE, FALSE, 0 ); - - hbox = gtk_hbox_new( FALSE, 5 ); - gtk_widget_show( hbox ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - - check3d = gtk_check_button_new_with_label( "Show 3D" ); - gtk_widget_show( check3d ); - gtk_box_pack_start( GTK_BOX( hbox ), check3d, FALSE, FALSE, 0 ); - - check2d = gtk_check_button_new_with_label( "Show 2D" ); - gtk_widget_show( check2d ); - gtk_box_pack_start( GTK_BOX( hbox ), check2d, FALSE, FALSE, 0 ); - - button = gtk_button_new_with_label( "Change" ); - gtk_widget_show( button ); - gtk_box_pack_end( GTK_BOX( hbox ), button, FALSE, FALSE, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( change_clicked ), entry ); - gtk_widget_set_size_request( button, 60, -1 ); - - hbox = gtk_hbox_new( FALSE, 5 ); - gtk_widget_show( hbox ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 ); - - button = gtk_button_new_with_label( "Cancel" ); - gtk_widget_show( button ); - gtk_box_pack_end( GTK_BOX( hbox ), button, FALSE, FALSE, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDCANCEL ) ); - gtk_widget_set_size_request( button, 60, -1 ); - - button = gtk_button_new_with_label( "OK" ); - gtk_widget_show( button ); - gtk_box_pack_end( GTK_BOX( hbox ), button, FALSE, FALSE, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( IDOK ) ); - gtk_widget_set_size_request( button, 60, -1 ); strcpy( portals.fn, GlobalRadiant().getMapName() ); char* fn = strrchr( portals.fn, '.' ); @@ -129,27 +77,19 @@ int DoLoadPortalFileDialog(){ strcpy( fn, ".prt" ); } - StringOutputStream value( 256 ); - value << portals.fn; - gtk_entry_set_text( GTK_ENTRY( entry ), value.c_str() ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( check2d ), portals.show_2d ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( check3d ), portals.show_3d ); + line->setText( portals.fn ); + check3d->setChecked( portals.show_3d ); + check2d->setChecked( portals.show_2d ); - gtk_widget_show( dlg ); - - while ( loop ) - gtk_main_iteration(); - - if ( ret == IDOK ) { - strcpy( portals.fn, gtk_entry_get_text( GTK_ENTRY( entry ) ) ); + if ( dialog.exec() ) { + strcpy( portals.fn, line->text().toLatin1().constData() ); portals.Purge(); - portals.show_3d = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( check3d ) ) ? true : false; - portals.show_2d = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( check2d ) ) ? true : false; + portals.show_3d = check3d->isChecked(); + portals.show_2d = check2d->isChecked(); + return true; } - gtk_widget_destroy( dlg ); - - return ret; + return false; } diff --git a/contrib/prtview/LoadPortalFileDialog.h b/contrib/prtview/LoadPortalFileDialog.h index 188ad4d0..49108c0e 100644 --- a/contrib/prtview/LoadPortalFileDialog.h +++ b/contrib/prtview/LoadPortalFileDialog.h @@ -19,4 +19,4 @@ #pragma once -int DoLoadPortalFileDialog(); +bool DoLoadPortalFileDialog(); diff --git a/contrib/prtview/portals.cpp b/contrib/prtview/portals.cpp index 8f61f241..7a5e41ab 100644 --- a/contrib/prtview/portals.cpp +++ b/contrib/prtview/portals.cpp @@ -35,31 +35,16 @@ CPortals portals; CPortalsRender render; -int compare( const void *arg1, const void *arg2 ){ - - if ( portals.portal[*( (const int *)arg1 )].dist > portals.portal[*( (const int *)arg2 )].dist ) { - return -1; - } - else if ( portals.portal[*( (const int *)arg1 )].dist < portals.portal[*( (const int *)arg2 )].dist ) { - return 1; - } - - return 0; -} - CBspPortal::CBspPortal(){ - memset( this, 0, sizeof( CBspPortal ) ); } CBspPortal::~CBspPortal(){ - delete[] point; - delete[] inner_point; } bool CBspPortal::Build( char *def ){ char *c = def; - unsigned int n; + unsigned int point_count; int dummy1, dummy2; int res_cnt = 0; @@ -76,10 +61,10 @@ bool CBspPortal::Build( char *def ){ return false; } - point = new CBspPoint[point_count]; - inner_point = new CBspPoint[point_count]; + point.resize( point_count ); + inner_point.reserve( point_count ); - for ( n = 0; n < point_count; n++ ) + for ( auto& p : point ) { for (; *c != 0 && *c != '('; c++ ){}; @@ -89,66 +74,47 @@ bool CBspPortal::Build( char *def ){ c++; - sscanf( c, "%f %f %f", point[n].p, point[n].p + 1, point[n].p + 2 ); + sscanf( c, "%f %f %f", &p.x(), &p.y(), &p.z() ); - center.p[0] += point[n].p[0]; - center.p[1] += point[n].p[1]; - center.p[2] += point[n].p[2]; + center += p; - if ( n == 0 ) { - for ( int i = 0; i < 3; i++ ) - { - min[i] = point[n].p[i]; - max[i] = point[n].p[i]; - } + if ( &p == &point.front() ) { + min = p; + max = p; } else { - for ( int i = 0; i < 3; i++ ) + for ( size_t i = 0; i < 3; ++i ) { - if ( min[i] > point[n].p[i] ) { - min[i] = point[n].p[i]; - } - if ( max[i] < point[n].p[i] ) { - max[i] = point[n].p[i]; - } + min[i] = std::min( min[i], p[i] ); + max[i] = std::max( max[i], p[i] ); } } } - center.p[0] /= (float)point_count; - center.p[1] /= (float)point_count; - center.p[2] /= (float)point_count; + center /= point.size(); - for ( n = 0; n < point_count; n++ ) + for ( const auto& p : point ) { - inner_point[n].p[0] = ( 0.01f * center.p[0] ) + ( 0.99f * point[n].p[0] ); - inner_point[n].p[1] = ( 0.01f * center.p[1] ) + ( 0.99f * point[n].p[1] ); - inner_point[n].p[2] = ( 0.01f * center.p[2] ) + ( 0.99f * point[n].p[2] ); + inner_point.push_back( ( center * 0.01f ) + ( p * 0.99f ) ); } - fp_color_random[0] = (float)( rand() & 0xff ) / 255.0f; - fp_color_random[1] = (float)( rand() & 0xff ) / 255.0f; - fp_color_random[2] = (float)( rand() & 0xff ) / 255.0f; + fp_color_random[0] = ( rand() & 0xff ) / 255.0f; + fp_color_random[1] = ( rand() & 0xff ) / 255.0f; + fp_color_random[2] = ( rand() & 0xff ) / 255.0f; fp_color_random[3] = 1.0f; return true; } CPortals::CPortals(){ - memset( this, 0, sizeof( CPortals ) ); } CPortals::~CPortals(){ - Purge(); } void CPortals::Purge(){ - delete[] portal; - delete[] portal_sort; - portal = NULL; - portal_sort = NULL; - portal_count = 0; + portal.clear(); /* delete[] node; @@ -159,6 +125,7 @@ void CPortals::Purge(){ void CPortals::Load(){ char buf[LINE_BUF + 1]; + unsigned int portal_count, node_count; memset( buf, 0, LINE_BUF + 1 ); @@ -179,7 +146,6 @@ void CPortals::Load(){ #define GETLINE \ if ( !fgets( buf, LINE_BUF, in ) ) { \ fclose( in ); \ - node_count = 0; \ globalErrorStream() << " ERROR - File ended prematurely.\n"; \ return; \ } @@ -239,7 +205,7 @@ void CPortals::Load(){ { fclose(in); - node_count = 0; + Purge(); globalErrorStream() << " ERROR - Extreme number of nodes, aborting.\n"; @@ -250,9 +216,6 @@ void CPortals::Load(){ if ( portal_count > 0xFFFF ) { fclose( in ); - portal_count = 0; - node_count = 0; - globalErrorStream() << " ERROR - Extreme number of portals, aborting.\n"; return; @@ -261,24 +224,19 @@ void CPortals::Load(){ if ( portal_count == 0 ) { fclose( in ); - portal_count = 0; - node_count = 0; - globalErrorStream() << " ERROR - number of portals equals 0, aborting.\n"; return; } // node = new CBspNode[node_count]; - portal = new CBspPortal[portal_count]; - portal_sort = new int[portal_count]; + portal.resize( portal_count ); - unsigned int n; unsigned test_vals_1, test_vals_2; hint_flags = false; - for ( n = 0; n < portal_count; ) + for ( unsigned int n = 0; n < portal_count; ) { if ( !fgets( buf, LINE_BUF, in ) ) { fclose( in ); @@ -306,7 +264,7 @@ void CPortals::Load(){ return; } - n++; + ++n; } fclose( in ); @@ -328,23 +286,17 @@ void Portals_constructShaders(){ GlobalOpenGLStateLibrary().getDefaultState( state ); state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE; state.m_sort = OpenGLState::eSortOverlayFirst; - state.m_linewidth = portals.width_2d * 0.5f; + state.m_linewidth = portals.width_2d; state.m_colour[0] = portals.fp_color_2d[0]; state.m_colour[1] = portals.fp_color_2d[1]; state.m_colour[2] = portals.fp_color_2d[2]; state.m_colour[3] = portals.fp_color_2d[3]; - if ( portals.aa_2d ) { - state.m_state |= RENDER_BLEND | RENDER_LINESMOOTH; - } + GlobalOpenGLStateLibrary().insert( g_state_wireframe, state ); GlobalOpenGLStateLibrary().getDefaultState( state ); state.m_state = RENDER_FILL | RENDER_BLEND | RENDER_COLOURWRITE | RENDER_COLOURCHANGE | RENDER_SMOOTH; - if ( portals.aa_3d ) { - state.m_state |= RENDER_POLYGONSMOOTH; - } - switch ( portals.zbuffer ) { case 1: @@ -376,16 +328,12 @@ void Portals_constructShaders(){ GlobalOpenGLStateLibrary().getDefaultState( state ); state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE; state.m_sort = OpenGLState::eSortOverlayFirst; - state.m_linewidth = portals.width_3d * 0.5f; + state.m_linewidth = portals.width_3d; state.m_colour[0] = portals.fp_color_3d[0]; state.m_colour[1] = portals.fp_color_3d[1]; state.m_colour[2] = portals.fp_color_3d[2]; state.m_colour[3] = portals.fp_color_3d[3]; - if ( portals.aa_3d ) { - state.m_state |= RENDER_LINESMOOTH; - } - switch ( portals.zbuffer ) { case 1: @@ -435,24 +383,24 @@ void Portals_shadersChanged(){ } void CPortals::FixColors(){ - fp_color_2d[0] = (float)GetRValue( color_2d ) / 255.0f; - fp_color_2d[1] = (float)GetGValue( color_2d ) / 255.0f; - fp_color_2d[2] = (float)GetBValue( color_2d ) / 255.0f; + fp_color_2d[0] = RGB_UNPACK_R( color_2d ) / 255.0f; + fp_color_2d[1] = RGB_UNPACK_G( color_2d ) / 255.0f; + fp_color_2d[2] = RGB_UNPACK_B( color_2d ) / 255.0f; fp_color_2d[3] = 1.0f; - fp_color_3d[0] = (float)GetRValue( color_3d ) / 255.0f; - fp_color_3d[1] = (float)GetGValue( color_3d ) / 255.0f; - fp_color_3d[2] = (float)GetBValue( color_3d ) / 255.0f; + fp_color_3d[0] = RGB_UNPACK_R( color_3d ) / 255.0f; + fp_color_3d[1] = RGB_UNPACK_G( color_3d ) / 255.0f; + fp_color_3d[2] = RGB_UNPACK_B( color_3d ) / 255.0f; fp_color_3d[3] = 1.0f; - fp_color_fog[0] = 0.0f; //(float)GetRValue(color_fog) / 255.0f; - fp_color_fog[1] = 0.0f; //(float)GetGValue(color_fog) / 255.0f; - fp_color_fog[2] = 0.0f; //(float)GetBValue(color_fog) / 255.0f; + fp_color_fog[0] = RGB_UNPACK_R( color_fog ) / 255.0f; + fp_color_fog[1] = RGB_UNPACK_G( color_fog ) / 255.0f; + fp_color_fog[2] = RGB_UNPACK_B( color_fog ) / 255.0f; fp_color_fog[3] = 1.0f; } void CPortalsRender::renderWireframe( Renderer& renderer, const VolumeTest& volume ) const { - if ( !portals.show_2d || portals.portal_count < 1 ) { + if ( !portals.show_2d || portals.portal.empty() ) { return; } @@ -462,16 +410,14 @@ void CPortalsRender::renderWireframe( Renderer& renderer, const VolumeTest& volu } void CPortalsDrawWireframe::render( RenderStateFlags state ) const { - unsigned int n, p; - - for ( n = 0; n < portals.portal_count; n++ ) + for ( const auto& prt : portals.portal ) { - glBegin( GL_LINE_LOOP ); + gl().glBegin( GL_LINE_LOOP ); - for ( p = 0; p < portals.portal[n].point_count; p++ ) - glVertex3fv( portals.portal[n].point[p].p ); + for ( const auto& p : prt.point ) + gl().glVertex3fv( p.data() ); - glEnd(); + gl().glEnd(); } } @@ -483,17 +429,13 @@ CubicClipVolume calculateCubicClipVolume( const Matrix4& viewproj ){ Vector4( 0, 0, -1, 1 ) ) ); - clip.min[0] = clip.cam[0] + ( portals.clip_range * 64.0f ); - clip.min[1] = clip.cam[1] + ( portals.clip_range * 64.0f ); - clip.min[2] = clip.cam[2] + ( portals.clip_range * 64.0f ); - clip.max[0] = clip.cam[0] - ( portals.clip_range * 64.0f ); - clip.max[1] = clip.cam[1] - ( portals.clip_range * 64.0f ); - clip.max[2] = clip.cam[2] - ( portals.clip_range * 64.0f ); + clip.min = clip.cam + Vector3( portals.clip_range ); + clip.max = clip.cam - Vector3( portals.clip_range ); return clip; } void CPortalsRender::renderSolid( Renderer& renderer, const VolumeTest& volume ) const { - if ( !portals.show_3d || portals.portal_count < 1 ) { + if ( !portals.show_3d || portals.portal.empty() ) { return; } @@ -517,142 +459,100 @@ void CPortalsRender::renderSolid( Renderer& renderer, const VolumeTest& volume ) } void CPortalsDrawSolid::render( RenderStateFlags state ) const { - float trans = ( 100.0f - portals.trans_3d ) / 100.0f; - - unsigned int n, p; + const float opacity = portals.opacity_3d / 100.0f; if ( portals.zbuffer != 0 ) { - float d; - - for ( n = 0; n < portals.portal_count; n++ ) + portals.portal_sort.clear(); + portals.portal_sort.reserve( portals.portal.size() ); + for ( auto& prt : portals.portal ) { - d = (float)clip.cam[0] - portals.portal[n].center.p[0]; - portals.portal[n].dist = d * d; + prt.dist = vector3_length_squared( clip.cam - prt.center ); - d = (float)clip.cam[1] - portals.portal[n].center.p[1]; - portals.portal[n].dist += d * d; - - d = (float)clip.cam[2] - portals.portal[n].center.p[2]; - portals.portal[n].dist += d * d; - - portals.portal_sort[n] = n; + portals.portal_sort.push_back( &prt ); } - qsort( portals.portal_sort, portals.portal_count, 4, compare ); + std::sort( portals.portal_sort.begin(), portals.portal_sort.end(), []( const CBspPortal *a, const CBspPortal *b ){ + return a->dist < b->dist; + } ); - for ( n = 0; n < portals.portal_count; n++ ) + for ( const auto prt : portals.portal_sort ) { - if ( portals.polygons == 2 && !portals.portal[portals.portal_sort[n]].hint ) { - continue; + if( ( !prt->hint && portals.draw_nonhints ) + || ( prt->hint && portals.draw_hints ) ) + { + if ( portals.clip ) { + if ( clip.min[0] < prt->min[0] + || clip.min[1] < prt->min[1] + || clip.min[2] < prt->min[2] + || clip.max[0] > prt->max[0] + || clip.max[1] > prt->max[1] + || clip.max[2] > prt->max[2] + ) continue; + } + + gl().glColor4f( prt->fp_color_random[0], prt->fp_color_random[1], prt->fp_color_random[2], opacity ); + + gl().glBegin( GL_POLYGON ); + + for ( const auto& p : prt->point ) + gl().glVertex3fv( p.data() ); + + gl().glEnd(); } - - if ( portals.clip ) { - if ( clip.min[0] < portals.portal[portals.portal_sort[n]].min[0] ) { - continue; - } - else if ( clip.min[1] < portals.portal[portals.portal_sort[n]].min[1] ) { - continue; - } - else if ( clip.min[2] < portals.portal[portals.portal_sort[n]].min[2] ) { - continue; - } - else if ( clip.max[0] > portals.portal[portals.portal_sort[n]].max[0] ) { - continue; - } - else if ( clip.max[1] > portals.portal[portals.portal_sort[n]].max[1] ) { - continue; - } - else if ( clip.max[2] > portals.portal[portals.portal_sort[n]].max[2] ) { - continue; - } - } - - glColor4f( portals.portal[portals.portal_sort[n]].fp_color_random[0], portals.portal[portals.portal_sort[n]].fp_color_random[1], - portals.portal[portals.portal_sort[n]].fp_color_random[2], trans ); - - glBegin( GL_POLYGON ); - - for ( p = 0; p < portals.portal[portals.portal_sort[n]].point_count; p++ ) - glVertex3fv( portals.portal[portals.portal_sort[n]].point[p].p ); - - glEnd(); } } else { - for ( n = 0; n < portals.portal_count; n++ ) + for ( const auto& prt : portals.portal ) { - if ( portals.polygons == 2 && !portals.portal[n].hint ) { - continue; + if( ( !prt.hint && portals.draw_nonhints ) + || ( prt.hint && portals.draw_hints ) ) + { + if ( portals.clip ) { + if ( clip.min[0] < prt.min[0] + || clip.min[1] < prt.min[1] + || clip.min[2] < prt.min[2] + || clip.max[0] > prt.max[0] + || clip.max[1] > prt.max[1] + || clip.max[2] > prt.max[2] + ) continue; + } + + gl().glColor4f( prt.fp_color_random[0], prt.fp_color_random[1], prt.fp_color_random[2], opacity ); + + gl().glBegin( GL_POLYGON ); + + for ( const auto& p : prt.point ) + gl().glVertex3fv( p.data() ); + + gl().glEnd(); } - - if ( portals.clip ) { - if ( clip.min[0] < portals.portal[n].min[0] ) { - continue; - } - else if ( clip.min[1] < portals.portal[n].min[1] ) { - continue; - } - else if ( clip.min[2] < portals.portal[n].min[2] ) { - continue; - } - else if ( clip.max[0] > portals.portal[n].max[0] ) { - continue; - } - else if ( clip.max[1] > portals.portal[n].max[1] ) { - continue; - } - else if ( clip.max[2] > portals.portal[n].max[2] ) { - continue; - } - } - - glColor4f( portals.portal[n].fp_color_random[0], portals.portal[n].fp_color_random[1], - portals.portal[n].fp_color_random[2], trans ); - - glBegin( GL_POLYGON ); - - for ( p = 0; p < portals.portal[n].point_count; p++ ) - glVertex3fv( portals.portal[n].point[p].p ); - - glEnd(); } } } void CPortalsDrawSolidOutline::render( RenderStateFlags state ) const { - for ( unsigned int n = 0; n < portals.portal_count; n++ ) + for ( const auto& prt : portals.portal ) { - if ( portals.lines == 2 && !portals.portal[n].hint ) { - continue; + if( ( !prt.hint && portals.draw_nonhints ) + || ( prt.hint && portals.draw_hints ) ) + { + if ( portals.clip ) { + if ( clip.min[0] < prt.min[0] + || clip.min[1] < prt.min[1] + || clip.min[2] < prt.min[2] + || clip.max[0] > prt.max[0] + || clip.max[1] > prt.max[1] + || clip.max[2] > prt.max[2] + ) continue; + } + + gl().glBegin( GL_LINE_LOOP ); + + for ( const auto& p : prt.inner_point ) + gl().glVertex3fv( p.data() ); + + gl().glEnd(); } - - if ( portals.clip ) { - if ( clip.min[0] < portals.portal[n].min[0] ) { - continue; - } - else if ( clip.min[1] < portals.portal[n].min[1] ) { - continue; - } - else if ( clip.min[2] < portals.portal[n].min[2] ) { - continue; - } - else if ( clip.max[0] > portals.portal[n].max[0] ) { - continue; - } - else if ( clip.max[1] > portals.portal[n].max[1] ) { - continue; - } - else if ( clip.max[2] > portals.portal[n].max[2] ) { - continue; - } - } - - glBegin( GL_LINE_LOOP ); - - for ( unsigned int p = 0; p < portals.portal[n].point_count; p++ ) - glVertex3fv( portals.portal[n].inner_point[p].p ); - - glEnd(); } } diff --git a/contrib/prtview/portals.h b/contrib/prtview/portals.h index ae54fd1c..6770f8ae 100644 --- a/contrib/prtview/portals.h +++ b/contrib/prtview/portals.h @@ -19,17 +19,12 @@ #pragma once -#include #include "irender.h" #include "renderable.h" #include "math/vector.h" +#include -class CBspPoint { -public: - float p[3]; -}; - class CBspPortal { public: CBspPortal(); @@ -38,13 +33,12 @@ public: protected: public: - CBspPoint center; - unsigned point_count; - CBspPoint *point; - CBspPoint *inner_point; + Vector3 center{ 0 }; + std::vector point; + std::vector inner_point; float fp_color_random[4]; - float min[3]; - float max[3]; + Vector3 min; + Vector3 max; float dist; bool hint; @@ -56,11 +50,12 @@ public: #else #define PRTVIEW_PATH_MAX 260 #endif -typedef guint32 PackedColour; -#define RGB( r, g, b ) ( (guint32)( ( (guint8) ( r ) | ( (guint16) ( g ) << 8 ) ) | ( ( (guint32) (guint8) ( b ) ) << 16 ) ) ) -#define GetRValue( rgb ) ( (guint8)( rgb ) ) -#define GetGValue( rgb ) ( (guint8)( ( (guint16)( rgb ) ) >> 8 ) ) -#define GetBValue( rgb ) ( (guint8)( ( rgb ) >> 16 ) ) + +using PackedColour = std::uint32_t; +#define RGB_PACK( r, g, b ) ( (std::uint32_t)( ( (std::uint8_t)( r ) | ( (std::uint16_t)( (std::uint8_t)( g ) ) << 8 ) ) | ( ( (std::uint32_t)(std::uint8_t)( b ) ) << 16 ) ) ) +#define RGB_UNPACK_R( rgb ) ( (std::uint8_t)( rgb ) ) +#define RGB_UNPACK_G( rgb ) ( (std::uint8_t)( ( (std::uint16_t)( rgb ) ) >> 8 ) ) +#define RGB_UNPACK_B( rgb ) ( (std::uint8_t)( ( rgb ) >> 16 ) ) class CPortals { @@ -83,33 +78,31 @@ public: char fn[PRTVIEW_PATH_MAX]; int zbuffer; - int polygons; - int lines; + bool polygons; + bool lines; bool show_3d; - bool aa_3d; bool fog; PackedColour color_3d; - float width_3d; // in 8'ths + int width_3d; float fp_color_3d[4]; PackedColour color_fog; float fp_color_fog[4]; - float trans_3d; - float clip_range; + int opacity_3d; + int clip_range; bool clip; + bool draw_hints; + bool draw_nonhints; + bool show_2d; - bool aa_2d; PackedColour color_2d; - float width_2d; // in 8'ths + int width_2d; float fp_color_2d[4]; - CBspPortal *portal; - int *portal_sort; + std::vector portal; + std::vector portal_sort; bool hint_flags; // CBspNode *node; - - unsigned int node_count; - unsigned int portal_count; }; class CubicClipVolume diff --git a/contrib/prtview/prtview.cpp b/contrib/prtview/prtview.cpp index 2d93fd9a..20f93865 100644 --- a/contrib/prtview/prtview.cpp +++ b/contrib/prtview/prtview.cpp @@ -50,19 +50,20 @@ CopiedString INIfn; const char RENDER_2D[] = "Render2D"; const char WIDTH_2D[] = "Width2D"; -const char AA_2D[] = "AntiAlias2D"; const char COLOR_2D[] = "Color2D"; +const char DRAW_HINTS[] = "DrawHints"; +const char DRAW_NONHINTS[] = "DrawNonHints"; + const char RENDER_3D[] = "Render3D"; const char WIDTH_3D[] = "Width3D"; -const char AA_3D[] = "AntiAlias3D"; const char COLOR_3D[] = "Color3D"; const char COLOR_FOG[] = "ColorFog"; const char FOG[] = "Fog"; const char ZBUFFER[] = "ZBuffer"; const char POLYGON[] = "Polygons"; const char LINE[] = "Lines"; -const char TRANS_3D[] = "Transparency"; +const char OPACITY_3D[] = "Opacity"; const char CLIP_RANGE[] = "ClipRange"; const char CLIP[] = "Clip"; @@ -72,59 +73,29 @@ void PrtView_construct(){ tmp << GlobalRadiant().getSettingsPath() << "prtview.ini"; INIfn = tmp.c_str(); - portals.show_2d = INIGetInt( RENDER_2D, FALSE ) ? true : false; - portals.aa_2d = INIGetInt( AA_2D, FALSE ) ? true : false; - portals.width_2d = (float)INIGetInt( WIDTH_2D, 10 ); - portals.color_2d = (PackedColour)INIGetInt( COLOR_2D, RGB( 0, 0, 255 ) ) & 0xFFFFFF; + portals.show_2d = INIGetInt( RENDER_2D, 0 ); + portals.width_2d = std::clamp( INIGetInt( WIDTH_2D, 3 ), 1, 10 ); + portals.color_2d = INIGetInt( COLOR_2D, RGB_PACK( 0, 0, 255 ) ) & 0xFFFFFF; - if ( portals.width_2d > 40.0f ) { - portals.width_2d = 40.0f; - } - else if ( portals.width_2d < 2.0f ) { - portals.width_2d = 2.0f; - } + portals.draw_hints = INIGetInt( DRAW_HINTS, 1 ); + portals.draw_nonhints = INIGetInt( DRAW_NONHINTS, 1 ); - portals.show_3d = INIGetInt( RENDER_3D, TRUE ) ? true : false; + portals.show_3d = INIGetInt( RENDER_3D, 1 ); portals.zbuffer = INIGetInt( ZBUFFER, 1 ); - portals.fog = INIGetInt( FOG, FALSE ) ? true : false; - portals.polygons = INIGetInt( POLYGON, TRUE ); - portals.lines = INIGetInt( LINE, TRUE ); - portals.aa_3d = INIGetInt( AA_3D, FALSE ) ? true : false; - portals.width_3d = (float)INIGetInt( WIDTH_3D, 4 ); - portals.color_3d = (PackedColour)INIGetInt( COLOR_3D, RGB( 255, 255, 0 ) ) & 0xFFFFFF; - portals.color_fog = (PackedColour)INIGetInt( COLOR_FOG, RGB( 127, 127, 127 ) ) & 0xFFFFFF; - portals.trans_3d = (float)INIGetInt( TRANS_3D, 50 ); - portals.clip = INIGetInt( CLIP, FALSE ) ? true : false; - portals.clip_range = (float)INIGetInt( CLIP_RANGE, 16 ); + portals.fog = INIGetInt( FOG, 0 ); + portals.polygons = INIGetInt( POLYGON, 1 ); + portals.lines = INIGetInt( LINE, 1 ); + portals.width_3d = std::clamp( INIGetInt( WIDTH_3D, 3 ), 1, 10 ); + portals.color_3d = INIGetInt( COLOR_3D, RGB_PACK( 255, 255, 0 ) ) & 0xFFFFFF; + portals.color_fog = INIGetInt( COLOR_FOG, RGB_PACK( 127, 127, 127 ) ) & 0xFFFFFF; + portals.opacity_3d = std::clamp( INIGetInt( OPACITY_3D, 50 ), 0, 100 ); + portals.clip = INIGetInt( CLIP, 0 ); + portals.clip_range = std::clamp( INIGetInt( CLIP_RANGE, 1024 ), 64, 8192 ); - if ( portals.clip_range < 1 ) { - portals.clip_range = 1; - } - else if ( portals.clip_range > 128 ) { - portals.clip_range = 128; - } - - if ( portals.zbuffer < 0 ) { + if ( portals.zbuffer < 0 || portals.zbuffer > 2 ) portals.zbuffer = 0; - } - else if ( portals.zbuffer > 2 ) { - portals.zbuffer = 0; - } - if ( portals.width_3d > 40.0f ) { - portals.width_3d = 40.0f; - } - else if ( portals.width_3d < 2.0f ) { - portals.width_3d = 2.0f; - } - - if ( portals.trans_3d > 100.0f ) { - portals.trans_3d = 100.0f; - } - else if ( portals.trans_3d < 0.0f ) { - portals.trans_3d = 0.0f; - } SaveConfig(); @@ -141,22 +112,20 @@ void PrtView_destroy(){ void SaveConfig(){ INISetInt( RENDER_2D, portals.show_2d, "Draw in 2D windows" ); - INISetInt( WIDTH_2D, (int)portals.width_2d, "Width of lines in 2D windows (in units of 1/2)" ); - INISetInt( COLOR_2D, (int)portals.color_2d, "Color of lines in 2D windows" ); - INISetInt( AA_2D, portals.aa_2d, "Draw lines in 2D window anti-aliased" ); + INISetInt( WIDTH_2D, portals.width_2d, "Width of lines in 2D windows" ); + INISetInt( COLOR_2D, portals.color_2d, "Color of lines in 2D windows" ); INISetInt( ZBUFFER, portals.zbuffer, "ZBuffer level in 3D window" ); INISetInt( FOG, portals.fog, "Use depth cueing in 3D window" ); - INISetInt( POLYGON, portals.polygons, "Render using polygons polygons in 3D window" ); - INISetInt( LINE, portals.polygons, "Render using lines in 3D window" ); + INISetInt( POLYGON, portals.polygons, "Render using polygons in 3D window" ); + INISetInt( LINE, portals.lines, "Render using lines in 3D window" ); INISetInt( RENDER_3D, portals.show_3d, "Draw in 3D windows" ); - INISetInt( WIDTH_3D, (int)portals.width_3d, "Width of lines in 3D window (in units of 1/2)" ); - INISetInt( COLOR_3D, (int)portals.color_3d, "Color of lines/polygons in 3D window" ); - INISetInt( COLOR_FOG, (int)portals.color_fog, "Color of distant lines/polygons in 3D window" ); - INISetInt( AA_3D, portals.aa_3d, "Draw lines in 3D window anti-aliased" ); - INISetInt( TRANS_3D, (int)portals.trans_3d, "Transparency in 3d view (0 = solid, 100 = invisible)" ); + INISetInt( WIDTH_3D, portals.width_3d, "Width of lines in 3D window" ); + INISetInt( COLOR_3D, portals.color_3d, "Color of lines/polygons in 3D window" ); + INISetInt( COLOR_FOG, portals.color_fog, "Color of distant lines/polygons in 3D window" ); + INISetInt( OPACITY_3D, portals.opacity_3d, "Opacity in 3d view (0 = invisible, 100 = solid)" ); INISetInt( CLIP, portals.clip, "Cubic clipper active for portal viewer" ); - INISetInt( CLIP_RANGE, (int)portals.clip_range, "Portal viewer cubic clip distance (in units of 64)" ); + INISetInt( CLIP_RANGE, portals.clip_range, "Portal viewer cubic clip distance (in units of 64)" ); } @@ -201,10 +170,10 @@ static const char *PLUGIN_COMMANDS = Q3R_CMD_LOAD; -GtkWidget *g_pRadiantWnd = NULL; +QWidget *g_pRadiantWnd = NULL; const char* QERPlug_Init( void *hApp, void* pMainWidget ){ - g_pRadiantWnd = (GtkWidget*)pMainWidget; + g_pRadiantWnd = static_cast( pMainWidget ); return "Portal Viewer for Q3Radiant"; } @@ -229,7 +198,7 @@ void QERPlug_Dispatch( const char* p, float* vMin, float* vMax, bool bSingleBrus DoAboutDlg(); } else if ( !strcmp( p,Q3R_CMD_LOAD ) ) { - if ( DoLoadPortalFileDialog() == IDOK ) { + if ( DoLoadPortalFileDialog() ) { portals.Load(); SceneChangeNotify(); } diff --git a/contrib/prtview/prtview.h b/contrib/prtview/prtview.h index 96255deb..c7a55dd9 100644 --- a/contrib/prtview/prtview.h +++ b/contrib/prtview/prtview.h @@ -27,8 +27,4 @@ void SaveConfig(); int INIGetInt( const char *key, int def ); void INISetInt( const char *key, int val, const char *comment = 0 ); -typedef struct _GtkWidget GtkWidget; -extern GtkWidget *g_pRadiantWnd; - -#define IDOK 1 -#define IDCANCEL 2 +extern class QWidget *g_pRadiantWnd; diff --git a/contrib/shaderplug/shaderplug.cpp b/contrib/shaderplug/shaderplug.cpp index eb8a7b0a..3ca7849b 100644 --- a/contrib/shaderplug/shaderplug.cpp +++ b/contrib/shaderplug/shaderplug.cpp @@ -30,8 +30,6 @@ #include "stream/stringstream.h" #include "os/file.h" -#include - #include "iplugin.h" #include "qerplugin.h" #include "ifilesystem.h" @@ -41,9 +39,6 @@ #include "generic/callback.h" -namespace { -const char SHADERTAG_FILE[] = "shadertags.xml"; -} class ShaderPlugPluginDependencies : public GlobalRadiantModuleRef, public GlobalFileSystemModuleRef, @@ -57,7 +52,7 @@ public: namespace Shaderplug { -GtkWindow* g_window; +QWidget* g_window; std::vector archives; std::set shaders; @@ -67,7 +62,7 @@ XmlTagBuilder TagBuilder; void CreateTagFile(); const char* init( void* hApp, void* pMainWidget ){ - g_window = GTK_WINDOW( pMainWidget ); + g_window = static_cast( pMainWidget ); return ""; } const char* getName(){ @@ -81,12 +76,12 @@ const char* getCommandTitleList(){ } void dispatch( const char* command, float* vMin, float* vMax, bool bSingleBrush ){ if ( string_equal( command, "About" ) ) { - GlobalRadiant().m_pfnMessageBox( GTK_WIDGET( g_window ), - "Shaderplug (1.0)\n\n" - "by Shaderman (shaderman@gmx.net)", + GlobalRadiant().m_pfnMessageBox( g_window, + "Shaderplug (1.0)

" + "by Shaderman (shaderman@gmx.net)", "About", - eMB_OK, - eMB_ICONDEFAULT ); + EMessageBoxType::Info, + 0 ); } if ( string_equal( command, "Create tag file" ) ) { CreateTagFile(); @@ -137,21 +132,21 @@ void GetAllShaders(){ void GetArchiveList(){ GlobalFileSystem().forEachArchive( LoadArchiveFileCaller() ); - globalOutputStream() << "Shaderplug: " << (Unsigned)Shaderplug::archives.size() << " archives found.\n"; + globalOutputStream() << "Shaderplug: " << Shaderplug::archives.size() << " archives found.\n"; } void CreateTagFile(){ const char* shader_type = GlobalRadiant().getGameDescriptionKeyValue( "shaders" ); GetAllShaders(); - globalOutputStream() << "Shaderplug: " << (Unsigned)shaders.size() << " shaders found.\n"; + globalOutputStream() << "Shaderplug: " << shaders.size() << " shaders found.\n"; if ( string_equal( shader_type, "quake3" ) ) { GetTextures( "jpg" ); GetTextures( "tga" ); GetTextures( "png" ); - globalOutputStream() << "Shaderplug: " << (Unsigned)textures.size() << " textures found.\n"; + globalOutputStream() << "Shaderplug: " << textures.size() << " textures found.\n"; } if ( shaders.size() || textures.size() != 0 ) { @@ -159,51 +154,41 @@ void CreateTagFile(){ TagBuilder.CreateXmlDocument(); - std::set::reverse_iterator r_iter; - - for ( r_iter = textures.rbegin(); r_iter != textures.rend(); ++r_iter ) + for ( auto r_iter = textures.crbegin(); r_iter != textures.crend(); ++r_iter ) { - TagBuilder.AddShaderNode( const_cast( ( *r_iter ).c_str() ), STOCK, TEXTURE ); + TagBuilder.AddShaderNode( r_iter->c_str(), TextureType::STOCK, NodeShaderType::TEXTURE ); } - for ( r_iter = shaders.rbegin(); r_iter != shaders.rend(); ++r_iter ) + for ( auto r_iter = shaders.crbegin(); r_iter != shaders.crend(); ++r_iter ) { - TagBuilder.AddShaderNode( const_cast( ( *r_iter ).c_str() ), STOCK, SHADER ); + TagBuilder.AddShaderNode( r_iter->c_str(), TextureType::STOCK, NodeShaderType::SHADER ); } // Get the tag file - StringOutputStream tagFileStream( 256 ); - tagFileStream << GlobalRadiant().getLocalRcPath() << SHADERTAG_FILE; - char* tagFile = tagFileStream.c_str(); - - char message[256]; - strcpy( message, "Tag file saved to\n" ); - strcat( message, tagFile ); - strcat( message, "\nPlease restart Radiant now.\n" ); + const auto tagFile = StringOutputStream( 256 )( GlobalRadiant().getLocalRcPath(), SHADERTAG_FILE ); + const auto message = StringOutputStream( 256 )( "Tag file saved to\n", tagFile, "\nPlease restart Radiant now.\n" ); if ( file_exists( tagFile ) ) { - EMessageBoxReturn result = GlobalRadiant().m_pfnMessageBox( GTK_WIDGET( g_window ), + EMessageBoxReturn result = GlobalRadiant().m_pfnMessageBox( g_window, "WARNING! A tag file already exists! Overwrite it?", "Overwrite tag file?", - eMB_NOYES, - eMB_ICONWARNING ); + EMessageBoxType::Warning, + eIDYES | eIDNO ); if ( result == eIDYES ) { TagBuilder.SaveXmlDoc( tagFile ); - GlobalRadiant().m_pfnMessageBox( GTK_WIDGET( g_window ), message, "INFO", eMB_OK, eMB_ICONASTERISK ); + GlobalRadiant().m_pfnMessageBox( g_window, message, "INFO", EMessageBoxType::Info, 0 ); } } else { TagBuilder.SaveXmlDoc( tagFile ); - GlobalRadiant().m_pfnMessageBox( GTK_WIDGET( g_window ), message, "INFO", eMB_OK, eMB_ICONASTERISK ); + GlobalRadiant().m_pfnMessageBox( g_window, message, "INFO", EMessageBoxType::Info, 0 ); } } else { - GlobalRadiant().m_pfnMessageBox( GTK_WIDGET( g_window ), - "No shaders or textures found. No XML tag file created!\n" - "", + GlobalRadiant().m_pfnMessageBox( g_window, + "No shaders or textures found. No XML tag file created!\n", "ERROR", - eMB_OK, - eMB_ICONERROR ); + EMessageBoxType::Error, 0 ); } } } // namespace diff --git a/contrib/sunplug/sunplug.cpp b/contrib/sunplug/sunplug.cpp index 3a9fea94..d91420a8 100644 --- a/contrib/sunplug/sunplug.cpp +++ b/contrib/sunplug/sunplug.cpp @@ -34,138 +34,20 @@ #include "scenelib.h" // declaration of datastructure of the map #include "qerplugin.h" // declaration to use other interfaces as a plugin -#include // to display something with gtk (windows, buttons etc.), the whole package might not be necessary +#include "generic/vector.h" +#include "gtkutil/spinbox.h" +#include +#include +#include +#include +#include +#include + + void about_plugin_window(); void MapCoordinator(); -#ifndef _WIN32 -// linux itoa implementation -char* itoa( int value, char* result, int base ){ - // check that the base if valid - if ( base < 2 || base > 16 ) { - *result = 0; - return result; - } - - char* out = result; - int quotient = value; - - do - { - *out = "0123456789abcdef"[abs( quotient % base )]; - ++out; - - quotient /= base; - } while ( quotient ); - - // Only apply negative sign for base 10 - if ( value < 0 && base == 10 ) { - *out++ = '-'; - } - - std::reverse( result, out ); - - *out = 0; - return result; -} -#endif - -typedef struct _mapcoord_setting_packet { - GtkSpinButton *spinner1, *spinner2, *spinner3, *spinner4; - Entity* worldspawn; -} mapcoord_setting_packet; - -static int map_minX, map_maxX, map_minY, map_maxY; -static int minX, maxX, minY, maxY; -mapcoord_setting_packet msp; - -// ************************** -// ** find entities by class ** from radiant/map.cpp -// ************************** -class EntityFindByClassname : public scene::Graph::Walker -{ - const char* m_name; - Entity*& m_entity; -public: - EntityFindByClassname( const char* name, Entity*& entity ) : m_name( name ), m_entity( entity ){ - m_entity = 0; - } - bool pre( const scene::Path& path, scene::Instance& instance ) const { - if ( m_entity == 0 ) { - Entity* entity = Node_getEntity( path.top() ); - if ( entity != 0 - && string_equal( m_name, entity->getClassName() ) ) { - m_entity = entity; - } - } - return true; - } -}; - -Entity* Scene_FindEntityByClass( const char* name ){ - Entity* entity; - GlobalSceneGraph().traverse( EntityFindByClassname( name, entity ) ); - return entity; -} - -// ************************** -// ** GTK callback functions ** -// ************************** - -static gboolean delete_event( GtkWidget *widget, GdkEvent *event, gpointer data ){ - /* If you return FALSE in the "delete_event" signal handler, - * GTK will emit the "destroy" signal. Returning TRUE means - * you don't want the window to be destroyed. - * This is useful for popping up 'are you sure you want to quit?' - * type dialogs. */ - - return FALSE; -} - -// destroy widget if destroy signal is passed to widget -static void destroy( GtkWidget *widget, gpointer data ){ - gtk_widget_destroy( widget ); -} - -// function for close button to destroy the toplevel widget -static void close_window( GtkWidget *widget, gpointer data ){ - gtk_widget_destroy( gtk_widget_get_toplevel( widget ) ); -} - -// callback function to assign the optimal mapcoords to the spinboxes -static void input_optimal( GtkWidget *widget, gpointer data ){ - gtk_spin_button_set_value( msp.spinner1, minX ); - gtk_spin_button_set_value( msp.spinner2, maxY ); - gtk_spin_button_set_value( msp.spinner3, maxX ); - gtk_spin_button_set_value( msp.spinner4, minY ); -} - -// Spinner return value function -gint grab_int_value( GtkSpinButton *a_spinner, gpointer user_data ) { - return gtk_spin_button_get_value_as_int( a_spinner ); -} - -// write the values of the Spinner-Boxes to the worldspawn -static void set_coordinates( GtkWidget *widget, gpointer data ){ - //Str str_min, str_max; - char buffer[10], str_min[20], str_max[20]; - - itoa( gtk_spin_button_get_value_as_int( msp.spinner1 ), str_min, 10 ); - itoa( gtk_spin_button_get_value_as_int( msp.spinner2 ), buffer, 10 ); - strcat( str_min, " " ); - strcat( str_min, buffer ); - msp.worldspawn->setKeyValue( "mapcoordsmins", str_min ); - - itoa( gtk_spin_button_get_value_as_int( msp.spinner3 ), str_max, 10 ); - itoa( gtk_spin_button_get_value_as_int( msp.spinner4 ), buffer, 10 ); - strcat( str_max, " " ); - strcat( str_max, buffer ); - UndoableCommand undo( "SunPlug.entitySetMapcoords" ); - msp.worldspawn->setKeyValue( "mapcoordsmaxs", str_max ); - - close_window( widget, NULL ); -} class SunPlugPluginDependencies : public GlobalRadiantModuleRef, // basic class for all other module refs @@ -184,11 +66,11 @@ public: // ************************* namespace SunPlug { -GtkWindow* main_window; +QWidget* main_window; char MenuList[100] = ""; const char* init( void* hApp, void* pMainWidget ){ - main_window = GTK_WINDOW( pMainWidget ); + main_window = static_cast( pMainWidget ); return "Initializing SunPlug for GTKRadiant"; } const char* getName(){ @@ -199,9 +81,9 @@ const char* getCommandList(){ const char etMapCoordinator[] = ";ET-MapCoordinator"; strcat( MenuList, about ); - if ( strncmp( GlobalRadiant().getGameName(), "etmain", 6 ) == 0 ) { +//. if ( strncmp( GlobalRadiant().getGameName(), "etmain", 6 ) == 0 ) { strcat( MenuList, etMapCoordinator ); - } +//. } return (const char*)MenuList; } const char* getCommandTitleList(){ @@ -247,196 +129,149 @@ extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules( ModuleServer& server g_SunPlugModule.selfRegister(); } + + +// ************************** +// ** find entities by class ** from radiant/map.cpp +// ************************** +class EntityFindByClassname : public scene::Graph::Walker +{ + const char* m_name; + Entity*& m_entity; +public: + EntityFindByClassname( const char* name, Entity*& entity ) : m_name( name ), m_entity( entity ){ + m_entity = 0; + } + bool pre( const scene::Path& path, scene::Instance& instance ) const { + if ( m_entity == 0 ) { + Entity* entity = Node_getEntity( path.top() ); + if ( entity != 0 + && string_equal( m_name, entity->getClassName() ) ) { + m_entity = entity; + } + } + return true; + } +}; + +Entity* Scene_FindEntityByClass( const char* name ){ + Entity* entity; + GlobalSceneGraph().traverse( EntityFindByClassname( name, entity ) ); + return entity; +} + // ************ // ** my stuff ** // ************ // About dialog void about_plugin_window(){ - GtkWidget *window, *vbox, *label, *button; + GlobalRadiant().m_pfnMessageBox( SunPlug::main_window, "SunPlug v1.0 for NetRadiant 1.5\nby Topsun", "About SunPlug", EMessageBoxType::Info, 0 ); +} - window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); // create a window - gtk_window_set_transient_for( GTK_WINDOW( window ), SunPlug::main_window ); // make the window to stay in front of the main window - g_signal_connect( G_OBJECT( window ), "delete_event", G_CALLBACK( delete_event ), NULL ); // connect the delete event - g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( destroy ), NULL ); // connect the destroy event for the window - gtk_window_set_title( GTK_WINDOW( window ), "About SunPlug" ); // set the title of the window for the window - gtk_window_set_resizable( GTK_WINDOW( window ), FALSE ); // don't let the user resize the window - gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); // force the user not to do something with the other windows - gtk_container_set_border_width( GTK_CONTAINER( window ), 10 ); // set the border of the window - vbox = gtk_vbox_new( FALSE, 10 ); // create a box to arrange new objects vertically - gtk_container_add( GTK_CONTAINER( window ), vbox ); // add the box to the window - - label = gtk_label_new( "SunPlug v1.0 for NetRadiant 1.5\nby Topsun" ); // create a label - gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT ); // text align left - gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, FALSE, 2 ); // insert the label in the box - - button = gtk_button_new_with_label( "OK" ); // create a button with text - g_signal_connect_swapped( G_OBJECT( button ), "clicked", G_CALLBACK( gtk_widget_destroy ), window ); // connect the click event to close the window - gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 2 ); // insert the button in the box - - gtk_window_set_position( GTK_WINDOW( window ), GTK_WIN_POS_CENTER ); // center the window on screen - - gtk_widget_show_all( window ); // show the window and all subelements +AABB GetMapBounds(){ + scene::Path path = makeReference( GlobalSceneGraph().root() ); // get the path to the root element of the graph + scene::Instance* instance = GlobalSceneGraph().find( path ); // find the instance to the given path + return instance->worldAABB(); // get the bounding box of the level } // get the current bounding box and return the optimal coordinates -void GetOptimalCoordinates( AABB *levelBoundingBox ){ - int half_width, half_heigth, center_x, center_y; - - half_width = levelBoundingBox->extents.x(); - half_heigth = levelBoundingBox->extents.y(); - center_x = levelBoundingBox->origin.x(); - center_y = levelBoundingBox->origin.y(); - - if ( half_width > 175 || half_heigth > 175 ) { // the square must be at least 350x350 units - // the wider side is the indicator for the square - if ( half_width >= half_heigth ) { - minX = center_x - half_width; - maxX = center_x + half_width; - minY = center_y - half_width; - maxY = center_y + half_width; - } - else { - minX = center_x - half_heigth; - maxX = center_x + half_heigth; - minY = center_y - half_heigth; - maxY = center_y + half_heigth; - } - } - else { - minX = center_x - 175; - maxX = center_x + 175; - minY = center_y - 175; - maxY = center_y + 175; - } +auto GetOptimalCoordinates(){ + const AABB bounds = GetMapBounds(); + const float max = std::max( { bounds.extents.x(), bounds.extents.y(), 175.f } ); // the square must be at least 350x350 units + return std::pair( BasicVector2( bounds.origin.vec2() - Vector2( max, max ) ), + BasicVector2( bounds.origin.vec2() + Vector2( max, max ) ) ); } + // MapCoordinator dialog window void MapCoordinator(){ - GtkWidget *window, *vbox, *table, *label, *spinnerMinX, *spinnerMinY, *spinnerMaxX, *spinnerMaxY, *button; - GtkAdjustment *spinner_adj_MinX, *spinner_adj_MinY, *spinner_adj_MaxX, *spinner_adj_MaxY; - Entity *theWorldspawn = NULL; - const char *buffer; - char line[20]; - - // in any case we need a window to show the user what to do - window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); // create the window - gtk_window_set_transient_for( GTK_WINDOW( window ), SunPlug::main_window ); // make the window to stay in front of the main window - g_signal_connect( G_OBJECT( window ), "delete_event", G_CALLBACK( delete_event ), NULL ); // connect the delete event for the window - g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( destroy ), NULL ); // connect the destroy event for the window - gtk_window_set_title( GTK_WINDOW( window ), "ET-MapCoordinator" ); // set the title of the window for the window - gtk_window_set_resizable( GTK_WINDOW( window ), FALSE ); // don't let the user resize the window - gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); // force the user not to do something with the other windows - gtk_container_set_border_width( GTK_CONTAINER( window ), 10 ); // set the border of the window - - vbox = gtk_vbox_new( FALSE, 10 ); // create a box to arrange new objects vertically - gtk_container_add( GTK_CONTAINER( window ), vbox ); // add the box to the window - - scene::Path path = makeReference( GlobalSceneGraph().root() ); // get the path to the root element of the graph - scene::Instance* instance = GlobalSceneGraph().find( path ); // find the instance to the given path - AABB levelBoundingBox = instance->worldAABB(); // get the bounding box of the level - - theWorldspawn = Scene_FindEntityByClass( "worldspawn" ); // find the entity worldspawn - if ( theWorldspawn != 0 ) { // need to have a worldspawn otherwise setting a value crashes the radiant - // next two if's: get the current values of the mapcoords - buffer = theWorldspawn->getKeyValue( "mapcoordsmins" ); // upper left corner - if ( strlen( buffer ) > 0 ) { - strncpy( line, buffer, 19 ); - map_minX = atoi( strtok( line, " " ) ); // minimum of x value - map_minY = atoi( strtok( NULL, " " ) ); // maximum of y value + // find the entity worldspawn + if ( Entity *theWorldspawn = Scene_FindEntityByClass( "worldspawn" ) ) { // need to have a worldspawn otherwise setting a value crashes the radiant + // get the current values of the mapcoords + BasicVector2 min( 0, 0 ), max( 0, 0 ); + { + StringTokeniser tokeniser( theWorldspawn->getKeyValue( "mapcoordsmins" ) ); // upper left corner + min.x() = atoi( tokeniser.getToken() ); // minimum of x value + min.y() = atoi( tokeniser.getToken() ); // maximum of y value } - else { - map_minX = 0; - map_minY = 0; - } - buffer = theWorldspawn->getKeyValue( "mapcoordsmaxs" ); // lower right corner - if ( strlen( buffer ) > 0 ) { - strncpy( line, buffer, 19 ); - map_maxX = atoi( strtok( line, " " ) ); // maximum of x value - map_maxY = atoi( strtok( NULL, " " ) ); // minimum of y value - } - else { - map_maxX = 0; - map_maxY = 0; + { + StringTokeniser tokeniser( theWorldspawn->getKeyValue( "mapcoordsmaxs" ) ); // lower right corner + max.x() = atoi( tokeniser.getToken() ); // maximum of x value + max.y() = atoi( tokeniser.getToken() ); // minimum of y value } globalOutputStream() << "SunPlug: calculating optimal coordinates\n"; // write to console that we are calculating the coordinates - GetOptimalCoordinates( &levelBoundingBox ); // calculate optimal mapcoords with the dimensions of the level bounding box - globalOutputStream() << "SunPlug: advised mapcoordsmins=" << minX << " " << maxY << "\n"; // console info about mapcoordsmins - globalOutputStream() << "SunPlug: advised mapcoordsmaxs=" << maxX << " " << minY << "\n"; // console info about mapcoordsmaxs + const auto [ calc_min, calc_max ] = GetOptimalCoordinates(); // calculate optimal mapcoords with the dimensions of the level bounding box + globalOutputStream() << "SunPlug: advised mapcoordsmins=" << calc_min.x() << " " << calc_max.y() << "\n"; // console info about mapcoordsmins + globalOutputStream() << "SunPlug: advised mapcoordsmaxs=" << calc_max.x() << " " << calc_min.y() << "\n"; // console info about mapcoordsmaxs - spinner_adj_MinX = (GtkAdjustment *)gtk_adjustment_new( map_minX, -65536.0, 65536.0, 1.0, 5.0, 0 ); // create adjustment for value and range of minimum x value - spinner_adj_MinY = (GtkAdjustment *)gtk_adjustment_new( map_minY, -65536.0, 65536.0, 1.0, 5.0, 0 ); // create adjustment for value and range of minimum y value - spinner_adj_MaxX = (GtkAdjustment *)gtk_adjustment_new( map_maxX, -65536.0, 65536.0, 1.0, 5.0, 0 ); // create adjustment for value and range of maximum x value - spinner_adj_MaxY = (GtkAdjustment *)gtk_adjustment_new( map_maxY, -65536.0, 65536.0, 1.0, 5.0, 0 ); // create adjustment for value and range of maximum y value + { + QDialog dialog( SunPlug::main_window, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "ET-MapCoordinator" ); + { + auto form = new QFormLayout( &dialog ); + form->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + { + auto spin_minX = new SpinBox( -65536, 65536, min.x() ); + auto spin_minY = new SpinBox( -65536, 65536, min.y() ); + auto spin_maxX = new SpinBox( -65536, 65536, max.x() ); + auto spin_maxY = new SpinBox( -65536, 65536, max.y() ); + spin_minX->setPrefix( "X: " ); + spin_minY->setPrefix( "Y: " ); + spin_maxX->setPrefix( "X: " ); + spin_maxY->setPrefix( "Y: " ); + { + auto button = new QPushButton( "Get optimal mapcoords" ); + form->addWidget( button ); + QObject::connect( button, &QPushButton::clicked, [&](){ + spin_minX->setValue( calc_min.x() ); + spin_minY->setValue( calc_max.y() ); + spin_maxX->setValue( calc_max.x() ); + spin_maxY->setValue( calc_min.y() ); + } ); + } + { + auto line = new QFrame; + line->setFrameShape( QFrame::Shape::HLine ); + line->setFrameShadow( QFrame::Shadow::Raised ); + form->addRow( line ); + } + { + auto hbox = new QHBoxLayout; + hbox->addWidget( spin_minX ); + hbox->addWidget( spin_minY ); + form->addRow( new QLabel( "MapCoordsMins" ), hbox ); + } + { + auto hbox = new QHBoxLayout; + hbox->addWidget( spin_maxX ); + hbox->addWidget( spin_maxY ); + form->addRow( new QLabel( "MapCoordsMaxs" ), hbox ); + } + { + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel ); + form->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept ); + QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject ); + buttons->button( QDialogButtonBox::StandardButton::Ok )->setText( "Set" ); + } - button = gtk_button_new_with_label( "Get optimal mapcoords" ); // create button with text - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( input_optimal ), NULL ); // connect button with callback function - gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 2 ); // insert button into vbox - - gtk_box_pack_start( GTK_BOX( vbox ), gtk_hseparator_new(), FALSE, FALSE, 2 ); // insert separator into vbox - - table = gtk_table_new( 4, 3, TRUE ); // create table - gtk_table_set_row_spacings( GTK_TABLE( table ), 8 ); // set row spacings - gtk_table_set_col_spacings( GTK_TABLE( table ), 8 ); // set column spacings - gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, FALSE, 2 ); // insert table into vbox - - label = gtk_label_new( "x" ); // create label - gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT ); // align text to the left side - gtk_table_attach_defaults( GTK_TABLE( table ), label, 1, 2, 0, 1 ); // insert label into table - - label = gtk_label_new( "y" ); // create label - gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT ); // align text to the left side - gtk_table_attach_defaults( GTK_TABLE( table ), label, 2, 3, 0, 1 ); // insert label into table - - label = gtk_label_new( "mapcoordsmins" ); // create label - gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT ); // align text to the left side - gtk_table_attach_defaults( GTK_TABLE( table ), label, 0, 1, 1, 2 ); // insert label into table - - spinnerMinX = gtk_spin_button_new( spinner_adj_MinX, 1.0, 0 ); // create textbox with value spin, value and value range - gtk_table_attach_defaults( GTK_TABLE( table ), spinnerMinX, 1, 2, 1, 2 ); // insert spinbox into table - - spinnerMinY = gtk_spin_button_new( spinner_adj_MinY, 1.0, 0 ); // create textbox with value spin, value and value range - gtk_table_attach_defaults( GTK_TABLE( table ), spinnerMinY, 2, 3, 1, 2 ); // insert spinbox into table - - label = gtk_label_new( "mapcoordsmaxs" ); // create label - gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT ); // align text to the left side - gtk_table_attach_defaults( GTK_TABLE( table ), label, 0, 1, 2, 3 ); // insert label into table - - spinnerMaxX = gtk_spin_button_new( spinner_adj_MaxX, 1.0, 0 ); // create textbox with value spin, value and value range - gtk_table_attach_defaults( GTK_TABLE( table ), spinnerMaxX, 1, 2, 2, 3 ); // insert spinbox into table - - spinnerMaxY = gtk_spin_button_new( spinner_adj_MaxY, 1.0, 0 ); // create textbox with value spin, value and value range - gtk_table_attach_defaults( GTK_TABLE( table ), spinnerMaxY, 2, 3, 2, 3 ); // insert spinbox into table - - // put the references to the spinboxes and the worldspawn into the global exchange - msp.spinner1 = GTK_SPIN_BUTTON( spinnerMinX ); - msp.spinner2 = GTK_SPIN_BUTTON( spinnerMinY ); - msp.spinner3 = GTK_SPIN_BUTTON( spinnerMaxX ); - msp.spinner4 = GTK_SPIN_BUTTON( spinnerMaxY ); - msp.worldspawn = theWorldspawn; - - button = gtk_button_new_with_label( "Set" ); // create button with text - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( set_coordinates ), NULL ); // connect button with callback function - gtk_table_attach_defaults( GTK_TABLE( table ), button, 1, 2, 3, 4 ); // insert button into table - - button = gtk_button_new_with_label( "Cancel" ); // create button with text - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( close_window ), NULL ); // connect button with callback function - gtk_table_attach_defaults( GTK_TABLE( table ), button, 2, 3, 3, 4 ); // insert button into table + if( dialog.exec() ){ + UndoableCommand undo( "SunPlug.entitySetMapcoords" ); + theWorldspawn->setKeyValue( "mapcoordsmins", ( spin_minX->text() + " " + spin_minY->text() ).toLatin1().constData() ); + theWorldspawn->setKeyValue( "mapcoordsmaxs", ( spin_maxX->text() + " " + spin_maxY->text() ).toLatin1().constData() ); + } + } + } + } } else { globalErrorStream() << "SunPlug: no worldspawn found!\n"; // output error to console - label = gtk_label_new( "ERROR: No worldspawn was found in the map!\nIn order to use this tool the map must have at least one brush in the worldspawn. " ); // create a label - gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT ); // text align left - gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, FALSE, 2 ); // insert the label in the box - - button = gtk_button_new_with_label( "OK" ); // create a button with text - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( close_window ), NULL ); // connect the click event to close the window - gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 2 ); // insert the button in the box + GlobalRadiant().m_pfnMessageBox( SunPlug::main_window, + "No worldspawn was found in the map!\nIn order to use this tool the map must have at least one brush in the worldspawn.", + "ET-MapCoordinator", EMessageBoxType::Error, 0 ); } - - gtk_window_set_position( GTK_WINDOW( window ), GTK_WIN_POS_CENTER ); // center the window - gtk_widget_show_all( window ); // show the window and all subelements } diff --git a/contrib/ufoaiplug/ufoai.cpp b/contrib/ufoaiplug/ufoai.cpp index 274beba9..ec5fa1b7 100644 --- a/contrib/ufoaiplug/ufoai.cpp +++ b/contrib/ufoaiplug/ufoai.cpp @@ -30,8 +30,6 @@ #include "string/string.h" #include "modulesystem/singletonmodule.h" -#include - #define PLUGIN_VERSION "0.4" #include "ifilter.h" @@ -59,10 +57,10 @@ public: namespace UFOAI { -GtkWindow* g_mainwnd; +QWidget* g_mainwnd; const char* init( void* hApp, void* pMainWidget ){ - g_mainwnd = GTK_WINDOW( pMainWidget ); + g_mainwnd = static_cast( pMainWidget ); return "Initializing GTKRadiant UFOAI plugin"; } const char* getName(){ @@ -78,9 +76,13 @@ const char* getCommandTitleList(){ void dispatch( const char* command, float* vMin, float* vMax, bool bSingleBrush ){ const char *message = NULL; if ( string_equal( command, "About" ) ) { - GlobalRadiant().m_pfnMessageBox( GTK_WIDGET( g_mainwnd ), - "UFO:AI Plugin (http://ufoai.sf.net)\nBuild: " __DATE__ "\nRadiant version: " RADIANT_VERSION "\nPlugin version: " PLUGIN_VERSION "\nAuthor: Martin Gerhardy (tlh2000/mattn)\n", "About", - eMB_OK, eMB_ICONDEFAULT ); + GlobalRadiant().m_pfnMessageBox( g_mainwnd, + "UFO:AI Plugin (http://ufoai.sf.net)" + "
Build: " __DATE__ + "
Radiant version: " RADIANT_VERSION + "
Plugin version: " PLUGIN_VERSION + "
Author: Martin Gerhardy (tlh2000/mattn)
", + "About", EMessageBoxType::Info, 0 ); } else if ( string_equal( command, "Level 1" ) ) { filter_level( CONTENTS_LEVEL1 ); @@ -129,9 +131,9 @@ void dispatch( const char* command, float* vMin, float* vMax, bool bSingleBrush } if ( message != NULL ) { - GlobalRadiant().m_pfnMessageBox( GTK_WIDGET( g_mainwnd ), + GlobalRadiant().m_pfnMessageBox( g_mainwnd, message, "Note", - eMB_OK, eMB_ICONDEFAULT ); + EMessageBoxType::Info, 0 ); } SceneChangeNotify(); } diff --git a/contrib/ufoaiplug/ufoai_filters.cpp b/contrib/ufoaiplug/ufoai_filters.cpp index c14df36e..ff5af6df 100644 --- a/contrib/ufoaiplug/ufoai_filters.cpp +++ b/contrib/ufoaiplug/ufoai_filters.cpp @@ -219,7 +219,7 @@ void filter_level( int flag ){ } else { - globalOutputStream() << "UFO:AI: Found " << Unsigned( brushes.size() ) << " brushes.\n"; + globalOutputStream() << "UFO:AI: Found " << brushes.size() << " brushes.\n"; } // now let's filter all entities like misc_model, func_breakable and func_door that have the spawnflags set @@ -228,7 +228,7 @@ void filter_level( int flag ){ } else { - globalOutputStream() << "UFO:AI: Found " << Unsigned( entities.size() ) << " entities.\n"; + globalOutputStream() << "UFO:AI: Found " << entities.size() << " entities.\n"; } #endif } @@ -248,7 +248,7 @@ void filter_stepon( void ){ } else { - globalOutputStream() << "UFO:AI: Hiding " << Unsigned( brushes.size() ) << " stepon brushes.\n"; + globalOutputStream() << "UFO:AI: Hiding " << brushes.size() << " stepon brushes.\n"; } } @@ -268,7 +268,7 @@ void filter_nodraw( void ){ } else { - globalOutputStream() << "UFO:AI: Hiding " << Unsigned( brushes.size() ) << " nodraw brushes.\n"; + globalOutputStream() << "UFO:AI: Hiding " << brushes.size() << " nodraw brushes.\n"; } #endif } @@ -289,7 +289,7 @@ void filter_actorclip( void ){ } else { - globalOutputStream() << "UFO:AI: Hiding " << Unsigned( brushes.size() ) << " actorclip brushes.\n"; + globalOutputStream() << "UFO:AI: Hiding " << brushes.size() << " actorclip brushes.\n"; } #endif } @@ -310,7 +310,7 @@ void filter_weaponclip( void ){ } else { - globalOutputStream() << "UFO:AI: Hiding " << Unsigned( brushes.size() ) << " weaponclip brushes.\n"; + globalOutputStream() << "UFO:AI: Hiding " << brushes.size() << " weaponclip brushes.\n"; } #endif } diff --git a/contrib/ufoaiplug/ufoai_gtk.cpp b/contrib/ufoaiplug/ufoai_gtk.cpp index 70828e69..5c9b8801 100644 --- a/contrib/ufoaiplug/ufoai_gtk.cpp +++ b/contrib/ufoaiplug/ufoai_gtk.cpp @@ -22,42 +22,6 @@ #include "itoolbar.h" #include "iscenegraph.h" -#include - -/** - * GTK callback functions - */ - - -#if 0 -/** - * @brief If you return FALSE in the "delete_event" signal handler, - * GTK will emit the "destroy" signal. Returning TRUE means - * you don't want the window to be destroyed. - * This is useful for popping up 'are you sure you want to quit?' - * type dialogs. - */ -static gboolean delete_event( GtkWidget *widget, GdkEvent *event, gpointer data ){ - return FALSE; -} - -/** - * @brief destroy widget if destroy signal is passed to widget - */ -static void destroy( GtkWidget *widget, gpointer data ){ - gtk_widget_destroy( widget ); -} - -/** - * @brief function for close button to destroy the toplevel widget - */ -static void close_window( GtkWidget *widget, gpointer data ){ - gtk_widget_destroy( gtk_widget_get_toplevel( widget ) ); -} -#endif - -/* =============================== */ - #define NUM_TOOLBARBUTTONS 12 /** diff --git a/contrib/ufoaiplug/ufoai_gtk.h b/contrib/ufoaiplug/ufoai_gtk.h index f29f69f9..f74d7425 100644 --- a/contrib/ufoaiplug/ufoai_gtk.h +++ b/contrib/ufoaiplug/ufoai_gtk.h @@ -19,7 +19,6 @@ #pragma once #include "itoolbar.h" -#include const IToolbarButton* GetToolbarButton( std::size_t index ); const IToolbarButton* GetToolbarNoButton( std::size_t index ); diff --git a/docs/shaderManual/general-directives.html b/docs/shaderManual/general-directives.html index 25a6c0fd..036f3deb 100644 --- a/docs/shaderManual/general-directives.html +++ b/docs/shaderManual/general-directives.html @@ -153,7 +153,6 @@ textures/skies/xtoxicsky_dm9
  • The fog volume can only have one surface visible (from outside the fog).
  • Fog must be made of one brush. It cannot be made of adjacent brushes.
  • -
  • Fog brushes must be axial. This means that only square or rectangular brushes may contain fog, and those must have their edges drawn along the axes of the map grid (all 90 degree angles).

Design Notes:

diff --git a/docs/shaderManual/stage-directives.html b/docs/shaderManual/stage-directives.html index 6dd44acf..2adcb2b3 100644 --- a/docs/shaderManual/stage-directives.html +++ b/docs/shaderManual/stage-directives.html @@ -278,9 +278,6 @@ textures/obsidian_video/intro

rgbGen exactVertex

Like vertex, except vertex ignores overbrightbits. Engine uses this mode in default shaders for vertexlit surfaces. Generally brighter under default settings.

-

rgbGen fromVertex

-

(Pending)

-

rgbGen entity

Colors are grabbed from the entity's modulate field. This is used for things like explosions. This keyword would probably not be used by a level designer.

@@ -294,11 +291,8 @@ textures/obsidian_video/intro

rgbGen lightingDiffuse is used when you want the RGB values to be computed for a dynamic model (i.e. non-map object) in the world using regular in-game lighting. For example, you would specify on shaders for items, characters, weapons, etc.

-

rgbGen noise

-

(Probably doesn't exist)

-

rgbGen wave func base amplitude phase freq

-

Colors are generated using the specified waveform. An affected texture with become darker and lighter, but will not change hue. Hue stays constant. Note that the RGB values for color will not go below 0 (black) or above 1 (white). Valid waveforms are sin, triangle, square, sawtooth, inversesawtooth and noise (see Waveform Functions).

+

Colors are generated using the specified waveform. An affected texture will become darker and lighter, but will not change hue. Hue stays constant. Note that the RGB values for color will not go below 0 (black) or above 1 (white). Valid waveforms are sin, triangle, square, sawtooth, inversesawtooth and noise (see Waveform Functions).

rgbGen const ( R G B )

A constant vertex colour is assigned to the affected surface. This modifies the hue of the texture.

diff --git a/include/icamera.h b/include/icamera.h index 1efc286c..98f13e58 100644 --- a/include/icamera.h +++ b/include/icamera.h @@ -60,5 +60,4 @@ struct _QERCameraTable PFN_GETCAMERA m_pfnGetCamera; PFN_SETCAMERA m_pfnSetCamera; - PFN_GETCAMWINDOWEXTENTS m_pfnGetCamWindowExtents; }; diff --git a/include/igl.h b/include/igl.h index a37b0a70..0e7ddd2e 100644 --- a/include/igl.h +++ b/include/igl.h @@ -25,2065 +25,7 @@ #include #include "generic/constant.h" -#if defined( WIN32 ) -#define QGL_DLLEXPORT __stdcall -#else -#define QGL_DLLEXPORT -#endif - -typedef unsigned int GLenum; -typedef unsigned char GLboolean; -typedef unsigned int GLbitfield; -typedef signed char GLbyte; -typedef short GLshort; -typedef int GLint; -typedef int GLsizei; -typedef unsigned char GLubyte; -typedef unsigned short GLushort; -typedef unsigned int GLuint; -typedef float GLfloat; -typedef float GLclampf; -typedef double GLdouble; -typedef double GLclampd; -typedef void GLvoid; - -#if !defined( GL_VERSION_1_1 ) -#define GL_VERSION_1_1 1 - -#define GL_ZERO 0 -#define GL_ONE 1 -#define GL_TRUE 1 -#define GL_FALSE 0 -#define GL_POINTS 0x0000 -#define GL_LINES 0x0001 -#define GL_LINE_LOOP 0x0002 -#define GL_LINE_STRIP 0x0003 -#define GL_TRIANGLES 0x0004 -#define GL_TRIANGLE_STRIP 0x0005 -#define GL_TRIANGLE_FAN 0x0006 -#define GL_QUADS 0x0007 -#define GL_QUAD_STRIP 0x0008 -#define GL_POLYGON 0x0009 -#define GL_ACCUM 0x0100 -#define GL_LOAD 0x0101 -#define GL_RETURN 0x0102 -#define GL_MULT 0x0103 -#define GL_ADD 0x0104 -#define GL_NEVER 0x0200 -#define GL_LESS 0x0201 -#define GL_EQUAL 0x0202 -#define GL_LEQUAL 0x0203 -#define GL_GREATER 0x0204 -#define GL_NOTEQUAL 0x0205 -#define GL_GEQUAL 0x0206 -#define GL_ALWAYS 0x0207 -#define GL_SRC_COLOR 0x0300 -#define GL_ONE_MINUS_SRC_COLOR 0x0301 -#define GL_SRC_ALPHA 0x0302 -#define GL_ONE_MINUS_SRC_ALPHA 0x0303 -#define GL_DST_ALPHA 0x0304 -#define GL_ONE_MINUS_DST_ALPHA 0x0305 -#define GL_DST_COLOR 0x0306 -#define GL_ONE_MINUS_DST_COLOR 0x0307 -#define GL_SRC_ALPHA_SATURATE 0x0308 -#define GL_BYTE 0x1400 -#define GL_UNSIGNED_BYTE 0x1401 -#define GL_SHORT 0x1402 -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_INT 0x1404 -#define GL_UNSIGNED_INT 0x1405 -#define GL_FLOAT 0x1406 -#define GL_2_BYTES 0x1407 -#define GL_3_BYTES 0x1408 -#define GL_4_BYTES 0x1409 -#define GL_DOUBLE 0x140A -#define GL_NONE 0 -#define GL_FRONT_LEFT 0x0400 -#define GL_FRONT_RIGHT 0x0401 -#define GL_BACK_LEFT 0x0402 -#define GL_BACK_RIGHT 0x0403 -#define GL_FRONT 0x0404 -#define GL_BACK 0x0405 -#define GL_LEFT 0x0406 -#define GL_RIGHT 0x0407 -#define GL_FRONT_AND_BACK 0x0408 -#define GL_AUX0 0x0409 -#define GL_AUX1 0x040A -#define GL_AUX2 0x040B -#define GL_AUX3 0x040C -#define GL_NO_ERROR 0 -#define GL_INVALID_ENUM 0x0500 -#define GL_INVALID_VALUE 0x0501 -#define GL_INVALID_OPERATION 0x0502 -#define GL_STACK_OVERFLOW 0x0503 -#define GL_STACK_UNDERFLOW 0x0504 -#define GL_OUT_OF_MEMORY 0x0505 -#define GL_2D 0x0600 -#define GL_3D 0x0601 -#define GL_3D_COLOR 0x0602 -#define GL_3D_COLOR_TEXTURE 0x0603 -#define GL_4D_COLOR_TEXTURE 0x0604 -#define GL_PASS_THROUGH_TOKEN 0x0700 -#define GL_POINT_TOKEN 0x0701 -#define GL_LINE_TOKEN 0x0702 -#define GL_POLYGON_TOKEN 0x0703 -#define GL_BITMAP_TOKEN 0x0704 -#define GL_DRAW_PIXEL_TOKEN 0x0705 -#define GL_COPY_PIXEL_TOKEN 0x0706 -#define GL_LINE_RESET_TOKEN 0x0707 -#define GL_EXP 0x0800 -#define GL_EXP2 0x0801 -#define GL_CW 0x0900 -#define GL_CCW 0x0901 -#define GL_COEFF 0x0A00 -#define GL_ORDER 0x0A01 -#define GL_DOMAIN 0x0A02 -#define GL_CURRENT_COLOR 0x0B00 -#define GL_CURRENT_INDEX 0x0B01 -#define GL_CURRENT_NORMAL 0x0B02 -#define GL_CURRENT_TEXTURE_COORDS 0x0B03 -#define GL_CURRENT_RASTER_COLOR 0x0B04 -#define GL_CURRENT_RASTER_INDEX 0x0B05 -#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 -#define GL_CURRENT_RASTER_POSITION 0x0B07 -#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 -#define GL_CURRENT_RASTER_DISTANCE 0x0B09 -#define GL_POINT_SMOOTH 0x0B10 -#define GL_POINT_SIZE 0x0B11 -#define GL_POINT_SIZE_RANGE 0x0B12 -#define GL_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_LINE_SMOOTH 0x0B20 -#define GL_LINE_WIDTH 0x0B21 -#define GL_LINE_WIDTH_RANGE 0x0B22 -#define GL_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_LINE_STIPPLE 0x0B24 -#define GL_LINE_STIPPLE_PATTERN 0x0B25 -#define GL_LINE_STIPPLE_REPEAT 0x0B26 -#define GL_LIST_MODE 0x0B30 -#define GL_MAX_LIST_NESTING 0x0B31 -#define GL_LIST_BASE 0x0B32 -#define GL_LIST_INDEX 0x0B33 -#define GL_POLYGON_MODE 0x0B40 -#define GL_POLYGON_SMOOTH 0x0B41 -#define GL_POLYGON_STIPPLE 0x0B42 -#define GL_EDGE_FLAG 0x0B43 -#define GL_CULL_FACE 0x0B44 -#define GL_CULL_FACE_MODE 0x0B45 -#define GL_FRONT_FACE 0x0B46 -#define GL_LIGHTING 0x0B50 -#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 -#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 -#define GL_LIGHT_MODEL_AMBIENT 0x0B53 -#define GL_SHADE_MODEL 0x0B54 -#define GL_COLOR_MATERIAL_FACE 0x0B55 -#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 -#define GL_COLOR_MATERIAL 0x0B57 -#define GL_FOG 0x0B60 -#define GL_FOG_INDEX 0x0B61 -#define GL_FOG_DENSITY 0x0B62 -#define GL_FOG_START 0x0B63 -#define GL_FOG_END 0x0B64 -#define GL_FOG_MODE 0x0B65 -#define GL_FOG_COLOR 0x0B66 -#define GL_DEPTH_RANGE 0x0B70 -#define GL_DEPTH_TEST 0x0B71 -#define GL_DEPTH_WRITEMASK 0x0B72 -#define GL_DEPTH_CLEAR_VALUE 0x0B73 -#define GL_DEPTH_FUNC 0x0B74 -#define GL_ACCUM_CLEAR_VALUE 0x0B80 -#define GL_STENCIL_TEST 0x0B90 -#define GL_STENCIL_CLEAR_VALUE 0x0B91 -#define GL_STENCIL_FUNC 0x0B92 -#define GL_STENCIL_VALUE_MASK 0x0B93 -#define GL_STENCIL_FAIL 0x0B94 -#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 -#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 -#define GL_STENCIL_REF 0x0B97 -#define GL_STENCIL_WRITEMASK 0x0B98 -#define GL_MATRIX_MODE 0x0BA0 -#define GL_NORMALIZE 0x0BA1 -#define GL_VIEWPORT 0x0BA2 -#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 -#define GL_PROJECTION_STACK_DEPTH 0x0BA4 -#define GL_TEXTURE_STACK_DEPTH 0x0BA5 -#define GL_MODELVIEW_MATRIX 0x0BA6 -#define GL_PROJECTION_MATRIX 0x0BA7 -#define GL_TEXTURE_MATRIX 0x0BA8 -#define GL_ATTRIB_STACK_DEPTH 0x0BB0 -#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 -#define GL_ALPHA_TEST 0x0BC0 -#define GL_ALPHA_TEST_FUNC 0x0BC1 -#define GL_ALPHA_TEST_REF 0x0BC2 -#define GL_DITHER 0x0BD0 -#define GL_BLEND_DST 0x0BE0 -#define GL_BLEND_SRC 0x0BE1 -#define GL_BLEND 0x0BE2 -#define GL_LOGIC_OP_MODE 0x0BF0 -#define GL_INDEX_LOGIC_OP 0x0BF1 -#define GL_COLOR_LOGIC_OP 0x0BF2 -#define GL_AUX_BUFFERS 0x0C00 -#define GL_DRAW_BUFFER 0x0C01 -#define GL_READ_BUFFER 0x0C02 -#define GL_SCISSOR_BOX 0x0C10 -#define GL_SCISSOR_TEST 0x0C11 -#define GL_INDEX_CLEAR_VALUE 0x0C20 -#define GL_INDEX_WRITEMASK 0x0C21 -#define GL_COLOR_CLEAR_VALUE 0x0C22 -#define GL_COLOR_WRITEMASK 0x0C23 -#define GL_INDEX_MODE 0x0C30 -#define GL_RGBA_MODE 0x0C31 -#define GL_DOUBLEBUFFER 0x0C32 -#define GL_STEREO 0x0C33 -#define GL_RENDER_MODE 0x0C40 -#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 -#define GL_POINT_SMOOTH_HINT 0x0C51 -#define GL_LINE_SMOOTH_HINT 0x0C52 -#define GL_POLYGON_SMOOTH_HINT 0x0C53 -#define GL_FOG_HINT 0x0C54 -#define GL_TEXTURE_GEN_S 0x0C60 -#define GL_TEXTURE_GEN_T 0x0C61 -#define GL_TEXTURE_GEN_R 0x0C62 -#define GL_TEXTURE_GEN_Q 0x0C63 -#define GL_PIXEL_MAP_I_TO_I 0x0C70 -#define GL_PIXEL_MAP_S_TO_S 0x0C71 -#define GL_PIXEL_MAP_I_TO_R 0x0C72 -#define GL_PIXEL_MAP_I_TO_G 0x0C73 -#define GL_PIXEL_MAP_I_TO_B 0x0C74 -#define GL_PIXEL_MAP_I_TO_A 0x0C75 -#define GL_PIXEL_MAP_R_TO_R 0x0C76 -#define GL_PIXEL_MAP_G_TO_G 0x0C77 -#define GL_PIXEL_MAP_B_TO_B 0x0C78 -#define GL_PIXEL_MAP_A_TO_A 0x0C79 -#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 -#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 -#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 -#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 -#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 -#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 -#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 -#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 -#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 -#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 -#define GL_UNPACK_SWAP_BYTES 0x0CF0 -#define GL_UNPACK_LSB_FIRST 0x0CF1 -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#define GL_UNPACK_SKIP_ROWS 0x0CF3 -#define GL_UNPACK_SKIP_PIXELS 0x0CF4 -#define GL_UNPACK_ALIGNMENT 0x0CF5 -#define GL_PACK_SWAP_BYTES 0x0D00 -#define GL_PACK_LSB_FIRST 0x0D01 -#define GL_PACK_ROW_LENGTH 0x0D02 -#define GL_PACK_SKIP_ROWS 0x0D03 -#define GL_PACK_SKIP_PIXELS 0x0D04 -#define GL_PACK_ALIGNMENT 0x0D05 -#define GL_MAP_COLOR 0x0D10 -#define GL_MAP_STENCIL 0x0D11 -#define GL_INDEX_SHIFT 0x0D12 -#define GL_INDEX_OFFSET 0x0D13 -#define GL_RED_SCALE 0x0D14 -#define GL_RED_BIAS 0x0D15 -#define GL_ZOOM_X 0x0D16 -#define GL_ZOOM_Y 0x0D17 -#define GL_GREEN_SCALE 0x0D18 -#define GL_GREEN_BIAS 0x0D19 -#define GL_BLUE_SCALE 0x0D1A -#define GL_BLUE_BIAS 0x0D1B -#define GL_ALPHA_SCALE 0x0D1C -#define GL_ALPHA_BIAS 0x0D1D -#define GL_DEPTH_SCALE 0x0D1E -#define GL_DEPTH_BIAS 0x0D1F -#define GL_MAX_EVAL_ORDER 0x0D30 -#define GL_MAX_LIGHTS 0x0D31 -#define GL_MAX_CLIP_PLANES 0x0D32 -#define GL_MAX_TEXTURE_SIZE 0x0D33 -#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 -#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 -#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 -#define GL_MAX_NAME_STACK_DEPTH 0x0D37 -#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 -#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 -#define GL_MAX_VIEWPORT_DIMS 0x0D3A -#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B -#define GL_SUBPIXEL_BITS 0x0D50 -#define GL_INDEX_BITS 0x0D51 -#define GL_RED_BITS 0x0D52 -#define GL_GREEN_BITS 0x0D53 -#define GL_BLUE_BITS 0x0D54 -#define GL_ALPHA_BITS 0x0D55 -#define GL_DEPTH_BITS 0x0D56 -#define GL_STENCIL_BITS 0x0D57 -#define GL_ACCUM_RED_BITS 0x0D58 -#define GL_ACCUM_GREEN_BITS 0x0D59 -#define GL_ACCUM_BLUE_BITS 0x0D5A -#define GL_ACCUM_ALPHA_BITS 0x0D5B -#define GL_NAME_STACK_DEPTH 0x0D70 -#define GL_AUTO_NORMAL 0x0D80 -#define GL_MAP1_COLOR_4 0x0D90 -#define GL_MAP1_INDEX 0x0D91 -#define GL_MAP1_NORMAL 0x0D92 -#define GL_MAP1_TEXTURE_COORD_1 0x0D93 -#define GL_MAP1_TEXTURE_COORD_2 0x0D94 -#define GL_MAP1_TEXTURE_COORD_3 0x0D95 -#define GL_MAP1_TEXTURE_COORD_4 0x0D96 -#define GL_MAP1_VERTEX_3 0x0D97 -#define GL_MAP1_VERTEX_4 0x0D98 -#define GL_MAP2_COLOR_4 0x0DB0 -#define GL_MAP2_INDEX 0x0DB1 -#define GL_MAP2_NORMAL 0x0DB2 -#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 -#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 -#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 -#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 -#define GL_MAP2_VERTEX_3 0x0DB7 -#define GL_MAP2_VERTEX_4 0x0DB8 -#define GL_MAP1_GRID_DOMAIN 0x0DD0 -#define GL_MAP1_GRID_SEGMENTS 0x0DD1 -#define GL_MAP2_GRID_DOMAIN 0x0DD2 -#define GL_MAP2_GRID_SEGMENTS 0x0DD3 -#define GL_TEXTURE_1D 0x0DE0 -#define GL_TEXTURE_2D 0x0DE1 -#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 -#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 -#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 -#define GL_SELECTION_BUFFER_POINTER 0x0DF3 -#define GL_SELECTION_BUFFER_SIZE 0x0DF4 -#define GL_TEXTURE_WIDTH 0x1000 -#define GL_TEXTURE_HEIGHT 0x1001 -#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 -#define GL_TEXTURE_BORDER_COLOR 0x1004 -#define GL_TEXTURE_BORDER 0x1005 -#define GL_DONT_CARE 0x1100 -#define GL_FASTEST 0x1101 -#define GL_NICEST 0x1102 -#define GL_LIGHT0 0x4000 -#define GL_LIGHT1 0x4001 -#define GL_LIGHT2 0x4002 -#define GL_LIGHT3 0x4003 -#define GL_LIGHT4 0x4004 -#define GL_LIGHT5 0x4005 -#define GL_LIGHT6 0x4006 -#define GL_LIGHT7 0x4007 -#define GL_AMBIENT 0x1200 -#define GL_DIFFUSE 0x1201 -#define GL_SPECULAR 0x1202 -#define GL_POSITION 0x1203 -#define GL_SPOT_DIRECTION 0x1204 -#define GL_SPOT_EXPONENT 0x1205 -#define GL_SPOT_CUTOFF 0x1206 -#define GL_CONSTANT_ATTENUATION 0x1207 -#define GL_LINEAR_ATTENUATION 0x1208 -#define GL_QUADRATIC_ATTENUATION 0x1209 -#define GL_COMPILE 0x1300 -#define GL_COMPILE_AND_EXECUTE 0x1301 -#define GL_CLEAR 0x1500 -#define GL_AND 0x1501 -#define GL_AND_REVERSE 0x1502 -#define GL_COPY 0x1503 -#define GL_AND_INVERTED 0x1504 -#define GL_NOOP 0x1505 -#define GL_XOR 0x1506 -#define GL_OR 0x1507 -#define GL_NOR 0x1508 -#define GL_EQUIV 0x1509 -#define GL_INVERT 0x150A -#define GL_OR_REVERSE 0x150B -#define GL_COPY_INVERTED 0x150C -#define GL_OR_INVERTED 0x150D -#define GL_NAND 0x150E -#define GL_SET 0x150F -#define GL_EMISSION 0x1600 -#define GL_SHININESS 0x1601 -#define GL_AMBIENT_AND_DIFFUSE 0x1602 -#define GL_COLOR_INDEXES 0x1603 -#define GL_MODELVIEW 0x1700 -#define GL_PROJECTION 0x1701 -#define GL_TEXTURE 0x1702 -#define GL_COLOR 0x1800 -#define GL_DEPTH 0x1801 -#define GL_STENCIL 0x1802 -#define GL_COLOR_INDEX 0x1900 -#define GL_STENCIL_INDEX 0x1901 -#define GL_DEPTH_COMPONENT 0x1902 -#define GL_RED 0x1903 -#define GL_GREEN 0x1904 -#define GL_BLUE 0x1905 -#define GL_ALPHA 0x1906 -#define GL_RGB 0x1907 -#define GL_RGBA 0x1908 -#define GL_LUMINANCE 0x1909 -#define GL_LUMINANCE_ALPHA 0x190A -#define GL_BITMAP 0x1A00 -#define GL_POINT 0x1B00 -#define GL_LINE 0x1B01 -#define GL_FILL 0x1B02 -#define GL_RENDER 0x1C00 -#define GL_FEEDBACK 0x1C01 -#define GL_SELECT 0x1C02 -#define GL_FLAT 0x1D00 -#define GL_SMOOTH 0x1D01 -#define GL_KEEP 0x1E00 -#define GL_REPLACE 0x1E01 -#define GL_INCR 0x1E02 -#define GL_DECR 0x1E03 -#define GL_VENDOR 0x1F00 -#define GL_RENDERER 0x1F01 -#define GL_VERSION 0x1F02 -#define GL_EXTENSIONS 0x1F03 -#define GL_S 0x2000 -#define GL_T 0x2001 -#define GL_R 0x2002 -#define GL_Q 0x2003 -#define GL_MODULATE 0x2100 -#define GL_DECAL 0x2101 -#define GL_TEXTURE_ENV_MODE 0x2200 -#define GL_TEXTURE_ENV_COLOR 0x2201 -#define GL_TEXTURE_ENV 0x2300 -#define GL_EYE_LINEAR 0x2400 -#define GL_OBJECT_LINEAR 0x2401 -#define GL_SPHERE_MAP 0x2402 -#define GL_TEXTURE_GEN_MODE 0x2500 -#define GL_OBJECT_PLANE 0x2501 -#define GL_EYE_PLANE 0x2502 -#define GL_NEAREST 0x2600 -#define GL_LINEAR 0x2601 -#define GL_NEAREST_MIPMAP_NEAREST 0x2700 -#define GL_LINEAR_MIPMAP_NEAREST 0x2701 -#define GL_NEAREST_MIPMAP_LINEAR 0x2702 -#define GL_LINEAR_MIPMAP_LINEAR 0x2703 -#define GL_TEXTURE_MAG_FILTER 0x2800 -#define GL_TEXTURE_MIN_FILTER 0x2801 -#define GL_TEXTURE_WRAP_S 0x2802 -#define GL_TEXTURE_WRAP_T 0x2803 -#define GL_CLAMP 0x2900 -#define GL_REPEAT 0x2901 -#define GL_CLIP_PLANE0 0x3000 -#define GL_CLIP_PLANE1 0x3001 -#define GL_CLIP_PLANE2 0x3002 -#define GL_CLIP_PLANE3 0x3003 -#define GL_CLIP_PLANE4 0x3004 -#define GL_CLIP_PLANE5 0x3005 -#define GL_CURRENT_BIT 0x00000001 -#define GL_POINT_BIT 0x00000002 -#define GL_LINE_BIT 0x00000004 -#define GL_POLYGON_BIT 0x00000008 -#define GL_POLYGON_STIPPLE_BIT 0x00000010 -#define GL_PIXEL_MODE_BIT 0x00000020 -#define GL_LIGHTING_BIT 0x00000040 -#define GL_FOG_BIT 0x00000080 -#define GL_DEPTH_BUFFER_BIT 0x00000100 -#define GL_ACCUM_BUFFER_BIT 0x00000200 -#define GL_STENCIL_BUFFER_BIT 0x00000400 -#define GL_VIEWPORT_BIT 0x00000800 -#define GL_TRANSFORM_BIT 0x00001000 -#define GL_ENABLE_BIT 0x00002000 -#define GL_COLOR_BUFFER_BIT 0x00004000 -#define GL_HINT_BIT 0x00008000 -#define GL_EVAL_BIT 0x00010000 -#define GL_LIST_BIT 0x00020000 -#define GL_TEXTURE_BIT 0x00040000 -#define GL_SCISSOR_BIT 0x00080000 -#define GL_ALL_ATTRIB_BITS 0x000fffff -#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 -#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 -#define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff -#define GL_POLYGON_OFFSET_UNITS 0x2A00 -#define GL_POLYGON_OFFSET_POINT 0x2A01 -#define GL_POLYGON_OFFSET_LINE 0x2A02 -#define GL_POLYGON_OFFSET_FILL 0x8037 -#define GL_POLYGON_OFFSET_FACTOR 0x8038 -#define GL_ALPHA4 0x803B -#define GL_ALPHA8 0x803C -#define GL_ALPHA12 0x803D -#define GL_ALPHA16 0x803E -#define GL_LUMINANCE4 0x803F -#define GL_LUMINANCE8 0x8040 -#define GL_LUMINANCE12 0x8041 -#define GL_LUMINANCE16 0x8042 -#define GL_LUMINANCE4_ALPHA4 0x8043 -#define GL_LUMINANCE6_ALPHA2 0x8044 -#define GL_LUMINANCE8_ALPHA8 0x8045 -#define GL_LUMINANCE12_ALPHA4 0x8046 -#define GL_LUMINANCE12_ALPHA12 0x8047 -#define GL_LUMINANCE16_ALPHA16 0x8048 -#define GL_INTENSITY 0x8049 -#define GL_INTENSITY4 0x804A -#define GL_INTENSITY8 0x804B -#define GL_INTENSITY12 0x804C -#define GL_INTENSITY16 0x804D -#define GL_R3_G3_B2 0x2A10 -#define GL_RGB4 0x804F -#define GL_RGB5 0x8050 -#define GL_RGB8 0x8051 -#define GL_RGB10 0x8052 -#define GL_RGB12 0x8053 -#define GL_RGB16 0x8054 -#define GL_RGBA2 0x8055 -#define GL_RGBA4 0x8056 -#define GL_RGB5_A1 0x8057 -#define GL_RGBA8 0x8058 -#define GL_RGB10_A2 0x8059 -#define GL_RGBA12 0x805A -#define GL_RGBA16 0x805B -#define GL_TEXTURE_RED_SIZE 0x805C -#define GL_TEXTURE_GREEN_SIZE 0x805D -#define GL_TEXTURE_BLUE_SIZE 0x805E -#define GL_TEXTURE_ALPHA_SIZE 0x805F -#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 -#define GL_TEXTURE_INTENSITY_SIZE 0x8061 -#define GL_PROXY_TEXTURE_1D 0x8063 -#define GL_PROXY_TEXTURE_2D 0x8064 -#define GL_TEXTURE_PRIORITY 0x8066 -#define GL_TEXTURE_RESIDENT 0x8067 -#define GL_TEXTURE_BINDING_1D 0x8068 -#define GL_TEXTURE_BINDING_2D 0x8069 -#define GL_VERTEX_ARRAY 0x8074 -#define GL_NORMAL_ARRAY 0x8075 -#define GL_COLOR_ARRAY 0x8076 -#define GL_INDEX_ARRAY 0x8077 -#define GL_TEXTURE_COORD_ARRAY 0x8078 -#define GL_EDGE_FLAG_ARRAY 0x8079 -#define GL_VERTEX_ARRAY_SIZE 0x807A -#define GL_VERTEX_ARRAY_TYPE 0x807B -#define GL_VERTEX_ARRAY_STRIDE 0x807C -#define GL_NORMAL_ARRAY_TYPE 0x807E -#define GL_NORMAL_ARRAY_STRIDE 0x807F -#define GL_COLOR_ARRAY_SIZE 0x8081 -#define GL_COLOR_ARRAY_TYPE 0x8082 -#define GL_COLOR_ARRAY_STRIDE 0x8083 -#define GL_INDEX_ARRAY_TYPE 0x8085 -#define GL_INDEX_ARRAY_STRIDE 0x8086 -#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 -#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 -#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A -#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C -#define GL_VERTEX_ARRAY_POINTER 0x808E -#define GL_NORMAL_ARRAY_POINTER 0x808F -#define GL_COLOR_ARRAY_POINTER 0x8090 -#define GL_INDEX_ARRAY_POINTER 0x8091 -#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 -#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 -#define GL_V2F 0x2A20 -#define GL_V3F 0x2A21 -#define GL_C4UB_V2F 0x2A22 -#define GL_C4UB_V3F 0x2A23 -#define GL_C3F_V3F 0x2A24 -#define GL_N3F_V3F 0x2A25 -#define GL_C4F_N3F_V3F 0x2A26 -#define GL_T2F_V3F 0x2A27 -#define GL_T4F_V4F 0x2A28 -#define GL_T2F_C4UB_V3F 0x2A29 -#define GL_T2F_C3F_V3F 0x2A2A -#define GL_T2F_N3F_V3F 0x2A2B -#define GL_T2F_C4F_N3F_V3F 0x2A2C -#define GL_T4F_C4F_N3F_V4F 0x2A2D - -#define glAccum GlobalOpenGL().m_glAccum -#define glAlphaFunc GlobalOpenGL().m_glAlphaFunc -#define glAreTexturesResident GlobalOpenGL().m_glAreTexturesResident -#define glArrayElement GlobalOpenGL().m_glArrayElement -#define glBegin GlobalOpenGL().m_glBegin -#define glBindTexture GlobalOpenGL().m_glBindTexture -#define glBitmap GlobalOpenGL().m_glBitmap -#define glBlendFunc GlobalOpenGL().m_glBlendFunc -#define glCallList GlobalOpenGL().m_glCallList -#define glCallLists GlobalOpenGL().m_glCallLists -#define glClear GlobalOpenGL().m_glClear -#define glClearAccum GlobalOpenGL().m_glClearAccum -#define glClearColor GlobalOpenGL().m_glClearColor -#define glClearDepth GlobalOpenGL().m_glClearDepth -#define glClearIndex GlobalOpenGL().m_glClearIndex -#define glClearStencil GlobalOpenGL().m_glClearStencil -#define glClipPlane GlobalOpenGL().m_glClipPlane -#define glColor3b GlobalOpenGL().m_glColor3b -#define glColor3bv GlobalOpenGL().m_glColor3bv -#define glColor3d GlobalOpenGL().m_glColor3d -#define glColor3dv GlobalOpenGL().m_glColor3dv -#define glColor3f GlobalOpenGL().m_glColor3f -#define glColor3fv GlobalOpenGL().m_glColor3fv -#define glColor3i GlobalOpenGL().m_glColor3i -#define glColor3iv GlobalOpenGL().m_glColor3iv -#define glColor3s GlobalOpenGL().m_glColor3s -#define glColor3sv GlobalOpenGL().m_glColor3sv -#define glColor3ub GlobalOpenGL().m_glColor3ub -#define glColor3ubv GlobalOpenGL().m_glColor3ubv -#define glColor3ui GlobalOpenGL().m_glColor3ui -#define glColor3uiv GlobalOpenGL().m_glColor3uiv -#define glColor3us GlobalOpenGL().m_glColor3us -#define glColor3usv GlobalOpenGL().m_glColor3usv -#define glColor4b GlobalOpenGL().m_glColor4b -#define glColor4bv GlobalOpenGL().m_glColor4bv -#define glColor4d GlobalOpenGL().m_glColor4d -#define glColor4dv GlobalOpenGL().m_glColor4dv -#define glColor4f GlobalOpenGL().m_glColor4f -#define glColor4fv GlobalOpenGL().m_glColor4fv -#define glColor4i GlobalOpenGL().m_glColor4i -#define glColor4iv GlobalOpenGL().m_glColor4iv -#define glColor4s GlobalOpenGL().m_glColor4s -#define glColor4sv GlobalOpenGL().m_glColor4sv -#define glColor4ub GlobalOpenGL().m_glColor4ub -#define glColor4ubv GlobalOpenGL().m_glColor4ubv -#define glColor4ui GlobalOpenGL().m_glColor4ui -#define glColor4uiv GlobalOpenGL().m_glColor4uiv -#define glColor4us GlobalOpenGL().m_glColor4us -#define glColor4usv GlobalOpenGL().m_glColor4usv -#define glColorMask GlobalOpenGL().m_glColorMask -#define glColorMaterial GlobalOpenGL().m_glColorMaterial -#define glColorPointer GlobalOpenGL().m_glColorPointer -#define glCopyPixels GlobalOpenGL().m_glCopyPixels -#define glCopyTexImage1D GlobalOpenGL().m_glCopyTexImage1D -#define glCopyTexImage2D GlobalOpenGL().m_glCopyTexImage2D -#define glCopyTexSubImage1D GlobalOpenGL().m_glCopyTexSubImage1D -#define glCopyTexSubImage2D GlobalOpenGL().m_glCopyTexSubImage2D -#define glCullFace GlobalOpenGL().m_glCullFace -#define glDeleteLists GlobalOpenGL().m_glDeleteLists -#define glDeleteTextures GlobalOpenGL().m_glDeleteTextures -#define glDepthFunc GlobalOpenGL().m_glDepthFunc -#define glDepthMask GlobalOpenGL().m_glDepthMask -#define glDepthRange GlobalOpenGL().m_glDepthRange -#define glDisable GlobalOpenGL().m_glDisable -#define glDisableClientState GlobalOpenGL().m_glDisableClientState -#define glDrawArrays GlobalOpenGL().m_glDrawArrays -#define glDrawBuffer GlobalOpenGL().m_glDrawBuffer -#define glDrawElements GlobalOpenGL().m_glDrawElements -#define glDrawPixels GlobalOpenGL().m_glDrawPixels -#define glEdgeFlag GlobalOpenGL().m_glEdgeFlag -#define glEdgeFlagPointer GlobalOpenGL().m_glEdgeFlagPointer -#define glEdgeFlagv GlobalOpenGL().m_glEdgeFlagv -#define glEnable GlobalOpenGL().m_glEnable -#define glEnableClientState GlobalOpenGL().m_glEnableClientState -#define glEnd GlobalOpenGL().m_glEnd -#define glEndList GlobalOpenGL().m_glEndList -#define glEvalCoord1d GlobalOpenGL().m_glEvalCoord1d -#define glEvalCoord1dv GlobalOpenGL().m_glEvalCoord1dv -#define glEvalCoord1f GlobalOpenGL().m_glEvalCoord1f -#define glEvalCoord1fv GlobalOpenGL().m_glEvalCoord1fv -#define glEvalCoord2d GlobalOpenGL().m_glEvalCoord2d -#define glEvalCoord2dv GlobalOpenGL().m_glEvalCoord2dv -#define glEvalCoord2f GlobalOpenGL().m_glEvalCoord2f -#define glEvalCoord2fv GlobalOpenGL().m_glEvalCoord2fv -#define glEvalMesh1 GlobalOpenGL().m_glEvalMesh1 -#define glEvalMesh2 GlobalOpenGL().m_glEvalMesh2 -#define glEvalPoint1 GlobalOpenGL().m_glEvalPoint1 -#define glEvalPoint2 GlobalOpenGL().m_glEvalPoint2 -#define glFeedbackBuffer GlobalOpenGL().m_glFeedbackBuffer -#define glFinish GlobalOpenGL().m_glFinish -#define glFlush GlobalOpenGL().m_glFlush -#define glFogf GlobalOpenGL().m_glFogf -#define glFogfv GlobalOpenGL().m_glFogfv -#define glFogi GlobalOpenGL().m_glFogi -#define glFogiv GlobalOpenGL().m_glFogiv -#define glFrontFace GlobalOpenGL().m_glFrontFace -#define glFrustum GlobalOpenGL().m_glFrustum -#define glGenLists GlobalOpenGL().m_glGenLists -#define glGenTextures GlobalOpenGL().m_glGenTextures -#define glGetBooleanv GlobalOpenGL().m_glGetBooleanv -#define glGetClipPlane GlobalOpenGL().m_glGetClipPlane -#define glGetDoublev GlobalOpenGL().m_glGetDoublev -#define glGetError GlobalOpenGL().m_glGetError -#define glGetFloatv GlobalOpenGL().m_glGetFloatv -#define glGetIntegerv GlobalOpenGL().m_glGetIntegerv -#define glGetLightfv GlobalOpenGL().m_glGetLightfv -#define glGetLightiv GlobalOpenGL().m_glGetLightiv -#define glGetMapdv GlobalOpenGL().m_glGetMapdv -#define glGetMapfv GlobalOpenGL().m_glGetMapfv -#define glGetMapiv GlobalOpenGL().m_glGetMapiv -#define glGetMaterialfv GlobalOpenGL().m_glGetMaterialfv -#define glGetMaterialiv GlobalOpenGL().m_glGetMaterialiv -#define glGetPixelMapfv GlobalOpenGL().m_glGetPixelMapfv -#define glGetPixelMapuiv GlobalOpenGL().m_glGetPixelMapuiv -#define glGetPixelMapusv GlobalOpenGL().m_glGetPixelMapusv -#define glGetPointerv GlobalOpenGL().m_glGetPointerv -#define glGetPolygonStipple GlobalOpenGL().m_glGetPolygonStipple -#define glGetString GlobalOpenGL().m_glGetString -#define glGetTexEnvfv GlobalOpenGL().m_glGetTexEnvfv -#define glGetTexEnviv GlobalOpenGL().m_glGetTexEnviv -#define glGetTexGendv GlobalOpenGL().m_glGetTexGendv -#define glGetTexGenfv GlobalOpenGL().m_glGetTexGenfv -#define glGetTexGeniv GlobalOpenGL().m_glGetTexGeniv -#define glGetTexImage GlobalOpenGL().m_glGetTexImage -#define glGetTexLevelParameterfv GlobalOpenGL().m_glGetTexLevelParameter -#define glGetTexLevelParameteriv GlobalOpenGL().m_glGetTexLevelParameteriv -#define glGetTexParameterfv GlobalOpenGL().m_glGetTexParameterfv -#define glGetTexParameteriv GlobalOpenGL().m_glGetTexParameteriv -#define glHint GlobalOpenGL().m_glHint -#define glIndexMask GlobalOpenGL().m_glIndexMask -#define glIndexPointer GlobalOpenGL().m_glIndexPointer -#define glIndexd GlobalOpenGL().m_glIndexd -#define glIndexdv GlobalOpenGL().m_glIndexdv -#define glIndexf GlobalOpenGL().m_glIndexf -#define glIndexfv GlobalOpenGL().m_glIndexfv -#define glIndexi GlobalOpenGL().m_glIndexi -#define glIndexiv GlobalOpenGL().m_glIndexiv -#define glIndexs GlobalOpenGL().m_glIndexs -#define glIndexsv GlobalOpenGL().m_glIndexsv -#define glIndexub GlobalOpenGL().m_glIndexub -#define glIndexubv GlobalOpenGL().m_glIndexubv -#define glInitNames GlobalOpenGL().m_glInitNames -#define glInterleavedArrays GlobalOpenGL().m_glInterleavedArrays -#define glIsEnabled GlobalOpenGL().m_glIsEnabled -#define glIsList GlobalOpenGL().m_glIsList -#define glIsTexture GlobalOpenGL().m_glIsTexture -#define glLightModelf GlobalOpenGL().m_glLightModelf -#define glLightModelfv GlobalOpenGL().m_glLightModelfv -#define glLightModeli GlobalOpenGL().m_glLightModeli -#define glLightModeliv GlobalOpenGL().m_glLightModeliv -#define glLightf GlobalOpenGL().m_glLightf -#define glLightfv GlobalOpenGL().m_glLightfv -#define glLighti GlobalOpenGL().m_glLighti -#define glLightiv GlobalOpenGL().m_glLightiv -#define glLineStipple GlobalOpenGL().m_glLineStipple -#define glLineWidth GlobalOpenGL().m_glLineWidth -#define glListBase GlobalOpenGL().m_glListBase -#define glLoadIdentity GlobalOpenGL().m_glLoadIdentity -#define glLoadMatrixd GlobalOpenGL().m_glLoadMatrixd -#define glLoadMatrixf GlobalOpenGL().m_glLoadMatrixf -#define glLoadName GlobalOpenGL().m_glLoadName -#define glLogicOp GlobalOpenGL().m_glLogicOp -#define glMap1d GlobalOpenGL().m_glMap1d -#define glMap1f GlobalOpenGL().m_glMap1f -#define glMap2d GlobalOpenGL().m_glMap2d -#define glMap2f GlobalOpenGL().m_glMap2f -#define glMapGrid1d GlobalOpenGL().m_glMapGrid1d -#define glMapGrid1f GlobalOpenGL().m_glMapGrid1f -#define glMapGrid2d GlobalOpenGL().m_glMapGrid2d -#define glMapGrid2f GlobalOpenGL().m_glMapGrid2f -#define glMaterialf GlobalOpenGL().m_glMaterialf -#define glMaterialfv GlobalOpenGL().m_glMaterialfv -#define glMateriali GlobalOpenGL().m_glMateriali -#define glMaterialiv GlobalOpenGL().m_glMaterialiv -#define glMatrixMode GlobalOpenGL().m_glMatrixMode -#define glMultMatrixd GlobalOpenGL().m_glMultMatrixd -#define glMultMatrixf GlobalOpenGL().m_glMultMatrixf -#define glNewList GlobalOpenGL().m_glNewList -#define glNormal3b GlobalOpenGL().m_glNormal3b -#define glNormal3bv GlobalOpenGL().m_glNormal3bv -#define glNormal3d GlobalOpenGL().m_glNormal3d -#define glNormal3dv GlobalOpenGL().m_glNormal3dv -#define glNormal3f GlobalOpenGL().m_glNormal3f -#define glNormal3fv GlobalOpenGL().m_glNormal3fv -#define glNormal3i GlobalOpenGL().m_glNormal3i -#define glNormal3iv GlobalOpenGL().m_glNormal3iv -#define glNormal3s GlobalOpenGL().m_glNormal3s -#define glNormal3sv GlobalOpenGL().m_glNormal3sv -#define glNormalPointer GlobalOpenGL().m_glNormalPointer -#define glOrtho GlobalOpenGL().m_glOrtho -#define glPassThrough GlobalOpenGL().m_glPassThrough -#define glPixelMapfv GlobalOpenGL().m_glPixelMapfv -#define glPixelMapuiv GlobalOpenGL().m_glPixelMapuiv -#define glPixelMapusv GlobalOpenGL().m_glPixelMapusv -#define glPixelStoref GlobalOpenGL().m_glPixelStoref -#define glPixelStorei GlobalOpenGL().m_glPixelStorei -#define glPixelTransferf GlobalOpenGL().m_glPixelTransferf -#define glPixelTransferi GlobalOpenGL().m_glPixelTransferi -#define glPixelZoom GlobalOpenGL().m_glPixelZoom -#define glPointSize GlobalOpenGL().m_glPointSize -#define glPolygonMode GlobalOpenGL().m_glPolygonMode -#define glPolygonOffset GlobalOpenGL().m_glPolygonOffset -#define glPolygonStipple GlobalOpenGL().m_glPolygonStipple -#define glPopAttrib GlobalOpenGL().m_glPopAttrib -#define glPopClientAttrib GlobalOpenGL().m_glPopClientAttrib -#define glPopMatrix GlobalOpenGL().m_glPopMatrix -#define glPopName GlobalOpenGL().m_glPopName -#define glPrioritizeTextures GlobalOpenGL().m_glPrioritizeTextures -#define glPushAttrib GlobalOpenGL().m_glPushAttrib -#define glPushClientAttrib GlobalOpenGL().m_glPushClientAttrib -#define glPushMatrix GlobalOpenGL().m_glPushMatrix -#define glPushName GlobalOpenGL().m_glPushName -#define glRasterPos2d GlobalOpenGL().m_glRasterPos2d -#define glRasterPos2dv GlobalOpenGL().m_glRasterPos2dv -#define glRasterPos2f GlobalOpenGL().m_glRasterPos2f -#define glRasterPos2fv GlobalOpenGL().m_glRasterPos2fv -#define glRasterPos2i GlobalOpenGL().m_glRasterPos2i -#define glRasterPos2iv GlobalOpenGL().m_glRasterPos2iv -#define glRasterPos2s GlobalOpenGL().m_glRasterPos2s -#define glRasterPos2sv GlobalOpenGL().m_glRasterPos2sv -#define glRasterPos3d GlobalOpenGL().m_glRasterPos3d -#define glRasterPos3dv GlobalOpenGL().m_glRasterPos3dv -#define glRasterPos3f GlobalOpenGL().m_glRasterPos3f -#define glRasterPos3fv GlobalOpenGL().m_glRasterPos3fv -#define glRasterPos3i GlobalOpenGL().m_glRasterPos3i -#define glRasterPos3iv GlobalOpenGL().m_glRasterPos3iv -#define glRasterPos3s GlobalOpenGL().m_glRasterPos3s -#define glRasterPos3sv GlobalOpenGL().m_glRasterPos3sv -#define glRasterPos4d GlobalOpenGL().m_glRasterPos4d -#define glRasterPos4dv GlobalOpenGL().m_glRasterPos4dv -#define glRasterPos4f GlobalOpenGL().m_glRasterPos4f -#define glRasterPos4fv GlobalOpenGL().m_glRasterPos4fv -#define glRasterPos4i GlobalOpenGL().m_glRasterPos4i -#define glRasterPos4iv GlobalOpenGL().m_glRasterPos4iv -#define glRasterPos4s GlobalOpenGL().m_glRasterPos4s -#define glRasterPos4sv GlobalOpenGL().m_glRasterPos4sv -#define glReadBuffer GlobalOpenGL().m_glReadBuffer -#define glReadPixels GlobalOpenGL().m_glReadPixels -#define glRectd GlobalOpenGL().m_glRectd -#define glRectdv GlobalOpenGL().m_glRectdv -#define glRectf GlobalOpenGL().m_glRectf -#define glRectfv GlobalOpenGL().m_glRectfv -#define glRecti GlobalOpenGL().m_glRecti -#define glRectiv GlobalOpenGL().m_glRectiv -#define glRects GlobalOpenGL().m_glRects -#define glRectsv GlobalOpenGL().m_glRectsv -#define glRenderMode GlobalOpenGL().m_glRenderMode -#define glRotated GlobalOpenGL().m_glRotated -#define glRotatef GlobalOpenGL().m_glRotatef -#define glScaled GlobalOpenGL().m_glScaled -#define glScalef GlobalOpenGL().m_glScalef -#define glScissor GlobalOpenGL().m_glScissor -#define glSelectBuffer GlobalOpenGL().m_glSelectBuffer -#define glShadeModel GlobalOpenGL().m_glShadeModel -#define glStencilFunc GlobalOpenGL().m_glStencilFunc -#define glStencilMask GlobalOpenGL().m_glStencilMask -#define glStencilOp GlobalOpenGL().m_glStencilOp -#define glTexCoord1d GlobalOpenGL().m_glTexCoord1d -#define glTexCoord1dv GlobalOpenGL().m_glTexCoord1dv -#define glTexCoord1f GlobalOpenGL().m_glTexCoord1f -#define glTexCoord1fv GlobalOpenGL().m_glTexCoord1fv -#define glTexCoord1i GlobalOpenGL().m_glTexCoord1i -#define glTexCoord1iv GlobalOpenGL().m_glTexCoord1iv -#define glTexCoord1s GlobalOpenGL().m_glTexCoord1s -#define glTexCoord1sv GlobalOpenGL().m_glTexCoord1sv -#define glTexCoord2d GlobalOpenGL().m_glTexCoord2d -#define glTexCoord2dv GlobalOpenGL().m_glTexCoord2dv -#define glTexCoord2f GlobalOpenGL().m_glTexCoord2f -#define glTexCoord2fv GlobalOpenGL().m_glTexCoord2fv -#define glTexCoord2i GlobalOpenGL().m_glTexCoord2i -#define glTexCoord2iv GlobalOpenGL().m_glTexCoord2iv -#define glTexCoord2s GlobalOpenGL().m_glTexCoord2s -#define glTexCoord2sv GlobalOpenGL().m_glTexCoord2sv -#define glTexCoord3d GlobalOpenGL().m_glTexCoord3d -#define glTexCoord3dv GlobalOpenGL().m_glTexCoord3dv -#define glTexCoord3f GlobalOpenGL().m_glTexCoord3f -#define glTexCoord3fv GlobalOpenGL().m_glTexCoord3fv -#define glTexCoord3i GlobalOpenGL().m_glTexCoord3i -#define glTexCoord3iv GlobalOpenGL().m_glTexCoord3iv -#define glTexCoord3s GlobalOpenGL().m_glTexCoord3s -#define glTexCoord3sv GlobalOpenGL().m_glTexCoord3sv -#define glTexCoord4d GlobalOpenGL().m_glTexCoord4d -#define glTexCoord4dv GlobalOpenGL().m_glTexCoord4dv -#define glTexCoord4f GlobalOpenGL().m_glTexCoord4f -#define glTexCoord4fv GlobalOpenGL().m_glTexCoord4fv -#define glTexCoord4i GlobalOpenGL().m_glTexCoord4i -#define glTexCoord4iv GlobalOpenGL().m_glTexCoord4iv -#define glTexCoord4s GlobalOpenGL().m_glTexCoord4s -#define glTexCoord4sv GlobalOpenGL().m_glTexCoord4sv -#define glTexCoordPointer GlobalOpenGL().m_glTexCoordPointer -#define glTexEnvf GlobalOpenGL().m_glTexEnvf -#define glTexEnvfv GlobalOpenGL().m_glTexEnvfv -#define glTexEnvi GlobalOpenGL().m_glTexEnvi -#define glTexEnviv GlobalOpenGL().m_glTexEnviv -#define glTexGend GlobalOpenGL().m_glTexGend -#define glTexGendv GlobalOpenGL().m_glTexGendv -#define glTexGenf GlobalOpenGL().m_glTexGenf -#define glTexGenfv GlobalOpenGL().m_glTexGenfv -#define glTexGeni GlobalOpenGL().m_glTexGeni -#define glTexGeniv GlobalOpenGL().m_glTexGeniv -#define glTexImage1D GlobalOpenGL().m_glTexImage1D -#define glTexImage2D GlobalOpenGL().m_glTexImage2D -#define glTexParameterf GlobalOpenGL().m_glTexParameterf -#define glTexParameterfv GlobalOpenGL().m_glTexParameterfv -#define glTexParameteri GlobalOpenGL().m_glTexParameteri -#define glTexParameteriv GlobalOpenGL().m_glTexParameteriv -#define glTexSubImage1D GlobalOpenGL().m_glTexSubImage1D -#define glTexSubImage2D GlobalOpenGL().m_glTexSubImage2D -#define glTranslated GlobalOpenGL().m_glTranslated -#define glTranslatef GlobalOpenGL().m_glTranslatef -#define glVertex2d GlobalOpenGL().m_glVertex2d -#define glVertex2dv GlobalOpenGL().m_glVertex2dv -#define glVertex2f GlobalOpenGL().m_glVertex2f -#define glVertex2fv GlobalOpenGL().m_glVertex2fv -#define glVertex2i GlobalOpenGL().m_glVertex2i -#define glVertex2iv GlobalOpenGL().m_glVertex2iv -#define glVertex2s GlobalOpenGL().m_glVertex2s -#define glVertex2sv GlobalOpenGL().m_glVertex2sv -#define glVertex3d GlobalOpenGL().m_glVertex3d -#define glVertex3dv GlobalOpenGL().m_glVertex3dv -#define glVertex3f GlobalOpenGL().m_glVertex3f -#define glVertex3fv GlobalOpenGL().m_glVertex3fv -#define glVertex3i GlobalOpenGL().m_glVertex3i -#define glVertex3iv GlobalOpenGL().m_glVertex3iv -#define glVertex3s GlobalOpenGL().m_glVertex3s -#define glVertex3sv GlobalOpenGL().m_glVertex3sv -#define glVertex4d GlobalOpenGL().m_glVertex4d -#define glVertex4dv GlobalOpenGL().m_glVertex4dv -#define glVertex4f GlobalOpenGL().m_glVertex4f -#define glVertex4fv GlobalOpenGL().m_glVertex4fv -#define glVertex4i GlobalOpenGL().m_glVertex4i -#define glVertex4iv GlobalOpenGL().m_glVertex4iv -#define glVertex4s GlobalOpenGL().m_glVertex4s -#define glVertex4sv GlobalOpenGL().m_glVertex4sv -#define glVertexPointer GlobalOpenGL().m_glVertexPointer -#define glViewport GlobalOpenGL().m_glViewport - -#endif - - -#if !defined( GL_EXT_vertex_array ) -#define GL_EXT_vertex_array 1 - -#define GL_VERTEX_ARRAY_EXT 0x8074 -#define GL_NORMAL_ARRAY_EXT 0x8075 -#define GL_COLOR_ARRAY_EXT 0x8076 -#define GL_INDEX_ARRAY_EXT 0x8077 -#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 -#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 -#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A -#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B -#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C -#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D -#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E -#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F -#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 -#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 -#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 -#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 -#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 -#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 -#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 -#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 -#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 -#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 -#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A -#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B -#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C -#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D -#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E -#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F -#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 -#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 -#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 -#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 -#define GL_DOUBLE_EXT GL_DOUBLE - -#endif - - -#if !defined( GL_EXT_bgra ) -#define GL_EXT_bgra 1 - -#define GL_BGR_EXT 0x80E0 -#define GL_BGRA_EXT 0x80E1 - -#endif - - -#if !defined( GL_EXT_paletted_texture ) -#define GL_EXT_paletted_texture 1 - -#define GL_COLOR_TABLE_FORMAT_EXT 0x80D8 -#define GL_COLOR_TABLE_WIDTH_EXT 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE_EXT 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE_EXT 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE_EXT 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE_EXT 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE_EXT 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE_EXT 0x80DF - -#define GL_COLOR_INDEX1_EXT 0x80E2 -#define GL_COLOR_INDEX2_EXT 0x80E3 -#define GL_COLOR_INDEX4_EXT 0x80E4 -#define GL_COLOR_INDEX8_EXT 0x80E5 -#define GL_COLOR_INDEX12_EXT 0x80E6 -#define GL_COLOR_INDEX16_EXT 0x80E7 - -#define GL_LOGIC_OP GL_INDEX_LOGIC_OP -#define GL_TEXTURE_COMPONENTS GL_TEXTURE_INTERNAL_FORMAT - -#endif - -#if !defined( GL_ARB_multitexture ) -#define GL_ARB_multitexture 1 - -#define GL_TEXTURE0_ARB 0x84C0 -#define GL_TEXTURE1_ARB 0x84C1 -#define GL_TEXTURE2_ARB 0x84C2 -#define GL_TEXTURE3_ARB 0x84C3 -#define GL_TEXTURE4_ARB 0x84C4 -#define GL_TEXTURE5_ARB 0x84C5 -#define GL_TEXTURE6_ARB 0x84C6 -#define GL_TEXTURE7_ARB 0x84C7 -#define GL_TEXTURE8_ARB 0x84C8 -#define GL_TEXTURE9_ARB 0x84C9 -#define GL_TEXTURE10_ARB 0x84CA -#define GL_TEXTURE11_ARB 0x84CB -#define GL_TEXTURE12_ARB 0x84CC -#define GL_TEXTURE13_ARB 0x84CD -#define GL_TEXTURE14_ARB 0x84CE -#define GL_TEXTURE15_ARB 0x84CF -#define GL_TEXTURE16_ARB 0x84D0 -#define GL_TEXTURE17_ARB 0x84D1 -#define GL_TEXTURE18_ARB 0x84D2 -#define GL_TEXTURE19_ARB 0x84D3 -#define GL_TEXTURE20_ARB 0x84D4 -#define GL_TEXTURE21_ARB 0x84D5 -#define GL_TEXTURE22_ARB 0x84D6 -#define GL_TEXTURE23_ARB 0x84D7 -#define GL_TEXTURE24_ARB 0x84D8 -#define GL_TEXTURE25_ARB 0x84D9 -#define GL_TEXTURE26_ARB 0x84DA -#define GL_TEXTURE27_ARB 0x84DB -#define GL_TEXTURE28_ARB 0x84DC -#define GL_TEXTURE29_ARB 0x84DD -#define GL_TEXTURE30_ARB 0x84DE -#define GL_TEXTURE31_ARB 0x84DF -#define GL_ACTIVE_TEXTURE_ARB 0x84E0 -#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 -#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 - -#define glActiveTextureARB GlobalOpenGL().m_glActiveTextureARB -#define glClientActiveTextureARB GlobalOpenGL().m_glClientActiveTextureARB -#define glMultiTexCoord1dARB GlobalOpenGL().m_glMultiTexCoord1dARB -#define glMultiTexCoord1dvARB GlobalOpenGL().m_glMultiTexCoord1dvARB -#define glMultiTexCoord1fARB GlobalOpenGL().m_glMultiTexCoord1fARB -#define glMultiTexCoord1fvARB GlobalOpenGL().m_glMultiTexCoord1fvARB -#define glMultiTexCoord1iARB GlobalOpenGL().m_glMultiTexCoord1iARB -#define glMultiTexCoord1ivARB GlobalOpenGL().m_glMultiTexCoord1ivARB -#define glMultiTexCoord1sARB GlobalOpenGL().m_glMultiTexCoord1sARB -#define glMultiTexCoord1svARB GlobalOpenGL().m_glMultiTexCoord1svARB -#define glMultiTexCoord2dARB GlobalOpenGL().m_glMultiTexCoord2dARB -#define glMultiTexCoord2dvARB GlobalOpenGL().m_glMultiTexCoord2dvARB -#define glMultiTexCoord2fARB GlobalOpenGL().m_glMultiTexCoord2fARB -#define glMultiTexCoord2fvARB GlobalOpenGL().m_glMultiTexCoord2fvARB -#define glMultiTexCoord2iARB GlobalOpenGL().m_glMultiTexCoord2iARB -#define glMultiTexCoord2ivARB GlobalOpenGL().m_glMultiTexCoord2ivARB -#define glMultiTexCoord2sARB GlobalOpenGL().m_glMultiTexCoord2sARB -#define glMultiTexCoord2svARB GlobalOpenGL().m_glMultiTexCoord2svARB -#define glMultiTexCoord3dARB GlobalOpenGL().m_glMultiTexCoord3dARB -#define glMultiTexCoord3dvARB GlobalOpenGL().m_glMultiTexCoord3dvARB -#define glMultiTexCoord3fARB GlobalOpenGL().m_glMultiTexCoord3fARB -#define glMultiTexCoord3fvARB GlobalOpenGL().m_glMultiTexCoord3fvARB -#define glMultiTexCoord3iARB GlobalOpenGL().m_glMultiTexCoord3iARB -#define glMultiTexCoord3ivARB GlobalOpenGL().m_glMultiTexCoord3ivARB -#define glMultiTexCoord3sARB GlobalOpenGL().m_glMultiTexCoord3sARB -#define glMultiTexCoord3svARB GlobalOpenGL().m_glMultiTexCoord3svARB -#define glMultiTexCoord4dARB GlobalOpenGL().m_glMultiTexCoord4dARB -#define glMultiTexCoord4dvARB GlobalOpenGL().m_glMultiTexCoord4dvARB -#define glMultiTexCoord4fARB GlobalOpenGL().m_glMultiTexCoord4fARB -#define glMultiTexCoord4fvARB GlobalOpenGL().m_glMultiTexCoord4fvARB -#define glMultiTexCoord4iARB GlobalOpenGL().m_glMultiTexCoord4iARB -#define glMultiTexCoord4ivARB GlobalOpenGL().m_glMultiTexCoord4ivARB -#define glMultiTexCoord4sARB GlobalOpenGL().m_glMultiTexCoord4sARB -#define glMultiTexCoord4svARB GlobalOpenGL().m_glMultiTexCoord4svARB - -#endif - - -// EXT_texture_compression_s3tc -#if !defined( GL_EXT_texture_compression_s3tc ) -#define GL_EXT_texture_compression_s3tc 1 - -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 - -#endif - - -// ARB_texture_compression -#if !defined( GL_ARB_texture_compression ) -#define GL_ARB_texture_compression 1 - -#define GL_COMPRESSED_ALPHA_ARB 0x84E9 -#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB -#define GL_COMPRESSED_INTENSITY_ARB 0x84EC -#define GL_COMPRESSED_RGB_ARB 0x84ED -#define GL_COMPRESSED_RGBA_ARB 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 -#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 - -#define glCompressedTexImage3DARB GlobalOpenGL().m_glCompressedTexImage3DARB -#define glCompressedTexImage2DARB GlobalOpenGL().m_glCompressedTexImage2DARB -#define glCompressedTexImage1DARB GlobalOpenGL().m_glCompressedTexImage1DARB -#define glCompressedTexSubImage3DARB GlobalOpenGL().m_glCompressedTexSubImage3DARB -#define glCompressedTexSubImage2DARB GlobalOpenGL().m_glCompressedTexSubImage2DARB -#define glCompressedTexSubImage1DARB GlobalOpenGL().m_glCompressedTexSubImage1DARB -#define glGetCompressedTexImageARB GlobalOpenGL().m_glGetCompressedTexImageARB - -#endif - - -// GL 1.2 - -#if !defined( GL_VERSION_1_2 ) - -#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 -#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 -#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_UNSIGNED_BYTE_3_3_2 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2 0x8036 -#define GL_RESCALE_NORMAL 0x803A -#define GL_TEXTURE_BINDING_3D 0x806A -#define GL_PACK_SKIP_IMAGES 0x806B -#define GL_PACK_IMAGE_HEIGHT 0x806C -#define GL_UNPACK_SKIP_IMAGES 0x806D -#define GL_UNPACK_IMAGE_HEIGHT 0x806E -#define GL_TEXTURE_3D 0x806F -#define GL_PROXY_TEXTURE_3D 0x8070 -#define GL_TEXTURE_DEPTH 0x8071 -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE 0x8073 -#define GL_BGR 0x80E0 -#define GL_BGRA 0x80E1 -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_ELEMENTS_INDICES 0x80E9 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_TEXTURE_MIN_LOD 0x813A -#define GL_TEXTURE_MAX_LOD 0x813B -#define GL_TEXTURE_BASE_LEVEL 0x813C -#define GL_TEXTURE_MAX_LEVEL 0x813D -#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 -#define GL_SINGLE_COLOR 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR 0x81FA -#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E - -#define glCopyTexSubImage3D GlobalOpenGL().m_glCopyTexSubImage3D -#define glDrawRangeElements GlobalOpenGL().m_glDrawRangeElements -#define glTexImage3D GlobalOpenGL().m_glTexImage3D -#define glTexSubImage3D GlobalOpenGL().m_glTexSubImage3D - -#endif - - -// GL 1.3 - -#if !defined( GL_VERSION_1_3 ) -#define GL_VERSION_1_3 1 - -#define GL_MULTISAMPLE 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE 0x809F -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#define GL_CLAMP_TO_BORDER 0x812D -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_ACTIVE_TEXTURE 0x84E0 -#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 -#define GL_MAX_TEXTURE_UNITS 0x84E2 -#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 -#define GL_SUBTRACT 0x84E7 -#define GL_COMPRESSED_ALPHA 0x84E9 -#define GL_COMPRESSED_LUMINANCE 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB -#define GL_COMPRESSED_INTENSITY 0x84EC -#define GL_COMPRESSED_RGB 0x84ED -#define GL_COMPRESSED_RGBA 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT 0x84EF -#define GL_NORMAL_MAP 0x8511 -#define GL_REFLECTION_MAP 0x8512 -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -#define GL_COMBINE 0x8570 -#define GL_COMBINE_RGB 0x8571 -#define GL_COMBINE_ALPHA 0x8572 -#define GL_RGB_SCALE 0x8573 -#define GL_ADD_SIGNED 0x8574 -#define GL_INTERPOLATE 0x8575 -#define GL_CONSTANT 0x8576 -#define GL_PRIMARY_COLOR 0x8577 -#define GL_PREVIOUS 0x8578 -#define GL_SOURCE0_RGB 0x8580 -#define GL_SOURCE1_RGB 0x8581 -#define GL_SOURCE2_RGB 0x8582 -#define GL_SOURCE0_ALPHA 0x8588 -#define GL_SOURCE1_ALPHA 0x8589 -#define GL_SOURCE2_ALPHA 0x858A -#define GL_OPERAND0_RGB 0x8590 -#define GL_OPERAND1_RGB 0x8591 -#define GL_OPERAND2_RGB 0x8592 -#define GL_OPERAND0_ALPHA 0x8598 -#define GL_OPERAND1_ALPHA 0x8599 -#define GL_OPERAND2_ALPHA 0x859A -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 -#define GL_TEXTURE_COMPRESSED 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -#define GL_DOT3_RGB 0x86AE -#define GL_DOT3_RGBA 0x86AF -#define GL_MULTISAMPLE_BIT 0x20000000 - -#define glActiveTexture GlobalOpenGL().m_glActiveTexture -#define glClientActiveTexture GlobalOpenGL().m_glClientActiveTexture -#define glCompressedTexImage1D GlobalOpenGL().m_glCompressedTexImage1D -#define glCompressedTexImage2D GlobalOpenGL().m_glCompressedTexImage2D -#define glCompressedTexImage3D GlobalOpenGL().m_glCompressedTexImage3D -#define glCompressedTexSubImage1D GlobalOpenGL().m_glCompressedTexSubImage1D -#define glCompressedTexSubImage2D GlobalOpenGL().m_glCompressedTexSubImage2D -#define glCompressedTexSubImage3D GlobalOpenGL().m_glCompressedTexSubImage3D -#define glGetCompressedTexImage GlobalOpenGL().m_glGetCompressedTexImage -#define glLoadTransposeMatrixd GlobalOpenGL().m_glLoadTransposeMatrixd -#define glLoadTransposeMatrixf GlobalOpenGL().m_glLoadTransposeMatrixf -#define glMultTransposeMatrixd GlobalOpenGL().m_glMultTransposeMatrixd -#define glMultTransposeMatrixf GlobalOpenGL().m_glMultTransposeMatrixf -#define glMultiTexCoord1d GlobalOpenGL().m_glMultiTexCoord1d -#define glMultiTexCoord1dv GlobalOpenGL().m_glMultiTexCoord1dv -#define glMultiTexCoord1f GlobalOpenGL().m_glMultiTexCoord1f -#define glMultiTexCoord1fv GlobalOpenGL().m_glMultiTexCoord1fv -#define glMultiTexCoord1i GlobalOpenGL().m_glMultiTexCoord1i -#define glMultiTexCoord1iv GlobalOpenGL().m_glMultiTexCoord1iv -#define glMultiTexCoord1s GlobalOpenGL().m_glMultiTexCoord1s -#define glMultiTexCoord1sv GlobalOpenGL().m_glMultiTexCoord1sv -#define glMultiTexCoord2d GlobalOpenGL().m_glMultiTexCoord2d -#define glMultiTexCoord2dv GlobalOpenGL().m_glMultiTexCoord2dv -#define glMultiTexCoord2f GlobalOpenGL().m_glMultiTexCoord2f -#define glMultiTexCoord2fv GlobalOpenGL().m_glMultiTexCoord2fv -#define glMultiTexCoord2i GlobalOpenGL().m_glMultiTexCoord2i -#define glMultiTexCoord2iv GlobalOpenGL().m_glMultiTexCoord2iv -#define glMultiTexCoord2s GlobalOpenGL().m_glMultiTexCoord2s -#define glMultiTexCoord2sv GlobalOpenGL().m_glMultiTexCoord2sv -#define glMultiTexCoord3d GlobalOpenGL().m_glMultiTexCoord3d -#define glMultiTexCoord3dv GlobalOpenGL().m_glMultiTexCoord3dv -#define glMultiTexCoord3f GlobalOpenGL().m_glMultiTexCoord3f -#define glMultiTexCoord3fv GlobalOpenGL().m_glMultiTexCoord3fv -#define glMultiTexCoord3i GlobalOpenGL().m_glMultiTexCoord3i -#define glMultiTexCoord3iv GlobalOpenGL().m_glMultiTexCoord3iv -#define glMultiTexCoord3s GlobalOpenGL().m_glMultiTexCoord3s -#define glMultiTexCoord3sv GlobalOpenGL().m_glMultiTexCoord3sv -#define glMultiTexCoord4d GlobalOpenGL().m_glMultiTexCoord4d -#define glMultiTexCoord4dv GlobalOpenGL().m_glMultiTexCoord4dv -#define glMultiTexCoord4f GlobalOpenGL().m_glMultiTexCoord4f -#define glMultiTexCoord4fv GlobalOpenGL().m_glMultiTexCoord4fv -#define glMultiTexCoord4i GlobalOpenGL().m_glMultiTexCoord4i -#define glMultiTexCoord4iv GlobalOpenGL().m_glMultiTexCoord4iv -#define glMultiTexCoord4s GlobalOpenGL().m_glMultiTexCoord4s -#define glMultiTexCoord4sv GlobalOpenGL().m_glMultiTexCoord4sv -#define glSampleCoverage GlobalOpenGL().m_glSampleCoverage - -#endif - - -// GL 1.4 -#if !defined( GL_VERSION_1_4 ) -#define GL_VERSION_1_4 1 - -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_POINT_SIZE_MIN 0x8126 -#define GL_POINT_SIZE_MAX 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 -#define GL_POINT_DISTANCE_ATTENUATION 0x8129 -#define GL_GENERATE_MIPMAP 0x8191 -#define GL_GENERATE_MIPMAP_HINT 0x8192 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_DEPTH_COMPONENT24 0x81A6 -#define GL_DEPTH_COMPONENT32 0x81A7 -#define GL_MIRRORED_REPEAT 0x8370 -#define GL_FOG_COORDINATE_SOURCE 0x8450 -#define GL_FOG_COORDINATE 0x8451 -#define GL_FRAGMENT_DEPTH 0x8452 -#define GL_CURRENT_FOG_COORDINATE 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 -#define GL_FOG_COORDINATE_ARRAY 0x8457 -#define GL_COLOR_SUM 0x8458 -#define GL_CURRENT_SECONDARY_COLOR 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D -#define GL_SECONDARY_COLOR_ARRAY 0x845E -#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD -#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE -#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF -#define GL_TEXTURE_FILTER_CONTROL 0x8500 -#define GL_TEXTURE_LOD_BIAS 0x8501 -#define GL_INCR_WRAP 0x8507 -#define GL_DECR_WRAP 0x8508 -#define GL_TEXTURE_DEPTH_SIZE 0x884A -#define GL_DEPTH_TEXTURE_MODE 0x884B -#define GL_TEXTURE_COMPARE_MODE 0x884C -#define GL_TEXTURE_COMPARE_FUNC 0x884D -#define GL_COMPARE_R_TO_TEXTURE 0x884E - -#define glBlendColor GlobalOpenGL().m_glBlendColor -#define glBlendEquation GlobalOpenGL().m_glBlendEquation -#define glBlendFuncSeparate GlobalOpenGL().m_glBlendFuncSeparate -#define glFogCoordPointer GlobalOpenGL().m_glFogCoordPointer -#define glFogCoordd GlobalOpenGL().m_glFogCoordd -#define glFogCoorddv GlobalOpenGL().m_glFogCoorddv -#define glFogCoordf GlobalOpenGL().m_glFogCoordf -#define glFogCoordfv GlobalOpenGL().m_glFogCoordfv -#define glMultiDrawArrays GlobalOpenGL().m_glMultiDrawArrays -#define glMultiDrawElements GlobalOpenGL().m_glMultiDrawElements -#define glPointParameterf GlobalOpenGL().m_glPointParameterf -#define glPointParameterfv GlobalOpenGL().m_glPointParameterfv -#define glSecondaryColor3b GlobalOpenGL().m_glSecondaryColor3b -#define glSecondaryColor3bv GlobalOpenGL().m_glSecondaryColor3bv -#define glSecondaryColor3d GlobalOpenGL().m_glSecondaryColor3d -#define glSecondaryColor3dv GlobalOpenGL().m_glSecondaryColor3dv -#define glSecondaryColor3f GlobalOpenGL().m_glSecondaryColor3f -#define glSecondaryColor3fv GlobalOpenGL().m_glSecondaryColor3fv -#define glSecondaryColor3i GlobalOpenGL().m_glSecondaryColor3i -#define glSecondaryColor3iv GlobalOpenGL().m_glSecondaryColor3iv -#define glSecondaryColor3s GlobalOpenGL().m_glSecondaryColor3s -#define glSecondaryColor3sv GlobalOpenGL().m_glSecondaryColor3sv -#define glSecondaryColor3ub GlobalOpenGL().m_glSecondaryColor3ub -#define glSecondaryColor3ubv GlobalOpenGL().m_glSecondaryColor3ubv -#define glSecondaryColor3ui GlobalOpenGL().m_glSecondaryColor3ui -#define glSecondaryColor3uiv GlobalOpenGL().m_glSecondaryColor3uiv -#define glSecondaryColor3us GlobalOpenGL().m_glSecondaryColor3us -#define glSecondaryColor3usv GlobalOpenGL().m_glSecondaryColor3usv -#define glSecondaryColorPointer GlobalOpenGL().m_glSecondaryColorPointer -#define glWindowPos2d GlobalOpenGL().m_glWindowPos2d -#define glWindowPos2dv GlobalOpenGL().m_glWindowPos2dv -#define glWindowPos2f GlobalOpenGL().m_glWindowPos2f -#define glWindowPos2fv GlobalOpenGL().m_glWindowPos2fv -#define glWindowPos2i GlobalOpenGL().m_glWindowPos2i -#define glWindowPos2iv GlobalOpenGL().m_glWindowPos2iv -#define glWindowPos2s GlobalOpenGL().m_glWindowPos2s -#define glWindowPos2sv GlobalOpenGL().m_glWindowPos2sv -#define glWindowPos3d GlobalOpenGL().m_glWindowPos3d -#define glWindowPos3dv GlobalOpenGL().m_glWindowPos3dv -#define glWindowPos3f GlobalOpenGL().m_glWindowPos3f -#define glWindowPos3fv GlobalOpenGL().m_glWindowPos3fv -#define glWindowPos3i GlobalOpenGL().m_glWindowPos3i -#define glWindowPos3iv GlobalOpenGL().m_glWindowPos3iv -#define glWindowPos3s GlobalOpenGL().m_glWindowPos3s -#define glWindowPos3sv GlobalOpenGL().m_glWindowPos3sv - -#endif - - -// GL 1.5 -#if !defined( GL_VERSION_1_5 ) -#define GL_VERSION_1_5 1 - -#define GL_FOG_COORD GL_FOG_COORDINATE -#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY -#define GL_SRC0_RGB GL_SOURCE0_RGB -#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER -#define GL_FOG_COORD_SOURCE GL_FOG_COORDINATE_SOURCE -#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE -#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA -#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE -#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE -#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA -#define GL_SRC1_RGB GL_SOURCE1_RGB -#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING -#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA -#define GL_SRC2_RGB GL_SOURCE2_RGB -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 -#define GL_QUERY_COUNTER_BITS 0x8864 -#define GL_CURRENT_QUERY 0x8865 -#define GL_QUERY_RESULT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE 0x8867 -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F -#define GL_READ_ONLY 0x88B8 -#define GL_WRITE_ONLY 0x88B9 -#define GL_READ_WRITE 0x88BA -#define GL_BUFFER_ACCESS 0x88BB -#define GL_BUFFER_MAPPED 0x88BC -#define GL_BUFFER_MAP_POINTER 0x88BD -#define GL_STREAM_DRAW 0x88E0 -#define GL_STREAM_READ 0x88E1 -#define GL_STREAM_COPY 0x88E2 -#define GL_STATIC_DRAW 0x88E4 -#define GL_STATIC_READ 0x88E5 -#define GL_STATIC_COPY 0x88E6 -#define GL_DYNAMIC_DRAW 0x88E8 -#define GL_DYNAMIC_READ 0x88E9 -#define GL_DYNAMIC_COPY 0x88EA -#define GL_SAMPLES_PASSED 0x8914 - -typedef std::ptrdiff_t GLsizeiptr; -typedef std::ptrdiff_t GLintptr; - -#define glBeginQuery GlobalOpenGL().m_glBeginQuery -#define glBindBuffer GlobalOpenGL().m_glBindBuffer -#define glBufferData GlobalOpenGL().m_glBufferData -#define glBufferSubData GlobalOpenGL().m_glBufferSubData -#define glDeleteBuffers GlobalOpenGL().m_glDeleteBuffers -#define glDeleteQueries GlobalOpenGL().m_glDeleteQueries -#define glEndQuery GlobalOpenGL().m_glEndQuery -#define glGenBuffers GlobalOpenGL().m_glGenBuffers -#define glGenQueries GlobalOpenGL().m_glGenQueries -#define glGetBufferParameteriv GlobalOpenGL().m_glGetBufferParameteriv -#define glGetBufferPointerv GlobalOpenGL().m_glGetBufferPointerv -#define glGetBufferSubData GlobalOpenGL().m_glGetBufferSubData -#define glGetQueryObjectiv GlobalOpenGL().m_glGetQueryObjectiv -#define glGetQueryObjectuiv GlobalOpenGL().m_glGetQueryObjectuiv -#define glGetQueryiv GlobalOpenGL().m_glGetQueryiv -#define glIsBuffer GlobalOpenGL().m_glIsBuffer -#define glIsQuery GlobalOpenGL().m_glIsQuery -#define glMapBuffer GlobalOpenGL().m_glMapBuffer -#define glUnmapBuffer GlobalOpenGL().m_glUnmapBuffer - -#endif - - -// GL_ARB_vertex_program -#if !defined( GL_ARB_vertex_program ) -#define GL_ARB_vertex_program - -#define GL_VERTEX_PROGRAM_ARB 0x8620 -#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 -#define GL_COLOR_SUM_ARB 0x8458 -#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A -#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 -#define GL_PROGRAM_LENGTH_ARB 0x8627 -#define GL_PROGRAM_FORMAT_ARB 0x8876 -#define GL_PROGRAM_BINDING_ARB 0x8677 -#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 -#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 -#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 -#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 -#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 -#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 -#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 -#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 -#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 -#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 -#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA -#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB -#define GL_PROGRAM_ATTRIBS_ARB 0x88AC -#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD -#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE -#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF -#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 -#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 -#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 -#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 -#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 -#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 -#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 -#define GL_PROGRAM_STRING_ARB 0x8628 -#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B -#define GL_CURRENT_MATRIX_ARB 0x8641 -#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 -#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 -#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 -#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F -#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E -#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 -#define GL_MATRIX0_ARB 0x88C0 -#define GL_MATRIX1_ARB 0x88C1 -#define GL_MATRIX2_ARB 0x88C2 -#define GL_MATRIX3_ARB 0x88C3 -#define GL_MATRIX4_ARB 0x88C4 -#define GL_MATRIX5_ARB 0x88C5 -#define GL_MATRIX6_ARB 0x88C6 -#define GL_MATRIX7_ARB 0x88C7 -#define GL_MATRIX8_ARB 0x88C8 -#define GL_MATRIX9_ARB 0x88C9 -#define GL_MATRIX10_ARB 0x88CA -#define GL_MATRIX11_ARB 0x88CB -#define GL_MATRIX12_ARB 0x88CC -#define GL_MATRIX13_ARB 0x88CD -#define GL_MATRIX14_ARB 0x88CE -#define GL_MATRIX15_ARB 0x88CF -#define GL_MATRIX16_ARB 0x88D0 -#define GL_MATRIX17_ARB 0x88D1 -#define GL_MATRIX18_ARB 0x88D2 -#define GL_MATRIX19_ARB 0x88D3 -#define GL_MATRIX20_ARB 0x88D4 -#define GL_MATRIX21_ARB 0x88D5 -#define GL_MATRIX22_ARB 0x88D6 -#define GL_MATRIX23_ARB 0x88D7 -#define GL_MATRIX24_ARB 0x88D8 -#define GL_MATRIX25_ARB 0x88D9 -#define GL_MATRIX26_ARB 0x88DA -#define GL_MATRIX27_ARB 0x88DB -#define GL_MATRIX28_ARB 0x88DC -#define GL_MATRIX29_ARB 0x88DD -#define GL_MATRIX30_ARB 0x88DE -#define GL_MATRIX31_ARB 0x88DF - -#define glVertexAttrib1sARB GlobalOpenGL().m_glVertexAttrib1sARB -#define glVertexAttrib1fARB GlobalOpenGL().m_glVertexAttrib1fARB -#define glVertexAttrib1dARB GlobalOpenGL().m_glVertexAttrib1dARB -#define glVertexAttrib2sARB GlobalOpenGL().m_glVertexAttrib2sARB -#define glVertexAttrib2fARB GlobalOpenGL().m_glVertexAttrib2fARB -#define glVertexAttrib2dARB GlobalOpenGL().m_glVertexAttrib2dARB -#define glVertexAttrib3sARB GlobalOpenGL().m_glVertexAttrib3sARB -#define glVertexAttrib3fARB GlobalOpenGL().m_glVertexAttrib3fARB -#define glVertexAttrib3dARB GlobalOpenGL().m_glVertexAttrib3dARB -#define glVertexAttrib4sARB GlobalOpenGL().m_glVertexAttrib4sARB -#define glVertexAttrib4fARB GlobalOpenGL().m_glVertexAttrib4fARB -#define glVertexAttrib4dARB GlobalOpenGL().m_glVertexAttrib4dARB -#define glVertexAttrib4NubARB GlobalOpenGL().m_glVertexAttrib4NubARB -#define glVertexAttrib1svARB GlobalOpenGL().m_glVertexAttrib1svARB -#define glVertexAttrib1fvARB GlobalOpenGL().m_glVertexAttrib1fvARB -#define glVertexAttrib1dvARB GlobalOpenGL().m_glVertexAttrib1dvARB -#define glVertexAttrib2svARB GlobalOpenGL().m_glVertexAttrib2svARB -#define glVertexAttrib2fvARB GlobalOpenGL().m_glVertexAttrib2fvARB -#define glVertexAttrib2dvARB GlobalOpenGL().m_glVertexAttrib2dvARB -#define glVertexAttrib3svARB GlobalOpenGL().m_glVertexAttrib3svARB -#define glVertexAttrib3fvARB GlobalOpenGL().m_glVertexAttrib3fvARB -#define glVertexAttrib3dvARB GlobalOpenGL().m_glVertexAttrib3dvARB -#define glVertexAttrib4bvARB GlobalOpenGL().m_glVertexAttrib4bvARB -#define glVertexAttrib4svARB GlobalOpenGL().m_glVertexAttrib4svARB -#define glVertexAttrib4ivARB GlobalOpenGL().m_glVertexAttrib4ivARB -#define glVertexAttrib4ubvARB GlobalOpenGL().m_glVertexAttrib4ubvARB -#define glVertexAttrib4usvARB GlobalOpenGL().m_glVertexAttrib4usvARB -#define glVertexAttrib4uivARB GlobalOpenGL().m_glVertexAttrib4uivARB -#define glVertexAttrib4fvARB GlobalOpenGL().m_glVertexAttrib4fvARB -#define glVertexAttrib4dvARB GlobalOpenGL().m_glVertexAttrib4dvARB -#define glVertexAttrib4NbvARB GlobalOpenGL().m_glVertexAttrib4NbvARB -#define glVertexAttrib4NsvARB GlobalOpenGL().m_glVertexAttrib4NsvARB -#define glVertexAttrib4NivARB GlobalOpenGL().m_glVertexAttrib4NivARB -#define glVertexAttrib4NubvARB GlobalOpenGL().m_glVertexAttrib4NubvARB -#define glVertexAttrib4NusvARB GlobalOpenGL().m_glVertexAttrib4NusvARB -#define glVertexAttrib4NuivARB GlobalOpenGL().m_glVertexAttrib4NuivARB -#define glVertexAttribPointerARB GlobalOpenGL().m_glVertexAttribPointerARB -#define glEnableVertexAttribArrayARB GlobalOpenGL().m_glEnableVertexAttribArrayARB -#define glDisableVertexAttribArrayARB GlobalOpenGL().m_glDisableVertexAttribArrayARB -#define glProgramStringARB GlobalOpenGL().m_glProgramStringARB -#define glBindProgramARB GlobalOpenGL().m_glBindProgramARB -#define glDeleteProgramsARB GlobalOpenGL().m_glDeleteProgramsARB -#define glGenProgramsARB GlobalOpenGL().m_glGenProgramsARB -#define glProgramEnvParameter4dARB GlobalOpenGL().m_glProgramEnvParameter4dARB -#define glProgramEnvParameter4dvARB GlobalOpenGL().m_glProgramEnvParameter4dvARB -#define glProgramEnvParameter4fARB GlobalOpenGL().m_glProgramEnvParameter4fARB -#define glProgramEnvParameter4fvARB GlobalOpenGL().m_glProgramEnvParameter4fvARB -#define glProgramLocalParameter4dARB GlobalOpenGL().m_glProgramLocalParameter4dARB -#define glProgramLocalParameter4dvARB GlobalOpenGL().m_glProgramLocalParameter4dvARB -#define glProgramLocalParameter4fARB GlobalOpenGL().m_glProgramLocalParameter4fARB -#define glProgramLocalParameter4fvARB GlobalOpenGL().m_glProgramLocalParameter4fvARB -#define glGetProgramEnvParameterdvARB GlobalOpenGL().m_glGetProgramEnvParameterdvARB -#define glGetProgramEnvParameterfvARB GlobalOpenGL().m_glGetProgramEnvParameterfvARB -#define glGetProgramLocalParameterdvARB GlobalOpenGL().m_glGetProgramLocalParameterdvARB -#define glGetProgramLocalParameterfvARB GlobalOpenGL().m_glGetProgramLocalParameterfvARB -#define glGetProgramivARB GlobalOpenGL().m_glGetProgramivARB -#define glGetProgramStringARB GlobalOpenGL().m_glGetProgramStringARB -#define glGetVertexAttribdvARB GlobalOpenGL().m_glGetVertexAttribdvARB -#define glGetVertexAttribfvARB GlobalOpenGL().m_glGetVertexAttribfvARB -#define glGetVertexAttribivARB GlobalOpenGL().m_glGetVertexAttribivARB -#define glGetVertexAttribPointervARB GlobalOpenGL().m_glGetVertexAttribPointervARB -#define glIsProgramARB GlobalOpenGL().m_glIsProgramARB - -#endif - - -// GL_ARB_fragment_program -#if !defined( GL_ARB_fragment_program ) -#define GL_ARB_fragment_program 1 - -#define GL_FRAGMENT_PROGRAM_ARB 0x8804 -#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 -#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 -#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 -#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 -#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 -#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A -#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B -#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C -#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D -#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E -#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F -#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 -#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 - -#endif - - -// GL_ARB_shader_objects -#if !defined( GL_ARB_shader_objects ) -#define GL_ARB_shader_objects 1 - -#define GL_PROGRAM_OBJECT_ARB 0x8B40 -#define GL_SHADER_OBJECT_ARB 0x8B48 -#define GL_OBJECT_TYPE_ARB 0x8B4E -#define GL_OBJECT_SUBTYPE_ARB 0x8B4F -#define GL_FLOAT_VEC2_ARB 0x8B50 -#define GL_FLOAT_VEC3_ARB 0x8B51 -#define GL_FLOAT_VEC4_ARB 0x8B52 -#define GL_INT_VEC2_ARB 0x8B53 -#define GL_INT_VEC3_ARB 0x8B54 -#define GL_INT_VEC4_ARB 0x8B55 -#define GL_BOOL_ARB 0x8B56 -#define GL_BOOL_VEC2_ARB 0x8B57 -#define GL_BOOL_VEC3_ARB 0x8B58 -#define GL_BOOL_VEC4_ARB 0x8B59 -#define GL_FLOAT_MAT2_ARB 0x8B5A -#define GL_FLOAT_MAT3_ARB 0x8B5B -#define GL_FLOAT_MAT4_ARB 0x8B5C -#define GL_SAMPLER_1D_ARB 0x8B5D -#define GL_SAMPLER_2D_ARB 0x8B5E -#define GL_SAMPLER_3D_ARB 0x8B5F -#define GL_SAMPLER_CUBE_ARB 0x8B60 -#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 -#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 -#define GL_SAMPLER_2D_RECT_ARB 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 -#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 -#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 -#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 -#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 -#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 -#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 -#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 -#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 -#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 - -#define glDeleteObjectARB GlobalOpenGL().m_glDeleteObjectARB -#define glGetHandleARB GlobalOpenGL().m_glGetHandleARB -#define glDetachObjectARB GlobalOpenGL().m_glDetachObjectARB -#define glCreateShaderObjectARB GlobalOpenGL().m_glCreateShaderObjectARB -#define glShaderSourceARB GlobalOpenGL().m_glShaderSourceARB -#define glCompileShaderARB GlobalOpenGL().m_glCompileShaderARB -#define glCreateProgramObjectARB GlobalOpenGL().m_glCreateProgramObjectARB -#define glAttachObjectARB GlobalOpenGL().m_glAttachObjectARB -#define glLinkProgramARB GlobalOpenGL().m_glLinkProgramARB -#define glUseProgramObjectARB GlobalOpenGL().m_glUseProgramObjectARB -#define glValidateProgramARB GlobalOpenGL().m_glValidateProgramARB -#define glUniform1fARB GlobalOpenGL().m_glUniform1fARB -#define glUniform2fARB GlobalOpenGL().m_glUniform2fARB -#define glUniform3fARB GlobalOpenGL().m_glUniform3fARB -#define glUniform4fARB GlobalOpenGL().m_glUniform4fARB -#define glUniform1iARB GlobalOpenGL().m_glUniform1iARB -#define glUniform2iARB GlobalOpenGL().m_glUniform2iARB -#define glUniform3iARB GlobalOpenGL().m_glUniform3iARB -#define glUniform4iARB GlobalOpenGL().m_glUniform4iARB -#define glUniform1fvARB GlobalOpenGL().m_glUniform1fvARB -#define glUniform2fvARB GlobalOpenGL().m_glUniform2fvARB -#define glUniform3fvARB GlobalOpenGL().m_glUniform3fvARB -#define glUniform4fvARB GlobalOpenGL().m_glUniform4fvARB -#define glUniform1ivARB GlobalOpenGL().m_glUniform1ivARB -#define glUniform2ivARB GlobalOpenGL().m_glUniform2ivARB -#define glUniform3ivARB GlobalOpenGL().m_glUniform3ivARB -#define glUniform4ivARB GlobalOpenGL().m_glUniform4ivARB -#define glUniformMatrix2fvARB GlobalOpenGL().m_glUniformMatrix2fvARB -#define glUniformMatrix3fvARB GlobalOpenGL().m_glUniformMatrix3fvARB -#define glUniformMatrix4fvARB GlobalOpenGL().m_glUniformMatrix4fvARB -#define glGetObjectParameterfvARB GlobalOpenGL().m_glGetObjectParameterfvARB -#define glGetObjectParameterivARB GlobalOpenGL().m_glGetObjectParameterivARB -#define glGetInfoLogARB GlobalOpenGL().m_glGetInfoLogARB -#define glGetAttachedObjectsARB GlobalOpenGL().m_glGetAttachedObjectsARB -#define glGetUniformLocationARB GlobalOpenGL().m_glGetUniformLocationARB -#define glGetActiveUniformARB GlobalOpenGL().m_glGetActiveUniformARB -#define glGetUniformfvARB GlobalOpenGL().m_glGetUniformfvARB -#define glGetUniformivARB GlobalOpenGL().m_glGetUniformivARB -#define glGetShaderSourceARB GlobalOpenGL().m_glGetShaderSourceARB - -typedef char GLcharARB; -typedef unsigned int GLhandleARB; - -#endif - -// GL_ARB_vertex_shader -#if !defined( GL_ARB_vertex_shader ) -#define GL_ARB_vertex_shader 1 - -#define GL_VERTEX_SHADER_ARB 0x8B31 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A -#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D -#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 -#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A - -#if 0 -#define glVertexAttrib1fARB GlobalOpenGL().m_glVertexAttrib1fARB -#define glVertexAttrib1sARB GlobalOpenGL().m_glVertexAttrib1sARB -#define glVertexAttrib1dARB GlobalOpenGL().m_glVertexAttrib1dARB -#define glVertexAttrib2fARB GlobalOpenGL().m_glVertexAttrib2fARB -#define glVertexAttrib2sARB GlobalOpenGL().m_glVertexAttrib2sARB -#define glVertexAttrib2dARB GlobalOpenGL().m_glVertexAttrib2dARB -#define glVertexAttrib3fARB GlobalOpenGL().m_glVertexAttrib3fARB -#define glVertexAttrib3sARB GlobalOpenGL().m_glVertexAttrib3sARB -#define glVertexAttrib3dARB GlobalOpenGL().m_glVertexAttrib3dARB -#define glVertexAttrib4fARB GlobalOpenGL().m_glVertexAttrib4fARB -#define glVertexAttrib4sARB GlobalOpenGL().m_glVertexAttrib4sARB -#define glVertexAttrib4dARB GlobalOpenGL().m_glVertexAttrib4dARB -#define glVertexAttrib4NubARB GlobalOpenGL().m_glVertexAttrib4NubARB -#define glVertexAttrib1fvARB GlobalOpenGL().m_glVertexAttrib1fvARB -#define glVertexAttrib1svARB GlobalOpenGL().m_glVertexAttrib1svARB -#define glVertexAttrib1dvARB GlobalOpenGL().m_glVertexAttrib1dvARB -#define glVertexAttrib2fvARB GlobalOpenGL().m_glVertexAttrib2fvARB -#define glVertexAttrib2svARB GlobalOpenGL().m_glVertexAttrib2svARB -#define glVertexAttrib2dvARB GlobalOpenGL().m_glVertexAttrib2dvARB -#define glVertexAttrib3fvARB GlobalOpenGL().m_glVertexAttrib3fvARB -#define glVertexAttrib3svARB GlobalOpenGL().m_glVertexAttrib3svARB -#define glVertexAttrib3dvARB GlobalOpenGL().m_glVertexAttrib3dvARB -#define glVertexAttrib4fvARB GlobalOpenGL().m_glVertexAttrib4fvARB -#define glVertexAttrib4svARB GlobalOpenGL().m_glVertexAttrib4svARB -#define glVertexAttrib4dvARB GlobalOpenGL().m_glVertexAttrib4dvARB -#define glVertexAttrib4ivARB GlobalOpenGL().m_glVertexAttrib4ivARB -#define glVertexAttrib4bvARB GlobalOpenGL().m_glVertexAttrib4bvARB -#define glVertexAttrib4ubvARB GlobalOpenGL().m_glVertexAttrib4ubvARB -#define glVertexAttrib4usvARB GlobalOpenGL().m_glVertexAttrib4usvARB -#define glVertexAttrib4uivARB GlobalOpenGL().m_glVertexAttrib4uivARB -#define glVertexAttrib4NbvARB GlobalOpenGL().m_glVertexAttrib4NbvARB -#define glVertexAttrib4NsvARB GlobalOpenGL().m_glVertexAttrib4NsvARB -#define glVertexAttrib4NivARB GlobalOpenGL().m_glVertexAttrib4NivARB -#define glVertexAttrib4NubvARB GlobalOpenGL().m_glVertexAttrib4NubvARB -#define glVertexAttrib4NusvARB GlobalOpenGL().m_glVertexAttrib4NusvARB -#define glVertexAttrib4NuivARB GlobalOpenGL().m_glVertexAttrib4NuivARB -#define glVertexAttribPointerARB GlobalOpenGL().m_glVertexAttribPointerARB -#define glEnableVertexAttribArrayARB GlobalOpenGL().m_glEnableVertexAttribArrayARB -#define glDisableVertexAttribArrayARB GlobalOpenGL().m_glDisableVertexAttribArrayARB -#endif -#define glBindAttribLocationARB GlobalOpenGL().m_glBindAttribLocationARB -#define glGetActiveAttribARB GlobalOpenGL().m_glGetActiveAttribARB -#define glGetAttribLocationARB GlobalOpenGL().m_glGetAttribLocationARB -#if 0 -#define glGetVertexAttribdvARB GlobalOpenGL().m_glGetVertexAttribdvARB -#define glGetVertexAttribfvARB GlobalOpenGL().m_glGetVertexAttribfvARB -#define glGetVertexAttribivARB GlobalOpenGL().m_glGetVertexAttribivARB -#define glGetVertexAttribPointervARB GlobalOpenGL().m_glGetVertexAttribPointervARB -#endif -#endif - - - -// GL_ARB_fragment_shader -#if !defined( GL_ARB_fragment_shader ) -#define GL_ARB_fragment_shader 1 - -#define GL_FRAGMENT_SHADER_ARB 0x8B30 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B - -#endif - - -// GL_ARB_shading_language_100 -#if !defined( GL_ARB_shading_language_100 ) -#define GL_ARB_shading_language_100 1 - -#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C - -#endif - - -// GL_NV_vertex_program2 -#if !defined( GL_NV_vertex_program ) -#define GL_NV_vertex_program 1 - -#define GL_VERTEX_PROGRAM_NV 0x8620 -#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 -#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 -#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 -#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 -#define GL_CURRENT_ATTRIB_NV 0x8626 -#define GL_PROGRAM_LENGTH_NV 0x8627 -#define GL_PROGRAM_STRING_NV 0x8628 -#define GL_MODELVIEW_PROJECTION_NV 0x8629 -#define GL_IDENTITY_NV 0x862A -#define GL_INVERSE_NV 0x862B -#define GL_TRANSPOSE_NV 0x862C -#define GL_INVERSE_TRANSPOSE_NV 0x862D -#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E -#define GL_MAX_TRACK_MATRICES_NV 0x862F -#define GL_MATRIX0_NV 0x8630 -#define GL_MATRIX1_NV 0x8631 -#define GL_MATRIX2_NV 0x8632 -#define GL_MATRIX3_NV 0x8633 -#define GL_MATRIX4_NV 0x8634 -#define GL_MATRIX5_NV 0x8635 -#define GL_MATRIX6_NV 0x8636 -#define GL_MATRIX7_NV 0x8637 -#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 -#define GL_CURRENT_MATRIX_NV 0x8641 -#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 -#define GL_PROGRAM_PARAMETER_NV 0x8644 -#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 -#define GL_PROGRAM_TARGET_NV 0x8646 -#define GL_PROGRAM_RESIDENT_NV 0x8647 -#define GL_TRACK_MATRIX_NV 0x8648 -#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 -#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A -#define GL_PROGRAM_ERROR_POSITION_NV 0x864B -#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 -#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 -#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 -#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 -#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 -#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 -#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 -#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 -#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 -#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 -#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A -#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B -#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C -#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D -#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E -#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F -#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 -#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 -#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 -#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 -#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 -#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 -#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 -#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 -#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 -#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 -#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A -#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B -#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C -#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D -#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E -#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F -#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 -#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 -#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 -#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 -#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 -#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 -#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 -#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 -#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 -#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 -#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A -#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B -#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C -#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D -#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E -#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F - -#define glAreProgramsResidentNV GlobalOpenGL().m_glAreProgramsResidentNV -#define glBindProgramNV GlobalOpenGL().m_glBindProgramNV -#define glDeleteProgramsNV GlobalOpenGL().m_glDeleteProgramsNV -#define glExecuteProgramNV GlobalOpenGL().m_glExecuteProgramNV -#define glGenProgramsNV GlobalOpenGL().m_glGenProgramsNV -#define glGetProgramParameterdvNV GlobalOpenGL().m_glGetProgramParameterdvNV -#define glGetProgramParameterfvNV GlobalOpenGL().m_glGetProgramParameterfvNV -#define glGetProgramivNV GlobalOpenGL().m_glGetProgramivNV -#define glGetProgramStringNV GlobalOpenGL().m_glGetProgramStringNV -#define glGetTrackMatrixivNV GlobalOpenGL().m_glGetTrackMatrixivNV -#define glGetVertexAttribdvNV GlobalOpenGL().m_glGetVertexAttribdvNV -#define glGetVertexAttribfvNV GlobalOpenGL().m_glGetVertexAttribfvNV -#define glGetVertexAttribivNV GlobalOpenGL().m_glGetVertexAttribivNV -#define glGetVertexAttribPointervNV GlobalOpenGL().m_glGetVertexAttribPointervNV -#define glIsProgramNV GlobalOpenGL().m_glIsProgramNV -#define glLoadProgramNV GlobalOpenGL().m_glLoadProgramNV -#define glProgramParameter4fNV GlobalOpenGL().m_glProgramParameter4fNV -#define glProgramParameter4fvNV GlobalOpenGL().m_glProgramParameter4fvNV -#define glProgramParameters4fvNV GlobalOpenGL().m_glProgramParameters4fvNV -#define glRequestResidentProgramsNV GlobalOpenGL().m_glRequestResidentProgramsNV -#define glTrackMatrixNV GlobalOpenGL().m_glTrackMatrixNV -#define glVertexAttribPointerNV GlobalOpenGL().m_glVertexAttribPointerNV -#define glVertexAttrib1fNV GlobalOpenGL().m_glVertexAttrib1fNV -#define glVertexAttrib1fvNV GlobalOpenGL().m_glVertexAttrib1fvNV -#define glVertexAttrib2fNV GlobalOpenGL().m_glVertexAttrib2fNV -#define glVertexAttrib2fvNV GlobalOpenGL().m_glVertexAttrib2fvNV -#define glVertexAttrib3fNV GlobalOpenGL().m_glVertexAttrib3fNV -#define glVertexAttrib3fvNV GlobalOpenGL().m_glVertexAttrib3fvNV -#define glVertexAttrib4fNV GlobalOpenGL().m_glVertexAttrib4fNV -#define glVertexAttrib4fvNV GlobalOpenGL().m_glVertexAttrib4fvNV -#define glVertexAttribs1fvNV GlobalOpenGL().m_glVertexAttribs1fvNV -#define glVertexAttribs2fvNV GlobalOpenGL().m_glVertexAttribs2fvNV -#define glVertexAttribs3fvNV GlobalOpenGL().m_glVertexAttribs3fvNV -#define glVertexAttribs4fvNV GlobalOpenGL().m_glVertexAttribs4fvNV - -#endif - - -// GL_NV_fragment_program -#if !defined( GL_NV_fragment_program ) - -#define GL_NV_fragment_program 1 - -#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 -#define GL_FRAGMENT_PROGRAM_NV 0x8870 -#define GL_MAX_TEXTURE_COORDS_NV 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 -#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 -#define GL_PROGRAM_ERROR_STRING_NV 0x8874 - -#define glProgramNamedParameter4fNV GlobalOpenGL().m_glProgramNamedParameter4fNV -#define glProgramNamedParameter4fvNV GlobalOpenGL().m_glProgramNamedParameter4fvNV -#define glGetProgramNamedParameterfvNV GlobalOpenGL().m_glGetProgramNamedParameterfvNV - -#endif - - - - -/* ----------------------- GL_ARB_framebuffer_object ----------------------- */ - -#ifndef GL_ARB_framebuffer_object -#define GL_ARB_framebuffer_object 1 - -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#define GL_FRAMEBUFFER_DEFAULT 0x8218 -#define GL_FRAMEBUFFER_UNDEFINED 0x8219 -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#define GL_INDEX 0x8222 -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 -#define GL_DEPTH_STENCIL 0x84F9 -#define GL_UNSIGNED_INT_24_8 0x84FA -#define GL_DEPTH24_STENCIL8 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE 0x88F1 -#define GL_UNSIGNED_NORMALIZED 0x8C17 -#define GL_SRGB 0x8C40 -#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_READ_FRAMEBUFFER 0x8CA8 -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA -#define GL_RENDERBUFFER_SAMPLES 0x8CAB -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_COLOR_ATTACHMENT1 0x8CE1 -#define GL_COLOR_ATTACHMENT2 0x8CE2 -#define GL_COLOR_ATTACHMENT3 0x8CE3 -#define GL_COLOR_ATTACHMENT4 0x8CE4 -#define GL_COLOR_ATTACHMENT5 0x8CE5 -#define GL_COLOR_ATTACHMENT6 0x8CE6 -#define GL_COLOR_ATTACHMENT7 0x8CE7 -#define GL_COLOR_ATTACHMENT8 0x8CE8 -#define GL_COLOR_ATTACHMENT9 0x8CE9 -#define GL_COLOR_ATTACHMENT10 0x8CEA -#define GL_COLOR_ATTACHMENT11 0x8CEB -#define GL_COLOR_ATTACHMENT12 0x8CEC -#define GL_COLOR_ATTACHMENT13 0x8CED -#define GL_COLOR_ATTACHMENT14 0x8CEE -#define GL_COLOR_ATTACHMENT15 0x8CEF -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_STENCIL_ATTACHMENT 0x8D20 -#define GL_FRAMEBUFFER 0x8D40 -#define GL_RENDERBUFFER 0x8D41 -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_STENCIL_INDEX1 0x8D46 -#define GL_STENCIL_INDEX4 0x8D47 -#define GL_STENCIL_INDEX8 0x8D48 -#define GL_STENCIL_INDEX16 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 -#define GL_MAX_SAMPLES 0x8D57 - -#define glBindFramebuffer GlobalOpenGL().m_glBindFramebuffer -#define glBindRenderbuffer GlobalOpenGL().m_glBindRenderbuffer -#define glBlitFramebuffer GlobalOpenGL().m_glBlitFramebuffer -#define glCheckFramebufferStatus GlobalOpenGL().m_glCheckFramebufferStatus -#define glDeleteFramebuffers GlobalOpenGL().m_glDeleteFramebuffers -#define glDeleteRenderbuffers GlobalOpenGL().m_glDeleteRenderbuffers -#define glFramebufferRenderbuffer GlobalOpenGL().m_glFramebufferRenderbuffer -#define glFramebufferTexture1D GlobalOpenGL().m_glFramebufferTexture1D -#define glFramebufferTexture2D GlobalOpenGL().m_glFramebufferTexture2D -#define glFramebufferTexture3D GlobalOpenGL().m_glFramebufferTexture3D -#define glFramebufferTextureLayer GlobalOpenGL().m_glFramebufferTextureLayer -#define glGenFramebuffers GlobalOpenGL().m_glGenFramebuffers -#define glGenRenderbuffers GlobalOpenGL().m_glGenRenderbuffers -#define glGenerateMipmap GlobalOpenGL().m_glGenerateMipmap -#define glGetFramebufferAttachmentParameteriv GlobalOpenGL().m_glGetFramebufferAttachmentParameteriv -#define glGetRenderbufferParameteriv GlobalOpenGL().m_glGetRenderbufferParameteriv -#define glIsFramebuffer GlobalOpenGL().m_glIsFramebuffer -#define glIsRenderbuffer GlobalOpenGL().m_glIsRenderbuffer -#define glRenderbufferStorage GlobalOpenGL().m_glRenderbufferStorage -#define glRenderbufferStorageMultisample GlobalOpenGL().m_glRenderbufferStorageMultisample - -#endif /* GL_ARB_framebuffer_object */ - - - - +#include #include "gtkutil/glfont.h" /// \brief A module which wraps a runtime-binding of the standard OpenGL functions. @@ -2099,7 +41,9 @@ struct OpenGLBinding /// \brief Is true if the global shared OpenGL context is valid. bool contextValid; - OpenGLBinding() : contextValid( false ){ + QOpenGLFunctions_2_0 *funcs; + + OpenGLBinding() : contextValid( false ), funcs( nullptr ){ } /// \brief Asserts that there no OpenGL errors have occurred since the last call to glGetError. @@ -2120,809 +64,17 @@ struct OpenGLBinding drawString( s ); } - - // GL 1.1 - void ( QGL_DLLEXPORT *m_glAccum )( GLenum op, GLfloat value ); - void ( QGL_DLLEXPORT *m_glAlphaFunc )( GLenum func, GLclampf ref ); - GLboolean ( QGL_DLLEXPORT *m_glAreTexturesResident )( GLsizei n, const GLuint *textures, GLboolean *residences ); - void ( QGL_DLLEXPORT *m_glArrayElement )( GLint i ); - void ( QGL_DLLEXPORT *m_glBegin )( GLenum mode ); - void ( QGL_DLLEXPORT *m_glBindTexture )( GLenum target, GLuint texture ); - void ( QGL_DLLEXPORT *m_glBitmap )( GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap ); - void ( QGL_DLLEXPORT *m_glBlendFunc )( GLenum sfactor, GLenum dfactor ); - void ( QGL_DLLEXPORT *m_glCallList )( GLuint list ); - void ( QGL_DLLEXPORT *m_glCallLists )( GLsizei n, GLenum type, const GLvoid *lists ); - void ( QGL_DLLEXPORT *m_glClear )( GLbitfield mask ); - void ( QGL_DLLEXPORT *m_glClearAccum )( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ); - void ( QGL_DLLEXPORT *m_glClearColor )( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); - void ( QGL_DLLEXPORT *m_glClearDepth )( GLclampd depth ); - void ( QGL_DLLEXPORT *m_glClearIndex )( GLfloat c ); - void ( QGL_DLLEXPORT *m_glClearStencil )( GLint s ); - void ( QGL_DLLEXPORT *m_glClipPlane )( GLenum plane, const GLdouble *equation ); - void ( QGL_DLLEXPORT *m_glColor3b )( GLbyte red, GLbyte green, GLbyte blue ); - void ( QGL_DLLEXPORT *m_glColor3bv )( const GLbyte *v ); - void ( QGL_DLLEXPORT *m_glColor3d )( GLdouble red, GLdouble green, GLdouble blue ); - void ( QGL_DLLEXPORT *m_glColor3dv )( const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glColor3f )( GLfloat red, GLfloat green, GLfloat blue ); - void ( QGL_DLLEXPORT *m_glColor3fv )( const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glColor3i )( GLint red, GLint green, GLint blue ); - void ( QGL_DLLEXPORT *m_glColor3iv )( const GLint *v ); - void ( QGL_DLLEXPORT *m_glColor3s )( GLshort red, GLshort green, GLshort blue ); - void ( QGL_DLLEXPORT *m_glColor3sv )( const GLshort *v ); - void ( QGL_DLLEXPORT *m_glColor3ub )( GLubyte red, GLubyte green, GLubyte blue ); - void ( QGL_DLLEXPORT *m_glColor3ubv )( const GLubyte *v ); - void ( QGL_DLLEXPORT *m_glColor3ui )( GLuint red, GLuint green, GLuint blue ); - void ( QGL_DLLEXPORT *m_glColor3uiv )( const GLuint *v ); - void ( QGL_DLLEXPORT *m_glColor3us )( GLushort red, GLushort green, GLushort blue ); - void ( QGL_DLLEXPORT *m_glColor3usv )( const GLushort *v ); - void ( QGL_DLLEXPORT *m_glColor4b )( GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha ); - void ( QGL_DLLEXPORT *m_glColor4bv )( const GLbyte *v ); - void ( QGL_DLLEXPORT *m_glColor4d )( GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha ); - void ( QGL_DLLEXPORT *m_glColor4dv )( const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glColor4f )( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ); - void ( QGL_DLLEXPORT *m_glColor4fv )( const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glColor4i )( GLint red, GLint green, GLint blue, GLint alpha ); - void ( QGL_DLLEXPORT *m_glColor4iv )( const GLint *v ); - void ( QGL_DLLEXPORT *m_glColor4s )( GLshort red, GLshort green, GLshort blue, GLshort alpha ); - void ( QGL_DLLEXPORT *m_glColor4sv )( const GLshort *v ); - void ( QGL_DLLEXPORT *m_glColor4ub )( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ); - void ( QGL_DLLEXPORT *m_glColor4ubv )( const GLubyte *v ); - void ( QGL_DLLEXPORT *m_glColor4ui )( GLuint red, GLuint green, GLuint blue, GLuint alpha ); - void ( QGL_DLLEXPORT *m_glColor4uiv )( const GLuint *v ); - void ( QGL_DLLEXPORT *m_glColor4us )( GLushort red, GLushort green, GLushort blue, GLushort alpha ); - void ( QGL_DLLEXPORT *m_glColor4usv )( const GLushort *v ); - void ( QGL_DLLEXPORT *m_glColorMask )( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ); - void ( QGL_DLLEXPORT *m_glColorMaterial )( GLenum face, GLenum mode ); - void ( QGL_DLLEXPORT *m_glColorPointer )( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer ); - void ( QGL_DLLEXPORT *m_glCopyPixels )( GLint x, GLint y, GLsizei width, GLsizei height, GLenum type ); - void ( QGL_DLLEXPORT *m_glCopyTexImage1D )( GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border ); - void ( QGL_DLLEXPORT *m_glCopyTexImage2D )( GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border ); - void ( QGL_DLLEXPORT *m_glCopyTexSubImage1D )( GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width ); - void ( QGL_DLLEXPORT *m_glCopyTexSubImage2D )( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height ); - void ( QGL_DLLEXPORT *m_glCullFace )( GLenum mode ); - void ( QGL_DLLEXPORT *m_glDeleteLists )( GLuint list, GLsizei range ); - void ( QGL_DLLEXPORT *m_glDeleteTextures )( GLsizei n, const GLuint *textures ); - void ( QGL_DLLEXPORT *m_glDepthFunc )( GLenum func ); - void ( QGL_DLLEXPORT *m_glDepthMask )( GLboolean flag ); - void ( QGL_DLLEXPORT *m_glDepthRange )( GLclampd zNear, GLclampd zFar ); - void ( QGL_DLLEXPORT *m_glDisable )( GLenum cap ); - void ( QGL_DLLEXPORT *m_glDisableClientState )( GLenum array ); - void ( QGL_DLLEXPORT *m_glDrawArrays )( GLenum mode, GLint first, GLsizei count ); - void ( QGL_DLLEXPORT *m_glDrawBuffer )( GLenum mode ); - void ( QGL_DLLEXPORT *m_glDrawElements )( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices ); - void ( QGL_DLLEXPORT *m_glDrawPixels )( GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ); - void ( QGL_DLLEXPORT *m_glEdgeFlag )( GLboolean flag ); - void ( QGL_DLLEXPORT *m_glEdgeFlagPointer )( GLsizei stride, const GLvoid *pointer ); - void ( QGL_DLLEXPORT *m_glEdgeFlagv )( const GLboolean *flag ); - void ( QGL_DLLEXPORT *m_glEnable )( GLenum cap ); - void ( QGL_DLLEXPORT *m_glEnableClientState )( GLenum array ); - void ( QGL_DLLEXPORT *m_glEnd )( void ); - void ( QGL_DLLEXPORT *m_glEndList )( void ); - void ( QGL_DLLEXPORT *m_glEvalCoord1d )( GLdouble u ); - void ( QGL_DLLEXPORT *m_glEvalCoord1dv )( const GLdouble *u ); - void ( QGL_DLLEXPORT *m_glEvalCoord1f )( GLfloat u ); - void ( QGL_DLLEXPORT *m_glEvalCoord1fv )( const GLfloat *u ); - void ( QGL_DLLEXPORT *m_glEvalCoord2d )( GLdouble u, GLdouble v ); - void ( QGL_DLLEXPORT *m_glEvalCoord2dv )( const GLdouble *u ); - void ( QGL_DLLEXPORT *m_glEvalCoord2f )( GLfloat u, GLfloat v ); - void ( QGL_DLLEXPORT *m_glEvalCoord2fv )( const GLfloat *u ); - void ( QGL_DLLEXPORT *m_glEvalMesh1 )( GLenum mode, GLint i1, GLint i2 ); - void ( QGL_DLLEXPORT *m_glEvalMesh2 )( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ); - void ( QGL_DLLEXPORT *m_glEvalPoint1 )( GLint i ); - void ( QGL_DLLEXPORT *m_glEvalPoint2 )( GLint i, GLint j ); - void ( QGL_DLLEXPORT *m_glFeedbackBuffer )( GLsizei size, GLenum type, GLfloat *buffer ); - void ( QGL_DLLEXPORT *m_glFinish )( void ); - void ( QGL_DLLEXPORT *m_glFlush )( void ); - void ( QGL_DLLEXPORT *m_glFogf )( GLenum pname, GLfloat param ); - void ( QGL_DLLEXPORT *m_glFogfv )( GLenum pname, const GLfloat *params ); - void ( QGL_DLLEXPORT *m_glFogi )( GLenum pname, GLint param ); - void ( QGL_DLLEXPORT *m_glFogiv )( GLenum pname, const GLint *params ); - void ( QGL_DLLEXPORT *m_glFrontFace )( GLenum mode ); - void ( QGL_DLLEXPORT *m_glFrustum )( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar ); - GLuint ( QGL_DLLEXPORT *m_glGenLists )( GLsizei range ); - void ( QGL_DLLEXPORT *m_glGenTextures )( GLsizei n, GLuint *textures ); - void ( QGL_DLLEXPORT *m_glGetBooleanv )( GLenum pname, GLboolean *params ); - void ( QGL_DLLEXPORT *m_glGetClipPlane )( GLenum plane, GLdouble *equation ); - void ( QGL_DLLEXPORT *m_glGetDoublev )( GLenum pname, GLdouble *params ); - GLenum ( QGL_DLLEXPORT *m_glGetError )( void ); - void ( QGL_DLLEXPORT *m_glGetFloatv )( GLenum pname, GLfloat *params ); - void ( QGL_DLLEXPORT *m_glGetIntegerv )( GLenum pname, GLint *params ); - void ( QGL_DLLEXPORT *m_glGetLightfv )( GLenum light, GLenum pname, GLfloat *params ); - void ( QGL_DLLEXPORT *m_glGetLightiv )( GLenum light, GLenum pname, GLint *params ); - void ( QGL_DLLEXPORT *m_glGetMapdv )( GLenum target, GLenum query, GLdouble *v ); - void ( QGL_DLLEXPORT *m_glGetMapfv )( GLenum target, GLenum query, GLfloat *v ); - void ( QGL_DLLEXPORT *m_glGetMapiv )( GLenum target, GLenum query, GLint *v ); - void ( QGL_DLLEXPORT *m_glGetMaterialfv )( GLenum face, GLenum pname, GLfloat *params ); - void ( QGL_DLLEXPORT *m_glGetMaterialiv )( GLenum face, GLenum pname, GLint *params ); - void ( QGL_DLLEXPORT *m_glGetPixelMapfv )( GLenum map, GLfloat *values ); - void ( QGL_DLLEXPORT *m_glGetPixelMapuiv )( GLenum map, GLuint *values ); - void ( QGL_DLLEXPORT *m_glGetPixelMapusv )( GLenum map, GLushort *values ); - void ( QGL_DLLEXPORT *m_glGetPointerv )( GLenum pname, GLvoid* *params ); - void ( QGL_DLLEXPORT *m_glGetPolygonStipple )( GLubyte *mask ); - const GLubyte * ( QGL_DLLEXPORT * m_glGetString )(GLenum name); - void ( QGL_DLLEXPORT *m_glGetTexEnvfv )( GLenum target, GLenum pname, GLfloat *params ); - void ( QGL_DLLEXPORT *m_glGetTexEnviv )( GLenum target, GLenum pname, GLint *params ); - void ( QGL_DLLEXPORT *m_glGetTexGendv )( GLenum coord, GLenum pname, GLdouble *params ); - void ( QGL_DLLEXPORT *m_glGetTexGenfv )( GLenum coord, GLenum pname, GLfloat *params ); - void ( QGL_DLLEXPORT *m_glGetTexGeniv )( GLenum coord, GLenum pname, GLint *params ); - void ( QGL_DLLEXPORT *m_glGetTexImage )( GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels ); - void ( QGL_DLLEXPORT *m_glGetTexLevelParameterfv )( GLenum target, GLint level, GLenum pname, GLfloat *params ); - void ( QGL_DLLEXPORT *m_glGetTexLevelParameteriv )( GLenum target, GLint level, GLenum pname, GLint *params ); - void ( QGL_DLLEXPORT *m_glGetTexParameterfv )( GLenum target, GLenum pname, GLfloat *params ); - void ( QGL_DLLEXPORT *m_glGetTexParameteriv )( GLenum target, GLenum pname, GLint *params ); - void ( QGL_DLLEXPORT *m_glHint )( GLenum target, GLenum mode ); - void ( QGL_DLLEXPORT *m_glIndexMask )( GLuint mask ); - void ( QGL_DLLEXPORT *m_glIndexPointer )( GLenum type, GLsizei stride, const GLvoid *pointer ); - void ( QGL_DLLEXPORT *m_glIndexd )( GLdouble c ); - void ( QGL_DLLEXPORT *m_glIndexdv )( const GLdouble *c ); - void ( QGL_DLLEXPORT *m_glIndexf )( GLfloat c ); - void ( QGL_DLLEXPORT *m_glIndexfv )( const GLfloat *c ); - void ( QGL_DLLEXPORT *m_glIndexi )( GLint c ); - void ( QGL_DLLEXPORT *m_glIndexiv )( const GLint *c ); - void ( QGL_DLLEXPORT *m_glIndexs )( GLshort c ); - void ( QGL_DLLEXPORT *m_glIndexsv )( const GLshort *c ); - void ( QGL_DLLEXPORT *m_glIndexub )( GLubyte c ); - void ( QGL_DLLEXPORT *m_glIndexubv )( const GLubyte *c ); - void ( QGL_DLLEXPORT *m_glInitNames )( void ); - void ( QGL_DLLEXPORT *m_glInterleavedArrays )( GLenum format, GLsizei stride, const GLvoid *pointer ); - GLboolean ( QGL_DLLEXPORT *m_glIsEnabled )( GLenum cap ); - GLboolean ( QGL_DLLEXPORT *m_glIsList )( GLuint list ); - GLboolean ( QGL_DLLEXPORT *m_glIsTexture )( GLuint texture ); - void ( QGL_DLLEXPORT *m_glLightModelf )( GLenum pname, GLfloat param ); - void ( QGL_DLLEXPORT *m_glLightModelfv )( GLenum pname, const GLfloat *params ); - void ( QGL_DLLEXPORT *m_glLightModeli )( GLenum pname, GLint param ); - void ( QGL_DLLEXPORT *m_glLightModeliv )( GLenum pname, const GLint *params ); - void ( QGL_DLLEXPORT *m_glLightf )( GLenum light, GLenum pname, GLfloat param ); - void ( QGL_DLLEXPORT *m_glLightfv )( GLenum light, GLenum pname, const GLfloat *params ); - void ( QGL_DLLEXPORT *m_glLighti )( GLenum light, GLenum pname, GLint param ); - void ( QGL_DLLEXPORT *m_glLightiv )( GLenum light, GLenum pname, const GLint *params ); - void ( QGL_DLLEXPORT *m_glLineStipple )( GLint factor, GLushort pattern ); - void ( QGL_DLLEXPORT *m_glLineWidth )( GLfloat width ); - void ( QGL_DLLEXPORT *m_glListBase )( GLuint base ); - void ( QGL_DLLEXPORT *m_glLoadIdentity )( void ); - void ( QGL_DLLEXPORT *m_glLoadMatrixd )( const GLdouble *m ); - void ( QGL_DLLEXPORT *m_glLoadMatrixf )( const GLfloat *m ); - void ( QGL_DLLEXPORT *m_glLoadName )( GLuint name ); - void ( QGL_DLLEXPORT *m_glLogicOp )( GLenum opcode ); - void ( QGL_DLLEXPORT *m_glMap1d )( GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points ); - void ( QGL_DLLEXPORT *m_glMap1f )( GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points ); - void ( QGL_DLLEXPORT *m_glMap2d )( GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points ); - void ( QGL_DLLEXPORT *m_glMap2f )( GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points ); - void ( QGL_DLLEXPORT *m_glMapGrid1d )( GLint un, GLdouble u1, GLdouble u2 ); - void ( QGL_DLLEXPORT *m_glMapGrid1f )( GLint un, GLfloat u1, GLfloat u2 ); - void ( QGL_DLLEXPORT *m_glMapGrid2d )( GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2 ); - void ( QGL_DLLEXPORT *m_glMapGrid2f )( GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2 ); - void ( QGL_DLLEXPORT *m_glMaterialf )( GLenum face, GLenum pname, GLfloat param ); - void ( QGL_DLLEXPORT *m_glMaterialfv )( GLenum face, GLenum pname, const GLfloat *params ); - void ( QGL_DLLEXPORT *m_glMateriali )( GLenum face, GLenum pname, GLint param ); - void ( QGL_DLLEXPORT *m_glMaterialiv )( GLenum face, GLenum pname, const GLint *params ); - void ( QGL_DLLEXPORT *m_glMatrixMode )( GLenum mode ); - void ( QGL_DLLEXPORT *m_glMultMatrixd )( const GLdouble *m ); - void ( QGL_DLLEXPORT *m_glMultMatrixf )( const GLfloat *m ); - void ( QGL_DLLEXPORT *m_glNewList )( GLuint list, GLenum mode ); - void ( QGL_DLLEXPORT *m_glNormal3b )( GLbyte nx, GLbyte ny, GLbyte nz ); - void ( QGL_DLLEXPORT *m_glNormal3bv )( const GLbyte *v ); - void ( QGL_DLLEXPORT *m_glNormal3d )( GLdouble nx, GLdouble ny, GLdouble nz ); - void ( QGL_DLLEXPORT *m_glNormal3dv )( const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glNormal3f )( GLfloat nx, GLfloat ny, GLfloat nz ); - void ( QGL_DLLEXPORT *m_glNormal3fv )( const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glNormal3i )( GLint nx, GLint ny, GLint nz ); - void ( QGL_DLLEXPORT *m_glNormal3iv )( const GLint *v ); - void ( QGL_DLLEXPORT *m_glNormal3s )( GLshort nx, GLshort ny, GLshort nz ); - void ( QGL_DLLEXPORT *m_glNormal3sv )( const GLshort *v ); - void ( QGL_DLLEXPORT *m_glNormalPointer )( GLenum type, GLsizei stride, const GLvoid *pointer ); - void ( QGL_DLLEXPORT *m_glOrtho )( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar ); - void ( QGL_DLLEXPORT *m_glPassThrough )( GLfloat token ); - void ( QGL_DLLEXPORT *m_glPixelMapfv )( GLenum map, GLsizei mapsize, const GLfloat *values ); - void ( QGL_DLLEXPORT *m_glPixelMapuiv )( GLenum map, GLsizei mapsize, const GLuint *values ); - void ( QGL_DLLEXPORT *m_glPixelMapusv )( GLenum map, GLsizei mapsize, const GLushort *values ); - void ( QGL_DLLEXPORT *m_glPixelStoref )( GLenum pname, GLfloat param ); - void ( QGL_DLLEXPORT *m_glPixelStorei )( GLenum pname, GLint param ); - void ( QGL_DLLEXPORT *m_glPixelTransferf )( GLenum pname, GLfloat param ); - void ( QGL_DLLEXPORT *m_glPixelTransferi )( GLenum pname, GLint param ); - void ( QGL_DLLEXPORT *m_glPixelZoom )( GLfloat xfactor, GLfloat yfactor ); - void ( QGL_DLLEXPORT *m_glPointSize )( GLfloat size ); - void ( QGL_DLLEXPORT *m_glPolygonMode )( GLenum face, GLenum mode ); - void ( QGL_DLLEXPORT *m_glPolygonOffset )( GLfloat factor, GLfloat units ); - void ( QGL_DLLEXPORT *m_glPolygonStipple )( const GLubyte *mask ); - void ( QGL_DLLEXPORT *m_glPopAttrib )( void ); - void ( QGL_DLLEXPORT *m_glPopClientAttrib )( void ); - void ( QGL_DLLEXPORT *m_glPopMatrix )( void ); - void ( QGL_DLLEXPORT *m_glPopName )( void ); - void ( QGL_DLLEXPORT *m_glPrioritizeTextures )( GLsizei n, const GLuint *textures, const GLclampf *priorities ); - void ( QGL_DLLEXPORT *m_glPushAttrib )( GLbitfield mask ); - void ( QGL_DLLEXPORT *m_glPushClientAttrib )( GLbitfield mask ); - void ( QGL_DLLEXPORT *m_glPushMatrix )( void ); - void ( QGL_DLLEXPORT *m_glPushName )( GLuint name ); - void ( QGL_DLLEXPORT *m_glRasterPos2d )( GLdouble x, GLdouble y ); - void ( QGL_DLLEXPORT *m_glRasterPos2dv )( const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glRasterPos2f )( GLfloat x, GLfloat y ); - void ( QGL_DLLEXPORT *m_glRasterPos2fv )( const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glRasterPos2i )( GLint x, GLint y ); - void ( QGL_DLLEXPORT *m_glRasterPos2iv )( const GLint *v ); - void ( QGL_DLLEXPORT *m_glRasterPos2s )( GLshort x, GLshort y ); - void ( QGL_DLLEXPORT *m_glRasterPos2sv )( const GLshort *v ); - void ( QGL_DLLEXPORT *m_glRasterPos3d )( GLdouble x, GLdouble y, GLdouble z ); - void ( QGL_DLLEXPORT *m_glRasterPos3dv )( const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glRasterPos3f )( GLfloat x, GLfloat y, GLfloat z ); - void ( QGL_DLLEXPORT *m_glRasterPos3fv )( const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glRasterPos3i )( GLint x, GLint y, GLint z ); - void ( QGL_DLLEXPORT *m_glRasterPos3iv )( const GLint *v ); - void ( QGL_DLLEXPORT *m_glRasterPos3s )( GLshort x, GLshort y, GLshort z ); - void ( QGL_DLLEXPORT *m_glRasterPos3sv )( const GLshort *v ); - void ( QGL_DLLEXPORT *m_glRasterPos4d )( GLdouble x, GLdouble y, GLdouble z, GLdouble w ); - void ( QGL_DLLEXPORT *m_glRasterPos4dv )( const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glRasterPos4f )( GLfloat x, GLfloat y, GLfloat z, GLfloat w ); - void ( QGL_DLLEXPORT *m_glRasterPos4fv )( const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glRasterPos4i )( GLint x, GLint y, GLint z, GLint w ); - void ( QGL_DLLEXPORT *m_glRasterPos4iv )( const GLint *v ); - void ( QGL_DLLEXPORT *m_glRasterPos4s )( GLshort x, GLshort y, GLshort z, GLshort w ); - void ( QGL_DLLEXPORT *m_glRasterPos4sv )( const GLshort *v ); - void ( QGL_DLLEXPORT *m_glReadBuffer )( GLenum mode ); - void ( QGL_DLLEXPORT *m_glReadPixels )( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels ); - void ( QGL_DLLEXPORT *m_glRectd )( GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2 ); - void ( QGL_DLLEXPORT *m_glRectdv )( const GLdouble *v1, const GLdouble *v2 ); - void ( QGL_DLLEXPORT *m_glRectf )( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ); - void ( QGL_DLLEXPORT *m_glRectfv )( const GLfloat *v1, const GLfloat *v2 ); - void ( QGL_DLLEXPORT *m_glRecti )( GLint x1, GLint y1, GLint x2, GLint y2 ); - void ( QGL_DLLEXPORT *m_glRectiv )( const GLint *v1, const GLint *v2 ); - void ( QGL_DLLEXPORT *m_glRects )( GLshort x1, GLshort y1, GLshort x2, GLshort y2 ); - void ( QGL_DLLEXPORT *m_glRectsv )( const GLshort *v1, const GLshort *v2 ); - GLint ( QGL_DLLEXPORT *m_glRenderMode )( GLenum mode ); - void ( QGL_DLLEXPORT *m_glRotated )( GLdouble anm_gle, GLdouble x, GLdouble y, GLdouble z ); - void ( QGL_DLLEXPORT *m_glRotatef )( GLfloat anm_gle, GLfloat x, GLfloat y, GLfloat z ); - void ( QGL_DLLEXPORT *m_glScaled )( GLdouble x, GLdouble y, GLdouble z ); - void ( QGL_DLLEXPORT *m_glScalef )( GLfloat x, GLfloat y, GLfloat z ); - void ( QGL_DLLEXPORT *m_glScissor )( GLint x, GLint y, GLsizei width, GLsizei height ); - void ( QGL_DLLEXPORT *m_glSelectBuffer )( GLsizei size, GLuint *buffer ); - void ( QGL_DLLEXPORT *m_glShadeModel )( GLenum mode ); - void ( QGL_DLLEXPORT *m_glStencilFunc )( GLenum func, GLint ref, GLuint mask ); - void ( QGL_DLLEXPORT *m_glStencilMask )( GLuint mask ); - void ( QGL_DLLEXPORT *m_glStencilOp )( GLenum fail, GLenum zfail, GLenum zpass ); - void ( QGL_DLLEXPORT *m_glTexCoord1d )( GLdouble s ); - void ( QGL_DLLEXPORT *m_glTexCoord1dv )( const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glTexCoord1f )( GLfloat s ); - void ( QGL_DLLEXPORT *m_glTexCoord1fv )( const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glTexCoord1i )( GLint s ); - void ( QGL_DLLEXPORT *m_glTexCoord1iv )( const GLint *v ); - void ( QGL_DLLEXPORT *m_glTexCoord1s )( GLshort s ); - void ( QGL_DLLEXPORT *m_glTexCoord1sv )( const GLshort *v ); - void ( QGL_DLLEXPORT *m_glTexCoord2d )( GLdouble s, GLdouble t ); - void ( QGL_DLLEXPORT *m_glTexCoord2dv )( const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glTexCoord2f )( GLfloat s, GLfloat t ); - void ( QGL_DLLEXPORT *m_glTexCoord2fv )( const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glTexCoord2i )( GLint s, GLint t ); - void ( QGL_DLLEXPORT *m_glTexCoord2iv )( const GLint *v ); - void ( QGL_DLLEXPORT *m_glTexCoord2s )( GLshort s, GLshort t ); - void ( QGL_DLLEXPORT *m_glTexCoord2sv )( const GLshort *v ); - void ( QGL_DLLEXPORT *m_glTexCoord3d )( GLdouble s, GLdouble t, GLdouble r ); - void ( QGL_DLLEXPORT *m_glTexCoord3dv )( const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glTexCoord3f )( GLfloat s, GLfloat t, GLfloat r ); - void ( QGL_DLLEXPORT *m_glTexCoord3fv )( const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glTexCoord3i )( GLint s, GLint t, GLint r ); - void ( QGL_DLLEXPORT *m_glTexCoord3iv )( const GLint *v ); - void ( QGL_DLLEXPORT *m_glTexCoord3s )( GLshort s, GLshort t, GLshort r ); - void ( QGL_DLLEXPORT *m_glTexCoord3sv )( const GLshort *v ); - void ( QGL_DLLEXPORT *m_glTexCoord4d )( GLdouble s, GLdouble t, GLdouble r, GLdouble q ); - void ( QGL_DLLEXPORT *m_glTexCoord4dv )( const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glTexCoord4f )( GLfloat s, GLfloat t, GLfloat r, GLfloat q ); - void ( QGL_DLLEXPORT *m_glTexCoord4fv )( const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glTexCoord4i )( GLint s, GLint t, GLint r, GLint q ); - void ( QGL_DLLEXPORT *m_glTexCoord4iv )( const GLint *v ); - void ( QGL_DLLEXPORT *m_glTexCoord4s )( GLshort s, GLshort t, GLshort r, GLshort q ); - void ( QGL_DLLEXPORT *m_glTexCoord4sv )( const GLshort *v ); - void ( QGL_DLLEXPORT *m_glTexCoordPointer )( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer ); - void ( QGL_DLLEXPORT *m_glTexEnvf )( GLenum target, GLenum pname, GLfloat param ); - void ( QGL_DLLEXPORT *m_glTexEnvfv )( GLenum target, GLenum pname, const GLfloat *params ); - void ( QGL_DLLEXPORT *m_glTexEnvi )( GLenum target, GLenum pname, GLint param ); - void ( QGL_DLLEXPORT *m_glTexEnviv )( GLenum target, GLenum pname, const GLint *params ); - void ( QGL_DLLEXPORT *m_glTexGend )( GLenum coord, GLenum pname, GLdouble param ); - void ( QGL_DLLEXPORT *m_glTexGendv )( GLenum coord, GLenum pname, const GLdouble *params ); - void ( QGL_DLLEXPORT *m_glTexGenf )( GLenum coord, GLenum pname, GLfloat param ); - void ( QGL_DLLEXPORT *m_glTexGenfv )( GLenum coord, GLenum pname, const GLfloat *params ); - void ( QGL_DLLEXPORT *m_glTexGeni )( GLenum coord, GLenum pname, GLint param ); - void ( QGL_DLLEXPORT *m_glTexGeniv )( GLenum coord, GLenum pname, const GLint *params ); -#if defined( MACVERSION ) && MACVERSION > 15 - //Snow Leopard 16, Leopard 15, Tiger 14, Panther 13, ... - void ( QGL_DLLEXPORT *m_glTexImage1D )( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels ); - void ( QGL_DLLEXPORT *m_glTexImage2D )( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels ); -#else - void ( QGL_DLLEXPORT *m_glTexImage1D )( GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels ); - void ( QGL_DLLEXPORT *m_glTexImage2D )( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels ); -#endif - void ( QGL_DLLEXPORT *m_glTexParameterf )( GLenum target, GLenum pname, GLfloat param ); - void ( QGL_DLLEXPORT *m_glTexParameterfv )( GLenum target, GLenum pname, const GLfloat *params ); - void ( QGL_DLLEXPORT *m_glTexParameteri )( GLenum target, GLenum pname, GLint param ); - void ( QGL_DLLEXPORT *m_glTexParameteriv )( GLenum target, GLenum pname, const GLint *params ); - void ( QGL_DLLEXPORT *m_glTexSubImage1D )( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels ); - void ( QGL_DLLEXPORT *m_glTexSubImage2D )( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ); - void ( QGL_DLLEXPORT *m_glTranslated )( GLdouble x, GLdouble y, GLdouble z ); - void ( QGL_DLLEXPORT *m_glTranslatef )( GLfloat x, GLfloat y, GLfloat z ); - void ( QGL_DLLEXPORT *m_glVertex2d )( GLdouble x, GLdouble y ); - void ( QGL_DLLEXPORT *m_glVertex2dv )( const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glVertex2f )( GLfloat x, GLfloat y ); - void ( QGL_DLLEXPORT *m_glVertex2fv )( const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glVertex2i )( GLint x, GLint y ); - void ( QGL_DLLEXPORT *m_glVertex2iv )( const GLint *v ); - void ( QGL_DLLEXPORT *m_glVertex2s )( GLshort x, GLshort y ); - void ( QGL_DLLEXPORT *m_glVertex2sv )( const GLshort *v ); - void ( QGL_DLLEXPORT *m_glVertex3d )( GLdouble x, GLdouble y, GLdouble z ); - void ( QGL_DLLEXPORT *m_glVertex3dv )( const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glVertex3f )( GLfloat x, GLfloat y, GLfloat z ); - void ( QGL_DLLEXPORT *m_glVertex3fv )( const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glVertex3i )( GLint x, GLint y, GLint z ); - void ( QGL_DLLEXPORT *m_glVertex3iv )( const GLint *v ); - void ( QGL_DLLEXPORT *m_glVertex3s )( GLshort x, GLshort y, GLshort z ); - void ( QGL_DLLEXPORT *m_glVertex3sv )( const GLshort *v ); - void ( QGL_DLLEXPORT *m_glVertex4d )( GLdouble x, GLdouble y, GLdouble z, GLdouble w ); - void ( QGL_DLLEXPORT *m_glVertex4dv )( const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glVertex4f )( GLfloat x, GLfloat y, GLfloat z, GLfloat w ); - void ( QGL_DLLEXPORT *m_glVertex4fv )( const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glVertex4i )( GLint x, GLint y, GLint z, GLint w ); - void ( QGL_DLLEXPORT *m_glVertex4iv )( const GLint *v ); - void ( QGL_DLLEXPORT *m_glVertex4s )( GLshort x, GLshort y, GLshort z, GLshort w ); - void ( QGL_DLLEXPORT *m_glVertex4sv )( const GLshort *v ); - void ( QGL_DLLEXPORT *m_glVertexPointer )( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer ); - void ( QGL_DLLEXPORT *m_glViewport )( GLint x, GLint y, GLsizei width, GLsizei height ); - - // GL_ARB_multitexture - bool support_ARB_multitexture; - bool ARB_multitexture(){ - return support_ARB_multitexture; - } - void ( QGL_DLLEXPORT *m_glActiveTextureARB )( GLenum texture ); - void ( QGL_DLLEXPORT *m_glClientActiveTextureARB )( GLenum texture ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1dARB )( GLenum target, GLdouble s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1dvARB )( GLenum target, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1fARB )( GLenum target, GLfloat s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1fvARB )( GLenum target, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1iARB )( GLenum target, GLint s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1ivARB )( GLenum target, const GLint *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1sARB )( GLenum target, GLshort s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1svARB )( GLenum target, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2dARB )( GLenum target, GLdouble s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2dvARB )( GLenum target, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2fARB )( GLenum target, GLfloat s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2fvARB )( GLenum target, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2iARB )( GLenum target, GLint s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2ivARB )( GLenum target, const GLint *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2sARB )( GLenum target, GLshort s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2svARB )( GLenum target, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3dARB )( GLenum target, GLdouble s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3dvARB )( GLenum target, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3fARB )( GLenum target, GLfloat s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3fvARB )( GLenum target, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3iARB )( GLenum target, GLint s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3ivARB )( GLenum target, const GLint *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3sARB )( GLenum target, GLshort s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3svARB )( GLenum target, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4dARB )( GLenum target, GLdouble s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4dvARB )( GLenum target, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4fARB )( GLenum target, GLfloat s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4fvARB )( GLenum target, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4iARB )( GLenum target, GLint s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4ivARB )( GLenum target, const GLint *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4sARB )( GLenum target, GLshort s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4svARB )( GLenum target, const GLshort *v ); - // ARB_texture_compression bool support_ARB_texture_compression; bool ARB_texture_compression(){ return support_ARB_texture_compression; } - void ( QGL_DLLEXPORT *m_glCompressedTexImage3DARB )( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data ); - void ( QGL_DLLEXPORT *m_glCompressedTexImage2DARB )( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data ); - void ( QGL_DLLEXPORT *m_glCompressedTexImage1DARB )( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid* data ); - void ( QGL_DLLEXPORT *m_glCompressedTexSubImage3DARB )( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data ); - void ( QGL_DLLEXPORT *m_glCompressedTexSubImage2DARB )( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data ); - void ( QGL_DLLEXPORT *m_glCompressedTexSubImage1DARB )( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid* data ); - void ( QGL_DLLEXPORT *m_glGetCompressedTexImageARB )( GLenum target, GLint lod, GLvoid* img ); // EXT_texture_compression_s3tc bool support_EXT_texture_compression_s3tc; bool EXT_texture_compression_s3tc(){ return support_EXT_texture_compression_s3tc; } - - // GL 1.2 - bool support_GL_1_2; - bool GL_1_2(){ - return support_GL_1_2; - } - void ( QGL_DLLEXPORT *m_glCopyTexSubImage3D )( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ); - void ( QGL_DLLEXPORT *m_glDrawRangeElements )( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices ); - void ( QGL_DLLEXPORT *m_glTexImage3D )( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels ); - void ( QGL_DLLEXPORT *m_glTexSubImage3D )( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels ); - - // GL 1.3 - bool support_GL_1_3; - bool GL_1_3(){ - return support_GL_1_3; - } - void ( QGL_DLLEXPORT *m_glActiveTexture )( GLenum texture ); - void ( QGL_DLLEXPORT *m_glClientActiveTexture )( GLenum texture ); - void ( QGL_DLLEXPORT *m_glCompressedTexImage1D )( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data ); - void ( QGL_DLLEXPORT *m_glCompressedTexImage2D )( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data ); - void ( QGL_DLLEXPORT *m_glCompressedTexImage3D )( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data ); - void ( QGL_DLLEXPORT *m_glCompressedTexSubImage1D )( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data ); - void ( QGL_DLLEXPORT *m_glCompressedTexSubImage2D )( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data ); - void ( QGL_DLLEXPORT *m_glCompressedTexSubImage3D )( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data ); - void ( QGL_DLLEXPORT *m_glGetCompressedTexImage )( GLenum target, GLint lod, GLvoid *img ); - void ( QGL_DLLEXPORT *m_glLoadTransposeMatrixd )( const GLdouble m[16] ); - void ( QGL_DLLEXPORT *m_glLoadTransposeMatrixf )( const GLfloat m[16] ); - void ( QGL_DLLEXPORT *m_glMultTransposeMatrixd )( const GLdouble m[16] ); - void ( QGL_DLLEXPORT *m_glMultTransposeMatrixf )( const GLfloat m[16] ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1d )( GLenum target, GLdouble s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1dv )( GLenum target, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1f )( GLenum target, GLfloat s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1fv )( GLenum target, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1i )( GLenum target, GLint s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1iv )( GLenum target, const GLint *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1s )( GLenum target, GLshort s ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord1sv )( GLenum target, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2d )( GLenum target, GLdouble s, GLdouble t ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2dv )( GLenum target, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2f )( GLenum target, GLfloat s, GLfloat t ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2fv )( GLenum target, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2i )( GLenum target, GLint s, GLint t ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2iv )( GLenum target, const GLint *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2s )( GLenum target, GLshort s, GLshort t ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord2sv )( GLenum target, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3d )( GLenum target, GLdouble s, GLdouble t, GLdouble r ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3dv )( GLenum target, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3f )( GLenum target, GLfloat s, GLfloat t, GLfloat r ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3fv )( GLenum target, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3i )( GLenum target, GLint s, GLint t, GLint r ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3iv )( GLenum target, const GLint *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3s )( GLenum target, GLshort s, GLshort t, GLshort r ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord3sv )( GLenum target, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4d )( GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4dv )( GLenum target, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4f )( GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4fv )( GLenum target, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4i )( GLenum target, GLint s, GLint t, GLint r, GLint q ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4iv )( GLenum target, const GLint *v ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4s )( GLenum target, GLshort s, GLshort t, GLshort r, GLshort q ); - void ( QGL_DLLEXPORT *m_glMultiTexCoord4sv )( GLenum target, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glSampleCoverage )( GLclampf value, GLboolean invert ); - - // GL 1.4 - bool support_GL_1_4; - bool GL_1_4(){ - return support_GL_1_4; - } - void ( QGL_DLLEXPORT *m_glBlendColor )( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); - void ( QGL_DLLEXPORT *m_glBlendEquation )( GLenum mode ); - void ( QGL_DLLEXPORT *m_glBlendFuncSeparate )( GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha ); - void ( QGL_DLLEXPORT *m_glFogCoordPointer )( GLenum type, GLsizei stride, const GLvoid *pointer ); - void ( QGL_DLLEXPORT *m_glFogCoordd )( GLdouble coord ); - void ( QGL_DLLEXPORT *m_glFogCoorddv )( const GLdouble *coord ); - void ( QGL_DLLEXPORT *m_glFogCoordf )( GLfloat coord ); - void ( QGL_DLLEXPORT *m_glFogCoordfv )( const GLfloat *coord ); - void ( QGL_DLLEXPORT *m_glMultiDrawArrays )( GLenum mode, GLint *first, GLsizei *count, GLsizei primcount ); - void ( QGL_DLLEXPORT *m_glMultiDrawElements )( GLenum mode, GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount ); - void ( QGL_DLLEXPORT *m_glPointParameterf )( GLenum pname, GLfloat param ); - void ( QGL_DLLEXPORT *m_glPointParameterfv )( GLenum pname, GLfloat *params ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3b )( GLbyte red, GLbyte green, GLbyte blue ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3bv )( const GLbyte *v ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3d )( GLdouble red, GLdouble green, GLdouble blue ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3dv )( const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3f )( GLfloat red, GLfloat green, GLfloat blue ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3fv )( const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3i )( GLint red, GLint green, GLint blue ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3iv )( const GLint *v ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3s )( GLshort red, GLshort green, GLshort blue ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3sv )( const GLshort *v ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3ub )( GLubyte red, GLubyte green, GLubyte blue ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3ubv )( const GLubyte *v ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3ui )( GLuint red, GLuint green, GLuint blue ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3uiv )( const GLuint *v ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3us )( GLushort red, GLushort green, GLushort blue ); - void ( QGL_DLLEXPORT *m_glSecondaryColor3usv )( const GLushort *v ); - void ( QGL_DLLEXPORT *m_glSecondaryColorPointer )( GLint size, GLenum type, GLsizei stride, GLvoid *pointer ); - void ( QGL_DLLEXPORT *m_glWindowPos2d )( GLdouble x, GLdouble y ); - void ( QGL_DLLEXPORT *m_glWindowPos2dv )( const GLdouble *p ); - void ( QGL_DLLEXPORT *m_glWindowPos2f )( GLfloat x, GLfloat y ); - void ( QGL_DLLEXPORT *m_glWindowPos2fv )( const GLfloat *p ); - void ( QGL_DLLEXPORT *m_glWindowPos2i )( GLint x, GLint y ); - void ( QGL_DLLEXPORT *m_glWindowPos2iv )( const GLint *p ); - void ( QGL_DLLEXPORT *m_glWindowPos2s )( GLshort x, GLshort y ); - void ( QGL_DLLEXPORT *m_glWindowPos2sv )( const GLshort *p ); - void ( QGL_DLLEXPORT *m_glWindowPos3d )( GLdouble x, GLdouble y, GLdouble z ); - void ( QGL_DLLEXPORT *m_glWindowPos3dv )( const GLdouble *p ); - void ( QGL_DLLEXPORT *m_glWindowPos3f )( GLfloat x, GLfloat y, GLfloat z ); - void ( QGL_DLLEXPORT *m_glWindowPos3fv )( const GLfloat *p ); - void ( QGL_DLLEXPORT *m_glWindowPos3i )( GLint x, GLint y, GLint z ); - void ( QGL_DLLEXPORT *m_glWindowPos3iv )( const GLint *p ); - void ( QGL_DLLEXPORT *m_glWindowPos3s )( GLshort x, GLshort y, GLshort z ); - void ( QGL_DLLEXPORT *m_glWindowPos3sv )( const GLshort *p ); - - // GL 1.5 - bool support_GL_1_5; - bool GL_1_5(){ - return support_GL_1_5; - } - void ( QGL_DLLEXPORT *m_glBeginQuery )( GLenum target, GLuint id ); - void ( QGL_DLLEXPORT *m_glBindBuffer )( GLenum target, GLuint buffer ); - void ( QGL_DLLEXPORT *m_glBufferData )( GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage ); - void ( QGL_DLLEXPORT *m_glBufferSubData )( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data ); - void ( QGL_DLLEXPORT *m_glDeleteBuffers )( GLsizei n, const GLuint* buffers ); - void ( QGL_DLLEXPORT *m_glDeleteQueries )( GLsizei n, const GLuint* ids ); - void ( QGL_DLLEXPORT *m_glEndQuery )( GLenum target ); - void ( QGL_DLLEXPORT *m_glGenBuffers )( GLsizei n, GLuint* buffers ); - void ( QGL_DLLEXPORT *m_glGenQueries )( GLsizei n, GLuint* ids ); - void ( QGL_DLLEXPORT *m_glGetBufferParameteriv )( GLenum target, GLenum pname, GLint* params ); - void ( QGL_DLLEXPORT *m_glGetBufferPointerv )( GLenum target, GLenum pname, GLvoid** params ); - void ( QGL_DLLEXPORT *m_glGetBufferSubData )( GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data ); - void ( QGL_DLLEXPORT *m_glGetQueryObjectiv )( GLuint id, GLenum pname, GLint* params ); - void ( QGL_DLLEXPORT *m_glGetQueryObjectuiv )( GLuint id, GLenum pname, GLuint* params ); - void ( QGL_DLLEXPORT *m_glGetQueryiv )( GLenum target, GLenum pname, GLint* params ); - GLboolean ( QGL_DLLEXPORT *m_glIsBuffer )( GLuint buffer ); - GLboolean ( QGL_DLLEXPORT *m_glIsQuery )( GLuint id ); - GLvoid* ( QGL_DLLEXPORT * m_glMapBuffer )( GLenum target, GLenum access ); - GLboolean ( QGL_DLLEXPORT *m_glUnmapBuffer )( GLenum target ); - - // GL_ARB_vertex_program - bool support_ARB_vertex_program; - bool ARB_vertex_program(){ - return support_ARB_vertex_program; - } - void ( QGL_DLLEXPORT *m_glVertexAttrib1sARB )( GLuint index, GLshort x ); - void ( QGL_DLLEXPORT *m_glVertexAttrib1fARB )( GLuint index, GLfloat x ); - void ( QGL_DLLEXPORT *m_glVertexAttrib1dARB )( GLuint index, GLdouble x ); - void ( QGL_DLLEXPORT *m_glVertexAttrib2sARB )( GLuint index, GLshort x, GLshort y ); - void ( QGL_DLLEXPORT *m_glVertexAttrib2fARB )( GLuint index, GLfloat x, GLfloat y ); - void ( QGL_DLLEXPORT *m_glVertexAttrib2dARB )( GLuint index, GLdouble x, GLdouble y ); - void ( QGL_DLLEXPORT *m_glVertexAttrib3sARB )( GLuint index, GLshort x, GLshort y, GLshort z ); - void ( QGL_DLLEXPORT *m_glVertexAttrib3fARB )( GLuint index, GLfloat x, GLfloat y, GLfloat z ); - void ( QGL_DLLEXPORT *m_glVertexAttrib3dARB )( GLuint index, GLdouble x, GLdouble y, GLdouble z ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4sARB )( GLuint index, GLshort x, GLshort y, GLshort z, GLshort w ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4fARB )( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4dARB )( GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4NubARB )( GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w ); - void ( QGL_DLLEXPORT *m_glVertexAttrib1svARB )( GLuint index, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib1fvARB )( GLuint index, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib1dvARB )( GLuint index, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib2svARB )( GLuint index, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib2fvARB )( GLuint index, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib2dvARB )( GLuint index, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib3svARB )( GLuint index, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib3fvARB )( GLuint index, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib3dvARB )( GLuint index, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4bvARB )( GLuint index, const GLbyte *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4svARB )( GLuint index, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4ivARB )( GLuint index, const GLint *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4ubvARB )( GLuint index, const GLubyte *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4usvARB )( GLuint index, const GLushort *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4uivARB )( GLuint index, const GLuint *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4fvARB )( GLuint index, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4dvARB )( GLuint index, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4NbvARB )( GLuint index, const GLbyte *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4NsvARB )( GLuint index, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4NivARB )( GLuint index, const GLint *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4NubvARB )( GLuint index, const GLubyte *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4NusvARB )( GLuint index, const GLushort *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4NuivARB )( GLuint index, const GLuint *v ); - void ( QGL_DLLEXPORT *m_glVertexAttribPointerARB )( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer ); - void ( QGL_DLLEXPORT *m_glEnableVertexAttribArrayARB )( GLuint index ); - void ( QGL_DLLEXPORT *m_glDisableVertexAttribArrayARB )( GLuint index ); - void ( QGL_DLLEXPORT *m_glProgramStringARB )( GLenum target, GLenum format, GLsizei len, const GLvoid *string ); - void ( QGL_DLLEXPORT *m_glBindProgramARB )( GLenum target, GLuint program ); - void ( QGL_DLLEXPORT *m_glDeleteProgramsARB )( GLsizei n, const GLuint *programs ); - void ( QGL_DLLEXPORT *m_glGenProgramsARB )( GLsizei n, GLuint *programs ); - void ( QGL_DLLEXPORT *m_glProgramEnvParameter4dARB )( GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w ); - void ( QGL_DLLEXPORT *m_glProgramEnvParameter4dvARB )( GLenum target, GLuint index, const GLdouble *params ); - void ( QGL_DLLEXPORT *m_glProgramEnvParameter4fARB )( GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w ); - void ( QGL_DLLEXPORT *m_glProgramEnvParameter4fvARB )( GLenum target, GLuint index, const GLfloat *params ); - void ( QGL_DLLEXPORT *m_glProgramLocalParameter4dARB )( GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w ); - void ( QGL_DLLEXPORT *m_glProgramLocalParameter4dvARB )( GLenum target, GLuint index, const GLdouble *params ); - void ( QGL_DLLEXPORT *m_glProgramLocalParameter4fARB )( GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w ); - void ( QGL_DLLEXPORT *m_glProgramLocalParameter4fvARB )( GLenum target, GLuint index, const GLfloat *params ); - void ( QGL_DLLEXPORT *m_glGetProgramEnvParameterdvARB )( GLenum target, GLuint index, GLdouble *params ); - void ( QGL_DLLEXPORT *m_glGetProgramEnvParameterfvARB )( GLenum target, GLuint index, GLfloat *params ); - void ( QGL_DLLEXPORT *m_glGetProgramLocalParameterdvARB )( GLenum target, GLuint index, GLdouble *params ); - void ( QGL_DLLEXPORT *m_glGetProgramLocalParameterfvARB )( GLenum target, GLuint index, GLfloat *params ); - void ( QGL_DLLEXPORT *m_glGetProgramivARB )( GLenum target, GLenum pname, GLint *params ); - void ( QGL_DLLEXPORT *m_glGetProgramStringARB )( GLenum target, GLenum pname, GLvoid *string ); - void ( QGL_DLLEXPORT *m_glGetVertexAttribdvARB )( GLuint index, GLenum pname, GLdouble *params ); - void ( QGL_DLLEXPORT *m_glGetVertexAttribfvARB )( GLuint index, GLenum pname, GLfloat *params ); - void ( QGL_DLLEXPORT *m_glGetVertexAttribivARB )( GLuint index, GLenum pname, GLint *params ); - void ( QGL_DLLEXPORT *m_glGetVertexAttribPointervARB )( GLuint index, GLenum pname, GLvoid **pointer ); - GLboolean ( QGL_DLLEXPORT *m_glIsProgramARB )( GLuint program ); - - // GL_ARB_fragment_program - bool support_ARB_fragment_program; - bool ARB_fragment_program(){ - return support_ARB_fragment_program; - } - - // GL_ARB_shader_objects - bool support_ARB_shader_objects; - bool ARB_shader_objects(){ - return support_ARB_shader_objects; - } - void ( QGL_DLLEXPORT *m_glDeleteObjectARB )( GLhandleARB obj ); - GLhandleARB ( QGL_DLLEXPORT *m_glGetHandleARB )( GLenum pname ); - void ( QGL_DLLEXPORT *m_glDetachObjectARB )( GLhandleARB containerObj, GLhandleARB attachedObj ); - GLhandleARB ( QGL_DLLEXPORT *m_glCreateShaderObjectARB )( GLenum shaderType ); - void ( QGL_DLLEXPORT *m_glShaderSourceARB )( GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length ); - void ( QGL_DLLEXPORT *m_glCompileShaderARB )( GLhandleARB shaderObj ); - GLhandleARB ( QGL_DLLEXPORT *m_glCreateProgramObjectARB )( void ); - void ( QGL_DLLEXPORT *m_glAttachObjectARB )( GLhandleARB containerObj, GLhandleARB obj ); - void ( QGL_DLLEXPORT *m_glLinkProgramARB )( GLhandleARB programObj ); - void ( QGL_DLLEXPORT *m_glUseProgramObjectARB )( GLhandleARB programObj ); - void ( QGL_DLLEXPORT *m_glValidateProgramARB )( GLhandleARB programObj ); - void ( QGL_DLLEXPORT *m_glUniform1fARB )( GLint location, GLfloat v0 ); - void ( QGL_DLLEXPORT *m_glUniform2fARB )( GLint location, GLfloat v0, GLfloat v1 ); - void ( QGL_DLLEXPORT *m_glUniform3fARB )( GLint location, GLfloat v0, GLfloat v1, GLfloat v2 ); - void ( QGL_DLLEXPORT *m_glUniform4fARB )( GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3 ); - void ( QGL_DLLEXPORT *m_glUniform1iARB )( GLint location, GLint v0 ); - void ( QGL_DLLEXPORT *m_glUniform2iARB )( GLint location, GLint v0, GLint v1 ); - void ( QGL_DLLEXPORT *m_glUniform3iARB )( GLint location, GLint v0, GLint v1, GLint v2 ); - void ( QGL_DLLEXPORT *m_glUniform4iARB )( GLint location, GLint v0, GLint v1, GLint v2, GLint v3 ); - void ( QGL_DLLEXPORT *m_glUniform1fvARB )( GLint location, GLsizei count, const GLfloat *value ); - void ( QGL_DLLEXPORT *m_glUniform2fvARB )( GLint location, GLsizei count, const GLfloat *value ); - void ( QGL_DLLEXPORT *m_glUniform3fvARB )( GLint location, GLsizei count, const GLfloat *value ); - void ( QGL_DLLEXPORT *m_glUniform4fvARB )( GLint location, GLsizei count, const GLfloat *value ); - void ( QGL_DLLEXPORT *m_glUniform1ivARB )( GLint location, GLsizei count, const GLint *value ); - void ( QGL_DLLEXPORT *m_glUniform2ivARB )( GLint location, GLsizei count, const GLint *value ); - void ( QGL_DLLEXPORT *m_glUniform3ivARB )( GLint location, GLsizei count, const GLint *value ); - void ( QGL_DLLEXPORT *m_glUniform4ivARB )( GLint location, GLsizei count, const GLint *value ); - void ( QGL_DLLEXPORT *m_glUniformMatrix2fvARB )( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value ); - void ( QGL_DLLEXPORT *m_glUniformMatrix3fvARB )( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value ); - void ( QGL_DLLEXPORT *m_glUniformMatrix4fvARB )( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value ); - void ( QGL_DLLEXPORT *m_glGetObjectParameterfvARB )( GLhandleARB obj, GLenum pname, GLfloat *params ); - void ( QGL_DLLEXPORT *m_glGetObjectParameterivARB )( GLhandleARB obj, GLenum pname, GLint *params ); - void ( QGL_DLLEXPORT *m_glGetInfoLogARB )( GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog ); - void ( QGL_DLLEXPORT *m_glGetAttachedObjectsARB )( GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj ); - GLint ( QGL_DLLEXPORT *m_glGetUniformLocationARB )( GLhandleARB programObj, const GLcharARB *name ); - void ( QGL_DLLEXPORT *m_glGetActiveUniformARB )( GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name ); - void ( QGL_DLLEXPORT *m_glGetUniformfvARB )( GLhandleARB programObj, GLint location, GLfloat *params ); - void ( QGL_DLLEXPORT *m_glGetUniformivARB )( GLhandleARB programObj, GLint location, GLint *params ); - void ( QGL_DLLEXPORT *m_glGetShaderSourceARB )( GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source ); - - // GL_ARB_vertex_shader - bool support_ARB_vertex_shader; - bool ARB_vertex_shader(){ - return support_ARB_vertex_shader; - } -#if 0 - void ( QGL_DLLEXPORT *m_glVertexAttrib1fARB )( GLuint index, GLfloat v0 ); - void ( QGL_DLLEXPORT *m_glVertexAttrib1sARB )( GLuint index, GLshort v0 ); - void ( QGL_DLLEXPORT *m_glVertexAttrib1dARB )( GLuint index, GLdouble v0 ); - void ( QGL_DLLEXPORT *m_glVertexAttrib2fARB )( GLuint index, GLfloat v0, GLfloat v1 ); - void ( QGL_DLLEXPORT *m_glVertexAttrib2sARB )( GLuint index, GLshort v0, GLshort v1 ); - void ( QGL_DLLEXPORT *m_glVertexAttrib2dARB )( GLuint index, GLdouble v0, GLdouble v1 ); - void ( QGL_DLLEXPORT *m_glVertexAttrib3fARB )( GLuint index, GLfloat v0, GLfloat v1, GLfloat v2 ); - void ( QGL_DLLEXPORT *m_glVertexAttrib3sARB )( GLuint index, GLshort v0, GLshort v1, GLshort v2 ); - void ( QGL_DLLEXPORT *m_glVertexAttrib3dARB )( GLuint index, GLdouble v0, GLdouble v1, GLdouble v2 ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4fARB )( GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3 ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4sARB )( GLuint index, GLshort v0, GLshort v1, GLshort v2, GLshort v3 ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4dARB )( GLuint index, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3 ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4NubARB )( GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w ); - void ( QGL_DLLEXPORT *m_glVertexAttrib1fvARB )( GLuint index, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib1svARB )( GLuint index, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib1dvARB )( GLuint index, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib2fvARB )( GLuint index, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib2svARB )( GLuint index, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib2dvARB )( GLuint index, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib3fvARB )( GLuint index, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib3svARB )( GLuint index, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib3dvARB )( GLuint index, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4fvARB )( GLuint index, const GLfloat *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4svARB )( GLuint index, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4dvARB )( GLuint index, const GLdouble *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4ivARB )( GLuint index, const GLint *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4bvARB )( GLuint index, const GLbyte *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4ubvARB )( GLuint index, const GLubyte *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4usvARB )( GLuint index, const GLushort *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4uivARB )( GLuint index, const GLuint *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4NbvARB )( GLuint index, const GLbyte *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4NsvARB )( GLuint index, const GLshort *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4NivARB )( GLuint index, const GLint *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4NubvARB )( GLuint index, const GLubyte *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4NusvARB )( GLuint index, const GLushort *v ); - void ( QGL_DLLEXPORT *m_glVertexAttrib4NuivARB )( GLuint index, const GLuint *v ); - void ( QGL_DLLEXPORT *m_glVertexAttribPointerARB )( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer ); - void ( QGL_DLLEXPORT *m_glEnableVertexAttribArrayARB )( GLuint index ); - void ( QGL_DLLEXPORT *m_glDisableVertexAttribArrayARB )( GLuint index ); -#endif - void ( QGL_DLLEXPORT *m_glBindAttribLocationARB )( GLhandleARB programObj, GLuint index, const GLcharARB *name ); - void ( QGL_DLLEXPORT *m_glGetActiveAttribARB )( GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name ); - GLint ( QGL_DLLEXPORT *m_glGetAttribLocationARB )( GLhandleARB programObj, const GLcharARB *name ); -#if 0 - void ( QGL_DLLEXPORT *m_glGetVertexAttribdvARB )( GLuint index, GLenum pname, GLdouble *params ); - void ( QGL_DLLEXPORT *m_glGetVertexAttribfvARB )( GLuint index, GLenum pname, GLfloat *params ); - void ( QGL_DLLEXPORT *m_glGetVertexAttribivARB )( GLuint index, GLenum pname, GLint *params ); - void ( QGL_DLLEXPORT *m_glGetVertexAttribPointervARB )( GLuint index, GLenum pname, GLvoid **pointer ); -#endif - - // ARB_fragment_shader - bool support_ARB_fragment_shader; - bool ARB_fragment_shader(){ - return support_ARB_fragment_shader; - } - - // ARB_shading_language_100 - bool support_ARB_shading_language_100; - bool ARB_shading_language_100(){ - return support_ARB_shading_language_100; - } - - // GL_NV_vertex_program2 - bool support_NV_vertex_program2; - bool NV_vertex_program2(){ - return support_NV_vertex_program2; - } - GLboolean ( QGL_DLLEXPORT* m_glAreProgramsResidentNV )( GLsizei, const GLuint *, GLboolean * ); - void ( QGL_DLLEXPORT* m_glBindProgramNV )( GLenum, GLuint ); - void ( QGL_DLLEXPORT* m_glDeleteProgramsNV )( GLsizei, const GLuint * ); - void ( QGL_DLLEXPORT* m_glExecuteProgramNV )( GLenum, GLuint, const GLfloat * ); - void ( QGL_DLLEXPORT* m_glGenProgramsNV )( GLsizei, GLuint * ); - void ( QGL_DLLEXPORT* m_glGetProgramParameterdvNV )( GLenum, GLuint, GLenum, GLdouble * ); - void ( QGL_DLLEXPORT* m_glGetProgramParameterfvNV )( GLenum, GLuint, GLenum, GLfloat * ); - void ( QGL_DLLEXPORT* m_glGetProgramivNV )( GLuint, GLenum, GLint * ); - void ( QGL_DLLEXPORT* m_glGetProgramStringNV )( GLuint, GLenum, GLubyte * ); - void ( QGL_DLLEXPORT* m_glGetTrackMatrixivNV )( GLenum, GLuint, GLenum, GLint * ); - void ( QGL_DLLEXPORT* m_glGetVertexAttribdvNV )( GLuint, GLenum, GLdouble * ); - void ( QGL_DLLEXPORT* m_glGetVertexAttribfvNV )( GLuint, GLenum, GLfloat * ); - void ( QGL_DLLEXPORT* m_glGetVertexAttribivNV )( GLuint, GLenum, GLint * ); - void ( QGL_DLLEXPORT* m_glGetVertexAttribPointervNV )( GLuint, GLenum, GLvoid* * ); - GLboolean ( QGL_DLLEXPORT* m_glIsProgramNV )( GLuint ); - void ( QGL_DLLEXPORT* m_glLoadProgramNV )( GLenum, GLuint, GLsizei, const GLubyte * ); - void ( QGL_DLLEXPORT* m_glProgramParameter4fNV )( GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat ); - void ( QGL_DLLEXPORT* m_glProgramParameter4fvNV )( GLenum, GLuint, const GLfloat * ); - void ( QGL_DLLEXPORT* m_glProgramParameters4fvNV )( GLenum, GLuint, GLuint, const GLfloat * ); - void ( QGL_DLLEXPORT* m_glRequestResidentProgramsNV )( GLsizei, const GLuint * ); - void ( QGL_DLLEXPORT* m_glTrackMatrixNV )( GLenum, GLuint, GLenum, GLenum ); - void ( QGL_DLLEXPORT* m_glVertexAttribPointerNV )( GLuint, GLint, GLenum, GLsizei, const GLvoid * ); - void ( QGL_DLLEXPORT* m_glVertexAttrib1fNV )( GLuint, GLfloat ); - void ( QGL_DLLEXPORT* m_glVertexAttrib1fvNV )( GLuint, const GLfloat * ); - void ( QGL_DLLEXPORT* m_glVertexAttrib2fNV )( GLuint, GLfloat, GLfloat ); - void ( QGL_DLLEXPORT* m_glVertexAttrib2fvNV )( GLuint, const GLfloat * ); - void ( QGL_DLLEXPORT* m_glVertexAttrib3fNV )( GLuint, GLfloat, GLfloat, GLfloat ); - void ( QGL_DLLEXPORT* m_glVertexAttrib3fvNV )( GLuint, const GLfloat * ); - void ( QGL_DLLEXPORT* m_glVertexAttrib4fNV )( GLuint, GLfloat, GLfloat, GLfloat, GLfloat ); - void ( QGL_DLLEXPORT* m_glVertexAttrib4fvNV )( GLuint, const GLfloat * ); - void ( QGL_DLLEXPORT* m_glVertexAttribs1fvNV )( GLuint, GLsizei, const GLfloat * ); - void ( QGL_DLLEXPORT* m_glVertexAttribs2fvNV )( GLuint, GLsizei, const GLfloat * ); - void ( QGL_DLLEXPORT* m_glVertexAttribs3fvNV )( GLuint, GLsizei, const GLfloat * ); - void ( QGL_DLLEXPORT* m_glVertexAttribs4fvNV )( GLuint, GLsizei, const GLfloat * ); - - // GL_NV_fragment_program - bool support_NV_fragment_program; - bool NV_fragment_program(){ - return support_NV_fragment_program; - } - void ( QGL_DLLEXPORT* m_glProgramNamedParameter4fNV )( GLuint, GLsizei, const GLubyte *, GLfloat, GLfloat, GLfloat, GLfloat ); - void ( QGL_DLLEXPORT* m_glProgramNamedParameter4fvNV )( GLuint, GLsizei, const GLubyte *, const GLfloat * ); - void ( QGL_DLLEXPORT* m_glGetProgramNamedParameterfvNV )( GLuint, GLsizei, const GLubyte *, GLfloat * ); - - // GL_ARB_framebuffer_object - bool support_ARB_framebuffer_object; - bool ARB_framebuffer_object(){ - return support_ARB_framebuffer_object; - } - void ( QGL_DLLEXPORT * m_glBindFramebuffer )( GLenum target, GLuint framebuffer ); - void ( QGL_DLLEXPORT * m_glBindRenderbuffer )( GLenum target, GLuint renderbuffer ); - void ( QGL_DLLEXPORT * m_glBlitFramebuffer )( GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter ); - GLenum( QGL_DLLEXPORT * m_glCheckFramebufferStatus )( GLenum target ); - void ( QGL_DLLEXPORT * m_glDeleteFramebuffers )( GLsizei n, const GLuint * framebuffers ); - void ( QGL_DLLEXPORT * m_glDeleteRenderbuffers )( GLsizei n, const GLuint * renderbuffers ); - void ( QGL_DLLEXPORT * m_glFramebufferRenderbuffer )( GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer ); - void ( QGL_DLLEXPORT * m_glFramebufferTexture1D )( GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level ); - void ( QGL_DLLEXPORT * m_glFramebufferTexture2D )( GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level ); - void ( QGL_DLLEXPORT * m_glFramebufferTexture3D )( GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer ); - void ( QGL_DLLEXPORT * m_glFramebufferTextureLayer )( GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer ); - void ( QGL_DLLEXPORT * m_glGenFramebuffers )( GLsizei n, GLuint * framebuffers ); - void ( QGL_DLLEXPORT * m_glGenRenderbuffers )( GLsizei n, GLuint * renderbuffers ); - void ( QGL_DLLEXPORT * m_glGenerateMipmap )( GLenum target ); - void ( QGL_DLLEXPORT * m_glGetFramebufferAttachmentParameteriv )( GLenum target, GLenum attachment, GLenum pname, GLint * params ); - void ( QGL_DLLEXPORT * m_glGetRenderbufferParameteriv )( GLenum target, GLenum pname, GLint * params ); - GLboolean( QGL_DLLEXPORT * m_glIsFramebuffer )( GLuint framebuffer ); - GLboolean( QGL_DLLEXPORT * m_glIsRenderbuffer )( GLuint renderbuffer ); - void ( QGL_DLLEXPORT * m_glRenderbufferStorage )( GLenum target, GLenum internalformat, GLsizei width, GLsizei height ); - void ( QGL_DLLEXPORT * m_glRenderbufferStorageMultisample )( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height ); }; #include "modulesystem.h" @@ -2939,6 +91,10 @@ inline OpenGLBinding& GlobalOpenGL(){ return GlobalOpenGLModule::getTable(); } +inline QOpenGLFunctions_2_0& gl(){ + return *GlobalOpenGL().funcs; +} + #if defined( _DEBUG ) #define GlobalOpenGL_debugAssertNoErrors() GlobalOpenGL().assertNoErrors( __FILE__, __LINE__ ) #else diff --git a/include/igtkgl.h b/include/igtkgl.h index d8f32093..8ff3e3d0 100644 --- a/include/igtkgl.h +++ b/include/igtkgl.h @@ -23,18 +23,8 @@ #include "generic/constant.h" -typedef struct _GtkWidget GtkWidget; -typedef int gint; -typedef gint gboolean; - struct _QERGtkGLTable { INTEGER_CONSTANT( Version, 1 ); STRING_CONSTANT( Name, "gtkgl" ); - - GtkWidget* ( *glwidget_new )(gboolean zbufffer); - void ( *glwidget_swap_buffers )( GtkWidget* widget ); - gboolean ( *glwidget_make_current )( GtkWidget* widget ); - void ( *glwidget_destroy_context )( GtkWidget* widget ); - void ( *glwidget_create_context )( GtkWidget* widget ); }; diff --git a/include/irender.h b/include/irender.h index d1a7428b..49589941 100644 --- a/include/irender.h +++ b/include/irender.h @@ -29,31 +29,29 @@ // Rendering states to sort by. // Higher bits have the most effect - slowest state changes should be highest. -const unsigned int RENDER_DEFAULT = 0; -const unsigned int RENDER_LINESTIPPLE = 1 << 0; // glEnable(GL_LINE_STIPPLE) -const unsigned int RENDER_LINESMOOTH = 1 << 1; // glEnable(GL_LINE_SMOOTH) -const unsigned int RENDER_POLYGONSTIPPLE = 1 << 2; // glEnable(GL_POLYGON_STIPPLE) -const unsigned int RENDER_POLYGONSMOOTH = 1 << 3; // glEnable(GL_POLYGON_SMOOTH) -const unsigned int RENDER_ALPHATEST = 1 << 4; // glEnable(GL_ALPHA_TEST) -const unsigned int RENDER_DEPTHTEST = 1 << 5; // glEnable(GL_DEPTH_TEST) -const unsigned int RENDER_DEPTHWRITE = 1 << 6; // glDepthMask(GL_TRUE) -const unsigned int RENDER_COLOURWRITE = 1 << 7; // glColorMask(GL_TRUE; GL_TRUE; GL_TRUE; GL_TRUE) -const unsigned int RENDER_CULLFACE = 1 << 8; // glEnable(GL_CULL_FACE) -const unsigned int RENDER_SCALED = 1 << 9; // glEnable(GL_NORMALIZE) -const unsigned int RENDER_SMOOTH = 1 << 10; // glShadeModel -const unsigned int RENDER_FOG = 1 << 11; // glEnable(GL_FOG) -const unsigned int RENDER_LIGHTING = 1 << 12; // glEnable(GL_LIGHTING) -const unsigned int RENDER_BLEND = 1 << 13; // glEnable(GL_BLEND) -const unsigned int RENDER_OFFSETLINE = 1 << 14; // glEnable(GL_POLYGON_OFFSET_LINE) -const unsigned int RENDER_FILL = 1 << 15; // glPolygonMode -const unsigned int RENDER_COLOURARRAY = 1 << 16; // glEnableClientState(GL_COLOR_ARRAY) -const unsigned int RENDER_COLOURCHANGE = 1 << 17; // render() is allowed to call glColor*() -const unsigned int RENDER_TEXTURE = 1 << 18; // glEnable(GL_TEXTURE_2D) -const unsigned int RENDER_BUMP = 1 << 19; -const unsigned int RENDER_PROGRAM = 1 << 20; -const unsigned int RENDER_SCREEN = 1 << 21; -const unsigned int RENDER_TEXT = 1 << 22; // override: globalstate |= RENDER_TEXTURE | RENDER_BLEND | RENDER_FILL -const unsigned int RENDER_OVERRIDE = 1 << 23; // override: globalstate |= RENDER_FILL +const unsigned int RENDER_DEFAULT = 0; +const unsigned int RENDER_LINESTIPPLE = 1 << 0; // glEnable(GL_LINE_STIPPLE) +const unsigned int RENDER_POLYGONSTIPPLE = 1 << 1; // glEnable(GL_POLYGON_STIPPLE) +const unsigned int RENDER_ALPHATEST = 1 << 2; // glEnable(GL_ALPHA_TEST) +const unsigned int RENDER_DEPTHTEST = 1 << 3; // glEnable(GL_DEPTH_TEST) +const unsigned int RENDER_DEPTHWRITE = 1 << 4; // glDepthMask(GL_TRUE) +const unsigned int RENDER_COLOURWRITE = 1 << 5; // glColorMask(GL_TRUE; GL_TRUE; GL_TRUE; GL_TRUE) +const unsigned int RENDER_CULLFACE = 1 << 6; // glEnable(GL_CULL_FACE) +const unsigned int RENDER_SCALED = 1 << 7; // glEnable(GL_NORMALIZE) +const unsigned int RENDER_SMOOTH = 1 << 8; // glShadeModel +const unsigned int RENDER_FOG = 1 << 9; // glEnable(GL_FOG) +const unsigned int RENDER_LIGHTING = 1 << 10; // glEnable(GL_LIGHTING) +const unsigned int RENDER_BLEND = 1 << 11; // glEnable(GL_BLEND) +const unsigned int RENDER_OFFSETLINE = 1 << 12; // glEnable(GL_POLYGON_OFFSET_LINE) +const unsigned int RENDER_FILL = 1 << 13; // glPolygonMode +const unsigned int RENDER_COLOURARRAY = 1 << 14; // glEnableClientState(GL_COLOR_ARRAY) +const unsigned int RENDER_COLOURCHANGE = 1 << 15; // render() is allowed to call glColor*() +const unsigned int RENDER_TEXTURE = 1 << 16; // glEnable(GL_TEXTURE_2D) +const unsigned int RENDER_BUMP = 1 << 17; +const unsigned int RENDER_PROGRAM = 1 << 18; +const unsigned int RENDER_SCREEN = 1 << 19; +const unsigned int RENDER_TEXT = 1 << 20; // override: globalstate |= RENDER_TEXTURE | RENDER_BLEND | RENDER_FILL +const unsigned int RENDER_OVERRIDE = 1 << 21; // override: globalstate |= RENDER_FILL typedef unsigned int RenderStateFlags; @@ -138,9 +136,6 @@ public: virtual void realise() = 0; virtual void unrealise() = 0; - virtual bool lightingSupported() const = 0; - virtual bool useShaderLanguage() const = 0; - virtual const LightList& attach( LightCullable& cullable ) = 0; virtual void detach( LightCullable& cullable ) = 0; virtual void changed( LightCullable& cullable ) = 0; diff --git a/include/qerplugin.h b/include/qerplugin.h index c8975ada..a2e263fd 100644 --- a/include/qerplugin.h +++ b/include/qerplugin.h @@ -34,58 +34,47 @@ // NOTE: parent can be 0 in all functions but it's best to set them // this API does not depend on gtk+ or glib -typedef struct _GtkWidget GtkWidget; +class QWidget; +class QString; -enum EMessageBoxType +enum class EMessageBoxType { - eMB_OK, - eMB_OKCANCEL, - eMB_YESNO, - eMB_YESNOCANCEL, - eMB_NOYES, -}; - -enum EMessageBoxIcon -{ - eMB_ICONDEFAULT, - eMB_ICONERROR, - eMB_ICONWARNING, - eMB_ICONQUESTION, - eMB_ICONASTERISK, + Info, + Question, /* eIDYES | eIDNO */ + Warning, + Error, }; enum EMessageBoxReturn { - eIDOK, - eIDCANCEL, - eIDYES, - eIDNO, + eIDOK = 1, + eIDCANCEL = 2, + eIDYES = 4, + eIDNO = 8, }; // simple Message Box, see above for the 'type' flags - -typedef EMessageBoxReturn ( *PFN_QERAPP_MESSAGEBOX )( GtkWidget *parent, const char* text, const char* caption /* = "NetRadiant"*/, EMessageBoxType type /* = eMB_OK*/, EMessageBoxIcon icon /* = eMB_ICONDEFAULT*/ ); +//! \p buttons is combination of \enum EMessageBoxReturn flags or 0 for buttons, respecting \enum class EMessageBoxType +typedef EMessageBoxReturn ( *PFN_QERAPP_MESSAGEBOX )( QWidget *parent, const char* text, const char* caption /* = "NetRadiant"*/, EMessageBoxType type /* = Info*/, int buttons /* = 0*/ ); // file and directory selection functions return null if the user hits cancel // - 'title' is the dialog title (can be null) // - 'path' is used to set the initial directory (can be null) // - 'pattern': the first pattern is for the win32 mode, then comes the Gtk pattern list, see Radiant source for samples -typedef const char* ( *PFN_QERAPP_FILEDIALOG )( GtkWidget *parent, bool open, const char* title, const char* path /* = 0*/, const char* pattern /* = 0*/, bool want_load /* = false*/, bool want_import /* = false*/, bool want_save /* = false*/ ); - -// returns a gchar* string that must be g_free'd by the user -typedef char* ( *PFN_QERAPP_DIRDIALOG )( GtkWidget *parent, const char* title /* = "Choose Directory"*/, const char* path /* = 0*/ ); +typedef const char* ( *PFN_QERAPP_FILEDIALOG )( QWidget *parent, bool open, const char* title, const char* path /* = 0*/, const char* pattern /* = 0*/, bool want_load /* = false*/, bool want_import /* = false*/, bool want_save /* = false*/ ); +typedef QString ( *PFN_QERAPP_DIRDIALOG )( QWidget *parent, const QString& path /* = {} */ ); // return true if the user closed the dialog with 'Ok' // 'color' is used to set the initial value and store the selected value template class BasicVector3; typedef BasicVector3 Vector3; -typedef bool ( *PFN_QERAPP_COLORDIALOG )( GtkWidget *parent, Vector3& color, +typedef bool ( *PFN_QERAPP_COLORDIALOG )( QWidget *parent, Vector3& color, const char* title /* = "Choose Color"*/ ); -// load a .bmp file and create a GtkImage widget from it +// load an image file and create QIcon from it // NOTE: 'filename' is relative to /plugins/bitmaps/ -typedef struct _GtkImage GtkImage; -typedef GtkImage* ( *PFN_QERAPP_NEWIMAGE )( const char* filename ); +class QIcon; +typedef QIcon ( *PFN_QERAPP_NEWICON )( const char* filename ); // ======================================== @@ -156,12 +145,12 @@ struct _QERFuncTable_1 const char* ( *TextureBrowser_getSelectedShader )( ); - // GTK+ functions + // Qt functions PFN_QERAPP_MESSAGEBOX m_pfnMessageBox; PFN_QERAPP_FILEDIALOG m_pfnFileDialog; PFN_QERAPP_DIRDIALOG m_pfnDirDialog; PFN_QERAPP_COLORDIALOG m_pfnColorDialog; - PFN_QERAPP_NEWIMAGE m_pfnNewImage; + PFN_QERAPP_NEWICON m_pfnNewIcon; }; diff --git a/include/warnings.h b/include/warnings.h deleted file mode 100644 index 4aea4cd7..00000000 --- a/include/warnings.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#pragma once - -#if _MSC_VER > 1000 && defined( WIN32 ) -#pragma warning(disable:4355) // 'this' : used in base member initializer list -#pragma warning(disable:4503) // '[symbol]' : decorated name length exceeded, name was truncated -#endif diff --git a/install-dlls-msys2-mingw.sh b/install-dlls-msys2-mingw.sh index 78962b37..2875bf84 100644 --- a/install-dlls-msys2-mingw.sh +++ b/install-dlls-msys2-mingw.sh @@ -70,12 +70,8 @@ done cd $MINGWDIR for EXTRAPATH in \ - './lib/gtk-2.0/2.10.0/engines/*.dll' \ - './lib/gtk-2.0/modules/*.dll' \ - './share/themes' \ - './etc/fonts/fonts.conf' \ - './lib/gdk-pixbuf-2.0/2.10.0/loaders/*.dll' \ - './lib/gdk-pixbuf-2.0/2.10.0/loaders.cache' \ + './share/qt5/plugins/imageformats/*.dll' \ + './share/qt5/plugins/platforms/*.dll' \ ; do cp --parent -v `find $EXTRAPATH -type f` "$INSTALLDIR" done diff --git a/libs/debugging/debugging.h b/libs/debugging/debugging.h index debe855c..76d1402f 100644 --- a/libs/debugging/debugging.h +++ b/libs/debugging/debugging.h @@ -25,7 +25,6 @@ /// \brief Debugging macros for fatal error/assert messages. #include "stream/textstream.h" -#include "warnings.h" #include "generic/static.h" #if defined( _MSC_VER ) && ( defined( _M_IX86 ) || defined( _M_AMD64 ) ) diff --git a/libs/entitylib.h b/libs/entitylib.h index 15b33c4f..ce701547 100644 --- a/libs/entitylib.h +++ b/libs/entitylib.h @@ -50,36 +50,36 @@ inline void arrow_draw( const Vector3& origin, const Vector3& direction_forward, Vector3 tip3( vector3_added( vector3_added( endpoint, vector3_scaled( direction_forward, -8.0 ) ), vector3_scaled( direction_left, -4.0 ) ) ); Vector3 tip4( vector3_added( tip3, vector3_scaled( direction_left, 8.0 ) ) ); - glBegin( GL_LINES ); + gl().glBegin( GL_LINES ); - glVertex3fv( vector3_to_array( origin ) ); - glVertex3fv( vector3_to_array( endpoint ) ); + gl().glVertex3fv( vector3_to_array( origin ) ); + gl().glVertex3fv( vector3_to_array( endpoint ) ); - glVertex3fv( vector3_to_array( endpoint ) ); - glVertex3fv( vector3_to_array( tip1 ) ); + gl().glVertex3fv( vector3_to_array( endpoint ) ); + gl().glVertex3fv( vector3_to_array( tip1 ) ); - glVertex3fv( vector3_to_array( endpoint ) ); - glVertex3fv( vector3_to_array( tip2 ) ); + gl().glVertex3fv( vector3_to_array( endpoint ) ); + gl().glVertex3fv( vector3_to_array( tip2 ) ); - glVertex3fv( vector3_to_array( endpoint ) ); - glVertex3fv( vector3_to_array( tip3 ) ); + gl().glVertex3fv( vector3_to_array( endpoint ) ); + gl().glVertex3fv( vector3_to_array( tip3 ) ); - glVertex3fv( vector3_to_array( endpoint ) ); - glVertex3fv( vector3_to_array( tip4 ) ); + gl().glVertex3fv( vector3_to_array( endpoint ) ); + gl().glVertex3fv( vector3_to_array( tip4 ) ); - glVertex3fv( vector3_to_array( tip1 ) ); - glVertex3fv( vector3_to_array( tip3 ) ); + gl().glVertex3fv( vector3_to_array( tip1 ) ); + gl().glVertex3fv( vector3_to_array( tip3 ) ); - glVertex3fv( vector3_to_array( tip3 ) ); - glVertex3fv( vector3_to_array( tip2 ) ); + gl().glVertex3fv( vector3_to_array( tip3 ) ); + gl().glVertex3fv( vector3_to_array( tip2 ) ); - glVertex3fv( vector3_to_array( tip2 ) ); - glVertex3fv( vector3_to_array( tip4 ) ); + gl().glVertex3fv( vector3_to_array( tip2 ) ); + gl().glVertex3fv( vector3_to_array( tip4 ) ); - glVertex3fv( vector3_to_array( tip4 ) ); - glVertex3fv( vector3_to_array( tip1 ) ); + gl().glVertex3fv( vector3_to_array( tip4 ) ); + gl().glVertex3fv( vector3_to_array( tip1 ) ); - glEnd(); + gl().glEnd(); } class RenderableArrow : public OpenGLRenderable @@ -125,58 +125,58 @@ inline void aabb_draw_wire( const Vector3 points[8] ){ 1, 7 // diagonal line (connect mins to maxs corner) }; #if 1 - glVertexPointer( 3, GL_FLOAT, 0, points ); - glDrawElements( GL_LINES, sizeof( indices ) / sizeof( indices[0] ), GL_UNSIGNED_INT, indices ); + gl().glVertexPointer( 3, GL_FLOAT, 0, points ); + gl().glDrawElements( GL_LINES, sizeof( indices ) / sizeof( indices[0] ), GL_UNSIGNED_INT, indices ); #else - glBegin( GL_LINES ); + gl().glBegin( GL_LINES ); for ( std::size_t i = 0; i < sizeof( indices ) / sizeof( indices[0] ); ++i ) { - glVertex3fv( vector3_to_array( points[indices[i]] ) ); + gl().glVertex3fv( vector3_to_array( points[indices[i]] ) ); } - glEnd(); + gl().glEnd(); #endif } inline void aabb_draw_flatshade( const Vector3 points[8] ){ - glBegin( GL_QUADS ); + gl().glBegin( GL_QUADS ); - glNormal3fv( vector3_to_array( aabb_normals[0] ) ); - glVertex3fv( vector3_to_array( points[2] ) ); - glVertex3fv( vector3_to_array( points[1] ) ); - glVertex3fv( vector3_to_array( points[5] ) ); - glVertex3fv( vector3_to_array( points[6] ) ); + gl().glNormal3fv( vector3_to_array( aabb_normals[0] ) ); + gl().glVertex3fv( vector3_to_array( points[2] ) ); + gl().glVertex3fv( vector3_to_array( points[1] ) ); + gl().glVertex3fv( vector3_to_array( points[5] ) ); + gl().glVertex3fv( vector3_to_array( points[6] ) ); - glNormal3fv( vector3_to_array( aabb_normals[1] ) ); - glVertex3fv( vector3_to_array( points[1] ) ); - glVertex3fv( vector3_to_array( points[0] ) ); - glVertex3fv( vector3_to_array( points[4] ) ); - glVertex3fv( vector3_to_array( points[5] ) ); + gl().glNormal3fv( vector3_to_array( aabb_normals[1] ) ); + gl().glVertex3fv( vector3_to_array( points[1] ) ); + gl().glVertex3fv( vector3_to_array( points[0] ) ); + gl().glVertex3fv( vector3_to_array( points[4] ) ); + gl().glVertex3fv( vector3_to_array( points[5] ) ); - glNormal3fv( vector3_to_array( aabb_normals[2] ) ); - glVertex3fv( vector3_to_array( points[0] ) ); - glVertex3fv( vector3_to_array( points[1] ) ); - glVertex3fv( vector3_to_array( points[2] ) ); - glVertex3fv( vector3_to_array( points[3] ) ); + gl().glNormal3fv( vector3_to_array( aabb_normals[2] ) ); + gl().glVertex3fv( vector3_to_array( points[0] ) ); + gl().glVertex3fv( vector3_to_array( points[1] ) ); + gl().glVertex3fv( vector3_to_array( points[2] ) ); + gl().glVertex3fv( vector3_to_array( points[3] ) ); - glNormal3fv( vector3_to_array( aabb_normals[3] ) ); - glVertex3fv( vector3_to_array( points[0] ) ); - glVertex3fv( vector3_to_array( points[3] ) ); - glVertex3fv( vector3_to_array( points[7] ) ); - glVertex3fv( vector3_to_array( points[4] ) ); + gl().glNormal3fv( vector3_to_array( aabb_normals[3] ) ); + gl().glVertex3fv( vector3_to_array( points[0] ) ); + gl().glVertex3fv( vector3_to_array( points[3] ) ); + gl().glVertex3fv( vector3_to_array( points[7] ) ); + gl().glVertex3fv( vector3_to_array( points[4] ) ); - glNormal3fv( vector3_to_array( aabb_normals[4] ) ); - glVertex3fv( vector3_to_array( points[3] ) ); - glVertex3fv( vector3_to_array( points[2] ) ); - glVertex3fv( vector3_to_array( points[6] ) ); - glVertex3fv( vector3_to_array( points[7] ) ); + gl().glNormal3fv( vector3_to_array( aabb_normals[4] ) ); + gl().glVertex3fv( vector3_to_array( points[3] ) ); + gl().glVertex3fv( vector3_to_array( points[2] ) ); + gl().glVertex3fv( vector3_to_array( points[6] ) ); + gl().glVertex3fv( vector3_to_array( points[7] ) ); - glNormal3fv( vector3_to_array( aabb_normals[5] ) ); - glVertex3fv( vector3_to_array( points[7] ) ); - glVertex3fv( vector3_to_array( points[6] ) ); - glVertex3fv( vector3_to_array( points[5] ) ); - glVertex3fv( vector3_to_array( points[4] ) ); + gl().glNormal3fv( vector3_to_array( aabb_normals[5] ) ); + gl().glVertex3fv( vector3_to_array( points[7] ) ); + gl().glVertex3fv( vector3_to_array( points[6] ) ); + gl().glVertex3fv( vector3_to_array( points[5] ) ); + gl().glVertex3fv( vector3_to_array( points[4] ) ); - glEnd(); + gl().glEnd(); } inline void aabb_draw_wire( const AABB& aabb ){ @@ -195,69 +195,69 @@ inline void aabb_draw_textured( const AABB& aabb ){ Vector3 points[8]; aabb_corners( aabb, points ); - glBegin( GL_QUADS ); + gl().glBegin( GL_QUADS ); - glNormal3fv( vector3_to_array( aabb_normals[0] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[2] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[1] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[5] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[6] ) ); + gl().glNormal3fv( vector3_to_array( aabb_normals[0] ) ); + gl().glTexCoord2fv( aabb_texcoord_topleft ); + gl().glVertex3fv( vector3_to_array( points[2] ) ); + gl().glTexCoord2fv( aabb_texcoord_topright ); + gl().glVertex3fv( vector3_to_array( points[1] ) ); + gl().glTexCoord2fv( aabb_texcoord_botright ); + gl().glVertex3fv( vector3_to_array( points[5] ) ); + gl().glTexCoord2fv( aabb_texcoord_botleft ); + gl().glVertex3fv( vector3_to_array( points[6] ) ); - glNormal3fv( vector3_to_array( aabb_normals[1] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[1] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[0] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[4] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[5] ) ); + gl().glNormal3fv( vector3_to_array( aabb_normals[1] ) ); + gl().glTexCoord2fv( aabb_texcoord_topleft ); + gl().glVertex3fv( vector3_to_array( points[1] ) ); + gl().glTexCoord2fv( aabb_texcoord_topright ); + gl().glVertex3fv( vector3_to_array( points[0] ) ); + gl().glTexCoord2fv( aabb_texcoord_botright ); + gl().glVertex3fv( vector3_to_array( points[4] ) ); + gl().glTexCoord2fv( aabb_texcoord_botleft ); + gl().glVertex3fv( vector3_to_array( points[5] ) ); - glNormal3fv( vector3_to_array( aabb_normals[2] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[0] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[1] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[2] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[3] ) ); + gl().glNormal3fv( vector3_to_array( aabb_normals[2] ) ); + gl().glTexCoord2fv( aabb_texcoord_topleft ); + gl().glVertex3fv( vector3_to_array( points[0] ) ); + gl().glTexCoord2fv( aabb_texcoord_topright ); + gl().glVertex3fv( vector3_to_array( points[1] ) ); + gl().glTexCoord2fv( aabb_texcoord_botright ); + gl().glVertex3fv( vector3_to_array( points[2] ) ); + gl().glTexCoord2fv( aabb_texcoord_botleft ); + gl().glVertex3fv( vector3_to_array( points[3] ) ); - glNormal3fv( vector3_to_array( aabb_normals[3] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[0] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[3] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[7] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[4] ) ); + gl().glNormal3fv( vector3_to_array( aabb_normals[3] ) ); + gl().glTexCoord2fv( aabb_texcoord_topleft ); + gl().glVertex3fv( vector3_to_array( points[0] ) ); + gl().glTexCoord2fv( aabb_texcoord_topright ); + gl().glVertex3fv( vector3_to_array( points[3] ) ); + gl().glTexCoord2fv( aabb_texcoord_botright ); + gl().glVertex3fv( vector3_to_array( points[7] ) ); + gl().glTexCoord2fv( aabb_texcoord_botleft ); + gl().glVertex3fv( vector3_to_array( points[4] ) ); - glNormal3fv( vector3_to_array( aabb_normals[4] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[3] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[2] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[6] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[7] ) ); + gl().glNormal3fv( vector3_to_array( aabb_normals[4] ) ); + gl().glTexCoord2fv( aabb_texcoord_topleft ); + gl().glVertex3fv( vector3_to_array( points[3] ) ); + gl().glTexCoord2fv( aabb_texcoord_topright ); + gl().glVertex3fv( vector3_to_array( points[2] ) ); + gl().glTexCoord2fv( aabb_texcoord_botright ); + gl().glVertex3fv( vector3_to_array( points[6] ) ); + gl().glTexCoord2fv( aabb_texcoord_botleft ); + gl().glVertex3fv( vector3_to_array( points[7] ) ); - glNormal3fv( vector3_to_array( aabb_normals[5] ) ); - glTexCoord2fv( aabb_texcoord_topleft ); - glVertex3fv( vector3_to_array( points[7] ) ); - glTexCoord2fv( aabb_texcoord_topright ); - glVertex3fv( vector3_to_array( points[6] ) ); - glTexCoord2fv( aabb_texcoord_botright ); - glVertex3fv( vector3_to_array( points[5] ) ); - glTexCoord2fv( aabb_texcoord_botleft ); - glVertex3fv( vector3_to_array( points[4] ) ); + gl().glNormal3fv( vector3_to_array( aabb_normals[5] ) ); + gl().glTexCoord2fv( aabb_texcoord_topleft ); + gl().glVertex3fv( vector3_to_array( points[7] ) ); + gl().glTexCoord2fv( aabb_texcoord_topright ); + gl().glVertex3fv( vector3_to_array( points[6] ) ); + gl().glTexCoord2fv( aabb_texcoord_botright ); + gl().glVertex3fv( vector3_to_array( points[5] ) ); + gl().glTexCoord2fv( aabb_texcoord_botleft ); + gl().glVertex3fv( vector3_to_array( points[4] ) ); - glEnd(); + gl().glEnd(); } inline void aabb_draw_solid( const AABB& aabb, RenderStateFlags state ){ diff --git a/libs/gtkutil/accelerator.cpp b/libs/gtkutil/accelerator.cpp index f88da9e6..515b3b4c 100644 --- a/libs/gtkutil/accelerator.cpp +++ b/libs/gtkutil/accelerator.cpp @@ -25,79 +25,36 @@ #include #include -#include #include "generic/callback.h" #include "generic/bitfield.h" #include "string/string.h" -#include "pointer.h" -#include "closure.h" +#include "accelerator_translate.h" -#include +#include +#include +#include +#include +#include -const char* global_keys_find( unsigned int key ){ - const char *s; - if ( key == 0 ) { - return ""; - } - s = gdk_keyval_name( key ); - if ( !s ) { - return ""; - } - return s; +void accelerator_write( const QKeySequence& accelerator, TextOutputStream& ostream ){ + ostream << accelerator.toString().toLatin1().constData(); } -unsigned int global_keys_find( const char* name ){ - guint k; - if ( !name || !*name ) { - return 0; - } - k = gdk_keyval_from_name( name ); - if ( k == GDK_KEY_VoidSymbol ) { - return 0; - } - return k; -} +typedef std::map AcceleratorMap; -void accelerator_write( const Accelerator& accelerator, TextOutputStream& ostream ){ -#if 0 - if ( accelerator.modifiers & GDK_SHIFT_MASK ) { - ostream << "Shift + "; - } - if ( accelerator.modifiers & GDK_MOD1_MASK ) { - ostream << "Alt + "; - } - if ( accelerator.modifiers & GDK_CONTROL_MASK ) { - ostream << "Control + "; - } - - const char* keyName = global_keys_find( accelerator.key ); - if ( !string_empty( keyName ) ) { - ostream << keyName; - } - else - { - ostream << static_cast( accelerator.key ); - } -#endif - ostream << gtk_accelerator_get_label( accelerator.key, accelerator.modifiers ); -} - -typedef std::map AcceleratorMap; -typedef std::set AcceleratorSet; - -bool accelerator_map_insert( AcceleratorMap& acceleratorMap, Accelerator accelerator, const Callback& callback ){ - if ( accelerator.key != 0 ) { +bool accelerator_map_insert( AcceleratorMap& acceleratorMap, QKeySequence accelerator, const Callback& callback ){ + if ( QKeySequence_valid( accelerator ) ) { return acceleratorMap.insert( AcceleratorMap::value_type( accelerator, callback ) ).second; } return true; } -bool accelerator_map_erase( AcceleratorMap& acceleratorMap, Accelerator accelerator ){ - if ( accelerator.key != 0 ) { +bool accelerator_map_erase( AcceleratorMap& acceleratorMap, QKeySequence accelerator ){ + if ( QKeySequence_valid( accelerator ) ) { AcceleratorMap::iterator i = acceleratorMap.find( accelerator ); if ( i == acceleratorMap.end() ) { return false; @@ -107,18 +64,15 @@ bool accelerator_map_erase( AcceleratorMap& acceleratorMap, Accelerator accelera return true; } -Accelerator accelerator_for_event_key( guint keyval, guint state ){ - if ( keyval == GDK_KEY_ISO_Left_Tab ) { - keyval = GDK_KEY_Tab; - } - return Accelerator( keyval, (GdkModifierType)( state & gtk_accelerator_get_default_mod_mask() ) ); +QKeySequence accelerator_for_event_key( int keyval, Qt::KeyboardModifiers state ){ + return QKeySequence( keyval | state ); } -Accelerator accelerator_for_event_key( const GdkEventKey* event ){ - return accelerator_for_event_key( event->keyval, event->state ); +QKeySequence accelerator_for_event_key( const QKeyEvent* event ){ + return accelerator_for_event_key( event->key(), event->modifiers() ); } -bool AcceleratorMap_activate( const AcceleratorMap& acceleratorMap, const Accelerator& accelerator ){ +bool AcceleratorMap_activate( const AcceleratorMap& acceleratorMap, const QKeySequence& accelerator ){ AcceleratorMap::const_iterator i = acceleratorMap.find( accelerator ); if ( i != acceleratorMap.end() ) { ( *i ).second(); @@ -128,453 +82,118 @@ bool AcceleratorMap_activate( const AcceleratorMap& acceleratorMap, const Accele return false; } -static gboolean accelerator_key_event( GtkWindow* window, GdkEventKey* event, AcceleratorMap* acceleratorMap ){ - return AcceleratorMap_activate( *acceleratorMap, accelerator_for_event_key( event->keyval, event->state ) ); -} - - -AcceleratorMap g_special_accelerators; - - -namespace MouseButton -{ -enum -{ - Left = 1 << 0, - Right = 1 << 1, - Middle = 1 << 2, -}; -} - -typedef unsigned int ButtonMask; - -void print_buttons( ButtonMask mask ){ - globalOutputStream() << "button state: "; - if ( ( mask & MouseButton::Left ) != 0 ) { - globalOutputStream() << "Left "; - } - if ( ( mask & MouseButton::Right ) != 0 ) { - globalOutputStream() << "Right "; - } - if ( ( mask & MouseButton::Middle ) != 0 ) { - globalOutputStream() << "Middle "; - } - globalOutputStream() << "\n"; -} - -ButtonMask ButtonMask_for_event_button( guint button ){ - switch ( button ) - { - case 1: - return MouseButton::Left; - case 2: - return MouseButton::Middle; - case 3: - return MouseButton::Right; - } - return 0; -} - -bool window_has_accel( GtkWindow* toplevel ){ - return g_slist_length( gtk_accel_groups_from_object( G_OBJECT( toplevel ) ) ) != 0; -} - -namespace -{ -bool g_accel_enabled = true; -} - -bool global_accel_enabled(){ - return g_accel_enabled; -} - - -GClosure* accel_group_add_accelerator( GtkAccelGroup* group, Accelerator accelerator, const Callback& callback ); -void accel_group_remove_accelerator( GtkAccelGroup* group, Accelerator accelerator ); - -AcceleratorMap g_queuedAcceleratorsAdd; -AcceleratorSet g_queuedAcceleratorsRemove; - -void globalQueuedAccelerators_add( Accelerator accelerator, const Callback& callback ){ - if ( !g_queuedAcceleratorsAdd.insert( AcceleratorMap::value_type( accelerator, callback ) ).second ) { - globalErrorStream() << "globalQueuedAccelerators_add: accelerator already queued: " << accelerator << "\n"; - } -} - -void globalQueuedAccelerators_remove( Accelerator accelerator ){ - if ( g_queuedAcceleratorsAdd.erase( accelerator ) == 0 ) { - if ( !g_queuedAcceleratorsRemove.insert( accelerator ).second ) { - globalErrorStream() << "globalQueuedAccelerators_remove: accelerator already queued: " << accelerator << "\n"; - } - } -} - -void globalQueuedAccelerators_commit(){ - for ( AcceleratorSet::const_iterator i = g_queuedAcceleratorsRemove.begin(); i != g_queuedAcceleratorsRemove.end(); ++i ) - { - //globalOutputStream() << "removing: " << (*i).first << "\n"; - accel_group_remove_accelerator( global_accel, *i ); - } - g_queuedAcceleratorsRemove.clear(); - for ( AcceleratorMap::const_iterator i = g_queuedAcceleratorsAdd.begin(); i != g_queuedAcceleratorsAdd.end(); ++i ) - { - //globalOutputStream() << "adding: " << (*i).first << "\n"; - accel_group_add_accelerator( global_accel, ( *i ).first, ( *i ).second ); - } - g_queuedAcceleratorsAdd.clear(); -} - -void accel_group_test( GtkWindow* toplevel, GtkAccelGroup* accel ){ - guint n_entries; - gtk_accel_group_query( accel, '4', (GdkModifierType)0, &n_entries ); - globalOutputStream() << "grid4: " << n_entries << "\n"; - globalOutputStream() << "toplevel accelgroups: " << g_slist_length( gtk_accel_groups_from_object( G_OBJECT( toplevel ) ) ) << "\n"; -} - -typedef std::set WindowSet; -WindowSet g_accel_windows; - -bool Buttons_press( ButtonMask& buttons, guint button, guint state ){ - if ( buttons == 0 && bitfield_enable( buttons, ButtonMask_for_event_button( button ) ) != 0 ) { - ASSERT_MESSAGE( g_accel_enabled, "Buttons_press: accelerators not enabled" ); - g_accel_enabled = false; - for ( WindowSet::iterator i = g_accel_windows.begin(); i != g_accel_windows.end(); ++i ) - { - GtkWindow* toplevel = *i; - ASSERT_MESSAGE( window_has_accel( toplevel ), "ERROR" ); - ASSERT_MESSAGE( gtk_widget_is_toplevel( GTK_WIDGET( toplevel ) ), "disabling accel for non-toplevel window" ); - gtk_window_remove_accel_group( toplevel, global_accel ); -#if 0 - globalOutputStream() << reinterpret_cast( toplevel ) << ": disabled global accelerators\n"; -#endif -#if 0 - accel_group_test( toplevel, global_accel ); -#endif - } - } - buttons = bitfield_enable( buttons, ButtonMask_for_event_button( button ) ); -#if 0 - globalOutputStream() << "Buttons_press: "; - print_buttons( buttons ); -#endif - return false; -} - -bool Buttons_release( ButtonMask& buttons, guint button, guint state ){ - if ( buttons != 0 && bitfield_disable( buttons, ButtonMask_for_event_button( button ) ) == 0 ) { - ASSERT_MESSAGE( !g_accel_enabled, "Buttons_release: accelerators are enabled" ); - g_accel_enabled = true; - for ( WindowSet::iterator i = g_accel_windows.begin(); i != g_accel_windows.end(); ++i ) - { - GtkWindow* toplevel = *i; - ASSERT_MESSAGE( !window_has_accel( toplevel ), "ERROR" ); - ASSERT_MESSAGE( gtk_widget_is_toplevel( GTK_WIDGET( toplevel ) ), "enabling accel for non-toplevel window" ); - gtk_window_add_accel_group( toplevel, global_accel ); -#if 0 - globalOutputStream() << reinterpret_cast( toplevel ) << ": enabled global accelerators\n"; -#endif -#if 0 - accel_group_test( toplevel, global_accel ); -#endif - } - globalQueuedAccelerators_commit(); - } - buttons = bitfield_disable( buttons, ButtonMask_for_event_button( button ) ); -#if 0 - globalOutputStream() << "Buttons_release: "; - print_buttons( buttons ); -#endif - return false; -} - -bool Buttons_releaseAll( ButtonMask& buttons ){ - Buttons_release( buttons, MouseButton::Left | MouseButton::Middle | MouseButton::Right, 0 ); - return false; -} - -struct PressedButtons -{ - ButtonMask buttons; - - PressedButtons() : buttons( 0 ){ - } -}; - -gboolean PressedButtons_button_press( GtkWidget* widget, GdkEventButton* event, PressedButtons* pressed ){ - if ( event->type == GDK_BUTTON_PRESS ) { - return Buttons_press( pressed->buttons, event->button, event->state ); - } - return FALSE; -} - -gboolean PressedButtons_button_release( GtkWidget* widget, GdkEventButton* event, PressedButtons* pressed ){ - if ( event->type == GDK_BUTTON_RELEASE ) { - return Buttons_release( pressed->buttons, event->button, event->state ); - } - return FALSE; -} - -gboolean PressedButtons_focus_out( GtkWidget* widget, GdkEventFocus* event, PressedButtons* pressed ){ - Buttons_releaseAll( pressed->buttons ); - return FALSE; -} - -void PressedButtons_connect( PressedButtons& pressedButtons, GtkWidget* widget ){ - g_signal_connect( G_OBJECT( widget ), "button_press_event", G_CALLBACK( PressedButtons_button_press ), &pressedButtons ); - g_signal_connect( G_OBJECT( widget ), "button_release_event", G_CALLBACK( PressedButtons_button_release ), &pressedButtons ); - g_signal_connect( G_OBJECT( widget ), "focus_out_event", G_CALLBACK( PressedButtons_focus_out ), &pressedButtons ); -} - -PressedButtons g_pressedButtons; - #include struct PressedKeys { - typedef std::set Keys; + typedef std::set Keys; Keys keys; - std::size_t refcount; - - PressedKeys() : refcount( 0 ){ - } }; AcceleratorMap g_keydown_accelerators; AcceleratorMap g_keyup_accelerators; -bool Keys_press( PressedKeys::Keys& keys, guint keyval ){ - if ( keys.insert( gdk_keyval_to_lower( keyval ) ).second ) { - return AcceleratorMap_activate( g_keydown_accelerators, accelerator_for_event_key( keyval, 0 ) ); +bool Keys_press( PressedKeys::Keys& keys, int keyval ){ + if ( keys.insert( keyval ).second ) { + return AcceleratorMap_activate( g_keydown_accelerators, accelerator_for_event_key( keyval, {} ) ); } - return g_keydown_accelerators.find( accelerator_for_event_key( keyval, 0 ) ) != g_keydown_accelerators.end(); + return g_keydown_accelerators.find( accelerator_for_event_key( keyval, {} ) ) != g_keydown_accelerators.end(); } -bool Keys_release( PressedKeys::Keys& keys, guint keyval ){ - if ( keys.erase( gdk_keyval_to_lower( keyval ) ) != 0 ) { - return AcceleratorMap_activate( g_keyup_accelerators, accelerator_for_event_key( keyval, 0 ) ); +bool Keys_release( PressedKeys::Keys& keys, int keyval ){ + if ( keys.erase( keyval ) != 0 ) { + return AcceleratorMap_activate( g_keyup_accelerators, accelerator_for_event_key( keyval, {} ) ); } - return g_keyup_accelerators.find( accelerator_for_event_key( keyval, 0 ) ) != g_keyup_accelerators.end(); + return g_keyup_accelerators.find( accelerator_for_event_key( keyval, {} ) ) != g_keyup_accelerators.end(); } -void Keys_releaseAll( PressedKeys::Keys& keys, guint state ){ - for ( PressedKeys::Keys::iterator i = keys.begin(); i != keys.end(); ++i ) +void Keys_releaseAll( PressedKeys::Keys& keys, Qt::KeyboardModifiers state ){ + for ( auto key : keys ) { - AcceleratorMap_activate( g_keyup_accelerators, accelerator_for_event_key( *i, state ) ); + AcceleratorMap_activate( g_keyup_accelerators, accelerator_for_event_key( key, state ) ); } keys.clear(); } -gboolean PressedKeys_key_press( GtkWidget* widget, GdkEventKey* event, PressedKeys* pressedKeys ){ - //globalOutputStream() << "pressed: " << event->keyval << "\n"; - //return event->state == 0 && Keys_press( pressedKeys->keys, event->keyval ); - //NumLock perspective window fix - return ( event->state & ALLOWED_MODIFIERS ) == 0 && Keys_press( pressedKeys->keys, event->keyval ); +bool PressedKeys_key_press( const QKeyEvent* event, PressedKeys& pressedKeys ){ + //globalOutputStream() << "pressed: " << event->key() << "\n"; + return event->modifiers() == 0 && Keys_press( pressedKeys.keys, qt_keyvalue_is_known( event->key() )? event->key() : event->nativeVirtualKey() ); } -gboolean PressedKeys_key_release( GtkWidget* widget, GdkEventKey* event, PressedKeys* pressedKeys ){ - //globalOutputStream() << "released: " << event->keyval << "\n"; - return Keys_release( pressedKeys->keys, event->keyval ); -} - -gboolean PressedKeys_focus_in( GtkWidget* widget, GdkEventFocus* event, PressedKeys* pressedKeys ){ - ++pressedKeys->refcount; - return FALSE; -} - -gboolean PressedKeys_focus_out( GtkWidget* widget, GdkEventFocus* event, PressedKeys* pressedKeys ){ - if ( --pressedKeys->refcount == 0 ) { - Keys_releaseAll( pressedKeys->keys, 0 ); - } - return FALSE; +bool PressedKeys_key_release( const QKeyEvent* event, PressedKeys& pressedKeys ){ + //globalOutputStream() << "released: " << event->key() << "\n"; + return Keys_release( pressedKeys.keys, qt_keyvalue_is_known( event->key() )? event->key() : event->nativeVirtualKey() ); } PressedKeys g_pressedKeys; void GlobalPressedKeys_releaseAll(){ - Keys_releaseAll( g_pressedKeys.keys, 0 ); + Keys_releaseAll( g_pressedKeys.keys, {} ); } -void GlobalPressedKeys_connect( GtkWindow* window ){ - unsigned int key_press_handler = g_signal_connect( G_OBJECT( window ), "key_press_event", G_CALLBACK( PressedKeys_key_press ), &g_pressedKeys ); - unsigned int key_release_handler = g_signal_connect( G_OBJECT( window ), "key_release_event", G_CALLBACK( PressedKeys_key_release ), &g_pressedKeys ); - g_object_set_data( G_OBJECT( window ), "key_press_handler", gint_to_pointer( key_press_handler ) ); - g_object_set_data( G_OBJECT( window ), "key_release_handler", gint_to_pointer( key_release_handler ) ); - unsigned int focus_in_handler = g_signal_connect( G_OBJECT( window ), "focus_in_event", G_CALLBACK( PressedKeys_focus_in ), &g_pressedKeys ); - unsigned int focus_out_handler = g_signal_connect( G_OBJECT( window ), "focus_out_event", G_CALLBACK( PressedKeys_focus_out ), &g_pressedKeys ); - g_object_set_data( G_OBJECT( window ), "focus_in_handler", gint_to_pointer( focus_in_handler ) ); - g_object_set_data( G_OBJECT( window ), "focus_out_handler", gint_to_pointer( focus_out_handler ) ); -} - -void GlobalPressedKeys_disconnect( GtkWindow* window ){ - g_signal_handler_disconnect( G_OBJECT( window ), gpointer_to_int( g_object_get_data( G_OBJECT( window ), "key_press_handler" ) ) ); - g_signal_handler_disconnect( G_OBJECT( window ), gpointer_to_int( g_object_get_data( G_OBJECT( window ), "key_release_handler" ) ) ); - g_signal_handler_disconnect( G_OBJECT( window ), gpointer_to_int( g_object_get_data( G_OBJECT( window ), "focus_in_handler" ) ) ); - g_signal_handler_disconnect( G_OBJECT( window ), gpointer_to_int( g_object_get_data( G_OBJECT( window ), "focus_out_handler" ) ) ); -} - - - -void special_accelerators_add( Accelerator accelerator, const Callback& callback ){ - //globalOutputStream() << "special_accelerators_add: " << makeQuoted(accelerator) << "\n"; - if ( !accelerator_map_insert( g_special_accelerators, accelerator, callback ) ) { - globalErrorStream() << "special_accelerators_add: already exists: " << makeQuoted( accelerator ) << "\n"; +class PressedKeysHandler : public QObject +{ +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::ShortcutOverride ) { + QKeyEvent *keyEvent = static_cast( event ); + if( PressedKeys_key_press( keyEvent, g_pressedKeys ) ){ // note autorepeat fires this too + event->accept(); + return true; + } + } + else if( event->type() == QEvent::KeyPress ) { + QKeyEvent *keyEvent = static_cast( event ); + if( PressedKeys_key_press( keyEvent, g_pressedKeys ) ){ // note autorepeat fires this too + event->accept(); + return true; + } + } + else if( event->type() == QEvent::KeyRelease ) { + QKeyEvent *keyEvent = static_cast( event ); + if( !keyEvent->isAutoRepeat() && PressedKeys_key_release( keyEvent, g_pressedKeys ) ){ + event->accept(); + return true; + } + } + return QObject::eventFilter( obj, event ); // standard event processing } } -void special_accelerators_remove( Accelerator accelerator ){ - //globalOutputStream() << "special_accelerators_remove: " << makeQuoted(accelerator) << "\n"; - if ( !accelerator_map_erase( g_special_accelerators, accelerator ) ) { - globalErrorStream() << "special_accelerators_remove: not found: " << makeQuoted( accelerator ) << "\n"; - } +g_pressedKeysHandler; + +void GlobalPressedKeys_connect( QWidget* window ){ + window->installEventFilter( &g_pressedKeysHandler ); +// qApp->installEventFilter( &g_pressedKeysHandler ); + QObject::connect( qApp, &QApplication::focusChanged, GlobalPressedKeys_releaseAll ); } -void keydown_accelerators_add( Accelerator accelerator, const Callback& callback ){ + + + +void keydown_accelerators_add( QKeySequence accelerator, const Callback& callback ){ //globalOutputStream() << "keydown_accelerators_add: " << makeQuoted(accelerator) << "\n"; if ( !accelerator_map_insert( g_keydown_accelerators, accelerator, callback ) ) { globalErrorStream() << "keydown_accelerators_add: already exists: " << makeQuoted( accelerator ) << "\n"; } } -void keydown_accelerators_remove( Accelerator accelerator ){ +void keydown_accelerators_remove( QKeySequence accelerator ){ //globalOutputStream() << "keydown_accelerators_remove: " << makeQuoted(accelerator) << "\n"; if ( !accelerator_map_erase( g_keydown_accelerators, accelerator ) ) { globalErrorStream() << "keydown_accelerators_remove: not found: " << makeQuoted( accelerator ) << "\n"; } } -void keyup_accelerators_add( Accelerator accelerator, const Callback& callback ){ +void keyup_accelerators_add( QKeySequence accelerator, const Callback& callback ){ //globalOutputStream() << "keyup_accelerators_add: " << makeQuoted(accelerator) << "\n"; if ( !accelerator_map_insert( g_keyup_accelerators, accelerator, callback ) ) { globalErrorStream() << "keyup_accelerators_add: already exists: " << makeQuoted( accelerator ) << "\n"; } } -void keyup_accelerators_remove( Accelerator accelerator ){ +void keyup_accelerators_remove( QKeySequence accelerator ){ //globalOutputStream() << "keyup_accelerators_remove: " << makeQuoted(accelerator) << "\n"; if ( !accelerator_map_erase( g_keyup_accelerators, accelerator ) ) { globalErrorStream() << "keyup_accelerators_remove: not found: " << makeQuoted( accelerator ) << "\n"; } } - -gboolean accel_closure_callback( GtkAccelGroup* group, GtkWidget* widget, guint key, GdkModifierType modifiers, gpointer data ){ - ( *reinterpret_cast( data ) )( ); - return TRUE; -} - -GClosure* accel_group_add_accelerator( GtkAccelGroup* group, Accelerator accelerator, const Callback& callback ){ - if ( accelerator.key != 0 && gtk_accelerator_valid( accelerator.key, accelerator.modifiers ) ) { - //globalOutputStream() << "global_accel_connect: " << makeQuoted(accelerator) << "\n"; - GClosure* closure = create_cclosure( G_CALLBACK( accel_closure_callback ), callback ); - gtk_accel_group_connect( group, accelerator.key, accelerator.modifiers, GTK_ACCEL_VISIBLE, closure ); - return closure; - } - else - { - special_accelerators_add( accelerator, callback ); - return 0; - } -} - -void accel_group_remove_accelerator( GtkAccelGroup* group, Accelerator accelerator ){ - if ( accelerator.key != 0 && gtk_accelerator_valid( accelerator.key, accelerator.modifiers ) ) { - //globalOutputStream() << "global_accel_disconnect: " << makeQuoted(accelerator) << "\n"; - gtk_accel_group_disconnect_key( group, accelerator.key, accelerator.modifiers ); - } - else - { - special_accelerators_remove( accelerator ); - } -} - -GtkAccelGroup* global_accel = 0; - -void global_accel_init(){ - global_accel = gtk_accel_group_new(); -} - -void global_accel_destroy(){ - g_object_unref( global_accel ); -} - -GClosure* global_accel_group_add_accelerator( Accelerator accelerator, const Callback& callback ){ - if ( !global_accel_enabled() ) { - // workaround: cannot add to GtkAccelGroup while it is disabled - //globalOutputStream() << "queued for add: " << accelerator << "\n"; - globalQueuedAccelerators_add( accelerator, callback ); - return 0; - } - return accel_group_add_accelerator( global_accel, accelerator, callback ); -} -void global_accel_group_remove_accelerator( Accelerator accelerator ){ - if ( !global_accel_enabled() ) { - //globalOutputStream() << "queued for remove: " << accelerator << "\n"; - globalQueuedAccelerators_remove( accelerator ); - return; - } - accel_group_remove_accelerator( global_accel, accelerator ); -} - -/// \brief Propagates key events to the focus-widget, overriding global accelerators. -static gboolean override_global_accelerators( GtkWindow* window, GdkEventKey* event, gpointer data ){ - gboolean b = gtk_window_propagate_key_event( window, event ); - return b; -} - -void global_accel_connect_window( GtkWindow* window ){ -#if 1 - unsigned int override_handler = g_signal_connect( G_OBJECT( window ), "key_press_event", G_CALLBACK( override_global_accelerators ), 0 ); - g_object_set_data( G_OBJECT( window ), "override_handler", gint_to_pointer( override_handler ) ); - - GlobalPressedKeys_connect( window ); - - unsigned int special_key_press_handler = g_signal_connect( G_OBJECT( window ), "key_press_event", G_CALLBACK( accelerator_key_event ), &g_special_accelerators ); - g_object_set_data( G_OBJECT( window ), "special_key_press_handler", gint_to_pointer( special_key_press_handler ) ); -#else - unsigned int key_press_handler = g_signal_connect( G_OBJECT( window ), "key_press_event", G_CALLBACK( accelerator_key_event ), &g_keydown_accelerators ); - unsigned int key_release_handler = g_signal_connect( G_OBJECT( window ), "key_release_event", G_CALLBACK( accelerator_key_event ), &g_keyup_accelerators ); - g_object_set_data( G_OBJECT( window ), "key_press_handler", gint_to_pointer( key_press_handler ) ); - g_object_set_data( G_OBJECT( window ), "key_release_handler", gint_to_pointer( key_release_handler ) ); -#endif - g_accel_windows.insert( window ); - gtk_window_add_accel_group( window, global_accel ); -} -void global_accel_disconnect_window( GtkWindow* window ){ -#if 1 - GlobalPressedKeys_disconnect( window ); - - g_signal_handler_disconnect( G_OBJECT( window ), gpointer_to_int( g_object_get_data( G_OBJECT( window ), "override_handler" ) ) ); - g_signal_handler_disconnect( G_OBJECT( window ), gpointer_to_int( g_object_get_data( G_OBJECT( window ), "special_key_press_handler" ) ) ); -#else - g_signal_handler_disconnect( G_OBJECT( window ), gpointer_to_int( g_object_get_data( G_OBJECT( window ), "key_press_handler" ) ) ); - g_signal_handler_disconnect( G_OBJECT( window ), gpointer_to_int( g_object_get_data( G_OBJECT( window ), "key_release_handler" ) ) ); -#endif - gtk_window_remove_accel_group( window, global_accel ); - std::size_t count = g_accel_windows.erase( window ); - ASSERT_MESSAGE( count == 1, "failed to remove accel group\n" ); -} - - -GClosure* global_accel_group_find( Accelerator accelerator ){ - guint numEntries = 0; - GtkAccelGroupEntry* entry = gtk_accel_group_query( global_accel, accelerator.key, accelerator.modifiers, &numEntries ); - if ( numEntries != 0 ) { - if ( numEntries != 1 ) { - char* name = gtk_accelerator_name( accelerator.key, accelerator.modifiers ); - globalErrorStream() << "accelerator already in-use: " << name << "\n"; - g_free( name ); - } - return entry->closure; - } - return 0; -} - -void global_accel_group_connect( const Accelerator& accelerator, const Callback& callback ){ - if ( accelerator.key != 0 ) { - global_accel_group_add_accelerator( accelerator, callback ); - } -} - -void global_accel_group_disconnect( const Accelerator& accelerator, const Callback& callback ){ - if ( accelerator.key != 0 ) { - global_accel_group_remove_accelerator( accelerator ); - } -} diff --git a/libs/gtkutil/accelerator.h b/libs/gtkutil/accelerator.h index aec581d1..1ec1ed55 100644 --- a/libs/gtkutil/accelerator.h +++ b/libs/gtkutil/accelerator.h @@ -21,97 +21,49 @@ #pragma once -#include -#include +#include #include "generic/callback.h" -// ignore numlock -#define ALLOWED_MODIFIERS ( ~( GDK_MOD2_MASK | GDK_LOCK_MASK | GDK_MOD3_MASK | GDK_MOD4_MASK | GDK_MOD5_MASK ) ) - -struct Accelerator -{ - Accelerator( guint _key ) - : key( gdk_keyval_to_lower( _key ) ), modifiers( ( GdkModifierType ) 0 ){ - } - Accelerator( guint _key, GdkModifierType _modifiers ) - : key( gdk_keyval_to_lower( _key ) ), modifiers( ( GdkModifierType )( _modifiers & ALLOWED_MODIFIERS ) ){ - } - Accelerator( const Accelerator &src ) - : key( src.key ), modifiers( src.modifiers ){ - } - bool operator<( const Accelerator& other ) const { - guint k1 = key; - guint k2 = other.key; - int mod1 = modifiers; - int mod2 = other.modifiers; - return k1 < k2 || ( !( k2 < k1 ) && mod1 < mod2 ); - } - bool operator==( const Accelerator& other ) const { - guint k1 = key; - guint k2 = other.key; - int mod1 = modifiers; - int mod2 = other.modifiers; - return k1 == k2 && mod1 == mod2; - } - Accelerator &operator=( const Accelerator& other ){ - key = other.key; - modifiers = other.modifiers; - return *this; - } - guint key; //!this only gdk_keyval_to_lower - GdkModifierType modifiers; //!this only &= ALLOWED_MODIFIERS -}; - -inline Accelerator accelerator_null(){ - return Accelerator( 0, (GdkModifierType)0 ); +// technically this should also check if sequence has keys, not just modifiers +// but this works with current shortcuts providers ( QKeySequence( string ) & QKeySequenceEdit ) +inline bool QKeySequence_valid( const QKeySequence& accelerator ){ + return !accelerator.isEmpty() && accelerator[0] != Qt::Key_unknown; } -typedef struct _GdkEventKey GdkEventKey; -Accelerator accelerator_for_event_key( const GdkEventKey* event ); +QKeySequence accelerator_for_event_key( const class QKeyEvent* event ); -const char* global_keys_find( unsigned int key ); -unsigned int global_keys_find( const char* name ); - class TextOutputStream; -void accelerator_write( const Accelerator& accelerator, TextOutputStream& ostream ); +void accelerator_write( const QKeySequence& accelerator, TextOutputStream& ostream ); template -TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Accelerator& accelerator ){ +TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const QKeySequence& accelerator ){ accelerator_write( accelerator, ostream ); return ostream; } -void keydown_accelerators_add( Accelerator accelerator, const Callback& callback ); -void keydown_accelerators_remove( Accelerator accelerator ); -void keyup_accelerators_add( Accelerator accelerator, const Callback& callback ); -void keyup_accelerators_remove( Accelerator accelerator ); - -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkWindow GtkWindow; -void global_accel_connect_window( GtkWindow* window ); -void global_accel_disconnect_window( GtkWindow* window ); +void keydown_accelerators_add( QKeySequence accelerator, const Callback& callback ); +void keydown_accelerators_remove( QKeySequence accelerator ); +void keyup_accelerators_add( QKeySequence accelerator, const Callback& callback ); +void keyup_accelerators_remove( QKeySequence accelerator ); void GlobalPressedKeys_releaseAll(); +void GlobalPressedKeys_connect( class QWidget* window ); -typedef struct _GtkAccelGroup GtkAccelGroup; -extern GtkAccelGroup* global_accel; -void global_accel_init(); -void global_accel_destroy(); - -GClosure* global_accel_group_find( Accelerator accelerator ); - -void global_accel_group_connect( const Accelerator& accelerator, const Callback& callback ); -void global_accel_group_disconnect( const Accelerator& accelerator, const Callback& callback ); +class QAction; class Command { + mutable QAction *m_action{}; public: + QAction*& getAction() const { + return m_action; + } Callback m_callback; - const Accelerator& m_accelerator; - Command( const Callback& callback, const Accelerator& accelerator ) : m_callback( callback ), m_accelerator( accelerator ){ + const QKeySequence& m_accelerator; + Command( const Callback& callback, const QKeySequence& accelerator ) : m_callback( callback ), m_accelerator( accelerator ){ } }; @@ -120,24 +72,16 @@ class Toggle public: Command m_command; BoolExportCallback m_exportCallback; - Toggle( const Callback& callback, const Accelerator& accelerator, const BoolExportCallback& exportCallback ) : m_command( callback, accelerator ), m_exportCallback( exportCallback ){ + Toggle( const Callback& callback, const QKeySequence& accelerator, const BoolExportCallback& exportCallback ) : m_command( callback, accelerator ), m_exportCallback( exportCallback ){ } }; class KeyEvent { public: - const Accelerator& m_accelerator; + const QKeySequence& m_accelerator; Callback m_keyDown; Callback m_keyUp; - KeyEvent( const Accelerator& accelerator, const Callback& keyDown, const Callback& keyUp ) : m_accelerator( accelerator ), m_keyDown( keyDown ), m_keyUp( keyUp ){ + KeyEvent( const QKeySequence& accelerator, const Callback& keyDown, const Callback& keyUp ) : m_accelerator( accelerator ), m_keyDown( keyDown ), m_keyUp( keyUp ){ } }; - - - -struct PressedButtons; -typedef struct _GtkWidget GtkWidget; -void PressedButtons_connect( PressedButtons& pressedButtons, GtkWidget* widget ); - -extern PressedButtons g_pressedButtons; diff --git a/libs/gtkutil/accelerator_translate.h b/libs/gtkutil/accelerator_translate.h new file mode 100644 index 00000000..36899427 --- /dev/null +++ b/libs/gtkutil/accelerator_translate.h @@ -0,0 +1,553 @@ +/* + Copyright (C) 2001-2006, William Joseph. + All Rights Reserved. + + This file is part of GtkRadiant. + + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include + +///\brief checks whether keyvalue is known in Qt::Key enum +/// +inline bool qt_keyvalue_is_known( int keyvalue ){ + switch ( keyvalue ) { + case Qt::Key::Key_Escape : // misc keys + case Qt::Key::Key_Tab : + case Qt::Key::Key_Backtab : + case Qt::Key::Key_Backspace : + case Qt::Key::Key_Return : + case Qt::Key::Key_Enter : + case Qt::Key::Key_Insert : + case Qt::Key::Key_Delete : + case Qt::Key::Key_Pause : + case Qt::Key::Key_Print : // print screen + case Qt::Key::Key_SysReq : + case Qt::Key::Key_Clear : + case Qt::Key::Key_Home : // cursor movement + case Qt::Key::Key_End : + case Qt::Key::Key_Left : + case Qt::Key::Key_Up : + case Qt::Key::Key_Right : + case Qt::Key::Key_Down : + case Qt::Key::Key_PageUp : + case Qt::Key::Key_PageDown : + case Qt::Key::Key_Shift : // modifiers + case Qt::Key::Key_Control : + case Qt::Key::Key_Meta : + case Qt::Key::Key_Alt : + case Qt::Key::Key_CapsLock : + case Qt::Key::Key_NumLock : + case Qt::Key::Key_ScrollLock : + case Qt::Key::Key_F1 : // function keys + case Qt::Key::Key_F2 : + case Qt::Key::Key_F3 : + case Qt::Key::Key_F4 : + case Qt::Key::Key_F5 : + case Qt::Key::Key_F6 : + case Qt::Key::Key_F7 : + case Qt::Key::Key_F8 : + case Qt::Key::Key_F9 : + case Qt::Key::Key_F10 : + case Qt::Key::Key_F11 : + case Qt::Key::Key_F12 : + case Qt::Key::Key_F13 : + case Qt::Key::Key_F14 : + case Qt::Key::Key_F15 : + case Qt::Key::Key_F16 : + case Qt::Key::Key_F17 : + case Qt::Key::Key_F18 : + case Qt::Key::Key_F19 : + case Qt::Key::Key_F20 : + case Qt::Key::Key_F21 : + case Qt::Key::Key_F22 : + case Qt::Key::Key_F23 : + case Qt::Key::Key_F24 : + case Qt::Key::Key_F25 : // F25 .. F35 only on X11 + case Qt::Key::Key_F26 : + case Qt::Key::Key_F27 : + case Qt::Key::Key_F28 : + case Qt::Key::Key_F29 : + case Qt::Key::Key_F30 : + case Qt::Key::Key_F31 : + case Qt::Key::Key_F32 : + case Qt::Key::Key_F33 : + case Qt::Key::Key_F34 : + case Qt::Key::Key_F35 : + case Qt::Key::Key_Super_L : // extra keys + case Qt::Key::Key_Super_R : + case Qt::Key::Key_Menu : + case Qt::Key::Key_Hyper_L : + case Qt::Key::Key_Hyper_R : + case Qt::Key::Key_Help : + case Qt::Key::Key_Direction_L : + case Qt::Key::Key_Direction_R : + case Qt::Key::Key_Space : // 7 bit printable ASCII + case Qt::Key::Key_Exclam : + case Qt::Key::Key_QuoteDbl : + case Qt::Key::Key_NumberSign : + case Qt::Key::Key_Dollar : + case Qt::Key::Key_Percent : + case Qt::Key::Key_Ampersand : + case Qt::Key::Key_Apostrophe : + case Qt::Key::Key_ParenLeft : + case Qt::Key::Key_ParenRight : + case Qt::Key::Key_Asterisk : + case Qt::Key::Key_Plus : + case Qt::Key::Key_Comma : + case Qt::Key::Key_Minus : + case Qt::Key::Key_Period : + case Qt::Key::Key_Slash : + case Qt::Key::Key_0 : + case Qt::Key::Key_1 : + case Qt::Key::Key_2 : + case Qt::Key::Key_3 : + case Qt::Key::Key_4 : + case Qt::Key::Key_5 : + case Qt::Key::Key_6 : + case Qt::Key::Key_7 : + case Qt::Key::Key_8 : + case Qt::Key::Key_9 : + case Qt::Key::Key_Colon : + case Qt::Key::Key_Semicolon : + case Qt::Key::Key_Less : + case Qt::Key::Key_Equal : + case Qt::Key::Key_Greater : + case Qt::Key::Key_Question : + case Qt::Key::Key_At : + case Qt::Key::Key_A : + case Qt::Key::Key_B : + case Qt::Key::Key_C : + case Qt::Key::Key_D : + case Qt::Key::Key_E : + case Qt::Key::Key_F : + case Qt::Key::Key_G : + case Qt::Key::Key_H : + case Qt::Key::Key_I : + case Qt::Key::Key_J : + case Qt::Key::Key_K : + case Qt::Key::Key_L : + case Qt::Key::Key_M : + case Qt::Key::Key_N : + case Qt::Key::Key_O : + case Qt::Key::Key_P : + case Qt::Key::Key_Q : + case Qt::Key::Key_R : + case Qt::Key::Key_S : + case Qt::Key::Key_T : + case Qt::Key::Key_U : + case Qt::Key::Key_V : + case Qt::Key::Key_W : + case Qt::Key::Key_X : + case Qt::Key::Key_Y : + case Qt::Key::Key_Z : + case Qt::Key::Key_BracketLeft : + case Qt::Key::Key_Backslash : + case Qt::Key::Key_BracketRight : + case Qt::Key::Key_AsciiCircum : + case Qt::Key::Key_Underscore : + case Qt::Key::Key_QuoteLeft : + case Qt::Key::Key_BraceLeft : + case Qt::Key::Key_Bar : + case Qt::Key::Key_BraceRight : + case Qt::Key::Key_AsciiTilde : + + case Qt::Key::Key_nobreakspace : + case Qt::Key::Key_exclamdown : + case Qt::Key::Key_cent : + case Qt::Key::Key_sterling : + case Qt::Key::Key_currency : + case Qt::Key::Key_yen : + case Qt::Key::Key_brokenbar : + case Qt::Key::Key_section : + case Qt::Key::Key_diaeresis : + case Qt::Key::Key_copyright : + case Qt::Key::Key_ordfeminine : + case Qt::Key::Key_guillemotleft : // left angle quotation mark + case Qt::Key::Key_notsign : + case Qt::Key::Key_hyphen : + case Qt::Key::Key_registered : + case Qt::Key::Key_macron : + case Qt::Key::Key_degree : + case Qt::Key::Key_plusminus : + case Qt::Key::Key_twosuperior : + case Qt::Key::Key_threesuperior : + case Qt::Key::Key_acute : + case Qt::Key::Key_mu : + case Qt::Key::Key_paragraph : + case Qt::Key::Key_periodcentered : + case Qt::Key::Key_cedilla : + case Qt::Key::Key_onesuperior : + case Qt::Key::Key_masculine : + case Qt::Key::Key_guillemotright : // right angle quotation mark + case Qt::Key::Key_onequarter : + case Qt::Key::Key_onehalf : + case Qt::Key::Key_threequarters : + case Qt::Key::Key_questiondown : + case Qt::Key::Key_Agrave : + case Qt::Key::Key_Aacute : + case Qt::Key::Key_Acircumflex : + case Qt::Key::Key_Atilde : + case Qt::Key::Key_Adiaeresis : + case Qt::Key::Key_Aring : + case Qt::Key::Key_AE : + case Qt::Key::Key_Ccedilla : + case Qt::Key::Key_Egrave : + case Qt::Key::Key_Eacute : + case Qt::Key::Key_Ecircumflex : + case Qt::Key::Key_Ediaeresis : + case Qt::Key::Key_Igrave : + case Qt::Key::Key_Iacute : + case Qt::Key::Key_Icircumflex : + case Qt::Key::Key_Idiaeresis : + case Qt::Key::Key_ETH : + case Qt::Key::Key_Ntilde : + case Qt::Key::Key_Ograve : + case Qt::Key::Key_Oacute : + case Qt::Key::Key_Ocircumflex : + case Qt::Key::Key_Otilde : + case Qt::Key::Key_Odiaeresis : + case Qt::Key::Key_multiply : + case Qt::Key::Key_Ooblique : + case Qt::Key::Key_Ugrave : + case Qt::Key::Key_Uacute : + case Qt::Key::Key_Ucircumflex : + case Qt::Key::Key_Udiaeresis : + case Qt::Key::Key_Yacute : + case Qt::Key::Key_THORN : + case Qt::Key::Key_ssharp : + case Qt::Key::Key_division : + case Qt::Key::Key_ydiaeresis : + + // International input method support (X keycode - 0xEE00, the + // definition follows Qt/Embedded 2.3.7) Only interesting if + // you are writing your own input method + + // International & multi-key character composition + case Qt::Key::Key_AltGr : + case Qt::Key::Key_Multi_key : // Multi-key character compose + case Qt::Key::Key_Codeinput : + case Qt::Key::Key_SingleCandidate : + case Qt::Key::Key_MultipleCandidate : + case Qt::Key::Key_PreviousCandidate : + + // Misc Functions + case Qt::Key::Key_Mode_switch : // Character set switch + //case Qt::Key::Key_script_switch : // Alias for mode_switch + + // Japanese keyboard support + case Qt::Key::Key_Kanji : // Kanji, Kanji convert + case Qt::Key::Key_Muhenkan : // Cancel Conversion + //case Qt::Key::Key_Henkan_Mode : // Start/Stop Conversion + case Qt::Key::Key_Henkan : // Alias for Henkan_Mode + case Qt::Key::Key_Romaji : // to Romaji + case Qt::Key::Key_Hiragana : // to Hiragana + case Qt::Key::Key_Katakana : // to Katakana + case Qt::Key::Key_Hiragana_Katakana : // Hiragana/Katakana toggle + case Qt::Key::Key_Zenkaku : // to Zenkaku + case Qt::Key::Key_Hankaku : // to Hankaku + case Qt::Key::Key_Zenkaku_Hankaku : // Zenkaku/Hankaku toggle + case Qt::Key::Key_Touroku : // Add to Dictionary + case Qt::Key::Key_Massyo : // Delete from Dictionary + case Qt::Key::Key_Kana_Lock : // Kana Lock + case Qt::Key::Key_Kana_Shift : // Kana Shift + case Qt::Key::Key_Eisu_Shift : // Alphanumeric Shift + case Qt::Key::Key_Eisu_toggle : // Alphanumeric toggle + //case Qt::Key::Key_Kanji_Bangou : // Codeinput + //case Qt::Key::Key_Zen_Koho : // Multiple/All Candidate(s) + //case Qt::Key::Key_Mae_Koho : // Previous Candidate + + // Korean keyboard support + // + // In fact, many Korean users need only 2 keys, Key_Hangul and + // Key_Hangul_Hanja. But rest of the keys are good for future. + + case Qt::Key::Key_Hangul : // Hangul start/stop(toggle) + case Qt::Key::Key_Hangul_Start : // Hangul start + case Qt::Key::Key_Hangul_End : // Hangul end, English start + case Qt::Key::Key_Hangul_Hanja : // Start Hangul->Hanja Conversion + case Qt::Key::Key_Hangul_Jamo : // Hangul Jamo mode + case Qt::Key::Key_Hangul_Romaja : // Hangul Romaja mode + //case Qt::Key::Key_Hangul_Codeinput : // Hangul code input mode + case Qt::Key::Key_Hangul_Jeonja : // Jeonja mode + case Qt::Key::Key_Hangul_Banja : // Banja mode + case Qt::Key::Key_Hangul_PreHanja : // Pre Hanja conversion + case Qt::Key::Key_Hangul_PostHanja : // Post Hanja conversion + //case Qt::Key::Key_Hangul_SingleCandidate : // Single candidate + //case Qt::Key::Key_Hangul_MultipleCandidate : // Multiple candidate + //case Qt::Key::Key_Hangul_PreviousCandidate : // Previous candidate + case Qt::Key::Key_Hangul_Special : // Special symbols + //case Qt::Key::Key_Hangul_switch : // Alias for mode_switch + + // dead keys (X keycode - 0xED00 to avoid the conflict) + case Qt::Key::Key_Dead_Grave : + case Qt::Key::Key_Dead_Acute : + case Qt::Key::Key_Dead_Circumflex : + case Qt::Key::Key_Dead_Tilde : + case Qt::Key::Key_Dead_Macron : + case Qt::Key::Key_Dead_Breve : + case Qt::Key::Key_Dead_Abovedot : + case Qt::Key::Key_Dead_Diaeresis : + case Qt::Key::Key_Dead_Abovering : + case Qt::Key::Key_Dead_Doubleacute : + case Qt::Key::Key_Dead_Caron : + case Qt::Key::Key_Dead_Cedilla : + case Qt::Key::Key_Dead_Ogonek : + case Qt::Key::Key_Dead_Iota : + case Qt::Key::Key_Dead_Voiced_Sound : + case Qt::Key::Key_Dead_Semivoiced_Sound : + case Qt::Key::Key_Dead_Belowdot : + case Qt::Key::Key_Dead_Hook : + case Qt::Key::Key_Dead_Horn : + case Qt::Key::Key_Dead_Stroke : + case Qt::Key::Key_Dead_Abovecomma : + case Qt::Key::Key_Dead_Abovereversedcomma : + case Qt::Key::Key_Dead_Doublegrave : + case Qt::Key::Key_Dead_Belowring : + case Qt::Key::Key_Dead_Belowmacron : + case Qt::Key::Key_Dead_Belowcircumflex : + case Qt::Key::Key_Dead_Belowtilde : + case Qt::Key::Key_Dead_Belowbreve : + case Qt::Key::Key_Dead_Belowdiaeresis : + case Qt::Key::Key_Dead_Invertedbreve : + case Qt::Key::Key_Dead_Belowcomma : + case Qt::Key::Key_Dead_Currency : + case Qt::Key::Key_Dead_a : + case Qt::Key::Key_Dead_A : + case Qt::Key::Key_Dead_e : + case Qt::Key::Key_Dead_E : + case Qt::Key::Key_Dead_i : + case Qt::Key::Key_Dead_I : + case Qt::Key::Key_Dead_o : + case Qt::Key::Key_Dead_O : + case Qt::Key::Key_Dead_u : + case Qt::Key::Key_Dead_U : + case Qt::Key::Key_Dead_Small_Schwa : + case Qt::Key::Key_Dead_Capital_Schwa : + case Qt::Key::Key_Dead_Greek : + case Qt::Key::Key_Dead_Lowline : + case Qt::Key::Key_Dead_Aboveverticalline : + case Qt::Key::Key_Dead_Belowverticalline : + case Qt::Key::Key_Dead_Longsolidusoverlay : + + // multimedia/internet keys - ignored by default - see QKeyEvent c'tor + case Qt::Key::Key_Back : + case Qt::Key::Key_Forward : + case Qt::Key::Key_Stop : + case Qt::Key::Key_Refresh : + case Qt::Key::Key_VolumeDown : + case Qt::Key::Key_VolumeMute : + case Qt::Key::Key_VolumeUp : + case Qt::Key::Key_BassBoost : + case Qt::Key::Key_BassUp : + case Qt::Key::Key_BassDown : + case Qt::Key::Key_TrebleUp : + case Qt::Key::Key_TrebleDown : + case Qt::Key::Key_MediaPlay : + case Qt::Key::Key_MediaStop : + case Qt::Key::Key_MediaPrevious : + case Qt::Key::Key_MediaNext : + case Qt::Key::Key_MediaRecord : + case Qt::Key::Key_MediaPause : + case Qt::Key::Key_MediaTogglePlayPause : + case Qt::Key::Key_HomePage : + case Qt::Key::Key_Favorites : + case Qt::Key::Key_Search : + case Qt::Key::Key_Standby : + case Qt::Key::Key_OpenUrl : + case Qt::Key::Key_LaunchMail : + case Qt::Key::Key_LaunchMedia : + case Qt::Key::Key_Launch0 : + case Qt::Key::Key_Launch1 : + case Qt::Key::Key_Launch2 : + case Qt::Key::Key_Launch3 : + case Qt::Key::Key_Launch4 : + case Qt::Key::Key_Launch5 : + case Qt::Key::Key_Launch6 : + case Qt::Key::Key_Launch7 : + case Qt::Key::Key_Launch8 : + case Qt::Key::Key_Launch9 : + case Qt::Key::Key_LaunchA : + case Qt::Key::Key_LaunchB : + case Qt::Key::Key_LaunchC : + case Qt::Key::Key_LaunchD : + case Qt::Key::Key_LaunchE : + case Qt::Key::Key_LaunchF : + case Qt::Key::Key_MonBrightnessUp : + case Qt::Key::Key_MonBrightnessDown : + case Qt::Key::Key_KeyboardLightOnOff : + case Qt::Key::Key_KeyboardBrightnessUp : + case Qt::Key::Key_KeyboardBrightnessDown : + case Qt::Key::Key_PowerOff : + case Qt::Key::Key_WakeUp : + case Qt::Key::Key_Eject : + case Qt::Key::Key_ScreenSaver : + case Qt::Key::Key_WWW : + case Qt::Key::Key_Memo : + case Qt::Key::Key_LightBulb : + case Qt::Key::Key_Shop : + case Qt::Key::Key_History : + case Qt::Key::Key_AddFavorite : + case Qt::Key::Key_HotLinks : + case Qt::Key::Key_BrightnessAdjust : + case Qt::Key::Key_Finance : + case Qt::Key::Key_Community : + case Qt::Key::Key_AudioRewind : // Media rewind + case Qt::Key::Key_BackForward : + case Qt::Key::Key_ApplicationLeft : + case Qt::Key::Key_ApplicationRight : + case Qt::Key::Key_Book : + case Qt::Key::Key_CD : + case Qt::Key::Key_Calculator : + case Qt::Key::Key_ToDoList : + case Qt::Key::Key_ClearGrab : + case Qt::Key::Key_Close : + case Qt::Key::Key_Copy : + case Qt::Key::Key_Cut : + case Qt::Key::Key_Display : // Output switch key + case Qt::Key::Key_DOS : + case Qt::Key::Key_Documents : + case Qt::Key::Key_Excel : + case Qt::Key::Key_Explorer : + case Qt::Key::Key_Game : + case Qt::Key::Key_Go : + case Qt::Key::Key_iTouch : + case Qt::Key::Key_LogOff : + case Qt::Key::Key_Market : + case Qt::Key::Key_Meeting : + case Qt::Key::Key_MenuKB : + case Qt::Key::Key_MenuPB : + case Qt::Key::Key_MySites : + case Qt::Key::Key_News : + case Qt::Key::Key_OfficeHome : + case Qt::Key::Key_Option : + case Qt::Key::Key_Paste : + case Qt::Key::Key_Phone : + case Qt::Key::Key_Calendar : + case Qt::Key::Key_Reply : + case Qt::Key::Key_Reload : + case Qt::Key::Key_RotateWindows : + case Qt::Key::Key_RotationPB : + case Qt::Key::Key_RotationKB : + case Qt::Key::Key_Save : + case Qt::Key::Key_Send : + case Qt::Key::Key_Spell : + case Qt::Key::Key_SplitScreen : + case Qt::Key::Key_Support : + case Qt::Key::Key_TaskPane : + case Qt::Key::Key_Terminal : + case Qt::Key::Key_Tools : + case Qt::Key::Key_Travel : + case Qt::Key::Key_Video : + case Qt::Key::Key_Word : + case Qt::Key::Key_Xfer : + case Qt::Key::Key_ZoomIn : + case Qt::Key::Key_ZoomOut : + case Qt::Key::Key_Away : + case Qt::Key::Key_Messenger : + case Qt::Key::Key_WebCam : + case Qt::Key::Key_MailForward : + case Qt::Key::Key_Pictures : + case Qt::Key::Key_Music : + case Qt::Key::Key_Battery : + case Qt::Key::Key_Bluetooth : + case Qt::Key::Key_WLAN : + case Qt::Key::Key_UWB : + case Qt::Key::Key_AudioForward : // Media fast-forward + case Qt::Key::Key_AudioRepeat : // Toggle repeat mode + case Qt::Key::Key_AudioRandomPlay : // Toggle shuffle mode + case Qt::Key::Key_Subtitle : + case Qt::Key::Key_AudioCycleTrack : + case Qt::Key::Key_Time : + case Qt::Key::Key_Hibernate : + case Qt::Key::Key_View : + case Qt::Key::Key_TopMenu : + case Qt::Key::Key_PowerDown : + case Qt::Key::Key_Suspend : + case Qt::Key::Key_ContrastAdjust : + + case Qt::Key::Key_LaunchG : + case Qt::Key::Key_LaunchH : + + case Qt::Key::Key_TouchpadToggle : + case Qt::Key::Key_TouchpadOn : + case Qt::Key::Key_TouchpadOff : + + case Qt::Key::Key_MicMute : + + case Qt::Key::Key_Red : + case Qt::Key::Key_Green : + case Qt::Key::Key_Yellow : + case Qt::Key::Key_Blue : + + case Qt::Key::Key_ChannelUp : + case Qt::Key::Key_ChannelDown : + + case Qt::Key::Key_Guide : + case Qt::Key::Key_Info : + case Qt::Key::Key_Settings : + + case Qt::Key::Key_MicVolumeUp : + case Qt::Key::Key_MicVolumeDown : + + case Qt::Key::Key_New : + case Qt::Key::Key_Open : + case Qt::Key::Key_Find : + case Qt::Key::Key_Undo : + case Qt::Key::Key_Redo : + + case Qt::Key::Key_MediaLast : + + // Keypad navigation keys + case Qt::Key::Key_Select : + case Qt::Key::Key_Yes : + case Qt::Key::Key_No : + + // Newer misc keys + case Qt::Key::Key_Cancel : + case Qt::Key::Key_Printer : + case Qt::Key::Key_Execute : + case Qt::Key::Key_Sleep : + case Qt::Key::Key_Play : // Not the same as Key_MediaPlay + case Qt::Key::Key_Zoom : + //case Qt::Key::Key_Jisho : // IME: Dictionary key + //case Qt::Key::Key_Oyayubi_Left : // IME: Left Oyayubi key + //case Qt::Key::Key_Oyayubi_Right : // IME: Right Oyayubi key + case Qt::Key::Key_Exit : + + // Device keys + case Qt::Key::Key_Context1 : + case Qt::Key::Key_Context2 : + case Qt::Key::Key_Context3 : + case Qt::Key::Key_Context4 : + case Qt::Key::Key_Call : // set absolute state to in a call (do not toggle state) + case Qt::Key::Key_Hangup : // set absolute state to hang up (do not toggle state) + case Qt::Key::Key_Flip : + case Qt::Key::Key_ToggleCallHangup : // a toggle key for answering, or hanging up, based on current call state + case Qt::Key::Key_VoiceDial : + case Qt::Key::Key_LastNumberRedial : + + case Qt::Key::Key_Camera : + case Qt::Key::Key_CameraFocus : + + case Qt::Key::Key_unknown : + return true; + default: + return false; + } +} \ No newline at end of file diff --git a/libs/gtkutil/button.cpp b/libs/gtkutil/button.cpp deleted file mode 100644 index fb3d783a..00000000 --- a/libs/gtkutil/button.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "button.h" - -#include - -#include "stream/textstream.h" -#include "stream/stringstream.h" -#include "generic/callback.h" - -#include "image.h" -#include "pointer.h" - -void clicked_closure_callback( GtkWidget* widget, gpointer data ){ - ( *reinterpret_cast( data ) )( ); -} - -void button_connect_callback( GtkButton* button, const Callback& callback ){ -#if 1 - g_signal_connect_swapped( G_OBJECT( button ), "clicked", G_CALLBACK( callback.getThunk() ), callback.getEnvironment() ); -#else - g_signal_connect_closure( G_OBJECT( button ), "clicked", create_cclosure( G_CALLBACK( clicked_closure_callback ), callback ), FALSE ); -#endif -} -void button_connect_callback( GtkToolButton* button, const Callback& callback ){ - g_signal_connect_swapped( G_OBJECT( button ), "clicked", G_CALLBACK( callback.getThunk() ), callback.getEnvironment() ); -} - -guint toggle_button_connect_callback( GtkToggleButton* button, const Callback& callback ){ -#if 1 - guint handler = g_signal_connect_swapped( G_OBJECT( button ), "toggled", G_CALLBACK( callback.getThunk() ), callback.getEnvironment() ); -#else - guint handler = g_signal_connect_closure( G_OBJECT( button ), "toggled", create_cclosure( G_CALLBACK( clicked_closure_callback ), callback ), TRUE ); -#endif - g_object_set_data( G_OBJECT( button ), "handler", gint_to_pointer( handler ) ); - return handler; -} -guint toggle_button_connect_callback( GtkToggleToolButton* button, const Callback& callback ){ - guint handler = g_signal_connect_swapped( G_OBJECT( button ), "toggled", G_CALLBACK( callback.getThunk() ), callback.getEnvironment() ); - g_object_set_data( G_OBJECT( button ), "handler", gint_to_pointer( handler ) ); - return handler; -} - -void button_set_icon( GtkButton* button, const char* icon ){ - GtkImage* image = new_local_image( icon ); - gtk_widget_show( GTK_WIDGET( image ) ); - gtk_container_add( GTK_CONTAINER( button ), GTK_WIDGET( image ) ); -} - -void toggle_button_set_active_no_signal( GtkToggleButton* button, gboolean active ){ - //globalOutputStream() << "set active: " << active << "\n"; - guint handler_id = gpointer_to_int( g_object_get_data( G_OBJECT( button ), "handler" ) ); - //guint signal_id = g_signal_lookup("toggled", G_OBJECT_TYPE (button)); - //globalOutputStream() << "signal_id: " << signal_id << "\n"; - //guint found = g_signal_handler_find(G_OBJECT(button), G_SIGNAL_MATCH_ID, signal_id, 0, 0, 0, 0); - //globalOutputStream() << " handler found: " << found << "\n"; - g_signal_handler_block( G_OBJECT( button ), handler_id ); - gtk_toggle_button_set_active( button, active ); - g_signal_handler_unblock( G_OBJECT( button ), handler_id ); -} -void toggle_button_set_active_no_signal( GtkToggleToolButton* button, gboolean active ){ - guint handler_id = gpointer_to_int( g_object_get_data( G_OBJECT( button ), "handler" ) ); - g_signal_handler_block( G_OBJECT( button ), handler_id ); - gtk_toggle_tool_button_set_active( button, active ); - g_signal_handler_unblock( G_OBJECT( button ), handler_id ); -} - - -void radio_button_print_state( GtkRadioButton* button ){ - globalOutputStream() << "toggle button: "; - for ( GSList* radio = gtk_radio_button_get_group( button ); radio != 0; radio = g_slist_next( radio ) ) - { - globalOutputStream() << gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( radio->data ) ); - } - globalOutputStream() << "\n"; -} - -GtkToggleButton* radio_button_get_nth( GtkRadioButton* radio, int index ){ - GSList *group = gtk_radio_button_get_group( radio ); - return GTK_TOGGLE_BUTTON( g_slist_nth_data( group, g_slist_length( group ) - index - 1 ) ); -} - -void radio_button_set_active( GtkRadioButton* radio, int index ){ - //radio_button_print_state(radio); - gtk_toggle_button_set_active( radio_button_get_nth( radio, index ), TRUE ); - //radio_button_print_state(radio); -} - -void radio_button_set_active_no_signal( GtkRadioButton* radio, int index ){ - { - for ( GSList* l = gtk_radio_button_get_group( radio ); l != 0; l = g_slist_next( l ) ) - { - g_signal_handler_block( G_OBJECT( l->data ), gpointer_to_int( g_object_get_data( G_OBJECT( l->data ), "handler" ) ) ); - } - } - radio_button_set_active( radio, index ); - { - for ( GSList* l = gtk_radio_button_get_group( radio ); l != 0; l = g_slist_next( l ) ) - { - g_signal_handler_unblock( G_OBJECT( l->data ), gpointer_to_int( g_object_get_data( G_OBJECT( l->data ), "handler" ) ) ); - } - } -} - -int radio_button_get_active( GtkRadioButton* radio ){ - //radio_button_print_state(radio); - GSList *group = gtk_radio_button_get_group( radio ); - int index = g_slist_length( group ) - 1; - for (; group != 0; group = g_slist_next( group ) ) - { - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( group->data ) ) ) { - break; - } - else - { - index--; - } - } - return index; -} diff --git a/libs/gtkutil/button.h b/libs/gtkutil/button.h deleted file mode 100644 index 5da39198..00000000 --- a/libs/gtkutil/button.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#pragma once - -#include "generic/callbackfwd.h" - -typedef struct _GtkButton GtkButton; -typedef struct _GtkToolButton GtkToolButton; -typedef struct _GtkToggleButton GtkToggleButton; -typedef struct _GtkToggleToolButton GtkToggleToolButton; -typedef struct _GtkRadioButton GtkRadioButton; -typedef int gint; -typedef gint gboolean; -typedef unsigned int guint; - -void button_connect_callback( GtkButton* button, const Callback& callback ); -void button_connect_callback( GtkToolButton* button, const Callback& callback ); -guint toggle_button_connect_callback( GtkToggleButton* button, const Callback& callback ); -guint toggle_button_connect_callback( GtkToggleToolButton* button, const Callback& callback ); - -void button_set_icon( GtkButton* button, const char* icon ); -void toggle_button_set_active_no_signal( GtkToggleButton* item, gboolean active ); -void toggle_button_set_active_no_signal( GtkToggleToolButton* item, gboolean active ); - -void radio_button_set_active( GtkRadioButton* radio, int index ); -void radio_button_set_active_no_signal( GtkRadioButton* radio, int index ); -int radio_button_get_active( GtkRadioButton* radio ); diff --git a/libs/gtkutil/clipboard.cpp b/libs/gtkutil/clipboard.cpp index 9ee4196f..584158df 100644 --- a/libs/gtkutil/clipboard.cpp +++ b/libs/gtkutil/clipboard.cpp @@ -26,120 +26,43 @@ /// \file -/// \brief Platform-independent GTK clipboard support. -/// \todo Using GDK_SELECTION_CLIPBOARD fails on win32, so we use the win32 API directly for now. -#if defined( WIN32 ) +/// \brief Platform-independent clipboard support. -const char* c_clipboard_format = "RadiantClippings"; +#include +#include +#include -#include +constexpr char c_clipboard_format[] = "RadiantClippings"; void clipboard_copy( ClipboardCopyFunc copy ){ BufferOutputStream ostream; copy( ostream ); - bool bClipped = false; - UINT nClipboard = ::RegisterClipboardFormat( c_clipboard_format ); - if ( nClipboard > 0 ) { - if ( ::OpenClipboard( 0 ) ) { - EmptyClipboard(); - std::size_t length = ostream.size(); - HANDLE h = ::GlobalAlloc( GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, length + sizeof( std::size_t ) ); - if ( h != 0 ) { - char *buffer = reinterpret_cast( ::GlobalLock( h ) ); - *reinterpret_cast( buffer ) = length; - buffer += sizeof( std::size_t ); - memcpy( buffer, ostream.data(), length ); - ::GlobalUnlock( h ); - ::SetClipboardData( nClipboard, h ); - ::CloseClipboard(); - bClipped = true; - } - } - } + const std::size_t length = ostream.size(); + QByteArray array( sizeof( std::size_t ) + length, Qt::Initialization::Uninitialized ); + *reinterpret_cast( array.data() ) = length; + memcpy( array.data() + sizeof( std::size_t ), ostream.data(), length ); - if ( !bClipped ) { - globalWarningStream() << "Unable to register Windows clipboard formats, copy/paste between editors will not be possible\n"; - } + auto mimedata = new QMimeData; + mimedata->setData( c_clipboard_format, array ); + QGuiApplication::clipboard()->setMimeData( mimedata ); } void clipboard_paste( ClipboardPasteFunc paste ){ - UINT nClipboard = ::RegisterClipboardFormat( c_clipboard_format ); - if ( nClipboard > 0 && ::OpenClipboard( 0 ) ) { - if ( IsClipboardFormatAvailable( nClipboard ) ) { - HANDLE h = ::GetClipboardData( nClipboard ); - if ( h ) { - const char *buffer = reinterpret_cast( ::GlobalLock( h ) ); - std::size_t length = *reinterpret_cast( buffer ); - buffer += sizeof( std::size_t ); - BufferInputStream istream( buffer, length ); + if( const auto mimedata = QGuiApplication::clipboard()->mimeData() ){ + if( const auto array = mimedata->data( c_clipboard_format ); !array.isEmpty() ){ + /* 32 & 64 bit radiants use the same clipboard signature 👀 + handle varying sizeof( std::size_t ), also try to be safe + note: GtkR1.4 uses xml map format in clipboard */ + if( const std::size_t length = *reinterpret_cast( array.data() ); size_t( array.size() ) == length + sizeof( std::size_t ) ){ + BufferInputStream istream( array.data() + sizeof( std::size_t ), length ); paste( istream ); - ::GlobalUnlock( h ); - } + } else + if( const std::size_t length = *reinterpret_cast( array.data() ); size_t( array.size() ) == length + sizeof( std::uint32_t ) ){ + BufferInputStream istream( array.data() + sizeof( std::uint32_t ), length ); + paste( istream ); + } else + globalWarningStream() << "Unrecognized clipboard contents\n"; } - ::CloseClipboard(); } } - -#else - -#include - -enum -{ - RADIANT_CLIPPINGS = 23, -}; - -static const GtkTargetEntry clipboard_targets[] = { - { "RADIANT_CLIPPINGS", 0, RADIANT_CLIPPINGS, }, -}; - -static void clipboard_get( GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info, gpointer data ){ - std::size_t len = *reinterpret_cast( data ); - const char* buffer = ( len != 0 ) ? reinterpret_cast( data ) + sizeof( std::size_t ) : 0; - - GdkAtom type = GDK_NONE; - if ( info == clipboard_targets[0].info ) { - type = gdk_atom_intern( clipboard_targets[0].target, FALSE ); - } - - gtk_selection_data_set( selection_data, type, 8, reinterpret_cast( buffer ), static_cast( len ) ); -} - -static void clipboard_clear( GtkClipboard *clipboard, gpointer data ){ - delete [] reinterpret_cast( data ); -} - -static void clipboard_received( GtkClipboard *clipboard, GtkSelectionData *data, gpointer user_data ){ - if ( gtk_selection_data_get_length( data ) < 0 ) { - globalErrorStream() << "Error retrieving selection\n"; - } - else if ( strcmp( gdk_atom_name( gtk_selection_data_get_data_type( data ) ), clipboard_targets[0].target ) == 0 ) { - BufferInputStream istream( reinterpret_cast( gtk_selection_data_get_data( data ) ), gtk_selection_data_get_length( data ) ); - ( *reinterpret_cast( user_data ) )( istream ); - } -} - -void clipboard_copy( ClipboardCopyFunc copy ){ - GtkClipboard* clipboard = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ); - - BufferOutputStream ostream; - copy( ostream ); - std::size_t length = ostream.size(); - char* data = new char[length + sizeof( std::size_t )]; - *reinterpret_cast( data ) = length; - memcpy( data + sizeof( std::size_t ), ostream.data(), length ); - - gtk_clipboard_set_with_data( clipboard, clipboard_targets, 1, clipboard_get, clipboard_clear, data ); -} - -ClipboardPasteFunc g_clipboardPasteFunc = 0; -void clipboard_paste( ClipboardPasteFunc paste ){ - GtkClipboard* clipboard = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ); - - g_clipboardPasteFunc = paste; - gtk_clipboard_request_contents( clipboard, gdk_atom_intern( clipboard_targets[0].target, FALSE ), clipboard_received, &g_clipboardPasteFunc ); -} - - -#endif diff --git a/libs/gtkutil/closure.cpp b/libs/gtkutil/closure.cpp deleted file mode 100644 index 09e2fab7..00000000 --- a/libs/gtkutil/closure.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "closure.h" diff --git a/libs/gtkutil/closure.h b/libs/gtkutil/closure.h deleted file mode 100644 index ca2a3278..00000000 --- a/libs/gtkutil/closure.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#pragma once - -#include -#include "generic/callback.h" - -inline void closure_destroy( gpointer data, GClosure* closure ){ - delete reinterpret_cast( data ); -} - -inline GClosure* create_cclosure( GCallback func, const Callback& callback ){ - return g_cclosure_new( func, new Callback( callback ), closure_destroy ); -} - -inline GValue GValue_default(){ - GValue value; - value.g_type = 0; - return value; -} - -inline gint object_get_int_property( GObject* object, const char* property ){ - GValue gvalue = GValue_default(); - g_value_init( &gvalue, G_TYPE_INT ); - g_object_get_property( object, property, &gvalue ); - return g_value_get_int( &gvalue ); -} - -inline void object_set_int_property( GObject* object, const char* property, gint value ){ - GValue gvalue = GValue_default(); - g_value_init( &gvalue, G_TYPE_INT ); - g_value_set_int( &gvalue, value ); - g_object_set_property( object, property, &gvalue ); -} - -inline gboolean object_get_boolean_property( GObject* object, const char* property ){ - GValue gvalue = GValue_default(); - g_value_init( &gvalue, G_TYPE_BOOLEAN ); - g_object_get_property( object, property, &gvalue ); - return g_value_get_boolean( &gvalue ); -} - -inline void object_set_boolean_property( GObject* object, const char* property, gboolean value ){ - GValue gvalue = GValue_default(); - g_value_init( &gvalue, G_TYPE_BOOLEAN ); - g_value_set_boolean( &gvalue, value ); - g_object_set_property( object, property, &gvalue ); -} diff --git a/libs/gtkutil/container.h b/libs/gtkutil/container.h deleted file mode 100644 index c8be8e87..00000000 --- a/libs/gtkutil/container.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#pragma once - -#include - -inline GtkWidget* container_add_widget( GtkContainer* container, GtkWidget* widget ){ - gtk_container_add( container, widget ); - return widget; -} - -inline void container_remove( GtkWidget* item, gpointer data ){ - gtk_container_remove( GTK_CONTAINER( data ), item ); -} - -inline void container_remove_all( GtkContainer* container ){ - gtk_container_foreach( container, container_remove, container ); -} diff --git a/libs/gtkutil/cursor.cpp b/libs/gtkutil/cursor.cpp deleted file mode 100644 index 8eefe980..00000000 --- a/libs/gtkutil/cursor.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "cursor.h" - -#include "stream/textstream.h" - -#include -#include - -#if 0 -GdkCursor* create_blank_cursor(){ - GdkPixmap *pixmap; - GdkBitmap *mask; - char buffer [( 32 * 32 ) / 8]; - memset( buffer, 0, ( 32 * 32 ) / 8 ); - GdkColor white = {0, 0xffff, 0xffff, 0xffff}; - GdkColor black = {0, 0x0000, 0x0000, 0x0000}; - pixmap = gdk_bitmap_create_from_data( 0, buffer, 32, 32 ); - mask = gdk_bitmap_create_from_data( 0, buffer, 32, 32 ); - GdkCursor *cursor = gdk_cursor_new_from_pixmap( pixmap, mask, &white, &black, 1, 1 ); - gdk_drawable_unref( pixmap ); - gdk_drawable_unref( mask ); - - return cursor; -} - -void blank_cursor( GtkWidget* widget ){ - GdkCursor* cursor = create_blank_cursor(); - gdk_window_set_cursor( gtk_widget_get_window( widget ), cursor ); - gdk_cursor_unref( cursor ); -} - -void default_cursor( GtkWidget* widget ){ - gdk_window_set_cursor( gtk_widget_get_window( widget ), 0 ); -} -#endif - - -void Sys_GetCursorPos( GtkWindow* window, int *x, int *y ){ - gdk_display_get_pointer( gdk_display_get_default(), 0, x, y, 0 ); -} - -void Sys_SetCursorPos( GtkWindow* window, int x, int y ){ - GdkScreen *screen; - gdk_display_get_pointer( gdk_display_get_default(), &screen, 0, 0, 0 ); - gdk_display_warp_pointer( gdk_display_get_default(), screen, x, y ); -} diff --git a/libs/gtkutil/cursor.h b/libs/gtkutil/cursor.h index 0376f0fb..dccc9c8e 100644 --- a/libs/gtkutil/cursor.h +++ b/libs/gtkutil/cursor.h @@ -21,208 +21,143 @@ #pragma once -#include -#include -#include +#include +#include +#include +#include #include "debugging/debugging.h" -#if 0 -GdkCursor* create_blank_cursor(); -void blank_cursor( GtkWidget* widget ); -void default_cursor( GtkWidget* widget ); -#endif -void Sys_GetCursorPos( GtkWindow* window, int *x, int *y ); -void Sys_SetCursorPos( GtkWindow* window, int x, int y ); - - class DeferredMotion { - guint m_handler; - typedef void ( *MotionFunction )( gdouble x, gdouble y, guint state, void* data ); - MotionFunction m_function; - void* m_data; - gdouble m_x; - gdouble m_y; - guint m_state; - - static gboolean deferred( DeferredMotion* self ){ - self->m_handler = 0; - self->m_function( self->m_x, self->m_y, self->m_state, self->m_data ); - return FALSE; - } + QMouseEvent m_mouseMoveEvent; + QTimer m_timer; public: - DeferredMotion( MotionFunction function, void* data ) : m_handler( 0 ), m_function( function ), m_data( data ){ + template + DeferredMotion( Functor func ) : + m_mouseMoveEvent( QEvent::MouseMove, QPointF(), Qt::MouseButton::NoButton, Qt::MouseButtons(), Qt::KeyboardModifiers() ) + { + m_timer.setSingleShot( true ); + m_timer.callOnTimeout( [this, func](){ func( m_mouseMoveEvent ); } ); } - void motion( gdouble x, gdouble y, guint state ){ - m_x = x; - m_y = y; - m_state = state; - if ( m_handler == 0 ) { - m_handler = g_idle_add( (GSourceFunc)deferred, this ); - } - } - static gboolean gtk_motion( GtkWidget *widget, GdkEventMotion *event, DeferredMotion* self ){ - self->motion( event->x, event->y, event->state ); - return FALSE; + void motion( const QMouseEvent *event ){ + m_mouseMoveEvent = *event; + if( !m_timer.isActive() ) + m_timer.start(); } }; class DeferredMotionDelta { - int m_delta_x; - int m_delta_y; - unsigned int m_state; - guint m_motion_handler; - typedef void ( *MotionDeltaFunction )( int x, int y, unsigned int state, void* data ); - MotionDeltaFunction m_function; - void* m_data; - - static gboolean deferred_motion( gpointer data ){ - DeferredMotionDelta* self = reinterpret_cast( data ); - self->m_function( - self->m_delta_x, - self->m_delta_y, - self->m_state, - self->m_data - ); - self->m_motion_handler = 0; - self->m_delta_x = 0; - self->m_delta_y = 0; - return FALSE; - } + QMouseEvent m_mouseMoveEvent; + QTimer m_timer; + int m_delta_x = 0; + int m_delta_y = 0; public: - DeferredMotionDelta( MotionDeltaFunction function, void* data ) : m_delta_x( 0 ), m_delta_y( 0 ), m_motion_handler( 0 ), m_function( function ), m_data( data ){ + template + DeferredMotionDelta( Functor func ) : + m_mouseMoveEvent( QEvent::MouseMove, QPointF(), Qt::MouseButton::NoButton, Qt::MouseButtons(), Qt::KeyboardModifiers() ) + { + m_timer.setSingleShot( true ); + m_timer.callOnTimeout( [this, func](){ + func( m_delta_x, m_delta_y, m_mouseMoveEvent ); + m_delta_x = 0; + m_delta_y = 0; + } ); } void flush(){ - if ( m_motion_handler != 0 ) { - g_source_remove( m_motion_handler ); - deferred_motion( this ); - } + m_timer.stop(); +//. ? deferred_motion( this ); } - void motion_delta( int x, int y, unsigned int state ){ + void motion_delta( int x, int y, const QMouseEvent *event ){ m_delta_x += x; m_delta_y += y; - m_state = state; - if ( m_motion_handler == 0 ) { - m_motion_handler = g_idle_add( deferred_motion, this ); - } + m_mouseMoveEvent = *event; + if( !m_timer.isActive() ) + m_timer.start(); } }; -class FreezePointer + + +class FreezePointer : public QObject { - unsigned int handle_motion; - int recorded_x, recorded_y, last_x, last_y, center_x, center_y; - GtkWindow* m_window; - GtkWidget* m_widget; - typedef void ( *MotionDeltaFunction )( int x, int y, unsigned int state, void* data ); - MotionDeltaFunction m_function; - void* m_data; -public: - FreezePointer() : handle_motion( 0 ), m_function( 0 ), m_data( 0 ){ + QWidget* m_widget; + + //global coordinates + QPoint m_initial_pos; + bool m_trackingEstablished; + + std::function m_motion_delta_function; + std::function m_focus_out_function; + QTimer m_rescueTimer; + QPoint getCenter() const { + return m_widget->mapToGlobal( m_widget->rect().center() ); } - static gboolean motion_delta( GtkWidget *widget, GdkEventMotion *event, FreezePointer* self ){ - int current_x, current_y; - Sys_GetCursorPos( GTK_WINDOW( widget ), ¤t_x, ¤t_y ); -#define FIX_LINUX_TOUCHPAD 0 /* issues with this: mouse juddering - in win10 (system is already at normal scaling) - Leaving the DPI scaling to the application instead of the system half fixes it - in GNU/Linux - Mouselook is broken with custom Input Coordinate Tranformation */ -#if FIX_LINUX_TOUCHPAD - const int dx = current_x - self->last_x; - const int dy = current_y - self->last_y; - const int ddx = current_x - self->center_x; - const int ddy = current_y - self->center_y; - self->last_x = current_x; - self->last_y = current_y; - if ( dx != 0 || dy != 0 ) { - //globalOutputStream() << "motion x: " << dx << ", y: " << dy << "\n"; - if ( ddx < -32 || ddx > 32 || ddy < -32 || ddy > 32 ) { - Sys_SetCursorPos( GTK_WINDOW( widget ), self->center_x, self->center_y ); - self->last_x = self->center_x; - self->last_y = self->center_y; +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::MouseMove ) { + QMouseEvent *mouseEvent = static_cast( event ); + const QPoint center = getCenter(); + /* QCursor::setPos( center ) effect may happen not immediately; suspend processing till then, otherwise start dash will happen */ + if( !m_trackingEstablished ){ + m_trackingEstablished = mouseEvent->globalPos() == center; + QCursor::setPos( center ); + } + else if( mouseEvent->globalPos() != center ){ + const QPoint delta = mouseEvent->globalPos() - center; + m_motion_delta_function( delta.x(), delta.y(), mouseEvent ); + QCursor::setPos( center ); + } + // handle runaways with released buttons; FIXME: need more elegant way to persistently grab in this case + if( !m_widget->rect().contains( mouseEvent->pos() ) ){ // bomb cursor via timer to get it back to the widget + if( !m_rescueTimer.isActive() ){ + m_rescueTimer.callOnTimeout( [center = center](){ QCursor::setPos( center ); } ); + m_rescueTimer.start( 33 ); + } + } + else{ + m_rescueTimer.stop(); } -#else - const int dx = current_x - self->center_x; - const int dy = current_y - self->center_y; - if ( dx != 0 || dy != 0 ) { - //globalOutputStream() << "motion x: " << dx << ", y: " << dy << "\n"; - Sys_SetCursorPos( GTK_WINDOW( widget ), self->center_x, self->center_y ); -#endif - self->m_function( dx, dy, event->state, self->m_data ); } - return FALSE; + else if( event->type() == QEvent::FocusOut ) { + m_focus_out_function(); + } + return QObject::eventFilter( obj, event ); // standard event processing + } +public: + FreezePointer() : m_widget( nullptr ){ } - void freeze_pointer( GtkWindow* window, GtkWidget* widget, MotionDeltaFunction function, void* data ){ - ASSERT_MESSAGE( m_function == 0, "can't freeze pointer: already frozen" ); - - const GdkEventMask mask = static_cast( GDK_POINTER_MOTION_MASK - | GDK_POINTER_MOTION_HINT_MASK - | GDK_BUTTON_MOTION_MASK - | GDK_BUTTON1_MOTION_MASK - | GDK_BUTTON2_MOTION_MASK - | GDK_BUTTON3_MOTION_MASK - | GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK - | GDK_VISIBILITY_NOTIFY_MASK ); - - GdkCursor* cursor = gdk_cursor_new( GDK_BLANK_CURSOR ); - //GdkCursor* cursor = create_blank_cursor(); - //GdkGrabStatus status = - /* fixes cursor runaways during srsly quick drags in camera - drags with pressed buttons have no problem at all w/o this */ - gdk_pointer_grab( gtk_widget_get_window( GTK_WIDGET( window ) ), TRUE, mask, 0, cursor, GDK_CURRENT_TIME ); - //gdk_window_set_cursor ( gtk_widget_get_window( GTK_WIDGET( window ) ), cursor ); - /* is needed to fix activating neighbor widgets, that happens, if using upper one */ - gtk_grab_add( widget ); - - gdk_cursor_unref( cursor ); - - Sys_GetCursorPos( window, &recorded_x, &recorded_y ); - - /* using center for tracking for max safety */ - gdk_window_get_origin( gtk_widget_get_window( widget ), ¢er_x, ¢er_y ); - GtkAllocation allocation; - gtk_widget_get_allocation( widget, &allocation ); - center_y += allocation.height / 2; - center_x += allocation.width / 2; - - Sys_SetCursorPos( window, center_x, center_y ); - - last_x = center_x; - last_y = center_y; + void freeze_pointer( QWidget* widget, decltype( m_motion_delta_function ) motion_delta_function, decltype( m_focus_out_function ) focus_out_function ){ + ASSERT_MESSAGE( m_widget == nullptr, "can't freeze pointer: already frozen" ); m_widget = widget; - m_window = window; + m_initial_pos = QCursor::pos(); + m_trackingEstablished = false; + m_motion_delta_function = motion_delta_function; + m_focus_out_function = focus_out_function; - m_function = function; - m_data = data; - - handle_motion = g_signal_connect( G_OBJECT( window ), "motion_notify_event", G_CALLBACK( motion_delta ), this ); + m_widget->installEventFilter( this ); + m_widget->grabMouse( Qt::CursorShape::BlankCursor ); // is only needed for released mouse freezing, prevents certain glitches + /* using center for tracking for max safety */ + QCursor::setPos( getCenter() ); } void unfreeze_pointer( bool centerize ){ - ASSERT_MESSAGE( m_function != 0, "can't unfreeze pointer: is not frozen" ); + ASSERT_MESSAGE( m_widget != nullptr, "can't unfreeze pointer: is not frozen" ); - g_signal_handler_disconnect( G_OBJECT( m_window ), handle_motion ); + m_rescueTimer.stop(); + m_widget->releaseMouse(); + m_widget->removeEventFilter( this ); - m_function = 0; - m_data = 0; + if( centerize ) + QCursor::setPos( getCenter() ); + else + QCursor::setPos( m_initial_pos ); - if( centerize ){ - Sys_SetCursorPos( m_window, center_x, center_y ); - } - else{ - Sys_SetCursorPos( m_window, recorded_x, recorded_y ); - } -// gdk_window_set_cursor( gtk_widget_get_window( GTK_WIDGET( m_window ) ), 0 ); - gdk_pointer_ungrab( GDK_CURRENT_TIME ); - - gtk_grab_remove( m_widget ); + m_widget = nullptr; } }; @@ -232,38 +167,17 @@ public: class DeferredAdjustment { - gdouble m_value; - guint m_handler; - typedef void ( *ValueChangedFunction )( void* data, gdouble value ); - ValueChangedFunction m_function; - void* m_data; - - static gboolean deferred_value_changed( gpointer data ){ - DeferredAdjustment* self = reinterpret_cast( data ); - self->m_function( - self->m_data, - self->m_value - ); - self->m_handler = 0; - self->m_value = 0; - return FALSE; - } + int m_value; + QTimer m_timer; public: - DeferredAdjustment( ValueChangedFunction function, void* data ) : m_value( 0 ), m_handler( 0 ), m_function( function ), m_data( data ){ + template + DeferredAdjustment( Functor func ) { + m_timer.setSingleShot( true ); + m_timer.callOnTimeout( [this, func](){ func( m_value ); } ); } - void flush(){ - if ( m_handler != 0 ) { - g_source_remove( m_handler ); - deferred_value_changed( this ); - } - } - void value_changed( gdouble value ){ + void value_changed( int value ){ m_value = value; - if ( m_handler == 0 ) { - m_handler = g_idle_add( deferred_value_changed, this ); - } - } - static void adjustment_value_changed( GtkAdjustment *adjustment, DeferredAdjustment* self ){ - self->value_changed( gtk_adjustment_get_value( adjustment ) ); + if( !m_timer.isActive() ) + m_timer.start(); } }; diff --git a/libs/gtkutil/dialog.cpp b/libs/gtkutil/dialog.cpp index 211bba4d..95d7d4bb 100644 --- a/libs/gtkutil/dialog.cpp +++ b/libs/gtkutil/dialog.cpp @@ -21,250 +21,55 @@ #include "dialog.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "button.h" -#include "window.h" - -GtkVBox* create_dialog_vbox( int spacing, int border ){ - GtkVBox* vbox = GTK_VBOX( gtk_vbox_new( FALSE, spacing ) ); - gtk_widget_show( GTK_WIDGET( vbox ) ); - gtk_container_set_border_width( GTK_CONTAINER( vbox ), border ); - return vbox; -} - -GtkHBox* create_dialog_hbox( int spacing, int border ){ - GtkHBox* hbox = GTK_HBOX( gtk_hbox_new( FALSE, spacing ) ); - gtk_widget_show( GTK_WIDGET( hbox ) ); - gtk_container_set_border_width( GTK_CONTAINER( hbox ), border ); - return hbox; -} - -GtkFrame* create_dialog_frame( const char* label, GtkShadowType shadow ){ - GtkFrame* frame = GTK_FRAME( gtk_frame_new( label ) ); - gtk_widget_show( GTK_WIDGET( frame ) ); - gtk_frame_set_shadow_type( frame, shadow ); - return frame; -} - -GtkTable* create_dialog_table( unsigned int rows, unsigned int columns, unsigned int row_spacing, unsigned int col_spacing, int border ){ - GtkTable* table = GTK_TABLE( gtk_table_new( rows, columns, FALSE ) ); - gtk_widget_show( GTK_WIDGET( table ) ); - gtk_table_set_row_spacings( table, row_spacing ); - gtk_table_set_col_spacings( table, col_spacing ); - gtk_container_set_border_width( GTK_CONTAINER( table ), border ); - return table; -} - -GtkButton* create_dialog_button( const char* label, GCallback func, gpointer data ){ - GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( label ) ); - gtk_widget_set_size_request( GTK_WIDGET( button ), 64, -1 ); - gtk_widget_show( GTK_WIDGET( button ) ); - g_signal_connect( G_OBJECT( button ), "clicked", func, data ); - return button; -} - -GtkWindow* create_dialog_window( GtkWindow* parent, const char* title, GCallback func, gpointer data, int default_w, int default_h ){ - GtkWindow* window = create_floating_window( title, parent ); - gtk_window_set_default_size( window, default_w, default_h ); - gtk_window_set_position( window, GTK_WIN_POS_CENTER_ON_PARENT ); - g_signal_connect( G_OBJECT( window ), "delete_event", func, data ); - - return window; -} - -gboolean modal_dialog_button_clicked( GtkWidget *widget, ModalDialogButton* button ){ - button->m_dialog.loop = false; - button->m_dialog.ret = button->m_value; - return TRUE; -} - -gboolean modal_dialog_delete( GtkWidget *widget, GdkEvent* event, ModalDialog* dialog ){ - dialog->loop = 0; - dialog->ret = eIDCANCEL; - return TRUE; -} - -EMessageBoxReturn modal_dialog_show( GtkWindow* window, ModalDialog& dialog ){ - gtk_window_set_modal( GTK_WINDOW( window ), TRUE ); - gtk_widget_show( GTK_WIDGET( window ) ); - - dialog.loop = true; - while ( dialog.loop ) - { - gtk_main_iteration(); - } - - gtk_widget_hide( GTK_WIDGET( window ) ); - - return dialog.ret; -} - -GtkButton* create_modal_dialog_button( const char* label, ModalDialogButton& button ){ - return create_dialog_button( label, G_CALLBACK( modal_dialog_button_clicked ), &button ); -} - -GtkWindow* create_modal_dialog_window( GtkWindow* parent, const char* title, ModalDialog& dialog, int default_w, int default_h ){ - return create_dialog_window( parent, title, G_CALLBACK( modal_dialog_delete ), &dialog, default_w, default_h ); -} - -GtkWindow* create_fixedsize_modal_dialog_window( GtkWindow* parent, const char* title, ModalDialog& dialog, int width, int height ){ - GtkWindow* window = create_modal_dialog_window( parent, title, dialog, width, height ); - - gtk_window_set_resizable( window, FALSE ); - gtk_window_set_modal( window, TRUE ); - gtk_window_set_position( window, GTK_WIN_POS_CENTER ); - - window_remove_minmax( window ); - - //gtk_widget_set_size_request(GTK_WIDGET(window), width, height); - //gtk_window_set_default_size(window, width, height); - //gtk_window_resize(window, width, height); - //GdkGeometry geometry = { width, height, -1, -1, width, height, -1, -1, -1, -1, GDK_GRAVITY_STATIC, }; - //gtk_window_set_geometry_hints(window, GTK_WIDGET(window), &geometry, (GdkWindowHints)(GDK_HINT_POS|GDK_HINT_MIN_SIZE|GDK_HINT_BASE_SIZE)); - - return window; -} - -gboolean dialog_button_ok( GtkWidget *widget, ModalDialog* data ){ - data->loop = false; - data->ret = eIDOK; - return TRUE; -} - -gboolean dialog_button_cancel( GtkWidget *widget, ModalDialog* data ){ - data->loop = false; - data->ret = eIDCANCEL; - return TRUE; -} - -gboolean dialog_button_yes( GtkWidget *widget, ModalDialog* data ){ - data->loop = false; - data->ret = eIDYES; - return TRUE; -} - -gboolean dialog_button_no( GtkWidget *widget, ModalDialog* data ){ - data->loop = false; - data->ret = eIDNO; - return TRUE; -} - -gboolean dialog_delete_callback( GtkWidget *widget, GdkEventAny* event, ModalDialog* data ){ - gtk_widget_hide( widget ); - data->loop = false; - return TRUE; -} - -#include - -GtkWindow* create_simple_modal_dialog_window( const char* title, ModalDialog& dialog, GtkWidget* contents ){ - GtkWindow* window = create_fixedsize_modal_dialog_window( 0, title, dialog ); - - GtkAccelGroup* accel = gtk_accel_group_new(); - gtk_window_add_accel_group( window, accel ); - - GtkVBox* vbox1 = create_dialog_vbox( 8, 4 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox1 ) ); - - gtk_container_add( GTK_CONTAINER( vbox1 ), contents ); - - GtkAlignment* alignment = GTK_ALIGNMENT( gtk_alignment_new( 0.5, 0.0, 0.0, 0.0 ) ); - gtk_widget_show( GTK_WIDGET( alignment ) ); - gtk_box_pack_start( GTK_BOX( vbox1 ), GTK_WIDGET( alignment ), FALSE, FALSE, 0 ); - - GtkButton* button = create_dialog_button( "OK", G_CALLBACK( dialog_button_ok ), &dialog ); - gtk_container_add( GTK_CONTAINER( alignment ), GTK_WIDGET( button ) ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 ); - - return window; -} RadioHBox RadioHBox_new( StringArrayRange names ){ - GtkHBox* hbox = GTK_HBOX( gtk_hbox_new( TRUE, 4 ) ); - gtk_widget_show( GTK_WIDGET( hbox ) ); + auto hbox = new QHBoxLayout; + auto group = new QButtonGroup( hbox ); - GtkRadioButton* radio = 0; - for ( const char *name : names ) + for ( size_t i = 0; i < names.size(); ++i ) { - radio = GTK_RADIO_BUTTON( gtk_radio_button_new_with_label_from_widget( radio, name ) ); - gtk_widget_show( GTK_WIDGET( radio ) ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( radio ), FALSE, FALSE, 0 ); + auto button = new QRadioButton( names[i] ); + group->addButton( button, i ); // set ids 0+, default ones are negative + hbox->addWidget( button ); } - return RadioHBox( hbox, radio ); + return RadioHBox( hbox, group ); } PathEntry PathEntry_new(){ - GtkFrame* frame = GTK_FRAME( gtk_frame_new( NULL ) ); - gtk_widget_show( GTK_WIDGET( frame ) ); - gtk_frame_set_shadow_type( frame, GTK_SHADOW_IN ); - - // path entry - GtkHBox* hbox = GTK_HBOX( gtk_hbox_new( FALSE, 0 ) ); - gtk_widget_show( GTK_WIDGET( hbox ) ); - - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_entry_set_has_frame( entry, FALSE ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( entry ), TRUE, TRUE, 0 ); - - // browse button - GtkButton* button = GTK_BUTTON( gtk_button_new() ); - button_set_icon( button, "ellipsis.png" ); - gtk_widget_show( GTK_WIDGET( button ) ); - gtk_box_pack_end( GTK_BOX( hbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( hbox ) ); - - return PathEntry( frame, entry, button ); -} - -void PathEntry_setPath( PathEntry& self, const char* path ){ - gtk_entry_set_text( self.m_entry, path ); -} -typedef ReferenceCaller1 PathEntrySetPathCaller; - -void BrowsedPathEntry_clicked( GtkWidget* widget, BrowsedPathEntry* self ){ - self->m_browse( PathEntrySetPathCaller( self->m_entry ) ); -} - -BrowsedPathEntry::BrowsedPathEntry( const BrowseCallback& browse ) : - m_entry( PathEntry_new() ), - m_browse( browse ){ - g_signal_connect( G_OBJECT( m_entry.m_button ), "clicked", G_CALLBACK( BrowsedPathEntry_clicked ), this ); + auto entry = new QLineEdit; + auto button = entry->addAction( QApplication::style()->standardIcon( QStyle::SP_FileDialogStart ), QLineEdit::ActionPosition::TrailingPosition ); + return PathEntry( entry, button ); } -GtkLabel* DialogLabel_new( const char* name ){ - GtkLabel* label = GTK_LABEL( gtk_label_new( name ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 ); - gtk_label_set_justify( label, GTK_JUSTIFY_LEFT ); - - return label; +void DialogGrid_packRow( QGridLayout* grid, QWidget* row, QLabel *label ){ + const int rowCount = grid->rowCount(); + grid->addWidget( row, rowCount, 1 ); + grid->addWidget( label, rowCount, 0, Qt::AlignmentFlag::AlignRight ); } -GtkTable* DialogRow_new( const char* name, GtkWidget* widget ){ - GtkTable* table = GTK_TABLE( gtk_table_new( 1, 3, TRUE ) ); - gtk_widget_show( GTK_WIDGET( table ) ); - - gtk_table_set_col_spacings( table, 4 ); - gtk_table_set_row_spacings( table, 0 ); - - gtk_table_attach( table, GTK_WIDGET( DialogLabel_new( name ) ), 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - gtk_table_attach( table, widget, 1, 3, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - return table; +void DialogGrid_packRow( QGridLayout* grid, QWidget* row, const char* name ){ + DialogGrid_packRow( grid, row, new QLabel( name ) ); } -void DialogVBox_packRow( GtkVBox* vbox, GtkWidget* row ){ - gtk_box_pack_start( GTK_BOX( vbox ), row, FALSE, FALSE, 0 ); +void DialogGrid_packRow( QGridLayout* grid, QLayout* row, QLabel *label ){ + const int rowCount = grid->rowCount(); + grid->addLayout( row, rowCount, 1 ); + grid->addWidget( label, rowCount, 0, Qt::AlignmentFlag::AlignRight ); +} + +void DialogGrid_packRow( QGridLayout* grid, QLayout* row, const char* name ){ + DialogGrid_packRow( grid, row, new QLabel( name ) ); } diff --git a/libs/gtkutil/dialog.h b/libs/gtkutil/dialog.h index d93e1e92..5794f103 100644 --- a/libs/gtkutil/dialog.h +++ b/libs/gtkutil/dialog.h @@ -21,59 +21,24 @@ #pragma once -#include "generic/callback.h" #include "generic/arrayrange.h" -#include "qerplugin.h" -#include +class QWidget; +class QGridLayout; +class QButtonGroup; +class QHBoxLayout; +class QAction; +class QLineEdit; +class QLayout; +class QLabel; -struct ModalDialog -{ - ModalDialog() - : loop( true ), ret( eIDCANCEL ){ - } - bool loop; - EMessageBoxReturn ret; -}; - -struct ModalDialogButton -{ - ModalDialogButton( ModalDialog& dialog, EMessageBoxReturn value ) - : m_dialog( dialog ), m_value( value ){ - } - ModalDialog& m_dialog; - EMessageBoxReturn m_value; -}; - -GtkWindow* create_fixedsize_modal_window( GtkWindow* parent, const char* title, int width, int height ); - -GtkWindow* create_dialog_window( GtkWindow* parent, const char* title, GCallback func, gpointer data, int default_w = -1, int default_h = -1 ); -GtkTable* create_dialog_table( unsigned int rows, unsigned int columns, unsigned int row_spacing, unsigned int col_spacing, int border = 0 ); -GtkButton* create_dialog_button( const char* label, GCallback func, gpointer data ); -GtkVBox* create_dialog_vbox( int spacing, int border = 0 ); -GtkHBox* create_dialog_hbox( int spacing, int border = 0 ); -GtkFrame* create_dialog_frame( const char* label, GtkShadowType shadow = GTK_SHADOW_ETCHED_IN ); - -GtkButton* create_modal_dialog_button( const char* label, ModalDialogButton& button ); -GtkWindow* create_modal_dialog_window( GtkWindow* parent, const char* title, ModalDialog& dialog, int default_w = -1, int default_h = -1 ); -GtkWindow* create_fixedsize_modal_dialog_window( GtkWindow* parent, const char* title, ModalDialog& dialog, int width = -1, int height = -1 ); -EMessageBoxReturn modal_dialog_show( GtkWindow* window, ModalDialog& dialog ); - - -gboolean dialog_button_ok( GtkWidget *widget, ModalDialog* data ); -gboolean dialog_button_cancel( GtkWidget *widget, ModalDialog* data ); -gboolean dialog_button_yes( GtkWidget *widget, ModalDialog* data ); -gboolean dialog_button_no( GtkWidget *widget, ModalDialog* data ); -gboolean dialog_delete_callback( GtkWidget *widget, GdkEventAny* event, ModalDialog* data ); - -GtkWindow* create_simple_modal_dialog_window( const char* title, ModalDialog& dialog, GtkWidget* contents ); class RadioHBox { public: - GtkHBox* m_hbox; - GtkRadioButton* m_radio; - RadioHBox( GtkHBox* hbox, GtkRadioButton* radio ) : + QHBoxLayout* m_hbox; + QButtonGroup* m_radio; + RadioHBox( QHBoxLayout* hbox, QButtonGroup* radio ) : m_hbox( hbox ), m_radio( radio ){ } @@ -85,11 +50,9 @@ RadioHBox RadioHBox_new( StringArrayRange names ); class PathEntry { public: - GtkFrame* m_frame; - GtkEntry* m_entry; - GtkButton* m_button; - PathEntry( GtkFrame* frame, GtkEntry* entry, GtkButton* button ) : - m_frame( frame ), + QLineEdit* m_entry; + QAction* m_button; + PathEntry( QLineEdit* entry, QAction* button ) : m_entry( entry ), m_button( button ){ } @@ -97,18 +60,7 @@ public: PathEntry PathEntry_new(); -class BrowsedPathEntry -{ -public: - typedef Callback1 SetPathCallback; - typedef Callback1 BrowseCallback; - - PathEntry m_entry; - BrowseCallback m_browse; - - BrowsedPathEntry( const BrowseCallback& browse ); -}; - -GtkLabel* DialogLabel_new( const char* name ); -GtkTable* DialogRow_new( const char* name, GtkWidget* widget ); -void DialogVBox_packRow( GtkVBox* vbox, GtkWidget* row ); +void DialogGrid_packRow( QGridLayout* grid, QWidget* row, QLabel *label ); +void DialogGrid_packRow( QGridLayout* grid, QWidget* row, const char* name ); +void DialogGrid_packRow( QGridLayout* grid, QLayout* row, QLabel *label ); +void DialogGrid_packRow( QGridLayout* grid, QLayout* row, const char* name ); \ No newline at end of file diff --git a/libs/gtkutil/entry.h b/libs/gtkutil/entry.h index 0ad82689..96699125 100644 --- a/libs/gtkutil/entry.h +++ b/libs/gtkutil/entry.h @@ -23,32 +23,24 @@ #include #include -#include +#include -inline void entry_set_string( GtkEntry* entry, const char* string ){ - gtk_entry_set_text( entry, string ); -} - -inline void entry_set_int( GtkEntry* entry, int i ){ +inline void entry_set_int( QLineEdit* entry, int i ){ char buf[32]; sprintf( buf, "%d", i ); - entry_set_string( entry, buf ); + entry->setText( buf ); } -inline void entry_set_float( GtkEntry* entry, float f ){ +inline void entry_set_float( QLineEdit* entry, float f ){ char buf[32]; sprintf( buf, "%g", f ); - entry_set_string( entry, buf ); + entry->setText( buf ); } -inline const char* entry_get_string( GtkEntry* entry ){ - return gtk_entry_get_text( entry ); +inline int entry_get_int( QLineEdit* entry ){ + return atoi( entry->text().toLatin1().constData() ); } -inline int entry_get_int( GtkEntry* entry ){ - return atoi( entry_get_string( entry ) ); -} - -inline double entry_get_float( GtkEntry* entry ){ - return atof( entry_get_string( entry ) ); +inline double entry_get_float( QLineEdit* entry ){ + return atof( entry->text().toLatin1().constData() ); } diff --git a/libs/gtkutil/fbo.h b/libs/gtkutil/fbo.h new file mode 100644 index 00000000..ea698902 --- /dev/null +++ b/libs/gtkutil/fbo.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2001-2006, William Joseph. + All Rights Reserved. + + This file is part of GtkRadiant. + + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include +#include "debugging/debugging.h" + +class FBO +{ + QOpenGLFramebufferObject *m_fbo{}; +public: + const int m_samples; + + FBO( int w, int h, bool hasDepth, int samples ) : m_samples( samples ) + { + ASSERT_MESSAGE( QOpenGLFramebufferObject::hasOpenGLFramebufferObjects(), "QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()" ); + ASSERT_MESSAGE( QOpenGLFramebufferObject::hasOpenGLFramebufferBlit(), "QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()" ); + + QOpenGLFramebufferObjectFormat format; + if( hasDepth ) + format.setAttachment( QOpenGLFramebufferObject::Attachment::Depth ); + format.setSamples( samples ); + m_fbo = new QOpenGLFramebufferObject( w, h, format ); + + ASSERT_MESSAGE( m_fbo->isValid(), "m_fbo->isValid()" ); + } + FBO( FBO&& ) noexcept = delete; + ~FBO(){ + delete m_fbo; + } + bool bind(){ + if( m_fbo->format().samples() ) + gl().glEnable( GL_MULTISAMPLE ); + else + gl().glDisable( GL_MULTISAMPLE ); + return m_fbo->bind(); + } + bool release(){ + return m_fbo->release(); + } + void blit(){ + QOpenGLFramebufferObject::blitFramebuffer( nullptr, m_fbo ); + } +}; diff --git a/libs/gtkutil/filechooser.cpp b/libs/gtkutil/filechooser.cpp index 79dacec4..a344046b 100644 --- a/libs/gtkutil/filechooser.cpp +++ b/libs/gtkutil/filechooser.cpp @@ -25,14 +25,11 @@ #include #include -#include +#include #include "string/string.h" #include "stream/stringstream.h" -#include "container/array.h" #include "os/path.h" -#include "os/file.h" - #include "messagebox.h" @@ -91,20 +88,20 @@ public: GTKMasks( const FileTypeList& types ) : m_types( types ){ m_masks.reserve( m_types.size() ); - for ( FileTypeList::const_iterator i = m_types.begin(); i != m_types.end(); ++i ) + for ( const auto& type : types ) { - std::size_t len = strlen( ( *i ).m_name.c_str() ) + strlen( ( *i ).m_pattern.c_str() ) + 3; + std::size_t len = strlen( type.m_name.c_str() ) + strlen( type.m_pattern.c_str() ) + 3; StringOutputStream buffer( len + 1 ); // length + null char - buffer << ( *i ).m_name << " <" << ( *i ).m_pattern << ">"; + buffer << type.m_name << " (" << type.m_pattern << ")"; m_masks.push_back( buffer.c_str() ); } m_filters.reserve( m_types.size() ); - for ( FileTypeList::const_iterator i = m_types.begin(); i != m_types.end(); ++i ) + for ( const auto& type : types ) { - m_filters.push_back( ( *i ).m_pattern ); + m_filters.push_back( type.m_pattern ); } } @@ -121,9 +118,9 @@ public: }; -static char g_file_dialog_file[1024]; +static QByteArray g_file_dialog_file; -const char* file_dialog_show( GtkWidget* parent, bool open, const char* title, const char* path, const char* pattern, bool want_load, bool want_import, bool want_save ){ +const char* file_dialog( QWidget* parent, bool open, const char* title, const char* path, const char* pattern, bool want_load, bool want_import, bool want_save ){ if ( pattern == 0 ) { pattern = "*"; } @@ -131,165 +128,58 @@ const char* file_dialog_show( GtkWidget* parent, bool open, const char* title, c FileTypeList typelist; GlobalFiletypes().getTypeList( pattern, &typelist, want_load, want_import, want_save ); - GTKMasks masks( typelist ); + const GTKMasks masks( typelist ); - if ( title == 0 ) { - title = open ? "Open File" : "Save File"; - } - - GtkWidget* dialog; - if ( open ) { - dialog = gtk_file_chooser_dialog_new( title, - GTK_WINDOW( parent ), - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL ); - } - else - { - dialog = gtk_file_chooser_dialog_new( title, - GTK_WINDOW( parent ), - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, - NULL ); - gtk_file_chooser_set_current_name( GTK_FILE_CHOOSER( dialog ), "unnamed" ); - } - - gtk_window_set_modal( GTK_WINDOW( dialog ), TRUE ); - gtk_window_set_position( GTK_WINDOW( dialog ), GTK_WIN_POS_CENTER_ON_PARENT ); - - // we expect an actual path below, if the path is 0 we might crash if ( path != 0 && !string_empty( path ) ) { ASSERT_MESSAGE( path_is_absolute( path ), "file_dialog_show: path not absolute: " << makeQuoted( path ) ); - - Array new_path( strlen( path ) + 1 ); - - // copy path, replacing dir separators as appropriate - Array::iterator w = new_path.begin(); - for ( const char* r = path; *r != '\0'; ++r ) - { - *w++ = ( *r == '/' ) ? G_DIR_SEPARATOR : *r; - } - // terminate string - *w = '\0'; - - if( file_is_directory( new_path.data() ) ){ // folder path - gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( dialog ), new_path.data() ); - } - else{ // file path - gtk_file_chooser_set_filename( GTK_FILE_CHOOSER( dialog ), new_path.data() ); - } } // we should add all important paths as shortcut folder... // gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(dialog), "/tmp/", NULL); + QString filter; + if ( open && masks.m_filters.size() > 1 ){ - GtkFileFilter* filter = gtk_file_filter_new(); - gtk_file_filter_set_name( filter, "All supported formats" ); - for ( std::size_t i = 0; i < masks.m_filters.size(); ++i ) + filter += "All supported formats ("; + for ( const auto& f : masks.m_filters ) { - gtk_file_filter_add_pattern( filter, masks.m_filters[i].c_str() ); + filter += ' '; + filter += f.c_str(); } - gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( dialog ), filter ); + filter += ")"; } - for ( std::size_t i = 0; i < masks.m_filters.size(); ++i ) + for ( const auto& mask : masks.m_masks ) { - GtkFileFilter* filter = gtk_file_filter_new(); - gtk_file_filter_add_pattern( filter, masks.m_filters[i].c_str() ); - gtk_file_filter_set_name( filter, masks.m_masks[i].c_str() ); - gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( dialog ), filter ); + if( !filter.isEmpty() ) + filter += ";;"; + filter += mask.c_str(); } + // this handles backslashes as input and returns forwardly slashed path + // input path may be either folder or file + // only existing file path may be chosen for open; overwriting is prompted on save + g_file_dialog_file = open + ? QFileDialog::getOpenFileName( parent, title, path, filter ).toLatin1() + : QFileDialog::getSaveFileName( parent, title, path, filter ).toLatin1(); - if ( gtk_dialog_run( GTK_DIALOG( dialog ) ) == GTK_RESPONSE_ACCEPT ) { - strcpy( g_file_dialog_file, gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( dialog ) ) ); - - if ( !string_equal( pattern, "*" ) ) { - const char* extension = path_get_extension( g_file_dialog_file ); /* anything may be entered via 'location' dialog field, thus try to be safe */ - if ( string_empty( extension ) ) { /* add an extension */ - filetype_t type; - GtkFileFilter* filter = gtk_file_chooser_get_filter( GTK_FILE_CHOOSER( dialog ) ); - if ( filter != 0 // no filter set? some file-chooser implementations may allow the user to set no filter, which we treat as 'all files' - && !string_equal( gtk_file_filter_get_name( filter ), "All supported formats" ) ) - type = masks.GetTypeForGTKMask( gtk_file_filter_get_name( filter ) ).m_type; - else - type = masks.GetTypeForGTKMask( ( *masks.m_masks.begin() ).c_str() ).m_type; - - strcat( g_file_dialog_file, type.pattern + 1 ); - } - else{ /* validate extension */ - bool valid = false; - for ( std::size_t i = 0; i < masks.m_filters.size(); ++i ) - if( string_length( masks.m_filters[i].c_str() ) >= 2 && extension_equal( extension, masks.m_filters[i].c_str() + 2 ) ) - valid = true; - if( !valid ){ - g_file_dialog_file[0] = '\0'; - globalErrorStream() << makeQuoted( extension ) << " is unsupported file type for requested operation\n"; - } - } - } - - // convert back to unix format - for ( char* w = g_file_dialog_file; *w != '\0'; w++ ) - { - if ( *w == '\\' ) { - *w = '/'; - } - } + /* validate extension: it is possible pick existing file, not respecting the filter... */ + if( !g_file_dialog_file.isEmpty() && !string_equal( pattern, "*" ) ){ + const char* extension = path_get_extension( g_file_dialog_file.constData() ); + if( !string_empty( extension ) ) + for( const auto& f : masks.m_filters ) + if( extension_equal( extension, path_get_extension( f.c_str() ) ) ) + goto extension_validated; + qt_MessageBox( parent, StringOutputStream( 256 )( makeQuoted( extension ), " is unsupported file type for requested operation\n" ), extension, EMessageBoxType::Error ); + g_file_dialog_file.clear(); } - else - { - g_file_dialog_file[0] = '\0'; - } - - gtk_widget_destroy( dialog ); +extension_validated: // don't return an empty filename - if ( g_file_dialog_file[0] == '\0' ) { - return NULL; - } - - return g_file_dialog_file; + return g_file_dialog_file.isEmpty() + ? nullptr + : g_file_dialog_file.constData(); } -char* dir_dialog( GtkWidget* parent, const char* title, const char* path ){ - GtkWidget* dialog = gtk_file_chooser_dialog_new( title, - GTK_WINDOW( parent ), - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL ); - - gtk_window_set_modal( GTK_WINDOW( dialog ), TRUE ); - gtk_window_set_position( GTK_WINDOW( dialog ), GTK_WIN_POS_CENTER_ON_PARENT ); - - if ( !string_empty( path ) ) { - gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( dialog ), path ); - } - - char* filename = 0; - if ( gtk_dialog_run( GTK_DIALOG( dialog ) ) == GTK_RESPONSE_ACCEPT ) { - filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( dialog ) ); - } - - gtk_widget_destroy( dialog ); - - return filename; -} - -const char* file_dialog( GtkWidget* parent, bool open, const char* title, const char* path, const char* pattern, bool want_load, bool want_import, bool want_save ){ - for (;; ) - { - const char* file = file_dialog_show( parent, open, title, path, pattern, want_load, want_import, want_save ); - - if ( open - || file == 0 - || !file_exists( file ) - || gtk_MessageBox( parent, "The file specified already exists.\nDo you want to replace it?", title, eMB_NOYES, eMB_ICONQUESTION ) == eIDYES ) { - return file; - } - } +QString dir_dialog( QWidget *parent, const QString& path ){ + return QFileDialog::getExistingDirectory( parent, {}, path ); } diff --git a/libs/gtkutil/filechooser.h b/libs/gtkutil/filechooser.h index 9c0bc9c8..a20183e5 100644 --- a/libs/gtkutil/filechooser.h +++ b/libs/gtkutil/filechooser.h @@ -22,14 +22,14 @@ #pragma once /// \file -/// GTK+ file-chooser dialogs. +/// Qt file-chooser dialogs. -typedef struct _GtkWidget GtkWidget; -const char* file_dialog( GtkWidget *parent, bool open, const char* title, const char* path = nullptr, const char* pattern = nullptr, bool want_load = false, bool want_import = false, bool want_save = false ); +#include + +const char* file_dialog( class QWidget *parent, bool open, const char* title, const char* path = nullptr, const char* pattern = nullptr, bool want_load = false, bool want_import = false, bool want_save = false ); /// \brief Prompts the user to browse for a directory. /// The prompt window will be transient to \p parent. /// The directory will initially default to \p path, which must be an absolute path. -/// The returned string is allocated with \c g_malloc and must be freed with \c g_free. -char* dir_dialog( GtkWidget *parent, const char* title = "Choose Directory", const char* path = "" ); +QString dir_dialog( class QWidget *parent, const QString& path = {} ); diff --git a/libs/gtkutil/frame.cpp b/libs/gtkutil/frame.cpp deleted file mode 100644 index 57d9cd21..00000000 --- a/libs/gtkutil/frame.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "frame.h" - -#include - -GtkFrame* create_framed_widget( GtkWidget* widget ){ - GtkFrame* frame = GTK_FRAME( gtk_frame_new( 0 ) ); - gtk_widget_show( GTK_WIDGET( frame ) ); - gtk_frame_set_shadow_type( frame, GTK_SHADOW_IN ); - gtk_container_add( GTK_CONTAINER( frame ), widget ); - gtk_widget_show( GTK_WIDGET( widget ) ); - return frame; -} diff --git a/libs/gtkutil/glfont.cpp b/libs/gtkutil/glfont.cpp index cded7574..8094063a 100644 --- a/libs/gtkutil/glfont.cpp +++ b/libs/gtkutil/glfont.cpp @@ -21,9 +21,11 @@ #include "glfont.h" #include "igl.h" - -#include -#include +#include +#include +#include +#include +#include "stream/stringstream.h" void gray_to_texture( const unsigned int x_max, const unsigned int y_max, const unsigned char *in, unsigned char *out, const unsigned char fontColorR, const unsigned char fontColorG, const unsigned char fontColorB ){ /* normal with shadow */ @@ -94,89 +96,81 @@ class GLFontCallList final : public GLFont { GLuint m_displayList; GLuint m_atlas; - int m_pixelHeight; - int m_pixelAscent; - int m_pixelDescent; - PangoFontMap *m_fontmap; - PangoContext *m_ft2_context; + QFont m_font; + QFontMetrics m_metrics; + const int m_pixelHeight; + const int m_pixelAscent; + const int m_pixelDescent; public: - GLFontCallList( GLuint displayList, GLuint atlas, int asc, int desc, int pixelHeight, PangoFontMap *fontmap, PangoContext *ft2_context ) : - m_displayList( displayList ), m_atlas( atlas ), m_pixelHeight( pixelHeight ), m_pixelAscent( asc ), m_pixelDescent( desc ), m_fontmap( fontmap ), m_ft2_context( ft2_context ){ + GLFontCallList( GLuint displayList, GLuint atlas, const QFont& font, const QFontMetrics& metrics ) : + m_displayList( displayList ), m_atlas( atlas ), m_font( font ), m_metrics( metrics ), + m_pixelHeight( m_metrics.height() ), m_pixelAscent( m_metrics.ascent() ), m_pixelDescent( m_metrics.descent() ){ } ~GLFontCallList(){ - glDeleteLists( m_displayList, 128 ); - glDeleteTextures( 1, &m_atlas ); - if( m_ft2_context ) - g_object_unref( G_OBJECT( m_ft2_context ) ); - if( m_fontmap ) - g_object_unref( G_OBJECT( m_fontmap ) ); + gl().glDeleteLists( m_displayList, 128 ); + gl().glDeleteTextures( 1, &m_atlas ); } void printString( const char *s ){ GLboolean rasterPosValid; - glGetBooleanv( GL_CURRENT_RASTER_POSITION_VALID, &rasterPosValid ); + gl().glGetBooleanv( GL_CURRENT_RASTER_POSITION_VALID, &rasterPosValid ); if( !rasterPosValid ) return; GLfloat rasterPos[4]; - glGetFloatv( GL_CURRENT_RASTER_POSITION, rasterPos ); + gl().glGetFloatv( GL_CURRENT_RASTER_POSITION, rasterPos ); GLint viewport[4]; - glGetIntegerv( GL_VIEWPORT, viewport ); - glMatrixMode( GL_PROJECTION ); - glPushMatrix(); - glLoadIdentity(); - glOrtho( viewport[0], viewport[2], viewport[1], viewport[3], -1, 1 ); + gl().glGetIntegerv( GL_VIEWPORT, viewport ); + gl().glMatrixMode( GL_PROJECTION ); + gl().glPushMatrix(); + gl().glLoadIdentity(); + gl().glOrtho( viewport[0], viewport[2], viewport[1], viewport[3], -1, 1 ); - glMatrixMode( GL_MODELVIEW ); - glPushMatrix(); - glLoadIdentity(); - glTranslatef( rasterPos[0], rasterPos[1], 0 ); + gl().glMatrixMode( GL_MODELVIEW ); + gl().glPushMatrix(); + gl().glLoadIdentity(); + gl().glTranslatef( rasterPos[0], rasterPos[1], 0 ); - glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_POLYGON_BIT ); - glDisable( GL_LIGHTING ); - glEnable( GL_TEXTURE_2D ); - glDisable( GL_DEPTH_TEST ); - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + gl().glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_POLYGON_BIT ); + gl().glDisable( GL_LIGHTING ); + gl().glEnable( GL_TEXTURE_2D ); + gl().glDisable( GL_DEPTH_TEST ); + gl().glEnable( GL_BLEND ); + gl().glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + gl().glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glBindTexture( GL_TEXTURE_2D, m_atlas ); - GlobalOpenGL().m_glListBase( m_displayList ); - GlobalOpenGL().m_glCallLists( GLsizei( strlen( s ) ), GL_UNSIGNED_BYTE, reinterpret_cast( s ) ); + gl().glBindTexture( GL_TEXTURE_2D, m_atlas ); + gl().glListBase( m_displayList ); + gl().glCallLists( GLsizei( strlen( s ) ), GL_UNSIGNED_BYTE, reinterpret_cast( s ) ); - glPopAttrib(); + gl().glPopAttrib(); - glMatrixMode( GL_PROJECTION ); - glPopMatrix(); - glMatrixMode( GL_MODELVIEW ); //! must leave GL_MODELVIEW mode, as renderer relies on this during Renderer.render() - glPopMatrix(); + gl().glMatrixMode( GL_PROJECTION ); + gl().glPopMatrix(); + gl().glMatrixMode( GL_MODELVIEW ); //! must leave GL_MODELVIEW mode, as renderer relies on this during Renderer.render() + gl().glPopMatrix(); } - void renderString( const char *s, const GLuint& tex, const unsigned char colour[3], unsigned int& wid, unsigned int& hei ){ - if( !m_ft2_context || m_pixelHeight == 0 ){ - wid = hei = 0; - return; - } + void renderString( const char *s, const GLuint& tex, const unsigned char colour[3], unsigned int& out_wid, unsigned int& out_hei ){ + // proper way would be using painter.metrics, however this requires it being active()... + // same for painter.boundingRect() + result is not correct wrt width for some reason + const QRect rect = m_metrics.boundingRect( s ); + unsigned int wid = rect.width(); + unsigned int hei = rect.height(); - PangoLayout *layout; - PangoRectangle log_rect; - FT_Bitmap bitmap; + if ( wid > 0 && hei > 0 ) { + QImage image( wid, hei, QImage::Format::Format_Alpha8 ); + image.fill( 0 ); + QPainter painter; + painter.begin( &image ); + painter.setFont( m_font ); + painter.drawText( 0, m_metrics.height() - m_metrics.descent(), s ); + painter.end(); - layout = pango_layout_new( m_ft2_context ); - pango_layout_set_width( layout, -1 ); // -1 no wrapping. All text on one line. - pango_layout_set_text( layout, s, -1 ); // -1 null-terminated string. - pango_layout_get_extents( layout, NULL, &log_rect ); - - if ( log_rect.width > 0 && log_rect.height > 0 ) { - hei = bitmap.rows = PANGO_PIXELS_CEIL( log_rect.height );//m_pixelAscent + m_pixelDescent; - wid = bitmap.width = PANGO_PIXELS_CEIL( log_rect.width ); -// globalOutputStream() << wid << " " << hei << " rendering\n"; - bitmap.pitch = bitmap.width; - unsigned char *boo = (unsigned char *) malloc( bitmap.rows * bitmap.width ); - memset( boo, 0, bitmap.rows * bitmap.width ); - bitmap.buffer = boo; - bitmap.num_grays = 0xff; - bitmap.pixel_mode = FT_PIXEL_MODE_GRAY; - pango_ft2_render_layout_subpixel( &bitmap, layout, -log_rect.x, 0 ); + // using image.constBits() is inconsistently buggy for some reason + unsigned char *boo = (unsigned char *) malloc( wid * hei ); + for( unsigned int w = 0; w < wid; ++w ) + for( unsigned int h = 0; h < hei; ++h ) + boo[wid * h + w] = qAlpha( image.pixel( w, h ) ); hei += 2; wid += 2; @@ -365,44 +359,46 @@ public: //Now we just setup some texture parameters. - glBindTexture( GL_TEXTURE_2D, tex ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + gl().glBindTexture( GL_TEXTURE_2D, tex ); + gl().glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl().glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); -// glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); +// gl().glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +// gl().glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); +// gl().glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); -// glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + gl().glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + gl().glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); +// gl().glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); //Here we actually create the texture itself - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, wid * 3, hei, + gl().glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, wid * 3, hei, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0 ); /* normal with shadow */ - gray_to_texture( wid, hei, bitmap.buffer, buf, colour[0], colour[1], colour[2] ); - glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, wid, hei, GL_BGRA, GL_UNSIGNED_BYTE, buf ); + gray_to_texture( wid, hei, boo, buf, colour[0], colour[1], colour[2] ); + gl().glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, wid, hei, GL_BGRA, GL_UNSIGNED_BYTE, buf ); memset( buf, 0x00, 4 * hei * wid ); /* yellow selected with shadow */ - gray_to_texture( wid, hei, bitmap.buffer, buf, 255, 255, 0 ); - glTexSubImage2D( GL_TEXTURE_2D, 0, wid, 0, wid, hei, GL_BGRA, GL_UNSIGNED_BYTE, buf ); + gray_to_texture( wid, hei, boo, buf, 255, 255, 0 ); + gl().glTexSubImage2D( GL_TEXTURE_2D, 0, wid, 0, wid, hei, GL_BGRA, GL_UNSIGNED_BYTE, buf ); memset( buf, 0x00, 4 * hei * wid ); /* orange childSelected with shadow */ - gray_to_texture( wid, hei, bitmap.buffer, buf, 255, 128, 0 ); - glTexSubImage2D( GL_TEXTURE_2D, 0, wid * 2, 0, wid, hei, GL_BGRA, GL_UNSIGNED_BYTE, buf ); + gray_to_texture( wid, hei, boo, buf, 255, 128, 0 ); + gl().glTexSubImage2D( GL_TEXTURE_2D, 0, wid * 2, 0, wid, hei, GL_BGRA, GL_UNSIGNED_BYTE, buf ); - glBindTexture( GL_TEXTURE_2D, 0 ); + gl().glBindTexture( GL_TEXTURE_2D, 0 ); free( buf ); free( boo ); + + out_wid = wid; + out_hei = hei; } - g_object_unref( G_OBJECT( layout ) ); } int getPixelAscent() const { return m_pixelAscent; @@ -463,7 +459,7 @@ GLFont *glfont_create( const char* font_string ){ * How many chars in the charset */ maxchars = 256 * lastrow + last; - font_list_base = glGenLists( maxchars + 1 ); + font_list_base = gl().glGenLists( maxchars + 1 ); if ( font_list_base == 0 ) { ERROR_MESSAGE( "couldn't create font" ); } @@ -492,7 +488,7 @@ GLFont *glfont_create( const char* font_string ){ #include GLFont *glfont_create( const char* font_string ){ - GLuint font_list_base = glGenLists( 256 ); + GLuint font_list_base = gl().glGenLists( 256 ); gint font_height = 0, font_ascent = 0, font_descent = 0; PangoFontDescription* font_desc = pango_font_description_from_string( font_string ); @@ -647,41 +643,41 @@ public: bitmap.pixel_mode = FT_PIXEL_MODE_GRAY; pango_ft2_render_layout_subpixel( &bitmap, layout, -log_rect.x, y_offset_bitmap_render_pango_units ); - GlobalOpenGL().m_glGetFloatv( GL_CURRENT_COLOR, color ); + gl().glGetFloatv( GL_CURRENT_COLOR, color ); // Save state. I didn't see any OpenGL push/pop operations for these. // Question: Is saving/restoring this state necessary? Being safe. - GlobalOpenGL().m_glGetIntegerv( GL_UNPACK_ALIGNMENT, &previous_unpack_alignment ); - previous_blend_enabled = GlobalOpenGL().m_glIsEnabled( GL_BLEND ); - GlobalOpenGL().m_glGetIntegerv( GL_BLEND_SRC, &previous_blend_func_src ); - GlobalOpenGL().m_glGetIntegerv( GL_BLEND_DST, &previous_blend_func_dst ); - GlobalOpenGL().m_glGetFloatv( GL_RED_BIAS, &previous_red_bias ); - GlobalOpenGL().m_glGetFloatv( GL_GREEN_BIAS, &previous_green_bias ); - GlobalOpenGL().m_glGetFloatv( GL_BLUE_BIAS, &previous_blue_bias ); - GlobalOpenGL().m_glGetFloatv( GL_ALPHA_SCALE, &previous_alpha_scale ); + gl().glGetIntegerv( GL_UNPACK_ALIGNMENT, &previous_unpack_alignment ); + previous_blend_enabled = gl().glIsEnabled( GL_BLEND ); + gl().glGetIntegerv( GL_BLEND_SRC, &previous_blend_func_src ); + gl().glGetIntegerv( GL_BLEND_DST, &previous_blend_func_dst ); + gl().glGetFloatv( GL_RED_BIAS, &previous_red_bias ); + gl().glGetFloatv( GL_GREEN_BIAS, &previous_green_bias ); + gl().glGetFloatv( GL_BLUE_BIAS, &previous_blue_bias ); + gl().glGetFloatv( GL_ALPHA_SCALE, &previous_alpha_scale ); - GlobalOpenGL().m_glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); - GlobalOpenGL().m_glEnable( GL_BLEND ); - GlobalOpenGL().m_glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - GlobalOpenGL().m_glPixelTransferf( GL_RED_BIAS, color[0] ); - GlobalOpenGL().m_glPixelTransferf( GL_GREEN_BIAS, color[1] ); - GlobalOpenGL().m_glPixelTransferf( GL_BLUE_BIAS, color[2] ); - GlobalOpenGL().m_glPixelTransferf( GL_ALPHA_SCALE, color[3] ); + gl().glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + gl().glEnable( GL_BLEND ); + gl().glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + gl().glPixelTransferf( GL_RED_BIAS, color[0] ); + gl().glPixelTransferf( GL_GREEN_BIAS, color[1] ); + gl().glPixelTransferf( GL_BLUE_BIAS, color[2] ); + gl().glPixelTransferf( GL_ALPHA_SCALE, color[3] ); - GlobalOpenGL().m_glDrawPixels( bitmap.width, bitmap.rows, + gl().glDrawPixels( bitmap.width, bitmap.rows, GL_ALPHA, GL_UNSIGNED_BYTE, begin_bitmap_buffer ); g_free( begin_bitmap_buffer ); // Restore state in reverse order of how we set it. - GlobalOpenGL().m_glPixelTransferf( GL_ALPHA_SCALE, previous_alpha_scale ); - GlobalOpenGL().m_glPixelTransferf( GL_BLUE_BIAS, previous_blue_bias ); - GlobalOpenGL().m_glPixelTransferf( GL_GREEN_BIAS, previous_green_bias ); - GlobalOpenGL().m_glPixelTransferf( GL_RED_BIAS, previous_red_bias ); - GlobalOpenGL().m_glBlendFunc( previous_blend_func_src, previous_blend_func_dst ); + gl().glPixelTransferf( GL_ALPHA_SCALE, previous_alpha_scale ); + gl().glPixelTransferf( GL_BLUE_BIAS, previous_blue_bias ); + gl().glPixelTransferf( GL_GREEN_BIAS, previous_green_bias ); + gl().glPixelTransferf( GL_RED_BIAS, previous_red_bias ); + gl().glBlendFunc( previous_blend_func_src, previous_blend_func_dst ); if ( !previous_blend_enabled ) { - GlobalOpenGL().m_glDisable( GL_BLEND ); + gl().glDisable( GL_BLEND ); } - GlobalOpenGL().m_glPixelStorei( GL_UNPACK_ALIGNMENT, previous_unpack_alignment ); + gl().glPixelStorei( GL_UNPACK_ALIGNMENT, previous_unpack_alignment ); } g_object_unref( G_OBJECT( layout ) ); @@ -704,180 +700,97 @@ GLFont *glfont_create( const char* font_string ){ #elif 1 -#include -#include -#include +GLFont *glfont_create( const char* family, int fontSize, const char* appPath ){ + GLuint font_list_base = gl().glGenLists( 128 ); -PangoFont* tryFont( const char* font_string, PangoFontMap *fontmap, PangoContext *context, PangoFontDescription*& font_desc ){ - pango_font_description_free( font_desc ); - font_desc = pango_font_description_from_string( font_string ); - return pango_font_map_load_font( fontmap, context, font_desc ); -} - -GLFont *glfont_create( const char* font_string ){ - GLuint font_list_base = glGenLists( 128 ); - int font_height = 0, font_ascent = 0, font_descent = 0; - PangoFontDescription* font_desc = 0; - PangoFont* font = 0; - - PangoFontMap *fontmap = pango_ft2_font_map_new(); - pango_ft2_font_map_set_resolution( PANGO_FT2_FONT_MAP( fontmap ), 72, 72 ); - PangoContext *ft2_context = pango_font_map_create_context( fontmap ); - - do + QFont font; + font.setPointSize( fontSize ); { - if( *font_string != '\0' ) - if( ( font = tryFont( font_string, fontmap, ft2_context, font_desc ) ) ) - break; -#ifdef WIN32 - if( ( font = tryFont( "arial 12", fontmap, ft2_context, font_desc ) ) ) - break; - if( ( font = tryFont( "fixed 12", fontmap, ft2_context, font_desc ) ) ) - break; - if( ( font = tryFont( "courier new 12", fontmap, ft2_context, font_desc ) ) ) - break; -#endif - GtkSettings *settings = gtk_settings_get_default(); - gchar *fontname; - g_object_get( settings, "gtk-font-name", &fontname, NULL ); - font = tryFont( fontname, fontmap, ft2_context, font_desc ); - g_free( fontname ); - - if( !font ){ - const char* guessFonts[] = { "serif 12", "sans 12", "clean 12", "courier 12", "helvetica 12", "arial 12", "dejavu sans 12" }; - for( const auto str : guessFonts ){ - if( ( font = tryFont( str, fontmap, ft2_context, font_desc ) ) ) - break; - } - } - } while ( 0 ); - - if ( font != 0 ) { - pango_context_set_font_description( ft2_context, font_desc ); - PangoLayout *layout = pango_layout_new( ft2_context ); - -#if 1 //FONT_SIZE_WORKAROUND - pango_layout_set_width( layout, -1 ); // -1 no wrapping. All text on one line. - pango_layout_set_text( layout, "_|The quick brown fox jumped over the lazy sleeping dog's back then sat on a tack.", -1 ); // -1 null-terminated string. -#endif - - int font_ascent_pango_units = pango_layout_get_baseline( layout ); - PangoRectangle log_rect; - pango_layout_get_extents( layout, NULL, &log_rect ); - g_object_unref( G_OBJECT( layout ) ); - int font_descent_pango_units = log_rect.height - font_ascent_pango_units; - -// globalOutputStream() << pango_font_description_get_family( font_desc ) << " " << pango_font_description_get_size( font_desc ) << "\n"; - -// g_object_unref( G_OBJECT( ft2_context ) ); -// g_object_unref( G_OBJECT( fontmap ) ); - - font_ascent = PANGO_PIXELS_CEIL( font_ascent_pango_units ); - font_descent = PANGO_PIXELS_CEIL( font_descent_pango_units ); - font_height = font_ascent + font_descent; + const int id = QFontDatabase::addApplicationFont( QString( appPath ) + "bitmaps/MyriadPro-Regular.ttf" ); + if( id >= 0 && string_equal( family, "Myriad Pro" ) ) + font.setFamily( QFontDatabase::applicationFontFamilies( id ).at( 0 ) ); + else if( !string_empty( family ) ) + font.setFamily( family ); } + globalOutputStream() << "Using OpenGL font " << makeQuoted( font.toString().toLatin1().constData() ) << '\n'; + + QFontMetrics metrics( font ); + /* render displaylists */ GLuint atlas; - if ( font != 0 ) { - PangoLayout *layout; - PangoRectangle log_rect; - FT_Bitmap bitmap; - - layout = pango_layout_new( ft2_context ); - pango_layout_set_width( layout, -1 ); // -1 no wrapping. All text on one line. - - GLint alignment; - glGetIntegerv( GL_UNPACK_ALIGNMENT, &alignment ); - glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); - - glGenTextures( 1, &atlas ); - //Now we just setup some texture parameters. - glBindTexture( GL_TEXTURE_2D, atlas ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0 ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0 ); - //Here we actually create the texture itself - void* empty = calloc( font_height * 12 * font_height * 12 * 2, sizeof( GLubyte ) ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, font_height * 12, font_height * 12, // riskily assuming, that height >= max width - 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, empty ); - free( empty ); - + { + const int wid = metrics.maxWidth(); // <-slow func + const int hei = metrics.height(); + const int awidth = wid * 12; + const int aheight = hei * 12; + QImage image( awidth, aheight, QImage::Format::Format_Alpha8 ); + image.fill( 0 ); + QPainter painter; + painter.begin( &image ); + painter.setFont( font ); for( unsigned char c = 0; c < 128; ++c ){ - pango_layout_set_text( layout, reinterpret_cast( &c ), 1 ); - pango_layout_get_extents( layout, NULL, &log_rect ); + const QRect rect = painter.boundingRect( QRect(), Qt::AlignmentFlag::AlignCenter, QString( c ) ); + painter.drawText( c % 12 * wid, ( c / 12 + 1 ) * hei - metrics.descent(), QString( c ) ); - if ( log_rect.width > 0 && log_rect.height > 0 - && PANGO_PIXELS_CEIL( log_rect.width ) <= font_height ) { // ensure, that height >= width - bitmap.rows = PANGO_PIXELS_CEIL( log_rect.height ); - bitmap.width = PANGO_PIXELS_CEIL( log_rect.width ); - bitmap.pitch = bitmap.width; - unsigned char *boo = (unsigned char *) malloc( bitmap.rows * bitmap.width ); - memset( boo, 0, bitmap.rows * bitmap.width ); - bitmap.buffer = boo; - bitmap.num_grays = 0xff; - bitmap.pixel_mode = FT_PIXEL_MODE_GRAY; - pango_ft2_render_layout_subpixel( &bitmap, layout, -log_rect.x, 0 ); - /* convert grayscale byte per pixel to two bytes per pixel (white + alpha) */ - unsigned char *buf = (unsigned char *) malloc( bitmap.rows * bitmap.width * 2 ); - for( unsigned int i = 0; i < bitmap.rows * bitmap.width; ++i ){ - buf[i * 2] = 255; - buf[i * 2 + 1] = boo[i]; - } - - glTexSubImage2D( GL_TEXTURE_2D, - 0, - c % 12 * font_height, - c / 12 * font_height, - bitmap.width, - bitmap.rows, - GL_LUMINANCE_ALPHA, - GL_UNSIGNED_BYTE, - buf ); - - glNewList( font_list_base + c, GL_COMPILE ); - glBegin( GL_QUADS ); + if ( rect.width() > 0 && rect.height() > 0 ) { + gl().glNewList( font_list_base + c, GL_COMPILE ); + gl().glBegin( GL_QUADS ); const float x0 = 0; - const float x1 = bitmap.width; + const float x1 = rect.width(); const float y0 = 0; - const float y1 = bitmap.rows; + const float y1 = rect.height(); const float tx0 = ( c % 12 ) / 12.f; - const float tx1 = ( c % 12 + static_cast( bitmap.width ) / font_height ) / 12.f; + const float tx1 = ( c % 12 + static_cast( rect.width() ) / wid ) / 12.f; const float ty0 = ( c / 12 ) / 12.f; - const float ty1 = ( c / 12 + static_cast( bitmap.rows ) / font_height ) / 12.f; - glTexCoord2f( tx0, ty1 ); - glVertex2f( x0, y0 ); - glTexCoord2f( tx0, ty0 ); - glVertex2f( x0, y1 ); - glTexCoord2f( tx1, ty0 ); - glVertex2f( x1, y1 ); - glTexCoord2f( tx1, ty1 ); - glVertex2f( x1, y0 ); - glEnd(); - glTranslatef( bitmap.width, 0, 0 ); - glEndList(); - - free( boo ); - free( buf ); + const float ty1 = ( c / 12 + static_cast( rect.height() ) / hei ) / 12.f; + gl().glTexCoord2f( tx0, ty1 ); + gl().glVertex2f( x0, y0 ); + gl().glTexCoord2f( tx0, ty0 ); + gl().glVertex2f( x0, y1 ); + gl().glTexCoord2f( tx1, ty0 ); + gl().glVertex2f( x1, y1 ); + gl().glTexCoord2f( tx1, ty1 ); + gl().glVertex2f( x1, y0 ); + gl().glEnd(); + gl().glTranslatef( metrics.horizontalAdvance( c ), 0, 0 ); + gl().glEndList(); } } + painter.end(); + // image.save( "radAtlas.png" ); - glPixelStorei( GL_UNPACK_ALIGNMENT, alignment ); + GLint alignment; + gl().glGetIntegerv( GL_UNPACK_ALIGNMENT, &alignment ); + gl().glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + + gl().glGenTextures( 1, &atlas ); + //Now we just setup some texture parameters. + gl().glBindTexture( GL_TEXTURE_2D, atlas ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0 ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0 ); + //Here we actually create the texture itself + GLubyte* data = (GLubyte*)calloc( awidth * aheight * 2, sizeof( GLubyte ) ); + for( int w = 0; w < awidth; ++w ) + for( int h = 0; h < aheight; ++h ){ + data[( h * awidth + w ) * 2] = 255; + data[( h * awidth + w ) * 2 + 1] = qAlpha( image.pixel( w, h ) ); + } + gl().glTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, awidth, aheight, + 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data ); + free( data ); + + gl().glPixelStorei( GL_UNPACK_ALIGNMENT, alignment ); GlobalOpenGL_debugAssertNoErrors(); - - g_object_unref( G_OBJECT( layout ) ); } - pango_font_description_free( font_desc ); - - ASSERT_MESSAGE( font != 0, "font for OpenGL rendering was not created" ); - - return new GLFontCallList( font_list_base, atlas, font_ascent, font_descent, font_height, fontmap, ft2_context ); + return new GLFontCallList( font_list_base, atlas, font, metrics ); } diff --git a/libs/gtkutil/glfont.h b/libs/gtkutil/glfont.h index e53cebfd..2f68061d 100644 --- a/libs/gtkutil/glfont.h +++ b/libs/gtkutil/glfont.h @@ -30,10 +30,10 @@ public: virtual int getPixelAscent() const = 0; virtual int getPixelDescent() const = 0; virtual void printString( const char *s ) = 0; - virtual void renderString( const char *s, const GLuint& tex, const unsigned char colour[3], unsigned int& wid, unsigned int& hei ) = 0; + virtual void renderString( const char *s, const GLuint& tex, const unsigned char colour[3], unsigned int& out_wid, unsigned int& out_hei ) = 0; virtual ~GLFont(){ } }; -GLFont *glfont_create( const char* font_string ); +GLFont *glfont_create( const char* family, int fontSize, const char* appPath ); // release with delete diff --git a/libs/gtkutil/glwidget.cpp b/libs/gtkutil/glwidget.cpp index 3012f6b2..8d611df1 100644 --- a/libs/gtkutil/glwidget.cpp +++ b/libs/gtkutil/glwidget.cpp @@ -27,231 +27,50 @@ #include "igl.h" -#include -#include - -#include "pointer.h" +#include +#include +#include void ( *GLWidget_sharedContextCreated )() = 0; void ( *GLWidget_sharedContextDestroyed )() = 0; - -typedef int* attribs_t; -struct config_t -{ - const char* name; - attribs_t attribs; -}; -typedef const config_t* configs_iterator; - -int config_rgba32[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 24, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 16, - GDK_GL_ATTRIB_LIST_NONE, -}; - -const config_t configs[] = { - { - "colour-buffer = 32bpp, depth-buffer = none", - config_rgba32, - }, - { - "colour-buffer = 16bpp, depth-buffer = none", - config_rgba, - } -}; - -GdkGLConfig* glconfig_new(){ - GdkGLConfig* glconfig = 0; - - for ( configs_iterator i = configs, end = configs + 2; i != end; ++i ) - { - glconfig = gdk_gl_config_new( ( *i ).attribs ); - if ( glconfig != 0 ) { - globalOutputStream() << "OpenGL window configuration: " << ( *i ).name << "\n"; - return glconfig; - } - } - - globalOutputStream() << "OpenGL window configuration: colour-buffer = auto, depth-buffer = none\n"; - return gdk_gl_config_new_by_mode( (GdkGLConfigMode)( GDK_GL_MODE_RGBA | GDK_GL_MODE_DOUBLE ) ); -} - -int config_rgba32_depth32[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 24, - GDK_GL_DEPTH_SIZE, 32, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba32_depth24[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 24, - GDK_GL_DEPTH_SIZE, 24, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba32_depth16[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 24, - GDK_GL_DEPTH_SIZE, 16, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba32_depth[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 24, - GDK_GL_DEPTH_SIZE, 1, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba_depth16[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 16, - GDK_GL_DEPTH_SIZE, 16, - GDK_GL_ATTRIB_LIST_NONE, -}; - -int config_rgba_depth[] = { - GDK_GL_RGBA, - GDK_GL_DOUBLEBUFFER, - GDK_GL_BUFFER_SIZE, 16, - GDK_GL_DEPTH_SIZE, 1, - GDK_GL_ATTRIB_LIST_NONE, -}; - -const config_t configs_with_depth[] = -{ - { - "colour-buffer = 32bpp, depth-buffer = 32bpp", - config_rgba32_depth32, - }, - { - "colour-buffer = 32bpp, depth-buffer = 24bpp", - config_rgba32_depth24, - }, - { - "colour-buffer = 32bpp, depth-buffer = 16bpp", - config_rgba32_depth16, - }, - { - "colour-buffer = 32bpp, depth-buffer = auto", - config_rgba32_depth, - }, - { - "colour-buffer = 16bpp, depth-buffer = 16bpp", - config_rgba_depth16, - }, - { - "colour-buffer = auto, depth-buffer = auto", - config_rgba_depth, - }, -}; - -GdkGLConfig* glconfig_new_with_depth(){ - GdkGLConfig* glconfig = 0; - - for ( configs_iterator i = configs_with_depth, end = configs_with_depth + 6; i != end; ++i ) - { - glconfig = gdk_gl_config_new( ( *i ).attribs ); - if ( glconfig != 0 ) { - globalOutputStream() << "OpenGL window configuration: " << ( *i ).name << "\n"; - return glconfig; - } - } - - globalOutputStream() << "OpenGL window configuration: colour-buffer = auto, depth-buffer = auto (fallback)\n"; - return gdk_gl_config_new_by_mode( (GdkGLConfigMode)( GDK_GL_MODE_RGBA | GDK_GL_MODE_DOUBLE | GDK_GL_MODE_DEPTH ) ); -} - unsigned int g_context_count = 0; -namespace -{ -GtkWidget* g_shared = 0; -} -gint glwidget_context_created( GtkWidget* widget, gpointer data ){ +void glwidget_context_created( QOpenGLWidget& widget ){ + globalOutputStream() << "OpenGL window configuration:" + << " version: " << widget.format().majorVersion() << '.' << widget.format().minorVersion() + << " RGBA: " << widget.format().redBufferSize() << widget.format().greenBufferSize() << widget.format().blueBufferSize() << widget.format().alphaBufferSize() + << " depth: " << widget.format().depthBufferSize() + << " swapInterval: " << widget.format().swapInterval() + << " samples: " << widget.format().samples() + << "\n"; + + ASSERT_MESSAGE( widget.isValid(), "failed to create OpenGL widget" ); + if ( ++g_context_count == 1 ) { - g_shared = widget; - g_object_ref( G_OBJECT( g_shared ) ); - - glwidget_make_current( g_shared ); + GlobalOpenGL().funcs = widget.context()->versionFunctions(); + ASSERT_MESSAGE( GlobalOpenGL().funcs, "failed to initializeOpenGLFunctions" ); GlobalOpenGL().contextValid = true; GLWidget_sharedContextCreated(); } - return FALSE; } -gint glwidget_context_destroyed( GtkWidget* widget, gpointer data ){ +void glwidget_context_destroyed(){ if ( --g_context_count == 0 ) { + GlobalOpenGL().funcs = nullptr; GlobalOpenGL().contextValid = false; GLWidget_sharedContextDestroyed(); - - g_object_unref( G_OBJECT( g_shared ) ); - g_shared = 0; } - return FALSE; } -gboolean glwidget_enable_gl( GtkWidget* widget, GtkWidget* widget2, gpointer data ){ - if ( widget2 == 0 && !gtk_widget_is_gl_capable( widget ) ) { - GdkGLConfig* glconfig = ( g_object_get_data( G_OBJECT( widget ), "zbuffer" ) ) ? glconfig_new_with_depth() : glconfig_new(); - ASSERT_MESSAGE( glconfig != 0, "failed to create OpenGL config" ); - - gtk_widget_set_gl_capability( widget, glconfig, g_shared != 0 ? gtk_widget_get_gl_context( g_shared ) : 0, TRUE, GDK_GL_RGBA_TYPE ); - - gtk_widget_realize( widget ); - if ( g_shared == 0 ) { - g_shared = widget; - } - - // free glconfig? - } - return FALSE; -} - -GtkWidget* glwidget_new( gboolean zbuffer ){ - GtkWidget* widget = gtk_drawing_area_new(); - - g_object_set_data( G_OBJECT( widget ), "zbuffer", gint_to_pointer( zbuffer ) ); - - g_signal_connect( G_OBJECT( widget ), "hierarchy-changed", G_CALLBACK( glwidget_enable_gl ), 0 ); - - g_signal_connect( G_OBJECT( widget ), "realize", G_CALLBACK( glwidget_context_created ), 0 ); - g_signal_connect( G_OBJECT( widget ), "unrealize", G_CALLBACK( glwidget_context_destroyed ), 0 ); - - return widget; -} - -void glwidget_destroy_context( GtkWidget *widget ){ -} - -void glwidget_create_context( GtkWidget *widget ){ -} - -void glwidget_swap_buffers( GtkWidget *widget ){ - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable( widget ); - gdk_gl_drawable_swap_buffers( gldrawable ); -} - -gboolean glwidget_make_current( GtkWidget *widget ){ - GdkGLContext *glcontext = gtk_widget_get_gl_context( widget ); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable( widget ); - return gdk_gl_drawable_gl_begin( gldrawable, glcontext ); -} +void glwidget_setDefaultFormat(){ + QCoreApplication::setAttribute( Qt::ApplicationAttribute::AA_ShareOpenGLContexts ); + QSurfaceFormat format; + format.setVersion( 2, 0 ); + format.setSwapInterval( 0 ); +// format.setSamples( 8 ); + QSurfaceFormat::setDefaultFormat( format ); +} \ No newline at end of file diff --git a/libs/gtkutil/glwidget.h b/libs/gtkutil/glwidget.h index 41f17923..ede72d38 100644 --- a/libs/gtkutil/glwidget.h +++ b/libs/gtkutil/glwidget.h @@ -21,15 +21,10 @@ #pragma once -typedef struct _GtkWidget GtkWidget; -typedef int gint; -typedef gint gboolean; -#define NV_DRIVER_GAMMA_BUG 1 //! todo remove as soon, as driver will be fixed -GtkWidget* glwidget_new( gboolean zbuffer ); -void glwidget_swap_buffers( GtkWidget* widget ); -gboolean glwidget_make_current( GtkWidget* widget ); -void glwidget_destroy_context( GtkWidget* widget ); -void glwidget_create_context( GtkWidget* widget ); +void glwidget_setDefaultFormat(); +void glwidget_context_created( class QOpenGLWidget& widget ); +void glwidget_context_destroyed(); + extern void ( *GLWidget_sharedContextCreated )(); extern void ( *GLWidget_sharedContextDestroyed )(); diff --git a/libs/gtkutil/guisettings.cpp b/libs/gtkutil/guisettings.cpp new file mode 100644 index 00000000..c37883fa --- /dev/null +++ b/libs/gtkutil/guisettings.cpp @@ -0,0 +1,137 @@ +/* + Copyright (C) 2001-2006, William Joseph. + All Rights Reserved. + + This file is part of GtkRadiant. + + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "guisettings.h" + +#include +#include +#include +#include +#include +#include + +class GuiSetting +{ +protected: + const char * const m_path; +private: + inline static std::optional m_qsettings{}; +public: + inline static QSettings& qsettings(){ + return m_qsettings.has_value() + ? m_qsettings.value() + : m_qsettings.emplace( QCoreApplication::organizationName(), QCoreApplication::applicationName() ); + } + GuiSetting( const char* path ) : m_path( path ){} + virtual ~GuiSetting() = default; + virtual void save() const = 0; +}; + +class WindowSetting : public GuiSetting, QObject +{ + QWidget * const m_window; + bool m_wantSave{}; +public: + WindowSetting( QWidget *window, const char *path, int w, int h, int x, int y ) : GuiSetting( path ), m_window( window ){ + if( const QByteArray geometry = qsettings().value( m_path, QByteArray() ).toByteArray(); !geometry.isEmpty() ){ + m_window->restoreGeometry( geometry ); + m_wantSave = true; + } + else{ + if( w > 0 && h > 0 ) + m_window->resize( w, h ); + if( x > 0 && y > 0 ){ + m_window->move( x, y ); + m_wantSave = true; + } + else{ + m_window->installEventFilter( this ); + if( m_window->isVisible() ) + m_wantSave = true; + } + } + } + void save() const override { + // w/o restoreGeometry() or move(): only save, if window has been shown, so default pos has been applied + if( m_wantSave ) + qsettings().setValue( m_path, m_window->saveGeometry() ); + } +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + // deal with the case w/o restoreGeometry() or move(): + // when window is closed via VM means (gui cross, alt+f4), pos is defaulted on next show() (np with hide() ) + if( event->type() == QEvent::Show || event->type() == QEvent::Close ) { + m_window->setAttribute( Qt::WidgetAttribute::WA_Moved ); + m_window->removeEventFilter( this ); + m_wantSave = true; // also track 'was shown' property + } + return QObject::eventFilter( obj, event ); // standard event processing + } +}; + +class MainWindowSetting : public GuiSetting +{ + QMainWindow * const m_window; +public: + MainWindowSetting( QMainWindow *window, const char *path ) : GuiSetting( path ), m_window( window ){ + if( const QByteArray state = qsettings().value( m_path, QByteArray() ).toByteArray(); !state.isEmpty() ) + m_window->restoreState( state ); + else + m_window->showMaximized(); + } + void save() const override { + qsettings().setValue( m_path, m_window->saveState() ); + } +}; + +class SplitterSetting : public GuiSetting +{ + QSplitter * const m_splitter; +public: + SplitterSetting( QSplitter *splitter, const char *path, const QList &sizes ) : GuiSetting( path ), m_splitter( splitter ){ + if( const QByteArray state = qsettings().value( m_path, QByteArray() ).toByteArray(); !state.isEmpty() ) + m_splitter->restoreState( state ); + else + m_splitter->setSizes( sizes ); + } + void save() const override { + qsettings().setValue( m_path, m_splitter->saveState() ); + } +}; + + +GuiSettings::~GuiSettings(){ + for( auto setting : m_settings ) + delete setting; +} +void GuiSettings::save(){ + for( const auto setting : m_settings ) + setting->save(); +} +void GuiSettings::addWindow( QWidget *window, const char *path, int w /* = 0 */, int h /* = 0 */, int x /* = 0 */, int y /* = 0 */ ){ + m_settings.push_back( new WindowSetting( window, path, w, h, x, y ) ); +} +void GuiSettings::addMainWindow( QMainWindow *window, const char *path ){ + m_settings.push_back( new MainWindowSetting( window, path ) ); +} +void GuiSettings::addSplitter( QSplitter *splitter, const char *path, const QList &sizes ){ + m_settings.push_back( new SplitterSetting( splitter, path, sizes ) ); +} diff --git a/radiant/multimon.h b/libs/gtkutil/guisettings.h similarity index 50% rename from radiant/multimon.h rename to libs/gtkutil/guisettings.h index 0bc4ef19..9f5fe320 100644 --- a/radiant/multimon.h +++ b/libs/gtkutil/guisettings.h @@ -21,27 +21,24 @@ #pragma once -struct WindowPosition; +#include +#include -void PositionWindowOnPrimaryScreen( WindowPosition& position ); - -struct multimon_globals_t +/// @brief Controls default/save/restore gui settings. +/// Path strings must be unique and presumably string literals, since they aren't stored. +/// Widget pointers must stay valid till save(). +/// QCoreApplication::organizationName(), QCoreApplication::applicationName() must be set before first use. +/// \todo //. ?use QPointer for sanity +class GuiSettings { - bool m_bStartOnPrimMon; - - multimon_globals_t() : - m_bStartOnPrimMon( false ){ - } + std::vector m_settings; +public: + ~GuiSettings(); + void save(); + // zeros are meant to use defaults + void addWindow( class QWidget *window, const char *path, int w = 0, int h = 0, int x = 0, int y = 0 ); + void addMainWindow( class QMainWindow *window, const char *path ); + void addSplitter( class QSplitter *splitter, const char *path, const QList &sizes ); }; -extern multimon_globals_t g_multimon_globals; - -#if defined( WIN32 ) -void MultiMon_Construct(); -void MultiMon_Destroy(); -#else -inline void MultiMon_Construct(){ -} -inline void MultiMon_Destroy(){ -} -#endif +inline GuiSettings g_guiSettings; diff --git a/libs/gtkutil/idledraw.h b/libs/gtkutil/idledraw.h index e3c79681..a593f820 100644 --- a/libs/gtkutil/idledraw.h +++ b/libs/gtkutil/idledraw.h @@ -21,37 +21,29 @@ #pragma once -#include - #include "generic/callback.h" +#include + class IdleDraw { Callback m_draw; - unsigned int m_handler; - static gboolean draw( gpointer data ){ - reinterpret_cast( data )->m_draw(); - reinterpret_cast( data )->m_handler = 0; - return FALSE; - } + QTimer m_timer; public: - IdleDraw( const Callback& draw ) : m_draw( draw ), m_handler( 0 ){ - } - ~IdleDraw(){ - if ( m_handler != 0 ) { - g_source_remove( m_handler ); - } + IdleDraw( const Callback& draw ) : m_draw( draw ){ + m_timer.setSingleShot( true ); + m_timer.callOnTimeout( m_draw ); } void queueDraw(){ - if ( m_handler == 0 ) { - m_handler = g_idle_add( &draw, this ); - } + if( !m_timer.isActive() ) + m_timer.start(); } typedef MemberCaller QueueDrawCaller; void flush(){ - if ( m_handler != 0 ) { - draw( this ); + if ( m_timer.isActive() ) { + m_timer.stop(); + m_draw(); } } }; diff --git a/libs/gtkutil/image.cpp b/libs/gtkutil/image.cpp index e4122c84..add7423d 100644 --- a/libs/gtkutil/image.cpp +++ b/libs/gtkutil/image.cpp @@ -21,8 +21,6 @@ #include "image.h" -#include - #include "string/string.h" #include "stream/stringstream.h" #include "stream/textstream.h" @@ -37,46 +35,12 @@ void BitmapsPath_set( const char* path ){ g_bitmapsPath = path; } -GdkPixbuf* pixbuf_new_from_file_with_mask( const char* filename ){ - GError *error = nullptr; - GdkPixbuf* rgba = gdk_pixbuf_new_from_file( filename, &error ); - if ( rgba == 0 ) { - globalErrorStream() << "ERROR: gdk_pixbuf_new_from_file(): " << error->message << "\n"; - g_error_free( error ); - } - return rgba; +QPixmap new_local_image( const char* filename ){ + const auto fullPath = StringOutputStream( 256 )( g_bitmapsPath, filename ); + return QPixmap( QString( fullPath.c_str() ) ); } -GtkImage* image_new_from_file_with_mask( const char* filename ){ - GdkPixbuf* rgba = pixbuf_new_from_file_with_mask( filename ); - if ( rgba == 0 ) { - return 0; - } - else - { - GtkImage* image = GTK_IMAGE( gtk_image_new_from_pixbuf( rgba ) ); - g_object_unref( rgba ); - return image; - } -} - -GtkImage* image_new_missing(){ - return GTK_IMAGE( gtk_image_new_from_stock( GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_SMALL_TOOLBAR ) ); -} - -GtkImage* new_image( const char* filename ){ - { - GtkImage* image = image_new_from_file_with_mask( filename ); - if ( image != 0 ) { - return image; - } - } - - return image_new_missing(); -} - -GtkImage* new_local_image( const char* filename ){ - StringOutputStream fullPath( 256 ); - fullPath << g_bitmapsPath << filename; - return new_image( fullPath ); +QIcon new_local_icon( const char* filename ){ + const auto fullPath = StringOutputStream( 256 )( g_bitmapsPath, filename ); + return QIcon( fullPath.c_str() ); } diff --git a/libs/gtkutil/image.h b/libs/gtkutil/image.h index 2da5319d..c70e0710 100644 --- a/libs/gtkutil/image.h +++ b/libs/gtkutil/image.h @@ -23,11 +23,7 @@ void BitmapsPath_set( const char* path ); -typedef struct _GtkImage GtkImage; -typedef struct _GdkPixbuf GdkPixbuf; - -GdkPixbuf* pixbuf_new_from_file_with_mask( const char* filename ); -GtkImage* image_new_from_file_with_mask( const char* filename ); -GtkImage* image_new_missing(); -GtkImage* new_image( const char* filename ); // filename is full path to image file -GtkImage* new_local_image( const char* filename ); // filename is relative to local bitmaps path +#include +#include +QPixmap new_local_image( const char* filename ); // filename is relative to local bitmaps path +QIcon new_local_icon( const char* filename ); // filename is relative to local bitmaps path diff --git a/libs/gtkutil/menu.cpp b/libs/gtkutil/menu.cpp index b0258523..d4eafbe7 100644 --- a/libs/gtkutil/menu.cpp +++ b/libs/gtkutil/menu.cpp @@ -21,246 +21,18 @@ #include "menu.h" -#include -#include - #include "generic/callback.h" #include "accelerator.h" -#include "closure.h" -#include "container.h" -#include "pointer.h" -void menu_add_item( GtkMenu* menu, GtkMenuItem* item ){ - gtk_container_add( GTK_CONTAINER( menu ), GTK_WIDGET( item ) ); + +QAction* create_menu_item_with_mnemonic( QMenu* menu, const char *mnemonic, const Callback& callback ){ + return menu->addAction( mnemonic, callback ); } -GtkMenuItem* menu_separator( GtkMenu* menu ){ - GtkMenuItem* menu_item = GTK_MENU_ITEM( gtk_menu_item_new() ); - container_add_widget( GTK_CONTAINER( menu ), GTK_WIDGET( menu_item ) ); - gtk_widget_set_sensitive( GTK_WIDGET( menu_item ), FALSE ); - gtk_widget_show( GTK_WIDGET( menu_item ) ); - return menu_item; -} - -GtkTearoffMenuItem* menu_tearoff( GtkMenu* menu ){ - GtkTearoffMenuItem* menu_item = GTK_TEAROFF_MENU_ITEM( gtk_tearoff_menu_item_new() ); - container_add_widget( GTK_CONTAINER( menu ), GTK_WIDGET( menu_item ) ); -// gtk_widget_set_sensitive(GTK_WIDGET(menu_item), FALSE); -- controls whether menu is detachable - gtk_widget_show( GTK_WIDGET( menu_item ) ); - return menu_item; -} - -GtkMenuItem* new_sub_menu_item_with_mnemonic( const char* mnemonic ){ - GtkMenuItem* item = GTK_MENU_ITEM( gtk_menu_item_new_with_mnemonic( mnemonic ) ); - gtk_widget_show( GTK_WIDGET( item ) ); - - GtkWidget* sub_menu = gtk_menu_new(); - gtk_menu_item_set_submenu( item, sub_menu ); - +QAction* create_check_menu_item_with_mnemonic( QMenu* menu, const char* mnemonic, const Callback& callback ){ + QAction *item = menu->addAction( mnemonic, callback ); + item->setCheckable( true ); return item; } -GtkMenu* create_sub_menu_with_mnemonic( GtkMenuShell* parent, const char* mnemonic ){ - GtkMenuItem* item = new_sub_menu_item_with_mnemonic( mnemonic ); - container_add_widget( GTK_CONTAINER( parent ), GTK_WIDGET( item ) ); - return GTK_MENU( gtk_menu_item_get_submenu( item ) ); -} - -GtkMenu* create_sub_menu_with_mnemonic( GtkMenuBar* bar, const char* mnemonic ){ - return create_sub_menu_with_mnemonic( GTK_MENU_SHELL( bar ), mnemonic ); -} - -GtkMenu* create_sub_menu_with_mnemonic( GtkMenu* parent, const char* mnemonic ){ - return create_sub_menu_with_mnemonic( GTK_MENU_SHELL( parent ), mnemonic ); -} - -void activate_closure_callback( GtkWidget* widget, gpointer data ){ - ( *reinterpret_cast( data ) )( ); -} - -guint menu_item_connect_callback( GtkMenuItem* item, const Callback& callback ){ -#if 1 - return g_signal_connect_swapped( G_OBJECT( item ), "activate", G_CALLBACK( callback.getThunk() ), callback.getEnvironment() ); -#else - return g_signal_connect_closure( G_OBJECT( item ), "activate", create_cclosure( G_CALLBACK( activate_closure_callback ), callback ), FALSE ); -#endif -} - -guint check_menu_item_connect_callback( GtkCheckMenuItem* item, const Callback& callback ){ -#if 1 - guint handler = g_signal_connect_swapped( G_OBJECT( item ), "toggled", G_CALLBACK( callback.getThunk() ), callback.getEnvironment() ); -#else - guint handler = g_signal_connect_closure( G_OBJECT( item ), "toggled", create_cclosure( G_CALLBACK( activate_closure_callback ), callback ), TRUE ); -#endif - g_object_set_data( G_OBJECT( item ), "handler", gint_to_pointer( handler ) ); - return handler; -} - -GtkMenuItem* new_menu_item_with_mnemonic( const char *mnemonic, const Callback& callback ){ - GtkMenuItem* item = GTK_MENU_ITEM( gtk_menu_item_new_with_mnemonic( mnemonic ) ); - gtk_widget_show( GTK_WIDGET( item ) ); - menu_item_connect_callback( item, callback ); - return item; -} - -GtkMenuItem* create_menu_item_with_mnemonic( GtkMenu* menu, const char *mnemonic, const Callback& callback ){ - GtkMenuItem* item = new_menu_item_with_mnemonic( mnemonic, callback ); - container_add_widget( GTK_CONTAINER( menu ), GTK_WIDGET( item ) ); - return item; -} - -GtkCheckMenuItem* new_check_menu_item_with_mnemonic( const char* mnemonic, const Callback& callback ){ - GtkCheckMenuItem* item = GTK_CHECK_MENU_ITEM( gtk_check_menu_item_new_with_mnemonic( mnemonic ) ); - gtk_widget_show( GTK_WIDGET( item ) ); - check_menu_item_connect_callback( item, callback ); - return item; -} - -GtkCheckMenuItem* create_check_menu_item_with_mnemonic( GtkMenu* menu, const char* mnemonic, const Callback& callback ){ - GtkCheckMenuItem* item = new_check_menu_item_with_mnemonic( mnemonic, callback ); - container_add_widget( GTK_CONTAINER( menu ), GTK_WIDGET( item ) ); - return item; -} - -GtkRadioMenuItem* new_radio_menu_item_with_mnemonic( GSList** group, const char* mnemonic, const Callback& callback ){ - GtkRadioMenuItem* item = GTK_RADIO_MENU_ITEM( gtk_radio_menu_item_new_with_mnemonic( *group, mnemonic ) ); - if ( *group == 0 ) { - gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( item ), TRUE ); - } - *group = gtk_radio_menu_item_get_group( item ); - gtk_widget_show( GTK_WIDGET( item ) ); - check_menu_item_connect_callback( GTK_CHECK_MENU_ITEM( item ), callback ); - return item; -} - -GtkRadioMenuItem* create_radio_menu_item_with_mnemonic( GtkMenu* menu, GSList** group, const char* mnemonic, const Callback& callback ){ - GtkRadioMenuItem* item = new_radio_menu_item_with_mnemonic( group, mnemonic, callback ); - container_add_widget( GTK_CONTAINER( menu ), GTK_WIDGET( item ) ); - return item; -} - -void check_menu_item_set_active_no_signal( GtkCheckMenuItem* item, gboolean active ){ - guint handler_id = gpointer_to_int( g_object_get_data( G_OBJECT( item ), "handler" ) ); - g_signal_handler_block( G_OBJECT( item ), handler_id ); - gtk_check_menu_item_set_active( item, active ); - g_signal_handler_unblock( G_OBJECT( item ), handler_id ); -} - - - -void radio_menu_item_set_active_no_signal( GtkRadioMenuItem* item, gboolean active ){ - { - for ( GSList* l = gtk_radio_menu_item_get_group( item ); l != 0; l = g_slist_next( l ) ) - { - g_signal_handler_block( G_OBJECT( l->data ), gpointer_to_int( g_object_get_data( G_OBJECT( l->data ), "handler" ) ) ); - } - } - gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( item ), active ); - { - for ( GSList* l = gtk_radio_menu_item_get_group( item ); l != 0; l = g_slist_next( l ) ) - { - g_signal_handler_unblock( G_OBJECT( l->data ), gpointer_to_int( g_object_get_data( G_OBJECT( l->data ), "handler" ) ) ); - } - } -} - - -void menu_item_set_accelerator( GtkMenuItem* item, GClosure* closure ){ - GtkAccelLabel* accel_label = GTK_ACCEL_LABEL( gtk_bin_get_child( GTK_BIN( item ) ) ); - gtk_accel_label_set_accel_closure( accel_label, closure ); -} - -void accelerator_name( const Accelerator& accelerator, GString* gstring ){ - gboolean had_mod = FALSE; - if ( accelerator.modifiers & GDK_SHIFT_MASK ) { - g_string_append( gstring, "Shift" ); - had_mod = TRUE; - } - if ( accelerator.modifiers & GDK_CONTROL_MASK ) { - if ( had_mod ) { - g_string_append( gstring, "+" ); - } - g_string_append( gstring, "Ctrl" ); - had_mod = TRUE; - } - if ( accelerator.modifiers & GDK_MOD1_MASK ) { - if ( had_mod ) { - g_string_append( gstring, "+" ); - } - g_string_append( gstring, "Alt" ); - had_mod = TRUE; - } - - if ( had_mod ) { - g_string_append( gstring, "+" ); - } - if ( accelerator.key < 0x80 || ( accelerator.key > 0x80 && accelerator.key <= 0xff ) ) { - switch ( accelerator.key ) - { - case ' ': - g_string_append( gstring, "Space" ); - break; - case '\\': - g_string_append( gstring, "Backslash" ); - break; - default: - g_string_append_c( gstring, gchar( toupper( accelerator.key ) ) ); - break; - } - } - else - { - gchar *tmp; - - tmp = gtk_accelerator_name( accelerator.key, (GdkModifierType)0 ); - if ( tmp[0] != 0 && tmp[1] == 0 ) { - tmp[0] = gchar( toupper( tmp[0] ) ); - } - g_string_append( gstring, tmp ); - g_free( tmp ); - } -} - -void menu_item_set_accelerator( GtkMenuItem* item, Accelerator accelerator ){ - GString* gstring = g_string_new( nullptr ); - g_string_append( gstring, " " ); - accelerator_name( accelerator, gstring ); - - GtkAccelLabel* accel_label = GTK_ACCEL_LABEL( gtk_bin_get_child( GTK_BIN( item ) ) ); - g_free( accel_label->accel_string ); - accel_label->accel_string = g_string_free( gstring, FALSE ); - - gtk_widget_queue_resize( GTK_WIDGET( accel_label ) ); -} - -void menu_item_add_accelerator( GtkMenuItem* item, Accelerator accelerator ){ - if ( accelerator.key != 0 ) { - GClosure* closure = global_accel_group_find( accelerator ); - if ( closure != 0 ) { - menu_item_set_accelerator( item, closure ); - } - else - { - menu_item_set_accelerator( item, accelerator ); - } - } -} - -GtkMenuItem* create_menu_item_with_mnemonic( GtkMenu* menu, const char* mnemonic, const Command& command ){ - GtkMenuItem* item = create_menu_item_with_mnemonic( menu, mnemonic, command.m_callback ); - menu_item_add_accelerator( item, command.m_accelerator ); - return item; -} - -void check_menu_item_set_active_callback( GtkCheckMenuItem& item, bool enabled ){ - check_menu_item_set_active_no_signal( &item, enabled ); -} -typedef ReferenceCaller1 CheckMenuItemSetActiveCaller; - -GtkCheckMenuItem* create_check_menu_item_with_mnemonic( GtkMenu* menu, const char* mnemonic, const Toggle& toggle ){ - GtkCheckMenuItem* item = create_check_menu_item_with_mnemonic( menu, mnemonic, toggle.m_command.m_callback ); - menu_item_add_accelerator( GTK_MENU_ITEM( item ), toggle.m_command.m_accelerator ); - toggle.m_exportCallback( CheckMenuItemSetActiveCaller( *item ) ); - return item; -} diff --git a/libs/gtkutil/menu.h b/libs/gtkutil/menu.h index 9ee0e2b2..69635cfb 100644 --- a/libs/gtkutil/menu.h +++ b/libs/gtkutil/menu.h @@ -23,33 +23,7 @@ #include "generic/callbackfwd.h" -typedef int gint; -typedef gint gboolean; -typedef struct _GSList GSList; -typedef struct _GtkMenu GtkMenu; -typedef struct _GtkMenuBar GtkMenuBar; -typedef struct _GtkMenuItem GtkMenuItem; -typedef struct _GtkCheckMenuItem GtkCheckMenuItem; -typedef struct _GtkRadioMenuItem GtkRadioMenuItem; -typedef struct _GtkTearoffMenuItem GtkTearoffMenuItem; +#include -void menu_add_item( GtkMenu* menu, GtkMenuItem* item ); -GtkMenuItem* menu_separator( GtkMenu* menu ); -GtkTearoffMenuItem* menu_tearoff( GtkMenu* menu ); -GtkMenuItem* new_sub_menu_item_with_mnemonic( const char* mnemonic ); -GtkMenu* create_sub_menu_with_mnemonic( GtkMenuBar* bar, const char* mnemonic ); -GtkMenu* create_sub_menu_with_mnemonic( GtkMenu* parent, const char* mnemonic ); -GtkMenuItem* create_menu_item_with_mnemonic( GtkMenu* menu, const char* mnemonic, const Callback& callback ); -GtkCheckMenuItem* create_check_menu_item_with_mnemonic( GtkMenu* menu, const char* mnemonic, const Callback& callback ); -GtkRadioMenuItem* create_radio_menu_item_with_mnemonic( GtkMenu* menu, GSList** group, const char* mnemonic, const Callback& callback ); - -class Command; -GtkMenuItem* create_menu_item_with_mnemonic( GtkMenu* menu, const char* mnemonic, const Command& command ); -class Toggle; -GtkCheckMenuItem* create_check_menu_item_with_mnemonic( GtkMenu* menu, const char* mnemonic, const Toggle& toggle ); - - -typedef struct _GtkCheckMenuItem GtkCheckMenuItem; -void check_menu_item_set_active_no_signal( GtkCheckMenuItem* item, gboolean active ); -typedef struct _GtkRadioMenuItem GtkRadioMenuItem; -void radio_menu_item_set_active_no_signal( GtkRadioMenuItem* item, gboolean active ); +QAction* create_menu_item_with_mnemonic( QMenu* menu, const char *mnemonic, const Callback& callback ); +QAction* create_check_menu_item_with_mnemonic( QMenu* menu, const char* mnemonic, const Callback& callback ); diff --git a/libs/gtkutil/messagebox.cpp b/libs/gtkutil/messagebox.cpp index 350e1dd4..c1729503 100644 --- a/libs/gtkutil/messagebox.cpp +++ b/libs/gtkutil/messagebox.cpp @@ -20,177 +20,52 @@ */ #include "messagebox.h" +#include -#include -#include -#include "dialog.h" -#include "widget.h" - -GtkWidget* create_padding( int width, int height ){ - GtkWidget* widget = gtk_alignment_new( 0.0, 0.0, 0.0, 0.0 ); - gtk_widget_show( widget ); - gtk_widget_set_size_request( widget, width, height ); - return widget; +inline QMessageBox::StandardButtons qt_buttons_for_mask( int buttons ){ + QMessageBox::StandardButtons out; + if( buttons & eIDOK ) + out |= QMessageBox::StandardButton::Ok; + if( buttons & eIDCANCEL ) + out |= QMessageBox::StandardButton::Cancel; + if( buttons & eIDYES ) + out |= QMessageBox::StandardButton::Yes; + if( buttons & eIDNO ) + out |= QMessageBox::StandardButton::No; + return out; } -const char* messagebox_stock_icon( EMessageBoxIcon type ){ +EMessageBoxReturn qt_MessageBox( QWidget *parent, const char* text, const char* title /* = "NetRadiant" */, EMessageBoxType type /* = EMessageBoxType::Info */, int buttons /* = 0 */ ){ + QMessageBox::StandardButton ret{}; switch ( type ) { - default: - case eMB_ICONDEFAULT: - return GTK_STOCK_DIALOG_INFO; - case eMB_ICONERROR: - return GTK_STOCK_DIALOG_ERROR; - case eMB_ICONWARNING: - return GTK_STOCK_DIALOG_WARNING; - case eMB_ICONQUESTION: - return GTK_STOCK_DIALOG_QUESTION; - case eMB_ICONASTERISK: - return GTK_STOCK_DIALOG_INFO; - } -} - -EMessageBoxReturn gtk_MessageBox( GtkWidget *parent, const char* text, const char* title, EMessageBoxType type, EMessageBoxIcon icon ){ - ModalDialog dialog; - ModalDialogButton ok_button( dialog, eIDOK ); - ModalDialogButton cancel_button( dialog, eIDCANCEL ); - ModalDialogButton yes_button( dialog, eIDYES ); - ModalDialogButton no_button( dialog, eIDNO ); - - GtkWindow* parentWindow = parent != 0 ? GTK_WINDOW( parent ) : 0; - - GtkWindow* window = create_fixedsize_modal_dialog_window( parentWindow, title, dialog, 400, 100 ); - - if ( parentWindow != 0 ) { - //g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(floating_window_delete_present), parent); - gtk_window_deiconify( parentWindow ); + case EMessageBoxType::Info: + ret = QMessageBox::information( parent, title, text, buttons? qt_buttons_for_mask( buttons ) : QMessageBox::StandardButton::Ok ); + break; + case EMessageBoxType::Question: + ret = QMessageBox::question( parent, title, text, buttons? qt_buttons_for_mask( buttons ) : QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No ); + break; + case EMessageBoxType::Warning: + ret = QMessageBox::warning( parent, title, text, buttons? qt_buttons_for_mask( buttons ) : QMessageBox::StandardButton::Ok ); + break; + case EMessageBoxType::Error: + ret = QMessageBox::critical( parent, title, text, buttons? qt_buttons_for_mask( buttons ) : QMessageBox::StandardButton::Ok ); + break; } - GtkAccelGroup* accel = gtk_accel_group_new(); - gtk_window_add_accel_group( window, accel ); - - GtkVBox* vbox = create_dialog_vbox( 8, 8 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox ) ); - - - GtkHBox* hboxDummy = create_dialog_hbox( 0, 0 ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hboxDummy ), FALSE, FALSE, 0 ); - - gtk_box_pack_start( GTK_BOX( hboxDummy ), create_padding( 0, 50 ), FALSE, FALSE, 0 ); // HACK to force minimum height - - GtkHBox* iconBox = create_dialog_hbox( 16, 0 ); - gtk_box_pack_start( GTK_BOX( hboxDummy ), GTK_WIDGET( iconBox ), FALSE, FALSE, 0 ); - - GtkImage* image = GTK_IMAGE( gtk_image_new_from_stock( messagebox_stock_icon( icon ), GTK_ICON_SIZE_DIALOG ) ); - gtk_widget_show( GTK_WIDGET( image ) ); - gtk_box_pack_start( GTK_BOX( iconBox ), GTK_WIDGET( image ), FALSE, FALSE, 0 ); - - GtkLabel* label = GTK_LABEL( gtk_label_new( text ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - gtk_label_set_justify( label, GTK_JUSTIFY_LEFT ); - gtk_label_set_line_wrap( label, TRUE ); - gtk_box_pack_start( GTK_BOX( iconBox ), GTK_WIDGET( label ), TRUE, TRUE, 0 ); - - - GtkVBox* vboxDummy = create_dialog_vbox( 0, 0 ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( vboxDummy ), FALSE, FALSE, 0 ); - - GtkAlignment* alignment = GTK_ALIGNMENT( gtk_alignment_new( 0.5, 0.0, 0.0, 0.0 ) ); - gtk_widget_show( GTK_WIDGET( alignment ) ); - gtk_box_pack_start( GTK_BOX( vboxDummy ), GTK_WIDGET( alignment ), FALSE, FALSE, 0 ); - - GtkHBox* hbox = create_dialog_hbox( 8, 0 ); - gtk_container_add( GTK_CONTAINER( alignment ), GTK_WIDGET( hbox ) ); - - gtk_box_pack_start( GTK_BOX( vboxDummy ), create_padding( 400, 0 ), FALSE, FALSE, 0 ); // HACK to force minimum width - - - if ( type == eMB_OK ) { - GtkButton* button = create_modal_dialog_button( "OK", ok_button ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), TRUE, FALSE, 0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_show( GTK_WIDGET( button ) ); - - dialog.ret = eIDOK; - } - else if ( type == eMB_OKCANCEL ) { - { - GtkButton* button = create_modal_dialog_button( "OK", ok_button ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), TRUE, FALSE, 0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_show( GTK_WIDGET( button ) ); - } - - { - GtkButton* button = create_modal_dialog_button( "Cancel", cancel_button ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), TRUE, FALSE, 0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 ); - gtk_widget_show( GTK_WIDGET( button ) ); - } - - dialog.ret = eIDCANCEL; - } - else if ( type == eMB_YESNOCANCEL ) { - { - GtkButton* button = create_modal_dialog_button( "Yes", yes_button ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), TRUE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_show( GTK_WIDGET( button ) ); - } - - { - GtkButton* button = create_modal_dialog_button( "No", no_button ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), TRUE, FALSE, 0 ); - gtk_widget_show( GTK_WIDGET( button ) ); - } - { - GtkButton* button = create_modal_dialog_button( "Cancel", cancel_button ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), TRUE, FALSE, 0 ); - gtk_widget_show( GTK_WIDGET( button ) ); - } - - dialog.ret = eIDCANCEL; - } - else if ( type == eMB_NOYES ) { - { - GtkButton* button = create_modal_dialog_button( "No", no_button ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), TRUE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_show( GTK_WIDGET( button ) ); - } - { - GtkButton* button = create_modal_dialog_button( "Yes", yes_button ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), TRUE, FALSE, 0 ); - gtk_widget_show( GTK_WIDGET( button ) ); - } - - dialog.ret = eIDNO; - } - else /* if (type == eMB_YESNO) */ + switch ( ret ) { - { - GtkButton* button = create_modal_dialog_button( "Yes", yes_button ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), TRUE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_show( GTK_WIDGET( button ) ); - } - - { - GtkButton* button = create_modal_dialog_button( "No", no_button ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), TRUE, FALSE, 0 ); - gtk_widget_show( GTK_WIDGET( button ) ); - } - dialog.ret = eIDNO; + case QMessageBox::StandardButton::Ok: + return eIDOK; + case QMessageBox::StandardButton::Cancel: + return eIDCANCEL; + case QMessageBox::StandardButton::Yes: + return eIDYES; + case QMessageBox::StandardButton::No: + return eIDNO; + default: + ASSERT_MESSAGE( false, "unexpected EMessageBoxReturn" ); + return eIDOK; } - - modal_dialog_show( window, dialog ); - - gtk_widget_destroy( GTK_WIDGET( window ) ); - - return dialog.ret; } diff --git a/libs/gtkutil/messagebox.h b/libs/gtkutil/messagebox.h index 5b48d154..a769dfa0 100644 --- a/libs/gtkutil/messagebox.h +++ b/libs/gtkutil/messagebox.h @@ -23,6 +23,5 @@ #include "qerplugin.h" -typedef struct _GtkWidget GtkWidget; /// \brief Shows a modal message-box. -EMessageBoxReturn gtk_MessageBox( GtkWidget *parent, const char* text, const char* title = "NetRadiant", EMessageBoxType type = eMB_OK, EMessageBoxIcon icon = eMB_ICONDEFAULT ); +EMessageBoxReturn qt_MessageBox( class QWidget *parent, const char* text, const char* title = "NetRadiant", EMessageBoxType type = EMessageBoxType::Info, int buttons = 0 ); diff --git a/libs/gtkutil/mousepresses.h b/libs/gtkutil/mousepresses.h new file mode 100644 index 00000000..6ca05d0f --- /dev/null +++ b/libs/gtkutil/mousepresses.h @@ -0,0 +1,104 @@ +/* + Copyright (C) 2001-2006, William Joseph. + All Rights Reserved. + + This file is part of GtkRadiant. + + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "timer.h" +#include + +/// \brief manages mouse button presses in a way: +/// 1st pressed button determines the release result +/// release has result, when last button is released +/// press has result only for 1st button press +class MousePresses +{ +public: + enum Result + { + None = Qt::MouseButton::NoButton, + Left = Qt::MouseButton::LeftButton, + Right = Qt::MouseButton::RightButton, + Middle = Qt::MouseButton::MiddleButton, + Left2x, + Right2x, + Middle2x, + }; +private: + Result result_to_2x( Result button ) const { + switch ( button ) + { + case Left: return Left2x; + case Right: return Right2x; + case Middle: return Middle2x; + default: return None; + } + } + Result result_for_button( Qt::MouseButton button ) const { + switch ( button ) + { + case Qt::MouseButton::LeftButton: return Left; + case Qt::MouseButton::RightButton: return Right; + case Qt::MouseButton::MiddleButton: return Middle; + default: return None; + } + } + DoubleClickTimer m_doubleClick; + Result m_button{}; + Result m_buttonPrev{}; +public: +#if 1 + Result press( const QMouseEvent *event ){ + const Result newbutton = result_for_button( event->button() ); + if( newbutton != None && event->button() == event->buttons() ){ // brand new press definitely; process even if release event was lost, for responsiveness + m_button = newbutton; + m_doubleClick.click(); + return ( m_doubleClick.fired() && m_button == m_buttonPrev )? result_to_2x( m_button ) : m_button; + } + return None; + } + Result release( const QMouseEvent *event ){ + if( m_button != None && event->buttons() == 0 ){ // last button is released + const auto result = ( m_doubleClick.fired() && m_button == m_buttonPrev )? result_to_2x( m_button ) : m_button; + m_buttonPrev = std::exchange( m_button, None ); + return result; + } + return None; + } +#else + Result press( const QMouseEvent *event ){ + const Result newbutton = result_for_button( event->button() ); + if( newbutton != None && m_button == None ){ + m_button = newbutton; + m_doubleClick.click(); + return ( m_doubleClick.fired() && m_button == m_buttonPrev )? result_to_2x( m_button ) : m_button; + } + return None; + } + Result release( const QMouseEvent *event ){ // release event may be lost... ignore new press and release saved button for consistency + if( m_button != None && event->buttons() == 0 ){ // last button is released + const auto result = ( m_doubleClick.fired() && m_button == m_buttonPrev )? result_to_2x( m_button ) : m_button; + m_buttonPrev = std::exchange( m_button, None ); + return result; + } + return None; + } +#endif +}; diff --git a/libs/gtkutil/nonmodal.h b/libs/gtkutil/nonmodal.h index 471a8176..a422f164 100644 --- a/libs/gtkutil/nonmodal.h +++ b/libs/gtkutil/nonmodal.h @@ -21,136 +21,90 @@ #pragma once -#include -#include +#include +#include +#include #include "generic/callback.h" -#include "pointer.h" -#include "button.h" +#include "spinbox.h" -inline gboolean escape_clear_focus_widget( GtkWidget* widget, GdkEventKey* event, gpointer data ){ - if ( event->keyval == GDK_KEY_Escape ) { - gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( widget ) ) ), NULL ); - return TRUE; - } - return FALSE; -} - -inline void widget_connect_escape_clear_focus_widget( GtkWidget* widget ){ - g_signal_connect( G_OBJECT( widget ), "key_press_event", G_CALLBACK( escape_clear_focus_widget ), 0 ); -} - - -class NonModalEntry +class NonModalEntry : public QLineEdit { - bool m_editing; + bool m_editing{}; Callback m_apply; Callback m_cancel; - - static gboolean focus_in( GtkEntry* entry, GdkEventFocus *event, NonModalEntry* self ){ - self->m_editing = false; - return FALSE; - } - - static gboolean focus_out( GtkEntry* entry, GdkEventFocus *event, NonModalEntry* self ){ - if ( self->m_editing && gtk_widget_get_visible( GTK_WIDGET( entry ) ) ) { - self->m_apply(); - } - self->m_editing = false; - return FALSE; - } - - static gboolean changed( GtkEntry* entry, NonModalEntry* self ){ - self->m_editing = true; - return FALSE; - } - - static gboolean enter( GtkEntry* entry, GdkEventKey* event, NonModalEntry* self ){ - if ( event->keyval == GDK_KEY_Return ) { - self->m_apply(); - self->m_editing = false; - gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( entry ) ) ), NULL ); - return TRUE; - } - return FALSE; - } - - static gboolean escape( GtkEntry* entry, GdkEventKey* event, NonModalEntry* self ){ - if ( event->keyval == GDK_KEY_Escape ) { - self->m_cancel(); - self->m_editing = false; - gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( entry ) ) ), NULL ); - return TRUE; - } - return FALSE; - } - public: - NonModalEntry( const Callback& apply, const Callback& cancel ) : m_editing( false ), m_apply( apply ), m_cancel( cancel ){ + NonModalEntry( const Callback& apply, const Callback& cancel ) : QLineEdit(), m_apply( apply ), m_cancel( cancel ){ + QObject::connect( this, &QLineEdit::textEdited, [this](){ m_editing = true; } ); + QObject::connect( this, &QLineEdit::editingFinished, [this](){ // on enter or focus out + if( m_editing ){ + m_apply(); + m_editing = false; + } + clearFocus(); + } ); } - void connect( GtkEntry* entry ){ - g_signal_connect( G_OBJECT( entry ), "focus_in_event", G_CALLBACK( focus_in ), this ); - g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( focus_out ), this ); - g_signal_connect( G_OBJECT( entry ), "key_press_event", G_CALLBACK( enter ), this ); - g_signal_connect( G_OBJECT( entry ), "key_press_event", G_CALLBACK( escape ), this ); - g_signal_connect( G_OBJECT( entry ), "changed", G_CALLBACK( changed ), this ); +protected: + bool event( QEvent *event ) override { + if( event->type() == QEvent::ShortcutOverride ){ + QKeyEvent *keyEvent = static_cast( event ); + if( keyEvent->key() == Qt::Key_Escape ){ + m_editing = false; + m_cancel(); + clearFocus(); + event->accept(); + } + } + return QLineEdit::event( event ); + } + void focusInEvent( QFocusEvent *event ) override { + if( event->reason() == Qt::FocusReason::MouseFocusReason ) + QTimer::singleShot( 0, [this](){ selectAll(); } ); + QLineEdit::focusInEvent( event ); } }; -class NonModalSpinner +class NonModalSpinner : public DoubleSpinBox { + using DoubleSpinBox::DoubleSpinBox; + bool m_editing{}; Callback m_apply; Callback m_cancel; - - static gboolean changed( GtkSpinButton* spin, NonModalSpinner* self ){ - self->m_apply(); - return FALSE; - } - - static gboolean enter( GtkSpinButton* spin, GdkEventKey* event, NonModalSpinner* self ){ - if ( event->keyval == GDK_KEY_Return ) { - gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( spin ) ) ), NULL ); - return TRUE; - } - return FALSE; - } - - static gboolean escape( GtkSpinButton* spin, GdkEventKey* event, NonModalSpinner* self ){ - if ( event->keyval == GDK_KEY_Escape ) { - self->m_cancel(); - gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( spin ) ) ), NULL ); - return TRUE; - } - return FALSE; - } - public: - NonModalSpinner( const Callback& apply, const Callback& cancel ) : m_apply( apply ), m_cancel( cancel ){ + void setCallbacks( const Callback& apply, const Callback& cancel ){ + m_apply = apply; + m_cancel = cancel; + // on enter & focus out; need to track editing, as nonedited triggers this too + QObject::connect( this, &QAbstractSpinBox::editingFinished, [this](){ + if( m_editing ){ + m_editing = false; + m_apply(); + } + clearFocus(); + } ); + QObject::connect( lineEdit(), &QLineEdit::textEdited, [this](){ + m_editing = true; + } ); } - void connect( GtkSpinButton* spin ){ - guint handler = g_signal_connect( G_OBJECT( gtk_spin_button_get_adjustment( spin ) ), "value_changed", G_CALLBACK( changed ), this ); - g_object_set_data( G_OBJECT( spin ), "handler", gint_to_pointer( handler ) ); - g_signal_connect( G_OBJECT( spin ), "key_press_event", G_CALLBACK( enter ), this ); - g_signal_connect( G_OBJECT( spin ), "key_press_event", G_CALLBACK( escape ), this ); + bool event( QEvent *event ) override { + if( event->type() == QEvent::ShortcutOverride ){ + QKeyEvent *keyEvent = static_cast( event ); + if( keyEvent->key() == Qt::Key_Escape ){ + m_editing = false; + m_cancel(); + clearFocus(); + event->accept(); + } + } + return DoubleSpinBox::event( event ); + } + void stepBy( int steps ) override { + DoubleSpinBox::stepBy( steps ); + m_editing = false; + m_apply(); } }; - -class NonModalRadio -{ - Callback m_changed; - -public: - NonModalRadio( const Callback& changed ) : m_changed( changed ){ - } - void connect( GtkRadioButton* radio ){ - GSList* group = gtk_radio_button_get_group( radio ); - for (; group != 0; group = g_slist_next( group ) ) - { - toggle_button_connect_callback( GTK_TOGGLE_BUTTON( group->data ), m_changed ); - } - } -}; diff --git a/libs/gtkutil/paned.cpp b/libs/gtkutil/paned.cpp deleted file mode 100644 index dacd7209..00000000 --- a/libs/gtkutil/paned.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "paned.h" - -#include - -#include "frame.h" - -#if 0 -class PanedState -{ -public: - float position; - int size; -}; - -gboolean hpaned_allocate( GtkWidget* widget, GtkAllocation* allocation, PanedState* paned ){ - if ( paned->size != allocation->width ) { - paned->size = allocation->width; - gtk_paned_set_position( GTK_PANED( widget ), static_cast( paned->size * paned->position ) ); - } - return FALSE; -} - -gboolean vpaned_allocate( GtkWidget* widget, GtkAllocation* allocation, PanedState* paned ){ - if ( paned->size != allocation->height ) { - paned->size = allocation->height; - gtk_paned_set_position( GTK_PANED( widget ), static_cast( paned->size * paned->position ) ); - } - return FALSE; -} - -gboolean paned_position( GtkWidget* widget, gpointer dummy, PanedState* paned ){ - if ( paned->size != -1 ) { - paned->position = gtk_paned_get_position( GTK_PANED( widget ) ) / static_cast( paned->size ); - } - return FALSE; -} - -PanedState g_hpaned = { 0.5f, -1, }; -PanedState g_vpaned1 = { 0.5f, -1, }; -PanedState g_vpaned2 = { 0.5f, -1, }; -#endif - -GtkWidget* create_split_views( GtkWidget* topleft, GtkWidget* botleft, GtkWidget* topright, GtkWidget* botright, GtkWidget*& vsplit1, GtkWidget*& vsplit2 ){ - GtkHPaned* hsplit = GTK_HPANED( gtk_hpaned_new() ); - gtk_widget_show( GTK_WIDGET( hsplit ) ); - - //g_signal_connect( G_OBJECT( hsplit ), "size_allocate", G_CALLBACK( hpaned_allocate ), &g_hpaned ); - //g_signal_connect( G_OBJECT( hsplit ), "notify::position", G_CALLBACK( paned_position ), &g_hpaned ); - - { - GtkVPaned* vsplit = GTK_VPANED( gtk_vpaned_new() ); - vsplit1 = GTK_WIDGET( vsplit ); - //gtk_paned_add1( GTK_PANED( hsplit ), GTK_WIDGET( vsplit ) ); - gtk_paned_pack1( GTK_PANED( hsplit ), GTK_WIDGET( vsplit ), TRUE, TRUE ); - gtk_widget_show( GTK_WIDGET( vsplit ) ); - - //g_signal_connect( G_OBJECT( vsplit ), "size_allocate", G_CALLBACK( vpaned_allocate ), &g_vpaned1 ); - //g_signal_connect( G_OBJECT( vsplit ), "notify::position", G_CALLBACK( paned_position ), &g_vpaned1 ); - - //gtk_paned_add1( GTK_PANED( vsplit ), GTK_WIDGET( create_framed_widget( topleft ) ) ); - //gtk_paned_add2( GTK_PANED( vsplit ), GTK_WIDGET( create_framed_widget( botleft ) ) ); - gtk_paned_pack1( GTK_PANED( vsplit ), GTK_WIDGET( create_framed_widget( topleft ) ), TRUE, TRUE ); - gtk_paned_pack2( GTK_PANED( vsplit ), GTK_WIDGET( create_framed_widget( botleft ) ), TRUE, TRUE ); - } - { - GtkVPaned* vsplit = GTK_VPANED( gtk_vpaned_new() ); - vsplit2 = GTK_WIDGET( vsplit ); - //gtk_paned_add2( GTK_PANED( hsplit ), GTK_WIDGET( vsplit ) ); - gtk_paned_pack2( GTK_PANED( hsplit ), GTK_WIDGET( vsplit ), TRUE, TRUE ); - gtk_widget_show( GTK_WIDGET( vsplit ) ); - - //g_signal_connect( G_OBJECT( vsplit ), "size_allocate", G_CALLBACK( vpaned_allocate ), &g_vpaned2 ); - //g_signal_connect( G_OBJECT( vsplit ), "notify::position", G_CALLBACK( paned_position ), &g_vpaned2 ); - - //gtk_paned_add1( GTK_PANED( vsplit ), GTK_WIDGET( create_framed_widget( topright ) ) ); - //gtk_paned_add2( GTK_PANED( vsplit ), GTK_WIDGET( create_framed_widget( botright ) ) ); - gtk_paned_pack1( GTK_PANED( vsplit ), GTK_WIDGET( create_framed_widget( topright ) ), TRUE, TRUE ); - gtk_paned_pack2( GTK_PANED( vsplit ), GTK_WIDGET( create_framed_widget( botright ) ), TRUE, TRUE ); - } - return GTK_WIDGET( hsplit ); -} diff --git a/libs/gtkutil/paned.h b/libs/gtkutil/paned.h deleted file mode 100644 index c0e6ad44..00000000 --- a/libs/gtkutil/paned.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#pragma once - -typedef struct _GtkWidget GtkWidget; -GtkWidget* create_split_views( GtkWidget* topleft, GtkWidget* botleft, GtkWidget* topright, GtkWidget* botright, GtkWidget*& vsplit1, GtkWidget*& vsplit2 ); diff --git a/libs/gtkutil/pointer.cpp b/libs/gtkutil/pointer.cpp deleted file mode 100644 index 503845a4..00000000 --- a/libs/gtkutil/pointer.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "pointer.h" diff --git a/libs/gtkutil/spinbox.h b/libs/gtkutil/spinbox.h new file mode 100644 index 00000000..64c17cf8 --- /dev/null +++ b/libs/gtkutil/spinbox.h @@ -0,0 +1,118 @@ +/* + Copyright (C) 2001-2006, William Joseph. + All Rights Reserved. + + This file is part of GtkRadiant. + + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include +#include +#include +#include +#include + +template +class QSpinBox_mod : public SpinT +{ + using ValueT = typename std::conditional, int, double>::type; +public: + QSpinBox_mod( ValueT min = 0, ValueT max = 99, ValueT value = 0, int decimals = 2, ValueT step = 1, bool wrap = false ) : SpinT() { + if constexpr ( std::is_same_v ){ + SpinT::setLocale( QLocale::Language::C ); // force period separator + SpinT::setDecimals( decimals ); + } + SpinT::setRange( min, max ); + SpinT::setValue( value ); + SpinT::setSingleStep( step ); + SpinT::setWrapping( wrap ); + SpinT::setAccelerated( true ); + } +protected: + bool event( QEvent *event ) override { + /* QAbstractSpinBox has no well defined ShortcutOverride routine, unlike underlying QLineEdit + thus box' portion of key events ends up firing application's shortcuts (e.g. up, down, pgUp, pgDown) + let's lock entire input on the box except a few keys, handled by parent window */ + if( event->type() == QEvent::ShortcutOverride ){ + QKeyEvent *keyEvent = static_cast( event ); + if( keyEvent->key() != Qt::Key_Return + && keyEvent->key() != Qt::Key_Enter + && keyEvent->key() != Qt::Key_Escape ) + event->accept(); + } + return SpinT::event( event ); + } + void focusInEvent( QFocusEvent *event ) override { + if( event->reason() == Qt::FocusReason::MouseFocusReason ) + QTimer::singleShot( 0, [this](){ SpinT::selectAll(); } ); + SpinT::focusInEvent( event ); + } +}; + +using DoubleSpinBox = QSpinBox_mod; +using SpinBox = QSpinBox_mod; + + +/// \brief Label for a QSpinBox or QDoubleSpinBox +/// Changes their value by left mouse drag +/// Ctrl adds 10x multiplier +template +class SpinBoxLabel : public QLabel +{ +protected: + SpinBoxT *m_spin; + bool m_isInDrag{}; + QPoint m_dragStart; + int m_dragOccured; + int m_dragAccum; +public: + SpinBoxLabel( const QString& labelText, SpinBoxT* spin ) : QLabel( labelText ), m_spin( spin ) + { + setCursor( Qt::CursorShape::SizeHorCursor ); + } +protected: + void mousePressEvent( QMouseEvent* event ) override { + if( event->button() == Qt::MouseButton::LeftButton ){ + m_spin->setFocus(); + m_spin->selectAll(); + m_isInDrag = true; + m_dragStart = event->globalPos(); + m_dragOccured = false; + m_dragAccum = 0; + setCursor( Qt::CursorShape::BlankCursor ); + } + } + void mouseMoveEvent( QMouseEvent* event ) override { + if( m_isInDrag && event->buttons() == Qt::MouseButton::LeftButton ){ + m_dragAccum += event->globalPos().x() - m_dragStart.x(); + const int delta = m_dragAccum / 20; + if( delta != 0 ){ + m_dragOccured = true; + m_dragAccum %= 20; + m_spin->stepBy( event->modifiers().testFlag( Qt::KeyboardModifier::ControlModifier )? delta * 10 : delta ); + QCursor::setPos( m_dragStart ); + } + } + } + void mouseReleaseEvent( QMouseEvent* event ) override { + if( m_isInDrag ){ + m_isInDrag = false; + setCursor( Qt::CursorShape::SizeHorCursor ); + } + } +}; \ No newline at end of file diff --git a/libs/gtkutil/toolbar.cpp b/libs/gtkutil/toolbar.cpp index 49ebbfd3..98b4d3c6 100644 --- a/libs/gtkutil/toolbar.cpp +++ b/libs/gtkutil/toolbar.cpp @@ -21,67 +21,18 @@ #include "toolbar.h" -#include - #include "generic/callback.h" #include "accelerator.h" -#include "button.h" #include "image.h" -#include "closure.h" -#include "pointer.h" -GtkToolbar* toolbar_new(){ - GtkToolbar* toolbar = GTK_TOOLBAR( gtk_toolbar_new() ); - gtk_orientable_set_orientation( GTK_ORIENTABLE( toolbar ), GTK_ORIENTATION_HORIZONTAL ); - gtk_toolbar_set_style( toolbar, GTK_TOOLBAR_ICONS ); - gtk_toolbar_set_show_arrow( toolbar, FALSE ); - gtk_widget_show( GTK_WIDGET( toolbar ) ); - return toolbar; +QAction* toolbar_append_button( QToolBar* toolbar, const char* description, const char* icon, const Callback& callback ){ + return toolbar->addAction( new_local_icon( icon ), description, callback ); } -void toolbar_append_space( GtkToolbar* toolbar ){ - GtkToolItem* space = gtk_separator_tool_item_new(); - gtk_widget_show( GTK_WIDGET( space ) ); - gtk_toolbar_insert( toolbar, space, -1 ); -} - -void toolbar_append( GtkToolbar* toolbar, GtkToolItem* button, const char* description ){ - gtk_widget_show_all( GTK_WIDGET( button ) ); - gtk_tool_item_set_tooltip_text( button, description ); -// gtk_button_set_relief( button, GTK_RELIEF_NONE ); -// gtk_widget_set_can_focus( GTK_WIDGET( button ), FALSE ); -// gtk_widget_set_can_default( GTK_WIDGET( button ), FALSE ); - gtk_toolbar_insert( toolbar, button, -1 ); -} - -GtkToolButton* toolbar_append_button( GtkToolbar* toolbar, const char* description, const char* icon, const Callback& callback ){ - GtkToolButton* button = GTK_TOOL_BUTTON( gtk_tool_button_new( GTK_WIDGET( new_local_image( icon ) ), nullptr ) ); - button_connect_callback( button, callback ); - toolbar_append( toolbar, GTK_TOOL_ITEM( button ), description ); - return button; -} - -GtkToggleToolButton* toolbar_append_toggle_button( GtkToolbar* toolbar, const char* description, const char* icon, const Callback& callback ){ - GtkToggleToolButton* button = GTK_TOGGLE_TOOL_BUTTON( gtk_toggle_tool_button_new() ); - gtk_tool_button_set_icon_widget( GTK_TOOL_BUTTON( button ), GTK_WIDGET( new_local_image( icon ) ) ); - toggle_button_connect_callback( button, callback ); - toolbar_append( toolbar, GTK_TOOL_ITEM( button ), description ); - return button; -} - -GtkToolButton* toolbar_append_button( GtkToolbar* toolbar, const char* description, const char* icon, const Command& command ){ - return toolbar_append_button( toolbar, description, icon, command.m_callback ); -} - -void toggle_button_set_active_callback( GtkToggleToolButton& button, bool active ){ - toggle_button_set_active_no_signal( &button, active ); -} -typedef ReferenceCaller1 ToggleButtonSetActiveCaller; - -GtkToggleToolButton* toolbar_append_toggle_button( GtkToolbar* toolbar, const char* description, const char* icon, const Toggle& toggle ){ - GtkToggleToolButton* button = toolbar_append_toggle_button( toolbar, description, icon, toggle.m_command.m_callback ); - toggle.m_exportCallback( ToggleButtonSetActiveCaller( *button ) ); +QAction* toolbar_append_toggle_button( QToolBar* toolbar, const char* description, const char* icon, const Callback& callback ){ + QAction *button = toolbar_append_button( toolbar, description, icon, callback ); + button->setCheckable( true ); return button; } diff --git a/libs/gtkutil/toolbar.h b/libs/gtkutil/toolbar.h index 847879ff..d2341b40 100644 --- a/libs/gtkutil/toolbar.h +++ b/libs/gtkutil/toolbar.h @@ -22,18 +22,7 @@ #pragma once #include "generic/callbackfwd.h" +#include -typedef struct _GtkToolItem GtkToolItem; -typedef struct _GtkToolButton GtkToolButton; -typedef struct _GtkToggleToolButton GtkToggleToolButton; -typedef struct _GtkToolbar GtkToolbar; -class Command; -class Toggle; - -GtkToolbar* toolbar_new(); -void toolbar_append_space( GtkToolbar* toolbar ); -void toolbar_append( GtkToolbar* toolbar, GtkToolItem* button, const char* description ); -GtkToolButton* toolbar_append_button( GtkToolbar* toolbar, const char* description, const char* icon, const Callback& callback ); -GtkToolButton* toolbar_append_button( GtkToolbar* toolbar, const char* description, const char* icon, const Command& command ); -GtkToggleToolButton* toolbar_append_toggle_button( GtkToolbar* toolbar, const char* description, const char* icon, const Callback& callback ); -GtkToggleToolButton* toolbar_append_toggle_button( GtkToolbar* toolbar, const char* description, const char* icon, const Toggle& toggle ); +QAction* toolbar_append_button( QToolBar* toolbar, const char* description, const char* icon, const Callback& callback ); +QAction* toolbar_append_toggle_button( QToolBar* toolbar, const char* description, const char* icon, const Callback& callback ); diff --git a/libs/gtkutil/widget.h b/libs/gtkutil/widget.h index cf77ea29..f3eac83f 100644 --- a/libs/gtkutil/widget.h +++ b/libs/gtkutil/widget.h @@ -22,36 +22,11 @@ #pragma once #include -#include #include "generic/callback.h" -#include "warnings.h" #include "debugging/debugging.h" -inline bool widget_is_visible( GtkWidget* widget ){ - //return GTK_WIDGET_VISIBLE( widget ); - return gtk_widget_get_visible( widget ); -} - -inline void widget_set_visible( GtkWidget* widget, bool show ){ - if ( show ) { - /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */ - GtkWidget* glwidget = GTK_WIDGET( g_object_get_data( G_OBJECT( widget ), "glwidget" ) ); - if ( glwidget ){ - gtk_widget_hide( glwidget ); - gtk_widget_show( glwidget ); - } - gtk_widget_show( widget ); - } - else - { - gtk_widget_hide( widget ); - } -} - - -inline void widget_toggle_visible( GtkWidget* widget ){ - widget_set_visible( widget, !widget_is_visible( widget ) ); -} +#include +#include class ToggleItem { @@ -76,27 +51,11 @@ public: typedef MemberCaller1 AddCallbackCaller; }; -class ToggleShown +class ToggleShown : public QObject { bool m_shownDeferred; - - static gboolean notify_visible( GtkWidget* widget, gpointer dummy, ToggleShown* self ){ - /* destroy = notify::visible with visible = 0, thus let's filter it out */ - if( gtk_main_level() > 0 ){ //== 0 at destroy time - self->m_shownDeferred = widget_is_visible( self->m_widget ); - } - //globalOutputStream() << "ToggleShown::notify_visible time " << gtk_get_current_event_time() << " visible " << self->m_shownDeferred << "\n"; - self->update(); - return FALSE; - } - static gboolean destroy( GtkWidget* widget, ToggleShown* self ){ - //globalOutputStream() << "ToggleShown::destroy time " << gtk_get_current_event_time() << " visible " << self->m_shownDeferred << "\n"; - //self->m_shownDeferred = widget_is_visible( self->m_widget ); //always 0 at destroy time - self->m_widget = 0; - return FALSE; - } + QWidget* m_widget; public: - GtkWidget* m_widget; ToggleItem m_item; ToggleShown( const ToggleShown& other ) = delete; // NOT COPYABLE @@ -106,47 +65,44 @@ public: : m_shownDeferred( shown ), m_widget( 0 ), m_item( ActiveCaller( *this ) ){ } void update(){ - //globalOutputStream() << "ToggleShown::update\n"; m_item.update(); } bool active() const { - //globalOutputStream() << "ToggleShown::active\n"; - if ( m_widget == 0 ) { - return m_shownDeferred; - } - else - { - return widget_is_visible( m_widget ); - } + return m_widget == nullptr + ? m_shownDeferred + : m_widget->isVisible(); } void exportActive( const BoolImportCallback& importCallback ){ - //globalOutputStream() << "ToggleShown::exportActive\n"; importCallback( active() ); } typedef MemberCaller1 ActiveCaller; void set( bool shown ){ - //globalOutputStream() << "ToggleShown::set\n"; - if ( m_widget == 0 ) { - m_shownDeferred = shown; - } - else - { - widget_set_visible( m_widget, shown ); - } + m_shownDeferred = shown; + if ( m_widget != nullptr ) + m_widget->setVisible( shown ); } void toggle(){ - //globalOutputStream() << "ToggleShown::toggle\n"; - widget_toggle_visible( m_widget ); + m_widget->setVisible( m_shownDeferred = !m_widget->isVisible() ); } typedef MemberCaller ToggleCaller; - void connect( GtkWidget* widget ){ - //globalOutputStream() << "ToggleShown::connect\n"; + void connect( QWidget* widget ){ m_widget = widget; - widget_set_visible( m_widget, m_shownDeferred ); - g_signal_connect( G_OBJECT( m_widget ), "notify::visible", G_CALLBACK( notify_visible ), this ); - g_signal_connect( G_OBJECT( m_widget ), "destroy", G_CALLBACK( destroy ), this ); + m_widget->setVisible( m_shownDeferred ); + m_widget->installEventFilter( this ); + QObject::connect( m_widget, &QObject::destroyed, [this](){ m_widget = nullptr; } ); update(); } +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::Close ) { + m_shownDeferred = false; + /* HACK */ //. because widget isVisible() at this point + const auto tmp = std::exchange( m_widget, nullptr ); + update(); + m_widget = tmp; + } + return QObject::eventFilter( obj, event ); // standard event processing + } }; namespace{ @@ -162,34 +118,9 @@ typedef ConstReferenceCaller1 WidgetQueueDrawCaller; +typedef ReferenceCaller WidgetQueueDrawCaller; - -inline void widget_make_default( GtkWidget* widget ){ - gtk_widget_set_can_default( widget, TRUE ); - gtk_widget_grab_default( widget ); -} - -class WidgetFocusPrinter -{ - const char* m_name; - - static gboolean focus_in( GtkWidget *widget, GdkEventFocus *event, WidgetFocusPrinter* self ){ - globalOutputStream() << self->m_name << " takes focus\n"; - return FALSE; - } - static gboolean focus_out( GtkWidget *widget, GdkEventFocus *event, WidgetFocusPrinter* self ){ - globalOutputStream() << self->m_name << " loses focus\n"; - return FALSE; - } -public: - WidgetFocusPrinter( const char* name ) : m_name( name ){ - } - void connect( GtkWidget* widget ){ - g_signal_connect( G_OBJECT( widget ), "focus_in_event", G_CALLBACK( focus_in ), this ); - g_signal_connect( G_OBJECT( widget ), "focus_out_event", G_CALLBACK( focus_out ), this ); - } -}; diff --git a/libs/gtkutil/window.cpp b/libs/gtkutil/window.cpp deleted file mode 100644 index 6f68a162..00000000 --- a/libs/gtkutil/window.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "window.h" - -#include - -#include "pointer.h" -#include "accelerator.h" - -inline void CHECK_RESTORE( GtkWidget* w ){ - if ( gpointer_to_int( g_object_get_data( G_OBJECT( w ), "was_mapped" ) ) != 0 ) { - gtk_widget_show( w ); - /* workaround for gtk 2.24 issue: not displayed glwidget after min/restore */ - GtkWidget* glwidget = GTK_WIDGET( g_object_get_data( G_OBJECT( w ), "glwidget" ) ); - if ( glwidget ){ - gtk_widget_hide( glwidget ); - gtk_widget_show( glwidget ); - } - } -} - -inline void CHECK_MINIMIZE( GtkWidget* w ){ - g_object_set_data( G_OBJECT( w ), "was_mapped", gint_to_pointer( gtk_widget_get_visible( w ) ) ); - //gtk_widget_hide( w ); //fix for gtk 2.24 + the whole scheme isn't needed with gtk 2.16, 2.24; they do it all alone -} - -static gboolean main_window_iconified( GtkWidget* widget, GdkEventWindowState* event, gpointer data ){ - if ( ( event->changed_mask & ( GDK_WINDOW_STATE_ICONIFIED | GDK_WINDOW_STATE_WITHDRAWN ) ) != 0 ) { - if ( ( event->new_window_state & ( GDK_WINDOW_STATE_ICONIFIED | GDK_WINDOW_STATE_WITHDRAWN ) ) != 0 ) { - CHECK_MINIMIZE( GTK_WIDGET( data ) ); - } - else - { - CHECK_RESTORE( GTK_WIDGET( data ) ); - } - } - return FALSE; -} - -unsigned int connect_floating( GtkWindow* main_window, GtkWindow* floating ){ - return g_signal_connect( G_OBJECT( main_window ), "window_state_event", G_CALLBACK( main_window_iconified ), floating ); -} - -gboolean destroy_disconnect_floating( GtkWindow* widget, gpointer data ){ - g_signal_handler_disconnect( G_OBJECT( data ), gpointer_to_int( g_object_get_data( G_OBJECT( widget ), "floating_handler" ) ) ); - return FALSE; -} - -gboolean floating_window_delete_present( GtkWindow* floating, GdkEventFocus *event, GtkWindow* main_window ){ - if ( gtk_window_is_active( floating ) || gtk_window_is_active( main_window ) ) { - gtk_window_present( main_window ); - } - return FALSE; -} - -guint connect_floating_window_delete_present( GtkWindow* floating, GtkWindow* main_window ){ - return g_signal_connect( G_OBJECT( floating ), "delete_event", G_CALLBACK( floating_window_delete_present ), main_window ); -} - -gboolean floating_window_destroy_present( GtkWindow* floating, GtkWindow* main_window ){ - if ( gtk_window_is_active( floating ) || gtk_window_is_active( main_window ) ) { - gtk_window_present( main_window ); - } - return FALSE; -} - -guint connect_floating_window_destroy_present( GtkWindow* floating, GtkWindow* main_window ){ - return g_signal_connect( G_OBJECT( floating ), "destroy", G_CALLBACK( floating_window_destroy_present ), main_window ); -} - -GtkWindow* create_floating_window( const char* title, GtkWindow* parent ){ - GtkWindow* window = GTK_WINDOW( gtk_window_new( GTK_WINDOW_TOPLEVEL ) ); - gtk_window_set_title( window, title ); - - if ( parent != 0 ) { - gtk_window_set_transient_for( window, parent ); - connect_floating_window_destroy_present( window, parent ); - g_object_set_data( G_OBJECT( window ), "floating_handler", gint_to_pointer( connect_floating( parent, window ) ) ); - g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( destroy_disconnect_floating ), parent ); -/* - //gtk_window_set_type_hint (window,GDK_WINDOW_TYPE_HINT_UTILITY); - //gtk_window_set_type_hint (window,GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_keep_above ( window, TRUE ); - GtkWidget* widget = GTK_WIDGET( window ); - gtk_widget_realize ( widget ); - GdkWindow* gdk_window = gtk_widget_get_window( widget ); - //gdk_window_set_decorations ( gdk_window, (GdkWMDecoration)(GDK_DECOR_BORDER|GDK_DECOR_RESIZEH|GDK_DECOR_TITLE|GDK_DECOR_MENU|GDK_DECOR_MINIMIZE|GDK_DECOR_MAXIMIZE) ); - //gdk_window_set_functions ( gdk_window, (GdkWMFunction)( GDK_FUNC_RESIZE|GDK_FUNC_MOVE|GDK_FUNC_MINIMIZE|GDK_FUNC_MAXIMIZE|GDK_FUNC_CLOSE ) ); - //gdk_window_set_decorations ( gdk_window, (GdkWMDecoration)( GDK_DECOR_ALL ) ); - //gdk_window_set_functions ( gdk_window, (GdkWMFunction)( GDK_FUNC_ALL ) ); - //gdk_window_set_type_hint ( gdk_window, GDK_WINDOW_TYPE_HINT_DIALOG ); - //gdk_window_set_type_hint ( gdk_window, GDK_WINDOW_TYPE_HINT_UTILITY ); - //gdk_window_set_type_hint ( gdk_window, GDK_WINDOW_TYPE_HINT_NORMAL ); - gdk_window_set_skip_taskbar_hint ( gdk_window, TRUE ); - gdk_window_set_skip_pager_hint ( gdk_window, TRUE ); -*/ - } - - return window; -} - -void destroy_floating_window( GtkWindow* window ){ - gtk_widget_destroy( GTK_WIDGET( window ) ); -} - -gint window_realize_remove_sysmenu( GtkWidget* widget, gpointer data ){ - gdk_window_set_decorations( gtk_widget_get_window( widget ), (GdkWMDecoration)( GDK_DECOR_ALL | GDK_DECOR_MENU ) ); - return FALSE; -} - -gboolean persistent_floating_window_delete( GtkWindow* floating, GdkEvent *event, GtkWindow* main_window ){ - gtk_widget_hide( GTK_WIDGET( floating ) ); - return TRUE; -} - -GtkWindow* create_persistent_floating_window( const char* title, GtkWindow* main_window ){ - GtkWindow* window = GTK_WINDOW( create_floating_window( title, main_window ) ); - - gtk_widget_set_events( GTK_WIDGET( window ), GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK ); - - connect_floating_window_delete_present( window, main_window ); - g_signal_connect( G_OBJECT( window ), "delete_event", G_CALLBACK( persistent_floating_window_delete ), 0 ); - -#if 0 - if ( g_multimon_globals.m_bStartOnPrimMon && g_multimon_globals.m_bNoSysMenuPopups ) { - g_signal_connect( G_OBJECT( window ), "realize", G_CALLBACK( window_realize_remove_sysmenu ), 0 ); - } -#endif - - return window; -} - -gint window_realize_remove_minmax( GtkWidget* widget, gpointer data ){ - gdk_window_set_decorations( gtk_widget_get_window( widget ), (GdkWMDecoration)( GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE ) ); - return FALSE; -} - -void window_remove_minmax( GtkWindow* window ){ - g_signal_connect( G_OBJECT( window ), "realize", G_CALLBACK( window_realize_remove_minmax ), 0 ); -} - - -GtkScrolledWindow* create_scrolled_window( GtkPolicyType hscrollbar_policy, GtkPolicyType vscrollbar_policy, int border ){ - GtkScrolledWindow* scr = GTK_SCROLLED_WINDOW( gtk_scrolled_window_new( 0, 0 ) ); - gtk_widget_show( GTK_WIDGET( scr ) ); - gtk_scrolled_window_set_policy( scr, hscrollbar_policy, vscrollbar_policy ); - gtk_scrolled_window_set_shadow_type( scr, GTK_SHADOW_IN ); - gtk_container_set_border_width( GTK_CONTAINER( scr ), border ); - return scr; -} diff --git a/libs/gtkutil/window.h b/libs/gtkutil/window.h deleted file mode 100644 index d2ee6f14..00000000 --- a/libs/gtkutil/window.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#pragma once - -#include - -#include "debugging/debugging.h" -#include "generic/callback.h" -#include "widget.h" - -inline gboolean window_focus_in_clear_focus_widget( GtkWidget* widget, GdkEventKey* event, gpointer data ){ - gtk_window_set_focus( GTK_WINDOW( widget ), NULL ); - return FALSE; -} - -inline guint window_connect_focus_in_clear_focus_widget( GtkWindow* window ){ - return g_signal_connect( G_OBJECT( window ), "focus_in_event", G_CALLBACK( window_focus_in_clear_focus_widget ), NULL ); -} - - -unsigned int connect_floating( GtkWindow* main_window, GtkWindow* floating ); -GtkWindow* create_floating_window( const char* title, GtkWindow* parent ); -void destroy_floating_window( GtkWindow* window ); - -GtkWindow* create_persistent_floating_window( const char* title, GtkWindow* main_window ); -gboolean persistent_floating_window_delete( GtkWindow* floating, GdkEvent *event, GtkWindow* main_window ); - -void window_remove_minmax( GtkWindow* window ); - -GtkScrolledWindow* create_scrolled_window( GtkPolicyType hscrollbar_policy, GtkPolicyType vscrollbar_policy, int border = 0 ); - - -struct WindowPosition -{ - int x, y, w, h; - - WindowPosition(){ - } - WindowPosition( int _x, int _y, int _w, int _h ) - : x( _x ), y( _y ), w( _w ), h( _h ){ - } -}; - -const WindowPosition c_default_window_pos( 50, 25, 400, 300 ); - -inline void window_get_position( GtkWindow* window, WindowPosition& position ){ - ASSERT_MESSAGE( window != 0, "error saving window position" ); - - gtk_window_get_position( window, &position.x, &position.y ); - gtk_window_get_size( window, &position.w, &position.h ); -} - -inline void window_set_position( GtkWindow* window, const WindowPosition& position ){ - gtk_window_set_gravity( window, GDK_GRAVITY_STATIC ); - - GdkScreen* screen = gdk_screen_get_default(); - if ( position.x < 0 - || position.y < 0 - || position.x > gdk_screen_get_width( screen ) - || position.y > gdk_screen_get_height( screen ) ) { - gtk_window_set_position( window, GTK_WIN_POS_CENTER_ON_PARENT ); - } - else - { - gtk_window_move( window, position.x, position.y ); - } - - gtk_window_set_default_size( window, position.w, position.h ); -} - -inline void WindowPosition_Parse( WindowPosition& position, const char* value ){ - if ( sscanf( value, "%d %d %d %d", &position.x, &position.y, &position.w, &position.h ) != 4 ) { - position = WindowPosition( c_default_window_pos ); // ensure sane default value for window position - } -} -typedef ReferenceCaller1 WindowPositionImportStringCaller; - -inline void WindowPosition_Write( const WindowPosition& position, const StringImportCallback& importCallback ){ - char buffer[64]; - sprintf( buffer, "%d %d %d %d", position.x, position.y, position.w, position.h ); - importCallback( buffer ); -} -typedef ConstReferenceCaller1 WindowPositionExportStringCaller; - - - -class WindowPositionTracker -{ - WindowPosition m_position; - GtkWindow* m_window; - - static gboolean configure( GtkWidget* widget, GdkEventConfigure *event, WindowPositionTracker* self ){ - //globalOutputStream() << "WindowPositionTracker::configure\n"; - self->m_position = WindowPosition( event->x, event->y, event->width, event->height ); - return FALSE; - } - -public: - WindowPositionTracker() - : m_position( c_default_window_pos ), m_window( 0 ){ - } - - void sync( GtkWindow* window ){ - //globalOutputStream() << "WindowPositionTracker::sync\n"; - window_set_position( window, m_position ); - } - - void sync(){ - if( m_window ) - sync( m_window ); - } - - /** need to reapply pos on every hiding to keep wnd pos after hide+show (flickering between two positions, if doing on showing) - this stuff is weird: some wnds, like entity list, keep pos on hide/show... until you resize them -) - some, like floating xy/cam/groupdialog do not; if you remove glwidget from floating xy - it does xD - if you gtk_window_set_position( window, GTK_WIN_POS_CENTER_ALWAYS ), they do keep it, except of random centering after resizing (ms windows) - but this option doesn't sound healthy; - gtk_window_set_transient_for seems to do some gtk_window_set_position also - old questionable comment on this issue: - workaround for strange gtk behaviour - modifying the contents of a window while it is not visible causes the window position to change without sending a configure_event */ - static gboolean notify_visible( GtkWidget* widget, gpointer dummy, WindowPositionTracker* self ){ - if( !widget_is_visible( GTK_WIDGET( self->m_window ) ) ) - self->sync(); - return FALSE; - } - - void connect( GtkWindow* window ){ - //globalOutputStream() << "WindowPositionTracker::connect\n"; - m_window = window; - sync( window ); - g_signal_connect( G_OBJECT( window ), "configure_event", G_CALLBACK( configure ), this ); - g_signal_connect( G_OBJECT( window ), "notify::visible", G_CALLBACK( notify_visible ), this ); - } - - const WindowPosition& getPosition() const { - //globalOutputStream() << "WindowPositionTracker::getPosition\n"; - return m_position; - } - - //hack - void setPosition( const WindowPosition& position ){ - //globalOutputStream() << "WindowPositionTracker::setPosition\n"; - m_position = position; - } -}; - - -inline void WindowPositionTracker_importString( WindowPositionTracker& self, const char* value ){ - WindowPosition position; - WindowPosition_Parse( position, value ); - self.setPosition( position ); -} -typedef ReferenceCaller1 WindowPositionTrackerImportStringCaller; - -inline void WindowPositionTracker_exportString( const WindowPositionTracker& self, const StringImportCallback& importer ){ - WindowPosition_Write( self.getPosition(), importer ); -} -typedef ConstReferenceCaller1 WindowPositionTrackerExportStringCaller; diff --git a/libs/gtkutil/xorrectangle.h b/libs/gtkutil/xorrectangle.h index 59595cab..a1f0609a 100644 --- a/libs/gtkutil/xorrectangle.h +++ b/libs/gtkutil/xorrectangle.h @@ -25,75 +25,73 @@ #include "igl.h" class XORRectangle { - void draw( const rect_t& rect, const GLenum mode ) const{ - glBegin( mode ); - glVertex2f( rect.min[0], rect.max[1] ); - glVertex2f( rect.max[0], rect.max[1] ); - glVertex2f( rect.max[0], rect.min[1] ); - glVertex2f( rect.min[0], rect.min[1] ); - glEnd(); + void draw( const rect_t& rect, const GLenum mode ) const { + gl().glBegin( mode ); + gl().glVertex2f( rect.min[0], rect.max[1] ); + gl().glVertex2f( rect.max[0], rect.max[1] ); + gl().glVertex2f( rect.max[0], rect.min[1] ); + gl().glVertex2f( rect.min[0], rect.min[1] ); + gl().glEnd(); } public: XORRectangle() { } ~XORRectangle() { } - void set( rect_t rect, int width, int height ) { - if( rect.max[0] - rect.min[0] != 0.f && rect.max[1] - rect.min[1] != 0.f ) { + void render( rect_t rect, int viewWidth, int viewHeight ) { + if( rect.max[0] != rect.min[0] && rect.max[1] != rect.min[1] ) { GlobalOpenGL_debugAssertNoErrors(); - glViewport( 0, 0, width, height ); + gl().glViewport( 0, 0, viewWidth, viewHeight ); // set up viewpoint - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - glOrtho( -1, 1, -1, 1, -100, 100 ); + gl().glMatrixMode( GL_PROJECTION ); + gl().glLoadIdentity(); + gl().glOrtho( -1, 1, -1, 1, -100, 100 ); - glMatrixMode( GL_MODELVIEW ); - glLoadIdentity(); + gl().glMatrixMode( GL_MODELVIEW ); + gl().glLoadIdentity(); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glDisable( GL_DEPTH_TEST ); - glDisable( GL_TEXTURE_2D ); + gl().glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + gl().glDisable( GL_DEPTH_TEST ); + gl().glDisable( GL_TEXTURE_2D ); - if( GlobalOpenGL().GL_1_3() ) { - glDisable( GL_MULTISAMPLE ); - } + gl().glDisable( GL_MULTISAMPLE ); - glEnable( GL_BLEND ); + gl().glEnable( GL_BLEND ); /* additive to handle dark background */ - glBlendFunc( GL_ONE, GL_ONE ); + gl().glBlendFunc( GL_ONE, GL_ONE ); const float r = 10.f; switch ( rect.modifier ) { - case rect_t::eSelect: glColor3f( 1.f / r, .5f / r, 0.f ); break; - case rect_t::eDeselect: glColor3f( 0.f, 0.f, 1.f / r ); break; - case rect_t::eToggle: glColor3f( 1.f / r, 1.f / r, 1.f / r ); break; + case rect_t::eSelect: gl().glColor3f( 1.f / r, .5f / r, 0.f ); break; + case rect_t::eDeselect: gl().glColor3f( 0.f, 0.f, 1.f / r ); break; + case rect_t::eToggle: gl().glColor3f( 1.f / r, 1.f / r, 1.f / r ); break; } draw( rect, GL_QUADS ); /* filter to handle bright background */ - glBlendFunc( GL_ZERO, GL_SRC_COLOR ); + gl().glBlendFunc( GL_ZERO, GL_SRC_COLOR ); switch ( rect.modifier ) { - case rect_t::eSelect: glColor3f( 1.f, .9f, 0.7f ); break; - case rect_t::eDeselect: glColor3f( 0.8f, 0.8f, 1.f ); break; - case rect_t::eToggle: glColor3f( .8f, .8f, .8f ); break; + case rect_t::eSelect: gl().glColor3f( 1.f, .9f, 0.7f ); break; + case rect_t::eDeselect: gl().glColor3f( 0.8f, 0.8f, 1.f ); break; + case rect_t::eToggle: gl().glColor3f( .8f, .8f, .8f ); break; } draw( rect, GL_QUADS ); /* alpha blend on top */ - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + gl().glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); const float a = .3f; switch ( rect.modifier ) { - case rect_t::eSelect: glColor4f( 1.f, .5f, 0.f, a ); break; - case rect_t::eDeselect: glColor4f( 0.f, 0.f, 1.f, a ); break; - case rect_t::eToggle: glColor4f( 1.f, 1.f, 1.f, a ); break; + case rect_t::eSelect: gl().glColor4f( 1.f, .5f, 0.f, a ); break; + case rect_t::eDeselect: gl().glColor4f( 0.f, 0.f, 1.f, a ); break; + case rect_t::eToggle: gl().glColor4f( 1.f, 1.f, 1.f, a ); break; } draw( rect, GL_QUADS ); - glDisable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - glLineWidth( 1 ); - glColor3f( 1.f, .5f, 0.f ); + gl().glDisable( GL_BLEND ); + gl().glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + gl().glLineWidth( 1 ); + gl().glColor3f( 1.f, .5f, 0.f ); draw( rect, GL_LINE_LOOP ); GlobalOpenGL_debugAssertNoErrors(); diff --git a/libs/maplib.h b/libs/maplib.h index 288f89e0..8a2cbb2c 100644 --- a/libs/maplib.h +++ b/libs/maplib.h @@ -63,7 +63,7 @@ public: UndoFileChangeTracker() : m_size( 0 ), m_saved( MAPFILE_MAX_CHANGES ), m_pending( 0 ){ } void print(){ - globalOutputStream() << "saved: " << Unsigned( m_saved ) << " size: " << Unsigned( m_size ) << "\n"; + globalOutputStream() << "saved: " << m_saved << " size: " << m_size << "\n"; } void push(){ diff --git a/libs/math/aabb.h b/libs/math/aabb.h index fcfe380e..dcf689e6 100644 --- a/libs/math/aabb.h +++ b/libs/math/aabb.h @@ -183,9 +183,9 @@ inline unsigned int aabb_classify_plane( const AABB& aabb, const Plane3& plane ) inline unsigned int aabb_oriented_classify_plane( const AABB& aabb, const Matrix4& transform, const Plane3& plane ){ double distance_origin = vector3_dot( plane.normal(), aabb.origin ) + plane.dist(); - if ( fabs( distance_origin ) < ( fabs( aabb.extents[0] * vector3_dot( plane.normal(), vector4_to_vector3( transform.x() ) ) ) - + fabs( aabb.extents[1] * vector3_dot( plane.normal(), vector4_to_vector3( transform.y() ) ) ) - + fabs( aabb.extents[2] * vector3_dot( plane.normal(), vector4_to_vector3( transform.z() ) ) ) ) ) { + if ( fabs( distance_origin ) < ( fabs( aabb.extents[0] * vector3_dot( plane.normal(), transform.x().vec3() ) ) + + fabs( aabb.extents[1] * vector3_dot( plane.normal(), transform.y().vec3() ) ) + + fabs( aabb.extents[2] * vector3_dot( plane.normal(), transform.z().vec3() ) ) ) ) { return 1; // partially inside } else if ( distance_origin < 0 ) { @@ -208,9 +208,9 @@ inline void aabb_corners( const AABB& aabb, Vector3 corners[8] ){ } inline void aabb_corners_oriented( const AABB& aabb, const Matrix4& rotation, Vector3 corners[8] ){ - Vector3 x = vector4_to_vector3( rotation.x() ) * aabb.extents.x(); - Vector3 y = vector4_to_vector3( rotation.y() ) * aabb.extents.y(); - Vector3 z = vector4_to_vector3( rotation.z() ) * aabb.extents.z(); + Vector3 x = rotation.x().vec3() * aabb.extents.x(); + Vector3 y = rotation.y().vec3() * aabb.extents.y(); + Vector3 z = rotation.z().vec3() * aabb.extents.z(); corners[0] = aabb.origin + -x + y + z; corners[1] = aabb.origin + x + y + z; @@ -232,16 +232,16 @@ inline void aabb_planes( const AABB& aabb, Plane3 planes[6] ){ } inline void aabb_planes_oriented( const AABB& aabb, const Matrix4& rotation, Plane3 planes[6] ){ - double x = vector3_dot( vector4_to_vector3( rotation.x() ), aabb.origin ); - double y = vector3_dot( vector4_to_vector3( rotation.y() ), aabb.origin ); - double z = vector3_dot( vector4_to_vector3( rotation.z() ), aabb.origin ); + double x = vector3_dot( rotation.x().vec3(), aabb.origin ); + double y = vector3_dot( rotation.y().vec3(), aabb.origin ); + double z = vector3_dot( rotation.z().vec3(), aabb.origin ); - planes[0] = Plane3( vector4_to_vector3( rotation.x() ), x + aabb.extents[0] ); - planes[1] = Plane3( -vector4_to_vector3( rotation.x() ), -( x - aabb.extents[0] ) ); - planes[2] = Plane3( vector4_to_vector3( rotation.y() ), y + aabb.extents[1] ); - planes[3] = Plane3( -vector4_to_vector3( rotation.y() ), -( y - aabb.extents[1] ) ); - planes[4] = Plane3( vector4_to_vector3( rotation.z() ), z + aabb.extents[2] ); - planes[5] = Plane3( -vector4_to_vector3( rotation.z() ), -( z - aabb.extents[2] ) ); + planes[0] = Plane3( rotation.x().vec3(), x + aabb.extents[0] ); + planes[1] = Plane3( -rotation.x().vec3(), -( x - aabb.extents[0] ) ); + planes[2] = Plane3( rotation.y().vec3(), y + aabb.extents[1] ); + planes[3] = Plane3( -rotation.y().vec3(), -( y - aabb.extents[1] ) ); + planes[4] = Plane3( rotation.z().vec3(), z + aabb.extents[2] ); + planes[5] = Plane3( -rotation.z().vec3(), -( z - aabb.extents[2] ) ); } const Vector3 aabb_normals[6] = { diff --git a/libs/math/frustum.h b/libs/math/frustum.h index 57db6280..1b353890 100644 --- a/libs/math/frustum.h +++ b/libs/math/frustum.h @@ -549,9 +549,9 @@ inline double plane_distance_to_point( const Plane3& plane, const Vector3& point } inline double plane_distance_to_oriented_extents( const Plane3& plane, const Vector3& extents, const Matrix4& orientation ){ - return fabs( extents[0] * vector3_dot( plane.normal(), vector4_to_vector3( orientation.x() ) ) ) - + fabs( extents[1] * vector3_dot( plane.normal(), vector4_to_vector3( orientation.y() ) ) ) - + fabs( extents[2] * vector3_dot( plane.normal(), vector4_to_vector3( orientation.z() ) ) ); + return fabs( extents[0] * vector3_dot( plane.normal(), orientation.x().vec3() ) ) + + fabs( extents[1] * vector3_dot( plane.normal(), orientation.y().vec3() ) ) + + fabs( extents[2] * vector3_dot( plane.normal(), orientation.z().vec3() ) ); } /// \brief Return false if \p aabb with \p orientation is partially or completely outside \p plane. @@ -622,11 +622,11 @@ inline bool viewer_test_triangle( const Vector4& viewer, const Vector3& p0, cons inline Vector4 viewer_from_transformed_viewer( const Vector4& viewer, const Matrix4& transform ){ if ( viewer[3] == 0 ) { - return Vector4( matrix4_transformed_direction( transform, vector4_to_vector3( viewer ) ), 0 ); + return Vector4( matrix4_transformed_direction( transform, viewer.vec3() ), 0 ); } else { - return Vector4( matrix4_transformed_point( transform, vector4_to_vector3( viewer ) ), viewer[3] ); + return Vector4( matrix4_transformed_point( transform, viewer.vec3() ), viewer[3] ); } } diff --git a/libs/math/matrix.h b/libs/math/matrix.h index c34950e8..89013115 100644 --- a/libs/math/matrix.h +++ b/libs/math/matrix.h @@ -274,8 +274,8 @@ enum Matrix4Handedness inline Matrix4Handedness matrix4_handedness( const Matrix4& self ){ return ( vector3_dot( - vector3_cross( vector4_to_vector3( self.x() ), vector4_to_vector3( self.y() ) ), - vector4_to_vector3( self.z() ) + vector3_cross( self.x().vec3(), self.y().vec3() ), + self.z().vec3() ) < 0.0 ) ? MATRIX4_LEFTHANDED : MATRIX4_RIGHTHANDED; @@ -600,7 +600,7 @@ inline Matrix4 matrix4_translation_for_vec3( const Vector3& translation ){ /// \brief Returns the translation part of \p self. inline Vector3 matrix4_get_translation_vec3( const Matrix4& self ){ - return vector4_to_vector3( self.t() ); + return self.t().vec3(); } /// \brief Concatenates \p self with \p translation. @@ -1118,9 +1118,9 @@ inline Matrix4 matrix4_scale_for_vec3( const Vector3& scale ){ /// \p self must be affine and orthogonal to produce a meaningful result. inline Vector3 matrix4_get_scale_vec3( const Matrix4& self ){ return Vector3( - static_cast( vector3_length( vector4_to_vector3( self.x() ) ) ), - static_cast( vector3_length( vector4_to_vector3( self.y() ) ) ), - static_cast( vector3_length( vector4_to_vector3( self.z() ) ) ) + static_cast( vector3_length( self.x().vec3() ) ), + static_cast( vector3_length( self.y().vec3() ) ), + static_cast( vector3_length( self.z().vec3() ) ) ); } diff --git a/libs/pivot.h b/libs/pivot.h index 50f6f060..f3a88335 100644 --- a/libs/pivot.h +++ b/libs/pivot.h @@ -27,13 +27,13 @@ inline void billboard_viewplaneOriented( Matrix4& rotation, const Matrix4& world2screen ){ #if 1 rotation = g_matrix4_identity; - Vector3 x( vector3_normalised( vector4_to_vector3( world2screen.x() ) ) ); - Vector3 y( vector3_normalised( vector4_to_vector3( world2screen.y() ) ) ); - Vector3 z( vector3_normalised( vector4_to_vector3( world2screen.z() ) ) ); - vector4_to_vector3( rotation.y() ) = Vector3( x.y(), y.y(), z.y() ); - vector4_to_vector3( rotation.z() ) = vector3_negated( Vector3( x.z(), y.z(), z.z() ) ); - vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); - vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); + Vector3 x( vector3_normalised( world2screen.x().vec3() ) ); + Vector3 y( vector3_normalised( world2screen.y().vec3() ) ); + Vector3 z( vector3_normalised( world2screen.z().vec3() ) ); + rotation.y().vec3() = Vector3( x.y(), y.y(), z.y() ); + rotation.z().vec3() = vector3_negated( Vector3( x.z(), y.z(), z.z() ) ); + rotation.x().vec3() = vector3_normalised( vector3_cross( rotation.y().vec3(), rotation.z().vec3() ) ); + rotation.y().vec3() = vector3_cross( rotation.z().vec3(), rotation.x().vec3() ); #else Matrix4 screen2world( matrix4_full_inverse( world2screen ) ); @@ -65,10 +65,10 @@ inline void billboard_viewplaneOriented( Matrix4& rotation, const Matrix4& world ); rotation = g_matrix4_identity; - vector4_to_vector3( rotation.y() ) = vector3_normalised( vector3_subtracted( up, near_ ) ); - vector4_to_vector3( rotation.z() ) = vector3_normalised( vector3_subtracted( near_, far_ ) ); - vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); - vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); + rotation.y().vec3() = vector3_normalised( vector3_subtracted( up, near_ ) ); + rotation.z().vec3() = vector3_normalised( vector3_subtracted( near_, far_ ) ); + rotation.x().vec3() = vector3_normalised( vector3_cross( rotation.y().vec3(), rotation.z().vec3() ) ); + rotation.y().vec3() = vector3_cross( rotation.z().vec3(), rotation.x().vec3() ); #endif } @@ -77,10 +77,10 @@ inline void billboard_viewpointOriented( Matrix4& rotation, const Matrix4& world #if 1 rotation = g_matrix4_identity; - vector4_to_vector3( rotation.y() ) = vector3_normalised( vector4_to_vector3( screen2world.y() ) ); - vector4_to_vector3( rotation.z() ) = vector3_negated( vector3_normalised( vector4_to_vector3( screen2world.z() ) ) ); - vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); - vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); + rotation.y().vec3() = vector3_normalised( screen2world.y().vec3() ); + rotation.z().vec3() = vector3_negated( vector3_normalised( screen2world.z().vec3() ) ); + rotation.x().vec3() = vector3_normalised( vector3_cross( rotation.y().vec3(), rotation.z().vec3() ) ); + rotation.y().vec3() = vector3_cross( rotation.z().vec3(), rotation.x().vec3() ); #else Vector3 near_( vector4_projected( @@ -110,10 +110,10 @@ inline void billboard_viewpointOriented( Matrix4& rotation, const Matrix4& world ); rotation = g_matrix4_identity; - vector4_to_vector3( rotation.y() ) = vector3_normalised( vector3_subtracted( up, near_ ) ); - vector4_to_vector3( rotation.z() ) = vector3_normalised( vector3_subtracted( near_, far_ ) ); - vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); - vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); + rotation.y().vec3() = vector3_normalised( vector3_subtracted( up, near_ ) ); + rotation.z().vec3() = vector3_normalised( vector3_subtracted( near_, far_ ) ); + rotation.x().vec3() = vector3_normalised( vector3_cross( rotation.y().vec3(), rotation.z().vec3() ) ); + rotation.y().vec3() = vector3_cross( rotation.z().vec3(), rotation.x().vec3() ); #endif } @@ -139,9 +139,9 @@ inline void ConstructDevice2Object( Matrix4& device2object, const Matrix4& objec //! S = ( Inverse(Object2Screen *post ScaleOf(Object2Screen) ) *post Object2Screen inline void pivot_scale( Matrix4& scale, const Matrix4& pivot2screen ){ Matrix4 pre_scale( g_matrix4_identity ); - pre_scale[0] = static_cast( vector3_length( vector4_to_vector3( pivot2screen.x() ) ) ); - pre_scale[5] = static_cast( vector3_length( vector4_to_vector3( pivot2screen.y() ) ) ); - pre_scale[10] = static_cast( vector3_length( vector4_to_vector3( pivot2screen.z() ) ) ); + pre_scale[0] = static_cast( vector3_length( pivot2screen.x().vec3() ) ); + pre_scale[5] = static_cast( vector3_length( pivot2screen.y().vec3() ) ); + pre_scale[10] = static_cast( vector3_length( pivot2screen.z().vec3() ) ); scale = pivot2screen; matrix4_multiply_by_matrix4( scale, pre_scale ); @@ -194,7 +194,7 @@ inline void Pivot2World_viewpointSpace( Matrix4& manip2world, Vector3& axis, con matrix4_multiply_by_matrix4( manip2world, scale ); billboard_viewpointOriented( scale, pivot2screen ); - axis = vector4_to_vector3( scale.z() ); + axis = scale.z().vec3(); matrix4_multiply_by_matrix4( manip2world, scale ); pivot_perspective( scale, pivot2screen ); @@ -259,9 +259,9 @@ public: if ( m_vertices.data() == 0 ) { return; } - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex ); - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_vertices.data()->colour ); - glDrawArrays( GL_LINES, 0, m_vertices.size() ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_vertices.data()->colour ); + gl().glDrawArrays( GL_LINES, 0, m_vertices.size() ); } void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const { diff --git a/libs/render.h b/libs/render.h index 78fcc24a..03383886 100644 --- a/libs/render.h +++ b/libs/render.h @@ -778,7 +778,7 @@ struct DepthTestedPointVertex } ~DepthTestedPointVertex(){ if( query != 0 ) - glDeleteQueries( 1, &query ); + gl().glDeleteQueries( 1, &query ); } DepthTestedPointVertex( Vertex3f _vertex ) : colour( Colour4b( 255, 255, 255, 255 ) ), vertex( _vertex ){ @@ -843,8 +843,8 @@ inline ArbitraryMeshVertex arbitrarymeshvertex_quantised( const ArbitraryMeshVer /// \brief Sets up the OpenGL colour and vertex arrays for \p array. template inline void pointvertex_gl_array( const PointVertex_t* array ){ - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex_t ), &array->colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex_t ), &array->vertex ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex_t ), &array->colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex_t ), &array->vertex ); } template @@ -859,12 +859,12 @@ public: void render( RenderStateFlags state ) const { #define NV_DRIVER_BUG 0 #if NV_DRIVER_BUG - glColorPointer( 4, GL_UNSIGNED_BYTE, 0, 0 ); - glVertexPointer( 3, GL_FLOAT, 0, 0 ); - glDrawArrays( GL_TRIANGLE_FAN, 0, 0 ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, 0, 0 ); + gl().glVertexPointer( 3, GL_FLOAT, 0, 0 ); + gl().glDrawArrays( GL_TRIANGLE_FAN, 0, 0 ); #endif pointvertex_gl_array( m_array.data() ); - glDrawArrays( m_mode, 0, GLsizei( m_array.size() ) ); + gl().glDrawArrays( m_mode, 0, GLsizei( m_array.size() ) ); } }; @@ -879,7 +879,7 @@ public: void render( RenderStateFlags state ) const { pointvertex_gl_array( &m_vector.front() ); - glDrawArrays( m_mode, 0, GLsizei( m_vector.size() ) ); + gl().glDrawArrays( m_mode, 0, GLsizei( m_vector.size() ) ); } std::size_t size() const { @@ -911,7 +911,7 @@ public: void render( RenderStateFlags state ) const { pointvertex_gl_array( m_vertices.data() ); - glDrawArrays( m_mode, 0, m_vertices.size() ); + gl().glDrawArrays( m_mode, 0, m_vertices.size() ); } }; @@ -928,24 +928,24 @@ public: void render( RenderStateFlags state ) const { #if 1 pointvertex_gl_array( m_vertices.data() ); - glDrawElements( m_mode, GLsizei( m_indices.size() ), RenderIndexTypeID, m_indices.data() ); + gl().glDrawElements( m_mode, GLsizei( m_indices.size() ), RenderIndexTypeID, m_indices.data() ); #else - glBegin( m_mode ); + gl().glBegin( m_mode ); if ( state & RENDER_COLOURARRAY != 0 ) { for ( std::size_t i = 0; i < m_indices.size(); ++i ) { - glColor4ubv( &m_vertices[m_indices[i]].colour.r ); - glVertex3fv( &m_vertices[m_indices[i]].vertex.x ); + gl().glColor4ubv( &m_vertices[m_indices[i]].colour.r ); + gl().glVertex3fv( &m_vertices[m_indices[i]].vertex.x ); } } else { for ( std::size_t i = 0; i < m_indices.size(); ++i ) { - glVertex3fv( &m_vertices[m_indices[i]].vertex.x ); + gl().glVertex3fv( &m_vertices[m_indices[i]].vertex.x ); } } - glEnd(); + gl().glEnd(); #endif } }; @@ -962,7 +962,7 @@ public: if( state & RENDER_COLOURWRITE ){ // render depending on visibility for( auto& p : m_array ){ GLuint sampleCount; - glGetQueryObjectuiv( p.query, GL_QUERY_RESULT, &sampleCount ); + gl().glGetQueryObjectuiv( p.query, GL_QUERY_RESULT, &sampleCount ); if ( sampleCount == 0 ){ p.colour = colour_occluded; } @@ -971,16 +971,16 @@ public: } } pointvertex_gl_array( m_array.data() ); - glDrawArrays( m_mode, 0, GLsizei( m_array.size() ) ); + gl().glDrawArrays( m_mode, 0, GLsizei( m_array.size() ) ); } else{ // test visibility for( auto& p : m_array ){ if( p.query == 0 ) - glGenQueries( 1, &p.query ); - glBeginQuery( GL_SAMPLES_PASSED, p.query ); - glVertexPointer( 3, GL_FLOAT, 0, &p.vertex ); - glDrawArrays( m_mode, 0, 1 ); - glEndQuery( GL_SAMPLES_PASSED ); + gl().glGenQueries( 1, &p.query ); + gl().glBeginQuery( GL_SAMPLES_PASSED, p.query ); + gl().glVertexPointer( 3, GL_FLOAT, 0, &p.vertex ); + gl().glDrawArrays( m_mode, 0, 1 ); + gl().glEndQuery( GL_SAMPLES_PASSED ); } } } @@ -1268,7 +1268,7 @@ public: texFree(); } void texAlloc( const char* text, const Vector3& color01 ){ - glGenTextures( 1, &tex ); + gl().glGenTextures( 1, &tex ); if( tex > 0 ){ const BasicVector3 colour = color01 * 255.f; GlobalOpenGL().m_font->renderString( text, tex, colour.data(), width, height ); @@ -1276,13 +1276,13 @@ public: } void texFree(){ if( tex > 0 ){ - glDeleteTextures( 1, &tex ); + gl().glDeleteTextures( 1, &tex ); tex = 0; } } void render( RenderStateFlags state ) const { if( tex > 0 ){ - glBindTexture( GL_TEXTURE_2D, tex ); + gl().glBindTexture( GL_TEXTURE_2D, tex ); //Here we draw the texturemaped quads. //The bitmap that we got from FreeType was not //oriented quite like we would like it to be, @@ -1297,260 +1297,21 @@ public: { subTex / 3.f, 0 }, { ( subTex + 1 ) / 3.f, 0 }, { ( subTex + 1 ) / 3.f, 1 } }; - glVertexPointer( 2, GL_FLOAT, 0, verts ); - glTexCoordPointer( 2, GL_FLOAT, 0, coords ); - glDrawArrays( GL_QUADS, 0, 4 ); + gl().glVertexPointer( 2, GL_FLOAT, 0, verts ); + gl().glTexCoordPointer( 2, GL_FLOAT, 0, coords ); + gl().glDrawArrays( GL_QUADS, 0, 4 ); #else // this is faster :0 - glBegin( GL_QUADS ); - glTexCoord2f( subTex / 3.f, 1 ); - glVertex2f( screenPos.x(), screenPos.y() ); - glTexCoord2f( subTex / 3.f, 0 ); - glVertex2f( screenPos.x(), screenPos.y() + height + .01f ); - glTexCoord2f( ( subTex + 1 ) / 3.f, 0 ); - glVertex2f( screenPos.x() + width + .01f, screenPos.y() + height + .01f ); - glTexCoord2f( ( subTex + 1 ) / 3.f, 1 ); - glVertex2f( screenPos.x() + width + .01f, screenPos.y() ); - glEnd(); + gl().glBegin( GL_QUADS ); + gl().glTexCoord2f( subTex / 3.f, 1 ); + gl().glVertex2f( screenPos.x(), screenPos.y() ); + gl().glTexCoord2f( subTex / 3.f, 0 ); + gl().glVertex2f( screenPos.x(), screenPos.y() + height + .01f ); + gl().glTexCoord2f( ( subTex + 1 ) / 3.f, 0 ); + gl().glVertex2f( screenPos.x() + width + .01f, screenPos.y() + height + .01f ); + gl().glTexCoord2f( ( subTex + 1 ) / 3.f, 1 ); + gl().glVertex2f( screenPos.x() + width + .01f, screenPos.y() ); + gl().glEnd(); #endif } } }; - - - -/////////////////////////////////////////////////////////////////////////////// -// check FBO completeness -/////////////////////////////////////////////////////////////////////////////// -inline bool checkFramebufferStatus() { - // check FBO status - GLenum status = glCheckFramebufferStatus( GL_FRAMEBUFFER ); - switch( status ) { - case GL_FRAMEBUFFER_COMPLETE: -// globalErrorStream() << "Framebuffer complete.\n"; - return true; - - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - globalErrorStream() << "[ERROR] Framebuffer incomplete: Attachment is NOT complete.\n"; - return false; - - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - globalErrorStream() << "[ERROR] Framebuffer incomplete: No image is attached to FBO.\n"; - return false; -/* - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: - globalErrorStream() << "[ERROR] Framebuffer incomplete: Attached images have different dimensions.\n"; - return false; - - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS: - globalErrorStream() << "[ERROR] Framebuffer incomplete: Color attached images have different internal formats.\n"; - return false; -*/ - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: - globalErrorStream() << "[ERROR] Framebuffer incomplete: Draw buffer.\n"; - return false; - - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: - globalErrorStream() << "[ERROR] Framebuffer incomplete: Read buffer.\n"; - return false; - - case GL_FRAMEBUFFER_UNSUPPORTED: - globalErrorStream() << "[ERROR] Framebuffer incomplete: Unsupported by FBO implementation.\n"; - return false; - - default: - globalErrorStream() << "[ERROR] Framebuffer incomplete: Unknown error.\n"; - return false; - } -} - - -class FBO -{ -public: - FBO(): - _constructed( false ), - _has_depth( false ), - _width( 0 ), - _height( 0 ), - _fbo( 0 ), - _tex( 0 ), - _depth( 0 ), - _color( 0 ){ - } - virtual ~FBO(){ - reset( 0, 0, 0, false ); - } - virtual void reset( int width, int height, int samples, bool has_depth ){ - _width = width; - _height = height; - _samples = samples; - _has_depth = has_depth; - if( _depth ) - glDeleteRenderbuffers( 1, &_depth ); - _depth = 0; - if( _color ) - glDeleteRenderbuffers( 1, &_color ); - _color = 0; - if( _fbo ) - glDeleteFramebuffers( 1, &_fbo ); - _fbo = 0; - _constructed = false; - } - virtual void start(){ - if( !_constructed ){ - construct(); - } - setMultisample(); - glBindFramebuffer( GL_FRAMEBUFFER, _fbo ); - } - virtual void save(){ - blit(); - } - virtual void blit(){ - glBindFramebuffer( GL_READ_FRAMEBUFFER, _fbo ); - glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ); - //glDrawBuffer( GL_BACK ); - glBlitFramebuffer( 0, 0, _width, _height, 0, 0, _width, _height, GL_COLOR_BUFFER_BIT, GL_NEAREST ); - glBindFramebuffer( GL_FRAMEBUFFER, 0 ); - } -protected: - bool _constructed; - bool _has_depth; - int _width; - int _height; - int _samples; - GLuint _fbo; - GLuint _tex; - GLuint _depth; - GLuint _color; - void setMultisample(){ - if( GlobalOpenGL().GL_1_3() ) { - if( _samples ) - glEnable( GL_MULTISAMPLE ); - else - glDisable( GL_MULTISAMPLE ); - } - } - virtual void construct() { - int curSamples; - glGetIntegerv( GL_SAMPLES, &curSamples ); - if( curSamples > 0 && _samples != 0 ){ - _samples = curSamples; - } - else{ - int maxSamples; - glGetIntegerv( GL_MAX_SAMPLES, &maxSamples ); - if( _samples > maxSamples ){ - _samples = maxSamples; - } - } -// globalErrorStream() << _samples << " samples\n"; - setMultisample(); - - glGenFramebuffers( 1, &_fbo ); - glBindFramebuffer( GL_FRAMEBUFFER, _fbo ); - - // Color buffer - glGenRenderbuffers( 1, &_color ); - glBindRenderbuffer( GL_RENDERBUFFER, _color ); - glRenderbufferStorageMultisample( GL_RENDERBUFFER, _samples, GL_RGBA8, _width, _height ); - glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _color ); - - if( _has_depth ){ - // Depth buffer - glGenRenderbuffers( 1, &_depth ); - glBindRenderbuffer( GL_RENDERBUFFER, _depth ); - glRenderbufferStorageMultisample( GL_RENDERBUFFER, _samples, GL_DEPTH_COMPONENT, _width, _height ); - glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depth ); - } - - if( !checkFramebufferStatus() && _samples > 0 ){ - globalErrorStream() << "Falling back to no multisampling.\n"; - _samples = 0; - reset( _width, _height, 0, _has_depth ); - construct(); - } - - _constructed = true; - } -private: -}; - -class FBO_fallback : public FBO -{ -public: - ~FBO_fallback(){ - reset( 0, 0, 0, false ); - } - void reset( int width, int height, int samples, bool has_depth ){ - _width = width; - _height = height; - if( _tex ) - glDeleteTextures( 1, &_tex ); - _tex = 0; - _constructed = false; - } - void start(){ - if( !_constructed ){ - construct(); - } - } - void save(){ - glBindTexture( GL_TEXTURE_2D, _tex ); - glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 0, 0, _width, _height, 0 ); - //glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_nWidth, m_nHeight ); - glBindTexture( GL_TEXTURE_2D, 0 ); - } - void blit(){ - glViewport( 0, 0, _width, _height ); - - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - glOrtho( 0, 1, 0, 1, -100, 100 ); - - glMatrixMode( GL_MODELVIEW ); - glLoadIdentity(); - - glDisable( GL_LINE_STIPPLE ); - glDisableClientState( GL_TEXTURE_COORD_ARRAY ); - glDisableClientState( GL_NORMAL_ARRAY ); - glDisableClientState( GL_COLOR_ARRAY ); - glDisable( GL_LIGHTING ); - glDisable( GL_COLOR_MATERIAL ); - glDisable( GL_DEPTH_TEST ); - glDisable( GL_TEXTURE_1D ); - - glEnable( GL_TEXTURE_2D ); - glDisable( GL_BLEND ); - - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glBindTexture( GL_TEXTURE_2D, _tex ); - - glColor4f( 1.f, 1.f, 1.f, 1.f ); - glBegin( GL_QUADS ); - - glTexCoord2i( 0, 0 ); - glVertex2i( 0, 0 ); - glTexCoord2i( 0, 1 ); - glVertex2i( 0, 1 ); - glTexCoord2i( 1, 1 ); - glVertex2i( 1, 1 ); - glTexCoord2i( 1, 0 ); - glVertex2i( 1, 0 ); - glEnd(); - glBindTexture( GL_TEXTURE_2D, 0 ); - } -protected: - void construct() { - glGenTextures( 1, &_tex ); - glEnable( GL_TEXTURE_2D ); - glBindTexture( GL_TEXTURE_2D, _tex ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - glBindTexture( GL_TEXTURE_2D, 0 ); - _constructed = true; - } -private: -}; diff --git a/libs/scenelib.h b/libs/scenelib.h index e34ca6fc..0907b5aa 100644 --- a/libs/scenelib.h +++ b/libs/scenelib.h @@ -24,7 +24,6 @@ #include "iscenegraph.h" #include "iselection.h" -#include "warnings.h" #include #include diff --git a/libs/script/scripttokeniser.h b/libs/script/scripttokeniser.h index 08276918..b1ae3601 100644 --- a/libs/script/scripttokeniser.h +++ b/libs/script/scripttokeniser.h @@ -109,7 +109,7 @@ class ScriptTokeniser final : public Tokeniser { case eNewline: if ( !m_crossline ) { - globalErrorStream() << Unsigned( getLine() ) << ":" << Unsigned( getColumn() ) << ": unexpected end-of-line before token\n"; + globalErrorStream() << getLine() << ":" << getColumn() << ": unexpected end-of-line before token\n"; return false; } break; @@ -162,7 +162,7 @@ class ScriptTokeniser final : public Tokeniser { case eNewline: if ( m_crossline ) { - globalErrorStream() << Unsigned( getLine() ) << ":" << Unsigned( getColumn() ) << ": unexpected end-of-line in quoted token\n"; + globalErrorStream() << getLine() << ":" << getColumn() << ": unexpected end-of-line in quoted token\n"; return false; } break; diff --git a/libs/script/scripttokenwriter.h b/libs/script/scripttokenwriter.h index bdee5d80..b2f38db1 100644 --- a/libs/script/scripttokenwriter.h +++ b/libs/script/scripttokenwriter.h @@ -53,7 +53,7 @@ public: } void writeUnsigned( std::size_t i ){ writeSeparator(); - m_ostream << Unsigned( i ); + m_ostream << i; } void writeFloat( double f ){ writeSeparator(); diff --git a/libs/stream/textstream.h b/libs/stream/textstream.h index 3c20f42c..2e0b0a22 100644 --- a/libs/stream/textstream.h +++ b/libs/stream/textstream.h @@ -201,6 +201,13 @@ inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const return ostream; } +#elif defined ( _WIN32 ) || defined ( __LP32__ ) + +// template +// inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const size_t i ){ +// return ostream_write( ostream, Unsigned( i ) ); +// } + #endif /// \brief Writes a null-terminated \p string to \p ostream. @@ -439,28 +446,26 @@ public: template class BufferedTextOutputStream : public TextOutputStream { - TextOutputStreamType outputStream; + TextOutputStreamType& outputStream; char m_buffer[SIZE]; - char* m_cur; - public: - BufferedTextOutputStream( TextOutputStreamType& outputStream ) : outputStream( outputStream ), m_cur( m_buffer ){ + BufferedTextOutputStream( TextOutputStreamType& outputStream ) : outputStream( outputStream ) { } ~BufferedTextOutputStream(){ - outputStream.write( m_buffer, m_cur - m_buffer ); } std::size_t write( const char* buffer, std::size_t length ){ std::size_t remaining = length; for (;; ) { - std::size_t n = std::min( remaining, std::size_t( ( m_buffer + SIZE ) - m_cur ) ); - m_cur = std::copy( buffer, buffer + n, m_cur ); + const std::size_t n = std::min( remaining, std::size_t( SIZE ) ); + std::copy( buffer, buffer + n, m_buffer ); remaining -= n; + buffer += n; if ( remaining == 0 ) { + outputStream.write( m_buffer, n ); return 0; } outputStream.write( m_buffer, SIZE ); - m_cur = m_buffer; } } }; diff --git a/libs/string/pooledstring.h b/libs/string/pooledstring.h index 49d48681..979e7dec 100644 --- a/libs/string/pooledstring.h +++ b/libs/string/pooledstring.h @@ -24,10 +24,10 @@ inline void StringPool_analyse( StringPool& pool ){ pooled += size + 20; ordered.insert( Ordered::value_type( ( *i ).value, ( *i ).key ) ); } - globalOutputStream() << "total: " << Unsigned( total ) << " pooled:" << Unsigned( pooled ) << "\n"; + globalOutputStream() << "total: " << total << " pooled:" << pooled << "\n"; for ( Ordered::iterator i = ordered.begin(); i != ordered.end(); ++i ) { - globalOutputStream() << ( *i ).second << " " << Unsigned( ( *i ).first ) << "\n"; + globalOutputStream() << ( *i ).second << " " << ( *i ).first << "\n"; } } diff --git a/libs/stringio.h b/libs/stringio.h index f85da6ea..be2de011 100644 --- a/libs/stringio.h +++ b/libs/stringio.h @@ -222,7 +222,7 @@ inline bool string_parse_size( const char* string, std::size_t& i ){ #define RETURN_FALSE_IF_FAIL( expression ) do{ if ( !expression ) {return false; } }while( 0 ) inline void Tokeniser_unexpectedError( Tokeniser& tokeniser, const char* token, const char* expected ){ - globalErrorStream() << Unsigned( tokeniser.getLine() ) << ":" << Unsigned( tokeniser.getColumn() ) << ": parse error at '" << ( token != 0 ? token : "#EOF" ) << "': expected '" << expected << "'\n"; + globalErrorStream() << tokeniser.getLine() << ":" << tokeniser.getColumn() << ": parse error at '" << ( token != 0 ? token : "#EOF" ) << "': expected '" << expected << "'\n"; } @@ -233,7 +233,7 @@ inline bool Tokeniser_getFloat( Tokeniser& tokeniser, float& f ){ } //fallback for 1.#IND 1.#INF 1.#QNAN cases, happening sometimes after texture locking algorithms else if ( token != 0 && strstr( token, ".#" ) ) { - globalWarningStream() << "Warning: " << Unsigned( tokeniser.getLine() ) << ":" << Unsigned( tokeniser.getColumn() ) << ": expected parse problem at '" << token << "': wanted '#number'\nProcessing anyway\n"; + globalWarningStream() << "Warning: " << tokeniser.getLine() << ":" << tokeniser.getColumn() << ": expected parse problem at '" << token << "': wanted '#number'\nProcessing anyway\n"; // *strstr( token, ".#" ) = '\0'; return true; } diff --git a/libs/timer.h b/libs/timer.h index 45964b56..4933e1be 100644 --- a/libs/timer.h +++ b/libs/timer.h @@ -43,3 +43,17 @@ public: }; + +class DoubleClickTimer +{ + Timer m_timer; + bool m_fired{}; +public: + void click(){ + m_fired = m_timer.elapsed_msec() < 250; + m_timer.start(); + } + bool fired() const { + return m_fired; + } +}; diff --git a/libs/transformlib.h b/libs/transformlib.h index b1bfc249..8b9b7457 100644 --- a/libs/transformlib.h +++ b/libs/transformlib.h @@ -93,9 +93,9 @@ struct Skew{ inline Matrix4 matrix4_transform_for_components( const Translation& translation, const Rotation& rotation, const Scale& scale, const Skew& skew ){ Matrix4 result( matrix4_rotation_for_quaternion_quantised( rotation ) ); result[skew.index] += skew.amount; - vector4_to_vector3( result.x() ) *= scale.x(); - vector4_to_vector3( result.y() ) *= scale.y(); - vector4_to_vector3( result.z() ) *= scale.z(); + result.x().vec3() *= scale.x(); + result.y().vec3() *= scale.y(); + result.z().vec3() *= scale.z(); result.tx() = translation.x(); result.ty() = translation.y(); result.tz() = translation.z(); diff --git a/libs/undolib.h b/libs/undolib.h index 3ffd227d..e0ed3b50 100644 --- a/libs/undolib.h +++ b/libs/undolib.h @@ -23,7 +23,6 @@ #include "iundo.h" #include "mapfile.h" -#include "warnings.h" #include "generic/callback.h" template diff --git a/libs/xml/xmltextags.cpp b/libs/xml/xmltextags.cpp index d9a40d57..3c8f9ba3 100644 --- a/libs/xml/xmltextags.cpp +++ b/libs/xml/xmltextags.cpp @@ -35,11 +35,13 @@ XmlTagBuilder::~XmlTagBuilder(){ xmlXPathFreeContext( context ); } -bool XmlTagBuilder::CreateXmlDocument(){ +bool XmlTagBuilder::CreateXmlDocument( const char* savefile ){ /* Creates an XML file returns TRUE if the file was created successfully or FALSE when failed */ + if( savefile != nullptr ) + m_savefilename = savefile; xmlTextWriterPtr writer; @@ -129,10 +131,10 @@ bool XmlTagBuilder::AddShaderNode( const char* shader, TextureType textureType, switch ( textureType ) { - case STOCK: + case TextureType::STOCK: xpathPtr = XpathEval( "/root/stock" ); break; - case CUSTOM: + case TextureType::CUSTOM: xpathPtr = XpathEval( "/root/custom" ); }; @@ -150,10 +152,10 @@ bool XmlTagBuilder::AddShaderNode( const char* shader, TextureType textureType, // create a new node and set the node attribute (shader path) switch ( nodeShaderType ) { - case SHADER: + case NodeShaderType::SHADER: newnode = xmlNewNode( NULL, (const xmlChar*)"shader" ); break; - case TEXTURE: + case NodeShaderType::TEXTURE: default: newnode = xmlNewNode( NULL, (const xmlChar*)"texture" ); break; @@ -202,7 +204,7 @@ bool XmlTagBuilder::DeleteShaderNode( const char* shader ){ */ char buffer[256]; - char* expression = GetTagsXpathExpression( buffer, shader, EMPTY ); + char* expression = GetTagsXpathExpression( buffer, shader, NodeTagType::EMPTY ); xmlXPathObjectPtr xpathPtr = XpathEval( expression ); xmlNodeSetPtr nodePtr; @@ -317,7 +319,7 @@ bool XmlTagBuilder::AddShaderTag( const char* shader, const char* content, NodeT // build the XPath expression char buffer[256]; - char* expression = GetTagsXpathExpression( buffer, shader, EMPTY ); + char* expression = GetTagsXpathExpression( buffer, shader, NodeTagType::EMPTY ); xmlXPathObjectPtr xpathPtr = XpathEval( expression ); xmlNodeSetPtr nodePtr; @@ -396,7 +398,6 @@ int XmlTagBuilder::RenameShaderTag( const char* oldtag, CopiedString newtag ){ } } - SaveXmlDoc(); xmlXPathFreeObject( result ); // CHANGED return num; } @@ -411,7 +412,7 @@ bool XmlTagBuilder::DeleteShaderTag( const char* shader, const char* tag ){ */ char buffer[256]; - char* expression = GetTagsXpathExpression( buffer, shader, TAG ); + char* expression = GetTagsXpathExpression( buffer, shader, NodeTagType::TAG ); xmlXPathObjectPtr xpathPtr = XpathEval( expression ); xmlNodeSetPtr nodePtr; if ( xpathPtr ) { @@ -466,7 +467,6 @@ bool XmlTagBuilder::DeleteTag( const char* tag ){ { DeleteShaderTag( iter->c_str(), tag ); } - SaveXmlDoc(); return true; } @@ -486,7 +486,7 @@ void XmlTagBuilder::GetShaderTags( const char* shader, std::vector } else { char buffer[256]; - expression = GetTagsXpathExpression( buffer, shader, TAG ); + expression = GetTagsXpathExpression( buffer, shader, NodeTagType::TAG ); } xmlXPathObjectPtr xpathPtr = XpathEval( expression ); diff --git a/libs/xml/xmltextags.h b/libs/xml/xmltextags.h index 3024e0b1..bc7dfcf5 100644 --- a/libs/xml/xmltextags.h +++ b/libs/xml/xmltextags.h @@ -30,19 +30,21 @@ #include #include -enum NodeTagType +constexpr char SHADERTAG_FILE[] = "shadertags.xml"; + +enum class NodeTagType { TAG, EMPTY }; -enum NodeShaderType +enum class NodeShaderType { SHADER, TEXTURE }; -enum TextureType +enum class TextureType { STOCK, CUSTOM @@ -52,8 +54,8 @@ class XmlTagBuilder { private: CopiedString m_savefilename; - xmlDocPtr doc; - xmlXPathContextPtr context; + xmlDocPtr doc{}; + xmlXPathContextPtr context{}; xmlXPathObjectPtr XpathEval( const char* queryString ){ const xmlChar* expression = (const xmlChar*)queryString; @@ -67,10 +69,10 @@ private: switch ( nodeTagType ) { - case TAG: + case NodeTagType::TAG: strcat( buffer, "']/tag" ); break; - case EMPTY: + case NodeTagType::EMPTY: strcat( buffer, "']" ); }; @@ -81,7 +83,7 @@ public: XmlTagBuilder(); ~XmlTagBuilder(); - bool CreateXmlDocument(); + bool CreateXmlDocument( const char* savefile = nullptr ); bool OpenXmlDoc( const char* file, const char* savefile = 0 ); bool SaveXmlDoc( const char* file ); bool SaveXmlDoc(); diff --git a/plugins/assmodel/model.cpp b/plugins/assmodel/model.cpp index 602c5be4..b13ed1f9 100644 --- a/plugins/assmodel/model.cpp +++ b/plugins/assmodel/model.cpp @@ -103,31 +103,22 @@ public: void render( RenderStateFlags state ) const { if ( ( state & RENDER_BUMP ) != 0 ) { - if ( GlobalShaderCache().useShaderLanguage() ) { - glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->normal ); - glVertexAttribPointerARB( c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->texcoord ); - glVertexAttribPointerARB( c_attr_Tangent, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->tangent ); - glVertexAttribPointerARB( c_attr_Binormal, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->bitangent ); - } - else - { - glVertexAttribPointerARB( 11, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->normal ); - glVertexAttribPointerARB( 8, 2, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->texcoord ); - glVertexAttribPointerARB( 9, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->tangent ); - glVertexAttribPointerARB( 10, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->bitangent ); - } + gl().glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->normal ); + gl().glVertexAttribPointer( c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->texcoord ); + gl().glVertexAttribPointer( c_attr_Tangent, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->tangent ); + gl().glVertexAttribPointer( c_attr_Binormal, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->bitangent ); } else { - glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->normal ); - glTexCoordPointer( 2, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->texcoord ); + gl().glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->normal ); + gl().glTexCoordPointer( 2, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->texcoord ); } - glVertexPointer( 3, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->vertex ); - glDrawElements( GL_TRIANGLES, GLsizei( m_indices.size() ), RenderIndexTypeID, m_indices.data() ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->vertex ); + gl().glDrawElements( GL_TRIANGLES, GLsizei( m_indices.size() ), RenderIndexTypeID, m_indices.data() ); #if defined( _DEBUG ) && !defined( _DEBUG_QUICKER ) GLfloat modelview[16]; - glGetFloatv( GL_MODELVIEW_MATRIX, modelview ); // I know this is slow as hell, but hey - we're in _DEBUG + gl().glGetFloatv( GL_MODELVIEW_MATRIX, modelview ); // I know this is slow as hell, but hey - we're in _DEBUG Matrix4 modelview_inv( modelview[0], modelview[1], modelview[2], modelview[3], modelview[4], modelview[5], modelview[6], modelview[7], @@ -136,17 +127,17 @@ public: matrix4_full_invert( modelview_inv ); Matrix4 modelview_inv_transposed = matrix4_transposed( modelview_inv ); - glBegin( GL_LINES ); + gl().glBegin( GL_LINES ); for ( Array::const_iterator i = m_vertices.begin(); i != m_vertices.end(); ++i ) { Vector3 normal = normal3f_to_vector3( ( *i ).normal ); normal = matrix4_transformed_direction( modelview_inv, vector3_normalised( matrix4_transformed_direction( modelview_inv_transposed, normal ) ) ); // do some magic Vector3 normalTransformed = vector3_added( vertex3f_to_vector3( ( *i ).vertex ), vector3_scaled( normal, 8 ) ); - glVertex3fv( vertex3f_to_array( ( *i ).vertex ) ); - glVertex3fv( vector3_to_array( normalTransformed ) ); + gl().glVertex3fv( vertex3f_to_array( ( *i ).vertex ) ); + gl().glVertex3fv( vector3_to_array( normalTransformed ) ); } - glEnd(); + gl().glEnd(); #endif } diff --git a/plugins/entity/curve.h b/plugins/entity/curve.h index 35b43a9a..cb4704f4 100644 --- a/plugins/entity/curve.h +++ b/plugins/entity/curve.h @@ -40,7 +40,7 @@ public: std::vector m_vertices; void render( RenderStateFlags state ) const { pointvertex_gl_array( &m_vertices.front() ); - glDrawArrays( GL_LINE_STRIP, 0, GLsizei( m_vertices.size() ) ); + gl().glDrawArrays( GL_LINE_STRIP, 0, GLsizei( m_vertices.size() ) ); } }; @@ -94,7 +94,7 @@ inline bool ControlPoints_parse( ControlPoints& controlPoints, const char* value } inline void ControlPoints_write( const ControlPoints& controlPoints, StringOutputStream& value ){ - value << Unsigned( controlPoints.size() ) << " ("; + value << controlPoints.size() << " ("; for ( ControlPoints::const_iterator i = controlPoints.begin(); i != controlPoints.end(); ++i ) { value << " " << ( *i ).x() << " " << ( *i ).y() << " " << ( *i ).z() << " "; diff --git a/plugins/entity/doom3group.cpp b/plugins/entity/doom3group.cpp index 58ba8451..630706d9 100644 --- a/plugins/entity/doom3group.cpp +++ b/plugins/entity/doom3group.cpp @@ -373,7 +373,7 @@ public: } else{ // place name in the middle of the "children cloud" - m_name_origin = extents_valid( childBounds.extents.x() )? childBounds.origin : vector4_to_vector3( localToWorld.t() ); + m_name_origin = extents_valid( childBounds.extents.x() )? childBounds.origin : localToWorld.t().vec3(); m_renderName.render( renderer, volume, g_matrix4_identity, selected, childSelected ); } } @@ -424,17 +424,6 @@ public: typedef MemberCaller TransformChangedCaller; }; -class ControlPointAddBounds -{ - AABB& m_bounds; -public: - ControlPointAddBounds( AABB& bounds ) : m_bounds( bounds ){ - } - void operator()( const Vector3& point ) const { - aabb_extend_by_point_safe( m_bounds, point ); - } -}; - class Doom3GroupInstance : public TargetableInstance, public TransformModifier, @@ -558,8 +547,8 @@ public: const AABB& getSelectedComponentsBounds() const { m_aabb_component = AABB(); - m_curveNURBS.forEachSelected( ControlPointAddBounds( m_aabb_component ) ); - m_curveCatmullRom.forEachSelected( ControlPointAddBounds( m_aabb_component ) ); + m_curveNURBS.forEachSelected( AABBExtendByPoint( m_aabb_component ) ); + m_curveCatmullRom.forEachSelected( AABBExtendByPoint( m_aabb_component ) ); return m_aabb_component; } void gatherSelectedComponents( const Vector3Callback& callback ) const { diff --git a/plugins/entity/group.cpp b/plugins/entity/group.cpp index d69c1cf2..93c16355 100644 --- a/plugins/entity/group.cpp +++ b/plugins/entity/group.cpp @@ -169,7 +169,7 @@ public: void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected, bool childSelected, const AABB& childBounds ) const { if ( m_renderName.excluded_not() ) { // place name in the middle of the "children cloud" - m_name_origin = extents_valid( childBounds.extents.x() )? childBounds.origin : vector4_to_vector3( localToWorld.t() ); + m_name_origin = extents_valid( childBounds.extents.x() )? childBounds.origin : localToWorld.t().vec3(); if ( selected || childSelected || g_showNames ) m_renderName.render( renderer, volume, g_matrix4_identity, selected, childSelected ); @@ -197,7 +197,7 @@ public: // } if ( m_renderName.excluded_not() ) { // place name in the middle of the "children cloud" - m_name_origin = extents_valid( childBounds.extents.x() )? childBounds.origin : vector4_to_vector3( localToWorld.t() ); + m_name_origin = extents_valid( childBounds.extents.x() )? childBounds.origin : localToWorld.t().vec3(); if ( selected || childSelected || ( g_showNames && aabb_fits_view( childBounds, volume.GetModelview(), volume.GetViewport(), g_showNamesRatio ) ) ) m_renderName.render( renderer, volume, g_matrix4_identity, selected, childSelected ); diff --git a/plugins/entity/light.cpp b/plugins/entity/light.cpp index c93d1717..4d1b43cb 100644 --- a/plugins/entity/light.cpp +++ b/plugins/entity/light.cpp @@ -74,7 +74,7 @@ void sphere_draw_fill( const Vector3& origin, float radius, int sides ){ const double dt = c_2pi / static_cast( sides ); const double dp = c_pi / static_cast( sides ); - glBegin( GL_TRIANGLES ); + gl().glBegin( GL_TRIANGLES ); for ( int i = 0; i <= sides - 1; ++i ) { for ( int j = 0; j <= sides - 2; ++j ) @@ -84,32 +84,32 @@ void sphere_draw_fill( const Vector3& origin, float radius, int sides ){ { Vector3 v( vector3_added( origin, vector3_scaled( vector3_for_spherical( t, p ), radius ) ) ); - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); } { Vector3 v( vector3_added( origin, vector3_scaled( vector3_for_spherical( t, p + dp ), radius ) ) ); - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); } { Vector3 v( vector3_added( origin, vector3_scaled( vector3_for_spherical( t + dt, p + dp ), radius ) ) ); - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); } { Vector3 v( vector3_added( origin, vector3_scaled( vector3_for_spherical( t, p ), radius ) ) ); - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); } { Vector3 v( vector3_added( origin, vector3_scaled( vector3_for_spherical( t + dt, p + dp ), radius ) ) ); - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); } { Vector3 v( vector3_added( origin, vector3_scaled( vector3_for_spherical( t + dt, p ), radius ) ) ); - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); } } } @@ -122,21 +122,21 @@ void sphere_draw_fill( const Vector3& origin, float radius, int sides ){ { Vector3 v( vector3_added( origin, vector3_scaled( vector3_for_spherical( t, p ), radius ) ) ); - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); } { Vector3 v( vector3_added( origin, vector3_scaled( vector3_for_spherical( t + dt, p + dp ), radius ) ) ); - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); } { Vector3 v( vector3_added( origin, vector3_scaled( vector3_for_spherical( t + dt, p ), radius ) ) ); - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); } } } - glEnd(); + gl().glEnd(); } void light_draw_radius_fill( const Vector3& origin, const float envelope[3] ){ @@ -202,12 +202,12 @@ void sphere_construct_fill( Vector3 radiiPoints[SPHERE_FILL_POINTS] ){ } void sphere_draw_fill( const Vector3& origin, float radius, const Vector3 radiiPoints[SPHERE_FILL_POINTS] ){ - glBegin( GL_TRIANGLE_STRIP ); + gl().glBegin( GL_TRIANGLE_STRIP ); for ( int i = 0; i < SPHERE_FILL_POINTS; ++i ) { - glVertex3fv( vector3_to_array( vector3_added( origin, vector3_scaled( radiiPoints[i], radius ) ) ) ); + gl().glVertex3fv( vector3_to_array( vector3_added( origin, vector3_scaled( radiiPoints[i], radius ) ) ) ); } - glEnd(); + gl().glEnd(); } #elif 0 // triangles @@ -310,12 +310,12 @@ void sphere_construct_fill( Vector3 radiiPoints[SPHERE_FILL_POINTS] ){ #endif void sphere_draw_fill( const Vector3& origin, float radius, const Vector3 radiiPoints[SPHERE_FILL_POINTS] ){ - glBegin( GL_TRIANGLES ); + gl().glBegin( GL_TRIANGLES ); for ( int i = 0; i < SPHERE_FILL_POINTS; ++i ) { - glVertex3fv( vector3_to_array( vector3_added( origin, vector3_scaled( radiiPoints[i], radius ) ) ) ); + gl().glVertex3fv( vector3_to_array( vector3_added( origin, vector3_scaled( radiiPoints[i], radius ) ) ) ); } - glEnd(); + gl().glEnd(); } #endif @@ -337,57 +337,57 @@ void light_draw_radius_fill( const Vector3& origin, const float envelope[3], con #if 0 //old straight calculations + render void sphere_draw_wire( const Vector3& origin, float radius, int sides ){ { - glBegin( GL_LINE_LOOP ); + gl().glBegin( GL_LINE_LOOP ); for ( int i = 0; i <= sides; i++ ) { double ds = sin( ( i * 2 * c_pi ) / sides ); double dc = cos( ( i * 2 * c_pi ) / sides ); - glVertex3f( + gl().glVertex3f( static_cast( origin[0] + radius * dc ), static_cast( origin[1] + radius * ds ), origin[2] ); } - glEnd(); + gl().glEnd(); } { - glBegin( GL_LINE_LOOP ); + gl().glBegin( GL_LINE_LOOP ); for ( int i = 0; i <= sides; i++ ) { double ds = sin( ( i * 2 * c_pi ) / sides ); double dc = cos( ( i * 2 * c_pi ) / sides ); - glVertex3f( + gl().glVertex3f( static_cast( origin[0] + radius * dc ), origin[1], static_cast( origin[2] + radius * ds ) ); } - glEnd(); + gl().glEnd(); } { - glBegin( GL_LINE_LOOP ); + gl().glBegin( GL_LINE_LOOP ); for ( int i = 0; i <= sides; i++ ) { double ds = sin( ( i * 2 * c_pi ) / sides ); double dc = cos( ( i * 2 * c_pi ) / sides ); - glVertex3f( + gl().glVertex3f( origin[0], static_cast( origin[1] + radius * dc ), static_cast( origin[2] + radius * ds ) ); } - glEnd(); + gl().glEnd(); } } @@ -456,14 +456,14 @@ void sphere_draw_wire( const Vector3& origin, float radius, const Vector3 radiiP int k = 0; for( int j = 0; j < 3; j++ ) { - glBegin( GL_LINE_LOOP ); + gl().glBegin( GL_LINE_LOOP ); for ( int i = 0; i < SPHERE_WIRE_SIDES; i++ ) { - glVertex3fv( vector3_to_array( vector3_added( origin, vector3_scaled( radiiPoints[k++], radius ) ) ) ); + gl().glVertex3fv( vector3_to_array( vector3_added( origin, vector3_scaled( radiiPoints[k++], radius ) ) ) ); } - glEnd(); + gl().glEnd(); } } @@ -483,33 +483,33 @@ void light_draw_radius_wire( const Vector3& origin, const float envelope[3], con void light_draw_box_lines( const Vector3& origin, const Vector3 points[8] ){ //draw lines from the center of the bbox to the corners - glBegin( GL_LINES ); + gl().glBegin( GL_LINES ); - glVertex3fv( vector3_to_array( origin ) ); - glVertex3fv( vector3_to_array( points[1] ) ); + gl().glVertex3fv( vector3_to_array( origin ) ); + gl().glVertex3fv( vector3_to_array( points[1] ) ); - glVertex3fv( vector3_to_array( origin ) ); - glVertex3fv( vector3_to_array( points[5] ) ); + gl().glVertex3fv( vector3_to_array( origin ) ); + gl().glVertex3fv( vector3_to_array( points[5] ) ); - glVertex3fv( vector3_to_array( origin ) ); - glVertex3fv( vector3_to_array( points[2] ) ); + gl().glVertex3fv( vector3_to_array( origin ) ); + gl().glVertex3fv( vector3_to_array( points[2] ) ); - glVertex3fv( vector3_to_array( origin ) ); - glVertex3fv( vector3_to_array( points[6] ) ); + gl().glVertex3fv( vector3_to_array( origin ) ); + gl().glVertex3fv( vector3_to_array( points[6] ) ); - glVertex3fv( vector3_to_array( origin ) ); - glVertex3fv( vector3_to_array( points[0] ) ); + gl().glVertex3fv( vector3_to_array( origin ) ); + gl().glVertex3fv( vector3_to_array( points[0] ) ); - glVertex3fv( vector3_to_array( origin ) ); - glVertex3fv( vector3_to_array( points[4] ) ); + gl().glVertex3fv( vector3_to_array( origin ) ); + gl().glVertex3fv( vector3_to_array( points[4] ) ); - glVertex3fv( vector3_to_array( origin ) ); - glVertex3fv( vector3_to_array( points[3] ) ); + gl().glVertex3fv( vector3_to_array( origin ) ); + gl().glVertex3fv( vector3_to_array( points[3] ) ); - glVertex3fv( vector3_to_array( origin ) ); - glVertex3fv( vector3_to_array( points[7] ) ); + gl().glVertex3fv( vector3_to_array( origin ) ); + gl().glVertex3fv( vector3_to_array( points[7] ) ); - glEnd(); + gl().glEnd(); } void light_vertices( const AABB& aabb_light, Vector3 points[6] ){ @@ -561,66 +561,66 @@ void light_draw( const AABB& aabb_light, RenderStateFlags state ){ }; #if !defined( USE_TRIANGLE_FAN ) - glBegin( GL_TRIANGLES ); + gl().glBegin( GL_TRIANGLES ); #else - glBegin( GL_TRIANGLE_FAN ); + gl().glBegin( GL_TRIANGLE_FAN ); #endif - glVertex3fv( vector3_to_array( points[0] ) ); - glVertex3fv( vector3_to_array( points[2] ) ); - glNormal3fv( vector3_to_array( normals[0] ) ); - glVertex3fv( vector3_to_array( points[3] ) ); + gl().glVertex3fv( vector3_to_array( points[0] ) ); + gl().glVertex3fv( vector3_to_array( points[2] ) ); + gl().glNormal3fv( vector3_to_array( normals[0] ) ); + gl().glVertex3fv( vector3_to_array( points[3] ) ); #if !defined( USE_TRIANGLE_FAN ) - glVertex3fv( vector3_to_array( points[0] ) ); - glVertex3fv( vector3_to_array( points[3] ) ); + gl().glVertex3fv( vector3_to_array( points[0] ) ); + gl().glVertex3fv( vector3_to_array( points[3] ) ); #endif - glNormal3fv( vector3_to_array( normals[1] ) ); - glVertex3fv( vector3_to_array( points[4] ) ); + gl().glNormal3fv( vector3_to_array( normals[1] ) ); + gl().glVertex3fv( vector3_to_array( points[4] ) ); #if !defined( USE_TRIANGLE_FAN ) - glVertex3fv( vector3_to_array( points[0] ) ); - glVertex3fv( vector3_to_array( points[4] ) ); + gl().glVertex3fv( vector3_to_array( points[0] ) ); + gl().glVertex3fv( vector3_to_array( points[4] ) ); #endif - glNormal3fv( vector3_to_array( normals[2] ) ); - glVertex3fv( vector3_to_array( points[5] ) ); + gl().glNormal3fv( vector3_to_array( normals[2] ) ); + gl().glVertex3fv( vector3_to_array( points[5] ) ); #if !defined( USE_TRIANGLE_FAN ) - glVertex3fv( vector3_to_array( points[0] ) ); - glVertex3fv( vector3_to_array( points[5] ) ); + gl().glVertex3fv( vector3_to_array( points[0] ) ); + gl().glVertex3fv( vector3_to_array( points[5] ) ); #endif - glNormal3fv( vector3_to_array( normals[3] ) ); - glVertex3fv( vector3_to_array( points[2] ) ); + gl().glNormal3fv( vector3_to_array( normals[3] ) ); + gl().glVertex3fv( vector3_to_array( points[2] ) ); #if defined( USE_TRIANGLE_FAN ) - glEnd(); - glBegin( GL_TRIANGLE_FAN ); + gl().glEnd(); + gl().glBegin( GL_TRIANGLE_FAN ); #endif - glVertex3fv( vector3_to_array( points[1] ) ); - glVertex3fv( vector3_to_array( points[2] ) ); - glNormal3fv( vector3_to_array( normals[7] ) ); - glVertex3fv( vector3_to_array( points[5] ) ); + gl().glVertex3fv( vector3_to_array( points[1] ) ); + gl().glVertex3fv( vector3_to_array( points[2] ) ); + gl().glNormal3fv( vector3_to_array( normals[7] ) ); + gl().glVertex3fv( vector3_to_array( points[5] ) ); #if !defined( USE_TRIANGLE_FAN ) - glVertex3fv( vector3_to_array( points[1] ) ); - glVertex3fv( vector3_to_array( points[5] ) ); + gl().glVertex3fv( vector3_to_array( points[1] ) ); + gl().glVertex3fv( vector3_to_array( points[5] ) ); #endif - glNormal3fv( vector3_to_array( normals[6] ) ); - glVertex3fv( vector3_to_array( points[4] ) ); + gl().glNormal3fv( vector3_to_array( normals[6] ) ); + gl().glVertex3fv( vector3_to_array( points[4] ) ); #if !defined( USE_TRIANGLE_FAN ) - glVertex3fv( vector3_to_array( points[1] ) ); - glVertex3fv( vector3_to_array( points[4] ) ); + gl().glVertex3fv( vector3_to_array( points[1] ) ); + gl().glVertex3fv( vector3_to_array( points[4] ) ); #endif - glNormal3fv( vector3_to_array( normals[5] ) ); - glVertex3fv( vector3_to_array( points[3] ) ); + gl().glNormal3fv( vector3_to_array( normals[5] ) ); + gl().glVertex3fv( vector3_to_array( points[3] ) ); #if !defined( USE_TRIANGLE_FAN ) - glVertex3fv( vector3_to_array( points[1] ) ); - glVertex3fv( vector3_to_array( points[3] ) ); + gl().glVertex3fv( vector3_to_array( points[1] ) ); + gl().glVertex3fv( vector3_to_array( points[3] ) ); #endif - glNormal3fv( vector3_to_array( normals[4] ) ); - glVertex3fv( vector3_to_array( points[2] ) ); + gl().glNormal3fv( vector3_to_array( normals[4] ) ); + gl().glVertex3fv( vector3_to_array( points[2] ) ); - glEnd(); + gl().glEnd(); } else { @@ -636,15 +636,15 @@ void light_draw( const AABB& aabb_light, RenderStateFlags state ){ 1, 3, 2 }; #if 1 - glVertexPointer( 3, GL_FLOAT, 0, points ); - glDrawElements( GL_TRIANGLES, sizeof( indices ) / sizeof( index_t ), RenderIndexTypeID, indices ); + gl().glVertexPointer( 3, GL_FLOAT, 0, points ); + gl().glDrawElements( GL_TRIANGLES, sizeof( indices ) / sizeof( index_t ), RenderIndexTypeID, indices ); #else - glBegin( GL_TRIANGLES ); + gl().glBegin( GL_TRIANGLES ); for ( unsigned int i = 0; i < sizeof( indices ) / sizeof( index_t ); ++i ) { - glVertex3fv( points[indices[i]] ); + gl().glVertex3fv( points[indices[i]] ); } - glEnd(); + gl().glEnd(); #endif } @@ -658,29 +658,29 @@ void light_draw( const AABB& aabb_light, RenderStateFlags state ){ GetVectorForKey( e, "light_up", vUp ); GetVectorForKey( e, "light_target", vTarget ); - glColor3f( 0, 1, 0 ); - glBegin( GL_LINE_LOOP ); + gl().glColor3f( 0, 1, 0 ); + gl().glBegin( GL_LINE_LOOP ); VectorAdd( vTarget, e->origin, vTemp ); VectorAdd( vTemp, vRight, vTemp ); VectorAdd( vTemp, vUp, vTemp ); - glVertex3fv( e->origin ); - glVertex3fv( vTemp ); + gl().glVertex3fv( e->origin ); + gl().glVertex3fv( vTemp ); VectorAdd( vTarget, e->origin, vTemp ); VectorAdd( vTemp, vUp, vTemp ); VectorSubtract( vTemp, vRight, vTemp ); - glVertex3fv( e->origin ); - glVertex3fv( vTemp ); + gl().glVertex3fv( e->origin ); + gl().glVertex3fv( vTemp ); VectorAdd( vTarget, e->origin, vTemp ); VectorAdd( vTemp, vRight, vTemp ); VectorSubtract( vTemp, vUp, vTemp ); - glVertex3fv( e->origin ); - glVertex3fv( vTemp ); + gl().glVertex3fv( e->origin ); + gl().glVertex3fv( vTemp ); VectorAdd( vTarget, e->origin, vTemp ); VectorSubtract( vTemp, vUp, vTemp ); VectorSubtract( vTemp, vRight, vTemp ); - glVertex3fv( e->origin ); - glVertex3fv( vTemp ); - glEnd(); + gl().glVertex3fv( e->origin ); + gl().glVertex3fv( vTemp ); + gl().glEnd(); } #endif @@ -959,10 +959,10 @@ public: RenderLightCenter( const Vector3& center, EntityClass& eclass ) : m_center( center ), m_eclass( eclass ){ } void render( RenderStateFlags state ) const { - glBegin( GL_POINTS ); - glColor3fv( vector3_to_array( m_eclass.color ) ); - glVertex3fv( vector3_to_array( m_center ) ); - glEnd(); + gl().glBegin( GL_POINTS ); + gl().glColor3fv( vector3_to_array( m_eclass.color ) ); + gl().glVertex3fv( vector3_to_array( m_center ) ); + gl().glEnd(); } }; @@ -1462,7 +1462,7 @@ public: if ( isProjected() ) { projection(); m_projectionOrientation = rotation(); - vector4_to_vector3( m_projectionOrientation.t() ) = localAABB().origin; + m_projectionOrientation.t().vec3() = localAABB().origin; renderer.addRenderable( m_renderProjection, m_projectionOrientation ); } else @@ -1589,7 +1589,7 @@ public: mutable Matrix4 m_localPivot; const Matrix4& getLocalPivot() const { m_localPivot = rotation_toMatrix( m_rotation ); - vector4_to_vector3( m_localPivot.t() ) = m_aabb_light.origin; + m_localPivot.t().vec3() = m_aabb_light.origin; return m_localPivot; } @@ -1604,7 +1604,7 @@ public: bool testAABB( const AABB& other ) const { if ( isProjected() ) { Matrix4 transform = rotation(); - vector4_to_vector3( transform.t() ) = localAABB().origin; + transform.t().vec3() = localAABB().origin; projection(); Frustum frustum( frustum_transformed( m_doom3Frustum, transform ) ); return frustum_test_aabb( frustum, other ) != c_volumeOutside; diff --git a/plugins/entity/light.h b/plugins/entity/light.h index 03fbf153..52bfc495 100644 --- a/plugins/entity/light.h +++ b/plugins/entity/light.h @@ -25,9 +25,8 @@ namespace scene { class Node; }; -class EntityClass; -scene::Node& New_Light( EntityClass* eclass ); +scene::Node& New_Light( class EntityClass* eclass ); enum LightType { LIGHTTYPE_DEFAULT, diff --git a/plugins/entity/namedentity.h b/plugins/entity/namedentity.h index d7f9d88b..5db5ffeb 100644 --- a/plugins/entity/namedentity.h +++ b/plugins/entity/namedentity.h @@ -180,7 +180,7 @@ RenderableNamedEntity( const NamedEntity& named, const Vector3& position ) : m_named( named ), m_position( position ){ } void render( RenderStateFlags state ) const { - glRasterPos3fv( vector3_to_array( m_position ) ); + gl().glRasterPos3fv( vector3_to_array( m_position ) ); GlobalOpenGL().drawString( g_showTargetNames ? m_named.name() : m_named.classname() ); } }; diff --git a/plugins/entity/targetable.h b/plugins/entity/targetable.h index 27a1a65c..7464a219 100644 --- a/plugins/entity/targetable.h +++ b/plugins/entity/targetable.h @@ -63,10 +63,10 @@ public: s2[0] = dir[0] + dir[1]; s2[1] = -dir[0] + dir[1]; - glBegin( GL_LINES ); + gl().glBegin( GL_LINES ); - glVertex3fv( vector3_to_array( start ) ); - glVertex3fv( vector3_to_array( end ) ); + gl().glVertex3fv( vector3_to_array( start ) ); + gl().glVertex3fv( vector3_to_array( end ) ); len *= 0.0625; // half / 8 @@ -74,13 +74,13 @@ public: for ( unsigned int i = 0, count = ( len < 32 ) ? 1 : static_cast( len * 0.0625 ); i < count; i++ ) { vector3_add( arrow, vector3_scaled( dir, ( len < 32 ) ? len : 32 ) ); - glVertex3fv( vector3_to_array( arrow ) ); - glVertex3f( arrow[0] + s1[0], arrow[1] + s1[1], arrow[2] + dir[2] ); - glVertex3fv( vector3_to_array( arrow ) ); - glVertex3f( arrow[0] + s2[0], arrow[1] + s2[1], arrow[2] + dir[2] ); + gl().glVertex3fv( vector3_to_array( arrow ) ); + gl().glVertex3f( arrow[0] + s1[0], arrow[1] + s1[1], arrow[2] + dir[2] ); + gl().glVertex3fv( vector3_to_array( arrow ) ); + gl().glVertex3f( arrow[0] + s2[0], arrow[1] + s2[1], arrow[2] + dir[2] ); } - glEnd(); + gl().glEnd(); } }; #endif @@ -401,7 +401,7 @@ public: return childBounds.origin; } #endif - return vector4_to_vector3( localToWorld().t() ); + return localToWorld().t().vec3(); } void render( Renderer& renderer, const VolumeTest& volume ) const { diff --git a/plugins/image/bmp.cpp b/plugins/image/bmp.cpp index bf26ebef..1fe00a92 100644 --- a/plugins/image/bmp.cpp +++ b/plugins/image/bmp.cpp @@ -146,7 +146,7 @@ Image* LoadBMPBuff( PointerInputStream& inputStream, std::size_t length ){ return 0; } if ( bmpHeader.fileSize != length ) { - globalErrorStream() << "LoadBMP: header size does not match file size (" << Unsigned( bmpHeader.fileSize ) << " vs. " << Unsigned( length ) << ")\n"; + globalErrorStream() << "LoadBMP: header size does not match file size (" << Unsigned( bmpHeader.fileSize ) << " vs. " << length << ")\n"; return 0; } if ( bmpHeader.compression != 0 ) { diff --git a/plugins/md3model/md5.cpp b/plugins/md3model/md5.cpp index 358296d8..7c18e84d 100644 --- a/plugins/md3model/md5.cpp +++ b/plugins/md3model/md5.cpp @@ -287,7 +287,7 @@ bool MD5Model_parse( Model& model, Tokeniser& tokeniser ){ MD5_RETURN_FALSE_IF_FAIL( MD5_parseString( tokeniser, jointName ) ); MD5_RETURN_FALSE_IF_FAIL( MD5_parseInteger( tokeniser, ( *i ).parent ) ); MD5_RETURN_FALSE_IF_FAIL( MD5_parseVector3( tokeniser, ( *i ).position ) ); - MD5_RETURN_FALSE_IF_FAIL( MD5_parseVector3( tokeniser, vector4_to_vector3( ( *i ).rotation ) ) ); + MD5_RETURN_FALSE_IF_FAIL( MD5_parseVector3( tokeniser, ( *i ).rotation.vec3() ) ); ( *i ).rotation.w() = -static_cast( sqrt( 1.0f - ( float_squared( ( *i ).rotation.x() ) + float_squared( ( *i ).rotation.y() ) + float_squared( ( *i ).rotation.z() ) ) ) ); tokeniser.nextLine(); } diff --git a/plugins/md3model/model.h b/plugins/md3model/model.h index 757bee68..596bea1f 100644 --- a/plugins/md3model/model.h +++ b/plugins/md3model/model.h @@ -145,48 +145,39 @@ public: void render( RenderStateFlags state ) const { #if 1 if ( ( state & RENDER_BUMP ) != 0 ) { - if ( GlobalShaderCache().useShaderLanguage() ) { - glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->normal ); - glVertexAttribPointerARB( c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->texcoord ); - glVertexAttribPointerARB( c_attr_Tangent, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->tangent ); - glVertexAttribPointerARB( c_attr_Binormal, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->bitangent ); - } - else - { - glVertexAttribPointerARB( 11, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->normal ); - glVertexAttribPointerARB( 8, 2, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->texcoord ); - glVertexAttribPointerARB( 9, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->tangent ); - glVertexAttribPointerARB( 10, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->bitangent ); - } + gl().glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->normal ); + gl().glVertexAttribPointer( c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->texcoord ); + gl().glVertexAttribPointer( c_attr_Tangent, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->tangent ); + gl().glVertexAttribPointer( c_attr_Binormal, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->bitangent ); } else { - glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->normal ); - glTexCoordPointer( 2, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->texcoord ); + gl().glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->normal ); + gl().glTexCoordPointer( 2, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->texcoord ); } - glVertexPointer( 3, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->vertex ); - glDrawElements( GL_TRIANGLES, GLsizei( m_indices.size() ), RenderIndexTypeID, m_indices.data() ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->vertex ); + gl().glDrawElements( GL_TRIANGLES, GLsizei( m_indices.size() ), RenderIndexTypeID, m_indices.data() ); #else - glBegin( GL_TRIANGLES ); + gl().glBegin( GL_TRIANGLES ); for ( unsigned int i = 0; i < m_indices.size(); ++i ) { - glTexCoord2fv( &m_vertices[m_indices[i]].texcoord.s ); - glNormal3fv( &m_vertices[m_indices[i]].normal.x ); - glVertex3fv( &m_vertices[m_indices[i]].vertex.x ); + gl().glTexCoord2fv( &m_vertices[m_indices[i]].texcoord.s ); + gl().glNormal3fv( &m_vertices[m_indices[i]].normal.x ); + gl().glVertex3fv( &m_vertices[m_indices[i]].vertex.x ); } - glEnd(); + gl().glEnd(); #endif #if defined( _DEBUG ) && !defined( _DEBUG_QUICKER ) - glBegin( GL_LINES ); + gl().glBegin( GL_LINES ); for ( VertexBuffer::const_iterator i = m_vertices.begin(); i != m_vertices.end(); ++i ) { Vector3 normal = vector3_added( vertex3f_to_vector3( ( *i ).vertex ), vector3_scaled( normal3f_to_vector3( ( *i ).normal ), 8 ) ); - glVertex3fv( vertex3f_to_array( ( *i ).vertex ) ); - glVertex3fv( vector3_to_array( normal ) ); + gl().glVertex3fv( vertex3f_to_array( ( *i ).vertex ) ); + gl().glVertex3fv( vector3_to_array( normal ) ); } - glEnd(); + gl().glEnd(); #endif } diff --git a/plugins/model/model.cpp b/plugins/model/model.cpp index efdf938c..bf2a0f46 100644 --- a/plugins/model/model.cpp +++ b/plugins/model/model.cpp @@ -91,31 +91,22 @@ public: void render( RenderStateFlags state ) const { if ( ( state & RENDER_BUMP ) != 0 ) { - if ( GlobalShaderCache().useShaderLanguage() ) { - glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->normal ); - glVertexAttribPointerARB( c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->texcoord ); - glVertexAttribPointerARB( c_attr_Tangent, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->tangent ); - glVertexAttribPointerARB( c_attr_Binormal, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->bitangent ); - } - else - { - glVertexAttribPointerARB( 11, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->normal ); - glVertexAttribPointerARB( 8, 2, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->texcoord ); - glVertexAttribPointerARB( 9, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->tangent ); - glVertexAttribPointerARB( 10, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->bitangent ); - } + gl().glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->normal ); + gl().glVertexAttribPointer( c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->texcoord ); + gl().glVertexAttribPointer( c_attr_Tangent, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->tangent ); + gl().glVertexAttribPointer( c_attr_Binormal, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->bitangent ); } else { - glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->normal ); - glTexCoordPointer( 2, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->texcoord ); + gl().glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->normal ); + gl().glTexCoordPointer( 2, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->texcoord ); } - glVertexPointer( 3, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->vertex ); - glDrawElements( GL_TRIANGLES, GLsizei( m_indices.size() ), RenderIndexTypeID, m_indices.data() ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_vertices.data()->vertex ); + gl().glDrawElements( GL_TRIANGLES, GLsizei( m_indices.size() ), RenderIndexTypeID, m_indices.data() ); #if defined( _DEBUG ) && !defined( _DEBUG_QUICKER ) GLfloat modelview[16]; - glGetFloatv( GL_MODELVIEW_MATRIX, modelview ); // I know this is slow as hell, but hey - we're in _DEBUG + gl().glGetFloatv( GL_MODELVIEW_MATRIX, modelview ); // I know this is slow as hell, but hey - we're in _DEBUG Matrix4 modelview_inv( modelview[0], modelview[1], modelview[2], modelview[3], modelview[4], modelview[5], modelview[6], modelview[7], @@ -124,17 +115,17 @@ public: matrix4_full_invert( modelview_inv ); Matrix4 modelview_inv_transposed = matrix4_transposed( modelview_inv ); - glBegin( GL_LINES ); + gl().glBegin( GL_LINES ); for ( Array::const_iterator i = m_vertices.begin(); i != m_vertices.end(); ++i ) { Vector3 normal = normal3f_to_vector3( ( *i ).normal ); normal = matrix4_transformed_direction( modelview_inv, vector3_normalised( matrix4_transformed_direction( modelview_inv_transposed, normal ) ) ); // do some magic Vector3 normalTransformed = vector3_added( vertex3f_to_vector3( ( *i ).vertex ), vector3_scaled( normal, 8 ) ); - glVertex3fv( vertex3f_to_array( ( *i ).vertex ) ); - glVertex3fv( vector3_to_array( normalTransformed ) ); + gl().glVertex3fv( vertex3f_to_array( ( *i ).vertex ) ); + gl().glVertex3fv( vector3_to_array( normalTransformed ) ); } - glEnd(); + gl().glEnd(); #endif } diff --git a/plugins/shaders/shaders.cpp b/plugins/shaders/shaders.cpp index b9ddc65a..2e804a03 100644 --- a/plugins/shaders/shaders.cpp +++ b/plugins/shaders/shaders.cpp @@ -48,8 +48,6 @@ #include "qerplugin.h" #include "irender.h" -#include - #include "debugging/debugging.h" #include "string/pooledstring.h" #include "math/vector.h" diff --git a/plugins/shaders/shaders.h b/plugins/shaders/shaders.h index 57225db3..02c58b89 100644 --- a/plugins/shaders/shaders.h +++ b/plugins/shaders/shaders.h @@ -32,8 +32,7 @@ void Shaders_Construct(); void Shaders_Destroy(); -class ShaderSystem; -ShaderSystem& GetShaderSystem(); +class ShaderSystem& GetShaderSystem(); enum ShaderLanguage { diff --git a/plugins/vfspk3/vfs.h b/plugins/vfspk3/vfs.h index 2fb50f2d..93e1341c 100644 --- a/plugins/vfspk3/vfs.h +++ b/plugins/vfspk3/vfs.h @@ -32,5 +32,4 @@ void FileSystem_Init(); void FileSystem_Shutdown(); -class VirtualFileSystem; -VirtualFileSystem& GetFileSystem(); +class VirtualFileSystem& GetFileSystem(); diff --git a/radiant/autosave.cpp b/radiant/autosave.cpp index 8dd5add6..6d3f3071 100644 --- a/radiant/autosave.cpp +++ b/radiant/autosave.cpp @@ -84,7 +84,7 @@ void Map_Snapshot(){ { StringOutputStream strMsg( 256 ); strMsg << "Snapshot save failed.. unabled to create directory\n" << snapshotsDir.c_str(); - gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), strMsg.c_str() ); + qt_MessageBox( MainFrame_getWindow(), strMsg.c_str() ); } } /* @@ -166,8 +166,8 @@ void QE_CheckAutoSave(){ } void Autosave_constructPreferences( PreferencesPage& page ){ - GtkWidget* autosave_enabled = page.appendCheckBox( "Autosave", "Enable Autosave", g_AutoSave_Enabled ); - GtkWidget* autosave_frequency = page.appendSpinner( "Autosave Frequency (minutes)", m_AutoSave_Frequency, 1, 1, 60 ); + QCheckBox* autosave_enabled = page.appendCheckBox( "Autosave", "Enable Autosave", g_AutoSave_Enabled ); + QWidget* autosave_frequency = page.appendSpinner( "Autosave Frequency (minutes)", m_AutoSave_Frequency, 1, 60 ); Widget_connectToggleDependency( autosave_frequency, autosave_enabled ); page.appendCheckBox( "", "Save Snapshots", g_SnapShots_Enabled ); } diff --git a/radiant/brush.cpp b/radiant/brush.cpp index 5c319029..c76237b5 100644 --- a/radiant/brush.cpp +++ b/radiant/brush.cpp @@ -273,7 +273,7 @@ void Brush::buildBRep(){ std::size_t faceIndex = std::distance( m_faces.begin(), i ); if ( !( *i )->contributes() ) { - globalOutputStream() << "face: " << Unsigned( faceIndex ) << " does not contribute\n"; + globalOutputStream() << "face: " << faceIndex << " does not contribute\n"; } Winding_printConnectivity( ( *i )->getWinding() ); @@ -548,7 +548,7 @@ void BrushInstance::transformComponents( const Matrix4& matrix ){ const Vector3 translation = matrix4_get_translation_vec3( matrix ); if( translation != g_vector3_identity ){ //has translation Matrix4 ma( matrix ); - Vector3& tra = vector4_to_vector3( ma.t() ); + Vector3& tra = ma.t().vec3(); tra = g_vector3_identity; if( g_matrix4_identity == ma ){ //only translation for ( const auto& fi : m_faceInstances ){ diff --git a/radiant/brush.h b/radiant/brush.h index f646848a..34592e21 100644 --- a/radiant/brush.h +++ b/radiant/brush.h @@ -79,12 +79,12 @@ inline bool texdef_sane( const texdef_t& texdef ){ } inline void Winding_DrawWireframe( const Winding& winding ){ - glVertexPointer( 3, GL_DOUBLE, sizeof( WindingVertex ), &winding.points.data()->vertex ); - glDrawArrays( GL_LINE_LOOP, 0, GLsizei( winding.numpoints ) ); + gl().glVertexPointer( 3, GL_DOUBLE, sizeof( WindingVertex ), &winding.points.data()->vertex ); + gl().glDrawArrays( GL_LINE_LOOP, 0, GLsizei( winding.numpoints ) ); } inline void Winding_Draw( const Winding& winding, const Vector3& normal, RenderStateFlags state ){ - glVertexPointer( 3, GL_DOUBLE, sizeof( WindingVertex ), &winding.points.data()->vertex ); + gl().glVertexPointer( 3, GL_DOUBLE, sizeof( WindingVertex ), &winding.points.data()->vertex ); Vector3 normals[c_brush_maxFaces]; @@ -94,19 +94,10 @@ inline void Winding_Draw( const Winding& winding, const Vector3& normal, RenderS { *i = normal; } - if ( GlobalShaderCache().useShaderLanguage() ) { - glNormalPointer( GL_FLOAT, sizeof( Vector3 ), normals ); - glVertexAttribPointerARB( c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->texcoord ); - glVertexAttribPointerARB( c_attr_Tangent, 3, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->tangent ); - glVertexAttribPointerARB( c_attr_Binormal, 3, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->bitangent ); - } - else - { - glVertexAttribPointerARB( 11, 3, GL_FLOAT, 0, sizeof( Vector3 ), normals ); - glVertexAttribPointerARB( 8, 2, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->texcoord ); - glVertexAttribPointerARB( 9, 3, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->tangent ); - glVertexAttribPointerARB( 10, 3, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->bitangent ); - } + gl().glNormalPointer( GL_FLOAT, sizeof( Vector3 ), normals ); + gl().glVertexAttribPointer( c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->texcoord ); + gl().glVertexAttribPointer( c_attr_Tangent, 3, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->tangent ); + gl().glVertexAttribPointer( c_attr_Binormal, 3, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->bitangent ); } else { @@ -116,48 +107,48 @@ inline void Winding_Draw( const Winding& winding, const Vector3& normal, RenderS { *i = normal; } - glNormalPointer( GL_FLOAT, sizeof( Vector3 ), normals ); + gl().glNormalPointer( GL_FLOAT, sizeof( Vector3 ), normals ); } if ( state & RENDER_TEXTURE ) { - glTexCoordPointer( 2, GL_FLOAT, sizeof( WindingVertex ), &winding.points.data()->texcoord ); + gl().glTexCoordPointer( 2, GL_FLOAT, sizeof( WindingVertex ), &winding.points.data()->texcoord ); } } #if 0 if ( state & RENDER_FILL ) { - glDrawArrays( GL_TRIANGLE_FAN, 0, GLsizei( winding.numpoints ) ); + gl().glDrawArrays( GL_TRIANGLE_FAN, 0, GLsizei( winding.numpoints ) ); } else { - glDrawArrays( GL_LINE_LOOP, 0, GLsizei( winding.numpoints ) ); + gl().glDrawArrays( GL_LINE_LOOP, 0, GLsizei( winding.numpoints ) ); } #else - glDrawArrays( GL_POLYGON, 0, GLsizei( winding.numpoints ) ); + gl().glDrawArrays( GL_POLYGON, 0, GLsizei( winding.numpoints ) ); #endif #if 0 const Winding& winding = winding; if ( state & RENDER_FILL ) { - glBegin( GL_POLYGON ); + gl().glBegin( GL_POLYGON ); } else { - glBegin( GL_LINE_LOOP ); + gl().glBegin( GL_LINE_LOOP ); } if ( state & RENDER_LIGHTING ) { - glNormal3fv( normal ); + gl().glNormal3fv( normal ); } for ( int i = 0; i < winding.numpoints; ++i ) { if ( state & RENDER_TEXTURE ) { - glTexCoord2fv( &winding.points[i][3] ); + gl().glTexCoord2fv( &winding.points[i][3] ); } - glVertex3fv( winding.points[i] ); + gl().glVertex3fv( winding.points[i] ); } - glEnd(); + gl().glEnd(); #endif } @@ -288,22 +279,6 @@ public: virtual void unrealiseShader() = 0; }; -class FaceShaderObserverRealise -{ -public: - void operator()( FaceShaderObserver& observer ) const { - observer.realiseShader(); - } -}; - -class FaceShaderObserverUnrealise -{ -public: - void operator()( FaceShaderObserver& observer ) const { - observer.unrealiseShader(); - } -}; - typedef ReferencePair FaceShaderObserverPair; @@ -404,11 +379,11 @@ public: void realise(){ ASSERT_MESSAGE( !m_realised, "FaceTexdef::realise: already realised" ); m_realised = true; - m_observers.forEach( FaceShaderObserverRealise() ); + m_observers.forEach( []( FaceShaderObserver& observer ){ observer.realiseShader(); } ); } void unrealise(){ ASSERT_MESSAGE( m_realised, "FaceTexdef::unrealise: already unrealised" ); - m_observers.forEach( FaceShaderObserverUnrealise() ); + m_observers.forEach( []( FaceShaderObserver& observer ){ observer.unrealiseShader(); } ); m_realised = false; } @@ -1445,16 +1420,16 @@ class RenderableWireframe : public OpenGLRenderable public: void render( RenderStateFlags state ) const { #if 1 - glVertexPointer( 3, GL_FLOAT, sizeof( DepthTestedPointVertex ), &m_vertices->vertex ); - glDrawElements( GL_LINES, GLsizei( m_size << 1 ), RenderIndexTypeID, m_faceVertex.data() ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( DepthTestedPointVertex ), &m_vertices->vertex ); + gl().glDrawElements( GL_LINES, GLsizei( m_size << 1 ), RenderIndexTypeID, m_faceVertex.data() ); #else - glBegin( GL_LINES ); + gl().glBegin( GL_LINES ); for ( std::size_t i = 0; i < m_size; ++i ) { - glVertex3fv( &m_vertices[m_faceVertex[i].first].vertex.x ); - glVertex3fv( &m_vertices[m_faceVertex[i].second].vertex.x ); + gl().glVertex3fv( &m_vertices[m_faceVertex[i].first].vertex.x ); + gl().glVertex3fv( &m_vertices[m_faceVertex[i].second].vertex.x ); } - glEnd(); + gl().glEnd(); #endif } @@ -1868,18 +1843,13 @@ public: { case SelectionSystem::eVertex: { - if( GlobalOpenGL().GL_1_5() ){ - if( volume.fill() ){ - renderer.SetState( m_state_deeppoint, Renderer::eFullMaterials ); - renderer.addRenderable( m_render_deepvertices, localToWorld ); - } - else{ - for( auto& p : m_uniqueVertexPoints ) - p.colour = colour_vertex; - renderer.addRenderable( m_render_vertices, localToWorld ); - } + if( volume.fill() ){ + renderer.SetState( m_state_deeppoint, Renderer::eFullMaterials ); + renderer.addRenderable( m_render_deepvertices, localToWorld ); } else{ + for( auto& p : m_uniqueVertexPoints ) + p.colour = colour_vertex; renderer.addRenderable( m_render_vertices, localToWorld ); } } @@ -3152,8 +3122,8 @@ public: Winding_Centroid( m_winding, m_plane, lineverts[0] ); lineverts[1] = vector3_added( lineverts[0], vector3_scaled( m_plane.normal(), Brush::m_maxWorldCoord * 4 ) ); - glVertexPointer( 3, GL_FLOAT, sizeof( Vector3 ), &lineverts[0] ); - glDrawArrays( GL_LINES, 0, GLsizei( 2 ) ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( Vector3 ), &lineverts[0] ); + gl().glDrawArrays( GL_LINES, 0, GLsizei( 2 ) ); } } diff --git a/radiant/brush_primit.cpp b/radiant/brush_primit.cpp index 48551fdf..bbaadd6b 100644 --- a/radiant/brush_primit.cpp +++ b/radiant/brush_primit.cpp @@ -248,16 +248,16 @@ inline void DebugAxisBase( const Vector3& normal ){ void Texdef_basisForNormal( const TextureProjection& projection, const Vector3& normal, Matrix4& basis ){ if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES ) { basis = g_matrix4_identity; - ComputeAxisBase( normal, vector4_to_vector3( basis.x() ), vector4_to_vector3( basis.y() ) ); - vector4_to_vector3( basis.z() ) = normal; + ComputeAxisBase( normal, basis.x().vec3(), basis.y().vec3() ); + basis.z().vec3() = normal; matrix4_transpose( basis ); //DebugAxisBase( normal ); } else if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_VALVE ) { basis = g_matrix4_identity; - vector4_to_vector3( basis.x() ) = projection.m_basis_s; - vector4_to_vector3( basis.y() ) = vector3_negated( projection.m_basis_t ); - vector4_to_vector3( basis.z() ) = vector3_normalised( vector3_cross( vector4_to_vector3( basis.x() ), vector4_to_vector3( basis.y() ) ) ); + basis.x().vec3() = projection.m_basis_s; + basis.y().vec3() = vector3_negated( projection.m_basis_t ); + basis.z().vec3() = vector3_normalised( vector3_cross( basis.x().vec3(), basis.y().vec3() ) ); // matrix4_multiply_by_matrix4( basis, matrix4_rotation_for_z_degrees( -projection.m_texdef.rotate ) ); //globalOutputStream() << "debug: " << projection.m_basis_s << projection.m_basis_t << normal << "\n"; matrix4_transpose( basis ); @@ -305,8 +305,8 @@ void Texdef_EmitTextureCoordinates( const TextureProjection& projection, std::si matrix4_multiply_by_matrix4( local2tex, xyz2st ); } - const Vector3 tangent( vector3_normalised( vector4_to_vector3( matrix4_transposed( local2tex ).x() ) ) ); - const Vector3 bitangent( vector3_normalised( vector4_to_vector3( matrix4_transposed( local2tex ).y() ) ) ); + const Vector3 tangent( vector3_normalised( matrix4_transposed( local2tex ).x().vec3() ) ); + const Vector3 bitangent( vector3_normalised( matrix4_transposed( local2tex ).y().vec3() ) ); matrix4_multiply_by_matrix4( local2tex, localToWorld ); @@ -1319,6 +1319,11 @@ void ShiftScaleRotate_toFace( const texdef_t& shiftScaleRotate, TextureProjectio } } +void ShiftScaleRotate_fromPatch( texdef_t& shiftScaleRotate, const TextureProjection& projection ){ + TexMatToFakeTexCoords( projection.m_brushprimit_texdef, shiftScaleRotate ); +} + + inline void printAP( const TextureProjection& projection ){ globalOutputStream() << "AP: scale( " << projection.m_texdef.scale[0] << " " << projection.m_texdef.scale[1] << " ) shift( " << projection.m_texdef.shift[0] << " " << projection.m_texdef.shift[1] << " ) rotate: " << projection.m_texdef.rotate << "\n"; } @@ -1473,9 +1478,9 @@ void Texdef_transformLocked_original( TextureProjection& projection, std::size_t // globalOutputStream() << "transformed2stTransformed: " << transformed2stTransformed << "\n"; Matrix4 stTransformed2identity( matrix4_affine_inverse( matrix4_multiplied_by_matrix4( transformed2stTransformed, identity2transformed ) ) ); // globalOutputStream() << "stTransformed2identity: " << stTransformed2identity << "\n"; - Vector3 originalProjectionAxis( vector4_to_vector3( matrix4_affine_inverse( identity2stIdentity ).z() ) ); + Vector3 originalProjectionAxis( matrix4_affine_inverse( identity2stIdentity ).z().vec3() ); - Vector3 transformedProjectionAxis( vector4_to_vector3( stTransformed2identity.z() ) ); + Vector3 transformedProjectionAxis( stTransformed2identity.z().vec3() ); Matrix4 stIdentity2stOriginal; Texdef_toTransform( projection, (float)width, (float)height, stIdentity2stOriginal ); @@ -1530,7 +1535,7 @@ double Det3x3( double a00, double a01, double a02, + a02 * ( a10 * a21 - a11 * a20 ); } -void BP_from_ST( brushprimit_texdef_t& bp, const DoubleVector3 points[3], const DoubleVector3 st[3], const DoubleVector3& normal, const bool normalize = true ){ +void BP_from_ST( brushprimit_texdef_t& bp, const DoubleVector3 points[3], const DoubleVector3 st[3], const DoubleVector3& normal, const bool normalize /*= true*/ ){ double xyI[2], xyJ[2], xyK[2]; double stI[2], stJ[2], stK[2]; double D, D0, D1, D2; @@ -1882,8 +1887,8 @@ void Q3_to_matrix( const texdef_t& texdef, float width, float height, const Vect void BP_from_matrix( brushprimit_texdef_t& bp_texdef, const Vector3& normal, const Matrix4& transform ){ Matrix4 basis; basis = g_matrix4_identity; - ComputeAxisBase( normal, vector4_to_vector3( basis.x() ), vector4_to_vector3( basis.y() ) ); - vector4_to_vector3( basis.z() ) = normal; + ComputeAxisBase( normal, basis.x().vec3(), basis.y().vec3() ); + basis.z().vec3() = normal; matrix4_transpose( basis ); matrix4_affine_invert( basis ); @@ -1908,8 +1913,8 @@ void Texdef_Construct_local2tex4projection( const texdef_t& texdef, std::size_t { if( direction ){ //arbitrary Matrix4 basis = g_matrix4_identity; - ComputeAxisBase( *direction, vector4_to_vector3( basis.x() ), vector4_to_vector3( basis.y() ) ); - vector4_to_vector3( basis.z() ) = *direction; + ComputeAxisBase( *direction, basis.x().vec3(), basis.y().vec3() ); + basis.z().vec3() = *direction; matrix4_transpose( basis ); matrix4_multiply_by_matrix4( local2tex, basis ); @@ -2015,7 +2020,7 @@ void AP_from_BP( TextureProjection& projection, const Plane3& plane, std::size_t // globalOutputStream() << "invariantTexCoords: " << invariantTexCoords[0] << " " << invariantTexCoords[1] << "\n"; const Matrix4 tex2local = matrix4_affine_inverse( local2tex ); - AP_from_axes( vector4_to_vector3( tex2local.x() ) / width, vector4_to_vector3( tex2local.y() ) / height, plane.normal(), width, height, invariant, invariantTexCoords, projection.m_texdef ); + AP_from_axes( tex2local.x().vec3() / width, tex2local.y().vec3() / height, plane.normal(), width, height, invariant, invariantTexCoords, projection.m_texdef ); } void Valve220_from_BP( TextureProjection& projection, const Plane3& plane, std::size_t width, std::size_t height ) { @@ -2131,8 +2136,20 @@ void Texdef_Construct_local2tex_from_ST( const DoubleVector3 points[3], const Do { // Texdef_basisForNormal Matrix4 basis = g_matrix4_identity; - ComputeAxisBase( plane.normal(), vector4_to_vector3( basis.x() ), vector4_to_vector3( basis.y() ) ); - vector4_to_vector3( basis.z() ) = plane.normal(); + ComputeAxisBase( plane.normal(), basis.x().vec3(), basis.y().vec3() ); + basis.z().vec3() = plane.normal(); + matrix4_transpose( basis ); + matrix4_multiply_by_matrix4( local2tex, basis ); + } +} + +void BP_Construct_local2tex( const brushprimit_texdef_t& bp, const Plane3& plane, Matrix4& local2tex ){ + BPTexdef_toTransform( bp, local2tex ); + { + // Texdef_basisForNormal + Matrix4 basis = g_matrix4_identity; + ComputeAxisBase( plane.normal(), basis.x().vec3(), basis.y().vec3() ); + basis.z().vec3() = plane.normal(); matrix4_transpose( basis ); matrix4_multiply_by_matrix4( local2tex, basis ); } @@ -2154,8 +2171,8 @@ void Texdef_getTexAxes( const TextureProjection& projection, const Plane3& plane //Texdef_basisForNormal( proj, plane.normal(), xyz2st ); minus inverse of orthogonal basis via transpose Matrix4 xyz2st = g_matrix4_identity; - ComputeAxisBase( plane.normal(), vector4_to_vector3( xyz2st.x() ), vector4_to_vector3( xyz2st.y() ) ); - vector4_to_vector3( xyz2st.z() ) = plane.normal(); + ComputeAxisBase( plane.normal(), xyz2st.x().vec3(), xyz2st.y().vec3() ); + xyz2st.z().vec3() = plane.normal(); // natural texture basis, aligned to the plane matrix4_premultiply_by_matrix4( tex2local, xyz2st ); // ( A B )-1 = B-1 A-1 diff --git a/radiant/brush_primit.h b/radiant/brush_primit.h index 1f94cd6d..89e0fc54 100644 --- a/radiant/brush_primit.h +++ b/radiant/brush_primit.h @@ -86,7 +86,6 @@ public: float Texdef_getDefaultTextureScale(); -class texdef_t; struct Winding; class Matrix4; template class Plane3___; @@ -107,10 +106,12 @@ void Texdef_FitTexture( TextureProjection& projection, std::size_t width, std::s void Texdef_Construct_local2tex( const TextureProjection& projection, std::size_t width, std::size_t height, const Vector3& normal, Matrix4& local2tex ); void Texdef_Construct_local2tex4projection( const texdef_t& texdef, std::size_t width, std::size_t height, const Vector3& normal, const Vector3* direction, Matrix4& local2tex ); void Texdef_Construct_local2tex_from_ST( const DoubleVector3 points[3], const DoubleVector3 st[3], Matrix4& local2tex ); +void BP_Construct_local2tex( const brushprimit_texdef_t& bp, const Plane3& plane, Matrix4& local2tex ); void Texdef_EmitTextureCoordinates( const TextureProjection& projection, std::size_t width, std::size_t height, Winding& w, const Vector3& normal, const Matrix4& localToWorld ); void ShiftScaleRotate_fromFace( texdef_t& shiftScaleRotate, const TextureProjection& projection ); void ShiftScaleRotate_toFace( const texdef_t& shiftScaleRotate, TextureProjection& projection ); +void ShiftScaleRotate_fromPatch( texdef_t& shiftScaleRotate, const TextureProjection& projection ); void Texdef_transformLocked( TextureProjection& projection, std::size_t width, std::size_t height, const Plane3& plane, const Matrix4& transform, const Vector3& invariant = g_vector3_identity ); void Texdef_transform( TextureProjection& projection, std::size_t width, std::size_t height, const Plane3& plane, const Matrix4& transform, const Vector3& invariant = g_vector3_identity ); @@ -133,6 +134,8 @@ extern float g_texdef_default_scale; void Texdef_Convert( TexdefTypeId in, TexdefTypeId out, const Plane3& plane, TextureProjection& projection, std::size_t width, std::size_t height ); void Texdef_from_ST( TextureProjection& projection, const DoubleVector3 points[3], const DoubleVector3 st[3], std::size_t width, std::size_t height ); +void BP_from_ST( brushprimit_texdef_t& bp, const DoubleVector3 points[3], const DoubleVector3 st[3], const DoubleVector3& normal, const bool normalize = true ); +void BPTexdef_Assign( brushprimit_texdef_t& bp_td, const float* hShift, const float* vShift, const float* hScale, const float* vScale, const float* rotation ); //++timo replace everywhere texX by texS etc. ( ----> and in q3map !) // NOTE : ComputeAxisBase here and in q3map code must always BE THE SAME ! diff --git a/radiant/brushmanip.cpp b/radiant/brushmanip.cpp index 29a59ea3..1dbc39d2 100644 --- a/radiant/brushmanip.cpp +++ b/radiant/brushmanip.cpp @@ -98,11 +98,11 @@ const char* const c_brushPrism_name = "brushPrism"; void Brush_ConstructPrism( Brush& brush, const AABB& bounds, std::size_t sides, size_t axis, const char* shader, const TextureProjection& projection ){ if ( sides < c_brushPrism_minSides ) { - globalErrorStream() << c_brushPrism_name << ": sides " << Unsigned( sides ) << ": too few sides, minimum is " << Unsigned( c_brushPrism_minSides ) << "\n"; + globalErrorStream() << c_brushPrism_name << ": sides " << sides << ": too few sides, minimum is " << c_brushPrism_minSides << "\n"; return; } if ( sides > c_brushPrism_maxSides ) { - globalErrorStream() << c_brushPrism_name << ": sides " << Unsigned( sides ) << ": too many sides, maximum is " << Unsigned( c_brushPrism_maxSides ) << "\n"; + globalErrorStream() << c_brushPrism_name << ": sides " << sides << ": too many sides, maximum is " << c_brushPrism_maxSides << "\n"; return; } @@ -168,11 +168,11 @@ const char* const c_brushCone_name = "brushCone"; void Brush_ConstructCone( Brush& brush, const AABB& bounds, std::size_t sides, const char* shader, const TextureProjection& projection ){ if ( sides < c_brushCone_minSides ) { - globalErrorStream() << c_brushCone_name << ": sides " << Unsigned( sides ) << ": too few sides, minimum is " << Unsigned( c_brushCone_minSides ) << "\n"; + globalErrorStream() << c_brushCone_name << ": sides " << sides << ": too few sides, minimum is " << c_brushCone_minSides << "\n"; return; } if ( sides > c_brushCone_maxSides ) { - globalErrorStream() << c_brushCone_name << ": sides " << Unsigned( sides ) << ": too many sides, maximum is " << Unsigned( c_brushCone_maxSides ) << "\n"; + globalErrorStream() << c_brushCone_name << ": sides " << sides << ": too many sides, maximum is " << c_brushCone_maxSides << "\n"; return; } @@ -223,11 +223,11 @@ const char* const c_brushSphere_name = "brushSphere"; void Brush_ConstructSphere( Brush& brush, const AABB& bounds, std::size_t sides, const char* shader, const TextureProjection& projection ){ if ( sides < c_brushSphere_minSides ) { - globalErrorStream() << c_brushSphere_name << ": sides " << Unsigned( sides ) << ": too few sides, minimum is " << Unsigned( c_brushSphere_minSides ) << "\n"; + globalErrorStream() << c_brushSphere_name << ": sides " << sides << ": too few sides, minimum is " << c_brushSphere_minSides << "\n"; return; } if ( sides > c_brushSphere_maxSides ) { - globalErrorStream() << c_brushSphere_name << ": sides " << Unsigned( sides ) << ": too many sides, maximum is " << Unsigned( c_brushSphere_maxSides ) << "\n"; + globalErrorStream() << c_brushSphere_name << ": sides " << sides << ": too many sides, maximum is " << c_brushSphere_maxSides << "\n"; return; } @@ -276,11 +276,11 @@ const char* const c_brushRock_name = "brushRock"; void Brush_ConstructRock( Brush& brush, const AABB& bounds, std::size_t sides, const char* shader, const TextureProjection& projection ){ if ( sides < c_brushRock_minSides ) { - globalErrorStream() << c_brushRock_name << ": sides " << Unsigned( sides ) << ": too few sides, minimum is " << Unsigned( c_brushRock_minSides ) << "\n"; + globalErrorStream() << c_brushRock_name << ": sides " << sides << ": too few sides, minimum is " << c_brushRock_minSides << "\n"; return; } if ( sides > c_brushRock_maxSides ) { - globalErrorStream() << c_brushRock_name << ": sides " << Unsigned( sides ) << ": too many sides, maximum is " << Unsigned( c_brushRock_maxSides ) << "\n"; + globalErrorStream() << c_brushRock_name << ": sides " << sides << ": too many sides, maximum is " << c_brushRock_maxSides << "\n"; return; } @@ -413,54 +413,54 @@ void Brush_ConstructIcosahedron( Brush& brush, const AABB& bounds, std::size_t s void Brush_ConstructPrefab( Brush& brush, EBrushPrefab type, const AABB& bounds, std::size_t sides, bool option, const char* shader, const TextureProjection& projection ){ switch ( type ) { - case eBrushCuboid: + case EBrushPrefab::Cuboid: { UndoableCommand undo( "brushCuboid" ); Brush_ConstructCuboid( brush, bounds, shader, projection ); } break; - case eBrushPrism: + case EBrushPrefab::Prism: { const size_t axis = GlobalXYWnd_getCurrentViewType(); StringOutputStream command; - command << c_brushPrism_name << " -sides " << Unsigned( sides ) << " -axis " << Unsigned( axis ); + command << c_brushPrism_name << " -sides " << sides << " -axis " << axis; UndoableCommand undo( command.c_str() ); Brush_ConstructPrism( brush, bounds, sides, axis, shader, projection ); } break; - case eBrushCone: + case EBrushPrefab::Cone: { StringOutputStream command; - command << c_brushCone_name << " -sides " << Unsigned( sides ); + command << c_brushCone_name << " -sides " << sides; UndoableCommand undo( command.c_str() ); Brush_ConstructCone( brush, bounds, sides, shader, projection ); } break; - case eBrushSphere: + case EBrushPrefab::Sphere: { StringOutputStream command; - command << c_brushSphere_name << " -sides " << Unsigned( sides ); + command << c_brushSphere_name << " -sides " << sides; UndoableCommand undo( command.c_str() ); Brush_ConstructSphere( brush, bounds, sides, shader, projection ); } break; - case eBrushRock: + case EBrushPrefab::Rock: { StringOutputStream command; - command << c_brushRock_name << " -sides " << Unsigned( sides ); + command << c_brushRock_name << " -sides " << sides; UndoableCommand undo( command.c_str() ); Brush_ConstructRock( brush, bounds, sides, shader, projection ); } break; - case eBrushIcosahedron: + case EBrushPrefab::Icosahedron: { StringOutputStream command; - command << "brushIcosahedron" << " -subdivisions " << Unsigned( sides ); + command << "brushIcosahedron" << " -subdivisions " << sides; UndoableCommand undo( command.c_str() ); icosahedron::Brush_ConstructIcosahedron( brush, bounds, sides, option, shader, projection ); @@ -654,19 +654,8 @@ void Scene_BrushSetShader_Component_Selected( scene::Graph& graph, const char* n SceneChangeNotify(); } -class FaceSetDetail -{ - bool m_detail; -public: - FaceSetDetail( bool detail ) : m_detail( detail ){ - } - void operator()( Face& face ) const { - face.setDetail( m_detail ); - } -}; - void Scene_BrushSetDetail_Selected( scene::Graph& graph, bool detail ){ - Scene_ForEachSelectedBrush_ForEachFace( graph, FaceSetDetail( detail ) ); + Scene_ForEachSelectedBrush_ForEachFace( graph, [detail]( Face& face ){ face.setDetail( detail ); } ); SceneChangeNotify(); } @@ -931,14 +920,6 @@ void Scene_BrushGetTexdef_Component_Selected( scene::Graph& graph, TextureProjec #endif } -void Scene_BrushGetShaderSize_Component_Selected( scene::Graph& graph, size_t& width, size_t& height ){ - if ( !g_SelectedFaceInstances.empty() ) { - FaceInstance& faceInstance = g_SelectedFaceInstances.last(); - width = faceInstance.getFace().getShader().width(); - height = faceInstance.getFace().getShader().height(); - } -} - class FaceGetFlags { @@ -1236,8 +1217,8 @@ void BrushFilters_construct(){ #if 0 void normalquantisation_draw(){ - glPointSize( 1 ); - glBegin( GL_POINTS ); + gl().glPointSize( 1 ); + gl().glBegin( GL_POINTS ); for ( std::size_t i = 0; i <= c_quantise_normal; ++i ) { for ( std::size_t j = 0; j <= c_quantise_normal; ++j ) @@ -1248,12 +1229,12 @@ void normalquantisation_draw(){ static_cast( j ) ) ) ); VectorScale( normal3f_to_array( vertex ), 64.f, normal3f_to_array( vertex ) ); - glVertex3fv( normal3f_to_array( vertex ) ); + gl().glVertex3fv( normal3f_to_array( vertex ) ); vertex.x = -vertex.x; - glVertex3fv( normal3f_to_array( vertex ) ); + gl().glVertex3fv( normal3f_to_array( vertex ) ); } } - glEnd(); + gl().glEnd(); } class RenderableNormalQuantisation : public OpenGLRenderable @@ -1463,7 +1444,7 @@ public: : m_count( count ){ } void set(){ - Scene_BrushConstructPrefab( GlobalSceneGraph(), eBrushPrism, m_count, false, TextureBrowser_GetSelectedShader() ); + Scene_BrushConstructPrefab( GlobalSceneGraph(), EBrushPrefab::Prism, m_count, false, TextureBrowser_GetSelectedShader() ); } typedef MemberCaller SetCaller; }; @@ -1486,23 +1467,22 @@ public: : m_type( type ){ } void set(){ - DoSides( m_type, GlobalXYWnd_getCurrentViewType() ); + DoSides( m_type ); } typedef MemberCaller SetCaller; }; -BrushPrefab g_brushprism( eBrushPrism ); -BrushPrefab g_brushcone( eBrushCone ); -BrushPrefab g_brushsphere( eBrushSphere ); -BrushPrefab g_brushrock( eBrushRock ); -BrushPrefab g_brushicosahedron( eBrushIcosahedron ); +BrushPrefab g_brushprism( EBrushPrefab::Prism ); +BrushPrefab g_brushcone( EBrushPrefab::Cone ); +BrushPrefab g_brushsphere( EBrushPrefab::Sphere ); +BrushPrefab g_brushrock( EBrushPrefab::Rock ); +BrushPrefab g_brushicosahedron( EBrushPrefab::Icosahedron ); Callback g_texture_lock_status_changed; -BoolExportCaller g_texdef_movelock_caller( g_brush_texturelock_enabled ); -ToggleItem g_texdef_movelock_item( g_texdef_movelock_caller ); +ToggleItem g_texdef_movelock_item{ BoolExportCaller( g_brush_texturelock_enabled ) }; void Texdef_ToggleMoveLock(){ g_brush_texturelock_enabled = !g_brush_texturelock_enabled; @@ -1510,8 +1490,7 @@ void Texdef_ToggleMoveLock(){ g_texture_lock_status_changed(); } -BoolExportCaller g_texdef_moveVlock_caller( g_brush_textureVertexlock_enabled ); -ToggleItem g_texdef_moveVlock_item( g_texdef_moveVlock_caller ); +ToggleItem g_texdef_moveVlock_item{ BoolExportCaller( g_brush_textureVertexlock_enabled ) }; void Texdef_ToggleMoveVLock(){ g_brush_textureVertexlock_enabled = !g_brush_textureVertexlock_enabled; g_texdef_moveVlock_item.update(); @@ -1521,7 +1500,7 @@ void Texdef_ToggleMoveVLock(){ void Brush_registerCommands(){ - GlobalToggles_insert( "TogTexLock", FreeCaller(), ToggleItem::AddCallbackCaller( g_texdef_movelock_item ), Accelerator( 'T', GDK_SHIFT_MASK ) ); + GlobalToggles_insert( "TogTexLock", FreeCaller(), ToggleItem::AddCallbackCaller( g_texdef_movelock_item ), QKeySequence( "Shift+T" ) ); GlobalToggles_insert( "TogTexVertexLock", FreeCaller(), ToggleItem::AddCallbackCaller( g_texdef_moveVlock_item ) ); GlobalCommands_insert( "BrushPrism", BrushPrefab::SetCaller( g_brushprism ) ); @@ -1530,57 +1509,54 @@ void Brush_registerCommands(){ GlobalCommands_insert( "BrushRock", BrushPrefab::SetCaller( g_brushrock ) ); GlobalCommands_insert( "BrushIcosahedron", BrushPrefab::SetCaller( g_brushicosahedron ) ); - GlobalCommands_insert( "Brush3Sided", BrushMakeSided::SetCaller( g_brushmakesided3 ), Accelerator( '3', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "Brush4Sided", BrushMakeSided::SetCaller( g_brushmakesided4 ), Accelerator( '4', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "Brush5Sided", BrushMakeSided::SetCaller( g_brushmakesided5 ), Accelerator( '5', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "Brush6Sided", BrushMakeSided::SetCaller( g_brushmakesided6 ), Accelerator( '6', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "Brush7Sided", BrushMakeSided::SetCaller( g_brushmakesided7 ), Accelerator( '7', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "Brush8Sided", BrushMakeSided::SetCaller( g_brushmakesided8 ), Accelerator( '8', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "Brush9Sided", BrushMakeSided::SetCaller( g_brushmakesided9 ), Accelerator( '9', GDK_CONTROL_MASK ) ); + GlobalCommands_insert( "Brush3Sided", BrushMakeSided::SetCaller( g_brushmakesided3 ), QKeySequence( "Ctrl+3" ) ); + GlobalCommands_insert( "Brush4Sided", BrushMakeSided::SetCaller( g_brushmakesided4 ), QKeySequence( "Ctrl+4" ) ); + GlobalCommands_insert( "Brush5Sided", BrushMakeSided::SetCaller( g_brushmakesided5 ), QKeySequence( "Ctrl+5" ) ); + GlobalCommands_insert( "Brush6Sided", BrushMakeSided::SetCaller( g_brushmakesided6 ), QKeySequence( "Ctrl+6" ) ); + GlobalCommands_insert( "Brush7Sided", BrushMakeSided::SetCaller( g_brushmakesided7 ), QKeySequence( "Ctrl+7" ) ); + GlobalCommands_insert( "Brush8Sided", BrushMakeSided::SetCaller( g_brushmakesided8 ), QKeySequence( "Ctrl+8" ) ); + GlobalCommands_insert( "Brush9Sided", BrushMakeSided::SetCaller( g_brushmakesided9 ), QKeySequence( "Ctrl+9" ) ); - GlobalCommands_insert( "MakeDetail", FreeCaller(), Accelerator( 'D', GDK_MOD1_MASK ) ); - GlobalCommands_insert( "MakeStructural", FreeCaller(), Accelerator( 'S', GDK_MOD1_MASK ) ); + GlobalCommands_insert( "MakeDetail", FreeCaller(), QKeySequence( "Alt+D" ) ); + GlobalCommands_insert( "MakeStructural", FreeCaller(), QKeySequence( "Alt+S" ) ); } -void Brush_constructMenu( GtkMenu* menu ){ +void Brush_constructMenu( QMenu* menu ){ create_menu_item_with_mnemonic( menu, "Prism...", "BrushPrism" ); create_menu_item_with_mnemonic( menu, "Cone...", "BrushCone" ); create_menu_item_with_mnemonic( menu, "Sphere...", "BrushSphere" ); create_menu_item_with_mnemonic( menu, "Rock...", "BrushRock" ); create_menu_item_with_mnemonic( menu, "Icosahedron...", "BrushIcosahedron" ); - menu_separator( menu ); + menu->addSeparator(); { - GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic( menu, "CSG" ); - if ( g_Layout_enableDetachableMenus.m_value ) { - menu_tearoff( menu_in_menu ); - } - create_menu_item_with_mnemonic( menu_in_menu, "CSG _Subtract", "CSGSubtract" ); - create_menu_item_with_mnemonic( menu_in_menu, "CSG _Merge", "CSGMerge" ); - create_menu_item_with_mnemonic( menu_in_menu, "CSG _Wrap Merge", "CSGWrapMerge" ); - create_menu_item_with_mnemonic( menu_in_menu, "Make _Room", "CSGroom" ); - create_menu_item_with_mnemonic( menu_in_menu, "CSG _Tool", "CSGTool" ); - } - menu_separator( menu ); - { - GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic( menu, "Clipper" ); - if ( g_Layout_enableDetachableMenus.m_value ) { - menu_tearoff( menu_in_menu ); - } + QMenu* submenu = menu->addMenu( "CSG" ); - create_menu_item_with_mnemonic( menu_in_menu, "Clip selection", "ClipperClip" ); - create_menu_item_with_mnemonic( menu_in_menu, "Split selection", "ClipperSplit" ); - create_menu_item_with_mnemonic( menu_in_menu, "Flip Clip orientation", "ClipperFlip" ); + submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + + create_menu_item_with_mnemonic( submenu, "CSG &Subtract", "CSGSubtract" ); + create_menu_item_with_mnemonic( submenu, "CSG &Merge", "CSGMerge" ); + create_menu_item_with_mnemonic( submenu, "CSG &Wrap Merge", "CSGWrapMerge" ); + create_menu_item_with_mnemonic( submenu, "Make &Room", "CSGroom" ); + create_menu_item_with_mnemonic( submenu, "CSG &Tool", "CSGTool" ); } - menu_separator( menu ); + menu->addSeparator(); + { + QMenu* submenu = menu->addMenu( "Clipper" ); + + submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + + create_menu_item_with_mnemonic( submenu, "Clip selection", "ClipperClip" ); + create_menu_item_with_mnemonic( submenu, "Split selection", "ClipperSplit" ); + create_menu_item_with_mnemonic( submenu, "Flip Clip orientation", "ClipperFlip" ); + } + menu->addSeparator(); create_menu_item_with_mnemonic( menu, "Make detail", "MakeDetail" ); create_menu_item_with_mnemonic( menu, "Make structural", "MakeStructural" ); - menu_separator( menu ); + menu->addSeparator(); create_check_menu_item_with_mnemonic( menu, "Texture Lock", "TogTexLock" ); create_check_menu_item_with_mnemonic( menu, "Texture Vertex Lock", "TogTexVertexLock" ); create_menu_item_with_mnemonic( menu, "Reset Texture", "TextureReset/Cap" ); - create_menu_item_with_mnemonic( menu, "Copy Face Texture", "Copy" ); - create_menu_item_with_mnemonic( menu, "Paste Face Texture", "Paste" ); create_menu_item_with_mnemonic( menu, "AutoCaulk Selected", "AutoCaulkSelected" ); command_connect_accelerator( "Brush3Sided" ); diff --git a/radiant/brushmanip.h b/radiant/brushmanip.h index f3c4c67d..91fbdcbc 100644 --- a/radiant/brushmanip.h +++ b/radiant/brushmanip.h @@ -25,14 +25,14 @@ #include "string/stringfwd.h" #include "generic/callbackfwd.h" -enum EBrushPrefab +enum class EBrushPrefab { - eBrushCuboid, - eBrushPrism, - eBrushCone, - eBrushSphere, - eBrushRock, - eBrushIcosahedron, + Cuboid, + Prism, + Cone, + Sphere, + Rock, + Icosahedron, }; class TextureProjection; @@ -52,7 +52,6 @@ void Scene_BrushSetTexdef_Selected( scene::Graph& graph, const float* hShift, co void Scene_BrushSetTexdef_Component_Selected( scene::Graph& graph, const float* hShift, const float* vShift, const float* hScale, const float* vScale, const float* rotation ); void Scene_BrushGetTexdef_Selected( scene::Graph& graph, TextureProjection& projection ); void Scene_BrushGetTexdef_Component_Selected( scene::Graph& graph, TextureProjection& projection ); -void Scene_BrushGetShaderSize_Component_Selected( scene::Graph& graph, size_t& width, size_t& height ); void Scene_BrushSetFlags_Selected( scene::Graph& graph, const ContentsFlagsValue& flags ); void Scene_BrushSetFlags_Component_Selected( scene::Graph& graph, const ContentsFlagsValue& flags ); void Scene_BrushGetFlags_Selected( scene::Graph& graph, ContentsFlagsValue& flags ); @@ -85,8 +84,7 @@ void Scene_BrushProjectTexture_Component_Selected( scene::Graph& graph, const Te void Scene_BrushFitTexture_Selected( scene::Graph& graph, float s_repeat, float t_repeat, bool only_dimension ); void Scene_BrushFitTexture_Component_Selected( scene::Graph& graph, float s_repeat, float t_repeat, bool only_dimension ); -typedef struct _GtkMenu GtkMenu; -void Brush_constructMenu( GtkMenu* menu ); +void Brush_constructMenu( class QMenu* menu ); extern Callback g_texture_lock_status_changed; diff --git a/radiant/brushmodule.cpp b/radiant/brushmodule.cpp index d2259607..7bb8749b 100644 --- a/radiant/brushmodule.cpp +++ b/radiant/brushmodule.cpp @@ -90,9 +90,11 @@ void Brush_constructPreferences( PreferencesPage& page ){ FaceImportSnapPlanesCaller(), FaceExportSnapPlanesCaller() ); - page.appendEntry( + page.appendSpinner( "Default texture scale", - g_texdef_default_scale + g_texdef_default_scale, + 0.0625, + 64 ); if ( g_multipleBrushTypes ) { const char* names[] = { BrushType_getName( g_brushTypes[0] ), BrushType_getName( g_brushTypes[1] ), BrushType_getName( g_brushTypes[2] ) }; diff --git a/radiant/build.cpp b/radiant/build.cpp index 9887221b..6fc5116d 100644 --- a/radiant/build.cpp +++ b/radiant/build.cpp @@ -300,35 +300,27 @@ public: typedef std::pair BuildPair; #define SEPARATOR_STRING "-" -static bool is_separator( const BuildPair &p ){ - if ( !string_equal( p.first.c_str(), SEPARATOR_STRING ) ) { +inline bool is_separator( const CopiedString& name, const Build& commands ){ + if ( !string_equal( name.c_str(), SEPARATOR_STRING ) ) { return false; } - for ( Build::const_iterator j = p.second.begin(); j != p.second.end(); ++j ) + for ( const BuildCommand& cmd : commands ) { - if ( !string_equal( ( *j ).c_str(), "" ) ) { + if ( !string_empty( cmd.c_str() ) ) { return false; } } return true; } +inline bool is_separator( const BuildPair &p ){ + return is_separator( p.first, p.second ); +} -class BuildPairEqual -{ - const char* m_name; -public: - BuildPairEqual( const char* name ) : m_name( name ){ - } - bool operator()( const BuildPair& self ) const { - return string_equal( self.first.c_str(), m_name ); - } -}; - typedef std::list Project; Project::iterator Project_find( Project& project, const char* name ){ - return std::find_if( project.begin(), project.end(), BuildPairEqual( name ) ); + return std::find_if( project.begin(), project.end(), [name]( const BuildPair& self ){ return string_equal( self.first.c_str(), name ); } ); } Project::iterator Project_find( Project& project, std::size_t index ){ @@ -639,176 +631,144 @@ void build_commands_write( const char* filename ){ } -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "gtkutil/dialog.h" -#include "gtkutil/closure.h" -#include "gtkutil/window.h" -#include "gtkutil/accelerator.h" -#include "gtkdlgs.h" -void Build_refreshMenu( GtkMenu* menu ); +void Build_refreshMenu( QMenu* menu ); + +inline QTreeWidgetItem* new_item( const char *text ){ + auto item = new QTreeWidgetItem; + item->setText( 0, text ); + item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren ); + return item; +} #define LAST_ITER_STRING "..." -inline void last_iter_append( GtkListStore* store ){ - GtkTreeIter lastIter; - gtk_list_store_append( store, &lastIter ); - gtk_list_store_set( store, &lastIter, 0, LAST_ITER_STRING, -1 ); +inline void last_iter_append( QTreeWidget* tree ){ + tree->addTopLevelItem( new_item( LAST_ITER_STRING ) ); } -void BSPCommandList_Construct( GtkListStore* store, Project& project ){ - gtk_list_store_clear( store ); +void BSPCommandList_Construct( QTreeWidget* tree, Project& project ){ + tree->clear(); - for ( Project::iterator i = project.begin(); i != project.end(); ++i ) + for ( const auto& [ name, commands ] : project ) { - const char* buildName = ( *i ).first.c_str(); - - GtkTreeIter buildIter; - gtk_list_store_append( store, &buildIter ); - gtk_list_store_set( store, &buildIter, 0, const_cast( buildName ), -1 ); + tree->addTopLevelItem( new_item( name.c_str() ) ); } - last_iter_append( store ); -} - -static void project_cell_editing_started( GtkCellRenderer* cell, GtkCellEditable* editable, const gchar* path, gpointer data ) { - ASSERT_MESSAGE( GTK_IS_ENTRY( editable ), "editable is not GtkEntry" ); - GtkEntry* entry = GTK_ENTRY( editable ); - if( string_equal( LAST_ITER_STRING, gtk_entry_get_text( entry ) ) ) - gtk_entry_set_text( entry, "" ); + last_iter_append( tree ); } class ProjectList { public: Project& m_project; - GtkListStore* m_store; - GtkWidget* m_buildView; + QTreeWidget* m_buildView; bool m_changed; ProjectList( Project& project ) : m_project( project ), m_changed( false ){ } }; -gboolean project_cell_edited( GtkCellRendererText* cell, gchar* path_string, gchar* new_text, ProjectList* projectList ){ - Project& project = projectList->m_project; +void project_cell_edited( QTreeWidgetItem *item, ProjectList& projectList ){ + Project& project = projectList.m_project; + const auto new_text = item->text( 0 ).toLatin1(); - GtkTreePath* path = gtk_tree_path_new_from_string( path_string ); - - ASSERT_MESSAGE( gtk_tree_path_get_depth( path ) == 1, "invalid path length" ); - - GtkTreeIter iter; - gtk_tree_model_get_iter( GTK_TREE_MODEL( projectList->m_store ), &iter, path ); - - Project::iterator i = Project_find( project, gtk_tree_path_get_indices( path )[0] ); - if ( i != project.end() ) { - projectList->m_changed = true; - if ( string_empty( new_text ) ) { + Project::iterator i = Project_find( project, item->treeWidget()->indexOfTopLevelItem( item ) ); + if ( i != project.end() ) { // edit + projectList.m_changed = true; + if ( new_text.isEmpty() ) { // empty = delete project.erase( i ); - gtk_list_store_remove( projectList->m_store, &iter ); + delete item; } else { - ( *i ).first = new_text; - gtk_list_store_set( projectList->m_store, &iter, 0, new_text, -1 ); + ( *i ).first = new_text.constData(); } } - else if ( !string_empty( new_text ) && !string_equal( new_text, LAST_ITER_STRING ) ) { - projectList->m_changed = true; - project.push_back( Project::value_type( new_text, Build() ) ); + else if ( !new_text.isEmpty() && !string_equal( new_text, LAST_ITER_STRING ) ) { // add new + projectList.m_changed = true; + project.push_back( Project::value_type( new_text.constData(), Build() ) ); - gtk_list_store_set( projectList->m_store, &iter, 0, new_text, -1 ); - last_iter_append( projectList->m_store ); - //make command field activatable - g_signal_emit_by_name( G_OBJECT( gtk_tree_view_get_selection( GTK_TREE_VIEW( projectList->m_buildView ) ) ), "changed" ); + last_iter_append( projectList.m_buildView ); + //refresh command field + item->treeWidget()->currentItemChanged( item, nullptr ); } - gtk_tree_path_free( path ); - Build_refreshMenu( g_bsp_menu ); - - return FALSE; } BuildPair g_buildpair_copied; BuildCommand g_buildcommand_copied; -inline bool event_is_del( const GdkEventKey* event ){ - return accelerator_for_event_key( event ) == Accelerator( GDK_KEY_Delete ); -} -inline bool event_is_copy( const GdkEventKey* event ){ - return ( accelerator_for_event_key( event ) == Accelerator( 'C', GDK_CONTROL_MASK ) ) - || ( accelerator_for_event_key( event ) == Accelerator( GDK_KEY_Insert, GDK_CONTROL_MASK ) ); -} -inline bool event_is_paste( const GdkEventKey* event ){ - return ( accelerator_for_event_key( event ) == Accelerator( 'V', GDK_CONTROL_MASK ) ) - || ( accelerator_for_event_key( event ) == Accelerator( GDK_KEY_Insert, GDK_SHIFT_MASK ) ); -} +class Project_key_press : public QObject +{ + ProjectList& m_projectList; +public: + Project_key_press( ProjectList& projectList ) : QObject( projectList.m_buildView ), m_projectList( projectList ){} +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::KeyPress ) { + Project& project = m_projectList.m_project; + if( QTreeWidgetItem *item = m_projectList.m_buildView->currentItem() ){ + Project::iterator x = Project_find( project, item->treeWidget()->indexOfTopLevelItem( item ) ); + QKeyEvent *keyEvent = static_cast( event ); + if ( keyEvent->matches( QKeySequence::StandardKey::Delete ) && x != project.end() ) { + m_projectList.m_changed = true; + project.erase( x ); + Build_refreshMenu( g_bsp_menu ); -gboolean project_key_press( GtkWidget* widget, GdkEventKey* event, ProjectList* projectList ){ - Project& project = projectList->m_project; + const int id = item->treeWidget()->indexOfTopLevelItem( item ); + delete item; + m_projectList.m_buildView->currentItemChanged( m_projectList.m_buildView->topLevelItem( id ), nullptr ); //refresh command field + } + else if ( keyEvent->matches( QKeySequence::StandardKey::Copy ) && x != project.end() ) { + g_buildpair_copied = ( *x ); + } + else if ( keyEvent->matches( QKeySequence::StandardKey::Paste ) && !g_buildpair_copied.first.empty() ) { + m_projectList.m_changed = true; + project.insert( x, g_buildpair_copied ); + Build_refreshMenu( g_bsp_menu ); - if ( event_is_del( event ) || event_is_copy( event ) || event_is_paste( event ) ) { - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( widget ) ); - GtkTreeIter iter; - GtkTreeModel* model; - if ( gtk_tree_selection_get_selected( selection, &model, &iter ) ) { - GtkTreePath* path = gtk_tree_model_get_path( model, &iter ); - Project::iterator x = Project_find( project, gtk_tree_path_get_indices( path )[0] ); - gtk_tree_path_free( path ); + item->treeWidget()->insertTopLevelItem( item->treeWidget()->indexOfTopLevelItem( item ), new_item( g_buildpair_copied.first.c_str() ) ); + } - if ( event_is_del( event ) && x != project.end() ) { - projectList->m_changed = true; - project.erase( x ); - Build_refreshMenu( g_bsp_menu ); - - gtk_list_store_remove( projectList->m_store, &iter ); - } - else if ( event_is_copy( event ) && x != project.end() ) { - g_buildpair_copied = ( *x ); - } - else if ( event_is_paste( event ) && !g_buildpair_copied.first.empty() ) { - projectList->m_changed = true; - project.insert( x, g_buildpair_copied ); - Build_refreshMenu( g_bsp_menu ); - - GtkTreeIter newIter; - gtk_list_store_insert_before( projectList->m_store, &newIter, &iter ); - gtk_list_store_set( projectList->m_store, &newIter, 0, g_buildpair_copied.first.c_str(), -1 ); + event->accept(); } } + return QObject::eventFilter( obj, event ); // standard event processing } - return FALSE; -} - +}; Build* g_current_build = 0; -gboolean project_selection_changed( GtkTreeSelection* selection, GtkListStore* store ){ +void project_selection_changed( QTreeWidgetItem* buildItem, QTreeWidget* cmdTree ){ Project& project = g_build_project; - gtk_list_store_clear( store ); + cmdTree->clear(); - GtkTreeIter iter; - GtkTreeModel* model; - if ( gtk_tree_selection_get_selected( selection, &model, &iter ) ) { - GtkTreePath* path = gtk_tree_model_get_path( model, &iter ); - Project::iterator x = Project_find( project, gtk_tree_path_get_indices( path )[0] ); - gtk_tree_path_free( path ); + if ( buildItem != nullptr ) { + Project::iterator x = Project_find( project, buildItem->treeWidget()->indexOfTopLevelItem( buildItem ) ); if ( x != project.end() ) { Build& build = ( *x ).second; g_current_build = &build; - for ( Build::iterator i = build.begin(); i != build.end(); ++i ) + for ( const BuildCommand& cmd : build ) { - GtkTreeIter commandIter; - gtk_list_store_append( store, &commandIter ); - gtk_list_store_set( store, &commandIter, 0, const_cast( ( *i ).c_str() ), -1 ); + cmdTree->addTopLevelItem( new_item( cmd.c_str() ) ); } - last_iter_append( store ); + last_iter_append( cmdTree ); } else { @@ -819,244 +779,178 @@ gboolean project_selection_changed( GtkTreeSelection* selection, GtkListStore* s { g_current_build = 0; } - - return FALSE; } -gboolean commands_cell_edited( GtkCellRendererText* cell, gchar* path_string, gchar* new_text, GtkListStore* store ){ +void commands_cell_edited( QTreeWidgetItem *item ){ if ( g_current_build == 0 ) { - return FALSE; + return; } Build& build = *g_current_build; + const auto new_text = item->text( 0 ).toLatin1(); - GtkTreePath* path = gtk_tree_path_new_from_string( path_string ); - - ASSERT_MESSAGE( gtk_tree_path_get_depth( path ) == 1, "invalid path length" ); - - GtkTreeIter iter; - gtk_tree_model_get_iter( GTK_TREE_MODEL( store ), &iter, path ); - - Build::iterator i = Build_find( build, gtk_tree_path_get_indices( path )[0] ); - if ( i != build.end() ) { + Build::iterator i = Build_find( build, item->treeWidget()->indexOfTopLevelItem( item ) ); + if ( i != build.end() ) { // edit g_build_changed = true; ( *i ).setString( new_text ); - - gtk_list_store_set( store, &iter, 0, new_text, -1 ); } - else if ( !string_empty( new_text ) && !string_equal( new_text, LAST_ITER_STRING ) ) { + else if ( !new_text.isEmpty() && !string_equal( new_text, LAST_ITER_STRING ) ) { // add new g_build_changed = true; build.push_back( Build::value_type( VariableString( new_text ) ) ); - gtk_list_store_set( store, &iter, 0, new_text, -1 ); - - last_iter_append( store ); + last_iter_append( item->treeWidget() ); } - gtk_tree_path_free( path ); - Build_refreshMenu( g_bsp_menu ); - - return FALSE; } -gboolean commands_key_press( GtkWidget* widget, GdkEventKey* event, GtkListStore* store ){ - if ( g_current_build == 0 ) { - return FALSE; - } - Build& build = *g_current_build; +class Commands_key_press : public QObject +{ + QTreeWidget* m_tree; +public: + Commands_key_press( QTreeWidget* tree ) : QObject( tree ), m_tree( tree ){} +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::KeyPress && g_current_build != nullptr ) { + Build& build = *g_current_build; + if( QTreeWidgetItem *item = m_tree->currentItem() ){ + Build::iterator x = Build_find( build, item->treeWidget()->indexOfTopLevelItem( item ) ); + QKeyEvent *keyEvent = static_cast( event ); + if ( keyEvent->matches( QKeySequence::StandardKey::Delete ) && x != build.end() ) { + g_build_changed = true; + build.erase( x ); - if ( event_is_del( event ) || event_is_copy( event ) || event_is_paste( event ) ) { - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( widget ) ); - GtkTreeIter iter; - GtkTreeModel* model; - if ( gtk_tree_selection_get_selected( selection, &model, &iter ) ) { - GtkTreePath* path = gtk_tree_model_get_path( model, &iter ); - Build::iterator i = Build_find( build, gtk_tree_path_get_indices( path )[0] ); - gtk_tree_path_free( path ); + delete item; + } + else if ( keyEvent->matches( QKeySequence::StandardKey::Copy ) && x != build.end() ) { + g_buildcommand_copied = ( *x ); + } + else if ( keyEvent->matches( QKeySequence::StandardKey::Paste ) && !g_buildpair_copied.first.empty() ) { + g_build_changed = true; + build.insert( x, g_buildcommand_copied ); - if ( event_is_del( event ) && i != build.end() ) { - g_build_changed = true; - build.erase( i ); + item->treeWidget()->insertTopLevelItem( item->treeWidget()->indexOfTopLevelItem( item ), new_item( g_buildcommand_copied.c_str() ) ); + } - gtk_list_store_remove( store, &iter ); - } - else if ( event_is_copy( event ) && i != build.end() ) { - g_buildcommand_copied = ( *i ); - } - else if ( event_is_paste( event ) ) { - g_build_changed = true; - build.insert( i, g_buildcommand_copied ); - - GtkTreeIter newIter; - gtk_list_store_insert_before( store, &newIter, &iter ); - gtk_list_store_set( store, &newIter, 0, g_buildcommand_copied.c_str(), -1 ); + event->accept(); } } + return QObject::eventFilter( obj, event ); // standard event processing } - return FALSE; -} +}; #include "qe3.h" -GtkWindow* BuildMenuDialog_construct( ModalDialog& modal, ProjectList& projectList ){ - GtkWindow* window = create_dialog_window( MainFrame_getWindow(), "Build Menu", G_CALLBACK( dialog_delete_callback ), &modal, -1, 400 ); +EMessageBoxReturn BuildMenuDialog_construct( ProjectList& projectList ){ + QDialog dialog( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Build Menu" ); - GtkWidget* buildView = 0; + QTreeWidget* buildView = nullptr; { - GtkTable* table1 = create_dialog_table( 3, 2, 4, 4, 4 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( table1 ) ); + auto grid = new QGridLayout( &dialog ); { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_table_attach( table1, GTK_WIDGET( vbox ), 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( GTK_FILL ), 0, 0 ); - { - GtkButton* button = create_dialog_button( "OK", G_CALLBACK( dialog_button_ok ), &modal ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - } - { - GtkButton* button = create_dialog_button( "Cancel", G_CALLBACK( dialog_button_cancel ), &modal ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - } - { - GtkButton* button = create_dialog_button( "Reset", G_CALLBACK( dialog_button_no ), &modal ); - gtk_widget_set_tooltip_text( GTK_WIDGET( button ), "Reset to editor start state" ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - } + auto buttons = new QDialogButtonBox; + buttons->setOrientation( Qt::Orientation::Vertical ); + // rejection via dialog means will return DialogCode::Rejected (0), eID* > 0 + QObject::connect( buttons->addButton( QDialogButtonBox::StandardButton::Ok ), + &QAbstractButton::clicked, [&dialog](){ dialog.done( eIDOK ); } ); + QObject::connect( buttons->addButton( QDialogButtonBox::StandardButton::Cancel ), + &QAbstractButton::clicked, &dialog, &QDialog::reject ); + QObject::connect( buttons->addButton( QDialogButtonBox::StandardButton::Reset ), + &QAbstractButton::clicked, [&dialog](){ dialog.done( eIDNO ); } ); + buttons->button( QDialogButtonBox::StandardButton::Reset )->setToolTip( "Reset to editor start state" ); + grid->addWidget( buttons, 0, 1 ); } { - GtkFrame* frame = create_dialog_frame( "Build menu" ); - gtk_table_attach( table1, GTK_WIDGET( frame ), 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 ); + auto frame = new QGroupBox( "Build menu" ); + grid->addWidget( frame, 0, 0 ); { - GtkScrolledWindow* scr = create_scrolled_window( GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC, 4 ); - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( scr ) ); - + auto tree = projectList.m_buildView = buildView = new QTreeWidget; + tree->setColumnCount( 1 ); + tree->setUniformRowHeights( true ); // optimization + tree->setHorizontalScrollBarPolicy( Qt::ScrollBarPolicy::ScrollBarAlwaysOff ); + tree->setSizeAdjustPolicy( QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents ); // scroll area will inherit column size + tree->header()->setStretchLastSection( false ); // non greedy column sizing + tree->header()->setSectionResizeMode( QHeaderView::ResizeMode::ResizeToContents ); // no text elision + tree->setHeaderHidden( true ); + tree->setRootIsDecorated( false ); + ( new QHBoxLayout( frame ) )->addWidget( tree ); { - GtkListStore* store = gtk_list_store_new( 1, G_TYPE_STRING ); + QObject::connect( tree, &QTreeWidget::itemChanged, [&projectList]( QTreeWidgetItem *item, int column ){ + project_cell_edited( item, projectList ); + } ); - GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) ); - gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), FALSE ); - - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - object_set_boolean_property( G_OBJECT( renderer ), "editable", TRUE ); - g_signal_connect( renderer, "edited", G_CALLBACK( project_cell_edited ), &projectList ); - g_signal_connect( renderer, "editing-started", G_CALLBACK( project_cell_editing_started ), 0 ); - - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "", renderer, "text", 0, NULL ); - gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column ); - - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) ); - gtk_tree_selection_set_mode( selection, GTK_SELECTION_BROWSE ); - - gtk_widget_show( view ); - - buildView = view; - projectList.m_buildView = buildView; - projectList.m_store = store; - gtk_container_add( GTK_CONTAINER( scr ), view ); - - g_signal_connect( G_OBJECT( view ), "key_press_event", G_CALLBACK( project_key_press ), &projectList ); - - g_object_unref( G_OBJECT( store ) ); + tree->installEventFilter( new Project_key_press( projectList ) ); } } } { - GtkFrame* frame = create_dialog_frame( "Commandline" ); - gtk_table_attach( table1, GTK_WIDGET( frame ), 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 ); + auto frame = new QGroupBox( "Commandline" ); + grid->addWidget( frame, 1, 0 ); { - GtkScrolledWindow* scr = create_scrolled_window( GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC, 4 ); - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( scr ) ); - + auto tree = new QTreeWidget; + tree->setColumnCount( 1 ); + tree->setUniformRowHeights( true ); // optimization + tree->setHorizontalScrollBarPolicy( Qt::ScrollBarPolicy::ScrollBarAlwaysOff ); + tree->setSizeAdjustPolicy( QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents ); // scroll area will inherit column size + tree->header()->setStretchLastSection( false ); // non greedy column sizing + tree->header()->setSectionResizeMode( QHeaderView::ResizeMode::ResizeToContents ); // no text elision + tree->setHeaderHidden( true ); + tree->setRootIsDecorated( false ); + ( new QHBoxLayout( frame ) )->addWidget( tree ); { - GtkListStore* store = gtk_list_store_new( 1, G_TYPE_STRING ); + QObject::connect( tree, &QTreeWidget::itemChanged, []( QTreeWidgetItem *item, int column ){ + commands_cell_edited( item ); + } ); - GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) ); - gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), FALSE ); + QObject::connect( buildView, &QTreeWidget::currentItemChanged, [tree]( QTreeWidgetItem *current, QTreeWidgetItem *previous ){ + project_selection_changed( current, tree ); + } ); - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - object_set_boolean_property( G_OBJECT( renderer ), "editable", TRUE ); - g_object_set( G_OBJECT( renderer ), "wrap-mode", PANGO_WRAP_WORD, NULL ); - //g_object_set( G_OBJECT( renderer ), "ellipsize", PANGO_ELLIPSIZE_MIDDLE, NULL ); - object_set_int_property( G_OBJECT( renderer ), "wrap-width", 640 ); - g_signal_connect( renderer, "edited", G_CALLBACK( commands_cell_edited ), store ); - g_signal_connect( renderer, "editing-started", G_CALLBACK( project_cell_editing_started ), 0 ); - - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "", renderer, "text", 0, NULL ); - gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column ); - - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) ); - gtk_tree_selection_set_mode( selection, GTK_SELECTION_BROWSE ); - - gtk_widget_show( view ); - - gtk_container_add( GTK_CONTAINER( scr ), view ); - - g_object_unref( G_OBJECT( store ) ); - - g_signal_connect( G_OBJECT( view ), "key_press_event", G_CALLBACK( commands_key_press ), store ); - - g_signal_connect( G_OBJECT( gtk_tree_view_get_selection( GTK_TREE_VIEW( buildView ) ) ), "changed", G_CALLBACK( project_selection_changed ), store ); + tree->installEventFilter( new Commands_key_press( tree ) ); } } } { - GtkWidget* expander = gtk_expander_new_with_mnemonic( "build variables" ); - gtk_widget_show( expander ); - gtk_table_attach( table1, expander, 0, 2, 2, 3, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( GTK_FILL ), 0, 0 ); + auto expander = new QGroupBox( "build variables" ); + expander->setFlat( true ); + expander->setCheckable( true ); + expander->setChecked( false ); + grid->addWidget( expander, 2, 0 ); bsp_init(); - for ( Tools::iterator i = g_build_tools.begin(); i != g_build_tools.end(); ++i ){ + for ( auto& [ name, tool ] : g_build_tools ){ StringBuffer output; - ( *i ).second.evaluate( output ); - build_set_variable( ( *i ).first.c_str(), output.c_str() ); + tool.evaluate( output ); + build_set_variable( name.c_str(), output.c_str() ); } StringOutputStream stream; - for( Variables::iterator i = g_build_variables.begin(); i != g_build_variables.end(); ++i ){ - stream << "[" << ( *i ).first << "] = " << ( *i ).second << "\n"; + for( const auto& [ name, var ] : g_build_variables ){ + stream << "[" << name << "] = " << var << "\n"; } build_clear_variables(); - GtkWidget* label = gtk_label_new( stream.c_str() ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); -#if 1 - gtk_label_set_ellipsize( GTK_LABEL( label ), PANGO_ELLIPSIZE_END ); -#else - gtk_label_set_line_wrap( GTK_LABEL( label ), TRUE ); - //gtk_label_set_max_width_chars( GTK_LABEL( label ), 100 ); - //gtk_label_set_width_chars( GTK_LABEL( label ), 100 ); - gtk_widget_set_size_request( label, 500, -1 ); -#endif - gtk_widget_show( label ); - gtk_container_add( GTK_CONTAINER( expander ), label ); + auto label = new QLabel( stream.c_str() ); + label->hide(); + ( new QHBoxLayout( expander ) )->addWidget( label ); + QObject::connect( expander, &QGroupBox::clicked, label, &QWidget::setVisible ); } } - BSPCommandList_Construct( projectList.m_store, g_build_project ); + BSPCommandList_Construct( projectList.m_buildView, g_build_project ); - return window; + return static_cast( dialog.exec() ); } void LoadBuildMenu(); void DoBuildMenu(){ - ModalDialog modal; - ProjectList projectList( g_build_project ); + const Project bakproj = g_build_project; - GtkWindow* window = BuildMenuDialog_construct( modal, projectList ); + const EMessageBoxReturn ret = BuildMenuDialog_construct( projectList ); - Project bakproj = g_build_project; - - EMessageBoxReturn ret = modal_dialog_show( window, modal ); - if ( ret == eIDCANCEL ) { + if ( ret == eIDCANCEL || ret == 0 ) { if ( projectList.m_changed || g_build_changed ){ g_build_project = bakproj; Build_refreshMenu( g_bsp_menu ); @@ -1071,8 +965,6 @@ void DoBuildMenu(){ else if ( projectList.m_changed ) { g_build_changed = true; } - - gtk_widget_destroy( GTK_WIDGET( window ) ); } @@ -1080,20 +972,19 @@ void DoBuildMenu(){ #include "gtkutil/menu.h" #include "mainframe.h" #include "preferences.h" -typedef struct _GtkMenuItem GtkMenuItem; -CopiedString g_lastExecutedBuild; +class BuildMenuItem *g_lastExecutedBuild = nullptr; class BuildMenuItem { const char* m_name; public: - GtkMenuItem* m_item; - BuildMenuItem( const char* name, GtkMenuItem* item ) + QAction* m_item; + BuildMenuItem( const char* name, QAction* item ) : m_name( name ), m_item( item ){ } void run(){ - g_lastExecutedBuild = m_name; + g_lastExecutedBuild = this; RunBSP( m_name ); } typedef MemberCaller RunCaller; @@ -1103,27 +994,36 @@ typedef std::list BuildMenuItems; BuildMenuItems g_BuildMenuItems; -GtkMenu* g_bsp_menu; +QMenu* g_bsp_menu; -void Build_constructMenu( GtkMenu* menu ){ - for ( Project::iterator i = g_build_project.begin(); i != g_build_project.end(); ++i ) +void Build_constructMenu( QMenu* menu ){ + for ( const auto& [ name, commands ] : g_build_project ) { - g_BuildMenuItems.push_back( BuildMenuItem( ( *i ).first.c_str(), 0 ) ); - if ( is_separator( *i ) ) { - g_BuildMenuItems.back().m_item = menu_separator( menu ); + g_BuildMenuItems.push_back( BuildMenuItem( name.c_str(), 0 ) ); + if ( is_separator( name, commands ) ) { + g_BuildMenuItems.back().m_item = menu->addSeparator(); } else { - g_BuildMenuItems.back().m_item = create_menu_item_with_mnemonic( menu, ( *i ).first.c_str(), BuildMenuItem::RunCaller( g_BuildMenuItems.back() ) ); + g_BuildMenuItems.back().m_item = create_menu_item_with_mnemonic( menu, name.c_str(), BuildMenuItem::RunCaller( g_BuildMenuItems.back() ) ); + { + QString str; + for( const BuildCommand& cmd : commands ){ + str += cmd.c_str(); + str += '\n'; + } + str.truncate( str.size() - 1 ); + g_BuildMenuItems.back().m_item->setToolTip( str ); + } } } } -void Build_refreshMenu( GtkMenu* menu ){ - for ( BuildMenuItems::iterator i = g_BuildMenuItems.begin(); i != g_BuildMenuItems.end(); ++i ) +void Build_refreshMenu( QMenu* menu ){ + for ( const BuildMenuItem& item : g_BuildMenuItems ) { - gtk_container_remove( GTK_CONTAINER( menu ), GTK_WIDGET( ( *i ).m_item ) ); + menu->removeAction( item.m_item ); } g_BuildMenuItems.clear(); @@ -1186,10 +1086,11 @@ void BuildMenu_Destroy(){ void Build_runRecentExecutedBuild(){ - if( g_lastExecutedBuild.empty() ){ - g_BuildMenuItems.begin()->run(); + if( std::any_of( g_BuildMenuItems.cbegin(), g_BuildMenuItems.cend(), []( const BuildMenuItem& item ){ return g_lastExecutedBuild == &item; } ) ){ + g_lastExecutedBuild->run(); } else{ - RunBSP( g_lastExecutedBuild.c_str() ); + if( !g_BuildMenuItems.empty() ) + g_BuildMenuItems.begin()->run(); } } diff --git a/radiant/build.h b/radiant/build.h index 7f0fe073..31da7686 100644 --- a/radiant/build.h +++ b/radiant/build.h @@ -35,8 +35,7 @@ void DoBuildMenu(); void BuildMenu_Construct(); void BuildMenu_Destroy(); -typedef struct _GtkMenu GtkMenu; -void Build_constructMenu( GtkMenu* menu ); -extern GtkMenu* g_bsp_menu; +void Build_constructMenu( class QMenu* menu ); +extern QMenu* g_bsp_menu; void Build_runRecentExecutedBuild(); diff --git a/radiant/camwindow.cpp b/radiant/camwindow.cpp index 74e89717..99196452 100644 --- a/radiant/camwindow.cpp +++ b/radiant/camwindow.cpp @@ -45,10 +45,10 @@ #include "math/frustum.h" #include "gtkutil/widget.h" -#include "gtkutil/button.h" #include "gtkutil/toolbar.h" #include "gtkutil/glwidget.h" #include "gtkutil/xorrectangle.h" +#include "gtkutil/fbo.h" #include "gtkmisc.h" #include "selection.h" #include "mainframe.h" @@ -60,6 +60,8 @@ #include "timer.h" +#include + Signal0 g_cameraMoved_callbacks; void AddCameraMovedCallback( const SignalHandler& handler ){ @@ -73,40 +75,21 @@ void CameraMovedNotify(){ struct camwindow_globals_private_t { - int m_nMoveSpeed; - int m_time_toMaxSpeed; - int m_nScrollMoveSpeed; - bool m_bZoomToPointer; - float m_strafeSpeed; - float m_angleSpeed; - bool m_bCamInverseMouse; - bool m_bCamDiscrete; - bool m_bCubicClipping; - int m_strafeMode; - bool m_bFaceWire; - bool m_bFaceFill; - int m_MSAA; - bool m_bShowWorkzone; - bool m_bShowSize; - - camwindow_globals_private_t() : - m_nMoveSpeed( 500 ), - m_time_toMaxSpeed( 200 ), - m_nScrollMoveSpeed( 100 ), - m_bZoomToPointer( true ), - m_strafeSpeed( 1.f ), - m_angleSpeed( 3.f ), - m_bCamInverseMouse( false ), - m_bCamDiscrete( true ), - m_bCubicClipping( false ), - m_strafeMode( 3 ), - m_bFaceWire( true ), - m_bFaceFill( true ), - m_MSAA( 8 ), - m_bShowWorkzone( true ), - m_bShowSize( true ){ - } - + int m_nMoveSpeed = 500; + int m_time_toMaxSpeed = 200; + int m_nScrollMoveSpeed = 100; + bool m_bZoomToPointer = true; + float m_strafeSpeed = 1.f; + float m_angleSpeed = 3.f; + bool m_bCamInverseMouse = false; + bool m_bCamDiscrete = true; + bool m_bCubicClipping = false; + int m_strafeMode = 3; + bool m_bFaceWire = true; + bool m_bFaceFill = true; + int m_MSAA = 8; + bool m_bShowWorkzone = true; + bool m_bShowSize = true; }; camwindow_globals_private_t g_camwindow_globals_private; @@ -127,14 +110,14 @@ const Matrix4 g_radiant2opengl( ); struct camera_t; -void Camera_mouseMove( camera_t& camera, int x, int y, unsigned int state ); +void Camera_mouseMove( camera_t& camera, int x, int y, const QMouseEvent& event ); struct MotionDeltaValues { int x; int y; - unsigned int state; - MotionDeltaValues( int x_, int y_, unsigned int state_ ): - x( x_ ), y( y_ ), state( state_ ) { + QMouseEvent mouseMoveEvent; + MotionDeltaValues( int x_, int y_, QMouseEvent mouseMoveEvent_ ) : + x( x_ ), y( y_ ), mouseMoveEvent( mouseMoveEvent_ ) { } }; @@ -176,7 +159,7 @@ struct camera_t unsigned int movementflags; // movement flags Timer m_keycontrol_timer; - guint m_keymove_handler; + QTimer m_keycontrol_caller; float m_keymove_speed_current; @@ -185,10 +168,6 @@ struct camera_t DeferredMotionDelta m_mouseMove; - static void motionDelta( int x, int y, unsigned int state, void* data ){ - Camera_mouseMove( *reinterpret_cast( data ), x, y, state ); - } - View* m_view; Callback m_update; @@ -204,9 +183,8 @@ struct camera_t angles( 0, 0, 0 ), color( 0, 0, 0 ), movementflags( 0 ), - m_keymove_handler( 0 ), m_keymove_speed_current( 0.f ), - m_mouseMove( motionDelta, this ), + m_mouseMove( [this]( int x, int y, const QMouseEvent& event ){ Camera_mouseMove( *this, x, y, event ); } ), m_view( view ), m_update( update ), m_update_motion_freemove( update_motion_freemove ){ @@ -381,46 +359,11 @@ void Camera_FreeMove( camera_t& camera, int dx, int dy ){ Camera_Freemove_updateAxes( camera ); } -#if 0 -void Cam_MouseControl( camera_t& camera, int x, int y ){ -// int xl, xh; -// int yl, yh; - float xf, yf; - xf = (float)( x - camera.width / 2 ) / ( camera.width / 2 ); - yf = (float)( y - camera.height / 2 ) / ( camera.height / 2 ); - -// xl = camera.width / 3; -// xh = xl * 2; -// yl = camera.height / 3; -// yh = yl * 2; - - xf *= 1.0f - fabsf( yf ); - if ( xf < 0 ) { - xf += 0.1f; - if ( xf > 0 ) { - xf = 0; - } - } - else - { - xf -= 0.1f; - if ( xf < 0 ) { - xf = 0; - } - } - - vector3_add( camera.origin, vector3_scaled( camera.forward, yf * 0.02f * g_camwindow_globals_private.m_nMoveSpeed ) ); - camera.angles[CAMERA_YAW] += xf * -0.1f * g_camwindow_globals_private.m_angleSpeed; - - Camera_updateModelview( camera ); -} -#endif // 0 - -void Camera_mouseMove( camera_t& camera, int x, int y, unsigned int state ){ +void Camera_mouseMove( camera_t& camera, int x, int y, const QMouseEvent& event ){ //globalOutputStream() << "mousemove... "; Camera_FreeMove( camera, -x, -y ); - camera.m_update_motion_freemove( MotionDeltaValues( x, y, state ) ); + camera.m_update_motion_freemove( MotionDeltaValues( x, y, event ) ); camera.m_update(); CameraMovedNotify(); } @@ -497,6 +440,10 @@ void Cam_KeyControl( camera_t& camera, float dtime ){ } void Camera_keyMove( camera_t& camera ){ +// globalOutputStream() << camera.m_keycontrol_timer.elapsed_sec() << '\n'; + if( camera.m_keycontrol_timer.elapsed_msec() == 0 ) // a lot of zeros happen = torn, slow, inconsistent motion 🤔 + return; + camera.m_mouseMove.flush(); //globalOutputStream() << "keymove... "; @@ -511,14 +458,10 @@ void Camera_keyMove( camera_t& camera ){ CameraMovedNotify(); } -gboolean camera_keymove( gpointer data ){ - Camera_keyMove( *reinterpret_cast( data ) ); - return TRUE; -} - void Camera_setMovementFlags( camera_t& camera, unsigned int mask ){ if ( ( ~camera.movementflags & mask ) != 0 && camera.movementflags == 0 ) { - camera.m_keymove_handler = g_idle_add( camera_keymove, &camera ); + camera.m_keycontrol_caller.callOnTimeout( [&camera](){ Camera_keyMove( camera ); } ); + camera.m_keycontrol_caller.start( 4 ); // with 0 consumes entire thread by spamming calls 🤷‍♀️ camera.m_keycontrol_timer.start(); camera.m_keymove_speed_current = 0; } @@ -526,8 +469,7 @@ void Camera_setMovementFlags( camera_t& camera, unsigned int mask ){ } void Camera_clearMovementFlags( camera_t& camera, unsigned int mask ){ if ( ( camera.movementflags & ~mask ) == 0 && camera.movementflags != 0 ) { - g_source_remove( camera.m_keymove_handler ); - camera.m_keymove_handler = 0; + camera.m_keycontrol_caller.stop(); } camera.movementflags &= ~mask; } @@ -713,43 +655,41 @@ public: }; -void Camera_motionDelta( int x, int y, unsigned int state, void* data ){ - camera_t* cam = reinterpret_cast( data ); +static void Camera_motionDelta( int x, int y, const QMouseEvent *event, camera_t& cam ){ + cam.m_mouseMove.motion_delta( x, y, event ); - cam->m_mouseMove.motion_delta( x, y, state ); - - cam->m_orbit = ( state & GDK_MOD1_MASK ) && ( state & GDK_BUTTON3_MASK ); - if( cam->m_orbit ){ - cam->m_strafe = false; + cam.m_orbit = ( event->modifiers() & Qt::KeyboardModifier::AltModifier ) && ( event->buttons() & Qt::MouseButton::RightButton ); + if( cam.m_orbit ){ + cam.m_strafe = false; return; } - cam->m_strafe_forward_invert = false; + cam.m_strafe_forward_invert = false; switch ( g_camwindow_globals_private.m_strafeMode ) { case 0: - cam->m_strafe = false; + cam.m_strafe = false; break; case 1: - cam->m_strafe = ( state & GDK_CONTROL_MASK ) || ( state & GDK_BUTTON3_MASK ); - cam->m_strafe_forward = false; + cam.m_strafe = ( event->modifiers() & Qt::KeyboardModifier::ControlModifier ) || ( event->buttons() & Qt::MouseButton::RightButton ); + cam.m_strafe_forward = false; break; case 2: - cam->m_strafe = ( state & GDK_CONTROL_MASK ) || ( state & GDK_BUTTON3_MASK ); - cam->m_strafe_forward = true; + cam.m_strafe = ( event->modifiers() & Qt::KeyboardModifier::ControlModifier ) || ( event->buttons() & Qt::MouseButton::RightButton ); + cam.m_strafe_forward = true; break; case 4: - cam->m_strafe_forward_invert = true; // fall through + cam.m_strafe_forward_invert = true; // fall through default: /* 3 & 4 */ - cam->m_strafe = ( state & GDK_CONTROL_MASK ) || ( state & GDK_BUTTON3_MASK ) || ( state & GDK_SHIFT_MASK ); - cam->m_strafe_forward = ( state & GDK_SHIFT_MASK ) != 0; + cam.m_strafe = ( event->modifiers() & Qt::KeyboardModifier::ControlModifier ) || ( event->buttons() & Qt::MouseButton::RightButton ) || ( event->modifiers() & Qt::KeyboardModifier::ShiftModifier ); + cam.m_strafe_forward = ( event->modifiers() & Qt::KeyboardModifier::ShiftModifier ) != 0; break; } - if( ( state & GDK_BUTTON1_MASK ) != 0 && g_camwindow_globals_private.m_strafeMode != 0 ){ - cam->m_strafe = true; - cam->m_strafe_forward = false; + if( ( event->buttons() & Qt::MouseButton::LeftButton ) != 0 && g_camwindow_globals_private.m_strafeMode != 0 ){ + cam.m_strafe = true; + cam.m_strafe_forward = false; } } @@ -820,7 +760,7 @@ class RenderableCamWorkzone : public OpenGLRenderable mutable std::array m_colorarr1[3]; public: void render( RenderStateFlags state ) const { - glEnableClientState( GL_EDGE_FLAG_ARRAY ); + gl().glEnableClientState( GL_EDGE_FLAG_ARRAY ); const AABB bounds = GlobalSelectionSystem().getBoundsSelected(); @@ -886,8 +826,8 @@ public: } } - glVertexPointer( 3, GL_FLOAT, sizeof( Vector3 ), verticesarr.data()->data() ); - glEdgeFlagPointer( sizeof( GLboolean ), edgearr.data() ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( Vector3 ), verticesarr.data()->data() ); + gl().glEdgeFlagPointer( sizeof( GLboolean ), edgearr.data() ); for( std::vector::const_iterator j = points.begin(); j != points.end(); ++++j ){ const std::vector::const_iterator jj = j + 1; for( std::size_t k = 0; k < count; k += 4 ){ @@ -901,18 +841,18 @@ public: verticesarr[k + 3][i3] = ( *j )[i3]; } - glPolygonOffset( -2, 2 ); - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( Colour4b ), colorarr0.data() ); - glDrawArrays( GL_QUADS, start0? 0 : 2, GLsizei( count - ( start0? 4 : 2 ) ) ); + gl().glPolygonOffset( -2, 2 ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( Colour4b ), colorarr0.data() ); + gl().glDrawArrays( GL_QUADS, start0? 0 : 2, GLsizei( count - ( start0? 4 : 2 ) ) ); - glPolygonOffset( 1, -1 ); - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( Colour4b ), colorarr1.data() ); - glDrawArrays( GL_QUADS, start0? 2 : 0, GLsizei( count - ( start0? 2 : 4 ) ) ); - glPolygonOffset( -1, 1 ); // restore default + gl().glPolygonOffset( 1, -1 ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( Colour4b ), colorarr1.data() ); + gl().glDrawArrays( GL_QUADS, start0? 2 : 0, GLsizei( count - ( start0? 2 : 4 ) ) ); + gl().glPolygonOffset( -1, 1 ); // restore default } } - glDisableClientState( GL_EDGE_FLAG_ARRAY ); + gl().glDisableClientState( GL_EDGE_FLAG_ARRAY ); } void render( Renderer& renderer, Shader* shader ) const { @@ -935,8 +875,6 @@ class CamWnd int m_PositionDragCursorY; #endif - guint m_freemove_handle_focusout; - static Shader* m_state_select0; static Shader* m_state_select1; static Shader* m_state_wire; @@ -950,29 +888,16 @@ class CamWnd RenderableCamWorkzone m_draw_workzone; public: - FBO* m_fbo; - FBO* fbo_get(){ - return m_fbo = m_fbo? m_fbo : GlobalOpenGL().support_ARB_framebuffer_object? new FBO : new FBO_fallback; - } - GtkWidget* m_gl_widget; - GtkWindow* m_parent; + QWidget* m_gl_widget; + QWidget* m_parent; SelectionSystemWindowObserver* m_window_observer; XORRectangle m_XORRectangle; + rect_t m_XORRect; DeferredDraw m_deferredDraw; DeferredMotion m_deferred_motion; - guint m_selection_button_press_handler; - guint m_selection_button_release_handler; - guint m_selection_motion_handler; - - guint m_freelook_button_press_handler; - guint m_freelook_button_release_handler; - - guint m_sizeHandler; - guint m_exposeHandler; - Timer m_render_time; CamWnd(); @@ -1027,12 +952,11 @@ public: void selection_motion_freemove( const MotionDeltaValues& delta ); + bool m_drawRequired{}; // whether complete redraw is required, or just overlay update is enough private: void Cam_Draw(); }; -typedef MemberCaller CamWndQueueDraw; - Shader* CamWnd::m_state_select0 = 0; Shader* CamWnd::m_state_select1 = 0; Shader* CamWnd::m_state_wire = 0; @@ -1067,25 +991,22 @@ void GlobalCamera_setCamWnd( CamWnd& camwnd ){ } -GtkWidget* CamWnd_getWidget( CamWnd& camwnd ){ +QWidget* CamWnd_getWidget( CamWnd& camwnd ){ return camwnd.m_gl_widget; } -GtkWindow* CamWnd_getParent( CamWnd& camwnd ){ - return camwnd.m_parent; -} - ToggleShown g_camera_shown( true ); -void CamWnd_Shown_Construct( GtkWindow* parent ){ - g_camera_shown.connect( GTK_WIDGET( parent ) ); +void CamWnd_Shown_Construct( QWidget* parent ){ + g_camera_shown.connect( parent ); } -void CamWnd_setParent( CamWnd& camwnd, GtkWindow* parent ){ +void CamWnd_setParent( CamWnd& camwnd, QWidget* parent ){ camwnd.m_parent = parent; } void CamWnd_Update( CamWnd& camwnd ){ + camwnd.m_drawRequired = true; camwnd.queue_draw(); } @@ -1124,21 +1045,11 @@ void context_menu_show(){ } } -void context_menu(){ - //need this hack, otherwise button wont be released = global accels broken, until correct button pressed again... - GdkEvent* event_ = gtk_get_current_event(); - if( event_ ){ - event_->type = GDK_BUTTON_RELEASE; - gtk_main_do_event( event_ ); - gdk_event_free( event_ ); - context_menu_show(); - } -} - /* GDK_2BUTTON_PRESS doesn't always work in this case, so... */ -bool context_menu_try( CamWnd* camwnd ){ +/* with Qt freezepointer interrupts internal doubleclick timer, so use custom one */ +inline bool context_menu_try( const CamWnd& camwnd ){ //globalOutputStream() << camwnd->m_rightClickTimer.elapsed_msec() << "\n"; - return camwnd->m_rightClickTimer.elapsed_msec() < 250; + return camwnd.m_rightClickTimer.elapsed_msec() < 250; //doesn't work if cam redraw > 200msec (3x click works): gtk_widget_queue_draw proceeds after timer.start() } @@ -1155,145 +1066,99 @@ void camera_orbit_init( camera_t& cam, Vector2 xy ){ cam.m_orbit = true; } -inline bool ORBIT_EVENT( GdkEventButton* event ){ - return event->button == 3 && modifiers_for_state( event->state ) == c_modifierAlt; +inline bool ORBIT_EVENT( const QMouseEvent *event ){ + return event->button() == Qt::MouseButton::RightButton && modifiers_for_state( event->modifiers() ) == c_modifierAlt; } -inline bool M2_EVENT( GdkEventButton* event ){ - return event->button == 3 && modifiers_for_state( event->state ) == c_modifierNone; +inline bool M2_EVENT( const QMouseEvent *event ){ + return event->button() == Qt::MouseButton::RightButton && modifiers_for_state( event->modifiers() ) == c_modifierNone; } -gboolean enable_freelook_button_press( GtkWidget* widget, GdkEventButton* event, CamWnd* camwnd ){ +static void enable_freelook_button_press( const QMouseEvent *event, CamWnd& camwnd ){ const bool m2 = M2_EVENT( event ); const bool m2alt = ORBIT_EVENT( event ); - if ( ( m2 || m2alt ) && event->type == GDK_BUTTON_PRESS ) { - camwnd->m_bFreeMove_entering = true; + if ( m2 || m2alt ) { + camwnd.m_bFreeMove_entering = true; if( m2 && context_menu_try( camwnd ) ){ - context_menu(); + context_menu_show(); } else{ if( m2alt ) - camera_orbit_init( camwnd->getCamera(), Vector2( event->x, event->y ) ); - camwnd->EnableFreeMove(); - camwnd->m_rightClickTimer.start(); - camwnd->m_rightClickMove = 0; + camera_orbit_init( camwnd.getCamera(), Vector2( event->x(), event->y() ) ); + camwnd.EnableFreeMove(); + camwnd.m_rightClickTimer.start(); + camwnd.m_rightClickMove = 0; } - return TRUE; } - return FALSE; } -gboolean disable_freelook_button_press( GtkWidget* widget, GdkEventButton* event, CamWnd* camwnd ){ +static void disable_freelook_button_press( const QMouseEvent *event, CamWnd& camwnd ){ const bool m2 = M2_EVENT( event ); const bool m2alt = ORBIT_EVENT( event ); - if ( ( m2 || m2alt ) && event->type == GDK_BUTTON_PRESS ) { - camwnd->m_bFreeMove_entering = false; + if ( m2 || m2alt ) { + camwnd.m_bFreeMove_entering = false; if( m2 && context_menu_try( camwnd ) ){ - camwnd->DisableFreeMove(); - context_menu(); + camwnd.DisableFreeMove(); + context_menu_show(); } else{ if( m2alt ) - camera_orbit_init( camwnd->getCamera(), Vector2( event->x, event->y ) ); - camwnd->m_rightClickTimer.start(); - camwnd->m_rightClickMove = 0; + camera_orbit_init( camwnd.getCamera(), Vector2( event->x(), event->y() ) ); + camwnd.m_rightClickTimer.start(); + camwnd.m_rightClickMove = 0; } - return TRUE; } - return FALSE; } -gboolean disable_freelook_button_release( GtkWidget* widget, GdkEventButton* event, CamWnd* camwnd ){ +static void disable_freelook_button_release( const QMouseEvent *event, CamWnd& camwnd ){ const bool m2 = M2_EVENT( event ); const bool m2alt = ORBIT_EVENT( event ); - if ( ( m2 || m2alt ) && event->type == GDK_BUTTON_RELEASE ) { - camwnd->getCamera().m_orbit = false; - if( ( ( camwnd->m_rightClickTimer.elapsed_msec() < 300 && camwnd->m_rightClickMove < 56 ) == !camwnd->m_bFreeMove_entering ) ){ - camwnd->DisableFreeMove(); - return TRUE; + if ( m2 || m2alt ) { + camwnd.getCamera().m_orbit = false; + if( ( ( camwnd.m_rightClickTimer.elapsed_msec() < 300 && camwnd.m_rightClickMove < 56 ) == !camwnd.m_bFreeMove_entering ) ){ + camwnd.DisableFreeMove(); } } - return FALSE; } -#if 0 -gboolean mousecontrol_button_press( GtkWidget* widget, GdkEventButton* event, CamWnd* camwnd ){ - if ( event->type == GDK_BUTTON_PRESS && event->button == 3 ) { - GtkAllocation allocation; - gtk_widget_get_allocation( widget, &allocation ); - Cam_MouseControl( camwnd->getCamera(), event->x, allocation.height - 1 - event->y ); - } - return FALSE; -} -#endif void camwnd_update_xor_rectangle( CamWnd& self, rect_t area ){ - if ( gtk_widget_get_visible( self.m_gl_widget ) ) { - if ( glwidget_make_current( self.m_gl_widget ) ) { - if ( Map_Valid( g_map ) && ScreenUpdates_Enabled() ) { - GlobalOpenGL_debugAssertNoErrors(); + self.m_XORRect = area; + self.queue_draw(); + } -// glDrawBuffer( GL_FRONT ); - self.fbo_get()->blit(); - self.m_XORRectangle.set( area, self.getCamera().width, self.getCamera().height ); - -// glDrawBuffer( GL_BACK ); - - GlobalOpenGL_debugAssertNoErrors(); -// glwidget_make_current( self.m_gl_widget ); - glwidget_swap_buffers( self.m_gl_widget ); - } - } - } +static void selection_button_press( const QMouseEvent *event, WindowObserver* observer ){ + if( !ORBIT_EVENT( event ) ) + observer->onMouseDown( WindowVector( event->x(), event->y() ), button_for_button( event->button() ), modifiers_for_state( event->modifiers() ) ); } - -gboolean selection_button_press( GtkWidget* widget, GdkEventButton* event, WindowObserver* observer ){ - if ( event->type == GDK_BUTTON_PRESS ) { - gtk_widget_grab_focus( widget ); - if( !ORBIT_EVENT( event ) ) - observer->onMouseDown( WindowVector( event->x, event->y ), button_for_button( event->button ), modifiers_for_state( event->state ) ); - } - return FALSE; +static void selection_button_release( const QMouseEvent *event, WindowObserver* observer ){ + observer->onMouseUp( WindowVector( event->x(), event->y() ), button_for_button( event->button() ), modifiers_for_state( event->modifiers() ) ); } -gboolean selection_button_release( GtkWidget* widget, GdkEventButton* event, WindowObserver* observer ){ - if ( event->type == GDK_BUTTON_RELEASE ) { - observer->onMouseUp( WindowVector( event->x, event->y ), button_for_button( event->button ), modifiers_for_state( event->state ) ); - } - return FALSE; -} - -void selection_motion( gdouble x, gdouble y, guint state, void* data ){ +void selection_motion( const QMouseEvent& event, WindowObserver* observer ){ //globalOutputStream() << "motion... "; - reinterpret_cast( data )->onMouseMotion( WindowVector( x, y ), modifiers_for_state( state ) ); + observer->onMouseMotion( WindowVector( event.x(), event.y() ), modifiers_for_state( event.modifiers() ) ); } -inline WindowVector windowvector_for_widget_centre( GtkWidget* widget ){ - GtkAllocation allocation; - gtk_widget_get_allocation( widget, &allocation ); - return WindowVector( static_cast( allocation.width / 2 ), static_cast( allocation.height / 2 ) ); +inline WindowVector windowvector_for_widget_centre( const QWidget* widget ){ + const QPoint center = widget->rect().center(); + return WindowVector( center.x(), center.y() ); } -gboolean selection_button_press_freemove( GtkWidget* widget, GdkEventButton* event, WindowObserver* observer ){ - if ( event->type == GDK_BUTTON_PRESS ) { - if( !ORBIT_EVENT( event ) ) - observer->onMouseDown( windowvector_for_widget_centre( widget ), button_for_button( event->button ), modifiers_for_state( event->state ) ); - } - return FALSE; +static void selection_button_press_freemove( QWidget* widget, const QMouseEvent *event, WindowObserver* observer ){ + if( !ORBIT_EVENT( event ) ) + observer->onMouseDown( windowvector_for_widget_centre( widget ), button_for_button( event->button() ), modifiers_for_state( event->modifiers() ) ); } -gboolean selection_button_release_freemove( GtkWidget* widget, GdkEventButton* event, WindowObserver* observer ){ - if ( event->type == GDK_BUTTON_RELEASE ) { - observer->onMouseUp( windowvector_for_widget_centre( widget ), button_for_button( event->button ), modifiers_for_state( event->state ) ); - } - return FALSE; +static void selection_button_release_freemove( QWidget* widget, const QMouseEvent *event, WindowObserver* observer ){ + observer->onMouseUp( windowvector_for_widget_centre( widget ), button_for_button( event->button() ), modifiers_for_state( event->modifiers() ) ); } void CamWnd::selection_motion_freemove( const MotionDeltaValues& delta ){ m_rightClickMove += sqrt( static_cast( delta.x * delta.x + delta.y * delta.y ) ); m_window_observer->incMouseMove( WindowVector( delta.x, delta.y ) ); - m_window_observer->onMouseMotion( windowvector_for_widget_centre( m_gl_widget ), modifiers_for_state( delta.state ) ); + m_window_observer->onMouseMotion( windowvector_for_widget_centre( m_gl_widget ), modifiers_for_state( delta.mouseMoveEvent.modifiers() ) ); } typedef MemberCaller1 CamWnd_selection_motion_freemove; @@ -1343,8 +1208,8 @@ static void camera_zoom( CamWnd& camwnd, float x, float y, float step ){ Vector3 normalized; - normalized[0] = 2.0f * x / static_cast( cam.width ) - 1.0f; - normalized[1] = 2.0f * y / static_cast( cam.height ) - 1.0f; + normalized[0] = 2.0f * x / cam.width - 1.0f; + normalized[1] = 2.0f * y / cam.height - 1.0f; normalized[1] *= -1.f; normalized[2] = 0.f; @@ -1359,59 +1224,41 @@ static void camera_zoom( CamWnd& camwnd, float x, float y, float step ){ } } -gboolean wheelmove_scroll( GtkWidget* widget, GdkEventScroll* event, CamWnd* camwnd ){ - //gtk_window_set_focus( camwnd->m_parent, camwnd->m_gl_widget ); - gtk_widget_grab_focus( camwnd->m_gl_widget ); - if( !gtk_window_is_active( camwnd->m_parent ) ) - gtk_window_present( camwnd->m_parent ); +static void wheelmove_scroll( const QWheelEvent *event, CamWnd& camwnd ){ + camera_t& cam = camwnd.getCamera(); - camera_t& cam = camwnd->getCamera(); + const int angleDelta = ( std::abs( event->angleDelta().y() ) > std::abs( event->angleDelta().x() ) ) // normal y() goes to x() with ALT pressed + ? event->angleDelta().y() + : event->angleDelta().x(); - if ( event->direction == GDK_SCROLL_UP ) { + if ( angleDelta > 0 ) { if ( cam.movementflags & MOVE_FOCUS ) { ++cam.m_focus_offset; - return FALSE; + return; } else if( cam.m_orbit ){ ++cam.m_orbit_offset; camera_orbit_scroll( cam ); - return FALSE; + return; } Camera_Freemove_updateAxes( cam ); - camera_zoom( *camwnd, event->x, event->y, g_camwindow_globals_private.m_nScrollMoveSpeed ); + camera_zoom( camwnd, event->position().x(), event->position().y(), g_camwindow_globals_private.m_nScrollMoveSpeed ); } - else if ( event->direction == GDK_SCROLL_DOWN ) { + else if ( angleDelta < 0 ) { if ( cam.movementflags & MOVE_FOCUS ) { --cam.m_focus_offset; - return FALSE; + return; } else if( cam.m_orbit ){ --cam.m_orbit_offset; camera_orbit_scroll( cam ); - return FALSE; + return; } Camera_Freemove_updateAxes( cam ); - camera_zoom( *camwnd, event->x, event->y, -g_camwindow_globals_private.m_nScrollMoveSpeed ); + camera_zoom( camwnd, event->position().x(), event->position().y(), -g_camwindow_globals_private.m_nScrollMoveSpeed ); } - - return FALSE; -} - -gboolean camera_size_allocate( GtkWidget* widget, GtkAllocation* allocation, CamWnd* camwnd ){ - camwnd->fbo_get()->reset( allocation->width, allocation->height, g_camwindow_globals_private.m_MSAA, true ); - camwnd->getCamera().width = allocation->width; - camwnd->getCamera().height = allocation->height; - Camera_updateProjection( camwnd->getCamera() ); - camwnd->m_window_observer->onSizeChanged( camwnd->getCamera().width, camwnd->getCamera().height ); - camwnd->queue_draw(); - return FALSE; -} - -gboolean camera_expose( GtkWidget* widget, GdkEventExpose* event, gpointer data ){ - reinterpret_cast( data )->draw(); - return FALSE; } void KeyEvent_connect( const char* name ){ @@ -1427,91 +1274,91 @@ void KeyEvent_disconnect( const char* name ){ } void CamWnd_registerCommands( CamWnd& camwnd ){ - GlobalKeyEvents_insert( "CameraForward", accelerator_null(), + GlobalKeyEvents_insert( "CameraForward", ReferenceCaller( camwnd.getCamera() ), ReferenceCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraBack", accelerator_null(), + GlobalKeyEvents_insert( "CameraBack", ReferenceCaller( camwnd.getCamera() ), ReferenceCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraLeft", accelerator_null(), + GlobalKeyEvents_insert( "CameraLeft", ReferenceCaller( camwnd.getCamera() ), ReferenceCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraRight", accelerator_null(), + GlobalKeyEvents_insert( "CameraRight", ReferenceCaller( camwnd.getCamera() ), ReferenceCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraStrafeRight", accelerator_null(), + GlobalKeyEvents_insert( "CameraStrafeRight", ReferenceCaller( camwnd.getCamera() ), ReferenceCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraStrafeLeft", accelerator_null(), + GlobalKeyEvents_insert( "CameraStrafeLeft", ReferenceCaller( camwnd.getCamera() ), ReferenceCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraUp", accelerator_null(), + GlobalKeyEvents_insert( "CameraUp", ReferenceCaller( camwnd.getCamera() ), ReferenceCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraDown", accelerator_null(), + GlobalKeyEvents_insert( "CameraDown", ReferenceCaller( camwnd.getCamera() ), ReferenceCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraAngleUp", accelerator_null(), + GlobalKeyEvents_insert( "CameraAngleUp", ReferenceCaller( camwnd.getCamera() ), ReferenceCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraAngleDown", accelerator_null(), + GlobalKeyEvents_insert( "CameraAngleDown", ReferenceCaller( camwnd.getCamera() ), ReferenceCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveForward", accelerator_null(), + GlobalKeyEvents_insert( "CameraFreeMoveForward", FreeMoveCameraMoveForwardKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveForwardKeyUpCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveBack", accelerator_null(), + GlobalKeyEvents_insert( "CameraFreeMoveBack", FreeMoveCameraMoveBackKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveBackKeyUpCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveLeft", accelerator_null(), + GlobalKeyEvents_insert( "CameraFreeMoveLeft", FreeMoveCameraMoveLeftKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveLeftKeyUpCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveRight", accelerator_null(), + GlobalKeyEvents_insert( "CameraFreeMoveRight", FreeMoveCameraMoveRightKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveRightKeyUpCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveForward2", accelerator_null(), + GlobalKeyEvents_insert( "CameraFreeMoveForward2", FreeMoveCameraMoveForwardKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveForwardKeyUpCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveBack2", accelerator_null(), + GlobalKeyEvents_insert( "CameraFreeMoveBack2", FreeMoveCameraMoveBackKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveBackKeyUpCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveLeft2", accelerator_null(), + GlobalKeyEvents_insert( "CameraFreeMoveLeft2", FreeMoveCameraMoveLeftKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveLeftKeyUpCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveRight2", accelerator_null(), + GlobalKeyEvents_insert( "CameraFreeMoveRight2", FreeMoveCameraMoveRightKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveRightKeyUpCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveUp", accelerator_null(), + GlobalKeyEvents_insert( "CameraFreeMoveUp", FreeMoveCameraMoveUpKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveUpKeyUpCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveDown", accelerator_null(), + GlobalKeyEvents_insert( "CameraFreeMoveDown", FreeMoveCameraMoveDownKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveDownKeyUpCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeFocus", accelerator_null(), + GlobalKeyEvents_insert( "CameraFreeFocus", FreeMoveCameraFocusKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraFocusKeyUpCaller( camwnd.getCamera() ) ); @@ -1614,12 +1461,6 @@ void CamWnd_Move_Discrete_Import( bool value ){ void CamWnd_Add_Handlers_Move( CamWnd& camwnd ){ - camwnd.m_selection_button_press_handler = g_signal_connect( G_OBJECT( camwnd.m_gl_widget ), "button_press_event", G_CALLBACK( selection_button_press ), camwnd.m_window_observer ); - camwnd.m_selection_button_release_handler = g_signal_connect( G_OBJECT( camwnd.m_gl_widget ), "button_release_event", G_CALLBACK( selection_button_release ), camwnd.m_window_observer ); - camwnd.m_selection_motion_handler = g_signal_connect( G_OBJECT( camwnd.m_gl_widget ), "motion_notify_event", G_CALLBACK( DeferredMotion::gtk_motion ), &camwnd.m_deferred_motion ); - - camwnd.m_freelook_button_press_handler = g_signal_connect( G_OBJECT( camwnd.m_gl_widget ), "button_press_event", G_CALLBACK( enable_freelook_button_press ), &camwnd ); - if ( g_camwindow_globals_private.m_bCamDiscrete ) { CamWnd_Move_Discrete_Enable( camwnd ); } @@ -1630,12 +1471,6 @@ void CamWnd_Add_Handlers_Move( CamWnd& camwnd ){ } void CamWnd_Remove_Handlers_Move( CamWnd& camwnd ){ - g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_selection_button_press_handler ); - g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_selection_button_release_handler ); - g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_selection_motion_handler ); - - g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_freelook_button_press_handler ); - if ( g_camwindow_globals_private.m_bCamDiscrete ) { CamWnd_Move_Discrete_Disable( camwnd ); } @@ -1646,12 +1481,6 @@ void CamWnd_Remove_Handlers_Move( CamWnd& camwnd ){ } void CamWnd_Add_Handlers_FreeMove( CamWnd& camwnd ){ - camwnd.m_selection_button_press_handler = g_signal_connect( G_OBJECT( camwnd.m_gl_widget ), "button_press_event", G_CALLBACK( selection_button_press_freemove ), camwnd.m_window_observer ); - camwnd.m_selection_button_release_handler = g_signal_connect( G_OBJECT( camwnd.m_gl_widget ), "button_release_event", G_CALLBACK( selection_button_release_freemove ), camwnd.m_window_observer ); - - camwnd.m_freelook_button_press_handler = g_signal_connect( G_OBJECT( camwnd.m_gl_widget ), "button_press_event", G_CALLBACK( disable_freelook_button_press ), &camwnd ); - camwnd.m_freelook_button_release_handler = g_signal_connect( G_OBJECT( camwnd.m_gl_widget ), "button_release_event", G_CALLBACK( disable_freelook_button_release ), &camwnd ); - KeyEvent_connect( "CameraFreeMoveForward" ); KeyEvent_connect( "CameraFreeMoveBack" ); KeyEvent_connect( "CameraFreeMoveLeft" ); @@ -1683,28 +1512,104 @@ void CamWnd_Remove_Handlers_FreeMove( CamWnd& camwnd ){ KeyEvent_disconnect( "CameraFreeMoveDown" ); KeyEvent_disconnect( "CameraFreeFocus" ); - - g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_selection_button_press_handler ); - g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_selection_button_release_handler ); - - g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_freelook_button_press_handler ); - g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_freelook_button_release_handler ); } +class CamGLWidget : public QOpenGLWidget +{ + CamWnd& m_camwnd; + FBO *m_fbo{}; +public: + CamGLWidget( CamWnd& camwnd ) : QOpenGLWidget(), m_camwnd( camwnd ) { + setMouseTracking( true ); + } + + ~CamGLWidget() override { + delete m_fbo; + glwidget_context_destroyed(); + } + +protected: + void initializeGL() override + { + glwidget_context_created( *this ); + } + void resizeGL( int w, int h ) override + { + delete m_fbo; + m_fbo = new FBO( w, h, true, g_camwindow_globals_private.m_MSAA ); + + m_camwnd.getCamera().width = w; + m_camwnd.getCamera().height = h; + Camera_updateProjection( m_camwnd.getCamera() ); + m_camwnd.m_window_observer->onSizeChanged( m_camwnd.getCamera().width, m_camwnd.getCamera().height ); + + m_camwnd.m_drawRequired = true; + } + void paintGL() override + { + if( m_fbo->m_samples != g_camwindow_globals_private.m_MSAA ){ + delete m_fbo; + m_fbo = new FBO( m_camwnd.getCamera().width, m_camwnd.getCamera().height, true, g_camwindow_globals_private.m_MSAA ); + } + + if ( Map_Valid( g_map ) && ScreenUpdates_Enabled() && m_fbo->bind() ) { + if( m_camwnd.m_drawRequired ){ + m_camwnd.m_drawRequired = false; + m_camwnd.draw(); + } + m_fbo->blit(); + m_fbo->release(); + m_camwnd.m_XORRectangle.render( m_camwnd.m_XORRect, m_camwnd.getCamera().width, m_camwnd.getCamera().height ); + GlobalOpenGL_debugAssertNoErrors(); + } + } + + void mousePressEvent( QMouseEvent *event ) override { + if( !m_camwnd.m_bFreeMove ){ + setFocus(); + selection_button_press( event, m_camwnd.m_window_observer ); + enable_freelook_button_press( event, m_camwnd ); + } + else{ + selection_button_press_freemove( this, event, m_camwnd.m_window_observer ); + disable_freelook_button_press( event, m_camwnd ); + } + } + void mouseMoveEvent( QMouseEvent *event ) override { + if( !m_camwnd.m_bFreeMove ){ + m_camwnd.m_deferred_motion.motion( event ); + } + else{ + ; + } + } + void mouseReleaseEvent( QMouseEvent *event ) override { + if( !m_camwnd.m_bFreeMove ){ + selection_button_release( event, m_camwnd.m_window_observer ); + } + else{ + selection_button_release_freemove( this, event, m_camwnd.m_window_observer ); + disable_freelook_button_release( event, m_camwnd ); + } + } + void wheelEvent( QWheelEvent *event ) override { + setFocus(); + if( !m_camwnd.m_parent->isActiveWindow() ){ + m_camwnd.m_parent->activateWindow(); + m_camwnd.m_parent->raise(); + } + wheelmove_scroll( event, m_camwnd ); + } +}; + CamWnd::CamWnd() : m_view( true ), - m_Camera( &m_view, CamWndQueueDraw( *this ), CamWnd_selection_motion_freemove( *this ) ), + m_Camera( &m_view, ReferenceCaller( *this ), CamWnd_selection_motion_freemove( *this ) ), m_cameraview( m_Camera, &m_view, ReferenceCaller( *this ) ), - m_fbo( 0 ), - m_gl_widget( glwidget_new( TRUE ) ), + m_gl_widget( new CamGLWidget( *this ) ), m_window_observer( NewWindowObserver() ), m_deferredDraw( WidgetQueueDrawCaller( *m_gl_widget ) ), - m_deferred_motion( selection_motion, m_window_observer ), - m_selection_button_press_handler( 0 ), - m_selection_button_release_handler( 0 ), - m_selection_motion_handler( 0 ), - m_freelook_button_press_handler( 0 ), - m_freelook_button_release_handler( 0 ), + m_deferred_motion( [this]( const QMouseEvent& event ){ selection_motion( event, m_window_observer ); } ), m_drawing( false ) { m_bFreeMove = false; @@ -1715,25 +1620,13 @@ CamWnd::CamWnd() : m_window_observer->setRectangleDrawCallback( ReferenceCaller1( *this ) ); m_window_observer->setView( m_view ); - g_object_ref( G_OBJECT( m_gl_widget ) ); - - gtk_widget_set_events( m_gl_widget, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK ); - gtk_widget_set_can_focus( m_gl_widget, TRUE ); - - m_sizeHandler = g_signal_connect( G_OBJECT( m_gl_widget ), "size_allocate", G_CALLBACK( camera_size_allocate ), this ); - m_exposeHandler = g_signal_connect( G_OBJECT( m_gl_widget ), "expose_event", G_CALLBACK( camera_expose ), this ); - - Map_addValidCallback( g_map, DeferredDrawOnMapValidChangedCaller( m_deferredDraw ) ); + Map_addValidCallback( g_map, DeferredDrawOnMapValidChangedCaller( m_deferredDraw ) ); //. correct would be m_drawRequired = true here CamWnd_registerCommands( *this ); CamWnd_Add_Handlers_Move( *this ); - g_signal_connect( G_OBJECT( m_gl_widget ), "scroll_event", G_CALLBACK( wheelmove_scroll ), this ); - AddSceneChangeCallback( ReferenceCaller( *this ) ); - - PressedButtons_connect( g_pressedButtons, m_gl_widget ); } CamWnd::~CamWnd(){ @@ -1743,13 +1636,6 @@ CamWnd::~CamWnd(){ CamWnd_Remove_Handlers_Move( *this ); - g_signal_handler_disconnect( G_OBJECT( m_gl_widget ), m_sizeHandler ); - g_signal_handler_disconnect( G_OBJECT( m_gl_widget ), m_exposeHandler ); - - g_object_unref( G_OBJECT( m_gl_widget ) ); - - delete m_fbo; - m_window_observer->release(); } @@ -1813,46 +1699,6 @@ void CamWnd::Cam_ChangeFloor( bool up ){ } -#if 0 - -// button_press -Sys_GetCursorPos( &m_PositionDragCursorX, &m_PositionDragCursorY ); - -// motion -if ( ( m_bFreeMove && ( buttons == ( RAD_CONTROL | RAD_SHIFT ) ) ) - || ( !m_bFreeMove && ( buttons == ( RAD_RBUTTON | RAD_CONTROL ) ) ) ) { - Cam_PositionDrag(); - CamWnd_Update( camwnd ); - CameraMovedNotify(); - return; -} - -void CamWnd::Cam_PositionDrag(){ - int x, y; - - Sys_GetCursorPos( GTK_WINDOW( m_gl_widget ), &x, &y ); - if ( x != m_PositionDragCursorX || y != m_PositionDragCursorY ) { - x -= m_PositionDragCursorX; - vector3_add( m_Camera.origin, vector3_scaled( m_Camera.vright, x ) ); - y -= m_PositionDragCursorY; - m_Camera.origin[2] -= y; - Camera_updateModelview(); - CamWnd_Update( camwnd ); - CameraMovedNotify(); - - Sys_SetCursorPos( GTK_WINDOW( m_parent ), m_PositionDragCursorX, m_PositionDragCursorY ); - } -} -#endif - - -// NOTE TTimo if there's an OS-level focus out of the application -// then we can release the camera cursor grab -static gboolean camwindow_freemove_focusout( GtkWidget* widget, GdkEventFocus* event, gpointer data ){ - reinterpret_cast( data )->DisableFreeMove(); - return FALSE; -} - void CamWnd::EnableFreeMove(){ //globalOutputStream() << "EnableFreeMove\n"; @@ -1863,9 +1709,14 @@ void CamWnd::EnableFreeMove(){ CamWnd_Remove_Handlers_Move( *this ); CamWnd_Add_Handlers_FreeMove( *this ); - gtk_window_set_focus( m_parent, m_gl_widget ); - m_freemove_handle_focusout = g_signal_connect( G_OBJECT( m_gl_widget ), "focus_out_event", G_CALLBACK( camwindow_freemove_focusout ), this ); - m_freezePointer.freeze_pointer( m_parent, m_gl_widget, Camera_motionDelta, &m_Camera ); + m_gl_widget->setFocus(); + m_freezePointer.freeze_pointer( m_gl_widget, + [this]( int x, int y, const QMouseEvent *event ){ + Camera_motionDelta( x, y, event, m_Camera ); + }, + [this](){ + DisableFreeMove(); // if there's an OS-level focus out of the application then we can release the camera cursor grab + } ); CamWnd_Update( *this ); } @@ -1881,7 +1732,6 @@ void CamWnd::DisableFreeMove(){ CamWnd_Add_Handlers_Move( *this ); m_freezePointer.unfreeze_pointer( true ); - g_signal_handler_disconnect( G_OBJECT( m_gl_widget ), m_freemove_handle_focusout ); CamWnd_Update( *this ); } @@ -1987,16 +1837,14 @@ ShowStatsExportCaller g_show_stats_caller; BoolExportCallback g_show_stats_callback( g_show_stats_caller ); ToggleItem g_show_stats( g_show_stats_callback ); */ -BoolExportCaller g_show_stats_caller( g_camwindow_globals.m_showStats ); -ToggleItem g_show_stats( g_show_stats_caller ); +ToggleItem g_show_stats( BoolExportCaller( g_camwindow_globals.m_showStats ) ); void ShowStatsToggle(){ g_camwindow_globals.m_showStats ^= 1; g_show_stats.update(); UpdateAllWindows(); } -BoolExportCaller g_show_workzone3d_caller( g_camwindow_globals_private.m_bShowWorkzone ); -ToggleItem g_show_workzone3d( g_show_workzone3d_caller ); +ToggleItem g_show_workzone3d( BoolExportCaller( g_camwindow_globals_private.m_bShowWorkzone ) ); void ShowWorkzone3dToggle(){ g_camwindow_globals_private.m_bShowWorkzone ^= 1; g_show_workzone3d.update(); @@ -2005,8 +1853,7 @@ void ShowWorkzone3dToggle(){ } } -BoolExportCaller g_show_size3d_caller( g_camwindow_globals_private.m_bShowSize ); -ToggleItem g_show_size3d( g_show_size3d_caller ); +ToggleItem g_show_size3d( BoolExportCaller( g_camwindow_globals_private.m_bShowSize ) ); void ShowSize3dToggle(){ g_camwindow_globals_private.m_bShowSize ^= 1; g_show_size3d.update(); @@ -2017,36 +1864,35 @@ void ShowSize3dToggle(){ void CamWnd::Cam_Draw(){ // globalOutputStream() << "Cam_Draw()\n"; - fbo_get()->start(); - glViewport( 0, 0, m_Camera.width, m_Camera.height ); + gl().glViewport( 0, 0, m_Camera.width, m_Camera.height ); #if 0 GLint viewprt[4]; - glGetIntegerv( GL_VIEWPORT, viewprt ); + gl().glGetIntegerv( GL_VIEWPORT, viewprt ); #endif // enable depth buffer writes - glDepthMask( GL_TRUE ); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + gl().glDepthMask( GL_TRUE ); + gl().glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); Vector3 clearColour( 0, 0, 0 ); if ( m_Camera.draw_mode != cd_lighting ) { clearColour = g_camwindow_globals.color_cameraback; } - glClearColor( clearColour[0], clearColour[1], clearColour[2], 0 ); - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + gl().glClearColor( clearColour[0], clearColour[1], clearColour[2], 0 ); + gl().glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); extern void Renderer_ResetStats(); Renderer_ResetStats(); extern void Cull_ResetStats(); Cull_ResetStats(); - glMatrixMode( GL_PROJECTION ); - glLoadMatrixf( reinterpret_cast( &m_Camera.projection ) ); + gl().glMatrixMode( GL_PROJECTION ); + gl().glLoadMatrixf( reinterpret_cast( &m_Camera.projection ) ); - glMatrixMode( GL_MODELVIEW ); - glLoadMatrixf( reinterpret_cast( &m_Camera.modelview ) ); + gl().glMatrixMode( GL_MODELVIEW ); + gl().glLoadMatrixf( reinterpret_cast( &m_Camera.modelview ) ); // one directional light source directly behind the viewer @@ -2065,16 +1911,25 @@ void CamWnd::Cam_Draw(){ inverse_cam_dir[2] = m_Camera.vpn[2]; inverse_cam_dir[3] = 0; - glLightfv( GL_LIGHT0, GL_POSITION, inverse_cam_dir ); + gl().glLightfv( GL_LIGHT0, GL_POSITION, inverse_cam_dir ); - glLightfv( GL_LIGHT0, GL_AMBIENT, ambient ); - glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse ); + gl().glLightfv( GL_LIGHT0, GL_AMBIENT, ambient ); + gl().glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse ); - glEnable( GL_LIGHT0 ); + gl().glEnable( GL_LIGHT0 ); } - unsigned int globalstate = RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_ALPHATEST | RENDER_BLEND | RENDER_CULLFACE | RENDER_COLOURARRAY | RENDER_OFFSETLINE | RENDER_POLYGONSMOOTH | RENDER_LINESMOOTH | RENDER_FOG | RENDER_COLOURCHANGE; + unsigned int globalstate = RENDER_DEPTHTEST + | RENDER_COLOURWRITE + | RENDER_DEPTHWRITE + | RENDER_ALPHATEST + | RENDER_BLEND + | RENDER_CULLFACE + | RENDER_COLOURARRAY + | RENDER_OFFSETLINE + | RENDER_FOG + | RENDER_COLOURCHANGE; switch ( m_Camera.draw_mode ) { case cd_wire: @@ -2135,81 +1990,68 @@ void CamWnd::Cam_Draw(){ } // prepare for 2d stuff - glColor4f( 1, 1, 1, 1 ); - glDisable( GL_BLEND ); - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - glOrtho( 0, (float)m_Camera.width, 0, (float)m_Camera.height, -100, 100 ); - glScalef( 1, -1, 1 ); - glTranslatef( 0, -(float)m_Camera.height, 0 ); - glMatrixMode( GL_MODELVIEW ); - glLoadIdentity(); + gl().glColor4f( 1, 1, 1, 1 ); + gl().glDisable( GL_BLEND ); + gl().glMatrixMode( GL_PROJECTION ); + gl().glLoadIdentity(); + gl().glOrtho( 0, (float)m_Camera.width, 0, (float)m_Camera.height, -100, 100 ); + gl().glScalef( 1, -1, 1 ); + gl().glTranslatef( 0, -(float)m_Camera.height, 0 ); + gl().glMatrixMode( GL_MODELVIEW ); + gl().glLoadIdentity(); - if ( GlobalOpenGL().GL_1_3() ) { - glClientActiveTexture( GL_TEXTURE0 ); - glActiveTexture( GL_TEXTURE0 ); - } + gl().glClientActiveTexture( GL_TEXTURE0 ); + gl().glActiveTexture( GL_TEXTURE0 ); - glDisableClientState( GL_TEXTURE_COORD_ARRAY ); - glDisableClientState( GL_NORMAL_ARRAY ); - glDisableClientState( GL_COLOR_ARRAY ); + gl().glDisableClientState( GL_TEXTURE_COORD_ARRAY ); + gl().glDisableClientState( GL_NORMAL_ARRAY ); + gl().glDisableClientState( GL_COLOR_ARRAY ); - glDisable( GL_TEXTURE_2D ); - glDisable( GL_LIGHTING ); - glDisable( GL_COLOR_MATERIAL ); - glDisable( GL_DEPTH_TEST ); - glLineWidth( 1 ); + gl().glDisable( GL_TEXTURE_2D ); + gl().glDisable( GL_LIGHTING ); + gl().glDisable( GL_COLOR_MATERIAL ); + gl().glDisable( GL_DEPTH_TEST ); + gl().glLineWidth( 1 ); // draw the crosshair if ( m_bFreeMove ) { - glBegin( GL_LINES ); - glVertex2f( (float)m_Camera.width / 2.f, (float)m_Camera.height / 2.f + 6 ); - glVertex2f( (float)m_Camera.width / 2.f, (float)m_Camera.height / 2.f + 2 ); - glVertex2f( (float)m_Camera.width / 2.f, (float)m_Camera.height / 2.f - 6 ); - glVertex2f( (float)m_Camera.width / 2.f, (float)m_Camera.height / 2.f - 2 ); - glVertex2f( (float)m_Camera.width / 2.f + 6, (float)m_Camera.height / 2.f ); - glVertex2f( (float)m_Camera.width / 2.f + 2, (float)m_Camera.height / 2.f ); - glVertex2f( (float)m_Camera.width / 2.f - 6, (float)m_Camera.height / 2.f ); - glVertex2f( (float)m_Camera.width / 2.f - 2, (float)m_Camera.height / 2.f ); - glEnd(); + gl().glBegin( GL_LINES ); + gl().glVertex2f( (float)m_Camera.width / 2.f, (float)m_Camera.height / 2.f + 6 ); + gl().glVertex2f( (float)m_Camera.width / 2.f, (float)m_Camera.height / 2.f + 2 ); + gl().glVertex2f( (float)m_Camera.width / 2.f, (float)m_Camera.height / 2.f - 6 ); + gl().glVertex2f( (float)m_Camera.width / 2.f, (float)m_Camera.height / 2.f - 2 ); + gl().glVertex2f( (float)m_Camera.width / 2.f + 6, (float)m_Camera.height / 2.f ); + gl().glVertex2f( (float)m_Camera.width / 2.f + 2, (float)m_Camera.height / 2.f ); + gl().glVertex2f( (float)m_Camera.width / 2.f - 6, (float)m_Camera.height / 2.f ); + gl().glVertex2f( (float)m_Camera.width / 2.f - 2, (float)m_Camera.height / 2.f ); + gl().glEnd(); } if ( g_camwindow_globals.m_showStats ) { - glRasterPos3f( 1.0f, static_cast( m_Camera.height ), 0.0f ); + gl().glRasterPos3f( 1.0f, static_cast( m_Camera.height ), 0.0f ); extern const char* Renderer_GetStats(); StringOutputStream stream; stream << Renderer_GetStats() << " | f2f: " << m_render_time.elapsed_msec(); GlobalOpenGL().drawString( stream.c_str() ); m_render_time.start(); - glRasterPos3f( 1.0f, static_cast( m_Camera.height ) - GlobalOpenGL().m_font->getPixelHeight(), 0.0f ); + gl().glRasterPos3f( 1.0f, static_cast( m_Camera.height ) - GlobalOpenGL().m_font->getPixelHeight(), 0.0f ); extern const char* Cull_GetStats(); GlobalOpenGL().drawString( Cull_GetStats() ); } // bind back to the default texture so that we don't have problems // elsewhere using/modifying texture maps between contexts - glBindTexture( GL_TEXTURE_2D, 0 ); - - fbo_get()->save(); + gl().glBindTexture( GL_TEXTURE_2D, 0 ); } void CamWnd::draw(){ m_drawing = true; //globalOutputStream() << "draw...\n"; - if ( glwidget_make_current( m_gl_widget ) ) { - if ( Map_Valid( g_map ) && ScreenUpdates_Enabled() ) { - GlobalOpenGL_debugAssertNoErrors(); - Cam_Draw(); - GlobalOpenGL_debugAssertNoErrors(); - //qglFinish(); - - //m_XORRectangle.set( rect_t() ); - } - - glwidget_swap_buffers( m_gl_widget ); - } + GlobalOpenGL_debugAssertNoErrors(); + Cam_Draw(); + GlobalOpenGL_debugAssertNoErrors(); m_drawing = false; } @@ -2330,8 +2172,7 @@ bool Camera_GetFarClip(){ return g_camwindow_globals_private.m_bCubicClipping; } -BoolExportCaller g_getfarclip_caller( g_camwindow_globals_private.m_bCubicClipping ); -ToggleItem g_getfarclip_item( g_getfarclip_caller ); +ToggleItem g_getfarclip_item( BoolExportCaller( g_camwindow_globals_private.m_bCubicClipping ) ); void Camera_SetFarClip( bool value ){ CamWnd& camwnd = *g_camwnd; @@ -2346,13 +2187,11 @@ void Camera_ToggleFarClip(){ } -void CamWnd_constructToolbar( GtkToolbar* toolbar ){ - toolbar_append_toggle_button( toolbar, "Cubic clip the camera view (Ctrl + \\)", "view_cubicclipping.png", "ToggleCubicClip" ); +void CamWnd_constructToolbar( QToolBar* toolbar ){ + toolbar_append_toggle_button( toolbar, "Cubic clip the camera view", "view_cubicclipping.png", "ToggleCubicClip" ); } void CamWnd_registerShortcuts(){ - toggle_add_accelerator( "ToggleCubicClip" ); - if ( g_pGameDescription->mGameType == "doom3" ) { command_connect_accelerator( "TogglePreview" ); } @@ -2460,9 +2299,6 @@ void CameraModePrev(){ void CamMSAAImport( int value ){ g_camwindow_globals_private.m_MSAA = value ? 1 << value : value; - if ( g_camwnd != 0 ) { - g_camwnd->fbo_get()->reset( g_camwnd->getCamera().width, g_camwnd->getCamera().height, g_camwindow_globals_private.m_MSAA, true ); - } } typedef FreeCaller1 MSAAImportCaller; @@ -2489,11 +2325,11 @@ void fieldOfViewImport( float value ){ typedef FreeCaller1 fieldOfViewImportCaller; void Camera_constructPreferences( PreferencesPage& page ){ - page.appendSlider( "Movement Speed", g_camwindow_globals_private.m_nMoveSpeed, TRUE, 0, 0, 500, 1, CAM_MAX_SPEED, 1, 10 ); - page.appendSlider( "Time to Max Speed", g_camwindow_globals_private.m_time_toMaxSpeed, TRUE, 0, 0, 200, 0, 5000, 10, 100 ); - page.appendSlider( "Scroll Move Speed", g_camwindow_globals_private.m_nScrollMoveSpeed, TRUE, 0, 0, 100, 0, 999, 1, 10 ); - page.appendSlider( "Strafe Speed", g_camwindow_globals_private.m_strafeSpeed, TRUE, 0, 0, 1, 0.1, 10, 0.1, 1 ); - page.appendSlider( "Mouse Sensitivity", g_camwindow_globals_private.m_angleSpeed, TRUE, 0, 0, 9, 0.1, 180, 0.1, 1 ); + page.appendSpinner( "Movement Speed", g_camwindow_globals_private.m_nMoveSpeed, 1, CAM_MAX_SPEED ); + page.appendSpinner( "Time to Max Speed", g_camwindow_globals_private.m_time_toMaxSpeed, 0, 5000 ); + page.appendSpinner( "Scroll Move Speed", g_camwindow_globals_private.m_nScrollMoveSpeed, 0, 999 ); + page.appendSpinner( "Strafe Speed", g_camwindow_globals_private.m_strafeSpeed, 0.1, 10 ); + page.appendSpinner( "Mouse Sensitivity", g_camwindow_globals_private.m_angleSpeed, 0.1, 30 ); page.appendCheckBox( "", "Invert mouse vertical axis", g_camwindow_globals_private.m_bCamInverseMouse ); page.appendCheckBox( "", "Zoom to Mouse pointer", g_camwindow_globals_private.m_bZoomToPointer ); page.appendCheckBox( @@ -2525,7 +2361,7 @@ void Camera_constructPreferences( PreferencesPage& page ){ IntExportCallback( RenderModeExportCaller() ) ); - if( GlobalOpenGL().support_ARB_framebuffer_object ){ + { const char* samples[] = { "0", "2", "4", "8", "16", "32" }; page.appendCombo( @@ -2544,7 +2380,7 @@ void Camera_constructPreferences( PreferencesPage& page ){ StringArrayRange( strafe_mode ) ); - page.appendSpinner( "Field Of View", 110.0, 1.0, 175.0, + page.appendSpinner( "Field Of View", 1.0, 175.0, FloatImportCallback( fieldOfViewImportCaller() ), FloatExportCallback( FloatExportCaller( camera_t::fieldOfView ) ) ); @@ -2577,56 +2413,56 @@ void CameraSpeed_decrease(){ /// \brief Initialisation for things that have the same lifespan as this module. void CamWnd_Construct(){ - GlobalCommands_insert( "CenterView", FreeCaller(), Accelerator( GDK_KEY_End ) ); - GlobalCommands_insert( "CameraFocusOnSelected", FreeCaller(), Accelerator( GDK_KEY_Tab ) ); + GlobalCommands_insert( "CenterView", FreeCaller(), QKeySequence( "End" ) ); + GlobalCommands_insert( "CameraFocusOnSelected", FreeCaller(), QKeySequence( "Tab" ) ); - GlobalToggles_insert( "ToggleCubicClip", FreeCaller(), ToggleItem::AddCallbackCaller( g_getfarclip_item ), Accelerator( '\\', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "CubicClipZoomIn", FreeCaller(), Accelerator( '[', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "CubicClipZoomOut", FreeCaller(), Accelerator( ']', GDK_CONTROL_MASK ) ); + GlobalToggles_insert( "ToggleCubicClip", FreeCaller(), ToggleItem::AddCallbackCaller( g_getfarclip_item ), QKeySequence( "Ctrl+\\" ) ); + GlobalCommands_insert( "CubicClipZoomIn", FreeCaller(), QKeySequence( "Ctrl+[" ) ); + GlobalCommands_insert( "CubicClipZoomOut", FreeCaller(), QKeySequence( "Ctrl+]" ) ); - GlobalCommands_insert( "UpFloor", FreeCaller(), Accelerator( GDK_KEY_Prior ) ); - GlobalCommands_insert( "DownFloor", FreeCaller(), Accelerator( GDK_KEY_Next ) ); + GlobalCommands_insert( "UpFloor", FreeCaller(), QKeySequence( "PgUp" ) ); + GlobalCommands_insert( "DownFloor", FreeCaller(), QKeySequence( "PgDown" ) ); - GlobalToggles_insert( "ToggleCamera", ToggleShown::ToggleCaller( g_camera_shown ), ToggleItem::AddCallbackCaller( g_camera_shown.m_item ), Accelerator( 'C', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); + GlobalToggles_insert( "ToggleCamera", ToggleShown::ToggleCaller( g_camera_shown ), ToggleItem::AddCallbackCaller( g_camera_shown.m_item ), QKeySequence( "Ctrl+Shift+C" ) ); // GlobalCommands_insert( "LookThroughSelected", FreeCaller() ); // GlobalCommands_insert( "LookThroughCamera", FreeCaller() ); if ( g_pGameDescription->mGameType == "doom3" ) { - GlobalCommands_insert( "TogglePreview", FreeCaller(), Accelerator( GDK_KEY_F3 ) ); + GlobalCommands_insert( "TogglePreview", FreeCaller(), QKeySequence( "F3" ) ); } - GlobalCommands_insert( "CameraModeNext", FreeCaller(), Accelerator( '}', GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "CameraModePrev", FreeCaller(), Accelerator( '{', GDK_SHIFT_MASK ) ); + GlobalCommands_insert( "CameraModeNext", FreeCaller(), QKeySequence( "Shift+]" ) ); + GlobalCommands_insert( "CameraModePrev", FreeCaller(), QKeySequence( "Shift+[" ) ); - GlobalCommands_insert( "CameraSpeedInc", FreeCaller(), Accelerator( GDK_KEY_KP_Add, GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "CameraSpeedDec", FreeCaller(), Accelerator( GDK_KEY_KP_Subtract, GDK_SHIFT_MASK ) ); + GlobalCommands_insert( "CameraSpeedInc", FreeCaller(), QKeySequence( Qt::SHIFT + Qt::Key_Plus + Qt::KeypadModifier ) ); + GlobalCommands_insert( "CameraSpeedDec", FreeCaller(), QKeySequence( Qt::SHIFT + Qt::Key_Minus + Qt::KeypadModifier ) ); - GlobalShortcuts_insert( "CameraForward", Accelerator( GDK_KEY_Up ) ); - GlobalShortcuts_insert( "CameraBack", Accelerator( GDK_KEY_Down ) ); - GlobalShortcuts_insert( "CameraLeft", Accelerator( GDK_KEY_Left ) ); - GlobalShortcuts_insert( "CameraRight", Accelerator( GDK_KEY_Right ) ); - GlobalShortcuts_insert( "CameraStrafeRight", Accelerator( 'D' ) ); - GlobalShortcuts_insert( "CameraStrafeLeft", Accelerator( 'A' ) ); + GlobalShortcuts_insert( "CameraForward", QKeySequence( "Up" ) ); + GlobalShortcuts_insert( "CameraBack", QKeySequence( "Down" ) ); + GlobalShortcuts_insert( "CameraLeft", QKeySequence( "Left" ) ); + GlobalShortcuts_insert( "CameraRight", QKeySequence( "Right" ) ); + GlobalShortcuts_insert( "CameraStrafeRight", QKeySequence( "D" ) ); + GlobalShortcuts_insert( "CameraStrafeLeft", QKeySequence( "A" ) ); - GlobalShortcuts_insert( "CameraUp", accelerator_null() ); - GlobalShortcuts_insert( "CameraDown", accelerator_null() ); - GlobalShortcuts_insert( "CameraAngleUp", accelerator_null() ); - GlobalShortcuts_insert( "CameraAngleDown", accelerator_null() ); + GlobalShortcuts_insert( "CameraUp" ); + GlobalShortcuts_insert( "CameraDown" ); + GlobalShortcuts_insert( "CameraAngleUp" ); + GlobalShortcuts_insert( "CameraAngleDown" ); - GlobalShortcuts_insert( "CameraFreeMoveForward", Accelerator( 'W' ) ); - GlobalShortcuts_insert( "CameraFreeMoveBack", Accelerator( 'S' ) ); - GlobalShortcuts_insert( "CameraFreeMoveLeft", Accelerator( 'A' ) ); - GlobalShortcuts_insert( "CameraFreeMoveRight", Accelerator( 'D' ) ); + GlobalShortcuts_insert( "CameraFreeMoveForward", QKeySequence( "W" ) ); + GlobalShortcuts_insert( "CameraFreeMoveBack", QKeySequence( "S" ) ); + GlobalShortcuts_insert( "CameraFreeMoveLeft", QKeySequence( "A" ) ); + GlobalShortcuts_insert( "CameraFreeMoveRight", QKeySequence( "D" ) ); - GlobalShortcuts_insert( "CameraFreeMoveForward2", Accelerator( GDK_KEY_Up ) ); - GlobalShortcuts_insert( "CameraFreeMoveBack2", Accelerator( GDK_KEY_Down ) ); - GlobalShortcuts_insert( "CameraFreeMoveLeft2", Accelerator( GDK_KEY_Left ) ); - GlobalShortcuts_insert( "CameraFreeMoveRight2", Accelerator( GDK_KEY_Right ) ); + GlobalShortcuts_insert( "CameraFreeMoveForward2", QKeySequence( "Up" ) ); + GlobalShortcuts_insert( "CameraFreeMoveBack2", QKeySequence( "Down" ) ); + GlobalShortcuts_insert( "CameraFreeMoveLeft2", QKeySequence( "Left" ) ); + GlobalShortcuts_insert( "CameraFreeMoveRight2", QKeySequence( "Right" ) ); - GlobalShortcuts_insert( "CameraFreeMoveUp", accelerator_null() ); - GlobalShortcuts_insert( "CameraFreeMoveDown", accelerator_null() ); + GlobalShortcuts_insert( "CameraFreeMoveUp" ); + GlobalShortcuts_insert( "CameraFreeMoveDown" ); - GlobalShortcuts_insert( "CameraFreeFocus", Accelerator( GDK_KEY_Tab ) ); + GlobalShortcuts_insert( "CameraFreeFocus", QKeySequence( "Tab" ) ); GlobalToggles_insert( "ShowStats", FreeCaller(), ToggleItem::AddCallbackCaller( g_show_stats ) ); GlobalToggles_insert( "ShowWorkzone3d", FreeCaller(), ToggleItem::AddCallbackCaller( g_show_workzone3d ) ); @@ -2653,7 +2489,8 @@ void CamWnd_Construct(){ GlobalPreferenceSystem().registerPreference( "CameraFaceFill", BoolImportStringCaller( g_camwindow_globals_private.m_bFaceFill ), BoolExportStringCaller( g_camwindow_globals_private.m_bFaceFill ) ); GlobalPreferenceSystem().registerPreference( "3DZoomInToPointer", BoolImportStringCaller( g_camwindow_globals_private.m_bZoomToPointer ), BoolExportStringCaller( g_camwindow_globals_private.m_bZoomToPointer ) ); GlobalPreferenceSystem().registerPreference( "fieldOfView", FloatImportStringCaller( camera_t::fieldOfView ), FloatExportStringCaller( camera_t::fieldOfView ) ); - GlobalPreferenceSystem().registerPreference( "CamVIS", makeBoolStringImportCallback( ToggleShownImportBoolCaller( g_camera_shown ) ), makeBoolStringExportCallback( ToggleShownExportBoolCaller( g_camera_shown ) ) ); + //. HACK: always show camera from start to have at least one ogl viewport shown = ogl initialized; otherwise loading map = loading textures = crash +// GlobalPreferenceSystem().registerPreference( "CamVIS", makeBoolStringImportCallback( ToggleShownImportBoolCaller( g_camera_shown ) ), makeBoolStringExportCallback( ToggleShownExportBoolCaller( g_camera_shown ) ) ); CamWnd_constructStatic(); diff --git a/radiant/camwindow.h b/radiant/camwindow.h index 4ff2ebe4..5fdfd48a 100644 --- a/radiant/camwindow.h +++ b/radiant/camwindow.h @@ -24,8 +24,7 @@ #include "math/vector.h" #include "signal/signalfwd.h" -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkWindow GtkWindow; +class QWidget; class CamWnd; CamWnd* NewCamWnd(); @@ -35,14 +34,13 @@ void AddCameraMovedCallback( const SignalHandler& handler ); void CamWnd_Update( CamWnd& camwnd ); -GtkWidget* CamWnd_getWidget( CamWnd& camwnd ); -void CamWnd_setParent( CamWnd& camwnd, GtkWindow* parent ); -void CamWnd_Shown_Construct( GtkWindow* parent ); +QWidget* CamWnd_getWidget( CamWnd& camwnd ); +void CamWnd_setParent( CamWnd& camwnd, QWidget* parent ); +void CamWnd_Shown_Construct( QWidget* parent ); void GlobalCamera_setCamWnd( CamWnd& camwnd ); -typedef struct _GtkToolbar GtkToolbar; -void CamWnd_constructToolbar( GtkToolbar* toolbar ); +void CamWnd_constructToolbar( class QToolBar* toolbar ); void CamWnd_registerShortcuts(); void GlobalCamera_Benchmark(); @@ -66,20 +64,12 @@ const Vector3& Camera_getViewVector( CamWnd& camwnd ); struct camwindow_globals_t { - Vector3 color_cameraback; - Vector3 color_selbrushes3d; + Vector3 color_cameraback = { 0.25f, 0.25f, 0.25f }; + Vector3 color_selbrushes3d = { 1.0f, 0.627451f, 0.0f }; - int m_nCubicScale; - - bool m_showStats; - - camwindow_globals_t() : - color_cameraback( 0.25f, 0.25f, 0.25f ), - color_selbrushes3d( 1.0f, 0.f, 0.f ), - m_nCubicScale( 14 ), - m_showStats( false ){ - } + int m_nCubicScale = 14; + bool m_showStats = false; }; extern camwindow_globals_t g_camwindow_globals; diff --git a/radiant/clippertool.cpp b/radiant/clippertool.cpp index 4c867942..2d0102bf 100644 --- a/radiant/clippertool.cpp +++ b/radiant/clippertool.cpp @@ -29,9 +29,6 @@ #include "mainframe.h" #include "camwindow.h" #include "xywindow.h" -#include "gtkutil/cursor.h" - -GdkCursor* g_clipper_cursor; ClipperPoints g_clipper_points; bool g_clipper_flipped = false; @@ -94,15 +91,12 @@ void Clipper_SelectionChanged( const Selectable& selectable ){ void Clipper_modeChanged( bool isClipper ){ - GdkCursor* cursor = isClipper? g_clipper_cursor : 0; - if( g_pParentWnd ){ - g_pParentWnd->forEachXYWnd( [&cursor]( XYWnd* xywnd ){ - gdk_window_set_cursor( gtk_widget_get_window( xywnd->GetWidget() ), cursor ); + g_pParentWnd->forEachXYWnd( [isClipper]( XYWnd* xywnd ){ + isClipper? xywnd->GetWidget()->setCursor( Qt::CursorShape::PointingHandCursor ) : xywnd->GetWidget()->unsetCursor(); } ); if( g_pParentWnd->GetCamWnd() ) - if( !isClipper || !gdk_pointer_is_grabbed() ) /* prevent cursor change `GDK_BLANK_CURSOR->g_clipper_cursor` during freelook */ - gdk_window_set_cursor( gtk_widget_get_window( CamWnd_getWidget( *g_pParentWnd->GetCamWnd() ) ), cursor ); + isClipper? CamWnd_getWidget( *g_pParentWnd->GetCamWnd() )->setCursor( Qt::CursorShape::PointingHandCursor ) : CamWnd_getWidget( *g_pParentWnd->GetCamWnd() )->unsetCursor(); } if( g_clipper_resetFlip ) @@ -173,8 +167,8 @@ void Clipper_tryDoubleclickedCut(){ //onMouseUp #include "signal/isignal.h" void Clipper_constructPreferences( PreferencesPage& page ){ page.appendCheckBox( "", "Caulk Clipper Cuts", g_clipper_caulk ); - GtkWidget* resetFlip = page.appendCheckBox( "", "Reset Flipped State", g_clipper_resetFlip ); - GtkWidget* resetPoints = page.appendCheckBox( "", "Reset Points on Split", g_clipper_resetPoints ); + QCheckBox* resetFlip = page.appendCheckBox( "", "Reset Flipped State", g_clipper_resetFlip ); + QCheckBox* resetPoints = page.appendCheckBox( "", "Reset Points on Split", g_clipper_resetPoints ); Widget_connectToggleDependency( resetFlip, resetPoints ); page.appendCheckBox( "", "2 Points in 2D Views", g_clipper_2pointsIn2d ); { @@ -196,16 +190,14 @@ void Clipper_registerPreferencesPage(){ } void Clipper_registerCommands(){ - GlobalCommands_insert( "ClipperClip", FreeCaller(), Accelerator( GDK_KEY_Return ) ); - GlobalCommands_insert( "ClipperSplit", FreeCaller(), Accelerator( GDK_KEY_Return, GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "ClipperFlip", FreeCaller(), Accelerator( GDK_KEY_Return, GDK_CONTROL_MASK ) ); + GlobalCommands_insert( "ClipperClip", FreeCaller(), QKeySequence( "Return" ) ); + GlobalCommands_insert( "ClipperSplit", FreeCaller(), QKeySequence( "Shift+Return" ) ); + GlobalCommands_insert( "ClipperFlip", FreeCaller(), QKeySequence( "Ctrl+Return" ) ); } SignalHandlerId ClipperTool_boundsChanged; void Clipper_Construct(){ - g_clipper_cursor = gdk_cursor_new( GDK_HAND2 ); - Clipper_registerCommands(); GlobalPreferenceSystem().registerPreference( "ClipperCaulk", BoolImportStringCaller( g_clipper_caulk ), BoolExportStringCaller( g_clipper_caulk ) ); GlobalPreferenceSystem().registerPreference( "ClipperResetFlip", BoolImportStringCaller( g_clipper_resetFlip ), BoolExportStringCaller( g_clipper_resetFlip ) ); @@ -221,6 +213,5 @@ void Clipper_Construct(){ } void Clipper_Destroy(){ - gdk_cursor_unref( g_clipper_cursor ); GlobalSceneGraph().removeBoundsChangedCallback( ClipperTool_boundsChanged ); } diff --git a/radiant/colors.cpp b/radiant/colors.cpp new file mode 100644 index 00000000..701c397d --- /dev/null +++ b/radiant/colors.cpp @@ -0,0 +1,351 @@ +/* + Copyright (C) 1999-2006 Id Software, Inc. and contributors. + For a list of contributors, see the accompanying CONTRIBUTORS file. + + This file is part of GtkRadiant. + + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "colors.h" + +#include "ientity.h" +#include "ieclass.h" +#include "eclasslib.h" + +#include "xywindow.h" +#include "camwindow.h" +#include "texwindow.h" +#include "mainframe.h" +#include "brushmodule.h" +#include "preferences.h" +#include "commands.h" +#include "gtkmisc.h" +#include "theme.h" + + + +//! Make COLOR_BRUSHES override worldspawn eclass colour. +void SetWorldspawnColour( const Vector3& colour ){ + EntityClass* worldspawn = GlobalEntityClassManager().findOrInsert( "worldspawn", true ); + eclass_release_state( worldspawn ); + worldspawn->color = colour; + eclass_capture_state( worldspawn ); +} + +void ColorScheme_Original(){ + TextureBrowser_setBackgroundColour( 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_reconstructStatic(); + 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_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 ); + XYWnd::recaptureStates(); + g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); + Brush_clipperColourChanged(); + 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( 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_reconstructStatic(); + 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 ); + XYWnd::recaptureStates(); + g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); + Brush_clipperColourChanged(); + 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( 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_reconstructStatic(); + 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 ); + XYWnd::recaptureStates(); + g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); + Brush_clipperColourChanged(); + 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( 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_reconstructStatic(); + 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 ); + XYWnd::recaptureStates(); + g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); + Brush_clipperColourChanged(); + 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_Blender(){ + TextureBrowser_setBackgroundColour( 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.627451f, 0.0f ); + CamWnd_reconstructStatic(); + CamWnd_Update( *g_pParentWnd->GetCamWnd() ); + + g_xywindow_globals.color_gridback = Vector3( .225803f, .225803f, .225803f ); + g_xywindow_globals.color_gridminor = Vector3( .254902f, .254902f, .254902f ); + g_xywindow_globals.color_gridmajor = Vector3( .294118f, .294118f, .294118f ); + g_xywindow_globals.color_gridblock = Vector3( 1.0f, 1.0f, 1.0f ); + g_xywindow_globals.color_gridtext = Vector3( .972549f, .972549f, .972549f ); + g_xywindow_globals.color_selbrushes = Vector3( 1.0f, 0.627451f, 0.0f ); + XYWnd::recaptureStates(); + g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); + Brush_clipperColourChanged(); + 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.516136f, 0.516136f, 0.516136f ); + XY_UpdateAllWindows(); +} + +/* color scheme to fit the GTK Adwaita Dark theme */ +void ColorScheme_AdwaitaDark() +{ + TextureBrowser_setBackgroundColour( 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_reconstructStatic(); + CamWnd_Update( *g_pParentWnd->GetCamWnd() ); + + g_xywindow_globals.color_gridback = Vector3( 0.25f, 0.25f, 0.25f ); + g_xywindow_globals.color_gridminor = Vector3( 0.21f, 0.23f, 0.23f ); + g_xywindow_globals.color_gridmajor = Vector3( 0.14f, 0.15f, 0.15f ); + 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 ); + XYWnd::recaptureStates(); + g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); + Brush_clipperColourChanged(); + g_xywindow_globals.color_brushes = Vector3( 0.73f, 0.73f, 0.73f ); + SetWorldspawnColour( g_xywindow_globals.color_brushes ); + g_xywindow_globals.color_viewname = Vector3( 0.5f, 0.0f, 0.75f ); + XY_UpdateAllWindows(); +} + +typedef Callback1 GetColourCallback; +typedef Callback1 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( MainFrame_getWindow(), colour ); + m_set( colour ); + } +}; + + + +void Colour_get( const Vector3& colour, Vector3& other ){ + other = colour; +} +typedef ConstReferenceCaller1 ColourGetCaller; + +void Colour_set( Vector3& colour, const Vector3& other ){ + colour = other; + SceneChangeNotify(); +} +typedef ReferenceCaller1 ColourSetCaller; + +void BrushColour_set( const Vector3& other ){ + g_xywindow_globals.color_brushes = other; + SetWorldspawnColour( g_xywindow_globals.color_brushes ); + SceneChangeNotify(); +} +typedef FreeCaller1 BrushColourSetCaller; + +void SelectedBrushColour_set( const Vector3& other ){ + g_xywindow_globals.color_selbrushes = other; + XYWnd::recaptureStates(); + SceneChangeNotify(); +} +typedef FreeCaller1 SelectedBrushColourSetCaller; + +void SelectedBrush3dColour_set( const Vector3& other ){ + g_camwindow_globals.color_selbrushes3d = other; + CamWnd_reconstructStatic(); + SceneChangeNotify(); +} +typedef FreeCaller1 SelectedBrush3dColourSetCaller; + +void ClipperColour_set( const Vector3& other ){ + g_xywindow_globals.color_clipper = other; + Brush_clipperColourChanged(); + SceneChangeNotify(); +} +typedef FreeCaller1 ClipperColourSetCaller; + +void TextureBrowserColour_get( Vector3& other ){ + other = TextureBrowser_getBackgroundColour(); +} +typedef FreeCaller1 TextureBrowserColourGetCaller; + +void TextureBrowserColour_set( const Vector3& other ){ + TextureBrowser_setBackgroundColour( other ); +} +typedef FreeCaller1 TextureBrowserColourSetCaller; + + +class ColoursMenu +{ +public: + ChooseColour m_textureback; + ChooseColour m_xyback; + ChooseColour m_gridmajor; + ChooseColour m_gridminor; + 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_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 ), SelectedBrushColourSetCaller() ), + m_selectedbrush3d( ColourGetCaller( g_camwindow_globals.color_selbrushes3d ), SelectedBrush3dColourSetCaller() ), + 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; + +void create_colours_menu( QMenu *menu ){ + menu = menu->addMenu( "Colors" ); + + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + + { + QMenu* submenu = menu->addMenu( "Themes" ); + + submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + + create_menu_item_with_mnemonic( submenu, "QE4 Original", "ColorSchemeOriginal" ); + create_menu_item_with_mnemonic( submenu, "Q3Radiant Original", "ColorSchemeQER" ); + create_menu_item_with_mnemonic( submenu, "Black and Green", "ColorSchemeBlackAndGreen" ); + create_menu_item_with_mnemonic( submenu, "Maya/Max/Lightwave Emulation", "ColorSchemeYdnar" ); + create_menu_item_with_mnemonic( submenu, "Blender/Dark", "ColorSchemeBlender" ); + create_menu_item_with_mnemonic( submenu, "Adwaita Dark", "ColorSchemeAdwaitaDark" ); + } + + theme_contruct_menu( menu ); + + create_menu_item_with_mnemonic( menu, "OpenGL Font...", "OpenGLFont" ); + + menu->addSeparator(); + + create_menu_item_with_mnemonic( menu, "&Texture Background...", "ChooseTextureBackgroundColor" ); + create_menu_item_with_mnemonic( menu, "Camera Background...", "ChooseCameraBackgroundColor" ); + create_menu_item_with_mnemonic( menu, "Grid Background...", "ChooseGridBackgroundColor" ); + create_menu_item_with_mnemonic( menu, "Grid Major...", "ChooseGridMajorColor" ); + create_menu_item_with_mnemonic( menu, "Grid Minor...", "ChooseGridMinorColor" ); + create_menu_item_with_mnemonic( menu, "Grid Text...", "ChooseGridTextColor" ); + create_menu_item_with_mnemonic( menu, "Grid Block...", "ChooseGridBlockColor" ); + create_menu_item_with_mnemonic( menu, "Default Brush (2D)...", "ChooseBrushColor" ); + create_menu_item_with_mnemonic( menu, "Selected Brush and Sizing (2D)...", "ChooseSelectedBrushColor" ); + create_menu_item_with_mnemonic( menu, "Selected Brush (Camera)...", "ChooseCameraSelectedBrushColor" ); + create_menu_item_with_mnemonic( menu, "Clipper...", "ChooseClipperColor" ); + create_menu_item_with_mnemonic( menu, "Active View Name and Outline...", "ChooseOrthoViewNameColor" ); +} + +void Colors_registerCommands(){ + GlobalCommands_insert( "ColorSchemeOriginal", FreeCaller() ); + GlobalCommands_insert( "ColorSchemeQER", FreeCaller() ); + GlobalCommands_insert( "ColorSchemeBlackAndGreen", FreeCaller() ); + GlobalCommands_insert( "ColorSchemeYdnar", FreeCaller() ); + GlobalCommands_insert( "ColorSchemeBlender", FreeCaller() ); + GlobalCommands_insert( "ColorSchemeAdwaitaDark", FreeCaller() ); + 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( "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 ) ); +} \ No newline at end of file diff --git a/libs/gtkutil/pointer.h b/radiant/colors.h similarity index 68% rename from libs/gtkutil/pointer.h rename to radiant/colors.h index b22f9abd..4344126f 100644 --- a/libs/gtkutil/pointer.h +++ b/radiant/colors.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. + 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. @@ -21,15 +21,9 @@ #pragma once -typedef int gint; -typedef void* gpointer; +template class BasicVector3; +typedef BasicVector3 Vector3; -#include - -inline gint gpointer_to_int( gpointer p ){ - return gint( std::size_t( p ) ); -} - -inline gpointer gint_to_pointer( gint i ){ - return gpointer( std::size_t( i ) ); -} +void SetWorldspawnColour( const Vector3& colour ); +void Colors_registerCommands(); +void create_colours_menu( class QMenu *menu ); \ No newline at end of file diff --git a/radiant/commands.cpp b/radiant/commands.cpp index 288a9da6..14ff3b4b 100644 --- a/radiant/commands.cpp +++ b/radiant/commands.cpp @@ -22,35 +22,33 @@ #include "commands.h" #include "debugging/debugging.h" -#include "warnings.h" #include #include "string/string.h" #include "versionlib.h" -#include #include "gtkutil/accelerator.h" #include "gtkutil/messagebox.h" #include "gtkmisc.h" struct ShortcutValue{ - Accelerator accelerator; - const Accelerator accelerator_default; + QKeySequence accelerator; + const QKeySequence accelerator_default; int type; // 0 = !isRegistered, 1 = command, 2 = toggle - ShortcutValue( const Accelerator& a ) : accelerator( a ), accelerator_default( a ), type( 0 ){ + ShortcutValue( const QKeySequence& a ) : accelerator( a ), accelerator_default( a ), type( 0 ){ } }; typedef std::map Shortcuts; Shortcuts g_shortcuts; -const Accelerator& GlobalShortcuts_insert( const char* name, const Accelerator& accelerator ){ +const QKeySequence& GlobalShortcuts_insert( const char* name, const QKeySequence& accelerator ){ return ( *g_shortcuts.insert( Shortcuts::value_type( name, ShortcutValue( accelerator ) ) ).first ).second.accelerator; } template void GlobalShortcuts_foreach( Functor& functor ){ - for ( auto& pair : g_shortcuts ) - functor( pair.first.c_str(), pair.second.accelerator ); + for ( auto& [name, shortcut] : g_shortcuts ) + functor( name.c_str(), shortcut.accelerator ); } void GlobalShortcuts_register( const char* name, int type ){ @@ -61,16 +59,16 @@ void GlobalShortcuts_register( const char* name, int type ){ } void GlobalShortcuts_reportUnregistered(){ - for ( auto& pair : g_shortcuts ) - if ( pair.second.accelerator.key != 0 && pair.second.type == 0 ) - globalWarningStream() << "shortcut not registered: " << pair.first << "\n"; + for ( const auto& [name, shortcut] : g_shortcuts ) + if ( !shortcut.accelerator.isEmpty() && shortcut.type == 0 ) + globalWarningStream() << "shortcut not registered: " << name << "\n"; } typedef std::map Commands; Commands g_commands; -void GlobalCommands_insert( const char* name, const Callback& callback, const Accelerator& accelerator ){ +void GlobalCommands_insert( const char* name, const Callback& callback, const QKeySequence& accelerator ){ bool added = g_commands.insert( Commands::value_type( name, Command( callback, GlobalShortcuts_insert( name, accelerator ) ) ) ).second; ASSERT_MESSAGE( added, "command already registered: " << makeQuoted( name ) ); } @@ -86,7 +84,7 @@ typedef std::map Toggles; Toggles g_toggles; -void GlobalToggles_insert( const char* name, const Callback& callback, const BoolExportCallback& exportCallback, const Accelerator& accelerator ){ +void GlobalToggles_insert( const char* name, const Callback& callback, const BoolExportCallback& exportCallback, const QKeySequence& accelerator ){ bool added = g_toggles.insert( Toggles::value_type( name, Toggle( callback, GlobalShortcuts_insert( name, accelerator ), exportCallback ) ) ).second; ASSERT_MESSAGE( added, "toggle already registered: " << makeQuoted( name ) ); } @@ -101,7 +99,7 @@ typedef std::map KeyEvents; KeyEvents g_keyEvents; -void GlobalKeyEvents_insert( const char* name, const Accelerator& accelerator, const Callback& keyDown, const Callback& keyUp ){ +void GlobalKeyEvents_insert( const char* name, const Callback& keyDown, const Callback& keyUp, const QKeySequence& accelerator ){ bool added = g_keyEvents.insert( KeyEvents::value_type( name, KeyEvent( GlobalShortcuts_insert( name, accelerator ), keyDown, keyUp ) ) ).second; ASSERT_MESSAGE( added, "command already registered: " << makeQuoted( name ) ); } @@ -112,6 +110,24 @@ const KeyEvent& GlobalKeyEvents_find( const char* name ){ } + + +#include "mainframe.h" + +#include "stream/textfilestream.h" +#include "stream/stringstream.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + void disconnect_accelerator( const char *name ){ Shortcuts::iterator i = g_shortcuts.find( name ); if ( i != g_shortcuts.end() ) { @@ -147,157 +163,93 @@ void connect_accelerator( const char *name ){ } -#include - -#include "gtkutil/dialog.h" -#include "mainframe.h" - -#include "stream/textfilestream.h" -#include "stream/stringstream.h" +inline void accelerator_item_set_icon( QTreeWidgetItem *item, const ShortcutValue& value ){ + value.accelerator != value.accelerator_default + ? item->setIcon( 1, QApplication::style()->standardIcon( QStyle::StandardPixmap::SP_DialogNoButton ) ) + : item->setIcon( 1, {} ); +} -struct command_list_dialog_t : public ModalDialog -{ - command_list_dialog_t() - : m_close_button( *this, eIDCANCEL ), m_list( NULL ), m_command_iter(), m_model( NULL ), m_waiting_for_key( false ){ - } - ModalDialogButton m_close_button; - GtkTreeView *m_list; - // waiting for new accelerator input state: - GtkTreeIter m_command_iter; - GtkTreeModel *m_model; - bool m_waiting_for_key; - void startWaitForKey( GtkTreeIter iter, GtkTreeModel *model ){ - m_command_iter = iter; - m_model = model; - m_waiting_for_key = true; // grab keyboard input - gtk_list_store_set( GTK_LIST_STORE( m_model ), &m_command_iter, 2, TRUE, -1 ); // highlight the row - } - bool stopWaitForKey(){ - if ( m_waiting_for_key ) { - m_waiting_for_key = false; - gtk_list_store_set( GTK_LIST_STORE( m_model ), &m_command_iter, 2, FALSE, -1 ); // unhighlight - m_model = NULL; - return true; - } - return false; - } -}; - -void accelerator_clear_button_clicked( GtkButton *btn, gpointer dialogptr ){ - command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr; - - if ( dialog.stopWaitForKey() ) // just unhighlight, user wanted to cancel - return; - - GtkTreeSelection *sel = gtk_tree_view_get_selection( dialog.m_list ); - GtkTreeModel *model; - GtkTreeIter iter; - if ( !gtk_tree_selection_get_selected( sel, &model, &iter ) ) { - return; - } - - gchar* commandName = nullptr; - gtk_tree_model_get( model, &iter, 0, &commandName, -1 ); +void accelerator_clear_button_clicked( QTreeWidgetItem *item ){ + const auto commandName = item->text( 0 ).toLatin1(); // clear the ACTUAL accelerator too! disconnect_accelerator( commandName ); - Shortcuts::iterator thisShortcutIterator = g_shortcuts.find( commandName ); - g_free( commandName ); - if ( thisShortcutIterator == g_shortcuts.end() ) { - return; - } - thisShortcutIterator->second.accelerator = accelerator_null(); - - gtk_list_store_set( GTK_LIST_STORE( model ), &iter, 1, "", -1 ); -} - -void accelerator_edit_button_clicked( GtkButton *btn, gpointer dialogptr ){ - command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr; - - // 1. find selected row - GtkTreeSelection *sel = gtk_tree_view_get_selection( dialog.m_list ); - GtkTreeModel *model; - GtkTreeIter iter; - if ( gtk_tree_selection_get_selected( sel, &model, &iter ) ) { - dialog.stopWaitForKey(); - dialog.startWaitForKey( iter, model ); + Shortcuts::iterator thisShortcutIterator = g_shortcuts.find( commandName.constData() ); + if ( thisShortcutIterator != g_shortcuts.end() ) { + thisShortcutIterator->second.accelerator = {}; + item->setText( 1, {} ); + accelerator_item_set_icon( item, thisShortcutIterator->second ); } } -gboolean accelerator_tree_butt_press( GtkWidget* widget, GdkEventButton* event, gpointer dialogptr ){ - if ( event->type == GDK_2BUTTON_PRESS && event->button == 1 ) { - accelerator_edit_button_clicked( 0, dialogptr ); - return TRUE; - } - return FALSE; -} +// note: ideally this should also consider some shortcuts being KeyEvent and thus enabled by occasion +// so technically they do not definitely clash with Command/Toggle with the same shortcut class VerifyAcceleratorNotTaken { const char *commandName; - const Accelerator &newAccel; - GtkWidget *widget; - GtkTreeModel *model; + const QKeySequence newAccel; + QTreeWidget *tree; public: bool allow; - VerifyAcceleratorNotTaken( const char *name, const Accelerator &accelerator, GtkWidget *w, GtkTreeModel *m ) : - commandName( name ), newAccel( accelerator ), widget( w ), model( m ), allow( true ){ + VerifyAcceleratorNotTaken( const char *name, const QKeySequence accelerator, QTreeWidget *tree ) : + commandName( name ), newAccel( accelerator ), tree( tree ), allow( true ){ } - void operator()( const char* name, Accelerator& accelerator ){ + void operator()( const char* name, QKeySequence& accelerator ){ if ( !allow - || accelerator.key == 0 + || !QKeySequence_valid( accelerator ) || !strcmp( name, commandName ) ) { return; } if ( accelerator == newAccel ) { StringOutputStream msg; - msg << "The command " << name << " is already assigned to the key " << accelerator << ".\n\n" - << "Do you want to unassign " << name << " first?"; - EMessageBoxReturn r = gtk_MessageBox( widget, msg.c_str(), "Key already used", eMB_YESNOCANCEL ); + msg << "The command " << name << " is already assigned to the key " << accelerator << ".

" + << "Do you want to unassign " << name << " first?"; + const EMessageBoxReturn r = qt_MessageBox( tree->window(), msg.c_str(), "Key already used", EMessageBoxType::Question, eIDYES | eIDNO | eIDCANCEL ); if ( r == eIDYES ) { // clear the ACTUAL accelerator too! disconnect_accelerator( name ); // delete the modifier - accelerator = accelerator_null(); + accelerator = {}; // empty the cell of the key binds dialog - GtkTreeIter i; - if ( gtk_tree_model_get_iter_first( model, &i ) ) { - do{ - gchar* thisName = nullptr; - gtk_tree_model_get( model, &i, 0, &thisName, -1 ); - if ( !strcmp( thisName, name ) ) { - gtk_list_store_set( GTK_LIST_STORE( model ), &i, 1, "", -1 ); + for( QTreeWidgetItemIterator it( tree ); *it; ++it ) + { + if( ( *it )->text( 0 ) == name ){ + ( *it )->setText( 1, {} ); + Shortcuts::const_iterator thisShortcutIterator = g_shortcuts.find( name ); + if ( thisShortcutIterator != g_shortcuts.end() ) { + accelerator_item_set_icon( ( *it ), thisShortcutIterator->second ); } - g_free( thisName ); - } while( gtk_tree_model_iter_next( model, &i ) ); + break; + } } } else if ( r == eIDCANCEL ) { // aborted allow = false; } + // eIDNO : keep duplicate key } } }; -static void accelerator_alter( GtkTreeModel *model, GtkTreeIter* iter, GdkEventKey *event, GtkWidget *parentWidget ){ +// multipurpose function: invalid accelerator = reset to default +static void accelerator_alter( QTreeWidgetItem *item, const QKeySequence accelerator ){ // 7. find the name of the accelerator - gchar* commandName = nullptr; - gtk_tree_model_get( model, iter, 0, &commandName, -1 ); + auto commandName = item->text( 0 ).toLatin1(); - Shortcuts::iterator thisShortcutIterator = g_shortcuts.find( commandName ); + Shortcuts::iterator thisShortcutIterator = g_shortcuts.find( commandName.constData() ); if ( thisShortcutIterator == g_shortcuts.end() ) { - globalErrorStream() << "commandName " << makeQuoted( commandName ) << " not found in g_shortcuts.\n"; - g_free( commandName ); + globalErrorStream() << "commandName " << makeQuoted( commandName.constData() ) << " not found in g_shortcuts.\n"; return; } // 8. build an Accelerator - const Accelerator newAccel( event? accelerator_for_event_key( event ) : thisShortcutIterator->second.accelerator_default ); - + const QKeySequence newAccel( QKeySequence_valid( accelerator )? accelerator : thisShortcutIterator->second.accelerator_default ); + // note: can skip the rest, if newAccel == current accel // 8. verify the key is still free, show a dialog to ask what to do if not - VerifyAcceleratorNotTaken verify_visitor( commandName, newAccel, parentWidget, model ); + VerifyAcceleratorNotTaken verify_visitor( commandName, newAccel, item->treeWidget() ); GlobalShortcuts_foreach( verify_visitor ); if ( verify_visitor.allow ) { // clear the ACTUAL accelerator first @@ -306,222 +258,175 @@ static void accelerator_alter( GtkTreeModel *model, GtkTreeIter* iter, GdkEventK thisShortcutIterator->second.accelerator = newAccel; // write into the cell - StringOutputStream modifiers; - modifiers << newAccel; - gtk_list_store_set( GTK_LIST_STORE( model ), iter, 1, modifiers.c_str(), -1 ); + item->setText( 1, newAccel.toString() ); + accelerator_item_set_icon( item, thisShortcutIterator->second ); // set the ACTUAL accelerator too! connect_accelerator( commandName ); } - - g_free( commandName ); -} -gboolean accelerator_window_key_press( GtkWidget *widget, GdkEventKey *event, gpointer dialogptr ){ - command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr; - - if ( !dialog.m_waiting_for_key ) { - return FALSE; - } - -#if 0 - if ( event->is_modifier ) { - return FALSE; - } -#else - switch ( event->keyval ) - { - case GDK_KEY_Shift_L: - case GDK_KEY_Shift_R: - case GDK_KEY_Control_L: - case GDK_KEY_Control_R: - case GDK_KEY_Caps_Lock: - case GDK_KEY_Shift_Lock: - case GDK_KEY_Meta_L: - case GDK_KEY_Meta_R: - case GDK_KEY_Alt_L: - case GDK_KEY_Alt_R: - case GDK_KEY_Super_L: - case GDK_KEY_Super_R: - case GDK_KEY_Hyper_L: - case GDK_KEY_Hyper_R: - return FALSE; - } -#endif - - accelerator_alter( dialog.m_model, &dialog.m_command_iter, event, widget ); - dialog.stopWaitForKey(); - return TRUE; } -void accelerator_reset_button_clicked( GtkButton *btn, gpointer dialogptr ){ - command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr; - - if ( dialog.stopWaitForKey() ) // just unhighlight, user wanted to cancel - return; - - GtkTreeSelection *sel = gtk_tree_view_get_selection( dialog.m_list ); - GtkTreeModel *model; - GtkTreeIter iter; - if ( gtk_tree_selection_get_selected( sel, &model, &iter ) ) { - accelerator_alter( model, &iter, nullptr, gtk_widget_get_toplevel( GTK_WIDGET( btn ) ) ); - } -} - -void accelerator_reset_all_button_clicked( GtkButton *btn, gpointer dialogptr ){ - command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr; - - if ( dialog.stopWaitForKey() ) // just unhighlight, user wanted to cancel - return; - - for ( auto& pair : g_shortcuts ){ // at first disconnect all to avoid conflicts during connecting - if( !( pair.second.accelerator == pair.second.accelerator_default ) ){ // can just do this for all, but it breaks menu accelerator labels :b +void accelerator_reset_all_button_clicked( QTreeWidget *tree ){ + for ( const auto&[name, value] : g_shortcuts ){ // at first disconnect all to avoid conflicts during connecting + if( value.accelerator != value.accelerator_default ){ // can just do this for all, but it breaks menu accelerator labels :b // clear the ACTUAL accelerator - disconnect_accelerator( pair.first.c_str() ); + disconnect_accelerator( name.c_str() ); } } - for ( auto& pair : g_shortcuts ){ - if( !( pair.second.accelerator == pair.second.accelerator_default ) ){ - pair.second.accelerator = pair.second.accelerator_default; + for ( auto&[name, value] : g_shortcuts ){ + if( value.accelerator != value.accelerator_default ){ + value.accelerator = value.accelerator_default; // set the ACTUAL accelerator - connect_accelerator( pair.first.c_str() ); + connect_accelerator( name.c_str() ); } } // update tree view - GtkTreeModel* model = gtk_tree_view_get_model( dialog.m_list ); - if( model ){ - GtkTreeIter i; - if ( gtk_tree_model_get_iter_first( model, &i ) ) { - do{ - gchar* commandName = nullptr; - gtk_tree_model_get( model, &i, 0, &commandName, -1 ); - - Shortcuts::iterator thisShortcutIterator = g_shortcuts.find( commandName ); - if ( thisShortcutIterator != g_shortcuts.end() ) { - // write into the cell - StringOutputStream modifiers; - modifiers << thisShortcutIterator->second.accelerator; - gtk_list_store_set( GTK_LIST_STORE( model ), &i, 1, modifiers.c_str(), -1 ); - } - g_free( commandName ); - } while( gtk_tree_model_iter_next( model, &i ) ); + for( QTreeWidgetItemIterator it( tree ); *it; ++it ) + { + Shortcuts::const_iterator thisShortcutIterator = g_shortcuts.find( ( *it )->text( 0 ).toLatin1().constData() ); + if ( thisShortcutIterator != g_shortcuts.end() ) { + // write into the cell + ( *it )->setText( 1, thisShortcutIterator->second.accelerator.toString() ); + accelerator_item_set_icon( ( *it ), thisShortcutIterator->second ); } } } -static gboolean mid_search_func( GtkTreeModel* model, gint column, const gchar* key, GtkTreeIter* iter, gpointer search_data ) { - gchar* iter_string = 0; - gtk_tree_model_get( model, iter, column, &iter_string, -1 ); - const gboolean ret = iter_string? !string_in_string_nocase( iter_string, key ) : TRUE; - g_free( iter_string ); - return ret; -} +class Single_QKeySequenceEdit : public QKeySequenceEdit +{ +protected: + void keyPressEvent( QKeyEvent *e ) override { + QKeySequenceEdit::keyPressEvent( e ); + if( QKeySequence_valid( keySequence() ) ) + clearFocus(); // trigger editingFinished(); via losing focus 🙉 + // because this can still receive focus loss b4 getting deleted (practically because modal msgbox) + // and two editingFinished(); b no good + } + void focusOutEvent( QFocusEvent *event ) override { + editingFinished(); + } + bool event( QEvent *event ) override { // comsume ALL key presses including Tab + if( event->type() == QEvent::KeyPress ){ + keyPressEvent( static_cast( event ) ); + return true; + } + return QKeySequenceEdit::event( event ); + } +}; + +void accelerator_edit( QTreeWidgetItem *item ){ + auto edit = new Single_QKeySequenceEdit; + QObject::connect( edit, &QKeySequenceEdit::editingFinished, [item, edit](){ + const QKeySequence accelerator = edit->keySequence(); + item->treeWidget()->setItemWidget( item, 1, nullptr ); + if( QKeySequence_valid( accelerator ) ) + accelerator_alter( item, accelerator ); + } ); + item->treeWidget()->setItemWidget( item, 1, edit ); + edit->setFocus(); // track sanity gently via edit being focused property +} void DoCommandListDlg(){ - command_list_dialog_t dialog; + QDialog dialog( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Mapped Commands" ); - GtkWindow* window = create_modal_dialog_window( MainFrame_getWindow(), "Mapped Commands", dialog, -1, 400 ); - g_signal_connect( G_OBJECT( window ), "key-press-event", (GCallback) accelerator_window_key_press, &dialog ); + auto grid = new QGridLayout( &dialog ); - GtkAccelGroup* accel = gtk_accel_group_new(); - gtk_window_add_accel_group( window, accel ); + auto tree = new QTreeWidget; + grid->addWidget( tree, 1, 0, 1, 2 ); + tree->setColumnCount( 2 ); + tree->setSortingEnabled( true ); + tree->sortByColumn( 0, Qt::SortOrder::AscendingOrder ); + tree->setUniformRowHeights( true ); // optimization + tree->setHorizontalScrollBarPolicy( Qt::ScrollBarPolicy::ScrollBarAlwaysOff ); + tree->setSizeAdjustPolicy( QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents ); // scroll area will inherit column size + tree->header()->setStretchLastSection( false ); // non greedy column sizing + tree->header()->setSectionResizeMode( QHeaderView::ResizeMode::ResizeToContents ); // no text elision + tree->setRootIsDecorated( false ); + tree->setHeaderLabels( { "Command", "Key" } ); - GtkHBox* hbox = create_dialog_hbox( 4, 4 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( hbox ) ); + QObject::connect( tree, &QTreeWidget::itemActivated, []( QTreeWidgetItem *item, int column ){ + if( item != nullptr ) + accelerator_edit( item ); + } ); { - GtkScrolledWindow* scr = create_scrolled_window( GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( scr ), TRUE, TRUE, 0 ); + // Initialize dialog + const auto path = StringOutputStream( 256 )( SettingsPath_get(), "commandlist.txt" ); + globalOutputStream() << "Writing the command list to " << path.c_str() << "\n"; + TextFileOutputStream commandList( path.c_str() ); + + for( const auto&[ name, value ] : g_shortcuts ) { - GtkListStore* store = gtk_list_store_new( 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INT ); + auto item = new QTreeWidgetItem( tree, { name.c_str(), value.accelerator.toString() } ); + accelerator_item_set_icon( item, value ); - GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) ); - dialog.m_list = GTK_TREE_VIEW( view ); - - //gtk_tree_view_set_enable_search( GTK_TREE_VIEW( view ), FALSE ); // annoying - gtk_tree_view_set_search_column( dialog.m_list, 0 ); - gtk_tree_view_set_search_equal_func( dialog.m_list, (GtkTreeViewSearchEqualFunc)mid_search_func, 0, 0 ); - - g_signal_connect( G_OBJECT( view ), "button_press_event", G_CALLBACK( accelerator_tree_butt_press ), &dialog ); - - { - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "Command", renderer, "text", 0, "weight-set", 2, "weight", 3, NULL ); - gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column ); + if ( !commandList.failed() ) { + int l = strlen( name.c_str() ); + commandList << name.c_str(); + while ( l++ < 32 ) + commandList << ' '; + commandList << value.accelerator << '\n'; } - - { - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "Key", renderer, "text", 1, "weight-set", 2, "weight", 3, NULL ); - gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column ); - } - - gtk_widget_show( view ); - gtk_container_add( GTK_CONTAINER( scr ), view ); - - { - // Initialize dialog - StringOutputStream path( 256 ); - path << SettingsPath_get() << "commandlist.txt"; - globalOutputStream() << "Writing the command list to " << path.c_str() << "\n"; - - TextFileOutputStream m_commandList( path.c_str() ); - auto buildCommandList = [&m_commandList, store]( const char* name, const Accelerator& accelerator ){ - StringOutputStream modifiers; - modifiers << accelerator; - - { - GtkTreeIter iter; - gtk_list_store_append( store, &iter ); - gtk_list_store_set( store, &iter, 0, name, 1, modifiers.c_str(), 2, FALSE, 3, 800, -1 ); - } - - if ( !m_commandList.failed() ) { - int l = strlen( name ); - m_commandList << name; - while ( l++ < 32 ) - m_commandList << ' '; - m_commandList << modifiers.c_str() << '\n'; - } - }; - GlobalShortcuts_foreach( buildCommandList ); - } - - g_object_unref( G_OBJECT( store ) ); } } - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), TRUE, TRUE, 0 ); { - GtkButton* editbutton = create_dialog_button( "Edit", (GCallback) accelerator_edit_button_clicked, &dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( editbutton ), FALSE, FALSE, 0 ); + auto commandLine = new QLineEdit; + grid->addWidget( commandLine, 0, 0 ); + commandLine->setClearButtonEnabled( true ); + commandLine->setPlaceholderText( QString::fromUtf8( u8"🔍 by command name" ) ); - GtkButton* clearbutton = create_dialog_button( "Clear", (GCallback) accelerator_clear_button_clicked, &dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( clearbutton ), FALSE, FALSE, 0 ); + auto keyLine = new QLineEdit; + grid->addWidget( keyLine, 0, 1 ); + keyLine->setClearButtonEnabled( true ); + keyLine->setPlaceholderText( QString::fromUtf8( u8"🔍 by keys" ) ); - GtkButton* resetbutton = create_dialog_button( "Reset", (GCallback) accelerator_reset_button_clicked, &dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( resetbutton ), FALSE, FALSE, 0 ); - - GtkButton* resetallbutton = create_dialog_button( "Reset All", (GCallback) accelerator_reset_all_button_clicked, &dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( resetallbutton ), FALSE, FALSE, 0 ); - - GtkWidget *spacer = gtk_image_new(); - gtk_widget_show( spacer ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( spacer ), TRUE, TRUE, 0 ); - - GtkButton* button = create_modal_dialog_button( "Close", dialog.m_close_button ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 ); + const auto filter = [tree]( const int column, const QString& text ){ + for( QTreeWidgetItemIterator it( tree ); *it; ++it ) + { + ( *it )->setHidden( !( *it )->text( column ).contains( text, Qt::CaseSensitivity::CaseInsensitive ) ); + } + }; + QObject::connect( commandLine, &QLineEdit::textChanged, [filter]( const QString& text ){ filter( 0, text ); } ); + QObject::connect( keyLine, &QLineEdit::textChanged, [filter]( const QString& text ){ filter( 1, text ); } ); } - modal_dialog_show( window, dialog ); - gtk_widget_destroy( GTK_WIDGET( window ) ); + { + auto buttons = new QDialogButtonBox( Qt::Orientation::Vertical ); + grid->addWidget( buttons, 1, 2, 1, 1 ); + + QPushButton *editbutton = buttons->addButton( "Edit", QDialogButtonBox::ButtonRole::ActionRole ); + QObject::connect( editbutton, &QPushButton::clicked, [tree](){ + if( const auto items = tree->selectedItems(); !items.isEmpty() ) + accelerator_edit( items.first() ); + } ); + + QPushButton *clearbutton = buttons->addButton( "Clear", QDialogButtonBox::ButtonRole::ActionRole ); + QObject::connect( clearbutton, &QPushButton::clicked, [tree](){ + if( const auto items = tree->selectedItems(); !items.isEmpty() ) + accelerator_clear_button_clicked( items.first() ); + } ); + + QPushButton *resetbutton = buttons->addButton( "Reset", QDialogButtonBox::ButtonRole::ResetRole ); + QObject::connect( resetbutton, &QPushButton::clicked, [tree](){ + if( const auto items = tree->selectedItems(); !items.isEmpty() ) + accelerator_alter( items.first(), {} ); + } ); + + QPushButton *resetallbutton = buttons->addButton( "Reset All", QDialogButtonBox::ButtonRole::ResetRole ); + QObject::connect( resetallbutton, &QPushButton::clicked, [tree](){ + accelerator_reset_all_button_clicked( tree ); + } ); + } + + dialog.exec(); } + + #include "profile/profile.h" const char* const COMMANDS_VERSION = "1.0-gtk-accelnames"; @@ -537,10 +442,9 @@ void SaveCommandMap( const char* path ){ file << "\n"; file << "[Commands]\n"; - auto writeCommandMap = [&file]( const char* name, const Accelerator& accelerator ){ + auto writeCommandMap = [&file]( const char* name, const QKeySequence& accelerator ){ file << name << "="; - const char* key = gtk_accelerator_name( accelerator.key, accelerator.modifiers ); - file << key; + file << accelerator; file << "\n"; }; GlobalShortcuts_foreach( writeCommandMap ); @@ -554,25 +458,21 @@ class ReadCommandMap public: ReadCommandMap( const char* filename ) : m_filename( filename ), m_count( 0 ){ } - void operator()( const char* name, Accelerator& accelerator ){ + void operator()( const char* name, QKeySequence& accelerator ){ char value[1024]; if ( read_var( m_filename, "Commands", name, value ) ) { if ( string_empty( value ) ) { - accelerator = accelerator_null(); - return; + accelerator = {}; } - - guint key; - GdkModifierType modifiers; - gtk_accelerator_parse( value, &key, &modifiers ); - accelerator = Accelerator( key, modifiers ); - - if ( accelerator.key != 0 ) { - ++m_count; - } - else - { - globalWarningStream() << "WARNING: failed to parse user command " << makeQuoted( name ) << ": unknown key " << makeQuoted( value ) << "\n"; + else{ + accelerator = QKeySequence( value ); + if ( QKeySequence_valid( accelerator ) ) { + ++m_count; + } + else + { + globalWarningStream() << "WARNING: failed to parse user command " << makeQuoted( name ) << ": unknown key " << makeQuoted( value ) << "\n"; + } } } } @@ -604,7 +504,7 @@ void LoadCommandMap( const char* path ){ globalOutputStream() << "commands import: data version " << dataVersion << " is compatible with code version " << version << "\n"; ReadCommandMap visitor( strINI.c_str() ); GlobalShortcuts_foreach( visitor ); - globalOutputStream() << "parsed " << Unsigned( visitor.count() ) << " custom shortcuts\n"; + globalOutputStream() << "parsed " << visitor.count() << " custom shortcuts\n"; } else { diff --git a/radiant/commands.h b/radiant/commands.h index a545be0d..06bac05d 100644 --- a/radiant/commands.h +++ b/radiant/commands.h @@ -24,17 +24,17 @@ #include "gtkutil/accelerator.h" -const Accelerator& GlobalShortcuts_insert( const char* name, const Accelerator& accelerator ); +const QKeySequence& GlobalShortcuts_insert( const char* name, const QKeySequence& accelerator = {} ); void GlobalShortcuts_register( const char* name, int type ); // 1 = command, 2 = toggle void GlobalShortcuts_reportUnregistered(); -void GlobalCommands_insert( const char* name, const Callback& callback, const Accelerator& accelerator = accelerator_null() ); +void GlobalCommands_insert( const char* name, const Callback& callback, const QKeySequence& accelerator = {} ); const Command& GlobalCommands_find( const char* name ); -void GlobalToggles_insert( const char* name, const Callback& callback, const BoolExportCallback& exportCallback, const Accelerator& accelerator = accelerator_null() ); +void GlobalToggles_insert( const char* name, const Callback& callback, const BoolExportCallback& exportCallback, const QKeySequence& accelerator = {} ); const Toggle& GlobalToggles_find( const char* name ); -void GlobalKeyEvents_insert( const char* name, const Accelerator& accelerator, const Callback& keyDown, const Callback& keyUp ); +void GlobalKeyEvents_insert( const char* name, const Callback& keyDown, const Callback& keyUp, const QKeySequence& accelerator = {} ); const KeyEvent& GlobalKeyEvents_find( const char* name ); diff --git a/radiant/console.cpp b/radiant/console.cpp index 14660ad2..7d3b6055 100644 --- a/radiant/console.cpp +++ b/radiant/console.cpp @@ -22,11 +22,9 @@ #include "console.h" #include -#include #include "gtkutil/accelerator.h" #include "gtkutil/messagebox.h" -#include "gtkutil/container.h" #include "gtkutil/menu.h" #include "gtkutil/nonmodal.h" #include "stream/stringstream.h" @@ -37,6 +35,9 @@ #include "gtkmisc.h" #include "mainframe.h" +#include +#include + // handle to the console log file namespace { @@ -66,8 +67,8 @@ void Sys_LogFile( bool enable ){ << "This is NetRadiant '" RADIANT_VERSION "' compiled " __DATE__ "\n" RADIANT_ABOUTMSG "\n"; } else{ - gtk_MessageBox( 0, "Failed to create log file, check write permissions in Radiant directory.\n", - "Console logging", eMB_OK, eMB_ICONERROR ); + qt_MessageBox( 0, "Failed to create log file, check write permissions in Radiant directory.\n", + "Console logging", EMessageBoxType::Error ); } } else if ( !enable && g_hLogFile != 0 ) { @@ -80,62 +81,38 @@ void Sys_LogFile( bool enable ){ } } -GtkWidget* g_console = 0; +QTextEdit* g_console = 0; -void console_clear(){ - GtkTextBuffer* buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW( g_console ) ); - gtk_text_buffer_set_text( buffer, "", -1 ); -} - -void console_populate_popup( GtkTextView* textview, GtkMenu* menu, gpointer user_data ){ - menu_separator( menu ); - - GtkWidget* item = gtk_menu_item_new_with_label( "Clear" ); - g_signal_connect( G_OBJECT( item ), "activate", G_CALLBACK( console_clear ), 0 ); - gtk_widget_show( item ); - container_add_widget( GTK_CONTAINER( menu ), item ); -} - -gboolean destroy_set_null( GtkWindow* widget, GtkWidget** p ){ - *p = 0; - return FALSE; -} - -WidgetFocusPrinter g_consoleWidgetFocusPrinter( "console" ); +class QTextEdit_console : public QTextEdit +{ +protected: + void contextMenuEvent( QContextMenuEvent *event ) override { + QMenu *menu = createStandardContextMenu(); + QAction *action = menu->addAction( "Clear" ); + connect( action, &QAction::triggered, this, &QTextEdit::clear ); + menu->exec( event->globalPos() ); + delete menu; + } +}; -GtkWidget* Console_constructWindow( GtkWindow* toplevel ){ - GtkWidget* scr = gtk_scrolled_window_new( 0, 0 ); - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); - gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN ); - gtk_widget_show( scr ); +QWidget* Console_constructWindow(){ + QTextEdit *text = new QTextEdit_console(); + text->setReadOnly( true ); + text->setUndoRedoEnabled( false ); + text->setAcceptRichText( false ); + text->setMinimumHeight( 10 ); + text->setFocusPolicy( Qt::FocusPolicy::NoFocus ); { - GtkWidget* text = gtk_text_view_new(); - gtk_widget_set_size_request( text, 0, -1 ); // allow shrinking - gtk_text_view_set_wrap_mode( GTK_TEXT_VIEW( text ), GTK_WRAP_WORD ); - gtk_text_view_set_editable( GTK_TEXT_VIEW( text ), FALSE ); - gtk_container_add( GTK_CONTAINER( scr ), text ); - gtk_widget_show( text ); g_console = text; //globalExtendedASCIICharacterSet().print(); - widget_connect_escape_clear_focus_widget( g_console ); - - //g_consoleWidgetFocusPrinter.connect(g_console); - - g_signal_connect( G_OBJECT( g_console ), "populate-popup", G_CALLBACK( console_populate_popup ), 0 ); - g_signal_connect( G_OBJECT( g_console ), "destroy", G_CALLBACK( destroy_set_null ), &g_console ); + text->connect( text, &QObject::destroyed, [](){ g_console = nullptr; } ); } - //prevent focusing on text view after click on tab of floating group dialog (np, if called via hotkey) - GtkWidget* vbox = gtk_vbox_new( FALSE, 0 ); - gtk_widget_show( vbox ); - gtk_box_pack_start( GTK_BOX( vbox ), scr, TRUE, TRUE, 0 ); - gtk_container_set_focus_chain( GTK_CONTAINER( vbox ), NULL ); - - return vbox; + return text; } //#pragma GCC push_options @@ -143,18 +120,16 @@ GtkWidget* Console_constructWindow( GtkWindow* toplevel ){ class GtkTextBufferOutputStream : public TextOutputStream { - GtkTextBuffer* textBuffer; - GtkTextIter* iter; - GtkTextTag* tag; + QTextEdit* textBuffer; public: - GtkTextBufferOutputStream( GtkTextBuffer* textBuffer, GtkTextIter* iter, GtkTextTag* tag ) : textBuffer( textBuffer ), iter( iter ), tag( tag ){ + GtkTextBufferOutputStream( QTextEdit* textBuffer ) : textBuffer( textBuffer ) { } std::size_t #ifdef __GNUC__ //__attribute__((optimize("O0"))) #endif write( const char* buffer, std::size_t length ){ - gtk_text_buffer_insert_with_tags( textBuffer, iter, buffer, gint( length ), tag, NULL ); + textBuffer->insertPlainText( QString::fromLatin1( buffer, length ) ); return length; } }; @@ -162,7 +137,7 @@ public: //#pragma GCC pop_options std::size_t Sys_Print( int level, const char* buf, std::size_t length ){ - bool contains_newline = std::find( buf, buf + length, '\n' ) != buf + length; + const bool contains_newline = std::find( buf, buf + length, '\n' ) != buf + length; if ( level == SYS_ERR ) { Sys_LogFile( true ); @@ -177,39 +152,25 @@ std::size_t Sys_Print( int level, const char* buf, std::size_t length ){ if ( level != SYS_NOCON ) { if ( g_console != 0 ) { - GtkTextBuffer* buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW( g_console ) ); + g_console->moveCursor( QTextCursor::End ); // must go before setTextColor() - GtkTextIter iter; - gtk_text_buffer_get_end_iter( buffer, &iter ); - - static GtkTextMark* end = gtk_text_buffer_create_mark( buffer, "end", &iter, FALSE ); - -// const GdkColor yellow = { 0, 0xb0ff, 0xb0ff, 0x0000 }; - const GdkColor orange = { 0, 0xffff, 0x8888, 0x0000 }; - const GdkColor red = { 0, 0xffff, 0x0000, 0x0000 }; - - static GtkTextTag* error_tag = gtk_text_buffer_create_tag( buffer, "red_foreground", "foreground-gdk", &red, nullptr ); - static GtkTextTag* warning_tag = gtk_text_buffer_create_tag( buffer, "yellow_foreground", "foreground-gdk", &orange, nullptr ); - static GtkTextTag* standard_tag = gtk_text_buffer_create_tag( buffer, "black_foreground", nullptr ); - GtkTextTag* tag; switch ( level ) { case SYS_WRN: - tag = warning_tag; + g_console->setTextColor( QColor( 255, 127, 0 ) ); break; case SYS_ERR: - tag = error_tag; + g_console->setTextColor( QColor( 255, 0, 0 ) ); break; case SYS_STD: case SYS_VRB: default: - tag = standard_tag; + g_console->setTextColor( g_console->palette().text().color() ); break; } - { - GtkTextBufferOutputStream textBuffer( buffer, &iter, tag ); + GtkTextBufferOutputStream textBuffer( g_console ); if ( !globalCharacterSet().isUTF8() ) { BufferedTextOutputStream buffered( textBuffer ); buffered << StringRange( buf, length ); @@ -220,15 +181,15 @@ std::size_t Sys_Print( int level, const char* buf, std::size_t length ){ } } - // update console widget immediately if we're doing something time-consuming - if ( contains_newline ) { - gtk_text_view_scroll_mark_onscreen( GTK_TEXT_VIEW( g_console ), end ); + if ( contains_newline ) { + g_console->ensureCursorVisible(); - if ( !ScreenUpdates_Enabled() && gtk_widget_get_realized( g_console ) ) { + // update console widget immediately if we're doing something time-consuming + if ( !ScreenUpdates_Enabled() && g_console->isVisible() ) { ScreenUpdates_process(); } } - } + } } return length; } diff --git a/radiant/console.h b/radiant/console.h index 11ef4aef..a878caf3 100644 --- a/radiant/console.h +++ b/radiant/console.h @@ -35,9 +35,7 @@ TextOutputStream& getSysPrintOutputStream(); TextOutputStream& getSysPrintWarningStream(); TextOutputStream& getSysPrintErrorStream(); -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkWindow GtkWindow; -GtkWidget* Console_constructWindow( GtkWindow* toplevel ); +class QWidget* Console_constructWindow(); // will open/close the log file based on the parameter void Sys_LogFile( bool enable ); diff --git a/radiant/csg.cpp b/radiant/csg.cpp index 09b8e134..20d7aa32 100644 --- a/radiant/csg.cpp +++ b/radiant/csg.cpp @@ -700,7 +700,7 @@ void CSG_Subtract(){ } else { - globalOutputStream() << "CSG Subtract: Subtracting " << Unsigned( selected_brushes.size() ) << " brushes.\n"; + globalOutputStream() << "CSG Subtract: Subtracting " << selected_brushes.size() << " brushes.\n"; UndoableCommand undo( "brushSubtract" ); @@ -709,8 +709,8 @@ void CSG_Subtract(){ std::size_t after = 0; GlobalSceneGraph().traverse( SubtractBrushesFromUnselected( selected_brushes, before, after ) ); globalOutputStream() << "CSG Subtract: Result: " - << Unsigned( after ) << " fragment" << ( after == 1 ? "" : "s" ) - << " from " << Unsigned( before ) << " brush" << ( before == 1 ? "" : "es" ) << ".\n"; + << after << " fragment" << ( after == 1 ? "" : "s" ) + << " from " << before << " brush" << ( before == 1 ? "" : "es" ) << ".\n"; SceneChangeNotify(); } @@ -934,7 +934,7 @@ void CSG_Merge(){ return; } - globalOutputStream() << "CSG Merge: Merging " << Unsigned( selected_brushes.size() ) << " brushes.\n"; + globalOutputStream() << "CSG Merge: Merging " << selected_brushes.size() << " brushes.\n"; UndoableCommand undo( "brushMerge" ); @@ -1294,46 +1294,31 @@ void CSG_DeleteComponents(){ ============= */ #include "mainframe.h" -#include #include "gtkutil/dialog.h" -#include "gtkutil/button.h" #include "gtkutil/accelerator.h" +#include "gtkutil/image.h" +#include "gtkutil/spinbox.h" +#include "gtkutil/guisettings.h" #include "xywindow.h" #include "camwindow.h" +#include +#include +#include +#include +#include +#include + struct CSGToolDialog { - GtkSpinButton* spin; - GtkWindow *window; - GtkToggleButton *radFaces, *radPlusFaces, *radProj, *radCam, *caulk, *removeInner; + QDoubleSpinBox* spin; + QWidget *window{}; + QRadioButton *radFaces, *radPlusFaces, *radProj, *radCam; + QToolButton *caulk, *removeInner; }; CSGToolDialog g_csgtool_dialog; -#if 0 -DoubleVector3 getExclusion(){ - if( gtk_toggle_button_get_active( g_csgtool_dialog.radProj ) ){ - return DoubleVector3( g_vector3_axes[GlobalXYWnd_getCurrentViewType()] ); - } - if( gtk_toggle_button_get_active( g_csgtool_dialog.radCam ) ){ - Vector3 angles( Camera_getAngles( *g_pParentWnd->GetCamWnd() ) ); -// globalOutputStream() << angles << " angles\n"; - DoubleVector3 radangles( degrees_to_radians( angles[0] ), degrees_to_radians( angles[1] ), degrees_to_radians( angles[2] ) ); -// globalOutputStream() << radangles << " radangles\n"; -// x = cos(yaw)*cos(pitch) -// y = sin(yaw)*cos(pitch) -// z = sin(pitch) - DoubleVector3 viewvector; - viewvector[0] = cos( radangles[1] ) * cos( radangles[0] ); - viewvector[1] = sin( radangles[1] ) * cos( radangles[0] ); - viewvector[2] = sin( radangles[0] ); -// globalOutputStream() << viewvector << " viewvector\n"; - return viewvector; - } - return DoubleVector3( 0, 0, 0 ); -} -#endif - class BrushFaceOffset { HollowSettings& m_settings; public: @@ -1368,28 +1353,30 @@ void CSG_MakeRoom(){ SceneChangeNotify(); } -void CSGdlg_getSettings( HollowSettings& settings, const CSGToolDialog& dialog ){ - gtk_spin_button_update( dialog.spin ); - settings.m_offset = static_cast( gtk_spin_button_get_value( dialog.spin ) ); - if( gtk_toggle_button_get_active( dialog.radProj ) ){ +HollowSettings CSGdlg_getSettings( const CSGToolDialog& dialog ){ + HollowSettings settings; + + settings.m_offset = dialog.spin->value(); + if( dialog.radProj->isChecked() ){ settings.m_excludeByAxis = true; settings.m_exclusionAxis = g_vector3_axes[GlobalXYWnd_getCurrentViewType()]; } - else if( gtk_toggle_button_get_active( dialog.radCam ) ){ + else if( dialog.radCam->isChecked() ){ settings.m_excludeByAxis = true; settings.m_exclusionAxis = Camera_getViewVector( *g_pParentWnd->GetCamWnd() ); } - else{ + else{ // either + or - faces settings.m_excludeByAxis = false; - settings.m_excludeSelectedFaces = gtk_toggle_button_get_active( dialog.radFaces ); + settings.m_excludeSelectedFaces = dialog.radFaces->isChecked(); } - settings.m_caulk = gtk_toggle_button_get_active( dialog.caulk ); - settings.m_removeInner = gtk_toggle_button_get_active( dialog.removeInner ); + settings.m_caulk = dialog.caulk->isChecked(); + settings.m_removeInner = dialog.removeInner->isChecked(); + + return settings; } void CSG_Hollow( EHollowType type, const char* undoString, const CSGToolDialog& dialog ){ - HollowSettings settings; - CSGdlg_getSettings( settings, dialog ); + HollowSettings settings = CSGdlg_getSettings( dialog ); settings.m_hollowType = type; UndoableCommand undo( undoString ); GlobalSceneGraph().traverse( BrushHollowSelectedWalker( settings ) ); @@ -1401,226 +1388,168 @@ void CSG_Hollow( EHollowType type, const char* undoString, const CSGToolDialog& //=================DLG -static gboolean CSGdlg_HollowDiag( GtkWidget *widget, CSGToolDialog* dialog ){ - CSG_Hollow( eDiag, "brushHollow::Diag", *dialog ); - return TRUE; -} - -static gboolean CSGdlg_HollowWrap( GtkWidget *widget, CSGToolDialog* dialog ){ - CSG_Hollow( eWrap, "brushHollow::Wrap", *dialog ); - return TRUE; -} - -static gboolean CSGdlg_HollowExtrude( GtkWidget *widget, CSGToolDialog* dialog ){ - CSG_Hollow( eExtrude, "brushHollow::Extrude", *dialog ); - return TRUE; -} - -static gboolean CSGdlg_HollowPull( GtkWidget *widget, CSGToolDialog* dialog ){ - CSG_Hollow( ePull, "brushHollow::Pull", *dialog ); - return TRUE; -} - -static gboolean CSGdlg_BrushShrink( GtkWidget *widget, CSGToolDialog* dialog ){ - HollowSettings settings; - CSGdlg_getSettings( settings, *dialog ); +static void CSGdlg_BrushShrink(){ + HollowSettings settings = CSGdlg_getSettings( g_csgtool_dialog ); settings.m_offset *= -1; UndoableCommand undo( "Shrink brush" ); // Scene_forEachSelectedBrush( BrushFaceOffset( settings ) ); Scene_forEachVisibleBrush( GlobalSceneGraph(), BrushFaceOffset( settings ) ); SceneChangeNotify(); - return TRUE; } -static gboolean CSGdlg_BrushExpand( GtkWidget *widget, CSGToolDialog* dialog ){ - HollowSettings settings; - CSGdlg_getSettings( settings, *dialog ); +static void CSGdlg_BrushExpand(){ + HollowSettings settings = CSGdlg_getSettings( g_csgtool_dialog ); UndoableCommand undo( "Expand brush" ); // Scene_forEachSelectedBrush( BrushFaceOffset( settings ) ); Scene_forEachVisibleBrush( GlobalSceneGraph(), BrushFaceOffset( settings ) ); SceneChangeNotify(); - return TRUE; } -static gboolean CSGdlg_grid2spin( GtkWidget *widget, CSGToolDialog* dialog ){ - gtk_spin_button_set_value( dialog->spin, GetGridSize() ); - return TRUE; -} -static gboolean CSGdlg_delete( GtkWidget *widget, GdkEventAny *event, CSGToolDialog* dialog ){ - gtk_widget_hide( GTK_WIDGET( dialog->window ) ); - return TRUE; -} +class CSG_SpinBoxLabel : public SpinBoxLabel +{ + using SpinBoxLabel::SpinBoxLabel; +protected: + void mouseReleaseEvent( QMouseEvent* event ) override { + if( !m_dragOccured ){ + m_spin->setValue( GetGridSize() ); + m_spin->setSingleStep( GetGridSize() ); + } + SpinBoxLabel::mouseReleaseEvent( event ); + } +}; + void CSG_Tool(){ - if ( g_csgtool_dialog.window == NULL ) { - g_csgtool_dialog.window = create_dialog_window( MainFrame_getWindow(), "CSG Tool", G_CALLBACK( CSGdlg_delete ), &g_csgtool_dialog ); - gtk_window_set_type_hint( g_csgtool_dialog.window, GDK_WINDOW_TYPE_HINT_UTILITY ); - - //GtkAccelGroup* accel = gtk_accel_group_new(); - //gtk_window_add_accel_group( g_csgtool_dialog.window, accel ); - global_accel_connect_window( g_csgtool_dialog.window ); + if ( g_csgtool_dialog.window == nullptr ) { + g_csgtool_dialog.window = new QWidget( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + g_csgtool_dialog.window->setWindowTitle( "CSG Tool" ); + g_guiSettings.addWindow( g_csgtool_dialog.window, "CSGTool/geometry" ); { - GtkHBox* hbox = create_dialog_hbox( 4, 4 ); - gtk_container_add( GTK_CONTAINER( g_csgtool_dialog.window ), GTK_WIDGET( hbox ) ); + auto grid = new QGridLayout( g_csgtool_dialog.window ); // 3 x 8 + grid->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); { - GtkTable* table = create_dialog_table( 3, 8, 4, 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - { - //GtkWidget* label = gtk_label_new( "<->" ); - //gtk_widget_show( label ); - GtkWidget* button = gtk_button_new_with_label( "Grid->" ); - gtk_table_attach( table, button, 0, 1, 0, 1, - (GtkAttachOptions) ( 0 ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_show( button ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( CSGdlg_grid2spin ), &g_csgtool_dialog ); - } - { - GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 16, 0, 9999, 1, 10, 0 ) ); - GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( adj, 1, 3 ) ); - gtk_widget_show( GTK_WIDGET( spin ) ); - gtk_widget_set_tooltip_text( GTK_WIDGET( spin ), "Thickness" ); - gtk_table_attach( table, GTK_WIDGET( spin ), 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( spin ), 64, -1 ); - gtk_spin_button_set_numeric( spin, TRUE ); + auto spin = g_csgtool_dialog.spin = new DoubleSpinBox( 0, 9999, 16, 3, 16 ); + spin->setToolTip( "Thickness" ); + grid->addWidget( spin, 0, 1 ); + } + { + auto label = new CSG_SpinBoxLabel( "Grid->", g_csgtool_dialog.spin ); + grid->addWidget( label, 0, 0 ); + } + { + //radio button group for choosing the exclude axis + auto radFaces = g_csgtool_dialog.radFaces = new QRadioButton( "-faces" ); + radFaces->setToolTip( "Exclude selected faces" ); + grid->addWidget( radFaces, 0, 2 ); - g_csgtool_dialog.spin = spin; - } - { - //radio button group for choosing the exclude axis - GtkWidget* radFaces = gtk_radio_button_new_with_label_from_widget( NULL, "-faces" ); - gtk_widget_set_tooltip_text( radFaces, "Exclude selected faces" ); - GtkWidget* radPlusFaces = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(radFaces), "+faces" ); - gtk_widget_set_tooltip_text( radPlusFaces, "Only process selected faces" ); - GtkWidget* radProj = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(radFaces), "-proj" ); - gtk_widget_set_tooltip_text( radProj, "Exclude faces, most orthogonal to active projection" ); - GtkWidget* radCam = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(radFaces), "-cam" ); - gtk_widget_set_tooltip_text( radCam, "Exclude faces, most orthogonal to camera view" ); + auto radPlusFaces = g_csgtool_dialog.radPlusFaces = new QRadioButton( "+faces" ); + radPlusFaces->setToolTip( "Only process selected faces" ); + grid->addWidget( radPlusFaces, 0, 3 ); - gtk_widget_show( radFaces ); - gtk_widget_show( radPlusFaces ); - gtk_widget_show( radProj ); - gtk_widget_show( radCam ); + auto radProj = g_csgtool_dialog.radProj = new QRadioButton( "-proj" ); + radProj->setToolTip( "Exclude faces, most orthogonal to active projection" ); + grid->addWidget( radProj, 0, 4 ); - gtk_table_attach( table, radFaces, 2, 3, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_table_attach( table, radPlusFaces, 3, 4, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_table_attach( table, radProj, 4, 5, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_table_attach( table, radCam, 5, 6, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - g_csgtool_dialog.radFaces = GTK_TOGGLE_BUTTON( radFaces ); - g_csgtool_dialog.radPlusFaces = GTK_TOGGLE_BUTTON( radPlusFaces ); - g_csgtool_dialog.radProj = GTK_TOGGLE_BUTTON( radProj ); - g_csgtool_dialog.radCam = GTK_TOGGLE_BUTTON( radCam ); - } - { - GtkWidget* button = gtk_toggle_button_new(); - button_set_icon( GTK_BUTTON( button ), "f-caulk.png" ); - gtk_button_set_relief( GTK_BUTTON( button ), GTK_RELIEF_NONE ); - gtk_table_attach( table, button, 6, 7, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_tooltip_text( button, "Caulk some faces" ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( button ), TRUE ); - gtk_widget_show( button ); - g_csgtool_dialog.caulk = GTK_TOGGLE_BUTTON( button ); - } - { - GtkWidget* button = gtk_toggle_button_new(); - button_set_icon( GTK_BUTTON( button ), "csgtool_removeinner.png" ); - gtk_button_set_relief( GTK_BUTTON( button ), GTK_RELIEF_NONE ); - gtk_table_attach( table, button, 7, 8, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_tooltip_text( button, "Remove inner brush" ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( button ), TRUE ); - gtk_widget_show( button ); - g_csgtool_dialog.removeInner = GTK_TOGGLE_BUTTON( button ); - } - { - GtkWidget* sep = gtk_hseparator_new(); - gtk_widget_show( sep ); - gtk_table_attach( table, sep, 0, 8, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkWidget* button = gtk_button_new(); - button_set_icon( GTK_BUTTON( button ), "csgtool_shrink.png" ); - gtk_table_attach( table, button, 0, 1, 2, 3, - (GtkAttachOptions) ( GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_tooltip_text( button, "Shrink brush" ); - gtk_widget_show( button ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( CSGdlg_BrushShrink ), &g_csgtool_dialog ); - } - { - GtkWidget* button = gtk_button_new(); - button_set_icon( GTK_BUTTON( button ), "csgtool_expand.png" ); - gtk_table_attach( table, button, 1, 2, 2, 3, - (GtkAttachOptions) ( GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_tooltip_text( button, "Expand brush" ); - gtk_widget_show( button ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( CSGdlg_BrushExpand ), &g_csgtool_dialog ); - } - { - GtkWidget* button = gtk_button_new(); - button_set_icon( GTK_BUTTON( button ), "csgtool_diagonal.png" ); - gtk_table_attach( table, button, 3, 4, 2, 3, - (GtkAttachOptions) ( GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_tooltip_text( button, "Hollow::diagonal joints" ); - gtk_widget_show( button ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( CSGdlg_HollowDiag ), &g_csgtool_dialog ); - } - { - GtkWidget* button = gtk_button_new(); - button_set_icon( GTK_BUTTON( button ), "csgtool_wrap.png" ); - gtk_table_attach( table, button, 4, 5, 2, 3, - (GtkAttachOptions) ( GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_tooltip_text( button, "Hollow::wrap" ); - gtk_widget_show( button ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( CSGdlg_HollowWrap ), &g_csgtool_dialog ); - } - { - GtkWidget* button = gtk_button_new(); - button_set_icon( GTK_BUTTON( button ), "csgtool_extrude.png" ); - gtk_table_attach( table, button, 5, 6, 2, 3, - (GtkAttachOptions) ( GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_tooltip_text( button, "Hollow::extrude faces" ); - gtk_widget_show( button ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( CSGdlg_HollowExtrude ), &g_csgtool_dialog ); - } - { - GtkWidget* button = gtk_button_new(); - button_set_icon( GTK_BUTTON( button ), "csgtool_pull.png" ); - gtk_table_attach( table, button, 6, 7, 2, 3, - (GtkAttachOptions) ( GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_tooltip_text( button, "Hollow::pull faces" ); - gtk_widget_show( button ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( CSGdlg_HollowPull ), &g_csgtool_dialog ); - } + auto radCam = g_csgtool_dialog.radCam = new QRadioButton( "-cam" ); + radCam->setToolTip( "Exclude faces, most orthogonal to camera view" ); + grid->addWidget( radCam, 0, 5 ); + radFaces->setChecked( true ); + } + { + auto button = g_csgtool_dialog.caulk = new QToolButton; + auto pix = new_local_image( "f-caulk.png" ); + button->setIcon( pix ); + button->setIconSize( pix.size() + QSize( 8, 8 ) ); + button->setToolTip( "Caulk some faces" ); + button->setCheckable( true ); + button->setChecked( true ); + grid->addWidget( button, 0, 6 ); + } + { + auto button = g_csgtool_dialog.removeInner = new QToolButton; + auto pix = new_local_image( "csgtool_removeinner.png" ); + button->setIcon( pix ); + button->setIconSize( pix.size() + QSize( 8, 8 ) ); + button->setToolTip( "Remove inner brush" ); + button->setCheckable( true ); + button->setChecked( true ); + grid->addWidget( button, 0, 7 ); + } + { + auto line = new QFrame; + line->setFrameShape( QFrame::Shape::HLine ); + line->setFrameShadow( QFrame::Shadow::Raised ); + grid->addWidget( line, 1, 0, 1, 8 ); + } + { + auto button = new QToolButton; + auto pix = new_local_image( "csgtool_shrink.png" ); + button->setIcon( pix ); + button->setIconSize( pix.size() + QSize( 8, 8 ) ); + button->setToolTip( "Shrink brush" ); + grid->addWidget( button, 2, 0 ); + QObject::connect( button, &QAbstractButton::clicked, CSGdlg_BrushShrink ); + } + { + auto button = new QToolButton; + auto pix = new_local_image( "csgtool_expand.png" ); + button->setIcon( pix ); + button->setIconSize( pix.size() + QSize( 8, 8 ) ); + button->setToolTip( "Expand brush" ); + grid->addWidget( button, 2, 1 ); + QObject::connect( button, &QAbstractButton::clicked, CSGdlg_BrushExpand ); + } + { + auto button = new QToolButton; + auto pix = new_local_image( "csgtool_diagonal.png" ); + button->setIcon( pix ); + button->setIconSize( pix.size() + QSize( 8, 8 ) ); + button->setToolTip( "Hollow::diagonal joints" ); + grid->addWidget( button, 2, 3 ); + QObject::connect( button, &QAbstractButton::clicked, [](){ CSG_Hollow( eDiag, "brushHollow::Diag", g_csgtool_dialog ); } ); + } + { + auto button = new QToolButton; + auto pix = new_local_image( "csgtool_wrap.png" ); + button->setIcon( pix ); + button->setIconSize( pix.size() + QSize( 8, 8 ) ); + button->setToolTip( "Hollow::wrap" ); + grid->addWidget( button, 2, 4 ); + QObject::connect( button, &QAbstractButton::clicked, [](){ CSG_Hollow( eWrap, "brushHollow::Wrap", g_csgtool_dialog ); } ); + } + { + auto button = new QToolButton; + auto pix = new_local_image( "csgtool_extrude.png" ); + button->setIcon( pix ); + button->setIconSize( pix.size() + QSize( 8, 8 ) ); + button->setToolTip( "Hollow::extrude faces" ); + grid->addWidget( button, 2, 5 ); + QObject::connect( button, &QAbstractButton::clicked, [](){ CSG_Hollow( eExtrude, "brushHollow::Extrude", g_csgtool_dialog ); } ); + } + { + auto button = new QToolButton; + auto pix = new_local_image( "csgtool_pull.png" ); + button->setIcon( pix ); + button->setIconSize( pix.size() + QSize( 8, 8 ) ); + button->setToolTip( "Hollow::pull faces" ); + grid->addWidget( button, 2, 6 ); + QObject::connect( button, &QAbstractButton::clicked, [](){ CSG_Hollow( ePull, "brushHollow::Pull", g_csgtool_dialog ); } ); } } } - gtk_widget_show( GTK_WIDGET( g_csgtool_dialog.window ) ); - gtk_window_present( g_csgtool_dialog.window ); + g_csgtool_dialog.window->show(); } +#include "commands.h" + +void CSG_registerCommands(){ + GlobalCommands_insert( "CSGSubtract", FreeCaller(), QKeySequence( "Shift+U" ) ); + GlobalCommands_insert( "CSGMerge", FreeCaller() ); + GlobalCommands_insert( "CSGWrapMerge", FreeCaller(), QKeySequence( "Ctrl+U" ) ); + GlobalCommands_insert( "CSGroom", FreeCaller() ); + GlobalCommands_insert( "CSGTool", FreeCaller() ); +} \ No newline at end of file diff --git a/radiant/csg.h b/radiant/csg.h index 55a369e6..0ac0c127 100644 --- a/radiant/csg.h +++ b/radiant/csg.h @@ -21,12 +21,8 @@ #pragma once -void CSG_MakeRoom(); -void CSG_Subtract(); -void CSG_Merge(); -void CSG_WrapMerge(); void CSG_DeleteComponents(); -void CSG_Tool(); +void CSG_registerCommands(); namespace scene { diff --git a/radiant/dialog.cpp b/radiant/dialog.cpp index 39d724b5..92825ecc 100644 --- a/radiant/dialog.cpp +++ b/radiant/dialog.cpp @@ -35,79 +35,67 @@ #include -#include - #include "stream/stringstream.h" #include "convert.h" #include "gtkutil/dialog.h" -#include "gtkutil/button.h" #include "gtkutil/entry.h" #include "gtkutil/image.h" +#include "gtkutil/spinbox.h" #include "gtkmisc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include -GtkEntry* DialogEntry_new(){ - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_widget_set_size_request( GTK_WIDGET( entry ), 64, -1 ); - return entry; -} -class DialogEntryRow +struct DialogSliderRow { -public: - DialogEntryRow( GtkWidget* row, GtkEntry* entry ) : m_row( row ), m_entry( entry ){ + QSlider *m_slider; + QHBoxLayout *m_layout; + DialogSliderRow( int lower, int upper, int step_increment, int page_increment ){ + m_slider = new QSlider( Qt::Orientation::Horizontal ); + m_slider->setRange( lower, upper ); + m_slider->setSingleStep( step_increment ); + m_slider->setPageStep( page_increment ); + + auto label = new QLabel; + label->setMinimumWidth( label->fontMetrics().horizontalAdvance( QString::number( upper ) ) ); + QObject::connect( m_slider, &QSlider::valueChanged, + [label]( int value ){ + label->setText( QString::number( value ) ); + } ); + + m_layout = new QHBoxLayout; + m_layout->addWidget( label ); + m_layout->addWidget( m_slider ); + } + + DialogSliderRow( double lower, double upper, double step_increment, double page_increment ){ + m_slider = new QSlider( Qt::Orientation::Horizontal ); + m_slider->setRange( lower * 10, upper * 10 ); + m_slider->setSingleStep( step_increment * 10 ); + m_slider->setPageStep( page_increment * 10 ); + + auto label = new QLabel; + label->setMinimumWidth( label->fontMetrics().horizontalAdvance( QString::number( upper, 'f', 1 ) ) ); + QObject::connect( m_slider, &QSlider::valueChanged, + [label]( int value ){ + label->setText( QString::number( value / 10.0, 'f', 1 ) ); + } ); + + m_layout = new QHBoxLayout; + m_layout->addWidget( label ); + m_layout->addWidget( m_slider ); } - GtkWidget* m_row; - GtkEntry* m_entry; }; -DialogEntryRow DialogEntryRow_new( const char* name ){ - GtkWidget* alignment = gtk_alignment_new( 0.0, 0.5, 0.0, 0.0 ); - gtk_widget_show( alignment ); - - GtkEntry* entry = DialogEntry_new(); - gtk_container_add( GTK_CONTAINER( alignment ), GTK_WIDGET( entry ) ); - - return DialogEntryRow( GTK_WIDGET( DialogRow_new( name, alignment ) ), entry ); -} - - -GtkSpinButton* DialogSpinner_new( double value, double lower, double upper, int fraction ){ - double step = 1.0 / double(fraction); - unsigned int digits = 0; - for (; fraction > 1; fraction /= 10 ) - { - ++digits; - } - GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( GTK_ADJUSTMENT( gtk_adjustment_new( value, lower, upper, step, 10, 0 ) ), step, digits ) ); - gtk_spin_button_set_numeric( spin, TRUE ); - gtk_widget_show( GTK_WIDGET( spin ) ); - gtk_widget_set_size_request( GTK_WIDGET( spin ), 64, -1 ); - return spin; -} - -class DialogSpinnerRow -{ -public: - DialogSpinnerRow( GtkWidget* row, GtkSpinButton* spin ) : m_row( row ), m_spin( spin ){ - } - GtkWidget* m_row; - GtkSpinButton* m_spin; -}; - -DialogSpinnerRow DialogSpinnerRow_new( const char* name, double value, double lower, double upper, int fraction ){ - GtkWidget* alignment = gtk_alignment_new( 0.0, 0.5, 0.0, 0.0 ); - gtk_widget_show( alignment ); - - GtkSpinButton* spin = DialogSpinner_new( value, lower, upper, fraction ); - gtk_container_add( GTK_CONTAINER( alignment ), GTK_WIDGET( spin ) ); - - return DialogSpinnerRow( GTK_WIDGET( DialogRow_new( name, alignment ) ), spin ); -} - - template< typename Type_, @@ -133,105 +121,76 @@ typedef ImportExport Stri -void BoolToggleImport( GtkToggleButton& widget, bool value ){ - gtk_toggle_button_set_active( &widget, value ); +void BoolToggleImport( QCheckBox& widget, bool value ){ + widget.setChecked( value ); } -void BoolToggleExport( GtkToggleButton& widget, const BoolImportCallback& importCallback ){ - importCallback( gtk_toggle_button_get_active( &widget ) ); +void BoolToggleExport( QCheckBox& widget, const BoolImportCallback& importCallback ){ + importCallback( widget.isChecked() ); } -typedef ImportExport BoolToggleImportExport; +typedef ImportExport BoolToggleImportExport; -void IntRadioImport( GtkRadioButton& widget, int index ){ - radio_button_set_active( &widget, index ); +void IntRadioImport( QButtonGroup& widget, int index ){ + widget.button( index )->setChecked( true ); } -void IntRadioExport( GtkRadioButton& widget, const IntImportCallback& importCallback ){ - importCallback( radio_button_get_active( &widget ) ); +void IntRadioExport( QButtonGroup& widget, const IntImportCallback& importCallback ){ + importCallback( widget.checkedId() ); } -typedef ImportExport IntRadioImportExport; - -void TextEntryImport( GtkEntry& widget, const char* text ){ - gtk_entry_set_text( &widget, text ); -} -void TextEntryExport( GtkEntry& widget, const StringImportCallback& importCallback ){ - importCallback( gtk_entry_get_text( &widget ) ); -} -typedef ImportExport TextEntryImportExport; +typedef ImportExport IntRadioImportExport; -void IntEntryImport( GtkEntry& widget, int value ){ - entry_set_int( &widget, value ); +void TextEntryImport( QLineEdit& widget, const char* text ){ + widget.setText( text ); } -void IntEntryExport( GtkEntry& widget, const IntImportCallback& importCallback ){ - importCallback( atoi( gtk_entry_get_text( &widget ) ) ); +void TextEntryExport( QLineEdit& widget, const StringImportCallback& importCallback ){ + importCallback( widget.text().toLatin1().constData() ); } -typedef ImportExport IntEntryImportExport; +typedef ImportExport TextEntryImportExport; -void SizeEntryImport( GtkEntry& widget, std::size_t value ){ - entry_set_int( &widget, int(value) ); +void FloatSpinnerImport( QDoubleSpinBox& widget, float value ){ + widget.setValue( value ); } -void SizeEntryExport( GtkEntry& widget, const SizeImportCallback& importCallback ){ - int value = atoi( gtk_entry_get_text( &widget ) ); - if ( value < 0 ) { - value = 0; - } - importCallback( value ); +void FloatSpinnerExport( QDoubleSpinBox& widget, const FloatImportCallback& importCallback ){ + importCallback( widget.value() ); } -typedef ImportExport SizeEntryImportExport; +typedef ImportExport FloatSpinnerImportExport; -void FloatEntryImport( GtkEntry& widget, float value ){ - entry_set_float( &widget, value ); +void IntSpinnerImport( QSpinBox& widget, int value ){ + widget.setValue( value ); } -void FloatEntryExport( GtkEntry& widget, const FloatImportCallback& importCallback ){ - importCallback( (float)atof( gtk_entry_get_text( &widget ) ) ); +void IntSpinnerExport( QSpinBox& widget, const IntImportCallback& importCallback ){ + importCallback( widget.value() ); } -typedef ImportExport FloatEntryImportExport; +typedef ImportExport IntSpinnerImportExport; -void FloatSpinnerImport( GtkSpinButton& widget, float value ){ - gtk_spin_button_set_value( &widget, value ); +void IntSliderImport( QSlider& widget, int value ){ + widget.setValue( value ); } -void FloatSpinnerExport( GtkSpinButton& widget, const FloatImportCallback& importCallback ){ - importCallback( static_cast( gtk_spin_button_get_value( &widget ) ) ); +void IntSliderExport( QSlider& widget, const IntImportCallback& importCallback ){ + importCallback( widget.value() ); } -typedef ImportExport FloatSpinnerImportExport; +typedef ImportExport IntSliderImportExport; + +// QSlider operates on int values only, so using 10x range for floats +void FloatSliderImport( QSlider& widget, float value ){ + widget.setValue( value * 10.0 ); +} +void FloatSliderExport( QSlider& widget, const FloatImportCallback& importCallback ){ + importCallback( widget.value() / 10.0 ); +} +typedef ImportExport FloatSliderImportExport; -void IntSpinnerImport( GtkSpinButton& widget, int value ){ - gtk_spin_button_set_value( &widget, value ); +void IntComboImport( QComboBox& widget, int value ){ + widget.setCurrentIndex( value ); } -void IntSpinnerExport( GtkSpinButton& widget, const IntImportCallback& importCallback ){ - importCallback( gtk_spin_button_get_value_as_int( &widget ) ); +void IntComboExport( QComboBox& widget, const IntImportCallback& importCallback ){ + importCallback( widget.currentIndex() ); } -typedef ImportExport IntSpinnerImportExport; - - -void IntAdjustmentImport( GtkAdjustment& widget, int value ){ - gtk_adjustment_set_value( &widget, value ); -} -void IntAdjustmentExport( GtkAdjustment& widget, const IntImportCallback& importCallback ){ - importCallback( (int)gtk_adjustment_get_value( &widget ) ); -} -typedef ImportExport IntAdjustmentImportExport; - -void FloatAdjustmentImport( GtkAdjustment& widget, float value ){ - gtk_adjustment_set_value( &widget, value ); -} -void FloatAdjustmentExport( GtkAdjustment& widget, const FloatImportCallback& importCallback ){ - importCallback( (float)gtk_adjustment_get_value( &widget ) ); -} -typedef ImportExport FloatAdjustmentImportExport; - - -void IntComboImport( GtkComboBox& widget, int value ){ - gtk_combo_box_set_active( &widget, value ); -} -void IntComboExport( GtkComboBox& widget, const IntImportCallback& importCallback ){ - importCallback( gtk_combo_box_get_active( &widget ) ); -} -typedef ImportExport IntComboImportExport; +typedef ImportExport IntComboImportExport; template @@ -307,9 +266,6 @@ public: // ============================================================================= // Dialog class -Dialog::Dialog() : m_window( 0 ), m_parent( 0 ){ -} - Dialog::~Dialog(){ for ( DialogDataList::iterator i = m_data.begin(); i != m_data.end(); ++i ) { @@ -322,112 +278,87 @@ Dialog::~Dialog(){ void Dialog::ShowDlg(){ ASSERT_MESSAGE( m_window != 0, "dialog was not constructed" ); importData(); - gtk_widget_show( GTK_WIDGET( m_window ) ); + m_window->show(); + m_window->raise(); + m_window->activateWindow(); } void Dialog::HideDlg(){ ASSERT_MESSAGE( m_window != 0, "dialog was not constructed" ); exportData(); - gtk_widget_hide( GTK_WIDGET( m_window ) ); + m_window->hide(); } -static gint delete_event_callback( GtkWidget *widget, GdkEvent* event, gpointer data ){ - reinterpret_cast( data )->HideDlg(); - reinterpret_cast( data )->EndModal( eIDCANCEL ); - return TRUE; -} - -void Dialog::Create(){ +void Dialog::Create( QWidget *parent ){ ASSERT_MESSAGE( m_window == 0, "dialog cannot be constructed" ); - m_window = BuildDialog(); - g_signal_connect( G_OBJECT( m_window ), "delete_event", G_CALLBACK( delete_event_callback ), this ); + m_window = new QDialog( parent, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + BuildDialog(); } void Dialog::Destroy(){ ASSERT_MESSAGE( m_window != 0, "dialog cannot be destroyed" ); - gtk_widget_destroy( GTK_WIDGET( m_window ) ); + delete m_window; m_window = 0; } -void Dialog::AddBoolToggleData( GtkToggleButton& widget, const BoolImportCallback& importViewer, const BoolExportCallback& exportViewer ){ +void Dialog::AddBoolToggleData( QCheckBox& widget, const BoolImportCallback& importViewer, const BoolExportCallback& exportViewer ){ AddCustomData( m_data ).apply( widget, importViewer, exportViewer ); } -void Dialog::AddIntRadioData( GtkRadioButton& widget, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ +void Dialog::AddIntRadioData( QButtonGroup& widget, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ AddCustomData( m_data ).apply( widget, importViewer, exportViewer ); } -void Dialog::AddTextEntryData( GtkEntry& widget, const StringImportCallback& importViewer, const StringExportCallback& exportViewer ){ +void Dialog::AddTextEntryData( QLineEdit& widget, const StringImportCallback& importViewer, const StringExportCallback& exportViewer ){ AddCustomData( m_data ).apply( widget, importViewer, exportViewer ); } -void Dialog::AddIntEntryData( GtkEntry& widget, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ - AddCustomData( m_data ).apply( widget, importViewer, exportViewer ); -} - -void Dialog::AddSizeEntryData( GtkEntry& widget, const SizeImportCallback& importViewer, const SizeExportCallback& exportViewer ){ - AddCustomData( m_data ).apply( widget, importViewer, exportViewer ); -} - -void Dialog::AddFloatEntryData( GtkEntry& widget, const FloatImportCallback& importViewer, const FloatExportCallback& exportViewer ){ - AddCustomData( m_data ).apply( widget, importViewer, exportViewer ); -} - -void Dialog::AddFloatSpinnerData( GtkSpinButton& widget, const FloatImportCallback& importViewer, const FloatExportCallback& exportViewer ){ +void Dialog::AddFloatSpinnerData( QDoubleSpinBox& widget, const FloatImportCallback& importViewer, const FloatExportCallback& exportViewer ){ AddCustomData( m_data ).apply( widget, importViewer, exportViewer ); } -void Dialog::AddIntSpinnerData( GtkSpinButton& widget, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ +void Dialog::AddIntSpinnerData( QSpinBox& widget, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ AddCustomData( m_data ).apply( widget, importViewer, exportViewer ); } -void Dialog::AddIntAdjustmentData( GtkAdjustment& widget, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ - AddCustomData( m_data ).apply( widget, importViewer, exportViewer ); +void Dialog::AddIntSliderData( QSlider& widget, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ + AddCustomData( m_data ).apply( widget, importViewer, exportViewer ); } -void Dialog::AddFloatAdjustmentData( GtkAdjustment& widget, const FloatImportCallback& importViewer, const FloatExportCallback& exportViewer ){ - AddCustomData( m_data ).apply( widget, importViewer, exportViewer ); +void Dialog::AddFloatSliderData( QSlider& widget, const FloatImportCallback& importViewer, const FloatExportCallback& exportViewer ){ + AddCustomData( m_data ).apply( widget, importViewer, exportViewer ); } -void Dialog::AddIntComboData( GtkComboBox& widget, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ +void Dialog::AddIntComboData( QComboBox& widget, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ AddCustomData( m_data ).apply( widget, importViewer, exportViewer ); } -void Dialog::AddDialogData( GtkToggleButton& widget, bool& data ){ +void Dialog::AddDialogData( QCheckBox& widget, bool& data ){ AddData( m_data ).apply( widget, data ); } -void Dialog::AddDialogData( GtkRadioButton& widget, int& data ){ +void Dialog::AddDialogData( QButtonGroup& widget, int& data ){ AddData( m_data ).apply( widget, data ); } -void Dialog::AddDialogData( GtkEntry& widget, CopiedString& data ){ +void Dialog::AddDialogData( QLineEdit& widget, CopiedString& data ){ AddData( m_data ).apply( widget, data ); } -void Dialog::AddDialogData( GtkEntry& widget, int& data ){ - AddData( m_data ).apply( widget, data ); -} -void Dialog::AddDialogData( GtkEntry& widget, std::size_t& data ){ - AddData( m_data ).apply( widget, data ); -} -void Dialog::AddDialogData( GtkEntry& widget, float& data ){ - AddData( m_data ).apply( widget, data ); -} -void Dialog::AddDialogData( GtkSpinButton& widget, float& data ){ +void Dialog::AddDialogData( QDoubleSpinBox& widget, float& data ){ AddData( m_data ).apply( widget, data ); } -void Dialog::AddDialogData( GtkSpinButton& widget, int& data ){ +void Dialog::AddDialogData( QSpinBox& widget, int& data ){ AddData( m_data ).apply( widget, data ); } -void Dialog::AddDialogData( GtkAdjustment& widget, int& data ){ - AddData( m_data ).apply( widget, data ); +void Dialog::AddDialogData( QSlider& widget, int& data ){ + AddData( m_data ).apply( widget, data ); } -void Dialog::AddDialogData( GtkAdjustment& widget, float& data ){ - AddData( m_data ).apply( widget, data ); +void Dialog::AddDialogData( QSlider& widget, float& data ){ + AddData( m_data ).apply( widget, data ); } -void Dialog::AddDialogData( GtkComboBox& widget, int& data ){ +void Dialog::AddDialogData( QComboBox& widget, int& data ){ AddData( m_data ).apply( widget, data ); } @@ -445,230 +376,152 @@ void Dialog::importData(){ } } -void Dialog::EndModal( EMessageBoxReturn code ){ - m_modal.loop = 0; - m_modal.ret = code; +void Dialog::EndModal( QDialog::DialogCode code ){ + m_window->done( code ); } -EMessageBoxReturn Dialog::DoModal(){ +QDialog::DialogCode Dialog::DoModal(){ importData(); PreModal(); - EMessageBoxReturn ret = modal_dialog_show( m_window, m_modal ); ASSERT_NOTNULL( m_window ); - if ( ret == eIDOK ) { + const QDialog::DialogCode ret = static_cast( m_window->exec() ); + if ( ret == QDialog::DialogCode::Accepted ) { exportData(); } - gtk_widget_hide( GTK_WIDGET( m_window ) ); + m_window->hide(); - PostModal( m_modal.ret ); + PostModal( ret ); - return m_modal.ret; + return ret; } -GtkWidget* Dialog::addCheckBox( GtkWidget* vbox, const char* name, const char* flag, const BoolImportCallback& importViewer, const BoolExportCallback& exportViewer ){ - GtkWidget* check = gtk_check_button_new_with_label( flag ); - gtk_widget_show( check ); - AddBoolToggleData( *GTK_TOGGLE_BUTTON( check ), importViewer, exportViewer ); - - DialogVBox_packRow( GTK_VBOX( vbox ), GTK_WIDGET( DialogRow_new( name, check ) ) ); +QCheckBox* Dialog::addCheckBox( QGridLayout* grid, const char* name, const char* flag, const BoolImportCallback& importViewer, const BoolExportCallback& exportViewer ){ + auto check = new QCheckBox( flag ); + AddBoolToggleData( *check, importViewer, exportViewer ); + DialogGrid_packRow( grid, check, name ); return check; } -GtkWidget* Dialog::addCheckBox( GtkWidget* vbox, const char* name, const char* flag, bool& data ){ - return addCheckBox( vbox, name, flag, BoolImportCaller( data ), BoolExportCaller( data ) ); +QCheckBox* Dialog::addCheckBox( QGridLayout* grid, const char* name, const char* flag, bool& data ){ + return addCheckBox( grid, name, flag, BoolImportCaller( data ), BoolExportCaller( data ) ); } -void Dialog::addCombo( GtkWidget* vbox, const char* name, StringArrayRange values, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ - GtkWidget* alignment = gtk_alignment_new( 0.0, 0.5, 0.0, 0.0 ); - gtk_widget_show( alignment ); - { - GtkWidget* combo = gtk_combo_box_text_new(); +QComboBox* Dialog::addCombo( QGridLayout* grid, const char* name, StringArrayRange values, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ + auto combo = new QComboBox; - for ( const char *value : values ) - { - gtk_combo_box_text_append_text( GTK_COMBO_BOX_TEXT( combo ), value ); - } + for ( const char *value : values ) + combo->addItem( value ); - AddIntComboData( *GTK_COMBO_BOX( combo ), importViewer, exportViewer ); + AddIntComboData( *combo, importViewer, exportViewer ); - gtk_widget_show( combo ); - gtk_container_add( GTK_CONTAINER( alignment ), combo ); - } + DialogGrid_packRow( grid, combo, name ); - GtkTable* row = DialogRow_new( name, alignment ); - DialogVBox_packRow( GTK_VBOX( vbox ), GTK_WIDGET( row ) ); + return combo; } -void Dialog::addCombo( GtkWidget* vbox, const char* name, int& data, StringArrayRange values ){ - addCombo( vbox, name, values, IntImportCaller( data ), IntExportCaller( data ) ); +QComboBox* Dialog::addCombo( QGridLayout* grid, const char* name, int& data, StringArrayRange values ){ + return addCombo( grid, name, values, IntImportCaller( data ), IntExportCaller( data ) ); } -void addSlider_( GtkAdjustment* adj, GtkWidget* vbox, const char* name, gboolean draw_value, const char* low, const char* high, int digits ){ -#if 0 - if ( !draw_value ) { - GtkWidget* hbox2 = gtk_hbox_new( FALSE, 0 ); - gtk_widget_show( hbox2 ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox2 ), FALSE, FALSE, 0 ); - { - GtkWidget* label = gtk_label_new( low ); - gtk_widget_show( label ); - gtk_box_pack_start( GTK_BOX( hbox2 ), label, FALSE, FALSE, 0 ); - } - { - GtkWidget* label = gtk_label_new( high ); - gtk_widget_show( label ); - gtk_box_pack_end( GTK_BOX( hbox2 ), label, FALSE, FALSE, 0 ); - } - } -#endif - // scale - GtkWidget* alignment = gtk_alignment_new( 0.0, 0.5, 1.0, 0.0 ); - gtk_widget_show( alignment ); +void Dialog::addSlider( QGridLayout* grid, const char* name, int& data, int lower, int upper, int step_increment, int page_increment ){ + DialogSliderRow row( lower, upper, step_increment, page_increment ); - GtkWidget* scale = gtk_hscale_new( adj ); - gtk_scale_set_value_pos( GTK_SCALE( scale ), GTK_POS_LEFT ); - gtk_widget_show( scale ); - gtk_container_add( GTK_CONTAINER( alignment ), scale ); + AddIntSliderData( *row.m_slider, IntImportCaller( data ), IntExportCaller( data ) ); - gtk_scale_set_draw_value( GTK_SCALE( scale ), draw_value ); - gtk_scale_set_digits( GTK_SCALE( scale ), digits ); - - GtkTable* row = DialogRow_new( name, alignment ); - DialogVBox_packRow( GTK_VBOX( vbox ), GTK_WIDGET( row ) ); + DialogGrid_packRow( grid, row.m_layout, name ); } -void Dialog::addSlider( GtkWidget* vbox, const char* name, int& data, gboolean draw_value, const char* low, const char* high, double value, double lower, double upper, double step_increment, double page_increment ){ - // adjustment - GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( value, lower, upper, step_increment, page_increment, 0 ) ); - AddIntAdjustmentData( *adj, IntImportCaller( data ), IntExportCaller( data ) ); +void Dialog::addSlider( QGridLayout* grid, const char* name, float& data, double lower, double upper, double step_increment, double page_increment ){ + DialogSliderRow row( lower, upper, step_increment, page_increment ); - addSlider_( adj, vbox, name, draw_value, low, high, 0 ); + AddFloatSliderData( *row.m_slider, FloatImportCaller( data ), FloatExportCaller( data ) ); + + DialogGrid_packRow( grid, row.m_layout, name ); } -void Dialog::addSlider( GtkWidget* vbox, const char* name, float& data, gboolean draw_value, const char* low, const char* high, double value, double lower, double upper, double step_increment, double page_increment ){ - // adjustment - GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( value, lower, upper, step_increment, page_increment, 0 ) ); - AddFloatAdjustmentData( *adj, FloatImportCaller( data ), FloatExportCaller( data ) ); +void Dialog::addRadio( QGridLayout* grid, const char* name, StringArrayRange names, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ + RadioHBox radioBox = RadioHBox_new( names ); + AddIntRadioData( *radioBox.m_radio, importViewer, exportViewer ); - addSlider_( adj, vbox, name, draw_value, low, high, 1 ); + DialogGrid_packRow( grid, radioBox.m_hbox, name ); } -void Dialog::addRadio( GtkWidget* vbox, const char* name, StringArrayRange names, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ - GtkWidget* alignment = gtk_alignment_new( 0.0, 0.5, 0.0, 0.0 ); - gtk_widget_show( alignment ); - { - RadioHBox radioBox = RadioHBox_new( names ); - gtk_container_add( GTK_CONTAINER( alignment ), GTK_WIDGET( radioBox.m_hbox ) ); - AddIntRadioData( *GTK_RADIO_BUTTON( radioBox.m_radio ), importViewer, exportViewer ); - } - - GtkTable* row = DialogRow_new( name, alignment ); - DialogVBox_packRow( GTK_VBOX( vbox ), GTK_WIDGET( row ) ); +void Dialog::addRadio( QGridLayout* grid, const char* name, int& data, StringArrayRange names ){ + addRadio( grid, name, names, IntImportCaller( data ), IntExportCaller( data ) ); } -void Dialog::addRadio( GtkWidget* vbox, const char* name, int& data, StringArrayRange names ){ - addRadio( vbox, name, names, IntImportCaller( data ), IntExportCaller( data ) ); -} +void Dialog::addRadioIcons( QGridLayout* grid, const char* name, StringArrayRange icons, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ + auto subgrid = new QGridLayout; + auto buttons = new QButtonGroup( subgrid ); -void Dialog::addRadioIcons( GtkWidget* vbox, const char* name, StringArrayRange icons, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ - GtkWidget* table = gtk_table_new( 2, icons.size(), FALSE ); - gtk_widget_show( table ); - - gtk_table_set_row_spacings( GTK_TABLE( table ), 5 ); - gtk_table_set_col_spacings( GTK_TABLE( table ), 5 ); - - GtkWidget* radio = 0; for ( size_t i = 0; i < icons.size(); ++i ) { - GtkImage* image = new_local_image( icons[i] ); - gtk_widget_show( GTK_WIDGET( image ) ); - gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( image ), i, i + 1, 0, 1, - (GtkAttachOptions) ( 0 ), - (GtkAttachOptions) ( 0 ), 0, 0 ); + auto label = new QLabel; + label->setPixmap( new_local_image( icons[i] ) ); + subgrid->addWidget( label, 0, i, Qt::AlignmentFlag::AlignHCenter ); - radio = gtk_radio_button_new_from_widget( GTK_RADIO_BUTTON( radio ) ); - gtk_widget_show( radio ); - gtk_table_attach( GTK_TABLE( table ), radio, i, i + 1, 1, 2, - (GtkAttachOptions) ( 0 ), - (GtkAttachOptions) ( 0 ), 0, 0 ); + auto button = new QRadioButton; + buttons->addButton( button, i ); // set ids 0+, default ones are negative + subgrid->addWidget( button, 1, i, Qt::AlignmentFlag::AlignHCenter ); } - AddIntRadioData( *GTK_RADIO_BUTTON( radio ), importViewer, exportViewer ); + AddIntRadioData( *buttons, importViewer, exportViewer ); - DialogVBox_packRow( GTK_VBOX( vbox ), GTK_WIDGET( DialogRow_new( name, table ) ) ); + DialogGrid_packRow( grid, subgrid, name ); } -void Dialog::addRadioIcons( GtkWidget* vbox, const char* name, int& data, StringArrayRange icons ){ - addRadioIcons( vbox, name, icons, IntImportCaller( data ), IntExportCaller( data ) ); +void Dialog::addRadioIcons( QGridLayout* grid, const char* name, int& data, StringArrayRange icons ){ + addRadioIcons( grid, name, icons, IntImportCaller( data ), IntExportCaller( data ) ); } -GtkWidget* Dialog::addIntEntry( GtkWidget* vbox, const char* name, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ - DialogEntryRow row( DialogEntryRow_new( name ) ); - AddIntEntryData( *row.m_entry, importViewer, exportViewer ); - DialogVBox_packRow( GTK_VBOX( vbox ), row.m_row ); - return row.m_row; -} - -GtkWidget* Dialog::addSizeEntry( GtkWidget* vbox, const char* name, const SizeImportCallback& importViewer, const SizeExportCallback& exportViewer ){ - DialogEntryRow row( DialogEntryRow_new( name ) ); - AddSizeEntryData( *row.m_entry, importViewer, exportViewer ); - DialogVBox_packRow( GTK_VBOX( vbox ), row.m_row ); - return row.m_row; -} - -GtkWidget* Dialog::addFloatEntry( GtkWidget* vbox, const char* name, const FloatImportCallback& importViewer, const FloatExportCallback& exportViewer ){ - DialogEntryRow row( DialogEntryRow_new( name ) ); - AddFloatEntryData( *row.m_entry, importViewer, exportViewer ); - DialogVBox_packRow( GTK_VBOX( vbox ), row.m_row ); - return row.m_row; -} - -GtkWidget* Dialog::addTextEntry( GtkWidget* vbox, const char* name, const StringImportCallback& importViewer, const StringExportCallback& exportViewer ){ - GtkEntry* entry = DialogEntry_new(); - gtk_widget_set_size_request( GTK_WIDGET( entry ), -1, -1 ); // unset - +void Dialog::addTextEntry( QGridLayout* grid, const char* name, const StringImportCallback& importViewer, const StringExportCallback& exportViewer ){ + auto entry = new QLineEdit; AddTextEntryData( *entry, importViewer, exportViewer ); - GtkTable* row = DialogRow_new( name, GTK_WIDGET( entry ) ); - DialogVBox_packRow( GTK_VBOX( vbox ), GTK_WIDGET( row ) ); - - return GTK_WIDGET( row ); + DialogGrid_packRow( grid, entry, name ); } -GtkWidget* Dialog::addPathEntry( GtkWidget* vbox, const char* name, bool browse_directory, const StringImportCallback& importViewer, const StringExportCallback& exportViewer ){ +void Dialog::addPathEntry( QGridLayout* grid, const char* name, bool browse_directory, const StringImportCallback& importViewer, const StringExportCallback& exportViewer ){ PathEntry pathEntry = PathEntry_new(); - g_signal_connect( G_OBJECT( pathEntry.m_button ), "clicked", G_CALLBACK( browse_directory ? button_clicked_entry_browse_directory : button_clicked_entry_browse_file ), pathEntry.m_entry ); - AddTextEntryData( *GTK_ENTRY( pathEntry.m_entry ), importViewer, exportViewer ); + if( browse_directory ) + QObject::connect( pathEntry.m_button, &QAction::triggered, [entry = pathEntry.m_entry](){ button_clicked_entry_browse_directory( entry ); } ); + else + QObject::connect( pathEntry.m_button, &QAction::triggered, [entry = pathEntry.m_entry](){ button_clicked_entry_browse_file( entry ); } ); - GtkTable* row = DialogRow_new( name, GTK_WIDGET( pathEntry.m_frame ) ); - DialogVBox_packRow( GTK_VBOX( vbox ), GTK_WIDGET( row ) ); + AddTextEntryData( *pathEntry.m_entry, importViewer, exportViewer ); - return GTK_WIDGET( row ); + DialogGrid_packRow( grid, pathEntry.m_entry, name ); } -GtkWidget* Dialog::addPathEntry( GtkWidget* vbox, const char* name, CopiedString& data, bool browse_directory ){ - return addPathEntry( vbox, name, browse_directory, StringImportCallback( StringImportCaller( data ) ), StringExportCallback( StringExportCaller( data ) ) ); +void Dialog::addPathEntry( QGridLayout* grid, const char* name, CopiedString& data, bool browse_directory ){ + addPathEntry( grid, name, browse_directory, StringImportCallback( StringImportCaller( data ) ), StringExportCallback( StringExportCaller( data ) ) ); } -GtkWidget* Dialog::addSpinner( GtkWidget* vbox, const char* name, double value, double lower, double upper, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ - DialogSpinnerRow row( DialogSpinnerRow_new( name, value, lower, upper, 1 ) ); - AddIntSpinnerData( *row.m_spin, importViewer, exportViewer ); - DialogVBox_packRow( GTK_VBOX( vbox ), row.m_row ); - return row.m_row; +QWidget* Dialog::addSpinner( QGridLayout* grid, const char* name, int lower, int upper, const IntImportCallback& importViewer, const IntExportCallback& exportViewer ){ + auto spin = new SpinBox( lower, upper ); + spin->setStepType( QAbstractSpinBox::StepType::AdaptiveDecimalStepType ); + AddIntSpinnerData( *spin, importViewer, exportViewer ); + DialogGrid_packRow( grid, spin, new SpinBoxLabel( name, spin ) ); + return spin; } -GtkWidget* Dialog::addSpinner( GtkWidget* vbox, const char* name, int& data, double value, double lower, double upper ){ - return addSpinner( vbox, name, value, lower, upper, IntImportCallback( IntImportCaller( data ) ), IntExportCallback( IntExportCaller( data ) ) ); +QWidget* Dialog::addSpinner( QGridLayout* grid, const char* name, int& data, int lower, int upper ){ + return addSpinner( grid, name, lower, upper, IntImportCallback( IntImportCaller( data ) ), IntExportCallback( IntExportCaller( data ) ) ); } -GtkWidget* Dialog::addSpinner( GtkWidget* vbox, const char* name, double value, double lower, double upper, const FloatImportCallback& importViewer, const FloatExportCallback& exportViewer ){ - DialogSpinnerRow row( DialogSpinnerRow_new( name, value, lower, upper, 10 ) ); - AddFloatSpinnerData( *row.m_spin, importViewer, exportViewer ); - DialogVBox_packRow( GTK_VBOX( vbox ), row.m_row ); - return row.m_row; +QWidget* Dialog::addSpinner( QGridLayout* grid, const char* name, double lower, double upper, const FloatImportCallback& importViewer, const FloatExportCallback& exportViewer ){ + auto spin = new DoubleSpinBox( lower, upper ); + spin->setStepType( QAbstractSpinBox::StepType::AdaptiveDecimalStepType ); + AddFloatSpinnerData( *spin, importViewer, exportViewer ); + DialogGrid_packRow( grid, spin, new SpinBoxLabel( name, spin ) ); + return spin; +} + +QWidget* Dialog::addSpinner( QGridLayout* grid, const char* name, float& data, double lower, double upper ){ + return addSpinner( grid, name, lower, upper, FloatImportCallback( FloatImportCaller( data ) ), FloatExportCallback( FloatExportCaller( data ) ) ); } diff --git a/radiant/dialog.h b/radiant/dialog.h index 9c05e994..2b68fb20 100644 --- a/radiant/dialog.h +++ b/radiant/dialog.h @@ -91,107 +91,88 @@ struct DLG_DATA virtual void exportData() const = 0; }; -typedef struct _GtkWindow GtkWindow; -typedef struct _GtkToggleButton GtkToggleButton; -typedef struct _GtkRadioButton GtkRadioButton; -typedef struct _GtkSpinButton GtkSpinButton; -typedef struct _GtkComboBox GtkComboBox; -typedef struct _GtkEntry GtkEntry; -typedef struct _GtkAdjustment GtkAdjustment; - template class CallbackDialogData; typedef std::list DialogDataList; +#include +class QGridLayout; +class QCheckBox; +class QComboBox; +class QSlider; +class QButtonGroup; +class QLineEdit; +class QSpinBox; +class QDoubleSpinBox; + class Dialog { - GtkWindow* m_window; + QDialog* m_window{}; DialogDataList m_data; public: - ModalDialog m_modal; - GtkWindow* m_parent; - - Dialog(); virtual ~Dialog(); /*! start modal dialog box you need to use AddModalButton to select eIDOK eIDCANCEL buttons */ - EMessageBoxReturn DoModal(); - void EndModal( EMessageBoxReturn code ); - virtual GtkWindow* BuildDialog() = 0; + QDialog::DialogCode DoModal(); + void EndModal( QDialog::DialogCode code ); + virtual void BuildDialog() = 0; virtual void exportData(); virtual void importData(); virtual void PreModal() { }; - virtual void PostModal( EMessageBoxReturn code ) { }; + virtual void PostModal( QDialog::DialogCode code ) { }; virtual void ShowDlg(); virtual void HideDlg(); - void Create(); + void Create( QWidget *parent ); void Destroy(); - GtkWindow* GetWidget(){ + QDialog* GetWidget(){ return m_window; } - const GtkWindow* GetWidget() const { + const QDialog* GetWidget() const { return m_window; } - GtkWidget* addCheckBox( GtkWidget* vbox, const char* name, const char* flag, const BoolImportCallback& importCallback, const BoolExportCallback& exportCallback ); - GtkWidget* addCheckBox( GtkWidget* vbox, const char* name, const char* flag, bool& data ); - void addCombo( GtkWidget* vbox, const char* name, StringArrayRange values, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); - void addCombo( GtkWidget* vbox, const char* name, int& data, StringArrayRange values ); - void addSlider( GtkWidget* vbox, const char* name, int& data, gboolean draw_value, const char* low, const char* high, double value, double lower, double upper, double step_increment, double page_increment ); - void addSlider( GtkWidget* vbox, const char* name, float& data, gboolean draw_value, const char* low, const char* high, double value, double lower, double upper, double step_increment, double page_increment ); - void addRadio( GtkWidget* vbox, const char* name, StringArrayRange names, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); - void addRadio( GtkWidget* vbox, const char* name, int& data, StringArrayRange names ); - void addRadioIcons( GtkWidget* vbox, const char* name, StringArrayRange icons, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); - void addRadioIcons( GtkWidget* vbox, const char* name, int& data, StringArrayRange icons ); - GtkWidget* addIntEntry( GtkWidget* vbox, const char* name, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); - GtkWidget* addEntry( GtkWidget* vbox, const char* name, int& data ){ - return addIntEntry( vbox, name, IntImportCaller( data ), IntExportCaller( data ) ); + QCheckBox* addCheckBox( QGridLayout *grid, const char* name, const char* flag, const BoolImportCallback& importCallback, const BoolExportCallback& exportCallback ); + QCheckBox* addCheckBox( QGridLayout *grid, const char* name, const char* flag, bool& data ); + QComboBox* addCombo( QGridLayout *grid, const char* name, StringArrayRange values, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); + QComboBox* addCombo( QGridLayout *grid, const char* name, int& data, StringArrayRange values ); + void addSlider( QGridLayout *grid, const char* name, int& data, int lower, int upper, int step_increment, int page_increment ); + void addSlider( QGridLayout *grid, const char* name, float& data, double lower, double upper, double step_increment, double page_increment ); + void addRadio( QGridLayout *grid, const char* name, StringArrayRange names, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); + void addRadio( QGridLayout *grid, const char* name, int& data, StringArrayRange names ); + void addRadioIcons( QGridLayout *grid, const char* name, StringArrayRange icons, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); + void addRadioIcons( QGridLayout *grid, const char* name, int& data, StringArrayRange icons ); + void addTextEntry( QGridLayout *grid, const char* name, const StringImportCallback& importCallback, const StringExportCallback& exportCallback ); + void addEntry( QGridLayout *grid, const char* name, CopiedString& data ){ + addTextEntry( grid, name, StringImportCallback( StringImportCaller( data ) ), StringExportCallback( StringExportCaller( data ) ) ); } - GtkWidget* addSizeEntry( GtkWidget* vbox, const char* name, const SizeImportCallback& importCallback, const SizeExportCallback& exportCallback ); - GtkWidget* addEntry( GtkWidget* vbox, const char* name, std::size_t& data ){ - return addSizeEntry( vbox, name, SizeImportCaller( data ), SizeExportCaller( data ) ); - } - GtkWidget* addFloatEntry( GtkWidget* vbox, const char* name, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ); - GtkWidget* addEntry( GtkWidget* vbox, const char* name, float& data ){ - return addFloatEntry( vbox, name, FloatImportCaller( data ), FloatExportCaller( data ) ); - } - GtkWidget* addTextEntry( GtkWidget* vbox, const char* name, const StringImportCallback& importCallback, const StringExportCallback& exportCallback ); - GtkWidget* addEntry( GtkWidget* vbox, const char* name, CopiedString& data ){ - return addTextEntry( vbox, name, StringImportCallback( StringImportCaller( data ) ), StringExportCallback( StringExportCaller( data ) ) ); - } - GtkWidget* addPathEntry( GtkWidget* vbox, const char* name, bool browse_directory, const StringImportCallback& importCallback, const StringExportCallback& exportCallback ); - GtkWidget* addPathEntry( GtkWidget* vbox, const char* name, CopiedString& data, bool directory ); - GtkWidget* addSpinner( GtkWidget* vbox, const char* name, int& data, double value, double lower, double upper ); - GtkWidget* addSpinner( GtkWidget* vbox, const char* name, double value, double lower, double upper, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); - GtkWidget* addSpinner( GtkWidget* vbox, const char* name, double value, double lower, double upper, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ); + void addPathEntry( QGridLayout *grid, const char* name, bool browse_directory, const StringImportCallback& importCallback, const StringExportCallback& exportCallback ); + void addPathEntry( QGridLayout *grid, const char* name, CopiedString& data, bool directory ); + QWidget* addSpinner( QGridLayout *grid, const char* name, int& data, int lower, int upper ); + QWidget* addSpinner( QGridLayout *grid, const char* name, int lower, int upper, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); + QWidget* addSpinner( QGridLayout *grid, const char* name, double lower, double upper, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ); + QWidget* addSpinner( QGridLayout* grid, const char* name, float& data, double lower, double upper ); protected: - void AddBoolToggleData( GtkToggleButton& object, const BoolImportCallback& importCallback, const BoolExportCallback& exportCallback ); - void AddIntRadioData( GtkRadioButton& object, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); - void AddTextEntryData( GtkEntry& object, const StringImportCallback& importCallback, const StringExportCallback& exportCallback ); - void AddIntEntryData( GtkEntry& object, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); - void AddSizeEntryData( GtkEntry& object, const SizeImportCallback& importCallback, const SizeExportCallback& exportCallback ); - void AddFloatEntryData( GtkEntry& object, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ); - void AddFloatSpinnerData( GtkSpinButton& object, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ); - void AddIntSpinnerData( GtkSpinButton& object, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); - void AddIntAdjustmentData( GtkAdjustment& object, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); - void AddFloatAdjustmentData( GtkAdjustment& object, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ); - void AddIntComboData( GtkComboBox& object, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); + void AddBoolToggleData( QCheckBox& object, const BoolImportCallback& importCallback, const BoolExportCallback& exportCallback ); + void AddIntRadioData( QButtonGroup& object, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); + void AddTextEntryData( QLineEdit& object, const StringImportCallback& importCallback, const StringExportCallback& exportCallback ); + void AddFloatSpinnerData( QDoubleSpinBox& object, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ); + void AddIntSpinnerData( QSpinBox& object, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); + void AddIntSliderData( QSlider& object, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); + void AddFloatSliderData( QSlider& object, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ); + void AddIntComboData( QComboBox& object, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ); - void AddDialogData( GtkToggleButton& object, bool& data ); - void AddDialogData( GtkRadioButton& object, int& data ); - void AddDialogData( GtkEntry& object, CopiedString& data ); - void AddDialogData( GtkEntry& object, int& data ); - void AddDialogData( GtkEntry& object, std::size_t& data ); - void AddDialogData( GtkEntry& object, float& data ); - void AddDialogData( GtkSpinButton& object, float& data ); - void AddDialogData( GtkSpinButton& object, int& data ); - void AddDialogData( GtkAdjustment& object, int& data ); - void AddDialogData( GtkAdjustment& object, float& data ); - void AddDialogData( GtkComboBox& object, int& data ); + void AddDialogData( QCheckBox& object, bool& data ); + void AddDialogData( QButtonGroup& object, int& data ); + void AddDialogData( QLineEdit& object, CopiedString& data ); + void AddDialogData( QDoubleSpinBox& object, float& data ); + void AddDialogData( QSpinBox& object, int& data ); + void AddDialogData( QSlider& object, int& data ); + void AddDialogData( QSlider& object, float& data ); + void AddDialogData( QComboBox& object, int& data ); }; diff --git a/radiant/entity.cpp b/radiant/entity.cpp index 2128b275..e8ff6239 100644 --- a/radiant/entity.cpp +++ b/radiant/entity.cpp @@ -52,11 +52,7 @@ struct entity_globals_t { - Vector3 color_entity; - - entity_globals_t() : - color_entity( 0.0f, 0.0f, 0.0f ){ - } + Vector3 color_entity = { 0.0f, 0.0f, 0.0f }; }; entity_globals_t g_entity_globals; @@ -384,13 +380,13 @@ int g_iLastLightIntensity; void Entity_createFromSelection( const char* name, const Vector3& origin ){ #if 0 if ( string_equal_nocase( name, "worldspawn" ) ) { - gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), "Can't create an entity with worldspawn.", "info" ); + qt_MessageBox( MainFrame_getWindow(), "Can't create an entity with worldspawn.", "info" ); return; } #else const scene::Node* world_node = Map_FindWorldspawn( g_map ); if ( world_node && string_equal( name, "worldspawn" ) ) { -// GlobalRadiant().m_pfnMessageBox( GTK_WIDGET( MainFrame_getWindow() ), "There's already a worldspawn in your map!", "Info", eMB_OK, eMB_ICONDEFAULT ); +// GlobalRadiant().m_pfnMessageBox( MainFrame_getWindow(), "There's already a worldspawn in your map!", "Info", EMessageBoxType::Info, 0 ); UndoableCommand undo( "ungroupSelectedPrimitives" ); Scene_parentSelectedBrushesToEntity( GlobalSceneGraph(), Map_FindOrInsertWorldspawn( g_map ) ); //=no action, if no worldspawn (but one inserted) (since insertion deselects everything) //Scene_parentSelectedBrushesToEntity( GlobalSceneGraph(), *Map_FindWorldspawn( g_map ) ); = crash, if no worldspawn @@ -468,7 +464,7 @@ void Entity_createFromSelection( const char* name, const Vector3& origin ){ || string_equal_nocase( name, "light_spot" ) ) { int intensity = g_iLastLightIntensity; - if ( DoLightIntensityDlg( &intensity ) == eIDOK ) { + if ( DoLightIntensityDlg( &intensity ) ) { g_iLastLightIntensity = intensity; char buf[30]; sprintf( buf, "255 255 255 %d", intensity ); @@ -480,7 +476,7 @@ void Entity_createFromSelection( const char* name, const Vector3& origin ){ if ( g_pGameDescription->mGameType != "doom3" ) { int intensity = g_iLastLightIntensity; - if ( DoLightIntensityDlg( &intensity ) == eIDOK ) { + if ( DoLightIntensityDlg( &intensity ) ) { g_iLastLightIntensity = intensity; char buf[10]; sprintf( buf, "%d", intensity ); @@ -499,7 +495,7 @@ void Entity_createFromSelection( const char* name, const Vector3& origin ){ } if ( isModel && string_empty( EntityClass_valueForKey( *entityClass, entityClass->miscmodel_key() ) ) ) { // handle set default model key value : no dialog needed - const char* model = misc_model_dialog( GTK_WIDGET( MainFrame_getWindow() ) ); + const char* model = misc_model_dialog( MainFrame_getWindow() ); if ( model != 0 ) { entity->setKeyValue( entityClass->miscmodel_key(), model ); } @@ -571,7 +567,7 @@ void Entity_setColour(){ g_entity_globals.color_entity = rgb; } } - if ( color_dialog( GTK_WIDGET( MainFrame_getWindow() ), g_entity_globals.color_entity ) ) { + if ( color_dialog( MainFrame_getWindow(), g_entity_globals.color_entity ) ) { char buffer[128]; sprintf( buffer, "%g %g %g", g_entity_globals.color_entity[0], g_entity_globals.color_entity[1], @@ -586,7 +582,7 @@ void Entity_setColour(){ } } -const char* misc_model_dialog( GtkWidget* parent, const char* filepath ){ +const char* misc_model_dialog( QWidget* parent, const char* filepath ){ StringOutputStream buffer( 1024 ); if( !string_empty( filepath ) ){ @@ -672,11 +668,11 @@ typedef ReferenceCaller1mGameType == "nexuiz" || g_pGameDescription->mGameType == "q1" ) { - create_menu_item_with_mnemonic( menu, "_KillConnect Entities", "EntitiesKillConnect" ); + create_menu_item_with_mnemonic( menu, "&KillConnect Entities", "EntitiesKillConnect" ); } - create_menu_item_with_mnemonic( menu, "_Move Primitives to Entity", "EntityMovePrimitivesToLast" ); - create_menu_item_with_mnemonic( menu, "_Select Color...", "EntityColorSet" ); - create_menu_item_with_mnemonic( menu, "_Normalize Color", "EntityColorNormalize" ); + create_menu_item_with_mnemonic( menu, "&Move Primitives to Entity", "EntityMovePrimitivesToLast" ); + create_menu_item_with_mnemonic( menu, "&Select Color...", "EntityColorSet" ); + create_menu_item_with_mnemonic( menu, "&Normalize Color", "EntityColorNormalize" ); } void Entity_registerShortcuts(){ @@ -727,12 +723,12 @@ void Entity_registerShortcuts(){ #include "stringio.h" void Entity_Construct(){ - GlobalCommands_insert( "EntityColorSet", FreeCaller(), Accelerator( 'K' ) ); + GlobalCommands_insert( "EntityColorSet", FreeCaller(), QKeySequence( "K" ) ); GlobalCommands_insert( "EntityColorNormalize", FreeCaller() ); - GlobalCommands_insert( "EntitiesConnect", FreeCaller(), Accelerator( 'K', GDK_CONTROL_MASK ) ); + GlobalCommands_insert( "EntitiesConnect", FreeCaller(), QKeySequence( "Ctrl+K" ) ); if ( g_pGameDescription->mGameType == "nexuiz" || g_pGameDescription->mGameType == "q1" ) - GlobalCommands_insert( "EntitiesKillConnect", FreeCaller(), Accelerator( 'K', GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "EntityMovePrimitivesToLast", FreeCaller(), Accelerator( 'M', GDK_CONTROL_MASK ) ); + GlobalCommands_insert( "EntitiesKillConnect", FreeCaller(), QKeySequence( "Shift+K" ) ); + GlobalCommands_insert( "EntityMovePrimitivesToLast", FreeCaller(), QKeySequence( "Ctrl+M" ) ); GlobalCommands_insert( "EntityMovePrimitivesToFirst", FreeCaller() ); GlobalCommands_insert( "EntityUngroup", FreeCaller() ); GlobalCommands_insert( "EntityUngroupPrimitives", FreeCaller() ); diff --git a/radiant/entity.h b/radiant/entity.h index 142e44ea..4522b2dc 100644 --- a/radiant/entity.h +++ b/radiant/entity.h @@ -29,12 +29,10 @@ void Scene_EntitySetKeyValue_Selected( const char* key, const char* value ); void Scene_EntitySetClassname_Selected( const char* classname ); -typedef struct _GtkWidget GtkWidget; -const char* misc_model_dialog( GtkWidget* parent, const char* filepath = "" ); +const char* misc_model_dialog( class QWidget* parent, const char* filepath = "" ); void Entity_setColour(); -typedef struct _GtkMenu GtkMenu; -void Entity_constructMenu( GtkMenu* menu ); +void Entity_constructMenu( class QMenu* menu ); void Entity_registerShortcuts(); diff --git a/radiant/entityinspector.cpp b/radiant/entityinspector.cpp index ff4a872c..8ada6300 100644 --- a/radiant/entityinspector.cpp +++ b/radiant/entityinspector.cpp @@ -32,8 +32,26 @@ #include #include -#include -#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "os/path.h" #include "eclasslib.h" @@ -50,9 +68,7 @@ #include "gtkutil/filechooser.h" #include "gtkutil/messagebox.h" #include "gtkutil/nonmodal.h" -#include "gtkutil/button.h" #include "gtkutil/entry.h" -#include "gtkutil/container.h" #include "qe3.h" #include "gtkmisc.h" @@ -64,13 +80,6 @@ #include "select.h" -GtkEntry* numeric_entry_new(){ - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_widget_set_size_request( GTK_WIDGET( entry ), 64, -1 ); - return entry; -} - namespace { typedef std::map KeyValues; @@ -104,54 +113,37 @@ void Scene_EntitySetKeyValue_Selected_Undoable( const char* key, const char* val class EntityAttribute { public: - virtual GtkWidget* getWidget() const = 0; + virtual QWidget* getWidget() const = 0; virtual void update() = 0; virtual void release() = 0; }; class BooleanAttribute final : public EntityAttribute { - CopiedString m_key; - GtkCheckButton* m_check; - - static gboolean toggled( GtkWidget *widget, BooleanAttribute* self ){ - self->apply(); - return FALSE; - } + const CopiedString m_key; + QCheckBox* m_check; public: BooleanAttribute( const char* key ) : m_key( key ), - m_check( 0 ){ - GtkCheckButton* check = GTK_CHECK_BUTTON( gtk_check_button_new() ); - gtk_widget_show( GTK_WIDGET( check ) ); - - m_check = check; - - guint handler = g_signal_connect( G_OBJECT( check ), "toggled", G_CALLBACK( toggled ), this ); - g_object_set_data( G_OBJECT( check ), "handler", gint_to_pointer( handler ) ); - + m_check( new QCheckBox ) + { + QObject::connect( m_check, &QAbstractButton::clicked, [this](){ apply(); } ); update(); } - GtkWidget* getWidget() const { - return GTK_WIDGET( m_check ); + QWidget* getWidget() const override { + return m_check; } - void release(){ + void release() override { delete this; } void apply(){ - Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( m_check ) ) ? "1" : "" ); + Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), m_check->isChecked() ? "1" : "" ); } typedef MemberCaller ApplyCaller; - void update(){ + void update() override { const char* value = SelectedEntity_getValueForKey( m_key.c_str() ); - if ( !string_empty( value ) ) { - toggle_button_set_active_no_signal( GTK_TOGGLE_BUTTON( m_check ), atoi( value ) != 0 ); - } - else - { - toggle_button_set_active_no_signal( GTK_TOGGLE_BUTTON( m_check ), false ); - } + m_check->setChecked( atoi( value ) != 0 ); // atoi( empty ) is also 0 } typedef MemberCaller UpdateCaller; }; @@ -159,43 +151,32 @@ public: class StringAttribute : public EntityAttribute { - CopiedString m_key; - GtkEntry* m_entry; - NonModalEntry m_nonModal; + const CopiedString m_key; + NonModalEntry *m_entry; public: StringAttribute( const char* key ) : m_key( key ), - m_entry( 0 ), - m_nonModal( ApplyCaller( *this ), UpdateCaller( *this ) ){ - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 ); - - m_entry = entry; - m_nonModal.connect( m_entry ); + m_entry( new NonModalEntry( ApplyCaller( *this ), UpdateCaller( *this ) ) ){ } virtual ~StringAttribute() = default; - GtkWidget* getWidget() const { - return GTK_WIDGET( m_entry ); + QWidget* getWidget() const override { + return m_entry; } - GtkEntry* getEntry() const { + QLineEdit* getEntry() const { return m_entry; } - void release(){ + void release() override { delete this; } void apply(){ - StringOutputStream value( 64 ); - value << gtk_entry_get_text( m_entry ); - Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), value.c_str() ); + const auto value = m_entry->text().toLatin1(); + Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), value.constData() ); } typedef MemberCaller ApplyCaller; - void update(){ - StringOutputStream value( 64 ); - value << SelectedEntity_getValueForKey( m_key.c_str() ); - gtk_entry_set_text( m_entry, value.c_str() ); + void update() override { + m_entry->setText( SelectedEntity_getValueForKey( m_key.c_str() ) ); } typedef MemberCaller UpdateCaller; }; @@ -222,90 +203,78 @@ public: class ColorAttribute final : public EntityAttribute { - CopiedString m_key; - BrowsedPathEntry m_entry; - NonModalEntry m_nonModal; + const CopiedString m_key; + NonModalEntry *m_entry; public: ColorAttribute( const char* key ) : m_key( key ), - m_entry( BrowseCaller( *this ) ), - m_nonModal( ApplyCaller( *this ), UpdateCaller( *this ) ){ - m_nonModal.connect( m_entry.m_entry.m_entry ); + m_entry( new NonModalEntry( ApplyCaller( *this ), UpdateCaller( *this ) ) ){ + auto button = m_entry->addAction( QApplication::style()->standardIcon( QStyle::SP_DialogOkButton ), QLineEdit::ActionPosition::TrailingPosition ); + QObject::connect( button, &QAction::triggered, [this](){ browse(); } ); } - void release(){ + void release() override { delete this; } - GtkWidget* getWidget() const { - return GTK_WIDGET( m_entry.m_entry.m_frame ); + QWidget* getWidget() const override { + return m_entry; } void apply(){ - StringOutputStream value( 64 ); - value << gtk_entry_get_text( GTK_ENTRY( m_entry.m_entry.m_entry ) ); - Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), value.c_str() ); + Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), m_entry->text().toLatin1().constData() ); } typedef MemberCaller ApplyCaller; - void update(){ - StringOutputStream value( 64 ); - value << SelectedEntity_getValueForKey( m_key.c_str() ); - gtk_entry_set_text( GTK_ENTRY( m_entry.m_entry.m_entry ), value.c_str() ); + void update() override { + m_entry->setText( SelectedEntity_getValueForKey( m_key.c_str() ) ); } typedef MemberCaller UpdateCaller; - void browse( const BrowsedPathEntry::SetPathCallback& setPath ){ /* hijack BrowsedPathEntry to call colour chooser */ + void browse(){ Vector3 color( 1, 1, 1 ); - string_parse_vector3( gtk_entry_get_text( GTK_ENTRY( m_entry.m_entry.m_entry ) ), color ); - if( color_dialog( gtk_widget_get_toplevel( GTK_WIDGET( m_entry.m_entry.m_frame ) ), color ) ){ + string_parse_vector3( m_entry->text().toLatin1().constData(), color ); + if( color_dialog( m_entry->window(), color ) ){ char buffer[64]; sprintf( buffer, "%g %g %g", color[0], color[1], color[2] ); - gtk_entry_set_text( GTK_ENTRY( m_entry.m_entry.m_entry ), buffer ); + m_entry->setText( buffer ); apply(); } } - typedef MemberCaller1 BrowseCaller; }; class ModelAttribute final : public EntityAttribute { - CopiedString m_key; - BrowsedPathEntry m_entry; - NonModalEntry m_nonModal; + const CopiedString m_key; + NonModalEntry *m_entry; public: ModelAttribute( const char* key ) : m_key( key ), - m_entry( BrowseCaller( *this ) ), - m_nonModal( ApplyCaller( *this ), UpdateCaller( *this ) ){ - m_nonModal.connect( m_entry.m_entry.m_entry ); + m_entry( new NonModalEntry( ApplyCaller( *this ), UpdateCaller( *this ) ) ){ + auto button = m_entry->addAction( QApplication::style()->standardIcon( QStyle::SP_FileDialogStart ), QLineEdit::ActionPosition::TrailingPosition ); + QObject::connect( button, &QAction::triggered, [this](){ browse(); } ); } - void release(){ + void release() override { delete this; } - GtkWidget* getWidget() const { - return GTK_WIDGET( m_entry.m_entry.m_frame ); + QWidget* getWidget() const override { + return m_entry; } void apply(){ - StringOutputStream value( 64 ); - value << gtk_entry_get_text( GTK_ENTRY( m_entry.m_entry.m_entry ) ); - Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), value.c_str() ); + Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), m_entry->text().toLatin1().constData() ); } typedef MemberCaller ApplyCaller; - void update(){ - StringOutputStream value( 64 ); - value << SelectedEntity_getValueForKey( m_key.c_str() ); - gtk_entry_set_text( GTK_ENTRY( m_entry.m_entry.m_entry ), value.c_str() ); + void update() override { + m_entry->setText( SelectedEntity_getValueForKey( m_key.c_str() ) ); } typedef MemberCaller UpdateCaller; - void browse( const BrowsedPathEntry::SetPathCallback& setPath ){ - const char *filename = misc_model_dialog( gtk_widget_get_toplevel( GTK_WIDGET( m_entry.m_entry.m_frame ) ), gtk_entry_get_text( GTK_ENTRY( m_entry.m_entry.m_entry ) ) ); + void browse(){ + const char *filename = misc_model_dialog( m_entry->window(), m_entry->text().toLatin1().constData() ); if ( filename != 0 ) { - setPath( filename ); + m_entry->setText( filename ); apply(); } } - typedef MemberCaller1 BrowseCaller; }; -const char* browse_sound( GtkWidget* parent, const char* filepath ){ +const char* browse_sound( QWidget* parent, const char* filepath ){ StringOutputStream buffer( 1024 ); if( !string_empty( filepath ) ){ @@ -336,43 +305,37 @@ const char* browse_sound( GtkWidget* parent, const char* filepath ){ class SoundAttribute final : public EntityAttribute { - CopiedString m_key; - BrowsedPathEntry m_entry; - NonModalEntry m_nonModal; + const CopiedString m_key; + NonModalEntry *m_entry; public: SoundAttribute( const char* key ) : m_key( key ), - m_entry( BrowseCaller( *this ) ), - m_nonModal( ApplyCaller( *this ), UpdateCaller( *this ) ){ - m_nonModal.connect( m_entry.m_entry.m_entry ); + m_entry( new NonModalEntry( ApplyCaller( *this ), UpdateCaller( *this ) ) ){ + auto button = m_entry->addAction( QApplication::style()->standardIcon( QStyle::SP_MediaVolume ), QLineEdit::ActionPosition::TrailingPosition ); + QObject::connect( button, &QAction::triggered, [this](){ browse(); } ); } - void release(){ + void release() override { delete this; } - GtkWidget* getWidget() const { - return GTK_WIDGET( m_entry.m_entry.m_frame ); + QWidget* getWidget() const override { + return m_entry; } void apply(){ - StringOutputStream value( 64 ); - value << gtk_entry_get_text( GTK_ENTRY( m_entry.m_entry.m_entry ) ); - Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), value.c_str() ); + Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), m_entry->text().toLatin1().constData() ); } typedef MemberCaller ApplyCaller; - void update(){ - StringOutputStream value( 64 ); - value << SelectedEntity_getValueForKey( m_key.c_str() ); - gtk_entry_set_text( GTK_ENTRY( m_entry.m_entry.m_entry ), value.c_str() ); + void update() override { + m_entry->setText( SelectedEntity_getValueForKey( m_key.c_str() ) ); } typedef MemberCaller UpdateCaller; - void browse( const BrowsedPathEntry::SetPathCallback& setPath ){ - const char *filename = browse_sound( gtk_widget_get_toplevel( GTK_WIDGET( m_entry.m_entry.m_frame ) ), gtk_entry_get_text( GTK_ENTRY( m_entry.m_entry.m_entry ) ) ); + void browse(){ + const char *filename = browse_sound( m_entry->window(), m_entry->text().toLatin1().constData() ); if ( filename != 0 ) { - setPath( filename ); + m_entry->setText( filename ); apply(); } } - typedef MemberCaller1 BrowseCaller; }; @@ -384,46 +347,45 @@ class CamAnglesButton { typedef Callback1 ApplyCallback; ApplyCallback m_apply; - static void click( GtkWidget* widget, CamAnglesButton* self ){ - Vector3 angles( Camera_getAngles( *g_pParentWnd->GetCamWnd() ) ); - if( !string_equal( GlobalRadiant().getRequiredGameDescriptionKeyValue( "entities" ), "quake" ) ) /* stupid quake bug */ - angles[0] = -angles[0]; - self->m_apply( angles ); - } public: - GtkButton* m_button; - CamAnglesButton( const ApplyCallback& apply ) : m_apply( apply ){ - m_button = GTK_BUTTON( gtk_button_new_with_label( "<-cam" ) ); - gtk_widget_show( GTK_WIDGET( m_button ) ); - g_signal_connect( G_OBJECT( m_button ), "clicked", G_CALLBACK( click ), this ); + QPushButton* m_button; + CamAnglesButton( const ApplyCallback& apply ) : m_apply( apply ), m_button( new QPushButton( "<-cam" ) ){ + QObject::connect( m_button, &QAbstractButton::clicked, [this](){ + Vector3 angles( Camera_getAngles( *g_pParentWnd->GetCamWnd() ) ); + if( !string_equal( GlobalRadiant().getRequiredGameDescriptionKeyValue( "entities" ), "quake" ) ) /* stupid quake bug */ + angles[0] = -angles[0]; + m_apply( angles ); + } ); } }; +inline QWidget *new_container_widget(){ + QWidget *w = new QWidget; + auto l = new QHBoxLayout( w ); + l->setContentsMargins( 0, 0, 0, 0 ); + return w; +} + class AngleAttribute final : public EntityAttribute { - CopiedString m_key; - GtkEntry* m_entry; - NonModalEntry m_nonModal; + const CopiedString m_key; + NonModalEntry* m_entry; CamAnglesButton m_butt; - GtkBox* m_hbox; + QWidget *m_hbox; public: AngleAttribute( const char* key ) : m_key( key ), - m_nonModal( ApplyCaller( *this ), UpdateCaller( *this ) ), - m_butt( ApplyVecCaller( *this ) ){ - m_entry = numeric_entry_new(); - m_nonModal.connect( m_entry ); - - m_hbox = GTK_BOX( gtk_hbox_new( FALSE, 4 ) ); - gtk_widget_show( GTK_WIDGET( m_hbox ) ); - gtk_box_pack_start( m_hbox, GTK_WIDGET( m_entry ), TRUE, TRUE, 0 ); - gtk_box_pack_start( m_hbox, GTK_WIDGET( m_butt.m_button ), FALSE, FALSE, 0 ); + m_entry( new NonModalEntry( ApplyCaller( *this ), UpdateCaller( *this ) ) ), + m_butt( ApplyVecCaller( *this ) ), + m_hbox( new_container_widget() ){ + m_hbox->layout()->addWidget( m_entry ); + m_hbox->layout()->addWidget( m_butt.m_button ); } - void release(){ + void release() override { delete this; } - GtkWidget* getWidget() const { - return GTK_WIDGET( m_hbox ); + QWidget* getWidget() const override { + return m_hbox; } void apply(){ StringOutputStream angle( 32 ); @@ -432,16 +394,16 @@ public: } typedef MemberCaller ApplyCaller; - void update(){ + void update() override { const char* value = SelectedEntity_getValueForKey( m_key.c_str() ); if ( !string_empty( value ) ) { StringOutputStream angle( 32 ); angle << angle_normalised( atof( value ) ); - gtk_entry_set_text( m_entry, angle.c_str() ); + m_entry->setText( angle.c_str() ); } else { - gtk_entry_set_text( m_entry, "0" ); + m_entry->setText( "0" ); } } typedef MemberCaller UpdateCaller; @@ -455,38 +417,29 @@ public: class DirectionAttribute final : public EntityAttribute { - CopiedString m_key; - GtkEntry* m_entry; - NonModalEntry m_nonModal; + const CopiedString m_key; + NonModalEntry* m_entry; RadioHBox m_radio; - NonModalRadio m_nonModalRadio; CamAnglesButton m_butt; - GtkHBox* m_hbox; + QWidget* m_hbox; static constexpr const char *const buttons[] = { "up", "down", "yaw" }; public: DirectionAttribute( const char* key ) : m_key( key ), - m_nonModal( ApplyCaller( *this ), UpdateCaller( *this ) ), + m_entry( new NonModalEntry( ApplyCaller( *this ), UpdateCaller( *this ) ) ), m_radio( RadioHBox_new( StringArrayRange( buttons ) ) ), - m_nonModalRadio( ApplyRadioCaller( *this ) ), - m_butt( ApplyVecCaller( *this ) ){ - m_entry = numeric_entry_new(); - m_nonModal.connect( m_entry ); - - m_nonModalRadio.connect( m_radio.m_radio ); - - m_hbox = GTK_HBOX( gtk_hbox_new( FALSE, 4 ) ); - gtk_widget_show( GTK_WIDGET( m_hbox ) ); - - gtk_box_pack_start( GTK_BOX( m_hbox ), GTK_WIDGET( m_radio.m_hbox ), TRUE, TRUE, 0 ); - gtk_box_pack_start( GTK_BOX( m_hbox ), GTK_WIDGET( m_entry ), TRUE, TRUE, 0 ); - gtk_box_pack_start( GTK_BOX( m_hbox ), GTK_WIDGET( m_butt.m_button ), FALSE, FALSE, 0 ); + m_butt( ApplyVecCaller( *this ) ), + m_hbox( new_container_widget() ){ + static_cast( m_hbox->layout() )->addLayout( m_radio.m_hbox ); + m_hbox->layout()->addWidget( m_entry ); + m_hbox->layout()->addWidget( m_butt.m_button ); + QObject::connect( m_radio.m_radio, &QButtonGroup::idClicked, ApplyRadioCaller( *this ) ); } - void release(){ + void release() override { delete this; } - GtkWidget* getWidget() const { - return GTK_WIDGET( m_hbox ); + QWidget* getWidget() const override { + return m_hbox; } void apply(){ StringOutputStream angle( 32 ); @@ -495,50 +448,49 @@ public: } typedef MemberCaller ApplyCaller; - void update(){ + void update() override { const char* value = SelectedEntity_getValueForKey( m_key.c_str() ); if ( !string_empty( value ) ) { - float f = float(atof( value ) ); + const float f = atof( value ); if ( f == -1 ) { - gtk_widget_set_sensitive( GTK_WIDGET( m_entry ), FALSE ); - radio_button_set_active_no_signal( m_radio.m_radio, 0 ); - gtk_entry_set_text( m_entry, "" ); + m_entry->setEnabled( false ); + m_radio.m_radio->button( 0 )->setChecked( true ); + m_entry->clear(); } else if ( f == -2 ) { - gtk_widget_set_sensitive( GTK_WIDGET( m_entry ), FALSE ); - radio_button_set_active_no_signal( m_radio.m_radio, 1 ); - gtk_entry_set_text( m_entry, "" ); + m_entry->setEnabled( false ); + m_radio.m_radio->button( 1 )->setChecked( true ); + m_entry->clear(); } else { - gtk_widget_set_sensitive( GTK_WIDGET( m_entry ), TRUE ); - radio_button_set_active_no_signal( m_radio.m_radio, 2 ); + m_entry->setEnabled( true ); + m_radio.m_radio->button( 2 )->setChecked( true ); StringOutputStream angle( 32 ); angle << angle_normalised( f ); - gtk_entry_set_text( m_entry, angle.c_str() ); + m_entry->setText( angle.c_str() ); } } else { - radio_button_set_active_no_signal( m_radio.m_radio, 2 ); - gtk_entry_set_text( m_entry, "0" ); + m_radio.m_radio->button( 2 )->setChecked( true ); + m_entry->setText( "0" ); } } typedef MemberCaller UpdateCaller; - void applyRadio(){ - int index = radio_button_get_active( m_radio.m_radio ); - if ( index == 0 ) { + void applyRadio( int id ){ + if ( id == 0 ) { Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), "-1" ); } - else if ( index == 1 ) { + else if ( id == 1 ) { Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), "-2" ); } - else if ( index == 2 ) { + else if ( id == 2 ) { apply(); } } - typedef MemberCaller ApplyRadioCaller; + typedef MemberCaller1 ApplyRadioCaller; void apply( const Vector3& angles ){ entry_set_float( m_entry, angles[1] ); @@ -551,52 +503,34 @@ public: class AnglesEntry { public: - GtkEntry* m_roll; - GtkEntry* m_pitch; - GtkEntry* m_yaw; + QLineEdit* m_roll; + QLineEdit* m_pitch; + QLineEdit* m_yaw; AnglesEntry() : m_roll( 0 ), m_pitch( 0 ), m_yaw( 0 ){ } }; class AnglesAttribute final : public EntityAttribute { - CopiedString m_key; + const CopiedString m_key; AnglesEntry m_angles; - NonModalEntry m_nonModal; CamAnglesButton m_butt; - GtkBox* m_hbox; + QWidget* m_hbox; public: AnglesAttribute( const char* key ) : m_key( key ), - m_nonModal( ApplyCaller( *this ), UpdateCaller( *this ) ), - m_butt( ApplyVecCaller( *this ) ){ - m_hbox = GTK_BOX( gtk_hbox_new( FALSE, 4 ) ); - gtk_widget_show( GTK_WIDGET( m_hbox ) ); - { - GtkEntry* entry = numeric_entry_new(); - gtk_box_pack_start( m_hbox, GTK_WIDGET( entry ), TRUE, TRUE, 0 ); - m_angles.m_pitch = entry; - m_nonModal.connect( m_angles.m_pitch ); - } - { - GtkEntry* entry = numeric_entry_new(); - gtk_box_pack_start( m_hbox, GTK_WIDGET( entry ), TRUE, TRUE, 0 ); - m_angles.m_yaw = entry; - m_nonModal.connect( m_angles.m_yaw ); - } - { - GtkEntry* entry = numeric_entry_new(); - gtk_box_pack_start( m_hbox, GTK_WIDGET( entry ), TRUE, TRUE, 0 ); - m_angles.m_roll = entry; - m_nonModal.connect( m_angles.m_roll ); - } - gtk_box_pack_start( m_hbox, GTK_WIDGET( m_butt.m_button ), FALSE, FALSE, 0 ); + m_butt( ApplyVecCaller( *this ) ), + m_hbox( new_container_widget() ){ + m_hbox->layout()->addWidget( m_angles.m_pitch = new NonModalEntry( ApplyCaller( *this ), UpdateCaller( *this ) ) ); + m_hbox->layout()->addWidget( m_angles.m_yaw = new NonModalEntry( ApplyCaller( *this ), UpdateCaller( *this ) ) ); + m_hbox->layout()->addWidget( m_angles.m_roll = new NonModalEntry( ApplyCaller( *this ), UpdateCaller( *this ) ) ); + m_hbox->layout()->addWidget( m_butt.m_button ); } - void release(){ + void release() override { delete this; } - GtkWidget* getWidget() const { - return GTK_WIDGET( m_hbox ); + QWidget* getWidget() const override { + return m_hbox; } void apply(){ StringOutputStream angles( 64 ); @@ -607,7 +541,7 @@ public: } typedef MemberCaller ApplyCaller; - void update(){ + void update() override { StringOutputStream angle( 32 ); const char* value = SelectedEntity_getValueForKey( m_key.c_str() ); if ( !string_empty( value ) ) { @@ -616,23 +550,20 @@ public: pitch_yaw_roll = DoubleVector3( 0, 0, 0 ); } - angle << angle_normalised( pitch_yaw_roll.x() ); - gtk_entry_set_text( m_angles.m_pitch, angle.c_str() ); - angle.clear(); + angle( angle_normalised( pitch_yaw_roll.x() ) ); + m_angles.m_pitch->setText( angle.c_str() ); - angle << angle_normalised( pitch_yaw_roll.y() ); - gtk_entry_set_text( m_angles.m_yaw, angle.c_str() ); - angle.clear(); + angle( angle_normalised( pitch_yaw_roll.y() ) ); + m_angles.m_yaw->setText( angle.c_str() ); - angle << angle_normalised( pitch_yaw_roll.z() ); - gtk_entry_set_text( m_angles.m_roll, angle.c_str() ); - angle.clear(); + angle( angle_normalised( pitch_yaw_roll.z() ) ); + m_angles.m_roll->setText( angle.c_str() ); } else { - gtk_entry_set_text( m_angles.m_pitch, "0" ); - gtk_entry_set_text( m_angles.m_yaw, "0" ); - gtk_entry_set_text( m_angles.m_roll, "0" ); + m_angles.m_pitch->setText( "0" ); + m_angles.m_yaw->setText( "0" ); + m_angles.m_roll->setText( "0" ); } } typedef MemberCaller UpdateCaller; @@ -649,49 +580,31 @@ public: class Vector3Entry { public: - GtkEntry* m_x; - GtkEntry* m_y; - GtkEntry* m_z; + QLineEdit* m_x; + QLineEdit* m_y; + QLineEdit* m_z; Vector3Entry() : m_x( 0 ), m_y( 0 ), m_z( 0 ){ } }; class Vector3Attribute final : public EntityAttribute { - CopiedString m_key; + const CopiedString m_key; Vector3Entry m_vector3; - NonModalEntry m_nonModal; - GtkBox* m_hbox; + QWidget* m_hbox; public: Vector3Attribute( const char* key ) : m_key( key ), - m_nonModal( ApplyCaller( *this ), UpdateCaller( *this ) ){ - m_hbox = GTK_BOX( gtk_hbox_new( TRUE, 4 ) ); - gtk_widget_show( GTK_WIDGET( m_hbox ) ); - { - GtkEntry* entry = numeric_entry_new(); - gtk_box_pack_start( m_hbox, GTK_WIDGET( entry ), TRUE, TRUE, 0 ); - m_vector3.m_x = entry; - m_nonModal.connect( m_vector3.m_x ); - } - { - GtkEntry* entry = numeric_entry_new(); - gtk_box_pack_start( m_hbox, GTK_WIDGET( entry ), TRUE, TRUE, 0 ); - m_vector3.m_y = entry; - m_nonModal.connect( m_vector3.m_y ); - } - { - GtkEntry* entry = numeric_entry_new(); - gtk_box_pack_start( m_hbox, GTK_WIDGET( entry ), TRUE, TRUE, 0 ); - m_vector3.m_z = entry; - m_nonModal.connect( m_vector3.m_z ); - } + m_hbox( new_container_widget() ){ + m_hbox->layout()->addWidget( m_vector3.m_x = new NonModalEntry( ApplyCaller( *this ), UpdateCaller( *this ) ) ); + m_hbox->layout()->addWidget( m_vector3.m_y = new NonModalEntry( ApplyCaller( *this ), UpdateCaller( *this ) ) ); + m_hbox->layout()->addWidget( m_vector3.m_z = new NonModalEntry( ApplyCaller( *this ), UpdateCaller( *this ) ) ); } - void release(){ + void release() override { delete this; } - GtkWidget* getWidget() const { - return GTK_WIDGET( m_hbox ); + QWidget* getWidget() const override { + return m_hbox; } void apply(){ StringOutputStream vector3( 64 ); @@ -702,7 +615,7 @@ public: } typedef MemberCaller ApplyCaller; - void update(){ + void update() override { StringOutputStream buffer( 32 ); const char* value = SelectedEntity_getValueForKey( m_key.c_str() ); if ( !string_empty( value ) ) { @@ -711,95 +624,62 @@ public: x_y_z = DoubleVector3( 0, 0, 0 ); } - buffer << x_y_z.x(); - gtk_entry_set_text( m_vector3.m_x, buffer.c_str() ); - buffer.clear(); + buffer( x_y_z.x() ); + m_vector3.m_x->setText( buffer.c_str() ); - buffer << x_y_z.y(); - gtk_entry_set_text( m_vector3.m_y, buffer.c_str() ); - buffer.clear(); + buffer( x_y_z.y() ); + m_vector3.m_y->setText( buffer.c_str() ); - buffer << x_y_z.z(); - gtk_entry_set_text( m_vector3.m_z, buffer.c_str() ); - buffer.clear(); + buffer( x_y_z.z() ); + m_vector3.m_z->setText( buffer.c_str() ); } else { - gtk_entry_set_text( m_vector3.m_x, "0" ); - gtk_entry_set_text( m_vector3.m_y, "0" ); - gtk_entry_set_text( m_vector3.m_z, "0" ); + m_vector3.m_x->setText( "0" ); + m_vector3.m_y->setText( "0" ); + m_vector3.m_z->setText( "0" ); } } typedef MemberCaller UpdateCaller; }; -class NonModalComboBox -{ - Callback m_changed; - guint m_changedHandler; - - static gboolean changed( GtkComboBox *widget, NonModalComboBox* self ){ - self->m_changed(); - return FALSE; - } - -public: - NonModalComboBox( const Callback& changed ) : m_changed( changed ), m_changedHandler( 0 ){ - } - void connect( GtkComboBox* combo ){ - m_changedHandler = g_signal_connect( G_OBJECT( combo ), "changed", G_CALLBACK( changed ), this ); - } - void setActive( GtkComboBox* combo, int value ){ - g_signal_handler_disconnect( G_OBJECT( combo ), m_changedHandler ); - gtk_combo_box_set_active( combo, value ); - connect( combo ); - } -}; - class ListAttribute final : public EntityAttribute { - CopiedString m_key; - GtkComboBox* m_combo; - NonModalComboBox m_nonModal; + const CopiedString m_key; + QComboBox* m_combo; const ListAttributeType& m_type; public: ListAttribute( const char* key, const ListAttributeType& type ) : m_key( key ), - m_combo( 0 ), - m_nonModal( ApplyCaller( *this ) ), + m_combo( new QComboBox ), m_type( type ){ - GtkWidget* combo = gtk_combo_box_text_new(); - - for ( ListAttributeType::const_iterator i = type.begin(); i != type.end(); ++i ) + for ( const auto&[ name, value ] : type ) { - gtk_combo_box_text_append_text( GTK_COMBO_BOX_TEXT( combo ), ( *i ).first.c_str() ); + m_combo->addItem( name.c_str() ); } - - gtk_widget_show( combo ); - m_nonModal.connect( GTK_COMBO_BOX( combo ) ); - - m_combo = GTK_COMBO_BOX( combo ); + QObject::connect( m_combo, QOverload::of( &QComboBox::activated ), ApplyCaller( *this ) ); } - void release(){ + void release() override { delete this; } - GtkWidget* getWidget() const { - return GTK_WIDGET( m_combo ); + QWidget* getWidget() const override { + return m_combo; } void apply(){ - Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), m_type[gtk_combo_box_get_active( m_combo )].second.c_str() ); + // looks safe to assume that user actions wont make m_combo->currentIndex() -1 + Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), m_type[m_combo->currentIndex()].second.c_str() ); } typedef MemberCaller ApplyCaller; - void update(){ + void update() override { const char* value = SelectedEntity_getValueForKey( m_key.c_str() ); ListAttributeType::const_iterator i = m_type.findValue( value ); if ( i != m_type.end() ) { - m_nonModal.setActive( m_combo, static_cast( std::distance( m_type.begin(), i ) ) ); + m_combo->setCurrentIndex( static_cast( std::distance( m_type.begin(), i ) ) ); } else { - m_nonModal.setActive( m_combo, 0 ); + m_combo->setCurrentIndex( 0 ); } } typedef MemberCaller UpdateCaller; @@ -808,27 +688,19 @@ public: namespace { -GtkWidget* g_entity_split0 = 0; -GtkWidget* g_entity_split1 = 0; -GtkWidget* g_entity_split2 = 0; -int g_entitysplit0_position = 255; -int g_entitysplit1_position = 231; -int g_entitysplit2_position = 57; - bool g_entityInspector_windowConstructed = false; -GtkTreeView* g_entityClassList; -GtkTextView* g_entityClassComment; +QTreeWidget* g_entityClassList; +QTextEdit* g_entityClassComment; -GtkCheckButton* g_entitySpawnflagsCheck[MAX_FLAGS]; +QCheckBox* g_entitySpawnflagsCheck[MAX_FLAGS]; -GtkEntry* g_entityKeyEntry; -GtkEntry* g_entityValueEntry; +QLineEdit* g_entityKeyEntry; +QLineEdit* g_entityValueEntry; -GtkToggleButton* g_focusToggleButton; +QToolButton* g_focusToggleButton; -GtkListStore* g_entlist_store; -GtkListStore* g_entprops_store; +QTreeWidget* g_entprops_store; const EntityClass* g_current_flags = 0; const EntityClass* g_current_comment = 0; const EntityClass* g_current_attributes = 0; @@ -839,17 +711,17 @@ int g_spawnflag_count; int spawn_table[MAX_FLAGS]; // we change the layout depending on how many spawn flags we need to display // the table is a 4x4 in which we need to put the comment box g_entityClassComment and the spawn flags.. -GtkTable* g_spawnflagsTable; +QGridLayout* g_spawnflagsTable; -GtkVBox* g_attributeBox = 0; +QGridLayout* g_attributeBox = nullptr; typedef std::vector EntityAttributes; EntityAttributes g_entityAttributes; } void GlobalEntityAttributes_clear(){ - for ( EntityAttributes::iterator i = g_entityAttributes.begin(); i != g_entityAttributes.end(); ++i ) + for ( EntityAttribute* attr : g_entityAttributes ) { - ( *i )->release(); + attr->release(); } g_entityAttributes.clear(); } @@ -912,26 +784,28 @@ const char* keyvalues_valueforkey( KeyValues& keyvalues, const char* key ){ return ""; } +// required to store EntityClass* in QVariant +Q_DECLARE_METATYPE( EntityClass* ) class EntityClassListStoreAppend : public EntityClassVisitor { - GtkListStore* store; + QTreeWidget* tree; public: - EntityClassListStoreAppend( GtkListStore* store_ ) : store( store_ ){ + EntityClassListStoreAppend( QTreeWidget* tree_ ) : tree( tree_ ){ } void visit( EntityClass* e ){ - GtkTreeIter iter; - gtk_list_store_append( store, &iter ); - gtk_list_store_set( store, &iter, 0, e->name(), 1, e, -1 ); + auto item = new QTreeWidgetItem( tree ); + item->setData( 0, Qt::ItemDataRole::DisplayRole, e->name() ); + item->setData( 0, Qt::ItemDataRole::UserRole, QVariant::fromValue( e ) ); } }; void EntityClassList_fill(){ - EntityClassListStoreAppend append( g_entlist_store ); + EntityClassListStoreAppend append( g_entityClassList ); GlobalEntityClassManager().forEach( append ); } void EntityClassList_clear(){ - gtk_list_store_clear( g_entlist_store ); + g_entityClassList->clear(); } void SetComment( EntityClass* eclass ){ @@ -940,142 +814,75 @@ void SetComment( EntityClass* eclass ){ } g_current_comment = eclass; + g_entityClassComment->setPlainText( eclass->comments() ); - GtkTextBuffer* buffer = gtk_text_view_get_buffer( g_entityClassComment ); - //gtk_text_buffer_set_text( buffer, eclass->comments(), -1 ); - const char* comment = eclass->comments(), *c; - int offset = 0, pattern_start = -1, spaces = 0; + { // Catch patterns like "\nstuff :" used to describe keys and spawnflags, and make them bold for readability. + QTextCharFormat format; + format.setFontWeight( QFont::Weight::Bold ); - gtk_text_buffer_set_text( buffer, comment, -1 ); - - // Catch patterns like "\nstuff :" used to describe keys and spawnflags, and make them bold for readability. - - for( c = comment; *c; ++c, ++offset ) { - if( *c == '\n' ) { - pattern_start = offset; - spaces = 0; - } - else if( pattern_start >= 0 && ( *c < 'a' || *c > 'z' ) && ( *c < 'A' || *c > 'Z' ) && ( *c < '0' || *c > '9' ) && ( *c != '_' ) ) { - if( *c == ':' && spaces <= 1 ) { - GtkTextIter iter_start, iter_end; - - gtk_text_buffer_get_iter_at_offset( buffer, &iter_start, pattern_start ); - gtk_text_buffer_get_iter_at_offset( buffer, &iter_end, offset ); - gtk_text_buffer_apply_tag_by_name( buffer, "bold", &iter_start, &iter_end ); - } - - if( *c == ' ' ){ - if( offset - pattern_start == 1 ){ - pattern_start = offset; - } - else{ - ++spaces; - } - } - else{ - pattern_start = -1; - } - } + QTextDocument *document = g_entityClassComment->document(); + const QRegularExpression rx( "^\\s*\\w+(?=\\s*:)", QRegularExpression::PatternOption::MultilineOption ); + for( QTextCursor cursor( document ); cursor = document->find( rx, cursor ), !cursor.isNull(); ) + cursor.mergeCharFormat( format ); } } -void EntityAttribute_setTooltip( GtkWidget* widget, const char* name, const char* description ){ +void EntityAttribute_setTooltip( QWidget* widget, const char* name, const char* description ){ StringOutputStream stream( 256 ); if( string_not_empty( name ) ) - stream << " " << name << " "; + stream << "      " << name << "    "; if( string_not_empty( description ) ){ - gchar *str = g_markup_escape_text( description, -1 ); - stream << "\n" << str; - g_free( str ); + stream << "
" << description; } if( !stream.empty() ) - gtk_widget_set_tooltip_markup( widget, stream.c_str() ); + widget->setToolTip( stream.c_str() ); } -void SurfaceFlags_setEntityClass( EntityClass* eclass ){ +void SpawnFlags_setEntityClass( EntityClass* eclass ){ if ( eclass == g_current_flags ) { return; } g_current_flags = eclass; - int spawnflag_count = 0; + g_spawnflag_count = 0; + // do a first pass to count the spawn flags, don't touch the widgets, we don't know in what state they are + for ( int i = 0; i < MAX_FLAGS; i++ ) { - // do a first pass to count the spawn flags, don't touch the widgets, we don't know in what state they are - for ( int i = 0; i < MAX_FLAGS; i++ ) - { - if ( eclass->flagnames[i] && eclass->flagnames[i][0] != 0 && strcmp( eclass->flagnames[i],"-" ) ) { - spawn_table[spawnflag_count] = i; - spawnflag_count++; - } + if ( eclass->flagnames[i][0] != 0 && strcmp( eclass->flagnames[i],"-" ) ) { + spawn_table[g_spawnflag_count++] = i; } + // hide all boxes + g_entitySpawnflagsCheck[i]->hide(); } - // disable all remaining boxes - // NOTE: these boxes might not even be on display + for ( int i = 0; i < g_spawnflag_count; ++i ) { - for ( int i = 0; i < g_spawnflag_count; ++i ) - { - GtkWidget* widget = GTK_WIDGET( g_entitySpawnflagsCheck[i] ); - gtk_label_set_text( GTK_LABEL( gtk_bin_get_child( GTK_BIN( widget ) ) ), " " ); - gtk_widget_hide( widget ); - g_object_ref( G_OBJECT( widget ) ); - gtk_container_remove( GTK_CONTAINER( g_spawnflagsTable ), widget ); - } - } + const auto str = StringOutputStream( 16 )( LowerCase( eclass->flagnames[spawn_table[i]] ) ); - g_spawnflag_count = spawnflag_count; + QCheckBox *check = g_entitySpawnflagsCheck[i]; + check->setText( str.c_str() ); + check->show(); - { - for ( int i = 0; i < g_spawnflag_count; ++i ) - { - GtkWidget* widget = GTK_WIDGET( g_entitySpawnflagsCheck[i] ); - gtk_widget_show( widget ); - - StringOutputStream str( 16 ); - str << LowerCase( eclass->flagnames[spawn_table[i]] ); - - gtk_table_attach( g_spawnflagsTable, widget, i % 4, i % 4 + 1, i / 4, i / 4 + 1, - (GtkAttachOptions)( GTK_FILL ), - (GtkAttachOptions)( GTK_FILL ), 0, 0 ); - g_object_unref( G_OBJECT( widget ) ); - - gtk_label_set_text( GTK_LABEL( gtk_bin_get_child( GTK_BIN( widget ) ) ), str.c_str() ); - - if( const EntityClassAttribute* attribute = eclass->flagAttributes[spawn_table[i]] ){ - EntityAttribute_setTooltip( widget, attribute->m_name.c_str(), attribute->m_description.c_str() ); - } + if( const EntityClassAttribute* attribute = eclass->flagAttributes[spawn_table[i]] ){ + EntityAttribute_setTooltip( check, attribute->m_name.c_str(), attribute->m_description.c_str() ); } } } void EntityClassList_selectEntityClass( EntityClass* eclass ){ - GtkTreeModel* model = GTK_TREE_MODEL( g_entlist_store ); - GtkTreeIter iter; - for ( gboolean good = gtk_tree_model_get_iter_first( model, &iter ); good; good = gtk_tree_model_iter_next( model, &iter ) ) - { - char* text; - gtk_tree_model_get( model, &iter, 0, &text, -1 ); - if ( string_equal( text, eclass->name() ) ) { - GtkTreeView* view = g_entityClassList; - GtkTreePath* path = gtk_tree_model_get_path( model, &iter ); - gtk_tree_selection_select_path( gtk_tree_view_get_selection( view ), path ); - if ( gtk_widget_get_realized( GTK_WIDGET( view ) ) ) { - gtk_tree_view_scroll_to_cell( view, path, 0, FALSE, 0, 0 ); - } - gtk_tree_path_free( path ); - good = FALSE; - } - g_free( text ); + auto list = g_entityClassList->findItems( eclass->name(), Qt::MatchFlag::MatchFixedString ); + if( !list.isEmpty() ){ + g_entityClassList->setCurrentItem( list.first() ); } } void EntityInspector_appendAttribute( const EntityClassAttributePair& attributePair, EntityAttribute& attribute ){ const char* keyname = attributePair.first.c_str(); //EntityClassAttributePair_getName( attributePair ); - GtkTable* row = DialogRow_new( keyname, attribute.getWidget() ); - EntityAttribute_setTooltip( GTK_WIDGET( row ), attributePair.second.m_name.c_str(), attributePair.second.m_description.c_str() ); - DialogVBox_packRow( g_attributeBox, GTK_WIDGET( row ) ); + auto label = new QLabel( keyname ); + EntityAttribute_setTooltip( label, attributePair.second.m_name.c_str(), attributePair.second.m_description.c_str() ); + DialogGrid_packRow( g_attributeBox, attribute.getWidget(), label ); } @@ -1131,20 +938,23 @@ typedef Static GlobalEntityAttributeFactory; void EntityInspector_setEntityClass( EntityClass *eclass ){ EntityClassList_selectEntityClass( eclass ); - SurfaceFlags_setEntityClass( eclass ); + SpawnFlags_setEntityClass( eclass ); if ( eclass != g_current_attributes ) { g_current_attributes = eclass; - container_remove_all( GTK_CONTAINER( g_attributeBox ) ); + while( QLayoutItem *item = g_attributeBox->takeAt( 0 ) ){ + delete item->widget(); + delete item; + } GlobalEntityAttributes_clear(); - for ( EntityClassAttributes::const_iterator i = eclass->m_attributes.begin(); i != eclass->m_attributes.end(); ++i ) + for ( const EntityClassAttributePair &pair : eclass->m_attributes ) { - EntityAttribute* attribute = GlobalEntityAttributeFactory::instance().create( ( *i ).second.m_type.c_str(), ( *i ).first.c_str() ); + EntityAttribute* attribute = GlobalEntityAttributeFactory::instance().create( pair.second.m_type.c_str(), pair.first.c_str() ); if ( attribute != 0 ) { g_entityAttributes.push_back( attribute ); - EntityInspector_appendAttribute( *i, *g_entityAttributes.back() ); + EntityInspector_appendAttribute( pair, *g_entityAttributes.back() ); } } } @@ -1152,41 +962,32 @@ void EntityInspector_setEntityClass( EntityClass *eclass ){ void EntityInspector_updateSpawnflags(){ { - int f = atoi( SelectedEntity_getValueForKey( "spawnflags" ) ); + const int f = atoi( SelectedEntity_getValueForKey( "spawnflags" ) ); for ( int i = 0; i < g_spawnflag_count; ++i ) { - int v = !!( f & ( 1 << spawn_table[i] ) ); + const bool v = !!( f & ( 1 << spawn_table[i] ) ); - toggle_button_set_active_no_signal( GTK_TOGGLE_BUTTON( g_entitySpawnflagsCheck[i] ), v ); - } - } - { - // take care of the remaining ones - for ( int i = g_spawnflag_count; i < MAX_FLAGS; ++i ) - { - toggle_button_set_active_no_signal( GTK_TOGGLE_BUTTON( g_entitySpawnflagsCheck[i] ), FALSE ); + g_entitySpawnflagsCheck[i]->setChecked( v ); } } } void EntityInspector_applySpawnflags(){ - int f, i, v; - char sz[32]; + int f = 0; - f = 0; - for ( i = 0; i < g_spawnflag_count; ++i ) + for ( int i = 0; i < g_spawnflag_count; ++i ) { - v = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( g_entitySpawnflagsCheck[i] ) ); + const int v = g_entitySpawnflagsCheck[i]->isChecked(); f |= v << spawn_table[i]; } + char sz[32]; sprintf( sz, "%i", f ); const char* value = ( f == 0 ) ? "" : sz; { - StringOutputStream command; - command << "entitySetFlags -flags " << f; - UndoableCommand undo( "entitySetSpawnflags" ); + const auto command = StringOutputStream( 64 )( "entitySetSpawnflags -flags ", f ); + UndoableCommand undo( command ); Scene_EntitySetKeyValue_Selected( "spawnflags", value ); } @@ -1202,32 +1003,16 @@ void EntityInspector_updateKeyValues(){ EntityInspector_updateSpawnflags(); - GtkListStore* store = g_entprops_store; - - // save current key/val pair around filling epair box - // row_select wipes it and sets to first in list - CopiedString strKey( gtk_entry_get_text( g_entityKeyEntry ) ); - CopiedString strVal( gtk_entry_get_text( g_entityValueEntry ) ); - - gtk_list_store_clear( store ); + g_entprops_store->clear(); // Walk through list and add pairs - for ( KeyValues::iterator i = g_selectedKeyValues.begin(); i != g_selectedKeyValues.end(); ++i ) + for ( const auto&[ key, value ] : g_selectedKeyValues ) { - GtkTreeIter iter; - gtk_list_store_append( store, &iter ); - StringOutputStream key( 64 ); - key << ( *i ).first; - StringOutputStream value( 64 ); - value << ( *i ).second; - gtk_list_store_set( store, &iter, 0, key.c_str(), 1, value.c_str(), -1 ); + g_entprops_store->addTopLevelItem( new QTreeWidgetItem( { key.c_str(), value.c_str() } ) ); } - gtk_entry_set_text( g_entityKeyEntry, strKey.c_str() ); - gtk_entry_set_text( g_entityValueEntry, strVal.c_str() ); - - for ( EntityAttributes::const_iterator i = g_entityAttributes.begin(); i != g_entityAttributes.end(); ++i ) + for ( EntityAttribute *attr : g_entityAttributes ) { - ( *i )->update(); + attr->update(); } } @@ -1252,86 +1037,69 @@ void EntityInspector_selectionChanged( const Selectable& ){ EntityInspector_keyValueChanged(); } -void EntityClassList_convertEntity(){ - GtkTreeView* view = g_entityClassList; - - GtkTreeModel* model; - GtkTreeIter iter; - if ( !gtk_tree_selection_get_selected( gtk_tree_view_get_selection( view ), &model, &iter ) ) { - gtk_MessageBox( gtk_widget_get_toplevel( GTK_WIDGET( g_entityClassList ) ), "You must have a selected class to create an entity", "info" ); - return; - } - - char* text; - gtk_tree_model_get( model, &iter, 0, &text, -1 ); - - { - Scene_EntitySetClassname_Selected( text ); - } - g_free( text ); -} - void EntityInspector_applyKeyValue(){ // Get current selection text - StringOutputStream key( 64 ); - key << gtk_entry_get_text( g_entityKeyEntry ); - StringOutputStream value( 64 ); - value << gtk_entry_get_text( g_entityValueEntry ); + const auto key = g_entityKeyEntry->text().toLatin1(); + const auto value = g_entityValueEntry->text().toLatin1(); // TTimo: if you change the classname to worldspawn you won't merge back in the structural brushes but create a parasite entity // if ( !strcmp( key.c_str(), "classname" ) && !strcmp( value.c_str(), "worldspawn" ) ) { -// gtk_MessageBox( gtk_widget_get_toplevel( GTK_WIDGET( g_entityKeyEntry ) ), "Cannot change \"classname\" key back to worldspawn.", 0, eMB_OK ); +// qt_MessageBox( g_entityKeyEntry->window(), "Cannot change \"classname\" key back to worldspawn." ); // return; // } // RR2DO2: we don't want spaces in entity keys - if ( strstr( key.c_str(), " " ) ) { - gtk_MessageBox( gtk_widget_get_toplevel( GTK_WIDGET( g_entityKeyEntry ) ), "No spaces are allowed in entity keys.", 0, eMB_OK ); + if ( strstr( key.constData(), " " ) ) { + qt_MessageBox( g_entityKeyEntry->window(), "No spaces are allowed in entity key names." ); return; } - if ( string_equal( key.c_str(), "classname" ) ) { - Scene_EntitySetClassname_Selected( value.c_str() ); + if ( string_equal( key.constData(), "classname" ) ) { + Scene_EntitySetClassname_Selected( value.constData() ); } else { - Scene_EntitySetKeyValue_Selected_Undoable( key.c_str(), value.c_str() ); + Scene_EntitySetKeyValue_Selected_Undoable( key.constData(), value.constData() ); } } void EntityInspector_clearKeyValue(){ // Get current selection text - StringOutputStream key( 64 ); - key << gtk_entry_get_text( g_entityKeyEntry ); + if( const auto item = g_entprops_store->currentItem() ){ + const auto key = item->text( 0 ).toLatin1(); - if ( !string_equal( key.c_str(), "classname" ) ) { - StringOutputStream command; - command << "entityDeleteKey -key " << key.c_str(); - UndoableCommand undo( command.c_str() ); - Scene_EntitySetKeyValue_Selected( key.c_str(), "" ); + if ( !string_equal( key.constData(), "classname" ) ) { + const auto command = StringOutputStream( 64 )( "entityDeleteKey -key ", key.constData() ); + UndoableCommand undo( command.c_str() ); + Scene_EntitySetKeyValue_Selected( key.constData(), "" ); + } } } -static gint EntityProperties_keypress( GtkEntry* widget, GdkEventKey* event, gpointer data ){ - if ( event->keyval == GDK_KEY_Delete ) { - EntityInspector_clearKeyValue(); - return TRUE; +class : public QObject +{ +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::ShortcutOverride ) { + QKeyEvent *keyEvent = static_cast( event ); + if( keyEvent->key() == Qt::Key_Delete ){ + EntityInspector_clearKeyValue(); + event->accept(); + } + } + return QObject::eventFilter( obj, event ); // standard event processing } - if ( event->keyval == GDK_KEY_Tab ) { - gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( widget ) ) ), GTK_WIDGET( g_entityKeyEntry ) ); - return TRUE; - } - return FALSE; } +g_EntityProperties_keypress; void EntityInspector_clearAllKeyValues(){ UndoableCommand undo( "entityClear" ); // remove all keys except classname and origin - for ( KeyValues::iterator i = g_selectedKeyValues.begin(); i != g_selectedKeyValues.end(); ++i ) + for ( const auto&[ key, value ] : g_selectedKeyValues ) { - if ( !string_equal( ( *i ).first.c_str(), "classname" ) && !string_equal( ( *i ).first.c_str(), "origin" ) ) { - Scene_EntitySetKeyValue_Selected( ( *i ).first.c_str(), "" ); + if ( !string_equal( key.c_str(), "classname" ) && !string_equal( key.c_str(), "origin" ) ) { + Scene_EntitySetKeyValue_Selected( key.c_str(), "" ); } } } @@ -1339,520 +1107,223 @@ void EntityInspector_clearAllKeyValues(){ // ============================================================================= // callbacks -static void EntityClassList_selection_changed( GtkTreeSelection* selection, gpointer data ){ - GtkTreeModel* model; - GtkTreeIter selected; - if ( gtk_tree_selection_get_selected( selection, &model, &selected ) ) { - EntityClass* eclass; - gtk_tree_model_get( model, &selected, 1, &eclass, -1 ); - if ( eclass != 0 ) { - SetComment( eclass ); - } +static void EntityClassList_selection_changed( QTreeWidgetItem *current, QTreeWidgetItem *previous ){ + if( current != nullptr ){ + SetComment( current->data( 0, Qt::ItemDataRole::UserRole ).value() ); } } -static gint EntityClassList_button_press( GtkWidget *widget, GdkEventButton *event, gpointer data ){ - if ( event->type == GDK_2BUTTON_PRESS ) { - EntityClassList_convertEntity(); - return TRUE; +static void EntityProperties_selection_changed( QTreeWidgetItem *item, int column ){ + if( item != nullptr ){ + g_entityKeyEntry->setText( item->text( 0 ) ); + g_entityValueEntry->setText( item->text( 1 ) ); } - return FALSE; } -static gint EntityClassList_keypress( GtkWidget* widget, GdkEventKey* event, gpointer data ){ - if ( event->keyval == GDK_KEY_Return ) { - EntityClassList_convertEntity(); - return TRUE; - } - // select the entity that starts with the key pressed -/* - unsigned int code = gdk_keyval_to_upper( event->keyval ); - if ( code <= 'Z' && code >= 'A' && event->state == 0 ) { - GtkTreeView* view = g_entityClassList; - GtkTreeModel* model; - GtkTreeIter iter; - if ( !gtk_tree_selection_get_selected( gtk_tree_view_get_selection( view ), &model, &iter ) - || !gtk_tree_model_iter_next( model, &iter ) ) { - gtk_tree_model_get_iter_first( model, &iter ); - } - - for ( std::size_t count = gtk_tree_model_iter_n_children( model, 0 ); count > 0; --count ) - { - char* text; - gtk_tree_model_get( model, &iter, 0, &text, -1 ); - - if ( toupper( text[0] ) == (int)code ) { - GtkTreePath* path = gtk_tree_model_get_path( model, &iter ); - gtk_tree_selection_select_path( gtk_tree_view_get_selection( view ), path ); - if ( gtk_widget_get_realized( GTK_WIDGET( view ) ) ) { - gtk_tree_view_scroll_to_cell( view, path, 0, FALSE, 0, 0 ); - } - gtk_tree_path_free( path ); - count = 1; - } - - g_free( text ); - - if ( !gtk_tree_model_iter_next( model, &iter ) ) { - gtk_tree_model_get_iter_first( model, &iter ); +class : public QObject +{ +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::ShortcutOverride ) { + QKeyEvent *keyEvent = static_cast( event ); + if( keyEvent->key() == Qt::Key_Return + || keyEvent->key() == Qt::Key_Enter + || keyEvent->key() == Qt::Key_Tab + || keyEvent->key() == Qt::Key_Up + || keyEvent->key() == Qt::Key_Down + || keyEvent->key() == Qt::Key_PageUp + || keyEvent->key() == Qt::Key_PageDown ){ + event->accept(); } } - - return TRUE; + return QObject::eventFilter( obj, event ); // standard event processing } -*/ - return FALSE; } +g_pressedKeysFilter; -static void EntityProperties_selection_changed( GtkTreeSelection* selection, gpointer data ){ - // find out what type of entity we are trying to create - GtkTreeModel* model; - GtkTreeIter iter; - if ( !gtk_tree_selection_get_selected( selection, &model, &iter ) ) { - return; - } - char* key; - char* val; - gtk_tree_model_get( model, &iter, 0, &key, 1, &val, -1 ); - - gtk_entry_set_text( g_entityKeyEntry, key ); - gtk_entry_set_text( g_entityValueEntry, val ); - - g_free( key ); - g_free( val ); -} - -static void SpawnflagCheck_toggled( GtkWidget *widget, gpointer data ){ - EntityInspector_applySpawnflags(); -} - -static gint EntityEntry_keypress( GtkEntry* widget, GdkEventKey* event, gpointer data ){ - if ( event->keyval == GDK_KEY_Return ) { - if ( widget == g_entityKeyEntry ) { - //gtk_entry_set_text( g_entityValueEntry, "" ); - gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( widget ) ) ), GTK_WIDGET( g_entityValueEntry ) ); - } - else - { - EntityInspector_applyKeyValue(); - } - return TRUE; - } - if ( event->keyval == GDK_KEY_Tab ) { - if ( widget == g_entityKeyEntry ) { - gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( widget ) ) ), GTK_WIDGET( g_entityValueEntry ) ); - } - else - { - gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( widget ) ) ), GTK_WIDGET( g_entityKeyEntry ) ); - } - return TRUE; - } - if ( event->keyval == GDK_KEY_Escape ) { - //gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( widget ) ) ), NULL ); - GroupDialog_showPage( g_page_entity ); - return TRUE; - } - - return FALSE; -} - -void EntityInspector_destroyWindow( GtkWidget* widget, gpointer data ){ - g_entitysplit0_position = gtk_paned_get_position( GTK_PANED( g_entity_split0 ) ); - g_entitysplit1_position = gtk_paned_get_position( GTK_PANED( g_entity_split1 ) ); - g_entitysplit2_position = gtk_paned_get_position( GTK_PANED( g_entity_split2 ) ); +void EntityInspector_destroyWindow(){ g_entityInspector_windowConstructed = false; GlobalEntityAttributes_clear(); } -static gint EntityInspector_hideWindowKB( GtkWidget* widget, GdkEventKey* event, gpointer data ){ - //if ( event->keyval == GDK_KEY_Escape && gtk_widget_get_visible( widget ) ) { - if ( event->keyval == GDK_KEY_Escape ) { - //GroupDialog_showPage( g_page_entity ); - gtk_widget_hide( GTK_WIDGET( GroupDialog_getWindow() ) ); - return TRUE; - } - /* this doesn't work, if tab is bound (func is not called then) */ - if ( event->keyval == GDK_KEY_Tab ) { - gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( widget ) ) ), GTK_WIDGET( g_entityKeyEntry ) ); - return TRUE; - } - return FALSE; -} +QWidget* EntityInspector_constructWindow( QWidget* toplevel ){ + auto splitter = new QSplitter( Qt::Vertical ); -void EntityInspector_selectTargeting( GtkButton *button, gpointer user_data ){ - bool focus = gtk_toggle_button_get_active( g_focusToggleButton ); - Select_ConnectedEntities( true, false, focus ); -} - -void EntityInspector_selectTargets( GtkButton *button, gpointer user_data ){ - bool focus = gtk_toggle_button_get_active( g_focusToggleButton ); - Select_ConnectedEntities( false, true, focus ); -} - -void EntityInspector_selectConnected( GtkButton *button, gpointer user_data ){ - bool focus = gtk_toggle_button_get_active( g_focusToggleButton ); - Select_ConnectedEntities( true, true, focus ); -} - -void EntityInspector_focusSelected( GtkButton *button, gpointer user_data ){ - FocusAllViews(); -} - -void EntityInspector_selectByKey( GtkButton *button, gpointer user_data ){ - Select_EntitiesByKeyValue( gtk_entry_get_text( g_entityKeyEntry ), nullptr ); -} - -void EntityInspector_selectByValue( GtkButton *button, gpointer user_data ){ - Select_EntitiesByKeyValue( nullptr, gtk_entry_get_text( g_entityValueEntry ) ); -} - -void EntityInspector_selectByKeyValue( GtkButton *button, gpointer user_data ){ - Select_EntitiesByKeyValue( gtk_entry_get_text( g_entityKeyEntry ), gtk_entry_get_text( g_entityValueEntry ) ); -} - - -GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){ - GtkWidget* vbox = gtk_vbox_new( FALSE, 2 ); - gtk_widget_show( vbox ); - gtk_container_set_border_width( GTK_CONTAINER( vbox ), 2 ); - - g_signal_connect( G_OBJECT( toplevel ), "key_press_event", G_CALLBACK( EntityInspector_hideWindowKB ), 0 ); - g_signal_connect( G_OBJECT( vbox ), "destroy", G_CALLBACK( EntityInspector_destroyWindow ), 0 ); + QObject::connect( splitter, &QObject::destroyed, EntityInspector_destroyWindow ); + splitter->installEventFilter( &g_pressedKeysFilter ); { - GtkWidget* split1 = gtk_vpaned_new(); - gtk_box_pack_start( GTK_BOX( vbox ), split1, TRUE, TRUE, 0 ); - gtk_widget_show( split1 ); + // class list + auto tree = g_entityClassList = new QTreeWidget; + tree->setColumnCount( 1 ); + tree->setSortingEnabled( true ); + tree->sortByColumn( 0, Qt::SortOrder::AscendingOrder ); + tree->setUniformRowHeights( true ); // optimization + tree->setHorizontalScrollBarPolicy( Qt::ScrollBarPolicy::ScrollBarAlwaysOff ); + tree->setSizeAdjustPolicy( QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents ); // scroll area will inherit column size + tree->header()->setStretchLastSection( false ); // non greedy column sizing + tree->header()->setSectionResizeMode( QHeaderView::ResizeMode::ResizeToContents ); // no text elision + tree->setHeaderHidden( true ); + tree->setRootIsDecorated( false ); + tree->setEditTriggers( QAbstractItemView::EditTrigger::NoEditTriggers ); + tree->setAutoScroll( true ); - g_entity_split1 = split1; + QObject::connect( tree, &QTreeWidget::itemActivated, []( QTreeWidgetItem *item, int column ){ + Scene_EntitySetClassname_Selected( item->text( 0 ).toLatin1().constData() ); + } ); + QObject::connect( tree, &QTreeWidget::currentItemChanged, EntityClassList_selection_changed ); + splitter->addWidget( tree ); + } + { + auto text = g_entityClassComment = new QTextEdit; + text->setReadOnly( true ); + text->setUndoRedoEnabled( false ); + text->setAcceptRichText( false ); + + splitter->addWidget( text ); + } + { + QWidget *containerWidget = new QWidget; // Adding a QLayout to a QSplitter is not supported, use proxy widget + splitter->addWidget( containerWidget ); + auto vbox = new QVBoxLayout( containerWidget ); + vbox->setContentsMargins( 0, 0, 0, 0 ); { - GtkWidget* split2 = gtk_vpaned_new(); - //gtk_paned_add1( GTK_PANED( split1 ), split2 ); - gtk_paned_pack1( GTK_PANED( split1 ), split2, FALSE, FALSE ); - gtk_widget_show( split2 ); - - g_entity_split2 = split2; - + // Spawnflags (4 colums wide max, or window gets too wide.) + auto grid = g_spawnflagsTable = new QGridLayout; + grid->setAlignment( Qt::AlignmentFlag::AlignLeft ); + vbox->addLayout( grid ); + for ( int i = 0; i < MAX_FLAGS; i++ ) { - // class list - GtkWidget* scr = gtk_scrolled_window_new( 0, 0 ); - gtk_widget_show( scr ); - //gtk_paned_add1( GTK_PANED( split2 ), scr ); - gtk_paned_pack1( GTK_PANED( split2 ), scr, FALSE, FALSE ); - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS ); - gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN ); - - { - GtkListStore* store = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_POINTER ); - - GtkTreeView* view = GTK_TREE_VIEW( gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) ) ); - //gtk_tree_view_set_enable_search( GTK_TREE_VIEW( view ), FALSE ); - gtk_tree_view_set_headers_visible( view, FALSE ); - g_signal_connect( G_OBJECT( view ), "button_press_event", G_CALLBACK( EntityClassList_button_press ), 0 ); - g_signal_connect( G_OBJECT( view ), "key_press_event", G_CALLBACK( EntityClassList_keypress ), 0 ); - - { - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "Key", renderer, "text", 0, NULL ); - gtk_tree_view_append_column( view, column ); - } - - { - GtkTreeSelection* selection = gtk_tree_view_get_selection( view ); - g_signal_connect( G_OBJECT( selection ), "changed", G_CALLBACK( EntityClassList_selection_changed ), 0 ); - } - - gtk_widget_show( GTK_WIDGET( view ) ); - - gtk_container_add( GTK_CONTAINER( scr ), GTK_WIDGET( view ) ); - - g_object_unref( G_OBJECT( store ) ); - g_entityClassList = view; - g_entlist_store = store; - } + auto check = g_entitySpawnflagsCheck[i] = new QCheckBox; + grid->addWidget( check, i / 4, i % 4 ); + check->hide(); + QObject::connect( check, &QAbstractButton::clicked, EntityInspector_applySpawnflags ); } + } + { + // key/value list + auto tree = g_entprops_store = new QTreeWidget; + tree->setColumnCount( 2 ); + tree->setUniformRowHeights( true ); // optimization + tree->setHorizontalScrollBarPolicy( Qt::ScrollBarPolicy::ScrollBarAlwaysOff ); + tree->header()->setSectionResizeMode( 0, QHeaderView::ResizeMode::ResizeToContents ); // no text elision + tree->setHeaderHidden( true ); + tree->setRootIsDecorated( false ); + tree->setEditTriggers( QAbstractItemView::EditTrigger::NoEditTriggers ); - { - GtkWidget* scr = gtk_scrolled_window_new( 0, 0 ); - gtk_widget_show( scr ); - //gtk_paned_add2( GTK_PANED( split2 ), scr ); - gtk_paned_pack2( GTK_PANED( split2 ), scr, FALSE, FALSE ); - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS ); - gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN ); + QObject::connect( tree, &QTreeWidget::itemPressed, EntityProperties_selection_changed ); + tree->installEventFilter( &g_EntityProperties_keypress ); - { - GtkTextView* text = GTK_TEXT_VIEW( gtk_text_view_new() ); - gtk_widget_set_size_request( GTK_WIDGET( text ), 0, -1 ); // allow shrinking - gtk_text_view_set_wrap_mode( text, GTK_WRAP_WORD ); - gtk_text_view_set_editable( text, FALSE ); - gtk_widget_show( GTK_WIDGET( text ) ); - gtk_container_add( GTK_CONTAINER( scr ), GTK_WIDGET( text ) ); - g_entityClassComment = text; - { - GtkTextBuffer *buffer = gtk_text_view_get_buffer( text ); - gtk_text_buffer_create_tag( buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL ); - } - } - } + vbox->addWidget( tree ); } { - GtkWidget* split0 = gtk_vpaned_new(); - //gtk_paned_add2( GTK_PANED( split1 ), split0 ); - gtk_paned_pack2( GTK_PANED( split1 ), split0, FALSE, FALSE ); - gtk_widget_show( split0 ); - g_entity_split0 = split0; - + // key/value entry + auto grid = new QGridLayout; + vbox->addLayout( grid ); { - GtkWidget* vbox2 = gtk_vbox_new( FALSE, 2 ); - gtk_widget_show( vbox2 ); - gtk_paned_pack1( GTK_PANED( split0 ), vbox2, FALSE, FALSE ); - - { - // Spawnflags (4 colums wide max, or window gets too wide.) - GtkTable* table = GTK_TABLE( gtk_table_new( 4, 4, FALSE ) ); - gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( table ), FALSE, TRUE, 0 ); - gtk_widget_show( GTK_WIDGET( table ) ); - - g_spawnflagsTable = table; - - for ( int i = 0; i < MAX_FLAGS; i++ ) - { - GtkCheckButton* check = GTK_CHECK_BUTTON( gtk_check_button_new_with_label( "" ) ); - g_object_ref( G_OBJECT( check ) ); - g_object_set_data( G_OBJECT( check ), "handler", gint_to_pointer( g_signal_connect( G_OBJECT( check ), "toggled", G_CALLBACK( SpawnflagCheck_toggled ), 0 ) ) ); - g_entitySpawnflagsCheck[i] = check; - } - } - - { - // key/value list - GtkWidget* scr = gtk_scrolled_window_new( 0, 0 ); - gtk_widget_show( scr ); - gtk_box_pack_start( GTK_BOX( vbox2 ), scr, TRUE, TRUE, 0 ); - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); - gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN ); - - { - GtkListStore* store = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_STRING ); - - GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) ); - gtk_tree_view_set_enable_search( GTK_TREE_VIEW( view ), FALSE ); - gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), FALSE ); - g_signal_connect( G_OBJECT( view ), "key_press_event", G_CALLBACK( EntityProperties_keypress ), 0 ); - - { - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "", renderer, "text", 0, NULL ); - gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column ); - } - - { - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "", renderer, "text", 1, NULL ); - gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column ); - } - - { - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) ); - g_signal_connect( G_OBJECT( selection ), "changed", G_CALLBACK( EntityProperties_selection_changed ), 0 ); - } - - gtk_widget_show( view ); - - gtk_container_add( GTK_CONTAINER( scr ), view ); - - g_object_unref( G_OBJECT( store ) ); - - g_entprops_store = store; - } - } - - { - // key/value entry - GtkTable* table = GTK_TABLE( gtk_table_new( 2, 3, FALSE ) ); - gtk_widget_show( GTK_WIDGET( table ) ); - gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( table ), FALSE, TRUE, 0 ); - gtk_table_set_row_spacings( table, 3 ); - gtk_table_set_col_spacings( table, 5 ); - - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 0, 1, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_widget_set_events( GTK_WIDGET( entry ), GDK_KEY_PRESS_MASK ); - g_signal_connect( G_OBJECT( entry ), "key_press_event", G_CALLBACK( EntityEntry_keypress ), 0 ); - g_entityKeyEntry = entry; - } - - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 1, 2, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_widget_set_events( GTK_WIDGET( entry ), GDK_KEY_PRESS_MASK ); - g_signal_connect( G_OBJECT( entry ), "key_press_event", G_CALLBACK( EntityEntry_keypress ), 0 ); - g_entityValueEntry = entry; - } - - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Value" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 1, 2, - (GtkAttachOptions)( GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Key" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 0, 1, - (GtkAttachOptions)( GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - - /* select by key/value buttons */ - GtkTable* tab = GTK_TABLE( gtk_table_new( 2, 2, FALSE ) ); - gtk_table_attach( table, GTK_WIDGET( tab ), 2, 3, 0, 2, - (GtkAttachOptions)( GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - table = tab; - gtk_widget_show( GTK_WIDGET( table ) ); - gtk_table_set_row_spacings( table, 0 ); - gtk_table_set_col_spacings( table, 0 ); - { - GtkWidget* button = gtk_button_new(); - gtk_button_set_image( GTK_BUTTON( button ), gtk_image_new_from_stock( GTK_STOCK_APPLY, GTK_ICON_SIZE_MENU ) ); - gtk_widget_set_can_focus( button, FALSE ); - gtk_widget_set_tooltip_text( button, "Select by key" ); - gtk_widget_show( button ); - gtk_table_attach( table, button, 0, 1, 0, 1, - (GtkAttachOptions)( GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectByKey ), 0 ); - } - { - GtkWidget* button = gtk_button_new(); - gtk_button_set_image( GTK_BUTTON( button ), gtk_image_new_from_stock( GTK_STOCK_APPLY, GTK_ICON_SIZE_MENU ) ); - gtk_widget_set_can_focus( button, FALSE ); - gtk_widget_set_tooltip_text( button, "Select by value" ); - gtk_widget_show( button ); - gtk_table_attach( table, button, 0, 1, 1, 2, - (GtkAttachOptions)( GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectByValue ), 0 ); - } - { - GtkWidget* button = gtk_button_new(); - gtk_button_set_image( GTK_BUTTON( button ), gtk_image_new_from_stock( GTK_STOCK_APPLY, GTK_ICON_SIZE_MENU ) ); - gtk_widget_set_can_focus( button, FALSE ); - gtk_widget_set_tooltip_text( button, "Select by key + value" ); - gtk_widget_show( button ); - gtk_table_attach( table, button, 1, 2, 0, 2, - (GtkAttachOptions)( GTK_FILL ), - (GtkAttachOptions)( GTK_FILL ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectByKeyValue ), 0 ); - } - } - - { - GtkBox* hbox = GTK_BOX( gtk_hbox_new( FALSE, 4 ) ); - gtk_widget_show( GTK_WIDGET( hbox ) ); - gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( hbox ), FALSE, TRUE, 0 ); - - { - GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "Clear All" ) ); - gtk_widget_set_can_focus( GTK_WIDGET( button ), FALSE ); - gtk_widget_show( GTK_WIDGET( button ) ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_clearAllKeyValues ), 0 ); - gtk_box_pack_start( hbox, GTK_WIDGET( button ), TRUE, TRUE, 0 ); - } - { - GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "Delete Key" ) ); - gtk_widget_set_can_focus( GTK_WIDGET( button ), FALSE ); - gtk_widget_show( GTK_WIDGET( button ) ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_clearKeyValue ), 0 ); - gtk_box_pack_start( hbox, GTK_WIDGET( button ), TRUE, TRUE, 0 ); - } - { - GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "<" ) ); - gtk_widget_set_tooltip_text( GTK_WIDGET( button ), "Select targeting entities" ); - gtk_widget_set_can_focus( GTK_WIDGET( button ), FALSE ); - gtk_widget_show( GTK_WIDGET( button ) ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectTargeting ), 0 ); - gtk_box_pack_start( hbox, GTK_WIDGET( button ), FALSE, FALSE, 0 ); - } - { - GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( ">" ) ); - gtk_widget_set_tooltip_text( GTK_WIDGET( button ), "Select targets" ); - gtk_widget_set_can_focus( GTK_WIDGET( button ), FALSE ); - gtk_widget_show( GTK_WIDGET( button ) ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectTargets ), 0 ); - gtk_box_pack_start( hbox, GTK_WIDGET( button ), FALSE, FALSE, 0 ); - } - { - GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "<->" ) ); - gtk_widget_set_tooltip_text( GTK_WIDGET( button ), "Select connected entities" ); - gtk_widget_set_can_focus( GTK_WIDGET( button ), FALSE ); - gtk_widget_show( GTK_WIDGET( button ) ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectConnected ), 0 ); - gtk_box_pack_start( hbox, GTK_WIDGET( button ), FALSE, FALSE, 0 ); - } - { - GtkWidget* button = gtk_toggle_button_new(); - GtkWidget* image = gtk_image_new_from_stock( GTK_STOCK_ZOOM_IN, GTK_ICON_SIZE_SMALL_TOOLBAR ); - gtk_button_set_image( GTK_BUTTON( button ), image ); - gtk_button_set_relief( GTK_BUTTON( button ), GTK_RELIEF_NONE ); - gtk_widget_set_can_focus( button, FALSE ); - gtk_box_pack_start( hbox, button, FALSE, FALSE, 0 ); - gtk_widget_set_tooltip_text( button, "AutoFocus on Selection" ); - gtk_widget_show( button ); - g_focusToggleButton = GTK_TOGGLE_BUTTON( button ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_focusSelected ), 0 ); - } - } + grid->addWidget( new QLabel( "Key" ), 0, 0 ); + grid->addWidget( new QLabel( "Value" ), 1, 0 ); + } + { + auto line = g_entityKeyEntry = new QLineEdit; + grid->addWidget( line, 0, 1 ); + QObject::connect( line, &QLineEdit::returnPressed, [](){ g_entityValueEntry->setFocus(); } ); } { - GtkWidget* scr = gtk_scrolled_window_new( 0, 0 ); - gtk_widget_show( scr ); - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC ); - - GtkWidget* viewport = gtk_viewport_new( 0, 0 ); - gtk_widget_show( viewport ); - gtk_viewport_set_shadow_type( GTK_VIEWPORT( viewport ), GTK_SHADOW_NONE ); - - g_attributeBox = GTK_VBOX( gtk_vbox_new( FALSE, 2 ) ); - gtk_widget_show( GTK_WIDGET( g_attributeBox ) ); - - gtk_container_add( GTK_CONTAINER( viewport ), GTK_WIDGET( g_attributeBox ) ); - gtk_container_add( GTK_CONTAINER( scr ), viewport ); - gtk_paned_pack2( GTK_PANED( split0 ), scr, FALSE, FALSE ); + auto line = g_entityValueEntry = new QLineEdit; + grid->addWidget( line, 1, 1 ); + QObject::connect( line, &QLineEdit::returnPressed, [](){ EntityInspector_applyKeyValue(); } ); + } + /* select by key/value buttons */ + { + auto b = new QToolButton; + b->setText( "+" ); + b->setToolTip( "Select by key" ); + grid->addWidget( b, 0, 2 ); + QObject::connect( b, &QAbstractButton::clicked, [](){ + Select_EntitiesByKeyValue( g_entityKeyEntry->text().toLatin1().constData(), nullptr ); + } ); + } + { + auto b = new QToolButton; + b->setText( "+" ); + b->setToolTip( "Select by value" ); + grid->addWidget( b, 1, 2 ); + QObject::connect( b, &QAbstractButton::clicked, [](){ + Select_EntitiesByKeyValue( nullptr, g_entityValueEntry->text().toLatin1().constData() ); + } ); + } + { + auto b = new QToolButton; + b->setText( "+" ); + b->setToolTip( "Select by key + value" ); + grid->addWidget( b, 0, 3, 2, 1 ); + QObject::connect( b, &QAbstractButton::clicked, [](){ + Select_EntitiesByKeyValue( g_entityKeyEntry->text().toLatin1().constData(), g_entityValueEntry->text().toLatin1().constData() ); + } ); + } + } + { + auto hbox = new QHBoxLayout; + vbox->addLayout( hbox ); + { + auto b = new QPushButton( "Clear All" ); + hbox->addWidget( b ); + QObject::connect( b, &QAbstractButton::clicked, EntityInspector_clearAllKeyValues ); + } + { + auto b = new QPushButton( "Delete Key" ); + hbox->addWidget( b ); + QObject::connect( b, &QAbstractButton::clicked, EntityInspector_clearKeyValue ); + } + { + auto b = new QToolButton; + hbox->addWidget( b ); + b->setText( "<" ); + b->setToolTip( "Select targeting entities" ); + QObject::connect( b, &QAbstractButton::clicked, [](){ Select_ConnectedEntities( true, false, g_focusToggleButton->isChecked() ); } ); + } + { + auto b = new QToolButton; + hbox->addWidget( b ); + b->setText( ">" ); + b->setToolTip( "Select targets" ); + QObject::connect( b, &QAbstractButton::clicked, [](){ Select_ConnectedEntities( false, true, g_focusToggleButton->isChecked() ); } ); + } + { + auto b = new QToolButton; + hbox->addWidget( b ); + b->setText( "<->" ); + b->setToolTip( "Select connected entities" ); + QObject::connect( b, &QAbstractButton::clicked, [](){ Select_ConnectedEntities( true, true, g_focusToggleButton->isChecked() ); } ); + } + { + auto b = g_focusToggleButton = new QToolButton; + hbox->addWidget( b ); + b->setText( u8"👀" ); + b->setToolTip( "AutoFocus on Selection" ); + b->setCheckable( true ); + QObject::connect( b, &QAbstractButton::clicked, []( bool checked ){ if( checked ) FocusAllViews(); } ); } } } - - { - // show the sliders in any case //no need, gtk can care - /*if ( g_entitysplit2_position < 22 ) { - g_entitysplit2_position = 22; - }*/ - gtk_paned_set_position( GTK_PANED( g_entity_split2 ), g_entitysplit2_position ); - /*if ( ( g_entitysplit1_position - g_entitysplit2_position ) < 27 ) { - g_entitysplit1_position = g_entitysplit2_position + 27; - }*/ - gtk_paned_set_position( GTK_PANED( g_entity_split1 ), g_entitysplit1_position ); - gtk_paned_set_position( GTK_PANED( g_entity_split0 ), g_entitysplit0_position ); + auto scroll = new QScrollArea; + scroll->setHorizontalScrollBarPolicy( Qt::ScrollBarPolicy::ScrollBarAlwaysOff ); + scroll->setWidgetResizable( true ); + splitter->addWidget( scroll ); + + QWidget *containerWidget = new QWidget; // Adding a QLayout to a QScrollArea is not supported, use proxy widget + g_attributeBox = new QGridLayout( containerWidget ); + g_attributeBox->setAlignment( Qt::AlignmentFlag::AlignTop ); + g_attributeBox->setColumnStretch( 0, 111 ); + g_attributeBox->setColumnStretch( 1, 333 ); + scroll->setWidget( containerWidget ); // widget's layout must be set b4 this! } g_entityInspector_windowConstructed = true; @@ -1862,10 +1333,9 @@ GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){ GlobalSelectionSystem().addSelectionChangeCallback( EntityInspectorSelectionChangedCaller() ); GlobalEntityCreator().setKeyValueChangedFunc( EntityInspector_keyValueChanged ); - // hack - gtk_container_set_focus_chain( GTK_CONTAINER( vbox ), NULL ); + g_guiSettings.addSplitter( splitter, "EntityInspector/splitter", { 55, 175, 255, 255 } ); - return vbox; + return splitter; } class EntityInspector : public ModuleObserver @@ -1899,11 +1369,6 @@ EntityInspector g_EntityInspector; void EntityInspector_construct(){ GlobalEntityClassManager().attach( g_EntityInspector ); - - GlobalPreferenceSystem().registerPreference( "EntitySplit0", IntImportStringCaller( g_entitysplit0_position ), IntExportStringCaller( g_entitysplit0_position ) ); - GlobalPreferenceSystem().registerPreference( "EntitySplit1", IntImportStringCaller( g_entitysplit1_position ), IntExportStringCaller( g_entitysplit1_position ) ); - GlobalPreferenceSystem().registerPreference( "EntitySplit2", IntImportStringCaller( g_entitysplit2_position ), IntExportStringCaller( g_entitysplit2_position ) ); - } void EntityInspector_destroy(){ diff --git a/radiant/entityinspector.h b/radiant/entityinspector.h index c7eb8010..5d70303b 100644 --- a/radiant/entityinspector.h +++ b/radiant/entityinspector.h @@ -21,8 +21,6 @@ #pragma once -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkWindow GtkWindow; -GtkWidget* EntityInspector_constructWindow( GtkWindow* parent ); +class QWidget* EntityInspector_constructWindow( QWidget* parent ); void EntityInspector_construct(); void EntityInspector_destroy(); diff --git a/radiant/entitylist.cpp b/radiant/entitylist.cpp index 10bb61e5..050371f5 100644 --- a/radiant/entitylist.cpp +++ b/radiant/entitylist.cpp @@ -23,7 +23,15 @@ #include "iselection.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "string/string.h" #include "scenelib.h" @@ -32,10 +40,9 @@ #include "generic/object.h" #include "gtkutil/widget.h" -#include "gtkutil/window.h" #include "gtkutil/idledraw.h" #include "gtkutil/accelerator.h" -#include "gtkutil/closure.h" +#include "gtkutil/guisettings.h" #include "treemodel.h" @@ -44,8 +51,6 @@ void RedrawEntityList(); typedef FreeCaller RedrawEntityListCaller; -typedef struct _GtkTreeView GtkTreeView; - class EntityList { public: @@ -59,29 +64,25 @@ public: EDirty m_dirty; IdleDraw m_idleDraw; - WindowPositionTracker m_positionTracker; - GtkWindow* m_window; - GtkWidget* m_check; - GtkTreeView* m_tree_view; - GraphTreeModel* m_tree_model; + QWidget* m_window; + QCheckBox* m_check; + QTreeView* m_tree_view; + QAbstractItemModel* m_tree_model; bool m_selection_disabled; bool m_search_from_start; - scene::Node* m_search_focus_node; EntityList() : m_dirty( EntityList::eDefault ), m_idleDraw( RedrawEntityListCaller() ), m_window( 0 ), m_selection_disabled( false ), - m_search_from_start( false ), - m_search_focus_node( 0 ){ - m_positionTracker.setPosition( WindowPosition( -1, -1, 350, 500 ) ); + m_search_from_start( false ){ } bool visible() const { - return gtk_widget_get_visible( GTK_WIDGET( m_window ) ); + return m_window->isVisible(); } }; @@ -95,128 +96,34 @@ inline EntityList& getEntityList(){ } } - -inline Nameable* Node_getNameable( scene::Node& node ){ - return NodeTypeCast::cast( node ); +void entitylist_focusSelected( bool checked ){ + if( checked ) + FocusAllViews(); } -const char* node_get_name( scene::Node& node ){ - Nameable* nameable = Node_getNameable( node ); - return ( nameable != 0 ) - ? nameable->name() - : "node"; +template +void item_model_foreach( Functor f, QAbstractItemModel* model, QModelIndex parent = QModelIndex() ) +{ + if ( !parent.isValid() ) + parent = model->index( 0, 0, QModelIndex() ); + + const int numRows = model->rowCount( parent ); + + for ( int i = 0; i < numRows; ++i ) + item_model_foreach( f, model, model->index( i, 0, parent ) ); + + f( parent ); } -template -inline void gtk_tree_model_get_pointer( GtkTreeModel* model, GtkTreeIter* iter, gint column, value_type** pointer ){ - GValue value = GValue_default(); - gtk_tree_model_get_value( model, iter, column, &value ); - *pointer = (value_type*)g_value_get_pointer( &value ); -} - - - -void entitylist_treeviewcolumn_celldatafunc( GtkTreeViewColumn* column, GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter, gpointer data ){ - scene::Node* node; - gtk_tree_model_get_pointer( model, iter, 0, &node ); - scene::Instance* instance; - gtk_tree_model_get_pointer( model, iter, 1, &instance ); - if ( node != 0 ) { - gtk_cell_renderer_set_fixed_size( renderer, -1, -1 ); - char* name = const_cast( node_get_name( *node ) ); - g_object_set( G_OBJECT( renderer ), "text", name, "visible", TRUE, NULL ); - - //globalOutputStream() << "rendering cell " << makeQuoted(name) << "\n"; - GtkStyle* style = gtk_widget_get_style( GTK_WIDGET( getEntityList().m_tree_view ) ); - if ( instance->childSelected() ) { - g_object_set( G_OBJECT( renderer ), "cell-background-gdk", &style->base[GTK_STATE_ACTIVE], NULL ); +void EntityList_UpdateSelection( QAbstractItemModel* model, QTreeView* view ){ + item_model_foreach( [model, view]( QModelIndex &index ){ + scene::Instance* instance = static_cast( index.data( c_ItemDataRole_Instance ).value() ); + if ( Selectable* selectable = Instance_getSelectable( *instance ) ) { + view->selectionModel()->select( index, selectable->isSelected() + ? QItemSelectionModel::SelectionFlag::Select + : QItemSelectionModel::SelectionFlag::Deselect ); } - else - { - g_object_set( G_OBJECT( renderer ), "cell-background-gdk", &style->base[GTK_STATE_NORMAL], NULL ); - } - } - else - { - gtk_cell_renderer_set_fixed_size( renderer, -1, 0 ); - g_object_set( G_OBJECT( renderer ), "text", "", "visible", FALSE, NULL ); - } -} - -void entitylist_focusSelected( GtkButton *button, gpointer user_data ){ - FocusAllViews(); -} - -static gboolean entitylist_tree_select( GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer data ){ - GtkTreeIter iter; - gtk_tree_model_get_iter( model, &iter, path ); - scene::Node* node; - gtk_tree_model_get_pointer( model, &iter, 0, &node ); - scene::Instance* instance; - gtk_tree_model_get_pointer( model, &iter, 1, &instance ); - Selectable* selectable = Instance_getSelectable( *instance ); - - if ( node == 0 ) { - if ( path_currently_selected ) { - getEntityList().m_selection_disabled = true; - GlobalSelectionSystem().setSelectedAll( false ); - getEntityList().m_selection_disabled = false; - } - } - else if ( selectable != 0 ) { - getEntityList().m_selection_disabled = true; - selectable->setSelected( !path_currently_selected ); - getEntityList().m_selection_disabled = false; - if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( getEntityList().m_check ) ) ){ - FocusAllViews(); - } - return TRUE; - } - - return FALSE; -} - -static gboolean entitylist_tree_select_null( GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer data ){ - return TRUE; -} - -void EntityList_ConnectSignals( GtkTreeView* view ){ - GtkTreeSelection* select = gtk_tree_view_get_selection( view ); - gtk_tree_selection_set_select_function( select, entitylist_tree_select, NULL, 0 ); -} - -void EntityList_DisconnectSignals( GtkTreeView* view ){ - GtkTreeSelection* select = gtk_tree_view_get_selection( view ); - gtk_tree_selection_set_select_function( select, entitylist_tree_select_null, 0, 0 ); -} - - - -gboolean treemodel_update_selection( GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, gpointer data ){ - GtkTreeView* view = reinterpret_cast( data ); - - scene::Instance* instance; - gtk_tree_model_get_pointer( model, iter, 1, &instance ); - Selectable* selectable = Instance_getSelectable( *instance ); - - if ( selectable != 0 ) { - GtkTreeSelection* selection = gtk_tree_view_get_selection( view ); - if ( selectable->isSelected() ) { - gtk_tree_selection_select_path( selection, path ); - } - else - { - gtk_tree_selection_unselect_path( selection, path ); - } - } - - return FALSE; -} - -void EntityList_UpdateSelection( GtkTreeModel* model, GtkTreeView* view ){ - EntityList_DisconnectSignals( view ); - gtk_tree_model_foreach( model, treemodel_update_selection, view ); - EntityList_ConnectSignals( view ); + }, model ); } @@ -225,7 +132,7 @@ void RedrawEntityList(){ { case EntityList::eInsertRemove: case EntityList::eSelection: - EntityList_UpdateSelection( GTK_TREE_MODEL( getEntityList().m_tree_model ), getEntityList().m_tree_view ); + EntityList_UpdateSelection( getEntityList().m_tree_model, getEntityList().m_tree_view ); default: break; } @@ -237,6 +144,23 @@ void entitylist_queue_draw(){ } void EntityList_SelectionUpdate(){ + if( getEntityList().visible() ){ + // deselect tree items on deseletion in the scene for some degree of consistency + if( getEntityList().m_tree_view->selectionModel()->hasSelection() ){ + QTimer::singleShot( 0, [](){ + for( const auto& index : getEntityList().m_tree_view->selectionModel()->selectedRows( 0 ) ){ + scene::Instance* instance = static_cast( index.data( c_ItemDataRole_Instance ).value() ); + if ( Selectable* selectable = Instance_getSelectable( *instance ) ) + if( !selectable->isSelected() ) + getEntityList().m_tree_view->selectionModel()->select( index, QItemSelectionModel::SelectionFlag::Deselect ); + } + } ); + } + + getEntityList().m_tree_view->viewport()->update(); // reads in Qt::ItemDataRole::BackgroundRole of visible items + } + return; //. making actual selection is ULTRA SLOW :F thus using Qt::ItemDataRole::BackgroundRole instead + if ( getEntityList().m_selection_disabled ) { return; } @@ -251,21 +175,13 @@ void EntityList_SelectionChanged( const Selectable& selectable ){ EntityList_SelectionUpdate(); } -void entitylist_treeview_rowcollapsed( GtkTreeView* view, GtkTreeIter* iter, GtkTreePath* path, gpointer user_data ){ -} - -void entitylist_treeview_row_expanded( GtkTreeView* view, GtkTreeIter* iter, GtkTreePath* path, gpointer user_data ){ - EntityList_SelectionUpdate(); -} - void EntityList_SetShown( bool shown ){ - widget_set_visible( GTK_WIDGET( getEntityList().m_window ), shown ); + getEntityList().m_window->setVisible( shown ); if( shown ){ /* expand map's root node for convenience */ - GtkTreePath* path = gtk_tree_path_new_from_string( "1" ); - if( !gtk_tree_view_row_expanded( getEntityList().m_tree_view, path ) ) - gtk_tree_view_expand_row( getEntityList().m_tree_view, path, FALSE ); - gtk_tree_path_free( path ); + auto index = getEntityList().m_tree_model->index( 0, 0 ); + if( index.isValid() && !getEntityList().m_tree_view->isExpanded( index ) ) + getEntityList().m_tree_view->expand( index ); } } @@ -273,291 +189,157 @@ void EntityList_toggleShown(){ EntityList_SetShown( !getEntityList().visible() ); } -gint graph_tree_model_compare_name( GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data ){ - scene::Node* first; - gtk_tree_model_get( model, a, 0, (gpointer*)&first, -1 ); - scene::Node* second; - gtk_tree_model_get( model, b, 0, (gpointer*)&second, -1 ); - int result = 0; - if ( first != 0 && second != 0 ) { - result = string_compare( node_get_name( *first ), node_get_name( *second ) ); +class Filter_QLineEdit : public QLineEdit +{ +protected: + void enterEvent( QEvent *event ) override { + setFocus(); } - if ( result == 0 ) { - return ( first < second ) ? -1 : ( second < first ) ? 1 : 0; + void leaveEvent( QEvent *event ) override { + clearFocus(); } - return result; + bool event( QEvent *event ) override { + if( event->type() == QEvent::ShortcutOverride ){ + QKeyEvent *keyEvent = static_cast( event ); + if( keyEvent->key() == Qt::Key_Escape ){ + clear(); + event->accept(); + } + } + else if( event->type() == QEvent::Hide ){ + if( !text().isEmpty() ) + clear(); // workaround: reset filtering, as modification of tree after setRowHidden() is ULTRA SLOW + } + return QLineEdit::event( event ); + } +}; + +void searchEntrySetModeIcon( QAction *action, bool search_from_start ){ + action->setIcon( QApplication::style()->standardIcon( + search_from_start + ? QStyle::StandardPixmap::SP_CommandLink + : QStyle::StandardPixmap::SP_FileDialogContentsView ) ); } /* search */ -static gboolean tree_view_search_equal_func( GtkTreeModel* model, gint column, const gchar* key, GtkTreeIter* iter, gpointer search_from_start ) { - scene::Node* node; - gtk_tree_model_get( model, iter, column, (gpointer*)&node, -1 ); - /* return FALSE means match */ - return ( node && !node->isRoot() ) - ? *(bool*)search_from_start - ? !string_equal_prefix_nocase( node_get_name( *node ), key ) - : !string_in_string_nocase( node_get_name( *node ), key ) - : TRUE; -} +void tree_view_filter( const char *string, bool from_start ){ + const auto traverse = [=]( const auto& self, QAbstractItemModel* model, QTreeView *tree, QModelIndex parent = QModelIndex() ) -> bool { + if ( !parent.isValid() ) + parent = model->index( 0, 0, QModelIndex() ); -void searchEntrySetModeIcon( GtkEntry* entry, bool search_from_start ){ - gtk_entry_set_icon_from_stock( entry, GTK_ENTRY_ICON_PRIMARY, search_from_start? GTK_STOCK_MEDIA_PLAY : GTK_STOCK_ABOUT ); - g_signal_emit_by_name( G_OBJECT( entry ), "changed" ); -} + const int numRows = model->rowCount( parent ); -void searchEntryIconPress( GtkEntry* entry, gint position, GdkEventButton* event, gpointer user_data ) { - if( position == GTK_ENTRY_ICON_PRIMARY ){ - getEntityList().m_search_from_start = !getEntityList().m_search_from_start; - searchEntrySetModeIcon( entry, getEntityList().m_search_from_start ); - } -} + bool childVisible = false; -gboolean searchEntryFocus( GtkWidget *widget, GdkEvent *event, gpointer user_data ){ - gtk_widget_grab_focus( widget ); - return FALSE; -} + for ( int i = 0; i < numRows; ++i ) + childVisible |= self( self, model, tree, model->index( i, 0, parent ) ); -gboolean searchEntryUnfocus( GtkWidget *widget, GdkEvent *event, gpointer user_data ){ - gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( widget ) ), NULL ); - return FALSE; -} + const bool visible = childVisible || string_empty( string ) + || ( from_start && string_equal_prefix_nocase( parent.data( Qt::ItemDataRole::DisplayRole ).toString().toLatin1().constData(), string ) ) + || ( !from_start && string_in_string_nocase( parent.data( Qt::ItemDataRole::DisplayRole ).toString().toLatin1().constData(), string ) ); + tree->setRowHidden( parent.row(), parent.parent(), !visible ); -gboolean searchEntryScroll( GtkWidget* widget, GdkEventScroll* event, gpointer user_data ){ -// globalOutputStream() << "scroll\n"; - if( string_empty( gtk_entry_get_text( GTK_ENTRY( widget ) ) ) ){ /* scroll through selected/child selected entities */ - GtkTreeModel* model = gtk_tree_view_get_model( getEntityList().m_tree_view ); - GtkTreePath* path0 = gtk_tree_path_new_from_string( "1" ); - GtkTreeIter iter0, iter, iter_first, iter_prev, iter_found, iter_next; - iter_first.stamp = iter_prev.stamp = iter_found.stamp = iter_next.stamp = 0; - if( gtk_tree_model_get_iter( model, &iter0, path0 ) ){ - if( gtk_tree_model_iter_children( model, &iter, &iter0 ) ) { - do{ - scene::Node* node; - gtk_tree_model_get_pointer( model, &iter, 0, &node ); - if( node ){ - scene::Instance* instance; - gtk_tree_model_get_pointer( model, &iter, 1, &instance ); - if( Instance_isSelected( *instance ) || instance->childSelected() ){ - if( iter_first.stamp == 0 ){ - iter_first = iter; - } - if( iter_found.stamp != 0 ){ - iter_next = iter; - break; - } - if( node == getEntityList().m_search_focus_node ){ - iter_found = iter; - } - else{ - iter_prev = iter; - } - } - } - } while( gtk_tree_model_iter_next( model, &iter ) ); - } - } - iter.stamp = 0; - if( iter_found.stamp != 0 ){ - iter = iter_found; - if( event->direction == GDK_SCROLL_DOWN ){ - if( iter_next.stamp != 0 ){ - iter = iter_next; - } - } - else{ - if( iter_prev.stamp != 0 ){ - iter = iter_prev; - } - } - } - else if( iter_first.stamp != 0 ){ - iter = iter_first; - } - if( iter.stamp != 0 ){ - gtk_tree_model_get_pointer( model, &iter, 0, &getEntityList().m_search_focus_node ); - GtkTreePath* path = gtk_tree_model_get_path( model, &iter ); - gtk_tree_view_scroll_to_cell( getEntityList().m_tree_view, path, 0, TRUE, .5f, 0.f ); - gtk_tree_path_free( path ); - } - gtk_tree_path_free( path0 ); - return FALSE; - } - /* hijack internal gtk keypress function for handling scroll via synthesized event */ - GdkEvent* eventmp = gdk_event_new( GDK_KEY_PRESS ); - if ( event->direction == GDK_SCROLL_UP ) { - eventmp->key.keyval = GDK_KEY_Up; - } - else if ( event->direction == GDK_SCROLL_DOWN ) { - eventmp->key.keyval = GDK_KEY_Down; - } - if( eventmp->key.keyval ){ - eventmp->key.window = gtk_widget_get_window( widget ); - if( eventmp->key.window ) - g_object_ref( eventmp->key.window ); - gtk_widget_event( widget, eventmp ); -// gtk_window_propagate_key_event( GTK_WINDOW( gtk_widget_get_toplevel( widget ) ), (GdkEventKey*)eventmp ); -// gtk_main_do_event( eventmp ); -// gdk_event_put( eventmp ); - } - gdk_event_free( eventmp ); - return FALSE; -} + return childVisible || visible; + }; -static gboolean searchEntryKeypress( GtkEntry* widget, GdkEventKey* event, gpointer user_data ){ - if ( event->keyval == GDK_KEY_Escape ) { - gtk_entry_set_text( GTK_ENTRY( widget ), "" ); - return TRUE; - } - return FALSE; + traverse( traverse, getEntityList().m_tree_model, getEntityList().m_tree_view ); } -extern GraphTreeModel* scene_graph_get_tree_model(); + +extern QAbstractItemModel* scene_graph_get_tree_model(); void AttachEntityTreeModel(){ getEntityList().m_tree_model = scene_graph_get_tree_model(); + getEntityList().m_tree_view->setModel( getEntityList().m_tree_model ); - gtk_tree_view_set_model( getEntityList().m_tree_view, GTK_TREE_MODEL( getEntityList().m_tree_model ) ); - - gtk_tree_view_set_search_column( getEntityList().m_tree_view, 0 ); + QObject::connect( getEntityList().m_tree_view->selectionModel(), &QItemSelectionModel::selectionChanged, + []( const QItemSelection &selected, const QItemSelection &deselected ){ + for( const auto& index : deselected.indexes() ){ + scene::Instance* instance = static_cast( index.data( c_ItemDataRole_Instance ).value() ); + if( Selectable* selectable = Instance_getSelectable( *instance ) ) + selectable->setSelected( false ); + } + for( const auto& index : selected.indexes() ){ + scene::Instance* instance = static_cast( index.data( c_ItemDataRole_Instance ).value() ); + if( Selectable* selectable = Instance_getSelectable( *instance ) ) + selectable->setSelected( true ); + } + if( !selected.empty() && getEntityList().m_check->isChecked() ) + FocusAllViews(); + } ); } void DetachEntityTreeModel(){ getEntityList().m_tree_model = 0; - - gtk_tree_view_set_model( getEntityList().m_tree_view, 0 ); + getEntityList().m_tree_view->setModel( nullptr ); } -void EntityList_constructWindow( GtkWindow* main_window ){ +void EntityList_constructWindow( QWidget* main_window ){ ASSERT_MESSAGE( getEntityList().m_window == 0, "error" ); - GtkWindow* window = create_persistent_floating_window( "Entity List", main_window ); - - //gtk_window_add_accel_group( window, global_accel ); - global_accel_connect_window( window ); - - getEntityList().m_positionTracker.connect( window ); - - - getEntityList().m_window = window; + auto window = getEntityList().m_window = new QWidget( main_window, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + window->setWindowTitle( "Entity List" ); + g_guiSettings.addWindow( window, "EntityList/geometry", 350, 500 ); { - GtkVBox* vbox = GTK_VBOX( gtk_vbox_new( FALSE, 0 ) ); - gtk_container_set_border_width( GTK_CONTAINER( vbox ), 0 ); - gtk_widget_show( GTK_WIDGET( vbox ) ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox ) ); - - GtkScrolledWindow* scr = create_scrolled_window( GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); - //gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( scr ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( scr ), TRUE, TRUE, 0 ); - + auto *vbox = new QVBoxLayout( window ); + vbox->setContentsMargins( 0, 0, 0, 0 ); { - GtkWidget* view = gtk_tree_view_new(); - gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), FALSE ); - - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - GtkTreeViewColumn* column = gtk_tree_view_column_new(); - gtk_tree_view_column_pack_start( column, renderer, TRUE ); - gtk_tree_view_column_set_cell_data_func( column, renderer, entitylist_treeviewcolumn_celldatafunc, 0, 0 ); - - GtkTreeSelection* select = gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) ); - gtk_tree_selection_set_mode( select, GTK_SELECTION_MULTIPLE ); - - g_signal_connect( G_OBJECT( view ), "row_expanded", G_CALLBACK( entitylist_treeview_row_expanded ), 0 ); - g_signal_connect( G_OBJECT( view ), "row_collapsed", G_CALLBACK( entitylist_treeview_rowcollapsed ), 0 ); - - gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column ); - - gtk_widget_show( view ); - gtk_container_add( GTK_CONTAINER( scr ), view ); - getEntityList().m_tree_view = GTK_TREE_VIEW( view ); + auto *tree = getEntityList().m_tree_view = new QTreeView; + tree->setHeaderHidden( true ); + tree->setEditTriggers( QAbstractItemView::EditTrigger::NoEditTriggers ); + tree->setUniformRowHeights( true ); // optimization + tree->setSizeAdjustPolicy( QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents ); // scroll area will inherit column size + tree->header()->setStretchLastSection( false ); // non greedy column sizing; + QHeaderView::ResizeMode::ResizeToContents = no text elision 🤷‍♀️ + tree->header()->setSectionResizeMode( QHeaderView::ResizeMode::ResizeToContents ); + tree->setSelectionMode( QAbstractItemView::SelectionMode::ExtendedSelection ); + vbox->addWidget( tree ); } { - GtkHBox* hbox = GTK_HBOX( gtk_hbox_new( FALSE, 0 ) ); - gtk_container_set_border_width( GTK_CONTAINER( hbox ), 0 ); - gtk_widget_show( GTK_WIDGET( hbox ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox ), FALSE, FALSE, 0 ); + auto *hbox = new QHBoxLayout; + vbox->addLayout( hbox ); { - GtkWidget* check = gtk_check_button_new_with_label( "AutoFocus on Selection" ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( check ), FALSE ); - gtk_widget_show( check ); - gtk_box_pack_start( GTK_BOX( hbox ), check, FALSE, FALSE, 0 ); - getEntityList().m_check = check; - g_signal_connect( G_OBJECT( check ), "clicked", G_CALLBACK( entitylist_focusSelected ), 0 ); + auto *check = getEntityList().m_check = new QCheckBox( "AutoFocus on Selection" ); + hbox->addWidget( check ); + QObject::connect( check, &QAbstractButton::clicked, entitylist_focusSelected ); } { //search entry - GtkWidget* entry = gtk_entry_new(); - gtk_box_pack_start( GTK_BOX( hbox ), entry, TRUE, TRUE, 8 ); - searchEntrySetModeIcon( GTK_ENTRY( entry ), getEntityList().m_search_from_start ); - gtk_entry_set_icon_tooltip_text( GTK_ENTRY( entry ), GTK_ENTRY_ICON_PRIMARY, "toggle search mode ( start / any position )" ); - gtk_widget_show( entry ); - g_signal_connect( G_OBJECT( entry ), "icon-press", G_CALLBACK( searchEntryIconPress ), 0 ); - g_signal_connect( G_OBJECT( entry ), "enter_notify_event", G_CALLBACK( searchEntryFocus ), 0 ); - g_signal_connect( G_OBJECT( entry ), "leave_notify_event", G_CALLBACK( searchEntryUnfocus ), 0 ); - g_signal_connect( G_OBJECT( entry ), "scroll_event", G_CALLBACK( searchEntryScroll ), 0 ); - g_signal_connect( G_OBJECT( entry ), "key_press_event", G_CALLBACK( searchEntryKeypress ), 0 ); - gtk_tree_view_set_search_entry( getEntityList().m_tree_view, GTK_ENTRY( entry ) ); - gtk_tree_view_set_search_equal_func( getEntityList().m_tree_view, (GtkTreeViewSearchEqualFunc)tree_view_search_equal_func, &getEntityList().m_search_from_start, 0 ); + QLineEdit *entry = new Filter_QLineEdit; + hbox->addWidget( entry ); + entry->setClearButtonEnabled( true ); + entry->setFocusPolicy( Qt::FocusPolicy::ClickFocus ); + + QAction *action = entry->addAction( QApplication::style()->standardIcon( QStyle::StandardPixmap::SP_CommandLink ), QLineEdit::LeadingPosition ); + searchEntrySetModeIcon( action, getEntityList().m_search_from_start ); + action->setToolTip( "toggle match mode ( start / any position )" ); + + QObject::connect( entry, &QLineEdit::textChanged, []( const QString& text ){ + tree_view_filter( text.toLatin1().constData(), getEntityList().m_search_from_start ); + } ); + QObject::connect( action, &QAction::triggered, [action, entry](){ + getEntityList().m_search_from_start ^= 1; + searchEntrySetModeIcon( action, getEntityList().m_search_from_start ); + entry->textChanged( entry->text() ); // trigger filtering update + } ); } } } - EntityList_ConnectSignals( getEntityList().m_tree_view ); AttachEntityTreeModel(); } void EntityList_destroyWindow(){ DetachEntityTreeModel(); - EntityList_DisconnectSignals( getEntityList().m_tree_view ); - destroy_floating_window( getEntityList().m_window ); + delete getEntityList().m_window; } #include "preferencesystem.h" -#include "iselection.h" - -namespace -{ -scene::Node* nullNode = 0; -} - -class NullSelectedInstance : public scene::Instance, public Selectable -{ - class TypeCasts - { - InstanceTypeCastTable m_casts; - public: - TypeCasts(){ - InstanceStaticCast::install( m_casts ); - } - InstanceTypeCastTable& get(){ - return m_casts; - } - }; - -public: - typedef LazyStatic StaticTypeCasts; - - NullSelectedInstance() : Instance( scene::Path( makeReference( *nullNode ) ), 0, this, StaticTypeCasts::instance().get() ){ - } - - void setSelected( bool select ){ - ERROR_MESSAGE( "error" ); - } - bool isSelected() const { - return true; - } -}; - -typedef LazyStatic StaticNullSelectedInstance; - #include "stringio.h" void EntityList_Construct(){ - graph_tree_model_insert( scene_graph_get_tree_model(), StaticNullSelectedInstance::instance() ); - g_EntityList = new EntityList; - GlobalPreferenceSystem().registerPreference( "EntityInfoDlg", WindowPositionTrackerImportStringCaller( getEntityList().m_positionTracker ), WindowPositionTrackerExportStringCaller( getEntityList().m_positionTracker ) ); GlobalPreferenceSystem().registerPreference( "EntListSearchFromStart", BoolImportStringCaller( getEntityList().m_search_from_start ), BoolExportStringCaller( getEntityList().m_search_from_start ) ); typedef FreeCaller1 EntityListSelectionChangedCaller; @@ -565,6 +347,4 @@ void EntityList_Construct(){ } void EntityList_Destroy(){ delete g_EntityList; - - graph_tree_model_erase( scene_graph_get_tree_model(), StaticNullSelectedInstance::instance() ); } diff --git a/radiant/entitylist.h b/radiant/entitylist.h index 629dafdd..f19b917f 100644 --- a/radiant/entitylist.h +++ b/radiant/entitylist.h @@ -24,7 +24,6 @@ void EntityList_Construct(); void EntityList_Destroy(); -typedef struct _GtkWindow GtkWindow; -void EntityList_constructWindow( GtkWindow* main_window ); +void EntityList_constructWindow( class QWidget* main_window ); void EntityList_destroyWindow(); void EntityList_toggleShown(); diff --git a/radiant/error.cpp b/radiant/error.cpp index eed1aa03..c6911eee 100644 --- a/radiant/error.cpp +++ b/radiant/error.cpp @@ -88,7 +88,7 @@ void Error( const char *error, ... ){ { scan = next; text[strlen( text ) + 1] = '\0'; - if ( ( scan[0] >= 0 ) && ( scan[0] <= 127 ) ) { + if ( scan[0] >= 0 ) { text[strlen( text )] = char(scan[0]); } else{ @@ -114,7 +114,7 @@ void Error( const char *error, ... ){ // glGetError .. can record several errors, clears after calling //++timo TODO: be able to deal with several errors if necessary, for now I'm just warning about pending error messages // NOTE: forget that, most boards don't seem to follow the OpenGL standard - GLenum iGLError = glGetError(); + GLenum iGLError = gl().glGetError(); if ( iGLError != GL_NO_ERROR ) { // use our own gluErrorString strcat( text, "gluErrorString: " ); diff --git a/radiant/feedback.cpp b/radiant/feedback.cpp index f9a02225..95559313 100644 --- a/radiant/feedback.cpp +++ b/radiant/feedback.cpp @@ -32,7 +32,9 @@ #include "igl.h" #include "iselection.h" -#include +#include +#include +#include #include "map.h" #include "dialog.h" @@ -128,17 +130,17 @@ void CPointMsg::DropHighlight(){ void CPointMsg::Draw2D( VIEWTYPE vt ){ NDIM1NDIM2( vt ) - glPointSize( 4 ); - glColor3f( 1.0f,0.0f,0.0f ); - glBegin( GL_POINTS ); - glVertex2f( pt[nDim1], pt[nDim2] ); - glEnd(); - glBegin( GL_LINE_LOOP ); - glVertex2f( pt[nDim1] - 8, pt[nDim2] - 8 ); - glVertex2f( pt[nDim1] + 8, pt[nDim2] - 8 ); - glVertex2f( pt[nDim1] + 8, pt[nDim2] + 8 ); - glVertex2f( pt[nDim1] - 8, pt[nDim2] + 8 ); - glEnd(); + gl().glPointSize( 4 ); + gl().glColor3f( 1.0f,0.0f,0.0f ); + gl().glBegin( GL_POINTS ); + gl().glVertex2f( pt[nDim1], pt[nDim2] ); + gl().glEnd(); + gl().glBegin( GL_LINE_LOOP ); + gl().glVertex2f( pt[nDim1] - 8, pt[nDim2] - 8 ); + gl().glVertex2f( pt[nDim1] + 8, pt[nDim2] - 8 ); + gl().glVertex2f( pt[nDim1] + 8, pt[nDim2] + 8 ); + gl().glVertex2f( pt[nDim1] - 8, pt[nDim2] + 8 ); + gl().glEnd(); } void CWindingMsg::saxStartElement( message_info_t *ctx, const xmlChar *name, const xmlChar **attrs ){ @@ -200,36 +202,32 @@ void CWindingMsg::Draw2D( VIEWTYPE vt ){ int i; NDIM1NDIM2( vt ) - glColor3f( 1.0f,0.f,0.0f ); + gl().glColor3f( 1.0f,0.f,0.0f ); - glPointSize( 4 ); - glBegin( GL_POINTS ); + gl().glPointSize( 4 ); + gl().glBegin( GL_POINTS ); for ( i = 0; i < numpoints; i++ ) - glVertex2f( wt[i][nDim1], wt[i][nDim2] ); - glEnd(); - glPointSize( 1 ); + gl().glVertex2f( wt[i][nDim1], wt[i][nDim2] ); + gl().glEnd(); + gl().glPointSize( 1 ); - glEnable( GL_BLEND ); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - glColor4f( 0.133f,0.4f,1.0f,0.5f ); - glBegin( GL_POLYGON ); + gl().glEnable( GL_BLEND ); + gl().glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + gl().glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + gl().glColor4f( 0.133f,0.4f,1.0f,0.5f ); + gl().glBegin( GL_POLYGON ); for ( i = 0; i < numpoints; i++ ) - glVertex2f( wt[i][nDim1], wt[i][nDim2] ); - glEnd(); - glDisable( GL_BLEND ); + gl().glVertex2f( wt[i][nDim1], wt[i][nDim2] ); + gl().glEnd(); + gl().glDisable( GL_BLEND ); } // triggered when the user selects an entry in the feedback box -static void feedback_selection_changed( GtkTreeSelection* selection, gpointer data ){ - g_DbgDlg.DropHighlight(); +void CDbgDlg::feedback_selection_changed( QTreeWidgetItem *current ){ + DropHighlight(); - GtkTreeModel* model; - GtkTreeIter selected; - if ( gtk_tree_selection_get_selected( selection, &model, &selected ) ) { - GtkTreePath* path = gtk_tree_model_get_path( model, &selected ); - g_DbgDlg.SetHighlight( gtk_tree_path_get_indices( path )[0] ); - gtk_tree_path_free( path ); + if( current != nullptr ){ + SetHighlight( m_clist->indexOfTopLevelItem( current ) ); } } @@ -241,88 +239,59 @@ void CDbgDlg::DropHighlight(){ } } -void CDbgDlg::SetHighlight( gint row ){ - ISAXHandler *h = GetElement( row ); - if ( h != NULL ) { +void CDbgDlg::SetHighlight( std::size_t row ){ + if ( ISAXHandler *h = m_feedbackElements.at( row ) ) { m_pDraw2D = h->Highlight(); m_pHighlight = h; } } -ISAXHandler *CDbgDlg::GetElement( std::size_t row ){ - return static_cast( g_ptr_array_index( m_pFeedbackElements, gint( row ) ) ); -} - void CDbgDlg::Init(){ DropHighlight(); // free all the ISAXHandler*, clean it - while ( m_pFeedbackElements->len ) - { - static_cast( g_ptr_array_index( m_pFeedbackElements, 0 ) )->Release(); - g_ptr_array_remove_index( m_pFeedbackElements, 0 ); - } + for( auto *e : m_feedbackElements ) + e->Release(); + m_feedbackElements.clear(); if ( m_clist != NULL ) { - gtk_list_store_clear( m_clist ); + m_clist->clear(); } } void CDbgDlg::Push( ISAXHandler *pHandler ){ // push in the list - g_ptr_array_add( m_pFeedbackElements, (void *)pHandler ); + m_feedbackElements.push_back( pHandler ); if ( GetWidget() == 0 ) { - Create(); + Create( MainFrame_getWindow() ); } // put stuff in the list - gtk_list_store_clear( m_clist ); - for ( std::size_t i = 0; i < static_cast( m_pFeedbackElements->len ); ++i ) + m_clist->clear(); + for ( auto *element : m_feedbackElements ) { - GtkTreeIter iter; - gtk_list_store_append( m_clist, &iter ); - gtk_list_store_set( m_clist, &iter, 0, GetElement( i )->getName(), -1 ); + auto *item = new QTreeWidgetItem( m_clist ); + item->setText( 0, element->getName() ); } ShowDlg(); } -GtkWindow* CDbgDlg::BuildDialog(){ - GtkWindow* window = create_floating_window( "Q3Map debug window", MainFrame_getWindow() ); +void CDbgDlg::BuildDialog(){ + GetWidget()->setWindowTitle( "Q3Map debug window" ); - GtkWidget* scr = gtk_scrolled_window_new( NULL, NULL ); - gtk_widget_show( scr ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( scr ) ); - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC ); - gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN ); + auto *tree = m_clist = new QTreeWidget; + ( new QVBoxLayout( GetWidget() ) )->addWidget( tree ); + tree->setColumnCount( 1 ); + tree->setUniformRowHeights( true ); // optimization + tree->setHorizontalScrollBarPolicy( Qt::ScrollBarPolicy::ScrollBarAlwaysOff ); + tree->setSizeAdjustPolicy( QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents ); // scroll area will inherit column size + tree->header()->setStretchLastSection( false ); // non greedy column sizing + tree->header()->setSectionResizeMode( QHeaderView::ResizeMode::ResizeToContents ); // no text elision + tree->setHeaderHidden( true ); + tree->setRootIsDecorated( false ); + tree->setEditTriggers( QAbstractItemView::EditTrigger::NoEditTriggers ); - { - GtkListStore* store = gtk_list_store_new( 1, G_TYPE_STRING ); - - GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) ); - gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), FALSE ); - - { - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "", renderer, "text", 0, NULL ); - gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column ); - } - - { - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) ); - gtk_tree_selection_set_mode( selection, GTK_SELECTION_BROWSE ); - g_signal_connect( G_OBJECT( selection ), "changed", G_CALLBACK( feedback_selection_changed ), NULL ); - } - - gtk_widget_show( view ); - - gtk_container_add( GTK_CONTAINER( scr ), view ); - - g_object_unref( G_OBJECT( store ) ); - - m_clist = store; - } - - return window; + QObject::connect( tree, &QTreeWidget::currentItemChanged, [this]( QTreeWidgetItem *current ){ feedback_selection_changed( current ); } ); } diff --git a/radiant/feedback.h b/radiant/feedback.h index 36c4242a..2b988aeb 100644 --- a/radiant/feedback.h +++ b/radiant/feedback.h @@ -29,7 +29,6 @@ #include "math/vector.h" #include "stream/stringstream.h" -#include #include "xmlstuff.h" #include "dialog.h" #include "xywindow.h" @@ -163,28 +162,23 @@ public: void Draw2D( VIEWTYPE vt ); }; -typedef struct _GtkListStore GtkListStore; - class CDbgDlg : public Dialog { - GPtrArray *m_pFeedbackElements; + std::vector m_feedbackElements; // the list widget we use in the dialog - GtkListStore* m_clist; - ISAXHandler *m_pHighlight; - IGL2DWindow* m_pDraw2D; + class QTreeWidget *m_clist{}; + ISAXHandler *m_pHighlight{}; + IGL2DWindow* m_pDraw2D{}; public: - CDbgDlg(){ - m_pFeedbackElements = g_ptr_array_new(); - m_pHighlight = NULL; - m_pDraw2D = NULL; - } // refresh items void Push( ISAXHandler * ); // clean the debug window, release all ISAXHanlders we have void Init(); - ISAXHandler *GetElement( std::size_t row ); - void SetHighlight( gint row ); +private: + void feedback_selection_changed( class QTreeWidgetItem *current ); + void SetHighlight( std::size_t row ); void DropHighlight(); +public: void draw2D( VIEWTYPE viewType ){ if ( m_pDraw2D != 0 ) { m_pDraw2D->Draw2D( viewType ); @@ -197,7 +191,7 @@ public: } // void HideDlg(); protected: - GtkWindow* BuildDialog(); + void BuildDialog() override; }; extern CDbgDlg g_DbgDlg; diff --git a/radiant/filterbar.cpp b/radiant/filterbar.cpp index 79a3d855..6ed0bfd8 100644 --- a/radiant/filterbar.cpp +++ b/radiant/filterbar.cpp @@ -1,5 +1,4 @@ #include "filterbar.h" -#include #include "gtkmisc.h" #include "gtkutil/widget.h" #include "gtkutil/toolbar.h" @@ -12,6 +11,9 @@ #include "gtkutil/accelerator.h" #include "generic/callback.h" +#include +#include + #include "entity.h" @@ -50,132 +52,148 @@ const char* GetCaulkShader(){ class CommonFunc { - const std::vector m_funcStrings; public: - CommonFunc( GtkToggleToolButton* button, const std::vector&& funcStrings ) : m_funcStrings( funcStrings ){ - g_signal_connect( G_OBJECT( gtk_bin_get_child( GTK_BIN( button ) ) ), "button_press_event", G_CALLBACK( texFunc ), this ); - } - CommonFunc( GtkToggleToolButton* button, const char* funcStrings ) : m_funcStrings( 1, funcStrings ){ - g_signal_connect( G_OBJECT( gtk_bin_get_child( GTK_BIN( button ) ) ), "button_press_event", G_CALLBACK( commandFunc ), this ); - } - static std::size_t m_toggleFuncNum; - static CommonFunc* m_recentFunc; - static gboolean resetToggleFuncNum( GtkWidget *widget, GdkEvent *event, gpointer user_data ){ - m_toggleFuncNum = 0; - // globalOutputStream() << "resetToggleFuncNum\n"; - return FALSE; - } - static gboolean texFunc( GtkWidget *widget, GdkEventButton *event, gpointer data ){ - CommonFunc* self = reinterpret_cast( data ); - if ( event->button == 3 && event->type == GDK_BUTTON_PRESS ) { - if ( m_recentFunc != self ){ - m_toggleFuncNum = 0; - m_recentFunc = self; - } - else{ - m_toggleFuncNum %= self->m_funcStrings.size(); - } + static inline CommonFunc* m_recentFunc{}; + virtual void exec() = 0; +}; - SetCommonShader( self->m_funcStrings[m_toggleFuncNum] ); - ++m_toggleFuncNum; - return TRUE; +class CommonFunc_tex : public CommonFunc +{ + const std::vector m_texNames; + std::size_t m_toggleTexNum{}; +public: + CommonFunc_tex( const std::vector&& texNames ) : m_texNames( std::move( texNames ) ){} + void exec() override { + if ( m_recentFunc != this ){ + m_toggleTexNum = 0; + m_recentFunc = this; } - return FALSE; - } - static gboolean commandFunc( GtkWidget *widget, GdkEventButton *event, gpointer data ){ - CommonFunc* self = reinterpret_cast( data ); - if ( event->button == 3 && event->type == GDK_BUTTON_PRESS ) { - GlobalCommands_find( self->m_funcStrings[0] ).m_callback(); - m_toggleFuncNum = 0; - m_recentFunc = self; - return TRUE; + else{ + m_toggleTexNum %= m_texNames.size(); } - return FALSE; + + SetCommonShader( m_texNames[m_toggleTexNum] ); + ++m_toggleTexNum; } }; -std::size_t CommonFunc::m_toggleFuncNum = 0; -CommonFunc* CommonFunc::m_recentFunc = nullptr; - -static std::list g_commonFuncs; - - -gboolean Func_Groups_button_press( GtkWidget *widget, GdkEventButton *event, gpointer data ){ - if ( event->button == 3 && event->type == GDK_BUTTON_PRESS ) { - Entity_createFromSelection( "func_group", g_vector3_identity ); - CommonFunc::m_toggleFuncNum = 0; - return TRUE; +class CommonFunc_command : public CommonFunc +{ + const char * const m_commandName; +public: + CommonFunc_command( const char* commandName ) : m_commandName( commandName ){} + void exec() override { + GlobalCommands_find( m_commandName ).m_callback(); + m_recentFunc = this; } - return FALSE; +}; + +class CommonFunc_group : public CommonFunc +{ +public: + void exec() override { + Entity_createFromSelection( "func_group", g_vector3_identity ); + m_recentFunc = this; + } +}; + + +class FilterToolbarHandler : public QObject +{ +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick ){ + QMouseEvent *mouseEvent = static_cast( event ); + if( mouseEvent->button() == Qt::MouseButton::RightButton ){ + QAction *action = m_toolbar->actionAt( mouseEvent->pos() ); + if( action != nullptr ){ + auto it = m_actions.find( action ); + if( it != m_actions.end() ){ + it->second->exec(); + return true; + } + } + } + } + else if( event->type() == QEvent::ContextMenu ){ // suppress context menu + return true; + } + else if( event->type() == QEvent::Enter ){ + CommonFunc::m_recentFunc = nullptr; + } + return QObject::eventFilter( obj, event ); // standard event processing + } +public: + std::map> m_actions; + static inline const QToolBar *m_toolbar{}; } +g_filter_toolbar_handler; -GtkToolbar* create_filter_toolbar(){ - GtkToolbar* toolbar = toolbar_new(); - g_signal_connect( G_OBJECT( toolbar ), "enter_notify_event", G_CALLBACK( CommonFunc::resetToggleFuncNum ), 0 ); +void create_filter_toolbar( QToolBar *toolbar ){ + g_filter_toolbar_handler.m_toolbar = toolbar; + toolbar->installEventFilter( &g_filter_toolbar_handler ); - GtkToggleToolButton* button; + QAction* button; - toolbar_append_toggle_button( toolbar, "World (ALT + 1)", "f-world.png", "FilterWorldBrushes" ); + toolbar_append_toggle_button( toolbar, "World", "f-world.png", "FilterWorldBrushes" ); - button = toolbar_append_toggle_button( toolbar, "Structural (CTRL + SHIFT + D)\nRightClick: MakeStructural", "f-structural.png", "FilterStructural" ); - g_commonFuncs.emplace_back( button, "MakeStructural" ); + button = toolbar_append_toggle_button( toolbar, "Structural\nRightClick: MakeStructural", "f-structural.png", "FilterStructural" ); + g_filter_toolbar_handler.m_actions.emplace( button, new CommonFunc_command( "MakeStructural" ) ); - button = toolbar_append_toggle_button( toolbar, "Details (CTRL + D)\nRightClick: MakeDetail", "f-details.png", "FilterDetails" ); - g_commonFuncs.emplace_back( button, "MakeDetail" ); + button = toolbar_append_toggle_button( toolbar, "Details\nRightClick: MakeDetail", "f-details.png", "FilterDetails" ); + g_filter_toolbar_handler.m_actions.emplace( button, new CommonFunc_command( "MakeDetail" ) ); button = toolbar_append_toggle_button( toolbar, "Func_Groups\nRightClick: create func_group", "f-funcgroups.png", "FilterFuncGroups" ); - g_signal_connect( G_OBJECT( gtk_bin_get_child( GTK_BIN( button ) ) ), "button_press_event", G_CALLBACK( Func_Groups_button_press ), 0 ); + g_filter_toolbar_handler.m_actions.emplace( button, new CommonFunc_group ); - toolbar_append_toggle_button( toolbar, "Patches (CTRL + P)", "patch_wireframe.png", "FilterPatches" ); - toolbar_append_space( toolbar ); + toolbar_append_toggle_button( toolbar, "Patches", "patch_wireframe.png", "FilterPatches" ); + toolbar->addSeparator(); // if ( g_pGameDescription->mGameType == "doom3" ) { -// button = toolbar_append_toggle_button( toolbar, "Visportals (ALT + 3)", "f-areaportal.png", "FilterVisportals" ); +// button = toolbar_append_toggle_button( toolbar, "Visportals", "f-areaportal.png", "FilterVisportals" ); // } // else{ -// button = toolbar_append_toggle_button( toolbar, "Areaportals (ALT + 3)", "f-areaportal.png", "FilterAreaportals" ); +// button = toolbar_append_toggle_button( toolbar, "Areaportals", "f-areaportal.png", "FilterAreaportals" ); // } - button = toolbar_append_toggle_button( toolbar, "Translucent (ALT + 4)\nRightClick: toggle tex\n\tnoDraw\n\tnoDrawNonSolid", "f-translucent.png", "FilterTranslucent" ); - g_commonFuncs.emplace_back( button, std::vector{ "nodraw", "nodrawnonsolid" } ); + button = toolbar_append_toggle_button( toolbar, "Translucent\nRightClick: toggle tex\n\tnoDraw\n\tnoDrawNonSolid", "f-translucent.png", "FilterTranslucent" ); + g_filter_toolbar_handler.m_actions.emplace( button, new CommonFunc_tex( std::vector{ "nodraw", "nodrawnonsolid" } ) ); - button = toolbar_append_toggle_button( toolbar, "Liquids (ALT + 5)\nRightClick: toggle tex\n\twaterCaulk\n\tlavaCaulk\n\tslimeCaulk", "f-liquids.png", "FilterLiquids" ); - g_commonFuncs.emplace_back( button, std::vector{ "watercaulk", "lavacaulk", "slimecaulk" } ); + button = toolbar_append_toggle_button( toolbar, "Liquids\nRightClick: toggle tex\n\twaterCaulk\n\tlavaCaulk\n\tslimeCaulk", "f-liquids.png", "FilterLiquids" ); + g_filter_toolbar_handler.m_actions.emplace( button, new CommonFunc_tex( std::vector{ "watercaulk", "lavacaulk", "slimecaulk" } ) ); - button = toolbar_append_toggle_button( toolbar, "Caulk (ALT + 6)\nRightClick: tex Caulk", "f-caulk.png", "FilterCaulk" ); - g_commonFuncs.emplace_back( button, std::vector{ "caulk" } ); + button = toolbar_append_toggle_button( toolbar, "Caulk\nRightClick: tex Caulk", "f-caulk.png", "FilterCaulk" ); + g_filter_toolbar_handler.m_actions.emplace( button, new CommonFunc_tex( std::vector{ "caulk" } ) ); - button = toolbar_append_toggle_button( toolbar, "Clips (ALT + 7)\nRightClick: toggle tex\n\tplayerClip\n\tweapClip", "f-clip.png", "FilterClips" ); - g_commonFuncs.emplace_back( button, std::vector{ "clip", "weapclip" } ); + button = toolbar_append_toggle_button( toolbar, "Clips\nRightClick: toggle tex\n\tplayerClip\n\tweapClip", "f-clip.png", "FilterClips" ); + g_filter_toolbar_handler.m_actions.emplace( button, new CommonFunc_tex( std::vector{ "clip", "weapclip" } ) ); - button = toolbar_append_toggle_button( toolbar, "HintsSkips (CTRL + H)\nRightClick: toggle tex\n\thint\n\thintLocal\n\thintSkip", "f-hint.png", "FilterHintsSkips" ); - g_commonFuncs.emplace_back( button, std::vector{ "hint", "hintlocal", "hintskip" } ); + button = toolbar_append_toggle_button( toolbar, "HintsSkips\nRightClick: toggle tex\n\thint\n\thintLocal\n\thintSkip", "f-hint.png", "FilterHintsSkips" ); + g_filter_toolbar_handler.m_actions.emplace( button, new CommonFunc_tex( std::vector{ "hint", "hintlocal", "hintskip" } ) ); button = toolbar_append_toggle_button( toolbar, "Sky", "f-sky.png", "FilterSky" ); - //toolbar_append_toggle_button( toolbar, "Paths (ALT + 8)", "texture_lock.png", "FilterPaths" ); - toolbar_append_space( toolbar ); - toolbar_append_toggle_button( toolbar, "Entities (ALT + 2)", "f-entities.png", "FilterEntities" ); + //toolbar_append_toggle_button( toolbar, "Paths", "texture_lock.png", "FilterPaths" ); + toolbar->addSeparator(); + toolbar_append_toggle_button( toolbar, "Entities", "f-entities.png", "FilterEntities" ); toolbar_append_toggle_button( toolbar, "Point Entities", "status_entiy.png", "FilterPointEntities" ); - toolbar_append_toggle_button( toolbar, "Lights (ALT + 0)", "f-lights.png", "FilterLights" ); - toolbar_append_toggle_button( toolbar, "Models (SHIFT + M)", "f-models.png", "FilterModels" ); + toolbar_append_toggle_button( toolbar, "Lights", "f-lights.png", "FilterLights" ); + toolbar_append_toggle_button( toolbar, "Models", "f-models.png", "FilterModels" ); - button = toolbar_append_toggle_button( toolbar, "Triggers (CTRL + SHIFT + T)\nRightClick: tex Trigger", "f-triggers.png", "FilterTriggers" ); - g_commonFuncs.emplace_back( button, std::vector{ "trigger" } ); + button = toolbar_append_toggle_button( toolbar, "Triggers\nRightClick: tex Trigger", "f-triggers.png", "FilterTriggers" ); + g_filter_toolbar_handler.m_actions.emplace( button, new CommonFunc_tex( std::vector{ "trigger" } ) ); - //toolbar_append_toggle_button( toolbar, "Decals (SHIFT + D)", "f-decals.png", "FilterDecals" ); - toolbar_append_space( toolbar ); + //toolbar_append_toggle_button( toolbar, "Decals", "f-decals.png", "FilterDecals" ); + toolbar->addSeparator(); //toolbar_append_button( toolbar, "InvertFilters", "f-invert.png", "InvertFilters" ); toolbar_append_button( toolbar, "ResetFilters", "f-reset.png", "ResetFilters" ); - toolbar_append_space( toolbar ); - button = toolbar_append_toggle_button( toolbar, "Region Set Selection (CTRL + SHIFT + R)\nRightClick: Region Off", "f-region.png", "RegionSetSelection" ); - g_commonFuncs.emplace_back( button, "RegionOff" ); + toolbar->addSeparator(); + button = toolbar_append_toggle_button( toolbar, "Region Set Selection\nRightClick: Region Off", "f-region.png", "RegionSetSelection" ); + g_filter_toolbar_handler.m_actions.emplace( button, new CommonFunc_command( "RegionOff" ) ); - button = toolbar_append_toggle_button( toolbar, "Hide Selected (H)\nRightClick: Show Hidden (SHIFT + H)", "f-hide.png", "HideSelected" ); - g_commonFuncs.emplace_back( button, "ShowHidden" ); - - return toolbar; + button = toolbar_append_toggle_button( toolbar, "Hide Selected\nRightClick: Show Hidden", "f-hide.png", "HideSelected" ); + g_filter_toolbar_handler.m_actions.emplace( button, new CommonFunc_command( "ShowHidden" ) ); } diff --git a/radiant/filterbar.h b/radiant/filterbar.h index b2dfadd7..b296adf0 100644 --- a/radiant/filterbar.h +++ b/radiant/filterbar.h @@ -24,9 +24,7 @@ //#include "string/string.h" #include "string/stringfwd.h" -typedef struct _GtkToolbar GtkToolbar; - -GtkToolbar* create_filter_toolbar(); +void create_filter_toolbar( class QToolBar *toolbar ); CopiedString GetCommonShader( const char* name ); diff --git a/radiant/filters.cpp b/radiant/filters.cpp index b9bbf6b4..d324edc2 100644 --- a/radiant/filters.cpp +++ b/radiant/filters.cpp @@ -39,11 +39,7 @@ struct filters_globals_t { - std::size_t exclude; - - filters_globals_t() : - exclude( 0 ){ - } + std::size_t exclude = 0; }; filters_globals_t g_filters_globals; @@ -148,7 +144,7 @@ public: typedef std::list ToggleFilterFlags; ToggleFilterFlags g_filter_items; -void add_filter_command( unsigned int flag, const char* command, const Accelerator& accelerator ){ +void add_filter_command( unsigned int flag, const char* command, const QKeySequence& accelerator = {} ){ g_filter_items.push_back( ToggleFilterFlag( flag ) ); GlobalToggles_insert( command, ToggleFilterFlag::ToggleCaller( g_filter_items.back() ), ToggleItem::AddCallbackCaller( g_filter_items.back().m_item ), accelerator ); } @@ -171,47 +167,47 @@ void ResetFilters(){ } } -void Filters_constructMenu( GtkMenu* menu_in_menu ){ - create_check_menu_item_with_mnemonic( menu_in_menu, "World", "FilterWorldBrushes" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Entities", "FilterEntities" ); +void Filters_constructMenu( QMenu* menu ){ + create_check_menu_item_with_mnemonic( menu, "World", "FilterWorldBrushes" ); + create_check_menu_item_with_mnemonic( menu, "Entities", "FilterEntities" ); if ( g_pGameDescription->mGameType == "doom3" ) { - create_check_menu_item_with_mnemonic( menu_in_menu, "Visportals", "FilterVisportals" ); + create_check_menu_item_with_mnemonic( menu, "Visportals", "FilterVisportals" ); } else { - create_check_menu_item_with_mnemonic( menu_in_menu, "Areaportals", "FilterAreaportals" ); + create_check_menu_item_with_mnemonic( menu, "Areaportals", "FilterAreaportals" ); } - create_check_menu_item_with_mnemonic( menu_in_menu, "Translucent", "FilterTranslucent" ); + create_check_menu_item_with_mnemonic( menu, "Translucent", "FilterTranslucent" ); if ( g_pGameDescription->mGameType != "doom3" ) { - create_check_menu_item_with_mnemonic( menu_in_menu, "Liquids", "FilterLiquids" ); + create_check_menu_item_with_mnemonic( menu, "Liquids", "FilterLiquids" ); } - create_check_menu_item_with_mnemonic( menu_in_menu, "Caulk", "FilterCaulk" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Clips", "FilterClips" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Paths", "FilterPaths" ); + create_check_menu_item_with_mnemonic( menu, "Caulk", "FilterCaulk" ); + create_check_menu_item_with_mnemonic( menu, "Clips", "FilterClips" ); + create_check_menu_item_with_mnemonic( menu, "Paths", "FilterPaths" ); if ( g_pGameDescription->mGameType != "doom3" ) { - create_check_menu_item_with_mnemonic( menu_in_menu, "Clusterportals", "FilterClusterportals" ); + create_check_menu_item_with_mnemonic( menu, "Clusterportals", "FilterClusterportals" ); } - create_check_menu_item_with_mnemonic( menu_in_menu, "Lights", "FilterLights" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Structural", "FilterStructural" ); + create_check_menu_item_with_mnemonic( menu, "Lights", "FilterLights" ); + create_check_menu_item_with_mnemonic( menu, "Structural", "FilterStructural" ); if ( g_pGameDescription->mGameType != "doom3" ) { - create_check_menu_item_with_mnemonic( menu_in_menu, "Lightgrid", "FilterLightgrid" ); + create_check_menu_item_with_mnemonic( menu, "Lightgrid", "FilterLightgrid" ); } - create_check_menu_item_with_mnemonic( menu_in_menu, "Patches", "FilterPatches" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Details", "FilterDetails" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Hints", "FilterHintsSkips" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Models", "FilterModels" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Triggers", "FilterTriggers" ); + create_check_menu_item_with_mnemonic( menu, "Patches", "FilterPatches" ); + create_check_menu_item_with_mnemonic( menu, "Details", "FilterDetails" ); + create_check_menu_item_with_mnemonic( menu, "Hints", "FilterHintsSkips" ); + create_check_menu_item_with_mnemonic( menu, "Models", "FilterModels" ); + create_check_menu_item_with_mnemonic( menu, "Triggers", "FilterTriggers" ); if ( g_pGameDescription->mGameType != "doom3" ) { - create_check_menu_item_with_mnemonic( menu_in_menu, "Botclips", "FilterBotClips" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Decals", "FilterDecals" ); + create_check_menu_item_with_mnemonic( menu, "Botclips", "FilterBotClips" ); + create_check_menu_item_with_mnemonic( menu, "Decals", "FilterDecals" ); } - create_check_menu_item_with_mnemonic( menu_in_menu, "FuncGroups", "FilterFuncGroups" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Point Entities", "FilterPointEntities" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Sky", "FilterSky" ); + create_check_menu_item_with_mnemonic( menu, "FuncGroups", "FilterFuncGroups" ); + create_check_menu_item_with_mnemonic( menu, "Point Entities", "FilterPointEntities" ); + create_check_menu_item_with_mnemonic( menu, "Sky", "FilterSky" ); // filter manipulation - menu_separator( menu_in_menu ); - create_menu_item_with_mnemonic( menu_in_menu, "Invert filters", "InvertFilters" ); - create_menu_item_with_mnemonic( menu_in_menu, "Reset filters", "ResetFilters" ); + menu->addSeparator(); + create_menu_item_with_mnemonic( menu, "Invert filters", "InvertFilters" ); + create_menu_item_with_mnemonic( menu, "Reset filters", "ResetFilters" ); } @@ -224,40 +220,40 @@ void ConstructFilters(){ GlobalCommands_insert( "InvertFilters", FreeCaller() ); GlobalCommands_insert( "ResetFilters", FreeCaller() ); - add_filter_command( EXCLUDE_WORLD, "FilterWorldBrushes", Accelerator( '1', GDK_MOD1_MASK ) ); - add_filter_command( EXCLUDE_ENT, "FilterEntities", Accelerator( '2', GDK_MOD1_MASK ) ); + add_filter_command( EXCLUDE_WORLD, "FilterWorldBrushes", QKeySequence( "Alt+1" ) ); + add_filter_command( EXCLUDE_ENT, "FilterEntities", QKeySequence( "Alt+2" ) ); if ( g_pGameDescription->mGameType == "doom3" ) { - add_filter_command( EXCLUDE_VISPORTALS, "FilterVisportals", Accelerator( '3', GDK_MOD1_MASK ) ); + add_filter_command( EXCLUDE_VISPORTALS, "FilterVisportals", QKeySequence( "Alt+3" ) ); } else { - add_filter_command( EXCLUDE_AREAPORTALS, "FilterAreaportals", Accelerator( '3', GDK_MOD1_MASK ) ); + add_filter_command( EXCLUDE_AREAPORTALS, "FilterAreaportals", QKeySequence( "Alt+3" ) ); } - add_filter_command( EXCLUDE_TRANSLUCENT, "FilterTranslucent", Accelerator( '4', GDK_MOD1_MASK ) ); - add_filter_command( EXCLUDE_LIQUIDS, "FilterLiquids", Accelerator( '5', GDK_MOD1_MASK ) ); - add_filter_command( EXCLUDE_CAULK, "FilterCaulk", Accelerator( '6', GDK_MOD1_MASK ) ); - add_filter_command( EXCLUDE_CLIP, "FilterClips", Accelerator( '7', GDK_MOD1_MASK ) ); - add_filter_command( EXCLUDE_PATHS, "FilterPaths", Accelerator( '8', GDK_MOD1_MASK ) ); + add_filter_command( EXCLUDE_TRANSLUCENT, "FilterTranslucent", QKeySequence( "Alt+4" ) ); + add_filter_command( EXCLUDE_LIQUIDS, "FilterLiquids", QKeySequence( "Alt+5" ) ); + add_filter_command( EXCLUDE_CAULK, "FilterCaulk", QKeySequence( "Alt+6" ) ); + add_filter_command( EXCLUDE_CLIP, "FilterClips", QKeySequence( "Alt+7" ) ); + add_filter_command( EXCLUDE_PATHS, "FilterPaths", QKeySequence( "Alt+8" ) ); if ( g_pGameDescription->mGameType != "doom3" ) { - add_filter_command( EXCLUDE_CLUSTERPORTALS, "FilterClusterportals", Accelerator( '9', GDK_MOD1_MASK ) ); + add_filter_command( EXCLUDE_CLUSTERPORTALS, "FilterClusterportals", QKeySequence( "Alt+9" ) ); } - add_filter_command( EXCLUDE_LIGHTS, "FilterLights", Accelerator( '0', GDK_MOD1_MASK ) ); - add_filter_command( EXCLUDE_STRUCTURAL, "FilterStructural", Accelerator( 'D', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); + add_filter_command( EXCLUDE_LIGHTS, "FilterLights", QKeySequence( "Alt+0" ) ); + add_filter_command( EXCLUDE_STRUCTURAL, "FilterStructural", QKeySequence( "Ctrl+Shift+D" ) ); if ( g_pGameDescription->mGameType != "doom3" ) { - add_filter_command( EXCLUDE_LIGHTGRID, "FilterLightgrid", accelerator_null() ); + add_filter_command( EXCLUDE_LIGHTGRID, "FilterLightgrid" ); } - add_filter_command( EXCLUDE_CURVES, "FilterPatches", Accelerator( 'P', GDK_CONTROL_MASK ) ); - add_filter_command( EXCLUDE_DETAILS, "FilterDetails", Accelerator( 'D', GDK_CONTROL_MASK ) ); - add_filter_command( EXCLUDE_HINTSSKIPS, "FilterHintsSkips", Accelerator( 'H', GDK_CONTROL_MASK ) ); - add_filter_command( EXCLUDE_MODELS, "FilterModels", Accelerator( 'M', GDK_SHIFT_MASK ) ); - add_filter_command( EXCLUDE_TRIGGERS, "FilterTriggers", Accelerator( 'T', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); + add_filter_command( EXCLUDE_CURVES, "FilterPatches", QKeySequence( "Ctrl+P" ) ); + add_filter_command( EXCLUDE_DETAILS, "FilterDetails", QKeySequence( "Ctrl+D" ) ); + add_filter_command( EXCLUDE_HINTSSKIPS, "FilterHintsSkips", QKeySequence( "Ctrl+H" ) ); + add_filter_command( EXCLUDE_MODELS, "FilterModels", QKeySequence( "Shift+M" ) ); + add_filter_command( EXCLUDE_TRIGGERS, "FilterTriggers", QKeySequence( "Ctrl+Shift+T" ) ); if ( g_pGameDescription->mGameType != "doom3" ) { - add_filter_command( EXCLUDE_BOTCLIP, "FilterBotClips", Accelerator( 'M', GDK_MOD1_MASK ) ); - add_filter_command( EXCLUDE_DECALS, "FilterDecals", Accelerator( 'D', GDK_SHIFT_MASK ) ); + add_filter_command( EXCLUDE_BOTCLIP, "FilterBotClips", QKeySequence( "Alt+M" ) ); + add_filter_command( EXCLUDE_DECALS, "FilterDecals", QKeySequence( "Shift+D" ) ); } - add_filter_command( EXCLUDE_FUNC_GROUPS, "FilterFuncGroups", accelerator_null() ); - add_filter_command( EXCLUDE_POINT_ENT, "FilterPointEntities", accelerator_null() ); - add_filter_command( EXCLUDE_SKY, "FilterSky", accelerator_null() ); + add_filter_command( EXCLUDE_FUNC_GROUPS, "FilterFuncGroups" ); + add_filter_command( EXCLUDE_POINT_ENT, "FilterPointEntities" ); + add_filter_command( EXCLUDE_SKY, "FilterSky" ); PerformFiltering(); } diff --git a/radiant/filters.h b/radiant/filters.h index 9006c6ca..750767e2 100644 --- a/radiant/filters.h +++ b/radiant/filters.h @@ -21,5 +21,4 @@ #pragma once -typedef struct _GtkMenu GtkMenu; -void Filters_constructMenu( GtkMenu* menu_in_menu ); +void Filters_constructMenu( class QMenu* menu ); diff --git a/radiant/findtexturedialog.cpp b/radiant/findtexturedialog.cpp index 73af64a0..d24c5474 100644 --- a/radiant/findtexturedialog.cpp +++ b/radiant/findtexturedialog.cpp @@ -31,9 +31,16 @@ #include "ishaders.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "gtkutil/window.h" +#include "gtkutil/guisettings.h" #include "stream/stringstream.h" #include "os/path.h" @@ -47,7 +54,6 @@ class FindTextureDialog : public Dialog { public: - WindowPositionTracker m_position_tracker; static void setReplaceStr( const char* name ); static void setFindStr( const char* name ); static bool isOpen(); @@ -57,11 +63,10 @@ public: FindTextureDialog(); virtual ~FindTextureDialog(); - GtkWindow* BuildDialog(); + void BuildDialog() override; - void constructWindow( GtkWindow* parent ){ - m_parent = parent; - Create(); + void constructWindow( QWidget* parent ){ + Create( parent ); } void destroyWindow(){ Destroy(); @@ -84,148 +89,92 @@ void FindTextureDialog_apply(){ FindReplaceTextures( find.c_str(), replace.c_str(), g_FindTextureDialog.m_bSelectedOnly ); } -static void OnApply( GtkWidget* widget, gpointer data ){ - g_FindTextureDialog.exportData(); - FindTextureDialog_apply(); -} -#if 0 -static void OnFind( GtkWidget* widget, gpointer data ){ - g_FindTextureDialog.exportData(); - FindTextureDialog_apply(); +class FindActiveTracker : public QObject +{ + const bool m_findActive; +public: + FindActiveTracker( bool findActive ) : m_findActive( findActive ){} +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::FocusIn ) { + g_bFindActive = m_findActive; + } + return QObject::eventFilter( obj, event ); // standard event processing + } +}; +FindActiveTracker s_find_focus_in( true ); +FindActiveTracker s_replace_focus_in( false ); + } -static void OnOK( GtkWidget* widget, gpointer data ){ - g_FindTextureDialog.exportData(); - FindTextureDialog_apply(); - g_FindTextureDialog.HideDlg(); -} -#endif -static void OnClose( GtkWidget* widget, gpointer data ){ - g_FindTextureDialog.HideDlg(); -} - - -static gint find_focus_in( GtkWidget* widget, GdkEventFocus *event, gpointer data ){ - g_bFindActive = true; - return FALSE; -} - -static gint replace_focus_in( GtkWidget* widget, GdkEventFocus *event, gpointer data ){ - g_bFindActive = false; - return FALSE; -} -} // ============================================================================= // FindTextureDialog class -FindTextureDialog::FindTextureDialog(){ - m_bSelectedOnly = FALSE; - m_position_tracker.setPosition( WindowPosition( -1, -1, 0, 0 ) ); +FindTextureDialog::FindTextureDialog() : m_bSelectedOnly( false ){ } FindTextureDialog::~FindTextureDialog(){ } -GtkWindow* FindTextureDialog::BuildDialog(){ - GtkWidget* vbox, *hbox, *table, *label; - GtkWidget* button, *check, *entry; +void FindTextureDialog::BuildDialog(){ + GetWidget()->setWindowTitle( "Find / Replace Texture(s)" ); - GtkWindow* dlg = create_floating_window( "Find / Replace Texture(s)", m_parent ); + g_guiSettings.addWindow( GetWidget(), "TextureBrowser/FindReplace" ); - m_position_tracker.connect( dlg ); + auto hbox = new QHBoxLayout( GetWidget() ); + auto form = new QFormLayout; + hbox->addLayout( form ); - hbox = gtk_hbox_new( FALSE, 5 ); - gtk_widget_show( hbox ); - gtk_container_add( GTK_CONTAINER( dlg ), GTK_WIDGET( hbox ) ); - gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 ); + { + auto entry = new QLineEdit; + form->addRow( "Find:", entry ); + AddDialogData( *entry, m_strFind ); + entry->installEventFilter( &s_find_focus_in ); + GlobalTextureEntryCompletion::instance().connect( entry ); + } + { + auto entry = new QLineEdit; + auto label = new QLabel( "Replace:" ); + form->addRow( label, entry ); + entry->setPlaceholderText( "Empty = search mode" ); + AddDialogData( *entry, m_strReplace ); + entry->installEventFilter( &s_replace_focus_in ); + GlobalTextureEntryCompletion::instance().connect( entry ); + } + { + auto check = new QCheckBox( "Within selected brushes only" ); + form->addWidget( check ); + AddDialogData( *check, m_bSelectedOnly ); + } - vbox = gtk_vbox_new( FALSE, 5 ); - gtk_widget_show( vbox ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), TRUE, TRUE, 0 ); - - table = gtk_table_new( 2, 2, FALSE ); - gtk_widget_show( table ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - gtk_table_set_row_spacings( GTK_TABLE( table ), 5 ); - gtk_table_set_col_spacings( GTK_TABLE( table ), 5 ); - - label = gtk_label_new( "Find:" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - - label = gtk_label_new( "Replace:*" ); - gtk_widget_set_tooltip_text( label, "Empty = search mode" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - - entry = gtk_entry_new(); - gtk_widget_show( entry ); - gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( entry ), "focus_in_event", - G_CALLBACK( find_focus_in ), 0 ); - AddDialogData( *GTK_ENTRY( entry ), m_strFind ); - GlobalTextureEntryCompletion::instance().connect( GTK_ENTRY( entry ) ); - - entry = gtk_entry_new(); - gtk_widget_set_tooltip_text( entry, "Empty = search mode" ); - gtk_widget_show( entry ); - gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( entry ), "focus_in_event", - G_CALLBACK( replace_focus_in ), 0 ); - AddDialogData( *GTK_ENTRY( entry ), m_strReplace ); - GlobalTextureEntryCompletion::instance().connect( GTK_ENTRY( entry ) ); - - check = gtk_check_button_new_with_label( "Within selected brushes only" ); - gtk_widget_show( check ); - gtk_box_pack_start( GTK_BOX( vbox ), check, TRUE, TRUE, 0 ); - AddDialogData( *GTK_TOGGLE_BUTTON( check ), m_bSelectedOnly ); - - vbox = gtk_vbox_new( FALSE, 5 ); - gtk_widget_show( vbox ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), FALSE, FALSE, 0 ); - - button = gtk_button_new_with_label( "Apply" ); - gtk_widget_show( button ); - gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnApply ), 0 ); - gtk_widget_set_size_request( button, 60, -1 ); - - button = gtk_button_new_with_label( "Close" ); - gtk_widget_show( button ); - gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnClose ), 0 ); - gtk_widget_set_size_request( button, 60, -1 ); - - return dlg; + { + auto buttons = new QDialogButtonBox( Qt::Orientation::Vertical ); + hbox->addWidget( buttons ); + QObject::connect( buttons->addButton( QDialogButtonBox::StandardButton::Apply ), &QPushButton::clicked, [](){ + g_FindTextureDialog.exportData(); + FindTextureDialog_apply(); + } ); + QObject::connect( buttons->addButton( QDialogButtonBox::StandardButton::Close ), &QPushButton::clicked, [](){ + g_FindTextureDialog.HideDlg(); + } ); + } } void FindTextureDialog::updateTextures( const char* name ){ if ( isOpen() ) { if ( g_bFindActive ) { - setFindStr( name + 9 ); + setFindStr( name + strlen( "textures/" ) ); } else { - setReplaceStr( name + 9 ); + setReplaceStr( name + strlen( "textures/" ) ); } } } bool FindTextureDialog::isOpen(){ - return gtk_widget_get_visible( GTK_WIDGET( g_FindTextureDialog.GetWidget() ) ); + return g_FindTextureDialog.GetWidget()->isVisible(); } void FindTextureDialog::setFindStr( const char* name ){ @@ -242,11 +191,10 @@ void FindTextureDialog::setReplaceStr( const char* name ){ void FindTextureDialog::show(){ g_FindTextureDialog.ShowDlg(); - gtk_window_present( g_FindTextureDialog.GetWidget() ); } -void FindTextureDialog_constructWindow( GtkWindow* main_window ){ +void FindTextureDialog_constructWindow( QWidget* main_window ){ g_FindTextureDialog.constructWindow( main_window ); } @@ -266,7 +214,6 @@ void FindTextureDialog_selectTexture( const char* name ){ void FindTextureDialog_Construct(){ GlobalCommands_insert( "FindReplaceTextures", FindTextureDialog::ShowCaller() ); - GlobalPreferenceSystem().registerPreference( "FindReplacehWnd", WindowPositionTrackerImportStringCaller( g_FindTextureDialog.m_position_tracker ), WindowPositionTrackerExportStringCaller( g_FindTextureDialog.m_position_tracker ) ); } void FindTextureDialog_Destroy(){ diff --git a/radiant/findtexturedialog.h b/radiant/findtexturedialog.h index 9c9e6a90..4c45502c 100644 --- a/radiant/findtexturedialog.h +++ b/radiant/findtexturedialog.h @@ -24,8 +24,7 @@ void FindTextureDialog_Construct(); void FindTextureDialog_Destroy(); -typedef struct _GtkWindow GtkWindow; -void FindTextureDialog_constructWindow( GtkWindow* main_window ); +void FindTextureDialog_constructWindow( class QWidget* main_window ); void FindTextureDialog_destroyWindow(); bool FindTextureDialog_isOpen(); void FindTextureDialog_selectTexture( const char* name ); diff --git a/radiant/glwidget.cpp b/radiant/glwidget.cpp index 9cb3ac66..83b18c3f 100644 --- a/radiant/glwidget.cpp +++ b/radiant/glwidget.cpp @@ -33,11 +33,6 @@ public: STRING_CONSTANT( Name, "*" ); GtkGLAPI(){ - m_gtkgl.glwidget_new = &glwidget_new; - m_gtkgl.glwidget_swap_buffers = &glwidget_swap_buffers; - m_gtkgl.glwidget_make_current = &glwidget_make_current; - m_gtkgl.glwidget_destroy_context = &glwidget_destroy_context; - m_gtkgl.glwidget_create_context = &glwidget_create_context; } _QERGtkGLTable* getTable(){ return &m_gtkgl; diff --git a/radiant/grid.cpp b/radiant/grid.cpp index a843d4ed..055ea8b3 100644 --- a/radiant/grid.cpp +++ b/radiant/grid.cpp @@ -221,29 +221,29 @@ typedef FreeCaller1 maxGridCo void Grid_registerCommands(){ - GlobalCommands_insert( "GridDown", FreeCaller(), Accelerator( '[' ) ); - GlobalCommands_insert( "GridUp", FreeCaller(), Accelerator( ']' ) ); + GlobalCommands_insert( "GridDown", FreeCaller(), QKeySequence( "[" ) ); + GlobalCommands_insert( "GridUp", FreeCaller(), QKeySequence( "]" ) ); GlobalCommands_insert( "ToggleGridSnap", FreeCaller() ); GlobalToggles_insert( "SetGrid0.125", GridMenuItem::SetCaller( g_gridMenu0125 ), ToggleItem::AddCallbackCaller( g_gridMenu0125.m_item ) ); GlobalToggles_insert( "SetGrid0.25", GridMenuItem::SetCaller( g_gridMenu025 ), ToggleItem::AddCallbackCaller( g_gridMenu025.m_item ) ); GlobalToggles_insert( "SetGrid0.5", GridMenuItem::SetCaller( g_gridMenu05 ), ToggleItem::AddCallbackCaller( g_gridMenu05.m_item ) ); - GlobalToggles_insert( "SetGrid1", GridMenuItem::SetCaller( g_gridMenu1 ), ToggleItem::AddCallbackCaller( g_gridMenu1.m_item ), Accelerator( '1' ) ); - GlobalToggles_insert( "SetGrid2", GridMenuItem::SetCaller( g_gridMenu2 ), ToggleItem::AddCallbackCaller( g_gridMenu2.m_item ), Accelerator( '2' ) ); - GlobalToggles_insert( "SetGrid4", GridMenuItem::SetCaller( g_gridMenu4 ), ToggleItem::AddCallbackCaller( g_gridMenu4.m_item ), Accelerator( '3' ) ); - GlobalToggles_insert( "SetGrid8", GridMenuItem::SetCaller( g_gridMenu8 ), ToggleItem::AddCallbackCaller( g_gridMenu8.m_item ), Accelerator( '4' ) ); - GlobalToggles_insert( "SetGrid16", GridMenuItem::SetCaller( g_gridMenu16 ), ToggleItem::AddCallbackCaller( g_gridMenu16.m_item ), Accelerator( '5' ) ); - GlobalToggles_insert( "SetGrid32", GridMenuItem::SetCaller( g_gridMenu32 ), ToggleItem::AddCallbackCaller( g_gridMenu32.m_item ), Accelerator( '6' ) ); - GlobalToggles_insert( "SetGrid64", GridMenuItem::SetCaller( g_gridMenu64 ), ToggleItem::AddCallbackCaller( g_gridMenu64.m_item ), Accelerator( '7' ) ); - GlobalToggles_insert( "SetGrid128", GridMenuItem::SetCaller( g_gridMenu128 ), ToggleItem::AddCallbackCaller( g_gridMenu128.m_item ), Accelerator( '8' ) ); - GlobalToggles_insert( "SetGrid256", GridMenuItem::SetCaller( g_gridMenu256 ), ToggleItem::AddCallbackCaller( g_gridMenu256.m_item ), Accelerator( '9' ) ); + GlobalToggles_insert( "SetGrid1", GridMenuItem::SetCaller( g_gridMenu1 ), ToggleItem::AddCallbackCaller( g_gridMenu1.m_item ), QKeySequence( "1" ) ); + GlobalToggles_insert( "SetGrid2", GridMenuItem::SetCaller( g_gridMenu2 ), ToggleItem::AddCallbackCaller( g_gridMenu2.m_item ), QKeySequence( "2" ) ); + GlobalToggles_insert( "SetGrid4", GridMenuItem::SetCaller( g_gridMenu4 ), ToggleItem::AddCallbackCaller( g_gridMenu4.m_item ), QKeySequence( "3" ) ); + GlobalToggles_insert( "SetGrid8", GridMenuItem::SetCaller( g_gridMenu8 ), ToggleItem::AddCallbackCaller( g_gridMenu8.m_item ), QKeySequence( "4" ) ); + GlobalToggles_insert( "SetGrid16", GridMenuItem::SetCaller( g_gridMenu16 ), ToggleItem::AddCallbackCaller( g_gridMenu16.m_item ), QKeySequence( "5" ) ); + GlobalToggles_insert( "SetGrid32", GridMenuItem::SetCaller( g_gridMenu32 ), ToggleItem::AddCallbackCaller( g_gridMenu32.m_item ), QKeySequence( "6" ) ); + GlobalToggles_insert( "SetGrid64", GridMenuItem::SetCaller( g_gridMenu64 ), ToggleItem::AddCallbackCaller( g_gridMenu64.m_item ), QKeySequence( "7" ) ); + GlobalToggles_insert( "SetGrid128", GridMenuItem::SetCaller( g_gridMenu128 ), ToggleItem::AddCallbackCaller( g_gridMenu128.m_item ), QKeySequence( "8" ) ); + GlobalToggles_insert( "SetGrid256", GridMenuItem::SetCaller( g_gridMenu256 ), ToggleItem::AddCallbackCaller( g_gridMenu256.m_item ), QKeySequence( "9" ) ); GlobalToggles_insert( "SetGrid512", GridMenuItem::SetCaller( g_gridMenu512 ), ToggleItem::AddCallbackCaller( g_gridMenu512.m_item ) ); GlobalToggles_insert( "SetGrid1024", GridMenuItem::SetCaller( g_gridMenu1024 ), ToggleItem::AddCallbackCaller( g_gridMenu1024.m_item ) ); } -void Grid_constructMenu( GtkMenu* menu ){ +void Grid_constructMenu( QMenu* menu ){ create_check_menu_item_with_mnemonic( menu, "Grid0.125", "SetGrid0.125" ); create_check_menu_item_with_mnemonic( menu, "Grid0.25", "SetGrid0.25" ); create_check_menu_item_with_mnemonic( menu, "Grid0.5", "SetGrid0.5" ); diff --git a/radiant/grid.h b/radiant/grid.h index acc8408d..295628a9 100644 --- a/radiant/grid.h +++ b/radiant/grid.h @@ -32,8 +32,7 @@ float GetMaxGridCoord(); void AddGridChangeCallback( const SignalHandler& handler ); void Grid_registerCommands(); -typedef struct _GtkMenu GtkMenu; -void Grid_constructMenu( GtkMenu* menu ); +void Grid_constructMenu( class QMenu* menu ); void Grid_registerShortcuts(); diff --git a/radiant/groupdialog.cpp b/radiant/groupdialog.cpp index 6f68b619..e654d729 100644 --- a/radiant/groupdialog.cpp +++ b/radiant/groupdialog.cpp @@ -32,116 +32,89 @@ #include -#include +#include +#include +#include +#include "gtkutil/guisettings.h" #include "gtkutil/widget.h" #include "gtkutil/accelerator.h" #include "entityinspector.h" #include "gtkmisc.h" -#include "multimon.h" #include "console.h" #include "commands.h" -#include "gtkutil/window.h" - class GroupDlg { public: - GtkWidget* m_pNotebook; - GtkWindow* m_window; + QTabWidget* m_pNotebook; + QWidget* m_window; GroupDlg(); - void Create( GtkWindow* parent ); + void Create( QWidget* parent ); void Show(){ - /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */ - GtkWidget* glwidget = GTK_WIDGET( g_object_get_data( G_OBJECT( m_window ), "glwidget" ) ); - if ( glwidget ){ - gtk_widget_hide( glwidget ); - gtk_widget_show( glwidget ); - } - gtk_widget_show( GTK_WIDGET( m_window ) ); + m_window->show(); + m_window->raise(); + m_window->activateWindow(); } void Hide(){ - gtk_widget_hide( GTK_WIDGET( m_window ) ); + m_window->hide(); } - - WindowPositionTracker m_position_tracker; }; namespace { GroupDlg g_GroupDlg; -std::size_t g_current_page; std::vector g_pages; } -void GroupDialog_updatePageTitle( GtkWindow* window, std::size_t pageIndex ){ - if ( pageIndex < g_pages.size() ) { - g_pages[pageIndex]( PointerCaller1( window ) ); +void GroupDialog_updatePageTitle( QWidget* window, int pageIndex ){ + if ( pageIndex >= 0 && pageIndex < static_cast( g_pages.size() ) ) { + const auto la = [window]( const char *title ){ window->setWindowTitle( title ); }; + g_pages[pageIndex]( ConstMemberCaller1( la ) ); } } -static gboolean switch_page( GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer data ){ - GroupDialog_updatePageTitle( GTK_WINDOW( data ), page_num ); - g_current_page = page_num; - - /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */ - g_object_set_data( G_OBJECT( g_GroupDlg.m_window ), "glwidget", g_object_get_data( G_OBJECT( gtk_notebook_get_nth_page( notebook, page_num ) ), "glwidget" ) ); - - return FALSE; -} - GroupDlg::GroupDlg() : m_window( 0 ){ - m_position_tracker.setPosition( WindowPosition( -1, -1, 444, 777 ) ); } -void GroupDlg::Create( GtkWindow* parent ){ +void GroupDlg::Create( QWidget* parent ){ ASSERT_MESSAGE( m_window == 0, "dialog already created" ); - GtkWindow* window = create_persistent_floating_window( "Entities", parent ); + m_window = new QWidget( parent, Qt::Window ); + m_window->setWindowTitle( "Entities" ); - global_accel_connect_window( window ); +//. window_connect_focus_in_clear_focus_widget( m_window ); - window_connect_focus_in_clear_focus_widget( window ); - - m_window = window; - -#ifdef WIN32 - if ( g_multimon_globals.m_bStartOnPrimMon ) { - WindowPosition pos( m_position_tracker.getPosition() ); - PositionWindowOnPrimaryScreen( pos ); - m_position_tracker.setPosition( pos ); - } -#endif - m_position_tracker.connect( window ); + g_guiSettings.addWindow( m_window, "GroupDlg/geometry", 444, 777 ); { - GtkWidget* notebook = gtk_notebook_new(); - gtk_widget_show( notebook ); - gtk_container_add( GTK_CONTAINER( window ), notebook ); - gtk_notebook_set_tab_pos( GTK_NOTEBOOK( notebook ), GTK_POS_BOTTOM ); - m_pNotebook = notebook; + auto box = new QVBoxLayout( m_window ); + box->setContentsMargins( 0, 0, 0, 0 ); + m_pNotebook = new QTabWidget; + m_pNotebook->setTabPosition( QTabWidget::TabPosition::South ); + m_pNotebook->setFocusPolicy( Qt::FocusPolicy::NoFocus ); + box->addWidget( m_pNotebook ); - g_signal_connect( G_OBJECT( notebook ), "switch_page", G_CALLBACK( switch_page ), window ); + QObject::connect( m_pNotebook, &QTabWidget::currentChanged, [window = m_window]( int index ){ + GroupDialog_updatePageTitle( window, index ); + } ); } } -GtkWidget* GroupDialog_addPage( const char* tabLabel, GtkWidget* widget, const StringExportCallback& title ){ - GtkWidget* w = gtk_label_new( tabLabel ); - gtk_widget_show( w ); - GtkWidget* page = gtk_notebook_get_nth_page( GTK_NOTEBOOK( g_GroupDlg.m_pNotebook ), gtk_notebook_insert_page( GTK_NOTEBOOK( g_GroupDlg.m_pNotebook ), widget, w, -1 ) ); +QWidget* GroupDialog_addPage( const char* tabLabel, QWidget* widget, const StringExportCallback& title ){ + g_GroupDlg.m_pNotebook->addTab( widget, tabLabel ); g_pages.push_back( title ); - - return page; + return widget; } bool GroupDialog_isShown(){ - return widget_is_visible( GTK_WIDGET( g_GroupDlg.m_window ) ); + return g_GroupDlg.m_window->isVisible(); } void GroupDialog_setShown( bool shown ){ shown ? g_GroupDlg.Show() : g_GroupDlg.Hide(); @@ -150,51 +123,41 @@ void GroupDialog_ToggleShow(){ GroupDialog_setShown( !GroupDialog_isShown() ); } -void GroupDialog_constructWindow( GtkWindow* main_window ){ +void GroupDialog_constructWindow( QWidget* main_window ){ g_GroupDlg.Create( main_window ); } void GroupDialog_destroyWindow(){ ASSERT_NOTNULL( g_GroupDlg.m_window ); - destroy_floating_window( g_GroupDlg.m_window ); + delete g_GroupDlg.m_window; g_GroupDlg.m_window = 0; } -GtkWindow* GroupDialog_getWindow(){ +QWidget* GroupDialog_getWindow(){ return g_GroupDlg.m_window; } void GroupDialog_show(){ g_GroupDlg.Show(); } -GtkWidget* GroupDialog_getPage(){ - return gtk_notebook_get_nth_page( GTK_NOTEBOOK( g_GroupDlg.m_pNotebook ), gint( g_current_page ) ); +QWidget* GroupDialog_getPage(){ + return g_GroupDlg.m_pNotebook->currentWidget(); } -void GroupDialog_setPage( GtkWidget* page ){ - g_current_page = gtk_notebook_page_num( GTK_NOTEBOOK( g_GroupDlg.m_pNotebook ), page ); - gtk_notebook_set_current_page( GTK_NOTEBOOK( g_GroupDlg.m_pNotebook ), gint( g_current_page ) ); -} - -void GroupDialog_showPage( GtkWidget* page ){ +void GroupDialog_showPage( QWidget* page ){ if ( GroupDialog_getPage() == page ) { GroupDialog_ToggleShow(); } else { - gtk_widget_show( GTK_WIDGET( g_GroupDlg.m_window ) ); - GroupDialog_setPage( page ); + g_GroupDlg.m_pNotebook->setCurrentWidget( page ); + GroupDialog_show(); } } -void GroupDialog_cycle(){ - g_current_page = ( g_current_page + 1 ) % g_pages.size(); - gtk_notebook_set_current_page( GTK_NOTEBOOK( g_GroupDlg.m_pNotebook ), gint( g_current_page ) ); -} - -void GroupDialog_updatePageTitle( GtkWidget* page ){ +void GroupDialog_updatePageTitle( QWidget* page ){ if ( GroupDialog_getPage() == page ) { - GroupDialog_updatePageTitle( g_GroupDlg.m_window, g_current_page ); + GroupDialog_updatePageTitle( g_GroupDlg.m_window, g_GroupDlg.m_pNotebook->currentIndex() ); } } @@ -202,7 +165,6 @@ void GroupDialog_updatePageTitle( GtkWidget* page ){ #include "preferencesystem.h" void GroupDialog_Construct(){ - GlobalPreferenceSystem().registerPreference( "EntityWnd", WindowPositionTrackerImportStringCaller( g_GroupDlg.m_position_tracker ), WindowPositionTrackerExportStringCaller( g_GroupDlg.m_position_tracker ) ); } void GroupDialog_Destroy(){ } diff --git a/radiant/groupdialog.h b/radiant/groupdialog.h index 010738b0..86f974bd 100644 --- a/radiant/groupdialog.h +++ b/radiant/groupdialog.h @@ -23,22 +23,21 @@ #include "generic/callback.h" -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkWindow GtkWindow; +class QWidget; void GroupDialog_Construct(); void GroupDialog_Destroy(); -void GroupDialog_constructWindow( GtkWindow* main_window ); +void GroupDialog_constructWindow( QWidget* main_window ); void GroupDialog_destroyWindow(); -GtkWindow* GroupDialog_getWindow(); +QWidget* GroupDialog_getWindow(); void GroupDialog_show(); inline void RawStringExport( const char* string, const StringImportCallback& importer ){ importer( string ); } typedef ConstPointerCaller1 RawStringExportCaller; -GtkWidget* GroupDialog_addPage( const char* tabLabel, GtkWidget* widget, const StringExportCallback& title ); +QWidget* GroupDialog_addPage( const char* tabLabel, QWidget* widget, const StringExportCallback& title ); -void GroupDialog_showPage( GtkWidget* page ); -void GroupDialog_updatePageTitle( GtkWidget* page ); +void GroupDialog_showPage( QWidget* page ); +void GroupDialog_updatePageTitle( QWidget* page ); diff --git a/radiant/gtkdlgs.cpp b/radiant/gtkdlgs.cpp index 2579d0c7..1d63e36c 100644 --- a/radiant/gtkdlgs.cpp +++ b/radiant/gtkdlgs.cpp @@ -44,8 +44,19 @@ #include "iscenegraph.h" #include "iselection.h" -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gtkutil/spinbox.h" +#include "gtkutil/guisettings.h" +#include +#include +#include #include "os/path.h" #include "math/aabb.h" @@ -111,10 +122,10 @@ struct gamecombo_t }; gamecombo_t gamecombo_for_dir( const char* dir ){ - if ( string_equal( dir, globalGameComboConfiguration().basegame_dir ) ) { - return gamecombo_t( 0, "", false ); + if ( path_equal( dir, globalGameComboConfiguration().basegame_dir ) ) { + return gamecombo_t( 0, dir, false ); } - else if ( string_equal( dir, globalGameComboConfiguration().known_dir ) ) { + else if ( path_equal( dir, globalGameComboConfiguration().known_dir ) ) { return gamecombo_t( 1, dir, false ); } else @@ -124,10 +135,10 @@ gamecombo_t gamecombo_for_dir( const char* dir ){ } gamecombo_t gamecombo_for_gamename( const char* gamename ){ - if ( ( strlen( gamename ) == 0 ) || !strcmp( gamename, globalGameComboConfiguration().basegame ) ) { - return gamecombo_t( 0, "", false ); + if ( string_empty( gamename ) || string_equal( gamename, globalGameComboConfiguration().basegame ) ) { + return gamecombo_t( 0, globalGameComboConfiguration().basegame_dir, false ); } - else if ( !strcmp( gamename, globalGameComboConfiguration().known ) ) { + else if ( string_equal( gamename, globalGameComboConfiguration().known ) ) { return gamecombo_t( 1, globalGameComboConfiguration().known_dir, false ); } else @@ -136,39 +147,6 @@ gamecombo_t gamecombo_for_gamename( const char* gamename ){ } } -inline void path_copy_clean( char* destination, const char* source ){ - char* i = destination; - - while ( *source != '\0' ) - { - *i++ = ( *source == '\\' ) ? '/' : *source; - ++source; - } - - if ( i != destination && *( i - 1 ) != '/' ) { - *( i++ ) = '/'; - } - - *i = '\0'; -} - - -struct GameCombo -{ - GtkComboBoxText* game_select; - GtkEntry* fsgame_entry; -}; - -gboolean OnSelchangeComboWhatgame( GtkWidget *widget, GameCombo* combo ){ - if( gchar* gamename = gtk_combo_box_text_get_active_text( combo->game_select ) ){ - gamecombo_t gamecombo = gamecombo_for_gamename( gamename ); - - gtk_entry_set_text( combo->fsgame_entry, gamecombo.fs_game ); - gtk_widget_set_sensitive( GTK_WIDGET( combo->fsgame_entry ), gamecombo.sensitive ); - g_free( gamename ); - } - return FALSE; -} class MappingMode { @@ -190,136 +168,42 @@ inline MappingMode& globalMappingMode(){ return LazyStaticMappingMode::instance(); } -class ProjectSettingsDialog + +struct GameCombo { -public: - GameCombo game_combo; - GtkComboBox* gamemode_combo; + QComboBox* game_select{}; + QComboBox* fsgame_entry{}; }; +static GameCombo s_gameCombo; -GtkWindow* ProjectSettingsDialog_construct( ProjectSettingsDialog& dialog, ModalDialog& modal ){ - GtkWindow* window = create_dialog_window( MainFrame_getWindow(), "Project Settings", G_CALLBACK( dialog_delete_callback ), &modal ); - { - GtkTable* table1 = create_dialog_table( 1, 2, 4, 4, 4 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( table1 ) ); - { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_table_attach( table1, GTK_WIDGET( vbox ), 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( GTK_FILL ), 0, 0 ); - { - GtkButton* button = create_dialog_button( "OK", G_CALLBACK( dialog_button_ok ), &modal ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - } - { - GtkButton* button = create_dialog_button( "Cancel", G_CALLBACK( dialog_button_cancel ), &modal ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - } - } - { - GtkFrame* frame = create_dialog_frame( "Project settings" ); - gtk_table_attach( table1, GTK_WIDGET( frame ), 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( GTK_FILL ), 0, 0 ); - { - GtkTable* table2 = create_dialog_table( ( globalMappingMode().do_mapping_mode ) ? 4 : 3, 2, 4, 4, 4 ); - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( table2 ) ); - - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Select mod" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table2, GTK_WIDGET( label ), 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 ); - } - { - GtkComboBoxText* combo = dialog.game_combo.game_select = GTK_COMBO_BOX_TEXT( gtk_combo_box_text_new() ); - - gtk_combo_box_text_append_text( combo, globalGameComboConfiguration().basegame ); - if ( globalGameComboConfiguration().known[0] != '\0' ) { - gtk_combo_box_text_append_text( combo, globalGameComboConfiguration().known ); - } - gtk_combo_box_text_append_text( combo, globalGameComboConfiguration().custom ); - - gtk_widget_show( GTK_WIDGET( combo ) ); - gtk_table_attach( table2, GTK_WIDGET( combo ), 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - g_signal_connect( G_OBJECT( combo ), "changed", G_CALLBACK( OnSelchangeComboWhatgame ), &dialog.game_combo ); - } - - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "fs_game" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table2, GTK_WIDGET( label ), 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table2, GTK_WIDGET( entry ), 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - dialog.game_combo.fsgame_entry = entry; - } - - if ( globalMappingMode().do_mapping_mode ) { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Mapping mode" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table2, GTK_WIDGET( label ), 0, 1, 3, 4, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 ); - - GtkComboBoxText* combo = GTK_COMBO_BOX_TEXT( gtk_combo_box_text_new() ); - gtk_combo_box_text_append_text( combo, globalMappingMode().sp_mapping_mode ); - gtk_combo_box_text_append_text( combo, globalMappingMode().mp_mapping_mode ); - - gtk_widget_show( GTK_WIDGET( combo ) ); - gtk_table_attach( table2, GTK_WIDGET( combo ), 1, 2, 3, 4, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - dialog.gamemode_combo = GTK_COMBO_BOX( combo ); - } - } - } - } - - // initialise the fs_game selection from the project settings into the dialog - const char* dir = gamename_get(); - gamecombo_t gamecombo = gamecombo_for_dir( dir ); - - gtk_combo_box_set_active( GTK_COMBO_BOX( dialog.game_combo.game_select ), gamecombo.game ); - gtk_entry_set_text( dialog.game_combo.fsgame_entry, gamecombo.fs_game ); - gtk_widget_set_sensitive( GTK_WIDGET( dialog.game_combo.fsgame_entry ), gamecombo.sensitive ); - - if ( globalMappingMode().do_mapping_mode ) { - const char *gamemode = gamemode_get(); - if ( string_empty( gamemode ) || string_equal( gamemode, "sp" ) ) { - gtk_combo_box_set_active( dialog.gamemode_combo, 0 ); - } - else - { - gtk_combo_box_set_active( dialog.gamemode_combo, 1 ); - } - } - - return window; +void GameModeImport( int value ){ + gamemode_set( value == 0? "sp" : "mp" ); } +typedef FreeCaller1 GameModeImportCaller; -void ProjectSettingsDialog_ok( ProjectSettingsDialog& dialog ){ - const char* dir = gtk_entry_get_text( dialog.game_combo.fsgame_entry ); +void GameModeExport( const IntImportCallback& importer ){ + const char *gamemode = gamemode_get(); + importer( ( string_empty( gamemode ) || string_equal( gamemode, "sp" ) )? 0 : 1 ); +} +typedef FreeCaller1 GameModeExportCaller; - const char* new_gamename = path_equal( dir, globalGameComboConfiguration().basegame_dir ) - ? "" - : dir; + +void FSGameImport( int value ){ +} +typedef FreeCaller1 FSGameImportCaller; + +void FSGameExport( const IntImportCallback& importer ){ +} +typedef FreeCaller1 FSGameExportCaller; + + +void GameImport( int value ){ + const auto dir = s_gameCombo.fsgame_entry->currentText().toLatin1(); + + const char* new_gamename = dir.isEmpty() + ? globalGameComboConfiguration().basegame_dir + : dir.constData(); if ( !path_equal( new_gamename, gamename_get() ) ) { if ( ConfirmModified( "Edit Project Settings" ) ) { @@ -332,512 +216,268 @@ void ProjectSettingsDialog_ok( ProjectSettingsDialog& dialog ){ EnginePath_Realise(); } } - - if ( globalMappingMode().do_mapping_mode ) { - // read from gamemode_combo - int active = gtk_combo_box_get_active( dialog.gamemode_combo ); - if ( active == -1 || active == 0 ) { - gamemode_set( "sp" ); - } - else - { - gamemode_set( "mp" ); - } - } } +typedef FreeCaller1 GameImportCaller; -void DoProjectSettings(){ - //if ( ConfirmModified( "Edit Project Settings" ) ) { - ModalDialog modal; - ProjectSettingsDialog dialog; +void GameExport( const IntImportCallback& importer ){ + const gamecombo_t gamecombo = gamecombo_for_dir( gamename_get() ); - GtkWindow* window = ProjectSettingsDialog_construct( dialog, modal ); + s_gameCombo.game_select->setCurrentIndex( gamecombo.game ); + s_gameCombo.fsgame_entry->setEditText( gamecombo.fs_game ); + s_gameCombo.fsgame_entry->setEnabled( gamecombo.sensitive ); +} +typedef FreeCaller1 GameExportCaller; - if ( modal_dialog_show( window, modal ) == eIDOK ) { - ProjectSettingsDialog_ok( dialog ); + +void Game_constructPreferences( PreferencesPage& page ){ + { + s_gameCombo.game_select = page.appendCombo( + "Select mod", + StringArrayRange(), + IntImportCallback( GameImportCaller() ), + IntExportCallback( GameExportCaller() ) + ); + s_gameCombo.game_select->addItem( globalGameComboConfiguration().basegame ); + if ( !string_empty( globalGameComboConfiguration().known ) ) + s_gameCombo.game_select->addItem( globalGameComboConfiguration().known ); + s_gameCombo.game_select->addItem( globalGameComboConfiguration().custom ); } + { + s_gameCombo.fsgame_entry = page.appendCombo( + "fs_game", + StringArrayRange(), + IntImportCallback( FSGameImportCaller() ), + IntExportCallback( FSGameExportCaller() ) + ); + s_gameCombo.fsgame_entry->setEditable( true ); + std::error_code err; // use func version with error handling, since other throws error on non-existing directory + for( const auto& entry : std::filesystem::directory_iterator( EnginePath_get(), std::filesystem::directory_options::skip_permission_denied, err ) ) + if( entry.is_directory() ) + s_gameCombo.fsgame_entry->addItem( entry.path().filename().string().c_str() ); + } + QObject::connect( s_gameCombo.game_select, &QComboBox::currentTextChanged, []( const QString& text ){ + const gamecombo_t gamecombo = gamecombo_for_gamename( text.toLatin1().constData() ); + s_gameCombo.fsgame_entry->setEditText( gamecombo.fs_game ); + s_gameCombo.fsgame_entry->setEnabled( gamecombo.sensitive ); + } ); - gtk_widget_destroy( GTK_WIDGET( window ) ); - //} + if( globalMappingMode().do_mapping_mode ){ + page.appendCombo( + "Mapping mode", + (const char*[]){ globalMappingMode().sp_mapping_mode, globalMappingMode().mp_mapping_mode }, + IntImportCallback( GameModeImportCaller() ), + IntExportCallback( GameModeExportCaller() ) + ); + } } // ============================================================================= // Arbitrary Sides dialog -void DoSides( int type, int axis ){ - ModalDialog dialog; - GtkWidget* spin, *toggle; - - GtkWindow* window = create_dialog_window( MainFrame_getWindow(), "Arbitrary sides", G_CALLBACK( dialog_delete_callback ), &dialog ); - - GtkAccelGroup* accel = gtk_accel_group_new(); - gtk_window_add_accel_group( window, accel ); +void DoSides( EBrushPrefab type ){ + QDialog dialog( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Arbitrary sides" ); + auto spin = new SpinBox; + auto check = new QCheckBox( "Truncate" ); { - GtkVBox* vbox = create_dialog_vbox( 0, 0 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox ) ); - GtkHBox* hbox = create_dialog_hbox( 4, 4 ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox ), FALSE, FALSE, 0 ); + auto form = new QFormLayout( &dialog ); + form->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); - GtkLabel* label; + QLabel* label = new SpinBoxLabel( "Sides:", spin ); + form->addRow( label, spin ); + form->addWidget( check ); + check->hide(); { - label = GTK_LABEL( gtk_label_new( "Sides:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( label ), FALSE, FALSE, 0 ); - } - { - toggle = gtk_check_button_new_with_label( "Truncate" ); - gtk_box_pack_end( GTK_BOX( vbox ), toggle, FALSE, FALSE, 0 ); - } - { - GtkAdjustment* adj; - EBrushPrefab BrushPrefabType = (EBrushPrefab)type; - switch ( BrushPrefabType ) + switch ( type ) { - case eBrushPrism : - case eBrushCone : - adj = GTK_ADJUSTMENT( gtk_adjustment_new( 8, 3, 1022, 1, 10, 0 ) ); + case EBrushPrefab::Prism : + case EBrushPrefab::Cone : + spin->setValue( 8 ); + spin->setRange( 3, 1022 ); break; - case eBrushSphere : - adj = GTK_ADJUSTMENT( gtk_adjustment_new( 8, 3, 31, 1, 10, 0 ) ); + case EBrushPrefab::Sphere : + spin->setValue( 8 ); + spin->setRange( 3, 31 ); break; - case eBrushRock : - adj = GTK_ADJUSTMENT( gtk_adjustment_new( 32, 10, 1000, 1, 10, 0 ) ); + case EBrushPrefab::Rock : + spin->setValue( 32 ); + spin->setRange( 10, 1000 ); break; - case eBrushIcosahedron : - adj = GTK_ADJUSTMENT( gtk_adjustment_new( 1, 0, 2, 1, 10, 0 ) ); //possible with 3, but buggy - gtk_widget_show( toggle ); - gtk_label_set_label( label, "Subdivisions" ); + case EBrushPrefab::Icosahedron : + spin->setValue( 1 ); + spin->setRange( 0, 2 ); //possible with 3, but buggy + check->show(); + label->setText( "Subdivisions:" ); break; default: - adj = GTK_ADJUSTMENT( gtk_adjustment_new( 8, 3, 31, 1, 10, 0 ) ); break; } - - spin = gtk_spin_button_new( adj, 1, 0 ); - gtk_widget_show( spin ); - gtk_box_pack_start( GTK_BOX( hbox ), spin, FALSE, FALSE, 0 ); - gtk_widget_set_size_request( spin, 64, -1 ); - gtk_spin_button_set_numeric( GTK_SPIN_BUTTON( spin ), TRUE ); } { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), TRUE, TRUE, 0 ); - { - GtkButton* button = create_dialog_button( "OK", G_CALLBACK( dialog_button_ok ), &dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 ); - } - { - GtkButton* button = create_dialog_button( "Cancel", G_CALLBACK( dialog_button_cancel ), &dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 ); - } + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel ); + form->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept ); + QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject ); } } - if ( modal_dialog_show( window, dialog ) == eIDOK ) { - gtk_spin_button_update ( GTK_SPIN_BUTTON( spin ) ); - const int sides = static_cast( gtk_spin_button_get_value( GTK_SPIN_BUTTON( spin ) ) ); - const bool option = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( toggle ) ); - Scene_BrushConstructPrefab( GlobalSceneGraph(), (EBrushPrefab)type, sides, option, TextureBrowser_GetSelectedShader() ); + if ( dialog.exec() ) { + const int sides = spin->value(); + const bool option = check->isChecked(); + Scene_BrushConstructPrefab( GlobalSceneGraph(), type, sides, option, TextureBrowser_GetSelectedShader() ); } - - gtk_widget_destroy( GTK_WIDGET( window ) ); } // ============================================================================= // About dialog (no program is complete without one) -void about_button_changelog( GtkWidget *widget, gpointer data ){ - StringOutputStream log( 256 ); - log << AppPath_get() << "changelog.txt"; - OpenURL( log.c_str() ); -} - -void about_button_credits( GtkWidget *widget, gpointer data ){ - StringOutputStream cred( 256 ); - cred << AppPath_get() << "credits.html"; - OpenURL( cred.c_str() ); -} - void DoAbout(){ - ModalDialog dialog; - ModalDialogButton ok_button( dialog, eIDOK ); - - GtkWindow* window = create_modal_dialog_window( MainFrame_getWindow(), "About NetRadiant", dialog ); + QDialog dialog( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "About NetRadiant" ); { - GtkVBox* vbox = create_dialog_vbox( 4, 4 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox ) ); - + auto vbox = new QVBoxLayout( &dialog ); { - GtkHBox* hbox = create_dialog_hbox( 4 ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox ), FALSE, TRUE, 0 ); - + auto hbox = new QHBoxLayout; + vbox->addLayout( hbox ); { - GtkVBox* vbox2 = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox2 ), TRUE, FALSE, 0 ); - { - //GtkFrame* frame = create_dialog_frame( 0, GTK_SHADOW_IN ); - //gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( frame ), FALSE, FALSE, 0 ); - { - GtkImage* image = new_local_image( "logo.png" ); - gtk_widget_show( GTK_WIDGET( image ) ); - gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( image ), FALSE, FALSE, 0 ); - //gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( image ) ); - } - } + auto label = new QLabel; + label->setPixmap( new_local_image( "logo.png" ) ); + hbox->addWidget( label ); } { - GtkLabel* label = GTK_LABEL( gtk_label_new( "NetRadiant " RADIANT_VERSION "\n" - __DATE__ "\n\n" - RADIANT_ABOUTMSG "\n\n" - "By alientrap.org\n\n" - "This program is free software\n" - "licensed under the GNU GPL.\n" - ) ); - - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( label ), FALSE, FALSE, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 ); - gtk_label_set_justify( label, GTK_JUSTIFY_LEFT ); + auto label = new QLabel( "NetRadiant " RADIANT_VERSION "\n" + __DATE__ "\n\n" + RADIANT_ABOUTMSG "\n\n" + "By alientrap.org\n\n" + "This program is free software\n" + "licensed under the GNU GPL.\n" + ); + hbox->addWidget( label ); } { - GtkVBox* vbox2 = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox2 ), FALSE, TRUE, 0 ); + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok, Qt::Orientation::Vertical ); + QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept ); + hbox->addWidget( buttons ); { - GtkButton* button = create_modal_dialog_button( "OK", ok_button ); - gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); + auto button = buttons->addButton( "Credits", QDialogButtonBox::ButtonRole::NoRole ); + QObject::connect( button, &QPushButton::clicked, [](){ OpenURL( StringOutputStream( 256 )( AppPath_get(), "credits.html" ) ); } ); + button->setEnabled( false ); } { - GtkButton* button = create_dialog_button( "Credits", G_CALLBACK( about_button_credits ), 0 ); - gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - gtk_widget_set_sensitive( GTK_WIDGET( button ), FALSE); - } - { - GtkButton* button = create_dialog_button( "Changelog", G_CALLBACK( about_button_changelog ), 0 ); - gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - gtk_widget_set_sensitive( GTK_WIDGET( button ), FALSE); + auto button = buttons->addButton( "Changelog", QDialogButtonBox::ButtonRole::NoRole ); + QObject::connect( button, &QPushButton::clicked, [](){ OpenURL( StringOutputStream( 256 )( AppPath_get(), "changelog.txt" ) ); } ); + button->setEnabled( false ); } } } { - GtkFrame* frame = create_dialog_frame( "OpenGL Properties" ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( frame ), FALSE, FALSE, 0 ); { - GtkTable* table = create_dialog_table( 3, 2, 4, 4, 4 ); - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( table ) ); + auto frame = new QGroupBox( "OpenGL Properties" ); + vbox->addWidget( frame ); { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Vendor:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Version:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Renderer:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 2, 3, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( reinterpret_cast( glGetString( GL_VENDOR ) ) ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( reinterpret_cast( glGetString( GL_VERSION ) ) ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( reinterpret_cast( glGetString( GL_RENDERER ) ) ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 1, 2, 2, 3, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); + auto form = new QFormLayout( frame ); + form->addRow( "Vendor:", new QLabel( reinterpret_cast( gl().glGetString( GL_VENDOR ) ) ) ); + form->addRow( "Version:", new QLabel( reinterpret_cast( gl().glGetString( GL_VERSION ) ) ) ); + form->addRow( "Renderer:", new QLabel( reinterpret_cast( gl().glGetString( GL_RENDERER ) ) ) ); } } { - GtkFrame* frame = create_dialog_frame( "OpenGL Extensions" ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( frame ), TRUE, TRUE, 0 ); + auto frame = new QGroupBox( "OpenGL Extensions" ); + vbox->addWidget( frame ); { - GtkScrolledWindow* sc_extensions = create_scrolled_window( GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, 4 ); - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( sc_extensions ) ); - { - GtkWidget* text_extensions = gtk_text_view_new(); - gtk_text_view_set_editable( GTK_TEXT_VIEW( text_extensions ), FALSE ); - gtk_container_add( GTK_CONTAINER( sc_extensions ), text_extensions ); - GtkTextBuffer* buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW( text_extensions ) ); - gtk_text_buffer_set_text( buffer, reinterpret_cast( glGetString( GL_EXTENSIONS ) ), -1 ); - gtk_text_view_set_wrap_mode( GTK_TEXT_VIEW( text_extensions ), GTK_WRAP_WORD ); - gtk_widget_show( text_extensions ); - } + auto textView = new QPlainTextEdit( reinterpret_cast( gl().glGetString( GL_EXTENSIONS ) ) ); + textView->setReadOnly( true ); + auto box = new QVBoxLayout( frame ); + box->addWidget( textView ); } } } } - - modal_dialog_show( window, dialog ); - - gtk_widget_destroy( GTK_WIDGET( window ) ); + dialog.exec(); } // ============================================================================= -// TextureLayout dialog - -// Last used texture scale values -static float last_used_texture_layout_scale_x = 4.0; -static float last_used_texture_layout_scale_y = 4.0; - -EMessageBoxReturn DoTextureLayout( float *fx, float *fy ){ - ModalDialog dialog; - ModalDialogButton ok_button( dialog, eIDOK ); - ModalDialogButton cancel_button( dialog, eIDCANCEL ); - GtkEntry* x; - GtkEntry* y; - - GtkWindow* window = create_modal_dialog_window( MainFrame_getWindow(), "Patch texture layout", dialog ); - - GtkAccelGroup* accel = gtk_accel_group_new(); - gtk_window_add_accel_group( window, accel ); - - { - GtkHBox* hbox = create_dialog_hbox( 4, 4 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( hbox ) ); - { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), TRUE, TRUE, 0 ); - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Texture will be fit across the patch based\n" - "on the x and y values given. Values of 1x1\n" - "will \"fit\" the texture. 2x2 will repeat\n" - "it twice, etc." ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( label ), TRUE, TRUE, 0 ); - gtk_label_set_justify( label, GTK_JUSTIFY_LEFT ); - } - { - GtkTable* table = create_dialog_table( 2, 2, 4, 4 ); - gtk_widget_show( GTK_WIDGET( table ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Texture x:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Texture y:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - x = entry; - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - y = entry; - } - } - } - { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), FALSE, FALSE, 0 ); - { - GtkButton* button = create_modal_dialog_button( "OK", ok_button ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 ); - } - { - GtkButton* button = create_modal_dialog_button( "Cancel", cancel_button ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 ); - } - } - } - - // Initialize with last used values - char buf[16]; - - sprintf( buf, "%f", last_used_texture_layout_scale_x ); - gtk_entry_set_text( x, buf ); - - sprintf( buf, "%f", last_used_texture_layout_scale_y ); - gtk_entry_set_text( y, buf ); - - // Set focus after initializing the values - gtk_widget_grab_focus( GTK_WIDGET( x ) ); - - EMessageBoxReturn ret = modal_dialog_show( window, dialog ); - if ( ret == eIDOK ) { - *fx = static_cast( atof( gtk_entry_get_text( x ) ) ); - *fy = static_cast( atof( gtk_entry_get_text( y ) ) ); - - // Remember last used values - last_used_texture_layout_scale_x = *fx; - last_used_texture_layout_scale_y = *fy; - } - - gtk_widget_destroy( GTK_WIDGET( window ) ); - - return ret; -} - class TextEditor { - GtkWidget *m_window = 0; - GtkWidget *m_textView; // slave, text widget from the gtk editor - GtkTextBuffer* m_textBuffer; - GtkWidget *m_button; // save button + QWidget *m_window = 0; + QTextEdit *m_textView; // slave, text widget from the gtk editor + QPushButton *m_button; // save button CopiedString m_filename; void construct(){ - GtkWidget *vbox, *hbox, *scr; + m_window = new QWidget( MainFrame_getWindow(), Qt::Window ); + g_guiSettings.addWindow( m_window, "ShaderEditor/geometry" ); - m_window = GTK_WIDGET( create_dialog_window( MainFrame_getWindow(), "", G_CALLBACK( gtk_widget_hide_on_delete ), 0, 400, 600 ) ); + auto *vbox = new QVBoxLayout( m_window ); + vbox->setContentsMargins( 0, 0, 0, 0 ); - vbox = gtk_vbox_new( FALSE, 5 ); - gtk_widget_show( vbox ); - gtk_container_add( GTK_CONTAINER( m_window ), GTK_WIDGET( vbox ) ); - gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 ); + m_textView = new QTextEdit; + m_textView->setAcceptRichText( false ); + m_textView->setLineWrapMode( QTextEdit::LineWrapMode::NoWrap ); + vbox->addWidget( m_textView ); - scr = gtk_scrolled_window_new( 0, 0 ); - gtk_widget_show( scr ); - gtk_box_pack_start( GTK_BOX( vbox ), scr, TRUE, TRUE, 0 ); - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); - gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN ); + m_button = new QPushButton( "Save" ); + m_button->setSizePolicy( QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed ); + vbox->addWidget( m_button, Qt::AlignmentFlag::AlignRight ); - m_textView = gtk_text_view_new(); - gtk_container_add( GTK_CONTAINER( scr ), m_textView ); - gtk_widget_show( m_textView ); + QObject::connect( m_textView->document(), &QTextDocument::modificationChanged, [this]( bool modified ){ + m_button->setEnabled( modified ); - m_textBuffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW( m_textView ) ); - g_signal_connect( G_OBJECT( m_textBuffer ), "modified-changed", - G_CALLBACK( modified_changed ), this ); + StringOutputStream str( 256 ); + str << ( modified? "*" : "" ) << m_filename; + m_window->setWindowTitle( str.c_str() ); + } ); - hbox = gtk_hbox_new( FALSE, 5 ); - gtk_widget_show( hbox ); - gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, TRUE, 0 ); - - m_button = gtk_button_new_with_label( "Close" ); - gtk_widget_show( m_button ); - gtk_box_pack_end( GTK_BOX( hbox ), m_button, FALSE, FALSE, 0 ); - g_signal_connect( G_OBJECT( m_button ), "clicked", - G_CALLBACK( editor_close ), this ); - gtk_widget_set_size_request( m_button, 60, -1 ); - - m_button = gtk_button_new_with_label( "Save" ); - gtk_widget_show( m_button ); - gtk_box_pack_end( GTK_BOX( hbox ), m_button, FALSE, FALSE, 0 ); - g_signal_connect( G_OBJECT( m_button ), "clicked", - G_CALLBACK( editor_save ), this ); - gtk_widget_set_size_request( m_button, 60, -1 ); + QObject::connect( m_button, &QAbstractButton::clicked, [this](){ editor_save(); } ); } - static void editor_close( GtkWidget *widget, TextEditor* self ){ - gtk_widget_hide( self->m_window ); - } - static void editor_save( GtkWidget *widget, TextEditor* self ){ - FILE *f = fopen( self->m_filename.c_str(), "wb" ); //write in binary mode to preserve line feeds + void editor_save(){ + FILE *f = fopen( m_filename.c_str(), "wb" ); //write in binary mode to preserve line feeds - if ( f == 0 ) { - gtk_MessageBox( self->m_window, "Error saving file !" ); + if ( f == nullptr ) { + globalErrorStream() << "Error saving file" << makeQuoted( m_filename ) << '\n'; return; } - /* Obtain iters for the start and end of points of the buffer */ - GtkTextIter start, end; - gtk_text_buffer_get_bounds( self->m_textBuffer, &start, &end ); - - /* Get the entire buffer text. */ - char *str = gtk_text_buffer_get_text( self->m_textBuffer, &start, &end, FALSE ); - - fwrite( str, 1, strlen( str ), f ); + const auto str = m_textView->toPlainText().toLatin1(); + fwrite( str.constData(), 1, str.length(), f ); fclose( f ); - g_free ( str ); - gtk_text_buffer_set_modified( self->m_textBuffer, FALSE ); + m_textView->document()->setModified( false ); } - static void modified_changed( GtkTextBuffer *textbuffer, TextEditor* self ){ - const gboolean modified = gtk_text_buffer_get_modified( textbuffer ); - gtk_widget_set_sensitive( self->m_button, modified ); - - StringOutputStream str( 256 ); - str << ( modified? "*" : "" ) << self->m_filename; - gtk_window_set_title( GTK_WINDOW( self->m_window ), str.c_str() ); - } - public: - void DoGtkTextEditor( const char* text, std::size_t size, std::size_t offset, const char* filename, const bool editable ){ + void DoGtkTextEditor( const char* text, const char* shaderName, const char* filename, const bool editable ){ if ( !m_window ) { construct(); // build it the first time we need it } m_filename = filename; + m_textView->setReadOnly( !editable ); + m_textView->setPlainText( text ); - gtk_text_buffer_set_text( m_textBuffer, text, size ); - gtk_text_buffer_set_modified( m_textBuffer, FALSE ); + m_window->show(); + m_window->raise(); + m_window->activateWindow(); - gtk_text_view_set_editable( GTK_TEXT_VIEW( m_textView ), editable ); + { // scroll to shader + const QRegularExpression::PatternOptions rxFlags = QRegularExpression::PatternOption::MultilineOption | + QRegularExpression::PatternOption::CaseInsensitiveOption; + const QRegularExpression rx( "^\\s*" + QRegularExpression::escape( shaderName ) + "(|:q3map)$", rxFlags ); + auto *doc = m_textView->document(); - // trying to show later - gtk_widget_show( m_window ); - gtk_window_present( GTK_WINDOW( m_window ) ); - - //#ifdef WIN32 - process_gui(); - //#endif - - { - GtkTextIter text_iter; - gtk_text_buffer_get_iter_at_offset( m_textBuffer, &text_iter, offset ); - gtk_text_buffer_place_cursor( m_textBuffer, &text_iter ); - gtk_text_view_scroll_to_iter( GTK_TEXT_VIEW( m_textView ), &text_iter, 0, TRUE, 0, 0); + for( QTextCursor cursor( doc ); cursor = doc->find( rx ), !cursor.isNull(); ) + if( !doc->find( QRegularExpression( "^\\s*\\{", rxFlags ), cursor ).isNull() ){ + QTextCursor cur( cursor ); + cur.movePosition( QTextCursor::MoveOperation::NextBlock, QTextCursor::MoveMode::MoveAnchor, 99 ); + m_textView->setTextCursor( cur ); + m_textView->setTextCursor( cursor ); + break; + } } - - //#ifdef WIN32 - gtk_widget_queue_draw( m_textView ); - //#endif } }; @@ -847,211 +487,60 @@ static TextEditor g_textEditor; // ============================================================================= // Light Intensity dialog -bool g_dontDoLightIntensityDlg = false; +static bool g_dontDoLightIntensityDlg = false; -void dontDoLightIntensityDlg_toggled( GtkToggleButton* togglebutton, gpointer user_data ){ - g_dontDoLightIntensityDlg = gtk_toggle_button_get_active( togglebutton ); -} +bool DoLightIntensityDlg( int *intensity ){ + if( g_dontDoLightIntensityDlg ) + return true; -EMessageBoxReturn DoLightIntensityDlg( int *intensity ){ - if( g_dontDoLightIntensityDlg ){ - return eIDOK; - } - ModalDialog dialog; - GtkEntry* intensity_entry; - ModalDialogButton ok_button( dialog, eIDOK ); - ModalDialogButton cancel_button( dialog, eIDCANCEL ); + QDialog dialog( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Light intensity" ); - GtkWindow* window = create_modal_dialog_window( MainFrame_getWindow(), "Light intensity", dialog, -1, -1 ); + auto spin = new SpinBox( -99999, 99999, *intensity ); - GtkAccelGroup *accel_group = gtk_accel_group_new(); - gtk_window_add_accel_group( window, accel_group ); + auto check = new QCheckBox( "Don't Show" ); + QObject::connect( check, &QCheckBox::toggled, []( bool checked ){ g_dontDoLightIntensityDlg = checked; } ); { - GtkHBox* hbox = create_dialog_hbox( 4, 4 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( hbox ) ); + auto form = new QFormLayout( &dialog ); + form->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + form->addRow( new QLabel( "ESC for default, ENTER to validate" ) ); + form->addRow( new SpinBoxLabel( "Intensity:", spin ), spin ); + form->addWidget( check ); + { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), TRUE, TRUE, 0 ); - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "ESC for default, ENTER to validate" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( label ), FALSE, FALSE, 0 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( entry ), TRUE, TRUE, 0 ); - - gtk_widget_grab_focus( GTK_WIDGET( entry ) ); - - intensity_entry = entry; - } - { - GtkWidget* check = gtk_check_button_new_with_label( "Don't Show" ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( check ), FALSE ); - gtk_widget_show( check ); - gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 ); - g_signal_connect( G_OBJECT( check ), "toggled", G_CALLBACK( dontDoLightIntensityDlg_toggled ), 0 ); - } - } - { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), FALSE, FALSE, 0 ); - - { - GtkButton* button = create_modal_dialog_button( "OK", ok_button ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel_group, GDK_KEY_Return, (GdkModifierType)0, GTK_ACCEL_VISIBLE ); - } - { - GtkButton* button = create_modal_dialog_button( "Cancel", cancel_button ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel_group, GDK_KEY_Escape, (GdkModifierType)0, GTK_ACCEL_VISIBLE ); - } + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel ); + form->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept ); + QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject ); } } - char buf[16]; - sprintf( buf, "%d", *intensity ); - gtk_entry_set_text( intensity_entry, buf ); - - EMessageBoxReturn ret = modal_dialog_show( window, dialog ); - if ( ret == eIDOK ) { - *intensity = atoi( gtk_entry_get_text( intensity_entry ) ); + if ( dialog.exec() ) { + *intensity = spin->value(); + return true; } - - gtk_widget_destroy( GTK_WIDGET( window ) ); - - return ret; + else + return false; } -// ============================================================================= -// Add new shader tag dialog +void DoShaderInfoDlg( const char* name, const char* filename, const char* title ){ + StringOutputStream text( 256 ); + text << "  The selected shader
"; + text << "" << name << "
"; + text << "  is located in file
"; + text << "" << filename << ""; -EMessageBoxReturn DoShaderTagDlg( CopiedString& tag, const char* title ){ - ModalDialog dialog; - GtkEntry* textentry; - ModalDialogButton ok_button( dialog, eIDOK ); - ModalDialogButton cancel_button( dialog, eIDCANCEL ); - - GtkWindow* window = create_modal_dialog_window( MainFrame_getWindow(), title, dialog, -1, -1 ); - - GtkAccelGroup *accel_group = gtk_accel_group_new(); - gtk_window_add_accel_group( window, accel_group ); - - { - GtkHBox* hbox = create_dialog_hbox( 4, 4 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( hbox ) ); - { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), TRUE, TRUE, 0 ); - { - //GtkLabel* label = GTK_LABEL(gtk_label_new("Enter one ore more tags separated by spaces")); - GtkLabel* label = GTK_LABEL( gtk_label_new( "ESC to cancel, ENTER to validate" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( label ), FALSE, FALSE, 0 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( entry ), TRUE, TRUE, 0 ); - - gtk_widget_grab_focus( GTK_WIDGET( entry ) ); - - textentry = entry; - } - } - { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), FALSE, FALSE, 0 ); - - { - GtkButton* button = create_modal_dialog_button( "OK", ok_button ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel_group, GDK_KEY_Return, (GdkModifierType)0, GTK_ACCEL_VISIBLE ); - } - { - GtkButton* button = create_modal_dialog_button( "Cancel", cancel_button ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel_group, GDK_KEY_Escape, (GdkModifierType)0, GTK_ACCEL_VISIBLE ); - } - } - } - - EMessageBoxReturn ret = modal_dialog_show( window, dialog ); - if ( ret == eIDOK ) { - tag = gtk_entry_get_text( textentry ); - } - - gtk_widget_destroy( GTK_WIDGET( window ) ); - - return ret; -} - -EMessageBoxReturn DoShaderInfoDlg( const char* name, const char* filename, const char* title ){ - ModalDialog dialog; - ModalDialogButton ok_button( dialog, eIDOK ); - - GtkWindow* window = create_modal_dialog_window( MainFrame_getWindow(), title, dialog, -1, -1 ); - - GtkAccelGroup *accel_group = gtk_accel_group_new(); - gtk_window_add_accel_group( window, accel_group ); - - { - GtkHBox* hbox = create_dialog_hbox( 4, 4 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( hbox ) ); - { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), FALSE, FALSE, 0 ); - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "The selected shader" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( label ), FALSE, FALSE, 0 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( name ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( label ), FALSE, FALSE, 0 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "is located in file" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( label ), FALSE, FALSE, 0 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( filename ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( label ), FALSE, FALSE, 0 ); - } - { - GtkButton* button = create_modal_dialog_button( "OK", ok_button ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel_group, GDK_KEY_Return, (GdkModifierType)0, GTK_ACCEL_VISIBLE ); - } - } - } - - EMessageBoxReturn ret = modal_dialog_show( window, dialog ); - - gtk_widget_destroy( GTK_WIDGET( window ) ); - - return ret; + qt_MessageBox( MainFrame_getWindow(), text.c_str(), title ); } -CopiedString g_TextEditor_editorCommand( "" ); +CopiedString g_TextEditor_editorCommand; #include "ifilesystem.h" #include "iarchive.h" #include "idatastream.h" -#ifdef WIN32 -#include -#endif void DoShaderView( const char *shaderFileName, const char *shaderName, bool external_editor ){ const char* pathRoot = GlobalFileSystem().findFile( shaderFileName ); @@ -1067,7 +556,7 @@ void DoShaderView( const char *shaderFileName, const char *shaderName, bool exte else if( external_editor && pathIsDir ){ if( g_TextEditor_editorCommand.empty() ){ #ifdef WIN32 - ShellExecute( (HWND)GDK_WINDOW_HWND( gtk_widget_get_window( GTK_WIDGET( MainFrame_getWindow() ) ) ), 0, pathFull.c_str(), 0, 0, SW_SHOWNORMAL ); + ShellExecute( (HWND)MainFrame_getWindow()->effectiveWinId(), 0, pathFull.c_str(), 0, 0, SW_SHOWNORMAL ); #else globalWarningStream() << "Failed to open '" << pathFull.c_str() << "'\nSet Shader Editor Command in preferences\n"; #endif @@ -1088,58 +577,7 @@ void DoShaderView( const char *shaderFileName, const char *shaderName, bool exte text[size] = 0; file->release(); - // look for the shader declaration - std::size_t offset = 0; - bool startOK = false; - bool endOK = false; - while ( !startOK || !endOK ){ - const char* found = string_in_string_nocase( text + offset, shaderName ); - if ( found == 0 ) { - break; - } - else{ - offset = found - text; - //validate found one... - startOK = endOK = false; - if ( offset == 0 ){ - startOK = true; - } - else{ - for ( const char* i = found - 1; i >= text; --i ){ - if( *i == '\t' || *i == ' ' ){ - startOK = true; - continue; - } - else if( *i == '\n' || *i == '\r' || *i == '}' ){ - startOK = true; - break; - } - else{ - startOK = false; - break; - } - } - } - for ( const char* i = found + strlen( shaderName ); i < text + size; ++i ){ - if( *i == '\t' || *i == ' ' ){ - endOK = true; - continue; - } - else if( *i == '\n' || *i == '\r' || *i == '{' || string_equal_nocase_n( i, ":q3map", 6 ) ){ - endOK = true; - break; - } - else{ - endOK = false; - break; - } - } - if( !startOK || !endOK ){ - ++offset; - } - } - } - g_textEditor.DoGtkTextEditor( text, size, offset, pathFull.c_str(), pathIsDir ); + g_textEditor.DoGtkTextEditor( text, shaderName, pathFull.c_str(), pathIsDir ); free( text ); } } diff --git a/radiant/gtkdlgs.h b/radiant/gtkdlgs.h index 0ea42b56..e3da4af4 100644 --- a/radiant/gtkdlgs.h +++ b/radiant/gtkdlgs.h @@ -30,19 +30,16 @@ #pragma once -#include "qerplugin.h" #include "string/string.h" -EMessageBoxReturn DoLightIntensityDlg( int *intensity ); -EMessageBoxReturn DoShaderTagDlg( CopiedString& tag, const char* title ); -EMessageBoxReturn DoShaderInfoDlg( const char* name, const char* filename, const char* title ); -EMessageBoxReturn DoTextureLayout( float *fx, float *fy ); +bool DoLightIntensityDlg( int *intensity ); +void DoShaderInfoDlg( const char* name, const char* filename, const char* title ); void DoShaderView( const char *shaderFileName, const char *shaderName, bool external_editor ); -void DoProjectSettings(); +void Game_constructPreferences( class PreferencesPage& page ); -void DoFind(); -void DoSides( int type, int axis ); +enum class EBrushPrefab; +void DoSides( EBrushPrefab type ); void DoAbout(); diff --git a/radiant/gtkmisc.cpp b/radiant/gtkmisc.cpp index 661ab493..29c17b3f 100644 --- a/radiant/gtkmisc.cpp +++ b/radiant/gtkmisc.cpp @@ -34,8 +34,6 @@ #include "gtkmisc.h" -#include - #include "math/vector.h" #include "os/path.h" @@ -43,142 +41,164 @@ #include "gtkutil/filechooser.h" #include "gtkutil/menu.h" #include "gtkutil/toolbar.h" +#include "gtkutil/image.h" #include "commands.h" +#include +#include +#include + void process_gui(){ - while ( gtk_events_pending() ) - { - gtk_main_iteration(); - } + QCoreApplication::processEvents(); } // ============================================================================= // Misc stuff -void command_connect_accelerator( const char* name ){ - const Command& command = GlobalCommands_find( name ); +static QWidget *g_shortcuts_widget = nullptr; + +void GlobalShortcuts_setWidget( QWidget *widget ){ + g_shortcuts_widget = widget; +} + +inline QAction* command_connect_accelerator( const Command& command ){ + QAction *&action = command.getAction(); + if( action == nullptr ){ + action = new QAction( g_shortcuts_widget ); + g_shortcuts_widget->addAction( action ); + action->setShortcutContext( Qt::ShortcutContext::ApplicationShortcut ); + QObject::connect( action, &QAction::triggered, command.m_callback ); + } + action->setShortcut( command.m_accelerator ); + return action; +} + + +inline QAction* command_connect_accelerator_( const char* name ){ GlobalShortcuts_register( name, 1 ); - global_accel_group_connect( command.m_accelerator, command.m_callback ); + return command_connect_accelerator( GlobalCommands_find( name ) ); +} + +void command_connect_accelerator( const char* name ){ + command_connect_accelerator_( name ); } void command_disconnect_accelerator( const char* name ){ const Command& command = GlobalCommands_find( name ); - global_accel_group_disconnect( command.m_accelerator, command.m_callback ); + if( command.getAction() != nullptr ) + command.getAction()->setShortcut( {} ); +} + + +static void action_set_checked_callback( QAction& action, bool enabled ){ + action.setChecked( enabled ); +} +typedef ReferenceCaller1 ActionSetCheckedCaller; + +inline QAction* toggle_add_accelerator_( const char* name ){ + GlobalShortcuts_register( name, 2 ); + const Toggle& toggle = GlobalToggles_find( name ); + auto action = command_connect_accelerator( toggle.m_command ); + action->setCheckable( true ); + toggle.m_exportCallback( ActionSetCheckedCaller( *action ) ); + return action; } void toggle_add_accelerator( const char* name ){ - const Toggle& toggle = GlobalToggles_find( name ); - GlobalShortcuts_register( name, 2 ); - global_accel_group_connect( toggle.m_command.m_accelerator, toggle.m_command.m_callback ); + toggle_add_accelerator_( name ); } void toggle_remove_accelerator( const char* name ){ const Toggle& toggle = GlobalToggles_find( name ); - global_accel_group_disconnect( toggle.m_command.m_accelerator, toggle.m_command.m_callback ); + if( toggle.m_command.getAction() != nullptr ) + toggle.m_command.getAction()->setShortcut( {} ); } -GtkCheckMenuItem* create_check_menu_item_with_mnemonic( GtkMenu* menu, const char* mnemonic, const char* commandName ){ - GlobalShortcuts_register( commandName, 2 ); - const Toggle& toggle = GlobalToggles_find( commandName ); - global_accel_group_connect( toggle.m_command.m_accelerator, toggle.m_command.m_callback ); - return create_check_menu_item_with_mnemonic( menu, mnemonic, toggle ); + +QAction* create_check_menu_item_with_mnemonic( QMenu* menu, const char* mnemonic, const char* commandName ){ + auto action = toggle_add_accelerator_( commandName ); + action->setText( mnemonic ); + menu->addAction( action ); + return action; } -GtkMenuItem* create_menu_item_with_mnemonic( GtkMenu* menu, const char *mnemonic, const char* commandName ){ - GlobalShortcuts_register( commandName, 1 ); - const Command& command = GlobalCommands_find( commandName ); - global_accel_group_connect( command.m_accelerator, command.m_callback ); - return create_menu_item_with_mnemonic( menu, mnemonic, command ); +QAction* create_menu_item_with_mnemonic( QMenu *menu, const char *mnemonic, const char* commandName ){ + auto action = command_connect_accelerator_( commandName ); + action->setText( mnemonic ); + menu->addAction( action ); + return action; } -GtkToolButton* toolbar_append_button( GtkToolbar* toolbar, const char* description, const char* icon, const char* commandName ){ - return toolbar_append_button( toolbar, description, icon, GlobalCommands_find( commandName ) ); -} -GtkToggleToolButton* toolbar_append_toggle_button( GtkToolbar* toolbar, const char* description, const char* icon, const char* commandName ){ - return toolbar_append_toggle_button( toolbar, description, icon, GlobalToggles_find( commandName ) ); -} - -// ============================================================================= -// File dialog - -bool color_dialog( GtkWidget *parent, Vector3& color, const char* title ){ - GtkWidget* dlg; - GdkColor clr = { 0, guint16( color[0] * 65535 ), - guint16( color[1] * 65535 ), - guint16( color[2] * 65535 ) }; - ModalDialog dialog; - - dlg = gtk_color_selection_dialog_new( title ); - gtk_color_selection_set_current_color( GTK_COLOR_SELECTION( gtk_color_selection_dialog_get_color_selection( GTK_COLOR_SELECTION_DIALOG( dlg ) ) ), &clr ); - g_signal_connect( G_OBJECT( dlg ), "delete_event", G_CALLBACK( dialog_delete_callback ), &dialog ); - GtkWidget *ok_button, *cancel_button; - g_object_get( G_OBJECT( dlg ), "ok-button", &ok_button, "cancel-button", &cancel_button, nullptr ); - g_signal_connect( G_OBJECT( ok_button ), "clicked", G_CALLBACK( dialog_button_ok ), &dialog ); - g_signal_connect( G_OBJECT( cancel_button ), "clicked", G_CALLBACK( dialog_button_cancel ), &dialog ); - - if ( parent != 0 ) { - gtk_window_set_transient_for( GTK_WINDOW( dlg ), GTK_WINDOW( parent ) ); +// can update this on QAction::changed() signal, but it's called too often and even on setChecked(); let's only have this on construction +static void toolbar_action_set_tooltip( QAction *action, const char *description ){ + if( QKeySequence_valid( action->shortcut() ) ){ + QString out; + const char *p = description; + for( ; *p && *p != '\n'; ++p ) // append 1st line + out += *p; + out += " ("; + out += action->shortcut().toString(); // append shortcut + out += ")"; + for( ; *p; ++p ) // append the rest + out += *p; + action->setToolTip( out ); } - - bool ok = modal_dialog_show( GTK_WINDOW( dlg ), dialog ) == eIDOK; - if ( ok ) { - gtk_color_selection_get_current_color( GTK_COLOR_SELECTION( gtk_color_selection_dialog_get_color_selection( GTK_COLOR_SELECTION_DIALOG( dlg ) ) ), &clr ); - color[0] = clr.red / 65535.0; - color[1] = clr.green / 65535.0; - color[2] = clr.blue / 65535.0; + else{ + action->setToolTip( description ); } +} - gtk_widget_destroy( dlg ); +QAction* toolbar_append_button( QToolBar* toolbar, const char* description, const char* icon, const char* commandName ){ + auto action = command_connect_accelerator_( commandName ); + action->setIcon( new_local_icon( icon ) ); + toolbar_action_set_tooltip( action, description ); + toolbar->addAction( action ); + return action; +} +QAction* toolbar_append_toggle_button( QToolBar* toolbar, const char* description, const char* icon, const char* commandName ){ + auto action = toggle_add_accelerator_( commandName ); + action->setIcon( new_local_icon( icon ) ); + toolbar_action_set_tooltip( action, description ); + toolbar->addAction( action ); + return action; +} + +#include +bool color_dialog( QWidget *parent, Vector3& color, const char* title ){ + const QColor clr = QColorDialog::getColor( QColor::fromRgbF( color[0], color[1], color[2] ), parent, title ); + + if( clr.isValid() ) + color = Vector3( clr.redF(), clr.greenF(), clr.blueF() ); + return clr.isValid(); +} + +bool OpenGLFont_dialog( QWidget *parent, const char* font, const int size, CopiedString &newfont, int &newsize ){ + bool ok; + QFont f = QFontDialog::getFont( &ok, QFont( font, size ), parent ); + if( ok ){ + newfont = f.family().toLatin1().constData(); + newsize = f.pointSize(); + } return ok; } -bool OpenGLFont_dialog( GtkWidget *parent, const char* font, CopiedString &newfont ){ - GtkWidget* dlg; - ModalDialog dialog; - - - dlg = gtk_font_selection_dialog_new( "OpenGLFont" ); - gtk_font_selection_dialog_set_font_name( GTK_FONT_SELECTION_DIALOG( dlg ), font ); - - g_signal_connect( G_OBJECT( dlg ), "delete_event", G_CALLBACK( dialog_delete_callback ), &dialog ); - g_signal_connect( G_OBJECT( gtk_font_selection_dialog_get_ok_button( GTK_FONT_SELECTION_DIALOG( dlg ) ) ), "clicked", G_CALLBACK( dialog_button_ok ), &dialog ); - g_signal_connect( G_OBJECT( gtk_font_selection_dialog_get_cancel_button( GTK_FONT_SELECTION_DIALOG( dlg ) ) ), "clicked", G_CALLBACK( dialog_button_cancel ), &dialog ); - - if ( parent != 0 ) { - gtk_window_set_transient_for( GTK_WINDOW( dlg ), GTK_WINDOW( parent ) ); - } - - bool ok = modal_dialog_show( GTK_WINDOW( dlg ), dialog ) == eIDOK; - if ( ok ) { - gchar* selectedfont = gtk_font_selection_dialog_get_font_name( GTK_FONT_SELECTION_DIALOG( dlg ) ); - newfont = selectedfont; - g_free( selectedfont ); - } - - gtk_widget_destroy( dlg ); - - return ok; -} - -void button_clicked_entry_browse_file( GtkWidget* widget, GtkEntry* entry ){ - const char *filename = file_dialog( gtk_widget_get_toplevel( widget ), true, "Choose File", gtk_entry_get_text( entry ) ); +void button_clicked_entry_browse_file( QLineEdit* entry ){ + const char *filename = file_dialog( entry, true, "Choose File", entry->text().toLatin1().constData() ); if ( filename != 0 ) { - gtk_entry_set_text( entry, filename ); + entry->setText( filename ); } } -void button_clicked_entry_browse_directory( GtkWidget* widget, GtkEntry* entry ){ - const char* text = gtk_entry_get_text( entry ); - char *dir = dir_dialog( gtk_widget_get_toplevel( widget ), "Choose Directory", path_is_absolute( text ) ? text : "" ); +void button_clicked_entry_browse_directory( QLineEdit* entry ){ + const QString dir = dir_dialog( entry, + path_is_absolute( entry->text().toLatin1().constData() ) + ? entry->text() + : QString() ); - if ( dir != 0 ) { - gchar* converted = g_filename_to_utf8( dir, -1, 0, 0, 0 ); - gtk_entry_set_text( entry, converted ); - g_free( dir ); - g_free( converted ); - } + if ( !dir.isEmpty() ) + entry->setText( dir ); } diff --git a/radiant/gtkmisc.h b/radiant/gtkmisc.h index 1d32e648..66ecb703 100644 --- a/radiant/gtkmisc.h +++ b/radiant/gtkmisc.h @@ -30,39 +30,35 @@ #pragma once +#include +#include + void process_gui(); +void GlobalShortcuts_setWidget( QWidget *widget ); + void command_connect_accelerator( const char* commandName ); void command_disconnect_accelerator( const char* commandName ); void toggle_add_accelerator( const char* commandName ); void toggle_remove_accelerator( const char* name ); -typedef struct _GtkMenu GtkMenu; -typedef struct _GtkMenuItem GtkMenuItem; -typedef struct _GtkCheckMenuItem GtkCheckMenuItem; +// this also sets up the shortcut using command_connect_accelerator +QAction* create_menu_item_with_mnemonic( QMenu *menu, const char *mnemonic, const char* commandName ); +// this also sets up the shortcut using command_connect_accelerator +QAction* create_check_menu_item_with_mnemonic( QMenu* menu, const char* mnemonic, const char* commandName ); // this also sets up the shortcut using command_connect_accelerator -GtkMenuItem* create_menu_item_with_mnemonic( GtkMenu *menu, const char *mnemonic, const char* commandName ); +QAction* toolbar_append_button( QToolBar* toolbar, const char* description, const char* icon, const char* commandName ); // this also sets up the shortcut using command_connect_accelerator -GtkCheckMenuItem* create_check_menu_item_with_mnemonic( GtkMenu* menu, const char* mnemonic, const char* commandName ); +QAction* toolbar_append_toggle_button( QToolBar* toolbar, const char* description, const char* icon, const char* commandName ); -typedef struct _GtkToolButton GtkToolButton; -typedef struct _GtkToggleToolButton GtkToggleToolButton; -typedef struct _GtkToolbar GtkToolbar; - -// this DOES NOT set up the shortcut using command_connect_accelerator -GtkToolButton* toolbar_append_button( GtkToolbar* toolbar, const char* description, const char* icon, const char* commandName ); -// this DOES NOT set up the shortcut using command_connect_accelerator -GtkToggleToolButton* toolbar_append_toggle_button( GtkToolbar* toolbar, const char* description, const char* icon, const char* commandName ); - -typedef struct _GtkWidget GtkWidget; template class BasicVector3; typedef BasicVector3 Vector3; -bool color_dialog( GtkWidget *parent, Vector3& color, const char* title = "Choose Color" ); +bool color_dialog( QWidget *parent, Vector3& color, const char* title = "Choose Color" ); #include "string/stringfwd.h" -bool OpenGLFont_dialog( GtkWidget *parent, const char* font, CopiedString &newfont ); +bool OpenGLFont_dialog( QWidget *parent, const char* font, const int size, CopiedString &newfont, int &newsize ); -typedef struct _GtkEntry GtkEntry; -void button_clicked_entry_browse_file( GtkWidget* widget, GtkEntry* entry ); -void button_clicked_entry_browse_directory( GtkWidget* widget, GtkEntry* entry ); +class QLineEdit; +void button_clicked_entry_browse_file( QLineEdit* entry ); +void button_clicked_entry_browse_directory( QLineEdit* entry ); diff --git a/radiant/gtktheme.cpp b/radiant/gtktheme.cpp deleted file mode 100644 index 5f176bad..00000000 --- a/radiant/gtktheme.cpp +++ /dev/null @@ -1,652 +0,0 @@ -/*************************************************************************** - main.cpp - description - ------------------- - begin : Wed Jan 1 19:06:46 GMT+4 2003 - copyright : (C) 2003 - 2005 by Alex Shaduri - email : ashaduri '@' gmail.com - ***************************************************************************/ - - -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#include -#else -#include -#endif - -#include - -#include -#include -#include -#include - -#include "gtktheme.h" -#include "mainframe.h" - - -// ------------------------------------------------------ -std::string& get_orig_theme(); -std::string& get_orig_font(); - -std::string get_current_theme(); -std::string get_current_font(); - -std::string get_selected_theme(); -std::string get_selected_font(); - -void set_theme( const std::string& theme_name, const std::string& font ); -void apply_theme( const std::string& theme_name, const std::string& font ); - - -GtkWidget* g_main_rc_window = NULL; -static std::string s_rc_file; - - -// ------------------------------------------------------ -GtkWidget* lookup_widget( GtkWidget* widget, const gchar* widget_name ) { - GtkWidget* parent, *found_widget; - - for( ;; ) { - if( GTK_IS_MENU( widget ) ) - parent = gtk_menu_get_attach_widget( GTK_MENU( widget ) ); - else - parent = gtk_widget_get_parent( widget ); - if( !parent ) - parent = (GtkWidget*)g_object_get_data( G_OBJECT( widget ), "GladeParentKey" ); - if( parent == NULL ) - break; - widget = parent; - } - - found_widget = (GtkWidget*)g_object_get_data( G_OBJECT( widget ), widget_name ); - if( !found_widget ) - g_warning( "Widget not found: %s", widget_name ); - return found_widget; -} - - - -void on_main_cancel_button_clicked( GtkButton* button, gpointer user_data ) { - set_theme( get_orig_theme(), get_orig_font() ); - gtk_widget_destroy( g_main_rc_window ); - g_main_rc_window = NULL; -} - -void on_main_reset_button_clicked( GtkButton* button, gpointer user_data ) { - set_theme( get_orig_theme(), get_orig_font() ); -} - -gboolean on_main_window_delete_event( GtkWidget* widget, GdkEvent* event, gpointer user_data ) { - set_theme( get_orig_theme(), get_orig_font() ); - gtk_widget_destroy( g_main_rc_window ); - g_main_rc_window = NULL; - return TRUE; -} - -void on_main_use_default_font_radio_toggled( GtkToggleButton* togglebutton, gpointer user_data ) { - const bool default_font = gtk_toggle_button_get_active( togglebutton ); - gtk_widget_set_sensitive( lookup_widget( g_main_rc_window, "main_font_selector_button" ), !default_font ); - apply_theme( get_selected_theme(), get_selected_font() ); -} - -void on_main_font_selector_button_font_set( GtkFontButton* fontbutton, gpointer user_data ) { - apply_theme( get_selected_theme(), get_selected_font() ); -} - -void on_main_ok_button_clicked( GtkButton* button, gpointer user_data ) { - gtk_widget_destroy( g_main_rc_window ); - g_main_rc_window = NULL; -} - - -#define GLADE_HOOKUP_OBJECT( component, widget, name ) \ - g_object_set_data_full( G_OBJECT( component ), name, \ - g_object_ref( (gpointer)widget ), (GDestroyNotify)g_object_unref ) - -#define GLADE_HOOKUP_OBJECT_NO_REF( component, widget, name ) \ - g_object_set_data( G_OBJECT( component ), name, widget ) - -GtkWidget* create_rc_window() { - GtkWidget* main_window; - GtkWidget* main_hbox; - GtkWidget* vbox1; - GtkWidget* hbox1; - GtkWidget* frame2; - GtkWidget* alignment3; - GtkWidget* scrolledwindow3; - GtkWidget* main_themelist; - GtkWidget* label1234; - GtkWidget* frame3; - GtkWidget* alignment4; - GtkWidget* vbox7; - GtkWidget* hbox8; - GtkWidget* vbox9; - GtkWidget* main_use_default_font_radio; - GtkWidget* main_use_custom_font_radio; - GtkWidget* alignment5; - GtkWidget* vbox10; - GtkWidget* hbox9; - GtkWidget* vbox11; - GtkWidget* main_font_selector_button; - GtkWidget* label669; - GtkWidget* vbox13; - GtkWidget* hbuttonbox1; - GtkWidget* hbox7; - GtkWidget* vbox6; - GtkWidget* hbox5; - GtkWidget* main_ok_button; - GtkWidget* main_cancel_button; - GtkWidget* main_reset_button; - GtkWidget* alignment2; - GtkWidget* hbox6; - GtkWidget* image1; - GtkWidget* label667; - GtkAccelGroup* accel_group; - - accel_group = gtk_accel_group_new(); - - main_window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - gtk_widget_set_name( main_window, "main_window" ); - gtk_window_set_title( GTK_WINDOW( main_window ), "Gtk2 Theme Selector" ); - gtk_window_set_transient_for( GTK_WINDOW( main_window ), MainFrame_getWindow() ); - gtk_window_set_position( GTK_WINDOW( main_window ), GTK_WIN_POS_CENTER_ON_PARENT ); - gtk_window_set_destroy_with_parent( GTK_WINDOW( main_window ), TRUE ); - - //gtk_window_set_keep_above ( GTK_WINDOW( main_window ), TRUE ); - - main_hbox = gtk_hbox_new( FALSE, 0 ); - gtk_widget_set_name( main_hbox, "main_hbox" ); - gtk_widget_show( main_hbox ); - gtk_container_add( GTK_CONTAINER( main_window ), main_hbox ); - gtk_widget_set_size_request( main_hbox, 310, 320 ); - gtk_window_resize( GTK_WINDOW( main_window ), 310, 640 ); - - vbox1 = gtk_vbox_new( FALSE, 0 ); - gtk_widget_set_name( vbox1, "vbox1" ); - gtk_widget_show( vbox1 ); - gtk_box_pack_start( GTK_BOX( main_hbox ), vbox1, TRUE, TRUE, 0 ); - gtk_container_set_border_width( GTK_CONTAINER( vbox1 ), 3 ); - - hbox1 = gtk_hbox_new( FALSE, 0 ); - gtk_widget_set_name( hbox1, "hbox1" ); - gtk_widget_show( hbox1 ); - gtk_box_pack_start( GTK_BOX( vbox1 ), hbox1, TRUE, TRUE, 0 ); - - frame2 = gtk_frame_new( NULL ); - gtk_widget_set_name( frame2, "frame2" ); - gtk_widget_show( frame2 ); - gtk_box_pack_start( GTK_BOX( hbox1 ), frame2, TRUE, TRUE, 0 ); - gtk_frame_set_shadow_type( GTK_FRAME( frame2 ), GTK_SHADOW_NONE ); - - alignment3 = gtk_alignment_new( 0.5, 0.5, 1, 1 ); - gtk_widget_set_name( alignment3, "alignment3" ); - gtk_widget_show( alignment3 ); - gtk_container_add( GTK_CONTAINER( frame2 ), alignment3 ); - gtk_alignment_set_padding( GTK_ALIGNMENT( alignment3 ), 0, 0, 12, 0 ); - - scrolledwindow3 = gtk_scrolled_window_new( NULL, NULL ); - gtk_widget_set_name( scrolledwindow3, "scrolledwindow3" ); - gtk_widget_show( scrolledwindow3 ); - gtk_container_add( GTK_CONTAINER( alignment3 ), scrolledwindow3 ); - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolledwindow3 ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); - gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scrolledwindow3 ), GTK_SHADOW_IN ); - - main_themelist = gtk_tree_view_new(); - gtk_widget_set_name( main_themelist, "main_themelist" ); - gtk_widget_show( main_themelist ); - gtk_container_add( GTK_CONTAINER( scrolledwindow3 ), main_themelist ); - gtk_widget_set_can_default( main_themelist, TRUE ); - gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( main_themelist ), FALSE ); - - label1234 = gtk_label_new( "Theme" ); - gtk_widget_set_name( label1234, "label1234" ); - gtk_widget_show( label1234 ); - gtk_frame_set_label_widget( GTK_FRAME( frame2 ), label1234 ); - gtk_label_set_use_markup( GTK_LABEL( label1234 ), TRUE ); - - frame3 = gtk_frame_new( NULL ); - gtk_widget_set_name( frame3, "frame3" ); - gtk_widget_show( frame3 ); - gtk_box_pack_start( GTK_BOX( vbox1 ), frame3, FALSE, FALSE, 9 ); - gtk_frame_set_shadow_type( GTK_FRAME( frame3 ), GTK_SHADOW_NONE ); - - alignment4 = gtk_alignment_new( 0.5, 0.5, 1, 1 ); - gtk_widget_set_name( alignment4, "alignment4" ); - gtk_widget_show( alignment4 ); - gtk_container_add( GTK_CONTAINER( frame3 ), alignment4 ); - gtk_alignment_set_padding( GTK_ALIGNMENT( alignment4 ), 0, 0, 12, 0 ); - - vbox7 = gtk_vbox_new( FALSE, 0 ); - gtk_widget_set_name( vbox7, "vbox7" ); - gtk_widget_show( vbox7 ); - gtk_container_add( GTK_CONTAINER( alignment4 ), vbox7 ); - - hbox8 = gtk_hbox_new( FALSE, 0 ); - gtk_widget_set_name( hbox8, "hbox8" ); - gtk_widget_show( hbox8 ); - gtk_box_pack_start( GTK_BOX( vbox7 ), hbox8, FALSE, FALSE, 0 ); - - vbox9 = gtk_vbox_new( FALSE, 0 ); - gtk_widget_set_name( vbox9, "vbox9" ); - gtk_widget_show( vbox9 ); - gtk_box_pack_start( GTK_BOX( hbox8 ), vbox9, TRUE, TRUE, 0 ); - - main_use_default_font_radio = gtk_radio_button_new_with_label_from_widget( NULL, "Use theme default font" ); - gtk_widget_set_name( main_use_default_font_radio, "main_use_default_font_radio" ); - gtk_widget_show( main_use_default_font_radio ); - gtk_box_pack_start( GTK_BOX( vbox9 ), main_use_default_font_radio, FALSE, FALSE, 0 ); - - main_use_custom_font_radio = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON( main_use_default_font_radio ), "Use custom font:" ); - gtk_widget_set_name( main_use_custom_font_radio, "main_use_custom_font_radio" ); - gtk_widget_show( main_use_custom_font_radio ); - gtk_box_pack_start( GTK_BOX( vbox9 ), main_use_custom_font_radio, FALSE, FALSE, 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( main_use_custom_font_radio ), TRUE ); - //gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( main_use_custom_font_radio ), FALSE ); - - alignment5 = gtk_alignment_new( 0.5, 0.5, 1, 1 ); - gtk_widget_set_name( alignment5, "alignment5" ); - gtk_widget_show( alignment5 ); - gtk_box_pack_start( GTK_BOX( vbox9 ), alignment5, TRUE, TRUE, 0 ); - gtk_alignment_set_padding( GTK_ALIGNMENT( alignment5 ), 0, 0, 12, 0 ); - - vbox10 = gtk_vbox_new( FALSE, 0 ); - gtk_widget_set_name( vbox10, "vbox10" ); - gtk_widget_show( vbox10 ); - gtk_container_add( GTK_CONTAINER( alignment5 ), vbox10 ); - - hbox9 = gtk_hbox_new( FALSE, 0 ); - gtk_widget_set_name( hbox9, "hbox9" ); - gtk_widget_show( hbox9 ); - gtk_box_pack_start( GTK_BOX( vbox10 ), hbox9, FALSE, FALSE, 0 ); - - vbox11 = gtk_vbox_new( FALSE, 0 ); - gtk_widget_set_name( vbox11, "vbox11" ); - gtk_widget_show( vbox11 ); - gtk_box_pack_start( GTK_BOX( hbox9 ), vbox11, TRUE, TRUE, 0 ); - - main_font_selector_button = gtk_font_button_new(); - gtk_widget_set_name( main_font_selector_button, "main_font_selector_button" ); - gtk_widget_show( main_font_selector_button ); - gtk_box_pack_start( GTK_BOX( vbox11 ), main_font_selector_button, FALSE, FALSE, 0 ); - - label669 = gtk_label_new( "Font" ); - gtk_widget_set_name( label669, "label669" ); - gtk_widget_show( label669 ); - gtk_frame_set_label_widget( GTK_FRAME( frame3 ), label669 ); - gtk_label_set_use_markup( GTK_LABEL( label669 ), TRUE ); - - vbox13 = gtk_vbox_new( FALSE, 0 ); - gtk_widget_set_name( vbox13, "vbox13" ); - gtk_widget_show( vbox13 ); - gtk_box_pack_start( GTK_BOX( vbox1 ), vbox13, FALSE, FALSE, 0 ); - - hbuttonbox1 = gtk_hbutton_box_new(); - gtk_widget_set_name( hbuttonbox1, "hbuttonbox1" ); - gtk_widget_show( hbuttonbox1 ); - gtk_box_pack_start( GTK_BOX( vbox1 ), hbuttonbox1, FALSE, FALSE, 0 ); - - hbox7 = gtk_hbox_new( FALSE, 0 ); - gtk_widget_set_name( hbox7, "hbox7" ); - gtk_widget_show( hbox7 ); - gtk_box_pack_start( GTK_BOX( vbox1 ), hbox7, FALSE, TRUE, 6 ); - - vbox6 = gtk_vbox_new( FALSE, 0 ); - gtk_widget_set_name( vbox6, "vbox6" ); - gtk_widget_show( vbox6 ); - gtk_box_pack_start( GTK_BOX( vbox1 ), vbox6, FALSE, FALSE, 0 ); - - hbox5 = gtk_hbox_new( TRUE, 0 ); - gtk_widget_set_name( hbox5, "hbox5" ); - gtk_widget_show( hbox5 ); - gtk_box_pack_start( GTK_BOX( vbox6 ), hbox5, FALSE, FALSE, 0 ); - gtk_container_set_border_width( GTK_CONTAINER( hbox5 ), 4 ); - - main_ok_button = gtk_button_new_from_stock( "gtk-ok" ); - gtk_widget_set_name( main_ok_button, "main_ok_button" ); - gtk_widget_show( main_ok_button ); - gtk_box_pack_end( GTK_BOX( hbox5 ), main_ok_button, TRUE, TRUE, 4 ); - gtk_widget_set_can_default( main_ok_button, TRUE ); - - main_cancel_button = gtk_button_new_from_stock( "gtk-cancel" ); - gtk_widget_set_name( main_cancel_button, "main_cancel_button" ); - gtk_widget_show( main_cancel_button ); - gtk_box_pack_end( GTK_BOX( hbox5 ), main_cancel_button, TRUE, TRUE, 4 ); - gtk_widget_set_can_default( main_cancel_button, TRUE ); - - main_reset_button = gtk_button_new(); - gtk_widget_set_name( main_reset_button, "main_reset_button" ); - gtk_widget_show( main_reset_button ); - gtk_box_pack_end( GTK_BOX( hbox5 ), main_reset_button, TRUE, TRUE, 4 ); - - alignment2 = gtk_alignment_new( 0.5, 0.5, 0, 0 ); - gtk_widget_set_name( alignment2, "alignment2" ); - gtk_widget_show( alignment2 ); - gtk_container_add( GTK_CONTAINER( main_reset_button ), alignment2 ); - - hbox6 = gtk_hbox_new( FALSE, 2 ); - gtk_widget_set_name( hbox6, "hbox6" ); - gtk_widget_show( hbox6 ); - gtk_container_add( GTK_CONTAINER( alignment2 ), hbox6 ); - - image1 = gtk_image_new_from_stock( "gtk-revert-to-saved", GTK_ICON_SIZE_BUTTON ); - gtk_widget_set_name( image1, "image1" ); - gtk_widget_show( image1 ); - gtk_box_pack_start( GTK_BOX( hbox6 ), image1, FALSE, FALSE, 0 ); - - label667 = gtk_label_new_with_mnemonic( "_Reset" ); - gtk_widget_set_name( label667, "label667" ); - gtk_widget_show( label667 ); - gtk_box_pack_start( GTK_BOX( hbox6 ), label667, FALSE, FALSE, 0 ); - - - g_signal_connect( (gpointer)main_window, "delete_event", - G_CALLBACK( on_main_window_delete_event ), - NULL ); - g_signal_connect( (gpointer)main_use_default_font_radio, "toggled", - G_CALLBACK( on_main_use_default_font_radio_toggled ), - NULL ); - g_signal_connect( (gpointer)main_font_selector_button, "font_set", - G_CALLBACK( on_main_font_selector_button_font_set ), - NULL ); - g_signal_connect( (gpointer)main_cancel_button, "clicked", - G_CALLBACK( on_main_cancel_button_clicked ), - NULL ); - g_signal_connect( (gpointer)main_reset_button, "clicked", - G_CALLBACK( on_main_reset_button_clicked ), - NULL ); - g_signal_connect( (gpointer)main_ok_button, "clicked", - G_CALLBACK( on_main_ok_button_clicked ), - NULL ); - - /* Store pointers to all widgets, for use by lookup_widget(). */ - GLADE_HOOKUP_OBJECT_NO_REF( main_window, main_window, "main_window" ); - GLADE_HOOKUP_OBJECT( main_window, main_hbox, "main_hbox" ); - GLADE_HOOKUP_OBJECT( main_window, vbox1, "vbox1" ); - GLADE_HOOKUP_OBJECT( main_window, hbox1, "hbox1" ); - GLADE_HOOKUP_OBJECT( main_window, frame2, "frame2" ); - GLADE_HOOKUP_OBJECT( main_window, alignment3, "alignment3" ); - GLADE_HOOKUP_OBJECT( main_window, scrolledwindow3, "scrolledwindow3" ); - GLADE_HOOKUP_OBJECT( main_window, main_themelist, "main_themelist" ); - GLADE_HOOKUP_OBJECT( main_window, label1234, "label1234" ); - GLADE_HOOKUP_OBJECT( main_window, frame3, "frame3" ); - GLADE_HOOKUP_OBJECT( main_window, alignment4, "alignment4" ); - GLADE_HOOKUP_OBJECT( main_window, vbox7, "vbox7" ); - GLADE_HOOKUP_OBJECT( main_window, hbox8, "hbox8" ); - GLADE_HOOKUP_OBJECT( main_window, vbox9, "vbox9" ); - GLADE_HOOKUP_OBJECT( main_window, main_use_default_font_radio, "main_use_default_font_radio" ); - GLADE_HOOKUP_OBJECT( main_window, main_use_custom_font_radio, "main_use_custom_font_radio" ); - GLADE_HOOKUP_OBJECT( main_window, alignment5, "alignment5" ); - GLADE_HOOKUP_OBJECT( main_window, vbox10, "vbox10" ); - GLADE_HOOKUP_OBJECT( main_window, hbox9, "hbox9" ); - GLADE_HOOKUP_OBJECT( main_window, vbox11, "vbox11" ); - GLADE_HOOKUP_OBJECT( main_window, main_font_selector_button, "main_font_selector_button" ); - GLADE_HOOKUP_OBJECT( main_window, label669, "label669" ); - GLADE_HOOKUP_OBJECT( main_window, vbox13, "vbox13" ); - GLADE_HOOKUP_OBJECT( main_window, hbuttonbox1, "hbuttonbox1" ); - GLADE_HOOKUP_OBJECT( main_window, hbox7, "hbox7" ); - GLADE_HOOKUP_OBJECT( main_window, vbox6, "vbox6" ); - GLADE_HOOKUP_OBJECT( main_window, hbox5, "hbox5" ); - GLADE_HOOKUP_OBJECT( main_window, main_ok_button, "main_ok_button" ); - GLADE_HOOKUP_OBJECT( main_window, main_cancel_button, "main_cancel_button" ); - GLADE_HOOKUP_OBJECT( main_window, main_reset_button, "main_reset_button" ); - GLADE_HOOKUP_OBJECT( main_window, alignment2, "alignment2" ); - GLADE_HOOKUP_OBJECT( main_window, hbox6, "hbox6" ); - GLADE_HOOKUP_OBJECT( main_window, image1, "image1" ); - GLADE_HOOKUP_OBJECT( main_window, label667, "label667" ); - - gtk_widget_grab_default( main_themelist ); - gtk_window_add_accel_group( GTK_WINDOW( main_window ), accel_group ); - - return main_window; -} - - - -static std::string gchar_to_string( gchar* gstr ) { - std::string str = ( gstr ? gstr : "" ); - g_free( gstr ); - return str; -} - - -// ------------------------------------------------------ -static std::string s_orig_theme; -static std::string s_orig_font; - -std::string& get_orig_theme() { - return s_orig_theme; -} - -std::string& get_orig_font() { - return s_orig_font; -} - - -// ------------------------------------------------------ -std::string get_current_theme() { - GtkSettings* settings = gtk_settings_get_default(); - gchar* theme; - g_object_get( settings, "gtk-theme-name", &theme, NULL ); - - /* dummy check */ - if( !g_ascii_isalnum( theme[0] ) ) { - g_free( theme ); - return ""; - } - return gchar_to_string( theme ); -} - -std::string get_current_font() { - return gchar_to_string( pango_font_description_to_string( gtk_rc_get_style( g_main_rc_window )->font_desc ) ); -} - - -// ------------------------------------------------------ -std::string get_selected_theme() { - GtkTreeView* treeview = GTK_TREE_VIEW( lookup_widget( g_main_rc_window, "main_themelist" ) ); - GtkTreeModel* model = gtk_tree_view_get_model( treeview ); - GtkTreeSelection* selection = gtk_tree_view_get_selection( treeview ); - - GtkTreeIter iter; - gtk_tree_selection_get_selected( selection, 0, &iter ); - - gchar* theme_name; - gtk_tree_model_get( model, &iter, 0, &theme_name, -1 ); -// std::cout << theme_name << "\n"; - return gchar_to_string( theme_name ); -} - -std::string get_selected_font() { -// GtkWidget* fontentry = lookup_widget( g_main_rc_window, "main_fontentry" ); -// return gtk_entry_get_text( GTK_ENTRY( fontentry ) ); - - const bool default_font = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( lookup_widget( g_main_rc_window, "main_use_default_font_radio" ) ) ); - if( default_font ) - return ""; - - GtkWidget* fontbutton = lookup_widget( g_main_rc_window, "main_font_selector_button" ); - return gtk_font_button_get_font_name( GTK_FONT_BUTTON( fontbutton ) ); -} - - -// ------------------------------------------------------ -static void themelist_selection_changed_cb( GtkTreeSelection* selection, gpointer data ) { - if( gtk_tree_selection_get_selected( selection, 0, 0 ) ) - apply_theme( get_selected_theme(), get_current_font() ); -} - - -// ------------------------------------------------------ -static void populate_with_themes( GtkWidget* w ) { - std::string search_path = gchar_to_string( gtk_rc_get_theme_dir() ); - - if( search_path.size() && search_path[search_path.size() - 1] != G_DIR_SEPARATOR ) - search_path += G_DIR_SEPARATOR_S; - - GDir* gdir = g_dir_open( search_path.c_str(), 0, NULL ); - if( gdir == NULL ) - return; - - char* name; - GList* glist = 0; - - while( ( name = const_cast( g_dir_read_name( gdir ) ) ) != NULL ) { - std::string filename = name; - -// if ( g_ascii_strup( fname.c_str(), -1 ) == "Default" ) -// continue; - - std::string fullname = search_path + filename; - std::string rc = fullname; - rc += G_DIR_SEPARATOR_S; - rc += "gtk-2.0"; - rc += G_DIR_SEPARATOR_S; - rc += "gtkrc"; - - bool is_dir = 0; - if( g_file_test( fullname.c_str(), G_FILE_TEST_IS_DIR ) ) - is_dir = 1; - - if( is_dir && g_file_test( rc.c_str(), G_FILE_TEST_IS_REGULAR ) ) { - glist = g_list_insert_sorted( glist, g_strdup( filename.c_str() ), ( GCompareFunc )strcmp ); - } - } - - g_dir_close( gdir ); - - // ---------------- tree - GtkTreeView* treeview = GTK_TREE_VIEW( w ); - GtkListStore* store = gtk_list_store_new( 1, G_TYPE_STRING ); - gtk_tree_view_set_model( treeview, GTK_TREE_MODEL( store ) ); - - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( - "Theme", gtk_cell_renderer_text_new(), - "text", 0, - NULL ); - gtk_tree_view_column_set_sizing( column, GTK_TREE_VIEW_COLUMN_GROW_ONLY ); - gtk_tree_view_append_column( GTK_TREE_VIEW( treeview ), column ); - - GtkTreeIter iter; - int i = 0, curr = 0; - while( char* theme = (char*)g_list_nth_data( glist, i ) ) { - gtk_list_store_append( store, &iter ); - gtk_list_store_set( store, &iter, 0, theme, -1 ); - - if( strcmp( theme, get_current_theme().c_str() ) == 0 ) { - curr = i; - } - ++i; - } - - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( treeview ) ); - - // set the default theme - - // THIS IS IMPORTANT!!! - gtk_widget_grab_focus( w ); - - std::stringstream str; - str << curr; - GtkTreePath* selpath = gtk_tree_path_new_from_string( str.str().c_str() ); - if( selpath ) { - gtk_tree_selection_select_path( selection, selpath ); - gtk_tree_view_scroll_to_cell( treeview, selpath, NULL, true, 0.5, 0.0 ); - gtk_tree_path_free( selpath ); - } - - g_signal_connect( G_OBJECT( selection ), "changed", - G_CALLBACK( themelist_selection_changed_cb ), NULL ); - - g_object_unref( G_OBJECT( store ) ); - - // ---------------- font - GtkWidget* fontbutton = lookup_widget( g_main_rc_window, "main_font_selector_button" ); - gtk_font_button_set_font_name( GTK_FONT_BUTTON( fontbutton ), get_current_font().c_str() ); -} - - -// ------------------------------------------------------ -void gtkThemeDlg() { - if( g_main_rc_window ) - return; - - s_rc_file = std::string( AppPath_get() ) + G_DIR_SEPARATOR_S + ".gtkrc-2.0.radiant"; - - g_main_rc_window = create_rc_window(); - - populate_with_themes( lookup_widget( g_main_rc_window, "main_themelist" ) ); - - get_orig_theme() = get_current_theme(); - get_orig_font() = get_current_font(); - - gtk_widget_show( g_main_rc_window ); -} - - -// ------------------------------- -void set_theme( const std::string& theme_name, const std::string& font ) { - if( theme_name.empty() ) - return; - - // tree - GtkTreeView* treeview = GTK_TREE_VIEW( lookup_widget( g_main_rc_window, "main_themelist" ) ); - GtkTreeModel* model = gtk_tree_view_get_model( treeview ); - GtkTreeSelection* selection = gtk_tree_view_get_selection( treeview ); - - GtkTreeIter iter; - gtk_tree_model_get_iter_first( model, &iter ); - - while( gtk_tree_model_iter_next( model, &iter ) ) { - gchar* text; - gtk_tree_model_get( model, &iter, 0, &text, -1 ); - std::string theme = gchar_to_string( text ); - - if( theme_name == theme ) { - gtk_tree_selection_select_iter( selection, &iter ); - break; - } - } - - // font - if( font != "" ) { - GtkWidget* fontbutton = lookup_widget( g_main_rc_window, "main_font_selector_button" ); - //gtk_font_button_set_font_name( GTK_FONT_BUTTON( fontbutton ), get_current_font().c_str() ); - gtk_font_button_set_font_name( GTK_FONT_BUTTON( fontbutton ), font.c_str() ); - } - - apply_theme( get_selected_theme(), get_selected_font() ); -} - -void apply_theme( const std::string& theme_name, const std::string& font ) { - std::stringstream strstr; - strstr << "gtk-theme-name = \"" << theme_name << "\"\n"; - - if( font != "" ) - strstr << "style \"user-font\"\n{\nfont_name=\"" << font << "\"\n}\nwidget_class \"*\" style \"user-font\""; - - //strstr << "\ngtk-menu-popup-delay = 10"; - -// std::cout << strstr.str() << "\n\n\n"; - std::fstream f; - f.open( s_rc_file.c_str(), std::ios::out ); - f << strstr.str(); - f.close(); - - GtkSettings* settings = gtk_settings_get_default(); - - gtk_rc_reparse_all_for_settings( settings, true ); -// gtk_rc_parse_string( strstr.str().c_str() ); -// gtk_rc_parse( "/root/.gtk-tmp" ); -// gtk_rc_reset_styles( settings ); - - //unlink(s_rc_file.c_str()); - - while( gtk_events_pending() ) - gtk_main_iteration(); -} diff --git a/radiant/gtktheme.h b/radiant/gtktheme.h deleted file mode 100644 index 1da9a4e2..00000000 --- a/radiant/gtktheme.h +++ /dev/null @@ -1,11 +0,0 @@ -/*************************************************************************** - main.cpp - description - ------------------- - begin : Wed Jan 1 2003 - copyright : (C) 2003 - 2005 by Alex Shaduri - email : ashaduri '@' gmail.com - ***************************************************************************/ - -#pragma once - -void gtkThemeDlg(); diff --git a/radiant/help.cpp b/radiant/help.cpp index cf011121..6d404e41 100644 --- a/radiant/help.cpp +++ b/radiant/help.cpp @@ -51,16 +51,16 @@ void HandleHelpCommand( CopiedString& str ){ OpenURL( str.c_str() ); } -void process_xlink( const char* filename, const char *menu_name, const char *base_url, GtkMenu *menu ){ +void process_xlink( const char* filename, const char *menu_name, const char *base_url, QMenu *menu ){ if ( file_exists( filename ) ) { xmlDocPtr pDoc = xmlParseFile( filename ); if ( pDoc ) { globalOutputStream() << "Processing .xlink file '" << filename << "'\n"; // create sub menu - GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic( menu, menu_name ); - if ( g_Layout_enableDetachableMenus.m_value ) { - menu_tearoff( menu_in_menu ); - } + menu = menu->addMenu( menu_name ); + + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + // start walking the nodes, find the 'links' one xmlNodePtr pNode = pDoc->children; while ( pNode && strcmp( (const char*)pNode->name, "links" ) ) @@ -93,7 +93,7 @@ void process_xlink( const char* filename, const char *menu_name, const char *bas prop = xmlGetProp( pNode, reinterpret_cast( "name" ) ); ASSERT_NOTNULL( prop ); - create_menu_item_with_mnemonic( menu_in_menu, reinterpret_cast( prop ), ReferenceCaller( mHelpURLs.back() ) ); + create_menu_item_with_mnemonic( menu, reinterpret_cast( prop ), ReferenceCaller( mHelpURLs.back() ) ); xmlFree( prop ); } pNode = pNode->next; @@ -112,14 +112,12 @@ void process_xlink( const char* filename, const char *menu_name, const char *bas } } -void create_game_help_menu( GtkMenu *menu ){ - StringOutputStream filename( 256 ); - filename << AppPath_get() << "global.xlink"; +void create_game_help_menu( QMenu *menu ){ + auto filename = StringOutputStream( 256 )( AppPath_get(), "global.xlink" ); process_xlink( filename.c_str(), "General", AppPath_get(), menu ); #if 1 - filename.clear(); - filename << g_pGameDescription->mGameToolsPath << "game.xlink"; + filename( g_pGameDescription->mGameToolsPath, "game.xlink" ); process_xlink( filename.c_str(), g_pGameDescription->getRequiredKeyValue( "name" ), g_pGameDescription->mGameToolsPath.c_str(), menu ); #else for ( std::list::iterator iGame = g_GamesDialog.mGames.begin(); iGame != g_GamesDialog.mGames.end(); ++iGame ) diff --git a/radiant/help.h b/radiant/help.h index 735f2ff3..c3fcb6c3 100644 --- a/radiant/help.h +++ b/radiant/help.h @@ -21,5 +21,4 @@ #pragma once -typedef struct _GtkMenu GtkMenu; -void create_game_help_menu( GtkMenu *menu ); +void create_game_help_menu( class QMenu *menu ); diff --git a/radiant/main.cpp b/radiant/main.cpp index 73209e32..d8b06f5a 100644 --- a/radiant/main.cpp +++ b/radiant/main.cpp @@ -69,13 +69,12 @@ #include "iundo.h" -#include - #include "commandlib.h" #include "os/file.h" #include "os/path.h" #include "stream/stringstream.h" #include "stream/textfilestream.h" +#include "character.h" #include "gtkutil/messagebox.h" #include "gtkutil/image.h" @@ -90,128 +89,12 @@ #include "stacktrace.h" #include "error.h" +#include +#include "gtkutil/glwidget.h" + void show_splash(); void hide_splash(); -void error_redirect( const gchar *domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data ){ - gboolean in_recursion; - gboolean is_fatal; - char buf[256]; - - in_recursion = ( log_level & G_LOG_FLAG_RECURSION ) != 0; - is_fatal = ( log_level & G_LOG_FLAG_FATAL ) != 0; - log_level = (GLogLevelFlags) ( log_level & G_LOG_LEVEL_MASK ); - - if ( !message ) { - message = "(0) message"; - } - - if ( domain ) { - strcpy( buf, domain ); - } - else{ - strcpy( buf, "**" ); - } - strcat( buf, "-" ); - - switch ( log_level ) - { - case G_LOG_LEVEL_ERROR: - if ( in_recursion ) { - strcat( buf, "ERROR (recursed) **: " ); - } - else{ - strcat( buf, "ERROR **: " ); - } - break; - case G_LOG_LEVEL_CRITICAL: - if ( in_recursion ) { - strcat( buf, "CRITICAL (recursed) **: " ); - } - else{ - strcat( buf, "CRITICAL **: " ); - } - break; - case G_LOG_LEVEL_WARNING: - if ( in_recursion ) { - strcat( buf, "WARNING (recursed) **: " ); - } - else{ - strcat( buf, "WARNING **: " ); - } - break; - case G_LOG_LEVEL_MESSAGE: - if ( in_recursion ) { - strcat( buf, "Message (recursed): " ); - } - else{ - strcat( buf, "Message: " ); - } - break; - case G_LOG_LEVEL_INFO: - if ( in_recursion ) { - strcat( buf, "INFO (recursed): " ); - } - else{ - strcat( buf, "INFO: " ); - } - break; - case G_LOG_LEVEL_DEBUG: - if ( in_recursion ) { - strcat( buf, "DEBUG (recursed): " ); - } - else{ - strcat( buf, "DEBUG: " ); - } - break; - default: - /* we are used for a log level that is not defined by GLib itself, - * try to make the best out of it. - */ - if ( in_recursion ) { - strcat( buf, "LOG (recursed:" ); - } - else{ - strcat( buf, "LOG (" ); - } - if ( log_level ) { - gchar string[] = "0x00): "; - gchar *p = string + 2; - guint i; - - i = g_bit_nth_msf( log_level, -1 ); - *p = i >> 4; - p++; - *p = '0' + ( i & 0xf ); - if ( *p > '9' ) { - *p += 'A' - '9' - 1; - } - - strcat( buf, string ); - } - else{ - strcat( buf, "): " ); - } - } - - strcat( buf, message ); - if ( is_fatal ) { - strcat( buf, "\naborting...\n" ); - } - else{ - strcat( buf, "\n" ); - } - - // spam it... - globalErrorStream() << buf << "\n"; - - // FIXME why are warnings is_fatal? -#ifndef _DEBUG - if ( is_fatal ) -#endif - ERROR_MESSAGE( "GTK+ error: " << buf ); -} - #if defined ( _DEBUG ) && defined ( WIN32 ) && defined ( _MSC_VER ) #include "crtdbg.h" #endif @@ -222,6 +105,28 @@ void crt_init(){ #endif } +void qute_messageHandler( QtMsgType type, const QMessageLogContext &context, const QString &msg ) +{ + static StringOutputStream buf( 256 ); + buf.clear(); + switch (type) + { + case QtInfoMsg: buf << "QT INF "; break; + case QtDebugMsg: buf << "QT DBG "; break; + case QtWarningMsg: buf << "QT WRN "; break; + case QtCriticalMsg: buf << "QT CRT "; break; + case QtFatalMsg: buf << "QT FTL "; break; + } + buf << context.category << ": " << msg.toLatin1().constData() << '\n'; + switch (type) + { + case QtInfoMsg: + case QtDebugMsg: globalOutputStream() << buf; break; + case QtWarningMsg: globalWarningStream() << buf; break; + case QtCriticalMsg: + case QtFatalMsg: globalErrorStream() << buf; break; + } +} class Lock { bool m_locked; @@ -302,12 +207,12 @@ public: ScopedLock lock( m_lock ); #if defined _DEBUG m_buffer << "Break into the debugger?\n"; - bool handled = gtk_MessageBox( 0, m_buffer.c_str(), "Radiant - Runtime Error", eMB_YESNO, eMB_ICONERROR ) == eIDNO; + bool handled = qt_MessageBox( 0, m_buffer.c_str(), "Radiant - Runtime Error", EMessageBoxType::Error, eIDYES | eIDNO ) == eIDNO; m_buffer.clear(); return handled; #else m_buffer << "Please report this error to the developers\n"; - gtk_MessageBox( 0, m_buffer.c_str(), "Radiant - Runtime Error", eMB_OK, eMB_ICONERROR ); + qt_MessageBox( 0, m_buffer.c_str(), "Radiant - Runtime Error", EMessageBoxType::Error ); m_buffer.clear(); #endif } @@ -326,7 +231,7 @@ void streams_init(){ void paths_init(){ const char* home = environment_get_home_path(); - if( !g_str_is_ascii( home ) ) + if( !string_is_ascii( home ) ) Error( "Home path is not ASCII: %s", home ); Q_mkdir( home ); @@ -341,7 +246,7 @@ void paths_init(){ g_strAppPath = environment_get_app_path(); - if( !g_str_is_ascii( g_strAppPath.c_str() ) ) + if( !string_is_ascii( g_strAppPath.c_str() ) ) Error( "Radiant path is not ASCII: %s", g_strAppPath.c_str() ); // radiant is installed in the parent dir of "tools/" @@ -403,7 +308,7 @@ bool check_version(){ msg << "This editor binary (" RADIANT_VERSION ") doesn't match what the latest setup has configured in this directory\n" "Make sure you run the right/latest editor binary you installed\n" << AppPath_get(); - gtk_MessageBox( 0, msg.c_str(), "Radiant", eMB_OK, eMB_ICONDEFAULT ); + qt_MessageBox( 0, msg.c_str(), "Radiant" ); } return bVerIsGood; #else @@ -431,7 +336,7 @@ void create_global_pid(){ if ( remove( g_pidFile.c_str() ) == -1 ) { StringOutputStream msg( 256 ); msg << "WARNING: Could not delete " << g_pidFile.c_str(); - gtk_MessageBox( 0, msg.c_str(), "Radiant", eMB_OK, eMB_ICONERROR ); + qt_MessageBox( 0, msg.c_str(), "Radiant", EMessageBoxType::Error ); } // in debug, never prompt to clean registry, turn console logging auto after a failed start @@ -441,14 +346,14 @@ void create_global_pid(){ "The failure may be related to current global preferences.\n" "Do you want to reset global preferences to defaults?"; - if ( gtk_MessageBox( 0, msg.c_str(), "Radiant - Startup Failure", eMB_YESNO, eMB_ICONQUESTION ) == eIDYES ) { + if ( qt_MessageBox( 0, msg.c_str(), "Radiant - Startup Failure", EMessageBoxType::Question ) == eIDYES ) { g_GamesDialog.Reset(); } msg.clear(); msg << "Logging console output to " << SettingsPath_get() << "radiant.log\nRefer to the log if Radiant fails to start again."; - gtk_MessageBox( 0, msg.c_str(), "Radiant - Console Log", eMB_OK ); + qt_MessageBox( 0, msg.c_str(), "Radiant - Console Log" ); #endif // set without saving, the class is not in a coherent state yet @@ -472,7 +377,7 @@ void remove_global_pid(){ if ( remove( g_pidFile.c_str() ) == -1 ) { StringOutputStream msg( 256 ); msg << "WARNING: Could not delete " << g_pidFile.c_str(); - gtk_MessageBox( 0, msg.c_str(), "Radiant", eMB_OK, eMB_ICONERROR ); + qt_MessageBox( 0, msg.c_str(), "Radiant", EMessageBoxType::Error ); } } @@ -490,7 +395,7 @@ void create_local_pid(){ if ( remove( g_pidGameFile.c_str() ) == -1 ) { StringOutputStream msg; msg << "WARNING: Could not delete " << g_pidGameFile.c_str(); - gtk_MessageBox( 0, msg.c_str(), "Radiant", eMB_OK, eMB_ICONERROR ); + qt_MessageBox( 0, msg.c_str(), "Radiant", EMessageBoxType::Error ); } // in debug, never prompt to clean registry, turn console logging auto after a failed start @@ -500,14 +405,14 @@ void create_local_pid(){ "The failure may be caused by current preferences.\n" "Do you want to reset all preferences to defaults?"; - if ( gtk_MessageBox( 0, msg.c_str(), "Radiant - Startup Failure", eMB_YESNO, eMB_ICONQUESTION ) == eIDYES ) { + if ( qt_MessageBox( 0, msg.c_str(), "Radiant - Startup Failure", EMessageBoxType::Question ) == eIDYES ) { Preferences_Reset(); } msg.clear(); msg << "Logging console output to " << SettingsPath_get() << "radiant.log\nRefer to the log if Radiant fails to start again."; - gtk_MessageBox( 0, msg.c_str(), "Radiant - Console Log", eMB_OK ); + qt_MessageBox( 0, msg.c_str(), "Radiant - Console Log" ); #endif // force console logging on! (will go in prefs too) @@ -535,44 +440,6 @@ void remove_local_pid(){ remove( g_pidGameFile.c_str() ); } -void add_local_rc_files(){ - { - StringOutputStream path( 512 ); - path << AppPath_get() << ".gtkrc-2.0.radiant"; - gtk_rc_add_default_file( path.c_str() ); - } -#ifdef WIN32 - { - StringOutputStream path( 512 ); - path << AppPath_get() << ".gtkrc-2.0.win"; - gtk_rc_add_default_file( path.c_str() ); - } -#endif -} - -#ifdef WIN32 -/* as in windows packages we are using local font file for entity names to avoid long parsing of all system fonts by fontconfig, - let's also write local.conf with absolute path to local fonts/ dir, as fonts.conf has no opportunity to get it, when pwd != radiant/ - ( when starting radiant by opening .map, associated to one, for example ) */ -void fontconfig_workaround(){ - StringOutputStream path( 1024 ); - path << AppPath_get() << "etc/fonts/local.conf"; - - TextFileOutputStream file( path.c_str() ); - if ( !file.failed() ) { - file << "\n\ -\n\ -\n\ - \n\ - \n\ - \n\ -\n\ - Load font from local dir\n\ - " << AppPath_get() << "etc/fonts\n\ -\n"; - } -} -#endif int main( int argc, char* argv[] ){ crt_init(); @@ -583,21 +450,21 @@ int main( int argc, char* argv[] ){ _setmaxstdio(2048); #endif - gtk_disable_setlocale(); - - gtk_init( &argc, &argv ); - - // redirect Gtk warnings to the console - g_log_set_handler( "Gdk", (GLogLevelFlags)( G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION ), error_redirect, 0 ); - g_log_set_handler( "Gtk", (GLogLevelFlags)( G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION ), error_redirect, 0 ); - g_log_set_handler( "GtkGLExt", (GLogLevelFlags)( G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION ), error_redirect, 0 ); - g_log_set_handler( "GLib", (GLogLevelFlags)( G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION ), error_redirect, 0 ); - g_log_set_handler( 0, (GLogLevelFlags)( G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION ), error_redirect, 0 ); + glwidget_setDefaultFormat(); // must go before QApplication instantiation +#ifdef WIN32 + std::vector args( argv, argv + argc ); + args.push_back( string_clone( "-platform" ) ); + args.push_back( string_clone( "windows:darkmode=1" ) ); + args.push_back( nullptr ); + argc += 2; + argv = args.data(); +#endif + QApplication qapplication( argc, argv ); + setlocale( LC_NUMERIC, "C" ); + qInstallMessageHandler( qute_messageHandler ); + QCoreApplication::setOrganizationName( "QtRadiant" ); + QCoreApplication::setApplicationName( "NetRadiant-Custom" ); + QCoreApplication::setApplicationVersion( QT_VERSION_STR ); GlobalDebugMessageHandler::instance().setHandler( GlobalPopupDebugMessageHandler::instance() ); @@ -605,12 +472,6 @@ int main( int argc, char* argv[] ){ paths_init(); - add_local_rc_files(); - -#ifdef WIN32 - fontconfig_workaround(); -#endif - if ( !check_version() ) { return EXIT_FAILURE; } @@ -643,8 +504,6 @@ int main( int argc, char* argv[] ){ Radiant_Initialise(); - global_accel_init(); - // user_shortcuts_init(); g_pParentWnd = 0; @@ -662,15 +521,14 @@ int main( int argc, char* argv[] ){ { Map_New(); } - // load up shaders now that we have the map loaded // eviltypeguy - TextureBrowser_ShowStartupShaders( GlobalTextureBrowser() ); + TextureBrowser_ShowStartupShaders(); remove_local_pid(); - gtk_main(); + qapplication.exec(); Map_Free(); @@ -682,8 +540,6 @@ int main( int argc, char* argv[] ){ // user_shortcuts_save(); - global_accel_destroy(); - Radiant_Shutdown(); // close the log file if any diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index f974e9e4..e52511a2 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -42,8 +42,22 @@ #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "commandlib.h" #include "scenelib.h" @@ -54,16 +68,13 @@ #include "eclasslib.h" #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/toolbar.h" #include "gtkutil/widget.h" +#include "gtkutil/guisettings.h" #include "autosave.h" #include "build.h" @@ -85,7 +96,6 @@ #include "help.h" #include "map.h" #include "mru.h" -#include "multimon.h" #include "patchdialog.h" #include "patchmanip.h" #include "plugin.h" @@ -109,33 +119,10 @@ #include "feedback.h" #include "referencecache.h" +#include "colors.h" +#include "theme.h" +#include "tools.h" #include "filterbar.h" -#include "gtktheme.h" - - -struct layout_globals_t -{ - WindowPosition m_position; - - - int nXYHeight; - int nXYWidth; - int nCamWidth; - int nCamHeight; - int nState; - - layout_globals_t() : - m_position( -1, -1, 962, 480 ), - - nXYHeight( 377 ), - nXYWidth( 480 ), - nCamWidth( 480 ), - nCamHeight( 250 ), - nState( 0 ){ - } -}; - -layout_globals_t g_layout_globals; // VFS @@ -435,44 +422,53 @@ void Paths_registerPreferencesPage(){ class PathsDialog : public Dialog { public: - GtkWindow* BuildDialog(){ - GtkFrame* frame = create_dialog_frame( "Path settings", GTK_SHADOW_ETCHED_IN ); + void BuildDialog() override { + GetWidget()->setWindowTitle( "Engine Path Configuration" ); - GtkVBox* vbox2 = create_dialog_vbox( 0, 4 ); - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( vbox2 ) ); + auto vbox = new QVBoxLayout( GetWidget() ); + { + auto frame = new QGroupBox( "Path settings" ); + vbox->addWidget( frame ); - const char* engine; + auto grid = new QGridLayout( frame ); + grid->setAlignment( Qt::AlignmentFlag::AlignTop ); + grid->setColumnStretch( 0, 111 ); + grid->setColumnStretch( 1, 333 ); + { + const char* engine; #if defined( WIN32 ) - engine = g_pGameDescription->getRequiredKeyValue( "engine_win32" ); + engine = g_pGameDescription->getRequiredKeyValue( "engine_win32" ); #elif defined( __linux__ ) || defined ( __FreeBSD__ ) - engine = g_pGameDescription->getRequiredKeyValue( "engine_linux" ); + engine = g_pGameDescription->getRequiredKeyValue( "engine_linux" ); #elif defined( __APPLE__ ) - engine = g_pGameDescription->getRequiredKeyValue( "engine_macos" ); + engine = g_pGameDescription->getRequiredKeyValue( "engine_macos" ); #else #error "unsupported platform" #endif - StringOutputStream text( 256 ); - text << "Select directory, where game executable sits (typically \"" << engine << "\")\n"; - GtkLabel* label = GTK_LABEL( gtk_label_new( text.c_str() ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_container_add( GTK_CONTAINER( vbox2 ), GTK_WIDGET( label ) ); - - { - PreferencesPage preferencesPage( *this, GTK_WIDGET( vbox2 ) ); - Paths_constructPreferences( preferencesPage ); + StringOutputStream text( 256 ); + text << "Select directory, where game executable sits (typically \"" << engine << "\")\n"; + grid->addWidget( new QLabel( text.c_str() ), 0, 0, 1, 2 ); + } + { + PreferencesPage preferencesPage( *this, grid ); + Paths_constructPreferences( preferencesPage ); + } + } + { + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok ); + vbox->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, GetWidget(), &QDialog::accept ); } - - return create_simple_modal_dialog_window( "Engine Path Configuration", m_modal, GTK_WIDGET( frame ) ); } }; PathsDialog g_PathsDialog; -bool g_strEnginePath_was_empty_1st_start = false; +static bool g_strEnginePath_was_empty_1st_start = false; void EnginePath_verify(){ if ( !file_exists( g_strEnginePath.c_str() ) || g_strEnginePath_was_empty_1st_start ) { - g_PathsDialog.Create(); + g_PathsDialog.Create( nullptr ); g_PathsDialog.DoModal(); g_PathsDialog.Destroy(); } @@ -579,14 +575,6 @@ void Radiant_loadModulesFromRoot( const char* directory ){ } } -//! Make COLOR_BRUSHES override worldspawn eclass colour. -void SetWorldspawnColour( const Vector3& colour ){ - EntityClass* worldspawn = GlobalEntityClassManager().findOrInsert( "worldspawn", true ); - eclass_release_state( worldspawn ); - worldspawn->color = colour; - eclass_capture_state( worldspawn ); -} - class WorldspawnColourEntityClassObserver : public ModuleObserver { @@ -651,7 +639,7 @@ void Radiant_Shutdown(){ void Exit(){ if ( ConfirmModified( "Exit Radiant" ) ) { - gtk_main_quit(); + QCoreApplication::quit(); } } @@ -667,392 +655,27 @@ void Exit(){ extern char **environ; #endif void Radiant_Restart(){ - ConfirmModified( "Restart Radiant" ); // user can choose to not save, it's ok + if( ConfirmModified( "Restart Radiant" ) ){ + StringOutputStream mapname; + mapname << "\"" << Map_Name( g_map ) << "\""; - StringOutputStream mapname; - mapname << "\"" << Map_Name( g_map ) << "\""; - - char *argv[] = { string_clone( environment_get_app_filepath() ), - Map_Unnamed( g_map )? NULL : string_clone( mapname.c_str() ), - NULL }; + char *argv[] = { string_clone( environment_get_app_filepath() ), + Map_Unnamed( g_map )? NULL : string_clone( mapname.c_str() ), + NULL }; #ifdef WIN32 - const int status = !_spawnv( P_NOWAIT, argv[0], argv ); + const int status = !_spawnv( P_NOWAIT, argv[0], argv ); #else - const int status = posix_spawn( NULL, argv[0], NULL, NULL, argv, environ ); + const int status = posix_spawn( NULL, argv[0], NULL, NULL, argv, environ ); #endif - // quit if radiant successfully started - if ( status == 0 ) { - gtk_main_quit(); + // quit if radiant successfully started + if ( status == 0 ) { + QCoreApplication::quit(); + } } } -void Undo(){ - GlobalUndoSystem().undo(); - SceneChangeNotify(); -} - -void Redo(){ - GlobalUndoSystem().redo(); - SceneChangeNotify(); -} - -void deleteSelection(){ - if( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent && GlobalSelectionSystem().countSelectedComponents() != 0 ){ - UndoableCommand undo( "deleteSelectedComponents" ); - CSG_DeleteComponents(); - } - else{ - UndoableCommand undo( "deleteSelected" ); - Select_Delete(); - } -} - -void Map_ExportSelected( TextOutputStream& ostream ){ - Map_ExportSelected( ostream, Map_getFormat( g_map ) ); -} - -void Map_ImportSelected( TextInputStream& istream ){ - Map_ImportSelected( istream, Map_getFormat( g_map ) ); -} - -void Selection_Copy(){ - clipboard_copy( Map_ExportSelected ); -} - -void Selection_Paste(){ - clipboard_paste( Map_ImportSelected ); -} - -void Copy(){ - if ( SelectedFaces_empty() ) { - Selection_Copy(); - } - else - { - SelectedFaces_copyTexture(); - } -} - -void Paste(){ - if ( SelectedFaces_empty() ) { - UndoableCommand undo( "paste" ); - - GlobalSelectionSystem().setSelectedAll( false ); - Selection_Paste(); - } - else - { - SelectedFaces_pasteTexture(); - } -} - -void TranslateToCamera(){ - CamWnd& camwnd = *g_pParentWnd->GetCamWnd(); - GlobalSelectionSystem().translateSelected( vector3_snapped( Camera_getOrigin( camwnd ) - GlobalSelectionSystem().getBoundsSelected().origin, GetSnapGridSize() ) ); -} - -void PasteToCamera(){ - GlobalSelectionSystem().setSelectedAll( false ); - UndoableCommand undo( "pasteToCamera" ); - Selection_Paste(); - TranslateToCamera(); -} - -void MoveToCamera(){ - UndoableCommand undo( "moveToCamera" ); - TranslateToCamera(); -} - - -void ColorScheme_Original(){ - 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_reconstructStatic(); - 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_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 ); - XYWnd::recaptureStates(); - g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); - Brush_clipperColourChanged(); - 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 ) ); - - 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_reconstructStatic(); - 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 ); - XYWnd::recaptureStates(); - g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); - Brush_clipperColourChanged(); - 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 ) ); - - 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_reconstructStatic(); - 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 ); - XYWnd::recaptureStates(); - g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); - Brush_clipperColourChanged(); - 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_reconstructStatic(); - 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 ); - XYWnd::recaptureStates(); - g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); - Brush_clipperColourChanged(); - 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_Blender(){ - 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.627451f, 0.0f ); - CamWnd_reconstructStatic(); - CamWnd_Update( *g_pParentWnd->GetCamWnd() ); - - g_xywindow_globals.color_gridback = Vector3( .225803f, .225803f, .225803f ); - g_xywindow_globals.color_gridminor = Vector3( .254902f, .254902f, .254902f ); - g_xywindow_globals.color_gridmajor = Vector3( .294118f, .294118f, .294118f ); - g_xywindow_globals.color_gridblock = Vector3( 1.0f, 1.0f, 1.0f ); - g_xywindow_globals.color_gridtext = Vector3( .972549f, .972549f, .972549f ); - g_xywindow_globals.color_selbrushes = Vector3( 1.0f, 0.627451f, 0.0f ); - XYWnd::recaptureStates(); - g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); - Brush_clipperColourChanged(); - 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.516136f, 0.516136f, 0.516136f ); - XY_UpdateAllWindows(); -} - -/* color scheme to fit the GTK Adwaita Dark theme */ -void ColorScheme_AdwaitaDark() -{ - 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_reconstructStatic(); - CamWnd_Update( *g_pParentWnd->GetCamWnd() ); - - g_xywindow_globals.color_gridback = Vector3( 0.25f, 0.25f, 0.25f ); - g_xywindow_globals.color_gridminor = Vector3( 0.21f, 0.23f, 0.23f ); - g_xywindow_globals.color_gridmajor = Vector3( 0.14f, 0.15f, 0.15f ); - 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 ); - XYWnd::recaptureStates(); - g_xywindow_globals.color_clipper = Vector3( 0.0f, 0.0f, 1.0f ); - Brush_clipperColourChanged(); - g_xywindow_globals.color_brushes = Vector3( 0.73f, 0.73f, 0.73f ); - SetWorldspawnColour( g_xywindow_globals.color_brushes ); - g_xywindow_globals.color_viewname = Vector3( 0.5f, 0.0f, 0.75f ); - XY_UpdateAllWindows(); -} - -typedef Callback1 GetColourCallback; -typedef Callback1 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 ); - } -}; - - - -void Colour_get( const Vector3& colour, Vector3& other ){ - other = colour; -} -typedef ConstReferenceCaller1 ColourGetCaller; - -void Colour_set( Vector3& colour, const Vector3& other ){ - colour = other; - SceneChangeNotify(); -} -typedef ReferenceCaller1 ColourSetCaller; - -void BrushColour_set( const Vector3& other ){ - g_xywindow_globals.color_brushes = other; - SetWorldspawnColour( g_xywindow_globals.color_brushes ); - SceneChangeNotify(); -} -typedef FreeCaller1 BrushColourSetCaller; - -void SelectedBrushColour_set( const Vector3& other ){ - g_xywindow_globals.color_selbrushes = other; - XYWnd::recaptureStates(); - SceneChangeNotify(); -} -typedef FreeCaller1 SelectedBrushColourSetCaller; - -void SelectedBrush3dColour_set( const Vector3& other ){ - g_camwindow_globals.color_selbrushes3d = other; - CamWnd_reconstructStatic(); - SceneChangeNotify(); -} -typedef FreeCaller1 SelectedBrush3dColourSetCaller; - -void ClipperColour_set( const Vector3& other ){ - g_xywindow_globals.color_clipper = other; - Brush_clipperColourChanged(); - SceneChangeNotify(); -} -typedef FreeCaller1 ClipperColourSetCaller; - -void TextureBrowserColour_get( Vector3& other ){ - other = TextureBrowser_getBackgroundColour( GlobalTextureBrowser() ); -} -typedef FreeCaller1 TextureBrowserColourGetCaller; - -void TextureBrowserColour_set( const Vector3& other ){ - TextureBrowser_setBackgroundColour( GlobalTextureBrowser(), other ); -} -typedef FreeCaller1 TextureBrowserColourSetCaller; - - -class ColoursMenu -{ -public: - ChooseColour m_textureback; - ChooseColour m_xyback; - ChooseColour m_gridmajor; - ChooseColour m_gridminor; - 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_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 ), SelectedBrushColourSetCaller() ), - m_selectedbrush3d( ColourGetCaller( g_camwindow_globals.color_selbrushes3d ), SelectedBrush3dColourSetCaller() ), - 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(){ - 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 ); - } - - GtkMenu* 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, "Blender/Dark", "ColorSchemeBlender" ); - create_menu_item_with_mnemonic( menu_3, "Adwaita Dark", "ColorSchemeAdwaitaDark" ); - - create_menu_item_with_mnemonic( menu_in_menu, "GTK Theme...", "gtkThemeDlg" ); - create_menu_item_with_mnemonic( menu_in_menu, "OpenGL Font...", "OpenGLFont" ); - - menu_separator( menu_in_menu ); - - create_menu_item_with_mnemonic( menu_in_menu, "_Texture Background...", "ChooseTextureBackgroundColor" ); - create_menu_item_with_mnemonic( menu_in_menu, "Camera Background...", "ChooseCameraBackgroundColor" ); - 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 Text...", "ChooseGridTextColor" ); - create_menu_item_with_mnemonic( menu_in_menu, "Grid Block...", "ChooseGridBlockColor" ); - create_menu_item_with_mnemonic( menu_in_menu, "Default Brush (2D)...", "ChooseBrushColor" ); - create_menu_item_with_mnemonic( menu_in_menu, "Selected Brush and Sizing (2D)...", "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 and Outline...", "ChooseOrthoViewNameColor" ); - - return colours_menu_item; -} - - void Restart(){ PluginsMenu_clear(); PluginToolbar_clear(); @@ -1067,6 +690,8 @@ void Restart(){ void OpenUpdateURL(){ + OpenURL( "https://github.com/Garux/netradiant-custom/releases/latest" ); +#if 0 // build the URL StringOutputStream URL( 256 ); URL << "http://www.icculus.org/netradiant/?cmd=update&data=dlupdate&query_dlup=1"; @@ -1080,6 +705,7 @@ void OpenUpdateURL(){ URL << "&Version_dlup=" RADIANT_VERSION; g_GamesDialog.AddPacksURL( URL ); OpenURL( URL.c_str() ); +#endif } // open the Q3Rad manual @@ -1091,833 +717,77 @@ void OpenHelpURL(){ } void OpenBugReportURL(){ - OpenURL( "http://www.icculus.org/netradiant/?cmd=bugs" ); + // OpenURL( "http://www.icculus.org/netradiant/?cmd=bugs" ); + OpenURL( "https://github.com/Garux/netradiant-custom/issues" ); } -GtkWidget* g_page_console; +QWidget* g_page_console; void Console_ToggleShow(){ GroupDialog_showPage( g_page_console ); } -GtkWidget* g_page_entity; +QWidget* g_page_entity; void EntityInspector_ToggleShow(){ GroupDialog_showPage( g_page_entity ); } -GtkWidget* g_page_models; +QWidget* g_page_models; void ModelBrowser_ToggleShow(){ GroupDialog_showPage( g_page_models ); } - -void SetClipMode( bool enable ); -void ModeChangeNotify(); - -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(); -} - - -bool EdgeMode(){ - return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eEdge; -} - -bool VertexMode(){ - return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eVertex; -} - -bool FaceMode(){ - return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace; -} - -template -class BoolFunctionExport +static class EverySecondTimer { + QTimer m_timer; public: - static void apply( const BoolImportCallback& importCallback ){ - importCallback( BoolFunction() ); - } -}; - -typedef FreeCaller1::apply> EdgeModeApplyCaller; -EdgeModeApplyCaller g_edgeMode_button_caller; -BoolExportCallback g_edgeMode_button_callback( g_edgeMode_button_caller ); -ToggleItem g_edgeMode_button( g_edgeMode_button_callback ); - -typedef FreeCaller1::apply> VertexModeApplyCaller; -VertexModeApplyCaller g_vertexMode_button_caller; -BoolExportCallback g_vertexMode_button_callback( g_vertexMode_button_caller ); -ToggleItem g_vertexMode_button( g_vertexMode_button_callback ); - -typedef FreeCaller1::apply> FaceModeApplyCaller; -FaceModeApplyCaller g_faceMode_button_caller; -BoolExportCallback 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(); -} - -void ComponentMode_SelectionChanged( const Selectable& selectable ){ - if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent - && GlobalSelectionSystem().countSelected() == 0 ) { - SelectionSystem_DefaultMode(); - ComponentModeChanged(); - } -} - -void SelectEdgeMode(){ -#if 0 - if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) { - GlobalSelectionSystem().Select( false ); - } -#endif - - if ( EdgeMode() ) { - SelectionSystem_DefaultMode(); - } - else if ( GlobalSelectionSystem().countSelected() != 0 ) { - if ( !g_currentToolModeSupportsComponentEditing ) { - g_defaultToolMode(); - } - - GlobalSelectionSystem().SetMode( SelectionSystem::eComponent ); - GlobalSelectionSystem().SetComponentMode( SelectionSystem::eEdge ); - } - - ComponentModeChanged(); - - ModeChangeNotify(); -} - -void SelectVertexMode(){ -#if 0 - if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) { - GlobalSelectionSystem().Select( false ); - } -#endif - - if ( VertexMode() ) { - SelectionSystem_DefaultMode(); - } - else if ( GlobalSelectionSystem().countSelected() != 0 ) { - if ( !g_currentToolModeSupportsComponentEditing ) { - g_defaultToolMode(); - } - - GlobalSelectionSystem().SetMode( SelectionSystem::eComponent ); - GlobalSelectionSystem().SetComponentMode( SelectionSystem::eVertex ); - } - - ComponentModeChanged(); - - ModeChangeNotify(); -} - -void SelectFaceMode(){ -#if 0 - if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) { - GlobalSelectionSystem().Select( false ); - } -#endif - - if ( FaceMode() ) { - SelectionSystem_DefaultMode(); - } - else if ( GlobalSelectionSystem().countSelected() != 0 ) { - if ( !g_currentToolModeSupportsComponentEditing ) { - g_defaultToolMode(); - } - - GlobalSelectionSystem().SetMode( SelectionSystem::eComponent ); - GlobalSelectionSystem().SetComponentMode( SelectionSystem::eFace ); - } - - ComponentModeChanged(); - - ModeChangeNotify(); -} - - -class CloneSelected : public scene::Graph::Walker -{ - const bool m_makeUnique; - const scene::Node* m_world; -public: - mutable std::vector m_cloned; - CloneSelected( bool makeUnique ) : m_makeUnique( makeUnique ), m_world( Map_FindWorldspawn( g_map ) ){ - } - bool pre( const scene::Path& path, scene::Instance& instance ) const { - if ( path.size() == 1 ) { - return true; - } - - if ( path.top().get_pointer() == m_world ) { // ignore worldspawn, but keep checking children - return true; - } - - if ( !path.top().get().isRoot() ) { - if ( Instance_isSelected( instance ) ) { - return false; + EverySecondTimer(){ + m_timer.setInterval( 1000 ); + m_timer.callOnTimeout( [](){ + if ( QGuiApplication::mouseButtons().testFlag( Qt::MouseButton::NoButton ) ) { + QE_CheckAutoSave(); } - if( m_makeUnique && instance.childSelected() ){ /* clone selected group entity primitives to new group entity */ - return false; - } - } - - return true; + } ); } - void post( const scene::Path& path, scene::Instance& instance ) const { - if ( path.size() == 1 ) { - return; - } - - if ( path.top().get_pointer() == m_world ) { // ignore worldspawn - return; - } - - if ( !path.top().get().isRoot() ) { - if ( Instance_isSelected( instance ) ) { - NodeSmartReference clone( Node_Clone( path.top() ) ); - Map_gatherNamespaced( clone ); - Node_getTraversable( path.parent().get() )->insert( clone ); - m_cloned.push_back( clone.get_pointer() ); - } - else if( m_makeUnique && instance.childSelected() ){ /* clone selected group entity primitives to new group entity */ - NodeSmartReference clone( Node_Clone_Selected( path.top() ) ); - Map_gatherNamespaced( clone ); - Node_getTraversable( path.parent().get() )->insert( clone ); - m_cloned.push_back( clone.get_pointer() ); - } - } + void enable(){ + m_timer.start(); } -}; - -void Scene_Clone_Selected( scene::Graph& graph, bool makeUnique ){ - CloneSelected cloneSelected( makeUnique ); - graph.traverse( cloneSelected ); - - Map_mergeClonedNames( makeUnique ); - - /* deselect originals */ - GlobalSelectionSystem().setSelectedAll( false ); - /* select cloned */ - for( scene::Node *node : cloneSelected.m_cloned ) - { - class walker : public scene::Traversable::Walker - { - public: - bool pre( scene::Node& node ) const override { - if( scene::Instantiable *instantiable = Node_getInstantiable( node ) ){ - class visitor : public scene::Instantiable::Visitor - { - public: - void visit( scene::Instance& instance ) const override { - Instance_setSelected( instance, true ); - } - }; - - instantiable->forEachInstance( visitor() ); - } - return true; - } - }; - Node_traverseSubgraph( *node, walker() ); + void disable(){ + m_timer.stop(); } } +s_qe_every_second_timer; -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_ ){ - } -}; - -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 ); - } - - ERROR_MESSAGE( "invalid viewtype" ); - return AxisBase( Vector3( 0, 0, 0 ), Vector3( 0, 0, 0 ), Vector3( 0, 0, 0 ) ); -} - -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 ); - } - - ERROR_MESSAGE( "invalid direction" ); - return Vector3( 0, 0, 0 ); -} - -bool g_bNudgeAfterClone = false; - -void Nudge_constructPreferences( PreferencesPage& page ){ - page.appendCheckBox( "", "Nudge selected after duplication", g_bNudgeAfterClone ); -} - -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 ); -} - -void Selection_Clone(){ - if ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ) { - UndoableCommand undo( "cloneSelected" ); - - Scene_Clone_Selected( GlobalSceneGraph(), false ); - - if( g_bNudgeAfterClone ){ - NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType()); - NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType()); - } - } -} - -void Selection_Clone_MakeUnique(){ - if ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ) { - UndoableCommand undo( "cloneSelectedMakeUnique" ); - - Scene_Clone_Selected( GlobalSceneGraph(), true ); - - if( g_bNudgeAfterClone ){ - 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 ); - } - } -} - -void Scene_Clone_Selected(){ - Scene_Clone_Selected( GlobalSceneGraph(), false ); -} - -void RepeatTransforms(){ - GlobalSelectionSystem().repeatTransforms( FreeCaller() ); -} - - -void Selection_NudgeUp(){ - UndoableCommand undo( "nudgeSelectedUp" ); - NudgeSelection( eNudgeUp, GetGridSize(), GlobalXYWnd_getCurrentViewType() ); -} - -void Selection_NudgeDown(){ - UndoableCommand undo( "nudgeSelectedDown" ); - NudgeSelection( eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType() ); -} - -void Selection_NudgeLeft(){ - UndoableCommand undo( "nudgeSelectedLeft" ); - NudgeSelection( eNudgeLeft, GetGridSize(), GlobalXYWnd_getCurrentViewType() ); -} - -void Selection_NudgeRight(){ - UndoableCommand undo( "nudgeSelectedRight" ); - NudgeSelection( eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType() ); -} - - -void TranslateToolExport( const BoolImportCallback& importCallback ){ - importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eTranslate ); -} - -void RotateToolExport( const BoolImportCallback& importCallback ){ - importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eRotate ); -} - -void ScaleToolExport( const BoolImportCallback& importCallback ){ - importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eScale ); -} - -void SkewToolExport( const BoolImportCallback& importCallback ){ - importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eSkew ); -} - -void DragToolExport( const BoolImportCallback& importCallback ){ - importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eDrag ); -} - -void ClipperToolExport( const BoolImportCallback& importCallback ){ - importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip ); -} - -void BuildToolExport( const BoolImportCallback& importCallback ){ - importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eBuild ); -} - -void UVToolExport( const BoolImportCallback& importCallback ){ - importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eUV ); -} - -FreeCaller1 g_translatemode_button_caller; -BoolExportCallback g_translatemode_button_callback( g_translatemode_button_caller ); -ToggleItem g_translatemode_button( g_translatemode_button_callback ); - -FreeCaller1 g_rotatemode_button_caller; -BoolExportCallback g_rotatemode_button_callback( g_rotatemode_button_caller ); -ToggleItem g_rotatemode_button( g_rotatemode_button_callback ); - -FreeCaller1 g_scalemode_button_caller; -BoolExportCallback g_scalemode_button_callback( g_scalemode_button_caller ); -ToggleItem g_scalemode_button( g_scalemode_button_callback ); - -FreeCaller1 g_skewmode_button_caller; -BoolExportCallback g_skewmode_button_callback( g_skewmode_button_caller ); -ToggleItem g_skewmode_button( g_skewmode_button_callback ); - -FreeCaller1 g_dragmode_button_caller; -BoolExportCallback g_dragmode_button_callback( g_dragmode_button_caller ); -ToggleItem g_dragmode_button( g_dragmode_button_callback ); - -FreeCaller1 g_clipper_button_caller; -BoolExportCallback g_clipper_button_callback( g_clipper_button_caller ); -ToggleItem g_clipper_button( g_clipper_button_callback ); - -FreeCaller1 g_build_button_caller; -BoolExportCallback g_build_button_callback( g_build_button_caller ); -ToggleItem g_build_button( g_build_button_callback ); - -FreeCaller1 g_uv_button_caller; -BoolExportCallback g_uv_button_callback( g_uv_button_caller ); -ToggleItem g_uv_button( g_uv_button_callback ); - -void ToolChanged(){ - g_translatemode_button.update(); - g_rotatemode_button.update(); - g_scalemode_button.update(); - g_skewmode_button.update(); - g_dragmode_button.update(); - g_clipper_button.update(); - g_build_button.update(); - g_uv_button.update(); -} - -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; - - Sys_Status( c_ResizeMode_status ); - GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eDrag ); - ToolChanged(); - ModeChangeNotify(); - } -} - - -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; - - Sys_Status( c_TranslateMode_status ); - GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eTranslate ); - ToolChanged(); - ModeChangeNotify(); - } -} - -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; - - Sys_Status( c_RotateMode_status ); - GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eRotate ); - ToolChanged(); - ModeChangeNotify(); - } -} - -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; - - Sys_Status( c_ScaleMode_status ); - GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eScale ); - ToolChanged(); - ModeChangeNotify(); - } -} - -const char* const c_SkewMode_status = "Transform Tool: transform objects and components"; - -void SkewMode(){ - if ( g_currentToolMode == SkewMode && g_defaultToolMode != SkewMode ) { - g_defaultToolMode(); - } - else - { - g_currentToolMode = SkewMode; - g_currentToolModeSupportsComponentEditing = true; - - Sys_Status( c_SkewMode_status ); - GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eSkew ); - ToolChanged(); - ModeChangeNotify(); - } -} - - -const char* const c_ClipperMode_status = "Clipper Tool: apply clip planes to brushes"; - -void ClipperMode(){ - if ( g_currentToolMode == ClipperMode && g_defaultToolMode != ClipperMode ) { - g_defaultToolMode(); - } - else - { - g_currentToolMode = ClipperMode; - g_currentToolModeSupportsComponentEditing = false; - - SelectionSystem_DefaultMode(); - ComponentModeChanged(); - - Sys_Status( c_ClipperMode_status ); - GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eClip ); - ToolChanged(); - ModeChangeNotify(); - } -} - - -const char* const c_BuildMode_status = "Build Tool: extrude, build chains, clone"; - -void BuildMode(){ - if ( g_currentToolMode == BuildMode && g_defaultToolMode != BuildMode ) { - g_defaultToolMode(); - } - else - { - g_currentToolMode = BuildMode; - g_currentToolModeSupportsComponentEditing = false; - - SelectionSystem_DefaultMode(); - ComponentModeChanged(); - - Sys_Status( c_BuildMode_status ); - GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eBuild ); - ToolChanged(); - ModeChangeNotify(); - } -} - - -const char* const c_UVMode_status = "UV Tool: edit texture alignment"; - -void UVMode(){ - if ( g_currentToolMode == UVMode && g_defaultToolMode != UVMode ) { - g_defaultToolMode(); - } - else - { - g_currentToolMode = UVMode; - g_currentToolModeSupportsComponentEditing = false; - - SelectionSystem_DefaultMode(); - ComponentModeChanged(); - - Sys_Status( c_UVMode_status ); - GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eUV ); - ToolChanged(); - ModeChangeNotify(); - } -} - - -void ToggleRotateScaleModes(){ - return g_currentToolMode == RotateMode? ScaleMode() : RotateMode(); -} - -void ToggleDragSkewModes(){ - return g_currentToolMode == DragMode? SkewMode() : DragMode(); -} - - -void Texdef_Rotate( float angle ){ - StringOutputStream command; - command << "brushRotateTexture -angle " << angle; - UndoableCommand undo( command.c_str() ); - Select_RotateTexture( angle ); -} -// these are actually {Anti,}Clockwise in BP mode only (AP/220 - 50/50) -// TODO is possible to make really {Anti,}Clockwise -void Texdef_RotateClockwise(){ - Texdef_Rotate( static_cast( -fabs( g_si_globals.rotate ) ) ); -} - -void Texdef_RotateAntiClockwise(){ - Texdef_Rotate( static_cast( 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 ); -} - -void Texdef_ScaleUp(){ - Texdef_Scale( 0, g_si_globals.scale[1] ); -} - -void Texdef_ScaleDown(){ - Texdef_Scale( 0, -g_si_globals.scale[1] ); -} - -void Texdef_ScaleLeft(){ - Texdef_Scale( -g_si_globals.scale[0],0 ); -} - -void Texdef_ScaleRight(){ - 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 ); -} - -void Texdef_ShiftLeft(){ - Texdef_Shift( -g_si_globals.shift[0], 0 ); -} - -void Texdef_ShiftRight(){ - Texdef_Shift( g_si_globals.shift[0], 0 ); -} - -void Texdef_ShiftUp(){ - Texdef_Shift( 0, g_si_globals.shift[1] ); -} - -void Texdef_ShiftDown(){ - Texdef_Shift( 0, -g_si_globals.shift[1] ); -} - - - -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() ) { - Snappable* snappable = Node_getSnappable( path.top() ); - if ( snappable != 0 - && Instance_isSelected( instance ) ) { - snappable->snapto( m_snap ); - } - } - return true; - } -}; - -void Scene_SnapToGrid_Selected( scene::Graph& graph, float snap ){ - graph.traverse( SnappableSnapToGridSelected( 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() ) { - ComponentSnappable* componentSnappable = Instance_getComponentSnappable( instance ); - if ( componentSnappable != 0 - && Instance_isSelected( instance ) ) { - componentSnappable->snapComponents( m_snap ); - } - } - return true; - } -}; - -void Scene_SnapToGrid_Component_Selected( scene::Graph& graph, float snap ){ - graph.traverse( ComponentSnappableSnapToGridSelected( snap ) ); -} - -void Selection_SnapToGrid(){ - StringOutputStream command; - command << "snapSelected -grid " << GetGridSize(); - UndoableCommand undo( command.c_str() ); - - if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent && GlobalSelectionSystem().countSelectedComponents() ) { - Scene_SnapToGrid_Component_Selected( GlobalSceneGraph(), GetGridSize() ); - } - else - { - Scene_SnapToGrid_Selected( GlobalSceneGraph(), GetGridSize() ); - } -} - - -static gboolean qe_every_second( gpointer data ){ - GdkModifierType mask; - - gdk_window_get_pointer( 0, 0, 0, &mask ); - - if ( ( mask & ( GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK ) ) == 0 ) { - QE_CheckAutoSave(); - } - - return TRUE; -} - -guint s_qe_every_second_id = 0; - -void EverySecondTimer_enable(){ - 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 ) { - g_source_remove( s_qe_every_second_id ); - s_qe_every_second_id = 0; - } -} - -void window_realize_remove_decoration( GtkWidget* widget, gpointer data ){ - gdk_window_set_decorations( gtk_widget_get_window( widget ), (GdkWMDecoration)( GDK_DECOR_ALL | GDK_DECOR_MENU | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE ) ); -} class WaitDialog { public: - GtkWindow* m_window; - GtkLabel* m_label; + QWidget* m_window; + QLabel* m_label; }; -WaitDialog create_wait_dialog( const char* title, const char* text, bool modal ){ - WaitDialog dialog; - - dialog.m_window = create_floating_window( title, MainFrame_getWindow() ); - gtk_window_set_modal( dialog.m_window, modal ); - 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 ); - - gtk_window_set_accept_focus( dialog.m_window, FALSE ); - gtk_window_set_focus_on_map( dialog.m_window, FALSE ); - - - g_signal_connect( G_OBJECT( dialog.m_window ), "realize", G_CALLBACK( window_realize_remove_decoration ), 0 ); +WaitDialog create_wait_dialog( const char* title, const char* text ){ + /* Qt::Tool window type doesn't steal focus, which saves e.g. from losing freelook camera mode on autosave + or entity menu from hiding, while clicked with ctrl, by tex/model loading popup. + Qt::WidgetAttribute::WA_ShowWithoutActivating is implied, but lets have it set too. */ + auto window = new QWidget( MainFrame_getWindow(), Qt::Tool | Qt::CustomizeWindowHint | Qt::WindowTitleHint ); + window->setWindowTitle( title ); + window->setWindowModality( Qt::WindowModality::ApplicationModal ); + window->setAttribute( Qt::WidgetAttribute::WA_ShowWithoutActivating ); + auto label = new QLabel( text ); { - 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 ); - - gtk_container_add( GTK_CONTAINER( dialog.m_window ), GTK_WIDGET( dialog.m_label ) ); + auto box = new QHBoxLayout( window ); + box->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + box->setContentsMargins( 20, 5, 20, 3 ); + box->addWidget( label ); + label->setMinimumWidth( 200 ); } - return dialog; + return WaitDialog{ window, label }; } namespace @@ -1935,23 +805,6 @@ bool redrawRequired(){ } } -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"; - g_list_free( list ); - return true; - } - //globalOutputStream() << "not active\n"; - } - g_list_free( list ); - return false; -} - typedef std::list StringStack; StringStack g_wait_stack; WaitDialog g_wait; @@ -1961,7 +814,7 @@ bool ScreenUpdates_Enabled(){ } void ScreenUpdates_process(){ - if ( redrawRequired() && gtk_widget_get_visible( GTK_WIDGET( g_wait.m_window ) ) ) { + if ( redrawRequired() ) { process_gui(); } } @@ -1969,22 +822,18 @@ void ScreenUpdates_process(){ void ScreenUpdates_Disable( const char* message, const char* title ){ if ( g_wait_stack.empty() ) { - EverySecondTimer_disable(); + s_qe_every_second_timer.disable(); process_gui(); - bool isActiveApp = MainFrame_isActiveApp(); + g_wait = create_wait_dialog( title, message ); - g_wait = create_wait_dialog( title, message, - !XYWnd::m_mnuDrop || !gtk_widget_get_visible( GTK_WIDGET( XYWnd::m_mnuDrop ) ) ); //hack: avoid hiding entity menu, clicked with ctrl, by tex/model loading popup - - if ( isActiveApp ) { - gtk_widget_show( GTK_WIDGET( g_wait.m_window ) ); - ScreenUpdates_process(); - } + g_wait.m_window->show(); + ScreenUpdates_process(); } - else if ( gtk_widget_get_visible( GTK_WIDGET( g_wait.m_window ) ) ) { - gtk_label_set_text( g_wait.m_label, message ); + else { + g_wait.m_window->setWindowTitle( title ); + g_wait.m_label->setText( message ); ScreenUpdates_process(); } g_wait_stack.push_back( message ); @@ -1994,16 +843,12 @@ 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); + s_qe_every_second_timer.enable(); - destroy_floating_window( g_wait.m_window ); - g_wait.m_window = 0; - - //gtk_window_present(MainFrame_getWindow()); + delete std::exchange( g_wait.m_window, nullptr ); } - else if ( gtk_widget_get_visible( GTK_WIDGET( g_wait.m_window ) ) ) { - gtk_label_set_text( g_wait.m_label, g_wait_stack.back().c_str() ); + else { + g_wait.m_label->setText( g_wait_stack.back().c_str() ); ScreenUpdates_process(); } } @@ -2030,113 +875,79 @@ void UpdateAllWindows(){ } -void ModeChangeNotify(){ - SceneChangeNotify(); -} - - LatchedInt g_Layout_viewStyle( 0, "Window Layout" ); LatchedBool g_Layout_enableDetachableMenus( true, "Detachable Menus" ); -LatchedBool g_Layout_enableMainToolbar( true, "Main Toolbar" ); -LatchedBool g_Layout_enablePatchToolbar( true, "Patch Toolbar" ); -LatchedBool g_Layout_enablePluginToolbar( true, "Plugin Toolbar" ); -LatchedBool g_Layout_enableFilterToolbar( true, "Filter Toolbar" ); - -LatchedBool g_Layout_SingleToolbar( true, "Single Scrollable Toolbar" ); -GtkMenuItem* create_file_menu(){ +void create_file_menu( QMenuBar *menubar ){ // 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 ); - } + QMenu *menu = menubar->addMenu( "&File" ); - create_menu_item_with_mnemonic( menu, "_New Map", "NewMap" ); - menu_separator( menu ); + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); - create_menu_item_with_mnemonic( menu, "_Open...", "OpenMap" ); - create_menu_item_with_mnemonic( menu, "_Import...", "ImportMap" ); - menu_separator( menu ); - 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" ); - create_menu_item_with_mnemonic( menu, "Save re_gion...", "SaveRegion" ); - menu_separator( menu ); -// 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 ); + create_menu_item_with_mnemonic( menu, "&New Map", "NewMap" ); + menu->addSeparator(); + + create_menu_item_with_mnemonic( menu, "&Open...", "OpenMap" ); + create_menu_item_with_mnemonic( menu, "&Import...", "ImportMap" ); + menu->addSeparator(); + 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" ); + create_menu_item_with_mnemonic( menu, "Save re&gion...", "SaveRegion" ); + menu->addSeparator(); +// create_menu_item_with_mnemonic( menu, "&Refresh models", "RefreshReferences" ); +// menu->addSeparator(); + create_menu_item_with_mnemonic( menu, "&Pointfile", "TogglePointfile" ); + menu->addSeparator(); 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; + menu->addSeparator(); + create_menu_item_with_mnemonic( menu, "E&xit", "Exit" ); } -GtkMenuItem* create_edit_menu(){ +void create_edit_menu( QMenuBar *menubar ){ // 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" ); + QMenu *menu = menubar->addMenu( "&Edit" ); + + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + + create_menu_item_with_mnemonic( menu, "&Undo", "Undo" ); + create_menu_item_with_mnemonic( menu, "&Redo", "Redo" ); + menu->addSeparator(); + 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" ); create_menu_item_with_mnemonic( menu, "Move To Camera", "MoveToCamera" ); - 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" ); - //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" ); + menu->addSeparator(); + 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" ); + //create_menu_item_with_mnemonic( menu, "Pa&rent", "ParentSelection" ); + menu->addSeparator(); + 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" ); - menu_separator( menu ); + menu->addSeparator(); -// 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( menu, "Select All Of Type", "SelectAllOfType" ); create_menu_item_with_mnemonic( menu, "Select Textured", "SelectTextured" ); - create_menu_item_with_mnemonic( menu, "_Expand Selection To Primitives", "ExpandSelectionToPrimitives" ); - create_menu_item_with_mnemonic( menu, "_Expand Selection To Entities", "ExpandSelectionToEntities" ); + create_menu_item_with_mnemonic( menu, "&Expand Selection To Primitives", "ExpandSelectionToPrimitives" ); + create_menu_item_with_mnemonic( menu, "&Expand Selection To Entities", "ExpandSelectionToEntities" ); create_menu_item_with_mnemonic( menu, "Select Connected Entities", "SelectConnectedEntities" ); - menu_separator( menu ); - create_menu_item_with_mnemonic( menu, "_Shortcuts...", FreeCaller() ); - create_menu_item_with_mnemonic( menu, "Pre_ferences...", "Preferences" ); - - return edit_menu_item; + menu->addSeparator(); + create_menu_item_with_mnemonic( menu, "&Shortcuts...", FreeCaller() ); + create_menu_item_with_mnemonic( menu, "Pre&ferences...", "Preferences" ); } - -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 ){ +void create_view_menu( QMenuBar *menubar, 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 ); - } + QMenu *menu = menubar->addMenu( "Vie&w" ); + + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); if ( style == MainFrame::eFloating ) { create_check_menu_item_with_mnemonic( menu, "Camera View", "ToggleCamera" ); @@ -2150,284 +961,248 @@ GtkMenuItem* create_view_menu( MainFrame::EViewStyle style ){ } create_menu_item_with_mnemonic( menu, "Model Browser", "ToggleModelBrowser" ); create_menu_item_with_mnemonic( menu, "Entity Inspector", "ToggleEntityInspector" ); - create_menu_item_with_mnemonic( menu, "_Surface Inspector", "SurfaceInspector" ); - create_menu_item_with_mnemonic( menu, "_Patch Inspector", "PatchInspector" ); + create_menu_item_with_mnemonic( menu, "&Surface Inspector", "SurfaceInspector" ); create_menu_item_with_mnemonic( menu, "Entity List", "EntityList" ); - menu_separator( menu ); + menu->addSeparator(); { - 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, "Focus on Selected", "CameraFocusOnSelected" ); - 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" ); + QMenu* submenu = menu->addMenu( "Camera" ); + + submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + + create_menu_item_with_mnemonic( submenu, "Focus on Selected", "CameraFocusOnSelected" ); + create_menu_item_with_mnemonic( submenu, "&Center", "CenterView" ); + create_menu_item_with_mnemonic( submenu, "&Up Floor", "UpFloor" ); + create_menu_item_with_mnemonic( submenu, "&Down Floor", "DownFloor" ); + submenu->addSeparator(); + create_menu_item_with_mnemonic( submenu, "Far Clip Plane In", "CubicClipZoomIn" ); + create_menu_item_with_mnemonic( submenu, "Far Clip Plane Out", "CubicClipZoomOut" ); + submenu->addSeparator(); + create_menu_item_with_mnemonic( submenu, "Next leak spot", "NextLeakSpot" ); + create_menu_item_with_mnemonic( submenu, "Previous leak spot", "PrevLeakSpot" ); //cameramodel is not implemented in instances, thus useless -// 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" ); +// submenu->addSeparator(); +// create_menu_item_with_mnemonic( submenu, "Look Through Selected", "LookThroughSelected" ); +// create_menu_item_with_mnemonic( submenu, "Look Through Camera", "LookThroughCamera" ); } - menu_separator( menu ); + menu->addSeparator(); { - GtkMenu* orthographic_menu = create_sub_menu_with_mnemonic( menu, "Orthographic" ); - if ( g_Layout_enableDetachableMenus.m_value ) { - menu_tearoff( orthographic_menu ); - } + QMenu* submenu = menu->addMenu( "Orthographic" ); + + submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + if ( style == MainFrame::eRegular || style == MainFrame::eRegularLeft || style == MainFrame::eFloating ) { - create_menu_item_with_mnemonic( orthographic_menu, "_Next (XY, XZ, YZ)", "NextView" ); - create_menu_item_with_mnemonic( orthographic_menu, "XY (Top)", "ViewTop" ); - create_menu_item_with_mnemonic( orthographic_menu, "XZ (Front)", "ViewFront" ); - create_menu_item_with_mnemonic( orthographic_menu, "YZ (Side)", "ViewSide" ); - menu_separator( orthographic_menu ); + create_menu_item_with_mnemonic( submenu, "&Next (XY, XZ, YZ)", "NextView" ); + create_menu_item_with_mnemonic( submenu, "XY (Top)", "ViewTop" ); + create_menu_item_with_mnemonic( submenu, "XZ (Front)", "ViewFront" ); + create_menu_item_with_mnemonic( submenu, "YZ (Side)", "ViewSide" ); + submenu->addSeparator(); } else{ - create_menu_item_with_mnemonic( orthographic_menu, "Center on Selected", "NextView" ); + create_menu_item_with_mnemonic( submenu, "Center on Selected", "NextView" ); } - create_menu_item_with_mnemonic( orthographic_menu, "Focus on Selected", "XYFocusOnSelected" ); - create_menu_item_with_mnemonic( orthographic_menu, "Center on Selected", "CenterXYView" ); - 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" ); + create_menu_item_with_mnemonic( submenu, "Focus on Selected", "XYFocusOnSelected" ); + create_menu_item_with_mnemonic( submenu, "Center on Selected", "CenterXYView" ); + submenu->addSeparator(); + create_menu_item_with_mnemonic( submenu, "&XY 100%", "Zoom100" ); + create_menu_item_with_mnemonic( submenu, "XY Zoom &In", "ZoomIn" ); + create_menu_item_with_mnemonic( submenu, "XY Zoom &Out", "ZoomOut" ); } - menu_separator( menu ); + menu->addSeparator(); { - 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 Entity _Angles", "ShowAngles" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Show Entity _Names", "ShowNames" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Show Light Radiuses", "ShowLightRadiuses" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Show Entity Boxes", "ShowBboxes" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Show Entity Connections", "ShowConnections" ); + QMenu* submenu = menu->addMenu( "Show" ); - menu_separator( menu_in_menu ); + submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Show 2D Size Info", "ShowSize2d" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Show 3D Size Info", "ShowSize3d" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Show Crosshair", "ToggleCrosshairs" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Show Grid", "ToggleGrid" ); - 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 2D Workzone", "ShowWorkzone2d" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Show 3D Workzone", "ShowWorkzone3d" ); - create_check_menu_item_with_mnemonic( menu_in_menu, "Show Renderer Stats", "ShowStats" ); + create_check_menu_item_with_mnemonic( submenu, "Show Entity &Angles", "ShowAngles" ); + create_check_menu_item_with_mnemonic( submenu, "Show Entity &Names", "ShowNames" ); + create_check_menu_item_with_mnemonic( submenu, "Show Light Radiuses", "ShowLightRadiuses" ); + create_check_menu_item_with_mnemonic( submenu, "Show Entity Boxes", "ShowBboxes" ); + create_check_menu_item_with_mnemonic( submenu, "Show Entity Connections", "ShowConnections" ); + + submenu->addSeparator(); + + create_check_menu_item_with_mnemonic( submenu, "Show 2D Size Info", "ShowSize2d" ); + create_check_menu_item_with_mnemonic( submenu, "Show 3D Size Info", "ShowSize3d" ); + create_check_menu_item_with_mnemonic( submenu, "Show Crosshair", "ToggleCrosshairs" ); + create_check_menu_item_with_mnemonic( submenu, "Show Grid", "ToggleGrid" ); + create_check_menu_item_with_mnemonic( submenu, "Show Blocks", "ShowBlocks" ); + create_check_menu_item_with_mnemonic( submenu, "Show C&oordinates", "ShowCoordinates" ); + create_check_menu_item_with_mnemonic( submenu, "Show Window Outline", "ShowWindowOutline" ); + create_check_menu_item_with_mnemonic( submenu, "Show Axes", "ShowAxes" ); + create_check_menu_item_with_mnemonic( submenu, "Show 2D Workzone", "ShowWorkzone2d" ); + create_check_menu_item_with_mnemonic( submenu, "Show 3D Workzone", "ShowWorkzone3d" ); + create_check_menu_item_with_mnemonic( submenu, "Show Renderer 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 ); + QMenu* submenu = menu->addMenu( "Filter" ); + + submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + + Filters_constructMenu( submenu ); } - menu_separator( menu ); + menu->addSeparator(); { create_check_menu_item_with_mnemonic( menu, "Hide Selected", "HideSelected" ); create_menu_item_with_mnemonic( menu, "Show Hidden", "ShowHidden" ); } - menu_separator( menu ); + menu->addSeparator(); { - 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_check_menu_item_with_mnemonic( menu_in_menu, "Set Se_lection", "RegionSetSelection" ); + QMenu* submenu = menu->addMenu( "Region" ); + + submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + + create_menu_item_with_mnemonic( submenu, "&Off", "RegionOff" ); + create_menu_item_with_mnemonic( submenu, "&Set XY", "RegionSetXY" ); + create_menu_item_with_mnemonic( submenu, "Set _Brush", "RegionSetBrush" ); + create_check_menu_item_with_mnemonic( submenu, "Set Se&lection", "RegionSetSelection" ); } //command_connect_accelerator( "CenterXYView" ); - - return view_menu_item; } -GtkMenuItem* create_selection_menu(){ +void create_selection_menu( QMenuBar *menubar ){ // 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 ); - } + QMenu *menu = menubar->addMenu( "M&odify" ); + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); { - 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" ); + QMenu* submenu = menu->addMenu( "Components" ); + + submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + + create_check_menu_item_with_mnemonic( submenu, "&Edges", "DragEdges" ); + create_check_menu_item_with_mnemonic( submenu, "&Vertices", "DragVertices" ); + create_check_menu_item_with_mnemonic( submenu, "&Faces", "DragFaces" ); } - menu_separator( menu ); + menu->addSeparator(); create_menu_item_with_mnemonic( menu, "Snap To Grid", "SnapToGrid" ); - menu_separator( menu ); + menu->addSeparator(); { - 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" ); - menu_separator( menu_in_menu ); - create_menu_item_with_mnemonic( menu_in_menu, "Nudge +Z", "MoveSelectionUP" ); - create_menu_item_with_mnemonic( menu_in_menu, "Nudge -Z", "MoveSelectionDOWN" ); + QMenu* submenu = menu->addMenu( "Nudge" ); + + submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + + create_menu_item_with_mnemonic( submenu, "Nudge Left", "SelectNudgeLeft" ); + create_menu_item_with_mnemonic( submenu, "Nudge Right", "SelectNudgeRight" ); + create_menu_item_with_mnemonic( submenu, "Nudge Up", "SelectNudgeUp" ); + create_menu_item_with_mnemonic( submenu, "Nudge Down", "SelectNudgeDown" ); + submenu->addSeparator(); + create_menu_item_with_mnemonic( submenu, "Nudge +Z", "MoveSelectionUP" ); + create_menu_item_with_mnemonic( submenu, "Nudge -Z", "MoveSelectionDOWN" ); } { - 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" ); - menu_separator( menu_in_menu ); - create_menu_item_with_mnemonic( menu_in_menu, "Rotate Clockwise", "RotateSelectionClockwise" ); - create_menu_item_with_mnemonic( menu_in_menu, "Rotate Anticlockwise", "RotateSelectionAnticlockwise" ); + QMenu* submenu = menu->addMenu( "Rotate" ); + + submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + + create_menu_item_with_mnemonic( submenu, "Rotate X", "RotateSelectionX" ); + create_menu_item_with_mnemonic( submenu, "Rotate Y", "RotateSelectionY" ); + create_menu_item_with_mnemonic( submenu, "Rotate Z", "RotateSelectionZ" ); + submenu->addSeparator(); + create_menu_item_with_mnemonic( submenu, "Rotate Clockwise", "RotateSelectionClockwise" ); + create_menu_item_with_mnemonic( submenu, "Rotate Anticlockwise", "RotateSelectionAnticlockwise" ); } { - 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_in_menu ); - create_menu_item_with_mnemonic( menu_in_menu, "Flip Horizontally", "MirrorSelectionHorizontally" ); - create_menu_item_with_mnemonic( menu_in_menu, "Flip Vertically", "MirrorSelectionVertically" ); + QMenu* submenu = menu->addMenu( "Flip" ); + + submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + + create_menu_item_with_mnemonic( submenu, "Flip &X", "MirrorSelectionX" ); + create_menu_item_with_mnemonic( submenu, "Flip &Y", "MirrorSelectionY" ); + create_menu_item_with_mnemonic( submenu, "Flip &Z", "MirrorSelectionZ" ); + submenu->addSeparator(); + create_menu_item_with_mnemonic( submenu, "Flip Horizontally", "MirrorSelectionHorizontally" ); + create_menu_item_with_mnemonic( submenu, "Flip Vertically", "MirrorSelectionVertically" ); } - menu_separator( menu ); + menu->addSeparator(); create_menu_item_with_mnemonic( menu, "Arbitrary rotation...", "ArbitraryRotation" ); create_menu_item_with_mnemonic( menu, "Arbitrary scale...", "ArbitraryScale" ); create_menu_item_with_mnemonic( menu, "Repeat Transforms", "RepeatTransforms" ); - - return selection_menu_item; } -GtkMenuItem* create_bsp_menu(){ +void create_bsp_menu( QMenuBar *menubar ){ // 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 ) ); + QMenu *menu = menubar->addMenu( "&Build" ); - if ( g_Layout_enableDetachableMenus.m_value ) { - menu_tearoff( menu ); - } + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); create_menu_item_with_mnemonic( menu, "Customize...", "BuildMenuCustomize" ); create_menu_item_with_mnemonic( menu, "Run recent build", "Build_runRecentExecutedBuild" ); - menu_separator( menu ); + menu->addSeparator(); + menu->setToolTipsVisible( true ); Build_constructMenu( menu ); g_bsp_menu = menu; - - return bsp_menu_item; } -GtkMenuItem* create_grid_menu(){ +void create_grid_menu( QMenuBar *menubar ){ // 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 ); - } + QMenu *menu = menubar->addMenu( "&Grid" ); + + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); Grid_constructMenu( menu ); - - return grid_menu_item; } -GtkMenuItem* create_misc_menu(){ +void create_misc_menu( QMenuBar *menubar ){ // 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 ); - } + QMenu *menu = menubar->addMenu( "M&isc" ); + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); #if 0 - create_menu_item_with_mnemonic( menu, "_Benchmark", FreeCaller() ); + create_menu_item_with_mnemonic( menu, "&Benchmark", FreeCaller() ); #endif - gtk_container_add( GTK_CONTAINER( menu ), GTK_WIDGET( create_colours_menu() ) ); + create_colours_menu( 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()); - create_menu_item_with_mnemonic( menu, "Set 2D _Background image...", FreeCaller() ); + create_menu_item_with_mnemonic( menu, "Set 2D &Background image...", FreeCaller() ); create_menu_item_with_mnemonic( menu, "Fullscreen", "Fullscreen" ); create_menu_item_with_mnemonic( menu, "Maximize view", "MaximizeView" ); - return misc_menu_item; } -GtkMenuItem* 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 ); - } +void create_entity_menu( QMenuBar *menubar ){ + // Entity menu + QMenu *menu = menubar->addMenu( "E&ntity" ); + + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); Entity_constructMenu( menu ); - - return entity_menu_item; } -GtkMenuItem* create_brush_menu(){ +void create_brush_menu( QMenuBar *menubar ){ // 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 ); - } + QMenu *menu = menubar->addMenu( "B&rush" ); + + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); Brush_constructMenu( menu ); - - return brush_menu_item; } -GtkMenuItem* create_patch_menu(){ +void create_patch_menu( QMenuBar *menubar ){ // 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 ); - } + QMenu *menu = menubar->addMenu( "&Curve" ); + + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); Patch_constructMenu( menu ); - - return patch_menu_item; } -GtkMenuItem* create_help_menu(){ +void create_help_menu( QMenuBar *menubar ){ // 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 ); - } + QMenu *menu = menubar->addMenu( "&Help" ); + + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); // create_menu_item_with_mnemonic( menu, "Manual", "OpenManual" ); @@ -2435,37 +1210,27 @@ GtkMenuItem* create_help_menu(){ // 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() ); - create_menu_item_with_mnemonic( menu, "_About", FreeCaller() ); - - return help_menu_item; + create_menu_item_with_mnemonic( menu, "Bug report", FreeCaller() ); + create_menu_item_with_mnemonic( menu, "Check for NetRadiant update (web)", "CheckForUpdate" ); // FIXME + create_menu_item_with_mnemonic( menu, "&About", FreeCaller() ); } -GtkMenuBar* create_main_menu( MainFrame::EViewStyle style ){ - GtkMenuBar* menu_bar = GTK_MENU_BAR( gtk_menu_bar_new() ); - gtk_widget_show( GTK_WIDGET( menu_bar ) ); - - 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() ) ); - - return menu_bar; +void create_main_menu( QMenuBar *menubar, MainFrame::EViewStyle style ){ + create_file_menu( menubar ); + create_edit_menu( menubar ); + create_view_menu( menubar, style ); + create_selection_menu( menubar ); + create_bsp_menu( menubar ); + create_grid_menu( menubar ); + create_misc_menu( menubar ); + create_entity_menu( menubar ); + create_brush_menu( menubar ); + create_patch_menu( menubar ); + create_plugins_menu( menubar ); + create_help_menu( menubar ); } -void PatchInspector_registerShortcuts(){ - command_connect_accelerator( "PatchInspector" ); -} - void Patch_registerShortcuts(){ command_connect_accelerator( "InvertCurveTextureX" ); command_connect_accelerator( "InvertCurveTextureY" ); @@ -2474,19 +1239,9 @@ void Patch_registerShortcuts(){ 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( "MouseTransform" ); - toggle_add_accelerator( "MouseDrag" ); - toggle_add_accelerator( "ToggleClipper" ); - toggle_add_accelerator( "MouseBuild" ); - toggle_add_accelerator( "MouseUV" ); - command_connect_accelerator( "MouseRotateOrScale" ); command_connect_accelerator( "MouseDragOrTransform" ); } @@ -2533,13 +1288,10 @@ void SurfaceInspector_registerShortcuts(){ } void TexBro_registerShortcuts(){ - command_connect_accelerator( "FindReplaceTextures" ); - command_connect_accelerator( "RefreshShaders" ); toggle_add_accelerator( "SearchFromStart" ); } void Misc_registerShortcuts(){ - command_connect_accelerator( "RefreshReferences" ); //refresh models command_connect_accelerator( "Redo2" ); command_connect_accelerator( "UnSelectSelection2" ); command_connect_accelerator( "DeleteSelection2" ); @@ -2548,7 +1300,6 @@ void Misc_registerShortcuts(){ void register_shortcuts(){ -// PatchInspector_registerShortcuts(); // Patch_registerShortcuts(); Grid_registerShortcuts(); // XYWnd_registerShortcuts(); @@ -2564,17 +1315,17 @@ void register_shortcuts(){ Entity_registerShortcuts(); } -void File_constructToolbar( GtkToolbar* toolbar ){ - 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 File_constructToolbar( QToolBar* toolbar ){ + toolbar_append_button( toolbar, "Open an existing map", "file_open.png", "OpenMap" ); + toolbar_append_button( toolbar, "Save the active map", "file_save.png", "SaveMap" ); } -void UndoRedo_constructToolbar( GtkToolbar* toolbar ){ - toolbar_append_button( toolbar, "Undo (CTRL + Z)", "undo.png", "Undo" ); - toolbar_append_button( toolbar, "Redo (CTRL + Y)", "redo.png", "Redo" ); +void UndoRedo_constructToolbar( QToolBar* toolbar ){ + toolbar_append_button( toolbar, "Undo", "undo.png", "Undo" ); + toolbar_append_button( toolbar, "Redo", "redo.png", "Redo" ); } -void RotateFlip_constructToolbar( GtkToolbar* toolbar ){ +void RotateFlip_constructToolbar( QToolBar* toolbar ){ // 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" ); @@ -2588,216 +1339,134 @@ void RotateFlip_constructToolbar( GtkToolbar* toolbar ){ toolbar_append_button( toolbar, "Rotate Clockwise", "brush_rotate_clock.png", "RotateSelectionClockwise" ); } -void Select_constructToolbar( GtkToolbar* toolbar ){ +void Select_constructToolbar( QToolBar* toolbar ){ 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 ){ - toolbar_append_button( toolbar, "CSG Subtract (SHIFT + U)", "selection_csgsubtract.png", "CSGSubtract" ); - toolbar_append_button( toolbar, "CSG Wrap Merge (CTRL + U)", "selection_csgmerge.png", "CSGWrapMerge" ); +void CSG_constructToolbar( QToolBar* toolbar ){ + toolbar_append_button( toolbar, "CSG Subtract", "selection_csgsubtract.png", "CSGSubtract" ); + toolbar_append_button( toolbar, "CSG Wrap Merge", "selection_csgmerge.png", "CSGWrapMerge" ); toolbar_append_button( toolbar, "Room", "selection_makeroom.png", "CSGroom" ); toolbar_append_button( toolbar, "CSG Tool", "ellipsis.png", "CSGTool" ); } -void ComponentModes_constructToolbar( GtkToolbar* toolbar ){ - 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 ComponentModes_constructToolbar( QToolBar* toolbar ){ + toolbar_append_toggle_button( toolbar, "Select Vertices", "modify_vertices.png", "DragVertices" ); + toolbar_append_toggle_button( toolbar, "Select Edges", "modify_edges.png", "DragEdges" ); + toolbar_append_toggle_button( toolbar, "Select Faces", "modify_faces.png", "DragFaces" ); } -void XYWnd_constructToolbar( GtkToolbar* toolbar ){ - toolbar_append_button( toolbar, "Change views (CTRL + TAB)", "view_change.png", "NextView" ); +void XYWnd_constructToolbar( QToolBar* toolbar ){ + toolbar_append_button( toolbar, "Change views", "view_change.png", "NextView" ); } -void Manipulators_constructToolbar( GtkToolbar* toolbar ){ - toolbar_append_toggle_button( toolbar, "Translate (W)", "select_mousetranslate.png", "MouseTranslate" ); - toolbar_append_toggle_button( toolbar, "Rotate (R)", "select_mouserotate.png", "MouseRotate" ); +void Manipulators_constructToolbar( QToolBar* toolbar ){ + toolbar_append_toggle_button( toolbar, "Translate", "select_mousetranslate.png", "MouseTranslate" ); + toolbar_append_toggle_button( toolbar, "Rotate", "select_mouserotate.png", "MouseRotate" ); toolbar_append_toggle_button( toolbar, "Scale", "select_mousescale.png", "MouseScale" ); - toolbar_append_toggle_button( toolbar, "Transform (Q)", "select_mousetransform.png", "MouseTransform" ); - toolbar_append_toggle_button( toolbar, "Resize (Q)", "select_mouseresize.png", "MouseDrag" ); - toolbar_append_toggle_button( toolbar, "Clipper (X)", "select_clipper.png", "ToggleClipper" ); -// toolbar_append_toggle_button( toolbar, "Build (B)", "select_mouserotate.png", "MouseBuild" ); - toolbar_append_toggle_button( toolbar, "UV Tool (G)", "select_mouseuv.png", "MouseUV" ); + toolbar_append_toggle_button( toolbar, "Transform (Q)", "select_mousetransform.png", "MouseTransform" ); // hardcoded shortcut tip of "MouseDragOrTransform"... + toolbar_append_toggle_button( toolbar, "Resize (Q)", "select_mouseresize.png", "MouseDrag" ); // hardcoded shortcut tip of "MouseDragOrTransform"... + toolbar_append_toggle_button( toolbar, "Clipper", "select_clipper.png", "ToggleClipper" ); +// toolbar_append_toggle_button( toolbar, "Build", "select_mouserotate.png", "MouseBuild" ); + toolbar_append_toggle_button( toolbar, "UV Tool", "select_mouseuv.png", "MouseUV" ); } -GtkToolbar* create_main_toolbar( MainFrame::EViewStyle style ){ - GtkToolbar* toolbar = toolbar_new(); - - File_constructToolbar( toolbar ); - toolbar_append_space( toolbar ); +void create_main_toolbar( QToolBar *toolbar, MainFrame::EViewStyle style ){ + File_constructToolbar( toolbar ); + toolbar->addSeparator(); UndoRedo_constructToolbar( toolbar ); - toolbar_append_space( toolbar ); + toolbar->addSeparator(); RotateFlip_constructToolbar( toolbar ); - toolbar_append_space( toolbar ); + toolbar->addSeparator(); Select_constructToolbar( toolbar ); - toolbar_append_space( toolbar ); + toolbar->addSeparator(); CSG_constructToolbar( toolbar ); - toolbar_append_space( toolbar ); + toolbar->addSeparator(); ComponentModes_constructToolbar( toolbar ); - toolbar_append_space( toolbar ); + toolbar->addSeparator(); if ( style != MainFrame::eSplit ) { XYWnd_constructToolbar( toolbar ); - toolbar_append_space( toolbar ); + toolbar->addSeparator(); } CamWnd_constructToolbar( toolbar ); - toolbar_append_space( toolbar ); + toolbar->addSeparator(); Manipulators_constructToolbar( toolbar ); - toolbar_append_space( toolbar ); + toolbar->addSeparator(); - if ( g_Layout_enablePatchToolbar.m_value ) { + if ( !string_empty( g_pGameDescription->getKeyValue( "no_patch" ) ) ) { Patch_constructToolbar( toolbar ); - toolbar_append_space( toolbar ); + toolbar->addSeparator(); } - toolbar_append_toggle_button( toolbar, "Texture Lock (SHIFT + T)", "texture_lock.png", "TogTexLock" ); + toolbar_append_toggle_button( toolbar, "Texture Lock", "texture_lock.png", "TogTexLock" ); toolbar_append_toggle_button( toolbar, "Texture Vertex Lock", "texture_vertexlock.png", "TogTexVertexLock" ); - toolbar_append_space( toolbar ); + toolbar->addSeparator(); - toolbar_append_button( toolbar, "Entities (N)", "entities.png", "ToggleEntityInspector" ); + toolbar_append_button( toolbar, "Entities", "entities.png", "ToggleEntityInspector" ); // disable the console and texture button in the regular layouts if ( style != MainFrame::eRegular && style != MainFrame::eRegularLeft ) { - toolbar_append_button( toolbar, "Console (O)", "console.png", "ToggleConsole" ); - toolbar_append_button( toolbar, "Texture Browser (T)", "texture_browser.png", "ToggleTextures" ); + toolbar_append_button( toolbar, "Console", "console.png", "ToggleConsole" ); + toolbar_append_button( toolbar, "Texture Browser", "texture_browser.png", "ToggleTextures" ); } // TODO: call light inspector - //GtkToolButton* g_view_lightinspector_button = toolbar_append_button(toolbar, "Light Inspector", "lightinspector.png", "ToggleLightInspector"); + //QAction* g_view_lightinspector_button = toolbar_append_button(toolbar, "Light Inspector", "lightinspector.png", "ToggleLightInspector"); - toolbar_append_space( toolbar ); + toolbar->addSeparator(); toolbar_append_button( toolbar, "Refresh Models", "refresh_models.png", "RefreshReferences" ); - - return toolbar; } -GtkLabel* create_main_statusbar_label(){ - 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 ) ); - return label; -} - -GtkWidget* create_main_statusbar( GtkWidget *pStatusLabel[c_status__count] ){ - GtkTable* table = GTK_TABLE( gtk_table_new( 1, c_status__count, FALSE ) ); - gtk_widget_show( GTK_WIDGET( table ) ); +void create_main_statusbar( QStatusBar *statusbar, QLabel *pStatusLabel[c_status__count] ){ + statusbar->setSizeGripEnabled( false ); { - GtkLabel* label = create_main_statusbar_label(); - gtk_label_set_ellipsize( label, PANGO_ELLIPSIZE_END ); - gtk_table_attach_defaults( table, GTK_WIDGET( label ), 0, 1, 0, 1 ); - pStatusLabel[c_status_command] = GTK_WIDGET( label ); + QLabel *label = new QLabel; + statusbar->addPermanentWidget( label, 1 ); + pStatusLabel[c_status_command] = label; } for ( int i = 1; i < c_status__count; ++i ) { - GtkFrame* frame = GTK_FRAME( gtk_frame_new( 0 ) ); - gtk_widget_show( GTK_WIDGET( frame ) ); - gtk_frame_set_shadow_type( frame, GTK_SHADOW_IN ); - if( i == c_status_grid || i == c_status_brushcount ) - gtk_table_attach( table, GTK_WIDGET( frame ), i, i + 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0 ); - else - gtk_table_attach_defaults( table, GTK_WIDGET( frame ), i, i + 1, 0, 1 ); - if( i == c_status_brushcount ){ - GtkWidget* hbox = gtk_hbox_new( FALSE, 0 ); - gtk_container_add( GTK_CONTAINER( frame ), hbox ); - gtk_widget_show( hbox ); - + QWidget *widget = new QWidget; + QHBoxLayout *hbox = new QHBoxLayout( widget ); + hbox->setMargin( 0 ); + statusbar->addPermanentWidget( widget, 0 ); const char* imgs[3] = { "status_brush.png", "patch_wireframe.png", "status_entiy.png" }; for( ; i < c_status_brushcount + 3; ++i ){ - GtkImage* image = new_local_image( imgs[i - c_status_brushcount] ); - gtk_widget_show( GTK_WIDGET( image ) ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( image ), FALSE, FALSE, 0 ); + QLabel *label = new QLabel(); + label->setPixmap( new_local_image( imgs[i - c_status_brushcount] ) ); + hbox->addWidget( label ); - GtkLabel* label = create_main_statusbar_label(); - gtk_label_set_width_chars( label, 5 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( label ), FALSE, TRUE, 0 ); - pStatusLabel[i] = GTK_WIDGET( label ); + label = new QLabel(); + label->setMinimumWidth( label->fontMetrics().horizontalAdvance( "99999" ) ); + hbox->addWidget( label ); + pStatusLabel[i] = label; } --i; } else{ - GtkLabel* label = create_main_statusbar_label(); - if( i == c_status_grid ) - gtk_widget_set_tooltip_markup( GTK_WIDGET( frame ), " G: Grid size\n F: map Format\n C: camera Clip distance \n L: texture Lock" ); + QLabel *label = new QLabel; + if( i == c_status_grid ){ + statusbar->addPermanentWidget( label, 0 ); + label->setToolTip( " G: Grid size
F: map Format
C: camera Clip distance
L: texture Lock" ); + } else - gtk_label_set_ellipsize( label, i == c_status_texture? PANGO_ELLIPSIZE_START : PANGO_ELLIPSIZE_END ); - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( label ) ); - pStatusLabel[i] = GTK_WIDGET( label ); + statusbar->addPermanentWidget( label, 1 ); + pStatusLabel[i] = label; } } - - return GTK_WIDGET( table ); } -#if 0 - - -WidgetFocusPrinter g_mainframeWidgetFocusPrinter( "mainframe" ); - -class WindowFocusPrinter -{ - 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; - } -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 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_get_visible( GTK_WIDGET( g_wait.m_window ) ) ) { - gtk_widget_show( GTK_WIDGET( g_wait.m_window ) ); - } - - return FALSE; - } -public: - void connect( GtkWindow* toplevel_window ){ - g_signal_connect( G_OBJECT( toplevel_window ), "notify::is-active", G_CALLBACK( notify ), this ); - } -}; - -MainWindowActive g_MainWindowActive; - SignalHandlerId XYWindowDestroyed_connect( const SignalHandler& handler ){ return g_pParentWnd->GetXYWnd()->onDestroyed.connectFirst( handler ); } @@ -2819,42 +1488,20 @@ void XYWindowMouseDown_disconnect( MouseEventHandlerId id ){ MainFrame* g_pParentWnd = 0; -GtkWindow* MainFrame_getWindow(){ - if ( g_pParentWnd == 0 ) { - return 0; - } - return g_pParentWnd->m_window; +QWidget* MainFrame_getWindow(){ + return g_pParentWnd == 0? 0 : g_pParentWnd->m_window; } -std::vector g_floating_windows; - -MainFrame::MainFrame() : m_window( 0 ), m_idleRedrawStatusText( RedrawStatusTextCaller( *this ) ){ - m_pXYWnd = 0; - m_pCamWnd = 0; - m_pZWnd = 0; - m_pYZWnd = 0; - m_pXZWnd = 0; - m_pActiveXY = 0; - - for ( int n = 0; n < c_status__count; ++n ) - m_statusLabel[n] = 0; - +MainFrame::MainFrame() : m_idleRedrawStatusText( RedrawStatusTextCaller( *this ) ){ Create(); } MainFrame::~MainFrame(){ - SaveWindowInfo(); - - gtk_widget_hide( GTK_WIDGET( m_window ) ); + SaveGuiState(); Shutdown(); - for ( std::vector::iterator i = g_floating_windows.begin(); i != g_floating_windows.end(); ++i ) - { - gtk_widget_destroy( *i ); - } - - gtk_widget_destroy( GTK_WIDGET( m_window ) ); + delete m_window; } void MainFrame::SetActiveXY( XYWnd* p ){ @@ -2870,88 +1517,59 @@ void MainFrame::SetActiveXY( XYWnd* p ){ } - +#ifdef WIN32 +#include +#endif void MainFrame_toggleFullscreen(){ - GtkWindow* wnd = MainFrame_getWindow(); - if( gdk_window_get_state( gtk_widget_get_window( GTK_WIDGET( wnd ) ) ) & GDK_WINDOW_STATE_FULLSCREEN ){ - //some portion of buttsex, because gtk_window_unfullscreen doesn't work correctly after calling some modal window - bool maximized = ( gdk_window_get_state( gtk_widget_get_window( GTK_WIDGET( wnd ) ) ) & GDK_WINDOW_STATE_MAXIMIZED ); - gtk_window_unfullscreen( wnd ); - if( maximized ){ - gtk_window_unmaximize( wnd ); - gtk_window_maximize( wnd ); - } - else{ - gtk_window_move( wnd, g_layout_globals.m_position.x, g_layout_globals.m_position.y ); - gtk_window_resize( wnd, g_layout_globals.m_position.w, g_layout_globals.m_position.h ); - } - } - else{ - gtk_window_fullscreen( wnd ); - } + QWidget *w = MainFrame_getWindow(); +#ifdef WIN32 // https://doc.qt.io/qt-5.15/windows-issues.html#fullscreen-opengl-based-windows + QWindowsWindowFunctions::setHasBorderInFullScreen( w->windowHandle(), true ); +#endif + w->setWindowState( w->windowState() ^ Qt::WindowState::WindowFullScreen ); } class MaximizeView { -public: - MaximizeView(): m_maximized( false ){ - } - void toggle(){ - return m_maximized ? restore() : maximize(); - } - bool isMaximized(){ - return m_maximized; - } -private: - bool m_maximized; - int m_vSplitPos; - int m_vSplit2Pos; - int m_hSplitPos; - - void restore(){ - m_maximized = false; - gtk_paned_set_position( GTK_PANED( g_pParentWnd->m_vSplit ), m_vSplitPos ); - gtk_paned_set_position( GTK_PANED( g_pParentWnd->m_vSplit2 ), m_vSplit2Pos ); - gtk_paned_set_position( GTK_PANED( g_pParentWnd->m_hSplit ), m_hSplitPos ); - } + bool m_maximized{}; + QList m_vSplitSizes; + QList m_vSplit2Sizes; + QList m_hSplitSizes; void maximize(){ m_maximized = true; - m_vSplitPos = gtk_paned_get_position( GTK_PANED( g_pParentWnd->m_vSplit ) ); - m_vSplit2Pos = gtk_paned_get_position( GTK_PANED( g_pParentWnd->m_vSplit2 ) ); - m_hSplitPos = gtk_paned_get_position( GTK_PANED( g_pParentWnd->m_hSplit ) ); + m_vSplitSizes = g_pParentWnd->m_vSplit->sizes(); + m_vSplit2Sizes = g_pParentWnd->m_vSplit2->sizes(); + m_hSplitSizes = g_pParentWnd->m_hSplit->sizes(); - int vSplitX, vSplitY, vSplit2X, vSplit2Y, hSplitX, hSplitY; - gdk_window_get_origin( gtk_widget_get_window( g_pParentWnd->m_vSplit ), &vSplitX, &vSplitY ); - gdk_window_get_origin( gtk_widget_get_window( g_pParentWnd->m_vSplit2 ), &vSplit2X, &vSplit2Y ); - gdk_window_get_origin( gtk_widget_get_window( g_pParentWnd->m_hSplit ), &hSplitX, &hSplitY ); + const QPoint cursor = g_pParentWnd->m_hSplit->mapFromGlobal( QCursor::pos() ); - vSplitY += m_vSplitPos; - vSplit2Y += m_vSplit2Pos; - hSplitX += m_hSplitPos; + if( cursor.y() < m_vSplitSizes[0] ) + g_pParentWnd->m_vSplit->setSizes( { 9999, 0 } ); + else + g_pParentWnd->m_vSplit->setSizes( { 0, 9999 } ); - int cur_x, cur_y; - Sys_GetCursorPos( MainFrame_getWindow(), &cur_x, &cur_y ); + if( cursor.y() < m_vSplit2Sizes[0] ) + g_pParentWnd->m_vSplit2->setSizes( { 9999, 0 } ); + else + g_pParentWnd->m_vSplit2->setSizes( { 0, 9999 } ); - if( cur_x > hSplitX ){ - gtk_paned_set_position( GTK_PANED( g_pParentWnd->m_hSplit ), 0 ); - } - else{ - gtk_paned_set_position( GTK_PANED( g_pParentWnd->m_hSplit ), 9999 ); - } - if( cur_y > vSplitY ){ - gtk_paned_set_position( GTK_PANED( g_pParentWnd->m_vSplit ), 0 ); - } - else{ - gtk_paned_set_position( GTK_PANED( g_pParentWnd->m_vSplit ), 9999 ); - } - if( cur_y > vSplit2Y ){ - gtk_paned_set_position( GTK_PANED( g_pParentWnd->m_vSplit2 ), 0 ); - } - else{ - gtk_paned_set_position( GTK_PANED( g_pParentWnd->m_vSplit2 ), 9999 ); + if( cursor.x() < m_hSplitSizes[0] ) + g_pParentWnd->m_hSplit->setSizes( { 9999, 0 } ); + else + g_pParentWnd->m_hSplit->setSizes( { 0, 9999 } ); + } +public: + void unmaximize(){ + if( m_maximized ){ + m_maximized = false; + g_pParentWnd->m_vSplit->setSizes( m_vSplitSizes ); + g_pParentWnd->m_vSplit2->setSizes( m_vSplit2Sizes ); + g_pParentWnd->m_hSplit->setSizes( m_hSplitSizes ); } } + void toggle(){ + return m_maximized ? unmaximize() : maximize(); + } }; MaximizeView g_maximizeview; @@ -2963,33 +1581,29 @@ void Maximize_View(){ -GtkWindow* 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 ); - - GtkImage* image = new_local_image( "splash.png" ); - gtk_widget_show( GTK_WIDGET( image ) ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( image ) ); - - if( gtk_image_get_storage_type( image ) == GTK_IMAGE_PIXBUF ){ - GdkBitmap* mask; - GdkPixbuf* pix = gtk_image_get_pixbuf( image ); - gdk_pixbuf_render_pixmap_and_mask( pix, NULL, &mask, 255 ); - gtk_widget_shape_combine_mask ( GTK_WIDGET( window ), mask, 0, 0 ); +class RadiantQMainWindow : public QMainWindow +{ +protected: + void closeEvent( QCloseEvent *event ) override { + event->ignore(); + Exit(); } + bool event( QEvent *event ) override { + if( event->type() == QEvent::ShortcutOverride && !QGuiApplication::mouseButtons().testFlag( Qt::MouseButton::NoButton ) ){ + event->accept(); // block shortcuts while mouse buttons are pressed + } + return QMainWindow::event( event ); + } +}; - gtk_widget_set_size_request( GTK_WIDGET( window ), -1, -1 ); - gtk_widget_show( GTK_WIDGET( window ) ); - return window; +QSplashScreen *create_splash(){ + QSplashScreen *splash = new QSplashScreen( new_local_image( "splash.png" ) ); + splash->show(); + return splash; } -static GtkWindow *splash_screen = 0; +static QSplashScreen *splash_screen = 0; void show_splash(){ splash_screen = create_splash(); @@ -2998,31 +1612,8 @@ void show_splash(){ } void hide_splash(){ - gtk_widget_destroy( GTK_WIDGET( splash_screen ) ); -} - -WindowPositionTracker g_posCamWnd; -WindowPositionTracker g_posXYWnd; -WindowPositionTracker g_posXZWnd; -WindowPositionTracker g_posYZWnd; - -static gint mainframe_delete( GtkWidget *widget, GdkEvent *event, gpointer data ){ - if ( ConfirmModified( "Exit Radiant" ) ) { - gtk_main_quit(); - } - - return TRUE; -} - -gboolean toolbar_redirect_scroll( GtkWidget* widget, GdkEventScroll* event, gpointer user_data ){ - //globalOutputStream() << "scroll\n"; - if ( event->direction == GDK_SCROLL_UP ) { - event->direction = GDK_SCROLL_RIGHT; - } - else if ( event->direction == GDK_SCROLL_DOWN ) { - event->direction = GDK_SCROLL_LEFT; - } - return FALSE; +//. splash_screen->finish(); + delete splash_screen; } @@ -3041,404 +1632,241 @@ void user_shortcuts_save(){ void MainFrame::Create(){ - GtkWindow* window = GTK_WINDOW( gtk_window_new( GTK_WINDOW_TOPLEVEL ) ); + QMainWindow *window = m_window = new RadiantQMainWindow(); GlobalWindowObservers_connectTopLevel( window ); - gtk_window_set_transient_for( splash_screen, window ); + QApplication::setWindowIcon( new_local_icon( "radiant.ico" ) ); -#if !defined( WIN32 ) - { - GdkPixbuf* pixbuf = pixbuf_new_from_file_with_mask( "bitmaps/icon.png" ); - if ( pixbuf != 0 ) { - gtk_window_set_default_icon( 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 ); - - m_position_tracker.connect( window ); - -#if 0 - g_mainframeWidgetFocusPrinter.connect( window ); - g_mainframeFocusPrinter.connect( window ); -#endif - - g_MainWindowActive.connect( window ); /* GlobalCommands_insert plugins commands */ - GetPlugInMgr().Init( GTK_WIDGET( window ) ); + GetPlugInMgr().Init( window ); /* then load shortcuts cfg */ user_shortcuts_init(); - GtkWidget* vbox = gtk_vbox_new( FALSE, 0 ); - gtk_container_add( GTK_CONTAINER( window ), vbox ); - gtk_widget_show( vbox ); - gtk_container_set_focus_chain( GTK_CONTAINER( vbox ), NULL ); - - global_accel_connect_window( window ); + GlobalPressedKeys_connect( window ); + GlobalShortcuts_setWidget( window ); + register_shortcuts(); m_nCurrentStyle = (EViewStyle)g_Layout_viewStyle.m_value; - register_shortcuts(); + create_main_menu( window->menuBar(), CurrentStyle() ); - GtkMenuBar* main_menu = create_main_menu( CurrentStyle() ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( main_menu ), FALSE, FALSE, 0 ); - - if( g_Layout_SingleToolbar.m_value ){ - if( g_Layout_enableMainToolbar.m_value || g_Layout_enablePluginToolbar.m_value || g_Layout_enableFilterToolbar.m_value ){ - GtkWidget* scr_win = gtk_scrolled_window_new( NULL, NULL ); - gtk_container_set_border_width( GTK_CONTAINER( scr_win ), 0 ); - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr_win ), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER ); - - GtkWidget* scrollbar = gtk_scrolled_window_get_hscrollbar( GTK_SCROLLED_WINDOW( scr_win ) ); - gtk_widget_set_size_request( scrollbar, 0, 0 ); - //gtk_widget_set_child_visible( scrollbar, FALSE ); - //gtk_container_set_border_width( GTK_CONTAINER( scrollbar ), 0 ); - - gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr_win ), GTK_SHADOW_NONE ); - gtk_box_pack_start( GTK_BOX( vbox ), scr_win, FALSE, FALSE, 0 ); - gtk_widget_show( scr_win ); - g_signal_connect( G_OBJECT( scr_win ), "scroll_event", G_CALLBACK( toolbar_redirect_scroll ), 0 ); - - GtkWidget* hbox = gtk_hbox_new( FALSE, 3 ); - gtk_widget_show( hbox ); - gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scr_win ), hbox ); - - if( g_Layout_enableMainToolbar.m_value ){ - GtkToolbar* main_toolbar = create_main_toolbar( CurrentStyle() ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( main_toolbar ), TRUE, TRUE, 0 ); - } - if ( g_Layout_enableFilterToolbar.m_value ){ - GtkToolbar* filter_toolbar = create_filter_toolbar(); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( filter_toolbar ), TRUE, TRUE, 0 ); - } - if ( g_Layout_enablePluginToolbar.m_value ){ - GtkToolbar* plugin_toolbar = create_plugin_toolbar(); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( plugin_toolbar ), TRUE, TRUE, 0 ); - } + { + { + QToolBar *toolbar = window->addToolBar( "Main Toolbar" ); + toolbar->setObjectName( "Main Toolbar" ); + create_main_toolbar( toolbar, CurrentStyle() ); } - - } - else{ - if( g_Layout_enableMainToolbar.m_value ){ - GtkToolbar* main_toolbar = create_main_toolbar( CurrentStyle() ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( main_toolbar ), FALSE, FALSE, 0 ); + { + QToolBar *toolbar = window->addToolBar( "Filter Toolbar" ); + toolbar->setObjectName( "Filter Toolbar" ); + create_filter_toolbar( toolbar ); } - if ( g_Layout_enablePluginToolbar.m_value || g_Layout_enableFilterToolbar.m_value ){ - GtkWidget* hbox = gtk_hbox_new( FALSE, 3 ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox ), FALSE, FALSE, 0 ); - gtk_widget_show( hbox ); - if ( g_Layout_enablePluginToolbar.m_value ){ - GtkToolbar* plugin_toolbar = create_plugin_toolbar(); - if ( g_Layout_enableFilterToolbar.m_value ){ - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( plugin_toolbar ), FALSE, FALSE, 0 ); - } - else{ - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( plugin_toolbar ), TRUE, TRUE, 0 ); - } - } - if ( g_Layout_enableFilterToolbar.m_value ){ - GtkToolbar* filter_toolbar = create_filter_toolbar(); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( filter_toolbar ), TRUE, TRUE, 0 ); - } + { + QToolBar *toolbar = window->addToolBar( "Plugin Toolbar" ); + toolbar->setObjectName( "Plugin Toolbar" ); + create_plugin_toolbar( toolbar ); } } - /*GtkToolbar* plugin_toolbar = create_plugin_toolbar(); - if ( !g_Layout_enablePluginToolbar.m_value ) { - gtk_widget_hide( GTK_WIDGET( plugin_toolbar ) ); - }*/ - - - - GtkWidget* main_statusbar = create_main_statusbar( m_statusLabel ); - gtk_box_pack_end( GTK_BOX( vbox ), main_statusbar, FALSE, TRUE, 2 ); + create_main_statusbar( window->statusBar(), m_statusLabel ); GroupDialog_constructWindow( window ); - /* want to realize it immediately; otherwise gtk paned splits positions wont be set correctly for floating group dlg */ - gtk_widget_realize ( GTK_WIDGET( GroupDialog_getWindow() ) ); - 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" ) ); - { - GtkFrame* frame = create_framed_widget( TextureBrowser_constructWindow( GroupDialog_getWindow() ) ); - g_page_textures = GroupDialog_addPage( "Textures", GTK_WIDGET( frame ), TextureBrowserExportTitleCaller() ); - /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */ - g_object_set_data( G_OBJECT( g_page_textures ), "glwidget", TextureBrowser_getGLWidget() ); - } + g_page_console = GroupDialog_addPage( "Console", Console_constructWindow(), RawStringExportCaller( "Console" ) ); + g_page_textures = GroupDialog_addPage( "Textures", TextureBrowser_constructWindow( GroupDialog_getWindow() ), TextureBrowserExportTitleCaller() ); } { - GtkFrame* frame = create_framed_widget( ModelBrowser_constructWindow( GroupDialog_getWindow() ) ); - g_page_models = GroupDialog_addPage( "Models", GTK_WIDGET( frame ), RawStringExportCaller( "Models" ) ); - /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */ - g_object_set_data( G_OBJECT( g_page_models ), "glwidget", ModelBrowser_getGLWidget() ); + g_page_models = GroupDialog_addPage( "Models", ModelBrowser_constructWindow( GroupDialog_getWindow() ), RawStringExportCaller( "Models" ) ); } -#ifdef WIN32 - if ( g_multimon_globals.m_bStartOnPrimMon ) { - PositionWindowOnPrimaryScreen( g_layout_globals.m_position ); - } -#endif - window_set_position( window, g_layout_globals.m_position ); - - m_window = window; - - gtk_widget_show( GTK_WIDGET( window ) ); + window->show(); if ( CurrentStyle() == eRegular || CurrentStyle() == eRegularLeft ) { - GtkWidget* hsplit = gtk_hpaned_new(); - m_hSplit = hsplit; - gtk_box_pack_start( GTK_BOX( vbox ), hsplit, TRUE, TRUE, 0 ); - gtk_widget_show( hsplit ); + window->setCentralWidget( m_hSplit = new QSplitter() ); { - GtkWidget* vsplit = gtk_vpaned_new(); - gtk_widget_show( vsplit ); - m_vSplit = vsplit; - GtkWidget* vsplit2 = gtk_vpaned_new(); - gtk_widget_show( vsplit2 ); - m_vSplit2 = vsplit2; + m_vSplit = new QSplitter( Qt::Vertical ); + m_vSplit2 = new QSplitter( Qt::Vertical ); if ( CurrentStyle() == eRegular ){ - gtk_paned_pack1( GTK_PANED( hsplit ), vsplit, TRUE, TRUE ); - gtk_paned_pack2( GTK_PANED( hsplit ), vsplit2, TRUE, TRUE ); + m_hSplit->addWidget( m_vSplit ); + m_hSplit->addWidget( m_vSplit2 ); } else{ - gtk_paned_pack2( GTK_PANED( hsplit ), vsplit, TRUE, TRUE ); - gtk_paned_pack1( GTK_PANED( hsplit ), vsplit2, TRUE, TRUE ); + m_hSplit->addWidget( m_vSplit2 ); + m_hSplit->addWidget( m_vSplit ); } // console - GtkWidget* console_window = Console_constructWindow( window ); - gtk_paned_pack2( GTK_PANED( vsplit ), console_window, TRUE, TRUE ); + m_vSplit->addWidget( Console_constructWindow() ); // xy m_pXYWnd = new XYWnd(); m_pXYWnd->SetViewType( XY ); - GtkWidget* xy_window = GTK_WIDGET( create_framed_widget( m_pXYWnd->GetWidget() ) ); - gtk_paned_pack1( GTK_PANED( vsplit ), xy_window, TRUE, TRUE ); + m_vSplit->insertWidget( 0, m_pXYWnd->GetWidget() ); { // 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_pack1( GTK_PANED( vsplit2 ), GTK_WIDGET( camera_window ), TRUE, TRUE ); + m_vSplit2->addWidget( CamWnd_getWidget( *m_pCamWnd ) ); // textures - GtkFrame* texture_window = create_framed_widget( TextureBrowser_constructWindow( window ) ); - - gtk_paned_pack2( GTK_PANED( vsplit2 ), GTK_WIDGET( texture_window ), TRUE, TRUE ); + m_vSplit2->addWidget( TextureBrowser_constructWindow( window ) ); } } } else if ( CurrentStyle() == eFloating ) { { - GtkWindow* window = create_persistent_floating_window( "Camera", m_window ); - global_accel_connect_window( window ); - g_posCamWnd.connect( window ); + QWidget* window = new QWidget( m_window, Qt::Window ); + window->setWindowTitle( "Camera" ); + g_guiSettings.addWindow( window, "floating/cam", 400, 300, 50, 100 ); 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 ) ); + auto box = new QHBoxLayout( window ); + box->setContentsMargins( 1, 1, 1, 1 ); + box->addWidget( CamWnd_getWidget( *m_pCamWnd ) ); } CamWnd_setParent( *m_pCamWnd, window ); + GlobalPressedKeys_connect( window ); + GlobalWindowObservers_connectTopLevel( window ); CamWnd_Shown_Construct( window ); - /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */ - g_object_set_data( G_OBJECT( window ), "glwidget", CamWnd_getWidget( *m_pCamWnd ) ); - - g_floating_windows.push_back( GTK_WIDGET( window ) ); } { - GtkWindow* window = create_persistent_floating_window( ViewType_getTitle( XY ), m_window ); - global_accel_connect_window( window ); - g_posXYWnd.connect( window ); + QWidget* window = new QWidget( m_window, Qt::Window ); + g_guiSettings.addWindow( window, "floating/xy", 400, 300, 500, 100 ); 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 ) ); + auto box = new QHBoxLayout( window ); + box->setContentsMargins( 1, 1, 1, 1 ); + box->addWidget( m_pXYWnd->GetWidget() ); } + GlobalWindowObservers_connectTopLevel( window ); XY_Top_Shown_Construct( window ); - /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */ - g_object_set_data( G_OBJECT( window ), "glwidget", m_pXYWnd->GetWidget() ); - - g_floating_windows.push_back( GTK_WIDGET( window ) ); } { - GtkWindow* window = create_persistent_floating_window( ViewType_getTitle( XZ ), m_window ); - global_accel_connect_window( window ); - g_posXZWnd.connect( window ); + QWidget* window = new QWidget( m_window, Qt::Window ); + g_guiSettings.addWindow( window, "floating/xz", 400, 300, 500, 450 ); 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 box = new QHBoxLayout( window ); + box->setContentsMargins( 1, 1, 1, 1 ); + box->addWidget( m_pXZWnd->GetWidget() ); } + GlobalWindowObservers_connectTopLevel( window ); XZ_Front_Shown_Construct( window ); - /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */ - g_object_set_data( G_OBJECT( window ), "glwidget", m_pXZWnd->GetWidget() ); - - g_floating_windows.push_back( GTK_WIDGET( window ) ); } { - GtkWindow* window = create_persistent_floating_window( ViewType_getTitle( YZ ), m_window ); - global_accel_connect_window( window ); - g_posYZWnd.connect( window ); + QWidget* window = new QWidget( m_window, Qt::Window ); + g_guiSettings.addWindow( window, "floating/yz", 400, 300, 50, 450 ); 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 box = new QHBoxLayout( window ); + box->setContentsMargins( 1, 1, 1, 1 ); + box->addWidget( m_pYZWnd->GetWidget() ); } + GlobalWindowObservers_connectTopLevel( window ); YZ_Side_Shown_Construct( window ); - /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */ - g_object_set_data( G_OBJECT( window ), "glwidget", m_pYZWnd->GetWidget() ); - - g_floating_windows.push_back( GTK_WIDGET( window ) ); } - m_vSplit = 0; - m_hSplit = 0; - m_vSplit2 = 0; - GroupDialog_show(); } else // 4 way { + window->setCentralWidget( m_hSplit = new QSplitter() ); + m_hSplit->addWidget( m_vSplit = new QSplitter( Qt::Vertical ) ); + m_hSplit->addWidget( m_vSplit2 = new QSplitter( Qt::Vertical ) ); + m_pCamWnd = NewCamWnd(); GlobalCamera_setCamWnd( *m_pCamWnd ); CamWnd_setParent( *m_pCamWnd, window ); - GtkWidget* camera = CamWnd_getWidget( *m_pCamWnd ); + m_vSplit->addWidget( CamWnd_getWidget( *m_pCamWnd ) ); m_pYZWnd = new XYWnd(); m_pYZWnd->SetViewType( YZ ); - GtkWidget* yz = m_pYZWnd->GetWidget(); + m_vSplit->addWidget( m_pYZWnd->GetWidget() ); m_pXYWnd = new XYWnd(); m_pXYWnd->SetViewType( XY ); - GtkWidget* xy = m_pXYWnd->GetWidget(); + m_vSplit2->addWidget( m_pXYWnd->GetWidget() ); m_pXZWnd = new XYWnd(); m_pXZWnd->SetViewType( XZ ); - GtkWidget* xz = m_pXZWnd->GetWidget(); - - m_hSplit = create_split_views( camera, yz, xy, xz, m_vSplit, m_vSplit2 ); - gtk_box_pack_start( GTK_BOX( vbox ), m_hSplit, TRUE, TRUE, 0 ); + m_vSplit2->addWidget( m_pXZWnd->GetWidget() ); } EntityList_constructWindow( window ); PreferencesDialog_constructWindow( window ); FindTextureDialog_constructWindow( window ); SurfaceInspector_constructWindow( window ); - PatchInspector_constructWindow( window ); + theme_contruct(); SetActiveXY( m_pXYWnd ); AddGridChangeCallback( SetGridStatusCaller( *this ) ); AddGridChangeCallback( FreeCaller() ); - g_defaultToolMode = DragMode; - g_defaultToolMode(); - SetStatusText( c_status_command, c_TranslateMode_status ); + s_qe_every_second_timer.enable(); - EverySecondTimer_enable(); + RestoreGuiState(); - if ( g_layout_globals.nState & GDK_WINDOW_STATE_MAXIMIZED || - g_layout_globals.nState & GDK_WINDOW_STATE_ICONIFIED ) { - gtk_window_maximize( window ); - } - if ( g_layout_globals.nState & GDK_WINDOW_STATE_FULLSCREEN ) { - gtk_window_fullscreen( window ); - } - - process_gui(); //window is maximized/fullscreened by window manager, which may be not instant - - if ( !FloatingGroupDialog() ) { - 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 ); - } - - gtk_paned_set_position( GTK_PANED( m_vSplit2 ), g_layout_globals.nCamHeight ); - } //GlobalShortcuts_reportUnregistered(); } -void MainFrame::SaveWindowInfo(){ +void MainFrame::SaveGuiState(){ //restore good state first - if( gdk_window_get_state( gtk_widget_get_window( GTK_WIDGET( m_window ) ) ) & GDK_WINDOW_STATE_ICONIFIED ){ - gtk_window_deiconify( m_window ); + g_maximizeview.unmaximize(); + + g_guiSettings.save(); +} + +void MainFrame::RestoreGuiState(){ + g_guiSettings.addWindow( m_window, "MainFrame/geometry", 962, 480 ); + g_guiSettings.addMainWindow( m_window, "MainFrame/state" ); + + if( !FloatingGroupDialog() && m_hSplit != nullptr && m_vSplit != nullptr && m_vSplit2 != nullptr ){ + g_guiSettings.addSplitter( m_hSplit, "MainFrame/m_hSplit", { 384, 576 } ); + g_guiSettings.addSplitter( m_vSplit, "MainFrame/m_vSplit", { 377, 20 } ); + g_guiSettings.addSplitter( m_vSplit2, "MainFrame/m_vSplit2", { 250, 150 } ); } - if( g_maximizeview.isMaximized() ){ - g_maximizeview.toggle(); - } - - 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 ) ); - } - - g_layout_globals.nCamHeight = gtk_paned_get_position( GTK_PANED( m_vSplit2 ) ); - } - - if( gdk_window_get_state( gtk_widget_get_window( GTK_WIDGET( m_window ) ) ) == 0 ){ - g_layout_globals.m_position = m_position_tracker.getPosition(); - } - - g_layout_globals.nState = gdk_window_get_state( gtk_widget_get_window( GTK_WIDGET( m_window ) ) ); } void MainFrame::Shutdown(){ - EverySecondTimer_disable(); + s_qe_every_second_timer.disable(); EntityList_destroyWindow(); - delete m_pXYWnd; - m_pXYWnd = 0; - delete m_pYZWnd; - m_pYZWnd = 0; - delete m_pXZWnd; - m_pXZWnd = 0; + delete std::exchange( m_pXYWnd, nullptr ); + delete std::exchange( m_pYZWnd, nullptr ); + delete std::exchange( m_pXZWnd, nullptr ); ModelBrowser_destroyWindow(); TextureBrowser_destroyWindow(); @@ -3449,7 +1877,6 @@ void MainFrame::Shutdown(){ PreferencesDialog_destroyWindow(); SurfaceInspector_destroyWindow(); FindTextureDialog_destroyWindow(); - PatchInspector_destroyWindow(); g_DbgDlg.destroyWindow(); @@ -3461,7 +1888,7 @@ void MainFrame::Shutdown(){ void MainFrame::RedrawStatusText(){ for( int i = 0; i < c_status__count; ++i ) - gtk_label_set_text( GTK_LABEL( m_statusLabel[i] ), m_status[i].c_str() ); + m_statusLabel[i]->setText( m_status[i].c_str() ); } void MainFrame::UpdateStatusText(){ @@ -3512,16 +1939,19 @@ void GridStatus_changed(){ } } -CopiedString g_strOpenGLFont = ""; +CopiedString g_OpenGLFont( "Myriad Pro" ); +int g_OpenGLFontSize = 8; void OpenGLFont_select(){ CopiedString newfont; - if( OpenGLFont_dialog( GTK_WIDGET( MainFrame_getWindow() ), g_strOpenGLFont.c_str(), newfont ) ){ + int newsize; + if( OpenGLFont_dialog( MainFrame_getWindow(), g_OpenGLFont.c_str(), g_OpenGLFontSize, newfont, newsize ) ){ { ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Changing OpenGL Font" ); delete GlobalOpenGL().m_font; - g_strOpenGLFont = newfont; - GlobalOpenGL().m_font = glfont_create( g_strOpenGLFont.c_str() ); + g_OpenGLFont = newfont; + g_OpenGLFontSize = newsize; + GlobalOpenGL().m_font = glfont_create( g_OpenGLFont.c_str(), g_OpenGLFontSize, g_strAppPath.c_str() ); } UpdateAllWindows(); } @@ -3530,10 +1960,10 @@ void OpenGLFont_select(){ void GlobalGL_sharedContextCreated(){ // report OpenGL information - globalOutputStream() << "GL_VENDOR: " << reinterpret_cast( glGetString( GL_VENDOR ) ) << "\n"; - globalOutputStream() << "GL_RENDERER: " << reinterpret_cast( glGetString( GL_RENDERER ) ) << "\n"; - globalOutputStream() << "GL_VERSION: " << reinterpret_cast( glGetString( GL_VERSION ) ) << "\n"; - globalOutputStream() << "GL_EXTENSIONS: " << reinterpret_cast( glGetString( GL_EXTENSIONS ) ) << "\n"; + globalOutputStream() << "GL_VENDOR: " << reinterpret_cast( gl().glGetString( GL_VENDOR ) ) << "\n"; + globalOutputStream() << "GL_RENDERER: " << reinterpret_cast( gl().glGetString( GL_RENDERER ) ) << "\n"; + globalOutputStream() << "GL_VERSION: " << reinterpret_cast( gl().glGetString( GL_VERSION ) ) << "\n"; + globalOutputStream() << "GL_EXTENSIONS: " << reinterpret_cast( gl().glGetString( GL_EXTENSIONS ) ) << "\n"; QGL_sharedContextCreated( GlobalOpenGL() ); @@ -3542,7 +1972,7 @@ void GlobalGL_sharedContextCreated(){ GlobalShaderCache().realise(); Textures_Realise(); - GlobalOpenGL().m_font = glfont_create( g_strOpenGLFont.c_str() ); + GlobalOpenGL().m_font = glfont_create( g_OpenGLFont.c_str(), g_OpenGLFontSize, g_strAppPath.c_str() ); } void GlobalGL_sharedContextDestroyed(){ @@ -3568,33 +1998,6 @@ void Layout_constructPreferences( PreferencesPage& page ){ LatchedImportCaller( g_Layout_enableDetachableMenus ), BoolExportCaller( g_Layout_enableDetachableMenus.m_latched ) ); - page.appendCheckBox( - "", "Main Toolbar", - LatchedImportCaller( g_Layout_enableMainToolbar ), - BoolExportCaller( g_Layout_enableMainToolbar.m_latched ) - ); - if ( !string_empty( g_pGameDescription->getKeyValue( "no_patch" ) ) ) { - page.appendCheckBox( - "", "Patch Toolbar", - LatchedImportCaller( g_Layout_enablePatchToolbar ), - BoolExportCaller( g_Layout_enablePatchToolbar.m_latched ) - ); - } - page.appendCheckBox( - "", "Plugin Toolbar", - LatchedImportCaller( g_Layout_enablePluginToolbar ), - BoolExportCaller( g_Layout_enablePluginToolbar.m_latched ) - ); - page.appendCheckBox( - "", "Filter Toolbar", - LatchedImportCaller( g_Layout_enableFilterToolbar ), - BoolExportCaller( g_Layout_enableFilterToolbar.m_latched ) - ); - page.appendCheckBox( - "", "Single Scrollable Toolbar", - LatchedImportCaller( g_Layout_SingleToolbar ), - BoolExportCaller( g_Layout_SingleToolbar.m_latched ) - ); } void Layout_constructPage( PreferenceGroup& group ){ @@ -3616,166 +2019,44 @@ void FocusAllViews(){ #include "stringio.h" void MainFrame_Construct(){ - GlobalCommands_insert( "OpenManual", FreeCaller(), Accelerator( GDK_KEY_F1 ) ); + GlobalCommands_insert( "OpenManual", FreeCaller(), QKeySequence( "F1" ) ); - GlobalCommands_insert( "NewMap", FreeCaller() ); - GlobalCommands_insert( "OpenMap", FreeCaller(), Accelerator( 'O', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "ImportMap", FreeCaller() ); - GlobalCommands_insert( "SaveMap", FreeCaller(), Accelerator( 'S', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "SaveMapAs", FreeCaller() ); - GlobalCommands_insert( "SaveSelected", FreeCaller() ); - GlobalCommands_insert( "SaveRegion", FreeCaller() ); GlobalCommands_insert( "RefreshReferences", FreeCaller() ); - GlobalCommands_insert( "ProjectSettings", FreeCaller() ); GlobalCommands_insert( "CheckForUpdate", FreeCaller() ); GlobalCommands_insert( "Exit", FreeCaller() ); - GlobalCommands_insert( "Undo", FreeCaller(), Accelerator( 'Z', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "Redo", FreeCaller(), Accelerator( 'Y', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "Redo2", FreeCaller(), Accelerator( 'Z', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); - GlobalCommands_insert( "Copy", FreeCaller(), Accelerator( 'C', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "Paste", FreeCaller(), Accelerator( 'V', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "PasteToCamera", FreeCaller(), Accelerator( 'V', GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "MoveToCamera", FreeCaller(), Accelerator( 'V', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); - GlobalCommands_insert( "CloneSelection", FreeCaller(), Accelerator( GDK_KEY_space ) ); - GlobalCommands_insert( "CloneSelectionAndMakeUnique", FreeCaller(), Accelerator( GDK_KEY_space, GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "DeleteSelection2", FreeCaller(), Accelerator( GDK_KEY_BackSpace ) ); - GlobalCommands_insert( "DeleteSelection", FreeCaller(), Accelerator( 'Z' ) ); - GlobalCommands_insert( "RepeatTransforms", FreeCaller(), Accelerator( 'R', GDK_CONTROL_MASK ) ); -// GlobalCommands_insert( "ParentSelection", FreeCaller() ); - GlobalCommands_insert( "UnSelectSelection2", FreeCaller(), Accelerator( GDK_KEY_Escape ) ); - GlobalCommands_insert( "UnSelectSelection", FreeCaller(), Accelerator( 'C' ) ); - GlobalCommands_insert( "InvertSelection", FreeCaller(), Accelerator( 'I' ) ); - GlobalCommands_insert( "SelectInside", FreeCaller() ); - GlobalCommands_insert( "SelectTouching", FreeCaller() ); - GlobalCommands_insert( "ExpandSelectionToPrimitives", FreeCaller(), Accelerator( 'E', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "ExpandSelectionToEntities", FreeCaller(), Accelerator( 'E', GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "SelectConnectedEntities", FreeCaller(), Accelerator( 'E', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); - GlobalCommands_insert( "Preferences", FreeCaller(), Accelerator( 'P' ) ); + GlobalCommands_insert( "Preferences", FreeCaller(), QKeySequence( "P" ) ); - GlobalCommands_insert( "ToggleConsole", FreeCaller(), Accelerator( 'O' ) ); - GlobalCommands_insert( "ToggleEntityInspector", FreeCaller(), Accelerator( 'N' ) ); - GlobalCommands_insert( "ToggleModelBrowser", FreeCaller(), Accelerator( '/' ) ); - GlobalCommands_insert( "EntityList", FreeCaller(), Accelerator( 'L' ) ); + GlobalCommands_insert( "ToggleConsole", FreeCaller(), QKeySequence( "O" ) ); + GlobalCommands_insert( "ToggleEntityInspector", FreeCaller(), QKeySequence( "N" ) ); + GlobalCommands_insert( "ToggleModelBrowser", FreeCaller(), QKeySequence( "/" ) ); + GlobalCommands_insert( "EntityList", FreeCaller(), QKeySequence( "L" ) ); -// GlobalCommands_insert( "ShowHidden", FreeCaller(), Accelerator( 'H', GDK_SHIFT_MASK ) ); -// GlobalCommands_insert( "HideSelected", FreeCaller(), Accelerator( 'H' ) ); Select_registerCommands(); - GlobalToggles_insert( "DragVertices", FreeCaller(), ToggleItem::AddCallbackCaller( g_vertexMode_button ), Accelerator( 'V' ) ); - GlobalToggles_insert( "DragEdges", FreeCaller(), ToggleItem::AddCallbackCaller( g_edgeMode_button ), Accelerator( 'E' ) ); - GlobalToggles_insert( "DragFaces", FreeCaller(), ToggleItem::AddCallbackCaller( g_faceMode_button ), Accelerator( 'F' ) ); - - GlobalCommands_insert( "ArbitraryRotation", FreeCaller(), Accelerator( 'R', GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "ArbitraryScale", FreeCaller(), Accelerator( 'S', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); + Tools_registerCommands(); GlobalCommands_insert( "BuildMenuCustomize", FreeCaller() ); - GlobalCommands_insert( "Build_runRecentExecutedBuild", FreeCaller(), Accelerator( GDK_KEY_F5 ) ); + GlobalCommands_insert( "Build_runRecentExecutedBuild", FreeCaller(), QKeySequence( "F5" ) ); - GlobalCommands_insert( "FindBrush", FreeCaller() ); - - GlobalCommands_insert( "MapInfo", FreeCaller(), Accelerator( 'M' ) ); - - - GlobalToggles_insert( "ToggleClipper", FreeCaller(), ToggleItem::AddCallbackCaller( g_clipper_button ), Accelerator( 'X' ) ); - - GlobalToggles_insert( "MouseTranslate", FreeCaller(), ToggleItem::AddCallbackCaller( g_translatemode_button ), Accelerator( 'W' ) ); - GlobalToggles_insert( "MouseRotate", FreeCaller(), ToggleItem::AddCallbackCaller( g_rotatemode_button ), Accelerator( 'R' ) ); - GlobalToggles_insert( "MouseScale", FreeCaller(), ToggleItem::AddCallbackCaller( g_scalemode_button ) ); - GlobalToggles_insert( "MouseTransform", FreeCaller(), ToggleItem::AddCallbackCaller( g_skewmode_button ) ); - GlobalToggles_insert( "MouseDrag", FreeCaller(), ToggleItem::AddCallbackCaller( g_dragmode_button ) ); - GlobalToggles_insert( "MouseBuild", FreeCaller(), ToggleItem::AddCallbackCaller( g_build_button ), Accelerator( 'B' ) ); - GlobalToggles_insert( "MouseUV", FreeCaller(), ToggleItem::AddCallbackCaller( g_uv_button ), Accelerator( Accelerator( 'G' ) ) ); - GlobalCommands_insert( "MouseRotateOrScale", FreeCaller() ); - GlobalCommands_insert( "MouseDragOrTransform", FreeCaller(), Accelerator( 'Q' ) ); - - GlobalCommands_insert( "gtkThemeDlg", FreeCaller() ); GlobalCommands_insert( "OpenGLFont", FreeCaller() ); - GlobalCommands_insert( "ColorSchemeOriginal", FreeCaller() ); - GlobalCommands_insert( "ColorSchemeQER", FreeCaller() ); - GlobalCommands_insert( "ColorSchemeBlackAndGreen", FreeCaller() ); - GlobalCommands_insert( "ColorSchemeYdnar", FreeCaller() ); - GlobalCommands_insert( "ColorSchemeBlender", FreeCaller() ); - GlobalCommands_insert( "ColorSchemeAdwaitaDark", FreeCaller() ); - 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( "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( "Fullscreen", FreeCaller(), Accelerator( GDK_KEY_F11 ) ); - GlobalCommands_insert( "MaximizeView", FreeCaller(), Accelerator( GDK_KEY_F12 ) ); + Colors_registerCommands(); + GlobalCommands_insert( "Fullscreen", FreeCaller(), QKeySequence( "F11" ) ); + GlobalCommands_insert( "MaximizeView", FreeCaller(), QKeySequence( "F12" ) ); - GlobalCommands_insert( "CSGSubtract", FreeCaller(), Accelerator( 'U', GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "CSGMerge", FreeCaller() ); - GlobalCommands_insert( "CSGWrapMerge", FreeCaller(), Accelerator( 'U', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "CSGroom", FreeCaller() ); - GlobalCommands_insert( "CSGTool", FreeCaller() ); + CSG_registerCommands(); Grid_registerCommands(); - GlobalCommands_insert( "SnapToGrid", FreeCaller(), Accelerator( 'G', GDK_CONTROL_MASK ) ); - - GlobalCommands_insert( "SelectAllOfType", FreeCaller(), Accelerator( 'A', GDK_SHIFT_MASK ) ); - - GlobalCommands_insert( "TexRotateClock", FreeCaller(), Accelerator( GDK_KEY_Next, GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "TexRotateCounter", FreeCaller(), Accelerator( GDK_KEY_Prior, GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "TexScaleUp", FreeCaller(), Accelerator( GDK_KEY_Up, GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "TexScaleDown", FreeCaller(), Accelerator( GDK_KEY_Down, GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "TexScaleLeft", FreeCaller(), Accelerator( GDK_KEY_Left, GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "TexScaleRight", FreeCaller(), Accelerator( GDK_KEY_Right, GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "TexShiftUp", FreeCaller(), Accelerator( GDK_KEY_Up, GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "TexShiftDown", FreeCaller(), Accelerator( GDK_KEY_Down, GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "TexShiftLeft", FreeCaller(), Accelerator( GDK_KEY_Left, GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "TexShiftRight", FreeCaller(), Accelerator( GDK_KEY_Right, GDK_SHIFT_MASK ) ); - - GlobalCommands_insert( "MoveSelectionDOWN", FreeCaller(), Accelerator( GDK_KEY_KP_Subtract ) ); - GlobalCommands_insert( "MoveSelectionUP", FreeCaller(), Accelerator( GDK_KEY_KP_Add ) ); - - GlobalCommands_insert( "SelectNudgeLeft", FreeCaller(), Accelerator( GDK_KEY_Left, GDK_MOD1_MASK ) ); - GlobalCommands_insert( "SelectNudgeRight", FreeCaller(), Accelerator( GDK_KEY_Right, GDK_MOD1_MASK ) ); - GlobalCommands_insert( "SelectNudgeUp", FreeCaller(), Accelerator( GDK_KEY_Up, GDK_MOD1_MASK ) ); - GlobalCommands_insert( "SelectNudgeDown", FreeCaller(), Accelerator( GDK_KEY_Down, GDK_MOD1_MASK ) ); - Patch_registerCommands(); XYShow_registerCommands(); - typedef FreeCaller1 ComponentModeSelectionChangedCaller; - GlobalSelectionSystem().addSelectionChangeCallback( ComponentModeSelectionChangedCaller() ); - GlobalPreferenceSystem().registerPreference( "DetachableMenus", makeBoolStringImportCallback( LatchedAssignCaller( g_Layout_enableDetachableMenus ) ), BoolExportStringCaller( g_Layout_enableDetachableMenus.m_latched ) ); - GlobalPreferenceSystem().registerPreference( "MainToolBar", makeBoolStringImportCallback( LatchedAssignCaller( g_Layout_enableMainToolbar ) ), BoolExportStringCaller( g_Layout_enableMainToolbar.m_latched ) ); - GlobalPreferenceSystem().registerPreference( "PatchToolBar", makeBoolStringImportCallback( LatchedAssignCaller( g_Layout_enablePatchToolbar ) ), BoolExportStringCaller( g_Layout_enablePatchToolbar.m_latched ) ); - GlobalPreferenceSystem().registerPreference( "PluginToolBar", makeBoolStringImportCallback( LatchedAssignCaller( g_Layout_enablePluginToolbar ) ), BoolExportStringCaller( g_Layout_enablePluginToolbar.m_latched ) ); - GlobalPreferenceSystem().registerPreference( "FilterToolBar", makeBoolStringImportCallback( LatchedAssignCaller( g_Layout_enableFilterToolbar ) ), BoolExportStringCaller( g_Layout_enableFilterToolbar.m_latched ) ); - GlobalPreferenceSystem().registerPreference( "SingleToolBar", makeBoolStringImportCallback( LatchedAssignCaller( g_Layout_SingleToolbar ) ), BoolExportStringCaller( g_Layout_SingleToolbar.m_latched ) ); GlobalPreferenceSystem().registerPreference( "QE4StyleWindows", makeIntStringImportCallback( LatchedAssignCaller( g_Layout_viewStyle ) ), 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 ) ); - - GlobalPreferenceSystem().registerPreference( "NudgeAfterClone", BoolImportStringCaller( g_bNudgeAfterClone ), BoolExportStringCaller( g_bNudgeAfterClone ) ); - GlobalPreferenceSystem().registerPreference( "OpenGLFont", CopiedStringImportStringCaller( g_strOpenGLFont ), CopiedStringExportStringCaller( g_strOpenGLFont ) ); + GlobalPreferenceSystem().registerPreference( "OpenGLFont", CopiedStringImportStringCaller( g_OpenGLFont ), CopiedStringExportStringCaller( g_OpenGLFont ) ); + GlobalPreferenceSystem().registerPreference( "OpenGLFontSize", IntImportStringCaller( g_OpenGLFontSize ), IntExportStringCaller( g_OpenGLFontSize ) ); GlobalPreferenceSystem().registerPreference( "ExtraResoucePath", CopiedStringImportStringCaller( g_strExtraResourcePath ), CopiedStringExportStringCaller( g_strExtraResourcePath ) ); GlobalPreferenceSystem().registerPreference( "EnginePath", CopiedStringImportStringCaller( g_strEnginePath ), CopiedStringExportStringCaller( g_strEnginePath ) ); @@ -3799,7 +2080,6 @@ void MainFrame_Construct(){ Layout_registerPreferencesPage(); Paths_registerPreferencesPage(); - PreferencesDialog_addSettingsPreferences( FreeCaller1() ); g_brushCount.setCountChangedCallback( FreeCaller() ); g_patchCount.setCountChangedCallback( FreeCaller() ); diff --git a/radiant/mainframe.h b/radiant/mainframe.h index dd46ba58..208cc4cc 100644 --- a/radiant/mainframe.h +++ b/radiant/mainframe.h @@ -21,22 +21,20 @@ #pragma once -#include "gtkutil/window.h" #include "gtkutil/idledraw.h" #include "gtkutil/widget.h" #include "string/string.h" #include "qerplugin.h" -class IPlugIn; -class IToolbarButton; - class XYWnd; class CamWnd; class ZWnd; -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkWindow GtkWindow; +class QMainWindow; +class QSplitter; +class QLabel; +class QWidget; const int c_status_command = 0; const int c_status_position = 1; @@ -61,34 +59,34 @@ public: MainFrame(); ~MainFrame(); - GtkWindow* m_window; + QMainWindow* m_window{}; private: void Create(); - void SaveWindowInfo(); + void SaveGuiState(); + void RestoreGuiState(); void Shutdown(); public: - GtkWidget* m_vSplit; - GtkWidget* m_hSplit; - GtkWidget* m_vSplit2; + QSplitter* m_vSplit{}; + QSplitter* m_hSplit{}; + QSplitter* m_vSplit2{}; private: - XYWnd* m_pXYWnd; - XYWnd* m_pYZWnd; - XYWnd* m_pXZWnd; - CamWnd* m_pCamWnd; - ZWnd* m_pZWnd; - XYWnd* m_pActiveXY; + XYWnd* m_pXYWnd{}; + XYWnd* m_pYZWnd{}; + XYWnd* m_pXZWnd{}; + CamWnd* m_pCamWnd{}; + ZWnd* m_pZWnd{}; + XYWnd* m_pActiveXY{}; CopiedString m_status[c_status__count]; - GtkWidget *m_statusLabel[c_status__count]; + QLabel *m_statusLabel[c_status__count]{}; EViewStyle m_nCurrentStyle; - WindowPositionTracker m_position_tracker; IdleDraw m_idleRedrawStatusText; @@ -139,7 +137,7 @@ public: extern MainFrame* g_pParentWnd; -GtkWindow* MainFrame_getWindow(); +QWidget* MainFrame_getWindow(); template @@ -147,8 +145,6 @@ class LatchedValue; typedef LatchedValue LatchedBool; extern LatchedBool g_Layout_enableDetachableMenus; -void deleteSelection(); - void Sys_Status( const char* status ); @@ -208,8 +204,6 @@ void Radiant_Shutdown(); void Radiant_Restart(); -void SaveMapAs(); - void XY_UpdateAllWindows(); void UpdateAllWindows(); @@ -255,6 +249,6 @@ void XYWindowDestroyed_disconnect( SignalHandlerId id ); MouseEventHandlerId XYWindowMouseDown_connect( const MouseEventHandler& handler ); void XYWindowMouseDown_disconnect( MouseEventHandlerId id ); -extern GtkWidget* g_page_entity; +extern QWidget* g_page_entity; void FocusAllViews(); diff --git a/radiant/map.cpp b/radiant/map.cpp index 5884b29e..24b48852 100644 --- a/radiant/map.cpp +++ b/radiant/map.cpp @@ -40,8 +40,6 @@ #include -#include - #include "scenelib.h" #include "transformlib.h" #include "selectionlib.h" @@ -864,190 +862,54 @@ void Scene_CountStuff( int& ents_ingame, int& groupents, int& groupents_ingame ) GlobalSceneGraph().traverse( CountStuffWalker( ents_ingame, groupents, groupents_ingame ) ); } -WindowPosition g_posMapInfoWnd( -1, -1, c_default_window_pos.w, c_default_window_pos.h ); +#include +#include +#include +#include +#include void DoMapInfo(){ - ModalDialog dialog; + QDialog dialog( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Map Info" ); - GtkWidget* w_brushes; - GtkWidget* w_patches; - GtkWidget* w_ents; - GtkWidget* w_ents_ingame; - GtkWidget* w_groupents; - GtkWidget* w_groupents_ingame; + auto w_brushes = new QLabel; + auto w_patches = new QLabel; + auto w_ents = new QLabel; + auto w_ents_ingame = new QLabel; + auto w_groupents = new QLabel; + auto w_groupents_ingame = new QLabel; - GtkListStore* EntityBreakdownWalker; - - GtkWindow* window = create_dialog_window( MainFrame_getWindow(), "Map Info", G_CALLBACK( dialog_delete_callback ), &dialog ); - - window_set_position( window, g_posMapInfoWnd ); + auto tree = new QTreeWidget; + tree->setColumnCount( 2 ); + tree->setSortingEnabled( true ); + tree->sortByColumn( 0, Qt::SortOrder::AscendingOrder ); + tree->setUniformRowHeights( true ); // optimization + tree->setHorizontalScrollBarPolicy( Qt::ScrollBarPolicy::ScrollBarAlwaysOff ); + tree->setSizeAdjustPolicy( QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents ); // scroll area will inherit column size + tree->header()->setStretchLastSection( false ); // non greedy column sizing + tree->header()->setSectionResizeMode( QHeaderView::ResizeMode::ResizeToContents ); // no text elision + tree->setRootIsDecorated( false ); + tree->setHeaderLabels( { "Entity", "Count" } ); { - GtkVBox* vbox = create_dialog_vbox( 4, 4 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox ) ); + auto grid = new QGridLayout( &dialog ); - { - GtkHBox* hbox = create_dialog_hbox( 4 ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox ), FALSE, FALSE, 0 ); + grid->addWidget( new QLabel( "Total Brushes:" ), 0, 0 ); + grid->addWidget( w_brushes, 0, 1 ); + grid->addWidget( new QLabel( "Total Patches:" ), 1, 0 ); + grid->addWidget( w_patches, 1, 1 ); + grid->addWidget( new QLabel( "Total Entities:" ), 2, 0 ); + grid->addWidget( w_ents, 2, 1 ); + grid->addWidget( new QLabel( "Ingame Entities:" ), 0, 2 ); + grid->addWidget( w_ents_ingame, 0, 3 ); + grid->addWidget( new QLabel( "Group Entities:" ), 1, 2 ); + grid->addWidget( w_groupents, 1, 3 ); + grid->addWidget( new QLabel( "Ingame Group Entities:" ), 2, 2 ); + grid->addWidget( w_groupents_ingame, 2, 3 ); - { - GtkTable* table = create_dialog_table( 3, 4, 4, 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - { - GtkWidget* label = gtk_label_new( "Total Brushes:" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 ); - } - { - GtkWidget* label = gtk_label_new( "" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 3, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 ); - w_brushes = label; - } - { - GtkWidget* label = gtk_label_new( "Total Patches:" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 ); - } - { - GtkWidget* label = gtk_label_new( "" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 3, 4, 0, 1, - (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 3, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 ); - w_patches = label; - } - { - GtkWidget* label = gtk_label_new( "Total Entities:" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 ); - } - { - GtkWidget* label = gtk_label_new( "" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 3, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 ); - w_ents = label; - } - { - GtkWidget* label = gtk_label_new( "Ingame Entities:" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 ); - } - { - GtkWidget* label = gtk_label_new( "" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 3, 4, 1, 2, - (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 3, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 ); - w_ents_ingame = label; - } - { - GtkWidget* label = gtk_label_new( "Group Entities:" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 ); - } - { - GtkWidget* label = gtk_label_new( "" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 1, 2, 2, 3, - (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 3, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 ); - w_groupents = label; - } - { - GtkWidget* label = gtk_label_new( "Ingame Group Entities:" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 2, 3, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 ); - } - { - GtkWidget* label = gtk_label_new( "" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 3, 4, 2, 3, - (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 3, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0.0, 0.5 ); - w_groupents_ingame = label; - } + grid->addWidget( new QLabel( "*** Entity breakdown ***" ), 3, 0, 1, 4, Qt::AlignmentFlag::AlignCenter ); - } - { - GtkVBox* vbox2 = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox2 ), FALSE, FALSE, 0 ); - - { - GtkButton* button = create_dialog_button( "Close", G_CALLBACK( dialog_button_ok ), &dialog ); - gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - - GtkAccelGroup *accel_group = gtk_accel_group_new(); - gtk_window_add_accel_group( window, accel_group ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel_group, GDK_KEY_Escape, (GdkModifierType)0, GTK_ACCEL_VISIBLE ); - } - } - } - { - GtkWidget* label = gtk_label_new( "*** Entity breakdown ***" ); - gtk_widget_show( label ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( label ), FALSE, TRUE, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0.5, 0.5 ); - } - { - GtkScrolledWindow* scr = create_scrolled_window( GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC, 4 ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( scr ), TRUE, TRUE, 0 ); - - { - GtkListStore* store = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_UINT ); - - GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) ); - gtk_tree_view_set_headers_clickable( GTK_TREE_VIEW( view ), TRUE ); - - { - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "Entity", renderer, "text", 0, NULL ); - gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column ); - gtk_tree_view_column_set_sort_column_id( column, 0 ); - } - - { - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "Count", renderer, "text", 1, NULL ); - gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column ); - gtk_tree_view_column_set_sort_column_id( column, 1 ); - } - - gtk_widget_show( view ); - - gtk_container_add( GTK_CONTAINER( scr ), view ); - - EntityBreakdownWalker = store; - } - } + grid->addWidget( tree, 4, 0, 1, 4 ); } // Initialize fields @@ -1056,54 +918,28 @@ void DoMapInfo(){ EntityBreakdown entitymap; Scene_EntityBreakdown( entitymap ); - for ( EntityBreakdown::iterator i = entitymap.begin(); i != entitymap.end(); ++i ) + for ( const auto&[name, count] : entitymap ) { - GtkTreeIter iter; - gtk_list_store_append( GTK_LIST_STORE( EntityBreakdownWalker ), &iter ); - gtk_list_store_set( GTK_LIST_STORE( EntityBreakdownWalker ), &iter, 0, ( *i ).first.c_str(), 1, Unsigned( ( *i ).second ), -1 ); + auto item = new QTreeWidgetItem( tree ); + item->setData( 0, Qt::ItemDataRole::DisplayRole, name.c_str() ); + item->setData( 1, Qt::ItemDataRole::DisplayRole, count ); } } - g_object_unref( G_OBJECT( EntityBreakdownWalker ) ); - int n_ents_ingame = 0; int n_groupents = 0; int n_groupents_ingame = 0; Scene_CountStuff( n_ents_ingame, n_groupents, n_groupents_ingame ); - char *markup; + StringOutputStream str; + w_brushes->setText( str( "", g_brushCount.get(), "" ).c_str() ); + w_patches->setText( str( "", g_patchCount.get(), "" ).c_str() ); + w_ents->setText( str( "", g_entityCount.get(), "" ).c_str() ); + w_ents_ingame->setText( str( "", n_ents_ingame, "" ).c_str() ); + w_groupents->setText( str( "", n_groupents, "" ).c_str() ); + w_groupents_ingame->setText( str( "", n_groupents_ingame, "" ).c_str() ); - markup = g_markup_printf_escaped( "%u ", Unsigned( g_brushCount.get() ) ); - gtk_label_set_markup( GTK_LABEL( w_brushes ), markup ); - g_free( markup ); - - markup = g_markup_printf_escaped( "%i ", Unsigned( g_patchCount.get() ) ); - gtk_label_set_markup( GTK_LABEL( w_patches ), markup ); - g_free( markup ); - - markup = g_markup_printf_escaped( "%u ", Unsigned( g_entityCount.get() ) ); - gtk_label_set_markup( GTK_LABEL( w_ents ), markup ); - g_free( markup ); - - markup = g_markup_printf_escaped( "%i ", n_ents_ingame ); - gtk_label_set_markup( GTK_LABEL( w_ents_ingame ), markup ); - g_free( markup ); - - markup = g_markup_printf_escaped( "%i ", n_groupents ); - gtk_label_set_markup( GTK_LABEL( w_groupents ), markup ); - g_free( markup ); - - markup = g_markup_printf_escaped( "%i ", n_groupents_ingame ); - gtk_label_set_markup( GTK_LABEL( w_groupents_ingame ), markup ); - g_free( markup ); - - modal_dialog_show( window, dialog ); - - // save before exit - /* it's saving centered position, set by create_dialog_window() somehow(TM), not actual one or set by window_set_position() */ - window_get_position( window, g_posMapInfoWnd ); - - gtk_widget_destroy( GTK_WIDGET( window ) ); + dialog.exec(); } @@ -1143,8 +979,8 @@ void Map_LoadFile( const char *filename ){ globalOutputStream() << "--- LoadMapFile ---\n"; globalOutputStream() << g_map.m_name << "\n"; - globalOutputStream() << Unsigned( g_brushCount.get() + g_patchCount.get() ) << " primitives\n"; - globalOutputStream() << Unsigned( g_entityCount.get() ) << " entities\n"; + globalOutputStream() << g_brushCount.get() + g_patchCount.get() << " primitives\n"; + globalOutputStream() << g_entityCount.get() << " entities\n"; //GlobalEntityCreator().printStatistics(); @@ -1410,8 +1246,7 @@ void Map_New(){ */ bool g_region_active = false; -BoolExportCaller g_region_caller( g_region_active ); -ToggleItem g_region_item( g_region_caller ); +ToggleItem g_region_item{ BoolExportCaller( g_region_active ) }; Vector3 g_region_mins; Vector3 g_region_maxs; @@ -1941,17 +1776,17 @@ const char* getMapsPath(){ const char* map_open( const char* title ){ const char* path = Map_Unnamed( g_map )? getMapsPath() : g_map.m_name.c_str(); - return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), true, title, path, MapFormat::Name, true, false, false ); + return file_dialog( MainFrame_getWindow(), true, title, path, MapFormat::Name, true, false, false ); } const char* map_import( const char* title ){ const char* path = Map_Unnamed( g_map )? getMapsPath() : g_map.m_name.c_str(); - return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), true, title, path, MapFormat::Name, false, true, false ); + return file_dialog( MainFrame_getWindow(), true, title, path, MapFormat::Name, false, true, false ); } const char* map_save( const char* title ){ const char* path = Map_Unnamed( g_map )? getMapsPath() : g_map.m_name.c_str(); - return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), false, title, path, MapFormat::Name, false, false, true ); + return file_dialog( MainFrame_getWindow(), false, title, path, MapFormat::Name, false, false, true ); } void OpenMap(){ @@ -2191,89 +2026,44 @@ static void GetSelectionIndex( int *ent, int *brush ){ *ent = int(count_entity); } +#include +#include +#include +#include "gtkutil/spinbox.h" + void DoFind(){ - ModalDialog dialog; - GtkEntry* entity; - GtkEntry* brush; - - GtkWindow* window = create_dialog_window( MainFrame_getWindow(), "Find Brush", G_CALLBACK( dialog_delete_callback ), &dialog ); - - GtkAccelGroup* accel = gtk_accel_group_new(); - gtk_window_add_accel_group( window, accel ); + QDialog dialog( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Find Brush" ); + auto entity = new SpinBox( 0, 999999 ); + entity->setButtonSymbols( QAbstractSpinBox::ButtonSymbols::NoButtons ); + auto brush = new SpinBox( 0, 999999 ); + brush->setButtonSymbols( QAbstractSpinBox::ButtonSymbols::NoButtons ); { - GtkVBox* vbox = create_dialog_vbox( 4, 4 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox ) ); - { - GtkTable* table = create_dialog_table( 2, 2, 4, 4 ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - { - GtkWidget* label = gtk_label_new( "Entity number" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1, - (GtkAttachOptions) ( 0 ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkWidget* label = gtk_label_new( "Brush number" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2, - (GtkAttachOptions) ( 0 ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_grab_focus( GTK_WIDGET( entry ) ); - entity = entry; - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); + auto form = new QFormLayout( &dialog ); + form->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); - brush = entry; - } - } + form->addRow( new SpinBoxLabel( "Entity number", entity ), entity ); + form->addRow( new SpinBoxLabel( "Brush number", brush ), brush ); { - GtkHBox* hbox = create_dialog_hbox( 4 ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox ), TRUE, TRUE, 0 ); - { - GtkButton* button = create_dialog_button( "Find", G_CALLBACK( dialog_button_ok ), &dialog ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 ); - } - { - GtkButton* button = create_dialog_button( "Close", G_CALLBACK( dialog_button_cancel ), &dialog ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 ); - } + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Close ); + buttons->addButton( "Find", QDialogButtonBox::ButtonRole::AcceptRole ); + form->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept ); + QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject ); } } // Initialize dialog - char buf[16]; int ent, br; GetSelectionIndex( &ent, &br ); - sprintf( buf, "%i", ent ); - gtk_entry_set_text( entity, buf ); - sprintf( buf, "%i", br ); - gtk_entry_set_text( brush, buf ); + entity->setValue( ent ); + brush->setValue( br ); - if ( modal_dialog_show( window, dialog ) == eIDOK ) { - const char *entstr = gtk_entry_get_text( entity ); - const char *brushstr = gtk_entry_get_text( brush ); - SelectBrush( atoi( entstr ), atoi( brushstr ) ); + if ( dialog.exec() ) { + SelectBrush( entity->value(), brush->value() ); } - - gtk_widget_destroy( GTK_WIDGET( window ) ); } @@ -2592,16 +2382,26 @@ CopiedString g_strLastMap; bool g_bLoadLastMap = false; void Map_Construct(){ + GlobalCommands_insert( "NewMap", FreeCaller() ); + GlobalCommands_insert( "OpenMap", FreeCaller(), QKeySequence( "Ctrl+O" ) ); + GlobalCommands_insert( "ImportMap", FreeCaller() ); + GlobalCommands_insert( "SaveMap", FreeCaller(), QKeySequence( "Ctrl+S" ) ); + GlobalCommands_insert( "SaveMapAs", FreeCaller() ); + GlobalCommands_insert( "SaveSelected", FreeCaller() ); + GlobalCommands_insert( "SaveRegion", FreeCaller() ); + GlobalCommands_insert( "RegionOff", FreeCaller() ); GlobalCommands_insert( "RegionSetXY", FreeCaller() ); GlobalCommands_insert( "RegionSetBrush", FreeCaller() ); - //GlobalCommands_insert( "RegionSetSelection", FreeCaller(), Accelerator( 'R', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); - GlobalToggles_insert( "RegionSetSelection", FreeCaller(), ToggleItem::AddCallbackCaller( g_region_item ), Accelerator( 'R', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); - GlobalCommands_insert( "AutoCaulkSelected", FreeCaller(), Accelerator( GDK_KEY_F4 ) ); + //GlobalCommands_insert( "RegionSetSelection", FreeCaller(), QKeySequence( "Ctrl+Shift+R" ) ); + GlobalToggles_insert( "RegionSetSelection", FreeCaller(), ToggleItem::AddCallbackCaller( g_region_item ), QKeySequence( "Ctrl+Shift+R" ) ); + GlobalCommands_insert( "AutoCaulkSelected", FreeCaller(), QKeySequence( "F4" ) ); + + GlobalCommands_insert( "FindBrush", FreeCaller() ); + GlobalCommands_insert( "MapInfo", FreeCaller(), QKeySequence( "M" ) ); GlobalPreferenceSystem().registerPreference( "LastMap", CopiedStringImportStringCaller( g_strLastMap ), CopiedStringExportStringCaller( g_strLastMap ) ); GlobalPreferenceSystem().registerPreference( "LoadLastMap", BoolImportStringCaller( g_bLoadLastMap ), BoolExportStringCaller( g_bLoadLastMap ) ); - GlobalPreferenceSystem().registerPreference( "MapInfoDlg", WindowPositionImportStringCaller( g_posMapInfoWnd ), WindowPositionExportStringCaller( g_posMapInfoWnd ) ); PreferencesDialog_addSettingsPreferences( FreeCaller1() ); diff --git a/radiant/map.h b/radiant/map.h index e3914d4a..b969ca92 100644 --- a/radiant/map.h +++ b/radiant/map.h @@ -110,11 +110,8 @@ void Map_RegionOff(); bool Map_SaveRegion( const char* filename ); -class TextInputStream; -class TextOutputStream; - -void Map_ImportSelected( TextInputStream& in, const MapFormat& format ); -void Map_ExportSelected( TextOutputStream& out, const MapFormat& format ); +void Map_ImportSelected( class TextInputStream& in, const MapFormat& format ); +void Map_ExportSelected( class TextOutputStream& out, const MapFormat& format ); bool Map_Modified( const Map& map ); void Map_SetModified( Map& map, bool modified ); @@ -125,8 +122,6 @@ bool Map_SaveAs(); scene::Node& Node_Clone( scene::Node& node ); scene::Node& Node_Clone_Selected( scene::Node& node ); -void DoMapInfo(); - void Scene_parentSelectedBrushesToEntity( scene::Graph& graph, scene::Node& parent ); void Scene_parentSubgraphSelectedBrushesToEntity( scene::Graph& graph, scene::Node& parent, const scene::Path& start ); std::size_t Scene_countSelectedBrushes( scene::Graph& graph ); @@ -135,13 +130,7 @@ std::size_t Scene_countSelectedBrushes( scene::Graph& graph ); void OnUndoSizeChanged(); -void NewMap(); -void OpenMap(); -void ImportMap(); -void SaveMapAs(); void SaveMap(); -void ExportMap(); -void SaveRegion(); void Map_Traverse( scene::Node& root, const scene::Traversable::Walker& walker ); diff --git a/radiant/modelwindow.cpp b/radiant/modelwindow.cpp index ca88311a..a6283466 100644 --- a/radiant/modelwindow.cpp +++ b/radiant/modelwindow.cpp @@ -39,12 +39,23 @@ #include "stream/stringstream.h" #include "generic/callback.h" -#include #include "gtkutil/glwidget.h" -#include "gtkutil/button.h" #include "gtkutil/toolbar.h" #include "gtkutil/cursor.h" #include "gtkmisc.h" +#include "gtkutil/fbo.h" +#include "gtkutil/mousepresses.h" +#include "gtkutil/guisettings.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "mainframe.h" #include "camwindow.h" @@ -511,8 +522,6 @@ public: } }; -void ModelBrowser_scrollChanged( void* data, gdouble value ); - class ModelBrowser : public scene::Instantiable::Observer { // track instances in the order of insertion @@ -520,24 +529,22 @@ class ModelBrowser : public scene::Instantiable::Observer public: ModelFS m_modelFS; CopiedString m_prefFoldersToLoad = "*models/99*"; - ModelBrowser() : m_scrollAdjustment( ModelBrowser_scrollChanged, this ){ + ModelBrowser() : m_scrollAdjustment( [this]( int value ){ + //globalOutputStream() << "vertical scroll\n"; + setOriginZ( -value ); + } ) + { } ~ModelBrowser(){ } - FBO* m_fbo = nullptr; - FBO* fbo_get(){ - return m_fbo = m_fbo? m_fbo : GlobalOpenGL().support_ARB_framebuffer_object? new FBO : new FBO_fallback; - } const int m_MSAA = 8; - GtkWindow* m_parent = nullptr; - GtkWidget* m_gl_widget = nullptr; - GtkWidget* m_gl_scroll = nullptr; - GtkWidget* m_treeViewTree = nullptr; + QWidget* m_parent = nullptr; + QOpenGLWidget* m_gl_widget = nullptr; + QScrollBar* m_gl_scroll = nullptr; + QTreeView* m_treeView = nullptr; - guint m_sizeHandler; - guint m_exposeHandler; int m_width; int m_height; @@ -563,16 +570,11 @@ private: return constructCellPos().totalHeight( m_height, m_modelInstances.size() ); } void updateScroll() const { - GtkAdjustment *vadjustment = gtk_range_get_adjustment( GTK_RANGE( m_gl_scroll ) ); - - gtk_adjustment_set_value( vadjustment, -m_originZ ); - gtk_adjustment_set_page_size( vadjustment, m_height ); - gtk_adjustment_set_page_increment( vadjustment, m_height / 2 ); - gtk_adjustment_set_step_increment( vadjustment, 20 ); - gtk_adjustment_set_lower( vadjustment, 0 ); - gtk_adjustment_set_upper( vadjustment, totalHeight() ); - - g_signal_emit_by_name( G_OBJECT( vadjustment ), "changed" ); + m_gl_scroll->setMinimum( 0 ); + m_gl_scroll->setMaximum( totalHeight() - m_height ); + m_gl_scroll->setValue( -m_originZ ); + m_gl_scroll->setPageStep( m_height ); + m_gl_scroll->setSingleStep( 20 ); } public: void setOriginZ( int origin ){ @@ -582,7 +584,7 @@ public: } void queueDraw() const { if ( m_gl_widget != nullptr ) - gtk_widget_queue_draw( m_gl_widget ); + widget_queue_draw( *m_gl_widget ); } bool m_originInvalid = true; void validate(){ @@ -595,30 +597,29 @@ public: } private: + void trackingDelta( int x, int y, const QMouseEvent *event ){ + m_move_amount += std::abs( x ) + std::abs( y ); + if ( event->buttons() & Qt::MouseButton::RightButton && y != 0 ) { // scroll view + const int scale = event->modifiers().testFlag( Qt::KeyboardModifier::ShiftModifier )? 4 : 1; + setOriginZ( m_originZ + y * scale ); + } + else if ( event->buttons() & Qt::MouseButton::LeftButton && ( x != 0 || y != 0 ) && m_currentModelId >= 0 ) { // rotate selected model + ASSERT_MESSAGE( m_currentModelId < static_cast( m_modelInstances.size() ), "modelBrowser.m_currentModelId out of range" ); + scene::Instance *instance = m_modelInstances[m_currentModelId]; + if( TransformNode *transformNode = Node_getTransformNode( instance->path().parent() ) ){ + Matrix4 rot( g_matrix4_identity ); + matrix4_pivoted_rotate_by_euler_xyz_degrees( rot, Vector3( y, 0, x ) * ( 45.f / m_cellSize ), constructCellPos().getOrigin( m_currentModelId ) ); + matrix4_premultiply_by_matrix4( const_cast( transformNode->localToParent() ), rot ); + instance->parent()->transformChangedLocal(); + instance->transformChangedLocal(); + queueDraw(); + } + } + } FreezePointer m_freezePointer; bool m_move_started = false; public: int m_move_amount; - static void trackingDelta( int x, int y, unsigned int state, void* data ){ - ModelBrowser& modelBrowser = *reinterpret_cast( data ); - modelBrowser.m_move_amount += std::abs( x ) + std::abs( y ); - if ( ( state & GDK_BUTTON3_MASK ) && y != 0 ) { // scroll view - const int scale = ( state & GDK_SHIFT_MASK )? 4 : 1; - modelBrowser.setOriginZ( modelBrowser.m_originZ + y * scale ); - } - else if ( ( state & GDK_BUTTON1_MASK ) && ( x != 0 || y != 0 ) && modelBrowser.m_currentModelId >= 0 ) { // rotate selected model - ASSERT_MESSAGE( modelBrowser.m_currentModelId < static_cast( modelBrowser.m_modelInstances.size() ), "modelBrowser.m_currentModelId out of range" ); - scene::Instance *instance = modelBrowser.m_modelInstances[modelBrowser.m_currentModelId]; - if( TransformNode *transformNode = Node_getTransformNode( instance->path().parent() ) ){ - Matrix4 rot( g_matrix4_identity ); - matrix4_pivoted_rotate_by_euler_xyz_degrees( rot, Vector3( y, 0, x ) * ( 45.f / modelBrowser.m_cellSize ), modelBrowser.constructCellPos().getOrigin( modelBrowser.m_currentModelId ) ); - matrix4_premultiply_by_matrix4( const_cast( transformNode->localToParent() ), rot ); - instance->parent()->transformChangedLocal(); - instance->transformChangedLocal(); - modelBrowser.queueDraw(); - } - } - } void tracking_MouseUp(){ if( m_move_started ){ m_move_started = false; @@ -629,7 +630,13 @@ public: tracking_MouseUp(); m_move_started = true; m_move_amount = 0; - m_freezePointer.freeze_pointer( m_parent, m_gl_widget, trackingDelta, this ); + m_freezePointer.freeze_pointer( m_gl_widget, + [this]( int x, int y, const QMouseEvent *event ){ + trackingDelta( x, y, event ); + }, + [this](){ + tracking_MouseUp(); + } ); } void insert( scene::Instance* instance ) override { @@ -749,18 +756,16 @@ origin -----> +x void ModelBrowser_render(){ g_ModelBrowser.validate(); - g_ModelBrowser.fbo_get()->start(); - const int W = g_ModelBrowser.m_width; const int H = g_ModelBrowser.m_height; - glViewport( 0, 0, W, H ); + gl().glViewport( 0, 0, W, H ); // enable depth buffer writes - glDepthMask( GL_TRUE ); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + gl().glDepthMask( GL_TRUE ); + gl().glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glClearColor( .25f, .25f, .25f, 0 ); - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + gl().glClearColor( .25f, .25f, .25f, 0 ); + gl().glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); const unsigned int globalstate = RENDER_DEPTHTEST | RENDER_COLOURWRITE @@ -769,8 +774,6 @@ void ModelBrowser_render(){ | RENDER_BLEND | RENDER_CULLFACE | RENDER_COLOURARRAY - | RENDER_POLYGONSMOOTH - | RENDER_LINESMOOTH | RENDER_FOG | RENDER_COLOURCHANGE | RENDER_FILL @@ -827,53 +830,51 @@ void ModelBrowser_render(){ m_view.Construct( m_projection, m_modelview, W, H ); - glMatrixMode( GL_PROJECTION ); - glLoadMatrixf( reinterpret_cast( &m_projection ) ); + gl().glMatrixMode( GL_PROJECTION ); + gl().glLoadMatrixf( reinterpret_cast( &m_projection ) ); - glMatrixMode( GL_MODELVIEW ); - glLoadMatrixf( reinterpret_cast( &m_modelview ) ); + gl().glMatrixMode( GL_MODELVIEW ); + gl().glLoadMatrixf( reinterpret_cast( &m_modelview ) ); if( g_ModelBrowser.m_currentFolder != nullptr ){ { // prepare for 2d stuff - glDisable( GL_BLEND ); + gl().glDisable( GL_BLEND ); - if ( GlobalOpenGL().GL_1_3() ) { - glClientActiveTexture( GL_TEXTURE0 ); - glActiveTexture( GL_TEXTURE0 ); - } + gl().glClientActiveTexture( GL_TEXTURE0 ); + gl().glActiveTexture( GL_TEXTURE0 ); - glDisableClientState( GL_TEXTURE_COORD_ARRAY ); - glDisableClientState( GL_NORMAL_ARRAY ); - glDisableClientState( GL_COLOR_ARRAY ); + gl().glDisableClientState( GL_TEXTURE_COORD_ARRAY ); + gl().glDisableClientState( GL_NORMAL_ARRAY ); + gl().glDisableClientState( GL_COLOR_ARRAY ); - glDisable( GL_TEXTURE_2D ); - glDisable( GL_LIGHTING ); - glDisable( GL_COLOR_MATERIAL ); - glDisable( GL_DEPTH_TEST ); + gl().glDisable( GL_TEXTURE_2D ); + gl().glDisable( GL_LIGHTING ); + gl().glDisable( GL_COLOR_MATERIAL ); + gl().glDisable( GL_DEPTH_TEST ); } { // brighter background squares - glColor4f( 0.3f, 0.3f, 0.3f, 1.f ); - glDepthMask( GL_FALSE ); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glDisable( GL_CULL_FACE ); + gl().glColor4f( 0.3f, 0.3f, 0.3f, 1.f ); + gl().glDepthMask( GL_FALSE ); + gl().glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + gl().glDisable( GL_CULL_FACE ); CellPos cellPos = g_ModelBrowser.constructCellPos(); - glBegin( GL_QUADS ); + gl().glBegin( GL_QUADS ); for( std::size_t i = g_ModelBrowser.m_currentFolder->m_files.size(); i != 0; --i ){ const Vector3 origin = cellPos.getOrigin(); const float minx = origin.x() - cellPos.getCellSize(); const float maxx = origin.x() + cellPos.getCellSize(); const float minz = origin.z() - cellPos.getCellSize(); const float maxz = origin.z() + cellPos.getCellSize(); - glVertex3f( minx, 0, maxz ); - glVertex3f( minx, 0, minz ); - glVertex3f( maxx, 0, minz ); - glVertex3f( maxx, 0, maxz ); + gl().glVertex3f( minx, 0, maxz ); + gl().glVertex3f( minx, 0, minz ); + gl().glVertex3f( maxx, 0, minz ); + gl().glVertex3f( maxx, 0, maxz ); ++cellPos; } - glEnd(); + gl().glEnd(); } // one directional light source directly behind the viewer @@ -890,12 +891,12 @@ void ModelBrowser_render(){ inverse_cam_dir[2] = -m_view.getViewDir()[2]; inverse_cam_dir[3] = 0; - glLightfv( GL_LIGHT0, GL_POSITION, inverse_cam_dir ); + gl().glLightfv( GL_LIGHT0, GL_POSITION, inverse_cam_dir ); - glLightfv( GL_LIGHT0, GL_AMBIENT, ambient ); - glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse ); + gl().glLightfv( GL_LIGHT0, GL_AMBIENT, ambient ); + gl().glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse ); - glEnable( GL_LIGHT0 ); + gl().glEnable( GL_LIGHT0 ); } { @@ -910,30 +911,28 @@ void ModelBrowser_render(){ } { // prepare for 2d stuff - glColor4f( 1, 1, 1, 1 ); - glDisable( GL_BLEND ); + gl().glColor4f( 1, 1, 1, 1 ); + gl().glDisable( GL_BLEND ); - if ( GlobalOpenGL().GL_1_3() ) { - glClientActiveTexture( GL_TEXTURE0 ); - glActiveTexture( GL_TEXTURE0 ); - } + gl().glClientActiveTexture( GL_TEXTURE0 ); + gl().glActiveTexture( GL_TEXTURE0 ); - glDisableClientState( GL_TEXTURE_COORD_ARRAY ); - glDisableClientState( GL_NORMAL_ARRAY ); - glDisableClientState( GL_COLOR_ARRAY ); + gl().glDisableClientState( GL_TEXTURE_COORD_ARRAY ); + gl().glDisableClientState( GL_NORMAL_ARRAY ); + gl().glDisableClientState( GL_COLOR_ARRAY ); - glDisable( GL_TEXTURE_2D ); - glDisable( GL_LIGHTING ); - glDisable( GL_COLOR_MATERIAL ); - glDisable( GL_DEPTH_TEST ); - glLineWidth( 1 ); + gl().glDisable( GL_TEXTURE_2D ); + gl().glDisable( GL_LIGHTING ); + gl().glDisable( GL_COLOR_MATERIAL ); + gl().glDisable( GL_DEPTH_TEST ); + gl().glLineWidth( 1 ); } { // render model file names CellPos cellPos = g_ModelBrowser.constructCellPos(); for( const CopiedString& string : g_ModelBrowser.m_currentFolder->m_files ){ const Vector3 pos = cellPos.getTextPos(); if( m_view.TestPoint( pos ) ){ - glRasterPos3f( pos.x(), pos.y(), pos.z() ); + gl().glRasterPos3f( pos.x(), pos.y(), pos.z() ); GlobalOpenGL().drawString( string.c_str() ); } ++cellPos; @@ -943,109 +942,102 @@ void ModelBrowser_render(){ // bind back to the default texture so that we don't have problems // elsewhere using/modifying texture maps between contexts - glBindTexture( GL_TEXTURE_2D, 0 ); - - g_ModelBrowser.fbo_get()->save(); + gl().glBindTexture( GL_TEXTURE_2D, 0 ); } -gboolean ModelBrowser_size_allocate( GtkWidget* widget, GtkAllocation* allocation, ModelBrowser* modelBrowser ){ - modelBrowser->fbo_get()->reset( allocation->width, allocation->height, modelBrowser->m_MSAA, true ); - modelBrowser->m_width = allocation->width; - modelBrowser->m_height = allocation->height; - modelBrowser->m_originInvalid = true; - modelBrowser->forEachModelInstance( models_set_transforms() ); - modelBrowser->queueDraw(); - return FALSE; -} - -gboolean ModelBrowser_expose( GtkWidget* widget, GdkEventExpose* event, ModelBrowser* modelBrowser ){ - if ( glwidget_make_current( modelBrowser->m_gl_widget ) ) { - GlobalOpenGL_debugAssertNoErrors(); - ModelBrowser_render(); - GlobalOpenGL_debugAssertNoErrors(); - glwidget_swap_buffers( modelBrowser->m_gl_widget ); +class ModelBrowserGLWidget : public QOpenGLWidget +{ + ModelBrowser& m_modBro; + FBO *m_fbo{}; + MousePresses m_mouse; +public: + ModelBrowserGLWidget( ModelBrowser& modelBrowser ) : QOpenGLWidget(), m_modBro( modelBrowser ) + { } - return FALSE; -} - - - -gboolean ModelBrowser_mouseScroll( GtkWidget* widget, GdkEventScroll* event, ModelBrowser* modelBrowser ){ - gtk_widget_grab_focus( widget ); - if( !gtk_window_is_active( modelBrowser->m_parent ) ) - gtk_window_present( modelBrowser->m_parent ); - - if ( event->direction == GDK_SCROLL_UP ) { - modelBrowser->setOriginZ( modelBrowser->m_originZ + 64 ); + ~ModelBrowserGLWidget() override { + delete m_fbo; + glwidget_context_destroyed(); } - else if ( event->direction == GDK_SCROLL_DOWN ) { - modelBrowser->setOriginZ( modelBrowser->m_originZ - 64 ); +protected: + void initializeGL() override + { + glwidget_context_created( *this ); } - return FALSE; -} + void resizeGL( int w, int h ) override + { + delete m_fbo; + m_fbo = new FBO( w, h, true, m_modBro.m_MSAA ); -void ModelBrowser_scrollChanged( void* data, gdouble value ){ - //globalOutputStream() << "vertical scroll\n"; - reinterpret_cast( data )->setOriginZ( -(int)value ); -} - -static void ModelBrowser_scrollbarScroll( GtkAdjustment *adjustment, ModelBrowser* modelBrowser ){ - modelBrowser->m_scrollAdjustment.value_changed( gtk_adjustment_get_value( adjustment ) ); -} - - -gboolean ModelBrowser_button_press( GtkWidget* widget, GdkEventButton* event, ModelBrowser* modelBrowser ){ - if ( event->type == GDK_BUTTON_PRESS ) { - gtk_widget_grab_focus( widget ); - if ( event->button == 1 || event->button == 3 ) { - modelBrowser->tracking_MouseDown(); - } - if ( event->button == 1 ) { - modelBrowser->testSelect( static_cast( event->x ), static_cast( event->y ) ); + m_modBro.m_width = w; + m_modBro.m_height = h; + m_modBro.m_originInvalid = true; + m_modBro.forEachModelInstance( models_set_transforms() ); + } + void paintGL() override + { + if( ScreenUpdates_Enabled() && m_fbo->bind() ){ + GlobalOpenGL_debugAssertNoErrors(); + ModelBrowser_render(); + GlobalOpenGL_debugAssertNoErrors(); + m_fbo->blit(); + m_fbo->release(); } } - /* create misc_model */ - else if ( event->type == GDK_2BUTTON_PRESS && event->button == 1 && modelBrowser->m_currentFolder != nullptr && modelBrowser->m_currentModelId >= 0 ) { - UndoableCommand undo( "insertModel" ); - // todo - // GlobalEntityClassManager() search for "misc_model" - // otherwise search for entityClass->miscmodel_is - // otherwise go with GlobalEntityClassManager().findOrInsert( "misc_model", false ); - EntityClass* entityClass = GlobalEntityClassManager().findOrInsert( "misc_model", false ); - NodeSmartReference node( GlobalEntityCreator().createEntity( entityClass ) ); - Node_getTraversable( GlobalSceneGraph().root() )->insert( node ); - - scene::Path entitypath( makeReference( GlobalSceneGraph().root() ) ); - entitypath.push( makeReference( node.get() ) ); - scene::Instance& instance = findInstance( entitypath ); - - if ( Transformable* transform = Instance_getTransformable( instance ) ) { // might be cool to consider model aabb here - transform->setType( TRANSFORM_PRIMITIVE ); - transform->setTranslation( vector3_snapped( Camera_getOrigin( *g_pParentWnd->GetCamWnd() ) - Camera_getViewVector( *g_pParentWnd->GetCamWnd() ) * 128.f, GetSnapGridSize() ) ); - transform->freezeTransform(); + void mousePressEvent( QMouseEvent *event ) override { + setFocus(); + const auto press = m_mouse.press( event ); + if( press == MousePresses::Left2x ){ + mouseDoubleClick(); + } + else if ( press == MousePresses::Left || press == MousePresses::Right ) { + m_modBro.tracking_MouseDown(); + if ( press == MousePresses::Left ) { + m_modBro.testSelect( event->x(), event->y() ); + } } - - GlobalSelectionSystem().setSelectedAll( false ); - Instance_setSelected( instance, true ); - - StringOutputStream sstream( 128 ); - sstream << modelBrowser->m_currentFolderPath << std::next( modelBrowser->m_currentFolder->m_files.begin(), modelBrowser->m_currentModelId )->c_str(); - Node_getEntity( node )->setKeyValue( entityClass->miscmodel_key(), sstream.c_str() ); } - return FALSE; -} + void mouseDoubleClick(){ + /* create misc_model */ + if ( m_modBro.m_currentFolder != nullptr && m_modBro.m_currentModelId >= 0 ) { + UndoableCommand undo( "insertModel" ); + // todo + // GlobalEntityClassManager() search for "misc_model" + // otherwise search for entityClass->miscmodel_is + // otherwise go with GlobalEntityClassManager().findOrInsert( "misc_model", false ); + EntityClass* entityClass = GlobalEntityClassManager().findOrInsert( "misc_model", false ); + NodeSmartReference node( GlobalEntityCreator().createEntity( entityClass ) ); + + Node_getTraversable( GlobalSceneGraph().root() )->insert( node ); + + scene::Path entitypath( makeReference( GlobalSceneGraph().root() ) ); + entitypath.push( makeReference( node.get() ) ); + scene::Instance& instance = findInstance( entitypath ); + + if ( Transformable* transform = Instance_getTransformable( instance ) ) { // might be cool to consider model aabb here + transform->setType( TRANSFORM_PRIMITIVE ); + transform->setTranslation( vector3_snapped( Camera_getOrigin( *g_pParentWnd->GetCamWnd() ) - Camera_getViewVector( *g_pParentWnd->GetCamWnd() ) * 128.f, GetSnapGridSize() ) ); + transform->freezeTransform(); + } + + GlobalSelectionSystem().setSelectedAll( false ); + Instance_setSelected( instance, true ); -gboolean ModelBrowser_button_release( GtkWidget* widget, GdkEventButton* event, ModelBrowser* modelBrowser ){ - if ( event->type == GDK_BUTTON_RELEASE ) { - if ( event->button == 1 || event->button == 3 ) { - modelBrowser->tracking_MouseUp(); - } - if ( event->button == 1 && modelBrowser->m_move_amount < 16 && modelBrowser->m_currentFolder != nullptr && modelBrowser->m_currentModelId >= 0 ) { // assign model to selected entity nodes StringOutputStream sstream( 128 ); - sstream << modelBrowser->m_currentFolderPath << std::next( modelBrowser->m_currentFolder->m_files.begin(), modelBrowser->m_currentModelId )->c_str(); + sstream << m_modBro.m_currentFolderPath << std::next( m_modBro.m_currentFolder->m_files.begin(), m_modBro.m_currentModelId )->c_str(); + Node_getEntity( node )->setKeyValue( entityClass->miscmodel_key(), sstream.c_str() ); + } + } + void mouseReleaseEvent( QMouseEvent *event ) override { + const auto release = m_mouse.release( event ); + if ( release == MousePresses::Left || release == MousePresses::Right ) { + m_modBro.tracking_MouseUp(); + } + if ( release == MousePresses::Left && m_modBro.m_move_amount < 16 && m_modBro.m_currentFolder != nullptr && m_modBro.m_currentModelId >= 0 ) { // assign model to selected entity nodes + StringOutputStream sstream( 128 ); + sstream << m_modBro.m_currentFolderPath << std::next( m_modBro.m_currentFolder->m_files.begin(), m_modBro.m_currentModelId )->c_str(); class EntityVisitor : public SelectionSystem::Visitor { const char* m_filePath; @@ -1062,58 +1054,61 @@ gboolean ModelBrowser_button_release( GtkWidget* widget, GdkEventButton* event, GlobalSelectionSystem().foreachSelected( visitor ); } } - return FALSE; -} + void wheelEvent( QWheelEvent *event ) override { + setFocus(); + if( !m_modBro.m_parent->isActiveWindow() ){ + m_modBro.m_parent->activateWindow(); + m_modBro.m_parent->raise(); + } + + m_modBro.setOriginZ( m_modBro.m_originZ + std::copysign( 64, event->angleDelta().y() ) ); + } +}; -static void TreeView_onRowActivated( GtkTreeView* treeview, GtkTreePath* path, GtkTreeViewColumn* col, gpointer userdata ){ - GtkTreeModel* model = gtk_tree_view_get_model( GTK_TREE_VIEW( treeview ) ); - GtkTreeIter iter; - if ( gtk_tree_model_get_iter( model, &iter, path ) ) { - std::deque iters; - iters.push_front( iter ); - GtkTreeIter parent; - while( gtk_tree_model_iter_parent( model, &parent, &iters.front() ) ) - iters.push_front( parent ); - StringOutputStream sstream( 64 ); - const ModelFS *modelFS = &g_ModelBrowser.m_modelFS; - for( GtkTreeIter& i : iters ){ - gchar* buffer; - gtk_tree_model_get( model, &i, 0, &buffer, -1 ); - const auto found = modelFS->m_folders.find( ModelFS( StringRange( buffer, strlen( buffer ) ) ) ); +static void TreeView_onRowActivated( const QModelIndex& index ){ + StringOutputStream sstream( 64 ); + const ModelFS *modelFS = &g_ModelBrowser.m_modelFS; + { + std::deque iters; + iters.push_front( index ); + while( iters.front().parent().isValid() ) + iters.push_front( iters.front().parent() ); + for( const QModelIndex& i : iters ){ + const auto dir = i.data( Qt::ItemDataRole::DisplayRole ).toByteArray(); + const auto found = modelFS->m_folders.find( ModelFS( StringRange( dir.constData(), strlen( dir.constData() ) ) ) ); if( found != modelFS->m_folders.end() ){ // ok to not find, while loading root modelFS = &( *found ); - sstream << buffer << "/"; + sstream << dir.constData() << "/"; } - g_free( buffer ); } + } //% globalOutputStream() << sstream.c_str() << " sstream.c_str()\n"; - ModelGraph_clear(); // this goes 1st: resets m_currentFolder + ModelGraph_clear(); // this goes 1st: resets m_currentFolder - g_ModelBrowser.m_currentFolder = modelFS; - g_ModelBrowser.m_currentFolderPath = sstream.c_str(); + g_ModelBrowser.m_currentFolder = modelFS; + g_ModelBrowser.m_currentFolderPath = sstream.c_str(); + { ScopeDisableScreenUpdates disableScreenUpdates( g_ModelBrowser.m_currentFolderPath.c_str(), "Loading Models" ); - { - for( const CopiedString& filename : g_ModelBrowser.m_currentFolder->m_files ){ - sstream.clear(); - sstream << g_ModelBrowser.m_currentFolderPath << filename; - ModelNode *modelNode = new ModelNode; - modelNode->setModel( sstream.c_str() ); - NodeSmartReference node( modelNode->node() ); - Node_getTraversable( g_modelGraph->root() )->insert( node ); - } - g_ModelBrowser.forEachModelInstance( models_set_transforms() ); + + for( const CopiedString& filename : g_ModelBrowser.m_currentFolder->m_files ){ + sstream( g_ModelBrowser.m_currentFolderPath, filename ); + ModelNode *modelNode = new ModelNode; + modelNode->setModel( sstream.c_str() ); + NodeSmartReference node( modelNode->node() ); + Node_getTraversable( g_modelGraph->root() )->insert( node ); } - - g_ModelBrowser.queueDraw(); - - //deactivate, so SPACE and RETURN wont be broken for 2d - gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( treeview ) ) ), NULL ); + g_ModelBrowser.forEachModelInstance( models_set_transforms() ); } + + g_ModelBrowser.queueDraw(); + + //deactivate, so SPACE and RETURN wont be broken for 2d + g_ModelBrowser.m_treeView->clearFocus(); } @@ -1132,12 +1127,11 @@ void modelFS_traverse( const ModelFS& modelFS ){ --depth; } #endif -void ModelBrowser_constructTreeModel( const ModelFS& modelFS, GtkTreeStore* store, GtkTreeIter* parent ){ - GtkTreeIter iter; - gtk_tree_store_append( store, &iter, parent ); - gtk_tree_store_set( store, &iter, 0, modelFS.m_folderName.c_str(), -1 ); +void ModelBrowser_constructTreeModel( const ModelFS& modelFS, QStandardItemModel* model, QStandardItem* parent ){ + auto item = new QStandardItem( modelFS.m_folderName.c_str() ); + parent->appendRow( item ); for( const ModelFS& m : modelFS.m_folders ) - ModelBrowser_constructTreeModel( m, store, &iter ); //recursion + ModelBrowser_constructTreeModel( m, model, item ); //recursion } typedef std::map ModelFoldersMap; @@ -1241,107 +1235,90 @@ void ModelBrowser_constructTree(){ //% modelFS_traverse( g_ModelBrowser.m_modelFS ); - GtkTreeStore* store = gtk_tree_store_new( 1, G_TYPE_STRING ); + auto model = new QStandardItemModel( g_ModelBrowser.m_treeView ); //. ? delete old or clear() & reuse { - if( !g_ModelBrowser.m_modelFS.m_files.empty() ){ // models in the root - GtkTreeIter iter; - gtk_tree_store_append( store, &iter, nullptr ); - gtk_tree_store_set( store, &iter, 0, "", -1 ); + if( !g_ModelBrowser.m_modelFS.m_files.empty() ){ // models in the root: add blank item for access + model->invisibleRootItem()->appendRow( new QStandardItem( "" ) ); } for( const ModelFS& m : g_ModelBrowser.m_modelFS.m_folders ) - ModelBrowser_constructTreeModel( m, store, nullptr ); + ModelBrowser_constructTreeModel( m, model, model->invisibleRootItem() ); } - gtk_tree_view_set_model( GTK_TREE_VIEW( g_ModelBrowser.m_treeViewTree ), GTK_TREE_MODEL( store ) ); - - g_object_unref( G_OBJECT( store ) ); + g_ModelBrowser.m_treeView->setModel( model ); } -GtkWidget* ModelBrowser_constructWindow( GtkWindow* toplevel ){ +class TexBro_QTreeView : public QTreeView +{ +protected: + bool event( QEvent *event ) override { + if( event->type() == QEvent::ShortcutOverride ){ + event->accept(); + return true; + } + return QTreeView::event( event ); + } +}; + +QWidget* ModelBrowser_constructWindow( QWidget* toplevel ){ g_ModelBrowser.m_parent = toplevel; - GtkWidget* table = gtk_table_new( 1, 3, FALSE ); - GtkWidget* vbox = gtk_vbox_new( FALSE, 0 ); - gtk_table_attach( GTK_TABLE( table ), vbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0 ); - gtk_widget_show( vbox ); + QSplitter *splitter = new QSplitter; + QWidget *containerWidgetLeft = new QWidget; // Adding a QLayout to a QSplitter is not supported, use proxy widget + QWidget *containerWidgetRight = new QWidget; // Adding a QLayout to a QSplitter is not supported, use proxy widget + splitter->addWidget( containerWidgetLeft ); + splitter->addWidget( containerWidgetRight ); + QVBoxLayout *vbox = new QVBoxLayout( containerWidgetLeft ); + QHBoxLayout *hbox = new QHBoxLayout( containerWidgetRight ); + + hbox->setContentsMargins( 0, 0, 0, 0 ); + vbox->setContentsMargins( 0, 0, 0, 0 ); + hbox->setSpacing( 0 ); + vbox->setSpacing( 0 ); { // menu bar - GtkToolbar* toolbar = toolbar_new(); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( toolbar ), FALSE, FALSE, 0 ); + QToolBar* toolbar = new QToolBar; + vbox->addWidget( toolbar ); - GtkToolButton* button = toolbar_append_button( toolbar, "Reload Model Folders Tree View", "texbro_refresh.png", FreeCaller() ); -// gtk_widget_set_size_request( GTK_WIDGET( button ), 22, 22 ); + toolbar_append_button( toolbar, "Reload Model Folders Tree View", "texbro_refresh.png", FreeCaller() ); } { // TreeView - GtkWidget* scr = gtk_scrolled_window_new( NULL, NULL ); - gtk_container_set_border_width( GTK_CONTAINER( scr ), 0 ); - // vertical only scrolling for treeview - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS ); - gtk_widget_show( scr ); + g_ModelBrowser.m_treeView = new TexBro_QTreeView; + g_ModelBrowser.m_treeView->setHeaderHidden( true ); + g_ModelBrowser.m_treeView->setEditTriggers( QAbstractItemView::EditTrigger::NoEditTriggers ); + g_ModelBrowser.m_treeView->setUniformRowHeights( true ); // optimization + g_ModelBrowser.m_treeView->setFocusPolicy( Qt::FocusPolicy::ClickFocus ); + g_ModelBrowser.m_treeView->setExpandsOnDoubleClick( false ); - g_ModelBrowser.m_treeViewTree = gtk_tree_view_new(); - GtkTreeView* treeview = GTK_TREE_VIEW( g_ModelBrowser.m_treeViewTree ); - //gtk_tree_view_set_enable_search( treeview, FALSE ); - - gtk_tree_view_set_headers_visible( treeview, FALSE ); - g_signal_connect( treeview, "row-activated", (GCallback) TreeView_onRowActivated, NULL ); - - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - //g_object_set( G_OBJECT( renderer ), "ellipsize", PANGO_ELLIPSIZE_START, NULL ); - gtk_tree_view_insert_column_with_attributes( treeview, -1, "", renderer, "text", 0, NULL ); + QObject::connect( g_ModelBrowser.m_treeView, &QAbstractItemView::activated, TreeView_onRowActivated ); ModelBrowser_constructTree(); - - //gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scr ), g_ModelBrowser.m_treeViewTree ); - gtk_container_add( GTK_CONTAINER( scr ), g_ModelBrowser.m_treeViewTree ); //GtkTreeView has native scrolling support; should not be used with the GtkViewport proxy. - gtk_widget_show( g_ModelBrowser.m_treeViewTree ); - - gtk_box_pack_start( GTK_BOX( vbox ), scr, TRUE, TRUE, 0 ); - } - { // gl_widget scrollbar - GtkWidget* w = g_ModelBrowser.m_gl_scroll = gtk_vscrollbar_new( GTK_ADJUSTMENT( gtk_adjustment_new( 0, 0, 0, 1, 1, 0 ) ) ); - gtk_table_attach( GTK_TABLE( table ), w, 2, 3, 0, 1, GTK_SHRINK, GTK_FILL, 0, 0 ); - gtk_widget_show( w ); - - GtkAdjustment *vadjustment = gtk_range_get_adjustment( GTK_RANGE( w ) ); - g_signal_connect( G_OBJECT( vadjustment ), "value_changed", G_CALLBACK( ModelBrowser_scrollbarScroll ), &g_ModelBrowser ); + vbox->addWidget( g_ModelBrowser.m_treeView ); } { // gl_widget - GtkWidget* w = g_ModelBrowser.m_gl_widget = glwidget_new( TRUE ); - g_object_ref( G_OBJECT( w ) ); + g_ModelBrowser.m_gl_widget = new ModelBrowserGLWidget( g_ModelBrowser ); + hbox->addWidget( g_ModelBrowser.m_gl_widget ); + } + { // gl_widget scrollbar + auto scroll = g_ModelBrowser.m_gl_scroll = new QScrollBar; + hbox->addWidget( scroll ); - gtk_widget_set_events( w, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK ); - gtk_widget_set_can_focus( w, TRUE ); - - gtk_table_attach_defaults( GTK_TABLE( table ), w, 1, 2, 0, 1 ); - gtk_widget_show( w ); - - g_ModelBrowser.m_sizeHandler = g_signal_connect( G_OBJECT( w ), "size_allocate", G_CALLBACK( ModelBrowser_size_allocate ), &g_ModelBrowser ); - g_ModelBrowser.m_exposeHandler = g_signal_connect( G_OBJECT( w ), "expose_event", G_CALLBACK( ModelBrowser_expose ), &g_ModelBrowser ); - - g_signal_connect( G_OBJECT( w ), "button_press_event", G_CALLBACK( ModelBrowser_button_press ), &g_ModelBrowser ); - g_signal_connect( G_OBJECT( w ), "button_release_event", G_CALLBACK( ModelBrowser_button_release ), &g_ModelBrowser ); - g_signal_connect( G_OBJECT( w ), "scroll_event", G_CALLBACK( ModelBrowser_mouseScroll ), &g_ModelBrowser ); + QObject::connect( scroll, &QAbstractSlider::valueChanged, []( int value ){ + g_ModelBrowser.m_scrollAdjustment.value_changed( value ); + } ); } - //prevent focusing on filter entry or tex dirs treeview after click on tab of floating group dialog (np, if called via hotkey) - gtk_container_set_focus_chain( GTK_CONTAINER( table ), NULL ); - - return table; + splitter->setStretchFactor( 0, 0 ); // consistent treeview side sizing on resizes + splitter->setStretchFactor( 1, 1 ); + g_guiSettings.addSplitter( splitter, "ModelBrowser/splitter", { 100, 500 } ); + return splitter; } void ModelBrowser_destroyWindow(){ - g_signal_handler_disconnect( G_OBJECT( g_ModelBrowser.m_gl_widget ), g_ModelBrowser.m_sizeHandler ); - g_signal_handler_disconnect( G_OBJECT( g_ModelBrowser.m_gl_widget ), g_ModelBrowser.m_exposeHandler ); - - g_object_unref( G_OBJECT( g_ModelBrowser.m_gl_widget ) ); g_ModelBrowser.m_gl_widget = nullptr; - - delete g_ModelBrowser.m_fbo; } @@ -1370,7 +1347,7 @@ typedef ReferenceCaller1 Folders void ModelBrowser_constructPage( PreferenceGroup& group ){ PreferencesPage page( group.createPage( "Model Browser", "Model Browser Preferences" ) ); - page.appendSpinner( "Model View Size", 80.0, 16.0, 8192.0, + page.appendSpinner( "Model View Size", 16.0, 8192.0, IntImportCallback( CellSizeImportCaller( g_ModelBrowser.m_cellSize ) ), IntExportCallback( IntExportCaller( g_ModelBrowser.m_cellSize ) ) ); page.appendEntry( "List of *folderToLoad/depth*", @@ -1396,10 +1373,6 @@ void ModelBrowser_Destroy(){ delete g_modelGraph; } -GtkWidget* ModelBrowser_getGLWidget(){ - return g_ModelBrowser.m_gl_widget; -} - void ModelBrowser_flushReferences(){ ModelGraph_clear(); g_ModelBrowser.queueDraw(); diff --git a/radiant/modelwindow.h b/radiant/modelwindow.h index da388304..23f30a42 100644 --- a/radiant/modelwindow.h +++ b/radiant/modelwindow.h @@ -26,12 +26,7 @@ void ModelBrowser_Construct(); void ModelBrowser_Destroy(); -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkWindow GtkWindow; - -GtkWidget* ModelBrowser_constructWindow( GtkWindow* toplevel ); +class QWidget* ModelBrowser_constructWindow( QWidget* toplevel ); void ModelBrowser_destroyWindow(); -GtkWidget* ModelBrowser_getGLWidget(); - void ModelBrowser_flushReferences(); diff --git a/radiant/mru.cpp b/radiant/mru.cpp index 6e82d6d6..5de785d4 100644 --- a/radiant/mru.cpp +++ b/radiant/mru.cpp @@ -23,7 +23,6 @@ #include #include -#include #include "os/file.h" #include "generic/callback.h" @@ -36,7 +35,7 @@ #define MRU_MAX 9 namespace { -GtkMenuItem *MRU_items[MRU_MAX]; +QAction *MRU_items[MRU_MAX]; std::size_t MRU_used; typedef CopiedString MRU_filename_t; MRU_filename_t MRU_filenames[MRU_MAX]; @@ -53,7 +52,7 @@ class EscapedMnemonic StringBuffer m_buffer; public: EscapedMnemonic( std::size_t capacity ) : m_buffer( capacity ){ - m_buffer.push_back( '_' ); + m_buffer.push_back( '&' ); } const char* c_str() const { return m_buffer.c_str(); @@ -64,8 +63,8 @@ public: std::size_t write( const char* buffer, std::size_t length ){ for ( const char* end = buffer + length; buffer != end; ++buffer ) { - if ( *buffer == '_' ) { - m_buffer.push_back( '_' ); + if ( *buffer == '&' ) { + m_buffer.push_back( '&' ); } m_buffer.push_back( *buffer ); @@ -82,8 +81,8 @@ inline EscapedMnemonic& operator<<( EscapedMnemonic& ostream, const T& t ){ void MRU_updateWidget( std::size_t index, const char *filename ){ EscapedMnemonic mnemonic( 64 ); - mnemonic << Unsigned( index + 1 ) << "- " << filename; - gtk_label_set_text_with_mnemonic( GTK_LABEL( gtk_bin_get_child( GTK_BIN( MRU_items[index] ) ) ), mnemonic.c_str() ); + mnemonic << index + 1 << "- " << filename; + MRU_items[index]->setText( mnemonic.c_str() ); } void MRU_SetText( std::size_t index, const char *filename ){ @@ -120,8 +119,8 @@ void MRU_AddFile( const char *str ){ MRU_SetText( i, MRU_GetText( i - 1 ) ); MRU_SetText( 0, str ); - gtk_widget_set_sensitive( GTK_WIDGET( MRU_items[0] ), TRUE ); - gtk_widget_show( GTK_WIDGET( MRU_items[MRU_used - 1] ) ); + MRU_items[0]->setEnabled( true ); + MRU_items[MRU_used - 1]->setVisible( true ); } void MRU_Init(){ @@ -130,13 +129,13 @@ void MRU_Init(){ } } -void MRU_AddWidget( GtkMenuItem *widget, std::size_t pos ){ +void MRU_AddWidget( QAction *widget, std::size_t pos ){ if ( pos < MRU_MAX ) { MRU_items[pos] = widget; if ( pos < MRU_used ) { MRU_updateWidget( pos, MRU_GetText( pos ) ); - gtk_widget_set_sensitive( GTK_WIDGET( MRU_items[0] ), TRUE ); - gtk_widget_show( GTK_WIDGET( MRU_items[pos] ) ); + MRU_items[0]->setEnabled( true ); + MRU_items[pos]->setVisible( true ); } } } @@ -158,12 +157,12 @@ void MRU_Activate( std::size_t index ){ MRU_SetText( i, MRU_GetText( i + 1 ) ); if ( MRU_used == 0 ) { - gtk_label_set_text( GTK_LABEL( gtk_bin_get_child( GTK_BIN( MRU_items[0] ) ) ), "Recent Files" ); - gtk_widget_set_sensitive( GTK_WIDGET( MRU_items[0] ), FALSE ); + MRU_items[0]->setText( "Recent Files" ); + MRU_items[0]->setEnabled( false ); } else { - gtk_widget_hide( GTK_WIDGET( MRU_items[MRU_used] ) ); + MRU_items[MRU_used]->setVisible( false ); } } } @@ -195,50 +194,50 @@ LoadMRU g_load_mru7( 7 ); LoadMRU g_load_mru8( 8 ); LoadMRU g_load_mru9( 9 ); -void MRU_constructMenu( GtkMenu* menu ){ +void MRU_constructMenu( QMenu* menu ){ { - GtkMenuItem* item = create_menu_item_with_mnemonic( menu, "_1", LoadMRUCaller( g_load_mru1 ) ); - gtk_widget_set_sensitive( GTK_WIDGET( item ), FALSE ); + QAction* item = create_menu_item_with_mnemonic( menu, "&1", LoadMRUCaller( g_load_mru1 ) ); + item->setEnabled( false ); MRU_AddWidget( item, 0 ); } { - GtkMenuItem* item = create_menu_item_with_mnemonic( menu, "_2", LoadMRUCaller( g_load_mru2 ) ); - gtk_widget_hide( GTK_WIDGET( item ) ); + QAction* item = create_menu_item_with_mnemonic( menu, "&2", LoadMRUCaller( g_load_mru2 ) ); + item->setVisible( false ); MRU_AddWidget( item, 1 ); } { - GtkMenuItem* item = create_menu_item_with_mnemonic( menu, "_3", LoadMRUCaller( g_load_mru3 ) ); - gtk_widget_hide( GTK_WIDGET( item ) ); + QAction* item = create_menu_item_with_mnemonic( menu, "&3", LoadMRUCaller( g_load_mru3 ) ); + item->setVisible( false ); MRU_AddWidget( item, 2 ); } { - GtkMenuItem* item = create_menu_item_with_mnemonic( menu, "_4", LoadMRUCaller( g_load_mru4 ) ); - gtk_widget_hide( GTK_WIDGET( item ) ); + QAction* item = create_menu_item_with_mnemonic( menu, "&4", LoadMRUCaller( g_load_mru4 ) ); + item->setVisible( false ); MRU_AddWidget( item, 3 ); } { - GtkMenuItem* item = create_menu_item_with_mnemonic( menu, "_5", LoadMRUCaller( g_load_mru5 ) ); - gtk_widget_hide( GTK_WIDGET( item ) ); + QAction* item = create_menu_item_with_mnemonic( menu, "&5", LoadMRUCaller( g_load_mru5 ) ); + item->setVisible( false ); MRU_AddWidget( item, 4 ); } { - GtkMenuItem* item = create_menu_item_with_mnemonic( menu, "_6", LoadMRUCaller( g_load_mru6 ) ); - gtk_widget_hide( GTK_WIDGET( item ) ); + QAction* item = create_menu_item_with_mnemonic( menu, "&6", LoadMRUCaller( g_load_mru6 ) ); + item->setVisible( false ); MRU_AddWidget( item, 5 ); } { - GtkMenuItem* item = create_menu_item_with_mnemonic( menu, "_7", LoadMRUCaller( g_load_mru7 ) ); - gtk_widget_hide( GTK_WIDGET( item ) ); + QAction* item = create_menu_item_with_mnemonic( menu, "&7", LoadMRUCaller( g_load_mru7 ) ); + item->setVisible( false ); MRU_AddWidget( item, 6 ); } { - GtkMenuItem* item = create_menu_item_with_mnemonic( menu, "_8", LoadMRUCaller( g_load_mru8 ) ); - gtk_widget_hide( GTK_WIDGET( item ) ); + QAction* item = create_menu_item_with_mnemonic( menu, "&8", LoadMRUCaller( g_load_mru8 ) ); + item->setVisible( false ); MRU_AddWidget( item, 7 ); } { - GtkMenuItem* item = create_menu_item_with_mnemonic( menu, "_9", LoadMRUCaller( g_load_mru9 ) ); - gtk_widget_hide( GTK_WIDGET( item ) ); + QAction* item = create_menu_item_with_mnemonic( menu, "&9", LoadMRUCaller( g_load_mru9 ) ); + item->setVisible( false ); MRU_AddWidget( item, 8 ); } } diff --git a/radiant/mru.h b/radiant/mru.h index 12a18a42..6978bd83 100644 --- a/radiant/mru.h +++ b/radiant/mru.h @@ -23,8 +23,7 @@ void MRU_AddFile( const char *str ); -typedef struct _GtkMenu GtkMenu; -void MRU_constructMenu( GtkMenu* menu ); +void MRU_constructMenu( class QMenu* menu ); void MRU_Construct(); void MRU_Destroy(); diff --git a/radiant/multimon.cpp b/radiant/multimon.cpp deleted file mode 100644 index 3cd472b2..00000000 --- a/radiant/multimon.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "multimon.h" - -#include "debugging/debugging.h" - -#include "gtkutil/window.h" -#include "preferences.h" - - -multimon_globals_t g_multimon_globals; - -//LatchedBool g_Multimon_enableSysMenuPopups( false, "Floating windows sysmenu icons" ); - -void MultiMonitor_constructPreferences( PreferencesPage& page ){ - //GtkWidget* primary_monitor = - page.appendCheckBox( "Multi Monitor", "Start on Primary Monitor", g_multimon_globals.m_bStartOnPrimMon ); -// GtkWidget* popup = page.appendCheckBox( -// "", "Disable system menu on popup windows", -// LatchedImportCaller( g_Multimon_enableSysMenuPopups ), -// BoolExportCaller( g_Multimon_enableSysMenuPopups.m_latched ) -// ); -// Widget_connectToggleDependency( popup, primary_monitor ); -} - -#include "preferencesystem.h" -#include "stringio.h" - -#include - -namespace -{ -GdkRectangle primaryMonitor; -} - -void PositionWindowOnPrimaryScreen( WindowPosition& position ){ - if ( position.w >= primaryMonitor.width - 12 ) { - position.w = primaryMonitor.width - 12; - } - if ( position.h >= primaryMonitor.height - 24 ) { - position.h = primaryMonitor.height - 48; - } - if ( position.x <= primaryMonitor.x || position.x + position.w >= ( primaryMonitor.x + primaryMonitor.width ) - 12 ) { - position.x = primaryMonitor.x + 6; - } - if ( position.y <= primaryMonitor.y || position.y + position.h >= ( primaryMonitor.y + primaryMonitor.height ) - 48 ) { - position.y = primaryMonitor.y + 24; - } -} - -void MultiMon_Construct(){ - // detect multiple monitors - - GdkScreen* screen = gdk_display_get_default_screen( gdk_display_get_default() ); - gint m = gdk_screen_get_n_monitors( screen ); - globalOutputStream() << "default screen has " << m << " monitors\n"; - for ( int j = 0; j != m; ++j ) - { - GdkRectangle geom; - gdk_screen_get_monitor_geometry( screen, j, &geom ); - globalOutputStream() << "monitor " << j << " geometry: " << geom.x << ", " << geom.y << ", " << geom.width << ", " << geom.height << "\n"; - if ( j == 0 ) { - // I am making the assumption that monitor 0 is always the primary monitor on win32. Tested on WinXP with gtk+-2.4. - primaryMonitor = geom; - } - } - - if ( m > 1 ) { - g_multimon_globals.m_bStartOnPrimMon = true; - } - - GlobalPreferenceSystem().registerPreference( "StartOnPrimMon", BoolImportStringCaller( g_multimon_globals.m_bStartOnPrimMon ), BoolExportStringCaller( g_multimon_globals.m_bStartOnPrimMon ) ); -// GlobalPreferenceSystem().registerPreference( "NoSysMenuPopups", makeBoolStringImportCallback( LatchedAssignCaller( g_Multimon_enableSysMenuPopups ) ), BoolExportStringCaller( g_Multimon_enableSysMenuPopups.m_latched ) ); - - PreferencesDialog_addInterfacePreferences( FreeCaller1() ); -} -void MultiMon_Destroy(){ -} diff --git a/radiant/patch.cpp b/radiant/patch.cpp index 627761ea..ae6920a7 100644 --- a/radiant/patch.cpp +++ b/radiant/patch.cpp @@ -153,9 +153,6 @@ void BezierCurveTree_FromCurveList( BezierCurveTree *pTree, std::forward_list> 1; @@ -1303,21 +1299,21 @@ void Patch::ConstructPrefab( const AABB& aabb, EPatchPrefab eType, int axis, std return; } - if ( eType != ePlane ) { + if ( eType != EPatchPrefab::Plane ) { vPos[0] = vector3_subtracted( aabb.origin, aabb.extents ); vPos[1] = aabb.origin; vPos[2] = vector3_added( aabb.origin, aabb.extents ); } - if ( eType == ePlane ) { + if ( eType == EPatchPrefab::Plane ) { constructPlane( aabb, axis, width, height ); } - else if ( eType == eSqCylinder - || eType == eCylinder - || eType == eDenseCylinder - || eType == eVeryDenseCylinder - || eType == eCone - || eType == eSphere ) { + else if ( eType == EPatchPrefab::SqCylinder + || eType == EPatchPrefab::Cylinder + || eType == EPatchPrefab::DenseCylinder + || eType == EPatchPrefab::VeryDenseCylinder + || eType == EPatchPrefab::Cone + || eType == EPatchPrefab::Sphere ) { unsigned char *pIndex; unsigned char pCylIndex[] = { @@ -1336,21 +1332,21 @@ void Patch::ConstructPrefab( const AABB& aabb, EPatchPrefab eType, int axis, std PatchControl *pStart; switch ( eType ) { - case eSqCylinder: + case EPatchPrefab::SqCylinder: setDims( 9, 3 ); pStart = m_ctrl.data(); break; - case eDenseCylinder: - case eVeryDenseCylinder: - case eCylinder: + case EPatchPrefab::DenseCylinder: + case EPatchPrefab::VeryDenseCylinder: + case EPatchPrefab::Cylinder: setDims( 9, 3 ); pStart = m_ctrl.data() + 1; break; - case eCone: + case EPatchPrefab::Cone: setDims( 9, 3 ); pStart = m_ctrl.data() + 1; break; - case eSphere: + case EPatchPrefab::Sphere: setDims( 9, 5 ); pStart = m_ctrl.data() + ( 9 + 1 ); break; @@ -1374,7 +1370,7 @@ void Patch::ConstructPrefab( const AABB& aabb, EPatchPrefab eType, int axis, std switch ( eType ) { - case eSqCylinder: + case EPatchPrefab::SqCylinder: { PatchControl* pCtrl = m_ctrl.data(); for ( std::size_t h = 0; h < 3; h++, pCtrl += 9 ) @@ -1383,9 +1379,9 @@ void Patch::ConstructPrefab( const AABB& aabb, EPatchPrefab eType, int axis, std } } break; - case eDenseCylinder: - case eVeryDenseCylinder: - case eCylinder: + case EPatchPrefab::DenseCylinder: + case EPatchPrefab::VeryDenseCylinder: + case EPatchPrefab::Cylinder: { PatchControl* pCtrl = m_ctrl.data(); for ( std::size_t h = 0; h < 3; h++, pCtrl += 9 ) @@ -1394,7 +1390,7 @@ void Patch::ConstructPrefab( const AABB& aabb, EPatchPrefab eType, int axis, std } } break; - case eCone: + case EPatchPrefab::Cone: { PatchControl* pCtrl = m_ctrl.data(); for ( std::size_t h = 0; h < 2; h++, pCtrl += 9 ) @@ -1412,7 +1408,7 @@ void Patch::ConstructPrefab( const AABB& aabb, EPatchPrefab eType, int axis, std } } break; - case eSphere: + case EPatchPrefab::Sphere: { PatchControl* pCtrl = m_ctrl.data() + 9; for ( std::size_t h = 0; h < 3; h++, pCtrl += 9 ) @@ -1444,7 +1440,7 @@ void Patch::ConstructPrefab( const AABB& aabb, EPatchPrefab eType, int axis, std return; } } - else if ( eType == eXactCylinder ) { + else if ( eType == EPatchPrefab::ExactCylinder ) { int n = ( width - 1 ) / 2; // n = number of segments setDims( width, height ); @@ -1470,7 +1466,7 @@ void Patch::ConstructPrefab( const AABB& aabb, EPatchPrefab eType, int axis, std } } } - else if ( eType == eXactCone ) { + else if ( eType == EPatchPrefab::ExactCone ) { int n = ( width - 1 ) / 2; // n = number of segments setDims( width, height ); @@ -1496,7 +1492,7 @@ void Patch::ConstructPrefab( const AABB& aabb, EPatchPrefab eType, int axis, std } } } - else if ( eType == eXactSphere ) { + else if ( eType == EPatchPrefab::ExactSphere ) { int n = ( width - 1 ) / 2; // n = number of segments (yaw) int m = ( height - 1 ) / 2; // m = number of segments (pitch) setDims( width, height ); @@ -1525,7 +1521,7 @@ void Patch::ConstructPrefab( const AABB& aabb, EPatchPrefab eType, int axis, std } } } - else if ( eType == eBevel ) { + else if ( eType == EPatchPrefab::Bevel ) { unsigned char *pIndex; unsigned char pBevIndex[] = { @@ -1548,7 +1544,7 @@ void Patch::ConstructPrefab( const AABB& aabb, EPatchPrefab eType, int axis, std } } } - else if ( eType == eEndCap ) { + else if ( eType == EPatchPrefab::EndCap ) { unsigned char *pIndex; unsigned char pEndIndex[] = { @@ -1574,16 +1570,16 @@ void Patch::ConstructPrefab( const AABB& aabb, EPatchPrefab eType, int axis, std } } - if ( eType == eDenseCylinder ) { + if ( eType == EPatchPrefab::DenseCylinder ) { InsertRemove( true, false, true ); } - if ( eType == eVeryDenseCylinder ) { + if ( eType == EPatchPrefab::VeryDenseCylinder ) { InsertRemove( true, false, false ); InsertRemove( true, false, true ); } - if ( eType == ePlane ) + if ( eType == EPatchPrefab::Plane ) CapTexture(); else NaturalTexture(); @@ -1592,21 +1588,21 @@ void Patch::ConstructPrefab( const AABB& aabb, EPatchPrefab eType, int axis, std void Patch::RenderDebug( RenderStateFlags state ) const { for ( std::size_t i = 0; i < m_tess.m_numStrips; i++ ) { - glBegin( GL_QUAD_STRIP ); + gl().glBegin( GL_QUAD_STRIP ); for ( std::size_t j = 0; j < m_tess.m_lenStrips; j++ ) { - glNormal3fv( normal3f_to_array( ( m_tess.m_vertices.data() + m_tess.m_indices[i * m_tess.m_lenStrips + j] )->normal ) ); - glTexCoord2fv( texcoord2f_to_array( ( m_tess.m_vertices.data() + m_tess.m_indices[i * m_tess.m_lenStrips + j] )->texcoord ) ); - glVertex3fv( vertex3f_to_array( ( m_tess.m_vertices.data() + m_tess.m_indices[i * m_tess.m_lenStrips + j] )->vertex ) ); + gl().glNormal3fv( normal3f_to_array( ( m_tess.m_vertices.data() + m_tess.m_indices[i * m_tess.m_lenStrips + j] )->normal ) ); + gl().glTexCoord2fv( texcoord2f_to_array( ( m_tess.m_vertices.data() + m_tess.m_indices[i * m_tess.m_lenStrips + j] )->texcoord ) ); + gl().glVertex3fv( vertex3f_to_array( ( m_tess.m_vertices.data() + m_tess.m_indices[i * m_tess.m_lenStrips + j] )->vertex ) ); } - glEnd(); + gl().glEnd(); } } void RenderablePatchSolid::RenderNormals() const { const std::size_t width = m_tess.m_numStrips + 1; const std::size_t height = m_tess.m_lenStrips >> 1; - glBegin( GL_LINES ); + gl().glBegin( GL_LINES ); for ( std::size_t i = 0; i < width; i++ ) { for ( std::size_t j = 0; j < height; j++ ) @@ -1618,8 +1614,8 @@ void RenderablePatchSolid::RenderNormals() const { vector3_scaled( normal3f_to_vector3( ( m_tess.m_vertices.data() + ( j * width + i ) )->normal ), 8 ) ) ); - glVertex3fv( vertex3f_to_array( ( m_tess.m_vertices.data() + ( j * width + i ) )->vertex ) ); - glVertex3fv( &vNormal[0] ); + gl().glVertex3fv( vertex3f_to_array( ( m_tess.m_vertices.data() + ( j * width + i ) )->vertex ) ); + gl().glVertex3fv( &vNormal[0] ); } { Vector3 vNormal( @@ -1628,8 +1624,8 @@ void RenderablePatchSolid::RenderNormals() const { vector3_scaled( normal3f_to_vector3( ( m_tess.m_vertices.data() + ( j * width + i ) )->tangent ), 8 ) ) ); - glVertex3fv( vertex3f_to_array( ( m_tess.m_vertices.data() + ( j * width + i ) )->vertex ) ); - glVertex3fv( &vNormal[0] ); + gl().glVertex3fv( vertex3f_to_array( ( m_tess.m_vertices.data() + ( j * width + i ) )->vertex ) ); + gl().glVertex3fv( &vNormal[0] ); } { Vector3 vNormal( @@ -1638,12 +1634,12 @@ void RenderablePatchSolid::RenderNormals() const { vector3_scaled( normal3f_to_vector3( ( m_tess.m_vertices.data() + ( j * width + i ) )->bitangent ), 8 ) ) ); - glVertex3fv( vertex3f_to_array( ( m_tess.m_vertices.data() + ( j * width + i ) )->vertex ) ); - glVertex3fv( &vNormal[0] ); + gl().glVertex3fv( vertex3f_to_array( ( m_tess.m_vertices.data() + ( j * width + i ) )->vertex ) ); + gl().glVertex3fv( &vNormal[0] ); } } } - glEnd(); + gl().glEnd(); } #define DEGEN_0a 0x01 diff --git a/radiant/patch.h b/radiant/patch.h index 271c3a43..aad3bac7 100644 --- a/radiant/patch.h +++ b/radiant/patch.h @@ -83,29 +83,29 @@ extern std::size_t MAX_PATCH_HEIGHT; #define MAX_PATCH_ROWCTRL ( ( ( MAX_PATCH_WIDTH - 1 ) - 1 ) / 2 ) #define MAX_PATCH_COLCTRL ( ( ( MAX_PATCH_HEIGHT - 1 ) - 1 ) / 2 ) -enum EPatchCap +enum class EPatchCap { - eCapBevel, - eCapEndCap, - eCapIBevel, - eCapIEndCap, - eCapCylinder, + Bevel, + EndCap, + IBevel, + IEndCap, + Cylinder, }; -enum EPatchPrefab +enum class EPatchPrefab { - ePlane, - eBevel, - eEndCap, - eCylinder, - eDenseCylinder, - eVeryDenseCylinder, - eSqCylinder, - eCone, - eSphere, - eXactCylinder, - eXactSphere, - eXactCone, + Plane, + Bevel, + EndCap, + Cylinder, + DenseCylinder, + VeryDenseCylinder, + SqCylinder, + Cone, + Sphere, + ExactCylinder, + ExactSphere, + ExactCone, }; enum EMatrixMajor @@ -213,22 +213,22 @@ public: void render( RenderStateFlags state ) const { { #if NV_DRIVER_BUG - glVertexPointer( 3, GL_FLOAT, 0, 0 ); - glDrawArrays( GL_TRIANGLE_FAN, 0, 0 ); + gl().glVertexPointer( 3, GL_FLOAT, 0, 0 ); + gl().glDrawArrays( GL_TRIANGLE_FAN, 0, 0 ); #endif std::size_t n = 0; - glVertexPointer( 3, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->vertex ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->vertex ); for ( std::size_t i = 0; i <= m_tess.m_curveTreeV.size(); ++i ) { - glDrawArrays( GL_LINE_STRIP, GLint( n ), GLsizei( m_tess.m_nArrayWidth ) ); + gl().glDrawArrays( GL_LINE_STRIP, GLint( n ), GLsizei( m_tess.m_nArrayWidth ) ); if ( i == m_tess.m_curveTreeV.size() ) { break; } if ( !BezierCurveTree_isLeaf( m_tess.m_curveTreeV[i] ) ) { - glDrawArrays( GL_LINE_STRIP, GLint( m_tess.m_curveTreeV[i]->index ), GLsizei( m_tess.m_nArrayWidth ) ); + gl().glDrawArrays( GL_LINE_STRIP, GLint( m_tess.m_curveTreeV[i]->index ), GLsizei( m_tess.m_nArrayWidth ) ); } n += ( m_tess.m_arrayHeight[i] * m_tess.m_nArrayWidth ); @@ -241,16 +241,16 @@ public: std::size_t n = m_tess.m_nArrayWidth * sizeof( ArbitraryMeshVertex ); for ( std::size_t i = 0; i <= m_tess.m_curveTreeU.size(); ++i ) { - glVertexPointer( 3, GL_FLOAT, GLsizei( n ), &p->vertex ); - glDrawArrays( GL_LINE_STRIP, 0, GLsizei( m_tess.m_nArrayHeight ) ); + gl().glVertexPointer( 3, GL_FLOAT, GLsizei( n ), &p->vertex ); + gl().glDrawArrays( GL_LINE_STRIP, 0, GLsizei( m_tess.m_nArrayHeight ) ); if ( i == m_tess.m_curveTreeU.size() ) { break; } if ( !BezierCurveTree_isLeaf( m_tess.m_curveTreeU[i] ) ) { - glVertexPointer( 3, GL_FLOAT, GLsizei( n ), &( m_tess.m_vertices.data() + ( m_tess.m_curveTreeU[i]->index ) )->vertex ); - glDrawArrays( GL_LINE_STRIP, 0, GLsizei( m_tess.m_nArrayHeight ) ); + gl().glVertexPointer( 3, GL_FLOAT, GLsizei( n ), &( m_tess.m_vertices.data() + ( m_tess.m_curveTreeU[i]->index ) )->vertex ); + gl().glDrawArrays( GL_LINE_STRIP, 0, GLsizei( m_tess.m_nArrayHeight ) ); } p += m_tess.m_arrayWidth[i]; @@ -266,11 +266,11 @@ public: RenderablePatchFixedWireframe( PatchTesselation& tess ) : m_tess( tess ){ } void render( RenderStateFlags state ) const { - glVertexPointer( 3, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->vertex ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->vertex ); const RenderIndex* strip_indices = m_tess.m_indices.data(); for ( std::size_t i = 0; i < m_tess.m_numStrips; i++, strip_indices += m_tess.m_lenStrips ) { - glDrawElements( GL_QUAD_STRIP, GLsizei( m_tess.m_lenStrips ), RenderIndexTypeID, strip_indices ); + gl().glDrawElements( GL_QUAD_STRIP, GLsizei( m_tess.m_lenStrips ), RenderIndexTypeID, strip_indices ); } } }; @@ -291,30 +291,21 @@ public: #endif { if ( ( state & RENDER_BUMP ) != 0 ) { - if ( GlobalShaderCache().useShaderLanguage() ) { - glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->normal ); - glVertexAttribPointerARB( c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->texcoord ); - glVertexAttribPointerARB( c_attr_Tangent, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->tangent ); - glVertexAttribPointerARB( c_attr_Binormal, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->bitangent ); - } - else - { - glVertexAttribPointerARB( 11, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->normal ); - glVertexAttribPointerARB( 8, 2, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->texcoord ); - glVertexAttribPointerARB( 9, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->tangent ); - glVertexAttribPointerARB( 10, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->bitangent ); - } + gl().glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->normal ); + gl().glVertexAttribPointer( c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->texcoord ); + gl().glVertexAttribPointer( c_attr_Tangent, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->tangent ); + gl().glVertexAttribPointer( c_attr_Binormal, 3, GL_FLOAT, 0, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->bitangent ); } else { - glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->normal ); - glTexCoordPointer( 2, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->texcoord ); + gl().glNormalPointer( GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->normal ); + gl().glTexCoordPointer( 2, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->texcoord ); } - glVertexPointer( 3, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->vertex ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( ArbitraryMeshVertex ), &m_tess.m_vertices.data()->vertex ); const RenderIndex* strip_indices = m_tess.m_indices.data(); for ( std::size_t i = 0; i < m_tess.m_numStrips; i++, strip_indices += m_tess.m_lenStrips ) { - glDrawElements( GL_QUAD_STRIP, GLsizei( m_tess.m_lenStrips ), RenderIndexTypeID, strip_indices ); + gl().glDrawElements( GL_QUAD_STRIP, GLsizei( m_tess.m_lenStrips ), RenderIndexTypeID, strip_indices ); } } @@ -468,7 +459,6 @@ private: public: Callback m_lightsChanged; -//static int m_CycleCapIndex; // = 0; static EPatchType m_type; STRING_CONSTANT( Name, "Patch" ); @@ -1627,7 +1617,7 @@ public: } if ( m_dragPlanes.isSelected() ) { // this should only be true when the transform is a pure translation. - m_patch.transform( m_dragPlanes.evaluateTransform( vector4_to_vector3( matrix.t() ) ) ); + m_patch.transform( m_dragPlanes.evaluateTransform( matrix.t().vec3() ) ); } } diff --git a/radiant/patchdialog.cpp b/radiant/patchdialog.cpp index 0fb023a3..0c5ffe73 100644 --- a/radiant/patchdialog.cpp +++ b/radiant/patchdialog.cpp @@ -19,8 +19,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -// -// Patch Dialog // // Leonardo Zide (leo@lokigames.com) // @@ -31,42 +29,17 @@ #include "debugging/debugging.h" -#include - -#include "gtkutil/idledraw.h" -#include "gtkutil/entry.h" -#include "gtkutil/button.h" +#include +#include +#include "gtkutil/spinbox.h" #include "gtkutil/nonmodal.h" #include "dialog.h" #include "gtkdlgs.h" #include "mainframe.h" #include "patchmanip.h" #include "patch.h" -#include "commands.h" -#include "preferences.h" -#include "signal/isignal.h" -#include - -// the increment we are using for the patch inspector (this is saved in the prefs) -struct pi_globals_t -{ - float shift[2]; - float scale[2]; - float rotate; - - pi_globals_t(){ - shift[0] = 8.0f; - shift[1] = 8.0f; - scale[0] = 0.5f; - scale[1] = 0.5f; - rotate = 45.0f; - } -}; - -pi_globals_t g_pi_globals; - class PatchFixedSubdivisions { public: @@ -137,51 +110,27 @@ void Scene_PatchGetFixedSubdivisions( PatchFixedSubdivisions& subdivisions ){ #endif } -class PatchSetFixedSubdivisions -{ - const PatchFixedSubdivisions& m_subdivisions; -public: - PatchSetFixedSubdivisions( const PatchFixedSubdivisions& subdivisions ) : m_subdivisions( subdivisions ){ - } - void operator()( Patch& patch ) const { - Patch_setFixedSubdivisions( patch, m_subdivisions ); - } -}; - void Scene_PatchSetFixedSubdivisions( const PatchFixedSubdivisions& subdivisions ){ UndoableCommand command( "patchSetFixedSubdivisions" ); - Scene_forEachVisibleSelectedPatch( PatchSetFixedSubdivisions( subdivisions ) ); + Scene_forEachVisibleSelectedPatch( [subdivisions]( Patch& patch ){ Patch_setFixedSubdivisions( patch, subdivisions ); } ); } -typedef struct _GtkCheckButton GtkCheckButton; - class Subdivisions { public: - GtkCheckButton* m_enabled; - GtkEntry* m_horizontal; - GtkEntry* m_vertical; + QGroupBox* m_enabled; + NonModalSpinner* m_horizontal; + NonModalSpinner* m_vertical; Subdivisions() : m_enabled( 0 ), m_horizontal( 0 ), m_vertical( 0 ){ } void update(){ PatchFixedSubdivisions subdivisions; Scene_PatchGetFixedSubdivisions( subdivisions ); - toggle_button_set_active_no_signal( GTK_TOGGLE_BUTTON( m_enabled ), subdivisions.m_enabled ); + m_enabled->setChecked( subdivisions.m_enabled ); - if ( subdivisions.m_enabled ) { - entry_set_int( m_horizontal, static_cast( subdivisions.m_x ) ); - entry_set_int( m_vertical, static_cast( subdivisions.m_y ) ); - gtk_widget_set_sensitive( GTK_WIDGET( m_horizontal ), TRUE ); - gtk_widget_set_sensitive( GTK_WIDGET( m_vertical ), TRUE ); - } - else - { - gtk_entry_set_text( m_horizontal, "" ); - gtk_entry_set_text( m_vertical, "" ); - gtk_widget_set_sensitive( GTK_WIDGET( m_horizontal ), FALSE ); - gtk_widget_set_sensitive( GTK_WIDGET( m_vertical ), FALSE ); - } + m_horizontal->setValue( subdivisions.m_x ); + m_vertical->setValue( subdivisions.m_y ); } void cancel(){ update(); @@ -190,234 +139,64 @@ public: void apply(){ Scene_PatchSetFixedSubdivisions( PatchFixedSubdivisions( - gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( m_enabled ) ), - static_cast( entry_get_int( m_horizontal ) ), - static_cast( entry_get_int( m_vertical ) ) + m_enabled->isChecked(), + static_cast( m_horizontal->value() ), + static_cast( m_vertical->value() ) ) ); } typedef MemberCaller ApplyCaller; - static void applyGtk( GtkToggleButton* toggle, Subdivisions* self ){ - self->apply(); - } }; -class PatchInspector : public Dialog -{ - GtkWindow* BuildDialog(); - Subdivisions m_subdivisions; - NonModalEntry m_horizontalSubdivisionsEntry; - NonModalEntry m_verticalSubdivisionsEntry; -public: - IdleDraw m_idleDraw; - WindowPositionTracker m_position_tracker; - Patch *m_Patch; - CopiedString m_strName; - float m_fS; - float m_fT; - float m_fX; - float m_fY; - float m_fZ; - /* float m_fHScale; - float m_fHShift; - float m_fRotate; - float m_fVScale; - float m_fVShift; */ - int m_nCol; - int m_nRow; - GtkComboBoxText *m_pRowCombo; - GtkComboBoxText *m_pColCombo; - std::size_t m_countRows; - std::size_t m_countCols; +static Subdivisions *g_subdivisions; -// turn on/off processing of the "changed" "value_changed" messages -// (need to turn off when we are feeding data in) -// NOTE: much more simple than blocking signals - bool m_bListenChanged; +QGroupBox* patch_tesselation_create(){ + g_subdivisions = new Subdivisions; - PatchInspector() : - m_horizontalSubdivisionsEntry( Subdivisions::ApplyCaller( m_subdivisions ), Subdivisions::CancelCaller( m_subdivisions ) ), - m_verticalSubdivisionsEntry( Subdivisions::ApplyCaller( m_subdivisions ), Subdivisions::CancelCaller( m_subdivisions ) ), - m_idleDraw( MemberCaller( *this ) ){ - m_fS = 0.0f; - m_fT = 0.0f; - m_fX = 0.0f; - m_fY = 0.0f; - m_fZ = 0.0f; - m_nCol = 0; - m_nRow = 0; - m_countRows = 0; - m_countCols = 0; - m_Patch = 0; - m_bListenChanged = true; + auto *frame = g_subdivisions->m_enabled = new QGroupBox( "Fixed Tesselation" ); - m_position_tracker.setPosition( c_default_window_pos ); - } + auto *hbox = new QHBoxLayout( frame ); + hbox->setContentsMargins( 0, 0, 0, 0 ); - bool visible(){ - return gtk_widget_get_visible( GTK_WIDGET( GetWidget() ) ); - } + auto *hspin = g_subdivisions->m_horizontal = new NonModalSpinner( 1, MAX_PATCH_SUBDIVISIONS, 4, 0, 1 ); + hspin->setCallbacks( Subdivisions::ApplyCaller( *g_subdivisions ), Subdivisions::CancelCaller( *g_subdivisions ) ); + auto *wlabel = new SpinBoxLabel( "H", hspin ); + hbox->addWidget( wlabel, 0, Qt::AlignmentFlag::AlignRight ); + hbox->addWidget( hspin, 0, Qt::AlignmentFlag::AlignLeft ); -// void UpdateInfo(); -// void SetPatchInfo(); - void GetPatchInfo(); - void UpdateSpinners( bool bUp, int nID ); -// read the current patch on map and initialize m_fX m_fY accordingly - void UpdateRowColInfo(); -// sync the dialog our internal data structures -// depending on the flag it will read or write -// we use m_nCol m_nRow m_fX m_fY m_fZ m_fS m_fT m_strName -// (NOTE: this doesn't actually commit stuff to the map or read from it) - void importData(); - void exportData(); -}; + auto *vspin = g_subdivisions->m_vertical = new NonModalSpinner( 1, MAX_PATCH_SUBDIVISIONS, 4, 0, 1 ); + vspin->setCallbacks( Subdivisions::ApplyCaller( *g_subdivisions ), Subdivisions::CancelCaller( *g_subdivisions ) ); + auto *hlabel = new SpinBoxLabel( "V", vspin ); + hbox->addWidget( hlabel, 0, Qt::AlignmentFlag::AlignRight ); + hbox->addWidget( vspin, 0, Qt::AlignmentFlag::AlignLeft ); -PatchInspector g_PatchInspector; + QObject::connect( frame, &QGroupBox::toggled, [hspin, wlabel, vspin, hlabel]( bool on ){ + hspin->setVisible( on ); + wlabel->setVisible( on ); + vspin->setVisible( on ); + hlabel->setVisible( on ); + } ); + frame->setCheckable( true ); + frame->setChecked( false ); + QObject::connect( frame, &QGroupBox::clicked, Subdivisions::ApplyCaller( *g_subdivisions ) ); -void PatchInspector_constructWindow( GtkWindow* main_window ){ - g_PatchInspector.m_parent = main_window; - g_PatchInspector.Create(); -} -void PatchInspector_destroyWindow(){ - g_PatchInspector.Destroy(); + return frame; } -void PatchInspector_queueDraw(){ - if ( g_PatchInspector.visible() ) { - g_PatchInspector.m_idleDraw.queueDraw(); +void patch_tesselation_update(){ + if( g_subdivisions != nullptr ){ + g_subdivisions->update(); } } -void DoPatchInspector(){ - g_PatchInspector.GetPatchInfo(); - if ( !g_PatchInspector.visible() ) { - g_PatchInspector.ShowDlg(); - } -} - -void PatchInspector_toggleShown(){ - if ( g_PatchInspector.visible() ) { - g_PatchInspector.m_Patch = 0; - g_PatchInspector.HideDlg(); - } - else{ - DoPatchInspector(); - } -} - - -// ============================================================================= -// static functions - -// memorize the current state (that is don't try to undo our do before changing something else) -static void OnApply( GtkWidget *widget, gpointer data ){ - g_PatchInspector.exportData(); - if ( g_PatchInspector.m_Patch != 0 ) { - UndoableCommand command( "patchSetTexture" ); - g_PatchInspector.m_Patch->undoSave(); - - if ( !texdef_name_valid( g_PatchInspector.m_strName.c_str() ) ) { - globalErrorStream() << "invalid texture name '" << g_PatchInspector.m_strName << "'\n"; - g_PatchInspector.m_strName = texdef_name_default(); - } - g_PatchInspector.m_Patch->SetShader( g_PatchInspector.m_strName.c_str() ); - - std::size_t r = g_PatchInspector.m_nRow; - std::size_t c = g_PatchInspector.m_nCol; - if ( r < g_PatchInspector.m_Patch->getHeight() - && c < g_PatchInspector.m_Patch->getWidth() ) { - PatchControl& p = g_PatchInspector.m_Patch->ctrlAt( r,c ); - p.m_vertex[0] = g_PatchInspector.m_fX; - p.m_vertex[1] = g_PatchInspector.m_fY; - p.m_vertex[2] = g_PatchInspector.m_fZ; - p.m_texcoord[0] = g_PatchInspector.m_fS; - p.m_texcoord[1] = g_PatchInspector.m_fT; - g_PatchInspector.m_Patch->controlPointsChanged(); - } - } -} - -static void OnSelchangeComboColRow( GtkWidget *widget, gpointer data ){ - if ( !g_PatchInspector.m_bListenChanged ) { - return; - } - // retrieve the current m_nRow and m_nCol, other params are not relevant - g_PatchInspector.exportData(); - // read the changed values ourselves - g_PatchInspector.UpdateRowColInfo(); - // now reflect our changes - g_PatchInspector.importData(); -} - -class PatchSetTextureRepeat -{ - float m_s, m_t; -public: - PatchSetTextureRepeat( float s, float t ) : m_s( s ), m_t( t ){ - } - void operator()( Patch& patch ) const { - patch.SetTextureRepeat( m_s, m_t ); - } -}; - -void Scene_PatchTileTexture_Selected( scene::Graph& graph, float s, float t ){ - Scene_forEachVisibleSelectedPatch( PatchSetTextureRepeat( s, t ) ); - SceneChangeNotify(); -} - -static void OnBtnPatchCap( GtkWidget *widget, gpointer data ){ - Patch_CapTexture(); -} - -static void OnBtnPatchFit11( GtkWidget *widget, gpointer data ){ - Patch_FitTexture11(); -} - -static void OnBtnPatchNatural( GtkWidget *widget, gpointer data ){ - Patch_NaturalTexture(); -} - -static void OnBtnPatchFit( GtkWidget *widget, gpointer data ){ - Patch_FitTexture(); -} - -static void OnBtnPatchFlipX( GtkWidget *widget, gpointer data ){ - Patch_FlipTextureX(); -} - -static void OnBtnPatchFlipY( GtkWidget *widget, gpointer data ){ - Patch_FlipTextureY(); -} - -struct PatchRotateTexture -{ - float m_angle; -public: - PatchRotateTexture( float angle ) : m_angle( angle ){ - } - void operator()( Patch& patch ) const { - patch.RotateTexture( m_angle ); - } -}; void Scene_PatchRotateTexture_Selected( scene::Graph& graph, float angle ){ - Scene_forEachVisibleSelectedPatch( PatchRotateTexture( angle ) ); + Scene_forEachVisibleSelectedPatch( [angle]( Patch& patch ){ patch.RotateTexture( angle ); } ); } -class PatchScaleTexture -{ - float m_s, m_t; -public: - PatchScaleTexture( float s, float t ) : m_s( s ), m_t( t ){ - } - void operator()( Patch& patch ) const { - patch.ScaleTexture( m_s, m_t ); - } -}; - -float Patch_convertScale( float scale ){ +inline float Patch_convertScale( float scale ){ if ( scale > 0 ) { return scale; } @@ -428,731 +207,9 @@ float Patch_convertScale( float scale ){ } void Scene_PatchScaleTexture_Selected( scene::Graph& graph, float s, float t ){ - Scene_forEachVisibleSelectedPatch( PatchScaleTexture( Patch_convertScale( s ), Patch_convertScale( t ) ) ); + Scene_forEachVisibleSelectedPatch( [s = Patch_convertScale( s ), t = Patch_convertScale( t )]( Patch& patch ){ patch.ScaleTexture( s, t ); } ); } -class PatchTranslateTexture -{ - float m_s, m_t; -public: - PatchTranslateTexture( float s, float t ) - : m_s( s ), m_t( t ){ - } - void operator()( Patch& patch ) const { - patch.TranslateTexture( m_s, m_t ); - } -}; - void Scene_PatchTranslateTexture_Selected( scene::Graph& graph, float s, float t ){ - Scene_forEachVisibleSelectedPatch( PatchTranslateTexture( s, t ) ); -} - -static void OnSpinChanged( GtkAdjustment *adj, gpointer data ){ - texdef_t td; - - td.rotate = 0; - td.scale[0] = td.scale[1] = 0; - td.shift[0] = td.shift[1] = 0; - - if ( gtk_adjustment_get_value( adj ) == 0 ) { - return; - } - - if ( adj == g_object_get_data( G_OBJECT( g_PatchInspector.GetWidget() ), "hshift_adj" ) ) { - g_pi_globals.shift[0] = static_cast( atof( gtk_entry_get_text( GTK_ENTRY( data ) ) ) ); - - if ( gtk_adjustment_get_value( adj ) > 0 ) { - td.shift[0] = g_pi_globals.shift[0]; - } - else{ - td.shift[0] = -g_pi_globals.shift[0]; - } - } - else if ( adj == g_object_get_data( G_OBJECT( g_PatchInspector.GetWidget() ), "vshift_adj" ) ) { - g_pi_globals.shift[1] = static_cast( atof( gtk_entry_get_text( GTK_ENTRY( data ) ) ) ); - - if ( gtk_adjustment_get_value( adj ) > 0 ) { - td.shift[1] = g_pi_globals.shift[1]; - } - else{ - td.shift[1] = -g_pi_globals.shift[1]; - } - } - else if ( adj == g_object_get_data( G_OBJECT( g_PatchInspector.GetWidget() ), "hscale_adj" ) ) { - g_pi_globals.scale[0] = static_cast( atof( gtk_entry_get_text( GTK_ENTRY( data ) ) ) ); - if ( g_pi_globals.scale[0] == 0.0f ) { - return; - } - if ( gtk_adjustment_get_value( adj ) > 0 ) { - td.scale[0] = g_pi_globals.scale[0]; - } - else{ - td.scale[0] = -g_pi_globals.scale[0]; - } - } - else if ( adj == g_object_get_data( G_OBJECT( g_PatchInspector.GetWidget() ), "vscale_adj" ) ) { - g_pi_globals.scale[1] = static_cast( atof( gtk_entry_get_text( GTK_ENTRY( data ) ) ) ); - if ( g_pi_globals.scale[1] == 0.0f ) { - return; - } - if ( gtk_adjustment_get_value( adj ) > 0 ) { - td.scale[1] = g_pi_globals.scale[1]; - } - else{ - td.scale[1] = -g_pi_globals.scale[1]; - } - } - else if ( adj == g_object_get_data( G_OBJECT( g_PatchInspector.GetWidget() ), "rotate_adj" ) ) { - g_pi_globals.rotate = static_cast( atof( gtk_entry_get_text( GTK_ENTRY( data ) ) ) ); - - if ( gtk_adjustment_get_value( adj ) > 0 ) { - td.rotate = g_pi_globals.rotate; - } - else{ - td.rotate = -g_pi_globals.rotate; - } - } - - gtk_adjustment_set_value( adj, 0 ); - - // will scale shift rotate the patch accordingly - - - if ( td.shift[0] || td.shift[1] ) { - UndoableCommand command( "patchTranslateTexture" ); - Scene_PatchTranslateTexture_Selected( GlobalSceneGraph(), td.shift[0], td.shift[1] ); - } - else if ( td.scale[0] || td.scale[1] ) { - UndoableCommand command( "patchScaleTexture" ); - Scene_PatchScaleTexture_Selected( GlobalSceneGraph(), td.scale[0], td.scale[1] ); - } - else if ( td.rotate ) { - UndoableCommand command( "patchRotateTexture" ); - Scene_PatchRotateTexture_Selected( GlobalSceneGraph(), td.rotate ); - } - - // update the point-by-point view - OnSelchangeComboColRow( 0,0 ); -} - -static gint OnDialogKey( GtkWidget* widget, GdkEventKey* event, gpointer data ){ - if ( event->keyval == GDK_KEY_Return ) { - OnApply( 0, 0 ); - return TRUE; - } - else if ( event->keyval == GDK_KEY_Escape ) { - g_PatchInspector.GetPatchInfo(); - return TRUE; - } - return FALSE; -} - -// ============================================================================= -// PatchInspector class - -GtkWindow* PatchInspector::BuildDialog(){ - GtkWindow* window = create_floating_window( "Patch Properties", m_parent ); - - m_position_tracker.connect( window ); - - global_accel_connect_window( window ); - - window_connect_focus_in_clear_focus_widget( window ); - - - { - GtkVBox* vbox = GTK_VBOX( gtk_vbox_new( FALSE, 5 ) ); - gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 ); - gtk_widget_show( GTK_WIDGET( vbox ) ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox ) ); - { - GtkHBox* hbox = GTK_HBOX( gtk_hbox_new( FALSE, 5 ) ); - gtk_widget_show( GTK_WIDGET( hbox ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox ), TRUE, TRUE, 0 ); - { - GtkVBox* vbox2 = GTK_VBOX( gtk_vbox_new( FALSE, 0 ) ); - gtk_container_set_border_width( GTK_CONTAINER( vbox2 ), 0 ); - gtk_widget_show( GTK_WIDGET( vbox2 ) ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox2 ), TRUE, TRUE, 0 ); - { - GtkFrame* frame = GTK_FRAME( gtk_frame_new( "Details" ) ); - gtk_widget_show( GTK_WIDGET( frame ) ); - gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( frame ), TRUE, TRUE, 0 ); - { - GtkVBox* vbox3 = GTK_VBOX( gtk_vbox_new( FALSE, 5 ) ); - gtk_container_set_border_width( GTK_CONTAINER( vbox3 ), 5 ); - gtk_widget_show( GTK_WIDGET( vbox3 ) ); - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( vbox3 ) ); - { - GtkTable* table = GTK_TABLE( gtk_table_new( 2, 2, FALSE ) ); - gtk_widget_show( GTK_WIDGET( table ) ); - gtk_box_pack_start( GTK_BOX( vbox3 ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - gtk_table_set_row_spacings( table, 5 ); - gtk_table_set_col_spacings( table, 5 ); - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Row:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 0, 1, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Column:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 1, 2, 0, 1, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - } - { - GtkComboBoxText* combo = m_pRowCombo = GTK_COMBO_BOX_TEXT( gtk_combo_box_text_new() ); - g_signal_connect( G_OBJECT( combo ), "changed", G_CALLBACK( OnSelchangeComboColRow ), this ); - AddDialogData( *GTK_COMBO_BOX( combo ), m_nRow ); - - gtk_widget_show( GTK_WIDGET( combo ) ); - gtk_table_attach( table, GTK_WIDGET( combo ), 0, 1, 1, 2, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( combo ), 60, -1 ); - } - - { - GtkComboBoxText* combo = m_pColCombo = GTK_COMBO_BOX_TEXT( gtk_combo_box_text_new() ); - g_signal_connect( G_OBJECT( combo ), "changed", G_CALLBACK( OnSelchangeComboColRow ), this ); - AddDialogData( *GTK_COMBO_BOX( combo ), m_nCol ); - - gtk_widget_show( GTK_WIDGET( combo ) ); - gtk_table_attach( table, GTK_WIDGET( combo ), 1, 2, 1, 2, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( combo ), 60, -1 ); - } - } - GtkTable* table = GTK_TABLE( gtk_table_new( 5, 2, FALSE ) ); - gtk_widget_show( GTK_WIDGET( table ) ); - gtk_box_pack_start( GTK_BOX( vbox3 ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - gtk_table_set_row_spacings( table, 5 ); - gtk_table_set_col_spacings( table, 5 ); - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "X:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 0, 1, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Y:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 1, 2, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Z:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 2, 3, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "S:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 3, 4, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "T:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 4, 5, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 0, 1, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - AddDialogData( *entry, m_fX ); - - g_signal_connect( G_OBJECT( entry ), "key_press_event", G_CALLBACK( OnDialogKey ), 0 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 1, 2, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - AddDialogData( *entry, m_fY ); - - g_signal_connect( G_OBJECT( entry ), "key_press_event", G_CALLBACK( OnDialogKey ), 0 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 2, 3, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - AddDialogData( *entry, m_fZ ); - - g_signal_connect( G_OBJECT( entry ), "key_press_event", G_CALLBACK( OnDialogKey ), 0 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 3, 4, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - AddDialogData( *entry, m_fS ); - - g_signal_connect( G_OBJECT( entry ), "key_press_event", G_CALLBACK( OnDialogKey ), 0 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 4, 5, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - AddDialogData( *entry, m_fT ); - - g_signal_connect( G_OBJECT( entry ), "key_press_event", G_CALLBACK( OnDialogKey ), 0 ); - } - } - } - if ( g_pGameDescription->mGameType == "doom3" ) { - GtkFrame* frame = GTK_FRAME( gtk_frame_new( "Tesselation" ) ); - gtk_widget_show( GTK_WIDGET( frame ) ); - gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( frame ), TRUE, TRUE, 0 ); - { - GtkVBox* vbox3 = GTK_VBOX( gtk_vbox_new( FALSE, 5 ) ); - gtk_container_set_border_width( GTK_CONTAINER( vbox3 ), 5 ); - gtk_widget_show( GTK_WIDGET( vbox3 ) ); - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( vbox3 ) ); - { - GtkTable* table = GTK_TABLE( gtk_table_new( 3, 2, FALSE ) ); - gtk_widget_show( GTK_WIDGET( table ) ); - gtk_box_pack_start( GTK_BOX( vbox3 ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - gtk_table_set_row_spacings( table, 5 ); - gtk_table_set_col_spacings( table, 5 ); - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Fixed" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 0, 1, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - } - { - GtkCheckButton* check = GTK_CHECK_BUTTON( gtk_check_button_new() ); - gtk_widget_show( GTK_WIDGET( check ) ); - gtk_table_attach( table, GTK_WIDGET( check ), 1, 2, 0, 1, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - m_subdivisions.m_enabled = check; - guint handler_id = g_signal_connect( G_OBJECT( check ), "toggled", G_CALLBACK( &Subdivisions::applyGtk ), &m_subdivisions ); - g_object_set_data( G_OBJECT( check ), "handler", gint_to_pointer( handler_id ) ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Horizontal" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 1, 2, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 1, 2, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - m_subdivisions.m_horizontal = entry; - m_horizontalSubdivisionsEntry.connect( entry ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Vertical" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 2, 3, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 2, 3, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - m_subdivisions.m_vertical = entry; - m_verticalSubdivisionsEntry.connect( entry ); - } - } - } - } - } - { - GtkFrame* frame = GTK_FRAME( gtk_frame_new( "Texturing" ) ); - gtk_widget_show( GTK_WIDGET( frame ) ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( frame ), TRUE, TRUE, 0 ); - { - GtkVBox* vbox2 = GTK_VBOX( gtk_vbox_new( FALSE, 5 ) ); - gtk_widget_show( GTK_WIDGET( vbox2 ) ); - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( vbox2 ) ); - gtk_container_set_border_width( GTK_CONTAINER( vbox2 ), 5 ); - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Name:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( label ), TRUE, TRUE, 0 ); - gtk_label_set_justify( label, GTK_JUSTIFY_LEFT ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - // gtk_editable_set_editable( GTK_EDITABLE( entry ), FALSE ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( entry ), TRUE, TRUE, 0 ); - AddDialogData( *entry, m_strName ); - - g_signal_connect( G_OBJECT( entry ), "key_press_event", G_CALLBACK( OnDialogKey ), 0 ); - } - { - GtkTable* table = GTK_TABLE( gtk_table_new( 5, 4, FALSE ) ); - gtk_widget_show( GTK_WIDGET( table ) ); - gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - gtk_table_set_row_spacings( table, 5 ); - gtk_table_set_col_spacings( table, 5 ); - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Horizontal Shift Step" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 2, 4, 0, 1, - (GtkAttachOptions)( GTK_FILL|GTK_EXPAND ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Vertical Shift Step" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 2, 4, 1, 2, - (GtkAttachOptions)( GTK_FILL|GTK_EXPAND ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Horizontal Stretch Step" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 2, 3, 2, 3, - (GtkAttachOptions)( GTK_FILL|GTK_EXPAND ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - { - GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "FlipX" ) ); - gtk_widget_show( GTK_WIDGET( button ) ); - gtk_table_attach( table, GTK_WIDGET( button ), 3, 4, 2, 3, - (GtkAttachOptions)( GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( OnBtnPatchFlipX ), 0 ); - gtk_widget_set_size_request( GTK_WIDGET( button ), 60, -1 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Vertical Stretch Step" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 2, 3, 3, 4, - (GtkAttachOptions)( GTK_FILL|GTK_EXPAND ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - { - GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "FlipY" ) ); - gtk_widget_show( GTK_WIDGET( button ) ); - gtk_table_attach( table, GTK_WIDGET( button ), 3, 4, 3, 4, - (GtkAttachOptions)( GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( OnBtnPatchFlipY ), 0 ); - gtk_widget_set_size_request( GTK_WIDGET( button ), 60, -1 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Rotate Step" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 2, 4, 4, 5, - (GtkAttachOptions)( GTK_FILL|GTK_EXPAND ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 0, 1, 0, 1, - (GtkAttachOptions)( GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 ); - g_object_set_data( G_OBJECT( window ), "hshift_entry", entry ); - // we fill in this data, if no patch is selected the widgets are unmodified when the inspector is raised - // so we need to have at least one initialisation somewhere - entry_set_float( entry, g_pi_globals.shift[0] ); - - GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0, -8192, 8192, 1, 1, 0 ) ); - g_signal_connect( G_OBJECT( adj ), "value_changed", G_CALLBACK( OnSpinChanged ), entry ); - g_object_set_data( G_OBJECT( window ), "hshift_adj", adj ); - - GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( adj, 1, 0 ) ); - gtk_widget_show( GTK_WIDGET( spin ) ); - gtk_table_attach( table, GTK_WIDGET( spin ), 1, 2, 0, 1, - (GtkAttachOptions)( 0 ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( spin ), 16, -1 ); - gtk_widget_set_can_focus( GTK_WIDGET( spin ), FALSE ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 0, 1, 1, 2, - (GtkAttachOptions)( GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 ); - entry_set_float( entry, g_pi_globals.shift[1] ); - - GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0, -8192, 8192, 1, 1, 0 ) ); - g_signal_connect( G_OBJECT( adj ), "value_changed", G_CALLBACK( OnSpinChanged ), entry ); - g_object_set_data( G_OBJECT( window ), "vshift_adj", adj ); - - GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( adj, 1, 0 ) ); - gtk_widget_show( GTK_WIDGET( spin ) ); - gtk_table_attach( table, GTK_WIDGET( spin ), 1, 2, 1, 2, - (GtkAttachOptions)( 0 ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( spin ), 16, -1 ); - gtk_widget_set_can_focus( GTK_WIDGET( spin ), FALSE ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 0, 1, 2, 3, - (GtkAttachOptions)( GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 ); - entry_set_float( entry, g_pi_globals.scale[0] ); - - GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0, -1000, 1000, 1, 1, 0 ) ); - g_signal_connect( G_OBJECT( adj ), "value_changed", G_CALLBACK( OnSpinChanged ), entry ); - g_object_set_data( G_OBJECT( window ), "hscale_adj", adj ); - - GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( adj, 1, 0 ) ); - gtk_widget_show( GTK_WIDGET( spin ) ); - gtk_table_attach( table, GTK_WIDGET( spin ), 1, 2, 2, 3, - (GtkAttachOptions)( 0 ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( spin ), 16, -1 ); - gtk_widget_set_can_focus( GTK_WIDGET( spin ), FALSE ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 0, 1, 3, 4, - (GtkAttachOptions)( GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 ); - entry_set_float( entry, g_pi_globals.scale[1] ); - - GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0, -1000, 1000, 1, 1, 0 ) ); - g_signal_connect( G_OBJECT( adj ), "value_changed", G_CALLBACK( OnSpinChanged ), entry ); - g_object_set_data( G_OBJECT( window ), "vscale_adj", adj ); - - GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( adj, 1, 0 ) ); - gtk_widget_show( GTK_WIDGET( spin ) ); - gtk_table_attach( table, GTK_WIDGET( spin ), 1, 2, 3, 4, - (GtkAttachOptions)( 0 ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( spin ), 16, -1 ); - gtk_widget_set_can_focus( GTK_WIDGET( spin ), FALSE ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( table, GTK_WIDGET( entry ), 0, 1, 4, 5, - (GtkAttachOptions)( GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 ); - entry_set_float( entry, g_pi_globals.rotate ); - - GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0, -1000, 1000, 1, 1, 0 ) ); // NOTE: Arnout - this really should be 360 but can't change it anymore as it could break existing maps - g_signal_connect( G_OBJECT( adj ), "value_changed", G_CALLBACK( OnSpinChanged ), entry ); - g_object_set_data( G_OBJECT( window ), "rotate_adj", adj ); - - GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( adj, 1, 0 ) ); - gtk_widget_show( GTK_WIDGET( spin ) ); - gtk_table_attach( table, GTK_WIDGET( spin ), 1, 2, 4, 5, - (GtkAttachOptions)( 0 ), - (GtkAttachOptions)( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( spin ), 16, -1 ); - gtk_widget_set_can_focus( GTK_WIDGET( spin ), FALSE ); - } - } - GtkHBox* hbox2 = GTK_HBOX( gtk_hbox_new( TRUE, 5 ) ); - gtk_widget_show( GTK_WIDGET( hbox2 ) ); - gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( hbox2 ), TRUE, FALSE, 0 ); - { - GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "CAP" ) ); - gtk_widget_show( GTK_WIDGET( button ) ); - gtk_box_pack_end( GTK_BOX( hbox2 ), GTK_WIDGET( button ), TRUE, FALSE, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( OnBtnPatchCap ), 0 ); - gtk_widget_set_size_request( GTK_WIDGET( button ), 60, -1 ); - } - { - GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "Set..." ) ); - gtk_widget_show( GTK_WIDGET( button ) ); - gtk_box_pack_end( GTK_BOX( hbox2 ), GTK_WIDGET( button ), TRUE, FALSE, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( OnBtnPatchFit ), 0 ); - gtk_widget_set_size_request( GTK_WIDGET( button ), 60, -1 ); - } - { - GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "Natural" ) ); - gtk_widget_show( GTK_WIDGET( button ) ); - gtk_box_pack_end( GTK_BOX( hbox2 ), GTK_WIDGET( button ), TRUE, FALSE, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( OnBtnPatchNatural ), 0 ); - gtk_widget_set_size_request( GTK_WIDGET( button ), 60, -1 ); - } - { - GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "Fit" ) ); - gtk_widget_show( GTK_WIDGET( button ) ); - gtk_box_pack_end( GTK_BOX( hbox2 ), GTK_WIDGET( button ), TRUE, FALSE, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( OnBtnPatchFit11 ), 0 ); - gtk_widget_set_size_request( GTK_WIDGET( button ), 60, -1 ); - } - } - } - } - } - - return window; -} - -// sync the dialog our internal data structures -void PatchInspector::exportData(){ - m_bListenChanged = false; - Dialog::exportData(); - m_bListenChanged = true; -} -void PatchInspector::importData(){ - m_bListenChanged = false; - Dialog::importData(); - m_bListenChanged = true; -} - -// read the map and feed in the stuff to the dialog box -void PatchInspector::GetPatchInfo(){ - if ( g_pGameDescription->mGameType == "doom3" ) { - m_subdivisions.update(); - } - - if ( GlobalSelectionSystem().countSelected() == 0 ) { - m_Patch = 0; - } - else - { - m_Patch = Node_getPatch( GlobalSelectionSystem().ultimateSelected().path().top() ); - } - - if ( m_Patch != 0 ) { - m_strName = m_Patch->GetShader(); - - // fill in the numbers for Row / Col selection - m_bListenChanged = false; - - { - gtk_combo_box_set_active( GTK_COMBO_BOX( m_pRowCombo ), 0 ); - - for ( std::size_t i = 0; i < m_countRows; ++i ) - { - gtk_combo_box_text_remove( m_pRowCombo, gint( m_countRows - i - 1 ) ); - } - - m_countRows = m_Patch->getHeight(); - for ( std::size_t i = 0; i < m_countRows; ++i ) - { - char buffer[16]; - sprintf( buffer, "%u", Unsigned( i ) ); - gtk_combo_box_text_append_text( m_pRowCombo, buffer ); - } - - gtk_combo_box_set_active( GTK_COMBO_BOX( m_pRowCombo ), 0 ); - } - - { - gtk_combo_box_set_active( GTK_COMBO_BOX( m_pColCombo ), 0 ); - - for ( std::size_t i = 0; i < m_countCols; ++i ) - { - gtk_combo_box_text_remove( m_pColCombo, gint( m_countCols - i - 1 ) ); - } - - m_countCols = m_Patch->getWidth(); - for ( std::size_t i = 0; i < m_countCols; ++i ) - { - char buffer[16]; - sprintf( buffer, "%u", Unsigned( i ) ); - gtk_combo_box_text_append_text( m_pColCombo, buffer ); - } - - gtk_combo_box_set_active( GTK_COMBO_BOX( m_pColCombo ), 0 ); - } - - m_bListenChanged = true; - - } - else - { - //globalWarningStream() << "WARNING: no patch\n"; - } - // fill in our internal structs - m_nRow = 0; - m_nCol = 0; - UpdateRowColInfo(); - // now update the dialog box - importData(); -} - -// read the current patch on map and initialize m_fX m_fY accordingly -// NOTE: don't call UpdateData in there, it's not meant for -void PatchInspector::UpdateRowColInfo(){ - m_fX = m_fY = m_fZ = m_fS = m_fT = 0.0; - - if ( m_Patch != 0 ) { - // we rely on whatever active row/column has been set before we get called - std::size_t r = m_nRow; - std::size_t c = m_nCol; - if ( r < m_Patch->getHeight() - && c < m_Patch->getWidth() ) { - const PatchControl& p = m_Patch->ctrlAt( r,c ); - m_fX = p.m_vertex[0]; - m_fY = p.m_vertex[1]; - m_fZ = p.m_vertex[2]; - m_fS = p.m_texcoord[0]; - m_fT = p.m_texcoord[1]; - } - } -} - - -void PatchInspector_SelectionChanged( const Selectable& selectable ){ - PatchInspector_queueDraw(); -} - - -#include "preferencesystem.h" - - -void PatchInspector_Construct(){ - GlobalCommands_insert( "PatchInspector", FreeCaller(), Accelerator( 'S', GDK_SHIFT_MASK ) ); - - GlobalPreferenceSystem().registerPreference( "PatchWnd", WindowPositionTrackerImportStringCaller( g_PatchInspector.m_position_tracker ), WindowPositionTrackerExportStringCaller( g_PatchInspector.m_position_tracker ) ); - GlobalPreferenceSystem().registerPreference( "SI_PatchTexdef_Scale1", FloatImportStringCaller( g_pi_globals.scale[0] ), FloatExportStringCaller( g_pi_globals.scale[0] ) ); - GlobalPreferenceSystem().registerPreference( "SI_PatchTexdef_Scale2", FloatImportStringCaller( g_pi_globals.scale[1] ), FloatExportStringCaller( g_pi_globals.scale[1] ) ); - GlobalPreferenceSystem().registerPreference( "SI_PatchTexdef_Shift1", FloatImportStringCaller( g_pi_globals.shift[0] ), FloatExportStringCaller( g_pi_globals.shift[0] ) ); - GlobalPreferenceSystem().registerPreference( "SI_PatchTexdef_Shift2", FloatImportStringCaller( g_pi_globals.shift[1] ), FloatExportStringCaller( g_pi_globals.shift[1] ) ); - GlobalPreferenceSystem().registerPreference( "SI_PatchTexdef_Rotate", FloatImportStringCaller( g_pi_globals.rotate ), FloatExportStringCaller( g_pi_globals.rotate ) ); - - typedef FreeCaller1 PatchInspectorSelectionChangedCaller; - GlobalSelectionSystem().addSelectionChangeCallback( PatchInspectorSelectionChangedCaller() ); - typedef FreeCaller PatchInspectorQueueDrawCaller; - Patch_addTextureChangedCallback( PatchInspectorQueueDrawCaller() ); -} -void PatchInspector_Destroy(){ + Scene_forEachVisibleSelectedPatch( [s, t]( Patch& patch ){ patch.TranslateTexture( s, t ); } ); } diff --git a/radiant/patchdialog.h b/radiant/patchdialog.h index 14f56564..77d0e0a5 100644 --- a/radiant/patchdialog.h +++ b/radiant/patchdialog.h @@ -21,13 +21,8 @@ #pragma once -void PatchInspector_Construct(); -void PatchInspector_Destroy(); - -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkWindow GtkWindow; -void PatchInspector_constructWindow( GtkWindow* main_window ); -void PatchInspector_destroyWindow(); +class QGroupBox* patch_tesselation_create(); +void patch_tesselation_update(); namespace scene { diff --git a/radiant/patchmanip.cpp b/radiant/patchmanip.cpp index 387ed758..87bcfee8 100644 --- a/radiant/patchmanip.cpp +++ b/radiant/patchmanip.cpp @@ -43,6 +43,7 @@ #include "select.h" #include "patch.h" #include "grid.h" +#include "patchdialog.h" PatchCreator* g_patchCreator = 0; @@ -73,17 +74,17 @@ void Scene_PatchConstructPrefab( scene::Graph& graph, const AABB aabb, const cha void Patch_makeCaps( Patch& patch, scene::Instance& instance, EPatchCap type, const char* shader ){ - if ( ( type == eCapEndCap || type == eCapIEndCap ) + if ( ( type == EPatchCap::EndCap || type == EPatchCap::IEndCap ) && patch.getWidth() != 5 ) { globalErrorStream() << "cannot create end-cap - patch width != 5\n"; return; } - if ( ( type == eCapBevel || type == eCapIBevel ) + if ( ( type == EPatchCap::Bevel || type == EPatchCap::IBevel ) && patch.getWidth() != 3 && patch.getWidth() != 5 ) { globalErrorStream() << "cannot create bevel-cap - patch width != 3\n"; return; } - if ( type == eCapCylinder + if ( type == EPatchCap::Cylinder && patch.getWidth() != 9 ) { globalErrorStream() << "cannot create cylinder-cap - patch width != 9\n"; return; @@ -130,49 +131,12 @@ public: } }; -enum ECapDialog { - PATCHCAP_BEVEL = 0, - PATCHCAP_ENDCAP, - PATCHCAP_INVERTED_BEVEL, - PATCHCAP_INVERTED_ENDCAP, - PATCHCAP_CYLINDER -}; - -EMessageBoxReturn DoCapDlg( ECapDialog *type ); - -void Scene_PatchDoCap_Selected( scene::Graph& graph, const char* shader ){ - ECapDialog nType; - - if ( DoCapDlg( &nType ) == eIDOK ) { - EPatchCap eType; - switch ( nType ) - { - case PATCHCAP_INVERTED_BEVEL: - eType = eCapIBevel; - break; - case PATCHCAP_BEVEL: - eType = eCapBevel; - break; - case PATCHCAP_INVERTED_ENDCAP: - eType = eCapIEndCap; - break; - case PATCHCAP_ENDCAP: - eType = eCapEndCap; - break; - case PATCHCAP_CYLINDER: - eType = eCapCylinder; - break; - default: - ERROR_MESSAGE( "invalid patch cap type" ); - return; - } - - InstanceVector instances; - Scene_forEachVisibleSelectedPatchInstance( PatchStoreInstance( instances ) ); - for ( auto i : instances ) - { - Patch_makeCaps( *Node_getPatch( i->path().top() ), *i, eType, shader ); - } +void Scene_PatchDoCap_Selected( scene::Graph& graph, const char* shader, EPatchCap type ){ + InstanceVector instances; + Scene_forEachVisibleSelectedPatchInstance( PatchStoreInstance( instances ) ); + for ( auto i : instances ) + { + Patch_makeCaps( *Node_getPatch( i->path().top() ), *i, type, shader ); } } @@ -285,175 +249,64 @@ Patch* Scene_GetUltimateSelectedVisiblePatch(){ } -class PatchCapTexture -{ -public: - void operator()( Patch& patch ) const { - //patch.ProjectTexture( Patch::m_CycleCapIndex ); - patch.CapTexture(); - } -}; - void Scene_PatchCapTexture_Selected( scene::Graph& graph ){ - Scene_forEachVisibleSelectedPatch( PatchCapTexture() ); - //Patch::m_CycleCapIndex = ( Patch::m_CycleCapIndex + 1 ) % 3; + Scene_forEachVisibleSelectedPatch( []( Patch& patch ){ patch.CapTexture(); } ); SceneChangeNotify(); } -class PatchProjectTexture -{ - const texdef_t& m_texdef; - const Vector3* m_direction; -public: - PatchProjectTexture( const texdef_t& texdef, const Vector3* direction ) : m_texdef( texdef ), m_direction( direction ) { - } - void operator()( Patch& patch ) const { - patch.ProjectTexture( m_texdef, m_direction ); - } -}; - void Scene_PatchProjectTexture_Selected( scene::Graph& graph, const texdef_t& texdef, const Vector3* direction ){ - Scene_forEachVisibleSelectedPatch( PatchProjectTexture( texdef, direction ) ); + Scene_forEachVisibleSelectedPatch( [texdef, direction]( Patch& patch ){ patch.ProjectTexture( texdef, direction ); } ); SceneChangeNotify(); } -class PatchProjectTexture_fromFace -{ - const TextureProjection& m_projection; - const Vector3& m_normal; -public: - PatchProjectTexture_fromFace( const TextureProjection& projection, const Vector3& normal ) : m_projection( projection ), m_normal( normal ) { - } - void operator()( Patch& patch ) const { - patch.ProjectTexture( m_projection, m_normal ); - } -}; - void Scene_PatchProjectTexture_Selected( scene::Graph& graph, const TextureProjection& projection, const Vector3& normal ){ - Scene_forEachVisibleSelectedPatch( PatchProjectTexture_fromFace( projection, normal ) ); + Scene_forEachVisibleSelectedPatch( [projection, normal]( Patch& patch ){ patch.ProjectTexture( projection, normal ); } ); SceneChangeNotify(); } -class PatchFlipTexture -{ - int m_axis; -public: - PatchFlipTexture( int axis ) : m_axis( axis ){ - } - void operator()( Patch& patch ) const { - patch.FlipTexture( m_axis ); - } -}; - void Scene_PatchFlipTexture_Selected( scene::Graph& graph, int axis ){ - Scene_forEachVisibleSelectedPatch( PatchFlipTexture( axis ) ); + Scene_forEachVisibleSelectedPatch( [axis]( Patch& patch ){ patch.FlipTexture( axis ); } ); } -class PatchNaturalTexture -{ -public: - void operator()( Patch& patch ) const { - patch.NaturalTexture(); - } -}; - void Scene_PatchNaturalTexture_Selected( scene::Graph& graph ){ - Scene_forEachVisibleSelectedPatch( PatchNaturalTexture() ); + Scene_forEachVisibleSelectedPatch( []( Patch& patch ){ patch.NaturalTexture(); } ); + SceneChangeNotify(); +} + +void Scene_PatchTileTexture_Selected( scene::Graph& graph, float s, float t ){ + Scene_forEachVisibleSelectedPatch( [s, t]( Patch& patch ){ patch.SetTextureRepeat( s, t ); } ); SceneChangeNotify(); } -class PatchInsertRemove -{ - bool m_insert, m_column, m_first; -public: - PatchInsertRemove( bool insert, bool column, bool first ) : m_insert( insert ), m_column( column ), m_first( first ){ - } - void operator()( Patch& patch ) const { - patch.InsertRemove( m_insert, m_column, m_first ); - } -}; - void Scene_PatchInsertRemove_Selected( scene::Graph& graph, bool bInsert, bool bColumn, bool bFirst ){ - Scene_forEachVisibleSelectedPatch( PatchInsertRemove( bInsert, bColumn, bFirst ) ); + Scene_forEachVisibleSelectedPatch( [bInsert, bColumn, bFirst]( Patch& patch ){ patch.InsertRemove( bInsert, bColumn, bFirst ); } ); } -class PatchInvertMatrix -{ -public: - void operator()( Patch& patch ) const { - patch.InvertMatrix(); - } -}; - void Scene_PatchInvert_Selected( scene::Graph& graph ){ - Scene_forEachVisibleSelectedPatch( PatchInvertMatrix() ); + Scene_forEachVisibleSelectedPatch( []( Patch& patch ){ patch.InvertMatrix(); } ); } -class PatchRedisperse -{ - EMatrixMajor m_major; -public: - PatchRedisperse( EMatrixMajor major ) : m_major( major ){ - } - void operator()( Patch& patch ) const { - patch.Redisperse( m_major ); - } -}; - void Scene_PatchRedisperse_Selected( scene::Graph& graph, EMatrixMajor major ){ - Scene_forEachVisibleSelectedPatch( PatchRedisperse( major ) ); + Scene_forEachVisibleSelectedPatch( [major]( Patch& patch ){ patch.Redisperse( major ); } ); } -class PatchSmooth -{ - EMatrixMajor m_major; -public: - PatchSmooth( EMatrixMajor major ) : m_major( major ){ - } - void operator()( Patch& patch ) const { - patch.Smooth( m_major ); - } -}; - void Scene_PatchSmooth_Selected( scene::Graph& graph, EMatrixMajor major ){ - Scene_forEachVisibleSelectedPatch( PatchSmooth( major ) ); + Scene_forEachVisibleSelectedPatch( [major]( Patch& patch ){ patch.Smooth( major ); } ); } -class PatchTransposeMatrix -{ -public: - void operator()( Patch& patch ) const { - patch.TransposeMatrix(); - } -}; - void Scene_PatchTranspose_Selected( scene::Graph& graph ){ - Scene_forEachVisibleSelectedPatch( PatchTransposeMatrix() ); + Scene_forEachVisibleSelectedPatch( []( Patch& patch ){ patch.TransposeMatrix(); } ); } -class PatchSetShader -{ - const char* m_name; -public: - PatchSetShader( const char* name ) - : m_name( name ){ - } - void operator()( Patch& patch ) const { - patch.SetShader( m_name ); - } -}; - void Scene_PatchSetShader_Selected( scene::Graph& graph, const char* name ){ - Scene_forEachVisibleSelectedPatch( PatchSetShader( name ) ); + Scene_forEachVisibleSelectedPatch( [name]( Patch& patch ){ patch.SetShader( name ); } ); SceneChangeNotify(); } void Scene_PatchGetShader_Selected( scene::Graph& graph, CopiedString& name ){ - Patch* patch = Scene_GetUltimateSelectedVisiblePatch(); - if ( patch != 0 ) { + if ( Patch* patch = Scene_GetUltimateSelectedVisiblePatch() ) name = patch->GetShader(); - } } class PatchSelectByShader @@ -535,61 +388,61 @@ void DoNewPatchDlg( EPatchPrefab prefab, int minrows, int mincols, int defrows, void Patch_XactCylinder(){ UndoableCommand undo( "patchCreateXactCylinder" ); - DoNewPatchDlg( eXactCylinder, 3, 7, 3, 13, 0, 0 ); + DoNewPatchDlg( EPatchPrefab::ExactCylinder, 3, 7, 3, 13, 0, 0 ); } void Patch_XactSphere(){ UndoableCommand undo( "patchCreateXactSphere" ); - DoNewPatchDlg( eXactSphere, 5, 7, 7, 13, 0, 0 ); + DoNewPatchDlg( EPatchPrefab::ExactSphere, 5, 7, 7, 13, 0, 0 ); } void Patch_XactCone(){ UndoableCommand undo( "patchCreateXactCone" ); - DoNewPatchDlg( eXactCone, 3, 7, 3, 13, 0, 0 ); + DoNewPatchDlg( EPatchPrefab::ExactCone, 3, 7, 3, 13, 0, 0 ); } void Patch_Cylinder(){ UndoableCommand undo( "patchCreateCylinder" ); - Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), eCylinder, GlobalXYWnd_getCurrentViewType() ); + Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), EPatchPrefab::Cylinder, GlobalXYWnd_getCurrentViewType() ); } void Patch_DenseCylinder(){ UndoableCommand undo( "patchCreateDenseCylinder" ); - Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), eDenseCylinder, GlobalXYWnd_getCurrentViewType() ); + Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), EPatchPrefab::DenseCylinder, GlobalXYWnd_getCurrentViewType() ); } void Patch_VeryDenseCylinder(){ UndoableCommand undo( "patchCreateVeryDenseCylinder" ); - Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), eVeryDenseCylinder, GlobalXYWnd_getCurrentViewType() ); + Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), EPatchPrefab::VeryDenseCylinder, GlobalXYWnd_getCurrentViewType() ); } void Patch_SquareCylinder(){ UndoableCommand undo( "patchCreateSquareCylinder" ); - Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), eSqCylinder, GlobalXYWnd_getCurrentViewType() ); + Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), EPatchPrefab::SqCylinder, GlobalXYWnd_getCurrentViewType() ); } void Patch_Endcap(){ UndoableCommand undo( "patchCreateEndCap" ); - Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), eEndCap, GlobalXYWnd_getCurrentViewType() ); + Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), EPatchPrefab::EndCap, GlobalXYWnd_getCurrentViewType() ); } void Patch_Bevel(){ UndoableCommand undo( "patchCreateBevel" ); - Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), eBevel, GlobalXYWnd_getCurrentViewType() ); + Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), EPatchPrefab::Bevel, GlobalXYWnd_getCurrentViewType() ); } void Patch_Sphere(){ UndoableCommand undo( "patchCreateSphere" ); - Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), eSphere, GlobalXYWnd_getCurrentViewType() ); + Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), EPatchPrefab::Sphere, GlobalXYWnd_getCurrentViewType() ); } void Patch_SquareBevel(){ @@ -601,13 +454,13 @@ void Patch_SquareEndcap(){ void Patch_Cone(){ UndoableCommand undo( "patchCreateCone" ); - Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), eCone, GlobalXYWnd_getCurrentViewType() ); + Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), EPatchPrefab::Cone, GlobalXYWnd_getCurrentViewType() ); } void Patch_Plane(){ UndoableCommand undo( "patchCreatePlane" ); - DoNewPatchDlg( ePlane, 3, 3, 3, 3, 0, 0 ); + DoNewPatchDlg( EPatchPrefab::Plane, 3, 3, 3, 3, 0, 0 ); } void Patch_InsertFirstColumn(){ @@ -694,12 +547,14 @@ void Patch_Transpose(){ Scene_PatchTranspose_Selected( GlobalSceneGraph() ); } +void DoCapDlg(); + void Patch_Cap(){ // FIXME: add support for patch cap creation // Patch_CapCurrent(); UndoableCommand undo( "patchPutCaps" ); - Scene_PatchDoCap_Selected( GlobalSceneGraph(), TextureBrowser_GetSelectedShader() ); + DoCapDlg(); } ///\todo Unfinished. @@ -734,16 +589,6 @@ void Patch_CapTexture(){ } void Patch_FitTexture(){ - float fx, fy; - if ( DoTextureLayout( &fx, &fy ) == eIDOK ) { - UndoableCommand command( "patchTileTexture" ); - Scene_PatchTileTexture_Selected( GlobalSceneGraph(), fx, fy ); - } -} - -void Patch_FitTexture11(){ - UndoableCommand command( "patchFitTexture" ); - Scene_PatchTileTexture_Selected( GlobalSceneGraph(), 1, 1 ); } void DoPatchDeformDlg(); @@ -816,7 +661,7 @@ void PatchFilters_construct(){ #include "preferences.h" void Patch_constructPreferences( PreferencesPage& page ){ - page.appendEntry( "Patch Subdivide Threshold", g_PatchSubdivideThreshold ); + page.appendSpinner( "Patch Subdivide Threshold", g_PatchSubdivideThreshold, 0, 128 ); } void Patch_constructPage( PreferenceGroup& group ){ PreferencesPage page( group.createPage( "Patches", "Patch Display Preferences" ) ); @@ -837,9 +682,9 @@ void PatchPreferences_construct(){ #include "generic/callback.h" void Patch_registerCommands(){ - GlobalCommands_insert( "InvertCurveTextureX", FreeCaller(), Accelerator( 'I', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); - GlobalCommands_insert( "InvertCurveTextureY", FreeCaller(), Accelerator( 'I', GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "NaturalizePatch", FreeCaller(), Accelerator( 'N', GDK_CONTROL_MASK ) ); + GlobalCommands_insert( "InvertCurveTextureX", FreeCaller(), QKeySequence( "Ctrl+Shift+I" ) ); + GlobalCommands_insert( "InvertCurveTextureY", FreeCaller(), QKeySequence( "Shift+I" ) ); + GlobalCommands_insert( "NaturalizePatch", FreeCaller(), QKeySequence( "Ctrl+N" ) ); GlobalCommands_insert( "PatchCylinder", FreeCaller() ); // GlobalCommands_insert( "PatchDenseCylinder", FreeCaller() ); // GlobalCommands_insert( "PatchVeryDenseCylinder", FreeCaller() ); @@ -853,35 +698,35 @@ void Patch_registerCommands(){ // GlobalCommands_insert( "PatchSquareEndcap", FreeCaller() ); GlobalCommands_insert( "PatchCone", FreeCaller() ); GlobalCommands_insert( "PatchSphere", FreeCaller() ); - GlobalCommands_insert( "SimplePatchMesh", FreeCaller(), Accelerator( 'P', GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "PatchInsertFirstColumn", FreeCaller(), Accelerator( GDK_KEY_KP_Add, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); + GlobalCommands_insert( "SimplePatchMesh", FreeCaller(), QKeySequence( "Shift+P" ) ); + GlobalCommands_insert( "PatchInsertFirstColumn", FreeCaller(), QKeySequence( Qt::CTRL + Qt::SHIFT + Qt::Key_Plus + Qt::KeypadModifier ) ); GlobalCommands_insert( "PatchInsertLastColumn", FreeCaller() ); - GlobalCommands_insert( "PatchInsertFirstRow", FreeCaller(), Accelerator( GDK_KEY_KP_Add, GDK_CONTROL_MASK ) ); + GlobalCommands_insert( "PatchInsertFirstRow", FreeCaller(), QKeySequence( Qt::CTRL + Qt::Key_Plus + Qt::KeypadModifier ) ); GlobalCommands_insert( "PatchInsertLastRow", FreeCaller() ); GlobalCommands_insert( "PatchDeleteFirstColumn", FreeCaller() ); - GlobalCommands_insert( "PatchDeleteLastColumn", FreeCaller(), Accelerator( GDK_KEY_KP_Subtract, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); + GlobalCommands_insert( "PatchDeleteLastColumn", FreeCaller(), QKeySequence( Qt::CTRL + Qt::SHIFT + Qt::Key_Minus + Qt::KeypadModifier ) ); GlobalCommands_insert( "PatchDeleteFirstRow", FreeCaller() ); - GlobalCommands_insert( "PatchDeleteLastRow", FreeCaller(), Accelerator( GDK_KEY_KP_Subtract, GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "InvertCurve", FreeCaller(), Accelerator( 'I', GDK_CONTROL_MASK ) ); - //GlobalCommands_insert( "RedisperseRows", FreeCaller(), Accelerator( 'E', GDK_CONTROL_MASK ) ); + GlobalCommands_insert( "PatchDeleteLastRow", FreeCaller(), QKeySequence( Qt::CTRL + Qt::Key_Minus + Qt::KeypadModifier ) ); + GlobalCommands_insert( "InvertCurve", FreeCaller(), QKeySequence( "Ctrl+I" ) ); + //GlobalCommands_insert( "RedisperseRows", FreeCaller(), QKeySequence( "Ctrl+E" ) ); GlobalCommands_insert( "RedisperseRows", FreeCaller() ); - //GlobalCommands_insert( "RedisperseCols", FreeCaller(), Accelerator( 'E', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); + //GlobalCommands_insert( "RedisperseCols", FreeCaller(), QKeySequence( "Ctrl+Shift+E" ) ); GlobalCommands_insert( "RedisperseCols", FreeCaller() ); - GlobalCommands_insert( "SmoothRows", FreeCaller(), Accelerator( 'W', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "SmoothCols", FreeCaller(), Accelerator( 'W', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); - GlobalCommands_insert( "MatrixTranspose", FreeCaller(), Accelerator( 'M', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); - GlobalCommands_insert( "CapCurrentCurve", FreeCaller(), Accelerator( 'C', GDK_SHIFT_MASK ) ); -// GlobalCommands_insert( "MakeOverlayPatch", FreeCaller(), Accelerator( 'Y' ) ); -// GlobalCommands_insert( "ClearPatchOverlays", FreeCaller(), Accelerator( 'L', GDK_CONTROL_MASK ) ); + GlobalCommands_insert( "SmoothRows", FreeCaller(), QKeySequence( "Ctrl+W" ) ); + GlobalCommands_insert( "SmoothCols", FreeCaller(), QKeySequence( "Ctrl+Shift+W" ) ); + GlobalCommands_insert( "MatrixTranspose", FreeCaller(), QKeySequence( "Ctrl+Shift+M" ) ); + GlobalCommands_insert( "CapCurrentCurve", FreeCaller(), QKeySequence( "Shift+C" ) ); +// GlobalCommands_insert( "MakeOverlayPatch", FreeCaller(), QKeySequence( "Y" ) ); +// GlobalCommands_insert( "ClearPatchOverlays", FreeCaller(), QKeySequence( "Ctrl+L" ) ); GlobalCommands_insert( "PatchDeform", FreeCaller() ); - GlobalCommands_insert( "PatchThicken", FreeCaller(), Accelerator( 'T', GDK_CONTROL_MASK ) ); + GlobalCommands_insert( "PatchThicken", FreeCaller(), QKeySequence( "Ctrl+T" ) ); } -void Patch_constructToolbar( GtkToolbar* toolbar ){ - toolbar_append_button( toolbar, "Put caps on the current patch (SHIFT + C)", "curve_cap.png", "CapCurrentCurve" ); +void Patch_constructToolbar( QToolBar* toolbar ){ + toolbar_append_button( toolbar, "Put caps on the current patch", "curve_cap.png", "CapCurrentCurve" ); } -void Patch_constructMenu( GtkMenu* menu ){ +void Patch_constructMenu( QMenu* menu ){ create_menu_item_with_mnemonic( menu, "Simple Patch Mesh...", "SimplePatchMesh" ); create_menu_item_with_mnemonic( menu, "Bevel", "PatchBevel" ); create_menu_item_with_mnemonic( menu, "End cap", "PatchEndCap" ); @@ -893,124 +738,109 @@ void Patch_constructMenu( GtkMenu* menu ){ create_menu_item_with_mnemonic( menu, "Sphere (9x5)", "PatchSphere" ); create_menu_item_with_mnemonic( menu, "Exact Sphere...", "PatchXactSphere" ); // { -// GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic( menu, "More Cylinders" ); -// if ( g_Layout_enableDetachableMenus.m_value ) { -// menu_tearoff( menu_in_menu ); -// } -// create_menu_item_with_mnemonic( menu_in_menu, "Dense Cylinder", "PatchDenseCylinder" ); -// create_menu_item_with_mnemonic( menu_in_menu, "Very Dense Cylinder", "PatchVeryDenseCylinder" ); -// create_menu_item_with_mnemonic( menu_in_menu, "Square Cylinder", "PatchSquareCylinder" ); +// QMenu* submenu = menu->addMenu( "More Cylinders" ); + +// submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + +// create_menu_item_with_mnemonic( submenu, "Dense Cylinder", "PatchDenseCylinder" ); +// create_menu_item_with_mnemonic( submenu, "Very Dense Cylinder", "PatchVeryDenseCylinder" ); +// create_menu_item_with_mnemonic( submenu, "Square Cylinder", "PatchSquareCylinder" ); // } // { // //not implemented // create_menu_item_with_mnemonic( menu, "Square Endcap", "PatchSquareBevel" ); // create_menu_item_with_mnemonic( menu, "Square Bevel", "PatchSquareEndcap" ); // } - menu_separator( menu ); + menu->addSeparator(); create_menu_item_with_mnemonic( menu, "Cap Selection", "CapCurrentCurve" ); - menu_separator( menu ); + menu->addSeparator(); { - GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic( menu, "Insert/Delete" ); - if ( g_Layout_enableDetachableMenus.m_value ) { - menu_tearoff( menu_in_menu ); - } - create_menu_item_with_mnemonic( menu_in_menu, "Insert (2) First Columns", "PatchInsertFirstColumn" ); - create_menu_item_with_mnemonic( menu_in_menu, "Insert (2) Last Columns", "PatchInsertLastColumn" ); - menu_separator( menu_in_menu ); - create_menu_item_with_mnemonic( menu_in_menu, "Insert (2) First Rows", "PatchInsertFirstRow" ); - create_menu_item_with_mnemonic( menu_in_menu, "Insert (2) Last Rows", "PatchInsertLastRow" ); - menu_separator( menu_in_menu ); - create_menu_item_with_mnemonic( menu_in_menu, "Del First (2) Columns", "PatchDeleteFirstColumn" ); - create_menu_item_with_mnemonic( menu_in_menu, "Del Last (2) Columns", "PatchDeleteLastColumn" ); - menu_separator( menu_in_menu ); - create_menu_item_with_mnemonic( menu_in_menu, "Del First (2) Rows", "PatchDeleteFirstRow" ); - create_menu_item_with_mnemonic( menu_in_menu, "Del Last (2) Rows", "PatchDeleteLastRow" ); - } - menu_separator( menu ); - { - GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic( menu, "Matrix" ); - if ( g_Layout_enableDetachableMenus.m_value ) { - menu_tearoff( menu_in_menu ); - } - create_menu_item_with_mnemonic( menu_in_menu, "Invert", "InvertCurve" ); - create_menu_item_with_mnemonic( menu_in_menu, "Transpose", "MatrixTranspose" ); + QMenu* submenu = menu->addMenu( "Insert/Delete" ); - menu_separator( menu_in_menu ); - create_menu_item_with_mnemonic( menu_in_menu, "Re-disperse Rows", "RedisperseRows" ); - create_menu_item_with_mnemonic( menu_in_menu, "Re-disperse Columns", "RedisperseCols" ); + submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); - menu_separator( menu_in_menu ); - create_menu_item_with_mnemonic( menu_in_menu, "Smooth Rows", "SmoothRows" ); - create_menu_item_with_mnemonic( menu_in_menu, "Smooth Columns", "SmoothCols" ); + create_menu_item_with_mnemonic( submenu, "Insert (2) First Columns", "PatchInsertFirstColumn" ); + create_menu_item_with_mnemonic( submenu, "Insert (2) Last Columns", "PatchInsertLastColumn" ); + submenu->addSeparator(); + create_menu_item_with_mnemonic( submenu, "Insert (2) First Rows", "PatchInsertFirstRow" ); + create_menu_item_with_mnemonic( submenu, "Insert (2) Last Rows", "PatchInsertLastRow" ); + submenu->addSeparator(); + create_menu_item_with_mnemonic( submenu, "Del First (2) Columns", "PatchDeleteFirstColumn" ); + create_menu_item_with_mnemonic( submenu, "Del Last (2) Columns", "PatchDeleteLastColumn" ); + submenu->addSeparator(); + create_menu_item_with_mnemonic( submenu, "Del First (2) Rows", "PatchDeleteFirstRow" ); + create_menu_item_with_mnemonic( submenu, "Del Last (2) Rows", "PatchDeleteLastRow" ); } - menu_separator( menu ); + menu->addSeparator(); { - GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic( menu, "Texture" ); - if ( g_Layout_enableDetachableMenus.m_value ) { - menu_tearoff( menu_in_menu ); - } - create_menu_item_with_mnemonic( menu_in_menu, "Project", "TextureReset/Cap" ); - create_menu_item_with_mnemonic( menu_in_menu, "Naturalize", "NaturalizePatch" ); - create_menu_item_with_mnemonic( menu_in_menu, "Invert X", "InvertCurveTextureX" ); - create_menu_item_with_mnemonic( menu_in_menu, "Invert Y", "InvertCurveTextureY" ); + QMenu* submenu = menu->addMenu( "Matrix" ); + + submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + + create_menu_item_with_mnemonic( submenu, "Invert", "InvertCurve" ); + create_menu_item_with_mnemonic( submenu, "Transpose", "MatrixTranspose" ); + + submenu->addSeparator(); + create_menu_item_with_mnemonic( submenu, "Re-disperse Rows", "RedisperseRows" ); + create_menu_item_with_mnemonic( submenu, "Re-disperse Columns", "RedisperseCols" ); + + submenu->addSeparator(); + create_menu_item_with_mnemonic( submenu, "Smooth Rows", "SmoothRows" ); + create_menu_item_with_mnemonic( submenu, "Smooth Columns", "SmoothCols" ); + } + menu->addSeparator(); + { + QMenu* submenu = menu->addMenu( "Texture" ); + + submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + + create_menu_item_with_mnemonic( submenu, "Reset Texture", "TextureReset/Cap" ); + create_menu_item_with_mnemonic( submenu, "Naturalize", "NaturalizePatch" ); + create_menu_item_with_mnemonic( submenu, "Invert X", "InvertCurveTextureX" ); + create_menu_item_with_mnemonic( submenu, "Invert Y", "InvertCurveTextureY" ); } -// menu_separator( menu ); +// menu->addSeparator(); // { //unfinished -// GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic( menu, "Overlay" ); -// if ( g_Layout_enableDetachableMenus.m_value ) { -// menu_tearoff( menu_in_menu ); -// } -// create_menu_item_with_mnemonic( menu_in_menu, "Set", "MakeOverlayPatch" ); -// create_menu_item_with_mnemonic( menu_in_menu, "Clear", "ClearPatchOverlays" ); +// QMenu* submenu = menu->addMenu( "Overlay" ); + +// submenu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + +// create_menu_item_with_mnemonic( submenu, "Set", "MakeOverlayPatch" ); +// create_menu_item_with_mnemonic( submenu, "Clear", "ClearPatchOverlays" ); // } - menu_separator( menu ); + menu->addSeparator(); create_menu_item_with_mnemonic( menu, "Deform...", "PatchDeform" ); create_menu_item_with_mnemonic( menu, "Thicken...", "PatchThicken" ); } -#include #include "gtkutil/dialog.h" #include "gtkutil/widget.h" +#include "gtkutil/spinbox.h" + +#include +#include +#include +#include +#include +#include +#include void DoNewPatchDlg( EPatchPrefab prefab, int minrows, int mincols, int defrows, int defcols, int maxrows, int maxcols ){ - ModalDialog dialog; - GtkComboBox* width; - GtkComboBox* height; - GtkWidget* redisperseCheckBox; + QDialog dialog( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Patch density" ); - GtkWindow* window = create_dialog_window( MainFrame_getWindow(), "Patch density", G_CALLBACK( dialog_delete_callback ), &dialog ); - - GtkAccelGroup* accel = gtk_accel_group_new(); - gtk_window_add_accel_group( window, accel ); + auto width = new QComboBox; + auto height = new QComboBox; + auto redisperseCheckBox = new QCheckBox( "Square" ); { - GtkHBox* hbox = create_dialog_hbox( 4, 4 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( hbox ) ); + auto form = new QFormLayout( &dialog ); + form->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); { - GtkTable* table = create_dialog_table( 3, 2, 4, 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Width:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Height:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } - - { - GtkComboBoxText* combo = GTK_COMBO_BOX_TEXT( gtk_combo_box_text_new() ); -#define D_ITEM( x ) if ( x >= mincols && ( !maxcols || x <= maxcols ) ) gtk_combo_box_text_append_text( combo, # x ) +#define D_ITEM( x ) if ( x >= mincols && ( !maxcols || x <= maxcols ) ) width->addItem( # x ) D_ITEM( 3 ); D_ITEM( 5 ); D_ITEM( 7 ); @@ -1027,16 +857,10 @@ void DoNewPatchDlg( EPatchPrefab prefab, int minrows, int mincols, int defrows, D_ITEM( 29 ); D_ITEM( 31 ); // MAX_PATCH_SIZE is 32, so we should be able to do 31... #undef D_ITEM - gtk_widget_show( GTK_WIDGET( combo ) ); - gtk_table_attach( table, GTK_WIDGET( combo ), 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - width = GTK_COMBO_BOX( combo ); + form->addRow( "Width:", width ); } { - GtkComboBoxText* combo = GTK_COMBO_BOX_TEXT( gtk_combo_box_text_new() ); -#define D_ITEM( x ) if ( x >= minrows && ( !maxrows || x <= maxrows ) ) gtk_combo_box_text_append_text( combo, # x ) +#define D_ITEM( x ) if ( x >= minrows && ( !maxrows || x <= maxrows ) ) height->addItem( # x ) D_ITEM( 3 ); D_ITEM( 5 ); D_ITEM( 7 ); @@ -1053,457 +877,289 @@ void DoNewPatchDlg( EPatchPrefab prefab, int minrows, int mincols, int defrows, D_ITEM( 29 ); D_ITEM( 31 ); // MAX_PATCH_SIZE is 32, so we should be able to do 31... #undef D_ITEM - gtk_widget_show( GTK_WIDGET( combo ) ); - gtk_table_attach( table, GTK_WIDGET( combo ), 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - height = GTK_COMBO_BOX( combo ); + form->addRow( "Height:", height ); } - if( prefab != ePlane ){ - GtkWidget* _redisperseCheckBox = gtk_check_button_new_with_label( "Square" ); - gtk_widget_set_tooltip_text( _redisperseCheckBox, "Redisperse columns & rows" ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( _redisperseCheckBox ), FALSE ); - gtk_widget_show( _redisperseCheckBox ); - gtk_table_attach( table, _redisperseCheckBox, 0, 2, 2, 3, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - redisperseCheckBox = _redisperseCheckBox; + if( prefab != EPatchPrefab::Plane ){ + redisperseCheckBox->setToolTip( "Redisperse columns & rows" ); + form->addWidget( redisperseCheckBox ); } - } - { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), TRUE, TRUE, 0 ); - { - GtkButton* button = create_dialog_button( "OK", G_CALLBACK( dialog_button_ok ), &dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_grab_focus( GTK_WIDGET( button ) ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 ); - } - { - GtkButton* button = create_dialog_button( "Cancel", G_CALLBACK( dialog_button_cancel ), &dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 ); - } + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel ); + form->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept ); + QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject ); } } // Initialize dialog - gtk_combo_box_set_active( width, ( defcols - mincols ) / 2 ); - gtk_combo_box_set_active( height, ( defrows - minrows ) / 2 ); + width->setCurrentIndex( ( defcols - mincols ) / 2 ); + height->setCurrentIndex( ( defrows - minrows ) / 2 ); - if ( modal_dialog_show( window, dialog ) == eIDOK ) { - int w = gtk_combo_box_get_active( width ) * 2 + mincols; - int h = gtk_combo_box_get_active( height ) * 2 + minrows; - bool redisperse = false; - if( prefab != ePlane ){ - redisperse = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( redisperseCheckBox ) ) ? true : false; - } + if ( dialog.exec() ) { + const int w = width->currentIndex() * 2 + mincols; + const int h = height->currentIndex() * 2 + minrows; + const bool redisperse = redisperseCheckBox->isChecked(); Scene_PatchConstructPrefab( GlobalSceneGraph(), PatchCreator_getBounds(), TextureBrowser_GetSelectedShader(), prefab, GlobalXYWnd_getCurrentViewType(), w, h, redisperse ); } - - gtk_widget_destroy( GTK_WIDGET( window ) ); } void DoPatchDeformDlg(){ - ModalDialog dialog; - GtkWidget* deformW; + QDialog dialog( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Patch deform" ); - GtkWidget* rndY; - GtkWidget* rndX; + auto spin = new SpinBox( -9999, 9999, 64 ); - GtkWindow* window = create_dialog_window( MainFrame_getWindow(), "Patch deform", G_CALLBACK( dialog_delete_callback ), &dialog ); - - GtkAccelGroup* accel = gtk_accel_group_new(); - gtk_window_add_accel_group( window, accel ); + RadioHBox radioBox = RadioHBox_new( (const char*[]){ "X", "Y", "Z" } ); + radioBox.m_radio->button( 2 )->setChecked( true ); { - GtkHBox* hbox = create_dialog_hbox( 4, 4 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( hbox ) ); + auto form = new QFormLayout( &dialog ); + form->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + form->addRow( new SpinBoxLabel( "Max deform:", spin ), spin ); + form->addRow( "", radioBox.m_hbox ); { - GtkTable* table = create_dialog_table( 2, 2, 4, 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Max deform:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } -// { -// GtkWidget* entry = gtk_entry_new(); -// gtk_entry_set_text( GTK_ENTRY( entry ), "64" ); -// gtk_widget_show( entry ); -// gtk_table_attach( table, entry, 1, 2, 0, 1, -// (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), -// (GtkAttachOptions) ( 0 ), 0, 0 ); -// -// deformW = entry; -// } - { - GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 64, -9999, 9999, 1, 10, 0 ) ); - GtkWidget* spin = gtk_spin_button_new( adj, 1, 0 ); - gtk_widget_show( spin ); - gtk_table_attach( table, spin, 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( spin, 64, -1 ); - gtk_spin_button_set_numeric( GTK_SPIN_BUTTON( spin ), TRUE ); - - deformW = spin; - } - { - // Create the radio button group for choosing the axis - GtkWidget* _rndZ = gtk_radio_button_new_with_label_from_widget( NULL, "Z" ); - GtkWidget* _rndY = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(_rndZ), "Y" ); - GtkWidget* _rndX = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(_rndZ), "X" ); - gtk_widget_show( _rndZ ); - gtk_widget_show( _rndY ); - gtk_widget_show( _rndX ); - - - GtkHBox* _hbox = create_dialog_hbox( 4, 4 ); - gtk_table_attach( table, GTK_WIDGET( _hbox ), 0, 2, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_box_pack_start( GTK_BOX( _hbox ), GTK_WIDGET( _rndX ), TRUE, TRUE, 0 ); - gtk_box_pack_start( GTK_BOX( _hbox ), GTK_WIDGET( _rndY ), TRUE, TRUE, 0 ); - gtk_box_pack_start( GTK_BOX( _hbox ), GTK_WIDGET( _rndZ ), TRUE, TRUE, 0 ); - - rndX = _rndX; - rndY = _rndY; - } - } - { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), TRUE, TRUE, 0 ); - { - GtkButton* button = create_dialog_button( "OK", G_CALLBACK( dialog_button_ok ), &dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_grab_focus( GTK_WIDGET( button ) ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 ); - } - { - GtkButton* button = create_dialog_button( "Cancel", G_CALLBACK( dialog_button_cancel ), &dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 ); - } + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel ); + form->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept ); + QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject ); } } - if ( modal_dialog_show( window, dialog ) == eIDOK ) { - //int deform = static_cast( atoi( gtk_entry_get_text( GTK_ENTRY( deformW ) ) ) ); - gtk_spin_button_update ( GTK_SPIN_BUTTON( deformW ) ); - int deform = static_cast( gtk_spin_button_get_value( GTK_SPIN_BUTTON( deformW ) ) ); - int axis = 2; //Z - if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( rndX ) ) ){ - axis = 0; - } - else if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( rndY ) ) ){ - axis = 1; - } + if ( dialog.exec() ) { + const int deform = spin->value(); + const int axis = radioBox.m_radio->checkedId(); Scene_PatchDeform( GlobalSceneGraph(), deform, axis ); } - gtk_widget_destroy( GTK_WIDGET( window ) ); } -EMessageBoxReturn DoCapDlg( ECapDialog* type ){ - ModalDialog dialog; - ModalDialogButton ok_button( dialog, eIDOK ); - ModalDialogButton cancel_button( dialog, eIDCANCEL ); - GtkWidget* bevel; - GtkWidget* ibevel; - GtkWidget* endcap; - GtkWidget* iendcap; - GtkWidget* cylinder; - - GtkWindow* window = create_modal_dialog_window( MainFrame_getWindow(), "Cap", dialog ); - - GtkAccelGroup *accel_group = gtk_accel_group_new(); - gtk_window_add_accel_group( window, accel_group ); +void DoCapDlg(){ + QDialog dialog( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Cap" ); + auto group = new QButtonGroup( &dialog ); { - GtkHBox* hbox = create_dialog_hbox( 4, 4 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( hbox ) ); - + auto form = new QFormLayout( &dialog ); + form->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); { - // Gef: Added a vbox to contain the toggle buttons - GtkVBox* radio_vbox = create_dialog_vbox( 4 ); - gtk_container_add( GTK_CONTAINER( hbox ), GTK_WIDGET( radio_vbox ) ); - - { - GtkTable* table = GTK_TABLE( gtk_table_new( 5, 2, FALSE ) ); - gtk_widget_show( GTK_WIDGET( table ) ); - gtk_box_pack_start( GTK_BOX( radio_vbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - gtk_table_set_row_spacings( table, 5 ); - gtk_table_set_col_spacings( table, 5 ); - - { - GtkImage* image = new_local_image( "cap_bevel.png" ); - gtk_widget_show( GTK_WIDGET( image ) ); - gtk_table_attach( table, GTK_WIDGET( image ), 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkImage* image = new_local_image( "cap_endcap.png" ); - gtk_widget_show( GTK_WIDGET( image ) ); - gtk_table_attach( table, GTK_WIDGET( image ), 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkImage* image = new_local_image( "cap_ibevel.png" ); - gtk_widget_show( GTK_WIDGET( image ) ); - gtk_table_attach( table, GTK_WIDGET( image ), 0, 1, 2, 3, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkImage* image = new_local_image( "cap_iendcap.png" ); - gtk_widget_show( GTK_WIDGET( image ) ); - gtk_table_attach( table, GTK_WIDGET( image ), 0, 1, 3, 4, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkImage* image = new_local_image( "cap_cylinder.png" ); - gtk_widget_show( GTK_WIDGET( image ) ); - gtk_table_attach( table, GTK_WIDGET( image ), 0, 1, 4, 5, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - - GtkRadioButton* group = 0; - { - GtkWidget* button = gtk_radio_button_new_with_label_from_widget( group, "Bevel" ); - gtk_widget_show( button ); - gtk_table_attach( table, button, 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - group = GTK_RADIO_BUTTON( button ); - bevel = button; - } - { - GtkWidget* button = gtk_radio_button_new_with_label_from_widget( group, "Endcap" ); - gtk_widget_show( button ); - gtk_table_attach( table, button, 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - endcap = button; - } - { - GtkWidget* button = gtk_radio_button_new_with_label_from_widget( group, "Inverted Bevel" ); - gtk_widget_show( button ); - gtk_table_attach( table, button, 1, 2, 2, 3, - (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - ibevel = button; - } - { - GtkWidget* button = gtk_radio_button_new_with_label_from_widget( group, "Inverted Endcap" ); - gtk_widget_show( button ); - gtk_table_attach( table, button, 1, 2, 3, 4, - (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - iendcap = button; - } - { - GtkWidget* button = gtk_radio_button_new_with_label_from_widget( group, "Cylinder" ); - gtk_widget_show( button ); - gtk_table_attach( table, button, 1, 2, 4, 5, - (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - cylinder = button; - } + const char* iconlabel[][2] = { { "cap_bevel.png", "Bevel" }, + { "cap_endcap.png", "Endcap" }, + { "cap_ibevel.png", "Inverted Bevel" }, + { "cap_iendcap.png", "Inverted Endcap" }, + { "cap_cylinder.png", "Cylinder" } }; + for( size_t i = 0; i < std::size( iconlabel ); ++i ){ + const auto [ stricon, strlabel ] = iconlabel[i]; + auto label = new QLabel; + label->setPixmap( new_local_image( stricon ) ); + auto button = new QRadioButton( strlabel ); + group->addButton( button, i ); // set ids 0+, default ones are negative + form->addRow( label, button ); } + for( int i = 0; i < form->count(); ++i ) + form->itemAt( i )->setAlignment( Qt::AlignmentFlag::AlignVCenter ); } - { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), FALSE, FALSE, 0 ); - { - GtkButton* button = create_modal_dialog_button( "OK", ok_button ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel_group, GDK_KEY_Return, (GdkModifierType)0, GTK_ACCEL_VISIBLE ); - } - { - GtkButton* button = create_modal_dialog_button( "Cancel", cancel_button ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel_group, GDK_KEY_Escape, (GdkModifierType)0, GTK_ACCEL_VISIBLE ); - } + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel ); + form->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept ); + QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject ); } } // Initialize dialog - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( bevel ), TRUE ); + group->button( 0 )->setChecked( true ); - EMessageBoxReturn ret = modal_dialog_show( window, dialog ); - if ( ret == eIDOK ) { - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( bevel ) ) ) { - *type = PATCHCAP_BEVEL; - } - else if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( endcap ) ) ) { - *type = PATCHCAP_ENDCAP; - } - else if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( ibevel ) ) ) { - *type = PATCHCAP_INVERTED_BEVEL; - } - else if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( iendcap ) ) ) { - *type = PATCHCAP_INVERTED_ENDCAP; - } - else if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( cylinder ) ) ) { - *type = PATCHCAP_CYLINDER; - } + if( dialog.exec() ){ + Scene_PatchDoCap_Selected( GlobalSceneGraph(), TextureBrowser_GetSelectedShader(), static_cast( group->checkedId() ) ); } - - gtk_widget_destroy( GTK_WIDGET( window ) ); - - return ret; } void DoPatchThickenDlg(){ - ModalDialog dialog; - GtkWidget* thicknessW; - GtkWidget* seamsW; - GtkWidget* radX; - GtkWidget* radY; - GtkWidget* radZ; + QDialog dialog( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + dialog.setWindowTitle( "Patch thicken" ); - GtkWindow* window = create_dialog_window( MainFrame_getWindow(), "Patch thicken", G_CALLBACK( dialog_delete_callback ), &dialog ); + const int grid = std::max( GetGridSize(), 1.f ); + auto spin = new SpinBox( -9999, 9999, grid, 2, grid ); - GtkAccelGroup* accel = gtk_accel_group_new(); - gtk_window_add_accel_group( window, accel ); + RadioHBox radioBox = RadioHBox_new( (const char*[]){ "X", "Y", "Z", "Normal" } ); + radioBox.m_radio->button( 3 )->setChecked( true ); + + auto check = new QCheckBox( "Side walls" ); + check->setChecked( true ); { - GtkHBox* hbox = create_dialog_hbox( 4, 4 ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( hbox ) ); + auto form = new QFormLayout( &dialog ); + form->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + form->addRow( new SpinBoxLabel( "Thickness:", spin ), spin ); + form->addRow( "", radioBox.m_hbox ); + form->addWidget( check ); { - GtkTable* table = create_dialog_table( 2, 4, 4, 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - { - GtkLabel* label = GTK_LABEL( gtk_label_new( "Thickness:" ) ); - gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); - } -// { -// GtkWidget* entry = gtk_entry_new(); -// gtk_entry_set_text( GTK_ENTRY( entry ), "16" ); -// gtk_widget_set_size_request( entry, 40, -1 ); -// gtk_widget_show( entry ); -// gtk_table_attach( table, entry, 1, 2, 0, 1, -// (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), -// (GtkAttachOptions) ( 0 ), 0, 0 ); -// -// thicknessW = entry; -// } - { - const float grid = std::max( GetGridSize(), 1.f ); - GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( grid, -9999, 9999, grid, 16, 0 ) ); - GtkWidget* spin = gtk_spin_button_new( adj, 1, 0 ); - gtk_widget_show( spin ); - gtk_table_attach( table, spin, 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( spin, 48, -1 ); - gtk_spin_button_set_numeric( GTK_SPIN_BUTTON( spin ), TRUE ); - - gtk_widget_grab_focus( spin ); - - thicknessW = spin; - } - { - // Create the "create seams" label - GtkWidget* _seamsCheckBox = gtk_check_button_new_with_label( "Side walls" ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( _seamsCheckBox ), TRUE ); - gtk_widget_show( _seamsCheckBox ); - gtk_table_attach( table, _seamsCheckBox, 2, 4, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - seamsW = _seamsCheckBox; - - } - { - // Create the radio button group for choosing the extrude axis - GtkWidget* _radNormals = gtk_radio_button_new_with_label_from_widget( NULL, "Normal" ); - GtkWidget* _radX = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(_radNormals), "X" ); - GtkWidget* _radY = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(_radNormals), "Y" ); - GtkWidget* _radZ = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(_radNormals), "Z" ); - gtk_widget_show( _radNormals ); - gtk_widget_show( _radX ); - gtk_widget_show( _radY ); - gtk_widget_show( _radZ ); - - - // Pack the buttons into the table - gtk_table_attach( table, _radNormals, 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_table_attach( table, _radX, 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_table_attach( table, _radY, 2, 3, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_table_attach( table, _radZ, 3, 4, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - radX = _radX; - radY = _radY; - radZ = _radZ; - } - } - { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), TRUE, TRUE, 0 ); - { - GtkButton* button = create_dialog_button( "OK", G_CALLBACK( dialog_button_ok ), &dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 ); - } - { - GtkButton* button = create_dialog_button( "Cancel", G_CALLBACK( dialog_button_cancel ), &dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 ); - } + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel ); + form->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept ); + QObject::connect( buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject ); } } - if ( modal_dialog_show( window, dialog ) == eIDOK ) { - int axis = 3; // Extrude along normals - bool seams; - //float thickness = static_cast( atoi( gtk_entry_get_text( GTK_ENTRY( thicknessW ) ) ) ); - gtk_spin_button_update ( GTK_SPIN_BUTTON( thicknessW ) ); - float thickness = static_cast( gtk_spin_button_get_value( GTK_SPIN_BUTTON( thicknessW ) ) ); - seams = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( seamsW )) ? true : false; - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radX))) { - axis = 0; - } - else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radY))) { - axis = 1; - } - else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radZ))) { - axis = 2; - } + if ( dialog.exec() ) { + const int thickness = spin->value(); + const bool seams = check->isChecked(); + const int axis = radioBox.m_radio->checkedId(); // 3 == Extrude along normals Scene_PatchThicken( GlobalSceneGraph(), thickness, seams, axis ); } - - gtk_widget_destroy( GTK_WIDGET( window ) ); +} + + + + +class PatchTexdefConstructor +{ +public: + brushprimit_texdef_t m_bp; + Matrix4 m_local2tex; + Matrix4 m_tex2local; + Plane3 m_plane; + // rip from UVManipulator::UpdateFaceData + PatchTexdefConstructor( Patch *patch ){ + m_plane.normal() = patch->Calculate_AvgNormal(); + m_plane.dist() = vector3_dot( m_plane.normal(), patch->localAABB().origin ); + const size_t patchWidth = patch->getWidth(); + const size_t patchHeight = patch->getHeight(); + { //! todo force or deduce orthogonal uv axes for convenience + Vector3 wDir, hDir; + patch->Calculate_AvgAxes( wDir, hDir ); + vector3_normalise( wDir ); + vector3_normalise( hDir ); +// globalOutputStream() << wDir << " wDir\n"; +// globalOutputStream() << hDir << " hDir\n"; +// globalOutputStream() << m_plane.normal() << " m_plane.normal()\n"; + + /* find longest row and column */ + float wLength = 0, hLength = 0; //!? todo break, if some of these is 0 + std::size_t row = 0, col = 0; + for ( std::size_t r = 0; r < patchHeight; ++r ){ + float length = 0; + for ( std::size_t c = 0; c < patchWidth - 1; ++c ){ + length += vector3_length( patch->ctrlAt( r, c + 1 ).m_vertex - patch->ctrlAt( r, c ).m_vertex ); + } + if( length - wLength > .1f || ( ( r == 0 || r == patchHeight - 1 ) && float_equal_epsilon( length, wLength, .1f ) ) ){ // prioritize first and last rows + wLength = length; + row = r; + } + } + for ( std::size_t c = 0; c < patchWidth; ++c ){ + float length = 0; + for ( std::size_t r = 0; r < patchHeight - 1; ++r ){ + length += vector3_length( patch->ctrlAt( r + 1, c ).m_vertex - patch->ctrlAt( r, c ).m_vertex ); + } + if( length - hLength > .1f || ( ( c == 0 || c == patchWidth - 1 ) && float_equal_epsilon( length, hLength, .1f ) ) ){ + hLength = length; + col = c; + } + } + //! todo handle case, when uv start = end, like projection to cylinder + //! todo consider max uv length to have manipulator size according to patch size + /* pick 3 points at the found row and column */ + const PatchControl* p0, *p1, *p2; + Vector3 v0, v1, v2; + { + float distW0 = 0, distW1 = 0; + for ( std::size_t c = 0; c < col; ++c ){ + distW0 += vector3_length( patch->ctrlAt( row, c + 1 ).m_vertex - patch->ctrlAt( row, c ).m_vertex ); + } + for ( std::size_t c = col; c < patchWidth - 1; ++c ){ + distW1 += vector3_length( patch->ctrlAt( row, c + 1 ).m_vertex - patch->ctrlAt( row, c ).m_vertex ); + } + float distH0 = 0, distH1 = 0; + for ( std::size_t r = 0; r < row; ++r ){ + distH0 += vector3_length( patch->ctrlAt( r + 1, col ).m_vertex - patch->ctrlAt( r, col ).m_vertex ); + } + for ( std::size_t r = row; r < patchHeight - 1; ++r ){ + distH1 += vector3_length( patch->ctrlAt( r + 1, col ).m_vertex - patch->ctrlAt( r, col ).m_vertex ); + } + + if( ( distW0 > distH0 && distW0 > distH1 ) || ( distW1 > distH0 && distW1 > distH1 ) ){ + p0 = &patch->ctrlAt( 0, col ); + p1 = &patch->ctrlAt( patchHeight - 1, col ); + p2 = distW0 > distW1? &patch->ctrlAt( row, 0 ) : &patch->ctrlAt( row, patchWidth - 1 ); + v0 = p0->m_vertex; //! the altered line, we want realistic offset values + v1 = v0 + hDir * hLength; + v2 = v0 + hDir * distH0 + ( distW0 > distW1? ( wDir * -distW0 ) : ( wDir * distW1 ) ); + } + else{ + p0 = &patch->ctrlAt( row, 0 ); + p1 = &patch->ctrlAt( row, patchWidth - 1 ); + p2 = distH0 > distH1? &patch->ctrlAt( 0, col ) : &patch->ctrlAt( patchHeight - 1, col ); + v0 = p0->m_vertex; //! the altered line, we want realistic offset values + v1 = v0 + wDir * wLength; + v2 = v0 + wDir * distW0 + ( distH0 > distH1? ( hDir * -distH0 ) : ( hDir * distH1 ) ); + } + + if( vector3_dot( plane3_for_points( v0, v1, v2 ).normal(), m_plane.normal() ) < 0 ){ + std::swap( p0, p1 ); + std::swap( v0, v1 ); + } + } + const DoubleVector3 vertices[3]{ v0, v1, v2 }; + const DoubleVector3 sts[3]{ DoubleVector3( p0->m_texcoord ), + DoubleVector3( p1->m_texcoord ), + DoubleVector3( p2->m_texcoord ) }; + Texdef_Construct_local2tex_from_ST( vertices, sts, m_local2tex ); + m_tex2local = matrix4_affine_inverse( m_local2tex ); + BP_from_ST( m_bp, vertices, sts, plane3_for_points( vertices ).normal() ); + m_bp.removeScale( patch->getShader()->getTexture().width, patch->getShader()->getTexture().height ); + } + } + bool valid() const { + return !( !std::isfinite( m_local2tex[0] ) //nan + || !std::isfinite( m_tex2local[0] ) //nan + || fabs( vector3_dot( m_plane.normal(), m_tex2local.z().vec3() ) ) < 1e-6 //projected along face + || vector3_length_squared( m_tex2local.x().vec3() ) < .01 //srsly scaled down, limit at max 10 textures per world unit + || vector3_length_squared( m_tex2local.y().vec3() ) < .01 ); + } +}; + +void Scene_PatchGetTexdef_Selected( scene::Graph& graph, TextureProjection &projection ){ + if ( Patch* patch = Scene_GetUltimateSelectedVisiblePatch() ){ + PatchTexdefConstructor c( patch ); + if( c.valid() ) + projection.m_brushprimit_texdef = c.m_bp; + } +} + +void Patch_SetTexdef( const float* hShift, const float* vShift, const float* hScale, const float* vScale, const float* rotation ){ + Scene_forEachVisibleSelectedPatch( [hShift, vShift, hScale, vScale, rotation]( Patch& patch ){ + PatchTexdefConstructor c( &patch ); + if( c.valid() ){ + BPTexdef_Assign( c.m_bp, hShift, vShift, hScale, vScale, rotation ); + Matrix4 local2tex; + c.m_bp.addScale( patch.getShader()->getTexture().width, patch.getShader()->getTexture().height ); + BP_Construct_local2tex( c.m_bp, c.m_plane, local2tex ); + matrix4_multiply_by_matrix4( local2tex, c.m_tex2local ); + patch.undoSave(); + for( auto& p : patch.getControlPoints() ) + p.m_texcoord = matrix4_transformed_point( local2tex, Vector3( p.m_texcoord ) ).vec2(); + patch.controlPointsChanged(); + } + else{ // fallback //. fixme: this is not cool; may be more valid cases in PatchTexdefConstructor, as in find one good triangle in problematic case + if( hShift ) + Scene_PatchTranslateTexture_Selected( GlobalSceneGraph(), *hShift > 0? 8 : -8, 0 ); + if( vShift ) + Scene_PatchTranslateTexture_Selected( GlobalSceneGraph(), 0, *vShift > 0? 8 : -8 ); + if( hScale ) + Scene_PatchScaleTexture_Selected( GlobalSceneGraph(), *hScale > 0? .5 : -.5, 0 ); + if( vScale ) + Scene_PatchScaleTexture_Selected( GlobalSceneGraph(), 0, *vScale > 0? .5 : -.5 ); + if( rotation ) + Scene_PatchRotateTexture_Selected( GlobalSceneGraph(), *rotation > 0? 15 : -15 ); + + } + Patch_textureChanged(); + } ); } diff --git a/radiant/patchmanip.h b/radiant/patchmanip.h index 48bbcdce..39953086 100644 --- a/radiant/patchmanip.h +++ b/radiant/patchmanip.h @@ -24,10 +24,8 @@ #include "string/stringfwd.h" void Patch_registerCommands(); -typedef struct _GtkToolbar GtkToolbar; -typedef struct _GtkMenu GtkMenu; -void Patch_constructToolbar( GtkToolbar* toolbar ); -void Patch_constructMenu( GtkMenu* menu ); +void Patch_constructToolbar( class QToolBar* toolbar ); +void Patch_constructMenu( class QMenu* menu ); namespace scene { @@ -40,6 +38,9 @@ void Scene_PatchSelectByShader( scene::Graph& graph, const char* name ); void Scene_PatchFindReplaceShader( scene::Graph& graph, const char* find, const char* replace ); void Scene_PatchFindReplaceShader_Selected( scene::Graph& graph, const char* find, const char* replace ); +void Scene_PatchGetTexdef_Selected( scene::Graph& graph, class TextureProjection &projection ); +void Patch_SetTexdef( const float* hShift, const float* vShift, const float* hScale, const float* vScale, const float* rotation ); + void Scene_PatchCapTexture_Selected( scene::Graph& graph ); class texdef_t; template class BasicVector3; @@ -58,10 +59,8 @@ void Patch_registerPreferencesPage(); void Patch_NaturalTexture(); void Patch_CapTexture(); -void Patch_FitTexture(); -void Patch_FitTexture11(); +void Scene_PatchFlipTexture_Selected( scene::Graph& graph, int axis ); void Patch_FlipTextureX(); void Patch_FlipTextureY(); -class PatchCreator; -extern PatchCreator* g_patchCreator; +extern class PatchCreator* g_patchCreator; diff --git a/radiant/plugin.cpp b/radiant/plugin.cpp index c5b88aac..e354de58 100644 --- a/radiant/plugin.cpp +++ b/radiant/plugin.cpp @@ -63,7 +63,6 @@ #include "mainframe.h" #include "build.h" #include "mru.h" -#include "multimon.h" #include "surfacedialog.h" #include "groupdialog.h" #include "patchdialog.h" @@ -157,11 +156,11 @@ public: m_radiantcore.TextureBrowser_getSelectedShader = TextureBrowser_GetSelectedShader; - m_radiantcore.m_pfnMessageBox = >k_MessageBox; + m_radiantcore.m_pfnMessageBox = &qt_MessageBox; m_radiantcore.m_pfnFileDialog = &file_dialog; m_radiantcore.m_pfnColorDialog = &color_dialog; m_radiantcore.m_pfnDirDialog = &dir_dialog; - m_radiantcore.m_pfnNewImage = &new_plugin_image; + m_radiantcore.m_pfnNewIcon = &new_plugin_icon; } _QERFuncTable_1* getTable(){ return &m_radiantcore; @@ -251,7 +250,6 @@ public: HomePaths_Construct(); VFS_Construct(); Grid_construct(); - MultiMon_Construct(); MRU_Construct(); Pointfile_Construct(); BuildMenu_Construct(); @@ -260,7 +258,6 @@ public: MainFrame_Construct(); GroupDialog_Construct(); SurfaceInspector_Construct(); - PatchInspector_Construct(); CamWnd_Construct(); XYWindow_Construct(); BuildMonitor_Construct(); @@ -290,7 +287,6 @@ public: BuildMonitor_Destroy(); XYWindow_Destroy(); CamWnd_Destroy(); - PatchInspector_Destroy(); SurfaceInspector_Destroy(); GroupDialog_Destroy(); MainFrame_Destroy(); @@ -299,7 +295,6 @@ public: BuildMenu_Destroy(); Pointfile_Destroy(); MRU_Destroy(); - MultiMon_Destroy(); Grid_destroy(); VFS_Destroy(); HomePaths_Destroy(); diff --git a/radiant/pluginapi.cpp b/radiant/pluginapi.cpp index a5fb3248..576b10e7 100644 --- a/radiant/pluginapi.cpp +++ b/radiant/pluginapi.cpp @@ -45,17 +45,6 @@ void QERApp_SetCamera( const Vector3& origin, const Vector3& angles ){ Camera_setAngles( camwnd, angles ); } -void QERApp_GetCamWindowExtents( int *x, int *y, int *width, int *height ){ -#if 0 - CamWnd* camwnd = g_pParentWnd->GetCamWnd(); - - gtk_window_get_position( GTK_WINDOW( camwnd->m_window ), x, y ); - - *width = camwnd->Camera()->width; - *height = camwnd->Camera()->height; -#endif -} - #include "icamera.h" class CameraAPI @@ -68,7 +57,6 @@ public: CameraAPI(){ m_camera.m_pfnGetCamera = &QERApp_GetCamera; m_camera.m_pfnSetCamera = &QERApp_SetCamera; - m_camera.m_pfnGetCamWindowExtents = &QERApp_GetCamWindowExtents; } _QERCameraTable* getTable(){ return &m_camera; diff --git a/radiant/pluginapi.h b/radiant/pluginapi.h index cb2acd13..a1eff203 100644 --- a/radiant/pluginapi.h +++ b/radiant/pluginapi.h @@ -27,4 +27,3 @@ typedef BasicVector3 Vector3; // camera API void QERApp_GetCamera( Vector3& origin, Vector3& angles ); void QERApp_SetCamera( const Vector3& origin, const Vector3& angles ); -void QERApp_GetCamWindowExtents( int *x, int *y, int *width, int *height ); diff --git a/radiant/pluginmanager.cpp b/radiant/pluginmanager.cpp index 5b9897cb..4c975e6b 100644 --- a/radiant/pluginmanager.cpp +++ b/radiant/pluginmanager.cpp @@ -69,7 +69,7 @@ public: /*! build directly from a SYN_PROVIDE interface */ - CPluginSlot( GtkWidget* main_window, const char* name, const _QERPluginTable& table ); + CPluginSlot( QWidget* main_window, const char* name, const _QERPluginTable& table ); /*! dispatching a command by name to the plugin */ @@ -83,7 +83,7 @@ public: const char* getGlobalCommand( std::size_t n ); }; -CPluginSlot::CPluginSlot( GtkWidget* main_window, const char* name, const _QERPluginTable& table ){ +CPluginSlot::CPluginSlot( QWidget* main_window, const char* name, const _QERPluginTable& table ){ mpTable = &table; m_menu_name = name; @@ -183,7 +183,7 @@ class CPluginSlots public: virtual ~CPluginSlots(); - void AddPluginSlot( GtkWidget* main_window, const char* name, const _QERPluginTable& table ){ + void AddPluginSlot( QWidget* main_window, const char* name, const _QERPluginTable& table ){ mSlots.push_back( new CPluginSlot( main_window, name, table ) ); } @@ -210,13 +210,13 @@ void CPluginSlots::PopulateMenu( PluginsVisitor& menu ){ CPluginSlots g_plugin_slots; -void FillPluginSlots( CPluginSlots& slots, GtkWidget* main_window ){ +void FillPluginSlots( CPluginSlots& slots, QWidget* main_window ){ class AddPluginVisitor : public PluginModules::Visitor { CPluginSlots& m_slots; - GtkWidget* m_main_window; + QWidget* m_main_window; public: - AddPluginVisitor( CPluginSlots& slots, GtkWidget* main_window ) + AddPluginVisitor( CPluginSlots& slots, QWidget* main_window ) : m_slots( slots ), m_main_window( main_window ){ } void visit( const char* name, const _QERPluginTable& table ) const { @@ -234,7 +234,7 @@ CPlugInManager& GetPlugInMgr(){ return g_PlugInMgr; } -void CPlugInManager::Init( GtkWidget* main_window ){ +void CPlugInManager::Init( QWidget* main_window ){ FillPluginSlots( g_plugin_slots, main_window ); } diff --git a/radiant/pluginmanager.h b/radiant/pluginmanager.h index f71f9ec1..a0b34f7f 100644 --- a/radiant/pluginmanager.h +++ b/radiant/pluginmanager.h @@ -23,8 +23,6 @@ #include -typedef struct _GtkWidget GtkWidget; - /*! \class IPlugin pure virtual interface for a plugin @@ -52,7 +50,7 @@ public: class CPlugInManager { public: - void Init( GtkWidget* main_window ); + void Init( class QWidget* main_window ); void constructMenu( PluginsVisitor& menu ); void Shutdown(); }; diff --git a/radiant/pluginmenu.cpp b/radiant/pluginmenu.cpp index 440a0107..24f3814a 100644 --- a/radiant/pluginmenu.cpp +++ b/radiant/pluginmenu.cpp @@ -23,9 +23,8 @@ #include "stream/textstream.h" -#include +#include -#include "gtkutil/pointer.h" #include "gtkutil/menu.h" #include "pluginmanager.h" @@ -35,17 +34,16 @@ #include "gtkmisc.h" #include -typedef std::stack MenuStack; +typedef std::stack MenuStack; -void PlugInMenu_Add( GtkMenu* plugin_menu, IPlugIn* pPlugIn ){ - GtkMenu *menu; +void PlugInMenu_Add( QMenu* plugin_menu, IPlugIn* pPlugIn ){ + QMenu *menu; const char *menuText; MenuStack menuStack; - menu = create_sub_menu_with_mnemonic( plugin_menu, pPlugIn->getMenuName() ); - if ( g_Layout_enableDetachableMenus.m_value ) { - menu_tearoff( menu ); - } + menu = plugin_menu->addMenu( pPlugIn->getMenuName() ); + + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); std::size_t nCount = pPlugIn->getCommandCount(); { @@ -55,7 +53,7 @@ void PlugInMenu_Add( GtkMenu* plugin_menu, IPlugIn* pPlugIn ){ if ( menuText != 0 && strlen( menuText ) > 0 ) { if ( plugin_menu_separator( menuText ) ) { - menu_separator( menu ); + menu->addSeparator(); } else if ( plugin_submenu_in( menuText ) ) { menuText = pPlugIn->getCommandTitle( --nCount ); @@ -64,10 +62,10 @@ void PlugInMenu_Add( GtkMenu* plugin_menu, IPlugIn* pPlugIn ){ continue; } menuStack.push( menu ); - menu = create_sub_menu_with_mnemonic( menu, menuText ); - if ( g_Layout_enableDetachableMenus.m_value ) { - menu_tearoff( menu ); - } + menu = menu->addMenu( menuText ); + + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + continue; } else if ( plugin_submenu_out( menuText ) ) { @@ -88,20 +86,20 @@ void PlugInMenu_Add( GtkMenu* plugin_menu, IPlugIn* pPlugIn ){ } } if ( !menuStack.empty() ) { - globalErrorStream() << pPlugIn->getMenuName() << " mismatched > <. " << Unsigned( menuStack.size() ) << " submenu(s) not closed.\n"; + globalErrorStream() << pPlugIn->getMenuName() << " mismatched > <. " << menuStack.size() << " submenu(s) not closed.\n"; } } } -GtkMenu* g_plugins_menu = 0; -GtkMenuItem* g_plugins_menu_separator = 0; +QMenu* g_plugins_menu = 0; +QAction* g_plugins_menu_separator = 0; void PluginsMenu_populate(){ class PluginsMenuConstructor : public PluginsVisitor { - GtkMenu* m_menu; + QMenu* m_menu; public: - PluginsMenuConstructor( GtkMenu* menu ) : m_menu( menu ){ + PluginsMenuConstructor( QMenu* menu ) : m_menu( menu ){ } void visit( IPlugIn& plugin ){ PlugInMenu_Add( m_menu, &plugin ); @@ -113,21 +111,21 @@ void PluginsMenu_populate(){ } void PluginsMenu_clear(){ +#if 0 // unused, intended for "Refresh" GList* lst = g_list_find( gtk_container_get_children( GTK_CONTAINER( g_plugins_menu ) ), GTK_WIDGET( g_plugins_menu_separator ) ); while ( lst->next ) { gtk_container_remove( GTK_CONTAINER( g_plugins_menu ), GTK_WIDGET( lst->next->data ) ); lst = g_list_find( gtk_container_get_children( GTK_CONTAINER( g_plugins_menu ) ), GTK_WIDGET( g_plugins_menu_separator ) ); } +#endif } -GtkMenuItem* create_plugins_menu(){ +void create_plugins_menu( QMenuBar *menubar ){ // Plugins menu - GtkMenuItem* plugins_menu_item = new_sub_menu_item_with_mnemonic( "_Plugins" ); - GtkMenu* menu = GTK_MENU( gtk_menu_item_get_submenu( plugins_menu_item ) ); - if ( g_Layout_enableDetachableMenus.m_value ) { - menu_tearoff( menu ); - } + QMenu *menu = menubar->addMenu( "&Plugins" ); + + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); g_plugins_menu = menu; @@ -140,6 +138,4 @@ GtkMenuItem* create_plugins_menu(){ #endif PluginsMenu_populate(); - - return plugins_menu_item; } diff --git a/radiant/pluginmenu.h b/radiant/pluginmenu.h index fdc1882c..282217f2 100644 --- a/radiant/pluginmenu.h +++ b/radiant/pluginmenu.h @@ -21,10 +21,7 @@ #pragma once -typedef struct _GtkMenuItem GtkMenuItem; -GtkMenuItem* create_plugins_menu(); +void create_plugins_menu( class QMenuBar *menubar ); -typedef struct _GtkMenu GtkMenu; -typedef struct _GtkMenuItem GtkMenuItem; void PluginsMenu_populate(); void PluginsMenu_clear(); diff --git a/radiant/plugintoolbar.cpp b/radiant/plugintoolbar.cpp index a98f4942..481e7c57 100644 --- a/radiant/plugintoolbar.cpp +++ b/radiant/plugintoolbar.cpp @@ -25,67 +25,54 @@ #include "itoolbar.h" #include "modulesystem.h" -#include - #include "stream/stringstream.h" +#include "os/file.h" #include "gtkutil/image.h" -#include "gtkutil/container.h" #include "gtkutil/toolbar.h" #include "mainframe.h" #include "plugin.h" -GtkImage* new_plugin_image( const char* filename ){ +QIcon new_plugin_icon( const char* filename ){ + StringOutputStream fullpath( 256 ); { - StringOutputStream fullpath( 256 ); - fullpath << AppPath_get() << g_pluginsDir << "bitmaps/" << filename; - GtkImage* image = image_new_from_file_with_mask( fullpath.c_str() ); - if ( image != 0 ) { - return image; - } + fullpath( AppPath_get(), g_pluginsDir, "bitmaps/", filename ); + if( file_exists( fullpath ) ) + return QIcon( fullpath.c_str() ); } { - StringOutputStream fullpath( 256 ); - fullpath << GameToolsPath_get() << g_pluginsDir << "bitmaps/" << filename; - GtkImage* image = image_new_from_file_with_mask( fullpath.c_str() ); - if ( image != 0 ) { - return image; - } + fullpath( GameToolsPath_get(), g_pluginsDir, "bitmaps/", filename ); + if( file_exists( fullpath ) ) + return QIcon( fullpath.c_str() ); } { - StringOutputStream fullpath( 256 ); - fullpath << AppPath_get() << g_modulesDir << "bitmaps/" << filename; - GtkImage* image = image_new_from_file_with_mask( fullpath.c_str() ); - if ( image != 0 ) { - return image; - } + fullpath( AppPath_get(), g_modulesDir, "bitmaps/", filename ); + if( file_exists( fullpath ) ) + return QIcon( fullpath.c_str() ); } - return image_new_missing(); + return {}; } -void toolbar_insert( GtkToolbar *toolbar, const char* icon, const char* text, const char* tooltip, IToolbarButton::EType type, GCallback callback, gpointer data ){ +void toolbar_insert( QToolBar *toolbar, const char* icon, const char* text, const char* tooltip, IToolbarButton::EType type, const IToolbarButton* ibutton ){ switch ( type ) { case IToolbarButton::eSpace: - toolbar_append_space( toolbar ); + toolbar->addSeparator(); return; case IToolbarButton::eButton: { - GtkToolButton* button = GTK_TOOL_BUTTON( gtk_tool_button_new( GTK_WIDGET( new_plugin_image( icon ) ), text ) ); - g_signal_connect( G_OBJECT( button ), "clicked", callback, data ); - toolbar_append( toolbar, GTK_TOOL_ITEM( button ), tooltip ); + QAction *button = toolbar->addAction( new_plugin_icon( icon ), text, [ibutton](){ ibutton->activate(); } ); + button->setToolTip( tooltip ); } return; case IToolbarButton::eToggleButton: { - GtkToggleToolButton* button = GTK_TOGGLE_TOOL_BUTTON( gtk_toggle_tool_button_new() ); - gtk_tool_button_set_icon_widget( GTK_TOOL_BUTTON( button ), GTK_WIDGET( new_plugin_image( icon ) ) ); - gtk_tool_button_set_label( GTK_TOOL_BUTTON( button ), text ); - g_signal_connect( G_OBJECT( button ), "toggled", callback, data ); - toolbar_append( toolbar, GTK_TOOL_ITEM( button ), tooltip ); + QAction *button = toolbar->addAction( new_plugin_icon( icon ), text, [ibutton](){ ibutton->activate(); } ); + button->setToolTip( tooltip ); + button->setCheckable( true ); } return; case IToolbarButton::eRadioButton: @@ -97,22 +84,18 @@ void toolbar_insert( GtkToolbar *toolbar, const char* icon, const char* text, co } } -void ActivateToolbarButton( GtkWidget *widget, gpointer data ){ - const_cast( reinterpret_cast( data ) )->activate(); +void PlugInToolbar_AddButton( QToolBar* toolbar, const IToolbarButton* button ){ + toolbar_insert( toolbar, button->getImage(), button->getText(), button->getTooltip(), button->getType(), button ); } -void PlugInToolbar_AddButton( GtkToolbar* toolbar, const IToolbarButton* button ){ - toolbar_insert( toolbar, button->getImage(), button->getText(), button->getTooltip(), button->getType(), G_CALLBACK( ActivateToolbarButton ), reinterpret_cast( const_cast( button ) ) ); -} - -GtkToolbar* g_plugin_toolbar = 0; +QToolBar* g_plugin_toolbar = 0; void PluginToolbar_populate(){ class AddToolbarItemVisitor : public ToolbarModules::Visitor { - GtkToolbar* m_toolbar; + QToolBar* m_toolbar; public: - AddToolbarItemVisitor( GtkToolbar* toolbar ) + AddToolbarItemVisitor( QToolBar* toolbar ) : m_toolbar( toolbar ){ } void visit( const char* name, const _QERPlugToolbarTable& table ) const { @@ -129,11 +112,12 @@ void PluginToolbar_populate(){ } void PluginToolbar_clear(){ +#if 0 // unused, intended for "Refresh" container_remove_all( GTK_CONTAINER( g_plugin_toolbar ) ); +#endif } -GtkToolbar* create_plugin_toolbar(){ - g_plugin_toolbar = toolbar_new(); +void create_plugin_toolbar( QToolBar *toolbar ){ + g_plugin_toolbar = toolbar; PluginToolbar_populate(); - return g_plugin_toolbar; } diff --git a/radiant/plugintoolbar.h b/radiant/plugintoolbar.h index 22384741..bf7eb54d 100644 --- a/radiant/plugintoolbar.h +++ b/radiant/plugintoolbar.h @@ -21,10 +21,8 @@ #pragma once -typedef struct _GtkToolbar GtkToolbar; -GtkToolbar* create_plugin_toolbar(); +void create_plugin_toolbar( class QToolBar *toolbar ); void PluginToolbar_populate(); void PluginToolbar_clear(); -typedef struct _GtkImage GtkImage; -GtkImage* new_plugin_image( const char* filename ); // filename is relative to plugin bitmaps path +class QIcon new_plugin_icon( const char* filename ); // filename is relative to plugin bitmaps path diff --git a/radiant/points.cpp b/radiant/points.cpp index 2c402e81..0539630e 100644 --- a/radiant/points.cpp +++ b/radiant/points.cpp @@ -49,8 +49,7 @@ #include "commands.h" -class CPointfile; -void Pointfile_Parse( CPointfile& pointfile ); +void Pointfile_Parse( class CPointfile& pointfile ); class CPointfile : public ISAXHandler, public Renderable, public OpenGLRenderable @@ -98,14 +97,14 @@ public: } } else if ( !show && shown() ) { - glDeleteLists( m_displaylist, 1 ); + gl().glDeleteLists( m_displaylist, 1 ); m_displaylist = 0; SceneChangeNotify(); } } void render( RenderStateFlags state ) const { - glCallList( m_displaylist ); + gl().glCallList( m_displaylist ); } void renderSolid( Renderer& renderer, const VolumeTest& volume ) const { @@ -153,17 +152,17 @@ void CPointfile::PushPoint( const Vector3& v ){ // create the display list at the end void CPointfile::GenerateDisplayList(){ - m_displaylist = glGenLists( 1 ); + m_displaylist = gl().glGenLists( 1 ); - glNewList( m_displaylist, GL_COMPILE ); + gl().glNewList( m_displaylist, GL_COMPILE ); - glBegin( GL_LINE_STRIP ); + gl().glBegin( GL_LINE_STRIP ); for ( std::size_t i = 0; i < s_num_points; i++ ) - glVertex3fv( vector3_to_array( s_pointvecs[i] ) ); - glEnd(); - glLineWidth( 1 ); + gl().glVertex3fv( vector3_to_array( s_pointvecs[i] ) ); + gl().glEnd(); + gl().glLineWidth( 1 ); - glEndList(); + gl().glEndList(); } // old (but still relevant) pointfile code ------------------------------------- @@ -305,7 +304,7 @@ void Pointfile_Parse( CPointfile& pointfile ){ pointfile.PushPoint( v ); } - g_free( text ); + free( text ); } void Pointfile_Clear(){ @@ -324,8 +323,8 @@ void Pointfile_Construct(){ GlobalShaderCache().attachRenderable( s_pointfile ); GlobalCommands_insert( "TogglePointfile", FreeCaller() ); - GlobalCommands_insert( "NextLeakSpot", FreeCaller(), Accelerator( 'K', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); - GlobalCommands_insert( "PrevLeakSpot", FreeCaller(), Accelerator( 'L', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); + GlobalCommands_insert( "NextLeakSpot", FreeCaller(), QKeySequence( "Ctrl+Shift+K" ) ); + GlobalCommands_insert( "PrevLeakSpot", FreeCaller(), QKeySequence( "Ctrl+Shift+L" ) ); } void Pointfile_Destroy(){ diff --git a/radiant/points.h b/radiant/points.h index ea022f29..1f811661 100644 --- a/radiant/points.h +++ b/radiant/points.h @@ -33,5 +33,4 @@ void Pointfile_Delete(); void Pointfile_Construct(); void Pointfile_Destroy(); -class ISAXHandler; -extern ISAXHandler& g_pointfile; +extern class ISAXHandler& g_pointfile; diff --git a/radiant/preferences.cpp b/radiant/preferences.cpp index 577ca9d9..e346a1db 100644 --- a/radiant/preferences.cpp +++ b/radiant/preferences.cpp @@ -30,8 +30,6 @@ #include "debugging/debugging.h" -#include - #include "generic/callback.h" #include "math/vector.h" #include "string/string.h" @@ -50,6 +48,16 @@ #include "qe3.h" #include "gtkdlgs.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include void Global_constructPreferences( PreferencesPage& page ){ @@ -124,7 +132,6 @@ void CGameDescription::Dump(){ CGameDescription *g_pGameDescription; -#include "warnings.h" #include "stream/textfilestream.h" #include "container/array.h" #include "xml/ixml.h" @@ -202,7 +209,7 @@ void GlobalPreferences_Init(){ void CGameDialog::LoadPrefs(){ // load global .pref file StringOutputStream strGlobalPref( 256 ); - strGlobalPref << g_Preferences.m_global_rc_path->str << "global.pref"; + strGlobalPref << g_Preferences.m_global_rc_path << "global.pref"; globalOutputStream() << "loading global preferences from " << makeQuoted( strGlobalPref.c_str() ) << "\n"; @@ -213,7 +220,7 @@ void CGameDialog::LoadPrefs(){ void CGameDialog::SavePrefs(){ StringOutputStream strGlobalPref( 256 ); - strGlobalPref << g_Preferences.m_global_rc_path->str << "global.pref"; + strGlobalPref << g_Preferences.m_global_rc_path << "global.pref"; globalOutputStream() << "saving global preferences to " << strGlobalPref.c_str() << "\n"; @@ -283,19 +290,30 @@ void CGameDialog::CreateGlobalFrame( PreferencesPage& page, bool global ){ page.appendCheckBox( "Startup", "Show Global Preferences", m_bGamePrompt ); } -GtkWindow* CGameDialog::BuildDialog(){ - GtkFrame* frame = create_dialog_frame( "Game settings", GTK_SHADOW_ETCHED_IN ); - - GtkVBox* vbox2 = create_dialog_vbox( 0, 4 ); - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( vbox2 ) ); +void CGameDialog::BuildDialog(){ + GetWidget()->setWindowTitle( "Global Preferences" ); + auto vbox = new QVBoxLayout( GetWidget() ); + vbox->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); { - PreferencesPage preferencesPage( *this, GTK_WIDGET( vbox2 ) ); - Global_constructPreferences( preferencesPage ); - CreateGlobalFrame( preferencesPage, true ); - } + auto frame = new QGroupBox( "Game settings" ); + vbox->addWidget( frame ); - return create_simple_modal_dialog_window( "Global Preferences", m_modal, GTK_WIDGET( frame ) ); + auto grid = new QGridLayout( frame ); + grid->setAlignment( Qt::AlignmentFlag::AlignTop ); + grid->setColumnStretch( 0, 111 ); + grid->setColumnStretch( 1, 333 ); + { + PreferencesPage preferencesPage( *this, grid ); + Global_constructPreferences( preferencesPage ); + CreateGlobalFrame( preferencesPage, true ); + } + } + { + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok ); + vbox->addWidget( buttons ); + QObject::connect( buttons, &QDialogButtonBox::accepted, GetWidget(), &QDialog::accept ); + } } class LoadGameFile @@ -343,15 +361,15 @@ void CGameDialog::ScanForGames(){ } void CGameDialog::InitGlobalPrefPath(){ - g_Preferences.m_global_rc_path = g_string_new( SettingsPath_get() ); + g_Preferences.m_global_rc_path = SettingsPath_get(); } void CGameDialog::Reset(){ - if ( !g_Preferences.m_global_rc_path ) { + if ( g_Preferences.m_global_rc_path.empty() ) { InitGlobalPrefPath(); } - file_remove( StringOutputStream( 256 )( g_Preferences.m_global_rc_path->str, "global.pref" ) ); + file_remove( StringOutputStream( 256 )( g_Preferences.m_global_rc_path, "global.pref" ) ); } void CGameDialog::Init(){ @@ -382,7 +400,7 @@ void CGameDialog::Init(){ } } if ( !currentGameDescription ) { - Create(); + Create( nullptr ); DoGameDialog(); // use m_nComboSelect to identify the game to run as and set the globals currentGameDescription = GameDescriptionForComboItem(); @@ -417,10 +435,9 @@ inline const char* GameDescription_getIdentifier( const CGameDescription& gameDe void CGameDialog::AddPacksURL( StringOutputStream &URL ){ // add the URLs for the list of game packs installed // FIXME: this is kinda hardcoded for now.. - std::list::iterator iGame; - for ( iGame = mGames.begin(); iGame != mGames.end(); ++iGame ) + for ( const CGameDescription *iGame : mGames ) { - URL << "&Games_dlup%5B%5D=" << GameDescription_getIdentifier( *( *iGame ) ); + URL << "&Games_dlup%5B%5D=" << GameDescription_getIdentifier( *iGame ); } } @@ -430,18 +447,17 @@ CGameDialog g_GamesDialog; // ============================================================================= // Widget callbacks for PrefsDlg -static void OnButtonClean( GtkWidget *widget, gpointer data ){ +static void OnButtonClean( PrefsDlg *dlg ){ // make sure this is what the user wants - if ( gtk_MessageBox( GTK_WIDGET( g_Preferences.GetWidget() ), + if ( qt_MessageBox( g_Preferences.GetWidget(), "This will close Radiant and clean the corresponding registry entries.\n" "Next time you start Radiant it will be good as new. Do you wish to continue?", - "Reset Registry", eMB_YESNO, eMB_ICONASTERISK ) == eIDYES ) { - PrefsDlg *dlg = (PrefsDlg*)data; - dlg->EndModal( eIDCANCEL ); + "Reset Registry", EMessageBoxType::Warning, eIDYES | eIDNO ) == eIDYES ) { + dlg->EndModal( QDialog::DialogCode::Rejected ); g_preferences_globals.disable_ini = true; Preferences_Reset(); - gtk_main_quit(); + QCoreApplication::quit(); } } @@ -469,41 +485,14 @@ void PrefsDlg::Init(){ // takes the form: global-pref-path/gamename/prefs-file // this is common to win32 and Linux init now - m_rc_path = g_string_new( m_global_rc_path->str ); - // game sub-dir - g_string_append( m_rc_path, g_pGameDescription->mGameFile.c_str() ); - g_string_append( m_rc_path, "/" ); - Q_mkdir( m_rc_path->str ); + m_rc_path = StringOutputStream( 256 )( m_global_rc_path, g_pGameDescription->mGameFile.c_str(), '/' ); + Q_mkdir( m_rc_path.c_str() ); // then the ini file - m_inipath = g_string_new( m_rc_path->str ); - g_string_append( m_inipath, PREFS_LOCAL_FILENAME ); + m_inipath = StringOutputStream( 256 )( m_rc_path, PREFS_LOCAL_FILENAME ); } -void notebook_set_page( GtkWidget* notebook, GtkWidget* page ){ - int pagenum = gtk_notebook_page_num( GTK_NOTEBOOK( notebook ), page ); - if ( gtk_notebook_get_current_page( GTK_NOTEBOOK( notebook ) ) != pagenum ) { - gtk_notebook_set_current_page( GTK_NOTEBOOK( notebook ), pagenum ); - } -} - -void PrefsDlg::showPrefPage( GtkWidget* prefpage ){ - notebook_set_page( m_notebook, prefpage ); - return; -} - -static void treeSelection( GtkTreeSelection* selection, gpointer data ){ - PrefsDlg *dlg = (PrefsDlg*)data; - - GtkTreeModel* model; - GtkTreeIter selected; - if ( gtk_tree_selection_get_selected( selection, &model, &selected ) ) { - GtkWidget* prefpage; - gtk_tree_model_get( model, &selected, 1, (gpointer*)&prefpage, -1 ); - dlg->showPrefPage( prefpage ); - } -} typedef std::list PreferenceGroupCallbacks; @@ -568,242 +557,173 @@ void PreferencesDialog_addSettingsPage( const PreferenceGroupCallback& callback PreferenceGroupCallbacks_pushBack( g_settingsCallbacks, callback ); } -void Widget_updateDependency( GtkWidget* self, GtkWidget* toggleButton ){ - gtk_widget_set_sensitive( self, gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( toggleButton ) ) && gtk_widget_is_sensitive( toggleButton ) ); +//! note: doesn't handle dependency on setting \p toggleButton insensitive +void Widget_connectToggleDependency( QWidget* self, QCheckBox* toggleButton ){ + QObject::connect( toggleButton, &QCheckBox::stateChanged, [self, toggleButton]( int state ){ + self->setEnabled( state && toggleButton->isEnabled() ); + } ); } - -void ToggleButton_toggled_Widget_updateDependency( GtkWidget *toggleButton, GtkWidget* self ){ - Widget_updateDependency( self, toggleButton ); -} - -void ToggleButton_state_changed_Widget_updateDependency( GtkWidget* toggleButton, GtkStateType state, GtkWidget* self ){ - if ( state == GTK_STATE_INSENSITIVE ) { - Widget_updateDependency( self, toggleButton ); - } -} - -void Widget_connectToggleDependency( GtkWidget* self, GtkWidget* toggleButton ){ - g_signal_connect( G_OBJECT( toggleButton ), "state_changed", G_CALLBACK( ToggleButton_state_changed_Widget_updateDependency ), self ); - g_signal_connect( G_OBJECT( toggleButton ), "toggled", G_CALLBACK( ToggleButton_toggled_Widget_updateDependency ), self ); - Widget_updateDependency( self, toggleButton ); +void Widget_connectToggleDependency( QCheckBox* self, QCheckBox* toggleButton ){ + Widget_connectToggleDependency( static_cast( self ), toggleButton ); } -inline GtkWidget* getVBox( GtkWidget* page ){ - return gtk_bin_get_child( GTK_BIN( page ) ); +QStandardItem* PreferenceTree_appendPage( QStandardItemModel* model, QStandardItem* parent, const char* name, int pageIndex ){ + auto item = new QStandardItem( name ); + item->setData( pageIndex, Qt::ItemDataRole::UserRole ); + parent->appendRow( item ); + return item; } -GtkTreeIter PreferenceTree_appendPage( GtkTreeStore* store, GtkTreeIter* parent, const char* name, GtkWidget* page ){ - GtkTreeIter group; - gtk_tree_store_append( store, &group, parent ); - gtk_tree_store_set( store, &group, 0, name, 1, page, -1 ); - return group; -} - -GtkWidget* PreferencePages_addPage( GtkWidget* notebook, const char* name ){ - GtkWidget* preflabel = gtk_label_new( name ); - gtk_widget_show( preflabel ); - - GtkWidget* pageframe = gtk_frame_new( name ); - gtk_container_set_border_width( GTK_CONTAINER( pageframe ), 4 ); - gtk_widget_show( pageframe ); - - GtkWidget* vbox = gtk_vbox_new( FALSE, 4 ); - gtk_widget_show( vbox ); - gtk_container_set_border_width( GTK_CONTAINER( vbox ), 4 ); - gtk_container_add( GTK_CONTAINER( pageframe ), vbox ); - - // Add the page to the notebook - gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel ); - - return pageframe; +auto PreferencePages_addPage( QStackedWidget* notebook, const char* name ){ + auto frame = new QGroupBox( name ); + auto grid = new QGridLayout( frame ); + grid->setAlignment( Qt::AlignmentFlag::AlignTop ); + grid->setColumnStretch( 0, 111 ); + grid->setColumnStretch( 1, 333 ); + return std::pair( notebook->addWidget( frame ), grid ); } class PreferenceTreeGroup : public PreferenceGroup { Dialog& m_dialog; - GtkWidget* m_notebook; - GtkTreeStore* m_store; - GtkTreeIter m_group; + QStackedWidget* m_notebook; + QStandardItemModel* m_model; + QStandardItem *m_group; public: - PreferenceTreeGroup( Dialog& dialog, GtkWidget* notebook, GtkTreeStore* store, GtkTreeIter group ) : + PreferenceTreeGroup( Dialog& dialog, QStackedWidget* notebook, QStandardItemModel* model, QStandardItem *group ) : m_dialog( dialog ), m_notebook( notebook ), - m_store( store ), + m_model( model ), m_group( group ){ } - PreferencesPage createPage( const char* treeName, const char* frameName ){ - GtkWidget* page = PreferencePages_addPage( m_notebook, frameName ); - PreferenceTree_appendPage( m_store, &m_group, treeName, page ); - return PreferencesPage( m_dialog, getVBox( page ) ); + PreferencesPage createPage( const char* treeName, const char* frameName ) override { + const auto [ pageIndex, layout ] = PreferencePages_addPage( m_notebook, frameName ); + PreferenceTree_appendPage( m_model, m_group, treeName, pageIndex ); + return PreferencesPage( m_dialog, layout ); } }; -#include - -GtkWindow* PrefsDlg::BuildDialog(){ +void PrefsDlg::BuildDialog(){ PreferencesDialog_addInterfacePreferences( FreeCaller1() ); - GtkWindow* dialog = create_floating_window( "NetRadiant Preferences", m_parent ); - - GtkAccelGroup* accel = gtk_accel_group_new(); - gtk_window_add_accel_group( dialog, accel ); + GetWidget()->setWindowTitle( "NetRadiant Preferences" ); { - GtkWidget* mainvbox = gtk_vbox_new( FALSE, 5 ); - gtk_container_add( GTK_CONTAINER( dialog ), mainvbox ); - gtk_container_set_border_width( GTK_CONTAINER( mainvbox ), 5 ); - gtk_widget_show( mainvbox ); - + auto grid = new QGridLayout( GetWidget() ); + grid->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); { - GtkWidget* hbox = gtk_hbox_new( FALSE, 5 ); - gtk_widget_show( hbox ); - gtk_box_pack_end( GTK_BOX( mainvbox ), hbox, FALSE, TRUE, 0 ); - - { - GtkButton* button = create_dialog_button( "OK", G_CALLBACK( dialog_button_ok ), &m_modal ); - gtk_box_pack_end( GTK_BOX( hbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - } - { - GtkButton* button = create_dialog_button( "Cancel", G_CALLBACK( dialog_button_cancel ), &m_modal ); - gtk_box_pack_end( GTK_BOX( hbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 ); - } - { - GtkButton* button = create_dialog_button( "Clean", G_CALLBACK( OnButtonClean ), this ); - gtk_box_pack_end( GTK_BOX( hbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - } + auto buttons = new QDialogButtonBox( QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel ); + grid->addWidget( buttons, 1, 1 ); + QObject::connect( buttons, &QDialogButtonBox::accepted, GetWidget(), &QDialog::accept ); + QObject::connect( buttons, &QDialogButtonBox::rejected, GetWidget(), &QDialog::reject ); + QObject::connect( buttons->addButton( "Clean", QDialogButtonBox::ButtonRole::ResetRole ), &QPushButton::clicked, [this](){ OnButtonClean( this ); } ); } { - GtkWidget* hbox = gtk_hbox_new( FALSE, 5 ); - gtk_box_pack_start( GTK_BOX( mainvbox ), hbox, TRUE, TRUE, 0 ); - gtk_widget_show( hbox ); - { - GtkWidget* sc_win = gtk_scrolled_window_new( 0, 0 ); - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( sc_win ), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC ); - gtk_box_pack_start( GTK_BOX( hbox ), sc_win, FALSE, FALSE, 0 ); - gtk_widget_show( sc_win ); - gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( sc_win ), GTK_SHADOW_IN ); - // prefs pages notebook - m_notebook = gtk_notebook_new(); - // hide the notebook tabs since its not supposed to look like a notebook - gtk_notebook_set_show_tabs( GTK_NOTEBOOK( m_notebook ), FALSE ); - gtk_box_pack_start( GTK_BOX( hbox ), m_notebook, TRUE, TRUE, 0 ); - gtk_widget_show( m_notebook ); - - + m_notebook = new QStackedWidget; + grid->addWidget( m_notebook, 0, 1 ); { - GtkTreeStore* store = gtk_tree_store_new( 2, G_TYPE_STRING, G_TYPE_POINTER ); + m_treeview = new QTreeView; + m_treeview->setHeaderHidden( true ); + m_treeview->setEditTriggers( QAbstractItemView::EditTrigger::NoEditTriggers ); + m_treeview->setUniformRowHeights( true ); // optimization + m_treeview->setHorizontalScrollBarPolicy( Qt::ScrollBarPolicy::ScrollBarAlwaysOff ); + m_treeview->setSizeAdjustPolicy( QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents ); // scroll area will inherit column size + m_treeview->setSizePolicy( QSizePolicy::Policy::Fixed, m_treeview->sizePolicy().verticalPolicy() ); + m_treeview->header()->setStretchLastSection( false ); // non greedy column sizing; + QHeaderView::ResizeMode::ResizeToContents = no text elision 🤷‍♀️ + m_treeview->header()->setSectionResizeMode( QHeaderView::ResizeMode::ResizeToContents ); + grid->addWidget( m_treeview, 0, 0, 2, 1 ); - GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) ); - m_treeview = view; - gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), FALSE ); + // store display name in column #0 and page index in data( Qt::ItemDataRole::UserRole ) + auto model = new QStandardItemModel( m_treeview ); + m_treeview->setModel( model ); - { - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "Preferences", renderer, "text", 0, NULL ); - gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column ); - } - - { - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) ); - g_signal_connect( G_OBJECT( selection ), "changed", G_CALLBACK( treeSelection ), this ); - } - - gtk_widget_show( view ); - - gtk_container_add( GTK_CONTAINER( sc_win ), view ); + QObject::connect( m_treeview->selectionModel(), &QItemSelectionModel::currentChanged, [this]( const QModelIndex& current ){ + m_notebook->setCurrentIndex( current.data( Qt::ItemDataRole::UserRole ).toInt() ); + } ); { /********************************************************************/ /* Add preference tree options */ /********************************************************************/ - // Front page... - //GtkWidget* front = - PreferencePages_addPage( m_notebook, "Front Page" ); - { - GtkWidget* global = PreferencePages_addPage( m_notebook, "Global Preferences" ); + const auto [ pageIndex, layout ] = PreferencePages_addPage( m_notebook, "Global Preferences" ); { - PreferencesPage preferencesPage( *this, getVBox( global ) ); + PreferencesPage preferencesPage( *this, layout ); Global_constructPreferences( preferencesPage ); } - GtkTreeIter group = PreferenceTree_appendPage( store, 0, "Global", global ); + QStandardItem *group = PreferenceTree_appendPage( model, model->invisibleRootItem(), "Global", pageIndex ); { - GtkWidget* game = PreferencePages_addPage( m_notebook, "Game" ); - PreferencesPage preferencesPage( *this, getVBox( game ) ); + const auto [ pageIndex, layout ] = PreferencePages_addPage( m_notebook, "Game" ); + PreferencesPage preferencesPage( *this, layout ); g_GamesDialog.CreateGlobalFrame( preferencesPage, false ); - PreferenceTree_appendPage( store, &group, "Game", game ); + PreferenceTree_appendPage( model, group, "Game", pageIndex ); } } { - GtkWidget* gamePage = PreferencePages_addPage( m_notebook, "Game Settings" ); + const auto [ pageIndex, layout ] = PreferencePages_addPage( m_notebook, "Game Settings" ); { - PreferencesPage preferencesPage( *this, getVBox( gamePage ) ); + PreferencesPage preferencesPage( *this, layout ); + Game_constructPreferences( preferencesPage ); PreferencesPageCallbacks_constructPage( g_gamePreferences, preferencesPage ); } - GtkTreeIter group = PreferenceTree_appendPage( store, 0, "Game", gamePage ); - PreferenceTreeGroup preferenceGroup( *this, m_notebook, store, group ); + QStandardItem *group = PreferenceTree_appendPage( model, model->invisibleRootItem(), "Game", pageIndex ); + PreferenceTreeGroup preferenceGroup( *this, m_notebook, model, group ); PreferenceGroupCallbacks_constructGroup( g_gameCallbacks, preferenceGroup ); } { - GtkWidget* interfacePage = PreferencePages_addPage( m_notebook, "Interface Preferences" ); + const auto [ pageIndex, layout ] = PreferencePages_addPage( m_notebook, "Interface Preferences" ); { - PreferencesPage preferencesPage( *this, getVBox( interfacePage ) ); + PreferencesPage preferencesPage( *this, layout ); PreferencesPageCallbacks_constructPage( g_interfacePreferences, preferencesPage ); } - GtkTreeIter group = PreferenceTree_appendPage( store, 0, "Interface", interfacePage ); - PreferenceTreeGroup preferenceGroup( *this, m_notebook, store, group ); + QStandardItem *group = PreferenceTree_appendPage( model, model->invisibleRootItem(), "Interface", pageIndex ); + PreferenceTreeGroup preferenceGroup( *this, m_notebook, model, group ); PreferenceGroupCallbacks_constructGroup( g_interfaceCallbacks, preferenceGroup ); } { - GtkWidget* display = PreferencePages_addPage( m_notebook, "Display Preferences" ); + const auto [ pageIndex, layout ] = PreferencePages_addPage( m_notebook, "Display Preferences" ); { - PreferencesPage preferencesPage( *this, getVBox( display ) ); + PreferencesPage preferencesPage( *this, layout ); PreferencesPageCallbacks_constructPage( g_displayPreferences, preferencesPage ); } - GtkTreeIter group = PreferenceTree_appendPage( store, 0, "Display", display ); - PreferenceTreeGroup preferenceGroup( *this, m_notebook, store, group ); + QStandardItem *group = PreferenceTree_appendPage( model, model->invisibleRootItem(), "Display", pageIndex ); + PreferenceTreeGroup preferenceGroup( *this, m_notebook, model, group ); PreferenceGroupCallbacks_constructGroup( g_displayCallbacks, preferenceGroup ); } { - GtkWidget* settings = PreferencePages_addPage( m_notebook, "General Settings" ); + const auto [ pageIndex, layout ] = PreferencePages_addPage( m_notebook, "General Settings" ); { - PreferencesPage preferencesPage( *this, getVBox( settings ) ); + PreferencesPage preferencesPage( *this, layout ); PreferencesPageCallbacks_constructPage( g_settingsPreferences, preferencesPage ); } - GtkTreeIter group = PreferenceTree_appendPage( store, 0, "Settings", settings ); - PreferenceTreeGroup preferenceGroup( *this, m_notebook, store, group ); + QStandardItem *group = PreferenceTree_appendPage( model, model->invisibleRootItem(), "Settings", pageIndex ); + PreferenceTreeGroup preferenceGroup( *this, m_notebook, model, group ); PreferenceGroupCallbacks_constructGroup( g_settingsCallbacks, preferenceGroup ); } } - - gtk_tree_view_expand_all( GTK_TREE_VIEW( view ) ); - - g_object_unref( G_OBJECT( store ) ); + // convenience calls + m_treeview->expandAll(); + m_treeview->setCurrentIndex( m_treeview->model()->index( 0, 0 ) ); } } } } - - gtk_notebook_set_current_page( GTK_NOTEBOOK( m_notebook ), 0 ); - - return dialog; } preferences_globals_t g_preferences_globals; @@ -811,9 +731,8 @@ preferences_globals_t g_preferences_globals; PrefsDlg g_Preferences; // global prefs instance -void PreferencesDialog_constructWindow( GtkWindow* main_window ){ - g_Preferences.m_parent = main_window; - g_Preferences.Create(); +void PreferencesDialog_constructWindow( QWidget* main_window ){ + g_Preferences.Create( main_window ); } void PreferencesDialog_destroyWindow(){ g_Preferences.Destroy(); @@ -851,10 +770,10 @@ StaticRegisterModule staticRegisterPreferenceSystem( StaticPreferenceSystemModul void Preferences_Load(){ g_GamesDialog.LoadPrefs(); - globalOutputStream() << "loading local preferences from " << g_Preferences.m_inipath->str << "\n"; + globalOutputStream() << "loading local preferences from " << g_Preferences.m_inipath << "\n"; - if ( !Preferences_Load( g_preferences, g_Preferences.m_inipath->str, g_GamesDialog.m_sGameFile.m_value.c_str() ) ) { - globalWarningStream() << "failed to load local preferences from " << g_Preferences.m_inipath->str << "\n"; + if ( !Preferences_Load( g_preferences, g_Preferences.m_inipath.c_str(), g_GamesDialog.m_sGameFile.m_value.c_str() ) ) { + globalWarningStream() << "failed to load local preferences from " << g_Preferences.m_inipath << "\n"; } } @@ -865,20 +784,20 @@ void Preferences_Save(){ g_GamesDialog.SavePrefs(); - globalOutputStream() << "saving local preferences to " << g_Preferences.m_inipath->str << "\n"; + globalOutputStream() << "saving local preferences to " << g_Preferences.m_inipath << "\n"; - if ( !Preferences_Save_Safe( g_preferences, g_Preferences.m_inipath->str ) ) { - globalWarningStream() << "failed to save local preferences to " << g_Preferences.m_inipath->str << "\n"; + if ( !Preferences_Save_Safe( g_preferences, g_Preferences.m_inipath.c_str() ) ) { + globalWarningStream() << "failed to save local preferences to " << g_Preferences.m_inipath << "\n"; } } void Preferences_Reset(){ - file_remove( g_Preferences.m_inipath->str ); + file_remove( g_Preferences.m_inipath.c_str() ); } -void PrefsDlg::PostModal( EMessageBoxReturn code ){ - if ( code == eIDOK ) { +void PrefsDlg::PostModal( QDialog::DialogCode code ){ + if ( code == QDialog::DialogCode::Accepted ) { Preferences_Save(); UpdateAllWindows(); } @@ -892,9 +811,8 @@ void PreferencesDialog_restartRequired( const char* staticName ){ void PreferencesDialog_showDialog(){ //if ( ConfirmModified( "Edit Preferences" ) && g_Preferences.DoModal() == eIDOK ) { - if( gtk_widget_get_realized( g_Preferences.m_treeview ) ) - gtk_widget_grab_focus( g_Preferences.m_treeview ); - if ( g_Preferences.DoModal() == eIDOK ) { + g_Preferences.m_treeview->setFocus(); // focus tree to have it immediately available for text search + if ( g_Preferences.DoModal() == QDialog::DialogCode::Accepted ) { if ( !g_restart_required.empty() ) { StringOutputStream message( 256 ); message << "Preference changes require a restart:\n\n"; @@ -903,7 +821,7 @@ void PreferencesDialog_showDialog(){ g_restart_required.clear(); message << "\nRestart now?"; - if( gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), message.c_str(), "Restart is required", eMB_YESNO, eMB_ICONQUESTION ) == eIDYES ) + if( qt_MessageBox( MainFrame_getWindow(), message.c_str(), "Restart is required", EMessageBoxType::Question ) == eIDYES ) Radiant_Restart(); } } diff --git a/radiant/preferences.h b/radiant/preferences.h index 6ea9b828..ae25df01 100644 --- a/radiant/preferences.h +++ b/radiant/preferences.h @@ -29,87 +29,75 @@ #pragma once #include "libxml/parser.h" +#include "stream/textstream.h" +#include "debugging/debugging.h" #include "dialog.h" #include #include -void Widget_connectToggleDependency( GtkWidget* self, GtkWidget* toggleButton ); +void Widget_connectToggleDependency( QWidget* self, QCheckBox* toggleButton ); +void Widget_connectToggleDependency( QCheckBox* self, QCheckBox* toggleButton ); class PreferencesPage { Dialog& m_dialog; - GtkWidget* m_vbox; + class QGridLayout* m_grid; public: - PreferencesPage( Dialog& dialog, GtkWidget* vbox ) : m_dialog( dialog ), m_vbox( vbox ){ + PreferencesPage( Dialog& dialog, QGridLayout* grid ) : m_dialog( dialog ), m_grid( grid ){ } - GtkWidget* appendCheckBox( const char* name, const char* flag, bool& data ){ - return m_dialog.addCheckBox( m_vbox, name, flag, data ); + QCheckBox* appendCheckBox( const char* name, const char* flag, bool& data ){ + return m_dialog.addCheckBox( m_grid, name, flag, data ); } - GtkWidget* appendCheckBox( const char* name, const char* flag, const BoolImportCallback& importCallback, const BoolExportCallback& exportCallback ){ - return m_dialog.addCheckBox( m_vbox, name, flag, importCallback, exportCallback ); + QCheckBox* appendCheckBox( const char* name, const char* flag, const BoolImportCallback& importCallback, const BoolExportCallback& exportCallback ){ + return m_dialog.addCheckBox( m_grid, name, flag, importCallback, exportCallback ); } - void appendCombo( const char* name, StringArrayRange values, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){ - m_dialog.addCombo( m_vbox, name, values, importCallback, exportCallback ); + QComboBox* appendCombo( const char* name, StringArrayRange values, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){ + return m_dialog.addCombo( m_grid, name, values, importCallback, exportCallback ); } - void appendCombo( const char* name, int& data, StringArrayRange values ){ - m_dialog.addCombo( m_vbox, name, data, values ); + QComboBox* appendCombo( const char* name, int& data, StringArrayRange values ){ + return m_dialog.addCombo( m_grid, name, data, values ); } - void appendSlider( const char* name, int& data, gboolean draw_value, const char* low, const char* high, double value, double lower, double upper, double step_increment, double page_increment ){ - m_dialog.addSlider( m_vbox, name, data, draw_value, low, high, value, lower, upper, step_increment, page_increment ); + void appendSlider( const char* name, int& data, int lower, int upper, int step_increment, int page_increment ){ + m_dialog.addSlider( m_grid, name, data, lower, upper, step_increment, page_increment ); } - void appendSlider( const char* name, float& data, gboolean draw_value, const char* low, const char* high, double value, double lower, double upper, double step_increment, double page_increment ){ - m_dialog.addSlider( m_vbox, name, data, draw_value, low, high, value, lower, upper, step_increment, page_increment ); + void appendSlider( const char* name, float& data, double lower, double upper, double step_increment, double page_increment ){ + m_dialog.addSlider( m_grid, name, data, lower, upper, step_increment, page_increment ); } void appendRadio( const char* name, StringArrayRange names, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){ - m_dialog.addRadio( m_vbox, name, names, importCallback, exportCallback ); + m_dialog.addRadio( m_grid, name, names, importCallback, exportCallback ); } void appendRadio( const char* name, int& data, StringArrayRange names ){ - m_dialog.addRadio( m_vbox, name, data, names ); + m_dialog.addRadio( m_grid, name, data, names ); } void appendRadioIcons( const char* name, StringArrayRange icons, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){ - m_dialog.addRadioIcons( m_vbox, name, icons, importCallback, exportCallback ); + m_dialog.addRadioIcons( m_grid, name, icons, importCallback, exportCallback ); } void appendRadioIcons( const char* name, int& data, StringArrayRange icons ){ - m_dialog.addRadioIcons( m_vbox, name, data, icons ); + m_dialog.addRadioIcons( m_grid, name, data, icons ); } - GtkWidget* appendEntry( const char* name, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){ - return m_dialog.addIntEntry( m_vbox, name, importCallback, exportCallback ); + void appendEntry( const char* name, const StringImportCallback& importCallback, const StringExportCallback& exportCallback ){ + m_dialog.addTextEntry( m_grid, name, importCallback, exportCallback ); } - GtkWidget* appendEntry( const char* name, int& data ){ - return m_dialog.addEntry( m_vbox, name, data ); + void appendEntry( const char* name, CopiedString& data ){ + m_dialog.addEntry( m_grid, name, data ); } - GtkWidget* appendEntry( const char* name, const SizeImportCallback& importCallback, const SizeExportCallback& exportCallback ){ - return m_dialog.addSizeEntry( m_vbox, name, importCallback, exportCallback ); + void appendPathEntry( const char* name, bool browse_directory, const StringImportCallback& importCallback, const StringExportCallback& exportCallback ){ + m_dialog.addPathEntry( m_grid, name, browse_directory, importCallback, exportCallback ); } - GtkWidget* appendEntry( const char* name, std::size_t& data ){ - return m_dialog.addEntry( m_vbox, name, data ); + void appendPathEntry( const char* name, CopiedString& data, bool directory ){ + m_dialog.addPathEntry( m_grid, name, data, directory ); } - GtkWidget* appendEntry( const char* name, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ){ - return m_dialog.addFloatEntry( m_vbox, name, importCallback, exportCallback ); + QWidget* appendSpinner( const char* name, int& data, int lower, int upper ){ + return m_dialog.addSpinner( m_grid, name, data, lower, upper ); } - GtkWidget* appendEntry( const char* name, float& data ){ - return m_dialog.addEntry( m_vbox, name, data ); + QWidget* appendSpinner( const char* name, int lower, int upper, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){ + return m_dialog.addSpinner( m_grid, name, lower, upper, importCallback, exportCallback ); } - GtkWidget* appendEntry( const char* name, const StringImportCallback& importCallback, const StringExportCallback& exportCallback ){ - return m_dialog.addTextEntry( m_vbox, name, importCallback, exportCallback ); + QWidget* appendSpinner( const char* name, double lower, double upper, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ){ + return m_dialog.addSpinner( m_grid, name, lower, upper, importCallback, exportCallback ); } - GtkWidget* appendEntry( const char* name, CopiedString& data ){ - return m_dialog.addEntry( m_vbox, name, data ); - } - GtkWidget* appendPathEntry( const char* name, bool browse_directory, const StringImportCallback& importCallback, const StringExportCallback& exportCallback ){ - return m_dialog.addPathEntry( m_vbox, name, browse_directory, importCallback, exportCallback ); - } - GtkWidget* appendPathEntry( const char* name, CopiedString& data, bool directory ){ - return m_dialog.addPathEntry( m_vbox, name, data, directory ); - } - GtkWidget* appendSpinner( const char* name, int& data, double value, double lower, double upper ){ - return m_dialog.addSpinner( m_vbox, name, data, value, lower, upper ); - } - GtkWidget* appendSpinner( const char* name, double value, double lower, double upper, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){ - return m_dialog.addSpinner( m_vbox, name, value, lower, upper, importCallback, exportCallback ); - } - GtkWidget* appendSpinner( const char* name, double value, double lower, double upper, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ){ - return m_dialog.addSpinner( m_vbox, name, value, lower, upper, importCallback, exportCallback ); + QWidget* appendSpinner( const char* name, float& data, double lower, double upper ){ + return m_dialog.addSpinner( m_grid, name, data, lower, upper ); } }; @@ -214,8 +202,6 @@ public: extern CGameDescription *g_pGameDescription; -typedef struct _GtkWidget GtkWidget; - class StringOutputStream; /*! @@ -286,7 +272,7 @@ public: Dialog API this is only called when the dialog is built at startup for main engine select */ - GtkWindow* BuildDialog(); + void BuildDialog() override; void GameFileAssign( int value ); void GameFileImport( int value ); @@ -341,12 +327,10 @@ class PrefsDlg : public Dialog { public: - GtkWidget *m_notebook; - GtkWidget *m_treeview; + class QStackedWidget *m_notebook; + class QTreeView *m_treeview; virtual ~PrefsDlg(){ - g_string_free( m_rc_path, true ); - g_string_free( m_inipath, true ); } /*! @@ -354,7 +338,7 @@ public: win32: AppPath linux: ~/.radiant/[version]/ */ - GString *m_global_rc_path; + CopiedString m_global_rc_path; /*! path to per-game settings @@ -362,26 +346,23 @@ public: win32: GameToolsPath linux: ~/.radiant/[version]/[gamename]/ */ - GString *m_rc_path; + CopiedString m_rc_path; /*! holds per-game settings m_rc_path+"local.pref" \todo FIXME at some point this should become XML property bag code too */ - GString *m_inipath; + CopiedString m_inipath; // initialize the above paths void Init(); - /*! Utility function for swapping notebook pages for tree list selections */ - void showPrefPage( GtkWidget* prefpage ); - protected: /*! Dialog API */ - GtkWindow* BuildDialog(); - void PostModal( EMessageBoxReturn code ); + void BuildDialog() override; + void PostModal( QDialog::DialogCode code ) override; }; extern PrefsDlg g_Preferences; @@ -389,14 +370,11 @@ extern PrefsDlg g_Preferences; struct preferences_globals_t { // disabled all INI / registry read write .. used when shutting down after registry cleanup - bool disable_ini; - preferences_globals_t() : disable_ini( false ){ - } + bool disable_ini = false; }; extern preferences_globals_t g_preferences_globals; -typedef struct _GtkWindow GtkWindow; -void PreferencesDialog_constructWindow( GtkWindow* main_window ); +void PreferencesDialog_constructWindow( QWidget* main_window ); void PreferencesDialog_destroyWindow(); void PreferencesDialog_showDialog(); diff --git a/radiant/qe3.cpp b/radiant/qe3.cpp index e3256eea..8df67a1c 100644 --- a/radiant/qe3.cpp +++ b/radiant/qe3.cpp @@ -41,7 +41,7 @@ #include -#include +#include #include "stream/textfilestream.h" #include "commandlib.h" @@ -92,9 +92,9 @@ void QE_InitVFS(){ StringOutputStream str( 256 ); // if we have a mod dir - if ( !string_equal( gamename, basegame ) ) { + if ( !path_equal( gamename, basegame ) ) { // ~/./ - if ( !string_equal( globalRoot, userRoot ) ) { + if ( !path_equal( globalRoot, userRoot ) ) { GlobalFileSystem().initDirectory( str( userRoot, gamename, '/' ) ); // userGamePath } @@ -105,7 +105,7 @@ void QE_InitVFS(){ } // ~/./ - if ( !string_equal( globalRoot, userRoot ) ) { + if ( !path_equal( globalRoot, userRoot ) ) { GlobalFileSystem().initDirectory( str( userRoot, basegame, '/' ) ); // userBasePath } @@ -144,9 +144,9 @@ bool ConfirmModified( const char* title ){ return true; } - EMessageBoxReturn result = gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), + EMessageBoxReturn result = qt_MessageBox( MainFrame_getWindow(), "The current map has changed since it was last saved.\nDo you want to save the current map before continuing?", - title, eMB_YESNOCANCEL, eMB_ICONQUESTION ); + title, EMessageBoxType::Question, eIDYES | eIDNO | eIDCANCEL ); if ( result == eIDCANCEL ) { return false; } @@ -159,7 +159,7 @@ bool ConfirmModified( const char* title ){ return Map_Save(); } } - return true; + return true; // eIDNO } void bsp_init(){ @@ -322,25 +322,5 @@ void Sys_SetTitle( const char *text, bool modified ){ title << " *"; } - gtk_window_set_title( MainFrame_getWindow(), title.c_str() ); -} - -bool g_bWaitCursor = false; - -void Sys_BeginWait(){ - ScreenUpdates_Disable( "Processing...", "Please Wait" ); - GdkCursor *cursor = gdk_cursor_new( GDK_WATCH ); - gdk_window_set_cursor( gtk_widget_get_window( GTK_WIDGET( MainFrame_getWindow() ) ), cursor ); - gdk_cursor_unref( cursor ); - g_bWaitCursor = true; -} - -void Sys_EndWait(){ - ScreenUpdates_Enable(); - gdk_window_set_cursor( gtk_widget_get_window( GTK_WIDGET( MainFrame_getWindow() ) ), 0 ); - g_bWaitCursor = false; -} - -void Sys_Beep(){ - gdk_beep(); + MainFrame_getWindow()->setWindowTitle( title.c_str() ); } diff --git a/radiant/qgl.cpp b/radiant/qgl.cpp index f207030a..edea9599 100644 --- a/radiant/qgl.cpp +++ b/radiant/qgl.cpp @@ -28,56 +28,14 @@ #include #include -#if defined( _WIN32 ) -#define WINGDIAPI __declspec( dllimport ) -#define APIENTRY __stdcall -#endif - -#include - -#if defined( _WIN32 ) -#undef WINGDIAPI -#undef APIENTRY -#endif #include "igl.h" - -#if defined( _WIN32 ) - -#include - -PROC ( WINAPI * qwglGetProcAddress )( LPCSTR ); - -#elif defined ( XWINDOWS ) - -#include -#include -#include - -Bool ( *qglXQueryExtension )( Display *dpy, int *errorb, int *event ); -void* ( *qglXGetProcAddressARB )( const GLubyte * procName ); -typedef void* ( *glXGetProcAddressARBProc )( const GLubyte *procName ); - -#else -#error "unsupported platform" -#endif - - void QGL_Shutdown( OpenGLBinding& table ){ globalOutputStream() << "Shutting down OpenGL module..."; -#if defined( WIN32 ) - qwglGetProcAddress = 0; -#elif defined( XWINDOWS ) - qglXQueryExtension = glXQueryExtension; - qglXGetProcAddressARB = 0; -#else -#error "unsupported platform" -#endif - globalOutputStream() << "Done.\n"; } @@ -115,435 +73,12 @@ void glInvalidFunction(){ ERROR_MESSAGE( "calling an invalid OpenGL function" ); } -#define EXTENSIONS_ENABLED 1 - -bool QGL_ExtensionSupported( const char* extension ){ -#if EXTENSIONS_ENABLED - const GLubyte *extensions = 0; - const GLubyte *start; - const GLubyte *where, *terminator; - - // Extension names should not have spaces. - where = (const GLubyte *) strchr( extension, ' ' ); - if ( where || *extension == '\0' ) { - return false; - } - - extensions = GlobalOpenGL().m_glGetString( GL_EXTENSIONS ); -#ifndef __APPLE__ - if ( !extensions ) { - return false; - } -#endif - - // It takes a bit of care to be fool-proof about parsing the - // OpenGL extensions string. Don't be fooled by sub-strings, etc. - for ( start = extensions; ; ) - { - where = (const GLubyte *) strstr( (const char *) start, extension ); - if ( !where ) { - break; - } - - terminator = where + strlen( extension ); - if ( where == start || *( where - 1 ) == ' ' ) { - if ( *terminator == ' ' || *terminator == '\0' ) { - return true; - } - } - - start = terminator; - } -#endif - - return false; -} - -typedef int ( QGL_DLLEXPORT * QGLFunctionPointer )(); - -QGLFunctionPointer QGL_getExtensionFunc( const char* symbol ){ -#if defined( XWINDOWS ) - //ASSERT_NOTNULL(qglXGetProcAddressARB); - if ( qglXGetProcAddressARB == 0 ) { - return reinterpret_cast( glInvalidFunction ); - } - else - { - return (QGLFunctionPointer) qglXGetProcAddressARB( reinterpret_cast( symbol ) ); - } -#elif defined( WIN32 ) - ASSERT_NOTNULL( qwglGetProcAddress ); - return (QGLFunctionPointer) qwglGetProcAddress( symbol ); -#else -#error "unsupported platform" -#endif -} - - -template -bool QGL_constructExtensionFunc( Func& func, const char* symbol ){ - func = reinterpret_cast( QGL_getExtensionFunc( symbol ) ); - return func != 0; -} - -template -void QGL_invalidateExtensionFunc( Func& func ){ - func = reinterpret_cast( glInvalidFunction ); -} void QGL_clear( OpenGLBinding& table ){ - QGL_invalidateExtensionFunc( table.m_glAccum ); - QGL_invalidateExtensionFunc( table.m_glAlphaFunc ); - QGL_invalidateExtensionFunc( table.m_glAreTexturesResident ); - QGL_invalidateExtensionFunc( table.m_glArrayElement ); - QGL_invalidateExtensionFunc( table.m_glBegin ); - QGL_invalidateExtensionFunc( table.m_glBindTexture ); - QGL_invalidateExtensionFunc( table.m_glBitmap ); - QGL_invalidateExtensionFunc( table.m_glBlendFunc ); - QGL_invalidateExtensionFunc( table.m_glCallList ); - QGL_invalidateExtensionFunc( table.m_glCallLists ); - QGL_invalidateExtensionFunc( table.m_glClear ); - QGL_invalidateExtensionFunc( table.m_glClearAccum ); - QGL_invalidateExtensionFunc( table.m_glClearColor ); - QGL_invalidateExtensionFunc( table.m_glClearDepth ); - QGL_invalidateExtensionFunc( table.m_glClearIndex ); - QGL_invalidateExtensionFunc( table.m_glClearStencil ); - QGL_invalidateExtensionFunc( table.m_glClipPlane ); - QGL_invalidateExtensionFunc( table.m_glColor3b ); - QGL_invalidateExtensionFunc( table.m_glColor3bv ); - QGL_invalidateExtensionFunc( table.m_glColor3d ); - QGL_invalidateExtensionFunc( table.m_glColor3dv ); - QGL_invalidateExtensionFunc( table.m_glColor3f ); - QGL_invalidateExtensionFunc( table.m_glColor3fv ); - QGL_invalidateExtensionFunc( table.m_glColor3i ); - QGL_invalidateExtensionFunc( table.m_glColor3iv ); - QGL_invalidateExtensionFunc( table.m_glColor3s ); - QGL_invalidateExtensionFunc( table.m_glColor3sv ); - QGL_invalidateExtensionFunc( table.m_glColor3ub ); - QGL_invalidateExtensionFunc( table.m_glColor3ubv ); - QGL_invalidateExtensionFunc( table.m_glColor3ui ); - QGL_invalidateExtensionFunc( table.m_glColor3uiv ); - QGL_invalidateExtensionFunc( table.m_glColor3us ); - QGL_invalidateExtensionFunc( table.m_glColor3usv ); - QGL_invalidateExtensionFunc( table.m_glColor4b ); - QGL_invalidateExtensionFunc( table.m_glColor4bv ); - QGL_invalidateExtensionFunc( table.m_glColor4d ); - QGL_invalidateExtensionFunc( table.m_glColor4dv ); - QGL_invalidateExtensionFunc( table.m_glColor4f ); - QGL_invalidateExtensionFunc( table.m_glColor4fv ); - QGL_invalidateExtensionFunc( table.m_glColor4i ); - QGL_invalidateExtensionFunc( table.m_glColor4iv ); - QGL_invalidateExtensionFunc( table.m_glColor4s ); - QGL_invalidateExtensionFunc( table.m_glColor4sv ); - QGL_invalidateExtensionFunc( table.m_glColor4ub ); - QGL_invalidateExtensionFunc( table.m_glColor4ubv ); - QGL_invalidateExtensionFunc( table.m_glColor4ui ); - QGL_invalidateExtensionFunc( table.m_glColor4uiv ); - QGL_invalidateExtensionFunc( table.m_glColor4us ); - QGL_invalidateExtensionFunc( table.m_glColor4usv ); - QGL_invalidateExtensionFunc( table.m_glColorMask ); - QGL_invalidateExtensionFunc( table.m_glColorMaterial ); - QGL_invalidateExtensionFunc( table.m_glColorPointer ); - QGL_invalidateExtensionFunc( table.m_glCopyPixels ); - QGL_invalidateExtensionFunc( table.m_glCopyTexImage1D ); - QGL_invalidateExtensionFunc( table.m_glCopyTexImage2D ); - QGL_invalidateExtensionFunc( table.m_glCopyTexSubImage1D ); - QGL_invalidateExtensionFunc( table.m_glCopyTexSubImage2D ); - QGL_invalidateExtensionFunc( table.m_glCullFace ); - QGL_invalidateExtensionFunc( table.m_glDeleteLists ); - QGL_invalidateExtensionFunc( table.m_glDeleteTextures ); - QGL_invalidateExtensionFunc( table.m_glDepthFunc ); - QGL_invalidateExtensionFunc( table.m_glDepthMask ); - QGL_invalidateExtensionFunc( table.m_glDepthRange ); - QGL_invalidateExtensionFunc( table.m_glDisable ); - QGL_invalidateExtensionFunc( table.m_glDisableClientState ); - QGL_invalidateExtensionFunc( table.m_glDrawArrays ); - QGL_invalidateExtensionFunc( table.m_glDrawBuffer ); - QGL_invalidateExtensionFunc( table.m_glDrawElements ); - QGL_invalidateExtensionFunc( table.m_glDrawPixels ); - QGL_invalidateExtensionFunc( table.m_glEdgeFlag ); - QGL_invalidateExtensionFunc( table.m_glEdgeFlagPointer ); - QGL_invalidateExtensionFunc( table.m_glEdgeFlagv ); - QGL_invalidateExtensionFunc( table.m_glEnable ); - QGL_invalidateExtensionFunc( table.m_glEnableClientState ); - QGL_invalidateExtensionFunc( table.m_glEnd ); - QGL_invalidateExtensionFunc( table.m_glEndList ); - QGL_invalidateExtensionFunc( table.m_glEvalCoord1d ); - QGL_invalidateExtensionFunc( table.m_glEvalCoord1dv ); - QGL_invalidateExtensionFunc( table.m_glEvalCoord1f ); - QGL_invalidateExtensionFunc( table.m_glEvalCoord1fv ); - QGL_invalidateExtensionFunc( table.m_glEvalCoord2d ); - QGL_invalidateExtensionFunc( table.m_glEvalCoord2dv ); - QGL_invalidateExtensionFunc( table.m_glEvalCoord2f ); - QGL_invalidateExtensionFunc( table.m_glEvalCoord2fv ); - QGL_invalidateExtensionFunc( table.m_glEvalMesh1 ); - QGL_invalidateExtensionFunc( table.m_glEvalMesh2 ); - QGL_invalidateExtensionFunc( table.m_glEvalPoint1 ); - QGL_invalidateExtensionFunc( table.m_glEvalPoint2 ); - QGL_invalidateExtensionFunc( table.m_glFeedbackBuffer ); - QGL_invalidateExtensionFunc( table.m_glFinish ); - QGL_invalidateExtensionFunc( table.m_glFlush ); - QGL_invalidateExtensionFunc( table.m_glFogf ); - QGL_invalidateExtensionFunc( table.m_glFogfv ); - QGL_invalidateExtensionFunc( table.m_glFogi ); - QGL_invalidateExtensionFunc( table.m_glFogiv ); - QGL_invalidateExtensionFunc( table.m_glFrontFace ); - QGL_invalidateExtensionFunc( table.m_glFrustum ); - QGL_invalidateExtensionFunc( table.m_glGenLists ); - QGL_invalidateExtensionFunc( table.m_glGenTextures ); - QGL_invalidateExtensionFunc( table.m_glGetBooleanv ); - QGL_invalidateExtensionFunc( table.m_glGetClipPlane ); - QGL_invalidateExtensionFunc( table.m_glGetDoublev ); - QGL_invalidateExtensionFunc( table.m_glGetError ); - QGL_invalidateExtensionFunc( table.m_glGetFloatv ); - QGL_invalidateExtensionFunc( table.m_glGetIntegerv ); - QGL_invalidateExtensionFunc( table.m_glGetLightfv ); - QGL_invalidateExtensionFunc( table.m_glGetLightiv ); - QGL_invalidateExtensionFunc( table.m_glGetMapdv ); - QGL_invalidateExtensionFunc( table.m_glGetMapfv ); - QGL_invalidateExtensionFunc( table.m_glGetMapiv ); - QGL_invalidateExtensionFunc( table.m_glGetMaterialfv ); - QGL_invalidateExtensionFunc( table.m_glGetMaterialiv ); - QGL_invalidateExtensionFunc( table.m_glGetPixelMapfv ); - QGL_invalidateExtensionFunc( table.m_glGetPixelMapuiv ); - QGL_invalidateExtensionFunc( table.m_glGetPixelMapusv ); - QGL_invalidateExtensionFunc( table.m_glGetPointerv ); - QGL_invalidateExtensionFunc( table.m_glGetPolygonStipple ); - table.m_glGetString = glGetString; - QGL_invalidateExtensionFunc( table.m_glGetTexEnvfv ); - QGL_invalidateExtensionFunc( table.m_glGetTexEnviv ); - QGL_invalidateExtensionFunc( table.m_glGetTexGendv ); - QGL_invalidateExtensionFunc( table.m_glGetTexGenfv ); - QGL_invalidateExtensionFunc( table.m_glGetTexGeniv ); - QGL_invalidateExtensionFunc( table.m_glGetTexImage ); - QGL_invalidateExtensionFunc( table.m_glGetTexLevelParameterfv ); - QGL_invalidateExtensionFunc( table.m_glGetTexLevelParameteriv ); - QGL_invalidateExtensionFunc( table.m_glGetTexParameterfv ); - QGL_invalidateExtensionFunc( table.m_glGetTexParameteriv ); - QGL_invalidateExtensionFunc( table.m_glHint ); - QGL_invalidateExtensionFunc( table.m_glIndexMask ); - QGL_invalidateExtensionFunc( table.m_glIndexPointer ); - QGL_invalidateExtensionFunc( table.m_glIndexd ); - QGL_invalidateExtensionFunc( table.m_glIndexdv ); - QGL_invalidateExtensionFunc( table.m_glIndexf ); - QGL_invalidateExtensionFunc( table.m_glIndexfv ); - QGL_invalidateExtensionFunc( table.m_glIndexi ); - QGL_invalidateExtensionFunc( table.m_glIndexiv ); - QGL_invalidateExtensionFunc( table.m_glIndexs ); - QGL_invalidateExtensionFunc( table.m_glIndexsv ); - QGL_invalidateExtensionFunc( table.m_glIndexub ); - QGL_invalidateExtensionFunc( table.m_glIndexubv ); - QGL_invalidateExtensionFunc( table.m_glInitNames ); - QGL_invalidateExtensionFunc( table.m_glInterleavedArrays ); - QGL_invalidateExtensionFunc( table.m_glIsEnabled ); - QGL_invalidateExtensionFunc( table.m_glIsList ); - QGL_invalidateExtensionFunc( table.m_glIsTexture ); - QGL_invalidateExtensionFunc( table.m_glLightModelf ); - QGL_invalidateExtensionFunc( table.m_glLightModelfv ); - QGL_invalidateExtensionFunc( table.m_glLightModeli ); - QGL_invalidateExtensionFunc( table.m_glLightModeliv ); - QGL_invalidateExtensionFunc( table.m_glLightf ); - QGL_invalidateExtensionFunc( table.m_glLightfv ); - QGL_invalidateExtensionFunc( table.m_glLighti ); - QGL_invalidateExtensionFunc( table.m_glLightiv ); - QGL_invalidateExtensionFunc( table.m_glLineStipple ); - QGL_invalidateExtensionFunc( table.m_glLineWidth ); - QGL_invalidateExtensionFunc( table.m_glListBase ); - QGL_invalidateExtensionFunc( table.m_glLoadIdentity ); - QGL_invalidateExtensionFunc( table.m_glLoadMatrixd ); - QGL_invalidateExtensionFunc( table.m_glLoadMatrixf ); - QGL_invalidateExtensionFunc( table.m_glLoadName ); - QGL_invalidateExtensionFunc( table.m_glLogicOp ); - QGL_invalidateExtensionFunc( table.m_glMap1d ); - QGL_invalidateExtensionFunc( table.m_glMap1f ); - QGL_invalidateExtensionFunc( table.m_glMap2d ); - QGL_invalidateExtensionFunc( table.m_glMap2f ); - QGL_invalidateExtensionFunc( table.m_glMapGrid1d ); - QGL_invalidateExtensionFunc( table.m_glMapGrid1f ); - QGL_invalidateExtensionFunc( table.m_glMapGrid2d ); - QGL_invalidateExtensionFunc( table.m_glMapGrid2f ); - QGL_invalidateExtensionFunc( table.m_glMaterialf ); - QGL_invalidateExtensionFunc( table.m_glMaterialfv ); - QGL_invalidateExtensionFunc( table.m_glMateriali ); - QGL_invalidateExtensionFunc( table.m_glMaterialiv ); - QGL_invalidateExtensionFunc( table.m_glMatrixMode ); - QGL_invalidateExtensionFunc( table.m_glMultMatrixd ); - QGL_invalidateExtensionFunc( table.m_glMultMatrixf ); - QGL_invalidateExtensionFunc( table.m_glNewList ); - QGL_invalidateExtensionFunc( table.m_glNormal3b ); - QGL_invalidateExtensionFunc( table.m_glNormal3bv ); - QGL_invalidateExtensionFunc( table.m_glNormal3d ); - QGL_invalidateExtensionFunc( table.m_glNormal3dv ); - QGL_invalidateExtensionFunc( table.m_glNormal3f ); - QGL_invalidateExtensionFunc( table.m_glNormal3fv ); - QGL_invalidateExtensionFunc( table.m_glNormal3i ); - QGL_invalidateExtensionFunc( table.m_glNormal3iv ); - QGL_invalidateExtensionFunc( table.m_glNormal3s ); - QGL_invalidateExtensionFunc( table.m_glNormal3sv ); - QGL_invalidateExtensionFunc( table.m_glNormalPointer ); - QGL_invalidateExtensionFunc( table.m_glOrtho ); - QGL_invalidateExtensionFunc( table.m_glPassThrough ); - QGL_invalidateExtensionFunc( table.m_glPixelMapfv ); - QGL_invalidateExtensionFunc( table.m_glPixelMapuiv ); - QGL_invalidateExtensionFunc( table.m_glPixelMapusv ); - QGL_invalidateExtensionFunc( table.m_glPixelStoref ); - QGL_invalidateExtensionFunc( table.m_glPixelStorei ); - QGL_invalidateExtensionFunc( table.m_glPixelTransferf ); - QGL_invalidateExtensionFunc( table.m_glPixelTransferi ); - QGL_invalidateExtensionFunc( table.m_glPixelZoom ); - QGL_invalidateExtensionFunc( table.m_glPointSize ); - QGL_invalidateExtensionFunc( table.m_glPolygonMode ); - QGL_invalidateExtensionFunc( table.m_glPolygonOffset ); - QGL_invalidateExtensionFunc( table.m_glPolygonStipple ); - QGL_invalidateExtensionFunc( table.m_glPopAttrib ); - QGL_invalidateExtensionFunc( table.m_glPopClientAttrib ); - QGL_invalidateExtensionFunc( table.m_glPopMatrix ); - QGL_invalidateExtensionFunc( table.m_glPopName ); - QGL_invalidateExtensionFunc( table.m_glPrioritizeTextures ); - QGL_invalidateExtensionFunc( table.m_glPushAttrib ); - QGL_invalidateExtensionFunc( table.m_glPushClientAttrib ); - QGL_invalidateExtensionFunc( table.m_glPushMatrix ); - QGL_invalidateExtensionFunc( table.m_glPushName ); - QGL_invalidateExtensionFunc( table.m_glRasterPos2d ); - QGL_invalidateExtensionFunc( table.m_glRasterPos2dv ); - QGL_invalidateExtensionFunc( table.m_glRasterPos2f ); - QGL_invalidateExtensionFunc( table.m_glRasterPos2fv ); - QGL_invalidateExtensionFunc( table.m_glRasterPos2i ); - QGL_invalidateExtensionFunc( table.m_glRasterPos2iv ); - QGL_invalidateExtensionFunc( table.m_glRasterPos2s ); - QGL_invalidateExtensionFunc( table.m_glRasterPos2sv ); - QGL_invalidateExtensionFunc( table.m_glRasterPos3d ); - QGL_invalidateExtensionFunc( table.m_glRasterPos3dv ); - QGL_invalidateExtensionFunc( table.m_glRasterPos3f ); - QGL_invalidateExtensionFunc( table.m_glRasterPos3fv ); - QGL_invalidateExtensionFunc( table.m_glRasterPos3i ); - QGL_invalidateExtensionFunc( table.m_glRasterPos3iv ); - QGL_invalidateExtensionFunc( table.m_glRasterPos3s ); - QGL_invalidateExtensionFunc( table.m_glRasterPos3sv ); - QGL_invalidateExtensionFunc( table.m_glRasterPos4d ); - QGL_invalidateExtensionFunc( table.m_glRasterPos4dv ); - QGL_invalidateExtensionFunc( table.m_glRasterPos4f ); - QGL_invalidateExtensionFunc( table.m_glRasterPos4fv ); - QGL_invalidateExtensionFunc( table.m_glRasterPos4i ); - QGL_invalidateExtensionFunc( table.m_glRasterPos4iv ); - QGL_invalidateExtensionFunc( table.m_glRasterPos4s ); - QGL_invalidateExtensionFunc( table.m_glRasterPos4sv ); - QGL_invalidateExtensionFunc( table.m_glReadBuffer ); - QGL_invalidateExtensionFunc( table.m_glReadPixels ); - QGL_invalidateExtensionFunc( table.m_glRectd ); - QGL_invalidateExtensionFunc( table.m_glRectdv ); - QGL_invalidateExtensionFunc( table.m_glRectf ); - QGL_invalidateExtensionFunc( table.m_glRectfv ); - QGL_invalidateExtensionFunc( table.m_glRecti ); - QGL_invalidateExtensionFunc( table.m_glRectiv ); - QGL_invalidateExtensionFunc( table.m_glRects ); - QGL_invalidateExtensionFunc( table.m_glRectsv ); - QGL_invalidateExtensionFunc( table.m_glRenderMode ); - QGL_invalidateExtensionFunc( table.m_glRotated ); - QGL_invalidateExtensionFunc( table.m_glRotatef ); - QGL_invalidateExtensionFunc( table.m_glScaled ); - QGL_invalidateExtensionFunc( table.m_glScalef ); - QGL_invalidateExtensionFunc( table.m_glScissor ); - QGL_invalidateExtensionFunc( table.m_glSelectBuffer ); - QGL_invalidateExtensionFunc( table.m_glShadeModel ); - QGL_invalidateExtensionFunc( table.m_glStencilFunc ); - QGL_invalidateExtensionFunc( table.m_glStencilMask ); - QGL_invalidateExtensionFunc( table.m_glStencilOp ); - QGL_invalidateExtensionFunc( table.m_glTexCoord1d ); - QGL_invalidateExtensionFunc( table.m_glTexCoord1dv ); - QGL_invalidateExtensionFunc( table.m_glTexCoord1f ); - QGL_invalidateExtensionFunc( table.m_glTexCoord1fv ); - QGL_invalidateExtensionFunc( table.m_glTexCoord1i ); - QGL_invalidateExtensionFunc( table.m_glTexCoord1iv ); - QGL_invalidateExtensionFunc( table.m_glTexCoord1s ); - QGL_invalidateExtensionFunc( table.m_glTexCoord1sv ); - QGL_invalidateExtensionFunc( table.m_glTexCoord2d ); - QGL_invalidateExtensionFunc( table.m_glTexCoord2dv ); - QGL_invalidateExtensionFunc( table.m_glTexCoord2f ); - QGL_invalidateExtensionFunc( table.m_glTexCoord2fv ); - QGL_invalidateExtensionFunc( table.m_glTexCoord2i ); - QGL_invalidateExtensionFunc( table.m_glTexCoord2iv ); - QGL_invalidateExtensionFunc( table.m_glTexCoord2s ); - QGL_invalidateExtensionFunc( table.m_glTexCoord2sv ); - QGL_invalidateExtensionFunc( table.m_glTexCoord3d ); - QGL_invalidateExtensionFunc( table.m_glTexCoord3dv ); - QGL_invalidateExtensionFunc( table.m_glTexCoord3f ); - QGL_invalidateExtensionFunc( table.m_glTexCoord3fv ); - QGL_invalidateExtensionFunc( table.m_glTexCoord3i ); - QGL_invalidateExtensionFunc( table.m_glTexCoord3iv ); - QGL_invalidateExtensionFunc( table.m_glTexCoord3s ); - QGL_invalidateExtensionFunc( table.m_glTexCoord3sv ); - QGL_invalidateExtensionFunc( table.m_glTexCoord4d ); - QGL_invalidateExtensionFunc( table.m_glTexCoord4dv ); - QGL_invalidateExtensionFunc( table.m_glTexCoord4f ); - QGL_invalidateExtensionFunc( table.m_glTexCoord4fv ); - QGL_invalidateExtensionFunc( table.m_glTexCoord4i ); - QGL_invalidateExtensionFunc( table.m_glTexCoord4iv ); - QGL_invalidateExtensionFunc( table.m_glTexCoord4s ); - QGL_invalidateExtensionFunc( table.m_glTexCoord4sv ); - QGL_invalidateExtensionFunc( table.m_glTexCoordPointer ); - QGL_invalidateExtensionFunc( table.m_glTexEnvf ); - QGL_invalidateExtensionFunc( table.m_glTexEnvfv ); - QGL_invalidateExtensionFunc( table.m_glTexEnvi ); - QGL_invalidateExtensionFunc( table.m_glTexEnviv ); - QGL_invalidateExtensionFunc( table.m_glTexGend ); - QGL_invalidateExtensionFunc( table.m_glTexGendv ); - QGL_invalidateExtensionFunc( table.m_glTexGenf ); - QGL_invalidateExtensionFunc( table.m_glTexGenfv ); - QGL_invalidateExtensionFunc( table.m_glTexGeni ); - QGL_invalidateExtensionFunc( table.m_glTexGeniv ); - QGL_invalidateExtensionFunc( table.m_glTexImage1D ); - QGL_invalidateExtensionFunc( table.m_glTexImage2D ); - QGL_invalidateExtensionFunc( table.m_glTexParameterf ); - QGL_invalidateExtensionFunc( table.m_glTexParameterfv ); - QGL_invalidateExtensionFunc( table.m_glTexParameteri ); - QGL_invalidateExtensionFunc( table.m_glTexParameteriv ); - QGL_invalidateExtensionFunc( table.m_glTexSubImage1D ); - QGL_invalidateExtensionFunc( table.m_glTexSubImage2D ); - QGL_invalidateExtensionFunc( table.m_glTranslated ); - QGL_invalidateExtensionFunc( table.m_glTranslatef ); - QGL_invalidateExtensionFunc( table.m_glVertex2d ); - QGL_invalidateExtensionFunc( table.m_glVertex2dv ); - QGL_invalidateExtensionFunc( table.m_glVertex2f ); - QGL_invalidateExtensionFunc( table.m_glVertex2fv ); - QGL_invalidateExtensionFunc( table.m_glVertex2i ); - QGL_invalidateExtensionFunc( table.m_glVertex2iv ); - QGL_invalidateExtensionFunc( table.m_glVertex2s ); - QGL_invalidateExtensionFunc( table.m_glVertex2sv ); - QGL_invalidateExtensionFunc( table.m_glVertex3d ); - QGL_invalidateExtensionFunc( table.m_glVertex3dv ); - QGL_invalidateExtensionFunc( table.m_glVertex3f ); - QGL_invalidateExtensionFunc( table.m_glVertex3fv ); - QGL_invalidateExtensionFunc( table.m_glVertex3i ); - QGL_invalidateExtensionFunc( table.m_glVertex3iv ); - QGL_invalidateExtensionFunc( table.m_glVertex3s ); - QGL_invalidateExtensionFunc( table.m_glVertex3sv ); - QGL_invalidateExtensionFunc( table.m_glVertex4d ); - QGL_invalidateExtensionFunc( table.m_glVertex4dv ); - QGL_invalidateExtensionFunc( table.m_glVertex4f ); - QGL_invalidateExtensionFunc( table.m_glVertex4fv ); - QGL_invalidateExtensionFunc( table.m_glVertex4i ); - QGL_invalidateExtensionFunc( table.m_glVertex4iv ); - QGL_invalidateExtensionFunc( table.m_glVertex4s ); - QGL_invalidateExtensionFunc( table.m_glVertex4sv ); - QGL_invalidateExtensionFunc( table.m_glVertexPointer ); - QGL_invalidateExtensionFunc( table.m_glViewport ); } int QGL_Init( OpenGLBinding& table ){ QGL_clear( table ); - -#if defined( WIN32 ) - qwglGetProcAddress = wglGetProcAddress; -#elif defined( XWINDOWS ) - qglXGetProcAddressARB = (glXGetProcAddressARBProc)dlsym( RTLD_DEFAULT, "glXGetProcAddressARB" ); - if ( ( qglXQueryExtension == 0 ) || ( qglXQueryExtension( GDK_DISPLAY(),0,0 ) != True ) ) { - return 0; - } -#else -#error "unsupported platform" -#endif - return 1; } @@ -555,7 +90,7 @@ void QGL_InitVersion(){ #if EXTENSIONS_ENABLED const std::size_t versionSize = 256; char version[versionSize]; - strncpy( version, reinterpret_cast( GlobalOpenGL().m_glGetString( GL_VERSION ) ), versionSize - 1 ); + strncpy( version, reinterpret_cast( gl().glGetString( GL_VERSION ) ), versionSize - 1 ); version[versionSize - 1] = '\0'; char* firstDot = strchr( version, '.' ); ASSERT_NOTNULL( firstDot ); @@ -589,863 +124,9 @@ void QGL_sharedContextCreated( OpenGLBinding& table ){ table.major_version = g_qglMajorVersion; table.minor_version = g_qglMinorVersion; - table.m_glAccum = glAccum; - table.m_glAlphaFunc = glAlphaFunc; - table.m_glAreTexturesResident = glAreTexturesResident; - table.m_glArrayElement = glArrayElement; - table.m_glBegin = glBegin; - table.m_glBindTexture = glBindTexture; - table.m_glBitmap = glBitmap; - table.m_glBlendFunc = glBlendFunc; - table.m_glCallList = glCallList; - table.m_glCallLists = glCallLists; - table.m_glClear = glClear; - table.m_glClearAccum = glClearAccum; - table.m_glClearColor = glClearColor; - table.m_glClearDepth = glClearDepth; - table.m_glClearIndex = glClearIndex; - table.m_glClearStencil = glClearStencil; - table.m_glClipPlane = glClipPlane; - table.m_glColor3b = glColor3b; - table.m_glColor3bv = glColor3bv; - table.m_glColor3d = glColor3d; - table.m_glColor3dv = glColor3dv; - table.m_glColor3f = glColor3f; - table.m_glColor3fv = glColor3fv; - table.m_glColor3i = glColor3i; - table.m_glColor3iv = glColor3iv; - table.m_glColor3s = glColor3s; - table.m_glColor3sv = glColor3sv; - table.m_glColor3ub = glColor3ub; - table.m_glColor3ubv = glColor3ubv; - table.m_glColor3ui = glColor3ui; - table.m_glColor3uiv = glColor3uiv; - table.m_glColor3us = glColor3us; - table.m_glColor3usv = glColor3usv; - table.m_glColor4b = glColor4b; - table.m_glColor4bv = glColor4bv; - table.m_glColor4d = glColor4d; - table.m_glColor4dv = glColor4dv; - table.m_glColor4f = glColor4f; - table.m_glColor4fv = glColor4fv; - table.m_glColor4i = glColor4i; - table.m_glColor4iv = glColor4iv; - table.m_glColor4s = glColor4s; - table.m_glColor4sv = glColor4sv; - table.m_glColor4ub = glColor4ub; - table.m_glColor4ubv = glColor4ubv; - table.m_glColor4ui = glColor4ui; - table.m_glColor4uiv = glColor4uiv; - table.m_glColor4us = glColor4us; - table.m_glColor4usv = glColor4usv; - table.m_glColorMask = glColorMask; - table.m_glColorMaterial = glColorMaterial; - table.m_glColorPointer = glColorPointer; - table.m_glCopyPixels = glCopyPixels; - table.m_glCopyTexImage1D = glCopyTexImage1D; - table.m_glCopyTexImage2D = glCopyTexImage2D; - table.m_glCopyTexSubImage1D = glCopyTexSubImage1D; - table.m_glCopyTexSubImage2D = glCopyTexSubImage2D; - table.m_glCullFace = glCullFace; - table.m_glDeleteLists = glDeleteLists; - table.m_glDeleteTextures = glDeleteTextures; - table.m_glDepthFunc = glDepthFunc; - table.m_glDepthMask = glDepthMask; - table.m_glDepthRange = glDepthRange; - table.m_glDisable = glDisable; - table.m_glDisableClientState = glDisableClientState; - table.m_glDrawArrays = glDrawArrays; - table.m_glDrawBuffer = glDrawBuffer; - table.m_glDrawElements = glDrawElements; - table.m_glDrawPixels = glDrawPixels; - table.m_glEdgeFlag = glEdgeFlag; - table.m_glEdgeFlagPointer = glEdgeFlagPointer; - table.m_glEdgeFlagv = glEdgeFlagv; - table.m_glEnable = glEnable; - table.m_glEnableClientState = glEnableClientState; - table.m_glEnd = glEnd; - table.m_glEndList = glEndList; - table.m_glEvalCoord1d = glEvalCoord1d; - table.m_glEvalCoord1dv = glEvalCoord1dv; - table.m_glEvalCoord1f = glEvalCoord1f; - table.m_glEvalCoord1fv = glEvalCoord1fv; - table.m_glEvalCoord2d = glEvalCoord2d; - table.m_glEvalCoord2dv = glEvalCoord2dv; - table.m_glEvalCoord2f = glEvalCoord2f; - table.m_glEvalCoord2fv = glEvalCoord2fv; - table.m_glEvalMesh1 = glEvalMesh1; - table.m_glEvalMesh2 = glEvalMesh2; - table.m_glEvalPoint1 = glEvalPoint1; - table.m_glEvalPoint2 = glEvalPoint2; - table.m_glFeedbackBuffer = glFeedbackBuffer; - table.m_glFinish = glFinish; - table.m_glFlush = glFlush; - table.m_glFogf = glFogf; - table.m_glFogfv = glFogfv; - table.m_glFogi = glFogi; - table.m_glFogiv = glFogiv; - table.m_glFrontFace = glFrontFace; - table.m_glFrustum = glFrustum; - table.m_glGenLists = glGenLists; - table.m_glGenTextures = glGenTextures; - table.m_glGetBooleanv = glGetBooleanv; - table.m_glGetClipPlane = glGetClipPlane; - table.m_glGetDoublev = glGetDoublev; - table.m_glGetError = glGetError; - table.m_glGetFloatv = glGetFloatv; - table.m_glGetIntegerv = glGetIntegerv; - table.m_glGetLightfv = glGetLightfv; - table.m_glGetLightiv = glGetLightiv; - table.m_glGetMapdv = glGetMapdv; - table.m_glGetMapfv = glGetMapfv; - table.m_glGetMapiv = glGetMapiv; - table.m_glGetMaterialfv = glGetMaterialfv; - table.m_glGetMaterialiv = glGetMaterialiv; - table.m_glGetPixelMapfv = glGetPixelMapfv; - table.m_glGetPixelMapuiv = glGetPixelMapuiv; - table.m_glGetPixelMapusv = glGetPixelMapusv; - table.m_glGetPointerv = glGetPointerv; - table.m_glGetPolygonStipple = glGetPolygonStipple; - table.m_glGetString = glGetString; - table.m_glGetTexEnvfv = glGetTexEnvfv; - table.m_glGetTexEnviv = glGetTexEnviv; - table.m_glGetTexGendv = glGetTexGendv; - table.m_glGetTexGenfv = glGetTexGenfv; - table.m_glGetTexGeniv = glGetTexGeniv; - table.m_glGetTexImage = glGetTexImage; - table.m_glGetTexLevelParameterfv = glGetTexLevelParameterfv; - table.m_glGetTexLevelParameteriv = glGetTexLevelParameteriv; - table.m_glGetTexParameterfv = glGetTexParameterfv; - table.m_glGetTexParameteriv = glGetTexParameteriv; - table.m_glHint = glHint; - table.m_glIndexMask = glIndexMask; - table.m_glIndexPointer = glIndexPointer; - table.m_glIndexd = glIndexd; - table.m_glIndexdv = glIndexdv; - table.m_glIndexf = glIndexf; - table.m_glIndexfv = glIndexfv; - table.m_glIndexi = glIndexi; - table.m_glIndexiv = glIndexiv; - table.m_glIndexs = glIndexs; - table.m_glIndexsv = glIndexsv; - table.m_glIndexub = glIndexub; - table.m_glIndexubv = glIndexubv; - table.m_glInitNames = glInitNames; - table.m_glInterleavedArrays = glInterleavedArrays; - table.m_glIsEnabled = glIsEnabled; - table.m_glIsList = glIsList; - table.m_glIsTexture = glIsTexture; - table.m_glLightModelf = glLightModelf; - table.m_glLightModelfv = glLightModelfv; - table.m_glLightModeli = glLightModeli; - table.m_glLightModeliv = glLightModeliv; - table.m_glLightf = glLightf; - table.m_glLightfv = glLightfv; - table.m_glLighti = glLighti; - table.m_glLightiv = glLightiv; - table.m_glLineStipple = glLineStipple; - table.m_glLineWidth = glLineWidth; - table.m_glListBase = glListBase; - table.m_glLoadIdentity = glLoadIdentity; - table.m_glLoadMatrixd = glLoadMatrixd; - table.m_glLoadMatrixf = glLoadMatrixf; - table.m_glLoadName = glLoadName; - table.m_glLogicOp = glLogicOp; - table.m_glMap1d = glMap1d; - table.m_glMap1f = glMap1f; - table.m_glMap2d = glMap2d; - table.m_glMap2f = glMap2f; - table.m_glMapGrid1d = glMapGrid1d; - table.m_glMapGrid1f = glMapGrid1f; - table.m_glMapGrid2d = glMapGrid2d; - table.m_glMapGrid2f = glMapGrid2f; - table.m_glMaterialf = glMaterialf; - table.m_glMaterialfv = glMaterialfv; - table.m_glMateriali = glMateriali; - table.m_glMaterialiv = glMaterialiv; - table.m_glMatrixMode = glMatrixMode; - table.m_glMultMatrixd = glMultMatrixd; - table.m_glMultMatrixf = glMultMatrixf; - table.m_glNewList = glNewList; - table.m_glNormal3b = glNormal3b; - table.m_glNormal3bv = glNormal3bv; - table.m_glNormal3d = glNormal3d; - table.m_glNormal3dv = glNormal3dv; - table.m_glNormal3f = glNormal3f; - table.m_glNormal3fv = glNormal3fv; - table.m_glNormal3i = glNormal3i; - table.m_glNormal3iv = glNormal3iv; - table.m_glNormal3s = glNormal3s; - table.m_glNormal3sv = glNormal3sv; - table.m_glNormalPointer = glNormalPointer; - table.m_glOrtho = glOrtho; - table.m_glPassThrough = glPassThrough; - table.m_glPixelMapfv = glPixelMapfv; - table.m_glPixelMapuiv = glPixelMapuiv; - table.m_glPixelMapusv = glPixelMapusv; - table.m_glPixelStoref = glPixelStoref; - table.m_glPixelStorei = glPixelStorei; - table.m_glPixelTransferf = glPixelTransferf; - table.m_glPixelTransferi = glPixelTransferi; - table.m_glPixelZoom = glPixelZoom; - table.m_glPointSize = glPointSize; - table.m_glPolygonMode = glPolygonMode; - table.m_glPolygonOffset = glPolygonOffset; - table.m_glPolygonStipple = glPolygonStipple; - table.m_glPopAttrib = glPopAttrib; - table.m_glPopClientAttrib = glPopClientAttrib; - table.m_glPopMatrix = glPopMatrix; - table.m_glPopName = glPopName; - table.m_glPrioritizeTextures = glPrioritizeTextures; - table.m_glPushAttrib = glPushAttrib; - table.m_glPushClientAttrib = glPushClientAttrib; - table.m_glPushMatrix = glPushMatrix; - table.m_glPushName = glPushName; - table.m_glRasterPos2d = glRasterPos2d; - table.m_glRasterPos2dv = glRasterPos2dv; - table.m_glRasterPos2f = glRasterPos2f; - table.m_glRasterPos2fv = glRasterPos2fv; - table.m_glRasterPos2i = glRasterPos2i; - table.m_glRasterPos2iv = glRasterPos2iv; - table.m_glRasterPos2s = glRasterPos2s; - table.m_glRasterPos2sv = glRasterPos2sv; - table.m_glRasterPos3d = glRasterPos3d; - table.m_glRasterPos3dv = glRasterPos3dv; - table.m_glRasterPos3f = glRasterPos3f; - table.m_glRasterPos3fv = glRasterPos3fv; - table.m_glRasterPos3i = glRasterPos3i; - table.m_glRasterPos3iv = glRasterPos3iv; - table.m_glRasterPos3s = glRasterPos3s; - table.m_glRasterPos3sv = glRasterPos3sv; - table.m_glRasterPos4d = glRasterPos4d; - table.m_glRasterPos4dv = glRasterPos4dv; - table.m_glRasterPos4f = glRasterPos4f; - table.m_glRasterPos4fv = glRasterPos4fv; - table.m_glRasterPos4i = glRasterPos4i; - table.m_glRasterPos4iv = glRasterPos4iv; - table.m_glRasterPos4s = glRasterPos4s; - table.m_glRasterPos4sv = glRasterPos4sv; - table.m_glReadBuffer = glReadBuffer; - table.m_glReadPixels = glReadPixels; - table.m_glRectd = glRectd; - table.m_glRectdv = glRectdv; - table.m_glRectf = glRectf; - table.m_glRectfv = glRectfv; - table.m_glRecti = glRecti; - table.m_glRectiv = glRectiv; - table.m_glRects = glRects; - table.m_glRectsv = glRectsv; - table.m_glRenderMode = glRenderMode; - table.m_glRotated = glRotated; - table.m_glRotatef = glRotatef; - table.m_glScaled = glScaled; - table.m_glScalef = glScalef; - table.m_glScissor = glScissor; - table.m_glSelectBuffer = glSelectBuffer; - table.m_glShadeModel = glShadeModel; - table.m_glStencilFunc = glStencilFunc; - table.m_glStencilMask = glStencilMask; - table.m_glStencilOp = glStencilOp; - table.m_glTexCoord1d = glTexCoord1d; - table.m_glTexCoord1dv = glTexCoord1dv; - table.m_glTexCoord1f = glTexCoord1f; - table.m_glTexCoord1fv = glTexCoord1fv; - table.m_glTexCoord1i = glTexCoord1i; - table.m_glTexCoord1iv = glTexCoord1iv; - table.m_glTexCoord1s = glTexCoord1s; - table.m_glTexCoord1sv = glTexCoord1sv; - table.m_glTexCoord2d = glTexCoord2d; - table.m_glTexCoord2dv = glTexCoord2dv; - table.m_glTexCoord2f = glTexCoord2f; - table.m_glTexCoord2fv = glTexCoord2fv; - table.m_glTexCoord2i = glTexCoord2i; - table.m_glTexCoord2iv = glTexCoord2iv; - table.m_glTexCoord2s = glTexCoord2s; - table.m_glTexCoord2sv = glTexCoord2sv; - table.m_glTexCoord3d = glTexCoord3d; - table.m_glTexCoord3dv = glTexCoord3dv; - table.m_glTexCoord3f = glTexCoord3f; - table.m_glTexCoord3fv = glTexCoord3fv; - table.m_glTexCoord3i = glTexCoord3i; - table.m_glTexCoord3iv = glTexCoord3iv; - table.m_glTexCoord3s = glTexCoord3s; - table.m_glTexCoord3sv = glTexCoord3sv; - table.m_glTexCoord4d = glTexCoord4d; - table.m_glTexCoord4dv = glTexCoord4dv; - table.m_glTexCoord4f = glTexCoord4f; - table.m_glTexCoord4fv = glTexCoord4fv; - table.m_glTexCoord4i = glTexCoord4i; - table.m_glTexCoord4iv = glTexCoord4iv; - table.m_glTexCoord4s = glTexCoord4s; - table.m_glTexCoord4sv = glTexCoord4sv; - table.m_glTexCoordPointer = glTexCoordPointer; - table.m_glTexEnvf = glTexEnvf; - table.m_glTexEnvfv = glTexEnvfv; - table.m_glTexEnvi = glTexEnvi; - table.m_glTexEnviv = glTexEnviv; - table.m_glTexGend = glTexGend; - table.m_glTexGendv = glTexGendv; - table.m_glTexGenf = glTexGenf; - table.m_glTexGenfv = glTexGenfv; - table.m_glTexGeni = glTexGeni; - table.m_glTexGeniv = glTexGeniv; - table.m_glTexImage1D = glTexImage1D; - table.m_glTexImage2D = glTexImage2D; - table.m_glTexParameterf = glTexParameterf; - table.m_glTexParameterfv = glTexParameterfv; - table.m_glTexParameteri = glTexParameteri; - table.m_glTexParameteriv = glTexParameteriv; - table.m_glTexSubImage1D = glTexSubImage1D; - table.m_glTexSubImage2D = glTexSubImage2D; - table.m_glTranslated = glTranslated; - table.m_glTranslatef = glTranslatef; - table.m_glVertex2d = glVertex2d; - table.m_glVertex2dv = glVertex2dv; - table.m_glVertex2f = glVertex2f; - table.m_glVertex2fv = glVertex2fv; - table.m_glVertex2i = glVertex2i; - table.m_glVertex2iv = glVertex2iv; - table.m_glVertex2s = glVertex2s; - table.m_glVertex2sv = glVertex2sv; - table.m_glVertex3d = glVertex3d; - table.m_glVertex3dv = glVertex3dv; - table.m_glVertex3f = glVertex3f; - table.m_glVertex3fv = glVertex3fv; - table.m_glVertex3i = glVertex3i; - table.m_glVertex3iv = glVertex3iv; - table.m_glVertex3s = glVertex3s; - table.m_glVertex3sv = glVertex3sv; - table.m_glVertex4d = glVertex4d; - table.m_glVertex4dv = glVertex4dv; - table.m_glVertex4f = glVertex4f; - table.m_glVertex4fv = glVertex4fv; - table.m_glVertex4i = glVertex4i; - table.m_glVertex4iv = glVertex4iv; - table.m_glVertex4s = glVertex4s; - table.m_glVertex4sv = glVertex4sv; - table.m_glVertexPointer = glVertexPointer; - table.m_glViewport = glViewport; - if ( QGL_ExtensionSupported( "GL_ARB_multitexture" ) ) { - table.support_ARB_multitexture = - QGL_constructExtensionFunc( table.m_glActiveTextureARB, "glActiveTextureARB" ) - && QGL_constructExtensionFunc( table.m_glClientActiveTextureARB, "glClientActiveTextureARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1dARB, "glMultiTexCoord1dARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1dvARB, "glMultiTexCoord1dvARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1fARB, "glMultiTexCoord1fARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1fvARB, "glMultiTexCoord1fvARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1iARB, "glMultiTexCoord1iARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1ivARB, "glMultiTexCoord1ivARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1sARB, "glMultiTexCoord1sARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1svARB, "glMultiTexCoord1svARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2dARB, "glMultiTexCoord2dARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2dvARB, "glMultiTexCoord2dvARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2fARB, "glMultiTexCoord2fARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2fvARB, "glMultiTexCoord2fvARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2iARB, "glMultiTexCoord2iARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2ivARB, "glMultiTexCoord2ivARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2sARB, "glMultiTexCoord2sARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2svARB, "glMultiTexCoord2svARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3dARB, "glMultiTexCoord3dARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3dvARB, "glMultiTexCoord3dvARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3fARB, "glMultiTexCoord3fARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3fvARB, "glMultiTexCoord3fvARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3iARB, "glMultiTexCoord3iARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3ivARB, "glMultiTexCoord3ivARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3sARB, "glMultiTexCoord3sARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3svARB, "glMultiTexCoord3svARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4dARB, "glMultiTexCoord4dARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4dvARB, "glMultiTexCoord4dvARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4fARB, "glMultiTexCoord4fARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4fvARB, "glMultiTexCoord4fvARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4iARB, "glMultiTexCoord4iARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4ivARB, "glMultiTexCoord4ivARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4sARB, "glMultiTexCoord4sARB" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4svARB, "glMultiTexCoord4svARB" ); - - if ( !table.support_ARB_multitexture ) { - extension_not_implemented( "GL_ARB_multitexture" ); - } - } - else - { - table.support_ARB_multitexture = false; - } - - if ( QGL_ExtensionSupported( "GL_ARB_texture_compression" ) ) { - table.support_ARB_texture_compression = - QGL_constructExtensionFunc( table.m_glCompressedTexImage3DARB, "glCompressedTexImage3DARB" ) - && QGL_constructExtensionFunc( table.m_glCompressedTexImage2DARB, "glCompressedTexImage2DARB" ) - && QGL_constructExtensionFunc( table.m_glCompressedTexImage1DARB, "glCompressedTexImage1DARB" ) - && QGL_constructExtensionFunc( table.m_glCompressedTexSubImage3DARB, "glCompressedTexSubImage3DARB" ) - && QGL_constructExtensionFunc( table.m_glCompressedTexSubImage2DARB, "glCompressedTexSubImage2DARB" ) - && QGL_constructExtensionFunc( table.m_glCompressedTexSubImage1DARB, "glCompressedTexSubImage1DARB" ) - && QGL_constructExtensionFunc( table.m_glGetCompressedTexImageARB, "glGetCompressedTexImageARB" ); - - if ( !table.support_ARB_texture_compression ) { - extension_not_implemented( "GL_ARB_texture_compression" ); - } - } - else - { - table.support_ARB_texture_compression = false; - } - - table.support_EXT_texture_compression_s3tc = QGL_ExtensionSupported( "GL_EXT_texture_compression_s3tc" ); - - // GL 1.2 - if ( table.major_version > 1 || table.minor_version >= 2 ) { - table.support_GL_1_2 = - QGL_constructExtensionFunc( table.m_glCopyTexSubImage3D, "glCopyTexSubImage3D" ) - && QGL_constructExtensionFunc( table.m_glDrawRangeElements, "glDrawRangeElements" ) - && QGL_constructExtensionFunc( table.m_glTexImage3D, "glTexImage3D" ) - && QGL_constructExtensionFunc( table.m_glTexSubImage3D, "glTexSubImage3D" ); - - if ( !table.support_GL_1_2 ) { - extension_not_implemented( "GL_VERSION_1_2" ); - } - } - else - { - table.support_GL_1_2 = false; - } - - // GL 1.3 - if ( table.major_version > 1 || table.minor_version >= 3 ) { - table.support_GL_1_3 = - QGL_constructExtensionFunc( table.m_glActiveTexture, "glActiveTexture" ) - && QGL_constructExtensionFunc( table.m_glClientActiveTexture, "glClientActiveTexture" ) - && QGL_constructExtensionFunc( table.m_glCompressedTexImage1D, "glCompressedTexImage1D" ) - && QGL_constructExtensionFunc( table.m_glCompressedTexImage2D, "glCompressedTexImage2D" ) - && QGL_constructExtensionFunc( table.m_glCompressedTexImage3D, "glCompressedTexImage3D" ) - && QGL_constructExtensionFunc( table.m_glCompressedTexSubImage1D, "glCompressedTexSubImage1D" ) - && QGL_constructExtensionFunc( table.m_glCompressedTexSubImage2D, "glCompressedTexSubImage2D" ) - && QGL_constructExtensionFunc( table.m_glCompressedTexSubImage3D, "glCompressedTexSubImage3D" ) - && QGL_constructExtensionFunc( table.m_glGetCompressedTexImage, "glGetCompressedTexImage" ) - && QGL_constructExtensionFunc( table.m_glLoadTransposeMatrixd, "glLoadTransposeMatrixd" ) - && QGL_constructExtensionFunc( table.m_glLoadTransposeMatrixf, "glLoadTransposeMatrixf" ) - && QGL_constructExtensionFunc( table.m_glMultTransposeMatrixd, "glMultTransposeMatrixd" ) - && QGL_constructExtensionFunc( table.m_glMultTransposeMatrixf, "glMultTransposeMatrixf" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1d, "glMultiTexCoord1d" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1dv, "glMultiTexCoord1dv" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1f, "glMultiTexCoord1f" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1fv, "glMultiTexCoord1fv" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1i, "glMultiTexCoord1i" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1iv, "glMultiTexCoord1iv" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1s, "glMultiTexCoord1s" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord1sv, "glMultiTexCoord1sv" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2d, "glMultiTexCoord2d" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2dv, "glMultiTexCoord2dv" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2f, "glMultiTexCoord2f" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2fv, "glMultiTexCoord2fv" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2i, "glMultiTexCoord2i" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2iv, "glMultiTexCoord2iv" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2s, "glMultiTexCoord2s" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord2sv, "glMultiTexCoord2sv" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3d, "glMultiTexCoord3d" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3dv, "glMultiTexCoord3dv" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3f, "glMultiTexCoord3f" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3fv, "glMultiTexCoord3fv" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3i, "glMultiTexCoord3i" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3iv, "glMultiTexCoord3iv" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3s, "glMultiTexCoord3s" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord3sv, "glMultiTexCoord3sv" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4d, "glMultiTexCoord4d" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4dv, "glMultiTexCoord4dv" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4f, "glMultiTexCoord4f" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4fv, "glMultiTexCoord4fv" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4i, "glMultiTexCoord4i" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4iv, "glMultiTexCoord4iv" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4s, "glMultiTexCoord4s" ) - && QGL_constructExtensionFunc( table.m_glMultiTexCoord4sv, "glMultiTexCoord4sv" ) - && QGL_constructExtensionFunc( table.m_glSampleCoverage, "glSampleCoverage" ); - - if ( !table.support_GL_1_3 ) { - extension_not_implemented( "GL_VERSION_1_3" ); - } - } - else - { - table.support_GL_1_3 = false; - } - - // GL 1.4 - if ( table.major_version > 1 || table.minor_version >= 4 ) { - table.support_GL_1_4 = - QGL_constructExtensionFunc( table.m_glBlendColor, "glBlendColor" ) - && QGL_constructExtensionFunc( table.m_glBlendEquation, "glBlendEquation" ) - && QGL_constructExtensionFunc( table.m_glBlendFuncSeparate, "glBlendFuncSeparate" ) - && QGL_constructExtensionFunc( table.m_glFogCoordPointer, "glFogCoordPointer" ) - && QGL_constructExtensionFunc( table.m_glFogCoordd, "glFogCoordd" ) - && QGL_constructExtensionFunc( table.m_glFogCoorddv, "glFogCoorddv" ) - && QGL_constructExtensionFunc( table.m_glFogCoordf, "glFogCoordf" ) - && QGL_constructExtensionFunc( table.m_glFogCoordfv, "glFogCoordfv" ) - && QGL_constructExtensionFunc( table.m_glMultiDrawArrays, "glMultiDrawArrays" ) - && QGL_constructExtensionFunc( table.m_glMultiDrawElements, "glMultiDrawElements" ) - && QGL_constructExtensionFunc( table.m_glPointParameterf, "glPointParameterf" ) - && QGL_constructExtensionFunc( table.m_glPointParameterfv, "glPointParameterfv" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3b, "glSecondaryColor3b" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3bv, "glSecondaryColor3bv" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3d, "glSecondaryColor3d" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3dv, "glSecondaryColor3dv" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3f, "glSecondaryColor3f" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3fv, "glSecondaryColor3fv" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3i, "glSecondaryColor3i" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3iv, "glSecondaryColor3iv" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3s, "glSecondaryColor3s" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3sv, "glSecondaryColor3sv" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3ub, "glSecondaryColor3ub" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3ubv, "glSecondaryColor3ubv" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3ui, "glSecondaryColor3ui" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3uiv, "glSecondaryColor3uiv" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3us, "glSecondaryColor3us" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColor3usv, "glSecondaryColor3usv" ) - && QGL_constructExtensionFunc( table.m_glSecondaryColorPointer, "glSecondaryColorPointer" ) - && QGL_constructExtensionFunc( table.m_glWindowPos2d, "glWindowPos2d" ) - && QGL_constructExtensionFunc( table.m_glWindowPos2dv, "glWindowPos2dv" ) - && QGL_constructExtensionFunc( table.m_glWindowPos2f, "glWindowPos2f" ) - && QGL_constructExtensionFunc( table.m_glWindowPos2fv, "glWindowPos2fv" ) - && QGL_constructExtensionFunc( table.m_glWindowPos2i, "glWindowPos2i" ) - && QGL_constructExtensionFunc( table.m_glWindowPos2iv, "glWindowPos2iv" ) - && QGL_constructExtensionFunc( table.m_glWindowPos2s, "glWindowPos2s" ) - && QGL_constructExtensionFunc( table.m_glWindowPos2sv, "glWindowPos2sv" ) - && QGL_constructExtensionFunc( table.m_glWindowPos3d, "glWindowPos3d" ) - && QGL_constructExtensionFunc( table.m_glWindowPos3dv, "glWindowPos3dv" ) - && QGL_constructExtensionFunc( table.m_glWindowPos3f, "glWindowPos3f" ) - && QGL_constructExtensionFunc( table.m_glWindowPos3fv, "glWindowPos3fv" ) - && QGL_constructExtensionFunc( table.m_glWindowPos3i, "glWindowPos3i" ) - && QGL_constructExtensionFunc( table.m_glWindowPos3iv, "glWindowPos3iv" ) - && QGL_constructExtensionFunc( table.m_glWindowPos3s, "glWindowPos3s" ) - && QGL_constructExtensionFunc( table.m_glWindowPos3sv, "glWindowPos3sv" ); - - if ( !table.support_GL_1_4 ) { - extension_not_implemented( "GL_VERSION_1_4" ); - } - } - else - { - table.support_GL_1_4 = false; - } - - // GL 1.5 - if ( table.major_version > 1 || table.minor_version >= 5 ) { - table.support_GL_1_5 = - QGL_constructExtensionFunc( table.m_glBeginQuery, "glBeginQuery" ) - && QGL_constructExtensionFunc( table.m_glBindBuffer, "glBindBuffer" ) - && QGL_constructExtensionFunc( table.m_glBufferData, "glBufferData" ) - && QGL_constructExtensionFunc( table.m_glBufferSubData, "glBufferSubData" ) - && QGL_constructExtensionFunc( table.m_glDeleteBuffers, "glDeleteBuffers" ) - && QGL_constructExtensionFunc( table.m_glDeleteQueries, "glDeleteQueries" ) - && QGL_constructExtensionFunc( table.m_glEndQuery, "glEndQuery" ) - && QGL_constructExtensionFunc( table.m_glGenBuffers, "glGenBuffers" ) - && QGL_constructExtensionFunc( table.m_glGenQueries, "glGenQueries" ) - && QGL_constructExtensionFunc( table.m_glGetBufferParameteriv, "glGetBufferParameteriv" ) - && QGL_constructExtensionFunc( table.m_glGetBufferPointerv, "glGetBufferPointerv" ) - && QGL_constructExtensionFunc( table.m_glGetBufferSubData, "glGetBufferSubData" ) - && QGL_constructExtensionFunc( table.m_glGetQueryObjectiv, "glGetQueryObjectiv" ) - && QGL_constructExtensionFunc( table.m_glGetQueryObjectuiv, "glGetQueryObjectuiv" ) - && QGL_constructExtensionFunc( table.m_glGetQueryiv, "glGetQueryiv" ) - && QGL_constructExtensionFunc( table.m_glIsBuffer, "glIsBuffer" ) - && QGL_constructExtensionFunc( table.m_glIsQuery, "glIsQuery" ) - && QGL_constructExtensionFunc( table.m_glMapBuffer, "glMapBuffer" ) - && QGL_constructExtensionFunc( table.m_glUnmapBuffer, "glUnmapBuffer" ); - - if ( !table.support_GL_1_5 ) { - extension_not_implemented( "GL_VERSION_1_5" ); - } - } - else - { - table.support_GL_1_5 = false; - } - - - if ( QGL_ExtensionSupported( "GL_ARB_vertex_program" ) ) { - table.support_ARB_vertex_program = - QGL_constructExtensionFunc( table.m_glVertexAttrib1sARB, "glVertexAttrib1sARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib1fARB, "glVertexAttrib1fARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib1dARB, "glVertexAttrib1dARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib2sARB, "glVertexAttrib2sARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib2fARB, "glVertexAttrib2fARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib2dARB, "glVertexAttrib2dARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib3sARB, "glVertexAttrib3sARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib3fARB, "glVertexAttrib3fARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib3dARB, "glVertexAttrib3dARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4sARB, "glVertexAttrib4sARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4fARB, "glVertexAttrib4fARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4dARB, "glVertexAttrib4dARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4NubARB, "glVertexAttrib4NubARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib1svARB, "glVertexAttrib1svARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib1fvARB, "glVertexAttrib1fvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib1dvARB, "glVertexAttrib1dvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib2svARB, "glVertexAttrib2svARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib2fvARB, "glVertexAttrib2fvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib2dvARB, "glVertexAttrib2dvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib3svARB, "glVertexAttrib3svARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib3fvARB, "glVertexAttrib3fvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib3dvARB, "glVertexAttrib3dvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4bvARB, "glVertexAttrib4bvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4svARB, "glVertexAttrib4svARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4ivARB, "glVertexAttrib4ivARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4ubvARB, "glVertexAttrib4ubvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4usvARB, "glVertexAttrib4usvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4uivARB, "glVertexAttrib4uivARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4fvARB, "glVertexAttrib4fvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4dvARB, "glVertexAttrib4dvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4NbvARB, "glVertexAttrib4NbvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4NsvARB, "glVertexAttrib4NsvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4NivARB, "glVertexAttrib4NivARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4NubvARB, "glVertexAttrib4NubvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4NusvARB, "glVertexAttrib4NusvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4NuivARB, "glVertexAttrib4NuivARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttribPointerARB, "glVertexAttribPointerARB" ) - && QGL_constructExtensionFunc( table.m_glEnableVertexAttribArrayARB, "glEnableVertexAttribArrayARB" ) - && QGL_constructExtensionFunc( table.m_glDisableVertexAttribArrayARB, "glDisableVertexAttribArrayARB" ) - && QGL_constructExtensionFunc( table.m_glProgramStringARB, "glProgramStringARB" ) - && QGL_constructExtensionFunc( table.m_glBindProgramARB, "glBindProgramARB" ) - && QGL_constructExtensionFunc( table.m_glDeleteProgramsARB, "glDeleteProgramsARB" ) - && QGL_constructExtensionFunc( table.m_glGenProgramsARB, "glGenProgramsARB" ) - && QGL_constructExtensionFunc( table.m_glProgramEnvParameter4dARB, "glProgramEnvParameter4dARB" ) - && QGL_constructExtensionFunc( table.m_glProgramEnvParameter4dvARB, "glProgramEnvParameter4dvARB" ) - && QGL_constructExtensionFunc( table.m_glProgramEnvParameter4fARB, "glProgramEnvParameter4fARB" ) - && QGL_constructExtensionFunc( table.m_glProgramEnvParameter4fvARB, "glProgramEnvParameter4fvARB" ) - && QGL_constructExtensionFunc( table.m_glProgramLocalParameter4dARB, "glProgramLocalParameter4dARB" ) - && QGL_constructExtensionFunc( table.m_glProgramLocalParameter4dvARB, "glProgramLocalParameter4dvARB" ) - && QGL_constructExtensionFunc( table.m_glProgramLocalParameter4fARB, "glProgramLocalParameter4fARB" ) - && QGL_constructExtensionFunc( table.m_glProgramLocalParameter4fvARB, "glProgramLocalParameter4fvARB" ) - && QGL_constructExtensionFunc( table.m_glGetProgramEnvParameterdvARB, "glGetProgramEnvParameterdvARB" ) - && QGL_constructExtensionFunc( table.m_glGetProgramEnvParameterfvARB, "glGetProgramEnvParameterfvARB" ) - && QGL_constructExtensionFunc( table.m_glGetProgramLocalParameterdvARB, "glGetProgramLocalParameterdvARB" ) - && QGL_constructExtensionFunc( table.m_glGetProgramLocalParameterfvARB, "glGetProgramLocalParameterfvARB" ) - && QGL_constructExtensionFunc( table.m_glGetProgramivARB, "glGetProgramivARB" ) - && QGL_constructExtensionFunc( table.m_glGetProgramStringARB, "glGetProgramStringARB" ) - && QGL_constructExtensionFunc( table.m_glGetVertexAttribdvARB, "glGetVertexAttribdvARB" ) - && QGL_constructExtensionFunc( table.m_glGetVertexAttribfvARB, "glGetVertexAttribfvARB" ) - && QGL_constructExtensionFunc( table.m_glGetVertexAttribivARB, "glGetVertexAttribivARB" ) - && QGL_constructExtensionFunc( table.m_glGetVertexAttribPointervARB, "glGetVertexAttribPointervARB" ) - && QGL_constructExtensionFunc( table.m_glIsProgramARB, "glIsProgramARB" ); - - if ( !table.support_ARB_vertex_program ) { - extension_not_implemented( "GL_ARB_vertex_program" ); - } - } - else - { - table.support_ARB_vertex_program = false; - } - - - table.support_ARB_fragment_program = QGL_ExtensionSupported( "GL_ARB_fragment_program" ); - - if ( QGL_ExtensionSupported( "GL_ARB_shader_objects" ) ) { - table.support_ARB_shader_objects = - QGL_constructExtensionFunc( table.m_glDeleteObjectARB, "glDeleteObjectARB" ) - && QGL_constructExtensionFunc( table.m_glGetHandleARB, "glGetHandleARB" ) - && QGL_constructExtensionFunc( table.m_glDetachObjectARB, "glDetachObjectARB" ) - && QGL_constructExtensionFunc( table.m_glCreateShaderObjectARB, "glCreateShaderObjectARB" ) - && QGL_constructExtensionFunc( table.m_glShaderSourceARB, "glShaderSourceARB" ) - && QGL_constructExtensionFunc( table.m_glCompileShaderARB, "glCompileShaderARB" ) - && QGL_constructExtensionFunc( table.m_glCreateProgramObjectARB, "glCreateProgramObjectARB" ) - && QGL_constructExtensionFunc( table.m_glAttachObjectARB, "glAttachObjectARB" ) - && QGL_constructExtensionFunc( table.m_glLinkProgramARB, "glLinkProgramARB" ) - && QGL_constructExtensionFunc( table.m_glUseProgramObjectARB, "glUseProgramObjectARB" ) - && QGL_constructExtensionFunc( table.m_glValidateProgramARB, "glValidateProgramARB" ) - && QGL_constructExtensionFunc( table.m_glUniform1fARB, "glUniform1fARB" ) - && QGL_constructExtensionFunc( table.m_glUniform2fARB, "glUniform2fARB" ) - && QGL_constructExtensionFunc( table.m_glUniform3fARB, "glUniform3fARB" ) - && QGL_constructExtensionFunc( table.m_glUniform4fARB, "glUniform4fARB" ) - && QGL_constructExtensionFunc( table.m_glUniform1iARB, "glUniform1iARB" ) - && QGL_constructExtensionFunc( table.m_glUniform2iARB, "glUniform2iARB" ) - && QGL_constructExtensionFunc( table.m_glUniform3iARB, "glUniform3iARB" ) - && QGL_constructExtensionFunc( table.m_glUniform4iARB, "glUniform4iARB" ) - && QGL_constructExtensionFunc( table.m_glUniform1fvARB, "glUniform1fvARB" ) - && QGL_constructExtensionFunc( table.m_glUniform2fvARB, "glUniform2fvARB" ) - && QGL_constructExtensionFunc( table.m_glUniform3fvARB, "glUniform3fvARB" ) - && QGL_constructExtensionFunc( table.m_glUniform4fvARB, "glUniform4fvARB" ) - && QGL_constructExtensionFunc( table.m_glUniform1ivARB, "glUniform1ivARB" ) - && QGL_constructExtensionFunc( table.m_glUniform2ivARB, "glUniform2ivARB" ) - && QGL_constructExtensionFunc( table.m_glUniform3ivARB, "glUniform3ivARB" ) - && QGL_constructExtensionFunc( table.m_glUniform4ivARB, "glUniform4ivARB" ) - && QGL_constructExtensionFunc( table.m_glUniformMatrix2fvARB, "glUniformMatrix2fvARB" ) - && QGL_constructExtensionFunc( table.m_glUniformMatrix3fvARB, "glUniformMatrix3fvARB" ) - && QGL_constructExtensionFunc( table.m_glUniformMatrix4fvARB, "glUniformMatrix4fvARB" ) - && QGL_constructExtensionFunc( table.m_glGetObjectParameterfvARB, "glGetObjectParameterfvARB" ) - && QGL_constructExtensionFunc( table.m_glGetObjectParameterivARB, "glGetObjectParameterivARB" ) - && QGL_constructExtensionFunc( table.m_glGetInfoLogARB, "glGetInfoLogARB" ) - && QGL_constructExtensionFunc( table.m_glGetAttachedObjectsARB, "glGetAttachedObjectsARB" ) - && QGL_constructExtensionFunc( table.m_glGetUniformLocationARB, "glGetUniformLocationARB" ) - && QGL_constructExtensionFunc( table.m_glGetActiveUniformARB, "glGetActiveUniformARB" ) - && QGL_constructExtensionFunc( table.m_glGetUniformfvARB, "glGetUniformfvARB" ) - && QGL_constructExtensionFunc( table.m_glGetUniformivARB, "glGetUniformivARB" ) - && QGL_constructExtensionFunc( table.m_glGetShaderSourceARB, "glGetShaderSourceARB" ); - - if ( !table.support_ARB_shader_objects ) { - extension_not_implemented( "GL_ARB_shader_objects" ); - } - } - else - { - table.support_ARB_shader_objects = false; - } - - if ( QGL_ExtensionSupported( "GL_ARB_vertex_shader" ) ) { - table.support_ARB_vertex_shader = - QGL_constructExtensionFunc( table.m_glVertexAttrib1fARB, "glVertexAttrib1fARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib1sARB, "glVertexAttrib1sARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib1dARB, "glVertexAttrib1dARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib2fARB, "glVertexAttrib2fARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib2sARB, "glVertexAttrib2sARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib2dARB, "glVertexAttrib2dARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib3fARB, "glVertexAttrib3fARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib3sARB, "glVertexAttrib3sARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib3dARB, "glVertexAttrib3dARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4fARB, "glVertexAttrib4fARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4sARB, "glVertexAttrib4sARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4dARB, "glVertexAttrib4dARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4NubARB, "glVertexAttrib4NubARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib1fvARB, "glVertexAttrib1fvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib1svARB, "glVertexAttrib1svARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib1dvARB, "glVertexAttrib1dvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib2fvARB, "glVertexAttrib2fvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib2svARB, "glVertexAttrib2svARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib2dvARB, "glVertexAttrib2dvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib3fvARB, "glVertexAttrib3fvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib3svARB, "glVertexAttrib3svARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib3dvARB, "glVertexAttrib3dvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4fvARB, "glVertexAttrib4fvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4svARB, "glVertexAttrib4svARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4dvARB, "glVertexAttrib4dvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4ivARB, "glVertexAttrib4ivARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4bvARB, "glVertexAttrib4bvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4ubvARB, "glVertexAttrib4ubvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4usvARB, "glVertexAttrib4usvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4uivARB, "glVertexAttrib4uivARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4NbvARB, "glVertexAttrib4NbvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4NsvARB, "glVertexAttrib4NsvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4NivARB, "glVertexAttrib4NivARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4NubvARB, "glVertexAttrib4NubvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4NusvARB, "glVertexAttrib4NusvARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4NuivARB, "glVertexAttrib4NuivARB" ) - && QGL_constructExtensionFunc( table.m_glVertexAttribPointerARB, "glVertexAttribPointerARB" ) - && QGL_constructExtensionFunc( table.m_glEnableVertexAttribArrayARB, "glEnableVertexAttribArrayARB" ) - && QGL_constructExtensionFunc( table.m_glDisableVertexAttribArrayARB, "glDisableVertexAttribArrayARB" ) - && QGL_constructExtensionFunc( table.m_glGetVertexAttribdvARB, "glGetVertexAttribdvARB" ) - && QGL_constructExtensionFunc( table.m_glGetVertexAttribfvARB, "glGetVertexAttribfvARB" ) - && QGL_constructExtensionFunc( table.m_glGetVertexAttribivARB, "glGetVertexAttribivARB" ) - && QGL_constructExtensionFunc( table.m_glGetVertexAttribPointervARB, "glGetVertexAttribPointervARB" ) - && QGL_constructExtensionFunc( table.m_glBindAttribLocationARB, "glBindAttribLocationARB" ) - && QGL_constructExtensionFunc( table.m_glGetActiveAttribARB, "glGetActiveAttribARB" ) - && QGL_constructExtensionFunc( table.m_glGetAttribLocationARB, "glGetAttribLocationARB" ); - - if ( !table.support_ARB_vertex_shader ) { - extension_not_implemented( "GL_ARB_vertex_shader" ); - } - } - else - { - table.support_ARB_vertex_shader = false; - } - - if ( QGL_ExtensionSupported( "GL_NV_vertex_program2" ) ) { - table.support_NV_vertex_program2 = - QGL_constructExtensionFunc( table.m_glAreProgramsResidentNV, "glAreProgramsResidentNV" ) - && QGL_constructExtensionFunc( table.m_glBindProgramNV, "glBindProgramNV" ) - && QGL_constructExtensionFunc( table.m_glDeleteProgramsNV, "glDeleteProgramsNV" ) - && QGL_constructExtensionFunc( table.m_glExecuteProgramNV, "glExecuteProgramNV" ) - && QGL_constructExtensionFunc( table.m_glGenProgramsNV, "glGenProgramsNV" ) - && QGL_constructExtensionFunc( table.m_glGetProgramParameterdvNV, "glGetProgramParameterdvNV" ) - && QGL_constructExtensionFunc( table.m_glGetProgramParameterfvNV, "glGetProgramParameterfvNV" ) - && QGL_constructExtensionFunc( table.m_glGetProgramivNV, "glGetProgramivNV" ) - && QGL_constructExtensionFunc( table.m_glGetProgramStringNV, "glGetProgramStringNV" ) - && QGL_constructExtensionFunc( table.m_glGetTrackMatrixivNV, "glGetTrackMatrixivNV" ) - && QGL_constructExtensionFunc( table.m_glGetVertexAttribdvNV, "glGetVertexAttribdvNV" ) - && QGL_constructExtensionFunc( table.m_glGetVertexAttribfvNV, "glGetVertexAttribfvNV" ) - && QGL_constructExtensionFunc( table.m_glGetVertexAttribivNV, "glGetVertexAttribivNV" ) - && QGL_constructExtensionFunc( table.m_glGetVertexAttribPointervNV, "glGetVertexAttribPointervNV" ) - && QGL_constructExtensionFunc( table.m_glIsProgramNV, "glIsProgramNV" ) - && QGL_constructExtensionFunc( table.m_glLoadProgramNV, "glLoadProgramNV" ) - && QGL_constructExtensionFunc( table.m_glProgramParameter4fNV, "glProgramParameter4fNV" ) - && QGL_constructExtensionFunc( table.m_glProgramParameter4fvNV, "glProgramParameter4fvNV" ) - && QGL_constructExtensionFunc( table.m_glProgramParameters4fvNV, "glProgramParameters4fvNV" ) - && QGL_constructExtensionFunc( table.m_glRequestResidentProgramsNV, "glRequestResidentProgramsNV" ) - && QGL_constructExtensionFunc( table.m_glTrackMatrixNV, "glTrackMatrixNV" ) - && QGL_constructExtensionFunc( table.m_glVertexAttribPointerNV, "glVertexAttribPointerNV" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib1fNV, "glVertexAttrib1fNV" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib1fvNV, "glVertexAttrib1fvNV" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib2fNV, "glVertexAttrib2fNV" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib2fvNV, "glVertexAttrib2fvNV" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib3fNV, "glVertexAttrib3fNV" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib3fvNV, "glVertexAttrib3fvNV" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4fNV, "glVertexAttrib4fNV" ) - && QGL_constructExtensionFunc( table.m_glVertexAttrib4fvNV, "glVertexAttrib4fvNV" ) - && QGL_constructExtensionFunc( table.m_glVertexAttribs1fvNV, "glVertexAttribs1fvNV" ) - && QGL_constructExtensionFunc( table.m_glVertexAttribs2fvNV, "glVertexAttribs2fvNV" ) - && QGL_constructExtensionFunc( table.m_glVertexAttribs3fvNV, "glVertexAttribs3fvNV" ) - && QGL_constructExtensionFunc( table.m_glVertexAttribs4fvNV, "glVertexAttribs4fvNV" ); - - if ( !table.support_NV_vertex_program2 ) { - extension_not_implemented( "GL_NV_vertex_program2" ); - } - } - else - { - table.support_NV_vertex_program2 = false; - QGL_invalidateExtensionFunc( table.m_glAreProgramsResidentNV ); - QGL_invalidateExtensionFunc( table.m_glBindProgramNV ); - QGL_invalidateExtensionFunc( table.m_glDeleteProgramsNV ); - QGL_invalidateExtensionFunc( table.m_glExecuteProgramNV ); - QGL_invalidateExtensionFunc( table.m_glGenProgramsNV ); - QGL_invalidateExtensionFunc( table.m_glGetProgramParameterdvNV ); - QGL_invalidateExtensionFunc( table.m_glGetProgramParameterfvNV ); - QGL_invalidateExtensionFunc( table.m_glGetProgramivNV ); - QGL_invalidateExtensionFunc( table.m_glGetProgramStringNV ); - QGL_invalidateExtensionFunc( table.m_glGetTrackMatrixivNV ); - QGL_invalidateExtensionFunc( table.m_glGetVertexAttribdvNV ); - QGL_invalidateExtensionFunc( table.m_glGetVertexAttribfvNV ); - QGL_invalidateExtensionFunc( table.m_glGetVertexAttribivNV ); - QGL_invalidateExtensionFunc( table.m_glGetVertexAttribPointervNV ); - QGL_invalidateExtensionFunc( table.m_glIsProgramNV ); - QGL_invalidateExtensionFunc( table.m_glLoadProgramNV ); - QGL_invalidateExtensionFunc( table.m_glProgramParameter4fNV ); - QGL_invalidateExtensionFunc( table.m_glProgramParameter4fvNV ); - QGL_invalidateExtensionFunc( table.m_glProgramParameters4fvNV ); - QGL_invalidateExtensionFunc( table.m_glRequestResidentProgramsNV ); - QGL_invalidateExtensionFunc( table.m_glTrackMatrixNV ); - QGL_invalidateExtensionFunc( table.m_glVertexAttribPointerNV ); - QGL_invalidateExtensionFunc( table.m_glVertexAttrib1fNV ); - QGL_invalidateExtensionFunc( table.m_glVertexAttrib1fvNV ); - QGL_invalidateExtensionFunc( table.m_glVertexAttrib2fNV ); - QGL_invalidateExtensionFunc( table.m_glVertexAttrib2fvNV ); - QGL_invalidateExtensionFunc( table.m_glVertexAttrib3fNV ); - QGL_invalidateExtensionFunc( table.m_glVertexAttrib3fvNV ); - QGL_invalidateExtensionFunc( table.m_glVertexAttrib4fNV ); - QGL_invalidateExtensionFunc( table.m_glVertexAttrib4fvNV ); - QGL_invalidateExtensionFunc( table.m_glVertexAttribs1fvNV ); - QGL_invalidateExtensionFunc( table.m_glVertexAttribs2fvNV ); - QGL_invalidateExtensionFunc( table.m_glVertexAttribs3fvNV ); - QGL_invalidateExtensionFunc( table.m_glVertexAttribs4fvNV ); - } - - if ( QGL_ExtensionSupported( "GL_NV_fragment_program" ) ) { - table.support_NV_fragment_program = - QGL_constructExtensionFunc( table.m_glProgramNamedParameter4fNV, "glProgramNamedParameter4fNV" ) - && QGL_constructExtensionFunc( table.m_glProgramNamedParameter4fvNV, "glProgramNamedParameter4fvNV" ) - && QGL_constructExtensionFunc( table.m_glGetProgramNamedParameterfvNV, "glGetProgramNamedParameterfvNV" ); - - if ( !table.support_NV_fragment_program ) { - extension_not_implemented( "GL_NV_fragment_program" ); - } - } - else - { - table.support_NV_fragment_program = false; - } - - table.support_ARB_fragment_shader = QGL_ExtensionSupported( "GL_ARB_fragment_shader" ); - table.support_ARB_shading_language_100 = QGL_ExtensionSupported( "GL_ARB_shading_language_100" ); - - if ( QGL_ExtensionSupported( "GL_EXT_texture_filter_anisotropic" ) ) { - glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &g_maxTextureAnisotropy ); + if ( QOpenGLContext::currentContext()->hasExtension( "GL_EXT_texture_filter_anisotropic" ) ) { + gl().glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &g_maxTextureAnisotropy ); globalOutputStream() << "Anisotropic filtering possible (max " << g_maxTextureAnisotropy << "x)\n"; } else @@ -1454,38 +135,8 @@ void QGL_sharedContextCreated( OpenGLBinding& table ){ g_maxTextureAnisotropy = 0; } - - if ( QGL_ExtensionSupported( "GL_ARB_framebuffer_object" ) ) { - table.support_ARB_framebuffer_object = - QGL_constructExtensionFunc( table.m_glBindFramebuffer, "glBindFramebuffer" ) - && QGL_constructExtensionFunc( table.m_glBindRenderbuffer, "glBindRenderbuffer" ) - && QGL_constructExtensionFunc( table.m_glBlitFramebuffer, "glBlitFramebuffer" ) - && QGL_constructExtensionFunc( table.m_glCheckFramebufferStatus, "glCheckFramebufferStatus" ) - && QGL_constructExtensionFunc( table.m_glDeleteFramebuffers, "glDeleteFramebuffers" ) - && QGL_constructExtensionFunc( table.m_glDeleteRenderbuffers, "glDeleteRenderbuffers" ) - && QGL_constructExtensionFunc( table.m_glFramebufferRenderbuffer, "glFramebufferRenderbuffer" ) - && QGL_constructExtensionFunc( table.m_glFramebufferTexture1D, "glFramebufferTexture1D" ) - && QGL_constructExtensionFunc( table.m_glFramebufferTexture2D, "glFramebufferTexture2D" ) - && QGL_constructExtensionFunc( table.m_glFramebufferTexture3D, "glFramebufferTexture3D" ) - && QGL_constructExtensionFunc( table.m_glFramebufferTextureLayer, "glFramebufferTextureLayer" ) - && QGL_constructExtensionFunc( table.m_glGenFramebuffers, "glGenFramebuffers" ) - && QGL_constructExtensionFunc( table.m_glGenRenderbuffers, "glGenRenderbuffers" ) - && QGL_constructExtensionFunc( table.m_glGenerateMipmap, "glGenerateMipmap" ) - && QGL_constructExtensionFunc( table.m_glGetFramebufferAttachmentParameteriv, "glGetFramebufferAttachmentParameteriv" ) - && QGL_constructExtensionFunc( table.m_glGetRenderbufferParameteriv, "glGetRenderbufferParameteriv" ) - && QGL_constructExtensionFunc( table.m_glIsFramebuffer, "glIsFramebuffer" ) - && QGL_constructExtensionFunc( table.m_glIsRenderbuffer, "glIsRenderbuffer" ) - && QGL_constructExtensionFunc( table.m_glRenderbufferStorage, "glRenderbufferStorage" ) - && QGL_constructExtensionFunc( table.m_glRenderbufferStorageMultisample, "glRenderbufferStorageMultisample" ); - - if ( !table.support_ARB_framebuffer_object ) { - extension_not_implemented( "GL_ARB_framebuffer_object" ); - } - } - else - { - table.support_ARB_framebuffer_object = false; - } + table.support_ARB_texture_compression = QOpenGLContext::currentContext()->hasExtension( "GL_ARB_texture_compression" ); + table.support_EXT_texture_compression_s3tc = QOpenGLContext::currentContext()->hasExtension( "GL_EXT_texture_compression_s3tc" ); } void QGL_sharedContextDestroyed( OpenGLBinding& table ){ @@ -1494,7 +145,7 @@ void QGL_sharedContextDestroyed( OpenGLBinding& table ){ void QGL_assertNoErrors( const char *file, int line ){ - GLenum error = GlobalOpenGL().m_glGetError(); + GLenum error = gl().glGetError(); while ( error != GL_NO_ERROR ) { const char* errorString = reinterpret_cast( qgluErrorString( error ) ); @@ -1505,7 +156,7 @@ void QGL_assertNoErrors( const char *file, int line ){ { ERROR_MESSAGE( "OpenGL error at " << file << ":" << line << ": " << errorString ); } - error = GlobalOpenGL().m_glGetError(); + error = gl().glGetError(); } } diff --git a/radiant/qgl.h b/radiant/qgl.h index 6c36c13a..53fe6eb9 100644 --- a/radiant/qgl.h +++ b/radiant/qgl.h @@ -25,6 +25,4 @@ struct OpenGLBinding; void QGL_sharedContextCreated( OpenGLBinding& table ); void QGL_sharedContextDestroyed( OpenGLBinding& table ); -bool QGL_ExtensionSupported( const char* extension ); - float QGL_maxTextureAnisotropy(); diff --git a/radiant/renderstate.cpp b/radiant/renderstate.cpp index 4ce1e75e..60fea79e 100644 --- a/radiant/renderstate.cpp +++ b/radiant/renderstate.cpp @@ -22,7 +22,6 @@ #include "renderstate.h" #include "debugging/debugging.h" -#include "warnings.h" #include "ishaders.h" #include "irender.h" @@ -73,16 +72,16 @@ inline void debug_int( const char* comment, int i ){ inline void debug_colour( const char* comment ){ #if ( DEBUG_RENDER ) Vector4 v; - glGetFloatv( GL_CURRENT_COLOR, reinterpret_cast( &v ) ); + gl().glGetFloatv( GL_CURRENT_COLOR, reinterpret_cast( &v ) ); globalOutputStream() << comment << " colour: " << v[0] << " " << v[1] << " " << v[2] << " " << v[3]; - if ( glIsEnabled( GL_COLOR_ARRAY ) ) { + if ( gl().glIsEnabled( GL_COLOR_ARRAY ) ) { globalOutputStream() << " ARRAY"; } - if ( glIsEnabled( GL_COLOR_MATERIAL ) ) { + if ( gl().glIsEnabled( GL_COLOR_MATERIAL ) ) { globalOutputStream() << " MATERIAL"; } globalOutputStream() << "\n"; @@ -118,26 +117,36 @@ void Renderer_ResetStats(){ const char* Renderer_GetStats(){ g_renderer_stats.clear(); - g_renderer_stats << "prims: " << Unsigned( g_count_prims ) - << " | states: " << Unsigned( g_count_states ) - << " | transforms: " << Unsigned( g_count_transforms ) + g_renderer_stats << "prims: " << g_count_prims + << " | states: " << g_count_states + << " | transforms: " << g_count_transforms << " | msec: " << g_timer.elapsed_msec(); return g_renderer_stats.c_str(); } -void printShaderLog( GLhandleARB object ){ +void printShaderLog( GLuint shader ){ GLint log_length = 0; - glGetObjectParameterivARB( object, GL_OBJECT_INFO_LOG_LENGTH_ARB, &log_length ); + gl().glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &log_length ); Array log( log_length ); - glGetInfoLogARB( object, log_length, &log_length, log.data() ); + gl().glGetShaderInfoLog( shader, log_length, &log_length, log.data() ); globalErrorStream() << StringRange( log.begin(), log_length ) << "\n"; } -void createShader( GLhandleARB program, const char* filename, GLenum type ){ - GLhandleARB shader = glCreateShaderObjectARB( type ); +void printProgramLog( GLuint program ){ + GLint log_length = 0; + gl().glGetProgramiv( program, GL_INFO_LOG_LENGTH, &log_length ); + + Array log( log_length ); + gl().glGetProgramInfoLog( program, log_length, &log_length, log.data() ); + + globalErrorStream() << StringRange( log.begin(), log_length ) << "\n"; +} + +void createShader( GLuint program, const char* filename, GLenum type ){ + GLuint shader = gl().glCreateShader( type ); GlobalOpenGL_debugAssertNoErrors(); // load shader @@ -145,20 +154,20 @@ void createShader( GLhandleARB program, const char* filename, GLenum type ){ std::size_t size = file_size( filename ); FileInputStream file( filename ); ASSERT_MESSAGE( !file.failed(), "failed to open " << makeQuoted( filename ) ); - Array buffer( size ); + Array buffer( size ); size = file.read( reinterpret_cast( buffer.data() ), size ); - const GLcharARB* string = buffer.data(); + const GLchar* string = buffer.data(); GLint length = GLint( size ); - glShaderSourceARB( shader, 1, &string, &length ); + gl().glShaderSource( shader, 1, &string, &length ); } // compile shader { - glCompileShaderARB( shader ); + gl().glCompileShader( shader ); GLint compiled = 0; - glGetObjectParameterivARB( shader, GL_OBJECT_COMPILE_STATUS_ARB, &compiled ); + gl().glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled ); if ( !compiled ) { printShaderLog( shader ); @@ -168,34 +177,34 @@ void createShader( GLhandleARB program, const char* filename, GLenum type ){ } // attach shader - glAttachObjectARB( program, shader ); + gl().glAttachShader( program, shader ); - glDeleteObjectARB( shader ); + gl().glDeleteShader( shader ); GlobalOpenGL_debugAssertNoErrors(); } -void GLSLProgram_link( GLhandleARB program ){ - glLinkProgramARB( program ); +void GLSLProgram_link( GLuint program ){ + gl().glLinkProgram( program ); GLint linked = false; - glGetObjectParameterivARB( program, GL_OBJECT_LINK_STATUS_ARB, &linked ); + gl().glGetProgramiv( program, GL_LINK_STATUS, &linked ); if ( !linked ) { - printShaderLog( program ); + printProgramLog( program ); } ASSERT_MESSAGE( linked, "program link failed" ); } -void GLSLProgram_validate( GLhandleARB program ){ - glValidateProgramARB( program ); +void GLSLProgram_validate( GLuint program ){ + gl().glValidateProgram( program ); GLint validated = false; - glGetObjectParameterivARB( program, GL_OBJECT_VALIDATE_STATUS_ARB, &validated ); + gl().glGetProgramiv( program, GL_VALIDATE_STATUS, &validated ); if ( !validated ) { - printShaderLog( program ); + printProgramLog( program ); } ASSERT_MESSAGE( validated, "program validation failed" ); @@ -207,7 +216,7 @@ bool g_depthfillPass_enabled = false; class GLSLBumpProgram : public GLProgram { public: - GLhandleARB m_program; + GLuint m_program; qtexture_t* m_light_attenuation_xy; qtexture_t* m_light_attenuation_z; GLint u_view_origin; @@ -221,52 +230,52 @@ public: void create(){ // create program - m_program = glCreateProgramObjectARB(); + m_program = gl().glCreateProgram(); // create shader { StringOutputStream filename( 256 ); - createShader( m_program, filename( GlobalRadiant().getAppPath(), "gl/lighting_DBS_omni_vp.glsl" ), GL_VERTEX_SHADER_ARB ); - createShader( m_program, filename( GlobalRadiant().getAppPath(), "gl/lighting_DBS_omni_fp.glsl" ), GL_FRAGMENT_SHADER_ARB ); + createShader( m_program, filename( GlobalRadiant().getAppPath(), "gl/lighting_DBS_omni_vp.glsl" ), GL_VERTEX_SHADER ); + createShader( m_program, filename( GlobalRadiant().getAppPath(), "gl/lighting_DBS_omni_fp.glsl" ), GL_FRAGMENT_SHADER ); } GLSLProgram_link( m_program ); GLSLProgram_validate( m_program ); - glUseProgramObjectARB( m_program ); + gl().glUseProgram( m_program ); - glBindAttribLocationARB( m_program, c_attr_TexCoord0, "attr_TexCoord0" ); - glBindAttribLocationARB( m_program, c_attr_Tangent, "attr_Tangent" ); - glBindAttribLocationARB( m_program, c_attr_Binormal, "attr_Binormal" ); + gl().glBindAttribLocation( m_program, c_attr_TexCoord0, "attr_TexCoord0" ); + gl().glBindAttribLocation( m_program, c_attr_Tangent, "attr_Tangent" ); + gl().glBindAttribLocation( m_program, c_attr_Binormal, "attr_Binormal" ); - glUniform1iARB( glGetUniformLocationARB( m_program, "u_diffusemap" ), 0 ); - glUniform1iARB( glGetUniformLocationARB( m_program, "u_bumpmap" ), 1 ); - glUniform1iARB( glGetUniformLocationARB( m_program, "u_specularmap" ), 2 ); - glUniform1iARB( glGetUniformLocationARB( m_program, "u_attenuationmap_xy" ), 3 ); - glUniform1iARB( glGetUniformLocationARB( m_program, "u_attenuationmap_z" ), 4 ); + gl().glUniform1i( gl().glGetUniformLocation( m_program, "u_diffusemap" ), 0 ); + gl().glUniform1i( gl().glGetUniformLocation( m_program, "u_bumpmap" ), 1 ); + gl().glUniform1i( gl().glGetUniformLocation( m_program, "u_specularmap" ), 2 ); + gl().glUniform1i( gl().glGetUniformLocation( m_program, "u_attenuationmap_xy" ), 3 ); + gl().glUniform1i( gl().glGetUniformLocation( m_program, "u_attenuationmap_z" ), 4 ); - u_view_origin = glGetUniformLocationARB( m_program, "u_view_origin" ); - u_light_origin = glGetUniformLocationARB( m_program, "u_light_origin" ); - u_light_color = glGetUniformLocationARB( m_program, "u_light_color" ); - u_bump_scale = glGetUniformLocationARB( m_program, "u_bump_scale" ); - u_specular_exponent = glGetUniformLocationARB( m_program, "u_specular_exponent" ); + u_view_origin = gl().glGetUniformLocation( m_program, "u_view_origin" ); + u_light_origin = gl().glGetUniformLocation( m_program, "u_light_origin" ); + u_light_color = gl().glGetUniformLocation( m_program, "u_light_color" ); + u_bump_scale = gl().glGetUniformLocation( m_program, "u_bump_scale" ); + u_specular_exponent = gl().glGetUniformLocation( m_program, "u_specular_exponent" ); - glUseProgramObjectARB( 0 ); + gl().glUseProgram( 0 ); GlobalOpenGL_debugAssertNoErrors(); } void destroy(){ - glDeleteObjectARB( m_program ); + gl().glDeleteProgram( m_program ); m_program = 0; } void enable(){ - glUseProgramObjectARB( m_program ); + gl().glUseProgram( m_program ); - glEnableVertexAttribArrayARB( c_attr_TexCoord0 ); - glEnableVertexAttribArrayARB( c_attr_Tangent ); - glEnableVertexAttribArrayARB( c_attr_Binormal ); + gl().glEnableVertexAttribArray( c_attr_TexCoord0 ); + gl().glEnableVertexAttribArray( c_attr_Tangent ); + gl().glEnableVertexAttribArray( c_attr_Binormal ); GlobalOpenGL_debugAssertNoErrors(); @@ -275,11 +284,11 @@ public: } void disable(){ - glUseProgramObjectARB( 0 ); + gl().glUseProgram( 0 ); - glDisableVertexAttribArrayARB( c_attr_TexCoord0 ); - glDisableVertexAttribArrayARB( c_attr_Tangent ); - glDisableVertexAttribArrayARB( c_attr_Binormal ); + gl().glDisableVertexAttribArray( c_attr_TexCoord0 ); + gl().glDisableVertexAttribArray( c_attr_Tangent ); + gl().glDisableVertexAttribArray( c_attr_Binormal ); GlobalOpenGL_debugAssertNoErrors(); @@ -300,18 +309,18 @@ public: Matrix4 local2light( world2light ); matrix4_multiply_by_matrix4( local2light, localToWorld ); // local->world->light - glUniform3fARB( u_view_origin, localViewer.x(), localViewer.y(), localViewer.z() ); - glUniform3fARB( u_light_origin, localLight.x(), localLight.y(), localLight.z() ); - glUniform3fARB( u_light_color, colour.x(), colour.y(), colour.z() ); - glUniform1fARB( u_bump_scale, 1.0 ); - glUniform1fARB( u_specular_exponent, 32.0 ); + gl().glUniform3f( u_view_origin, localViewer.x(), localViewer.y(), localViewer.z() ); + gl().glUniform3f( u_light_origin, localLight.x(), localLight.y(), localLight.z() ); + gl().glUniform3f( u_light_color, colour.x(), colour.y(), colour.z() ); + gl().glUniform1f( u_bump_scale, 1.0 ); + gl().glUniform1f( u_specular_exponent, 32.0 ); - glActiveTexture( GL_TEXTURE3 ); - glClientActiveTexture( GL_TEXTURE3 ); + gl().glActiveTexture( GL_TEXTURE3 ); + gl().glClientActiveTexture( GL_TEXTURE3 ); - glMatrixMode( GL_TEXTURE ); - glLoadMatrixf( reinterpret_cast( &local2light ) ); - glMatrixMode( GL_MODELVIEW ); + gl().glMatrixMode( GL_TEXTURE ); + gl().glLoadMatrixf( reinterpret_cast( &local2light ) ); + gl().glMatrixMode( GL_MODELVIEW ); GlobalOpenGL_debugAssertNoErrors(); } @@ -323,17 +332,17 @@ GLSLBumpProgram g_bumpGLSL; class GLSLDepthFillProgram : public GLProgram { public: - GLhandleARB m_program; + GLuint m_program; void create(){ // create program - m_program = glCreateProgramObjectARB(); + m_program = gl().glCreateProgram(); // create shader { StringOutputStream filename( 256 ); - createShader( m_program, filename( GlobalRadiant().getAppPath(), "gl/zfill_vp.glsl" ), GL_VERTEX_SHADER_ARB ); - createShader( m_program, filename( GlobalRadiant().getAppPath(), "gl/zfill_fp.glsl" ), GL_FRAGMENT_SHADER_ARB ); + createShader( m_program, filename( GlobalRadiant().getAppPath(), "gl/zfill_vp.glsl" ), GL_VERTEX_SHADER ); + createShader( m_program, filename( GlobalRadiant().getAppPath(), "gl/zfill_fp.glsl" ), GL_FRAGMENT_SHADER ); } GLSLProgram_link( m_program ); @@ -343,17 +352,17 @@ public: } void destroy(){ - glDeleteObjectARB( m_program ); + gl().glDeleteProgram( m_program ); m_program = 0; } void enable(){ - glUseProgramObjectARB( m_program ); + gl().glUseProgram( m_program ); GlobalOpenGL_debugAssertNoErrors(); debug_string( "enable depthfill" ); g_depthfillPass_enabled = true; } void disable(){ - glUseProgramObjectARB( 0 ); + gl().glUseProgram( 0 ); GlobalOpenGL_debugAssertNoErrors(); debug_string( "disable depthfill" ); g_depthfillPass_enabled = false; @@ -368,7 +377,7 @@ GLSLDepthFillProgram g_depthFillGLSL; class GLSLSkyboxProgram : public GLProgram { public: - GLhandleARB m_program; + GLuint m_program; GLint u_view_origin; GLSLSkyboxProgram() : m_program( 0 ){ @@ -376,34 +385,34 @@ public: void create(){ // create program - m_program = glCreateProgramObjectARB(); + m_program = gl().glCreateProgram(); // create shader { StringOutputStream filename( 256 ); - createShader( m_program, filename( GlobalRadiant().getAppPath(), "gl/skybox_vp.glsl" ), GL_VERTEX_SHADER_ARB ); - createShader( m_program, filename( GlobalRadiant().getAppPath(), "gl/skybox_fp.glsl" ), GL_FRAGMENT_SHADER_ARB ); + createShader( m_program, filename( GlobalRadiant().getAppPath(), "gl/skybox_vp.glsl" ), GL_VERTEX_SHADER ); + createShader( m_program, filename( GlobalRadiant().getAppPath(), "gl/skybox_fp.glsl" ), GL_FRAGMENT_SHADER ); } GLSLProgram_link( m_program ); GLSLProgram_validate( m_program ); - glUseProgramObjectARB( m_program ); + gl().glUseProgram( m_program ); - u_view_origin = glGetUniformLocationARB( m_program, "u_view_origin" ); + u_view_origin = gl().glGetUniformLocation( m_program, "u_view_origin" ); - glUseProgramObjectARB( 0 ); + gl().glUseProgram( 0 ); GlobalOpenGL_debugAssertNoErrors(); } void destroy(){ - glDeleteObjectARB( m_program ); + gl().glDeleteProgram( m_program ); m_program = 0; } void enable(){ - glUseProgramObjectARB( m_program ); + gl().glUseProgram( m_program ); GlobalOpenGL_debugAssertNoErrors(); @@ -411,7 +420,7 @@ public: } void disable(){ - glUseProgramObjectARB( 0 ); + gl().glUseProgram( 0 ); GlobalOpenGL_debugAssertNoErrors(); @@ -419,7 +428,7 @@ public: } void setParameters( const Vector3& viewer, const Matrix4& localToWorld, const Vector3& origin, const Vector3& colour, const Matrix4& world2light ){ - glUniform3fARB( u_view_origin, viewer.x(), viewer.y(), viewer.z() ); + gl().glUniform3f( u_view_origin, viewer.x(), viewer.y(), viewer.z() ); GlobalOpenGL_debugAssertNoErrors(); } @@ -428,395 +437,6 @@ public: GLSLSkyboxProgram g_skyboxGLSL; -// ARB path - -void createProgram( const char* filename, GLenum type ){ - std::size_t size = file_size( filename ); - FileInputStream file( filename ); - ASSERT_MESSAGE( !file.failed(), "failed to open " << makeQuoted( filename ) ); - Array buffer( size ); - size = file.read( reinterpret_cast( buffer.data() ), size ); - - glProgramStringARB( type, GL_PROGRAM_FORMAT_ASCII_ARB, GLsizei( size ), buffer.data() ); - - if ( GL_INVALID_OPERATION == glGetError() ) { - GLint errPos; - glGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &errPos ); - const GLubyte* errString = glGetString( GL_PROGRAM_ERROR_STRING_ARB ); - - globalErrorStream() << reinterpret_cast( filename ) << ":" << errPos << "\n" << reinterpret_cast( errString ); - - ERROR_MESSAGE( "error in gl program" ); - } -} - -class ARBBumpProgram : public GLProgram -{ -public: - GLuint m_vertex_program; - GLuint m_fragment_program; - - void create(){ - glEnable( GL_VERTEX_PROGRAM_ARB ); - glEnable( GL_FRAGMENT_PROGRAM_ARB ); - - { - glGenProgramsARB( 1, &m_vertex_program ); - glBindProgramARB( GL_VERTEX_PROGRAM_ARB, m_vertex_program ); - StringOutputStream filename( 256 ); - createProgram( filename( GlobalRadiant().getAppPath(), "gl/lighting_DBS_omni_vp.glp" ), GL_VERTEX_PROGRAM_ARB ); - - glGenProgramsARB( 1, &m_fragment_program ); - glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, m_fragment_program ); - createProgram( filename( GlobalRadiant().getAppPath(), "gl/lighting_DBS_omni_fp.glp" ), GL_FRAGMENT_PROGRAM_ARB ); - } - - glDisable( GL_VERTEX_PROGRAM_ARB ); - glDisable( GL_FRAGMENT_PROGRAM_ARB ); - - GlobalOpenGL_debugAssertNoErrors(); - } - - void destroy(){ - glDeleteProgramsARB( 1, &m_vertex_program ); - glDeleteProgramsARB( 1, &m_fragment_program ); - GlobalOpenGL_debugAssertNoErrors(); - } - - void enable(){ - glEnable( GL_VERTEX_PROGRAM_ARB ); - glEnable( GL_FRAGMENT_PROGRAM_ARB ); - glBindProgramARB( GL_VERTEX_PROGRAM_ARB, m_vertex_program ); - glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, m_fragment_program ); - - glEnableVertexAttribArrayARB( 8 ); - glEnableVertexAttribArrayARB( 9 ); - glEnableVertexAttribArrayARB( 10 ); - glEnableVertexAttribArrayARB( 11 ); - - GlobalOpenGL_debugAssertNoErrors(); - } - - void disable(){ - glDisable( GL_VERTEX_PROGRAM_ARB ); - glDisable( GL_FRAGMENT_PROGRAM_ARB ); - - glDisableVertexAttribArrayARB( 8 ); - glDisableVertexAttribArrayARB( 9 ); - glDisableVertexAttribArrayARB( 10 ); - glDisableVertexAttribArrayARB( 11 ); - - GlobalOpenGL_debugAssertNoErrors(); - } - - void setParameters( const Vector3& viewer, const Matrix4& localToWorld, const Vector3& origin, const Vector3& colour, const Matrix4& world2light ){ - Matrix4 world2local( localToWorld ); - matrix4_affine_invert( world2local ); - - Vector3 localLight( origin ); - matrix4_transform_point( world2local, localLight ); - - Vector3 localViewer( viewer ); - matrix4_transform_point( world2local, localViewer ); - - Matrix4 local2light( world2light ); - matrix4_multiply_by_matrix4( local2light, localToWorld ); // local->world->light - - // view origin - glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 4, localViewer.x(), localViewer.y(), localViewer.z(), 0 ); - - // light origin - glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 2, localLight.x(), localLight.y(), localLight.z(), 1 ); - - // light colour - glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 3, colour.x(), colour.y(), colour.z(), 0 ); - - // bump scale - glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 1, 1, 0, 0, 0 ); - - // specular exponent - glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 5, 32, 0, 0, 0 ); - - - glActiveTexture( GL_TEXTURE3 ); - glClientActiveTexture( GL_TEXTURE3 ); - - glMatrixMode( GL_TEXTURE ); - glLoadMatrixf( reinterpret_cast( &local2light ) ); - glMatrixMode( GL_MODELVIEW ); - - GlobalOpenGL_debugAssertNoErrors(); - } -}; - -class ARBDepthFillProgram : public GLProgram -{ -public: - GLuint m_vertex_program; - GLuint m_fragment_program; - - void create(){ - glEnable( GL_VERTEX_PROGRAM_ARB ); - glEnable( GL_FRAGMENT_PROGRAM_ARB ); - - { - glGenProgramsARB( 1, &m_vertex_program ); - glBindProgramARB( GL_VERTEX_PROGRAM_ARB, m_vertex_program ); - StringOutputStream filename( 256 ); - createProgram( filename( GlobalRadiant().getAppPath(), "gl/zfill_vp.glp" ), GL_VERTEX_PROGRAM_ARB ); - - glGenProgramsARB( 1, &m_fragment_program ); - glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, m_fragment_program ); - createProgram( filename( GlobalRadiant().getAppPath(), "gl/zfill_fp.glp" ), GL_FRAGMENT_PROGRAM_ARB ); - } - - glDisable( GL_VERTEX_PROGRAM_ARB ); - glDisable( GL_FRAGMENT_PROGRAM_ARB ); - - GlobalOpenGL_debugAssertNoErrors(); - } - - void destroy(){ - glDeleteProgramsARB( 1, &m_vertex_program ); - glDeleteProgramsARB( 1, &m_fragment_program ); - GlobalOpenGL_debugAssertNoErrors(); - } - - void enable(){ - glEnable( GL_VERTEX_PROGRAM_ARB ); - glEnable( GL_FRAGMENT_PROGRAM_ARB ); - glBindProgramARB( GL_VERTEX_PROGRAM_ARB, m_vertex_program ); - glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, m_fragment_program ); - - GlobalOpenGL_debugAssertNoErrors(); - } - - void disable(){ - glDisable( GL_VERTEX_PROGRAM_ARB ); - glDisable( GL_FRAGMENT_PROGRAM_ARB ); - - GlobalOpenGL_debugAssertNoErrors(); - } - - void setParameters( const Vector3& viewer, const Matrix4& localToWorld, const Vector3& origin, const Vector3& colour, const Matrix4& world2light ){ - } -}; - -ARBBumpProgram g_bumpARB; -ARBDepthFillProgram g_depthFillARB; - - -#if 0 -// NV20 path (unfinished) - -void createProgram( GLint program, const char* filename, GLenum type ){ - std::size_t size = file_size( filename ); - FileInputStream file( filename ); - ASSERT_MESSAGE( !file.failed(), "failed to open " << makeQuoted( filename ) ); - Array buffer( size ); - size = file.read( reinterpret_cast( buffer.data() ), size ); - - glLoadProgramNV( type, program, GLsizei( size ), buffer.data() ); - - if ( GL_INVALID_OPERATION == glGetError() ) { - GLint errPos; - glGetIntegerv( GL_PROGRAM_ERROR_POSITION_NV, &errPos ); - const GLubyte* errString = glGetString( GL_PROGRAM_ERROR_STRING_NV ); - - globalErrorStream() << filename << ":" << errPos << "\n" << errString; - - ERROR_MESSAGE( "error in gl program" ); - } -} - -GLuint m_vertex_program; -GLuint m_fragment_program; -qtexture_t* g_cube = 0; -qtexture_t* g_specular_lookup = 0; -qtexture_t* g_attenuation_xy = 0; -qtexture_t* g_attenuation_z = 0; - -void createVertexProgram(){ - { - glGenProgramsNV( 1, &m_vertex_program ); - glBindProgramNV( GL_VERTEX_PROGRAM_NV, m_vertex_program ); - StringOutputStream filename( 256 ); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_vp.nv30"; - createProgram( m_vertex_program, filename.c_str(), GL_VERTEX_PROGRAM_NV ); - - glGenProgramsNV( 1, &m_fragment_program ); - glBindProgramNV( GL_FRAGMENT_PROGRAM_NV, m_fragment_program ); - filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_fp.nv30"; - createProgram( m_fragment_program, filename.c_str(), GL_FRAGMENT_PROGRAM_NV ); - } - - g_cube = GlobalTexturesCache().capture( "generated/cube" ); - g_specular_lookup = GlobalTexturesCache().capture( "generated/specular" ); - - g_attenuation_xy = GlobalTexturesCache().capture( "lights/squarelight1" ); - glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, g_attenuation_xy->texture_number ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER ); - - g_attenuation_z = GlobalTexturesCache().capture( "lights/squarelight1a" ); - glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, g_attenuation_z->texture_number ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - - GlobalOpenGL_debugAssertNoErrors(); -} - -void destroyVertexProgram(){ - glDeleteProgramsNV( 1, &m_vertex_program ); - glDeleteProgramsNV( 1, &m_fragment_program ); - GlobalOpenGL_debugAssertNoErrors(); - - GlobalTexturesCache().release( g_cube ); - GlobalTexturesCache().release( g_specular_lookup ); - GlobalTexturesCache().release( g_attenuation_xy ); - GlobalTexturesCache().release( g_attenuation_z ); -} - -bool g_vertexProgram_enabled = false; - -void enableVertexProgram(){ - //set up the register combiners - //two general combiners - glCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 2 ); - - //combiner 0 does tex0+tex1 -> spare0 - glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, - GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, - GL_UNSIGNED_INVERT_NV, GL_RGB ); - glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_NV, GL_TEXTURE1_ARB, - GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, - GL_UNSIGNED_INVERT_NV, GL_RGB ); - glCombinerOutputNV( GL_COMBINER0_NV, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE0_NV, - GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); - - //combiner 1 does tex2 dot tex3 -> spare1 - glCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE2_ARB, - GL_EXPAND_NORMAL_NV, GL_RGB ); - glCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV, GL_TEXTURE3_ARB, - GL_EXPAND_NORMAL_NV, GL_RGB ); - glCombinerOutputNV( GL_COMBINER1_NV, GL_RGB, GL_SPARE1_NV, GL_DISCARD_NV, GL_DISCARD_NV, - GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE ); - - - - //final combiner outputs (1-spare0)*constant color 0*spare1 - //do constant color 0*spare1 in the EF multiplier - glFinalCombinerInputNV( GL_VARIABLE_E_NV, GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glFinalCombinerInputNV( GL_VARIABLE_F_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - - //now do (1-spare0)*EF - glFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_E_TIMES_F_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - glFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB ); - - glEnable( GL_VERTEX_PROGRAM_NV ); - glEnable( GL_REGISTER_COMBINERS_NV ); - glBindProgramNV( GL_VERTEX_PROGRAM_NV, m_vertex_program ); - glBindProgramNV( GL_FRAGMENT_PROGRAM_NV, m_fragment_program ); - - glActiveTexture( GL_TEXTURE0 ); - glEnable( GL_TEXTURE_2D ); - glActiveTexture( GL_TEXTURE1 ); - glEnable( GL_TEXTURE_1D ); - glActiveTexture( GL_TEXTURE2 ); - glEnable( GL_TEXTURE_2D ); - glActiveTexture( GL_TEXTURE3 ); - glEnable( GL_TEXTURE_2D ); - - glEnableClientState( GL_VERTEX_ATTRIB_ARRAY8_NV ); - glEnableClientState( GL_VERTEX_ATTRIB_ARRAY9_NV ); - glEnableClientState( GL_VERTEX_ATTRIB_ARRAY10_NV ); - glEnableClientState( GL_VERTEX_ATTRIB_ARRAY11_NV ); - - GlobalOpenGL_debugAssertNoErrors(); - g_vertexProgram_enabled = true; -} - -void disableVertexProgram(){ - glDisable( GL_VERTEX_PROGRAM_NV ); - glDisable( GL_REGISTER_COMBINERS_NV ); - - glActiveTexture( GL_TEXTURE0 ); - glDisable( GL_TEXTURE_2D ); - glActiveTexture( GL_TEXTURE1 ); - glDisable( GL_TEXTURE_1D ); - glActiveTexture( GL_TEXTURE2 ); - glDisable( GL_TEXTURE_2D ); - glActiveTexture( GL_TEXTURE3 ); - glDisable( GL_TEXTURE_2D ); - - glDisableClientState( GL_VERTEX_ATTRIB_ARRAY8_NV ); - glDisableClientState( GL_VERTEX_ATTRIB_ARRAY9_NV ); - glDisableClientState( GL_VERTEX_ATTRIB_ARRAY10_NV ); - glDisableClientState( GL_VERTEX_ATTRIB_ARRAY11_NV ); - - GlobalOpenGL_debugAssertNoErrors(); - g_vertexProgram_enabled = false; -} - -class GLstringNV -{ -public: - const GLubyte* m_string; - const GLint m_length; - GLstringNV( const char* string ) : m_string( reinterpret_cast( string ) ), m_length( GLint( string_length( string ) ) ){ - } -}; - -GLstringNV g_light_origin( "light_origin" ); -GLstringNV g_view_origin( "view_origin" ); -GLstringNV g_light_color( "light_color" ); -GLstringNV g_bumpGLSL_scale( "bump_scale" ); -GLstringNV g_specular_exponent( "specular_exponent" ); - -void setVertexProgramEnvironment( const Vector3& localViewer ){ - Matrix4 local2light( g_matrix4_identity ); - matrix4_translate_by_vec3( local2light, Vector3( 0.5, 0.5, 0.5 ) ); - matrix4_scale_by_vec3( local2light, Vector3( 0.5, 0.5, 0.5 ) ); - matrix4_scale_by_vec3( local2light, Vector3( 1.0 / 512.0, 1.0 / 512.0, 1.0 / 512.0 ) ); - matrix4_translate_by_vec3( local2light, vector3_negated( localViewer ) ); - - glActiveTexture( GL_TEXTURE3 ); - glClientActiveTexture( GL_TEXTURE3 ); - - glMatrixMode( GL_TEXTURE ); - glLoadMatrixf( reinterpret_cast( &local2light ) ); - glMatrixMode( GL_MODELVIEW ); - - glTrackMatrixNV( GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV ); - glTrackMatrixNV( GL_VERTEX_PROGRAM_NV, 4, GL_TEXTURE0_ARB, GL_IDENTITY_NV ); - - // view origin - //qglProgramNamedParameter4fNV(m_fragment_program, g_view_origin.m_length, g_view_origin.m_string, localViewer.x(), localViewer.y(), localViewer.z(), 0); - - // light origin - glProgramParameter4fNV( GL_VERTEX_PROGRAM_NV, 8, localViewer.x(), localViewer.y(), localViewer.z(), 1.0f ); - - // light colour - glCombinerParameterfNV( GL_CONSTANT_COLOR0_NV, 1, 1, 1, 1 ) - - // bump scale - //qglProgramNamedParameter4fNV(m_fragment_program, g_bumpGLSL_scale.m_length, g_bumpGLSL_scale.m_string, 1, 0, 0, 0); - - // specular exponent - //qglProgramNamedParameter4fNV(m_fragment_program, g_specular_exponent.m_length, g_specular_exponent.m_string, 32, 0, 0, 0); - - GlobalOpenGL_debugAssertNoErrors(); -} - -#endif - bool g_vertexArray_enabled = false; bool g_normalArray_enabled = false; @@ -1184,12 +804,12 @@ public: }; inline void setFogState( const OpenGLFogState& state ){ - glFogi( GL_FOG_MODE, state.mode ); - glFogf( GL_FOG_DENSITY, state.density ); - glFogf( GL_FOG_START, state.start ); - glFogf( GL_FOG_END, state.end ); - glFogi( GL_FOG_INDEX, state.index ); - glFogfv( GL_FOG_COLOR, vector4_to_array( state.colour ) ); + gl().glFogi( GL_FOG_MODE, state.mode ); + gl().glFogf( GL_FOG_DENSITY, state.density ); + gl().glFogf( GL_FOG_START, state.start ); + gl().glFogf( GL_FOG_END, state.end ); + gl().glFogi( GL_FOG_INDEX, state.index ); + gl().glFogfv( GL_FOG_COLOR, vector4_to_array( state.colour ) ); } #define DEBUG_SHADERS 0 @@ -1224,16 +844,12 @@ class OpenGLShaderCache final : public ShaderCache, public TexturesCacheObserver std::size_t m_unrealised; bool m_lightingEnabled; - bool m_lightingSupported; - const bool m_useShaderLanguage; public: OpenGLShaderCache() : m_shaders( CreateOpenGLShader( this ) ), m_unrealised( 3 ), // wait until shaders, gl-context and textures are realised before creating any render-states m_lightingEnabled( true ), - m_lightingSupported( false ), - m_useShaderLanguage( false ), m_lightsChanged( true ), m_traverseRenderablesMutex( false ){ } @@ -1262,14 +878,14 @@ public: m_shaders.release( name ); } void render( RenderStateFlags globalstate, const Matrix4& modelview, const Matrix4& projection, const Vector3& viewer ){ - glMatrixMode( GL_PROJECTION ); - glLoadMatrixf( reinterpret_cast( &projection ) ); + gl().glMatrixMode( GL_PROJECTION ); + gl().glLoadMatrixf( reinterpret_cast( &projection ) ); #if 0 //qglGetFloatv(GL_PROJECTION_MATRIX, reinterpret_cast(&projection)); #endif - glMatrixMode( GL_MODELVIEW ); - glLoadMatrixf( reinterpret_cast( &modelview ) ); + gl().glMatrixMode( GL_MODELVIEW ); + gl().glLoadMatrixf( reinterpret_cast( &modelview ) ); #if 0 //qglGetFloatv(GL_MODELVIEW_MATRIX, reinterpret_cast(&modelview)); #endif @@ -1277,9 +893,9 @@ public: ASSERT_MESSAGE( realised(), "render states are not realised" ); // global settings that are not set in renderstates - glFrontFace( GL_CW ); - glCullFace( GL_BACK ); - glPolygonOffset( -1, 1 ); + gl().glFrontFace( GL_CW ); + gl().glCullFace( GL_BACK ); + gl().glPolygonOffset( -1, 1 ); { const GLubyte pattern[132] = { 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, @@ -1299,27 +915,23 @@ public: 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55 }; - glPolygonStipple( pattern ); + gl().glPolygonStipple( pattern ); } - glEnableClientState( GL_VERTEX_ARRAY ); + gl().glEnableClientState( GL_VERTEX_ARRAY ); g_vertexArray_enabled = true; - glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); + gl().glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); - if ( GlobalOpenGL().GL_1_3() ) { - glActiveTexture( GL_TEXTURE0 ); - glClientActiveTexture( GL_TEXTURE0 ); - } + gl().glActiveTexture( GL_TEXTURE0 ); + gl().glClientActiveTexture( GL_TEXTURE0 ); - if ( GlobalOpenGL().ARB_shader_objects() ) { - glUseProgramObjectARB( 0 ); - glDisableVertexAttribArrayARB( c_attr_TexCoord0 ); - glDisableVertexAttribArrayARB( c_attr_Tangent ); - glDisableVertexAttribArrayARB( c_attr_Binormal ); - } + gl().glUseProgram( 0 ); + gl().glDisableVertexAttribArray( c_attr_TexCoord0 ); + gl().glDisableVertexAttribArray( c_attr_Tangent ); + gl().glDisableVertexAttribArray( c_attr_Binormal ); if ( globalstate & RENDER_TEXTURE ) { - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + gl().glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + gl().glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); } OpenGLState current; @@ -1327,37 +939,37 @@ public: current.m_sort = OpenGLState::eSortFirst; // default renderstate settings - glLineStipple( current.m_linestipple_factor, current.m_linestipple_pattern ); - glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - glDisable( GL_LIGHTING ); - glDisable( GL_TEXTURE_2D ); - glDisableClientState( GL_TEXTURE_COORD_ARRAY ); + gl().glLineStipple( current.m_linestipple_factor, current.m_linestipple_pattern ); + gl().glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + gl().glDisable( GL_LIGHTING ); + gl().glDisable( GL_TEXTURE_2D ); + gl().glDisableClientState( GL_TEXTURE_COORD_ARRAY ); g_texcoordArray_enabled = false; - glDisableClientState( GL_COLOR_ARRAY ); + gl().glDisableClientState( GL_COLOR_ARRAY ); g_colorArray_enabled = false; - glDisableClientState( GL_NORMAL_ARRAY ); + gl().glDisableClientState( GL_NORMAL_ARRAY ); g_normalArray_enabled = false; - glDisable( GL_BLEND ); - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - glDisable( GL_CULL_FACE ); - glShadeModel( GL_FLAT ); - glDisable( GL_DEPTH_TEST ); - glDepthMask( GL_FALSE ); - glDisable( GL_ALPHA_TEST ); - glDisable( GL_LINE_STIPPLE ); - glDisable( GL_POLYGON_STIPPLE ); - glDisable( GL_POLYGON_OFFSET_LINE ); + gl().glDisable( GL_BLEND ); + gl().glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + gl().glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + gl().glDisable( GL_CULL_FACE ); + gl().glShadeModel( GL_FLAT ); + gl().glDisable( GL_DEPTH_TEST ); + gl().glDepthMask( GL_FALSE ); + gl().glDisable( GL_ALPHA_TEST ); + gl().glDisable( GL_LINE_STIPPLE ); + gl().glDisable( GL_POLYGON_STIPPLE ); + gl().glDisable( GL_POLYGON_OFFSET_LINE ); - glBindTexture( GL_TEXTURE_2D, 0 ); - glColor4f( 1,1,1,1 ); - glDepthFunc( GL_LESS ); - glAlphaFunc( GL_ALWAYS, 0 ); - glLineWidth( 1 ); - glPointSize( 1 ); + gl().glBindTexture( GL_TEXTURE_2D, 0 ); + gl().glColor4f( 1,1,1,1 ); + gl().glDepthFunc( GL_LESS ); + gl().glAlphaFunc( GL_ALWAYS, 0 ); + gl().glLineWidth( 1 ); + gl().glPointSize( 1 ); - glHint( GL_FOG_HINT, GL_NICEST ); - glDisable( GL_FOG ); + gl().glHint( GL_FOG_HINT, GL_NICEST ); + gl().glDisable( GL_FOG ); setFogState( OpenGLFogState() ); GlobalOpenGL_debugAssertNoErrors(); @@ -1376,20 +988,12 @@ public: } void realise(){ if ( --m_unrealised == 0 ) { - if ( lightingSupported() && lightingEnabled() ) { - if ( useShaderLanguage() ) { - g_bumpGLSL.create(); - g_depthFillGLSL.create(); - } - else - { - g_bumpARB.create(); - g_depthFillARB.create(); - } + if ( lightingEnabled() ) { + g_bumpGLSL.create(); + g_depthFillGLSL.create(); } - if( lightingSupported() ) - g_skyboxGLSL.create(); + g_skyboxGLSL.create(); for ( Shaders::iterator i = m_shaders.begin(); i != m_shaders.end(); ++i ) { @@ -1407,18 +1011,11 @@ public: ( *i ).value->unrealise(); } } - if ( GlobalOpenGL().contextValid && lightingSupported() && lightingEnabled() ) { - if ( useShaderLanguage() ) { - g_bumpGLSL.destroy(); - g_depthFillGLSL.destroy(); - } - else - { - g_bumpARB.destroy(); - g_depthFillARB.destroy(); - } + if ( GlobalOpenGL().contextValid && lightingEnabled() ) { + g_bumpGLSL.destroy(); + g_depthFillGLSL.destroy(); } - if( GlobalOpenGL().contextValid && lightingSupported() ) + if( GlobalOpenGL().contextValid ) g_skyboxGLSL.destroy(); } } @@ -1430,66 +1027,23 @@ public: bool lightingEnabled() const { return m_lightingEnabled; } - bool lightingSupported() const { - return m_lightingSupported; + void extensionsInitialised(){ + setLightingEnabled( m_lightingEnabled ); } - bool useShaderLanguage() const { - return m_useShaderLanguage; - } - void setLighting( bool supported, bool enabled ){ - bool refresh = ( m_lightingSupported && m_lightingEnabled ) != ( supported && enabled ); + void setLightingEnabled( bool enabled ){ + const bool refresh = ( m_lightingEnabled != enabled ); if ( refresh ) { unrealise(); - GlobalShaderSystem().setLightingEnabled( supported && enabled ); + GlobalShaderSystem().setLightingEnabled( enabled ); } - m_lightingSupported = supported; m_lightingEnabled = enabled; if ( refresh ) { realise(); } } - void extensionsInitialised(){ - setLighting( GlobalOpenGL().GL_1_3() - && GlobalOpenGL().ARB_vertex_program() - && GlobalOpenGL().ARB_fragment_program() - && GlobalOpenGL().ARB_shader_objects() - && GlobalOpenGL().ARB_vertex_shader() - && GlobalOpenGL().ARB_fragment_shader() - && GlobalOpenGL().ARB_shading_language_100(), - m_lightingEnabled - ); - - if ( !lightingSupported() ) { - globalWarningStream() << "Lighting mode requires OpenGL features not supported by your graphics drivers:\n"; - if ( !GlobalOpenGL().GL_1_3() ) { - globalOutputStream() << " GL version 1.3 or better\n"; - } - if ( !GlobalOpenGL().ARB_vertex_program() ) { - globalOutputStream() << " GL_ARB_vertex_program\n"; - } - if ( !GlobalOpenGL().ARB_fragment_program() ) { - globalOutputStream() << " GL_ARB_fragment_program\n"; - } - if ( !GlobalOpenGL().ARB_shader_objects() ) { - globalOutputStream() << " GL_ARB_shader_objects\n"; - } - if ( !GlobalOpenGL().ARB_vertex_shader() ) { - globalOutputStream() << " GL_ARB_vertex_shader\n"; - } - if ( !GlobalOpenGL().ARB_fragment_shader() ) { - globalOutputStream() << " GL_ARB_fragment_shader\n"; - } - if ( !GlobalOpenGL().ARB_shading_language_100() ) { - globalOutputStream() << " GL_ARB_shading_language_100\n"; - } - } - } - void setLightingEnabled( bool enabled ){ - setLighting( m_lightingSupported, enabled ); - } // light culling @@ -1642,9 +1196,9 @@ ShaderCache* GetShaderCache(){ inline void setTextureState( GLint& current, const GLint& texture, GLenum textureUnit ){ if ( texture != current ) { - glActiveTexture( textureUnit ); - glClientActiveTexture( textureUnit ); - glBindTexture( GL_TEXTURE_2D, texture ); + gl().glActiveTexture( textureUnit ); + gl().glClientActiveTexture( textureUnit ); + gl().glBindTexture( GL_TEXTURE_2D, texture ); GlobalOpenGL_debugAssertNoErrors(); current = texture; } @@ -1652,7 +1206,7 @@ inline void setTextureState( GLint& current, const GLint& texture, GLenum textur inline void setTextureState( GLint& current, const GLint& texture ){ if ( texture != current ) { - glBindTexture( GL_TEXTURE_2D, texture ); + gl().glBindTexture( GL_TEXTURE_2D, texture ); GlobalOpenGL_debugAssertNoErrors(); current = texture; } @@ -1660,11 +1214,11 @@ inline void setTextureState( GLint& current, const GLint& texture ){ inline void setState( unsigned int state, unsigned int delta, unsigned int flag, GLenum glflag ){ if ( delta & state & flag ) { - glEnable( glflag ); + gl().glEnable( glflag ); GlobalOpenGL_debugAssertNoErrors(); } else if ( delta & ~state & flag ) { - glDisable( glflag ); + gl().glDisable( glflag ); GlobalOpenGL_debugAssertNoErrors(); } } @@ -1690,25 +1244,25 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned GlobalOpenGL_debugAssertNoErrors(); if ( delta & state & RENDER_TEXT ) { - glMatrixMode( GL_PROJECTION ); - glPushMatrix(); - glLoadIdentity(); + gl().glMatrixMode( GL_PROJECTION ); + gl().glPushMatrix(); + gl().glLoadIdentity(); GLint viewprt[4]; - glGetIntegerv( GL_VIEWPORT, viewprt ); + gl().glGetIntegerv( GL_VIEWPORT, viewprt ); //globalOutputStream() << viewprt[2] << " " << viewprt[3] << "\n"; - glOrtho( 0, viewprt[2], 0, viewprt[3], -100, 100 ); - glTranslated( double( viewprt[2] ) / 2.0, double( viewprt[3] ) / 2.0, 0 ); - glMatrixMode( GL_MODELVIEW ); - glPushMatrix(); - glLoadIdentity(); + gl().glOrtho( 0, viewprt[2], 0, viewprt[3], -100, 100 ); + gl().glTranslated( double( viewprt[2] ) / 2.0, double( viewprt[3] ) / 2.0, 0 ); + gl().glMatrixMode( GL_MODELVIEW ); + gl().glPushMatrix(); + gl().glLoadIdentity(); GlobalOpenGL_debugAssertNoErrors(); } else if ( delta & ~state & RENDER_TEXT ) { - glMatrixMode( GL_PROJECTION ); - glPopMatrix(); - glMatrixMode( GL_MODELVIEW ); - glPopMatrix(); + gl().glMatrixMode( GL_PROJECTION ); + gl().glPopMatrix(); + gl().glMatrixMode( GL_MODELVIEW ); + gl().glPopMatrix(); GlobalOpenGL_debugAssertNoErrors(); } @@ -1718,7 +1272,7 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned if ( program != current.m_program ) { if ( current.m_program != 0 ) { current.m_program->disable(); -//why? glColor4fv( vector4_to_array( current.m_colour ) ); +//why? gl().glColor4fv( vector4_to_array( current.m_colour ) ); debug_colour( "cleaning program" ); } @@ -1732,29 +1286,29 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned if ( delta & state & RENDER_FILL ) { //qglPolygonMode (GL_BACK, GL_LINE); //qglPolygonMode (GL_FRONT, GL_FILL); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + gl().glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); GlobalOpenGL_debugAssertNoErrors(); } else if ( delta & ~state & RENDER_FILL ) { - glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + gl().glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); GlobalOpenGL_debugAssertNoErrors(); } setState( state, delta, RENDER_OFFSETLINE, GL_POLYGON_OFFSET_LINE ); if ( delta & state & RENDER_LIGHTING ) { - glEnable( GL_LIGHTING ); - glEnable( GL_COLOR_MATERIAL ); - glEnable( GL_RESCALE_NORMAL ); - glEnableClientState( GL_NORMAL_ARRAY ); + gl().glEnable( GL_LIGHTING ); + gl().glEnable( GL_COLOR_MATERIAL ); + gl().glEnable( GL_RESCALE_NORMAL ); + gl().glEnableClientState( GL_NORMAL_ARRAY ); GlobalOpenGL_debugAssertNoErrors(); g_normalArray_enabled = true; } else if ( delta & ~state & RENDER_LIGHTING ) { - glDisable( GL_LIGHTING ); - glDisable( GL_COLOR_MATERIAL ); - glDisable( GL_RESCALE_NORMAL ); - glDisableClientState( GL_NORMAL_ARRAY ); + gl().glDisable( GL_LIGHTING ); + gl().glDisable( GL_COLOR_MATERIAL ); + gl().glDisable( GL_RESCALE_NORMAL ); + gl().glDisableClientState( GL_NORMAL_ARRAY ); GlobalOpenGL_debugAssertNoErrors(); g_normalArray_enabled = false; } @@ -1762,29 +1316,25 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned if ( delta & state & RENDER_TEXTURE ) { GlobalOpenGL_debugAssertNoErrors(); - if ( GlobalOpenGL().GL_1_3() ) { - glActiveTexture( GL_TEXTURE0 ); - glClientActiveTexture( GL_TEXTURE0 ); - } + gl().glActiveTexture( GL_TEXTURE0 ); + gl().glClientActiveTexture( GL_TEXTURE0 ); - glEnable( GL_TEXTURE_2D ); + gl().glEnable( GL_TEXTURE_2D ); - glColor4f( 1,1,1,self.m_colour[3] ); + gl().glColor4f( 1,1,1,self.m_colour[3] ); debug_colour( "setting texture" ); - glEnableClientState( GL_TEXTURE_COORD_ARRAY ); + gl().glEnableClientState( GL_TEXTURE_COORD_ARRAY ); GlobalOpenGL_debugAssertNoErrors(); g_texcoordArray_enabled = true; } else if ( delta & ~state & RENDER_TEXTURE ) { - if ( GlobalOpenGL().GL_1_3() ) { - glActiveTexture( GL_TEXTURE0 ); - glClientActiveTexture( GL_TEXTURE0 ); - } + gl().glActiveTexture( GL_TEXTURE0 ); + gl().glClientActiveTexture( GL_TEXTURE0 ); - glDisable( GL_TEXTURE_2D ); - glBindTexture( GL_TEXTURE_2D, 0 ); - glDisableClientState( GL_TEXTURE_COORD_ARRAY ); + gl().glDisable( GL_TEXTURE_2D ); + gl().glBindTexture( GL_TEXTURE_2D, 0 ); + gl().glDisableClientState( GL_TEXTURE_COORD_ARRAY ); GlobalOpenGL_debugAssertNoErrors(); g_texcoordArray_enabled = false; @@ -1797,31 +1347,27 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned // if an empty-alpha-channel or nearly-empty texture is used. It will be blank-transparent. // this could get better if you can get glTexEnviv (GL_TEXTURE_ENV, to work .. patches are welcome - glEnable( GL_BLEND ); - if ( GlobalOpenGL().GL_1_3() ) { - glActiveTexture( GL_TEXTURE0 ); - } -// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL ); -// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); //uses actual alpha channel, = invis, if qer_trans + empty alpha channel + gl().glEnable( GL_BLEND ); + gl().glActiveTexture( GL_TEXTURE0 ); +// gl().glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL ); +// gl().glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); //uses actual alpha channel, = invis, if qer_trans + empty alpha channel GlobalOpenGL_debugAssertNoErrors(); } else if ( delta & ~state & RENDER_BLEND ) { - glDisable( GL_BLEND ); - if ( GlobalOpenGL().GL_1_3() ) { - glActiveTexture( GL_TEXTURE0 ); - } -// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + gl().glDisable( GL_BLEND ); + gl().glActiveTexture( GL_TEXTURE0 ); +// gl().glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); GlobalOpenGL_debugAssertNoErrors(); } setState( state, delta, RENDER_CULLFACE, GL_CULL_FACE ); if ( delta & state & RENDER_SMOOTH ) { - glShadeModel( GL_SMOOTH ); + gl().glShadeModel( GL_SMOOTH ); GlobalOpenGL_debugAssertNoErrors(); } else if ( delta & ~state & RENDER_SMOOTH ) { - glShadeModel( GL_FLAT ); + gl().glShadeModel( GL_FLAT ); GlobalOpenGL_debugAssertNoErrors(); } @@ -1830,11 +1376,11 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned setState( state, delta, RENDER_DEPTHTEST, GL_DEPTH_TEST ); if ( delta & state & RENDER_DEPTHWRITE ) { - glDepthMask( GL_TRUE ); + gl().glDepthMask( GL_TRUE ); #if DEBUG_RENDER GLboolean depthEnabled; - glGetBooleanv( GL_DEPTH_WRITEMASK, &depthEnabled ); + gl().glGetBooleanv( GL_DEPTH_WRITEMASK, &depthEnabled ); ASSERT_MESSAGE( depthEnabled, "failed to set depth buffer mask bit" ); #endif debug_string( "enabled depth-buffer writing" ); @@ -1842,11 +1388,11 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned GlobalOpenGL_debugAssertNoErrors(); } else if ( delta & ~state & RENDER_DEPTHWRITE ) { - glDepthMask( GL_FALSE ); + gl().glDepthMask( GL_FALSE ); #if DEBUG_RENDER GLboolean depthEnabled; - glGetBooleanv( GL_DEPTH_WRITEMASK, &depthEnabled ); + gl().glGetBooleanv( GL_DEPTH_WRITEMASK, &depthEnabled ); ASSERT_MESSAGE( !depthEnabled, "failed to set depth buffer mask bit" ); #endif debug_string( "disabled depth-buffer writing" ); @@ -1855,40 +1401,38 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned } if ( delta & state & RENDER_COLOURWRITE ) { - glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); + gl().glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); GlobalOpenGL_debugAssertNoErrors(); } else if ( delta & ~state & RENDER_COLOURWRITE ) { - glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE ); + gl().glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE ); GlobalOpenGL_debugAssertNoErrors(); } setState( state, delta, RENDER_ALPHATEST, GL_ALPHA_TEST ); if ( delta & state & RENDER_COLOURARRAY ) { - glEnableClientState( GL_COLOR_ARRAY ); + gl().glEnableClientState( GL_COLOR_ARRAY ); GlobalOpenGL_debugAssertNoErrors(); debug_colour( "enabling color_array" ); g_colorArray_enabled = true; } else if ( delta & ~state & RENDER_COLOURARRAY ) { - glDisableClientState( GL_COLOR_ARRAY ); - glColor4fv( vector4_to_array( self.m_colour ) ); + gl().glDisableClientState( GL_COLOR_ARRAY ); + gl().glColor4fv( vector4_to_array( self.m_colour ) ); debug_colour( "cleaning color_array" ); GlobalOpenGL_debugAssertNoErrors(); g_colorArray_enabled = false; } if ( delta & ~state & RENDER_COLOURCHANGE ) { - glColor4fv( vector4_to_array( self.m_colour ) ); + gl().glColor4fv( vector4_to_array( self.m_colour ) ); GlobalOpenGL_debugAssertNoErrors(); } setState( state, delta, RENDER_LINESTIPPLE, GL_LINE_STIPPLE ); - setState( state, delta, RENDER_LINESMOOTH, GL_LINE_SMOOTH ); setState( state, delta, RENDER_POLYGONSTIPPLE, GL_POLYGON_STIPPLE ); - setState( state, delta, RENDER_POLYGONSMOOTH, GL_POLYGON_SMOOTH ); setState( state, delta, RENDER_FOG, GL_FOG ); @@ -1899,7 +1443,7 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned } if ( state & RENDER_DEPTHTEST && self.m_depthfunc != current.m_depthfunc ) { - glDepthFunc( self.m_depthfunc ); + gl().glDepthFunc( self.m_depthfunc ); GlobalOpenGL_debugAssertNoErrors(); current.m_depthfunc = self.m_depthfunc; } @@ -1907,7 +1451,7 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned if ( state & RENDER_LINESTIPPLE && ( self.m_linestipple_factor != current.m_linestipple_factor || self.m_linestipple_pattern != current.m_linestipple_pattern ) ) { - glLineStipple( self.m_linestipple_factor, self.m_linestipple_pattern ); + gl().glLineStipple( self.m_linestipple_factor, self.m_linestipple_pattern ); GlobalOpenGL_debugAssertNoErrors(); current.m_linestipple_factor = self.m_linestipple_factor; current.m_linestipple_pattern = self.m_linestipple_pattern; @@ -1917,7 +1461,7 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned if ( state & RENDER_ALPHATEST && ( self.m_alphafunc != current.m_alphafunc || self.m_alpharef != current.m_alpharef ) ) { - glAlphaFunc( self.m_alphafunc, self.m_alpharef ); + gl().glAlphaFunc( self.m_alphafunc, self.m_alpharef ); GlobalOpenGL_debugAssertNoErrors(); current.m_alphafunc = self.m_alphafunc; current.m_alpharef = self.m_alpharef; @@ -1944,7 +1488,7 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned texture7 = self.m_texture7; } - if ( GlobalOpenGL().GL_1_3() ) { + { setTextureState( current.m_texture, texture0, GL_TEXTURE0 ); setTextureState( current.m_texture1, texture1, GL_TEXTURE1 ); setTextureState( current.m_texture2, texture2, GL_TEXTURE2 ); @@ -1954,32 +1498,26 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned setTextureState( current.m_texture6, texture6, GL_TEXTURE6 ); setTextureState( current.m_texture7, texture7, GL_TEXTURE7 ); } - else - { - setTextureState( current.m_texture, texture0 ); - } } if( current.m_textureSkyBox != self.m_textureSkyBox ){ - if ( GlobalOpenGL().GL_1_3() ) { - glActiveTexture( GL_TEXTURE0 ); - glClientActiveTexture( GL_TEXTURE0 ); - } - glBindTexture( GL_TEXTURE_CUBE_MAP, self.m_textureSkyBox ); + gl().glActiveTexture( GL_TEXTURE0 ); + gl().glClientActiveTexture( GL_TEXTURE0 ); + gl().glBindTexture( GL_TEXTURE_CUBE_MAP, self.m_textureSkyBox ); GlobalOpenGL_debugAssertNoErrors(); current.m_textureSkyBox = self.m_textureSkyBox; } if ( state & RENDER_TEXTURE && self.m_colour[3] != current.m_colour[3] ) { debug_colour( "setting alpha" ); - glColor4f( 1,1,1,self.m_colour[3] ); + gl().glColor4f( 1,1,1,self.m_colour[3] ); GlobalOpenGL_debugAssertNoErrors(); } if ( !( state & RENDER_TEXTURE ) && self.m_colour != current.m_colour ) { - glColor4fv( vector4_to_array( self.m_colour ) ); + gl().glColor4fv( vector4_to_array( self.m_colour ) ); debug_colour( "setting non-texture" ); GlobalOpenGL_debugAssertNoErrors(); } @@ -1987,7 +1525,7 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned if ( state & RENDER_BLEND && ( self.m_blend_src != current.m_blend_src || self.m_blend_dst != current.m_blend_dst ) ) { - glBlendFunc( self.m_blend_src, self.m_blend_dst ); + gl().glBlendFunc( self.m_blend_src, self.m_blend_dst ); GlobalOpenGL_debugAssertNoErrors(); current.m_blend_src = self.m_blend_src; current.m_blend_dst = self.m_blend_dst; @@ -1995,14 +1533,14 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned if ( !( state & RENDER_FILL ) && self.m_linewidth != current.m_linewidth ) { - glLineWidth( self.m_linewidth ); + gl().glLineWidth( self.m_linewidth ); GlobalOpenGL_debugAssertNoErrors(); current.m_linewidth = self.m_linewidth; } if ( !( state & RENDER_FILL ) && self.m_pointsize != current.m_pointsize ) { - glPointSize( self.m_pointsize ); + gl().glPointSize( self.m_pointsize ); GlobalOpenGL_debugAssertNoErrors(); current.m_pointsize = self.m_pointsize; } @@ -2014,7 +1552,7 @@ void OpenGLState_apply( const OpenGLState& self, OpenGLState& current, unsigned void Renderables_flush( OpenGLStateBucket::Renderables& renderables, OpenGLState& current, unsigned int globalstate, const Vector3& viewer ){ const Matrix4* transform = 0; - glPushMatrix(); + gl().glPushMatrix(); if ( current.m_program != 0 && current.m_textureSkyBox != 0 && globalstate & RENDER_PROGRAM ) { current.m_program->setParameters( viewer, g_matrix4_identity, g_vector3_identity, g_vector3_identity, g_matrix4_identity ); @@ -2026,10 +1564,10 @@ void Renderables_flush( OpenGLStateBucket::Renderables& renderables, OpenGLState if ( !transform || ( transform != ( *i ).m_transform && !matrix4_affine_equal( *transform, *( *i ).m_transform ) ) ) { count_transform(); transform = ( *i ).m_transform; - glPopMatrix(); - glPushMatrix(); - glMultMatrixf( reinterpret_cast( transform ) ); - glFrontFace( ( ( current.m_state & RENDER_CULLFACE ) != 0 && matrix4_handedness( *transform ) == MATRIX4_RIGHTHANDED ) ? GL_CW : GL_CCW ); + gl().glPopMatrix(); + gl().glPushMatrix(); + gl().glMultMatrixf( reinterpret_cast( transform ) ); + gl().glFrontFace( ( ( current.m_state & RENDER_CULLFACE ) != 0 && matrix4_handedness( *transform ) == MATRIX4_RIGHTHANDED ) ? GL_CW : GL_CCW ); } count_prim(); @@ -2043,16 +1581,16 @@ void Renderables_flush( OpenGLStateBucket::Renderables& renderables, OpenGLState : static_cast( g_defaultPointLight )->getShader().lightFalloffImage()->texture_number; setTextureState( current.m_texture3, attenuation_xy, GL_TEXTURE3 ); - glActiveTexture( GL_TEXTURE3 ); - glBindTexture( GL_TEXTURE_2D, attenuation_xy ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER ); + gl().glActiveTexture( GL_TEXTURE3 ); + gl().glBindTexture( GL_TEXTURE_2D, attenuation_xy ); + gl().glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER ); + gl().glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER ); setTextureState( current.m_texture4, attenuation_z, GL_TEXTURE4 ); - glActiveTexture( GL_TEXTURE4 ); - glBindTexture( GL_TEXTURE_2D, attenuation_z ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + gl().glActiveTexture( GL_TEXTURE4 ); + gl().glBindTexture( GL_TEXTURE_2D, attenuation_z ); + gl().glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER ); + gl().glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); AABB lightBounds( ( *i ).m_light->aabb() ); @@ -2079,7 +1617,7 @@ void Renderables_flush( OpenGLStateBucket::Renderables& renderables, OpenGLState ( *i ).m_renderable->render( current.m_state ); } - glPopMatrix(); + gl().glPopMatrix(); renderables.clear(); } @@ -2088,26 +1626,26 @@ void OpenGLStateBucket::render( OpenGLState& current, unsigned int globalstate, OpenGLState_apply( m_state, current, globalstate ); debug_colour( "screen fill" ); - glMatrixMode( GL_PROJECTION ); - glPushMatrix(); - glLoadMatrixf( reinterpret_cast( &g_matrix4_identity ) ); + gl().glMatrixMode( GL_PROJECTION ); + gl().glPushMatrix(); + gl().glLoadMatrixf( reinterpret_cast( &g_matrix4_identity ) ); - glMatrixMode( GL_MODELVIEW ); - glPushMatrix(); - glLoadMatrixf( reinterpret_cast( &g_matrix4_identity ) ); + gl().glMatrixMode( GL_MODELVIEW ); + gl().glPushMatrix(); + gl().glLoadMatrixf( reinterpret_cast( &g_matrix4_identity ) ); - glBegin( GL_QUADS ); - glVertex3f( -1, -1, 0 ); - glVertex3f( 1, -1, 0 ); - glVertex3f( 1, 1, 0 ); - glVertex3f( -1, 1, 0 ); - glEnd(); + gl().glBegin( GL_QUADS ); + gl().glVertex3f( -1, -1, 0 ); + gl().glVertex3f( 1, -1, 0 ); + gl().glVertex3f( 1, 1, 0 ); + gl().glVertex3f( -1, 1, 0 ); + gl().glEnd(); - glMatrixMode( GL_PROJECTION ); - glPopMatrix(); + gl().glMatrixMode( GL_PROJECTION ); + gl().glPopMatrix(); - glMatrixMode( GL_MODELVIEW ); - glPopMatrix(); + gl().glMatrixMode( GL_MODELVIEW ); + gl().glPopMatrix(); } else if ( !m_renderables.empty() ) { OpenGLState_apply( m_state, current, globalstate ); @@ -2472,7 +2010,7 @@ void OpenGLShader::construct( const char* name ){ // construction from IShader m_shader = QERApp_Shader_ForName( name ); - if ( g_ShaderCache->lightingSupported() && g_ShaderCache->lightingEnabled() && m_shader->getBump() != 0 && m_shader->getBump()->texture_number != 0 ) { // is a bump shader + if ( g_ShaderCache->lightingEnabled() && m_shader->getBump() != 0 && m_shader->getBump()->texture_number != 0 ) { // is a bump shader state.m_state = RENDER_FILL | RENDER_CULLFACE | RENDER_TEXTURE | RENDER_DEPTHTEST | RENDER_DEPTHWRITE | RENDER_COLOURWRITE | RENDER_PROGRAM; state.m_colour[0] = 0; state.m_colour[1] = 0; @@ -2480,37 +2018,23 @@ void OpenGLShader::construct( const char* name ){ state.m_colour[3] = 1; state.m_sort = OpenGLState::eSortOpaque; - if ( g_ShaderCache->useShaderLanguage() ) { - state.m_program = &g_depthFillGLSL; - } - else - { - state.m_program = &g_depthFillARB; - } + state.m_program = &g_depthFillGLSL; OpenGLState& bumpPass = appendDefaultPass(); bumpPass.m_texture = m_shader->getDiffuse()->texture_number; bumpPass.m_texture1 = m_shader->getBump()->texture_number; bumpPass.m_texture2 = m_shader->getSpecular()->texture_number; - bumpPass.m_state = RENDER_BLEND | RENDER_FILL | RENDER_CULLFACE | RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_SMOOTH | RENDER_BUMP | RENDER_PROGRAM; + bumpPass.m_state = RENDER_BLEND | RENDER_FILL | RENDER_CULLFACE | RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_SMOOTH | RENDER_BUMP | RENDER_PROGRAM | RENDER_LIGHTING; - if ( g_ShaderCache->useShaderLanguage() ) { - bumpPass.m_state |= RENDER_LIGHTING; - bumpPass.m_program = &g_bumpGLSL; - } - else - { - bumpPass.m_program = &g_bumpARB; - } + bumpPass.m_program = &g_bumpGLSL; bumpPass.m_depthfunc = GL_LEQUAL; bumpPass.m_sort = OpenGLState::eSortMultiFirst; bumpPass.m_blend_src = GL_ONE; bumpPass.m_blend_dst = GL_ONE; } - // g_ShaderCache->lightingSupported() as in GLSL is available - else if( m_shader->getSkyBox() != nullptr && m_shader->getSkyBox()->texture_number != 0 && g_ShaderCache->lightingSupported() ) + else if( m_shader->getSkyBox() != nullptr && m_shader->getSkyBox()->texture_number != 0 ) { state.m_texture = m_shader->getTexture()->texture_number; state.m_textureSkyBox = m_shader->getSkyBox()->texture_number; diff --git a/radiant/scenegraph.cpp b/radiant/scenegraph.cpp index 6b03bea6..4b86175e 100644 --- a/radiant/scenegraph.cpp +++ b/radiant/scenegraph.cpp @@ -33,17 +33,6 @@ #include "instancelib.h" #include "treemodel.h" -class StringEqualPredicate -{ - const char* m_string; -public: - StringEqualPredicate( const char* string ) : m_string( string ){ - } - bool operator()( const char* other ) const { - return string_equal( m_string, other ); - } -}; - template class TypeIdMap { @@ -56,9 +45,9 @@ public: TypeIdMap() : m_typeNamesEnd( m_typeNames ){ } TypeId getTypeId( const char* name ){ - TypeName* i = std::find_if( m_typeNames, m_typeNamesEnd, StringEqualPredicate( name ) ); + TypeName* i = std::find_if( m_typeNames, m_typeNamesEnd, [name]( const char* other ){ return string_equal( name, other ); } ); if ( i == m_typeNamesEnd ) { - ASSERT_MESSAGE( m_typeNamesEnd != m_typeNames + SIZE, "reached maximum number of type names supported (" << Unsigned( SIZE ) << ")" ); + ASSERT_MESSAGE( m_typeNamesEnd != m_typeNames + SIZE, "reached maximum number of type names supported (" << SIZE << ")" ); *m_typeNamesEnd++ = name; } return i - m_typeNames; diff --git a/radiant/select.cpp b/radiant/select.cpp index fdfbec0a..09202a9c 100644 --- a/radiant/select.cpp +++ b/radiant/select.cpp @@ -31,22 +31,28 @@ #include "stream/stringstream.h" #include "signal/isignal.h" +#include "signal/isignal.h" #include "shaderlib.h" #include "scenelib.h" #include "gtkutil/idledraw.h" #include "gtkutil/dialog.h" #include "gtkutil/widget.h" +#include "gtkutil/clipboard.h" #include "brushmanip.h" #include "brush.h" #include "patch.h" #include "patchmanip.h" #include "patchdialog.h" +#include "surfacedialog.h" #include "texwindow.h" #include "mainframe.h" +#include "camwindow.h" +#include "tools.h" #include "grid.h" #include "map.h" #include "entityinspector.h" +#include "csg.h" @@ -934,6 +940,7 @@ void Select_ProjectTexture( const TextureProjection& projection, const Vector3& void Select_FitTexture( float horizontal, float vertical, bool only_dimension ){ if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) { Scene_BrushFitTexture_Selected( GlobalSceneGraph(), horizontal, vertical, only_dimension ); + Scene_PatchTileTexture_Selected( GlobalSceneGraph(), horizontal, vertical ); } Scene_BrushFitTexture_Component_Selected( GlobalSceneGraph(), horizontal, vertical, only_dimension ); @@ -952,8 +959,7 @@ inline void hide_node( scene::Node& node, bool hide ){ bool g_nodes_be_hidden = false; -BoolExportCaller g_hidden_caller( g_nodes_be_hidden ); -ToggleItem g_hidden_item( g_hidden_caller ); +ToggleItem g_hidden_item{ BoolExportCaller( g_nodes_be_hidden ) }; class HideSelectedWalker : public scene::Graph::Walker { @@ -1108,28 +1114,6 @@ void Selection_RotateAnticlockwise(){ } - -void Select_registerCommands(){ - GlobalCommands_insert( "ShowHidden", FreeCaller(), Accelerator( 'H', GDK_SHIFT_MASK ) ); - GlobalToggles_insert( "HideSelected", FreeCaller(), ToggleItem::AddCallbackCaller( g_hidden_item ), Accelerator( 'H' ) ); - - GlobalCommands_insert( "MirrorSelectionX", FreeCaller() ); - GlobalCommands_insert( "RotateSelectionX", FreeCaller() ); - GlobalCommands_insert( "MirrorSelectionY", FreeCaller() ); - GlobalCommands_insert( "RotateSelectionY", FreeCaller() ); - GlobalCommands_insert( "MirrorSelectionZ", FreeCaller() ); - GlobalCommands_insert( "RotateSelectionZ", FreeCaller() ); - - GlobalCommands_insert( "MirrorSelectionHorizontally", FreeCaller() ); - GlobalCommands_insert( "MirrorSelectionVertically", FreeCaller() ); - - GlobalCommands_insert( "RotateSelectionClockwise", FreeCaller() ); - GlobalCommands_insert( "RotateSelectionAnticlockwise", FreeCaller() ); - - GlobalCommands_insert( "SelectTextured", FreeCaller(), Accelerator( 'A', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); -} - - void Nudge( int nDim, float fNudge ){ Vector3 translate( 0, 0, 0 ); translate[nDim] = fNudge; @@ -1153,30 +1137,6 @@ void Selection_MoveUp(){ Selection_NudgeZ( GetGridSize() ); } -void SceneSelectionChange( const Selectable& selectable ){ - SceneChangeNotify(); -} - -SignalHandlerId Selection_boundsChanged; - -void Selection_construct(){ - typedef FreeCaller1 SceneSelectionChangeCaller; - GlobalSelectionSystem().addSelectionChangeCallback( SceneSelectionChangeCaller() ); - typedef FreeCaller1 UpdateWorkzoneForSelectionChangedCaller; - GlobalSelectionSystem().addSelectionChangeCallback( UpdateWorkzoneForSelectionChangedCaller() ); - typedef FreeCaller UpdateWorkzoneForSelectionCaller; - Selection_boundsChanged = GlobalSceneGraph().addBoundsChangedCallback( UpdateWorkzoneForSelectionCaller() ); -} - -void Selection_destroy(){ - GlobalSceneGraph().removeBoundsChangedCallback( Selection_boundsChanged ); -} - - -#include "gtkdlgs.h" -#include -#include - inline Quaternion quaternion_for_euler_xyz_degrees( const Vector3& eulerXYZ ){ #if 0 @@ -1206,302 +1166,616 @@ inline Quaternion quaternion_for_euler_xyz_degrees( const Vector3& eulerXYZ ){ #endif } -struct RotateDialog + +void Undo(){ + GlobalUndoSystem().undo(); + SceneChangeNotify(); +} + +void Redo(){ + GlobalUndoSystem().redo(); + SceneChangeNotify(); +} + +void deleteSelection(){ + if( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent && GlobalSelectionSystem().countSelectedComponents() != 0 ){ + UndoableCommand undo( "deleteSelectedComponents" ); + CSG_DeleteComponents(); + } + else{ + UndoableCommand undo( "deleteSelected" ); + Select_Delete(); + } +} + +void Map_ExportSelected( TextOutputStream& ostream ){ + Map_ExportSelected( ostream, Map_getFormat( g_map ) ); +} + +void Map_ImportSelected( TextInputStream& istream ){ + Map_ImportSelected( istream, Map_getFormat( g_map ) ); +} + +void Selection_Copy(){ + clipboard_copy( Map_ExportSelected ); +} + +void Selection_Paste(){ + clipboard_paste( Map_ImportSelected ); +} + +void Copy(){ + Selection_Copy(); +} + +void Paste(){ + UndoableCommand undo( "paste" ); + + GlobalSelectionSystem().setSelectedAll( false ); + Selection_Paste(); +} + +void TranslateToCamera(){ + CamWnd& camwnd = *g_pParentWnd->GetCamWnd(); + GlobalSelectionSystem().translateSelected( vector3_snapped( Camera_getOrigin( camwnd ) - GlobalSelectionSystem().getBoundsSelected().origin, GetSnapGridSize() ) ); +} + +void PasteToCamera(){ + GlobalSelectionSystem().setSelectedAll( false ); + UndoableCommand undo( "pasteToCamera" ); + Selection_Paste(); + TranslateToCamera(); +} + +void MoveToCamera(){ + UndoableCommand undo( "moveToCamera" ); + TranslateToCamera(); +} + + + +class CloneSelected : public scene::Graph::Walker { - GtkSpinButton* x; - GtkSpinButton* y; - GtkSpinButton* z; - GtkWindow *window; -}; + const bool m_makeUnique; + const scene::Node* m_world; +public: + mutable std::vector m_cloned; + CloneSelected( bool makeUnique ) : m_makeUnique( makeUnique ), m_world( Map_FindWorldspawn( g_map ) ){ + } + bool pre( const scene::Path& path, scene::Instance& instance ) const { + if ( path.size() == 1 ) { + return true; + } -static gboolean rotatedlg_apply( GtkWidget *widget, RotateDialog* rotateDialog ){ - Vector3 eulerXYZ; + if ( path.top().get_pointer() == m_world ) { // ignore worldspawn, but keep checking children + return true; + } - /* only update in scenario of enter pressed to also allow extra precision of values after execution by buttons */ - if( gtk_widget_has_focus( GTK_WIDGET( rotateDialog->x ) ) ) - gtk_spin_button_update( rotateDialog->x ); - else if( gtk_widget_has_focus( GTK_WIDGET( rotateDialog->y ) ) ) - gtk_spin_button_update( rotateDialog->y ); - else if( gtk_widget_has_focus( GTK_WIDGET( rotateDialog->z ) ) ) - gtk_spin_button_update( rotateDialog->z ); - - eulerXYZ[0] = static_cast( gtk_spin_button_get_value( rotateDialog->x ) ); - eulerXYZ[1] = static_cast( gtk_spin_button_get_value( rotateDialog->y ) ); - eulerXYZ[2] = static_cast( gtk_spin_button_get_value( rotateDialog->z ) ); - - StringOutputStream command; - command << "rotateSelectedEulerXYZ -x " << eulerXYZ[0] << " -y " << eulerXYZ[1] << " -z " << eulerXYZ[2]; - UndoableCommand undo( command.c_str() ); - - GlobalSelectionSystem().rotateSelected( quaternion_for_euler_xyz_degrees( eulerXYZ ) ); - return TRUE; -} - -static gboolean rotatedlg_cancel( GtkWidget *widget, RotateDialog* rotateDialog ){ - gtk_widget_hide( GTK_WIDGET( rotateDialog->window ) ); - - gtk_spin_button_set_value( rotateDialog->x, 0.0 ); // reset to 0 on close - gtk_spin_button_set_value( rotateDialog->y, 0.0 ); - gtk_spin_button_set_value( rotateDialog->z, 0.0 ); - - return TRUE; -} - -static gboolean rotatedlg_ok( GtkWidget *widget, RotateDialog* rotateDialog ){ - rotatedlg_apply( widget, rotateDialog ); -// rotatedlg_cancel( widget, rotateDialog ); - gtk_widget_hide( GTK_WIDGET( rotateDialog->window ) ); - return TRUE; -} - -static gboolean rotatedlg_delete( GtkWidget *widget, GdkEventAny *event, RotateDialog* rotateDialog ){ - rotatedlg_cancel( widget, rotateDialog ); - return TRUE; -} - -RotateDialog g_rotate_dialog; -void DoRotateDlg(){ - if ( g_rotate_dialog.window == NULL ) { - g_rotate_dialog.window = create_dialog_window( MainFrame_getWindow(), "Arbitrary rotation", G_CALLBACK( rotatedlg_delete ), &g_rotate_dialog ); - - GtkAccelGroup* accel = gtk_accel_group_new(); - gtk_window_add_accel_group( g_rotate_dialog.window, accel ); - - { - GtkHBox* hbox = create_dialog_hbox( 4, 4 ); - gtk_container_add( GTK_CONTAINER( g_rotate_dialog.window ), GTK_WIDGET( hbox ) ); - { - GtkTable* table = create_dialog_table( 3, 2, 4, 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - { - GtkWidget* label = gtk_label_new( " X " ); - gtk_widget_show( label ); - gtk_table_attach( table, label, 0, 1, 0, 1, - (GtkAttachOptions) ( 0 ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkWidget* label = gtk_label_new( " Y " ); - gtk_widget_show( label ); - gtk_table_attach( table, label, 0, 1, 1, 2, - (GtkAttachOptions) ( 0 ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkWidget* label = gtk_label_new( " Z " ); - gtk_widget_show( label ); - gtk_table_attach( table, label, 0, 1, 2, 3, - (GtkAttachOptions) ( 0 ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0, -359, 359, 1, 10, 0 ) ); - GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( adj, 1, 2 ) ); - gtk_widget_show( GTK_WIDGET( spin ) ); - gtk_table_attach( table, GTK_WIDGET( spin ), 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( spin ), 64, -1 ); - gtk_spin_button_set_wrap( spin, TRUE ); - - gtk_widget_grab_focus( GTK_WIDGET( spin ) ); - - g_rotate_dialog.x = spin; - } - { - GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0, -359, 359, 1, 10, 0 ) ); - GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( adj, 1, 2 ) ); - gtk_widget_show( GTK_WIDGET( spin ) ); - gtk_table_attach( table, GTK_WIDGET( spin ), 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( spin ), 64, -1 ); - gtk_spin_button_set_wrap( spin, TRUE ); - - g_rotate_dialog.y = spin; - } - { - GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0, -359, 359, 1, 10, 0 ) ); - GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( adj, 1, 2 ) ); - gtk_widget_show( GTK_WIDGET( spin ) ); - gtk_table_attach( table, GTK_WIDGET( spin ), 1, 2, 2, 3, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( spin ), 64, -1 ); - gtk_spin_button_set_wrap( spin, TRUE ); - - g_rotate_dialog.z = spin; - } + if ( !path.top().get().isRoot() ) { + if ( Instance_isSelected( instance ) ) { + return false; } - { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), TRUE, TRUE, 0 ); - { - GtkButton* button = create_dialog_button( "OK", G_CALLBACK( rotatedlg_ok ), &g_rotate_dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 ); - } - { - GtkButton* button = create_dialog_button( "Cancel", G_CALLBACK( rotatedlg_cancel ), &g_rotate_dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 ); - } - { - GtkButton* button = create_dialog_button( "Apply", G_CALLBACK( rotatedlg_apply ), &g_rotate_dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - } + if( m_makeUnique && instance.childSelected() ){ /* clone selected group entity primitives to new group entity */ + return false; + } + } + + return true; + } + void post( const scene::Path& path, scene::Instance& instance ) const { + if ( path.size() == 1 ) { + return; + } + + if ( path.top().get_pointer() == m_world ) { // ignore worldspawn + return; + } + + if ( !path.top().get().isRoot() ) { + if ( Instance_isSelected( instance ) ) { + NodeSmartReference clone( Node_Clone( path.top() ) ); + Map_gatherNamespaced( clone ); + Node_getTraversable( path.parent().get() )->insert( clone ); + m_cloned.push_back( clone.get_pointer() ); + } + else if( m_makeUnique && instance.childSelected() ){ /* clone selected group entity primitives to new group entity */ + NodeSmartReference clone( Node_Clone_Selected( path.top() ) ); + Map_gatherNamespaced( clone ); + Node_getTraversable( path.parent().get() )->insert( clone ); + m_cloned.push_back( clone.get_pointer() ); } } } - - gtk_widget_show( GTK_WIDGET( g_rotate_dialog.window ) ); -} - - - - - - - - - -struct ScaleDialog -{ - GtkWidget* x; - GtkWidget* y; - GtkWidget* z; - GtkWindow *window; }; -static gboolean scaledlg_apply( GtkWidget *widget, ScaleDialog* scaleDialog ){ - float sx, sy, sz; +void Scene_Clone_Selected( scene::Graph& graph, bool makeUnique ){ + CloneSelected cloneSelected( makeUnique ); + graph.traverse( cloneSelected ); - sx = static_cast( atof( gtk_entry_get_text( GTK_ENTRY( scaleDialog->x ) ) ) ); - sy = static_cast( atof( gtk_entry_get_text( GTK_ENTRY( scaleDialog->y ) ) ) ); - sz = static_cast( atof( gtk_entry_get_text( GTK_ENTRY( scaleDialog->z ) ) ) ); + Map_mergeClonedNames( makeUnique ); + /* deselect originals */ + GlobalSelectionSystem().setSelectedAll( false ); + /* select cloned */ + for( scene::Node *node : cloneSelected.m_cloned ) + { + class walker : public scene::Traversable::Walker + { + public: + bool pre( scene::Node& node ) const override { + if( scene::Instantiable *instantiable = Node_getInstantiable( node ) ){ + class visitor : public scene::Instantiable::Visitor + { + public: + void visit( scene::Instance& instance ) const override { + Instance_setSelected( instance, true ); + } + }; + + instantiable->forEachInstance( visitor() ); + } + return true; + } + }; + Node_traverseSubgraph( *node, walker() ); + } +} + +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_ ){ + } +}; + +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 ); + } + + ERROR_MESSAGE( "invalid viewtype" ); + return AxisBase( Vector3( 0, 0, 0 ), Vector3( 0, 0, 0 ), Vector3( 0, 0, 0 ) ); +} + +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 ); + } + + ERROR_MESSAGE( "invalid direction" ); + return Vector3( 0, 0, 0 ); +} + +bool g_bNudgeAfterClone = false; + +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 ); +} + +void Selection_Clone(){ + if ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ) { + UndoableCommand undo( "cloneSelected" ); + + Scene_Clone_Selected( GlobalSceneGraph(), false ); + + if( g_bNudgeAfterClone ){ + NudgeSelection(eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType()); + NudgeSelection(eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType()); + } + } +} + +void Selection_Clone_MakeUnique(){ + if ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ) { + UndoableCommand undo( "cloneSelectedMakeUnique" ); + + Scene_Clone_Selected( GlobalSceneGraph(), true ); + + if( g_bNudgeAfterClone ){ + 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 ); + } + } +} + +void Scene_Clone_Selected(){ + Scene_Clone_Selected( GlobalSceneGraph(), false ); +} + +void RepeatTransforms(){ + GlobalSelectionSystem().repeatTransforms( FreeCaller() ); +} + + +void Selection_NudgeUp(){ + UndoableCommand undo( "nudgeSelectedUp" ); + NudgeSelection( eNudgeUp, GetGridSize(), GlobalXYWnd_getCurrentViewType() ); +} + +void Selection_NudgeDown(){ + UndoableCommand undo( "nudgeSelectedDown" ); + NudgeSelection( eNudgeDown, GetGridSize(), GlobalXYWnd_getCurrentViewType() ); +} + +void Selection_NudgeLeft(){ + UndoableCommand undo( "nudgeSelectedLeft" ); + NudgeSelection( eNudgeLeft, GetGridSize(), GlobalXYWnd_getCurrentViewType() ); +} + +void Selection_NudgeRight(){ + UndoableCommand undo( "nudgeSelectedRight" ); + NudgeSelection( eNudgeRight, GetGridSize(), GlobalXYWnd_getCurrentViewType() ); +} + + + +void Texdef_Rotate( float angle ){ StringOutputStream command; - command << "scaleSelected -x " << sx << " -y " << sy << " -z " << sz; + command << "brushRotateTexture -angle " << angle; + UndoableCommand undo( command.c_str() ); + Select_RotateTexture( angle ); +} +// these are actually {Anti,}Clockwise in BP mode only (AP/220 - 50/50) +// TODO is possible to make really {Anti,}Clockwise +void Texdef_RotateClockwise(){ + Texdef_Rotate( static_cast( -fabs( g_si_globals.rotate ) ) ); +} + +void Texdef_RotateAntiClockwise(){ + Texdef_Rotate( static_cast( 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 ); +} + +void Texdef_ScaleUp(){ + Texdef_Scale( 0, g_si_globals.scale[1] ); +} + +void Texdef_ScaleDown(){ + Texdef_Scale( 0, -g_si_globals.scale[1] ); +} + +void Texdef_ScaleLeft(){ + Texdef_Scale( -g_si_globals.scale[0],0 ); +} + +void Texdef_ScaleRight(){ + 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 ); +} + +void Texdef_ShiftLeft(){ + Texdef_Shift( -g_si_globals.shift[0], 0 ); +} + +void Texdef_ShiftRight(){ + Texdef_Shift( g_si_globals.shift[0], 0 ); +} + +void Texdef_ShiftUp(){ + Texdef_Shift( 0, g_si_globals.shift[1] ); +} + +void Texdef_ShiftDown(){ + Texdef_Shift( 0, -g_si_globals.shift[1] ); +} + + + +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() ) { + Snappable* snappable = Node_getSnappable( path.top() ); + if ( snappable != 0 + && Instance_isSelected( instance ) ) { + snappable->snapto( m_snap ); + } + } + return true; + } +}; + +void Scene_SnapToGrid_Selected( scene::Graph& graph, float snap ){ + graph.traverse( SnappableSnapToGridSelected( 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() ) { + ComponentSnappable* componentSnappable = Instance_getComponentSnappable( instance ); + if ( componentSnappable != 0 + && Instance_isSelected( instance ) ) { + componentSnappable->snapComponents( m_snap ); + } + } + return true; + } +}; + +void Scene_SnapToGrid_Component_Selected( scene::Graph& graph, float snap ){ + graph.traverse( ComponentSnappableSnapToGridSelected( snap ) ); +} + +void Selection_SnapToGrid(){ + StringOutputStream command; + command << "snapSelected -grid " << GetGridSize(); UndoableCommand undo( command.c_str() ); - Select_Scale( sx, sy, sz ); - - return TRUE; + if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent && GlobalSelectionSystem().countSelectedComponents() ) { + Scene_SnapToGrid_Component_Selected( GlobalSceneGraph(), GetGridSize() ); + } + else + { + Scene_SnapToGrid_Selected( GlobalSceneGraph(), GetGridSize() ); + } } -static gboolean scaledlg_cancel( GtkWidget *widget, ScaleDialog* scaleDialog ){ - gtk_widget_hide( GTK_WIDGET( scaleDialog->window ) ); - gtk_entry_set_text( GTK_ENTRY( scaleDialog->x ), "1.0" ); - gtk_entry_set_text( GTK_ENTRY( scaleDialog->y ), "1.0" ); - gtk_entry_set_text( GTK_ENTRY( scaleDialog->z ), "1.0" ); - return TRUE; +#include +#include +#include +#include +#include "gtkutil/spinbox.h" + + +class RotateDialog : public QObject +{ + QWidget *m_window{}; + QDoubleSpinBox *m_x; + QDoubleSpinBox *m_y; + QDoubleSpinBox *m_z; + void construct(){ + m_window = new QWidget( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + m_window->setWindowTitle( "Arbitrary rotation" ); + m_window->installEventFilter( this ); + + auto grid = new QGridLayout( m_window ); + grid->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + + { + grid->addWidget( m_x = new DoubleSpinBox( -360, 360, 0, 6, 1, true ), 0, 1 ); + grid->addWidget( m_y = new DoubleSpinBox( -360, 360, 0, 6, 1, true ), 1, 1 ); + grid->addWidget( m_z = new DoubleSpinBox( -360, 360, 0, 6, 1, true ), 2, 1 ); + } + { + grid->addWidget( new SpinBoxLabel( " X ", m_x ), 0, 0 ); + grid->addWidget( new SpinBoxLabel( " Y ", m_y ), 1, 0 ); + grid->addWidget( new SpinBoxLabel( " Z ", m_z ), 2, 0 ); + } + { + auto buttons = new QDialogButtonBox( Qt::Orientation::Vertical ); + grid->addWidget( buttons, 0, 2, 3, 1 ); + QObject::connect( buttons->addButton( QDialogButtonBox::StandardButton::Ok ), &QPushButton::clicked, [this](){ ok(); } ); + QObject::connect( buttons->addButton( QDialogButtonBox::StandardButton::Cancel ), &QPushButton::clicked, [this](){ cancel(); } ); + QObject::connect( buttons->addButton( QDialogButtonBox::StandardButton::Apply ), &QPushButton::clicked, [this](){ apply(); } ); + } + } + void apply(){ + const Vector3 eulerXYZ( m_x->value(), m_y->value(), m_z->value() ); + + StringOutputStream command; + command << "rotateSelectedEulerXYZ -x " << eulerXYZ[0] << " -y " << eulerXYZ[1] << " -z " << eulerXYZ[2]; + UndoableCommand undo( command.c_str() ); + + GlobalSelectionSystem().rotateSelected( quaternion_for_euler_xyz_degrees( eulerXYZ ) ); + } + void cancel(){ + m_window->hide(); + + m_x->setValue( 0 ); // reset to 0 on close + m_y->setValue( 0 ); + m_z->setValue( 0 ); + } + void ok(){ + apply(); + // cancel(); + m_window->hide(); + } +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::ShortcutOverride ) { + QKeyEvent *keyEvent = static_cast( event ); + if( keyEvent->key() == Qt::Key_Escape ){ + cancel(); + event->accept(); + } + else if( keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter ){ + ok(); + event->accept(); + } + else if( keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Space ){ + event->accept(); + } + } + else if( event->type() == QEvent::Close ) { + event->ignore(); + cancel(); + return true; + } + return QObject::eventFilter( obj, event ); // standard event processing + } +public: + void show(){ + if( m_window == nullptr ) + construct(); + m_window->show(); + m_window->raise(); + m_window->activateWindow(); + } +} +g_rotate_dialog; + +void DoRotateDlg(){ + g_rotate_dialog.show(); } -static gboolean scaledlg_ok( GtkWidget *widget, ScaleDialog* scaleDialog ){ - scaledlg_apply( widget, scaleDialog ); - //scaledlg_cancel( widget, scaleDialog ); - gtk_widget_hide( GTK_WIDGET( scaleDialog->window ) ); - return TRUE; -} -static gboolean scaledlg_delete( GtkWidget *widget, GdkEventAny *event, ScaleDialog* scaleDialog ){ - scaledlg_cancel( widget, scaleDialog ); - return TRUE; -} -ScaleDialog g_scale_dialog; +class ScaleDialog : public QObject +{ + QWidget *m_window{}; + QDoubleSpinBox *m_x; + QDoubleSpinBox *m_y; + QDoubleSpinBox *m_z; + void construct(){ + m_window = new QWidget( MainFrame_getWindow(), Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); + m_window->setWindowTitle( "Arbitrary scale" ); + m_window->installEventFilter( this ); + + auto grid = new QGridLayout( m_window ); + grid->setSizeConstraint( QLayout::SizeConstraint::SetFixedSize ); + + { + grid->addWidget( m_x = new DoubleSpinBox( -32768, 32768, 1, 6, 1, false ), 0, 1 ); + grid->addWidget( m_y = new DoubleSpinBox( -32768, 32768, 1, 6, 1, false ), 1, 1 ); + grid->addWidget( m_z = new DoubleSpinBox( -32768, 32768, 1, 6, 1, false ), 2, 1 ); + } + { + grid->addWidget( new SpinBoxLabel( " X ", m_x ), 0, 0 ); + grid->addWidget( new SpinBoxLabel( " Y ", m_y ), 1, 0 ); + grid->addWidget( new SpinBoxLabel( " Z ", m_z ), 2, 0 ); + } + { + auto buttons = new QDialogButtonBox( Qt::Orientation::Vertical ); + grid->addWidget( buttons, 0, 2, 3, 1 ); + QObject::connect( buttons->addButton( QDialogButtonBox::StandardButton::Ok ), &QPushButton::clicked, [this](){ ok(); } ); + QObject::connect( buttons->addButton( QDialogButtonBox::StandardButton::Cancel ), &QPushButton::clicked, [this](){ cancel(); } ); + QObject::connect( buttons->addButton( QDialogButtonBox::StandardButton::Apply ), &QPushButton::clicked, [this](){ apply(); } ); + } + } + void apply(){ + const float sx = m_x->value(), sy = m_y->value(), sz = m_z->value(); + + StringOutputStream command; + command << "scaleSelected -x " << sx << " -y " << sy << " -z " << sz; + UndoableCommand undo( command.c_str() ); + + Select_Scale( sx, sy, sz ); + } + void cancel(){ + m_window->hide(); + + m_x->setValue( 1 ); // reset to 1 on close + m_y->setValue( 1 ); + m_z->setValue( 1 ); + } + void ok(){ + apply(); + // cancel(); + m_window->hide(); + } +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::ShortcutOverride ) { + QKeyEvent *keyEvent = static_cast( event ); + if( keyEvent->key() == Qt::Key_Escape ){ + cancel(); + event->accept(); + } + else if( keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter ){ + ok(); + event->accept(); + } + else if( keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Space ){ + event->accept(); + } + } + else if( event->type() == QEvent::Close ) { + event->ignore(); + cancel(); + return true; + } + return QObject::eventFilter( obj, event ); // standard event processing + } +public: + void show(){ + if( m_window == nullptr ) + construct(); + m_window->show(); + m_window->raise(); + m_window->activateWindow(); + } +} +g_scale_dialog; void DoScaleDlg(){ - if ( g_scale_dialog.window == NULL ) { - g_scale_dialog.window = create_dialog_window( MainFrame_getWindow(), "Arbitrary scale", G_CALLBACK( scaledlg_delete ), &g_scale_dialog ); - - GtkAccelGroup* accel = gtk_accel_group_new(); - gtk_window_add_accel_group( g_scale_dialog.window, accel ); - - { - GtkHBox* hbox = create_dialog_hbox( 4, 4 ); - gtk_container_add( GTK_CONTAINER( g_scale_dialog.window ), GTK_WIDGET( hbox ) ); - { - GtkTable* table = create_dialog_table( 3, 2, 4, 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - { - GtkWidget* label = gtk_label_new( " X " ); - gtk_widget_show( label ); - gtk_table_attach( table, label, 0, 1, 0, 1, - (GtkAttachOptions) ( 0 ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkWidget* label = gtk_label_new( " Y " ); - gtk_widget_show( label ); - gtk_table_attach( table, label, 0, 1, 1, 2, - (GtkAttachOptions) ( 0 ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkWidget* label = gtk_label_new( " Z " ); - gtk_widget_show( label ); - gtk_table_attach( table, label, 0, 1, 2, 3, - (GtkAttachOptions) ( 0 ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkWidget* entry = gtk_entry_new(); - gtk_entry_set_text( GTK_ENTRY( entry ), "1.0" ); - gtk_widget_show( entry ); - gtk_table_attach( table, entry, 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - g_scale_dialog.x = entry; - } - { - GtkWidget* entry = gtk_entry_new(); - gtk_entry_set_text( GTK_ENTRY( entry ), "1.0" ); - gtk_widget_show( entry ); - gtk_table_attach( table, entry, 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - g_scale_dialog.y = entry; - } - { - GtkWidget* entry = gtk_entry_new(); - gtk_entry_set_text( GTK_ENTRY( entry ), "1.0" ); - gtk_widget_show( entry ); - gtk_table_attach( table, entry, 1, 2, 2, 3, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - - g_scale_dialog.z = entry; - } - } - { - GtkVBox* vbox = create_dialog_vbox( 4 ); - gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), TRUE, TRUE, 0 ); - { - GtkButton* button = create_dialog_button( "OK", G_CALLBACK( scaledlg_ok ), &g_scale_dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - widget_make_default( GTK_WIDGET( button ) ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 ); - } - { - GtkButton* button = create_dialog_button( "Cancel", G_CALLBACK( scaledlg_cancel ), &g_scale_dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 ); - } - { - GtkButton* button = create_dialog_button( "Apply", G_CALLBACK( scaledlg_apply ), &g_scale_dialog ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - } - } - } - } - - gtk_widget_show( GTK_WIDGET( g_scale_dialog.window ) ); + g_scale_dialog.show(); } @@ -1578,3 +1852,101 @@ void Select_ConnectedEntities( bool targeting, bool targets, bool focus ){ void SelectConnectedEntities(){ Select_ConnectedEntities( true, true, false ); } + + + +void Select_registerCommands(){ + GlobalCommands_insert( "ShowHidden", FreeCaller(), QKeySequence( "Shift+H" ) ); + GlobalToggles_insert( "HideSelected", FreeCaller(), ToggleItem::AddCallbackCaller( g_hidden_item ), QKeySequence( "H" ) ); + + GlobalCommands_insert( "MirrorSelectionX", FreeCaller() ); + GlobalCommands_insert( "RotateSelectionX", FreeCaller() ); + GlobalCommands_insert( "MirrorSelectionY", FreeCaller() ); + GlobalCommands_insert( "RotateSelectionY", FreeCaller() ); + GlobalCommands_insert( "MirrorSelectionZ", FreeCaller() ); + GlobalCommands_insert( "RotateSelectionZ", FreeCaller() ); + + GlobalCommands_insert( "MirrorSelectionHorizontally", FreeCaller() ); + GlobalCommands_insert( "MirrorSelectionVertically", FreeCaller() ); + + GlobalCommands_insert( "RotateSelectionClockwise", FreeCaller() ); + GlobalCommands_insert( "RotateSelectionAnticlockwise", FreeCaller() ); + + GlobalCommands_insert( "SelectTextured", FreeCaller(), QKeySequence( "Ctrl+Shift+A" ) ); + + GlobalCommands_insert( "Undo", FreeCaller(), QKeySequence( "Ctrl+Z" ) ); + GlobalCommands_insert( "Redo", FreeCaller(), QKeySequence( "Ctrl+Shift+Z" ) ); + GlobalCommands_insert( "Redo2", FreeCaller(), QKeySequence( "Ctrl+Y" ) ); + GlobalCommands_insert( "Copy", FreeCaller(), QKeySequence( "Ctrl+C" ) ); + GlobalCommands_insert( "Paste", FreeCaller(), QKeySequence( "Ctrl+V" ) ); + GlobalCommands_insert( "PasteToCamera", FreeCaller(), QKeySequence( "Shift+V" ) ); + GlobalCommands_insert( "MoveToCamera", FreeCaller(), QKeySequence( "Ctrl+Shift+V" ) ); + GlobalCommands_insert( "CloneSelection", FreeCaller(), QKeySequence( "Space" ) ); + GlobalCommands_insert( "CloneSelectionAndMakeUnique", FreeCaller(), QKeySequence( "Shift+Space" ) ); + GlobalCommands_insert( "DeleteSelection2", FreeCaller(), QKeySequence( "Backspace" ) ); + GlobalCommands_insert( "DeleteSelection", FreeCaller(), QKeySequence( "Z" ) ); + GlobalCommands_insert( "RepeatTransforms", FreeCaller(), QKeySequence( "Ctrl+R" ) ); +// GlobalCommands_insert( "ParentSelection", FreeCaller() ); + GlobalCommands_insert( "UnSelectSelection2", FreeCaller(), QKeySequence( "Escape" ) ); + GlobalCommands_insert( "UnSelectSelection", FreeCaller(), QKeySequence( "C" ) ); + GlobalCommands_insert( "InvertSelection", FreeCaller(), QKeySequence( "I" ) ); + GlobalCommands_insert( "SelectInside", FreeCaller() ); + GlobalCommands_insert( "SelectTouching", FreeCaller() ); + GlobalCommands_insert( "ExpandSelectionToPrimitives", FreeCaller(), QKeySequence( "Ctrl+E" ) ); + GlobalCommands_insert( "ExpandSelectionToEntities", FreeCaller(), QKeySequence( "Shift+E" ) ); + GlobalCommands_insert( "SelectConnectedEntities", FreeCaller(), QKeySequence( "Ctrl+Shift+E" ) ); + + GlobalCommands_insert( "ArbitraryRotation", FreeCaller(), QKeySequence( "Shift+R" ) ); + GlobalCommands_insert( "ArbitraryScale", FreeCaller(), QKeySequence( "Ctrl+Shift+S" ) ); + + GlobalCommands_insert( "SnapToGrid", FreeCaller(), QKeySequence( "Ctrl+G" ) ); + + GlobalCommands_insert( "SelectAllOfType", FreeCaller(), QKeySequence( "Shift+A" ) ); + + GlobalCommands_insert( "TexRotateClock", FreeCaller(), QKeySequence( "Shift+PgDown" ) ); + GlobalCommands_insert( "TexRotateCounter", FreeCaller(), QKeySequence( "Shift+PgUp" ) ); + GlobalCommands_insert( "TexScaleUp", FreeCaller(), QKeySequence( "Ctrl+Up" ) ); + GlobalCommands_insert( "TexScaleDown", FreeCaller(), QKeySequence( "Ctrl+Down" ) ); + GlobalCommands_insert( "TexScaleLeft", FreeCaller(), QKeySequence( "Ctrl+Left" ) ); + GlobalCommands_insert( "TexScaleRight", FreeCaller(), QKeySequence( "Ctrl+Right" ) ); + GlobalCommands_insert( "TexShiftUp", FreeCaller(), QKeySequence( "Shift+Up" ) ); + GlobalCommands_insert( "TexShiftDown", FreeCaller(), QKeySequence( "Shift+Down" ) ); + GlobalCommands_insert( "TexShiftLeft", FreeCaller(), QKeySequence( "Shift+Left" ) ); + GlobalCommands_insert( "TexShiftRight", FreeCaller(), QKeySequence( "Shift+Right" ) ); + + GlobalCommands_insert( "MoveSelectionDOWN", FreeCaller(), QKeySequence( Qt::Key_Minus + Qt::KeypadModifier ) ); + GlobalCommands_insert( "MoveSelectionUP", FreeCaller(), QKeySequence( Qt::Key_Plus + Qt::KeypadModifier ) ); + + GlobalCommands_insert( "SelectNudgeLeft", FreeCaller(), QKeySequence( "Alt+Left" ) ); + GlobalCommands_insert( "SelectNudgeRight", FreeCaller(), QKeySequence( "Alt+Right" ) ); + GlobalCommands_insert( "SelectNudgeUp", FreeCaller(), QKeySequence( "Alt+Up" ) ); + GlobalCommands_insert( "SelectNudgeDown", FreeCaller(), QKeySequence( "Alt+Down" ) ); +} + + + +void SceneSelectionChange( const Selectable& selectable ){ + SceneChangeNotify(); +} + +SignalHandlerId Selection_boundsChanged; + +#include "preferencesystem.h" + +void Nudge_constructPreferences( PreferencesPage& page ){ + page.appendCheckBox( "", "Nudge selected after duplication", g_bNudgeAfterClone ); +} + +void Selection_construct(){ + GlobalPreferenceSystem().registerPreference( "NudgeAfterClone", BoolImportStringCaller( g_bNudgeAfterClone ), BoolExportStringCaller( g_bNudgeAfterClone ) ); + + PreferencesDialog_addSettingsPreferences( FreeCaller1() ); + + GlobalSelectionSystem().addSelectionChangeCallback( FreeCaller1() ); + GlobalSelectionSystem().addSelectionChangeCallback( FreeCaller1() ); + Selection_boundsChanged = GlobalSceneGraph().addBoundsChangedCallback( FreeCaller() ); +} + +void Selection_destroy(){ + GlobalSceneGraph().removeBoundsChangedCallback( Selection_boundsChanged ); +} diff --git a/radiant/select.h b/radiant/select.h index 34704b0f..4bbe5ea5 100644 --- a/radiant/select.h +++ b/radiant/select.h @@ -26,46 +26,26 @@ void Select_GetBounds( Vector3& mins, Vector3& maxs ); void Select_Delete(); -void Select_Invert(); -void Select_Inside(); -void Select_Touching(); -void Scene_ExpandSelectionToPrimitives(); -void Scene_ExpandSelectionToEntities(); +void deleteSelection(); - -void Selection_MoveDown(); -void Selection_MoveUp(); - -void Select_AllOfType(); void Select_EntitiesByKeyValue( const char* key, const char* value ); void Select_ConnectedEntities( bool targeting, bool targets, bool focus ); -void SelectConnectedEntities(); - -void DoRotateDlg(); -void DoScaleDlg(); void Select_SetShader( const char* shader ); void Select_SetShader_Undo( const char* shader ); -class TextureProjection; -void Select_SetTexdef( const TextureProjection& projection, bool setBasis = true, bool resetBasis = false ); +void Select_SetTexdef( const class TextureProjection& projection, bool setBasis = true, bool resetBasis = false ); void Select_SetTexdef( const float* hShift, const float* vShift, const float* hScale, const float* vScale, const float* rotation ); -class ContentsFlagsValue; -void Select_SetFlags( const ContentsFlagsValue& flags ); +void Select_SetFlags( const class ContentsFlagsValue& flags ); -void Select_RotateTexture( float amt ); -void Select_ScaleTexture( float x, float y ); -void Select_ShiftTexture( float x, float y ); -class texdef_t; -void Select_ProjectTexture( const texdef_t& texdef, const Vector3* direction ); -void Select_ProjectTexture( const TextureProjection& projection, const Vector3& normal ); +void Select_ProjectTexture( const class texdef_t& texdef, const Vector3* direction ); +void Select_ProjectTexture( const class TextureProjection& projection, const Vector3& normal ); void Select_FitTexture( float horizontal = 1, float vertical = 1, bool only_dimension = false ); void FindReplaceTextures( const char* pFind, const char* pReplace, bool bSelected ); -void HideSelected(); void Select_ShowAllHidden(); void Select_registerCommands(); diff --git a/radiant/selection.cpp b/radiant/selection.cpp index 2036b734..e61ba278 100644 --- a/radiant/selection.cpp +++ b/radiant/selection.cpp @@ -1119,13 +1119,13 @@ public: void render( RenderStateFlags state ) const { for ( std::size_t i = 0; i < m_primitives.size(); ++i ) { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_primitives[i].m_points[0].colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_primitives[i].m_points[0].vertex ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_primitives[i].m_points[0].colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_primitives[i].m_points[0].vertex ); switch ( m_primitives[i].m_count ) { case 1: break; - case 2: glDrawArrays( GL_LINES, 0, GLsizei( m_primitives[i].m_count ) ); break; - default: glDrawArrays( GL_POLYGON, 0, GLsizei( m_primitives[i].m_count ) ); break; + case 2: gl().glDrawArrays( GL_LINES, 0, GLsizei( m_primitives[i].m_count ) ); break; + default: gl().glDrawArrays( GL_POLYGON, 0, GLsizei( m_primitives[i].m_count ) ); break; } } } @@ -1546,9 +1546,9 @@ class RotateManipulator : public Manipulator RenderableCircle( std::size_t size ) : m_vertices( size ){ } void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_vertices.data()->colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex ); - glDrawArrays( GL_LINE_LOOP, 0, GLsizei( m_vertices.size() ) ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_vertices.data()->colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex ); + gl().glDrawArrays( GL_LINE_LOOP, 0, GLsizei( m_vertices.size() ) ); } void setColour( const Colour4b& colour ){ for ( Array::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i ) @@ -1565,9 +1565,9 @@ class RotateManipulator : public Manipulator RenderableSemiCircle( std::size_t size ) : m_vertices( size ){ } void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_vertices.data()->colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex ); - glDrawArrays( GL_LINE_STRIP, 0, GLsizei( m_vertices.size() ) ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_vertices.data()->colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex ); + gl().glDrawArrays( GL_LINE_STRIP, 0, GLsizei( m_vertices.size() ) ); } void setColour( const Colour4b& colour ){ for ( Array::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i ) @@ -1628,16 +1628,16 @@ public: } void updateCircleTransforms(){ - Vector3 localViewpoint( matrix4_transformed_direction( matrix4_transposed( m_pivot.m_worldSpace ), vector4_to_vector3( m_pivot.m_viewpointSpace.z() ) ) ); + Vector3 localViewpoint( matrix4_transformed_direction( matrix4_transposed( m_pivot.m_worldSpace ), m_pivot.m_viewpointSpace.z().vec3() ) ); m_circle_x_visible = !vector3_equal_epsilon( g_vector3_axis_x, localViewpoint, 1e-6f ); if ( m_circle_x_visible ) { m_local2world_x = g_matrix4_identity; - vector4_to_vector3( m_local2world_x.y() ) = normalised_safe( + m_local2world_x.y().vec3() = normalised_safe( vector3_cross( g_vector3_axis_x, localViewpoint ) ); - vector4_to_vector3( m_local2world_x.z() ) = normalised_safe( - vector3_cross( vector4_to_vector3( m_local2world_x.x() ), vector4_to_vector3( m_local2world_x.y() ) ) + m_local2world_x.z().vec3() = normalised_safe( + vector3_cross( m_local2world_x.x().vec3(), m_local2world_x.y().vec3() ) ); matrix4_premultiply_by_matrix4( m_local2world_x, m_pivot.m_worldSpace ); } @@ -1645,11 +1645,11 @@ public: m_circle_y_visible = !vector3_equal_epsilon( g_vector3_axis_y, localViewpoint, 1e-6f ); if ( m_circle_y_visible ) { m_local2world_y = g_matrix4_identity; - vector4_to_vector3( m_local2world_y.z() ) = normalised_safe( + m_local2world_y.z().vec3() = normalised_safe( vector3_cross( g_vector3_axis_y, localViewpoint ) ); - vector4_to_vector3( m_local2world_y.x() ) = normalised_safe( - vector3_cross( vector4_to_vector3( m_local2world_y.y() ), vector4_to_vector3( m_local2world_y.z() ) ) + m_local2world_y.x().vec3() = normalised_safe( + vector3_cross( m_local2world_y.y().vec3(), m_local2world_y.z().vec3() ) ); matrix4_premultiply_by_matrix4( m_local2world_y, m_pivot.m_worldSpace ); } @@ -1657,11 +1657,11 @@ public: m_circle_z_visible = !vector3_equal_epsilon( g_vector3_axis_z, localViewpoint, 1e-6f ); if ( m_circle_z_visible ) { m_local2world_z = g_matrix4_identity; - vector4_to_vector3( m_local2world_z.x() ) = normalised_safe( + m_local2world_z.x().vec3() = normalised_safe( vector3_cross( g_vector3_axis_z, localViewpoint ) ); - vector4_to_vector3( m_local2world_z.y() ) = normalised_safe( - vector3_cross( vector4_to_vector3( m_local2world_z.z() ), vector4_to_vector3( m_local2world_z.x() ) ) + m_local2world_z.y().vec3() = normalised_safe( + vector3_cross( m_local2world_z.z().vec3(), m_local2world_z.x().vec3() ) ); matrix4_premultiply_by_matrix4( m_local2world_z, m_pivot.m_worldSpace ); } @@ -1959,9 +1959,9 @@ class TranslateManipulator : public Manipulator, public ManipulatorSelectionChan RenderableArrowLine(){ } void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_line[0].colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_line[0].vertex ); - glDrawArrays( GL_LINES, 0, 2 ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_line[0].colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_line[0].vertex ); + gl().glDrawArrays( GL_LINES, 0, 2 ); } void setColour( const Colour4b& colour ){ m_line[0].colour = colour; @@ -1976,10 +1976,10 @@ class TranslateManipulator : public Manipulator, public ManipulatorSelectionChan : m_vertices( size ){ } void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( FlatShadedVertex ), &m_vertices.data()->colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( FlatShadedVertex ), &m_vertices.data()->vertex ); - glNormalPointer( GL_FLOAT, sizeof( FlatShadedVertex ), &m_vertices.data()->normal ); - glDrawArrays( GL_TRIANGLES, 0, GLsizei( m_vertices.size() ) ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( FlatShadedVertex ), &m_vertices.data()->colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( FlatShadedVertex ), &m_vertices.data()->vertex ); + gl().glNormalPointer( GL_FLOAT, sizeof( FlatShadedVertex ), &m_vertices.data()->normal ); + gl().glDrawArrays( GL_TRIANGLES, 0, GLsizei( m_vertices.size() ) ); } void setColour( const Colour4b& colour ){ for ( Array::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i ) @@ -1992,9 +1992,9 @@ class TranslateManipulator : public Manipulator, public ManipulatorSelectionChan { PointVertex m_quad[4]; void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_quad[0].colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_quad[0].vertex ); - glDrawArrays( GL_LINE_LOOP, 0, 4 ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_quad[0].colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_quad[0].vertex ); + gl().glDrawArrays( GL_LINE_LOOP, 0, 4 ); } void setColour( const Colour4b& colour ){ m_quad[0].colour = colour; @@ -2058,13 +2058,13 @@ public: // temp hack UpdateColours(); - Vector3 x = vector3_normalised( vector4_to_vector3( m_pivot.m_worldSpace.x() ) ); + Vector3 x = vector3_normalised( m_pivot.m_worldSpace.x().vec3() ); bool show_x = manipulator_show_axis( m_pivot, x ); - Vector3 y = vector3_normalised( vector4_to_vector3( m_pivot.m_worldSpace.y() ) ); + Vector3 y = vector3_normalised( m_pivot.m_worldSpace.y().vec3() ); bool show_y = manipulator_show_axis( m_pivot, y ); - Vector3 z = vector3_normalised( vector4_to_vector3( m_pivot.m_worldSpace.z() ) ); + Vector3 z = vector3_normalised( m_pivot.m_worldSpace.z().vec3() ); bool show_z = manipulator_show_axis( m_pivot, z ); renderer.SetState( m_state_wire, Renderer::eWireframeOnly ); @@ -2100,13 +2100,13 @@ public: SelectionPool selector; - Vector3 x = vector3_normalised( vector4_to_vector3( m_pivot.m_worldSpace.x() ) ); + Vector3 x = vector3_normalised( m_pivot.m_worldSpace.x().vec3() ); bool show_x = manipulator_show_axis( m_pivot, x ); - Vector3 y = vector3_normalised( vector4_to_vector3( m_pivot.m_worldSpace.y() ) ); + Vector3 y = vector3_normalised( m_pivot.m_worldSpace.y().vec3() ); bool show_y = manipulator_show_axis( m_pivot, y ); - Vector3 z = vector3_normalised( vector4_to_vector3( m_pivot.m_worldSpace.z() ) ); + Vector3 z = vector3_normalised( m_pivot.m_worldSpace.z().vec3() ); bool show_z = manipulator_show_axis( m_pivot, z ); { @@ -2197,9 +2197,9 @@ class ScaleManipulator : public Manipulator, public ManipulatorSelectionChangeab PointVertex m_line[2]; void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_line[0].colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_line[0].vertex ); - glDrawArrays( GL_LINES, 0, 2 ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_line[0].colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_line[0].vertex ); + gl().glDrawArrays( GL_LINES, 0, 2 ); } void setColour( const Colour4b& colour ){ m_line[0].colour = colour; @@ -2210,9 +2210,9 @@ class ScaleManipulator : public Manipulator, public ManipulatorSelectionChangeab { PointVertex m_quad[4]; void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_quad[0].colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_quad[0].vertex ); - glDrawArrays( GL_QUADS, 0, 4 ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_quad[0].colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_quad[0].vertex ); + gl().glDrawArrays( GL_QUADS, 0, 4 ); } void setColour( const Colour4b& colour ){ m_quad[0].colour = colour; @@ -2349,9 +2349,9 @@ class SkewManipulator : public Manipulator RenderableLine() { } void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_line[0].colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_line[0].vertex ); - glDrawArrays( GL_LINES, 0, 2 ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_line[0].colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_line[0].vertex ); + gl().glDrawArrays( GL_LINES, 0, 2 ); } void setColour( const Colour4b& colour ) { m_line[0].colour = colour; @@ -2366,10 +2366,10 @@ class SkewManipulator : public Manipulator : m_vertices( size ) { } void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( FlatShadedVertex ), &m_vertices.data()->colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( FlatShadedVertex ), &m_vertices.data()->vertex ); - glNormalPointer( GL_FLOAT, sizeof( FlatShadedVertex ), &m_vertices.data()->normal ); - glDrawArrays( GL_TRIANGLES, 0, GLsizei( m_vertices.size() ) ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( FlatShadedVertex ), &m_vertices.data()->colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( FlatShadedVertex ), &m_vertices.data()->vertex ); + gl().glNormalPointer( GL_FLOAT, sizeof( FlatShadedVertex ), &m_vertices.data()->normal ); + gl().glDrawArrays( GL_TRIANGLES, 0, GLsizei( m_vertices.size() ) ); } void setColour( const Colour4b & colour ) { for( Array::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i ) { @@ -2384,9 +2384,9 @@ class SkewManipulator : public Manipulator m_point( vertex3f_identity ) { } void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_point.colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_point.vertex ); - glDrawArrays( GL_POINTS, 0, 1 ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_point.colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_point.vertex ); + gl().glDrawArrays( GL_POINTS, 0, 1 ); } void setColour( const Colour4b & colour ) { m_point.colour = colour; @@ -4146,17 +4146,6 @@ DoubleVector3 testSelected_scene_snapped_point( const SelectionVolume& test, Cli return point; } -class Scene_insert_brush_vertices -{ - const Brush::VertexModeVertices& m_vertexModeVertices; -public: - Scene_insert_brush_vertices( const Brush::VertexModeVertices& vertexModeVertices ) : m_vertexModeVertices( vertexModeVertices ) { - } - void operator()( BrushInstance& brush ) const { - brush.insert_vertices( m_vertexModeVertices ); - } -}; - bool scene_insert_brush_vertices( const View& view, TranslateFreeXY_Z& freeDragXY_Z ){ SelectionVolume test( view ); ClipperSelector clipperSelector; @@ -4177,7 +4166,7 @@ bool scene_insert_brush_vertices( const View& view, TranslateFreeXY_Z& freeDragX vertexModeVertices.back().m_faces.push_back( clipperSelector.face() ); UndoableCommand undo( "InsertBrushVertices" ); - Scene_forEachSelectedBrush( Scene_insert_brush_vertices( vertexModeVertices ) ); + Scene_forEachSelectedBrush( [&vertexModeVertices]( BrushInstance& brush ){ brush.insert_vertices( vertexModeVertices ); } ); return true; } else if( !view.fill() ){ //+two points @@ -4195,7 +4184,7 @@ bool scene_insert_brush_vertices( const View& view, TranslateFreeXY_Z& freeDragX vertexModeVertices.push_back( Brush::VertexModeVertex( b, true ) ); UndoableCommand undo( "InsertBrushVertices" ); - Scene_forEachSelectedBrush( Scene_insert_brush_vertices( vertexModeVertices ) ); + Scene_forEachSelectedBrush( [&vertexModeVertices]( BrushInstance& brush ){ brush.insert_vertices( vertexModeVertices ); } ); return true; } } @@ -4257,10 +4246,10 @@ static bool g_bTmpComponentMode = false; class DragManipulator : public Manipulator { + ResizeTranslatable m_resize; TranslateFree m_freeResize; TranslateAxis2 m_axisResize; TranslateFreeXY_Z m_freeDragXY_Z; - ResizeTranslatable m_resize; DragNewBrush m_dragNewBrush; DragExtrudeFaces m_dragExtrudeFaces; bool m_dragSelected; //drag selected primitives or components @@ -4273,7 +4262,7 @@ public: static Shader* m_state_wire; - DragManipulator( Translatable& translatable ) : m_freeResize( m_resize ), m_axisResize( m_resize ), m_freeDragXY_Z( translatable ), m_renderCircle( 2 << 3 ){ + DragManipulator( Translatable& translatable ) : m_resize(), m_freeResize( m_resize ), m_axisResize( m_resize ), m_freeDragXY_Z( translatable ), m_renderCircle( 2 << 3 ){ setSelected( false ); draw_circle( m_renderCircle.m_vertices.size() >> 3, 5, m_renderCircle.m_vertices.data(), RemapXYZ() ); } @@ -4363,9 +4352,9 @@ public: start = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, bestPointSelector.best().depth(), 1 ) ) ); } else{ - const Vector3 near = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, -1, 1 ) ) ); - const Vector3 far = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, 1, 1 ) ) ); - start = vector3_normalised( far - near ) * ( 256.f + GetGridSize() * sqrt( 3.0 ) ) + near; + const Vector3 pnear = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, -1, 1 ) ) ); + const Vector3 pfar = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, 1, 1 ) ) ); + start = vector3_normalised( pfar - pnear ) * ( 256.f + GetGridSize() * sqrt( 3.0 ) ) + pnear; } vector3_snap( start, GetSnapGridSize() ); m_dragNewBrush.set0( start ); @@ -4478,12 +4467,12 @@ private: RenderablePoly( const std::vector>& polygons ) : m_polygons( polygons ){ } void render( RenderStateFlags state ) const { - glPolygonOffset( -2, -2 ); + gl().glPolygonOffset( -2, -2 ); for( const auto& poly : m_polygons ){ - glVertexPointer( 3, GL_FLOAT, sizeof( m_polygons[0][0] ), poly[0].data() ); - glDrawArrays( GL_POLYGON, 0, GLsizei( poly.size() ) ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( m_polygons[0][0] ), poly[0].data() ); + gl().glDrawArrays( GL_POLYGON, 0, GLsizei( poly.size() ) ); } - glPolygonOffset( -1, 1 ); // restore default + gl().glPolygonOffset( -1, 1 ); // restore default } }; RenderablePoly m_renderPoly{ m_polygons }; @@ -4495,8 +4484,8 @@ private: RenderableCircle( std::size_t size ) : m_vertices( size ){ } void render( RenderStateFlags state ) const { - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex ); - glDrawArrays( GL_LINE_LOOP, 0, GLsizei( m_vertices.size() ) ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex ); + gl().glDrawArrays( GL_LINE_LOOP, 0, GLsizei( m_vertices.size() ) ); } }; RenderableCircle m_renderCircle; @@ -4516,12 +4505,12 @@ class ClipManipulator : public Manipulator, public ManipulatorSelectionChangeabl m_p( vertex3f_identity ), m_set( false ) { } void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_p.colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_p.vertex ); - glDrawArrays( GL_POINTS, 0, 1 ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_p.colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_p.vertex ); + gl().glDrawArrays( GL_POINTS, 0, 1 ); - glColor4ub( m_p.colour.r, m_p.colour.g, m_p.colour.b, m_p.colour.a ); ///? - glRasterPos3f( m_namePos.x(), m_namePos.y(), m_namePos.z() ); + gl().glColor4ub( m_p.colour.r, m_p.colour.g, m_p.colour.b, m_p.colour.a ); ///? + gl().glRasterPos3f( m_namePos.x(), m_namePos.y(), m_namePos.z() ); GlobalOpenGL().drawChar( m_name ); } void setColour( const Colour4b& colour ) { @@ -4787,9 +4776,9 @@ class BuildManipulator : public Manipulator, public Manipulatable RenderableLine() { } void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_line[0].colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_line[0].vertex ); - glDrawArrays( GL_LINES, 0, 2 ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_line[0].colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_line[0].vertex ); + gl().glDrawArrays( GL_LINES, 0, 2 ); } void setColour( const Colour4b& colour ) { m_line[0].colour = colour; @@ -4803,9 +4792,9 @@ class BuildManipulator : public Manipulator, public Manipulatable m_point( vertex3f_identity ) { } void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_point.colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_point.vertex ); - glDrawArrays( GL_POINTS, 0, 1 ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_point.colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_point.vertex ); + gl().glDrawArrays( GL_POINTS, 0, 1 ); } void setColour( const Colour4b & colour ) { m_point.colour = colour; @@ -4880,9 +4869,9 @@ class UVManipulator : public Manipulator, public Manipulatable m_point( vertex3f_identity ) { } void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_point.colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_point.vertex ); - glDrawArrays( GL_POINTS, 0, 1 ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_point.colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_point.vertex ); + gl().glDrawArrays( GL_POINTS, 0, 1 ); } void setColour( const Colour4b & colour ) { m_point.colour = colour; @@ -4894,9 +4883,9 @@ class UVManipulator : public Manipulator, public Manipulatable RenderablePoints(){ } void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_points[0].colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_points[0].vertex ); - glDrawArrays( GL_POINTS, 0, m_points.size() ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_points[0].colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_points[0].vertex ); + gl().glDrawArrays( GL_POINTS, 0, m_points.size() ); } }; struct RenderableLines : public OpenGLRenderable @@ -4906,9 +4895,9 @@ class UVManipulator : public Manipulator, public Manipulatable } void render( RenderStateFlags state ) const { if( m_lines.size() != 0 ){ - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_lines[0].colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_lines[0].vertex ); - glDrawArrays( GL_LINES, 0, m_lines.size() ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_lines[0].colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_lines[0].vertex ); + gl().glDrawArrays( GL_LINES, 0, m_lines.size() ); } } }; @@ -4919,9 +4908,9 @@ class UVManipulator : public Manipulator, public Manipulatable RenderableCircle( std::size_t size ) : m_vertices( size ){ } void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_vertices.data()->colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex ); - glDrawArrays( GL_LINE_LOOP, 0, GLsizei( m_vertices.size() ) ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_vertices.data()->colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex ); + gl().glDrawArrays( GL_LINE_LOOP, 0, GLsizei( m_vertices.size() ) ); } void setColour( const Colour4b& colour ){ for ( Array::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i ) @@ -4940,10 +4929,10 @@ class UVManipulator : public Manipulator, public Manipulatable void render( RenderStateFlags state ) const { if( state & RENDER_FILL ){ const std::vector normals( m_patchControlArray->size(), g_vector3_axis_z ); - glNormalPointer( GL_FLOAT, sizeof( Vector3 ), normals.data() ); - glVertexPointer( 2, GL_FLOAT, sizeof( PatchControl ), &m_patchControlArray->data()->m_texcoord ); - glTexCoordPointer( 2, GL_FLOAT, sizeof( PatchControl ), &m_patchControlArray->data()->m_texcoord ); - glDrawElements( GL_TRIANGLES, GLsizei( m_trianglesIndices.size() ), RenderIndexTypeID, m_trianglesIndices.data() ); + gl().glNormalPointer( GL_FLOAT, sizeof( Vector3 ), normals.data() ); + gl().glVertexPointer( 2, GL_FLOAT, sizeof( PatchControl ), &m_patchControlArray->data()->m_texcoord ); + gl().glTexCoordPointer( 2, GL_FLOAT, sizeof( PatchControl ), &m_patchControlArray->data()->m_texcoord ); + gl().glDrawElements( GL_TRIANGLES, GLsizei( m_trianglesIndices.size() ), RenderIndexTypeID, m_trianglesIndices.data() ); } } }; @@ -5139,9 +5128,10 @@ private: } bool projection_valid() const { return !( !std::isfinite( m_local2tex[0] ) //nan - || fabs( vector3_dot( m_plane.normal(), vector4_to_vector3( m_tex2local.z() ) ) ) < 1e-6 //projected along face - || vector3_length_squared( vector4_to_vector3( m_tex2local.x() ) ) < .01 //srsly scaled down, limit at max 10 textures per world unit - || vector3_length_squared( vector4_to_vector3( m_tex2local.y() ) ) < .01 ); + || !std::isfinite( m_tex2local[0] ) //nan + || fabs( vector3_dot( m_plane.normal(), m_tex2local.z().vec3() ) ) < 1e-6 //projected along face + || vector3_length_squared( m_tex2local.x().vec3() ) < .01 //srsly scaled down, limit at max 10 textures per world unit + || vector3_length_squared( m_tex2local.y().vec3() ) < .01 ); } void UpdateFaceData( bool updateOrigin, bool updateLines = true ) { //!? todo fewer outer quads for large textures @@ -5268,12 +5258,12 @@ private: } m_faceTex2local = m_tex2local; - vector4_to_vector3( m_faceTex2local.x() ) = plane3_project_point( Plane3( m_plane.normal(), 0 ), vector4_to_vector3( m_tex2local.x() ), vector4_to_vector3( m_tex2local.z() ) ); - vector4_to_vector3( m_faceTex2local.y() ) = plane3_project_point( Plane3( m_plane.normal(), 0 ), vector4_to_vector3( m_tex2local.y() ), vector4_to_vector3( m_tex2local.z() ) ); + m_faceTex2local.x().vec3() = plane3_project_point( Plane3( m_plane.normal(), 0 ), m_tex2local.x().vec3(), m_tex2local.z().vec3() ); + m_faceTex2local.y().vec3() = plane3_project_point( Plane3( m_plane.normal(), 0 ), m_tex2local.y().vec3(), m_tex2local.z().vec3() ); m_faceTex2local = matrix4_multiplied_by_matrix4( // adjust to have UV's z = 0: move the plane along m_tex2local.z() so that plane.dist() = 0 matrix4_translation_for_vec3( - vector4_to_vector3( m_tex2local.z() ) * ( m_plane.dist() - vector3_dot( m_plane.normal(), vector4_to_vector3( m_tex2local.t() ) ) ) - / vector3_dot( m_plane.normal(), vector4_to_vector3( m_tex2local.z() ) ) + m_tex2local.z().vec3() * ( m_plane.dist() - vector3_dot( m_plane.normal(), m_tex2local.t().vec3() ) ) + / vector3_dot( m_plane.normal(), m_tex2local.z().vec3() ) ), m_faceTex2local ); m_faceLocal2tex = matrix4_affine_inverse( m_faceTex2local ); @@ -5380,9 +5370,9 @@ private: } m_pivot2world = m_tex2local; - vector3_normalise( vector4_to_vector3( m_pivot2world.x() ) ); - vector3_normalise( vector4_to_vector3( m_pivot2world.y() ) ); - vector4_to_vector3( m_pivot2world.t() ) = m_origin; + vector3_normalise( m_pivot2world.x().vec3() ); + vector3_normalise( m_pivot2world.y().vec3() ); + m_pivot2world.t().vec3() = m_origin; m_pivot2world0 = m_pivot2world; { @@ -5395,11 +5385,11 @@ private: } ); bestDist = sqrt( bestDist ); m_circle2world = g_matrix4_identity; - ComputeAxisBase( m_plane.normal(), vector4_to_vector3( m_circle2world.x() ), vector4_to_vector3( m_circle2world.y() ) ); - vector4_to_vector3( m_circle2world.x() ) *= bestDist; - vector4_to_vector3( m_circle2world.y() ) *= bestDist; - vector4_to_vector3( m_circle2world.z() ) = m_plane.normal(); - vector4_to_vector3( m_circle2world.t() ) = m_origin; + ComputeAxisBase( m_plane.normal(), m_circle2world.x().vec3(), m_circle2world.y().vec3() ); + m_circle2world.x().vec3() *= bestDist; + m_circle2world.y().vec3() *= bestDist; + m_circle2world.z().vec3() = m_plane.normal(); + m_circle2world.t().vec3() = m_origin; } min -= Vector2( 5, 5 ); @@ -5907,13 +5897,13 @@ public: } } ); Vector3 result( uv_origin_start ); - if( bestDistU * vector3_length( vector4_to_vector3( m_faceTex2local.y() ) ) < 3 || snapHard ){ + if( bestDistU * vector3_length( m_faceTex2local.y().vec3() ) < 3 || snapHard ){ result.y() = snapToU; } else{ result.y() = uv_origin.y(); } - if( bestDistV * vector3_length( vector4_to_vector3( m_faceTex2local.x() ) ) < 3 || snapHard ){ + if( bestDistV * vector3_length( m_faceTex2local.x().vec3() ) < 3 || snapHard ){ result.x() = snapToV; } else{ @@ -5945,7 +5935,7 @@ public: } } ); Vector3 result( uv_origin_start ); - if( bestDist * vector3_length( vector4_to_vector3( m_faceTex2local.y() ) ) < 3 || snapHard ){ + if( bestDist * vector3_length( m_faceTex2local.y().vec3() ) < 3 || snapHard ){ result.y() = snapTo; } else{ @@ -5977,7 +5967,7 @@ public: } } ); Vector3 result( uv_origin_start ); - if( bestDist * vector3_length( vector4_to_vector3( m_faceTex2local.x() ) ) < 3 || snapHard ){ + if( bestDist * vector3_length( m_faceTex2local.x().vec3() ) < 3 || snapHard ){ result.x() = snapTo; } else{ @@ -6045,31 +6035,31 @@ public: case eCircle: { Vector3 from = m_start - m_origin; - constrain_to_axis( from, vector4_to_vector3( m_tex2local.z() ) ); + constrain_to_axis( from, m_tex2local.z().vec3() ); Vector3 to = current - m_origin; - constrain_to_axis( to, vector4_to_vector3( m_tex2local.z() ) ); + constrain_to_axis( to, m_tex2local.z().vec3() ); Matrix4 rot = g_matrix4_identity; if( snap ){ matrix4_pivoted_rotate_by_axisangle( rot, - vector4_to_vector3( m_tex2local.z() ), - float_snapped( angle_for_axis( from, to, vector4_to_vector3( m_tex2local.z() ) ), static_cast( c_pi / 12.0 ) ), + m_tex2local.z().vec3(), + float_snapped( angle_for_axis( from, to, m_tex2local.z().vec3() ), static_cast( c_pi / 12.0 ) ), m_origin ); } else{ matrix4_pivoted_rotate_by_axisangle( rot, - vector4_to_vector3( m_tex2local.z() ), - angle_for_axis( from, to, vector4_to_vector3( m_tex2local.z() ) ), + m_tex2local.z().vec3(), + angle_for_axis( from, to, m_tex2local.z().vec3() ), m_origin ); } { // snap - const Vector3 uvec = vector3_normalised( matrix4_transformed_direction( rot, vector4_to_vector3( m_tex2local.x() ) ) ); - const Vector3 vvec = vector3_normalised( matrix4_transformed_direction( rot, vector4_to_vector3( m_tex2local.y() ) ) ); + const Vector3 uvec = vector3_normalised( matrix4_transformed_direction( rot, m_tex2local.x().vec3() ) ); + const Vector3 vvec = vector3_normalised( matrix4_transformed_direction( rot, m_tex2local.y().vec3() ) ); float bestDot = 0; Vector3 bestTo; bool V = false; forEachEdge( [&]( const Vector3& point0, const Vector3& point1 ){ Vector3 vec( point1 - point0 ); - constrain_to_axis( vec, vector4_to_vector3( m_tex2local.z() ) ); + constrain_to_axis( vec, m_tex2local.z().vec3() ); const float dotU = fabs( vector3_dot( uvec, vec ) ); if( dotU > bestDot ){ bestDot = dotU; @@ -6084,22 +6074,22 @@ public: } } ); if( bestDot > 0.9994f || snapHard ){ - const Vector3 bestFrom = vector3_normalised( vector4_to_vector3( V? m_tex2local.y() : m_tex2local.x() ) ); + const Vector3 bestFrom = vector3_normalised( V? m_tex2local.y().vec3() : m_tex2local.x().vec3() ); rot = g_matrix4_identity; matrix4_pivoted_rotate_by_axisangle( rot, - vector4_to_vector3( m_tex2local.z() ), - angle_for_axis( bestFrom, bestTo, vector4_to_vector3( m_tex2local.z() ) ), + m_tex2local.z().vec3(), + angle_for_axis( bestFrom, bestTo, m_tex2local.z().vec3() ), m_origin ); } } Matrix4 faceTex2local = matrix4_multiplied_by_matrix4( rot, m_tex2local ); - vector4_to_vector3( faceTex2local.x() ) = plane3_project_point( Plane3( m_plane.normal(), 0 ), vector4_to_vector3( faceTex2local.x() ), vector4_to_vector3( m_tex2local.z() ) ); - vector4_to_vector3( faceTex2local.y() ) = plane3_project_point( Plane3( m_plane.normal(), 0 ), vector4_to_vector3( faceTex2local.y() ), vector4_to_vector3( m_tex2local.z() ) ); + faceTex2local.x().vec3() = plane3_project_point( Plane3( m_plane.normal(), 0 ), faceTex2local.x().vec3(), m_tex2local.z().vec3() ); + faceTex2local.y().vec3() = plane3_project_point( Plane3( m_plane.normal(), 0 ), faceTex2local.y().vec3(), m_tex2local.z().vec3() ); faceTex2local = matrix4_multiplied_by_matrix4( // adjust to have UV's z = 0: move the plane along m_tex2local.z() so that plane.dist() = 0 matrix4_translation_for_vec3( - vector4_to_vector3( m_tex2local.z() ) * ( m_plane.dist() - vector3_dot( m_plane.normal(), vector4_to_vector3( faceTex2local.t() ) ) ) - / vector3_dot( m_plane.normal(), vector4_to_vector3( m_tex2local.z() ) ) + m_tex2local.z().vec3() * ( m_plane.dist() - vector3_dot( m_plane.normal(), faceTex2local.t().vec3() ) ) + / vector3_dot( m_plane.normal(), m_tex2local.z().vec3() ) ), faceTex2local ); m_lines2world = m_pivotLines2world = faceTex2local; @@ -6124,7 +6114,7 @@ public: } } ); Vector3 result( 1, uv_current.y(), 1 ); - if( bestDist * vector3_length( vector4_to_vector3( m_faceTex2local.y() ) ) < 3 || snapHard ){ + if( bestDist * vector3_length( m_faceTex2local.y().vec3() ) < 3 || snapHard ){ result.y() = snapTo; } result.y() = ( result.y() - uv_origin.y() ) / ( uv_start.y() - uv_origin.y() ); @@ -6133,7 +6123,7 @@ public: result.x() = fabs( result.y() ); /* prevent scaling to 0, limit at max 10 textures per world unit */ - if( vector3_length_squared( vector4_to_vector3( m_tex2local.y() ) * result.y() ) < .01 ) + if( vector3_length_squared( m_tex2local.y().vec3() * result.y() ) < .01 ) return; Matrix4 scale = g_matrix4_identity; @@ -6164,7 +6154,7 @@ public: } } ); Vector3 result( uv_current.x(), 1, 1 ); - if( bestDist * vector3_length( vector4_to_vector3( m_faceTex2local.x() ) ) < 3 || snapHard ){ + if( bestDist * vector3_length( m_faceTex2local.x().vec3() ) < 3 || snapHard ){ result.x() = snapTo; } result.x() = ( result.x() - uv_origin.x() ) / ( uv_start.x() - uv_origin.x() ); @@ -6173,7 +6163,7 @@ public: result.y() = fabs( result.x() ); /* prevent scaling to 0, limit at max 10 textures per world unit */ - if( vector3_length_squared( vector4_to_vector3( m_tex2local.x() ) * result.x() ) < .01 ) + if( vector3_length_squared( m_tex2local.x().vec3() * result.x() ) < .01 ) return; Matrix4 scale = g_matrix4_identity; @@ -6214,12 +6204,12 @@ public: } ); Vector3 result( uv_current.x(), uv_current.y(), 1 ); - if( bestDistU * vector3_length( vector4_to_vector3( m_faceTex2local.y() ) ) < 3 || snapHard ){ + if( bestDistU * vector3_length( m_faceTex2local.y().vec3() ) < 3 || snapHard ){ result.y() = snapToU; } result.y() = ( result.y() - uv_origin.y() ) / ( uv_start.y() - uv_origin.y() ); - if( bestDistV * vector3_length( vector4_to_vector3( m_faceTex2local.x() ) ) < 3 || snapHard ){ + if( bestDistV * vector3_length( m_faceTex2local.x().vec3() ) < 3 || snapHard ){ result.x() = snapToV; } result.x() = ( result.x() - uv_origin.x() ) / ( uv_start.x() - uv_origin.x() ); @@ -6230,8 +6220,8 @@ public: } /* prevent scaling to 0, limit at max 10 textures per world unit */ - if( vector3_length_squared( vector4_to_vector3( m_tex2local.x() ) * result.x() ) < .01 || - vector3_length_squared( vector4_to_vector3( m_tex2local.y() ) * result.y() ) < .01 ) + if( vector3_length_squared( m_tex2local.x().vec3() * result.x() ) < .01 || + vector3_length_squared( m_tex2local.y().vec3() * result.y() ) < .01 ) return; Matrix4 scale = g_matrix4_identity; @@ -6255,7 +6245,7 @@ public: skew[4] = uv_move.x() / ( m_selectedU->vertex - uv_origin ).y(); Matrix4 scale = matrix4_scale_for_vec3( // scale snap measurement space so that x/y = 1 - Vector3( vector3_length( vector4_to_vector3( m_faceTex2local.x() ) ) / vector3_length( vector4_to_vector3( m_faceTex2local.y() ) ), + Vector3( vector3_length( m_faceTex2local.x().vec3() ) / vector3_length( m_faceTex2local.y().vec3() ), 1, 1 ) ); const Vector3 skewed = vector3_normalised( matrix4_transformed_direction( matrix4_multiplied_by_matrix4( scale, skew ), g_vector3_axis_y ) ); matrix4_multiply_by_matrix4( scale, m_faceLocal2tex ); @@ -6301,7 +6291,7 @@ public: skew[1] = uv_move.y() / ( m_selectedV->vertex - uv_origin ).x(); Matrix4 scale = matrix4_scale_for_vec3( // scale snap measurement space so that x/y = 1 - Vector3( vector3_length( vector4_to_vector3( m_faceTex2local.x() ) ) / vector3_length( vector4_to_vector3( m_faceTex2local.y() ) ), + Vector3( vector3_length( m_faceTex2local.x().vec3() ) / vector3_length( m_faceTex2local.y().vec3() ), 1, 1 ) ); const Vector3 skewed = vector3_normalised( matrix4_transformed_direction( matrix4_multiplied_by_matrix4( scale, skew ), g_vector3_axis_x ) ); matrix4_multiply_by_matrix4( scale, m_faceLocal2tex ); @@ -6369,16 +6359,16 @@ public: functor( matrix4_transformed_point( m_faceLocal2tex, m_origin ) ); Vector3 result( uvmove ); - if( bestDistU * vector3_length( vector4_to_vector3( m_faceTex2local.y() ) ) < 3 || snapHard ){ + if( bestDistU * vector3_length( m_faceTex2local.y().vec3() ) < 3 || snapHard ){ result.y() = snapMoveU; } - if( bestDistV * vector3_length( vector4_to_vector3( m_faceTex2local.x() ) ) < 3 || snapHard ){ + if( bestDistV * vector3_length( m_faceTex2local.x().vec3() ) < 3 || snapHard ){ result.x() = snapMoveV; } if( snap ){ - auto& smaller = fabs( uvmove.x() * vector3_length( vector4_to_vector3( m_faceTex2local.x() ) ) ) < - fabs( uvmove.y() * vector3_length( vector4_to_vector3( m_faceTex2local.y() ) ) )? result.x() : result.y(); + auto& smaller = fabs( uvmove.x() * vector3_length( m_faceTex2local.x().vec3() ) ) < + fabs( uvmove.y() * vector3_length( m_faceTex2local.y().vec3() ) )? result.x() : result.y(); smaller = 0; } @@ -6446,16 +6436,16 @@ public: } Vector3 result( uvmove ); - if( bestDistU * vector3_length( vector4_to_vector3( m_faceTex2local.y() ) ) < 3 || snapHard ){ + if( bestDistU * vector3_length( m_faceTex2local.y().vec3() ) < 3 || snapHard ){ result.y() = snapMoveU; } - if( bestDistV * vector3_length( vector4_to_vector3( m_faceTex2local.x() ) ) < 3 || snapHard ){ + if( bestDistV * vector3_length( m_faceTex2local.x().vec3() ) < 3 || snapHard ){ result.x() = snapMoveV; } if( snap ){ - auto& smaller = fabs( uvmove.x() * vector3_length( vector4_to_vector3( m_faceTex2local.x() ) ) ) < - fabs( uvmove.y() * vector3_length( vector4_to_vector3( m_faceTex2local.y() ) ) )? result.x() : result.y(); + auto& smaller = fabs( uvmove.x() * vector3_length( m_faceTex2local.x().vec3() ) ) < + fabs( uvmove.y() * vector3_length( m_faceTex2local.y().vec3() ) )? result.x() : result.y(); smaller = 0; } @@ -6584,9 +6574,9 @@ class TransformOriginManipulator : public Manipulator, public ManipulatorSelecti m_point( vertex3f_identity ) { } void render( RenderStateFlags state ) const { - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_point.colour ); - glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_point.vertex ); - glDrawArrays( GL_POINTS, 0, 1 ); + gl().glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_point.colour ); + gl().glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_point.vertex ); + gl().glDrawArrays( GL_POINTS, 0, 1 ); } void setColour( const Colour4b & colour ) { m_point.colour = colour; @@ -7010,11 +7000,11 @@ public: Matrix4 device2manip; ConstructDevice2Manip( device2manip, m_pivot2world_start, view.GetModelview(), view.GetProjection(), view.GetViewport() ); if( m_pivot_moving ){ - m_manipulator->GetManipulatable()->Construct( device2manip, device_point[0], device_point[1], m_bounds, vector4_to_vector3( GetPivot2World().t() ) ); + m_manipulator->GetManipulatable()->Construct( device2manip, device_point[0], device_point[1], m_bounds, GetPivot2World().t().vec3() ); m_undo_begun = false; } else if( movingOrigin ){ - m_transformOrigin_manipulator.GetManipulatable()->Construct( device2manip, device_point[0], device_point[1], m_bounds, vector4_to_vector3( GetPivot2World().t() ) ); + m_transformOrigin_manipulator.GetManipulatable()->Construct( device2manip, device_point[0], device_point[1], m_bounds, GetPivot2World().t().vec3() ); } } @@ -7340,16 +7330,16 @@ public: m_rotation = rotation; m_repeatableTransforms.m_rotation = rotation; if( ( m_repeatableTransforms.m_rotationOriginSet = m_pivotIsCustom ) ) - m_repeatableTransforms.m_rotationOrigin = vector4_to_vector3( m_pivot2world.t() ); + m_repeatableTransforms.m_rotationOrigin = m_pivot2world.t().vec3(); if ( Mode() == eComponent ) { - Scene_Rotate_Component_Selected( GlobalSceneGraph(), m_rotation, vector4_to_vector3( m_pivot2world.t() ) ); + Scene_Rotate_Component_Selected( GlobalSceneGraph(), m_rotation, m_pivot2world.t().vec3() ); matrix4_assign_rotation_for_pivot( m_pivot2world, m_component_selection.back() ); } else { - Scene_Rotate_Selected( GlobalSceneGraph(), m_rotation, vector4_to_vector3( m_pivot2world.t() ) ); + Scene_Rotate_Selected( GlobalSceneGraph(), m_rotation, m_pivot2world.t().vec3() ); matrix4_assign_rotation_for_pivot( m_pivot2world, m_selection.back() ); } @@ -7368,14 +7358,14 @@ public: m_scale = scaling; m_repeatableTransforms.m_scale = scaling; if( ( m_repeatableTransforms.m_scaleOriginSet = m_pivotIsCustom ) ) - m_repeatableTransforms.m_scaleOrigin = vector4_to_vector3( m_pivot2world.t() ); + m_repeatableTransforms.m_scaleOrigin = m_pivot2world.t().vec3(); if ( Mode() == eComponent ) { - Scene_Scale_Component_Selected( GlobalSceneGraph(), m_scale, vector4_to_vector3( m_pivot2world.t() ) ); + Scene_Scale_Component_Selected( GlobalSceneGraph(), m_scale, m_pivot2world.t().vec3() ); } else { - Scene_Scale_Selected( GlobalSceneGraph(), m_scale, vector4_to_vector3( m_pivot2world.t() ) ); + Scene_Scale_Selected( GlobalSceneGraph(), m_scale, m_pivot2world.t().vec3() ); } if( ManipulatorMode() == eSkew ){ @@ -7396,14 +7386,14 @@ public: m_skew = skew; m_repeatableTransforms.m_skew = skew; if( ( m_repeatableTransforms.m_skewOriginSet = m_pivotIsCustom ) ) - m_repeatableTransforms.m_skewOrigin = vector4_to_vector3( m_pivot2world.t() ); + m_repeatableTransforms.m_skewOrigin = m_pivot2world.t().vec3(); if ( Mode() == eComponent ) { - Scene_Skew_Component_Selected( GlobalSceneGraph(), m_skew, vector4_to_vector3( m_pivot2world.t() ) ); + Scene_Skew_Component_Selected( GlobalSceneGraph(), m_skew, m_pivot2world.t().vec3() ); } else { - Scene_Skew_Selected( GlobalSceneGraph(), m_skew, vector4_to_vector3( m_pivot2world.t() ) ); + Scene_Skew_Selected( GlobalSceneGraph(), m_skew, m_pivot2world.t().vec3() ); } m_pivot2world[skew.index] = skew.amount; SceneChangeNotify(); @@ -7412,7 +7402,7 @@ public: void rotateSelected( const Quaternion& rotation, bool snapOrigin = false ){ if( snapOrigin && !m_pivotIsCustom ) - vector3_snap( vector4_to_vector3( m_pivot2world.t() ), GetSnapGridSize() ); + vector3_snap( m_pivot2world.t().vec3(), GetSnapGridSize() ); startMove(); rotate( rotation ); freezeTransforms(); @@ -7424,7 +7414,7 @@ public: } void scaleSelected( const Vector3& scaling, bool snapOrigin = false ){ if( snapOrigin && !m_pivotIsCustom ) - vector3_snap( vector4_to_vector3( m_pivot2world.t() ), GetSnapGridSize() ); + vector3_snap( m_pivot2world.t().vec3(), GetSnapGridSize() ); startMove(); scale( scaling ); freezeTransforms(); @@ -7439,11 +7429,11 @@ public: if( Mode() == ePrimitive ) clone(); if ( Mode() == eComponent ) { - GlobalSelectionSystem().foreachSelectedComponent( transform_component_selected( m_repeatableTransforms, vector4_to_vector3( m_pivot2world.t() ) ) ); + GlobalSelectionSystem().foreachSelectedComponent( transform_component_selected( m_repeatableTransforms, m_pivot2world.t().vec3() ) ); } else { - GlobalSelectionSystem().foreachSelected( transform_selected( m_repeatableTransforms, vector4_to_vector3( m_pivot2world.t() ) ) ); + GlobalSelectionSystem().foreachSelected( transform_selected( m_repeatableTransforms, m_pivot2world.t().vec3() ) ); } freezeTransforms(); } @@ -7458,7 +7448,7 @@ public: void transformOriginTranslate( const Vector3& translation, const bool set[3] ){ m_pivot2world = m_pivot2world_start; - setCustomTransformOrigin( translation + vector4_to_vector3( m_pivot2world_start.t() ), set ); + setCustomTransformOrigin( translation + m_pivot2world_start.t().vec3(), set ); SceneChangeNotify(); } @@ -7695,9 +7685,9 @@ void Scene_Intersect( const View& view, const float device_point[2], const float intersection = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, bestPointSelector.best().depth(), 1 ) ) ); } else{ - const Vector3 near = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, -1, 1 ) ) ); - const Vector3 far = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, 1, 1 ) ) ); - intersection = vector3_normalised( far - near ) * 256.f + near; + const Vector3 pnear = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, -1, 1 ) ) ); + const Vector3 pfar = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, 1, 1 ) ) ); + intersection = vector3_normalised( pfar - pnear ) * 256.f + pnear; } } @@ -7787,11 +7777,11 @@ inline AABB Instance_getPivotBounds( scene::Instance& instance ){ || !node_is_group( instance.path().top() ) ) ) { Editable* editable = Node_getEditable( instance.path().top() ); if ( editable != 0 ) { - return AABB( vector4_to_vector3( matrix4_multiplied_by_matrix4( instance.localToWorld(), editable->getLocalPivot() ).t() ), Vector3( 0, 0, 0 ) ); + return AABB( matrix4_multiplied_by_matrix4( instance.localToWorld(), editable->getLocalPivot() ).t().vec3(), Vector3( 0, 0, 0 ) ); } else { - return AABB( vector4_to_vector3( instance.localToWorld().t() ), Vector3( 0, 0, 0 ) ); + return AABB( instance.localToWorld().t().vec3(), Vector3( 0, 0, 0 ) ); } } @@ -7906,7 +7896,7 @@ void RadiantSelectionSystem::ConstructPivot() const { m_pivot2world = matrix4_translation_for_vec3( object_pivot ); } else{ -// m_pivot2world = matrix4_translation_for_vec3( vector4_to_vector3( m_pivot2world.t() ) ); +// m_pivot2world = matrix4_translation_for_vec3( m_pivot2world.t().vec3() ); matrix4_assign_rotation( m_pivot2world, g_matrix4_identity ); } @@ -7997,7 +7987,7 @@ void RadiantSelectionSystem::renderSolid( Renderer& renderer, const VolumeTest& bool g_bLeftMouseClickSelector = true; void SelectionSystem_constructPreferences( PreferencesPage& page ){ - page.appendSpinner( "Selector size (pixels)", g_SELECT_EPSILON, 8, 2, 64 ); + page.appendSpinner( "Selector size (pixels)", g_SELECT_EPSILON, 2, 64 ); page.appendCheckBox( "", "Prefer point entities in 2D", getSelectionSystem().m_bPreferPointEntsIn2D ); page.appendCheckBox( "", "Left mouse click tunnel selector", g_bLeftMouseClickSelector ); { diff --git a/radiant/server.cpp b/radiant/server.cpp index 81ea5efa..53b2b6a5 100644 --- a/radiant/server.cpp +++ b/radiant/server.cpp @@ -22,7 +22,6 @@ #include "server.h" #include "debugging/debugging.h" -#include "warnings.h" #include #include diff --git a/radiant/server.h b/radiant/server.h index e1d4e8b1..21914072 100644 --- a/radiant/server.h +++ b/radiant/server.h @@ -21,8 +21,7 @@ #pragma once -class ModuleServer; -ModuleServer& GlobalModuleServer_get(); +class ModuleServer& GlobalModuleServer_get(); void GlobalModuleServer_loadModule( const char* filename ); void GlobalModuleServer_Initialise(); void GlobalModuleServer_Shutdown(); diff --git a/radiant/stacktrace.cpp b/radiant/stacktrace.cpp index d6944b92..cf5b70ea 100644 --- a/radiant/stacktrace.cpp +++ b/radiant/stacktrace.cpp @@ -266,7 +266,7 @@ void write_stack_trace( PCONTEXT pContext, TextOutputStream& outputStream ){ DWORD dwLineDisplacement; if ( SymGetLineFromAddr64( m_hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo ) ) { - outputStream << " " << lineInfo.FileName << " line " << Unsigned( lineInfo.LineNumber ); + outputStream << " " << lineInfo.FileName << " line " << lineInfo.LineNumber; } } else diff --git a/radiant/stacktrace.h b/radiant/stacktrace.h index 430980aa..e45cb41a 100644 --- a/radiant/stacktrace.h +++ b/radiant/stacktrace.h @@ -21,5 +21,4 @@ #pragma once -class TextOutputStream; -void write_stack_trace( TextOutputStream& outputStream ); +void write_stack_trace( class TextOutputStream& outputStream ); diff --git a/radiant/surfacedialog.cpp b/radiant/surfacedialog.cpp index 8c41a54d..1419d79c 100644 --- a/radiant/surfacedialog.cpp +++ b/radiant/surfacedialog.cpp @@ -28,15 +28,21 @@ #include "surfacedialog.h" #include "debugging/debugging.h" -#include "warnings.h" #include "iscenegraph.h" #include "itexdef.h" #include "iundo.h" #include "iselection.h" -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "signal/isignal.h" #include "generic/object.h" @@ -50,9 +56,9 @@ #include "gtkutil/dialog.h" #include "gtkutil/entry.h" #include "gtkutil/nonmodal.h" -#include "gtkutil/pointer.h" #include "gtkutil/glwidget.h" //Shamus: For Textool -#include "gtkutil/button.h" +#include "gtkutil/guisettings.h" +#include "gtkutil/spinbox.h" #include "map.h" #include "select.h" #include "patchmanip.h" @@ -71,57 +77,13 @@ #include "grid.h" #include "textureentry.h" -//NOTE: Proper functioning of Textool currently requires that the "#if 1" lines in -// brush_primit.h be changed to "#if 0". add/removeScale screws this up ATM. :-) -// Plus, Radiant seems to work just fine without that stuff. ;-) - -#define TEXTOOL_ENABLED 0 - -#if TEXTOOL_ENABLED - -namespace TexTool -{ - -//Shamus: Textool function prototypes -gboolean size_allocate( GtkWidget *, GtkAllocation *, gpointer ); -gboolean expose( GtkWidget *, GdkEventExpose *, gpointer ); -gboolean button_press( GtkWidget *, GdkEventButton *, gpointer ); -gboolean button_release( GtkWidget *, GdkEventButton *, gpointer ); -gboolean motion( GtkWidget *, GdkEventMotion *, gpointer ); -void flipX( GtkToggleButton *, gpointer ); -void flipY( GtkToggleButton *, gpointer ); - -//End Textool function prototypes - -//Shamus: Textool globals -GtkWidget * g_textoolWin; -//End Textool globals - -void queueDraw(){ - gtk_widget_queue_draw( g_textoolWin ); -} - -} - -#endif - -inline void spin_button_set_step( GtkSpinButton* spin, gfloat step ){ -#if 1 - gtk_adjustment_set_step_increment( gtk_spin_button_get_adjustment( spin ), step ); -#else - GValue gvalue = GValue_default(); - g_value_init( &gvalue, G_TYPE_DOUBLE ); - g_value_set_double( &gvalue, step ); - g_object_set( G_OBJECT( gtk_spin_button_get_adjustment( spin ) ), "step-increment", &gvalue, NULL ); -#endif -} class Increment { float& m_f; public: - GtkSpinButton* m_spin; - GtkEntry* m_entry; + QDoubleSpinBox* m_spin; + QLineEdit* m_entry; Increment( float& f ) : m_f( f ), m_spin( 0 ), m_entry( 0 ){ } void cancel(){ @@ -129,8 +91,8 @@ public: } typedef MemberCaller CancelCaller; void apply(){ - m_f = static_cast( entry_get_float( m_entry ) ); - spin_button_set_step( m_spin, m_f ); + m_f = entry_get_float( m_entry ); + m_spin->setSingleStep( m_f ); } typedef MemberCaller ApplyCaller; }; @@ -139,31 +101,27 @@ void SurfaceInspector_GridChange(); class SurfaceInspector : public Dialog { - GtkWindow* BuildDialog(); + void BuildDialog() override; - NonModalEntry m_textureEntry; - NonModalSpinner m_hshiftSpinner; - NonModalEntry m_hshiftEntry; - NonModalSpinner m_vshiftSpinner; - NonModalEntry m_vshiftEntry; - NonModalSpinner m_hscaleSpinner; - NonModalEntry m_hscaleEntry; - NonModalSpinner m_vscaleSpinner; - NonModalEntry m_vscaleEntry; - NonModalSpinner m_rotateSpinner; - NonModalEntry m_rotateEntry; + NonModalEntry *m_textureEntry; + NonModalSpinner *m_hshiftSpinner; + NonModalEntry *m_hshiftEntry; + NonModalSpinner *m_vshiftSpinner; + NonModalEntry *m_vshiftEntry; + NonModalSpinner *m_hscaleSpinner; + NonModalEntry *m_hscaleEntry; + NonModalSpinner *m_vscaleSpinner; + NonModalEntry *m_vscaleEntry; + NonModalSpinner *m_rotateSpinner; + NonModalEntry *m_rotateEntry; IdleDraw m_idleDraw; - GtkCheckButton* m_surfaceFlags[32]; - GtkCheckButton* m_contentFlags[32]; + QCheckBox* m_surfaceFlags[32]; + QCheckBox* m_contentFlags[32]; - NonModalEntry m_valueEntry; - GtkEntry* m_valueEntryWidget; + NonModalEntry *m_valueEntry; public: - WindowPositionTracker m_positionTracker; - WindowPositionTrackerImportStringCaller m_importPosition; - WindowPositionTrackerExportStringCaller m_exportPosition; // Dialog Data float m_fitHorizontal; @@ -174,24 +132,9 @@ public: Increment m_hscaleIncrement; Increment m_vscaleIncrement; Increment m_rotateIncrement; - GtkEntry* m_texture; SurfaceInspector() : - m_textureEntry( ApplyShaderCaller( *this ), UpdateCaller( *this ) ), - m_hshiftSpinner( ApplyTexdef_HShiftCaller( *this ), UpdateCaller( *this ) ), - m_hshiftEntry( Increment::ApplyCaller( m_hshiftIncrement ), Increment::CancelCaller( m_hshiftIncrement ) ), - m_vshiftSpinner( ApplyTexdef_VShiftCaller( *this ), UpdateCaller( *this ) ), - m_vshiftEntry( Increment::ApplyCaller( m_vshiftIncrement ), Increment::CancelCaller( m_vshiftIncrement ) ), - m_hscaleSpinner( ApplyTexdef_HScaleCaller( *this ), UpdateCaller( *this ) ), - m_hscaleEntry( Increment::ApplyCaller( m_hscaleIncrement ), Increment::CancelCaller( m_hscaleIncrement ) ), - m_vscaleSpinner( ApplyTexdef_VScaleCaller( *this ), UpdateCaller( *this ) ), - m_vscaleEntry( Increment::ApplyCaller( m_vscaleIncrement ), Increment::CancelCaller( m_vscaleIncrement ) ), - m_rotateSpinner( ApplyTexdef_RotationCaller( *this ), UpdateCaller( *this ) ), - m_rotateEntry( Increment::ApplyCaller( m_rotateIncrement ), Increment::CancelCaller( m_rotateIncrement ) ), m_idleDraw( UpdateCaller( *this ) ), - m_valueEntry( ApplyFlagsCaller( *this ), UpdateCaller( *this ) ), - m_importPosition( m_positionTracker ), - m_exportPosition( m_positionTracker ), m_hshiftIncrement( g_si_globals.shift[0] ), m_vshiftIncrement( g_si_globals.shift[1] ), m_hscaleIncrement( g_si_globals.scale[0] ), @@ -199,19 +142,17 @@ public: m_rotateIncrement( g_si_globals.rotate ){ m_fitVertical = 1; m_fitHorizontal = 1; - m_positionTracker.setPosition( WindowPosition( -1, -1, 300, 400 ) ); } - void constructWindow( GtkWindow* main_window ){ - m_parent = main_window; - Create(); + void constructWindow( QWidget* main_window ){ + Create( main_window ); AddGridChangeCallback( FreeCaller() ); } void destroyWindow(){ Destroy(); } bool visible() const { - return gtk_widget_get_visible( GTK_WIDGET( GetWidget() ) ); + return GetWidget()->isVisible(); } void queueDraw(){ if ( visible() ) { @@ -251,7 +192,7 @@ inline SurfaceInspector& getSurfaceInspector(){ } } -void SurfaceInspector_constructWindow( GtkWindow* main_window ){ +void SurfaceInspector_constructWindow( QWidget* main_window ){ getSurfaceInspector().constructWindow( main_window ); } void SurfaceInspector_destroyWindow(){ @@ -267,7 +208,6 @@ namespace CopiedString g_selectedShader; TextureProjection g_selectedTexdef; ContentsFlagsValue g_selectedFlags; -size_t g_selectedShaderSize[2]; } void SurfaceInspector_SetSelectedShader( const char* shader ){ @@ -286,17 +226,11 @@ void SurfaceInspector_SetSelectedFlags( const ContentsFlagsValue& flags ){ } static bool s_texture_selection_dirty = false; +static bool s_patch_mode = false; void SurfaceInspector_updateSelection(){ s_texture_selection_dirty = true; SurfaceInspector_queueDraw(); - -#if TEXTOOL_ENABLED - if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES ) { - TexTool::queueDraw(); - //globalOutputStream() << "textool texture changed..\n"; - } -#endif } void SurfaceInspector_SelectionChanged( const Selectable& selectable ){ @@ -307,6 +241,7 @@ void SurfaceInspector_SetCurrent_FromSelected(){ if ( s_texture_selection_dirty == true ) { s_texture_selection_dirty = false; if ( !g_SelectedFaceInstances.empty() ) { + s_patch_mode = false; TextureProjection projection; //This *may* be the point before it fucks up... Let's see! //Yep, there was a call to removeScale in there... @@ -314,10 +249,6 @@ void SurfaceInspector_SetCurrent_FromSelected(){ SurfaceInspector_SetSelectedTexdef( projection ); - Scene_BrushGetShaderSize_Component_Selected( GlobalSceneGraph(), g_selectedShaderSize[0], g_selectedShaderSize[1] ); - g_selectedTexdef.m_brushprimit_texdef.coords[0][2] = float_mod( g_selectedTexdef.m_brushprimit_texdef.coords[0][2], (float)g_selectedShaderSize[0] ); - g_selectedTexdef.m_brushprimit_texdef.coords[1][2] = float_mod( g_selectedTexdef.m_brushprimit_texdef.coords[1][2], (float)g_selectedShaderSize[1] ); - CopiedString name; Scene_BrushGetShader_Component_Selected( GlobalSceneGraph(), name ); if ( string_not_empty( name.c_str() ) ) { @@ -331,14 +262,18 @@ void SurfaceInspector_SetCurrent_FromSelected(){ else { TextureProjection projection; - Scene_BrushGetTexdef_Selected( GlobalSceneGraph(), projection ); - SurfaceInspector_SetSelectedTexdef( projection ); - CopiedString name; Scene_BrushGetShader_Selected( GlobalSceneGraph(), name ); if ( string_empty( name.c_str() ) ) { + s_patch_mode = true; Scene_PatchGetShader_Selected( GlobalSceneGraph(), name ); + Scene_PatchGetTexdef_Selected( GlobalSceneGraph(), projection ); } + else{ + s_patch_mode = false; + Scene_BrushGetTexdef_Selected( GlobalSceneGraph(), projection ); + } + SurfaceInspector_SetSelectedTexdef( projection ); if ( string_not_empty( name.c_str() ) ) { SurfaceInspector_SetSelectedShader( name.c_str() ); } @@ -406,10 +341,9 @@ void SurfaceInspector_GridChange(){ // we move the textures in pixels, not world units. (i.e. increment values are in pixel) // depending on the texture scale it doesn't take the same amount of pixels to move of GetGridSize() // increment * scale = gridsize -static void OnBtnMatchGrid( GtkWidget *widget, gpointer data ){ - float hscale, vscale; - hscale = static_cast( gtk_spin_button_get_value( getSurfaceInspector().m_hscaleIncrement.m_spin ) ); - vscale = static_cast( gtk_spin_button_get_value( getSurfaceInspector().m_vscaleIncrement.m_spin ) ); +static void OnBtnMatchGrid(){ + const float hscale = getSurfaceInspector().m_hscaleIncrement.m_spin->value(); + const float vscale = getSurfaceInspector().m_vscaleIncrement.m_spin->value(); if ( hscale == 0.0f || vscale == 0.0f ) { globalErrorStream() << "ERROR: unexpected scale == 0.0f\n"; @@ -423,10 +357,6 @@ static void OnBtnMatchGrid( GtkWidget *widget, gpointer data ){ // or update it because something new has been selected // Shamus: It does get called when the SI is hidden, but not when you select something new. ;-) void DoSurface(){ - if ( getSurfaceInspector().GetWidget() == 0 ) { - getSurfaceInspector().Create(); - - } getSurfaceInspector().Update(); //getSurfaceInspector().importData(); //happens in .ShowDlg() anyway getSurfaceInspector().ShowDlg(); @@ -451,18 +381,18 @@ enum EProjectTexture eProjectCam = 2, }; -void SurfaceInspector_ProjectTexture( GtkWidget* widget, EProjectTexture type ){ +void SurfaceInspector_ProjectTexture( EProjectTexture type, bool isGuiClick ){ if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_QUAKE ) globalWarningStream() << "function doesn't work for *brushes*, having Axial Projection type\n"; //works for patches texdef_t texdef; - if( widget ){ //gui buttons + if( isGuiClick ){ //gui buttons getSurfaceInspector().exportData(); - texdef.shift[0] = static_cast( gtk_spin_button_get_value( getSurfaceInspector().m_hshiftIncrement.m_spin ) ); - texdef.shift[1] = static_cast( gtk_spin_button_get_value( getSurfaceInspector().m_vshiftIncrement.m_spin ) ); - texdef.scale[0] = static_cast( gtk_spin_button_get_value( getSurfaceInspector().m_hscaleIncrement.m_spin ) ); - texdef.scale[1] = static_cast( gtk_spin_button_get_value( getSurfaceInspector().m_vscaleIncrement.m_spin ) ); - texdef.rotate = static_cast( gtk_spin_button_get_value( getSurfaceInspector().m_rotateIncrement.m_spin ) ); + texdef.shift[0] = getSurfaceInspector().m_hshiftIncrement.m_spin->value(); + texdef.shift[1] = getSurfaceInspector().m_vshiftIncrement.m_spin->value(); + texdef.scale[0] = getSurfaceInspector().m_hscaleIncrement.m_spin->value(); + texdef.scale[1] = getSurfaceInspector().m_vscaleIncrement.m_spin->value(); + texdef.rotate = getSurfaceInspector().m_rotateIncrement.m_spin->value(); } else{ //bind texdef.scale[0] = texdef.scale[1] = Texdef_getDefaultTextureScale(); @@ -491,13 +421,13 @@ void SurfaceInspector_ProjectTexture( GtkWidget* widget, EProjectTexture type ){ } void SurfaceInspector_ProjectTexture_eProjectAxial(){ - SurfaceInspector_ProjectTexture( 0, eProjectAxial ); + SurfaceInspector_ProjectTexture( eProjectAxial, false ); } void SurfaceInspector_ProjectTexture_eProjectOrtho(){ - SurfaceInspector_ProjectTexture( 0, eProjectOrtho ); + SurfaceInspector_ProjectTexture( eProjectOrtho, false ); } void SurfaceInspector_ProjectTexture_eProjectCam(){ - SurfaceInspector_ProjectTexture( 0, eProjectCam ); + SurfaceInspector_ProjectTexture( eProjectCam, false ); } void SurfaceInspector_ResetTexture(){ @@ -505,50 +435,23 @@ void SurfaceInspector_ResetTexture(){ TextureProjection projection; TexDef_Construct_Default( projection ); -#if TEXTOOL_ENABLED - - //Shamus: - if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES ) { - // Scale up texture width/height if in BP mode... -//NOTE: This may not be correct any more! :-P - if ( !g_SelectedFaceInstances.empty() ) { - Face & face = g_SelectedFaceInstances.last().getFace(); - float x = face.getShader().m_state->getTexture().width; - float y = face.getShader().m_state->getTexture().height; - projection.m_brushprimit_texdef.coords[0][0] /= x; - projection.m_brushprimit_texdef.coords[0][1] /= y; - projection.m_brushprimit_texdef.coords[1][0] /= x; - projection.m_brushprimit_texdef.coords[1][1] /= y; - } - } -#endif - Select_SetTexdef( projection, false, true ); Scene_PatchCapTexture_Selected( GlobalSceneGraph() ); } -static void OnBtnPatchCap( GtkWidget *widget, gpointer data ){ - Patch_CapTexture(); +void SurfaceInspector_InvertTextureHorizontally(){ + UndoableCommand undo( "textureInvertHorizontally" ); + const float shift = -getSurfaceInspector().m_hshiftIncrement.m_spin->value(); + const float scale = -getSurfaceInspector().m_hscaleIncrement.m_spin->value(); + Select_SetTexdef( &shift, 0, &scale, 0, 0 ); + Scene_PatchFlipTexture_Selected( GlobalSceneGraph(), 0 ); } - -static void OnBtnPatchNatural( GtkWidget *widget, gpointer data ){ - Patch_NaturalTexture(); -} - -static void OnBtnPatchFit( GtkWidget *widget, gpointer data ){ - Patch_FitTexture(); -} - -static void OnBtnPatchFit11( GtkWidget *widget, gpointer data ){ - Patch_FitTexture11(); -} - -static void OnBtnReset( GtkWidget *widget, gpointer data ){ - SurfaceInspector_ResetTexture(); -} - -static void OnBtnProject( GtkWidget *widget, EProjectTexture type ){ - SurfaceInspector_ProjectTexture( widget, type ); +void SurfaceInspector_InvertTextureVertically(){ + UndoableCommand undo( "textureInvertVertically" ); + const float shift = -getSurfaceInspector().m_vshiftIncrement.m_spin->value(); + const float scale = -getSurfaceInspector().m_vscaleIncrement.m_spin->value(); + Select_SetTexdef( 0, &shift, 0, &scale, 0 ); + Scene_PatchFlipTexture_Selected( GlobalSceneGraph(), 1 ); } @@ -582,36 +485,39 @@ void SurfaceInspector_FaceFitHeightOnly(){ Select_FitTexture( 0, getSurfaceInspector().m_fitVertical, true ); } - -static void OnBtnFaceFit( GtkWidget *widget, gpointer data ){ - SurfaceInspector_FitTexture(); -} - -static void OnBtnFaceFitWidth( GtkWidget *widget, gpointer data ){ - SurfaceInspector_FaceFitWidth(); -} - -static void OnBtnFaceFitHeight( GtkWidget *widget, gpointer data ){ - SurfaceInspector_FaceFitHeight(); -} - -static gboolean OnBtnFaceFitWidthOnly( GtkWidget *widget, GdkEventButton *event, gpointer data ){ - if ( event->button == 3 && event->type == GDK_BUTTON_PRESS ) { - SurfaceInspector_FaceFitWidthOnly(); - return TRUE; +class : public QObject +{ +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick ){ + QMouseEvent *mouseEvent = static_cast( event ); + if( mouseEvent->button() == Qt::MouseButton::RightButton ){ + SurfaceInspector_FaceFitWidthOnly(); + return true; + } + } + return QObject::eventFilter( obj, event ); // standard event processing } - return FALSE; } +OnBtnFaceFitWidthOnly; -static gboolean OnBtnFaceFitHeightOnly( GtkWidget *widget, GdkEventButton *event, gpointer data ){ - if ( event->button == 3 && event->type == GDK_BUTTON_PRESS ) { - SurfaceInspector_FaceFitHeightOnly(); - return TRUE; +class : public QObject +{ +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick ){ + QMouseEvent *mouseEvent = static_cast( event ); + if( mouseEvent->button() == Qt::MouseButton::RightButton ){ + SurfaceInspector_FaceFitHeightOnly(); + return true; + } + } + return QObject::eventFilter( obj, event ); // standard event processing } - return FALSE; } +OnBtnFaceFitHeightOnly; -static void OnBtnUnsetFlags( GtkWidget *widget, gpointer data ){ +static void OnBtnUnsetFlags(){ UndoableCommand undo( "flagsUnSetSelected" ); Select_SetFlags( ContentsFlagsValue( 0, 0, 0, false ) ); } @@ -705,584 +611,316 @@ const char* getContentFlagName( std::size_t bit ){ return value; } +class : public QObject +{ +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + // QEvent::KeyPress & return true: override QDialog keyPressEvent also + if( event->type() == QEvent::ShortcutOverride || event->type() == QEvent::KeyPress ) { + QKeyEvent *keyEvent = static_cast( event ); + if( keyEvent->key() == Qt::Key_Return + || keyEvent->key() == Qt::Key_Enter + || keyEvent->key() == Qt::Key_Escape + || keyEvent->key() == Qt::Key_Tab + || keyEvent->key() == Qt::Key_Up + || keyEvent->key() == Qt::Key_Down + || keyEvent->key() == Qt::Key_PageUp + || keyEvent->key() == Qt::Key_PageDown ){ + event->accept(); + return true; + } + } + return QObject::eventFilter( obj, event ); // standard event processing + } +} +g_pressedKeysFilter; // ============================================================================= // SurfaceInspector class -guint togglebutton_connect_toggled( GtkToggleButton* button, const Callback& callback ){ - return g_signal_connect_swapped( G_OBJECT( button ), "toggled", G_CALLBACK( callback.getThunk() ), callback.getEnvironment() ); -} +void SurfaceInspector::BuildDialog(){ + GetWidget()->setWindowTitle( "Surface Inspector" ); -GtkWindow* SurfaceInspector::BuildDialog(){ - GtkWindow* window = create_floating_window( "Surface Inspector", m_parent ); + g_guiSettings.addWindow( GetWidget(), "SurfaceInspector/geometry", 99, 99 ); - m_positionTracker.connect( window ); - - global_accel_connect_window( window ); - - window_connect_focus_in_clear_focus_widget( window ); + GetWidget()->installEventFilter( &g_pressedKeysFilter ); +//. window_connect_focus_in_clear_focus_widget( window ); { - // replaced by only the vbox: - GtkWidget* vbox = gtk_vbox_new( FALSE, 5 ); - gtk_widget_show( vbox ); - gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox ) ); - gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 ); - + auto *vbox = new QVBoxLayout( GetWidget() ); { - GtkWidget* hbox2 = gtk_hbox_new( FALSE, 5 ); - gtk_widget_show( hbox2 ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox2 ), FALSE, FALSE, 0 ); - + auto *form = new QFormLayout; + vbox->addLayout( form ); { - GtkWidget* label = gtk_label_new( "Texture" ); - gtk_widget_show( label ); - gtk_box_pack_start( GTK_BOX( hbox2 ), label, FALSE, TRUE, 0 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_box_pack_start( GTK_BOX( hbox2 ), GTK_WIDGET( entry ), TRUE, TRUE, 0 ); - m_texture = entry; - m_textureEntry.connect( entry ); - GlobalTextureEntryCompletion::instance().connect( entry ); + m_textureEntry = new NonModalEntry( ApplyShaderCaller( *this ), UpdateCaller( *this ) ); + GlobalTextureEntryCompletion::instance().connect( m_textureEntry ); + form->addRow( "Texture", m_textureEntry ); } } - - { - GtkWidget* table = gtk_table_new( 6, 4, FALSE ); - gtk_widget_show( table ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( table ), FALSE, FALSE, 0 ); - gtk_table_set_row_spacings( GTK_TABLE( table ), 5 ); - gtk_table_set_col_spacings( GTK_TABLE( table ), 5 ); + auto *hbox = new QHBoxLayout; + vbox->addLayout( hbox ); { - GtkWidget* label = gtk_label_new( "Horizontal shift" ); - gtk_widget_show( label ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); + auto *form = new QFormLayout; + hbox->addLayout( form ); + { + auto spin = m_hshiftSpinner = new NonModalSpinner( -8192, 8192, 0, 2, 2 ); + spin->setCallbacks( ApplyTexdef_HShiftCaller( *this ), UpdateCaller( *this ) ); + m_hshiftIncrement.m_spin = spin; + form->addRow( new SpinBoxLabel( "Horizontal shift", spin ), spin ); + } + { + auto spin = m_vshiftSpinner = new NonModalSpinner( -8192, 8192, 0, 2, 2 ); + spin->setCallbacks( ApplyTexdef_VShiftCaller( *this ), UpdateCaller( *this ) ); + m_vshiftIncrement.m_spin = spin; + form->addRow( new SpinBoxLabel( "Vertical shift", spin ), spin ); + } + { + auto spin = m_hscaleSpinner = new NonModalSpinner( -8192, 8192, .5, 5, .5 ); + spin->setCallbacks( ApplyTexdef_HScaleCaller( *this ), UpdateCaller( *this ) ); + m_hscaleIncrement.m_spin = spin; + auto *hbox = new QHBoxLayout; + hbox->setContentsMargins( 0, 0, 0, 0 ); + hbox->addWidget( new SpinBoxLabel( "Horizontal stretch", spin ) ); + auto *b = new QToolButton; + b->setText( "-" ); + hbox->addWidget( b ); + auto *c = new QWidget; + c->setLayout( hbox ); + form->addRow( c, spin ); + QObject::connect( b, &QAbstractButton::clicked, SurfaceInspector_InvertTextureHorizontally ); + } + { + auto spin = m_vscaleSpinner = new NonModalSpinner( -8192, 8192, .5, 5, .5 ); + spin->setCallbacks( ApplyTexdef_VScaleCaller( *this ), UpdateCaller( *this ) ); + m_vscaleIncrement.m_spin = spin; + auto *hbox = new QHBoxLayout; + hbox->setContentsMargins( 0, 0, 0, 0 ); + hbox->addWidget( new SpinBoxLabel( "Vertical stretch ", spin ) ); + auto *b = new QToolButton; + b->setText( "-" ); + hbox->addWidget( b ); + auto *c = new QWidget; + c->setLayout( hbox ); + form->addRow( c, spin ); + QObject::connect( b, &QAbstractButton::clicked, SurfaceInspector_InvertTextureVertically ); + } + { + auto spin = m_rotateSpinner = new NonModalSpinner( -360, 360, 0, 2, 45, true ); + spin->setCallbacks( ApplyTexdef_RotationCaller( *this ), UpdateCaller( *this ) ); + m_rotateIncrement.m_spin = spin; + form->addRow( new SpinBoxLabel( "Rotate", spin ), spin ); + } } { - GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( GTK_ADJUSTMENT( gtk_adjustment_new( 0, -8192, 8192, 2, 8, 0 ) ), 0, 2 ) ); - m_hshiftIncrement.m_spin = spin; - m_hshiftSpinner.connect( spin ); - gtk_widget_show( GTK_WIDGET( spin ) ); - gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( spin ), 1, 2, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( spin ), 60, -1 ); - } - { - GtkWidget* label = gtk_label_new( "Step" ); - gtk_widget_show( label ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); - gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( entry ), 3, 4, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 ); - m_hshiftIncrement.m_entry = entry; - m_hshiftEntry.connect( entry ); - } - { - GtkWidget* label = gtk_label_new( "Vertical shift" ); - gtk_widget_show( label ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( GTK_ADJUSTMENT( gtk_adjustment_new( 0, -8192, 8192, 2, 8, 0 ) ), 0, 2 ) ); - m_vshiftIncrement.m_spin = spin; - m_vshiftSpinner.connect( spin ); - gtk_widget_show( GTK_WIDGET( spin ) ); - gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( spin ), 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( spin ), 60, -1 ); - } - { - GtkWidget* label = gtk_label_new( "Step" ); - gtk_widget_show( label ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); - gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( entry ), 3, 4, 1, 2, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 ); - m_vshiftIncrement.m_entry = entry; - m_vshiftEntry.connect( entry ); - } - { - GtkWidget* label = gtk_label_new( "Horizontal stretch" ); - gtk_widget_show( label ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( GTK_ADJUSTMENT( gtk_adjustment_new( 0, -8192, 8192, 2, 8, 0 ) ), 0, 5 ) ); - m_hscaleIncrement.m_spin = spin; - m_hscaleSpinner.connect( spin ); - gtk_widget_show( GTK_WIDGET( spin ) ); - gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( spin ), 1, 2, 2, 3, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( spin ), 60, -1 ); - } - { - GtkWidget* label = gtk_label_new( "Step" ); - gtk_widget_show( label ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); - gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 2, 3, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 2, 3 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( entry ), 3, 4, 2, 3, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 2, 3 ); - gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 ); - m_hscaleIncrement.m_entry = entry; - m_hscaleEntry.connect( entry ); - } - { - GtkWidget* label = gtk_label_new( "Vertical stretch" ); - gtk_widget_show( label ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 3, 4, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( GTK_ADJUSTMENT( gtk_adjustment_new( 0, -8192, 8192, 2, 8, 0 ) ), 0, 5 ) ); - m_vscaleIncrement.m_spin = spin; - m_vscaleSpinner.connect( spin ); - gtk_widget_show( GTK_WIDGET( spin ) ); - gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( spin ), 1, 2, 3, 4, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( spin ), 60, -1 ); - } - { - GtkWidget* label = gtk_label_new( "Step" ); - gtk_widget_show( label ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); - gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 3, 4, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( entry ), 3, 4, 3, 4, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 ); - m_vscaleIncrement.m_entry = entry; - m_vscaleEntry.connect( entry ); - } - { - GtkWidget* label = gtk_label_new( "Rotate" ); - gtk_widget_show( label ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 4, 5, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( GTK_ADJUSTMENT( gtk_adjustment_new( 0, -8192, 8192, 2, 45, 0 ) ), 0, 2 ) ); - m_rotateIncrement.m_spin = spin; - m_rotateSpinner.connect( spin ); - gtk_widget_show( GTK_WIDGET( spin ) ); - gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( spin ), 1, 2, 4, 5, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( spin ), 60, -1 ); - gtk_spin_button_set_wrap( spin, TRUE ); - } - { - GtkWidget* label = gtk_label_new( "Step" ); - gtk_widget_show( label ); - gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); - gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 4, 5, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( entry ), 3, 4, 4, 5, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( GTK_WIDGET( entry ), 50, -1 ); - m_rotateIncrement.m_entry = entry; - m_rotateEntry.connect( entry ); - } - { - // match grid button - GtkWidget* button = gtk_button_new_with_label( "Match Grid" ); - gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 2, 4, 5, 6, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( OnBtnMatchGrid ), 0 ); + auto *form = new QFormLayout; + hbox->addLayout( form ); + { + auto entry = m_hshiftEntry = new NonModalEntry( Increment::ApplyCaller( m_hshiftIncrement ), Increment::CancelCaller( m_hshiftIncrement ) ); + m_hshiftIncrement.m_entry = entry; + form->addRow( "Step", entry ); + } + { + auto entry = m_vshiftEntry = new NonModalEntry( Increment::ApplyCaller( m_vshiftIncrement ), Increment::CancelCaller( m_vshiftIncrement ) ); + m_vshiftIncrement.m_entry = entry; + form->addRow( "Step", entry ); + } + { + auto entry = m_hscaleEntry = new NonModalEntry( Increment::ApplyCaller( m_hscaleIncrement ), Increment::CancelCaller( m_hscaleIncrement ) ); + m_hscaleIncrement.m_entry = entry; + form->addRow( "Step", entry ); + } + { + auto entry = m_vscaleEntry = new NonModalEntry( Increment::ApplyCaller( m_vscaleIncrement ), Increment::CancelCaller( m_vscaleIncrement ) ); + m_vscaleIncrement.m_entry = entry; + form->addRow( "Step", entry ); + } + { + auto entry = m_rotateEntry = new NonModalEntry( Increment::ApplyCaller( m_rotateIncrement ), Increment::CancelCaller( m_rotateIncrement ) ); + m_rotateIncrement.m_entry = entry; + form->addRow( "Step", entry ); + } } + hbox->setStretch( 0, 1 ); + } + { + // match grid button + auto *b = new QPushButton( "Match Grid" ); + b->setMinimumWidth( 10 ); + vbox->addWidget( b, 0, Qt::AlignmentFlag::AlignRight ); + QObject::connect( b, &QAbstractButton::clicked, OnBtnMatchGrid ); } { - GtkWidget* frame = gtk_frame_new( "Texturing" ); - gtk_widget_show( frame ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( frame ), FALSE, FALSE, 0 ); + auto *frame = new QGroupBox( "Texturing" ); + vbox->addWidget( frame ); + auto *grid = new QGridLayout( frame ); // 4 x 4 { - GtkWidget* table = gtk_table_new( 5, 4, FALSE ); - gtk_widget_show( table ); - gtk_container_add( GTK_CONTAINER( frame ), table ); - gtk_table_set_row_spacings( GTK_TABLE( table ), 5 ); - gtk_table_set_col_spacings( GTK_TABLE( table ), 5 ); - gtk_container_set_border_width( GTK_CONTAINER( table ), 5 ); - { - GtkWidget* label = gtk_label_new( "Brush" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkWidget* label = gtk_label_new( "Patch" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 3, 4, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkWidget* button = gtk_button_new_with_label( "Width" ); - gtk_widget_set_tooltip_text( button, "Fit texture width, scale height\nRightClick: fit width, keep height" ); - gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 2, 3, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnBtnFaceFitWidth ), 0 ); - g_signal_connect( G_OBJECT( button ), "button_press_event", G_CALLBACK( OnBtnFaceFitWidthOnly ), 0 ); - gtk_widget_set_size_request( button, 60, -1 ); - } - { - GtkWidget* button = gtk_button_new_with_label( "Height" ); - gtk_widget_set_tooltip_text( button, "Fit texture height, scale width\nRightClick: fit height, keep width" ); - gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 3, 4, 0, 1, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnBtnFaceFitHeight ), 0 ); - g_signal_connect( G_OBJECT( button ), "button_press_event", G_CALLBACK( OnBtnFaceFitHeightOnly ), 0 ); - gtk_widget_set_size_request( button, 60, -1 ); - } - { - GtkWidget* button = gtk_button_new_with_label( "Reset" ); - gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 0, 1, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnBtnReset ), 0 ); - gtk_widget_set_size_request( button, 60, -1 ); - } - { - GtkWidget* button = gtk_button_new_with_label( "Fit" ); - gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 1, 2, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnBtnFaceFit ), 0 ); - gtk_widget_set_size_request( button, 60, -1 ); - } - { - GtkWidget* label = gtk_label_new( "Project:" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3, - (GtkAttachOptions) ( GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - } - { - GtkWidget* button = gtk_button_new_with_label( "Axial" ); - gtk_widget_set_tooltip_text( button, "Axial projection (along nearest axis)" ); - gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 1, 2, 2, 3, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 5 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnBtnProject ), (gpointer)eProjectAxial ); - GtkRequisition req; - gtk_widget_size_request( button, &req ); - gtk_widget_set_size_request( button, 60, req.height * 3 / 4 ); - } - { - GtkWidget* button = gtk_button_new_with_label( "Ortho" ); - gtk_widget_set_tooltip_text( button, "Project along active ortho view" ); - gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 2, 3, 2, 3, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 5 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnBtnProject ), (gpointer)eProjectOrtho ); - GtkRequisition req; - gtk_widget_size_request( button, &req ); - gtk_widget_set_size_request( button, 60, req.height * 3 / 4 ); - } - { - GtkWidget* button = gtk_button_new_with_label( "Cam" ); - gtk_widget_set_tooltip_text( button, "Project along camera view direction" ); - gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 3, 4, 2, 3, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 5 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnBtnProject ), (gpointer)eProjectCam ); - GtkRequisition req; - gtk_widget_size_request( button, &req ); - gtk_widget_set_size_request( button, 60, req.height * 3 / 4 ); - } - { - GtkWidget* button = gtk_button_new_with_label( "CAP" ); - gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 0, 1, 4, 5, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnBtnPatchCap ), 0 ); - gtk_widget_set_size_request( button, 60, -1 ); - } - { - GtkWidget* button = gtk_button_new_with_label( "Set..." ); - gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 1, 2, 4, 5, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnBtnPatchFit ), 0 ); - gtk_widget_set_size_request( button, 60, -1 ); - } - { - GtkWidget* button = gtk_button_new_with_label( "Natural" ); - gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 2, 3, 4, 5, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnBtnPatchNatural ), 0 ); - gtk_widget_set_size_request( button, 60, -1 ); - } - { - GtkWidget* button = gtk_button_new_with_label( "Fit" ); - gtk_widget_show( button ); - gtk_table_attach( GTK_TABLE( table ), button, 3, 4, 4, 5, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnBtnPatchFit11 ), 0 ); - gtk_widget_set_size_request( button, 60, -1 ); - } - { - GtkWidget* spin = gtk_spin_button_new( GTK_ADJUSTMENT( gtk_adjustment_new( 1, 0, 1 << 16, 1, 10, 0 ) ), 0, 3 ); - gtk_widget_show( spin ); - gtk_table_attach( GTK_TABLE( table ), spin, 2, 3, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( spin, 60, -1 ); - AddDialogData( *GTK_SPIN_BUTTON( spin ), m_fitHorizontal ); - } - { - GtkWidget* spin = gtk_spin_button_new( GTK_ADJUSTMENT( gtk_adjustment_new( 1, 0, 1 << 16, 1, 10, 0 ) ), 0, 3 ); - gtk_widget_show( spin ); - gtk_table_attach( GTK_TABLE( table ), spin, 3, 4, 1, 2, - (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions) ( 0 ), 0, 0 ); - gtk_widget_set_size_request( spin, 60, -1 ); - AddDialogData( *GTK_SPIN_BUTTON( spin ), m_fitVertical ); - } + auto *b = new QPushButton( "Width" ); + b->setMinimumWidth( 10 ); + b->setToolTip( "Fit texture width, scale height\nRightClick: fit width, keep height" ); + grid->addWidget( b, 0, 2 ); + QObject::connect( b, &QAbstractButton::clicked, SurfaceInspector_FaceFitWidth ); + b->installEventFilter( &OnBtnFaceFitWidthOnly ); + } + { + auto *b = new QPushButton( "Height" ); + b->setMinimumWidth( 10 ); + b->setToolTip( "Fit texture height, scale width\nRightClick: fit height, keep width" ); + grid->addWidget( b, 0, 3 ); + QObject::connect( b, &QAbstractButton::clicked, SurfaceInspector_FaceFitHeight ); + b->installEventFilter( &OnBtnFaceFitHeightOnly ); + } + { + auto *b = new QPushButton( "Reset" ); + b->setMinimumWidth( 10 ); + grid->addWidget( b, 1, 0 ); + QObject::connect( b, &QAbstractButton::clicked, SurfaceInspector_ResetTexture ); + } + { + auto *b = new QPushButton( "Fit" ); + b->setMinimumWidth( 10 ); + grid->addWidget( b, 1, 1 ); + QObject::connect( b, &QAbstractButton::clicked, SurfaceInspector_FitTexture ); + } + { + auto *spin = new DoubleSpinBox( 0, 1 << 9, 1, 3, 1 ); + grid->addWidget( spin, 1, 2 ); + AddDialogData( *spin, m_fitHorizontal ); + } + { + auto *spin = new DoubleSpinBox( 0, 1 << 9, 1, 3, 1 ); + grid->addWidget( spin, 1, 3 ); + AddDialogData( *spin, m_fitVertical ); + } + { + grid->addWidget( new QLabel( "Project:" ), 2, 0 ); + } + { + auto *b = new QPushButton( "Axial" ); + b->setMinimumWidth( 10 ); + b->setToolTip( "Axial projection (along nearest axis)" ); + grid->addWidget( b, 2, 1 ); + QObject::connect( b, &QAbstractButton::clicked, [](){ SurfaceInspector_ProjectTexture( eProjectAxial, true ); } ); + } + { + auto *b = new QPushButton( "Ortho" ); + b->setMinimumWidth( 10 ); + b->setToolTip( "Project along active ortho view" ); + grid->addWidget( b, 2, 2 ); + QObject::connect( b, &QAbstractButton::clicked, [](){ SurfaceInspector_ProjectTexture( eProjectOrtho, true ); } ); + } + { + auto *b = new QPushButton( "Cam" ); + b->setMinimumWidth( 10 ); + b->setToolTip( "Project along camera view direction" ); + grid->addWidget( b, 2, 3 ); + QObject::connect( b, &QAbstractButton::clicked, [](){ SurfaceInspector_ProjectTexture( eProjectCam, true ); } ); + } + { + grid->addWidget( new QLabel( "Patch" ), 3, 0 ); + } + { + auto *b = new QPushButton( "Natural" ); + b->setMinimumWidth( 10 ); + grid->addWidget( b, 3, 1 ); + QObject::connect( b, &QAbstractButton::clicked, Patch_NaturalTexture ); + } + if ( g_pGameDescription->mGameType == "doom3" ){ + grid->addWidget( patch_tesselation_create(), 3, 2, 1, 2 ); } } - if ( !string_empty( g_pGameDescription->getKeyValue( "si_flags" ) ) ) { + if ( !string_empty( g_pGameDescription->getKeyValue( "si_flags" ) ) ) + { { - GtkFrame* frame = GTK_FRAME( gtk_frame_new( "Surface Flags" ) ); - gtk_widget_show( GTK_WIDGET( frame ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( frame ), TRUE, TRUE, 0 ); + auto *frame = new QGroupBox( "Surface Flags" ); + frame->setCheckable( true ); + frame->setChecked( false ); + vbox->addWidget( frame ); + + auto *box = new QVBoxLayout( frame ); + box->setContentsMargins( 0, 0, 0, 0 ); + auto *container = new QWidget; + box->addWidget( container ); + auto *grid = new QGridLayout( container ); + + // QObject::connect( frame, &QGroupBox::clicked, container, &QWidget::setVisible ); + QObject::connect( frame, &QGroupBox::clicked, [container, wnd = GetWidget()]( bool checked ){ + container->setVisible( checked ); + wnd->adjustSize(); + QTimer::singleShot( 0, [wnd](){ wnd->resize( 99, 99 ); } ); + } ); + container->setVisible( false ); { - GtkVBox* vbox3 = GTK_VBOX( gtk_vbox_new( FALSE, 4 ) ); - //gtk_container_set_border_width(GTK_CONTAINER(vbox3), 4); - gtk_widget_show( GTK_WIDGET( vbox3 ) ); - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( vbox3 ) ); + QCheckBox** p = m_surfaceFlags; + + for ( int c = 0; c != 4; ++c ) { - GtkTable* table = GTK_TABLE( gtk_table_new( 8, 4, FALSE ) ); - gtk_widget_show( GTK_WIDGET( table ) ); - gtk_box_pack_start( GTK_BOX( vbox3 ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - gtk_table_set_row_spacings( table, 0 ); - gtk_table_set_col_spacings( table, 0 ); - - GtkCheckButton** p = m_surfaceFlags; - - for ( int c = 0; c != 4; ++c ) + for ( int r = 0; r != 8; ++r ) { - for ( int r = 0; r != 8; ++r ) - { - GtkCheckButton* check = GTK_CHECK_BUTTON( gtk_check_button_new_with_label( getSurfaceFlagName( c * 8 + r ) ) ); - gtk_widget_show( GTK_WIDGET( check ) ); - gtk_table_attach( table, GTK_WIDGET( check ), c, c + 1, r, r + 1, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - *p++ = check; - guint handler_id = togglebutton_connect_toggled( GTK_TOGGLE_BUTTON( check ), ApplyFlagsCaller( *this ) ); - g_object_set_data( G_OBJECT( check ), "handler", gint_to_pointer( handler_id ) ); - } + auto *check = new QCheckBox( getSurfaceFlagName( c * 8 + r ) ); + grid->addWidget( check, r, c ); + *p++ = check; + QObject::connect( check, &QAbstractButton::clicked, ApplyFlagsCaller( *this ) ); } } } } { - GtkFrame* frame = GTK_FRAME( gtk_frame_new( "Content Flags" ) ); - gtk_widget_show( GTK_WIDGET( frame ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( frame ), TRUE, TRUE, 0 ); + auto *frame = new QGroupBox( "Content Flags" ); + frame->setCheckable( true ); + frame->setChecked( false ); + vbox->addWidget( frame ); + + auto *box = new QVBoxLayout( frame ); + box->setContentsMargins( 0, 0, 0, 0 ); + auto *container = new QWidget; + box->addWidget( container ); + auto *grid = new QGridLayout( container ); + + QObject::connect( frame, &QGroupBox::clicked, [container, wnd = GetWidget()]( bool checked ){ + container->setVisible( checked ); + wnd->adjustSize(); + QTimer::singleShot( 0, [wnd](){ wnd->resize( 99, 99 ); } ); + } ); + container->setVisible( false ); { - GtkVBox* vbox3 = GTK_VBOX( gtk_vbox_new( FALSE, 4 ) ); - //gtk_container_set_border_width(GTK_CONTAINER(vbox3), 4); - gtk_widget_show( GTK_WIDGET( vbox3 ) ); - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( vbox3 ) ); + QCheckBox** p = m_contentFlags; + + for ( int c = 0; c != 4; ++c ) { - - GtkTable* table = GTK_TABLE( gtk_table_new( 8, 4, FALSE ) ); - gtk_widget_show( GTK_WIDGET( table ) ); - gtk_box_pack_start( GTK_BOX( vbox3 ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); - gtk_table_set_row_spacings( table, 0 ); - gtk_table_set_col_spacings( table, 0 ); - - GtkCheckButton** p = m_contentFlags; - - for ( int c = 0; c != 4; ++c ) + for ( int r = 0; r != 8; ++r ) { - for ( int r = 0; r != 8; ++r ) - { - GtkCheckButton* check = GTK_CHECK_BUTTON( gtk_check_button_new_with_label( getContentFlagName( c * 8 + r ) ) ); - gtk_widget_show( GTK_WIDGET( check ) ); - gtk_table_attach( table, GTK_WIDGET( check ), c, c + 1, r, r + 1, - (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), - (GtkAttachOptions)( 0 ), 0, 0 ); - *p++ = check; - guint handler_id = togglebutton_connect_toggled( GTK_TOGGLE_BUTTON( check ), ApplyFlagsCaller( *this ) ); - g_object_set_data( G_OBJECT( check ), "handler", gint_to_pointer( handler_id ) ); - } + auto *check = new QCheckBox( getContentFlagName( c * 8 + r ) ); + grid->addWidget( check, r, c ); + *p++ = check; + QObject::connect( check, &QAbstractButton::clicked, ApplyFlagsCaller( *this ) ); } - - // not allowed to modify detail flag using Surface Inspector - gtk_widget_set_sensitive( GTK_WIDGET( m_contentFlags[BRUSH_DETAIL_FLAG] ), FALSE ); } + // not allowed to modify detail flag using Surface Inspector + m_contentFlags[BRUSH_DETAIL_FLAG]->setEnabled( false ); } } { - GtkFrame* frame = GTK_FRAME( gtk_frame_new( "Value" ) ); - gtk_widget_show( GTK_WIDGET( frame ) ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( frame ), TRUE, TRUE, 0 ); + auto *frame = new QGroupBox( "Value" ); + vbox->addWidget( frame ); { - GtkVBox* hbox3 = GTK_VBOX( gtk_hbox_new( FALSE, 4 ) ); - gtk_container_set_border_width( GTK_CONTAINER( hbox3 ), 4 ); - gtk_widget_show( GTK_WIDGET( hbox3 ) ); - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( hbox3 ) ); - { - GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); - gtk_widget_show( GTK_WIDGET( entry ) ); - gtk_box_pack_start( GTK_BOX( hbox3 ), GTK_WIDGET( entry ), TRUE, TRUE, 0 ); - m_valueEntryWidget = entry; - m_valueEntry.connect( entry ); + m_valueEntry = new NonModalEntry( ApplyFlagsCaller( *this ), UpdateCaller( *this ) ); } { - GtkWidget* button = gtk_button_new_with_label( "Unset" ); - gtk_widget_set_tooltip_text( button, "Unset flags" ); - gtk_widget_show( button ); - gtk_box_pack_start( GTK_BOX( hbox3 ), button, TRUE, TRUE, 0 ); - g_signal_connect( G_OBJECT( button ), "clicked", - G_CALLBACK( OnBtnUnsetFlags ), 0 ); - GtkRequisition req; - gtk_widget_size_request( button, &req ); - gtk_widget_set_size_request( button, 60, req.height * 3 / 4 ); + auto *b = new QPushButton( "Unset" ); + b->setToolTip( "Unset flags" ); + QObject::connect( b, &QAbstractButton::clicked, OnBtnUnsetFlags ); + + auto *form = new QFormLayout( frame ); + form->addRow( m_valueEntry, b ); } } } } - -#if TEXTOOL_ENABLED - if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES ) { -// Shamus: Textool goodies... - GtkWidget * frame = gtk_frame_new( "Textool" ); - gtk_widget_show( frame ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( frame ), FALSE, FALSE, 0 ); - { - //Prolly should make this a member or global var, so the SI can draw on it... - TexTool::g_textoolWin = glwidget_new( FALSE ); - // --> Dunno, but this stuff may be necessary... (Looks like it!) - g_object_ref( G_OBJECT( TexTool::g_textoolWin ) ); - gtk_widget_set_events( TexTool::g_textoolWin, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK ); - gtk_widget_set_can_focus( TexTool::g_textoolWin, TRUE ); - // <-- end stuff... - gtk_widget_show( TexTool::g_textoolWin ); - gtk_widget_set_size_request( TexTool::g_textoolWin, -1, 240 ); //Yeah! - gtk_container_add( GTK_CONTAINER( frame ), TexTool::g_textoolWin ); - - g_signal_connect( G_OBJECT( TexTool::g_textoolWin ), "size_allocate", G_CALLBACK( TexTool::size_allocate ), NULL ); - g_signal_connect( G_OBJECT( TexTool::g_textoolWin ), "expose_event", G_CALLBACK( TexTool::expose ), NULL ); - g_signal_connect( G_OBJECT( TexTool::g_textoolWin ), "button_press_event", G_CALLBACK( TexTool::button_press ), NULL ); - g_signal_connect( G_OBJECT( TexTool::g_textoolWin ), "button_release_event", G_CALLBACK( TexTool::button_release ), NULL ); - g_signal_connect( G_OBJECT( TexTool::g_textoolWin ), "motion_notify_event", G_CALLBACK( TexTool::motion ), NULL ); - } - { - GtkWidget * hbox = gtk_hbox_new( FALSE, 5 ); - gtk_widget_show( hbox ); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox ), FALSE, FALSE, 0 ); - // Checkboxes go here... (Flip X/Y) - GtkWidget * flipX = gtk_check_button_new_with_label( "Flip X axis" ); - GtkWidget * flipY = gtk_check_button_new_with_label( "Flip Y axis" ); - gtk_widget_show( flipX ); - gtk_widget_show( flipY ); - gtk_box_pack_start( GTK_BOX( hbox ), flipX, FALSE, FALSE, 0 ); - gtk_box_pack_start( GTK_BOX( hbox ), flipY, FALSE, FALSE, 0 ); - -//Instead of this, we probably need to create a vbox to put into the frame, then the -//window, then the hbox. !!! FIX !!! -// gtk_container_add(GTK_CONTAINER(frame), hbox); - -//Hmm. Do we really need g_object_set_data? Mebbe not... And we don't! :-) -// g_object_set_data(G_OBJECT(flipX), "handler", gint_to_pointer(g_signal_connect(G_OBJECT(flipX), "toggled", G_CALLBACK(TexTool::flipX), 0))); -// g_object_set_data(G_OBJECT(flipY), "handler", gint_to_pointer(g_signal_connect(G_OBJECT(flipY), "toggled", G_CALLBACK(TexTool::flipY), 0))); -//Instead, just do: - g_signal_connect( G_OBJECT( flipX ), "toggled", G_CALLBACK( TexTool::flipX ), NULL ); - g_signal_connect( G_OBJECT( flipY ), "toggled", G_CALLBACK( TexTool::flipY ), NULL ); - } - } -#endif } - - return window; } /* @@ -1295,87 +933,68 @@ GtkWindow* SurfaceInspector::BuildDialog(){ =============== */ -void spin_button_set_value_no_signal( GtkSpinButton* spin, gdouble value ){ - guint handler_id = gpointer_to_int( g_object_get_data( G_OBJECT( spin ), "handler" ) ); - g_signal_handler_block( G_OBJECT( gtk_spin_button_get_adjustment( spin ) ), handler_id ); - gtk_spin_button_set_value( spin, value ); - g_signal_handler_unblock( G_OBJECT( gtk_spin_button_get_adjustment( spin ) ), handler_id ); -} - -void spin_button_set_step_increment( GtkSpinButton* spin, gdouble value ){ - gtk_adjustment_set_step_increment( gtk_spin_button_get_adjustment( spin ), value ); -} - void SurfaceInspector::Update(){ const char * name = SurfaceInspector_GetSelectedShader(); if ( shader_is_texture( name ) ) { - gtk_entry_set_text( m_texture, shader_get_textureName( name ) ); + m_textureEntry->setText( shader_get_textureName( name ) ); } else { - gtk_entry_set_text( m_texture, "" ); + m_textureEntry->clear(); } texdef_t shiftScaleRotate; -//Shamus: This is where we get into trouble--the BP code tries to convert to a "faked" -//shift, rotate & scale values from the brush face, which seems to screw up for some reason. -//!!! FIX !!! -/*globalOutputStream() << "--> SI::Update. About to do ShiftScaleRotate_fromFace()...\n"; - SurfaceInspector_GetSelectedBPTexdef(); - globalOutputStream() << "BP: (" << g_selectedBrushPrimitTexdef.coords[0][0] << ", " << g_selectedBrushPrimitTexdef.coords[0][1] << ")(" - << g_selectedBrushPrimitTexdef.coords[1][0] << ", " << g_selectedBrushPrimitTexdef.coords[1][1] << ")(" - << g_selectedBrushPrimitTexdef.coords[0][2] << ", " << g_selectedBrushPrimitTexdef.coords[1][2] << ") SurfaceInspector::Update\n";//*/ -//Ok, it's screwed up *before* we get here... - ShiftScaleRotate_fromFace( shiftScaleRotate, SurfaceInspector_GetSelectedTexdef() ); - - // normalize again to hide the ridiculously high scale values that get created when using texlock - shiftScaleRotate.shift[0] = float_mod( shiftScaleRotate.shift[0], (float)g_selectedShaderSize[0] ); - shiftScaleRotate.shift[1] = float_mod( shiftScaleRotate.shift[1], (float)g_selectedShaderSize[1] ); + if( s_patch_mode ) + ShiftScaleRotate_fromPatch( shiftScaleRotate, SurfaceInspector_GetSelectedTexdef() ); + else + ShiftScaleRotate_fromFace( shiftScaleRotate, SurfaceInspector_GetSelectedTexdef() ); { - spin_button_set_value_no_signal( m_hshiftIncrement.m_spin, shiftScaleRotate.shift[0] ); - spin_button_set_step_increment( m_hshiftIncrement.m_spin, g_si_globals.shift[0] ); + m_hshiftIncrement.m_spin->setValue( shiftScaleRotate.shift[0] ); + m_hshiftIncrement.m_spin->setSingleStep( g_si_globals.shift[0] ); entry_set_float( m_hshiftIncrement.m_entry, g_si_globals.shift[0] ); } { - spin_button_set_value_no_signal( m_vshiftIncrement.m_spin, shiftScaleRotate.shift[1] ); - spin_button_set_step_increment( m_vshiftIncrement.m_spin, g_si_globals.shift[1] ); + m_vshiftIncrement.m_spin->setValue( shiftScaleRotate.shift[1] ); + m_vshiftIncrement.m_spin->setSingleStep( g_si_globals.shift[1] ); entry_set_float( m_vshiftIncrement.m_entry, g_si_globals.shift[1] ); } { - spin_button_set_value_no_signal( m_hscaleIncrement.m_spin, shiftScaleRotate.scale[0] ); - spin_button_set_step_increment( m_hscaleIncrement.m_spin, g_si_globals.scale[0] ); + m_hscaleIncrement.m_spin->setValue( shiftScaleRotate.scale[0] ); + m_hscaleIncrement.m_spin->setSingleStep( g_si_globals.scale[0] ); entry_set_float( m_hscaleIncrement.m_entry, g_si_globals.scale[0] ); } { - spin_button_set_value_no_signal( m_vscaleIncrement.m_spin, shiftScaleRotate.scale[1] ); - spin_button_set_step_increment( m_vscaleIncrement.m_spin, g_si_globals.scale[1] ); + m_vscaleIncrement.m_spin->setValue( shiftScaleRotate.scale[1] ); + m_vscaleIncrement.m_spin->setSingleStep( g_si_globals.scale[1] ); entry_set_float( m_vscaleIncrement.m_entry, g_si_globals.scale[1] ); } { - spin_button_set_value_no_signal( m_rotateIncrement.m_spin, shiftScaleRotate.rotate ); - spin_button_set_step_increment( m_rotateIncrement.m_spin, g_si_globals.rotate ); + m_rotateIncrement.m_spin->setValue( shiftScaleRotate.rotate ); + m_rotateIncrement.m_spin->setSingleStep( g_si_globals.rotate ); entry_set_float( m_rotateIncrement.m_entry, g_si_globals.rotate ); } + patch_tesselation_update(); + if ( !string_empty( g_pGameDescription->getKeyValue( "si_flags" ) ) ) { ContentsFlagsValue flags( SurfaceInspector_GetSelectedFlags() ); - entry_set_int( m_valueEntryWidget, flags.m_value ); + entry_set_int( m_valueEntry, flags.m_value ); - for ( GtkCheckButton** p = m_surfaceFlags; p != m_surfaceFlags + 32; ++p ) + for ( QCheckBox** p = m_surfaceFlags; p != m_surfaceFlags + 32; ++p ) { - toggle_button_set_active_no_signal( GTK_TOGGLE_BUTTON( *p ), flags.m_surfaceFlags & ( 1 << ( p - m_surfaceFlags ) ) ); + ( *p )->setChecked( flags.m_surfaceFlags & ( 1 << ( p - m_surfaceFlags ) ) ); } - for ( GtkCheckButton** p = m_contentFlags; p != m_contentFlags + 32; ++p ) + for ( QCheckBox** p = m_contentFlags; p != m_contentFlags + 32; ++p ) { - toggle_button_set_active_no_signal( GTK_TOGGLE_BUTTON( *p ), flags.m_contentFlags & ( 1 << ( p - m_contentFlags ) ) ); + ( *p )->setChecked( flags.m_contentFlags & ( 1 << ( p - m_contentFlags ) ) ); } } } @@ -1389,7 +1008,7 @@ void SurfaceInspector::Update(){ =============== */ void SurfaceInspector::ApplyShader(){ - const auto name = StringOutputStream( 256 )( GlobalTexturePrefix_get(), PathCleaned( gtk_entry_get_text( m_texture ) ) ); + const auto name = StringOutputStream( 256 )( GlobalTexturePrefix_get(), PathCleaned( m_textureEntry->text().toLatin1().constData() ) ); // TTimo: detect and refuse invalid texture names (at least the ones with spaces) if ( !texdef_name_valid( name.c_str() ) ) { @@ -1405,16 +1024,13 @@ void SurfaceInspector::ApplyShader(){ void SurfaceInspector::ApplyTexdef(){ texdef_t shiftScaleRotate; - shiftScaleRotate.shift[0] = static_cast( gtk_spin_button_get_value( m_hshiftIncrement.m_spin ) ); - shiftScaleRotate.shift[1] = static_cast( gtk_spin_button_get_value( m_vshiftIncrement.m_spin ) ); - shiftScaleRotate.scale[0] = static_cast( gtk_spin_button_get_value( m_hscaleIncrement.m_spin ) ); - shiftScaleRotate.scale[1] = static_cast( gtk_spin_button_get_value( m_vscaleIncrement.m_spin ) ); - shiftScaleRotate.rotate = static_cast( gtk_spin_button_get_value( m_rotateIncrement.m_spin ) ); + shiftScaleRotate.shift[0] = m_hshiftIncrement.m_spin->value(); + shiftScaleRotate.shift[1] = m_vshiftIncrement.m_spin->value(); + shiftScaleRotate.scale[0] = m_hscaleIncrement.m_spin->value(); + shiftScaleRotate.scale[1] = m_vscaleIncrement.m_spin->value(); + shiftScaleRotate.rotate = m_rotateIncrement.m_spin->value(); TextureProjection projection; -//Shamus: This is the other place that screws up, it seems, since it doesn't seem to do the -//conversion from the face (I think) and so bogus values end up in the thing... !!! FIX !!! -//This is actually OK. :-P ShiftScaleRotate_toFace( shiftScaleRotate, projection ); UndoableCommand undo( "textureProjectionSetSelected" ); @@ -1422,63 +1038,68 @@ void SurfaceInspector::ApplyTexdef(){ } #endif void SurfaceInspector::ApplyTexdef_HShift(){ - const float value = static_cast( gtk_spin_button_get_value( m_hshiftIncrement.m_spin ) ); + const float value = m_hshiftIncrement.m_spin->value(); StringOutputStream command; command << "textureProjectionSetSelected -hShift " << value; UndoableCommand undo( command.c_str() ); Select_SetTexdef( &value, 0, 0, 0, 0 ); + Patch_SetTexdef( &value, 0, 0, 0, 0 ); } void SurfaceInspector::ApplyTexdef_VShift(){ - const float value = static_cast( gtk_spin_button_get_value( m_vshiftIncrement.m_spin ) ); + const float value = m_vshiftIncrement.m_spin->value(); StringOutputStream command; command << "textureProjectionSetSelected -vShift " << value; UndoableCommand undo( command.c_str() ); Select_SetTexdef( 0, &value, 0, 0, 0 ); + Patch_SetTexdef( 0, &value, 0, 0, 0 ); } void SurfaceInspector::ApplyTexdef_HScale(){ - const float value = static_cast( gtk_spin_button_get_value( m_hscaleIncrement.m_spin ) ); + const float value = m_hscaleIncrement.m_spin->value(); StringOutputStream command; command << "textureProjectionSetSelected -hScale " << value; UndoableCommand undo( command.c_str() ); Select_SetTexdef( 0, 0, &value, 0, 0 ); + Patch_SetTexdef( 0, 0, &value, 0, 0 ); } void SurfaceInspector::ApplyTexdef_VScale(){ - const float value = static_cast( gtk_spin_button_get_value( m_vscaleIncrement.m_spin ) ); + const float value = m_vscaleIncrement.m_spin->value(); StringOutputStream command; command << "textureProjectionSetSelected -vScale " << value; UndoableCommand undo( command.c_str() ); Select_SetTexdef( 0, 0, 0, &value, 0 ); + Patch_SetTexdef( 0, 0, 0, &value, 0 ); } void SurfaceInspector::ApplyTexdef_Rotation(){ - const float value = static_cast( gtk_spin_button_get_value( m_rotateIncrement.m_spin ) ); + const float value = m_rotateIncrement.m_spin->value(); StringOutputStream command; command << "textureProjectionSetSelected -rotation " << static_cast( float_to_integer( value * 100.f ) ) / 100.f;; UndoableCommand undo( command.c_str() ); Select_SetTexdef( 0, 0, 0, 0, &value ); + Patch_SetTexdef( 0, 0, 0, 0, &value ); } void SurfaceInspector::ApplyFlags(){ unsigned int surfaceflags = 0; - for ( GtkCheckButton** p = m_surfaceFlags; p != m_surfaceFlags + 32; ++p ) + for ( QCheckBox** p = m_surfaceFlags; p != m_surfaceFlags + 32; ++p ) { - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( *p ) ) ) { + if ( ( *p )->isChecked() ) { surfaceflags |= ( 1 << ( p - m_surfaceFlags ) ); } } unsigned int contentflags = 0; - for ( GtkCheckButton** p = m_contentFlags; p != m_contentFlags + 32; ++p ) + for ( QCheckBox** p = m_contentFlags; p != m_contentFlags + 32; ++p ) { - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( *p ) ) ) { + if ( ( *p )->isChecked() ) { contentflags |= ( 1 << ( p - m_contentFlags ) ); } } - int value = entry_get_int( m_valueEntryWidget ); + int value = entry_get_int( m_valueEntry ); UndoableCommand undo( "flagsSetSelected" ); Select_SetFlags( ContentsFlagsValue( surfaceflags, contentflags, value, true ) ); @@ -2124,8 +1745,8 @@ void SurfaceInspector_registerPreferencesPage(){ } void SurfaceInspector_registerCommands(){ - GlobalCommands_insert( "TextureReset/Cap", FreeCaller(), Accelerator( 'N', GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "FitTexture", FreeCaller(), Accelerator( 'F', GDK_CONTROL_MASK ) ); + GlobalCommands_insert( "TextureReset/Cap", FreeCaller(), QKeySequence( "Shift+N" ) ); + GlobalCommands_insert( "FitTexture", FreeCaller(), QKeySequence( "Ctrl+F" ) ); GlobalCommands_insert( "FitTextureWidth", FreeCaller() ); GlobalCommands_insert( "FitTextureHeight", FreeCaller() ); GlobalCommands_insert( "FitTextureWidthOnly", FreeCaller() ); @@ -2133,7 +1754,7 @@ void SurfaceInspector_registerCommands(){ GlobalCommands_insert( "TextureProjectAxial", FreeCaller() ); GlobalCommands_insert( "TextureProjectOrtho", FreeCaller() ); GlobalCommands_insert( "TextureProjectCam", FreeCaller() ); - GlobalCommands_insert( "SurfaceInspector", FreeCaller(), Accelerator( 'S' ) ); + GlobalCommands_insert( "SurfaceInspector", FreeCaller(), QKeySequence( "S" ) ); // GlobalCommands_insert( "FaceCopyTexture", FreeCaller() ); // GlobalCommands_insert( "FacePasteTexture", FreeCaller() ); @@ -2150,7 +1771,6 @@ void SurfaceInspector_Construct(){ FaceTextureClipboard_setDefault(); - GlobalPreferenceSystem().registerPreference( "SurfaceWnd", getSurfaceInspector().m_importPosition, getSurfaceInspector().m_exportPosition ); GlobalPreferenceSystem().registerPreference( "SI_SurfaceTexdef_Scale1", FloatImportStringCaller( g_si_globals.scale[0] ), FloatExportStringCaller( g_si_globals.scale[0] ) ); GlobalPreferenceSystem().registerPreference( "SI_SurfaceTexdef_Scale2", FloatImportStringCaller( g_si_globals.scale[1] ), FloatExportStringCaller( g_si_globals.scale[1] ) ); GlobalPreferenceSystem().registerPreference( "SI_SurfaceTexdef_Shift1", FloatImportStringCaller( g_si_globals.shift[0] ), FloatExportStringCaller( g_si_globals.shift[0] ) ); @@ -2170,803 +1790,3 @@ void SurfaceInspector_Destroy(){ delete g_SurfaceInspector; } - - -#if TEXTOOL_ENABLED - -namespace TexTool { // namespace hides these symbols from other object-files -// -//Shamus: Textool functions, including GTK+ callbacks -// - -//NOTE: Black screen when TT first comes up is caused by an uninitialized Extent... !!! FIX !!! -// But... You can see down below that it *is* initialized! WTF? -struct Extent -{ - float minX, minY, maxX, maxY; - float width() { return fabs( maxX - minX ); } - float height() { return fabs( maxY - minY ); } -}; - -//This seems to control the texture scale... (Yep! ;-) -Extent extents = { -2.0f, -2.0f, +2.0f, +2.0f }; -brushprimit_texdef_t tm; // Texture transform matrix -Vector2 pts[c_brush_maxFaces]; -Vector2 center; -int numPts; -int textureNum; -Vector2 textureSize; -Vector2 windowSize; -#define VP_PADDING 1.2 -#define PI 3.14159265358979 -bool lButtonDown = false; -bool rButtonDown = false; -//int dragPoint; -//int anchorPoint; -bool haveAnchor = false; -brushprimit_texdef_t currentBP; -brushprimit_texdef_t origBP; // Original brush primitive (before we muck it up) -float controlRadius = 5.0f; -float rotationAngle = 0.0f; -float rotationAngle2 = 0.0f; -float oldRotationAngle; -Vector2 rotationPoint; -bool translatingX = false; // Widget state variables -bool translatingY = false; -bool scalingX = false; -bool scalingY = false; -bool rotating = false; -bool resizingX = false; // Not sure what this means... :-/ -bool resizingY = false; -float origAngle, origScaleX, origScaleY; -Vector2 oldCenter; - - -// Function prototypes (move up to top later...) - -void DrawCircularArc( Vector2 ctr, float startAngle, float endAngle, float radius ); - - -void CopyPointsFromSelectedFace(){ - // Make sure that there's a face and winding to get! - - if ( g_SelectedFaceInstances.empty() ) { - numPts = 0; - return; - } - - Face & face = g_SelectedFaceInstances.last().getFace(); - textureNum = face.getShader().m_state->getTexture().texture_number; - textureSize.x() = face.getShader().m_state->getTexture().width; - textureSize.y() = face.getShader().m_state->getTexture().height; -//globalOutputStream() << "--> Texture #" << textureNum << ": " << textureSize.x() << " x " << textureSize.y() << "...\n"; - - currentBP = SurfaceInspector_GetSelectedTexdef().m_brushprimit_texdef; - - face.EmitTextureCoordinates(); - Winding & w = face.getWinding(); - int count = 0; - - for ( Winding::const_iterator i = w.begin(); i != w.end(); i++ ) - { - //globalOutputStream() << (*i).texcoord.x() << " " << (*i).texcoord.y() << ", "; - pts[count].x() = ( *i ).texcoord.x(); - pts[count].y() = ( *i ).texcoord.y(); - count++; - } - - numPts = count; - - //globalOutputStream() << " ..copied points\n"; -} - -brushprimit_texdef_t bp; -//This approach is probably wrongheaded and just not right anyway. So, !!! FIX !!! [DONE] -void CommitChanges(){ - texdef_t t; // Throwaway, since this is BP only - - bp.coords[0][0] = tm.coords[0][0] * origBP.coords[0][0] + tm.coords[0][1] * origBP.coords[1][0]; - bp.coords[0][1] = tm.coords[0][0] * origBP.coords[0][1] + tm.coords[0][1] * origBP.coords[1][1]; - bp.coords[0][2] = tm.coords[0][0] * origBP.coords[0][2] + tm.coords[0][1] * origBP.coords[1][2] + tm.coords[0][2]; -//Ok, this works for translation... -// bp.coords[0][2] = tm.coords[0][0] * origBP.coords[0][2] + tm.coords[0][1] * origBP.coords[1][2] + tm.coords[0][2] * textureSize.x(); - bp.coords[1][0] = tm.coords[1][0] * origBP.coords[0][0] + tm.coords[1][1] * origBP.coords[1][0]; - bp.coords[1][1] = tm.coords[1][0] * origBP.coords[0][1] + tm.coords[1][1] * origBP.coords[1][1]; - bp.coords[1][2] = tm.coords[1][0] * origBP.coords[0][2] + tm.coords[1][1] * origBP.coords[1][2] + tm.coords[1][2]; -// bp.coords[1][2] = tm.coords[1][0] * origBP.coords[0][2] + tm.coords[1][1] * origBP.coords[1][2] + tm.coords[1][2] * textureSize.y(); - -//This doesn't work: g_brush_texture_changed(); -// Let's try this: -//Note: We should only set an undo *after* the button has been released... !!! FIX !!! -//Definitely *should* have an undo, though! -// UndoableCommand undo("textureProjectionSetSelected"); - Select_SetTexdef( TextureProjection( t, bp, Vector3( 0, 0, 0 ), Vector3( 0, 0, 0 ) ) ); -//This is working, but for some reason the translate is causing the rest of the SI -//widgets to yield bad readings... !!! FIX !!! -//I.e., click on textool window, translate face wireframe, then controls go crazy. Dunno why. -//It's because there were some uncommented out add/removeScale functions in brush.h and a -//removeScale in brushmanip.cpp... :-/ -//Translate isn't working at all now... :-( -//It's because we need to multiply in some scaling factor (prolly the texture width/height) -//Yep. :-P -} - -void UpdateControlPoints(){ - CommitChanges(); - - // Init texture transform matrix - - tm.coords[0][0] = 1.0f; tm.coords[0][1] = 0.0f; tm.coords[0][2] = 0.0f; - tm.coords[1][0] = 0.0f; tm.coords[1][1] = 1.0f; tm.coords[1][2] = 0.0f; -} - - -/* - For shifting we have: - */ -/* - The code that should provide reasonable defaults, but doesn't for some reason: - It's scaling the BP by 128 for some reason, between the time it's created and the - time we get back to the SI widgets: - - static void OnBtnAxial(GtkWidget *widget, gpointer data) - { - UndoableCommand undo("textureDefault"); - TextureProjection projection; - TexDef_Construct_Default(projection); - Select_SetTexdef(projection); - } - - Select_SetTexdef() calls Scene_BrushSetTexdef_Component_Selected(GlobalSceneGraph(), projection) - which is in brushmanip.h: This eventually calls - Texdef_Assign(m_texdef, texdef, m_brushprimit_texdef, brushprimit_texdef) in class Face... - which just copies from brushpr to m_brushpr... - */ - -//Small problem with this thing: It's scaled to the texture which is all screwed up... !!! FIX !!! [DONE] -//Prolly should separate out the grid drawing so that we can draw it behind the polygon. -const float gridWidth = 1.3f; // Let's try an absolute height... WORKS!!! -// NOTE that 2.0 is the height of the viewport. Dunno why... Should make collision -// detection easier... -const float gridRadius = gridWidth * 0.5f; - -typedef const float WidgetColor[3]; -const WidgetColor widgetColor[10] = { - { 1.0000f, 0.2000f, 0.0000f }, // Red - { 0.9137f, 0.9765f, 0.4980f }, // Yellow - { 0.0000f, 0.6000f, 0.3216f }, // Green - { 0.6157f, 0.7726f, 0.8196f }, // Cyan - { 0.4980f, 0.5000f, 0.4716f }, // Grey - - // Highlight colors - { 1.0000f, 0.6000f, 0.4000f }, // Light Red - { 1.0000f, 1.0000f, 0.8980f }, // Light Yellow - { 0.4000f, 1.0000f, 0.7216f }, // Light Green - { 1.0000f, 1.0000f, 1.0000f }, // Light Cyan - { 0.8980f, 0.9000f, 0.8716f } // Light Grey -}; - -#define COLOR_RED 0 -#define COLOR_YELLOW 1 -#define COLOR_GREEN 2 -#define COLOR_CYAN 3 -#define COLOR_GREY 4 -#define COLOR_LT_RED 5 -#define COLOR_LT_YELLOW 6 -#define COLOR_LT_GREEN 7 -#define COLOR_LT_CYAN 8 -#define COLOR_LT_GREY 9 - -void DrawControlWidgets(){ -//Note that the grid should go *behind* the face outline... !!! FIX !!! - // Grid - float xStart = center.x() - ( gridWidth / 2.0f ); - float yStart = center.y() - ( gridWidth / 2.0f ); - float xScale = ( extents.height() / extents.width() ) * ( textureSize.y() / textureSize.x() ); - - glPushMatrix(); -//Small problem with this approach: Changing the center point in the TX code doesn't seem to -//change anything here--prolly because we load a new identity matrix. A couple of ways to fix -//this would be to get rid of that code, or change the center to a new point by taking into -//account the transforms that we toss with the new identity matrix. Dunno which is better. - glLoadIdentity(); - glScalef( xScale, 1.0, 1.0 ); // Will that square it up? Yup. - glRotatef( static_cast( radians_to_degrees( atan2( -currentBP.coords[0][1], currentBP.coords[0][0] ) ) ), 0.0, 0.0, -1.0 ); - glTranslatef( -center.x(), -center.y(), 0.0 ); - - // Circle - glColor3fv( translatingX && translatingY ? widgetColor[COLOR_LT_YELLOW] : widgetColor[COLOR_YELLOW] ); - glBegin( GL_LINE_LOOP ); - DrawCircularArc( center, 0, 2.0f * PI, gridRadius * 0.16 ); - - glEnd(); - - // Axes - glBegin( GL_LINES ); - glColor3fv( translatingY && !translatingX ? widgetColor[COLOR_LT_GREEN] : widgetColor[COLOR_GREEN] ); - glVertex2f( center.x(), center.y() + ( gridRadius * 0.16 ) ); - glVertex2f( center.x(), center.y() + ( gridRadius * 1.00 ) ); - glColor3fv( translatingX && !translatingY ? widgetColor[COLOR_LT_RED] : widgetColor[COLOR_RED] ); - glVertex2f( center.x() + ( gridRadius * 0.16 ), center.y() ); - glVertex2f( center.x() + ( gridRadius * 1.00 ), center.y() ); - glEnd(); - - // Arrowheads - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glBegin( GL_TRIANGLES ); - glColor3fv( translatingY && !translatingX ? widgetColor[COLOR_LT_GREEN] : widgetColor[COLOR_GREEN] ); - glVertex2f( center.x(), center.y() + ( gridRadius * 1.10 ) ); - glVertex2f( center.x() + ( gridRadius * 0.06 ), center.y() + ( gridRadius * 0.94 ) ); - glVertex2f( center.x() - ( gridRadius * 0.06 ), center.y() + ( gridRadius * 0.94 ) ); - glColor3fv( translatingX && !translatingY ? widgetColor[COLOR_LT_RED] : widgetColor[COLOR_RED] ); - glVertex2f( center.x() + ( gridRadius * 1.10 ), center.y() ); - glVertex2f( center.x() + ( gridRadius * 0.94 ), center.y() + ( gridRadius * 0.06 ) ); - glVertex2f( center.x() + ( gridRadius * 0.94 ), center.y() - ( gridRadius * 0.06 ) ); - glEnd(); - - // Arc - glBegin( GL_LINE_STRIP ); - glColor3fv( rotating ? widgetColor[COLOR_LT_CYAN] : widgetColor[COLOR_CYAN] ); - DrawCircularArc( center, 0.03f * PI, 0.47f * PI, gridRadius * 0.90 ); - glEnd(); - - // Boxes - glColor3fv( scalingY && !scalingX ? widgetColor[COLOR_LT_GREEN] : widgetColor[COLOR_GREEN] ); - glBegin( GL_LINES ); - glVertex2f( center.x() + ( gridRadius * 0.20 ), center.y() + ( gridRadius * 1.50 ) ); - glVertex2f( center.x() - ( gridRadius * 0.20 ), center.y() + ( gridRadius * 1.50 ) ); - glEnd(); - glBegin( GL_LINE_LOOP ); - glVertex2f( center.x() + ( gridRadius * 0.10 ), center.y() + ( gridRadius * 1.40 ) ); - glVertex2f( center.x() - ( gridRadius * 0.10 ), center.y() + ( gridRadius * 1.40 ) ); - glVertex2f( center.x() - ( gridRadius * 0.10 ), center.y() + ( gridRadius * 1.20 ) ); - glVertex2f( center.x() + ( gridRadius * 0.10 ), center.y() + ( gridRadius * 1.20 ) ); - glEnd(); - - glColor3fv( scalingX && !scalingY ? widgetColor[COLOR_LT_RED] : widgetColor[COLOR_RED] ); - glBegin( GL_LINES ); - glVertex2f( center.x() + ( gridRadius * 1.50 ), center.y() + ( gridRadius * 0.20 ) ); - glVertex2f( center.x() + ( gridRadius * 1.50 ), center.y() - ( gridRadius * 0.20 ) ); - glEnd(); - glBegin( GL_LINE_LOOP ); - glVertex2f( center.x() + ( gridRadius * 1.40 ), center.y() + ( gridRadius * 0.10 ) ); - glVertex2f( center.x() + ( gridRadius * 1.40 ), center.y() - ( gridRadius * 0.10 ) ); - glVertex2f( center.x() + ( gridRadius * 1.20 ), center.y() - ( gridRadius * 0.10 ) ); - glVertex2f( center.x() + ( gridRadius * 1.20 ), center.y() + ( gridRadius * 0.10 ) ); - glEnd(); - - glColor3fv( scalingX && scalingY ? widgetColor[COLOR_LT_CYAN] : widgetColor[COLOR_CYAN] ); - glBegin( GL_LINE_STRIP ); - glVertex2f( center.x() + ( gridRadius * 1.50 ), center.y() + ( gridRadius * 1.10 ) ); - glVertex2f( center.x() + ( gridRadius * 1.50 ), center.y() + ( gridRadius * 1.50 ) ); - glVertex2f( center.x() + ( gridRadius * 1.10 ), center.y() + ( gridRadius * 1.50 ) ); - glEnd(); - glBegin( GL_LINE_LOOP ); - glVertex2f( center.x() + ( gridRadius * 1.40 ), center.y() + ( gridRadius * 1.40 ) ); - glVertex2f( center.x() + ( gridRadius * 1.40 ), center.y() + ( gridRadius * 1.20 ) ); - glVertex2f( center.x() + ( gridRadius * 1.20 ), center.y() + ( gridRadius * 1.20 ) ); - glVertex2f( center.x() + ( gridRadius * 1.20 ), center.y() + ( gridRadius * 1.40 ) ); - glEnd(); - - glPopMatrix(); -} - -void DrawControlPoints(){ - glColor3f( 1, 1, 1 ); - glBegin( GL_LINE_LOOP ); - - for ( int i = 0; i < numPts; i++ ) - glVertex2f( pts[i].x(), pts[i].y() ); - - glEnd(); -} - -// Note: Setup and all that jazz must be done by the caller! - -void DrawCircularArc( Vector2 ctr, float startAngle, float endAngle, float radius ){ - float stepSize = ( 2.0f * PI ) / 200.0f; - - for ( float angle = startAngle; angle <= endAngle; angle += stepSize ) - glVertex2f( ctr.x() + radius * cos( angle ), ctr.y() + radius * sin( angle ) ); -} - - -void focus(){ - if ( numPts == 0 ) { - return; - } - - // Find selected texture's extents... - - extents.minX = extents.maxX = pts[0].x(), - extents.minY = extents.maxY = pts[0].y(); - - for ( int i = 1; i < numPts; i++ ) - { - if ( pts[i].x() < extents.minX ) { - extents.minX = pts[i].x(); - } - if ( pts[i].x() > extents.maxX ) { - extents.maxX = pts[i].x(); - } - if ( pts[i].y() < extents.minY ) { - extents.minY = pts[i].y(); - } - if ( pts[i].y() > extents.maxY ) { - extents.maxY = pts[i].y(); - } - } - - // Do some viewport fitting stuff... - -//globalOutputStream() << "--> Center: " << center.x() << ", " << center.y() << "\n"; -//globalOutputStream() << "--> Extents (stage 1): " << extents.minX << ", " -// << extents.maxX << ", " << extents.minY << ", " << extents.maxY << "\n"; - // TTimo: Apply a ratio to get the area we'll draw. - center.x() = 0.5f * ( extents.minX + extents.maxX ), - center.y() = 0.5f * ( extents.minY + extents.maxY ); - extents.minX = center.x() + VP_PADDING * ( extents.minX - center.x() ), - extents.minY = center.y() + VP_PADDING * ( extents.minY - center.y() ), - extents.maxX = center.x() + VP_PADDING * ( extents.maxX - center.x() ), - extents.maxY = center.y() + VP_PADDING * ( extents.maxY - center.y() ); -//globalOutputStream() << "--> Extents (stage 2): " << extents.minX << ", " -// << extents.maxX << ", " << extents.minY << ", " << extents.maxY << "\n"; - - // TTimo: We want a texture with the same X / Y ratio. - // TTimo: Compute XY space / window size ratio. - float SSize = extents.width(), TSize = extents.height(); - float ratioX = textureSize.x() * extents.width() / windowSize.x(), - ratioY = textureSize.y() * extents.height() / windowSize.y(); -//globalOutputStream() << "--> Texture size: " << textureSize.x() << ", " << textureSize.y() << "\n"; -//globalOutputStream() << "--> Window size: " << windowSize.x() << ", " << windowSize.y() << "\n"; - - if ( ratioX > ratioY ) { - TSize = ( windowSize.y() * ratioX ) / textureSize.y(); -// TSize = extents.width() * (windowSize.y() / windowSize.x()) * (textureSize.x() / textureSize.y()); - } - else - { - SSize = ( windowSize.x() * ratioY ) / textureSize.x(); -// SSize = extents.height() * (windowSize.x() / windowSize.y()) * (textureSize.y() / textureSize.x()); - } - - extents.minX = center.x() - 0.5f * SSize, extents.maxX = center.x() + 0.5f * SSize, - extents.minY = center.y() - 0.5f * TSize, extents.maxY = center.y() + 0.5f * TSize; -//globalOutputStream() << "--> Extents (stage 3): " << extents.minX << ", " -// << extents.maxX << ", " << extents.minY << ", " << extents.maxY << "\n"; -} - -gboolean size_allocate( GtkWidget * win, GtkAllocation * a, gpointer ){ - windowSize.x() = a->width; - windowSize.y() = a->height; - queueDraw(); - return false; -} - -gboolean expose( GtkWidget * win, GdkEventExpose * e, gpointer ){ -// globalOutputStream() << "--> Textool Window was exposed!\n"; -// globalOutputStream() << " (window width/height: " << cc << "/" << e->area.height << ")\n"; - -// windowSize.x() = e->area.width, windowSize.y() = e->area.height; -//This needs to go elsewhere... -// InitTextool(); - - if ( !glwidget_make_current( win ) ) { - globalOutputStream() << " FAILED to make current! Oh, the agony! :-(\n"; - return true; - } - - CopyPointsFromSelectedFace(); - - if ( !lButtonDown ) { - focus(); - } - - // Probably should init button/anchor states here as well... -// rotationAngle = 0.0f; - glClearColor( 0, 0, 0, 0 ); - glViewport( 0, 0, e->area.width, e->area.height ); - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - -//??? - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - glDisable( GL_DEPTH_TEST ); - glDisable( GL_BLEND ); - - glOrtho( extents.minX, extents.maxX, extents.maxY, extents.minY, -1, 1 ); - - glColor3f( 1, 1, 1 ); - // draw the texture background - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glBindTexture( GL_TEXTURE_2D, textureNum ); - - glEnable( GL_TEXTURE_2D ); - glBegin( GL_QUADS ); - glTexCoord2f( extents.minX, extents.minY ); - glVertex2f( extents.minX, extents.minY ); - glTexCoord2f( extents.maxX, extents.minY ); - glVertex2f( extents.maxX, extents.minY ); - glTexCoord2f( extents.maxX, extents.maxY ); - glVertex2f( extents.maxX, extents.maxY ); - glTexCoord2f( extents.minX, extents.maxY ); - glVertex2f( extents.minX, extents.maxY ); - glEnd(); - glDisable( GL_TEXTURE_2D ); - - // draw the texture-space grid - glColor3fv( widgetColor[COLOR_GREY] ); - glBegin( GL_LINES ); - - const int gridSubdivisions = 8; - const float gridExtents = 4.0f; - - for ( int i = 0; i < gridSubdivisions + 1; ++i ) - { - float y = i * ( gridExtents / float(gridSubdivisions) ); - float x = i * ( gridExtents / float(gridSubdivisions) ); - glVertex2f( 0, y ); - glVertex2f( gridExtents, y ); - glVertex2f( x, 0 ); - glVertex2f( x, gridExtents ); - } - - glEnd(); - - DrawControlPoints(); - DrawControlWidgets(); -//??? - // reset the current texture -// glBindTexture(GL_TEXTURE_2D, 0); -// glFinish(); - glwidget_swap_buffers( win ); - - return false; -} - -/*int FindSelectedPoint(int x, int y) - { - for(int i=0; i Textool button press...\n"; - - if ( e->button == 1 ) { - lButtonDown = true; - GlobalUndoSystem().start(); - - origBP = currentBP; - - //globalOutputStream() << "--> Original BP: [" << origBP.coords[0][0] << "][" << origBP.coords[0][1] << "][" << origBP.coords[0][2] << "]\n"; - //globalOutputStream() << " [" << origBP.coords[1][0] << "][" << origBP.coords[1][1] << "][" << origBP.coords[1][2] << "]\n"; - //float angle = atan2(origBP.coords[0][1], origBP.coords[0][0]) * 180.0f / 3.141592653589f; - origAngle = ( origBP.coords[0][1] > 0 ? PI : -PI ); // Could also be -PI... !!! FIX !!! [DONE] - - if ( origBP.coords[0][0] != 0.0f ) { - origAngle = atan( origBP.coords[0][1] / origBP.coords[0][0] ); - } - - origScaleX = origBP.coords[0][0] / cos( origAngle ); - origScaleY = origBP.coords[1][1] / cos( origAngle ); - rotationAngle = origAngle; - oldCenter[0] = oldCenter[1] = 0; - - //globalOutputStream() << "--> BP stats: ang=" << origAngle * RAD_TO_DEG << ", scale=" << origScaleX << "/" << origScaleY << "\n"; - //Should also set the Flip X/Y checkboxes here as well... !!! FIX !!! - //Also: should reverse texture left/right up/down instead of flipping the points... - -//disnowok -//float nx = windowSize.x() * (e->x - extents.minX) / (extents.maxX - extents.minX); -//float ny = windowSize.y() * (e->y - extents.minY) / (extents.maxY - extents.minY); -//disdoes... -//But I want it to scroll the texture window, not the points... !!! FIX !!! -//Actually, should scroll the texture window only when mouse is down on no widgets... - float nx = e->x / windowSize.x() * extents.width() + extents.minX; - float ny = e->y / windowSize.y() * extents.height() + extents.minY; - trans.x() = -tm.coords[0][0] * nx - tm.coords[0][1] * ny; - trans.y() = -tm.coords[1][0] * nx - tm.coords[1][1] * ny; - - dragPoint.x() = e->x, dragPoint.y() = e->y; - trans2.x() = nx, trans2.y() = ny; - oldRotationAngle = rotationAngle; -// oldTrans.x() = tm.coords[0][2] - nx * textureSize.x(); -// oldTrans.y() = tm.coords[1][2] - ny * textureSize.y(); - oldTrans.x() = tm.coords[0][2]; - oldTrans.y() = tm.coords[1][2]; - oldCenter.x() = center.x(); - oldCenter.y() = center.y(); - - queueDraw(); - - return true; - } -/* else if (e->button == 3) - { - rButtonDown = true; - }//*/ - -//globalOutputStream() << "(" << (haveAnchor ? "anchor" : "released") << ")\n"; - - return false; -} - -gboolean button_release( GtkWidget * win, GdkEventButton * e, gpointer ){ -// globalOutputStream() << "--> Textool button release...\n"; - - if ( e->button == 1 ) { -/* float ptx = e->x / windowSize.x() * extents.width() + extents.minX; - float pty = e->y / windowSize.y() * extents.height() + extents.minY; - - //This prolly should go into the mouse move code... - //Doesn't work correctly anyway... - if (translatingX || translatingY) - center.x() = ptx, center.y() = pty;//*/ - - lButtonDown = false; - - if ( translatingX || translatingY ) { - GlobalUndoSystem().finish( "translateTexture" ); - } - else if ( rotating ) { - GlobalUndoSystem().finish( "rotateTexture" ); - } - else if ( scalingX || scalingY ) { - GlobalUndoSystem().finish( "scaleTexture" ); - } - else if ( resizingX || resizingY ) { - GlobalUndoSystem().finish( "resizeTexture" ); - } - else - { - GlobalUndoSystem().finish( "textoolUnknown" ); - } - - rotating = translatingX = translatingY = scalingX = scalingY = resizingX = resizingY = false; - - queueDraw(); - } - else if ( e->button == 3 ) { - rButtonDown = false; - } - - return true; -} - -/* - void C2DView::GridForWindow( float c[2], int x, int y) - { - SpaceForWindow( c, x, y ); - if ( !m_bDoGrid ) - return; - c[0] /= m_GridStep[0]; - c[1] /= m_GridStep[1]; - c[0] = (float)floor( c[0] + 0.5f ); - c[1] = (float)floor( c[1] + 0.5f ); - c[0] *= m_GridStep[0]; - c[1] *= m_GridStep[1]; - } - void C2DView::SpaceForWindow( float c[2], int x, int y) - { - c[0] = ((float)(x))/((float)(m_rect.right-m_rect.left))*(m_Maxs[0]-m_Mins[0])+m_Mins[0]; - c[1] = ((float)(y))/((float)(m_rect.bottom-m_rect.top))*(m_Maxs[1]-m_Mins[1])+m_Mins[1]; - } - */ -gboolean motion( GtkWidget * win, GdkEventMotion * e, gpointer ){ -// globalOutputStream() << "--> Textool motion...\n"; - - if ( lButtonDown ) { - if ( translatingX || translatingY ) { - float ptx = e->x / windowSize.x() * extents.width() + extents.minX; - float pty = e->y / windowSize.y() * extents.height() + extents.minY; - -//Need to fix this to take the rotation angle into account, so that it moves along -//the rotated X/Y axis... - if ( translatingX ) { -// tm.coords[0][2] = (trans.x() + ptx) * textureSize.x(); -//This works, but only when the angle is zero. !!! FIX !!! [DONE] -// tm.coords[0][2] = oldCenter.x() + (ptx * textureSize.x()); - tm.coords[0][2] = oldTrans.x() + ( ptx - trans2.x() ) * textureSize.x(); -// center.x() = oldCenter.x() + (ptx - trans2.x()); - } - - if ( translatingY ) { -// tm.coords[1][2] = (trans.y() + pty) * textureSize.y(); -// tm.coords[1][2] = oldCenter.y() + (pty * textureSize.y()); - tm.coords[1][2] = oldTrans.y() + ( pty - trans2.y() ) * textureSize.y(); -// center.y() = oldCenter.y() + (pty - trans2.y()); - } - -//Need to update center.x/y() so that the widget translates as well. Also, oldCenter -//is badly named... Should be oldTrans or something like that... !!! FIX !!! -//Changing center.x/y() here doesn't seem to change anything... :-/ - UpdateControlPoints(); - } - else if ( rotating ) { - // Shamus: New rotate code - int cx = (int)( windowSize.x() * ( center.x() - extents.minX ) / extents.width() ); - int cy = (int)( windowSize.y() * ( center.y() - extents.minY ) / extents.height() ); - Vector3 v1( dragPoint.x() - cx, dragPoint.y() - cy, 0 ), v2( e->x - cx, e->y - cy, 0 ); - - vector3_normalise( v1 ); - vector3_normalise( v2 ); - float c = vector3_dot( v1, v2 ); - Vector3 cross = vector3_cross( v1, v2 ); - float s = vector3_length( cross ); - - if ( cross[2] > 0 ) { - s = -s; - } - -// Problem with this: arcsin/cos seems to only return -90 to 90 and 0 to 180... -// Can't derive angle from that! - -//rotationAngle = asin(s);// * 180.0f / 3.141592653589f; - rotationAngle = acos( c ); -//rotationAngle2 = asin(s); - if ( cross[2] < 0 ) { - rotationAngle = -rotationAngle; - } - -//NO! DOESN'T WORK! rotationAngle -= 45.0f * DEG_TO_RAD; -//Let's try this: -//No wok. -/*c = cos(rotationAngle - oldRotationAngle); - s = sin(rotationAngle - oldRotationAngle); - rotationAngle += oldRotationAngle; - //c += cos(oldRotationAngle); - //s += sin(oldRotationAngle); - //rotationAngle += oldRotationAngle; - //c %= 2.0 * PI; - //s %= 2.0 * PI; - //rotationAngle %= 2.0 * PI;//*/ - -//This is wrong... Hmm... -//It seems to shear the texture instead of rotating it... !!! FIX !!! -// Now it rotates correctly. Seems TTimo was overcomplicating things here... ;-) - -// Seems like what needs to happen here is multiplying these rotations by tm... !!! FIX !!! - -// See brush_primit.cpp line 244 (Texdef_EmitTextureCoordinates()) for where texcoords come from... - - tm.coords[0][0] = c; - tm.coords[0][1] = s; - tm.coords[1][0] = -s; - tm.coords[1][1] = c; -//It doesn't work anymore... Dunno why... -//tm.coords[0][2] = -trans.x(); // This works!!! Yeah!!! -//tm.coords[1][2] = -trans.y(); -//nope. -//tm.coords[0][2] = rotationPoint.x(); // This works, but strangely... -//tm.coords[1][2] = rotationPoint.y(); -//tm.coords[0][2] = 0;// center.x() / 2.0f; -//tm.coords[1][2] = 0;// center.y() / 2.0f; -//No. -//tm.coords[0][2] = -(center.x() * textureSize.x()); -//tm.coords[1][2] = -(center.y() * textureSize.y()); -//Eh? No, but seems to be getting closer... -/*float ptx = e->x / windowSize.x() * extents.width() + extents.minX; - float pty = e->y / windowSize.y() * extents.height() + extents.minY; - tm.coords[0][2] = -c * center.x() - s * center.y() + ptx; - tm.coords[1][2] = s * center.x() - c * center.x() + pty;//*/ -//Kinda works, but center drifts around on non-square textures... -/*tm.coords[0][2] = (-c * center.x() - s * center.y()) * textureSize.x(); - tm.coords[1][2] = ( s * center.x() - c * center.y()) * textureSize.y();//*/ -//Rotates correctly, but not around the actual center of the face's points... -/*tm.coords[0][2] = -c * center.x() * textureSize.x() - s * center.y() * textureSize.y(); - tm.coords[1][2] = s * center.x() * textureSize.x() - c * center.y() * textureSize.y();//*/ -//Yes!!! - tm.coords[0][2] = ( -c * center.x() * textureSize.x() - s * center.y() * textureSize.y() ) + center.x() * textureSize.x(); - tm.coords[1][2] = ( s * center.x() * textureSize.x() - c * center.y() * textureSize.y() ) + center.y() * textureSize.y(); //*/ -//This doesn't work... -//And this is the wrong place for this anyway (I'm pretty sure). -/*tm.coords[0][2] += oldCenter.x(); - tm.coords[1][2] += oldCenter.y();//*/ - UpdateControlPoints(); // will cause a redraw - } - - return true; - } - else // Check for widget mouseovers - { - Vector2 tran; - float nx = e->x / windowSize.x() * extents.width() + extents.minX; - float ny = e->y / windowSize.y() * extents.height() + extents.minY; - // Translate nx/y to the "center" point... - nx -= center.x(); - ny -= center.y(); - ny = -ny; // Flip Y-axis so that increasing numbers move up - - tran.x() = tm.coords[0][0] * nx + tm.coords[0][1] * ny; - tran.y() = tm.coords[1][0] * nx + tm.coords[1][1] * ny; -//This doesn't seem to generate a valid distance from the center--for some reason it -//calculates a fixed number every time -//Look at nx/y above: they're getting fixed there! !!! FIX !!! [DONE] - float dist = sqrt( ( nx * nx ) + ( ny * ny ) ); - // Normalize to the 2.0 = height standard (for now) -//globalOutputStream() << "--> Distance before: " << dist; - dist = dist * 2.0f / extents.height(); -//globalOutputStream() << ". After: " << dist; - tran.x() = tran.x() * 2.0f / extents.height(); - tran.y() = tran.y() * 2.0f / extents.height(); -//globalOutputStream() << ". Trans: " << tran.x() << ", " << tran.y() << "\n"; - -//Let's try this instead... -//Interesting! It seems that e->x/y are rotated -//(no, they're not--the TM above is what's doing it...) - nx = ( ( e->x / windowSize.y() ) * 2.0f ) - ( windowSize.x() / windowSize.y() ); - ny = ( ( e->y / windowSize.y() ) * 2.0f ) - ( windowSize.y() / windowSize.y() ); - ny = -ny; -//Cool! It works! Now just need to do rotation... - - rotating = translatingX = translatingY = scalingX = scalingY = resizingX = resizingY = false; - - if ( dist < ( gridRadius * 0.16f ) ) { - translatingX = translatingY = true; - } - else if ( dist > ( gridRadius * 0.16f ) && dist < ( gridRadius * 1.10f ) - && fabs( ny ) < ( gridRadius * 0.05f ) && nx > 0 ) { - translatingX = true; - } - else if ( dist > ( gridRadius * 0.16f ) && dist < ( gridRadius * 1.10f ) - && fabs( nx ) < ( gridRadius * 0.05f ) && ny > 0 ) { - translatingY = true; - } - // Should tighten up the angle on this, or put this test after the axis tests... - else if ( tran.x() > 0 && tran.y() > 0 - && ( dist > ( gridRadius * 0.82f ) && dist < ( gridRadius * 0.98f ) ) ) { - rotating = true; - } - - queueDraw(); - - return true; - } - - return false; -} - -//It seems the fake tex coords conversion is screwing this stuff up... !!! FIX !!! -//This is still wrong... Prolly need to do something with the oldScaleX/Y stuff... -void flipX( GtkToggleButton *, gpointer ){ -// globalOutputStream() << "--> Flip X...\n"; - //Shamus: -// SurfaceInspector_GetSelectedBPTexdef(); // Refresh g_selectedBrushPrimitTexdef... -// tm.coords[0][0] = -tm.coords[0][0]; -// tm.coords[1][0] = -tm.coords[1][0]; -// tm.coords[0][0] = -tm.coords[0][0]; // This should be correct now...Nope. -// tm.coords[1][1] = -tm.coords[1][1]; - tm.coords[0][0] = -tm.coords[0][0]; // This should be correct now... - tm.coords[1][0] = -tm.coords[1][0]; -// tm.coords[2][0] = -tm.coords[2][0];//wil wok? no. - UpdateControlPoints(); -} - -void flipY( GtkToggleButton *, gpointer ){ -// globalOutputStream() << "--> Flip Y...\n"; -// tm.coords[0][1] = -tm.coords[0][1]; -// tm.coords[1][1] = -tm.coords[1][1]; -// tm.coords[0][1] = -tm.coords[0][1]; // This should be correct now...Nope. -// tm.coords[1][0] = -tm.coords[1][0]; - tm.coords[0][1] = -tm.coords[0][1]; // This should be correct now... - tm.coords[1][1] = -tm.coords[1][1]; -// tm.coords[2][1] = -tm.coords[2][1];//wil wok? no. - UpdateControlPoints(); -} - -} // end namespace TexTool - -#endif diff --git a/radiant/surfacedialog.h b/radiant/surfacedialog.h index 30925019..f3ad8725 100644 --- a/radiant/surfacedialog.h +++ b/radiant/surfacedialog.h @@ -25,9 +25,7 @@ void SurfaceInspector_Construct(); void SurfaceInspector_Destroy(); -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkWindow GtkWindow; -void SurfaceInspector_constructWindow( GtkWindow* widget ); +void SurfaceInspector_constructWindow( class QWidget* widget ); void SurfaceInspector_destroyWindow(); bool SelectedFaces_empty(); @@ -39,18 +37,10 @@ void FaceTextureClipboard_setDefault(); // the increment we are using for the surface inspector (this is saved in the prefs) struct si_globals_t { - float shift[2]; - float scale[2]; - float rotate; + float shift[2] = { 8.0f, 8.0f }; + float scale[2] = { 0.5f, 0.5f }; + float rotate = 45.0f; - bool m_bSnapTToGrid; - - si_globals_t() : m_bSnapTToGrid( false ){ - shift[0] = 8.0f; - shift[1] = 8.0f; - scale[0] = 0.5f; - scale[1] = 0.5f; - rotate = 45.0f; - } + bool m_bSnapTToGrid = false; }; extern si_globals_t g_si_globals; diff --git a/radiant/textureentry.h b/radiant/textureentry.h index e5da3d71..8759db02 100644 --- a/radiant/textureentry.h +++ b/radiant/textureentry.h @@ -22,9 +22,11 @@ #pragma once -#include - -#include "gtkutil/idledraw.h" +#include +#include +#include +#include +#include #include "generic/static.h" #include "signal/isignal.h" @@ -33,39 +35,34 @@ #include "texwindow.h" template -class EntryCompletion +class EntryCompletion : public QObject { - GtkListStore* m_store; - bool m_invalid; + QCompleter* m_completer{}; + QStringListModel* m_model{}; + bool m_invalid = true; public: - EntryCompletion() : m_store( 0 ), m_invalid( true ){ + ~EntryCompletion(){ + delete m_completer; } - static gboolean focus_in( GtkEntry* entry, GdkEventFocus *event, EntryCompletion* self ){ - self->update(); - return FALSE; - } - - void connect( GtkEntry* entry ){ - if ( m_store == 0 ) { - m_store = gtk_list_store_new( 1, G_TYPE_STRING ); - - fill(); + void connect( QLineEdit* entry ){ + if ( m_completer == nullptr ) { + m_completer = new QCompleter; + m_model = new QStringListModel( m_completer ); + m_completer->setModel( m_model ); + m_completer->setCaseSensitivity( Qt::CaseSensitivity::CaseInsensitive ); StringList().connect( InvalidateCaller( *this ) ); } - GtkEntryCompletion* completion = gtk_entry_completion_new(); - gtk_entry_set_completion( entry, completion ); - gtk_entry_completion_set_model( completion, GTK_TREE_MODEL( m_store ) ); - gtk_entry_completion_set_text_column( completion, 0 ); - g_signal_connect( G_OBJECT( entry ), "focus_in_event", G_CALLBACK( focus_in ), this ); + entry->setCompleter( m_completer ); + entry->installEventFilter( this ); } void append( const char* string ){ - GtkTreeIter iter; - gtk_list_store_append( m_store, &iter ); - gtk_list_store_set( m_store, &iter, 0, string, -1 ); + if( m_model->insertRow( m_model->rowCount() ) ){ + m_model->setData( m_model->index( m_model->rowCount() - 1 ), string ); + } } typedef MemberCaller1 AppendCaller; @@ -75,7 +72,7 @@ public: } void clear(){ - gtk_list_store_clear( m_store ); + m_model->removeRows( 0, m_model->rowCount() ); } void update(){ @@ -89,6 +86,13 @@ public: m_invalid = true; } typedef MemberCaller InvalidateCaller; +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::FocusIn ) { + update(); + } + return QObject::eventFilter( obj, event ); // standard event processing + } }; /* loaded ( shaders + textures ) */ diff --git a/radiant/textures.cpp b/radiant/textures.cpp index 51b50c63..757897b2 100644 --- a/radiant/textures.cpp +++ b/radiant/textures.cpp @@ -22,7 +22,6 @@ #include "textures.h" #include "debugging/debugging.h" -#include "warnings.h" #include "itextures.h" #include "igl.h" @@ -92,28 +91,28 @@ void SetTexParameters( ETexturesMode mode ){ switch ( mode ) { case eTextures_NEAREST: - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); break; case eTextures_NEAREST_MIPMAP_NEAREST: - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); break; case eTextures_NEAREST_MIPMAP_LINEAR: - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); break; case eTextures_LINEAR: - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); break; case eTextures_LINEAR_MIPMAP_NEAREST: - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); break; case eTextures_LINEAR_MIPMAP_LINEAR: - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); break; default: globalErrorStream() << "invalid texture mode\n"; @@ -123,7 +122,7 @@ void SetTexParameters( ETexturesMode mode ){ void SetTexAnisotropy( bool anisotropy ){ float maxAniso = QGL_maxTextureAnisotropy(); if ( maxAniso > 1 ) { - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy ? maxAniso : 1.f ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy ? maxAniso : 1.f ); } } @@ -191,19 +190,19 @@ void LoadTextureRGBA( qtexture_t* q, unsigned char* pPixels, int nWidth, int nHe q->color[1] = total[1] / ( nCount * 255 ); q->color[2] = total[2] / ( nCount * 255 ); - glGenTextures( 1, &q->texture_number ); + gl().glGenTextures( 1, &q->texture_number ); - glBindTexture( GL_TEXTURE_2D, q->texture_number ); + gl().glBindTexture( GL_TEXTURE_2D, q->texture_number ); SetTexParameters( g_texture_mode ); SetTexAnisotropy( g_TextureAnisotropy ); #if 1 - glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE ); - glTexImage2D( GL_TEXTURE_2D, 0, g_texture_globals.texture_components, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPixels ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE ); + gl().glTexImage2D( GL_TEXTURE_2D, 0, g_texture_globals.texture_components, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPixels ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, std::min( g_Textures_mipLevel, static_cast( log2( static_cast( std::max( nWidth, nHeight ) ) ) ) ) ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, std::min( g_Textures_mipLevel, static_cast( log2( static_cast( std::max( nWidth, nHeight ) ) ) ) ) ); - glBindTexture( GL_TEXTURE_2D, 0 ); + gl().glBindTexture( GL_TEXTURE_2D, 0 ); #else int gl_width = 1; while ( gl_width < nWidth ) @@ -241,7 +240,7 @@ void LoadTextureRGBA( qtexture_t* q, unsigned char* pPixels, int nWidth, int nHe } int mip = 0; - glTexImage2D( GL_TEXTURE_2D, mip++, g_texture_globals.texture_components, gl_width, gl_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, outpixels ); + gl().glTexImage2D( GL_TEXTURE_2D, mip++, g_texture_globals.texture_components, gl_width, gl_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, outpixels ); while ( gl_width > 1 || gl_height > 1 ) { GL_MipReduce( outpixels, outpixels, gl_width, gl_height, 1, 1 ); @@ -253,10 +252,10 @@ void LoadTextureRGBA( qtexture_t* q, unsigned char* pPixels, int nWidth, int nHe gl_height >>= 1; } - glTexImage2D( GL_TEXTURE_2D, mip++, g_texture_globals.texture_components, gl_width, gl_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, outpixels ); + gl().glTexImage2D( GL_TEXTURE_2D, mip++, g_texture_globals.texture_components, gl_width, gl_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, outpixels ); } - glBindTexture( GL_TEXTURE_2D, 0 ); + gl().glBindTexture( GL_TEXTURE_2D, 0 ); if ( resampled ) { free( outpixels ); } @@ -359,17 +358,17 @@ void qtexture_realise( qtexture_t& texture, const TextureKey& key ){ images[i] = key.first.loadImage( StringOutputStream( 64 )( key.second, suffixes[i] ) ); } if( std::all_of( images, images + std::size( images ), []( const Image *img ){ return img != nullptr; } ) ){ - glGenTextures( 1, &texture.texture_number ); - glBindTexture( GL_TEXTURE_CUBE_MAP, texture.texture_number ); - glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_FALSE ); + gl().glGenTextures( 1, &texture.texture_number ); + gl().glBindTexture( GL_TEXTURE_CUBE_MAP, texture.texture_number ); + gl().glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_FALSE ); - glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0 ); - glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0); //this or mipmaps are required for samplerCube to work + gl().glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + gl().glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + gl().glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); + gl().glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + gl().glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + gl().glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0 ); + gl().glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0); //this or mipmaps are required for samplerCube to work // fix non quadratic, varying sizes; GL_TEXTURE_CUBE_MAP requires this unsigned int size = 0; for( const auto img : images ) @@ -381,12 +380,12 @@ void qtexture_realise( qtexture_t& texture, const TextureKey& key ){ pix = static_cast( malloc( size * size * 4 ) ); R_ResampleTexture( img.getRGBAPixels(), img.getWidth(), img.getHeight(), pix, size, size, 4 ); } - glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, g_texture_globals.texture_components, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix ); + gl().glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, g_texture_globals.texture_components, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix ); if( pix != img.getRGBAPixels() ) free( pix ); } - glBindTexture( GL_TEXTURE_CUBE_MAP, 0 ); + gl().glBindTexture( GL_TEXTURE_CUBE_MAP, 0 ); globalOutputStream() << "Loaded Skybox: \"" << key.second << "\"\n"; GlobalOpenGL_debugAssertNoErrors(); } @@ -402,7 +401,7 @@ void qtexture_realise( qtexture_t& texture, const TextureKey& key ){ void qtexture_unrealise( qtexture_t& texture ){ if ( GlobalOpenGL().contextValid && texture.texture_number != 0 ) { - glDeleteTextures( 1, &texture.texture_number ); + gl().glDeleteTextures( 1, &texture.texture_number ); GlobalOpenGL_debugAssertNoErrors(); } } @@ -545,7 +544,7 @@ public: } - glGetIntegerv( GL_MAX_TEXTURE_SIZE, &max_tex_size ); + gl().glGetIntegerv( GL_MAX_TEXTURE_SIZE, &max_tex_size ); if ( max_tex_size == 0 ) { max_tex_size = 1024; } @@ -608,12 +607,12 @@ void Textures_ModeChanged(){ for ( TexturesMap::iterator i = g_texturesmap->begin(); i != g_texturesmap->end(); ++i ) { - glBindTexture( GL_TEXTURE_2D, ( *i ).value->texture_number ); + gl().glBindTexture( GL_TEXTURE_2D, ( *i ).value->texture_number ); SetTexParameters( g_texture_mode ); SetTexAnisotropy( g_TextureAnisotropy ); } - glBindTexture( GL_TEXTURE_2D, 0 ); + gl().glBindTexture( GL_TEXTURE_2D, 0 ); } g_texturesModeChangedNotify(); } @@ -776,7 +775,6 @@ void Textures_constructPreferences( PreferencesPage& page ){ } page.appendSpinner( "Texture Gamma", - 1.0, 0.0, 5.0, FloatImportCallback( TextureGammaImportCaller( g_texture_globals.fGamma ) ), @@ -852,6 +850,7 @@ void Textures_Destroy(){ #include "modulesystem/modulesmap.h" #include "modulesystem/singletonmodule.h" #include "modulesystem/moduleregistry.h" +#include "qerplugin.h" class TexturesDependencies : public GlobalRadiantModuleRef, diff --git a/radiant/texwindow.cpp b/radiant/texwindow.cpp index 335db2a9..0e89f03f 100644 --- a/radiant/texwindow.cpp +++ b/radiant/texwindow.cpp @@ -28,7 +28,6 @@ #include "texwindow.h" #include "debugging/debugging.h" -#include "warnings.h" #include "ifilesystem.h" #include "iundo.h" @@ -40,7 +39,21 @@ #include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "signal/signal.h" #include "math/vector.h" @@ -64,6 +77,8 @@ #include "gtkutil/glwidget.h" #include "gtkutil/messagebox.h" #include "gtkutil/toolbar.h" +#include "gtkutil/mousepresses.h" +#include "gtkutil/guisettings.h" #include "error.h" #include "map.h" @@ -128,79 +143,36 @@ bool g_TextureBrowser_filter_searchFromStart = false; } - -void TextureBrowser_scrollChanged( void* data, gdouble value ); - - enum StartupShaders { STARTUPSHADERS_NONE = 0, STARTUPSHADERS_COMMON, }; -void TextureBrowser_hideUnusedExport( const BoolImportCallback& importer ); -typedef FreeCaller1 TextureBrowserHideUnusedExport; - -void TextureBrowser_showShadersExport( const BoolImportCallback& importer ); -typedef FreeCaller1 TextureBrowserShowShadersExport; - -void TextureBrowser_showTexturesExport( const BoolImportCallback& importer ); -typedef FreeCaller1 TextureBrowserShowTexturesExport; - -void TextureBrowser_showShaderlistOnly( const BoolImportCallback& importer ){ - importer( g_TextureBrowser_shaderlistOnly ); -} -typedef FreeCaller1 TextureBrowserShowShaderlistOnlyExport; - -void TextureBrowser_fixedSize( const BoolImportCallback& importer ){ - importer( g_TextureBrowser_fixedSize ); -} -typedef FreeCaller1 TextureBrowserFixedSizeExport; - -void TextureBrowser_filterNotex( const BoolImportCallback& importer ){ - importer( g_TextureBrowser_filterNotex ); -} -typedef FreeCaller1 TextureBrowserFilterNotexExport; - -void TextureBrowser_enableAlpha( const BoolImportCallback& importer ){ - importer( g_TextureBrowser_enableAlpha ); -} -typedef FreeCaller1 TextureBrowserEnableAlphaExport; - -void TextureBrowser_filter_searchFromStart( const BoolImportCallback& importer ){ - importer( g_TextureBrowser_filter_searchFromStart ); -} -typedef FreeCaller1 TextureBrowser_filter_searchFromStartExport; - class TextureBrowser { -public: - int width, height; - int originy; + int m_originy; int m_nTotalHeight; +public: + int m_width, m_height; - CopiedString shader; + CopiedString m_shader; // current shader - GtkWindow* m_parent; - GtkWidget* m_gl_widget; - GtkWidget* m_texture_scroll; - GtkWidget* m_treeViewTree; - GtkWidget* m_treeViewTags; - GtkWidget* m_tag_frame; - GtkListStore* m_assigned_store; - GtkListStore* m_available_store; - GtkWidget* m_assigned_tree; - GtkWidget* m_available_tree; - GtkWidget* m_scr_win_tree; - GtkWidget* m_scr_win_tags; - GtkWidget* m_tag_notebook; - GtkWidget* m_search_button; - GtkWidget* m_shader_info_item; - GtkWidget* m_filter_entry; + QWidget* m_parent; + QOpenGLWidget* m_gl_widget; + QScrollBar* m_texture_scroll; + QTabWidget* m_tabs; + QTreeView* m_treeView; + QStandardItemModel* m_treeViewModel; + QListWidget* m_tagsListWidget; + QMenu* m_tagsMenu; + QAction* m_shader_info_item{}; + QLineEdit* m_filter_entry; + QAction* m_filter_action; + CopiedString m_filter_string; std::set m_all_tags; - GtkListStore* m_all_tags_list; std::vector m_copied_tags; std::set m_found_shaders; @@ -211,88 +183,56 @@ public: ToggleItem m_fixedsize_item; ToggleItem m_filternotex_item; ToggleItem m_enablealpha_item; + ToggleItem m_tags_item; ToggleItem m_filter_searchFromStart_item; - guint m_sizeHandler; - guint m_exposeHandler; - bool m_heightChanged; bool m_originInvalid; DeferredAdjustment m_scrollAdjustment; FreezePointer m_freezePointer; - Vector3 color_textureback; -// the increment step we use against the wheel mouse - std::size_t m_mouseWheelScrollIncrement; + Vector3 m_color_textureback; + // the increment step we use against the wheel mouse + int m_mouseWheelScrollIncrement; std::size_t m_textureScale; -// make the texture increments match the grid changes + bool m_showShaders; bool m_showTextures; bool m_showTextureScrollbar; StartupShaders m_startupShaders; -// if true, the texture window will only display in-use shaders -// if false, all the shaders in memory are displayed + // if true, the texture window will only display in-use shaders + // if false, all the shaders in memory are displayed bool m_hideUnused; - bool m_rmbSelected; - bool m_searchedTags; - bool m_tags; + bool m_searchedTags; // flag to show m_found_shaders + bool m_tags; // whether to show tags gui bool m_move_started; - int m_move_amount; - BasicVector2 m_move_start; -// The uniform size (in pixels) that textures are resized to when m_resizeTextures is true. + // The uniform size (in pixels) that textures are resized to when m_resizeTextures is true. int m_uniformTextureSize; int m_uniformTextureMinSize; bool m_hideNonShadersInCommon; static bool wads; -// Return the display width of a texture in the texture browser - void getTextureWH( qtexture_t* tex, int &W, int &H ){ - // Don't use uniform size - W = std::max( std::size_t( 1 ), tex->width * m_textureScale / 100 ); - H = std::max( std::size_t( 1 ), tex->height * m_textureScale / 100 ); - - if ( g_TextureBrowser_fixedSize ){ - if ( W >= H ) { - // Texture is square, or wider than it is tall - if ( W >= m_uniformTextureSize ){ - H = m_uniformTextureSize * H / W; - W = m_uniformTextureSize; - } - else if ( W <= m_uniformTextureMinSize ){ - H = m_uniformTextureMinSize * H / W; - W = m_uniformTextureMinSize; - } - } - else { - // Texture taller than it is wide - if ( H >= m_uniformTextureSize ){ - W = m_uniformTextureSize * W / H; - H = m_uniformTextureSize; - } - else if ( H <= m_uniformTextureMinSize ){ - W = m_uniformTextureMinSize * W / H; - H = m_uniformTextureMinSize; - } - } - } - } TextureBrowser() : m_texture_scroll( 0 ), - m_hideunused_item( TextureBrowserHideUnusedExport() ), - m_showshaders_item( TextureBrowserShowShadersExport() ), - m_showtextures_item( TextureBrowserShowTexturesExport() ), - m_showshaderlistonly_item( TextureBrowserShowShaderlistOnlyExport() ), - m_fixedsize_item( TextureBrowserFixedSizeExport() ), - m_filternotex_item( TextureBrowserFilterNotexExport() ), - m_enablealpha_item( TextureBrowserEnableAlphaExport() ), - m_filter_searchFromStart_item( TextureBrowser_filter_searchFromStartExport() ), + m_hideunused_item( BoolExportCaller( m_hideUnused ) ), + m_showshaders_item( BoolExportCaller( m_showShaders ) ), + m_showtextures_item( BoolExportCaller( m_showTextures ) ), + m_showshaderlistonly_item( BoolExportCaller( g_TextureBrowser_shaderlistOnly ) ), + m_fixedsize_item( BoolExportCaller( g_TextureBrowser_fixedSize ) ), + m_filternotex_item( BoolExportCaller( g_TextureBrowser_filterNotex ) ), + m_enablealpha_item( BoolExportCaller( g_TextureBrowser_enableAlpha ) ), + m_tags_item( BoolExportCaller( m_tags ) ), + m_filter_searchFromStart_item( BoolExportCaller( g_TextureBrowser_filter_searchFromStart ) ), m_heightChanged( true ), m_originInvalid( true ), - m_scrollAdjustment( TextureBrowser_scrollChanged, this ), - color_textureback( 0.25f, 0.25f, 0.25f ), + m_scrollAdjustment( [this]( int value ){ + //globalOutputStream() << "vertical scroll\n"; + setOriginY( -value ); + } ), + m_color_textureback( 0.25f, 0.25f, 0.25f ), m_mouseWheelScrollIncrement( 64 ), m_textureScale( 50 ), m_showShaders( true ), @@ -300,7 +240,6 @@ public: m_showTextureScrollbar( true ), m_startupShaders( STARTUPSHADERS_NONE ), m_hideUnused( false ), - m_rmbSelected( false ), m_searchedTags( false ), m_tags( false ), m_move_started( false ), @@ -308,63 +247,129 @@ public: m_uniformTextureMinSize( 48 ), m_hideNonShadersInCommon( true ){ } + void queueDraw() const { + if ( m_gl_widget != nullptr ) + widget_queue_draw( *m_gl_widget ); + } + void draw(); + void setOriginY( int originy ){ + m_originy = originy; + clampOriginY(); + updateScroll(); + queueDraw(); + } +private: + void clampOriginY(){ + m_originy = std::clamp( m_originy, m_height - totalHeight(), 0 ); + } + void evaluateHeight(); + int totalHeight(){ + evaluateHeight(); + return m_nTotalHeight; + } +public: + int getOriginY(){ + if ( m_originInvalid ) { + m_originInvalid = false; + clampOriginY(); + updateScroll(); + } + return m_originy; + } + void heightChanged(){ + m_heightChanged = true; + updateScroll(); + queueDraw(); + } + void updateScroll(){ + if ( m_showTextureScrollbar ) { + const int total_height = std::max( totalHeight(), m_height ); + + QScrollBar* s = m_texture_scroll; + s->setMinimum( 0 ); + s->setMaximum( total_height - m_height ); + s->setValue( - getOriginY() ); + s->setPageStep( m_height ); + s->setSingleStep( 20 ); + } + } + // Return the display width of a texture in the texture browser + auto getTextureWH( const qtexture_t* tex ) const { + // Don't use uniform size + int W = std::max( std::size_t( 1 ), tex->width * m_textureScale / 100 ); + int H = std::max( std::size_t( 1 ), tex->height * m_textureScale / 100 ); + + if ( g_TextureBrowser_fixedSize ){ + if ( W >= H ) { + // Texture is square, or wider than it is tall + if ( W > m_uniformTextureSize ){ + H = m_uniformTextureSize * H / W; + W = m_uniformTextureSize; + } + else if ( W < m_uniformTextureMinSize ){ + H = m_uniformTextureMinSize * H / W; + W = m_uniformTextureMinSize; + } + } + else { + // Texture taller than it is wide + if ( H > m_uniformTextureSize ){ + W = m_uniformTextureSize * W / H; + H = m_uniformTextureSize; + } + else if ( H < m_uniformTextureMinSize ){ + W = m_uniformTextureMinSize * W / H; + H = m_uniformTextureMinSize; + } + } + } + return std::pair( W, H ); + } }; bool TextureBrowser::wads = false; +static TextureBrowser g_TexBro; + void ( *TextureBrowser_textureSelected )( const char* shader ); -void TextureBrowser_updateScroll( TextureBrowser& textureBrowser ); - - -void TextureBrowser_queueDraw( TextureBrowser& textureBrowser ){ - if ( textureBrowser.m_gl_widget != 0 ) { - gtk_widget_queue_draw( textureBrowser.m_gl_widget ); - } +inline const char* TextureBrowser_getCommonShadersName(){ + static const char* const value = string_empty( g_pGameDescription->getKeyValue( "common_shaders_name" ) ) + ? "Common" + : g_pGameDescription->getKeyValue( "common_shaders_name" ); + return value; } -const char* TextureBrowser_getCommonShadersName(){ - const char* value = g_pGameDescription->getKeyValue( "common_shaders_name" ); - if ( !string_empty( value ) ) { - return value; - } - return "Common"; +inline const char* TextureBrowser_getCommonShadersDir(){ + static const char* const value = string_empty( g_pGameDescription->getKeyValue( "common_shaders_dir" ) ) + ? "common/" + : g_pGameDescription->getKeyValue( "common_shaders_dir" ); + return value; } -const char* TextureBrowser_getCommonShadersDir(){ - const char* value = g_pGameDescription->getKeyValue( "common_shaders_dir" ); - if ( !string_empty( value ) ) { - return value; - } - return "common/"; -} - -inline int TextureBrowser_fontHeight( TextureBrowser& textureBrowser ){ +inline int TextureBrowser_fontHeight(){ return GlobalOpenGL().m_font->getPixelHeight(); } const char* TextureBrowser_GetSelectedShader(){ - return GlobalTextureBrowser().shader.c_str(); + return g_TexBro.m_shader.c_str(); } -const char* TextureBrowser_GetSelectedShader( TextureBrowser& textureBrowser ){ - return textureBrowser.shader.c_str(); -} - -void TextureBrowser_SetStatus( TextureBrowser& textureBrowser, const char* name ){ +void TextureBrowser_SetStatus( const char* name ){ IShader* shader = QERApp_Shader_ForName( name ); qtexture_t* q = shader->getTexture(); StringOutputStream strTex( 256 ); - strTex << ( string_equal_prefix_nocase( name, "textures/" )? name + 9 : name ) << " W: " << Unsigned( q->width ) << " H: " << Unsigned( q->height ); + strTex << ( string_equal_prefix_nocase( name, "textures/" )? name + 9 : name ) << " W: " << q->width << " H: " << q->height; shader->DecRef(); g_pParentWnd->SetStatusText( c_status_texture, strTex.c_str() ); } void TextureBrowser_Focus( TextureBrowser& textureBrowser, const char* name ); +void TextureBrowser_tagsSetCheckboxesForShader( const char *shader ); void TextureBrowser_SetSelectedShader( TextureBrowser& textureBrowser, const char* shader ){ - textureBrowser.shader = shader; - TextureBrowser_SetStatus( textureBrowser, shader ); + textureBrowser.m_shader = shader; + TextureBrowser_SetStatus( shader ); TextureBrowser_Focus( textureBrowser, shader ); if ( FindTextureDialog_isOpen() ) { @@ -372,24 +377,21 @@ void TextureBrowser_SetSelectedShader( TextureBrowser& textureBrowser, const cha } // disable the menu item "shader info" if no shader was selected - if ( textureBrowser.m_shader_info_item == NULL ){ - return; - } - IShader* ishader = QERApp_Shader_ForName( shader ); - CopiedString filename = ishader->getShaderFileName(); + if ( textureBrowser.m_shader_info_item != nullptr ){ + IShader* ishader = QERApp_Shader_ForName( shader ); + CopiedString filename = ishader->getShaderFileName(); - if ( filename.empty() ) { - gtk_widget_set_sensitive( textureBrowser.m_shader_info_item, FALSE ); - } - else { - gtk_widget_set_sensitive( textureBrowser.m_shader_info_item, TRUE ); + textureBrowser.m_shader_info_item->setDisabled( filename.empty() ); + + ishader->DecRef(); } - ishader->DecRef(); + if( textureBrowser.m_tabs->currentIndex() == 1 ) + TextureBrowser_tagsSetCheckboxesForShader( shader ); } void TextureBrowser_SetSelectedShader( const char* shader ){ - TextureBrowser_SetSelectedShader( GlobalTextureBrowser(), shader ); + TextureBrowser_SetSelectedShader( g_TexBro, shader ); } @@ -406,56 +408,41 @@ CopiedString g_TextureBrowser_currentDirectory; ============================================================================ */ -class TextureLayout +struct TextureLayout { -public: // texture layout functions // TTimo: now based on shaders - int current_x, current_y, current_row; + int current_x = 8; + int current_y = -4; + int current_row = 0; + + auto nextPos( const TextureBrowser& textureBrowser, qtexture_t* current_texture ){ + const auto [nWidth, nHeight] = textureBrowser.getTextureWH( current_texture ); + if ( current_x + nWidth > textureBrowser.m_width - 8 && current_row ) { // go to the next row unless the texture is the first on the row + current_x = 8; + current_y -= current_row + TextureBrowser_fontHeight() + 1;//+4 + current_row = 0; + } + + const int x = current_x; + const int y = current_y; + + // Is our texture larger than the row? If so, grow the + // row height to match it + + if ( current_row < nHeight ) { + current_row = nHeight; + } + + // never go less than 96, or the names get all crunched up + current_x += std::max( nWidth, 96 ) + 8; + + return std::pair( x, y ); + } }; -void Texture_StartPos( TextureLayout& layout ){ - layout.current_x = 8; - layout.current_y = -4; - layout.current_row = 0; -} - -void Texture_NextPos( TextureBrowser& textureBrowser, TextureLayout& layout, qtexture_t* current_texture, int *x, int *y ){ - qtexture_t* q = current_texture; - - int nWidth, nHeight; - textureBrowser.getTextureWH( q, nWidth, nHeight ); - if ( layout.current_x + nWidth > textureBrowser.width - 8 && layout.current_row ) { // go to the next row unless the texture is the first on the row - layout.current_x = 8; - layout.current_y -= layout.current_row + TextureBrowser_fontHeight( textureBrowser ) + 1;//+4 - layout.current_row = 0; - } - - *x = layout.current_x; - *y = layout.current_y; - - // Is our texture larger than the row? If so, grow the - // row height to match it - - if ( layout.current_row < nHeight ) { - layout.current_row = nHeight; - } - - // never go less than 96, or the names get all crunched up - layout.current_x += nWidth < 96 ? 96 : nWidth; - layout.current_x += 8; -} - -bool TextureSearch_IsShown( const char* name ){ - std::set::iterator iter; - - iter = GlobalTextureBrowser().m_found_shaders.find( name ); - - return iter != GlobalTextureBrowser().m_found_shaders.end(); -} - -bool Texture_filtered( const char* name, TextureBrowser& textureBrowser ){ - const char* filter = gtk_entry_get_text( GTK_ENTRY( textureBrowser.m_filter_entry ) ); +bool Texture_filtered( const char* name, const TextureBrowser& textureBrowser ){ + const char* filter = textureBrowser.m_filter_string.c_str(); if( string_empty( filter ) ){ return false; } @@ -480,25 +467,12 @@ CopiedString g_shadernotex; bool show_shaders, bool show_textures, bool hideUnused, bool hideNonShadersInCommon textureBrowser.m_showShaders, textureBrowser.m_showTextures, textureBrowser.m_hideUnused, textureBrowser.m_hideNonShadersInCommon */ -bool Texture_IsShown( IShader* shader, TextureBrowser& textureBrowser ){ +bool Texture_IsShown( IShader* shader, const TextureBrowser& textureBrowser ){ // filter notex / shadernotex images if ( g_TextureBrowser_filterNotex && ( string_equal( g_notex.c_str(), shader->getTexture()->name ) || string_equal( g_shadernotex.c_str(), shader->getTexture()->name ) ) ) { return false; } - if ( g_TextureBrowser_currentDirectory == "Untagged" ) { - std::set::iterator iter; - - iter = textureBrowser.m_found_shaders.find( shader->getName() ); - - if ( iter == textureBrowser.m_found_shaders.end() ) { - return false; - } - else { - return true; - } - } - if ( !shader_equal_prefix( shader->getName(), "textures/" ) ) { return false; } @@ -521,7 +495,7 @@ bool Texture_IsShown( IShader* shader, TextureBrowser& textureBrowser ){ } if ( textureBrowser.m_searchedTags ) { - return TextureSearch_IsShown( shader->getName() ); + return textureBrowser.m_found_shaders.find( shader->getName() ) != textureBrowser.m_found_shaders.cend(); } else { if ( !shader_equal_prefix( shader_get_textureName( shader->getName() ), g_TextureBrowser_currentDirectory.c_str() ) ) { @@ -536,69 +510,26 @@ bool Texture_IsShown( IShader* shader, TextureBrowser& textureBrowser ){ return true; } -void TextureBrowser_heightChanged( TextureBrowser& textureBrowser ){ - textureBrowser.m_heightChanged = true; +void TextureBrowser::evaluateHeight(){ + if ( m_heightChanged ) { + m_heightChanged = false; - TextureBrowser_updateScroll( textureBrowser ); - TextureBrowser_queueDraw( textureBrowser ); -} - -void TextureBrowser_evaluateHeight( TextureBrowser& textureBrowser ){ - if ( textureBrowser.m_heightChanged ) { - textureBrowser.m_heightChanged = false; - - textureBrowser.m_nTotalHeight = 0; + m_nTotalHeight = 0; TextureLayout layout; - Texture_StartPos( layout ); for ( QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement() ) { IShader* shader = QERApp_ActiveShaders_IteratorCurrent(); - if ( !Texture_IsShown( shader, textureBrowser ) ) { - continue; + if ( Texture_IsShown( shader, *this ) ) { + layout.nextPos( *this, shader->getTexture() ); + const auto [nWidth, nHeight] = getTextureWH( shader->getTexture() ); + m_nTotalHeight = std::max( m_nTotalHeight, abs( layout.current_y ) + TextureBrowser_fontHeight() + nHeight + 4 ); } - - int x, y; - Texture_NextPos( textureBrowser, layout, shader->getTexture(), &x, &y ); - int nWidth, nHeight; - textureBrowser.getTextureWH( shader->getTexture(), nWidth, nHeight ); - textureBrowser.m_nTotalHeight = std::max( textureBrowser.m_nTotalHeight, abs( layout.current_y ) + TextureBrowser_fontHeight( textureBrowser ) + nHeight + 4 ); } } } -int TextureBrowser_TotalHeight( TextureBrowser& textureBrowser ){ - TextureBrowser_evaluateHeight( textureBrowser ); - return textureBrowser.m_nTotalHeight; -} - -void TextureBrowser_clampOriginY( TextureBrowser& textureBrowser ){ - if ( textureBrowser.originy > 0 ) { - textureBrowser.originy = 0; - } - const int lower = std::min( textureBrowser.height - TextureBrowser_TotalHeight( textureBrowser ), 0 ); - if ( textureBrowser.originy < lower ) { - textureBrowser.originy = lower; - } -} - -int TextureBrowser_getOriginY( TextureBrowser& textureBrowser ){ - if ( textureBrowser.m_originInvalid ) { - textureBrowser.m_originInvalid = false; - TextureBrowser_clampOriginY( textureBrowser ); - TextureBrowser_updateScroll( textureBrowser ); - } - return textureBrowser.originy; -} - -void TextureBrowser_setOriginY( TextureBrowser& textureBrowser, int originy ){ - textureBrowser.originy = originy; - TextureBrowser_clampOriginY( textureBrowser ); - TextureBrowser_updateScroll( textureBrowser ); - TextureBrowser_queueDraw( textureBrowser ); -} - Signal0 g_activeShadersChangedCallbacks; @@ -630,7 +561,7 @@ void TextureBrowser_addShadersRealiseCallback( const SignalHandler& handler ){ } void TextureBrowser_activeShadersChanged( TextureBrowser& textureBrowser ){ - TextureBrowser_heightChanged( textureBrowser ); + textureBrowser.heightChanged(); textureBrowser.m_originInvalid = true; g_activeShadersChangedCallbacks(); @@ -639,8 +570,8 @@ void TextureBrowser_activeShadersChanged( TextureBrowser& textureBrowser ){ void TextureBrowser_importShowScrollbar( TextureBrowser& textureBrowser, bool value ){ textureBrowser.m_showTextureScrollbar = value; if ( textureBrowser.m_texture_scroll != 0 ) { - widget_set_visible( textureBrowser.m_texture_scroll, textureBrowser.m_showTextureScrollbar ); - TextureBrowser_updateScroll( textureBrowser ); + textureBrowser.m_texture_scroll->setVisible( textureBrowser.m_showTextureScrollbar ); + textureBrowser.updateScroll(); } } typedef ReferenceCaller1 TextureBrowserImportShowScrollbarCaller; @@ -661,7 +592,7 @@ typedef ReferenceCaller1mGameType != "doom3" ) { // load remaining texture files @@ -791,60 +722,24 @@ void TextureBrowser_ShowDirectory( TextureBrowser& textureBrowser, const char* d } } - TextureBrowser_SetHideUnused( textureBrowser, false ); - TextureBrowser_setOriginY( textureBrowser, 0 ); + TextureBrowser_SetHideUnused( g_TexBro, false ); + g_TexBro.setOriginY( 0 ); TextureBrowser_updateTitle(); } -void TextureBrowser_ShowTagSearchResult( TextureBrowser& textureBrowser, const char* directory ){ - g_TextureBrowser_currentDirectory = directory; - TextureBrowser_heightChanged( textureBrowser ); - - std::size_t shaders_count; - GlobalShaderSystem().foreachShaderName( makeCallback1( TextureCategoryLoadShader( directory, shaders_count ) ) ); - globalOutputStream() << "Showing " << Unsigned( shaders_count ) << " shaders.\n"; - - if ( g_pGameDescription->mGameType != "doom3" ) { - // load remaining texture files - StringOutputStream dirstring( 64 ); - dirstring << "textures/" << directory; - - { - LoadTexturesByTypeVisitor visitor( dirstring.c_str() ); - Radiant_getImageModules().foreachModule( visitor ); - } - } - - // we'll display the newly loaded textures + all the ones already in use - TextureBrowser_SetHideUnused( textureBrowser, false ); -} - - -void TextureBrowser_hideUnusedExport( const BoolImportCallback& importer ){ - importer( GlobalTextureBrowser().m_hideUnused ); -} - -void TextureBrowser_showShadersExport( const BoolImportCallback& importer ){ - importer( GlobalTextureBrowser().m_showShaders ); -} - -void TextureBrowser_showTexturesExport( const BoolImportCallback& importer ){ - importer( GlobalTextureBrowser().m_showTextures ); -} - void TextureBrowser_SetHideUnused( TextureBrowser& textureBrowser, bool hideUnused ){ textureBrowser.m_hideUnused = hideUnused; textureBrowser.m_hideunused_item.update(); - TextureBrowser_heightChanged( textureBrowser ); + textureBrowser.heightChanged(); textureBrowser.m_originInvalid = true; } -void TextureBrowser_ShowStartupShaders( TextureBrowser& textureBrowser ){ - if ( textureBrowser.m_startupShaders == STARTUPSHADERS_COMMON ) { - TextureBrowser_ShowDirectory( textureBrowser, TextureBrowser_getCommonShadersDir() ); +void TextureBrowser_ShowStartupShaders(){ + if ( g_TexBro.m_startupShaders == STARTUPSHADERS_COMMON ) { + TextureBrowser_ShowDirectory( TextureBrowser_getCommonShadersDir() ); } } @@ -856,7 +751,6 @@ void TextureBrowser_ShowStartupShaders( TextureBrowser& textureBrowser ){ void TextureBrowser_Focus( TextureBrowser& textureBrowser, const char* name ){ TextureLayout layout; // scroll origin so the texture is completely on screen - Texture_StartPos( layout ); for ( QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement() ) { @@ -866,8 +760,7 @@ void TextureBrowser_Focus( TextureBrowser& textureBrowser, const char* name ){ continue; } - int x, y; - Texture_NextPos( textureBrowser, layout, shader->getTexture(), &x, &y ); + const auto [ x, y ] = layout.nextPos( textureBrowser, shader->getTexture() ); qtexture_t* q = shader->getTexture(); if ( !q ) { break; @@ -876,32 +769,30 @@ void TextureBrowser_Focus( TextureBrowser& textureBrowser, const char* name ){ // we have found when texdef->name and the shader name match // NOTE: as everywhere else for our comparisons, we are not case sensitive if ( shader_equal( name, shader->getName() ) ) { - //int textureHeight = (int)( q->height * ( (float)textureBrowser.m_textureScale / 100 ) ) + 2 * TextureBrowser_fontHeight( textureBrowser ); - int textureWidth, textureHeight; - textureBrowser.getTextureWH( q, textureWidth, textureHeight ); - textureHeight += 2 * TextureBrowser_fontHeight( textureBrowser ); + //int textureHeight = (int)( q->height * ( (float)textureBrowser.m_textureScale / 100 ) ) + 2 * TextureBrowser_fontHeight(); + auto [textureWidth, textureHeight] = textureBrowser.getTextureWH( q ); + textureHeight += 2 * TextureBrowser_fontHeight(); - int originy = TextureBrowser_getOriginY( textureBrowser ); + int originy = textureBrowser.getOriginY(); if ( y > originy ) { originy = y + 4; } - if ( y - textureHeight < originy - textureBrowser.height ) { - originy = ( y - textureHeight ) + textureBrowser.height; + if ( y - textureHeight < originy - textureBrowser.m_height ) { + originy = ( y - textureHeight ) + textureBrowser.m_height; } - TextureBrowser_setOriginY( textureBrowser, originy ); + textureBrowser.setOriginY( originy ); return; } } } IShader* Texture_At( TextureBrowser& textureBrowser, int mx, int my ){ - my += TextureBrowser_getOriginY( textureBrowser ) - textureBrowser.height; + my = textureBrowser.getOriginY() - my - 1; TextureLayout layout; - Texture_StartPos( layout ); for ( QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement() ) { IShader* shader = QERApp_ActiveShaders_IteratorCurrent(); @@ -910,17 +801,15 @@ IShader* Texture_At( TextureBrowser& textureBrowser, int mx, int my ){ continue; } - int x, y; - Texture_NextPos( textureBrowser, layout, shader->getTexture(), &x, &y ); + const auto [ x, y ] = layout.nextPos( textureBrowser, shader->getTexture() ); qtexture_t *q = shader->getTexture(); if ( !q ) { break; } - int nWidth, nHeight; - textureBrowser.getTextureWH( q, nWidth, nHeight ); + const auto [nWidth, nHeight] = textureBrowser.getTextureWH( q ); if ( mx > x && mx - x < nWidth - && my < y && y - my < nHeight + TextureBrowser_fontHeight( textureBrowser ) ) { + && my < y && y - my < nHeight + TextureBrowser_fontHeight() ) { return shader; } } @@ -935,16 +824,14 @@ IShader* Texture_At( TextureBrowser& textureBrowser, int mx, int my ){ By mouse click ============== */ -void SelectTexture( TextureBrowser& textureBrowser, int mx, int my, guint32 flags, bool texturizeSelection ){ - if ( ( flags & GDK_SHIFT_MASK ) == 0 ) { - IShader* shader = Texture_At( textureBrowser, mx, my ); - if ( shader != 0 ) { - TextureBrowser_SetSelectedShader( textureBrowser, shader->getName() ); - TextureBrowser_textureSelected( shader->getName() ); +void SelectTexture( TextureBrowser& textureBrowser, int mx, int my, bool texturizeSelection ){ + IShader* shader = Texture_At( textureBrowser, mx, my ); + if ( shader != 0 ) { + TextureBrowser_SetSelectedShader( textureBrowser, shader->getName() ); + TextureBrowser_textureSelected( shader->getName() ); - if ( !FindTextureDialog_isOpen() && !textureBrowser.m_rmbSelected && !texturizeSelection ) { - Select_SetShader_Undo( shader->getName() ); - } + if ( !FindTextureDialog_isOpen() && !texturizeSelection ) { + Select_SetShader_Undo( shader->getName() ); } } } @@ -957,16 +844,6 @@ void SelectTexture( TextureBrowser& textureBrowser, int mx, int my, guint32 flag ============================================================================ */ -void TextureBrowser_trackingDelta( int x, int y, unsigned int state, void* data ){ - if ( y != 0 ) { - TextureBrowser& textureBrowser = *reinterpret_cast( data ); - const int scale = ( state & GDK_SHIFT_MASK )? 4 : 1; - const int originy = TextureBrowser_getOriginY( textureBrowser ) + y * scale; - TextureBrowser_setOriginY( textureBrowser, originy ); - textureBrowser.m_move_amount += std::abs( y ); - } -} - void TextureBrowser_Tracking_MouseUp( TextureBrowser& textureBrowser ){ if( textureBrowser.m_move_started ){ textureBrowser.m_move_started = false; @@ -977,24 +854,27 @@ void TextureBrowser_Tracking_MouseUp( TextureBrowser& textureBrowser ){ void TextureBrowser_Tracking_MouseDown( TextureBrowser& textureBrowser ){ TextureBrowser_Tracking_MouseUp( textureBrowser ); textureBrowser.m_move_started = true; - textureBrowser.m_move_amount = 0; - textureBrowser.m_freezePointer.freeze_pointer( textureBrowser.m_parent, textureBrowser.m_gl_widget, TextureBrowser_trackingDelta, &textureBrowser ); + textureBrowser.m_freezePointer.freeze_pointer( textureBrowser.m_gl_widget, + [&textureBrowser]( int x, int y, const QMouseEvent *event ){ + if ( y != 0 ) { + const int scale = event->modifiers().testFlag( Qt::KeyboardModifier::ShiftModifier )? 4 : 1; + const int originy = textureBrowser.getOriginY() + y * scale; + textureBrowser.setOriginY( originy ); + } + }, + [&textureBrowser](){ + TextureBrowser_Tracking_MouseUp( textureBrowser ); + } ); } -void TextureBrowser_Selection_MouseDown( TextureBrowser& textureBrowser, guint32 flags, int pointx, int pointy, bool texturizeSelection ){ - SelectTexture( textureBrowser, pointx, textureBrowser.height - 1 - pointy, flags, texturizeSelection ); -} - -void TextureBrowser_Selection_MouseUp( TextureBrowser& textureBrowser, guint32 flags, int pointx, int pointy ){ - if ( ( flags & GDK_SHIFT_MASK ) != 0 ) { - IShader* shader = Texture_At( textureBrowser, pointx, textureBrowser.height - 1 - pointy ); - if ( shader != 0 ) { - if ( shader->IsDefault() ) { - globalWarningStream() << shader->getName() << " is not a shader, it's a texture.\n"; - } - else{ - DoShaderView( shader->getShaderFileName(), shader->getName(), ( flags & GDK_CONTROL_MASK ) != 0 ); - } +void TextureBrowser_ViewShader( TextureBrowser& textureBrowser, Qt::KeyboardModifiers modifiers, int pointx, int pointy ){ + IShader* shader = Texture_At( textureBrowser, pointx, pointy ); + if ( shader != 0 ) { + if ( shader->IsDefault() ) { + globalWarningStream() << shader->getName() << " is not a shader, it's a texture.\n"; + } + else{ + DoShaderView( shader->getShaderFileName(), shader->getName(), modifiers.testFlag( Qt::KeyboardModifier::ControlModifier ) ); } } } @@ -1009,68 +889,63 @@ void TextureBrowser_Selection_MouseUp( TextureBrowser& textureBrowser, guint32 f /* ============ - Texture_Draw TTimo: relying on the shaders list to display the textures we must query all qtexture_t* to manage and display through the IShaders interface this allows a plugin to completely override the texture system ============ */ -void Texture_Draw( TextureBrowser& textureBrowser ){ - const int fontHeight = TextureBrowser_fontHeight( textureBrowser ); +void TextureBrowser::draw(){ + evaluateHeight(); + const int fontHeight = TextureBrowser_fontHeight(); const int fontDescent = GlobalOpenGL().m_font->getPixelDescent(); - const int originy = TextureBrowser_getOriginY( textureBrowser ); + const int originy = getOriginY(); - glClearColor( textureBrowser.color_textureback[0], - textureBrowser.color_textureback[1], - textureBrowser.color_textureback[2], - 0 ); - glViewport( 0, 0, textureBrowser.width, textureBrowser.height ); - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); + gl().glClearColor( m_color_textureback[0], + m_color_textureback[1], + m_color_textureback[2], + 0 ); + gl().glViewport( 0, 0, m_width, m_height ); + gl().glMatrixMode( GL_PROJECTION ); + gl().glLoadIdentity(); - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - glDisable( GL_DEPTH_TEST ); - if( GlobalOpenGL().GL_1_3() ) { - glDisable( GL_MULTISAMPLE ); - } + gl().glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + gl().glDisable( GL_DEPTH_TEST ); + gl().glDisable( GL_MULTISAMPLE ); if ( g_TextureBrowser_enableAlpha ) { - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + gl().glEnable( GL_BLEND ); + gl().glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); } else { - glDisable( GL_BLEND ); + gl().glDisable( GL_BLEND ); } - glOrtho( 0, textureBrowser.width, originy - textureBrowser.height, originy, -100, 100 ); - glEnable( GL_TEXTURE_2D ); + gl().glOrtho( 0, m_width, originy - m_height, originy, -100, 100 ); + gl().glEnable( GL_TEXTURE_2D ); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + gl().glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); TextureLayout layout; - Texture_StartPos( layout ); for ( QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement() ) { IShader* shader = QERApp_ActiveShaders_IteratorCurrent(); - if ( !Texture_IsShown( shader, textureBrowser ) ) { + if ( !Texture_IsShown( shader, *this ) ) { continue; } - int x, y; - Texture_NextPos( textureBrowser, layout, shader->getTexture(), &x, &y ); + const auto [ x, y ] = layout.nextPos( *this, shader->getTexture() ); qtexture_t *q = shader->getTexture(); if ( !q ) { break; } - int nWidth, nHeight; - textureBrowser.getTextureWH( q, nWidth, nHeight ); + const auto [nWidth, nHeight] = getTextureWH( q ); // Is this texture visible? if ( ( y - nHeight - fontHeight < originy ) - && ( y > originy - textureBrowser.height ) ) { - glLineWidth( 1 ); - glDisable( GL_TEXTURE_2D ); + && ( y > originy - m_height ) ) { + gl().glLineWidth( 1 ); + gl().glDisable( GL_TEXTURE_2D ); const float xf = x; const float yf = y - fontHeight; float xfMax = xf + 1.5 + nWidth; @@ -1078,22 +953,17 @@ void Texture_Draw( TextureBrowser& textureBrowser ){ float yfMax = yf + 1.5; float yfMin = yf - nHeight - 1.5; #define TEXBRO_RENDER_BORDER \ - glBegin( GL_LINE_LOOP ); \ - glVertex2f( xfMin, yfMax ); \ - glVertex2f( xfMin, yfMin ); \ - glVertex2f( xfMax, yfMin ); \ - glVertex2f( xfMax, yfMax ); \ - glEnd(); + gl().glBegin( GL_LINE_LOOP ); \ + gl().glVertex2f( xfMin, yfMax ); \ + gl().glVertex2f( xfMin, yfMin ); \ + gl().glVertex2f( xfMax, yfMin ); \ + gl().glVertex2f( xfMax, yfMax ); \ + gl().glEnd(); //selected texture - if ( shader_equal( TextureBrowser_GetSelectedShader( textureBrowser ), shader->getName() ) ) { - glLineWidth( 2 ); - if ( textureBrowser.m_rmbSelected ) { - glColor3f( 0, 0, 1 ); - } - else { - glColor3f( 1, 0, 0 ); - } + if ( shader_equal( m_shader.c_str(), shader->getName() ) ) { + gl().glLineWidth( 2 ); + gl().glColor3f( 1, 0, 0 ); xfMax += .5; xfMin -= .5; yfMax += .5; @@ -1101,67 +971,67 @@ void Texture_Draw( TextureBrowser& textureBrowser ){ TEXBRO_RENDER_BORDER } // highlight in-use textures - else if ( !textureBrowser.m_hideUnused && shader->IsInUse() ) { - glColor3f( 0.5, 1, 0.5 ); + else if ( !m_hideUnused && shader->IsInUse() ) { + gl().glColor3f( 0.5, 1, 0.5 ); TEXBRO_RENDER_BORDER } // shader white border: else if ( !shader->IsDefault() ) { - glColor3f( 1, 1, 1 ); + gl().glColor3f( 1, 1, 1 ); TEXBRO_RENDER_BORDER } // shader stipple: if ( !shader->IsDefault() ) { - glEnable( GL_LINE_STIPPLE ); - glLineStipple( 1, 0xF000 ); - glColor3f( 0, 0, 0 ); + gl().glEnable( GL_LINE_STIPPLE ); + gl().glLineStipple( 1, 0xF000 ); + gl().glColor3f( 0, 0, 0 ); TEXBRO_RENDER_BORDER - glDisable( GL_LINE_STIPPLE ); + gl().glDisable( GL_LINE_STIPPLE ); } // draw checkerboard for transparent textures if ( g_TextureBrowser_enableAlpha ) { - glBegin( GL_QUADS ); + gl().glBegin( GL_QUADS ); for ( int i = 0; i < nHeight; i += 8 ) for ( int j = 0; j < nWidth; j += 8 ) { const unsigned char color = ( i + j ) / 8 % 2 ? 0x66 : 0x99; - glColor3ub( color, color, color ); + gl().glColor3ub( color, color, color ); const int left = j; const int right = std::min( j + 8, nWidth ); const int top = i; const int bottom = std::min( i + 8, nHeight ); - glVertex2i( x + right, y - nHeight - fontHeight + top ); - glVertex2i( x + left, y - nHeight - fontHeight + top ); - glVertex2i( x + left, y - nHeight - fontHeight + bottom ); - glVertex2i( x + right, y - nHeight - fontHeight + bottom ); + gl().glVertex2i( x + right, y - nHeight - fontHeight + top ); + gl().glVertex2i( x + left, y - nHeight - fontHeight + top ); + gl().glVertex2i( x + left, y - nHeight - fontHeight + bottom ); + gl().glVertex2i( x + right, y - nHeight - fontHeight + bottom ); } - glEnd(); + gl().glEnd(); } // Draw the texture - glEnable( GL_TEXTURE_2D ); - glBindTexture( GL_TEXTURE_2D, q->texture_number ); + gl().glEnable( GL_TEXTURE_2D ); + gl().glBindTexture( GL_TEXTURE_2D, q->texture_number ); GlobalOpenGL_debugAssertNoErrors(); - glColor3f( 1, 1, 1 ); - glBegin( GL_QUADS ); - glTexCoord2i( 0, 0 ); - glVertex2i( x, y - fontHeight ); - glTexCoord2i( 1, 0 ); - glVertex2i( x + nWidth, y - fontHeight ); - glTexCoord2i( 1, 1 ); - glVertex2i( x + nWidth, y - fontHeight - nHeight ); - glTexCoord2i( 0, 1 ); - glVertex2i( x, y - fontHeight - nHeight ); - glEnd(); + gl().glColor3f( 1, 1, 1 ); + gl().glBegin( GL_QUADS ); + gl().glTexCoord2i( 0, 0 ); + gl().glVertex2i( x, y - fontHeight ); + gl().glTexCoord2i( 1, 0 ); + gl().glVertex2i( x + nWidth, y - fontHeight ); + gl().glTexCoord2i( 1, 1 ); + gl().glVertex2i( x + nWidth, y - fontHeight - nHeight ); + gl().glTexCoord2i( 0, 1 ); + gl().glVertex2i( x, y - fontHeight - nHeight ); + gl().glEnd(); // draw the texture name -// glDisable( GL_TEXTURE_2D ); -// glColor3f( 1, 1, 1 ); //already set +// gl().glDisable( GL_TEXTURE_2D ); +// gl().glColor3f( 1, 1, 1 ); //already set - glRasterPos2i( x, y - fontHeight - fontDescent + 3 );//+5 + gl().glRasterPos2i( x, y - fontHeight - fontDescent + 3 );//+5 // don't draw the directory name const char* name = shader->getName(); @@ -1174,8 +1044,8 @@ void Texture_Draw( TextureBrowser& textureBrowser ){ } // reset the current texture - glBindTexture( GL_TEXTURE_2D, 0 ); - glDisable( GL_BLEND ); + gl().glBindTexture( GL_TEXTURE_2D, 0 ); + gl().glDisable( GL_BLEND ); //qglFinish(); } @@ -1187,7 +1057,7 @@ void TextureBrowser_setScale( TextureBrowser& textureBrowser, std::size_t scale textureBrowser.m_originInvalid = true; g_activeShadersChangedCallbacks(); - TextureBrowser_queueDraw( textureBrowser ); + textureBrowser.queueDraw(); } void TextureBrowser_setUniformSize( TextureBrowser& textureBrowser, std::size_t scale ){ @@ -1197,7 +1067,7 @@ void TextureBrowser_setUniformSize( TextureBrowser& textureBrowser, std::size_t textureBrowser.m_originInvalid = true; g_activeShadersChangedCallbacks(); - TextureBrowser_queueDraw( textureBrowser ); + textureBrowser.queueDraw(); } void TextureBrowser_setUniformMinSize( TextureBrowser& textureBrowser, std::size_t scale ){ @@ -1207,234 +1077,15 @@ void TextureBrowser_setUniformMinSize( TextureBrowser& textureBrowser, std::size textureBrowser.m_originInvalid = true; g_activeShadersChangedCallbacks(); - TextureBrowser_queueDraw( textureBrowser ); + textureBrowser.queueDraw(); } -void TextureBrowser_MouseWheel( TextureBrowser& textureBrowser, bool bUp ){ - int originy = TextureBrowser_getOriginY( textureBrowser ); - - if ( bUp ) { - originy += int(textureBrowser.m_mouseWheelScrollIncrement); - } - else - { - originy -= int(textureBrowser.m_mouseWheelScrollIncrement); - } - - TextureBrowser_setOriginY( textureBrowser, originy ); -} - -#include "xml/xmltextags.h" -XmlTagBuilder TagBuilder; - -enum -{ - TAG_COLUMN = 0, - N_COLUMNS = 1 -}; - -void BuildStoreAssignedTags( GtkListStore* store, const char* shader, TextureBrowser* textureBrowser ){ - GtkTreeIter iter; - - gtk_list_store_clear( store ); - - std::vector assigned_tags; - TagBuilder.GetShaderTags( shader, assigned_tags ); - - for ( size_t i = 0; i < assigned_tags.size(); i++ ) - { - gtk_list_store_append( store, &iter ); - gtk_list_store_set( store, &iter, TAG_COLUMN, assigned_tags[i].c_str(), -1 ); - } -} - -void BuildStoreAvailableTags( GtkListStore* storeAvailable, - GtkListStore* storeAssigned, - const std::set& allTags, - TextureBrowser* textureBrowser ){ - GtkTreeIter iterAssigned; - GtkTreeIter iterAvailable; - - gtk_list_store_clear( storeAvailable ); - - bool row = gtk_tree_model_get_iter_first( GTK_TREE_MODEL( storeAssigned ), &iterAssigned ) != 0; - - if ( !row ) { // does the shader have tags assigned? - for ( const CopiedString& tag : allTags ) - { - gtk_list_store_append( storeAvailable, &iterAvailable ); - gtk_list_store_set( storeAvailable, &iterAvailable, TAG_COLUMN, tag.c_str(), -1 ); - } - } - else - { - while ( row ) // available tags = all tags - assigned tags - { - gchar* tag_assigned; - gtk_tree_model_get( GTK_TREE_MODEL( storeAssigned ), &iterAssigned, TAG_COLUMN, &tag_assigned, -1 ); - - for ( const CopiedString& tag : allTags ) - { - if ( !string_equal( tag_assigned, tag.c_str() ) ) { - gtk_list_store_append( storeAvailable, &iterAvailable ); - gtk_list_store_set( storeAvailable, &iterAvailable, TAG_COLUMN, tag.c_str(), -1 ); - } - else - { - row = gtk_tree_model_iter_next( GTK_TREE_MODEL( storeAssigned ), &iterAssigned ) != 0; - - if ( row ) { - g_free( tag_assigned ); - gtk_tree_model_get( GTK_TREE_MODEL( storeAssigned ), &iterAssigned, TAG_COLUMN, &tag_assigned, -1 ); - } - } - } - - g_free( tag_assigned ); - } - } -} - -gboolean TextureBrowser_button_press( GtkWidget* widget, GdkEventButton* event, TextureBrowser* textureBrowser ){ - if ( event->type == GDK_BUTTON_PRESS ) { - gtk_widget_grab_focus( widget ); - if ( event->button == 3 ) { - TextureBrowser_Tracking_MouseDown( *textureBrowser ); - textureBrowser->m_move_start = BasicVector2( event->x, event->y ); - } - else if ( event->button == 1 || event->button == 2 ) { - TextureBrowser_Selection_MouseDown( *textureBrowser, event->state, static_cast( event->x ), static_cast( event->y ), event->button == 2 ); - - if ( GlobalTextureBrowser().m_tags ) { - textureBrowser->m_rmbSelected = false; - gtk_widget_hide( textureBrowser->m_tag_frame ); - } - } - } - /* loads directory, containing active shader + focuses on it */ - else if ( event->type == GDK_2BUTTON_PRESS && event->button == 1 && !TextureBrowser::wads ) { - const StringRange range( strchr( textureBrowser->shader.c_str(), '/' ) + 1, strrchr( textureBrowser->shader.c_str(), '/' ) + 1 ); - if( !range.empty() ){ - const CopiedString dir = range; - ScopeDisableScreenUpdates disableScreenUpdates( dir.c_str(), "Loading Textures" ); - TextureBrowser_ShowDirectory( *textureBrowser, dir.c_str() ); - TextureBrowser_Focus( *textureBrowser, textureBrowser->shader.c_str() ); - TextureBrowser_queueDraw( *textureBrowser ); - } - } - else if ( event->type == GDK_2BUTTON_PRESS && event->button == 3 ) { - ScopeDisableScreenUpdates disableScreenUpdates( TextureBrowser_getCommonShadersDir(), "Loading Textures" ); - TextureBrowser_ShowDirectory( *textureBrowser, TextureBrowser_getCommonShadersDir() ); - TextureBrowser_queueDraw( *textureBrowser ); - } - return FALSE; -} - -gboolean TextureBrowser_button_release( GtkWidget* widget, GdkEventButton* event, TextureBrowser* textureBrowser ){ - if ( event->type == GDK_BUTTON_RELEASE ) { - if ( event->button == 3 ) { - TextureBrowser_Tracking_MouseUp( *textureBrowser ); - if ( GlobalTextureBrowser().m_tags && textureBrowser->m_move_amount < 16 ) { - textureBrowser->m_rmbSelected = true; - TextureBrowser_Selection_MouseDown( *textureBrowser, event->state, textureBrowser->m_move_start.x(), textureBrowser->m_move_start.y(), false ); - - BuildStoreAssignedTags( textureBrowser->m_assigned_store, textureBrowser->shader.c_str(), textureBrowser ); - BuildStoreAvailableTags( textureBrowser->m_available_store, textureBrowser->m_assigned_store, textureBrowser->m_all_tags, textureBrowser ); - textureBrowser->m_heightChanged = true; - gtk_widget_show( textureBrowser->m_tag_frame ); - - process_gui(); - - TextureBrowser_Focus( *textureBrowser, textureBrowser->shader.c_str() ); - } - } - else if ( event->button == 1 ) { - TextureBrowser_Selection_MouseUp( *textureBrowser, event->state, static_cast( event->x ), static_cast( event->y ) ); - } - } - return FALSE; -} - -gboolean TextureBrowser_motion( GtkWidget *widget, GdkEventMotion *event, TextureBrowser* textureBrowser ){ - return FALSE; -} - -gboolean TextureBrowser_scroll( GtkWidget* widget, GdkEventScroll* event, TextureBrowser* textureBrowser ){ - gtk_widget_grab_focus( widget ); - if( !gtk_window_is_active( textureBrowser->m_parent ) ) - gtk_window_present( textureBrowser->m_parent ); - - if ( event->direction == GDK_SCROLL_UP ) { - TextureBrowser_MouseWheel( *textureBrowser, true ); - } - else if ( event->direction == GDK_SCROLL_DOWN ) { - TextureBrowser_MouseWheel( *textureBrowser, false ); - } - return FALSE; -} - -void TextureBrowser_scrollChanged( void* data, gdouble value ){ - //globalOutputStream() << "vertical scroll\n"; - TextureBrowser_setOriginY( *reinterpret_cast( data ), -(int)value ); -} - -static void TextureBrowser_verticalScroll( GtkAdjustment *adjustment, TextureBrowser* textureBrowser ){ - textureBrowser->m_scrollAdjustment.value_changed( gtk_adjustment_get_value( adjustment ) ); -} - -void TextureBrowser_updateScroll( TextureBrowser& textureBrowser ){ - if ( textureBrowser.m_showTextureScrollbar ) { - int totalHeight = TextureBrowser_TotalHeight( textureBrowser ); - - totalHeight = std::max( totalHeight, textureBrowser.height ); - - GtkAdjustment *vadjustment = gtk_range_get_adjustment( GTK_RANGE( textureBrowser.m_texture_scroll ) ); - - gtk_adjustment_set_value( vadjustment, -TextureBrowser_getOriginY( textureBrowser ) ); - gtk_adjustment_set_page_size( vadjustment, textureBrowser.height ); - gtk_adjustment_set_page_increment( vadjustment, textureBrowser.height / 2 ); - gtk_adjustment_set_step_increment( vadjustment, 20 ); - gtk_adjustment_set_lower( vadjustment, 0 ); - gtk_adjustment_set_upper( vadjustment, totalHeight ); - - g_signal_emit_by_name( G_OBJECT( vadjustment ), "changed" ); - } -} - -gboolean TextureBrowser_size_allocate( GtkWidget* widget, GtkAllocation* allocation, TextureBrowser* textureBrowser ){ - textureBrowser->width = allocation->width; - textureBrowser->height = allocation->height; - TextureBrowser_heightChanged( *textureBrowser ); - textureBrowser->m_originInvalid = true; - TextureBrowser_queueDraw( *textureBrowser ); - return FALSE; -} - -gboolean TextureBrowser_expose( GtkWidget* widget, GdkEventExpose* event, TextureBrowser* textureBrowser ){ - if ( glwidget_make_current( textureBrowser->m_gl_widget ) ) { - GlobalOpenGL_debugAssertNoErrors(); - TextureBrowser_evaluateHeight( *textureBrowser ); - Texture_Draw( *textureBrowser ); - GlobalOpenGL_debugAssertNoErrors(); - glwidget_swap_buffers( textureBrowser->m_gl_widget ); - } - return FALSE; -} - - -TextureBrowser g_TextureBrowser; - -TextureBrowser& GlobalTextureBrowser(){ - return g_TextureBrowser; -} - - void TextureBrowser_ToggleHideUnused(){ - TextureBrowser_SetHideUnused( g_TextureBrowser, !g_TextureBrowser.m_hideUnused ); + TextureBrowser_SetHideUnused( g_TexBro, !g_TexBro.m_hideUnused ); } -void TextureGroups_constructTreeModel( TextureGroups groups, GtkTreeStore* store ){ - GtkTreeIter iter, child; +void TextureGroups_constructTreeModel( TextureGroups groups, QStandardItemModel* model ){ + auto root = model->invisibleRootItem(); TextureGroups::const_iterator i = groups.begin(); while ( i != groups.end() ) @@ -1443,33 +1094,34 @@ void TextureGroups_constructTreeModel( TextureGroups groups, GtkTreeStore* store const char* firstUnderscore = strchr( dirName, '_' ); StringRange dirRoot( dirName, ( firstUnderscore == 0 ) ? dirName : firstUnderscore + 1 ); - TextureGroups::const_iterator next = i; - ++next; + TextureGroups::const_iterator next = std::next( i ); if ( firstUnderscore != 0 && next != groups.end() && string_equal_start( ( *next ).c_str(), dirRoot ) ) { - gtk_tree_store_append( store, &iter, NULL ); - gtk_tree_store_set( store, &iter, 0, CopiedString( StringRange( dirName, firstUnderscore ) ).c_str(), 1, "", -1 ); + auto subroot = new QStandardItem( CopiedString( StringRange( dirName, firstUnderscore ) ).c_str() ); + root->appendRow( subroot ); // keep going... while ( i != groups.end() && string_equal_start( ( *i ).c_str(), dirRoot ) ) { - gtk_tree_store_append( store, &child, &iter ); - gtk_tree_store_set( store, &child, 0, ( *i ).c_str(), 1, ( *i ).c_str(), -1 ); + auto item = new QStandardItem( ( *i ).c_str() ); + item->setData( ( *i ).c_str(), Qt::ItemDataRole::ToolTipRole ); + subroot->appendRow( item ); ++i; } } else { - gtk_tree_store_append( store, &iter, NULL ); - gtk_tree_store_set( store, &iter, 0, dirName, 1, dirName, -1 ); + auto item = new QStandardItem( dirName ); + item->setData( dirName, Qt::ItemDataRole::ToolTipRole ); + root->appendRow( item ); ++i; } } } -void TextureGroups_constructTreeModel_childless( TextureGroups groups, GtkTreeStore* store ){ - GtkTreeIter iter; +void TextureGroups_constructTreeModel_childless( TextureGroups groups, QStandardItemModel* model ){ + auto root = model->invisibleRootItem(); TextureGroups::const_iterator i = groups.begin(); while ( i != groups.end() ) @@ -1479,8 +1131,9 @@ void TextureGroups_constructTreeModel_childless( TextureGroups groups, GtkTreeSt const char* pakNameEnd = strrchr( dirName, '.' ); ASSERT_MESSAGE( pakName != 0 && pakNameEnd != 0 && pakNameEnd > pakName, "interesting wad path" ); { - gtk_tree_store_append( store, &iter, NULL ); - gtk_tree_store_set( store, &iter, 0, CopiedString( StringRange( pakName + 1, pakNameEnd ) ).c_str(), 1, dirName, -1 ); + auto item = new QStandardItem( CopiedString( StringRange( pakName + 1, pakNameEnd ) ).c_str() ); + item->setData( dirName, Qt::ItemDataRole::ToolTipRole ); + root->appendRow( item ); ++i; } } @@ -1504,480 +1157,425 @@ void TextureGroups_constructTreeView( TextureGroups& groups ){ void TextureBrowser_constructTreeStore(){ TextureGroups groups; TextureGroups_constructTreeView( groups ); - GtkTreeStore* store = gtk_tree_store_new( 2, G_TYPE_STRING, G_TYPE_STRING ); /* 0=display name;1=load path */ + + auto model = new QStandardItemModel( g_TexBro.m_treeView ); //. ? delete old or clear() & reuse + + // store display name in column #0 and load path in data( Qt::ItemDataRole::ToolTipRole ) + // tooltips are only wanted for TextureBrowser::wads, but well if( !TextureBrowser::wads ) - TextureGroups_constructTreeModel( groups, store ); + TextureGroups_constructTreeModel( groups, model ); else - TextureGroups_constructTreeModel_childless( groups, store ); + TextureGroups_constructTreeModel_childless( groups, model ); - gtk_tree_view_set_model( GTK_TREE_VIEW( g_TextureBrowser.m_treeViewTree ), GTK_TREE_MODEL( store ) ); - - g_object_unref( G_OBJECT( store ) ); + g_TexBro.m_treeView->setModel( model ); } -void TextureBrowser_constructTreeStoreTags(){ - GtkTreeStore* store = gtk_tree_store_new( 1, G_TYPE_STRING ); - GtkTreeModel* model = GTK_TREE_MODEL( g_TextureBrowser.m_all_tags_list ); - - gtk_tree_view_set_model( GTK_TREE_VIEW( g_TextureBrowser.m_treeViewTags ), model ); - - g_object_unref( G_OBJECT( store ) ); -} - -void TreeView_onRowActivated( GtkTreeView* treeview, GtkTreePath* path, GtkTreeViewColumn* col, gpointer userdata ){ - GtkTreeIter iter; - - GtkTreeModel* model = gtk_tree_view_get_model( GTK_TREE_VIEW( treeview ) ); - - if ( gtk_tree_model_get_iter( model, &iter, path ) ) { - gchar dirName[1024]; - - gchar* buffer; - gtk_tree_model_get( model, &iter, 1, &buffer, -1 ); - strcpy( dirName, buffer ); - g_free( buffer ); - - if( string_empty( dirName ) ) //empty = directory group root - return; - - g_TextureBrowser.m_searchedTags = false; +void TreeView_onRowActivated( const QModelIndex& index ){ + auto dirName = index.data( Qt::ItemDataRole::ToolTipRole ).toByteArray(); + if( !dirName.isEmpty() ){ // empty = directory group root + g_TexBro.m_searchedTags = false; if ( !TextureBrowser::wads ) { - strcat( dirName, "/" ); + dirName.append( '/' ); } ScopeDisableScreenUpdates disableScreenUpdates( dirName, "Loading Textures" ); - TextureBrowser_ShowDirectory( GlobalTextureBrowser(), dirName ); - TextureBrowser_queueDraw( GlobalTextureBrowser() ); + TextureBrowser_ShowDirectory( dirName.data() ); + g_TexBro.queueDraw(); //deactivate, so SPACE and RETURN wont be broken for 2d - gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( treeview ) ) ), NULL ); + g_TexBro.m_treeView->clearFocus(); } } -static gboolean TextureBrowser_tree_view_set_tooltip_query_cb( GtkWidget* widget, gint x, gint y, gboolean keyboard_tip, GtkTooltip* tooltip, gpointer data ){ - GtkTreeIter iter; - GtkTreePath* path; - GtkTreeModel* model; - GtkTreeView* tree_view = GTK_TREE_VIEW( widget ); - if( !gtk_tree_view_get_tooltip_context( GTK_TREE_VIEW( widget ), &x, &y, keyboard_tip, &model, &path, &iter ) ) - return FALSE; - gchar* buffer; - gtk_tree_model_get( model, &iter, 1, &buffer, -1 ); - gtk_tooltip_set_text( tooltip, buffer ); - gtk_tree_view_set_tooltip_row( tree_view, tooltip, path ); - g_free( buffer ); - gtk_tree_path_free( path ); - return TRUE; -} +class TexBro_QTreeView : public QTreeView +{ +protected: + bool event( QEvent *event ) override { + if( event->type() == QEvent::ShortcutOverride ){ + event->accept(); + return true; + } + return QTreeView::event( event ); + } +}; void TextureBrowser_createTreeViewTree(){ - GtkCellRenderer* renderer; - g_TextureBrowser.m_treeViewTree = gtk_tree_view_new(); - GtkTreeView* treeview = GTK_TREE_VIEW( g_TextureBrowser.m_treeViewTree ); - //gtk_tree_view_set_enable_search( treeview, FALSE ); + g_TexBro.m_treeView = new TexBro_QTreeView; + g_TexBro.m_treeView->setHeaderHidden( true ); + g_TexBro.m_treeView->setEditTriggers( QAbstractItemView::EditTrigger::NoEditTriggers ); + g_TexBro.m_treeView->setUniformRowHeights( true ); // optimization + g_TexBro.m_treeView->setFocusPolicy( Qt::FocusPolicy::ClickFocus ); + g_TexBro.m_treeView->setExpandsOnDoubleClick( false ); - gtk_tree_view_set_headers_visible( treeview, FALSE ); - g_signal_connect( treeview, "row-activated", (GCallback) TreeView_onRowActivated, NULL ); - - renderer = gtk_cell_renderer_text_new(); - //g_object_set( G_OBJECT( renderer ), "ellipsize", PANGO_ELLIPSIZE_START, NULL ); - gtk_tree_view_insert_column_with_attributes( treeview, -1, "", renderer, "text", 0, NULL ); - - if( TextureBrowser::wads ){ - //gtk_tree_view_set_tooltip_column( treeview, 1 ); - /* set own tooltip callback, since convenience function is using markup */ - g_signal_connect( treeview, "query-tooltip", G_CALLBACK( TextureBrowser_tree_view_set_tooltip_query_cb ), NULL ); - gtk_widget_set_has_tooltip( g_TextureBrowser.m_treeViewTree, TRUE ); - } + QObject::connect( g_TexBro.m_treeView, &QAbstractItemView::activated, TreeView_onRowActivated ); TextureBrowser_constructTreeStore(); } -void TextureBrowser_addTag(); -void TextureBrowser_renameTag(); -void TextureBrowser_deleteTag(); +static QMenu* TextureBrowser_constructViewMenu(){ + QMenu *menu = new QMenu( "View" ); -void TextureBrowser_createContextMenu( GtkWidget *treeview, GdkEventButton *event ){ - GtkWidget* menu = gtk_menu_new(); - - GtkWidget* menuitem = gtk_menu_item_new_with_label( "Add tag" ); - g_signal_connect( menuitem, "activate", (GCallback)TextureBrowser_addTag, treeview ); - gtk_menu_shell_append( GTK_MENU_SHELL( menu ), menuitem ); - - menuitem = gtk_menu_item_new_with_label( "Rename tag" ); - g_signal_connect( menuitem, "activate", (GCallback)TextureBrowser_renameTag, treeview ); - gtk_menu_shell_append( GTK_MENU_SHELL( menu ), menuitem ); - - menuitem = gtk_menu_item_new_with_label( "Delete tag" ); - g_signal_connect( menuitem, "activate", (GCallback)TextureBrowser_deleteTag, treeview ); - gtk_menu_shell_append( GTK_MENU_SHELL( menu ), menuitem ); - - gtk_widget_show_all( menu ); - - gtk_menu_popup( GTK_MENU( menu ), NULL, NULL, NULL, NULL, - ( event != NULL ) ? event->button : 0, - gdk_event_get_time( (GdkEvent*)event ) ); -} - -void TextureBrowser_searchTags(); - -gboolean TreeViewTags_onButtonPressed( GtkWidget *treeview, GdkEventButton *event ){ - if ( event->type == GDK_BUTTON_PRESS && event->button == 3 ) { - GtkTreePath *path; - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( treeview ) ); - - if ( gtk_tree_view_get_path_at_pos( GTK_TREE_VIEW( treeview ), event->x, event->y, &path, NULL, NULL, NULL ) ) { - gtk_tree_selection_unselect_all( selection ); - gtk_tree_selection_select_path( selection, path ); - gtk_tree_path_free( path ); - } - - TextureBrowser_createContextMenu( treeview, event ); - return TRUE; - } - if( event->type == GDK_2BUTTON_PRESS && event->button == 1 ){ - TextureBrowser_searchTags(); - return TRUE; - } - return FALSE; -} - -void TextureBrowser_createTreeViewTags(){ - GtkCellRenderer* renderer; - g_TextureBrowser.m_treeViewTags = gtk_tree_view_new(); - GtkTreeView* treeview = GTK_TREE_VIEW( g_TextureBrowser.m_treeViewTags ); -// gtk_tree_view_set_enable_search( treeview, FALSE ); - - g_signal_connect( treeview, "button-press-event", (GCallback)TreeViewTags_onButtonPressed, NULL ); - - gtk_tree_view_set_headers_visible( treeview, FALSE ); - - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_insert_column_with_attributes( treeview, -1, "", renderer, "text", 0, NULL ); - - TextureBrowser_constructTreeStoreTags(); -} - -GtkMenuItem* TextureBrowser_constructViewMenu( GtkMenu* menu ){ - GtkMenuItem* textures_menu_item = new_sub_menu_item_with_mnemonic( "_View" ); - - if ( g_Layout_enableDetachableMenus.m_value ) { - menu_tearoff( menu ); - } + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); create_check_menu_item_with_mnemonic( menu, "Hide _Unused", "ShowInUse" ); create_menu_item_with_mnemonic( menu, "Show All", "ShowAllTextures" ); - menu_separator( menu ); + menu->addSeparator(); // we always want to show shaders but don't want a "Show Shaders" menu for doom3 and .wad file games if ( g_pGameDescription->mGameType == "doom3" || TextureBrowser::wads ) { - g_TextureBrowser.m_showShaders = true; + g_TexBro.m_showShaders = true; } else { create_check_menu_item_with_mnemonic( menu, "Show shaders", "ToggleShowShaders" ); create_check_menu_item_with_mnemonic( menu, "Show textures", "ToggleShowTextures" ); - menu_separator( menu ); + menu->addSeparator(); } - if ( g_TextureBrowser.m_tags ) { - create_menu_item_with_mnemonic( menu, "Show Untagged", "ShowUntagged" ); - } if ( g_pGameDescription->mGameType != "doom3" && !TextureBrowser::wads ) { create_check_menu_item_with_mnemonic( menu, "ShaderList Only", "ToggleShowShaderlistOnly" ); } if ( !TextureBrowser::wads ) { create_check_menu_item_with_mnemonic( menu, "Hide Image Missing", "FilterNotex" ); - menu_separator( menu ); + menu->addSeparator(); } create_check_menu_item_with_mnemonic( menu, "Fixed Size", "FixedSize" ); create_check_menu_item_with_mnemonic( menu, "Transparency", "EnableAlpha" ); + menu->addSeparator(); + create_check_menu_item_with_mnemonic( menu, "Tags Gui", "TagsToggleGui" ); + if ( !TextureBrowser::wads ) { - menu_separator( menu ); - g_TextureBrowser.m_shader_info_item = GTK_WIDGET( create_menu_item_with_mnemonic( menu, "Shader Info", "ShaderInfo" ) ); - gtk_widget_set_sensitive( g_TextureBrowser.m_shader_info_item, FALSE ); + menu->addSeparator(); + g_TexBro.m_shader_info_item = create_menu_item_with_mnemonic( menu, "Shader Info", "ShaderInfo" ); + g_TexBro.m_shader_info_item->setDisabled( true ); } - return textures_menu_item; + return menu; } -void Popup_View_Menu( GtkMenu *menu ){ - gtk_menu_popup( menu, NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time() ); -} -#if 0 -GtkMenuItem* TextureBrowser_constructToolsMenu( GtkMenu* menu ){ - GtkMenuItem* textures_menu_item = new_sub_menu_item_with_mnemonic( "_Tools" ); - - if ( g_Layout_enableDetachableMenus.m_value ) { - menu_tearoff( menu ); - } - - create_menu_item_with_mnemonic( menu, "Flush & Reload Shaders", "RefreshShaders" ); - create_menu_item_with_mnemonic( menu, "Find / Replace...", "FindReplaceTextures" ); - - return textures_menu_item; -} -#endif -GtkMenuItem* TextureBrowser_constructTagsMenu( GtkMenu* menu ){ - GtkMenuItem* textures_menu_item = new_sub_menu_item_with_mnemonic( "T_ags" ); - - if ( g_Layout_enableDetachableMenus.m_value ) { - menu_tearoff( menu ); - } - - create_menu_item_with_mnemonic( menu, "Add tag", "AddTag" ); - create_menu_item_with_mnemonic( menu, "Rename tag", "RenameTag" ); - create_menu_item_with_mnemonic( menu, "Delete tag", "DeleteTag" ); - menu_separator( menu ); - create_menu_item_with_mnemonic( menu, "Copy tags from selected", "CopyTag" ); - create_menu_item_with_mnemonic( menu, "Paste tags to selected", "PasteTag" ); - - return textures_menu_item; +void Popup_View_Menu( QMenu *menu ){ + menu->popup( QCursor::pos() ); } -gboolean TextureBrowser_tagMoveHelper( GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, std::vector* selected ){ - g_assert( selected != NULL ); - GtkTreeRowReference* rowref = gtk_tree_row_reference_new( model, path ); - selected->push_back( rowref ); +#include "xml/xmltextags.h" +XmlTagBuilder TagBuilder; - return FALSE; + +static QMenu* TextureBrowser_constructTagsMenu(){ + auto menu = new QMenu( "Tags" ); + + menu->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + + create_menu_item_with_mnemonic( menu, "Add tag", "TagAdd" ); + create_menu_item_with_mnemonic( menu, "Rename tag", "TagRename" ); + create_menu_item_with_mnemonic( menu, "Delete tag", "TagDelete" ); + menu->addSeparator(); + create_menu_item_with_mnemonic( menu, "Copy tags from selected", "TagCopy" ); + create_menu_item_with_mnemonic( menu, "Paste tags to selected", "TagPaste" ); + menu->addSeparator(); + create_menu_item_with_mnemonic( menu, "Search tag", "TagSearch" ); + create_menu_item_with_mnemonic( menu, "Search Untagged", "TagSearchUntagged" ); + + return menu; } -void TextureBrowser_assignTags(){ - std::vector selected; +inline void TextureBrowser_tagsEnableGui( bool enable ){ + if( enable ) + g_TexBro.m_tabs->addTab( g_TexBro.m_tagsListWidget, "Tags" ); + else + g_TexBro.m_tabs->removeTab( 1 ); +} - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_available_tree ) ); - - gtk_tree_selection_selected_foreach( selection, (GtkTreeSelectionForeachFunc)TextureBrowser_tagMoveHelper, &selected ); - - if ( !selected.empty() ) { - for ( GtkTreeRowReference* ref : selected ) - { - GtkTreePath* path = gtk_tree_row_reference_get_path( ref ); - - if ( path ) { - GtkTreeIter iter; - - if ( gtk_tree_model_get_iter( GTK_TREE_MODEL( g_TextureBrowser.m_available_store ), &iter, path ) ) { - gchar* tag_assigned; - gtk_tree_model_get( GTK_TREE_MODEL( g_TextureBrowser.m_available_store ), &iter, TAG_COLUMN, &tag_assigned, -1 ); - if ( !TagBuilder.CheckShaderTag( g_TextureBrowser.shader.c_str() ) ) { - // create a custom shader/texture entry - IShader* ishader = QERApp_Shader_ForName( g_TextureBrowser.shader.c_str() ); - - if ( ishader->IsDefault() ) { - // it's a texture - TagBuilder.AddShaderNode( g_TextureBrowser.shader.c_str(), CUSTOM, TEXTURE ); - } - else { - // it's a shader - TagBuilder.AddShaderNode( g_TextureBrowser.shader.c_str(), CUSTOM, SHADER ); - } - ishader->DecRef(); - } - TagBuilder.AddShaderTag( g_TextureBrowser.shader.c_str(), (char*)tag_assigned, TAG ); - - gtk_list_store_remove( g_TextureBrowser.m_available_store, &iter ); - gtk_list_store_append( g_TextureBrowser.m_assigned_store, &iter ); - gtk_list_store_set( g_TextureBrowser.m_assigned_store, &iter, TAG_COLUMN, (char*)tag_assigned, -1 ); - - g_free( tag_assigned ); - } - } +class Tags_QListWidget : public QListWidget +{ + using QListWidget::QListWidget; +protected: + bool event( QEvent *event ) override { + if( event->type() == QEvent::ShortcutOverride ){ + event->accept(); + return true; } - - std::for_each( selected.begin(), selected.end(), gtk_tree_row_reference_free ); - - // Save changes - TagBuilder.SaveXmlDoc(); + return QListWidget::event( event ); } -} + void contextMenuEvent( QContextMenuEvent *event ) override { + g_TexBro.m_tagsMenu->popup( event->globalPos() ); + } +}; -void TextureBrowser_removeTags(){ - std::vector selected; +void TextureBrowser_tagsSetCheckboxesForShader( const char *shader ){ + std::vector assigned_tags; + TagBuilder.GetShaderTags( shader, assigned_tags ); - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_assigned_tree ) ); - - gtk_tree_selection_selected_foreach( selection, (GtkTreeSelectionForeachFunc)TextureBrowser_tagMoveHelper, &selected ); - - if ( !selected.empty() ) { - for ( GtkTreeRowReference* ref : selected ) - { - GtkTreePath* path = gtk_tree_row_reference_get_path( ref ); - - if ( path ) { - GtkTreeIter iter; - - if ( gtk_tree_model_get_iter( GTK_TREE_MODEL( g_TextureBrowser.m_assigned_store ), &iter, path ) ) { - gchar* tag; - gtk_tree_model_get( GTK_TREE_MODEL( g_TextureBrowser.m_assigned_store ), &iter, TAG_COLUMN, &tag, -1 ); - TagBuilder.DeleteShaderTag( g_TextureBrowser.shader.c_str(), tag ); - gtk_list_store_remove( g_TextureBrowser.m_assigned_store, &iter ); - g_free( tag ); - } + const auto contains = [&assigned_tags]( const char *tag )->bool { + for( auto it = assigned_tags.cbegin(); it != assigned_tags.cend(); ++it ) + if( string_equal( tag, it->c_str() ) ){ + assigned_tags.erase( it ); // assuming / hoping that tag names are unique, thus can run faster + return true; } - } + return false; + }; - std::for_each( selected.begin(), selected.end(), gtk_tree_row_reference_free ); - - // Update the "available tags list" - BuildStoreAvailableTags( g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, g_TextureBrowser.m_all_tags, &g_TextureBrowser ); - - // Save changes - TagBuilder.SaveXmlDoc(); - } -} - -void TextureBrowser_buildTagList(){ - GtkTreeIter treeIter; - gtk_list_store_clear( g_TextureBrowser.m_all_tags_list ); - - std::set::iterator iter; - - for ( iter = g_TextureBrowser.m_all_tags.begin(); iter != g_TextureBrowser.m_all_tags.end(); ++iter ) + for( int i = 0; i < g_TexBro.m_tagsListWidget->count(); ++i ) { - gtk_list_store_append( g_TextureBrowser.m_all_tags_list, &treeIter ); - gtk_list_store_set( g_TextureBrowser.m_all_tags_list, &treeIter, TAG_COLUMN, ( *iter ).c_str(), -1 ); + auto item = g_TexBro.m_tagsListWidget->item( i ); + item->setCheckState( contains( item->data( Qt::ItemDataRole::DisplayRole ).toByteArray() )? Qt::CheckState::Checked : Qt::CheckState::Unchecked ); } } +void TextureBrowser_tagAssignmentChanged( const QModelIndex &index ){ + const bool assigned = Qt::CheckState::Checked == static_cast( index.data( Qt::ItemDataRole::CheckStateRole ).toInt() ); + const auto tag = index.data( Qt::ItemDataRole::DisplayRole ).toByteArray(); + + if( assigned ){ + if ( !TagBuilder.CheckShaderTag( g_TexBro.m_shader.c_str() ) ) { + // create a custom shader/texture entry + IShader* ishader = QERApp_Shader_ForName( g_TexBro.m_shader.c_str() ); + + if ( ishader->IsDefault() ) { + // it's a texture + TagBuilder.AddShaderNode( g_TexBro.m_shader.c_str(), TextureType::CUSTOM, NodeShaderType::TEXTURE ); + } + else { + // it's a shader + TagBuilder.AddShaderNode( g_TexBro.m_shader.c_str(), TextureType::CUSTOM, NodeShaderType::SHADER ); + } + ishader->DecRef(); + } + TagBuilder.AddShaderTag( g_TexBro.m_shader.c_str(), tag, NodeTagType::TAG ); + } + else{ + TagBuilder.DeleteShaderTag( g_TexBro.m_shader.c_str(), tag ); + } +} + +class Tags_QItemDelegate : public QItemDelegate +{ + using QItemDelegate::QItemDelegate; +protected: + /* track user edit of tag name */ + void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const override { + const QByteArray propname = editor->metaObject()->userProperty().name(); + const auto newName = propname.isEmpty()? QByteArray() : editor->property( propname ).toByteArray(); + if ( newName.isEmpty() ){ + qt_MessageBox( g_TexBro.m_parent, "New tag name is empty :0", ":o", EMessageBoxType::Error ); + } + else{ + const auto oldName = index.data( Qt::ItemDataRole::DisplayRole ).toByteArray(); + + if( oldName != newName // is changed + && g_TexBro.m_all_tags.find( newName.constData() ) != g_TexBro.m_all_tags.cend() ){ // & found in existing names + qt_MessageBox( g_TexBro.m_parent, "New tag name is already taken :0", newName.constData(), EMessageBoxType::Error ); + } + else{ + TagBuilder.RenameShaderTag( oldName, newName.constData() ); + + g_TexBro.m_all_tags.erase( oldName.constData() ); + g_TexBro.m_all_tags.insert( newName.constData() ); + + QItemDelegate::setModelData( editor, model, index ); // normal processing + } + } + } + bool editorEvent( QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index ) override { + /* let's do some infamous juggling to track user unduced CheckState change */ + if( event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::KeyPress ){ + if( const QVariant value = index.data( Qt::ItemDataRole::CheckStateRole ); value.isValid() ){ + const bool ret = QItemDelegate::editorEvent( event, model, option, index ); + if( ret && value != index.data( Qt::ItemDataRole::CheckStateRole ) ){ + TextureBrowser_tagAssignmentChanged( index ); + } + return ret; + } + } + return QItemDelegate::editorEvent( event, model, option, index ); + } +}; + void TextureBrowser_searchTags(){ - std::vector selected; - char buffer[256]; - char tags_searched[256]; - - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_treeViewTags ) ); - - gtk_tree_selection_selected_foreach( selection, (GtkTreeSelectionForeachFunc)TextureBrowser_tagMoveHelper, &selected ); + const auto selected = g_TexBro.m_tagsListWidget->selectedItems(); if ( !selected.empty() ) { - strcpy( buffer, "/root/*/*[tag='" ); - strcpy( tags_searched, "[TAGS] " ); + auto buffer = StringOutputStream( 256 )( "/root/*/*[tag='" ); + auto tags_searched = StringOutputStream( 256 )( "[TAGS] " ); for ( auto it = selected.begin(); it != selected.end(); ++it ) { - GtkTreePath* path = gtk_tree_row_reference_get_path( *it ); - - if ( path ) { - GtkTreeIter iter; - - if ( gtk_tree_model_get_iter( GTK_TREE_MODEL( g_TextureBrowser.m_all_tags_list ), &iter, path ) ) { - gchar* tag; - gtk_tree_model_get( GTK_TREE_MODEL( g_TextureBrowser.m_all_tags_list ), &iter, TAG_COLUMN, &tag, -1 ); - - strcat( buffer, tag ); - strcat( tags_searched, tag ); - g_free( tag ); - if ( it + 1 != selected.end() ) { - strcat( buffer, "' and tag='" ); - strcat( tags_searched, ", " ); - } - } + const auto tag = ( *it )->text().toLatin1(); + buffer << tag.constData(); + tags_searched << tag.constData(); + if ( it + 1 != selected.end() ) { + buffer << "' and tag='"; + tags_searched << ", "; } } - strcat( buffer, "']" ); + buffer << "']"; - std::for_each( selected.begin(), selected.end(), gtk_tree_row_reference_free ); + g_TexBro.m_found_shaders.clear(); // delete old list + TagBuilder.TagSearch( buffer, g_TexBro.m_found_shaders ); - g_TextureBrowser.m_found_shaders.clear(); // delete old list - TagBuilder.TagSearch( buffer, g_TextureBrowser.m_found_shaders ); - - if ( !g_TextureBrowser.m_found_shaders.empty() ) { // found something - size_t shaders_found = g_TextureBrowser.m_found_shaders.size(); - - globalOutputStream() << "Found " << (unsigned int)shaders_found << " textures and shaders with " << tags_searched << "\n"; + if ( !g_TexBro.m_found_shaders.empty() ) { // found something + globalOutputStream() << "Found " << g_TexBro.m_found_shaders.size() << " textures and shaders with " << tags_searched << "\n"; ScopeDisableScreenUpdates disableScreenUpdates( "Searching...", "Loading Textures" ); - std::set::iterator iter; - - for ( iter = g_TextureBrowser.m_found_shaders.begin(); iter != g_TextureBrowser.m_found_shaders.end(); iter++ ) + for ( const CopiedString& shader : g_TexBro.m_found_shaders ) { - std::string path = ( *iter ).c_str(); - size_t pos = path.find_last_of( "/", path.size() ); - std::string name = path.substr( pos + 1, path.size() ); + std::string path = shader.c_str(); + const size_t pos = path.find_last_of( "/" ); + const std::string name = path.substr( pos + 1 ); path = path.substr( 0, pos + 1 ); TextureDirectory_loadTexture( path.c_str(), name.c_str() ); } } - TextureBrowser_SetHideUnused( g_TextureBrowser, false ); - g_TextureBrowser.m_searchedTags = true; + TextureBrowser_SetHideUnused( g_TexBro, false ); + g_TexBro.m_searchedTags = true; g_TextureBrowser_currentDirectory = tags_searched; - g_TextureBrowser.m_nTotalHeight = 0; - TextureBrowser_setOriginY( g_TextureBrowser, 0 ); - TextureBrowser_heightChanged( g_TextureBrowser ); + g_TexBro.heightChanged(); + g_TexBro.m_originInvalid = true; + TextureBrowser_updateTitle(); + + //deactivate, so SPACE and RETURN wont be broken for 2d + g_TexBro.m_tagsListWidget->clearFocus(); + } +} + +void TextureBrowser_showUntagged(){ + EMessageBoxReturn result = qt_MessageBox( g_TexBro.m_parent, + "WARNING! This function might need a lot of memory and time.
" + "It shows all textures & shaders indexed by ShaderPlug plugin, but having no tag.
" + "Are you sure you want to use it?", + "Show Untagged", EMessageBoxType::Warning, eIDYES | eIDNO ); + + if ( result == eIDYES ) { + g_TexBro.m_found_shaders.clear(); + TagBuilder.GetUntagged( g_TexBro.m_found_shaders ); + + ScopeDisableScreenUpdates disableScreenUpdates( "Searching untagged textures...", "Loading Textures" ); + + for ( const CopiedString& shader : g_TexBro.m_found_shaders ) + { + std::string path = shader.c_str(); + size_t pos = path.find_last_of( "/", path.size() ); + std::string name = path.substr( pos + 1, path.size() ); + path = path.substr( 0, pos + 1 ); + TextureDirectory_loadTexture( path.c_str(), name.c_str() ); + } + + TextureBrowser_SetHideUnused( g_TexBro, false ); + g_TexBro.m_searchedTags = true; + g_TextureBrowser_currentDirectory = "Untagged"; + g_TexBro.heightChanged(); + g_TexBro.m_originInvalid = true; TextureBrowser_updateTitle(); } } -void TextureBrowser_toggleSearchButton(){ - gint page = gtk_notebook_get_current_page( GTK_NOTEBOOK( g_TextureBrowser.m_tag_notebook ) ); - - if ( page == 0 ) { // tag page - gtk_widget_show_all( g_TextureBrowser.m_search_button ); - } - else { - gtk_widget_hide( g_TextureBrowser.m_search_button ); - } -} - -void TextureBrowser_constructTagNotebook(){ - g_TextureBrowser.m_tag_notebook = gtk_notebook_new(); - GtkWidget* labelTags = gtk_label_new( "Tags" ); - GtkWidget* labelTextures = gtk_label_new( "Textures" ); - - gtk_notebook_append_page( GTK_NOTEBOOK( g_TextureBrowser.m_tag_notebook ), g_TextureBrowser.m_scr_win_tree, labelTextures ); - gtk_notebook_append_page( GTK_NOTEBOOK( g_TextureBrowser.m_tag_notebook ), g_TextureBrowser.m_scr_win_tags, labelTags ); - - g_signal_connect( G_OBJECT( g_TextureBrowser.m_tag_notebook ), "switch-page", G_CALLBACK( TextureBrowser_toggleSearchButton ), NULL ); - - gtk_widget_show_all( g_TextureBrowser.m_tag_notebook ); -} - -void TextureBrowser_constructSearchButton(){ - GtkWidget* image = gtk_image_new_from_stock( GTK_STOCK_FIND, GTK_ICON_SIZE_SMALL_TOOLBAR ); - g_TextureBrowser.m_search_button = gtk_button_new(); - g_signal_connect( G_OBJECT( g_TextureBrowser.m_search_button ), "clicked", G_CALLBACK( TextureBrowser_searchTags ), NULL ); - gtk_widget_set_tooltip_text( g_TextureBrowser.m_search_button, "Search with selected tags" ); - gtk_container_add( GTK_CONTAINER( g_TextureBrowser.m_search_button ), image ); -} - void TextureBrowser_checkTagFile(){ - const char SHADERTAG_FILE[] = "shadertags.xml"; + const auto rc_filename = StringOutputStream( 256 )( LocalRcPath_get(), SHADERTAG_FILE ); + const auto default_filename = StringOutputStream( 256 )( g_pGameDescription->mGameToolsPath, SHADERTAG_FILE ); - auto rc_filename = StringOutputStream( 256 )( LocalRcPath_get(), SHADERTAG_FILE ); + if ( file_exists( rc_filename ) && TagBuilder.OpenXmlDoc( rc_filename ) ) + { + globalOutputStream() << "Loaded tag file " << rc_filename << ".\n"; + } + else if ( file_exists( default_filename ) && TagBuilder.OpenXmlDoc( default_filename, rc_filename ) ) // load default tagfile + { + globalOutputStream() << "Loaded default tag file " << default_filename << ".\n"; + } + else + { + // globalWarningStream() << "Unable to find default tag file " << default_filename << ". No tag support. Plugins -> ShaderPlug -> Create tag file: to start using texture tags\n"; + const bool ok = TagBuilder.CreateXmlDocument( rc_filename ); + ASSERT_MESSAGE( ok, "empty tag document was not created" ); + globalOutputStream() << "Created empty tag file " << rc_filename << ". Plugins -> ShaderPlug -> Create tag file: to index all textures and shaders, if needed.\n"; + } +} - if ( file_exists( rc_filename ) ) { - g_TextureBrowser.m_tags = TagBuilder.OpenXmlDoc( rc_filename ); +void TextureBrowser_addTag(){ + auto tag = StringOutputStream( 64 )( "NewTag" ); + int index = 0; + while( g_TexBro.m_all_tags.find( tag.c_str() ) != g_TexBro.m_all_tags.cend() ) + tag( "NewTag", ++index ); - if ( g_TextureBrowser.m_tags ) { - globalOutputStream() << "Loading tag file " << rc_filename << ".\n"; + auto item = new QListWidgetItem( tag.c_str() ); + item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren ); + item->setCheckState( Qt::CheckState::Unchecked ); // is needed to see checkbox + g_TexBro.m_tagsListWidget->addItem( item ); + + g_TexBro.m_all_tags.insert( tag.c_str() ); + + g_TexBro.m_tagsListWidget->scrollToItem( item ); + g_TexBro.m_tagsListWidget->editItem( item ); +} + +void TextureBrowser_renameTag(){ + const auto selected = g_TexBro.m_tagsListWidget->selectedItems(); + + if ( !selected.empty() ) { + g_TexBro.m_tagsListWidget->editItem( selected.front() ); + } +} + +void TextureBrowser_deleteTag(){ + const auto selected = g_TexBro.m_tagsListWidget->selectedItems(); + if ( !selected.empty() ) { + if ( eIDYES == qt_MessageBox( g_TexBro.m_parent, "Are you sure you want to delete the selected tags?", "Delete Tag", EMessageBoxType::Question ) ) { + for( auto item : selected ){ + auto tag = item->text().toLatin1(); + delete item; + TagBuilder.DeleteTag( tag.constData() ); + g_TexBro.m_all_tags.erase( tag.constData() ); + } + } + } +} + +void TextureBrowser_copyTag(){ + g_TexBro.m_copied_tags.clear(); + TagBuilder.GetShaderTags( g_TexBro.m_shader.c_str(), g_TexBro.m_copied_tags ); +} + +void TextureBrowser_pasteTag(){ + const CopiedString shader = g_TexBro.m_shader; + + if ( !TagBuilder.CheckShaderTag( shader.c_str() ) ) { + IShader* ishader = QERApp_Shader_ForName( shader.c_str() ); + if ( ishader->IsDefault() ) { + // it's a texture + TagBuilder.AddShaderNode( shader.c_str(), TextureType::CUSTOM, NodeShaderType::TEXTURE ); + } + else + { + // it's a shader + TagBuilder.AddShaderNode( shader.c_str(), TextureType::CUSTOM, NodeShaderType::SHADER ); + } + ishader->DecRef(); + + for ( const CopiedString& tag : g_TexBro.m_copied_tags ) + { + TagBuilder.AddShaderTag( shader.c_str(), tag.c_str(), NodeTagType::TAG ); } } else { - // load default tagfile - auto default_filename = StringOutputStream( 256 )( g_pGameDescription->mGameToolsPath, SHADERTAG_FILE ); - - if ( file_exists( default_filename ) ) { - g_TextureBrowser.m_tags = TagBuilder.OpenXmlDoc( default_filename, rc_filename ); - - if ( g_TextureBrowser.m_tags ) { - globalOutputStream() << "Loading default tag file " << default_filename << ".\n"; + for ( const CopiedString& tag : g_TexBro.m_copied_tags ) + { + if ( !TagBuilder.CheckShaderTag( shader.c_str(), tag.c_str() ) ) { + // the tag doesn't exist - let's add it + TagBuilder.AddShaderTag( shader.c_str(), tag.c_str(), NodeTagType::TAG ); } } - else - { - globalWarningStream() << "Unable to find default tag file " << default_filename << ". No tag support. Plugins -> ShaderPlug -> Create tag file: to start using texture tags\n"; - } } + + TextureBrowser_tagsSetCheckboxesForShader( shader.c_str() ); } + void TextureBrowser_SetNotex(){ StringOutputStream name( 256 ); name << GlobalRadiant().getAppPath() << "bitmaps/notex.png"; @@ -1988,336 +1586,257 @@ void TextureBrowser_SetNotex(){ g_shadernotex = name.c_str(); } -void TextureBrowser_filterChanged( GtkEditable *editable, TextureBrowser* textureBrowser ){ - gtk_entry_set_icon_sensitive( GTK_ENTRY( editable ), GTK_ENTRY_ICON_SECONDARY, ( gtk_entry_get_text_length( GTK_ENTRY( editable ) ) > 0 ) ); - TextureBrowser_heightChanged( *textureBrowser ); - textureBrowser->m_originInvalid = true; -} -void TextureBrowser_filterIconPress( GtkEntry* entry, gint position, GdkEventButton* event, gpointer user_data ) { - if( position == GTK_ENTRY_ICON_PRIMARY ){ - GlobalToggles_find( "SearchFromStart" ).m_command.m_callback(); +class Filter_QLineEdit : public QLineEdit +{ +protected: + void enterEvent( QEvent *event ) override { + setFocus(); } - else{ - gtk_entry_set_text( entry, "" ); + void leaveEvent( QEvent *event ) override { + clearFocus(); } -} - -static gboolean TextureBrowser_filterKeypress( GtkEntry* widget, GdkEventKey* event, gpointer user_data ){ - if ( event->keyval == GDK_KEY_Escape ) { - gtk_entry_set_text( GTK_ENTRY( widget ), "" ); - return TRUE; + bool event( QEvent *event ) override { + if( event->type() == QEvent::ShortcutOverride ){ + QKeyEvent *keyEvent = static_cast( event ); + if( keyEvent->key() == Qt::Key_Escape ){ + clear(); + event->accept(); + } + } + return QLineEdit::event( event ); } - return FALSE; +}; + +void TextureBrowser_filterSetModeIcon( QAction *action ){ + action->setIcon( QApplication::style()->standardIcon( + g_TextureBrowser_filter_searchFromStart + ? QStyle::StandardPixmap::SP_CommandLink + : QStyle::StandardPixmap::SP_FileDialogContentsView ) ); } -gboolean TextureBrowser_filterEntryFocus( GtkWidget *widget, GdkEvent *event, gpointer user_data ){ - gtk_widget_grab_focus( widget ); - return FALSE; -} +#include "timer.h" -gboolean TextureBrowser_filterEntryUnfocus( GtkWidget *widget, GdkEvent *event, gpointer user_data ){ - gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( widget ) ), NULL ); - return FALSE; -} - -void TextureBrowser_filterSetModeIcon( GtkEntry* entry ){ - if( g_TextureBrowser_filter_searchFromStart ){ - gtk_entry_set_icon_from_stock( entry, GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_MEDIA_PLAY ); +class TexWndGLWidget : public QOpenGLWidget +{ + TextureBrowser& m_texBro; + MousePresses m_mouse; +public: + TexWndGLWidget( TextureBrowser& textureBrowser ) : QOpenGLWidget(), m_texBro( textureBrowser ) + { } - else{ - gtk_entry_set_icon_from_stock( entry, GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_ABOUT ); + + ~TexWndGLWidget() override { + glwidget_context_destroyed(); } -} +protected: + void initializeGL() override + { + glwidget_context_created( *this ); + } + void resizeGL( int w, int h ) override + { + m_texBro.m_width = w; + m_texBro.m_height = h; + m_texBro.heightChanged(); + m_texBro.m_originInvalid = true; + } + void paintGL() override + { + GlobalOpenGL_debugAssertNoErrors(); + m_texBro.draw(); + GlobalOpenGL_debugAssertNoErrors(); + } + + void mousePressEvent( QMouseEvent *event ) override { + setFocus(); + const auto press = m_mouse.press( event ); + if( press == MousePresses::Left2x || press == MousePresses::Right2x ){ + mouseDoubleClick( press ); + } + else if ( press == MousePresses::Right ) { + TextureBrowser_Tracking_MouseDown( m_texBro ); + } + else if ( press == MousePresses::Left || press == MousePresses::Middle ) { + if ( !event->modifiers().testFlag( Qt::KeyboardModifier::ShiftModifier ) ) + SelectTexture( m_texBro, event->x(), event->y(), press == MousePresses::Middle ); + } + } + void mouseDoubleClick( MousePresses::Result press ){ + /* loads directory, containing active shader + focuses on it */ + if ( press == MousePresses::Left2x && !TextureBrowser::wads ) { + const StringRange range( strchr( m_texBro.m_shader.c_str(), '/' ) + 1, strrchr( m_texBro.m_shader.c_str(), '/' ) + 1 ); + if( !range.empty() ){ + const CopiedString dir = range; + ScopeDisableScreenUpdates disableScreenUpdates( dir.c_str(), "Loading Textures" ); + TextureBrowser_ShowDirectory( dir.c_str() ); + TextureBrowser_Focus( m_texBro, m_texBro.m_shader.c_str() ); + m_texBro.queueDraw(); + } + } + else if ( press == MousePresses::Right2x ) { + ScopeDisableScreenUpdates disableScreenUpdates( TextureBrowser_getCommonShadersDir(), "Loading Textures" ); + TextureBrowser_ShowDirectory( TextureBrowser_getCommonShadersDir() ); + m_texBro.queueDraw(); + } + } + void mouseReleaseEvent( QMouseEvent *event ) override { + const auto release = m_mouse.release( event ); + if ( release == MousePresses::Right ) { + TextureBrowser_Tracking_MouseUp( m_texBro ); + } + else if ( release == MousePresses::Left && event->modifiers().testFlag( Qt::KeyboardModifier::ShiftModifier ) ) { + TextureBrowser_ViewShader( m_texBro, event->modifiers(), event->x(), event->y() ); + } + } + void wheelEvent( QWheelEvent *event ) override { + setFocus(); + + if( !m_texBro.m_parent->isActiveWindow() ){ + m_texBro.m_parent->activateWindow(); + m_texBro.m_parent->raise(); + } + + const int originy = m_texBro.getOriginY() + std::copysign( m_texBro.m_mouseWheelScrollIncrement, event->angleDelta().y() ); + m_texBro.setOriginY( originy ); + } +}; -GtkWidget* TextureBrowser_constructWindow( GtkWindow* toplevel ){ - // The gl_widget and the tag assignment frame should be packed into a GtkVPaned with the slider - // position stored in local.pref. gtk_paned_get_position() and gtk_paned_set_position() don't - // seem to work in gtk 2.4 and the arrow buttons don't handle GTK_FILL, so here's another thing - // for the "once-the-gtk-libs-are-updated-TODO-list" :x - +QWidget* TextureBrowser_constructWindow( QWidget* toplevel ){ TextureBrowser_checkTagFile(); TextureBrowser_SetNotex(); - GlobalShaderSystem().setActiveShadersChangedNotify( ReferenceCaller( g_TextureBrowser ) ); + GlobalShaderSystem().setActiveShadersChangedNotify( ReferenceCaller( g_TexBro ) ); - g_TextureBrowser.m_parent = toplevel; + g_TexBro.m_parent = toplevel; - GtkWidget* table = gtk_table_new( 3, 3, FALSE ); - GtkWidget* frame_table = NULL; - GtkWidget* vbox = gtk_vbox_new( FALSE, 0 ); - gtk_table_attach( GTK_TABLE( table ), vbox, 0, 1, 0, 3, GTK_FILL, GTK_FILL, 0, 0 ); - gtk_widget_show( vbox ); + QSplitter *splitter = new QSplitter; + QWidget *containerWidgetLeft = new QWidget; // Adding a QLayout to a QSplitter is not supported, use proxy widget + QWidget *containerWidgetRight = new QWidget; // Adding a QLayout to a QSplitter is not supported, use proxy widget + splitter->addWidget( containerWidgetLeft ); + splitter->addWidget( containerWidgetRight ); + QVBoxLayout *vbox = new QVBoxLayout( containerWidgetLeft ); + QHBoxLayout *hbox = new QHBoxLayout( containerWidgetRight ); + + hbox->setContentsMargins( 0, 0, 0, 0 ); + vbox->setContentsMargins( 0, 0, 0, 0 ); + hbox->setSpacing( 0 ); + vbox->setSpacing( 0 ); - GtkToolbar* toolbar; { // menu bar - GtkMenu* menu_view = GTK_MENU( gtk_menu_new() ); - TextureBrowser_constructViewMenu( menu_view ); - gtk_menu_set_title( menu_view, "View" ); + QToolBar *toolbar = new QToolBar; + vbox->addWidget( toolbar ); - toolbar = toolbar_new(); - gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( toolbar ), FALSE, FALSE, 0 ); + QMenu* menu_view = TextureBrowser_constructViewMenu(); + + //show detached menu over floating tex bro and main wnd... + menu_view->setParent( toolbar, menu_view->windowFlags() ); //don't reset windowFlags //view menu button - GtkToolButton* button = toolbar_append_button( toolbar, "View", "texbro_view.png", PointerCaller( menu_view ) ); -// gtk_widget_set_size_request( GTK_WIDGET( button ), 24, 24 ); // 24 is minimal here for non scissored icon with any gtk theme + toolbar_append_button( toolbar, "View", "texbro_view.png", PointerCaller( menu_view ) ); - //show detached menu over floating tex bro - gtk_menu_attach_to_widget( menu_view, GTK_WIDGET( button ), NULL ); + toolbar_append_button( toolbar, "Find / Replace...", "texbro_gtk-find-and-replace.png", "FindReplaceTextures" ); - button = toolbar_append_button( toolbar, "Find / Replace...", "texbro_gtk-find-and-replace.png", "FindReplaceTextures" ); -// gtk_widget_set_size_request( GTK_WIDGET( button ), 22, 22 ); - - button = toolbar_append_button( toolbar, "Flush & Reload Shaders", "texbro_refresh.png", "RefreshShaders" ); -// gtk_widget_set_size_request( GTK_WIDGET( button ), 22, 22 ); + toolbar_append_button( toolbar, "Flush & Reload Shaders", "texbro_refresh.png", "RefreshShaders" ); } { // filter entry - GtkWidget* entry = g_TextureBrowser.m_filter_entry = gtk_entry_new(); - gtk_widget_set_size_request( entry, 64, -1 ); - gtk_box_pack_start( GTK_BOX( vbox ), entry, FALSE, FALSE, 0 ); - gtk_entry_set_icon_from_stock( GTK_ENTRY( entry ), GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR ); - gtk_entry_set_icon_sensitive( GTK_ENTRY( entry ), GTK_ENTRY_ICON_SECONDARY, FALSE ); - TextureBrowser_filterSetModeIcon( GTK_ENTRY( entry ) ); - gtk_entry_set_icon_tooltip_text( GTK_ENTRY( entry ), GTK_ENTRY_ICON_PRIMARY, "toggle match mode ( start / any position )" ); - gtk_widget_show( entry ); - g_signal_connect( G_OBJECT( entry ), "changed", G_CALLBACK( TextureBrowser_filterChanged ), &g_TextureBrowser ); - g_signal_connect( G_OBJECT( entry ), "icon-press", G_CALLBACK( TextureBrowser_filterIconPress ), 0 ); - g_signal_connect( G_OBJECT( entry ), "key_press_event", G_CALLBACK( TextureBrowser_filterKeypress ), 0 ); - g_signal_connect( G_OBJECT( entry ), "enter_notify_event", G_CALLBACK( TextureBrowser_filterEntryFocus ), 0 ); - g_signal_connect( G_OBJECT( entry ), "leave_notify_event", G_CALLBACK( TextureBrowser_filterEntryUnfocus ), 0 ); + QLineEdit *entry = g_TexBro.m_filter_entry = new Filter_QLineEdit; + vbox->addWidget( entry ); + entry->setClearButtonEnabled( true ); + entry->setFocusPolicy( Qt::FocusPolicy::ClickFocus ); + + QAction *action = g_TexBro.m_filter_action = entry->addAction( QApplication::style()->standardIcon( QStyle::StandardPixmap::SP_CommandLink ), QLineEdit::LeadingPosition ); + TextureBrowser_filterSetModeIcon( action ); + action->setToolTip( "toggle match mode ( start / any position )" ); + + QObject::connect( entry, &QLineEdit::textChanged, []( const QString& text ){ + g_TexBro.m_filter_string = text.toLatin1().constData(); + g_TexBro.heightChanged(); + g_TexBro.m_originInvalid = true; + } ); + QObject::connect( action, &QAction::triggered, GlobalToggles_find( "SearchFromStart" ).m_command.m_callback ); } { // Texture TreeView - GtkWidget* w = g_TextureBrowser.m_scr_win_tree = gtk_scrolled_window_new( NULL, NULL ); - gtk_container_set_border_width( GTK_CONTAINER( w ), 0 ); - - // vertical only scrolling for treeview - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( w ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS ); - - gtk_widget_show( w ); - TextureBrowser_createTreeViewTree(); - - //gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( w ), g_TextureBrowser.m_treeViewTree ); - gtk_container_add( GTK_CONTAINER( w ), g_TextureBrowser.m_treeViewTree ); //GtkTreeView has native scrolling support; should not be used with the GtkViewport proxy. - gtk_widget_show( g_TextureBrowser.m_treeViewTree ); - } - { // gl_widget scrollbar - GtkWidget* w = g_TextureBrowser.m_texture_scroll = gtk_vscrollbar_new( GTK_ADJUSTMENT( gtk_adjustment_new( 0, 0, 0, 1, 1, 0 ) ) ); - gtk_table_attach( GTK_TABLE( table ), w, 2, 3, 1, 2, GTK_SHRINK, GTK_FILL, 0, 0 ); - gtk_widget_show( w ); - - GtkAdjustment *vadjustment = gtk_range_get_adjustment( GTK_RANGE( w ) ); - g_signal_connect( G_OBJECT( vadjustment ), "value_changed", G_CALLBACK( TextureBrowser_verticalScroll ), &g_TextureBrowser ); - - widget_set_visible( w, g_TextureBrowser.m_showTextureScrollbar ); } { // gl_widget -#if NV_DRIVER_GAMMA_BUG - GtkWidget* w = g_TextureBrowser.m_gl_widget = glwidget_new( TRUE ); -#else - GtkWidget* w = g_TextureBrowser.m_gl_widget = glwidget_new( FALSE ); -#endif - g_object_ref( G_OBJECT( w ) ); + g_TexBro.m_gl_widget = new TexWndGLWidget( g_TexBro ); - gtk_widget_set_events( w, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK ); - gtk_widget_set_can_focus( w, TRUE ); + hbox->addWidget( g_TexBro.m_gl_widget ); + } + { // gl_widget scrollbar + auto scroll = g_TexBro.m_texture_scroll = new QScrollBar; + hbox->addWidget( scroll ); - gtk_table_attach_defaults( GTK_TABLE( table ), w, 1, 2, 1, 2 ); - gtk_widget_show( w ); + QObject::connect( scroll, &QAbstractSlider::valueChanged, []( int value ){ + g_TexBro.m_scrollAdjustment.value_changed( value ); + } ); - g_TextureBrowser.m_sizeHandler = g_signal_connect( G_OBJECT( w ), "size_allocate", G_CALLBACK( TextureBrowser_size_allocate ), &g_TextureBrowser ); - g_TextureBrowser.m_exposeHandler = g_signal_connect( G_OBJECT( w ), "expose_event", G_CALLBACK( TextureBrowser_expose ), &g_TextureBrowser ); - - g_signal_connect( G_OBJECT( w ), "button_press_event", G_CALLBACK( TextureBrowser_button_press ), &g_TextureBrowser ); - g_signal_connect( G_OBJECT( w ), "button_release_event", G_CALLBACK( TextureBrowser_button_release ), &g_TextureBrowser ); - g_signal_connect( G_OBJECT( w ), "motion_notify_event", G_CALLBACK( TextureBrowser_motion ), &g_TextureBrowser ); - g_signal_connect( G_OBJECT( w ), "scroll_event", G_CALLBACK( TextureBrowser_scroll ), &g_TextureBrowser ); + scroll->setVisible( g_TexBro.m_showTextureScrollbar ); } - // tag stuff - if ( g_TextureBrowser.m_tags ) { - { // fill tag GtkListStore - g_TextureBrowser.m_all_tags_list = gtk_list_store_new( N_COLUMNS, G_TYPE_STRING ); - GtkTreeSortable* sortable = GTK_TREE_SORTABLE( g_TextureBrowser.m_all_tags_list ); - gtk_tree_sortable_set_sort_column_id( sortable, TAG_COLUMN, GTK_SORT_ASCENDING ); + { // tag stuff + g_TexBro.m_tagsListWidget = new Tags_QListWidget; + g_TexBro.m_tagsListWidget->setSortingEnabled( true ); + g_TexBro.m_tagsListWidget->setSelectionMode( QAbstractItemView::SelectionMode::ExtendedSelection ); + g_TexBro.m_tagsListWidget->setEditTriggers( QAbstractItemView::EditTrigger::SelectedClicked | QAbstractItemView::EditTrigger::EditKeyPressed ); + g_TexBro.m_tagsListWidget->setUniformItemSizes( true ); // optimization + g_TexBro.m_tagsListWidget->setFocusPolicy( Qt::FocusPolicy::ClickFocus ); - TagBuilder.GetAllTags( g_TextureBrowser.m_all_tags ); - TextureBrowser_buildTagList(); - } - { // tag menu bar - GtkMenu* menu_tags = GTK_MENU( gtk_menu_new() ); - gtk_menu_set_title( menu_tags, "Tags" ); - TextureBrowser_constructTagsMenu( menu_tags ); + g_TexBro.m_tagsListWidget->setItemDelegate( new Tags_QItemDelegate( g_TexBro.m_tagsListWidget ) ); - GtkToolButton* button = toolbar_append_button( toolbar, "Tags", "texbro_tags.png", PointerCaller( menu_tags ) ); -// gtk_widget_set_size_request( GTK_WIDGET( button ), 22, 22 ); + QObject::connect( g_TexBro.m_tagsListWidget, &QListWidget::activated, TextureBrowser_searchTags ); - //show detached menu over floating tex bro and main wnd... - gtk_menu_attach_to_widget( menu_tags, GTK_WIDGET( button ), NULL ); - } - { // Tag TreeView - g_TextureBrowser.m_scr_win_tags = gtk_scrolled_window_new( NULL, NULL ); - gtk_container_set_border_width( GTK_CONTAINER( g_TextureBrowser.m_scr_win_tags ), 0 ); - - // vertical only scrolling for treeview - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( g_TextureBrowser.m_scr_win_tags ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS ); - - TextureBrowser_createTreeViewTags(); - - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_treeViewTags ) ); - gtk_tree_selection_set_mode( selection, GTK_SELECTION_MULTIPLE ); - - gtk_container_add( GTK_CONTAINER( g_TextureBrowser.m_scr_win_tags ), g_TextureBrowser.m_treeViewTags ); - gtk_widget_show( GTK_WIDGET( g_TextureBrowser.m_treeViewTags ) ); - } - { // Texture/Tag notebook - TextureBrowser_constructTagNotebook(); - gtk_box_pack_start( GTK_BOX( vbox ), g_TextureBrowser.m_tag_notebook, TRUE, TRUE, 0 ); - } - { // Tag search button - TextureBrowser_constructSearchButton(); - gtk_box_pack_end( GTK_BOX( vbox ), g_TextureBrowser.m_search_button, FALSE, FALSE, 0 ); - } - { // Tag frame - frame_table = gtk_table_new( 3, 3, FALSE ); - - g_TextureBrowser.m_tag_frame = gtk_frame_new( "Tag assignment" ); - gtk_frame_set_label_align( GTK_FRAME( g_TextureBrowser.m_tag_frame ), 0.5, 0.5 ); - gtk_frame_set_shadow_type( GTK_FRAME( g_TextureBrowser.m_tag_frame ), GTK_SHADOW_NONE ); - - gtk_table_attach( GTK_TABLE( table ), g_TextureBrowser.m_tag_frame, 1, 3, 2, 3, GTK_FILL, GTK_SHRINK, 0, 0 ); - - gtk_widget_show( frame_table ); - - gtk_container_add( GTK_CONTAINER( g_TextureBrowser.m_tag_frame ), frame_table ); - } - { // assigned tag list - GtkWidget* scrolled_win = gtk_scrolled_window_new( NULL, NULL ); - gtk_container_set_border_width( GTK_CONTAINER( scrolled_win ), 0 ); - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolled_win ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS ); - - g_TextureBrowser.m_assigned_store = gtk_list_store_new( N_COLUMNS, G_TYPE_STRING ); - - GtkTreeSortable* sortable = GTK_TREE_SORTABLE( g_TextureBrowser.m_assigned_store ); - gtk_tree_sortable_set_sort_column_id( sortable, TAG_COLUMN, GTK_SORT_ASCENDING ); - - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - - g_TextureBrowser.m_assigned_tree = gtk_tree_view_new_with_model( GTK_TREE_MODEL( g_TextureBrowser.m_assigned_store ) ); - g_object_unref( G_OBJECT( g_TextureBrowser.m_assigned_store ) ); - g_signal_connect( g_TextureBrowser.m_assigned_tree, "row-activated", (GCallback) TextureBrowser_removeTags, NULL ); - gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( g_TextureBrowser.m_assigned_tree ), FALSE ); - - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_assigned_tree ) ); - gtk_tree_selection_set_mode( selection, GTK_SELECTION_MULTIPLE ); - - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "", renderer, "text", TAG_COLUMN, NULL ); - gtk_tree_view_append_column( GTK_TREE_VIEW( g_TextureBrowser.m_assigned_tree ), column ); - gtk_widget_show( g_TextureBrowser.m_assigned_tree ); - - gtk_widget_show( scrolled_win ); - gtk_container_add( GTK_CONTAINER( scrolled_win ), g_TextureBrowser.m_assigned_tree ); - - gtk_table_attach( GTK_TABLE( frame_table ), scrolled_win, 0, 1, 1, 3, GTK_FILL, GTK_FILL, 0, 0 ); - } - { // available tag list - GtkWidget* scrolled_win = gtk_scrolled_window_new( NULL, NULL ); - gtk_container_set_border_width( GTK_CONTAINER( scrolled_win ), 0 ); - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolled_win ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS ); - - g_TextureBrowser.m_available_store = gtk_list_store_new( N_COLUMNS, G_TYPE_STRING ); - GtkTreeSortable* sortable = GTK_TREE_SORTABLE( g_TextureBrowser.m_available_store ); - gtk_tree_sortable_set_sort_column_id( sortable, TAG_COLUMN, GTK_SORT_ASCENDING ); - - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - - g_TextureBrowser.m_available_tree = gtk_tree_view_new_with_model( GTK_TREE_MODEL( g_TextureBrowser.m_available_store ) ); - g_object_unref( G_OBJECT( g_TextureBrowser.m_available_store ) ); - g_signal_connect( g_TextureBrowser.m_available_tree, "row-activated", (GCallback) TextureBrowser_assignTags, NULL ); - gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( g_TextureBrowser.m_available_tree ), FALSE ); - - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_available_tree ) ); - gtk_tree_selection_set_mode( selection, GTK_SELECTION_MULTIPLE ); - - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "", renderer, "text", TAG_COLUMN, NULL ); - gtk_tree_view_append_column( GTK_TREE_VIEW( g_TextureBrowser.m_available_tree ), column ); - gtk_widget_show( g_TextureBrowser.m_available_tree ); - - gtk_widget_show( scrolled_win ); - gtk_container_add( GTK_CONTAINER( scrolled_win ), g_TextureBrowser.m_available_tree ); - - gtk_table_attach( GTK_TABLE( frame_table ), scrolled_win, 2, 3, 1, 3, GTK_FILL, GTK_FILL, 0, 0 ); - } - { // tag arrow buttons - GtkWidget* m_btn_left = gtk_button_new(); - GtkWidget* m_btn_right = gtk_button_new(); - GtkWidget* m_arrow_left = gtk_arrow_new( GTK_ARROW_LEFT, GTK_SHADOW_OUT ); - GtkWidget* m_arrow_right = gtk_arrow_new( GTK_ARROW_RIGHT, GTK_SHADOW_OUT ); - gtk_container_add( GTK_CONTAINER( m_btn_left ), m_arrow_left ); - gtk_container_add( GTK_CONTAINER( m_btn_right ), m_arrow_right ); - - // workaround. the size of the tag frame depends of the requested size of the arrow buttons. - gtk_widget_set_size_request( m_arrow_left, -1, 68 ); - gtk_widget_set_size_request( m_arrow_right, -1, 68 ); - - gtk_table_attach( GTK_TABLE( frame_table ), m_btn_left, 1, 2, 1, 2, GTK_SHRINK, GTK_EXPAND, 0, 0 ); - gtk_table_attach( GTK_TABLE( frame_table ), m_btn_right, 1, 2, 2, 3, GTK_SHRINK, GTK_EXPAND, 0, 0 ); - - g_signal_connect( G_OBJECT( m_btn_left ), "clicked", G_CALLBACK( TextureBrowser_assignTags ), NULL ); - g_signal_connect( G_OBJECT( m_btn_right ), "clicked", G_CALLBACK( TextureBrowser_removeTags ), NULL ); - - gtk_widget_show( m_btn_left ); - gtk_widget_show( m_btn_right ); - gtk_widget_show( m_arrow_left ); - gtk_widget_show( m_arrow_right ); - } - { // tag fram labels - GtkWidget* m_lbl_assigned = gtk_label_new( "Assigned" ); - GtkWidget* m_lbl_unassigned = gtk_label_new( "Available" ); - - gtk_table_attach( GTK_TABLE( frame_table ), m_lbl_assigned, 0, 1, 0, 1, GTK_EXPAND, GTK_SHRINK, 0, 0 ); - gtk_table_attach( GTK_TABLE( frame_table ), m_lbl_unassigned, 2, 3, 0, 1, GTK_EXPAND, GTK_SHRINK, 0, 0 ); - - gtk_widget_show( m_lbl_assigned ); - gtk_widget_show( m_lbl_unassigned ); + TagBuilder.GetAllTags( g_TexBro.m_all_tags ); + for ( const CopiedString& tag : g_TexBro.m_all_tags ){ + auto item = new QListWidgetItem( tag.c_str() ); + item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren ); + item->setCheckState( Qt::CheckState::Unchecked ); // is needed to see checkbox + g_TexBro.m_tagsListWidget->addItem( item ); } } - else { // no tag support, show the texture tree only - gtk_box_pack_start( GTK_BOX( vbox ), g_TextureBrowser.m_scr_win_tree, TRUE, TRUE, 0 ); + { // tag context menu + g_TexBro.m_tagsMenu = TextureBrowser_constructTagsMenu(); + + //show detached menu over floating tex bro and main wnd... + g_TexBro.m_tagsMenu->setParent( g_TexBro.m_tagsListWidget, g_TexBro.m_tagsMenu->windowFlags() ); //don't reset windowFlags } - //prevent focusing on filter entry or tex dirs treeview after click on tab of floating group dialog (np, if called via hotkey) - gtk_container_set_focus_chain( GTK_CONTAINER( table ), NULL ); + { // Texture/Tag notebook + g_TexBro.m_tabs = new QTabWidget; + g_TexBro.m_tabs->setFocusPolicy( Qt::FocusPolicy::ClickFocus ); + g_TexBro.m_tabs->setDocumentMode( true ); + g_TexBro.m_tabs->setTabBarAutoHide( true ); + g_TexBro.m_tabs->addTab( g_TexBro.m_treeView, "Textures" ); + static_cast( g_TexBro.m_tagsListWidget )->setParent( g_TexBro.m_tabs ); + TextureBrowser_tagsEnableGui( g_TexBro.m_tags ); + vbox->addWidget( g_TexBro.m_tabs ); - return table; + QObject::connect( g_TexBro.m_tabs, &QTabWidget::currentChanged, []( int index ){ + if( index == 1 ) + TextureBrowser_tagsSetCheckboxesForShader( g_TexBro.m_shader.c_str() ); + } ); + } + + splitter->setStretchFactor( 0, 0 ); // consistent treeview side sizing on resizes + splitter->setStretchFactor( 1, 1 ); + g_guiSettings.addSplitter( splitter, "TextureBrowser/splitter", { 100, 800 } ); + return splitter; } void TextureBrowser_destroyWindow(){ GlobalShaderSystem().setActiveShadersChangedNotify( Callback() ); - - g_signal_handler_disconnect( G_OBJECT( g_TextureBrowser.m_gl_widget ), g_TextureBrowser.m_sizeHandler ); - g_signal_handler_disconnect( G_OBJECT( g_TextureBrowser.m_gl_widget ), g_TextureBrowser.m_exposeHandler ); - - g_object_unref( G_OBJECT( g_TextureBrowser.m_gl_widget ) ); } -const Vector3& TextureBrowser_getBackgroundColour( TextureBrowser& textureBrowser ){ - return textureBrowser.color_textureback; +const Vector3& TextureBrowser_getBackgroundColour(){ + return g_TexBro.m_color_textureback; } -void TextureBrowser_setBackgroundColour( TextureBrowser& textureBrowser, const Vector3& colour ){ - textureBrowser.color_textureback = colour; - TextureBrowser_queueDraw( textureBrowser ); -} - -void TextureBrowser_selectionHelper( GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, std::vector* selected ){ - g_assert( selected != NULL ); - - gchar* name; - gtk_tree_model_get( model, iter, TAG_COLUMN, &name, -1 ); - selected->push_back( name ); +void TextureBrowser_setBackgroundColour( const Vector3& colour ){ + g_TexBro.m_color_textureback = colour; + g_TexBro.queueDraw(); } void TextureBrowser_shaderInfo(){ @@ -2329,169 +1848,9 @@ void TextureBrowser_shaderInfo(){ shader->DecRef(); } -void TextureBrowser_addTag(){ - CopiedString tag; - - EMessageBoxReturn result = DoShaderTagDlg( tag, "Add shader tag" ); - - if ( result == eIDOK && !tag.empty() ) { - GtkTreeIter iter, iter2; - g_TextureBrowser.m_all_tags.insert( tag.c_str() ); - gtk_list_store_append( g_TextureBrowser.m_available_store, &iter ); - gtk_list_store_set( g_TextureBrowser.m_available_store, &iter, TAG_COLUMN, tag.c_str(), -1 ); - - // Select the currently added tag in the available list - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_available_tree ) ); - gtk_tree_selection_select_iter( selection, &iter ); - - gtk_list_store_append( g_TextureBrowser.m_all_tags_list, &iter2 ); - gtk_list_store_set( g_TextureBrowser.m_all_tags_list, &iter2, TAG_COLUMN, tag.c_str(), -1 ); - } -} - -void TextureBrowser_renameTag(){ - /* WORKAROUND: The tag treeview is set to GTK_SELECTION_MULTIPLE. Because - gtk_tree_selection_get_selected() doesn't work with GTK_SELECTION_MULTIPLE, - we need to count the number of selected rows first and use - gtk_tree_selection_selected_foreach() then to go through the list of selected - rows (which always contains a single row). - */ - - std::vector selected; - - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_treeViewTags ) ); - gtk_tree_selection_selected_foreach( selection, GtkTreeSelectionForeachFunc( TextureBrowser_selectionHelper ), &selected ); - - if ( selected.size() == 1 ) { // we only rename a single tag - CopiedString newTag; - EMessageBoxReturn result = DoShaderTagDlg( newTag, "Rename shader tag" ); - - if ( result == eIDOK && !newTag.empty() ) { - GtkTreeIter iterList; - gchar* oldTag = selected.front(); - - bool row = gtk_tree_model_get_iter_first( GTK_TREE_MODEL( g_TextureBrowser.m_all_tags_list ), &iterList ) != 0; - - while ( row ) - { - gchar* rowTag; - gtk_tree_model_get( GTK_TREE_MODEL( g_TextureBrowser.m_all_tags_list ), &iterList, TAG_COLUMN, &rowTag, -1 ); - - if ( string_equal( rowTag, oldTag ) ) { - gtk_list_store_set( g_TextureBrowser.m_all_tags_list, &iterList, TAG_COLUMN, newTag.c_str(), -1 ); - } - g_free( rowTag ); - row = gtk_tree_model_iter_next( GTK_TREE_MODEL( g_TextureBrowser.m_all_tags_list ), &iterList ) != 0; - } - - TagBuilder.RenameShaderTag( oldTag, newTag.c_str() ); - - g_TextureBrowser.m_all_tags.erase( CopiedString( oldTag ) ); - g_TextureBrowser.m_all_tags.insert( newTag ); - - BuildStoreAssignedTags( g_TextureBrowser.m_assigned_store, g_TextureBrowser.shader.c_str(), &g_TextureBrowser ); - BuildStoreAvailableTags( g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, g_TextureBrowser.m_all_tags, &g_TextureBrowser ); - } - } - else - { - gtk_MessageBox( GTK_WIDGET( g_TextureBrowser.m_parent ), "Select a single tag for renaming." ); - } - - std::for_each( selected.begin(), selected.end(), g_free ); -} - -void TextureBrowser_deleteTag(){ - std::vector selected; - - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_treeViewTags ) ); - gtk_tree_selection_selected_foreach( selection, GtkTreeSelectionForeachFunc( TextureBrowser_selectionHelper ), &selected ); - - if ( selected.size() == 1 ) { // we only delete a single tag - EMessageBoxReturn result = gtk_MessageBox( GTK_WIDGET( g_TextureBrowser.m_parent ), "Are you sure you want to delete the selected tag?", "Delete Tag", eMB_YESNO, eMB_ICONQUESTION ); - - if ( result == eIDYES ) { - GtkTreeIter iterSelected; - - gchar* tagSelected = selected.front(); - - bool row = gtk_tree_model_get_iter_first( GTK_TREE_MODEL( g_TextureBrowser.m_all_tags_list ), &iterSelected ) != 0; - - while ( row ) - { - gchar *rowTag; - gtk_tree_model_get( GTK_TREE_MODEL( g_TextureBrowser.m_all_tags_list ), &iterSelected, TAG_COLUMN, &rowTag, -1 ); - - if ( string_equal( rowTag, tagSelected ) ) { - gtk_list_store_remove( g_TextureBrowser.m_all_tags_list, &iterSelected ); - g_free( rowTag ); - break; - } - g_free( rowTag ); - row = gtk_tree_model_iter_next( GTK_TREE_MODEL( g_TextureBrowser.m_all_tags_list ), &iterSelected ) != 0; - } - - TagBuilder.DeleteTag( tagSelected ); - g_TextureBrowser.m_all_tags.erase( CopiedString( tagSelected ) ); - - BuildStoreAssignedTags( g_TextureBrowser.m_assigned_store, g_TextureBrowser.shader.c_str(), &g_TextureBrowser ); - BuildStoreAvailableTags( g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, g_TextureBrowser.m_all_tags, &g_TextureBrowser ); - } - } - else { - gtk_MessageBox( GTK_WIDGET( g_TextureBrowser.m_parent ), "Select a single tag for deletion." ); - } - - std::for_each( selected.begin(), selected.end(), g_free ); -} - -void TextureBrowser_copyTag(){ - g_TextureBrowser.m_copied_tags.clear(); - TagBuilder.GetShaderTags( g_TextureBrowser.shader.c_str(), g_TextureBrowser.m_copied_tags ); -} - -void TextureBrowser_pasteTag(){ - IShader* ishader = QERApp_Shader_ForName( g_TextureBrowser.shader.c_str() ); - const CopiedString shader = g_TextureBrowser.shader; - - if ( !TagBuilder.CheckShaderTag( shader.c_str() ) ) { - CopiedString shaderFile = ishader->getShaderFileName(); - if ( shaderFile.empty() ) { - // it's a texture - TagBuilder.AddShaderNode( shader.c_str(), CUSTOM, TEXTURE ); - } - else - { - // it's a shader - TagBuilder.AddShaderNode( shader.c_str(), CUSTOM, SHADER ); - } - - for ( size_t i = 0; i < g_TextureBrowser.m_copied_tags.size(); ++i ) - { - TagBuilder.AddShaderTag( shader.c_str(), g_TextureBrowser.m_copied_tags[i].c_str(), TAG ); - } - } - else - { - for ( size_t i = 0; i < g_TextureBrowser.m_copied_tags.size(); ++i ) - { - if ( !TagBuilder.CheckShaderTag( shader.c_str(), g_TextureBrowser.m_copied_tags[i].c_str() ) ) { - // the tag doesn't exist - let's add it - TagBuilder.AddShaderTag( shader.c_str(), g_TextureBrowser.m_copied_tags[i].c_str(), TAG ); - } - } - } - - ishader->DecRef(); - - TagBuilder.SaveXmlDoc(); - BuildStoreAssignedTags( g_TextureBrowser.m_assigned_store, shader.c_str(), &g_TextureBrowser ); - BuildStoreAvailableTags( g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, g_TextureBrowser.m_all_tags, &g_TextureBrowser ); -} - void RefreshShaders(){ g_TextureBrowser_currentDirectory = ""; - g_TextureBrowser.m_searchedTags = false; + g_TexBro.m_searchedTags = false; TextureBrowser_updateTitle(); ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Loading Shaders" ); @@ -2501,92 +1860,71 @@ void RefreshShaders(){ } void TextureBrowser_ToggleShowShaders(){ - g_TextureBrowser.m_showShaders ^= 1; - g_TextureBrowser.m_showshaders_item.update(); + g_TexBro.m_showShaders ^= 1; + g_TexBro.m_showshaders_item.update(); - g_TextureBrowser.m_heightChanged = true; - g_TextureBrowser.m_originInvalid = true; + g_TexBro.m_heightChanged = true; + g_TexBro.m_originInvalid = true; g_activeShadersChangedCallbacks(); - TextureBrowser_queueDraw( g_TextureBrowser ); + g_TexBro.queueDraw(); } void TextureBrowser_ToggleShowTextures(){ - g_TextureBrowser.m_showTextures ^= 1; - g_TextureBrowser.m_showtextures_item.update(); + g_TexBro.m_showTextures ^= 1; + g_TexBro.m_showtextures_item.update(); - g_TextureBrowser.m_heightChanged = true; - g_TextureBrowser.m_originInvalid = true; + g_TexBro.m_heightChanged = true; + g_TexBro.m_originInvalid = true; g_activeShadersChangedCallbacks(); - TextureBrowser_queueDraw( g_TextureBrowser ); + g_TexBro.queueDraw(); } void TextureBrowser_ToggleShowShaderListOnly(){ g_TextureBrowser_shaderlistOnly ^= 1; - g_TextureBrowser.m_showshaderlistonly_item.update(); + g_TexBro.m_showshaderlistonly_item.update(); TextureBrowser_constructTreeStore(); } void TextureBrowser_showAll(){ g_TextureBrowser_currentDirectory = ""; - g_TextureBrowser.m_searchedTags = false; -// TextureBrowser_SetHideUnused( g_TextureBrowser, false ); + g_TexBro.m_searchedTags = false; +// TextureBrowser_SetHideUnused( g_TexBro, false ); TextureBrowser_ToggleHideUnused(); //toggle to show all used on the first hit and all on the second TextureBrowser_updateTitle(); } -void TextureBrowser_showUntagged(){ - EMessageBoxReturn result = gtk_MessageBox( GTK_WIDGET( g_TextureBrowser.m_parent ), "WARNING! This function might need a lot of memory and time. Are you sure you want to use it?", "Show Untagged", eMB_YESNO, eMB_ICONWARNING ); - - if ( result == eIDYES ) { - g_TextureBrowser.m_found_shaders.clear(); - TagBuilder.GetUntagged( g_TextureBrowser.m_found_shaders ); - std::set::iterator iter; - - ScopeDisableScreenUpdates disableScreenUpdates( "Searching untagged textures...", "Loading Textures" ); - - for ( iter = g_TextureBrowser.m_found_shaders.begin(); iter != g_TextureBrowser.m_found_shaders.end(); iter++ ) - { - std::string path = ( *iter ).c_str(); - size_t pos = path.find_last_of( "/", path.size() ); - std::string name = path.substr( pos + 1, path.size() ); - path = path.substr( 0, pos + 1 ); - TextureDirectory_loadTexture( path.c_str(), name.c_str() ); - globalErrorStream() << path.c_str() << name.c_str() << "\n"; - } - - g_TextureBrowser_currentDirectory = "Untagged"; - TextureBrowser_queueDraw( GlobalTextureBrowser() ); - TextureBrowser_heightChanged( g_TextureBrowser ); - TextureBrowser_updateTitle(); - } -} - void TextureBrowser_FixedSize(){ g_TextureBrowser_fixedSize ^= 1; - GlobalTextureBrowser().m_fixedsize_item.update(); - TextureBrowser_activeShadersChanged( GlobalTextureBrowser() ); + g_TexBro.m_fixedsize_item.update(); + TextureBrowser_activeShadersChanged( g_TexBro ); } void TextureBrowser_FilterNotex(){ g_TextureBrowser_filterNotex ^= 1; - GlobalTextureBrowser().m_filternotex_item.update(); - TextureBrowser_activeShadersChanged( GlobalTextureBrowser() ); + g_TexBro.m_filternotex_item.update(); + TextureBrowser_activeShadersChanged( g_TexBro ); } void TextureBrowser_EnableAlpha(){ g_TextureBrowser_enableAlpha ^= 1; - GlobalTextureBrowser().m_enablealpha_item.update(); - TextureBrowser_activeShadersChanged( GlobalTextureBrowser() ); + g_TexBro.m_enablealpha_item.update(); + TextureBrowser_activeShadersChanged( g_TexBro ); +} + +void TextureBrowser_tagsToggleGui(){ + g_TexBro.m_tags ^= 1; + g_TexBro.m_tags_item.update(); + TextureBrowser_tagsEnableGui( g_TexBro.m_tags ); } void TextureBrowser_filter_searchFromStart(){ g_TextureBrowser_filter_searchFromStart ^= 1; - GlobalTextureBrowser().m_filter_searchFromStart_item.update(); - TextureBrowser_activeShadersChanged( GlobalTextureBrowser() ); - TextureBrowser_filterSetModeIcon( GTK_ENTRY( GlobalTextureBrowser().m_filter_entry ) ); + g_TexBro.m_filter_searchFromStart_item.update(); + TextureBrowser_activeShadersChanged( g_TexBro ); + TextureBrowser_filterSetModeIcon( g_TexBro.m_filter_action ); } @@ -2663,31 +2001,31 @@ typedef ReferenceCaller1 Unifo void TextureBrowser_constructPreferences( PreferencesPage& page ){ page.appendCheckBox( "", "Texture scrollbar", - TextureBrowserImportShowScrollbarCaller( GlobalTextureBrowser() ), - BoolExportCaller( GlobalTextureBrowser().m_showTextureScrollbar ) + TextureBrowserImportShowScrollbarCaller( g_TexBro ), + BoolExportCaller( g_TexBro.m_showTextureScrollbar ) ); { const char* texture_scale[] = { "10%", "25%", "50%", "100%", "200%" }; page.appendCombo( "Texture Thumbnail Scale", StringArrayRange( texture_scale ), - IntImportCallback( TextureScaleImportCaller( GlobalTextureBrowser() ) ), - IntExportCallback( TextureScaleExportCaller( GlobalTextureBrowser() ) ) + IntImportCallback( TextureScaleImportCaller( g_TexBro ) ), + IntExportCallback( TextureScaleExportCaller( g_TexBro ) ) ); } - page.appendSpinner( "Thumbnails Max Size", GlobalTextureBrowser().m_uniformTextureSize, 160.0, 16, 8192 ); - page.appendSpinner( "Thumbnails Min Size", GlobalTextureBrowser().m_uniformTextureMinSize, 48.0, 16, 8192 ); - page.appendEntry( "Mousewheel Increment", GlobalTextureBrowser().m_mouseWheelScrollIncrement ); + page.appendSpinner( "Thumbnails Max Size", g_TexBro.m_uniformTextureSize, 16, 8192 ); + page.appendSpinner( "Thumbnails Min Size", g_TexBro.m_uniformTextureMinSize, 16, 8192 ); + page.appendSpinner( "Mousewheel Increment", g_TexBro.m_mouseWheelScrollIncrement, 0, 8192 ); { const char* startup_shaders[] = { "None", TextureBrowser_getCommonShadersName() }; - page.appendCombo( "Load Shaders at Startup", reinterpret_cast( GlobalTextureBrowser().m_startupShaders ), StringArrayRange( startup_shaders ) ); + page.appendCombo( "Load Shaders at Startup", reinterpret_cast( g_TexBro.m_startupShaders ), StringArrayRange( startup_shaders ) ); } { StringOutputStream sstream( 256 ); sstream << "Hide nonShaders in " << TextureBrowser_getCommonShadersDir() << " folder"; page.appendCheckBox( "", sstream.c_str(), - GlobalTextureBrowser().m_hideNonShadersInCommon + g_TexBro.m_hideNonShadersInCommon ); } } @@ -2711,55 +2049,58 @@ void TextureClipboard_textureSelected( const char* shader ); void TextureBrowser_Construct(){ GlobalCommands_insert( "ShaderInfo", FreeCaller() ); - GlobalCommands_insert( "ShowUntagged", FreeCaller() ); - GlobalCommands_insert( "AddTag", FreeCaller() ); - GlobalCommands_insert( "RenameTag", FreeCaller() ); - GlobalCommands_insert( "DeleteTag", FreeCaller() ); - GlobalCommands_insert( "CopyTag", FreeCaller() ); - GlobalCommands_insert( "PasteTag", FreeCaller() ); + GlobalCommands_insert( "TagSearchUntagged", FreeCaller() ); + GlobalCommands_insert( "TagSearch", FreeCaller() ); + GlobalCommands_insert( "TagAdd", FreeCaller() ); + GlobalCommands_insert( "TagRename", FreeCaller() ); + GlobalCommands_insert( "TagDelete", FreeCaller() ); + GlobalCommands_insert( "TagCopy", FreeCaller() ); + GlobalCommands_insert( "TagPaste", FreeCaller() ); GlobalCommands_insert( "RefreshShaders", FreeCaller() ); - GlobalToggles_insert( "ShowInUse", FreeCaller(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_hideunused_item ), Accelerator( 'U' ) ); - GlobalCommands_insert( "ShowAllTextures", FreeCaller(), Accelerator( 'A', GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "ToggleTextures", FreeCaller(), Accelerator( 'T' ) ); - GlobalToggles_insert( "ToggleShowShaders", FreeCaller(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showshaders_item ) ); - GlobalToggles_insert( "ToggleShowTextures", FreeCaller(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showtextures_item ) ); - GlobalToggles_insert( "ToggleShowShaderlistOnly", FreeCaller(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showshaderlistonly_item ) ); - GlobalToggles_insert( "FixedSize", FreeCaller(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_fixedsize_item ) ); - GlobalToggles_insert( "FilterNotex", FreeCaller(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_filternotex_item ) ); - GlobalToggles_insert( "EnableAlpha", FreeCaller(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_enablealpha_item ) ); - GlobalToggles_insert( "SearchFromStart", FreeCaller(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_filter_searchFromStart_item ) ); + GlobalToggles_insert( "ShowInUse", FreeCaller(), ToggleItem::AddCallbackCaller( g_TexBro.m_hideunused_item ), QKeySequence( "U" ) ); + GlobalCommands_insert( "ShowAllTextures", FreeCaller(), QKeySequence( "Ctrl+A" ) ); + GlobalCommands_insert( "ToggleTextures", FreeCaller(), QKeySequence( "T" ) ); + GlobalToggles_insert( "ToggleShowShaders", FreeCaller(), ToggleItem::AddCallbackCaller( g_TexBro.m_showshaders_item ) ); + GlobalToggles_insert( "ToggleShowTextures", FreeCaller(), ToggleItem::AddCallbackCaller( g_TexBro.m_showtextures_item ) ); + GlobalToggles_insert( "ToggleShowShaderlistOnly", FreeCaller(), ToggleItem::AddCallbackCaller( g_TexBro.m_showshaderlistonly_item ) ); + GlobalToggles_insert( "FixedSize", FreeCaller(), ToggleItem::AddCallbackCaller( g_TexBro.m_fixedsize_item ) ); + GlobalToggles_insert( "FilterNotex", FreeCaller(), ToggleItem::AddCallbackCaller( g_TexBro.m_filternotex_item ) ); + GlobalToggles_insert( "EnableAlpha", FreeCaller(), ToggleItem::AddCallbackCaller( g_TexBro.m_enablealpha_item ) ); + GlobalToggles_insert( "TagsToggleGui", FreeCaller(), ToggleItem::AddCallbackCaller( g_TexBro.m_tags_item ) ); + GlobalToggles_insert( "SearchFromStart", FreeCaller(), ToggleItem::AddCallbackCaller( g_TexBro.m_filter_searchFromStart_item ) ); GlobalPreferenceSystem().registerPreference( "TextureScale", - makeSizeStringImportCallback( TextureBrowserSetScaleCaller( g_TextureBrowser ) ), - SizeExportStringCaller( g_TextureBrowser.m_textureScale ) + makeSizeStringImportCallback( TextureBrowserSetScaleCaller( g_TexBro ) ), + SizeExportStringCaller( g_TexBro.m_textureScale ) ); GlobalPreferenceSystem().registerPreference( "UniformTextureSize", - makeIntStringImportCallback(UniformTextureSizeImportCaller(g_TextureBrowser)), - IntExportStringCaller(g_TextureBrowser.m_uniformTextureSize) ); + makeIntStringImportCallback(UniformTextureSizeImportCaller(g_TexBro)), + IntExportStringCaller(g_TexBro.m_uniformTextureSize) ); GlobalPreferenceSystem().registerPreference( "UniformTextureMinSize", - makeIntStringImportCallback(UniformTextureMinSizeImportCaller(g_TextureBrowser)), - IntExportStringCaller(g_TextureBrowser.m_uniformTextureMinSize) ); + makeIntStringImportCallback(UniformTextureMinSizeImportCaller(g_TexBro)), + IntExportStringCaller(g_TexBro.m_uniformTextureMinSize) ); GlobalPreferenceSystem().registerPreference( "TextureScrollbar", - makeBoolStringImportCallback( TextureBrowserImportShowScrollbarCaller( g_TextureBrowser ) ), - BoolExportStringCaller( GlobalTextureBrowser().m_showTextureScrollbar ) + makeBoolStringImportCallback( TextureBrowserImportShowScrollbarCaller( g_TexBro ) ), + BoolExportStringCaller( g_TexBro.m_showTextureScrollbar ) ); - GlobalPreferenceSystem().registerPreference( "ShowShaders", BoolImportStringCaller( GlobalTextureBrowser().m_showShaders ), BoolExportStringCaller( GlobalTextureBrowser().m_showShaders ) ); - GlobalPreferenceSystem().registerPreference( "ShowTextures", BoolImportStringCaller( GlobalTextureBrowser().m_showTextures ), BoolExportStringCaller( GlobalTextureBrowser().m_showTextures ) ); + GlobalPreferenceSystem().registerPreference( "ShowShaders", BoolImportStringCaller( g_TexBro.m_showShaders ), BoolExportStringCaller( g_TexBro.m_showShaders ) ); + GlobalPreferenceSystem().registerPreference( "ShowTextures", BoolImportStringCaller( g_TexBro.m_showTextures ), BoolExportStringCaller( g_TexBro.m_showTextures ) ); GlobalPreferenceSystem().registerPreference( "ShowShaderlistOnly", BoolImportStringCaller( g_TextureBrowser_shaderlistOnly ), BoolExportStringCaller( g_TextureBrowser_shaderlistOnly ) ); GlobalPreferenceSystem().registerPreference( "FixedSize", BoolImportStringCaller( g_TextureBrowser_fixedSize ), BoolExportStringCaller( g_TextureBrowser_fixedSize ) ); GlobalPreferenceSystem().registerPreference( "FilterNotex", BoolImportStringCaller( g_TextureBrowser_filterNotex ), BoolExportStringCaller( g_TextureBrowser_filterNotex ) ); GlobalPreferenceSystem().registerPreference( "EnableAlpha", BoolImportStringCaller( g_TextureBrowser_enableAlpha ), BoolExportStringCaller( g_TextureBrowser_enableAlpha ) ); + GlobalPreferenceSystem().registerPreference( "TagsShowGui", BoolImportStringCaller( g_TexBro.m_tags ), BoolExportStringCaller( g_TexBro.m_tags ) ); GlobalPreferenceSystem().registerPreference( "SearchFromStart", BoolImportStringCaller( g_TextureBrowser_filter_searchFromStart ), BoolExportStringCaller( g_TextureBrowser_filter_searchFromStart ) ); - GlobalPreferenceSystem().registerPreference( "LoadShaders", IntImportStringCaller( reinterpret_cast( GlobalTextureBrowser().m_startupShaders ) ), IntExportStringCaller( reinterpret_cast( GlobalTextureBrowser().m_startupShaders ) ) ); - GlobalPreferenceSystem().registerPreference( "WheelMouseInc", SizeImportStringCaller( GlobalTextureBrowser().m_mouseWheelScrollIncrement ), SizeExportStringCaller( GlobalTextureBrowser().m_mouseWheelScrollIncrement ) ); - GlobalPreferenceSystem().registerPreference( "SI_Colors0", Vector3ImportStringCaller( GlobalTextureBrowser().color_textureback ), Vector3ExportStringCaller( GlobalTextureBrowser().color_textureback ) ); - GlobalPreferenceSystem().registerPreference( "HideNonShadersInCommon", BoolImportStringCaller( GlobalTextureBrowser().m_hideNonShadersInCommon ), BoolExportStringCaller( GlobalTextureBrowser().m_hideNonShadersInCommon ) ); + GlobalPreferenceSystem().registerPreference( "LoadShaders", IntImportStringCaller( reinterpret_cast( g_TexBro.m_startupShaders ) ), IntExportStringCaller( reinterpret_cast( g_TexBro.m_startupShaders ) ) ); + GlobalPreferenceSystem().registerPreference( "WheelMouseInc", IntImportStringCaller( g_TexBro.m_mouseWheelScrollIncrement ), IntExportStringCaller( g_TexBro.m_mouseWheelScrollIncrement ) ); + GlobalPreferenceSystem().registerPreference( "SI_Colors0", Vector3ImportStringCaller( g_TexBro.m_color_textureback ), Vector3ExportStringCaller( g_TexBro.m_color_textureback ) ); + GlobalPreferenceSystem().registerPreference( "HideNonShadersInCommon", BoolImportStringCaller( g_TexBro.m_hideNonShadersInCommon ), BoolExportStringCaller( g_TexBro.m_hideNonShadersInCommon ) ); - g_TextureBrowser.shader = texdef_name_default(); + g_TexBro.m_shader = texdef_name_default(); TextureBrowser::wads = !string_empty( g_pGameDescription->getKeyValue( "show_wads" ) ); - Textures_setModeChangedNotify( ReferenceCaller( g_TextureBrowser ) ); + Textures_setModeChangedNotify( ConstMemberCaller( g_TexBro ) ); TextureBrowser_registerPreferencesPage(); @@ -2768,11 +2109,9 @@ void TextureBrowser_Construct(){ TextureBrowser_textureSelected = TextureClipboard_textureSelected; } void TextureBrowser_Destroy(){ + TagBuilder.SaveXmlDoc(); + GlobalShaderSystem().detach( g_ShadersObserver ); Textures_setModeChangedNotify( Callback() ); } - -GtkWidget* TextureBrowser_getGLWidget(){ - return GlobalTextureBrowser().m_gl_widget; -} diff --git a/radiant/texwindow.h b/radiant/texwindow.h index d46052c4..7e8509ce 100644 --- a/radiant/texwindow.h +++ b/radiant/texwindow.h @@ -24,38 +24,31 @@ #include "generic/callbackfwd.h" #include "signal/signalfwd.h" -typedef struct _GtkWidget GtkWidget; - -class TextureBrowser; -TextureBrowser& GlobalTextureBrowser(); - -typedef struct _GtkWindow GtkWindow; -GtkWidget* TextureBrowser_constructWindow( GtkWindow* toplevel ); +class QWidget; +QWidget* TextureBrowser_constructWindow( QWidget* toplevel ); void TextureBrowser_destroyWindow(); -void TextureBrowser_ShowDirectory( TextureBrowser& textureBrowser, const char* name ); -void TextureBrowser_ShowStartupShaders( TextureBrowser& textureBrowser ); - +void TextureBrowser_ShowStartupShaders(); const char* TextureBrowser_GetSelectedShader(); void TextureBrowser_Construct(); void TextureBrowser_Destroy(); + typedef Callback1 StringImportCallback; template class FreeCaller1; -extern GtkWidget* g_page_textures; +extern QWidget* g_page_textures; void TextureBrowser_exportTitle( const StringImportCallback& importer ); typedef FreeCaller1 TextureBrowserExportTitleCaller; + template class BasicVector3; typedef BasicVector3 Vector3; -const Vector3& TextureBrowser_getBackgroundColour( TextureBrowser& textureBrowser ); -void TextureBrowser_setBackgroundColour( TextureBrowser& textureBrowser, const Vector3& colour ); +const Vector3& TextureBrowser_getBackgroundColour(); +void TextureBrowser_setBackgroundColour( const Vector3& colour ); void TextureBrowser_addActiveShadersChangedCallback( const SignalHandler& handler ); void TextureBrowser_addShadersRealiseCallback( const SignalHandler& handler ); - -GtkWidget* TextureBrowser_getGLWidget(); diff --git a/radiant/theme.cpp b/radiant/theme.cpp new file mode 100644 index 00000000..8ec52359 --- /dev/null +++ b/radiant/theme.cpp @@ -0,0 +1,182 @@ +/* + Copyright (C) 2001-2006, William Joseph. + All Rights Reserved. + + This file is part of GtkRadiant. + + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include "preferences.h" +#include "mainframe.h" +#include "preferencesystem.h" +#include "stringio.h" + + +enum class ETheme{ + Light = 0, + Dark, + Darker +}; + +static QActionGroup *s_theme_group; +static ETheme s_theme = ETheme::Dark; + +void theme_set( ETheme theme ){ + s_theme = theme; +#ifdef WIN32 +// QSettings settings( "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", QSettings::NativeFormat ); +// if( settings.value( "AppsUseLightTheme" ) == 0 ) +#endif + static const QPalette default_palette = qApp->palette(); + + const char* sheet = R"( + QToolTip { + color: #ffffff; + background-color: #4D4F4B; + border: 1px solid white; + } + QScrollBar:vertical { + width: 7px; + } + QScrollBar:horizontal { + height: 7px; + } + QToolBar::separator:horizontal { + width: 1px; + margin: 3px 1px; + background-color: #aaaaaa; + } + + QToolBar::separator:vertical { + height: 1px; + margin: 1px 3px; + background-color: #aaaaaa; + } + QToolButton { + padding: 0; + margin: 0; + } + )"; + + if( theme == ETheme::Light ){ + qApp->setPalette( default_palette ); + } + else if( theme == ETheme::Dark ){ + qApp->setStyle( QStyleFactory::create( "Fusion" ) ); + QPalette darkPalette; + QColor darkColor = QColor( 83, 84, 81 ); + QColor disabledColor = QColor( 127, 127, 127 ); + darkPalette.setColor( QPalette::Window, darkColor ); + darkPalette.setColor( QPalette::WindowText, Qt::white ); + darkPalette.setColor( QPalette::Disabled, QPalette::WindowText, disabledColor ); + darkPalette.setColor( QPalette::Base, QColor( 46, 52, 54 ) ); + darkPalette.setColor( QPalette::AlternateBase, darkColor ); + darkPalette.setColor( QPalette::ToolTipBase, Qt::white ); + darkPalette.setColor( QPalette::ToolTipText, Qt::white ); + darkPalette.setColor( QPalette::Text, Qt::white ); + darkPalette.setColor( QPalette::Disabled, QPalette::Text, disabledColor ); + darkPalette.setColor( QPalette::Button, darkColor.lighter( 130 ) ); + darkPalette.setColor( QPalette::ButtonText, Qt::white ); + darkPalette.setColor( QPalette::Disabled, QPalette::ButtonText, disabledColor.lighter( 130 ) ); + darkPalette.setColor( QPalette::BrightText, Qt::red ); + darkPalette.setColor( QPalette::Link, QColor( 42, 130, 218 ) ); + + darkPalette.setColor( QPalette::Highlight, QColor( 250, 203, 129 ) ); + darkPalette.setColor( QPalette::Inactive, QPalette::Highlight, disabledColor ); + darkPalette.setColor( QPalette::HighlightedText, Qt::black ); + darkPalette.setColor( QPalette::Disabled, QPalette::HighlightedText, disabledColor ); + + qApp->setPalette( darkPalette ); + + qApp->setStyleSheet( sheet ); + } + else if( theme == ETheme::Darker ){ + qApp->setStyle( QStyleFactory::create( "Fusion" ) ); + QPalette darkPalette; + QColor darkColor = QColor( 45, 45, 45 ); + QColor disabledColor = QColor( 127, 127, 127 ); + darkPalette.setColor( QPalette::Window, darkColor ); + darkPalette.setColor( QPalette::WindowText, Qt::white ); + darkPalette.setColor( QPalette::Base, QColor( 18, 18, 18 ) ); + darkPalette.setColor( QPalette::AlternateBase, darkColor ); + darkPalette.setColor( QPalette::ToolTipBase, Qt::white ); + darkPalette.setColor( QPalette::ToolTipText, Qt::white ); + darkPalette.setColor( QPalette::Text, Qt::white ); + darkPalette.setColor( QPalette::Disabled, QPalette::Text, disabledColor ); + darkPalette.setColor( QPalette::Button, darkColor ); + darkPalette.setColor( QPalette::ButtonText, Qt::white ); + darkPalette.setColor( QPalette::Disabled, QPalette::ButtonText, disabledColor ); + darkPalette.setColor( QPalette::BrightText, Qt::red ); + darkPalette.setColor( QPalette::Link, QColor( 42, 130, 218 ) ); + + darkPalette.setColor( QPalette::Highlight, QColor( 42, 130, 218 ) ); + darkPalette.setColor( QPalette::HighlightedText, Qt::black ); + darkPalette.setColor( QPalette::Disabled, QPalette::HighlightedText, disabledColor ); + + qApp->setPalette( darkPalette ); + + qApp->setStyleSheet( sheet ); + } +} + +void theme_contruct_menu( class QMenu *menu ){ + auto *m = menu->addMenu( "GUI Theme" ); + m->setTearOffEnabled( g_Layout_enableDetachableMenus.m_value ); + auto *group = s_theme_group = new QActionGroup( m ); + { + auto *a = m->addAction( "Light" ); + a->setCheckable( true ); + group->addAction( a ); + } + { + auto *a = m->addAction( "Dark" ); + a->setCheckable( true ); + group->addAction( a ); + } + { + auto *a = m->addAction( "Darker" ); + a->setCheckable( true ); + group->addAction( a ); + } + + QObject::connect( s_theme_group, &QActionGroup::triggered, []( QAction *action ){ + theme_set( static_cast( s_theme_group->actions().indexOf( action ) ) ); + } ); +} + +void ThemeImport( int value ){ + s_theme = static_cast( value ); + if( s_theme_group != nullptr && 0 <= value && value < s_theme_group->actions().size() ){ + s_theme_group->actions().at( value )->setChecked( true ); + } +} +typedef FreeCaller1 ThemeImportCaller; + +void ThemeExport( const IntImportCallback& importer ){ + importer( static_cast( s_theme ) ); +} +typedef FreeCaller1 ThemeExportCaller; + + +void theme_contruct(){ + GlobalPreferenceSystem().registerPreference( "GUITheme", makeIntStringImportCallback( ThemeImportCaller() ), makeIntStringExportCallback( ThemeExportCaller() ) ); + theme_set( s_theme ); // set theme here, not in importer, so it's set on the very 1st start too (when there is no preference to load) +} diff --git a/libs/gtkutil/container.cpp b/radiant/theme.h similarity index 90% rename from libs/gtkutil/container.cpp rename to radiant/theme.h index 8790307e..c016b209 100644 --- a/libs/gtkutil/container.cpp +++ b/radiant/theme.h @@ -19,4 +19,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "container.h" +#pragma once + +void theme_contruct_menu( class QMenu *menu ); +void theme_contruct(); \ No newline at end of file diff --git a/radiant/tools.cpp b/radiant/tools.cpp new file mode 100644 index 00000000..febd6a53 --- /dev/null +++ b/radiant/tools.cpp @@ -0,0 +1,442 @@ +/* + Copyright (C) 1999-2006 Id Software, Inc. and contributors. + For a list of contributors, see the accompanying CONTRIBUTORS file. + + This file is part of GtkRadiant. + + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "tools.h" + +#include "iscenegraph.h" +#include "iselection.h" +#include "mainframe.h" +#include "commands.h" +#include "generic/callback.h" +#include "signal/isignal.h" +#include "gtkutil/widget.h" + + +void ModeChangeNotify(){ + SceneChangeNotify(); +} + +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(); +} + + +bool EdgeMode(){ + return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent + && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eEdge; +} + +bool VertexMode(){ + return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent + && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eVertex; +} + +bool FaceMode(){ + return GlobalSelectionSystem().Mode() == SelectionSystem::eComponent + && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace; +} + +template +class BoolFunctionExport +{ +public: + static void apply( const BoolImportCallback& importCallback ){ + importCallback( BoolFunction() ); + } +}; + +typedef FreeCaller1::apply> EdgeModeApplyCaller; +EdgeModeApplyCaller g_edgeMode_button_caller; +BoolExportCallback g_edgeMode_button_callback( g_edgeMode_button_caller ); +ToggleItem g_edgeMode_button( g_edgeMode_button_callback ); + +typedef FreeCaller1::apply> VertexModeApplyCaller; +VertexModeApplyCaller g_vertexMode_button_caller; +BoolExportCallback g_vertexMode_button_callback( g_vertexMode_button_caller ); +ToggleItem g_vertexMode_button( g_vertexMode_button_callback ); + +typedef FreeCaller1::apply> FaceModeApplyCaller; +FaceModeApplyCaller g_faceMode_button_caller; +BoolExportCallback 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(); +} + +void ComponentMode_SelectionChanged( const Selectable& selectable ){ + if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent + && GlobalSelectionSystem().countSelected() == 0 ) { + SelectionSystem_DefaultMode(); + ComponentModeChanged(); + } +} + +void SelectEdgeMode(){ +#if 0 + if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) { + GlobalSelectionSystem().Select( false ); + } +#endif + + if ( EdgeMode() ) { + SelectionSystem_DefaultMode(); + } + else if ( GlobalSelectionSystem().countSelected() != 0 ) { + if ( !g_currentToolModeSupportsComponentEditing ) { + g_defaultToolMode(); + } + + GlobalSelectionSystem().SetMode( SelectionSystem::eComponent ); + GlobalSelectionSystem().SetComponentMode( SelectionSystem::eEdge ); + } + + ComponentModeChanged(); + + ModeChangeNotify(); +} + +void SelectVertexMode(){ +#if 0 + if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) { + GlobalSelectionSystem().Select( false ); + } +#endif + + if ( VertexMode() ) { + SelectionSystem_DefaultMode(); + } + else if ( GlobalSelectionSystem().countSelected() != 0 ) { + if ( !g_currentToolModeSupportsComponentEditing ) { + g_defaultToolMode(); + } + + GlobalSelectionSystem().SetMode( SelectionSystem::eComponent ); + GlobalSelectionSystem().SetComponentMode( SelectionSystem::eVertex ); + } + + ComponentModeChanged(); + + ModeChangeNotify(); +} + +void SelectFaceMode(){ +#if 0 + if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) { + GlobalSelectionSystem().Select( false ); + } +#endif + + if ( FaceMode() ) { + SelectionSystem_DefaultMode(); + } + else if ( GlobalSelectionSystem().countSelected() != 0 ) { + if ( !g_currentToolModeSupportsComponentEditing ) { + g_defaultToolMode(); + } + + GlobalSelectionSystem().SetMode( SelectionSystem::eComponent ); + GlobalSelectionSystem().SetComponentMode( SelectionSystem::eFace ); + } + + ComponentModeChanged(); + + ModeChangeNotify(); +} + + + +void TranslateToolExport( const BoolImportCallback& importCallback ){ + importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eTranslate ); +} + +void RotateToolExport( const BoolImportCallback& importCallback ){ + importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eRotate ); +} + +void ScaleToolExport( const BoolImportCallback& importCallback ){ + importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eScale ); +} + +void SkewToolExport( const BoolImportCallback& importCallback ){ + importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eSkew ); +} + +void DragToolExport( const BoolImportCallback& importCallback ){ + importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eDrag ); +} + +void ClipperToolExport( const BoolImportCallback& importCallback ){ + importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip ); +} + +void BuildToolExport( const BoolImportCallback& importCallback ){ + importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eBuild ); +} + +void UVToolExport( const BoolImportCallback& importCallback ){ + importCallback( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eUV ); +} + +FreeCaller1 g_translatemode_button_caller; +BoolExportCallback g_translatemode_button_callback( g_translatemode_button_caller ); +ToggleItem g_translatemode_button( g_translatemode_button_callback ); + +FreeCaller1 g_rotatemode_button_caller; +BoolExportCallback g_rotatemode_button_callback( g_rotatemode_button_caller ); +ToggleItem g_rotatemode_button( g_rotatemode_button_callback ); + +FreeCaller1 g_scalemode_button_caller; +BoolExportCallback g_scalemode_button_callback( g_scalemode_button_caller ); +ToggleItem g_scalemode_button( g_scalemode_button_callback ); + +FreeCaller1 g_skewmode_button_caller; +BoolExportCallback g_skewmode_button_callback( g_skewmode_button_caller ); +ToggleItem g_skewmode_button( g_skewmode_button_callback ); + +FreeCaller1 g_dragmode_button_caller; +BoolExportCallback g_dragmode_button_callback( g_dragmode_button_caller ); +ToggleItem g_dragmode_button( g_dragmode_button_callback ); + +FreeCaller1 g_clipper_button_caller; +BoolExportCallback g_clipper_button_callback( g_clipper_button_caller ); +ToggleItem g_clipper_button( g_clipper_button_callback ); + +FreeCaller1 g_build_button_caller; +BoolExportCallback g_build_button_callback( g_build_button_caller ); +ToggleItem g_build_button( g_build_button_callback ); + +FreeCaller1 g_uv_button_caller; +BoolExportCallback g_uv_button_callback( g_uv_button_caller ); +ToggleItem g_uv_button( g_uv_button_callback ); + +void ToolChanged(){ + g_translatemode_button.update(); + g_rotatemode_button.update(); + g_scalemode_button.update(); + g_skewmode_button.update(); + g_dragmode_button.update(); + g_clipper_button.update(); + g_build_button.update(); + g_uv_button.update(); +} + +constexpr char 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; + + Sys_Status( c_ResizeMode_status ); + GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eDrag ); + ToolChanged(); + ModeChangeNotify(); + } +} + + +constexpr char 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; + + Sys_Status( c_TranslateMode_status ); + GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eTranslate ); + ToolChanged(); + ModeChangeNotify(); + } +} + +constexpr char 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; + + Sys_Status( c_RotateMode_status ); + GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eRotate ); + ToolChanged(); + ModeChangeNotify(); + } +} + +constexpr char 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; + + Sys_Status( c_ScaleMode_status ); + GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eScale ); + ToolChanged(); + ModeChangeNotify(); + } +} + +constexpr char c_SkewMode_status[] = "Transform Tool: transform objects and components"; + +void SkewMode(){ + if ( g_currentToolMode == SkewMode && g_defaultToolMode != SkewMode ) { + g_defaultToolMode(); + } + else + { + g_currentToolMode = SkewMode; + g_currentToolModeSupportsComponentEditing = true; + + Sys_Status( c_SkewMode_status ); + GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eSkew ); + ToolChanged(); + ModeChangeNotify(); + } +} + + +constexpr char c_ClipperMode_status[] = "Clipper Tool: apply clip planes to brushes"; + +void ClipperMode(){ + if ( g_currentToolMode == ClipperMode && g_defaultToolMode != ClipperMode ) { + g_defaultToolMode(); + } + else + { + g_currentToolMode = ClipperMode; + g_currentToolModeSupportsComponentEditing = false; + + SelectionSystem_DefaultMode(); + ComponentModeChanged(); + + Sys_Status( c_ClipperMode_status ); + GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eClip ); + ToolChanged(); + ModeChangeNotify(); + } +} + + +constexpr char c_BuildMode_status[] = "Build Tool: extrude, build chains, clone"; + +void BuildMode(){ + if ( g_currentToolMode == BuildMode && g_defaultToolMode != BuildMode ) { + g_defaultToolMode(); + } + else + { + g_currentToolMode = BuildMode; + g_currentToolModeSupportsComponentEditing = false; + + SelectionSystem_DefaultMode(); + ComponentModeChanged(); + + Sys_Status( c_BuildMode_status ); + GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eBuild ); + ToolChanged(); + ModeChangeNotify(); + } +} + + +constexpr char c_UVMode_status[] = "UV Tool: edit texture alignment"; + +void UVMode(){ + if ( g_currentToolMode == UVMode && g_defaultToolMode != UVMode ) { + g_defaultToolMode(); + } + else + { + g_currentToolMode = UVMode; + g_currentToolModeSupportsComponentEditing = false; + + SelectionSystem_DefaultMode(); + ComponentModeChanged(); + + Sys_Status( c_UVMode_status ); + GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eUV ); + ToolChanged(); + ModeChangeNotify(); + } +} + + +void ToggleRotateScaleModes(){ + return g_currentToolMode == RotateMode? ScaleMode() : RotateMode(); +} + +void ToggleDragSkewModes(){ + return g_currentToolMode == DragMode? SkewMode() : DragMode(); +} + + + +void Tools_registerCommands(){ + GlobalToggles_insert( "DragVertices", FreeCaller(), ToggleItem::AddCallbackCaller( g_vertexMode_button ), QKeySequence( "V" ) ); + GlobalToggles_insert( "DragEdges", FreeCaller(), ToggleItem::AddCallbackCaller( g_edgeMode_button ), QKeySequence( "E" ) ); + GlobalToggles_insert( "DragFaces", FreeCaller(), ToggleItem::AddCallbackCaller( g_faceMode_button ), QKeySequence( "F" ) ); + + GlobalToggles_insert( "ToggleClipper", FreeCaller(), ToggleItem::AddCallbackCaller( g_clipper_button ), QKeySequence( "X" ) ); + + GlobalToggles_insert( "MouseTranslate", FreeCaller(), ToggleItem::AddCallbackCaller( g_translatemode_button ), QKeySequence( "W" ) ); + GlobalToggles_insert( "MouseRotate", FreeCaller(), ToggleItem::AddCallbackCaller( g_rotatemode_button ), QKeySequence( "R" ) ); + GlobalToggles_insert( "MouseScale", FreeCaller(), ToggleItem::AddCallbackCaller( g_scalemode_button ) ); + GlobalToggles_insert( "MouseTransform", FreeCaller(), ToggleItem::AddCallbackCaller( g_skewmode_button ) ); + GlobalToggles_insert( "MouseDrag", FreeCaller(), ToggleItem::AddCallbackCaller( g_dragmode_button ) ); + GlobalToggles_insert( "MouseBuild", FreeCaller(), ToggleItem::AddCallbackCaller( g_build_button ), QKeySequence( "B" ) ); + GlobalToggles_insert( "MouseUV", FreeCaller(), ToggleItem::AddCallbackCaller( g_uv_button ), QKeySequence( "G" ) ); + GlobalCommands_insert( "MouseRotateOrScale", FreeCaller() ); + GlobalCommands_insert( "MouseDragOrTransform", FreeCaller(), QKeySequence( "Q" ) ); + + GlobalSelectionSystem().addSelectionChangeCallback( FreeCaller1() ); + + g_defaultToolMode = DragMode; + g_defaultToolMode(); +} \ No newline at end of file diff --git a/libs/gtkutil/frame.h b/radiant/tools.h similarity index 76% rename from libs/gtkutil/frame.h rename to radiant/tools.h index 1970875b..899b2071 100644 --- a/libs/gtkutil/frame.h +++ b/radiant/tools.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2001-2006, William Joseph. - All Rights Reserved. + 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. @@ -21,6 +21,8 @@ #pragma once -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkFrame GtkFrame; -GtkFrame* create_framed_widget( GtkWidget* widget ); + +void Tools_registerCommands(); + +void SelectionSystem_DefaultMode(); +void ComponentModeChanged(); \ No newline at end of file diff --git a/radiant/treemodel.cpp b/radiant/treemodel.cpp index 51289437..67f7f4c7 100644 --- a/radiant/treemodel.cpp +++ b/radiant/treemodel.cpp @@ -24,7 +24,11 @@ #include "debugging/debugging.h" #include -#include + +#include +#include +#include +#include #include "iscenegraph.h" #include "nameable.h" @@ -34,623 +38,28 @@ #include "string/string.h" #include "generic/reference.h" + inline Nameable* Node_getNameable( scene::Node& node ){ return NodeTypeCast::cast( node ); } -#if 0 - -#include "gtkutil/gtktreestore.h" - -template -inline void gtk_tree_model_get_pointer( GtkTreeModel* model, GtkTreeIter* iter, gint column, value_type** pointer ){ - GValue value = GValue_default(); - gtk_tree_model_get_value( model, iter, column, &value ); - *pointer = (value_type*)g_value_get_pointer( &value ); +const char* node_get_name( scene::Node& node ){ + Nameable* nameable = Node_getNameable( node ); + return ( nameable != 0 ) + ? nameable->name() + : "node"; } - -typedef GtkTreeStore GraphTreeModel; - -GtkTreeStore* graph_tree_model_new( graph_type* graph ){ - return gtk_tree_store_new( 2, G_TYPE_POINTER, G_TYPE_POINTER ); -} - -void graph_tree_model_delete( GraphTreeModel* model ){ - g_object_unref( G_OBJECT( model ) ); -} - - -bool graph_tree_model_subtree_find_node( GraphTreeModel* model, GtkTreeIter* parent, const scene::Node& node, GtkTreeIter* iter ){ - for ( gboolean success = gtk_tree_model_iter_children( GTK_TREE_MODEL( model ), iter, parent ); - success; - success = gtk_tree_model_iter_next( GTK_TREE_MODEL( model ), iter ) ) - { - scene::Node* current; - gtk_tree_model_get_pointer( GTK_TREE_MODEL( model ), iter, 0, ¤t ); - if ( current == node ) { - return true; - } +const char* node_get_name_safe( scene::Node& node ){ + volatile intptr_t n = (intptr_t)&node; // see the comment on line 650 + if ( n == 0 ) { + return ""; } - return false; + return node_get_name( node ); } -typedef GtkTreeIter DoubleGtkTreeIter[2]; - -bool graph_tree_model_find_top( GraphTreeModel* model, const scene::Path& path, GtkTreeIter& iter ){ - int swap = 0; - GtkTreeIter* parent_pointer = NULL; - GtkTreeIter parent; - for ( scene::Path::const_iterator i = path.begin(); i != path.end(); ++i ) - { - if ( !graph_tree_model_subtree_find_node( model, parent_pointer, *i, &iter ) ) { - return false; - } - parent = iter; - parent_pointer = &parent; - } - return true; -} - -bool graph_tree_model_find_parent( GraphTreeModel* model, const scene::Path& path, GtkTreeIter& iter ){ - int swap = 0; - GtkTreeIter* parent_pointer = NULL; - ASSERT_MESSAGE( path.size() > 1, "path too short" ); - for ( scene::Path::const_iterator i = path.begin(); i != path.end() - 1; ++i ) - { - GtkTreeIter child; - if ( !graph_tree_model_subtree_find_node( model, parent_pointer, *i, &child ) ) { - return false; - } - iter = child; - parent_pointer = &iter; - } - return true; -} - -void node_attach_name_changed_callback( scene::Node& node, const Callback& callback ){ - if ( node != 0 ) { - Nameable* nameable = Node_getNameable( node ); - if ( nameable != 0 ) { - nameable->attach( callback ); - } - } -} -void node_detach_name_changed_callback( scene::Node& node, const Callback& callback ){ - if ( node != 0 ) { - Nameable* nameable = Node_getNameable( node ); - if ( nameable != 0 ) { - nameable->detach( callback ); - } - } -} - -GraphTreeModel* scene_graph_get_tree_model(); // temp hack - -void graph_tree_model_row_changed( const scene::Instance& instance ){ - GraphTreeModel* model = scene_graph_get_tree_model(); - - GtkTreeIter child; - ASSERT_MESSAGE( graph_tree_model_find_top( model, instance.path(), child ), "RUNTIME ERROR" ); - - gtk_tree_store_set( GTK_TREE_STORE( model ), &child, 0, instance.path().top(), -1 ); -} - -void graph_tree_model_row_inserted( GraphTreeModel* model, const scene::Instance& instance ){ - GtkTreeIter parent; - GtkTreeIter* parent_pointer = NULL; - if ( instance.path().size() != 1 ) { - ASSERT_MESSAGE( graph_tree_model_find_parent( model, instance.path(), parent ), "RUNTIME ERROR" ); - parent_pointer = &parent; - } - - gpointer node = instance.path().top(); - gconstpointer selectable = Instance_getSelectable( instance ); - - GtkTreeIter child; - gtk_tree_store_append( GTK_TREE_STORE( model ), &child, parent_pointer ); - gtk_tree_store_set( GTK_TREE_STORE( model ), &child, 0, node, 1, selectable, -1 ); - - node_attach_name_changed_callback( instance.path().top(), ConstReferenceCaller( instance ) ); -} - -void graph_tree_model_row_deleted( GraphTreeModel* model, const scene::Instance& instance ){ - GtkTreeIter child; - ASSERT_MESSAGE( graph_tree_model_find_top( model, instance.path(), child ), "RUNTIME ERROR" ); - - node_detach_name_changed_callback( instance.path().top(), ConstReferenceCaller( instance ) ); - - gtk_tree_store_remove( GTK_TREE_STORE( model ), &child ); -} - -#elif 0 - -const char* node_get_name( scene::Node& node ); - -typedef scene::Node* NodePointer; - -class NodeNameLess -{ -public: - bool operator()( const NodePointer& self, const NodePointer& other ) const { - if ( self == 0 ) { - return true; - } - if ( other == 0 ) { - return false; - } - int result = string_compare( node_get_name( self ), node_get_name( other ) ); - if ( result == 0 ) { - return self < other; - } - return result < 0; - } -}; - -class PathNameLess -{ -public: - bool operator()( const PathConstReference& self, const PathConstReference& other ) const { - return std::lexicographical_compare( self.get().begin(), self.get().end(), other.get().begin(), other.get().end(), NodeNameLess() ); - } -}; - -typedef std::map graph_type; - -struct GraphTreeModel -{ - GObject parent; - - graph_type* graph; -}; - -struct GraphTreeModelClass -{ - GObjectClass parent_class; -}; - -#define GRAPH_TREE_MODEL( p ) ( reinterpret_cast( p ) ) - -static GtkTreeModelFlags graph_tree_model_get_flags( GtkTreeModel* tree_model ){ - return GTK_TREE_MODEL_ITERS_PERSIST; -} - -static gint graph_tree_model_get_n_columns( GtkTreeModel* tree_model ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - GraphTreeModel* graph_tree_model = (GraphTreeModel*) tree_model; - - return 2; -} - -static const gint c_stamp = 0xabcdef; - -inline graph_type::iterator graph_iterator_read_tree_iter( GtkTreeIter* iter ){ - ASSERT_MESSAGE( iter != 0, "tree model error" ); - ASSERT_MESSAGE( iter->user_data != 0, "tree model error" ); - ASSERT_MESSAGE( iter->stamp == c_stamp, "tree model error" ); - return *reinterpret_cast( &iter->user_data ); -} - -inline void graph_iterator_write_tree_iter( graph_type::iterator i, GtkTreeIter* iter ){ - ASSERT_MESSAGE( iter != 0, "tree model error" ); - iter->stamp = c_stamp; - *reinterpret_cast( &iter->user_data ) = i; - ASSERT_MESSAGE( iter->user_data != 0, "tree model error" ); -} - -static GType graph_tree_model_get_column_type( GtkTreeModel *tree_model, gint index ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - GraphTreeModel *graph_tree_model = (GraphTreeModel *) tree_model; - - return G_TYPE_POINTER; -} - -static gboolean graph_tree_model_get_iter( GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreePath* path ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - gint* indices = gtk_tree_path_get_indices( path ); - gint depth = gtk_tree_path_get_depth( path ); - - g_return_val_if_fail( depth > 0, FALSE ); - - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - - if ( graph.empty() ) { - return FALSE; - } - - GtkTreeIter tmp; - GtkTreeIter* parent = 0; - - for ( gint i = 0; i < depth; i++ ) - { - if ( !gtk_tree_model_iter_nth_child( tree_model, iter, parent, indices[i] ) ) { - return FALSE; - } - tmp = *iter; - parent = &tmp; - } - - return TRUE; -} - -static GtkTreePath* graph_tree_model_get_path( GtkTreeModel* tree_model, GtkTreeIter* iter ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = graph_iterator_read_tree_iter( iter ); - - GtkTreePath* path = gtk_tree_path_new(); - - for ( std::size_t depth = ( *i ).first.get().size(); depth != 0; --depth ) - { - std::size_t index = 0; - - while ( i != graph.begin() && ( *i ).first.get().size() >= depth ) - { - --i; - if ( ( *i ).first.get().size() == depth ) { - ++index; - } - } - - gtk_tree_path_prepend_index( path, index ); - } - - return path; -} - - -static void graph_tree_model_get_value( GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - ASSERT_MESSAGE( column == 0 || column == 1, "tree model error" ); - - graph_type::iterator i = graph_iterator_read_tree_iter( iter ); - - g_value_init( value, G_TYPE_POINTER ); - - if ( column == 0 ) { - g_value_set_pointer( value, reinterpret_cast( ( *i ).first.get().top() ) ); - } - else{ - g_value_set_pointer( value, reinterpret_cast( Instance_getSelectable( *( *i ).second ) ) ); - } -} - -static gboolean graph_tree_model_iter_next( GtkTreeModel *tree_model, GtkTreeIter *iter ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = graph_iterator_read_tree_iter( iter ); - std::size_t depth = ( *i ).first.get().size(); - - ++i; - - while ( i != graph.end() && ( *i ).first.get().size() > depth ) - { - ++i; - } - - if ( i == graph.end() || ( *i ).first.get().size() != depth ) { - return FALSE; - } - - graph_iterator_write_tree_iter( i, iter ); - - return TRUE; -} - -static gboolean graph_tree_model_iter_children( GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = ( parent == 0 ) ? graph.begin() : graph_iterator_read_tree_iter( parent ); - std::size_t depth = ( parent == 0 ) ? 1 : ( *i ).first.get().size() + 1; - - if ( parent != 0 ) { - ++i; - } - - if ( i != graph.end() && ( *i ).first.get().size() == depth ) { - graph_iterator_write_tree_iter( i, iter ); - return TRUE; - } - - return FALSE; -} - -static gboolean graph_tree_model_iter_has_child( GtkTreeModel *tree_model, GtkTreeIter *iter ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = graph_iterator_read_tree_iter( iter ); - std::size_t depth = ( *i ).first.get().size() + 1; - - return ++i != graph.end() && ( *i ).first.get().size() == depth; -} - -static gint graph_tree_model_iter_n_children( GtkTreeModel *tree_model, GtkTreeIter *parent ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = ( parent == 0 ) ? graph.begin() : graph_iterator_read_tree_iter( parent ); - std::size_t depth = ( parent == 0 ) ? 1 : ( *i ).first.get().size() + 1; - - if ( parent != 0 ) { - ++i; - } - - gint count = 0; - while ( i != graph.end() && ( *i ).first.get().size() >= depth ) - { - ++count; - ++i; - } - - return count; -} - -static gboolean graph_tree_model_iter_nth_child( GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = ( parent == 0 ) ? graph.begin() : graph_iterator_read_tree_iter( parent ); - std::size_t depth = ( parent == 0 ) ? 1 : ( *i ).first.get().size() + 1; - - if ( parent != 0 ) { - ++i; - } - - while ( i != graph.end() && ( *i ).first.get().size() >= depth ) - { - if ( ( *i ).first.get().size() == depth && n-- == 0 ) { - graph_iterator_write_tree_iter( i, iter ); - return TRUE; - } - ++i; - } - - return FALSE; -} - -static gboolean graph_tree_model_iter_parent( GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - graph_type& graph = *GRAPH_TREE_MODEL( tree_model )->graph; - graph_type::iterator i = graph_iterator_read_tree_iter( child ); - std::size_t depth = ( *i ).first.get().size(); - if ( depth == 1 ) { - return FALSE; - } - else - { - do - { - --i; - } - while ( ( *i ).first.get().size() >= depth ); - graph_iterator_write_tree_iter( i, iter ); - return TRUE; - } -} - -static GObjectClass *g_parent_class = 0; - -static void graph_tree_model_init( GraphTreeModel *graph_tree_model ){ - graph_tree_model->graph = 0; -} - -static void graph_tree_model_finalize( GObject* object ){ - GraphTreeModel* graph_tree_model = GRAPH_TREE_MODEL( object ); - - /* must chain up */ - ( *g_parent_class->finalize )( object ); -} - -static void graph_tree_model_class_init( GraphTreeModelClass *class_ ){ - GObjectClass *object_class; - - g_parent_class = (GObjectClass*)g_type_class_peek_parent( class_ ); - object_class = (GObjectClass *) class_; - - object_class->finalize = graph_tree_model_finalize; -} - -static void graph_tree_model_tree_model_init( GtkTreeModelIface *iface ){ - iface->get_flags = graph_tree_model_get_flags; - iface->get_n_columns = graph_tree_model_get_n_columns; - iface->get_column_type = graph_tree_model_get_column_type; - iface->get_iter = graph_tree_model_get_iter; - iface->get_path = graph_tree_model_get_path; - iface->get_value = graph_tree_model_get_value; - iface->iter_next = graph_tree_model_iter_next; - iface->iter_children = graph_tree_model_iter_children; - iface->iter_has_child = graph_tree_model_iter_has_child; - iface->iter_n_children = graph_tree_model_iter_n_children; - iface->iter_nth_child = graph_tree_model_iter_nth_child; - iface->iter_parent = graph_tree_model_iter_parent; -} - -static gboolean graph_tree_model_row_draggable( GtkTreeDragSource *drag_source, GtkTreePath *path ){ -#ifdef _DEBUG - gint depth = gtk_tree_path_get_depth( path ); -#endif - return gtk_tree_path_get_depth( path ) > 1; -} - -static gboolean graph_tree_model_drag_data_delete( GtkTreeDragSource *drag_source, GtkTreePath *path ){ - GtkTreeIter iter; - - if ( gtk_tree_model_get_iter( GTK_TREE_MODEL( drag_source ), &iter, path ) ) { - graph_type::iterator i = graph_iterator_read_tree_iter( &iter ); - Path_deleteTop( ( *i ).first ); - return TRUE; - } - else - { - return FALSE; - } -} - -static gboolean graph_tree_model_drag_data_get( GtkTreeDragSource *drag_source, GtkTreePath *path, GtkSelectionData *selection_data ){ - if ( gtk_tree_set_row_drag_data( selection_data, GTK_TREE_MODEL( drag_source ), path ) ) { - return TRUE; - } - else - { - /* FIXME handle text targets at least. */ - } - - return FALSE; -} - -static void graph_tree_model_drag_source_init( GtkTreeDragSourceIface *iface ){ - iface->row_draggable = graph_tree_model_row_draggable; - iface->drag_data_delete = graph_tree_model_drag_data_delete; - iface->drag_data_get = graph_tree_model_drag_data_get; -} - -static gboolean graph_tree_model_drag_data_received( GtkTreeDragDest *drag_dest, GtkTreePath *dest, GtkSelectionData *selection_data ){ - GtkTreeModel *tree_model = GTK_TREE_MODEL( drag_dest ); - - GtkTreeModel *src_model = 0; - GtkTreePath *src_path = 0; - if ( gtk_tree_get_row_drag_data( selection_data, &src_model, &src_path ) - && src_model == tree_model ) { - /* Copy the given row to a new position */ - GtkTreeIter iter; - - if ( gtk_tree_model_get_iter( src_model, &iter, src_path ) ) { - int bleh = 0; - } - } - else - { - /* FIXME maybe add some data targets eventually, or handle text - * targets in the simple case. - */ - } - - return FALSE; -} - -static gboolean graph_tree_model_row_drop_possible( GtkTreeDragDest *drag_dest, GtkTreePath *dest_path, GtkSelectionData *selection_data ){ - gboolean retval = FALSE; - - GtkTreeModel *src_model = 0; - GtkTreePath *src_path = 0; - if ( gtk_tree_get_row_drag_data( selection_data, &src_model, &src_path ) ) { - /* can only drag to ourselves */ - if ( src_model == GTK_TREE_MODEL( drag_dest ) ) { - /* Can't drop into ourself. */ - if ( !gtk_tree_path_is_ancestor( src_path, dest_path ) ) { - /* Can't drop if dest_path's parent doesn't exist */ - if ( gtk_tree_path_get_depth( dest_path ) > 1 ) { - GtkTreePath* tmp = gtk_tree_path_copy( dest_path ); - gtk_tree_path_up( tmp ); - - GtkTreeIter iter; - retval = gtk_tree_model_get_iter( GTK_TREE_MODEL( drag_dest ), &iter, tmp ); - - gtk_tree_path_free( tmp ); - } - } - } - - gtk_tree_path_free( src_path ); - } - - return retval; -} - -static void graph_tree_model_drag_dest_init( GtkTreeDragDestIface *iface ){ - iface->drag_data_received = graph_tree_model_drag_data_received; - iface->row_drop_possible = graph_tree_model_row_drop_possible; -} - -GType graph_tree_model_get_type(){ - static GType graph_tree_model_type = 0; - - if ( !graph_tree_model_type ) { - static const GTypeInfo graph_tree_model_info = - { - sizeof( GraphTreeModelClass ), - 0, /* base_init */ - 0, /* base_finalize */ - (GClassInitFunc) graph_tree_model_class_init, - 0, /* class_finalize */ - 0, /* class_data */ - sizeof( GraphTreeModel ), - 0, /* n_preallocs */ - (GInstanceInitFunc) graph_tree_model_init - }; - - static const GInterfaceInfo tree_model_info = - { - (GInterfaceInitFunc) graph_tree_model_tree_model_init, - 0, - 0 - }; - - static const GInterfaceInfo drag_source_info = - { - (GInterfaceInitFunc) graph_tree_model_drag_source_init, - 0, - 0 - }; - - static const GInterfaceInfo drag_dest_info = - { - (GInterfaceInitFunc) graph_tree_model_drag_dest_init, - 0, - 0 - }; - - graph_tree_model_type = g_type_register_static( G_TYPE_OBJECT, "GraphTreeModel", - &graph_tree_model_info, (GTypeFlags)0 ); - - g_type_add_interface_static( graph_tree_model_type, - GTK_TYPE_TREE_MODEL, - &tree_model_info ); - g_type_add_interface_static( graph_tree_model_type, - GTK_TYPE_TREE_DRAG_SOURCE, - &drag_source_info ); - g_type_add_interface_static( graph_tree_model_type, - GTK_TYPE_TREE_DRAG_DEST, - &drag_dest_info ); - } - - return graph_tree_model_type; -} - -GraphTreeModel* graph_tree_model_new(){ - GraphTreeModel* graph_tree_model = GRAPH_TREE_MODEL( g_object_new( graph_tree_model_get_type(), 0 ) ); - - graph_tree_model->graph = new graph_type; - - return graph_tree_model; -} - -void graph_tree_model_delete( GraphTreeModel* model ){ - delete model->graph; - g_object_unref( G_OBJECT( model ) ); -} - - -class TempNameable : public Nameable -{ - const char* m_name; -public: - TempNameable( const char* name ) : m_name( name ){ - } - const char* name() const { - return m_name; - } - void attach( const NameCallback& callback ){ - } - void detach( const NameCallback& callback ){ - } -}; - void node_attach_name_changed_callback( scene::Node& node, const NameCallback& callback ){ - // line 650: Reference cannot be bound to dereferenced null pointer in well-defined - // C++ code, and Clang will assume that comparison below always evaluates - // to true, resulting in a segmentation fault. Use a dirty hack to force - // Clang to check those "bad" references for null nonetheless. - volatile intptr_t n = (intptr_t)&node; - + volatile intptr_t n = (intptr_t)&node; // see the comment on line 650 if ( n != 0 ) { Nameable* nameable = Node_getNameable( node ); if ( nameable != 0 ) { @@ -660,7 +69,6 @@ void node_attach_name_changed_callback( scene::Node& node, const NameCallback& c } void node_detach_name_changed_callback( scene::Node& node, const NameCallback& callback ){ volatile intptr_t n = (intptr_t)&node; // see the comment on line 650 - if ( n != 0 ) { Nameable* nameable = Node_getNameable( node ); if ( nameable != 0 ) { @@ -669,332 +77,10 @@ void node_detach_name_changed_callback( scene::Node& node, const NameCallback& c } } -GraphTreeModel* scene_graph_get_tree_model(); // temp hack +void graph_tree_model_set_name( const scene::Instance& instance, const char* name ); -void graph_tree_model_row_inserted( GraphTreeModel* model, graph_type::iterator i ){ - GtkTreeIter iter; - graph_iterator_write_tree_iter( i, &iter ); - GtkTreePath* tree_path = graph_tree_model_get_path( GTK_TREE_MODEL( model ), &iter ); - - gint depth = gtk_tree_path_get_depth( tree_path ); - gint* indices = gtk_tree_path_get_indices( tree_path ); - - gtk_tree_model_row_inserted( GTK_TREE_MODEL( model ), tree_path, &iter ); - - gtk_tree_path_free( tree_path ); -} - -void graph_tree_model_row_deleted( GraphTreeModel* model, graph_type::iterator i ){ - GtkTreeIter iter; - graph_iterator_write_tree_iter( i, &iter ); - - GtkTreePath* tree_path = graph_tree_model_get_path( GTK_TREE_MODEL( model ), &iter ); - - gtk_tree_model_row_deleted( GTK_TREE_MODEL( model ), tree_path ); - - gtk_tree_path_free( tree_path ); -} - -#include "generic/referencecounted.h" - -void graph_tree_model_set_name( const scene::Instance& instance, const char* name ){ - GraphTreeModel* model = scene_graph_get_tree_model(); - - if ( string_empty( name ) ) { // hack! - graph_type::iterator i = model->graph->find( PathConstReference( instance.path() ) ); - ASSERT_MESSAGE( i != model->graph->end(), "ERROR" ); - - graph_tree_model_row_deleted( model, i ); - - model->graph->erase( i ); - } - else - { - graph_type::iterator i = model->graph->insert( graph_type::value_type( PathConstReference( instance.path() ), &const_cast( instance ) ) ).first; - - graph_tree_model_row_inserted( model, i ); - } -} - -void graph_tree_model_insert( GraphTreeModel* model, const scene::Instance& instance ){ - graph_type::iterator i = model->graph->insert( graph_type::value_type( PathConstReference( instance.path() ), &const_cast( instance ) ) ).first; - - graph_tree_model_row_inserted( model, i ); - - node_attach_name_changed_callback( instance.path().top(), ConstReferenceCaller1( instance ) ); -} - -void graph_tree_model_erase( GraphTreeModel* model, const scene::Instance& instance ){ - node_detach_name_changed_callback( instance.path().top(), ConstReferenceCaller1( instance ) ); - - graph_type::iterator i = model->graph->find( PathConstReference( instance.path() ) ); - ASSERT_MESSAGE( i != model->graph->end(), "ERROR" ); - - graph_tree_model_row_deleted( model, i ); - - model->graph->erase( i ); -} - -#elif 1 - -class GraphTreeNode; -void graph_tree_model_row_changed( GraphTreeNode& node ); - -class GraphTreeNode -{ -public: - typedef std::pair key_type; -private: - struct Compare{ - bool operator()( const key_type& one, const key_type& other ) const { - const int n = string_compare( one.first.c_str(), other.first.c_str() ); - return n != 0? n < 0 : one.second < other.second; - } - }; - typedef std::map ChildNodes; - ChildNodes m_childnodes; - - struct Dummy{}; - std::list m_list; // dummy list for child index identification - std::list::const_iterator m_parentListIterator; // iterator from parent's list - bool m_searchFromEnd = false; //silly optimization -public: - Reference m_instance; - GraphTreeNode* m_parent; - - typedef ChildNodes::iterator iterator; - typedef ChildNodes::value_type value_type; - typedef ChildNodes::size_type size_type; - - GraphTreeNode( scene::Instance& instance ) : m_instance( instance ), m_parent( 0 ){ - m_instance.get().setChildSelectedChangedCallback( RowChangedCaller( *this ) ); - } - ~GraphTreeNode(){ - m_instance.get().setChildSelectedChangedCallback( Callback() ); - ASSERT_MESSAGE( empty(), "GraphTreeNode::~GraphTreeNode: memory leak" ); - } - GraphTreeNode( GraphTreeNode&& ) noexcept = delete; - - iterator begin(){ - return m_childnodes.begin(); - } - iterator end(){ - return m_childnodes.end(); - } - - size_type size() const { - return m_childnodes.size(); - } - bool empty() const { - return m_childnodes.empty(); - } -// may not be called on the root node! - int getIndex() const { - const int idx = m_parent->m_searchFromEnd? - m_parent->m_list.size() - std::distance( m_parentListIterator, m_parent->m_list.cend() ) : - std::distance( m_parent->m_list.cbegin(), m_parentListIterator ); - m_parent->m_searchFromEnd = idx * 2 > int( m_parent->size() ); - return idx; - } - - iterator insert( const value_type& value ){ - auto [ i, inserted ] = m_childnodes.insert( value ); - ASSERT_MESSAGE( inserted, "GraphTreeNode::insert: already added" ); - ( *i ).second->m_parent = this; - const auto pos = std::next( i ) == end()? m_list.end() : std::next( i )->second->m_parentListIterator; - i->second->m_parentListIterator = m_list.insert( pos, Dummy() ); - return i; - } - void erase( iterator i ){ - m_list.erase( i->second->m_parentListIterator ); - m_childnodes.erase( i ); - } - iterator find( const key_type& key ){ - return m_childnodes.find( key ); - } - - void rowChanged(){ - graph_tree_model_row_changed( *this ); - } - typedef MemberCaller RowChangedCaller; -}; - -struct GraphTreeModel -{ - GObject parent; - - GraphTreeNode* m_graph; -}; - -struct GraphTreeModelClass -{ - GObjectClass parent_class; -}; - -#define GRAPH_TREE_MODEL( p ) ( reinterpret_cast( p ) ) - -static GtkTreeModelFlags graph_tree_model_get_flags( GtkTreeModel* tree_model ){ - return GTK_TREE_MODEL_ITERS_PERSIST; -} - -static gint graph_tree_model_get_n_columns( GtkTreeModel* tree_model ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - //GraphTreeModel* graph_tree_model = (GraphTreeModel*) tree_model; - - return 2; -} - -static const gint c_stamp = 0xabcdef; - -inline GraphTreeNode::iterator graph_iterator_read_tree_iter( GtkTreeIter* iter ){ - ASSERT_MESSAGE( iter != 0, "tree model error" ); - ASSERT_MESSAGE( iter->user_data != 0, "tree model error" ); - ASSERT_MESSAGE( iter->stamp == c_stamp, "tree model error" ); - return *reinterpret_cast( &iter->user_data ); -} - -inline void graph_iterator_write_tree_iter( GraphTreeNode::iterator i, GtkTreeIter* iter ){ - ASSERT_MESSAGE( iter != 0, "tree model error" ); - iter->stamp = c_stamp; - *reinterpret_cast( &iter->user_data ) = i; - ASSERT_MESSAGE( iter->user_data != 0, "tree model error" ); -} - -static GType graph_tree_model_get_column_type( GtkTreeModel *tree_model, gint index ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - //GraphTreeModel *graph_tree_model = (GraphTreeModel *) tree_model; - - return G_TYPE_POINTER; -} - -static gboolean graph_tree_model_get_iter( GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreePath* path ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - gint* indices = gtk_tree_path_get_indices( path ); - gint depth = gtk_tree_path_get_depth( path ); - - g_return_val_if_fail( depth > 0, FALSE ); - - GraphTreeNode* graph = GRAPH_TREE_MODEL( tree_model )->m_graph; - - if ( graph->empty() ) { - return FALSE; - } - - GtkTreeIter tmp; - GtkTreeIter* parent = 0; - - for ( gint i = 0; i < depth; i++ ) - { - if ( !gtk_tree_model_iter_nth_child( tree_model, iter, parent, indices[i] ) ) { - return FALSE; - } - tmp = *iter; - parent = &tmp; - } - - return TRUE; -} - -static GtkTreePath* graph_tree_model_get_path( GtkTreeModel* tree_model, GtkTreeIter* iter ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - GraphTreeNode* graph = GRAPH_TREE_MODEL( tree_model )->m_graph; - - GtkTreePath* path = gtk_tree_path_new(); - - for ( GraphTreeNode* node = ( *graph_iterator_read_tree_iter( iter ) ).second; node != graph; node = node->m_parent ) - { - gtk_tree_path_prepend_index( path, gint( node->getIndex() ) ); - } - - return path; -} - - -static void graph_tree_model_get_value( GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - ASSERT_MESSAGE( column == 0 || column == 1, "tree model error" ); - - GraphTreeNode::iterator i = graph_iterator_read_tree_iter( iter ); - - g_value_init( value, G_TYPE_POINTER ); - - if ( column == 0 ) { - g_value_set_pointer( value, reinterpret_cast( ( *i ).first.second ) ); - } - else - { - g_value_set_pointer( value, reinterpret_cast( &( *i ).second->m_instance.get() ) ); - } -} - -static gboolean graph_tree_model_iter_next( GtkTreeModel *tree_model, GtkTreeIter *iter ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - GraphTreeNode::iterator i = graph_iterator_read_tree_iter( iter ); - GraphTreeNode& parent = *( *i ).second->m_parent; - - ASSERT_MESSAGE( i != parent.end(), "RUNTIME ERROR" ); - - if ( ++i == parent.end() ) { - return FALSE; - } - - graph_iterator_write_tree_iter( i, iter ); - - return TRUE; -} - -static gboolean graph_tree_model_iter_children( GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - GraphTreeNode& node = ( parent == 0 ) ? *GRAPH_TREE_MODEL( tree_model )->m_graph : *( *graph_iterator_read_tree_iter( parent ) ).second; - if ( !node.empty() ) { - graph_iterator_write_tree_iter( node.begin(), iter ); - return TRUE; - } - - return FALSE; -} - -static gboolean graph_tree_model_iter_has_child( GtkTreeModel *tree_model, GtkTreeIter *iter ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - GraphTreeNode& node = *( *graph_iterator_read_tree_iter( iter ) ).second; - return !node.empty(); -} - -static gint graph_tree_model_iter_n_children( GtkTreeModel *tree_model, GtkTreeIter *parent ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - GraphTreeNode& node = ( parent == 0 ) ? *GRAPH_TREE_MODEL( tree_model )->m_graph : *( *graph_iterator_read_tree_iter( parent ) ).second; - return static_cast( node.size() ); -} - -static gboolean graph_tree_model_iter_nth_child( GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - GraphTreeNode& node = ( parent == 0 ) ? *GRAPH_TREE_MODEL( tree_model )->m_graph : *( *graph_iterator_read_tree_iter( parent ) ).second; - if ( static_cast( n ) < node.size() ) { - graph_iterator_write_tree_iter( std::next( node.begin(), n ), iter ); - return TRUE; - } - - return FALSE; -} - -static gboolean graph_tree_model_iter_parent( GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child ){ - ASSERT_MESSAGE( tree_model != 0, "RUNTIME ERROR" ); - GraphTreeNode& node = *( *graph_iterator_read_tree_iter( child ) ).second; - if ( node.m_parent != GRAPH_TREE_MODEL( tree_model )->m_graph ) { - GraphTreeNode& parentParent = *node.m_parent->m_parent; - for ( GraphTreeNode::iterator i = parentParent.begin(); i != parentParent.end(); ++i ) - { - if ( ( *i ).second == node.m_parent ) { - graph_iterator_write_tree_iter( i, iter ); - return TRUE; - } - } - } - return FALSE; -} - -static GObjectClass *g_parent_class = 0; +#include "iselection.h" namespace { @@ -1013,424 +99,238 @@ namespace NullInstance g_null_instance; } -static void graph_tree_model_init( GraphTreeModel *graph_tree_model ){ - graph_tree_model->m_graph = new GraphTreeNode( g_null_instance ); -} -static void graph_tree_model_finalize( GObject* object ){ - GraphTreeModel* graph_tree_model = GRAPH_TREE_MODEL( object ); - - delete graph_tree_model->m_graph; - - /* must chain up */ - ( *g_parent_class->finalize )( object ); -} - -static void graph_tree_model_class_init( GraphTreeModelClass *class_ ){ - GObjectClass *object_class; - - g_parent_class = (GObjectClass*)g_type_class_peek_parent( class_ ); - object_class = (GObjectClass *) class_; - - object_class->finalize = graph_tree_model_finalize; -} - -static void graph_tree_model_tree_model_init( GtkTreeModelIface *iface ){ - iface->get_flags = graph_tree_model_get_flags; - iface->get_n_columns = graph_tree_model_get_n_columns; - iface->get_column_type = graph_tree_model_get_column_type; - iface->get_iter = graph_tree_model_get_iter; - iface->get_path = graph_tree_model_get_path; - iface->get_value = graph_tree_model_get_value; - iface->iter_next = graph_tree_model_iter_next; - iface->iter_children = graph_tree_model_iter_children; - iface->iter_has_child = graph_tree_model_iter_has_child; - iface->iter_n_children = graph_tree_model_iter_n_children; - iface->iter_nth_child = graph_tree_model_iter_nth_child; - iface->iter_parent = graph_tree_model_iter_parent; -} - -GType graph_tree_model_get_type(){ - static GType graph_tree_model_type = 0; - - if ( !graph_tree_model_type ) { - static const GTypeInfo graph_tree_model_info = - { - sizeof( GraphTreeModelClass ), - 0, /* base_init */ - 0, /* base_finalize */ - (GClassInitFunc) graph_tree_model_class_init, - 0, /* class_finalize */ - 0, /* class_data */ - sizeof( GraphTreeModel ), - 0, /* n_preallocs */ - (GInstanceInitFunc) graph_tree_model_init, - 0 - }; - - static const GInterfaceInfo tree_model_info = - { - (GInterfaceInitFunc) graph_tree_model_tree_model_init, - 0, - 0 - }; - - graph_tree_model_type = g_type_register_static( G_TYPE_OBJECT, "GraphTreeModel", - &graph_tree_model_info, (GTypeFlags)0 ); - - g_type_add_interface_static( graph_tree_model_type, - GTK_TYPE_TREE_MODEL, - &tree_model_info ); - } - - return graph_tree_model_type; -} - -GraphTreeModel* graph_tree_model_new(){ - GraphTreeModel* graph_tree_model = GRAPH_TREE_MODEL( g_object_new( graph_tree_model_get_type(), 0 ) ); - - return graph_tree_model; -} - -void graph_tree_model_delete( GraphTreeModel* model ){ - g_object_unref( G_OBJECT( model ) ); -} - -void graph_tree_model_row_changed( GraphTreeModel* model, GraphTreeNode::iterator i ){ - GtkTreeIter iter; - graph_iterator_write_tree_iter( i, &iter ); - - GtkTreePath* tree_path = graph_tree_model_get_path( GTK_TREE_MODEL( model ), &iter ); - - gtk_tree_model_row_changed( GTK_TREE_MODEL( model ), tree_path, &iter ); - - gtk_tree_path_free( tree_path ); -} - -void graph_tree_model_row_inserted( GraphTreeModel* model, GraphTreeNode::iterator i ){ - GtkTreeIter iter; - graph_iterator_write_tree_iter( i, &iter ); - - GtkTreePath* tree_path = graph_tree_model_get_path( GTK_TREE_MODEL( model ), &iter ); - - gtk_tree_model_row_inserted( GTK_TREE_MODEL( model ), tree_path, &iter ); - - gtk_tree_path_free( tree_path ); -} - -void graph_tree_model_row_deleted( GraphTreeModel* model, GraphTreeNode::iterator i ){ - GtkTreeIter iter; - graph_iterator_write_tree_iter( i, &iter ); - - GtkTreePath* tree_path = graph_tree_model_get_path( GTK_TREE_MODEL( model ), &iter ); - - gtk_tree_model_row_deleted( GTK_TREE_MODEL( model ), tree_path ); - - gtk_tree_path_free( tree_path ); -} - -void graph_tree_model_row_inserted( GraphTreeModel& model, GraphTreeNode::iterator i ){ - graph_tree_model_row_inserted( &model, i ); -} - -void graph_tree_model_row_deleted( GraphTreeModel& model, GraphTreeNode::iterator i ){ - graph_tree_model_row_deleted( &model, i ); -} - -const char* node_get_name( scene::Node& node ); - -const char* node_get_name_safe( scene::Node& node ){ - volatile intptr_t n = (intptr_t)&node; // see the comment on line 650 - if ( n == 0 ) { - return ""; - } - return node_get_name( node ); -} - -GraphTreeNode* graph_tree_model_find_parent( GraphTreeModel* model, const scene::Path& path ){ - GraphTreeNode* parent = model->m_graph; - for ( scene::Path::const_iterator i = path.begin(); i != path.end() - 1; ++i ) - { - GraphTreeNode::iterator child = parent->find( GraphTreeNode::key_type( node_get_name_safe( ( *i ).get() ), ( *i ).get_pointer() ) ); - ASSERT_MESSAGE( child != parent->end(), "ERROR" ); - parent = ( *child ).second; - } - return parent; -} - -void node_attach_name_changed_callback( scene::Node& node, const NameCallback& callback ){ - volatile intptr_t n = (intptr_t)&node; // see the comment on line 650 - if ( n != 0 ) { - Nameable* nameable = Node_getNameable( node ); - if ( nameable != 0 ) { - nameable->attach( callback ); - } - } -} -void node_detach_name_changed_callback( scene::Node& node, const NameCallback& callback ){ - volatile intptr_t n = (intptr_t)&node; // see the comment on line 650 - if ( n != 0 ) { - Nameable* nameable = Node_getNameable( node ); - if ( nameable != 0 ) { - nameable->detach( callback ); - } - } -} - -GraphTreeModel* scene_graph_get_tree_model(); // temp hack - -void graph_tree_node_foreach_pre( GraphTreeNode::iterator root, const Callback1& callback ){ - callback( root ); - for ( GraphTreeNode::iterator i = ( *root ).second->begin(); i != ( *root ).second->end(); ++i ) - { - graph_tree_node_foreach_pre( i, callback ); - } -} - -void graph_tree_node_foreach_post( GraphTreeNode::iterator root, const Callback1& callback ){ - for ( GraphTreeNode::iterator i = ( *root ).second->begin(); i != ( *root ).second->end(); ++i ) - { - graph_tree_node_foreach_post( i, callback ); - } - callback( root ); -} - -void graph_tree_model_row_changed( GraphTreeNode& node ){ - GraphTreeModel* model = scene_graph_get_tree_model(); - const scene::Instance& instance = node.m_instance.get(); - - GraphTreeNode::iterator i = node.m_parent->find( GraphTreeNode::key_type( node_get_name_safe( instance.path().top().get() ), instance.path().top().get_pointer() ) ); - - graph_tree_model_row_changed( model, i ); -} - -void graph_tree_model_set_name( const scene::Instance& instance, const char* name ){ - GraphTreeModel* model = scene_graph_get_tree_model(); - GraphTreeNode* parent = graph_tree_model_find_parent( model, instance.path() ); - - GraphTreeNode::iterator oldNode = parent->find( GraphTreeNode::key_type( node_get_name_safe( instance.path().top().get() ), instance.path().top().get_pointer() ) ); - graph_tree_node_foreach_post( oldNode, ReferenceCaller1( *model ) ); - GraphTreeNode* node( ( *oldNode ).second ); - parent->erase( oldNode ); - - GraphTreeNode::iterator newNode = parent->insert( GraphTreeNode::value_type( GraphTreeNode::key_type( name, &instance.path().top().get() ), node ) ); - graph_tree_node_foreach_pre( newNode, ReferenceCaller1( *model ) ); -} - -void graph_tree_model_insert( GraphTreeModel* model, const scene::Instance& instance ){ - GraphTreeNode* parent = graph_tree_model_find_parent( model, instance.path() ); - - GraphTreeNode::iterator i = parent->insert( GraphTreeNode::value_type( GraphTreeNode::key_type( node_get_name_safe( instance.path().top().get() ), instance.path().top().get_pointer() ), new GraphTreeNode( const_cast( instance ) ) ) ); - - graph_tree_model_row_inserted( model, i ); - - node_attach_name_changed_callback( instance.path().top(), ConstReferenceCaller1( instance ) ); -} - -void graph_tree_model_erase( GraphTreeModel* model, const scene::Instance& instance ){ - node_detach_name_changed_callback( instance.path().top(), ConstReferenceCaller1( instance ) ); - - GraphTreeNode* parent = graph_tree_model_find_parent( model, instance.path() ); - - GraphTreeNode::iterator i = parent->find( GraphTreeNode::key_type( node_get_name_safe( instance.path().top().get() ), instance.path().top().get_pointer() ) ); - - graph_tree_model_row_deleted( model, i ); - - GraphTreeNode* node( ( *i ).second ); - parent->erase( i ); - delete node; -} - - - -#endif - - - - -#if 0 -class TestGraphTreeModel +class GraphTreeNode { +private: + struct Compare{ + bool operator()( const GraphTreeNode *one, const GraphTreeNode *other ) const { + const int n = string_compare( one->m_name.c_str(), other->m_name.c_str() ); + return n != 0? n < 0 : one->m_node < other->m_node; + } + }; + typedef std::vector ChildNodes; + ChildNodes m_childnodes; public: - TestGraphTreeModel(){ - gtk_init( 0, 0 ); + Reference m_instance; + GraphTreeNode* m_parent; + CopiedString m_name; + scene::Node* m_node; - graph_type graph; + typedef ChildNodes::iterator iterator; - scene::Node* root = *(scene::Node*)0xa0000000; - scene::Node* node1 = (scene::Node*)0xa0000001; - scene::Node* node2 = (scene::Node*)0xa0000002; - scene::Node* node3 = (scene::Node*)0xa0000003; - scene::Node* node4 = (scene::Node*)0xa0000004; - scene::Instance* instance = (scene::Instance*)0xaaaaaaaa; + GraphTreeNode( scene::Instance& instance, const char *name, scene::Node* node ) : + m_instance( instance ), m_parent( 0 ), m_name( name ), m_node( node ){ + } + ~GraphTreeNode(){ + ASSERT_MESSAGE( empty(), "GraphTreeNode::~GraphTreeNode: memory leak" ); + } + GraphTreeNode( GraphTreeNode&& ) noexcept = delete; - scene::Path rootpath( root ); + iterator begin(){ + return m_childnodes.begin(); + } + iterator end(){ + return m_childnodes.end(); + } - graph.insert( graph_type::value_type( rootpath, instance ) ); + std::size_t size() const { + return m_childnodes.size(); + } + bool empty() const { + return m_childnodes.empty(); + } + // may not be called on the root node! + int getIndex() const { + return getIndex( m_parent->find( m_name.c_str(), m_node ) ); + } + // iterator in parent's children list! + int getIndex( iterator it ) const { + return std::distance( m_parent->begin(), it ); + } + GraphTreeNode *child( int row ) const { + if( row < 0 || size_t( row ) >= m_childnodes.size() ) + return nullptr; + return m_childnodes[row]; + } - rootpath.push( node1 ); - graph.insert( graph_type::value_type( rootpath, instance ) ); - rootpath.pop(); - - rootpath.push( node2 ); - graph.insert( graph_type::value_type( rootpath, instance ) ); - rootpath.push( node3 ); - graph.insert( graph_type::value_type( rootpath, instance ) ); - rootpath.pop(); - rootpath.push( node4 ); - graph.insert( graph_type::value_type( rootpath, instance ) ); - rootpath.pop(); - rootpath.pop(); - - GtkTreeModel* model = GTK_TREE_MODEL( graph_tree_model_new( &graph ) ); - - { - gint n_columns = gtk_tree_model_get_n_columns( model ); - ASSERT_MESSAGE( n_columns == 2, "test failed!" ); - } - - { - GType type = gtk_tree_model_get_column_type( model, 0 ); - ASSERT_MESSAGE( type == G_TYPE_POINTER, "test failed!" ); - } - - { - GType type = gtk_tree_model_get_column_type( model, 1 ); - ASSERT_MESSAGE( type == G_TYPE_POINTER, "test failed!" ); - } - - - { - GtkTreeIter iter; - gtk_tree_model_get_iter_first( model, &iter ); - - graph_type::iterator i = graph_iterator_read_tree_iter( &iter ); - ASSERT_MESSAGE( ( *i ).first.get().size() == 2 && ( *i ).first.get().top() == node1, "test failed!" ); - } - - { - GtkTreeIter iter; - gtk_tree_model_get_iter_first( model, &iter ); - - ASSERT_MESSAGE( !gtk_tree_model_iter_has_child( model, &iter ), "test failed!" ); - - ASSERT_MESSAGE( gtk_tree_model_iter_n_children( model, &iter ) == 0, "test failed!" ); - - gtk_tree_model_iter_next( model, &iter ); - - ASSERT_MESSAGE( gtk_tree_model_iter_has_child( model, &iter ), "test failed!" ); - - ASSERT_MESSAGE( gtk_tree_model_iter_n_children( model, &iter ) == 2, "test failed!" ); - - { - GtkTreeIter child; - gtk_tree_model_iter_nth_child( model, &child, &iter, 0 ); - - scene::Node* test; - gtk_tree_model_get_value( model, &child, 0, (GValue*)&test ); - ASSERT_MESSAGE( test == node3, "test failed!" ); - - { - GtkTreeIter parent; - gtk_tree_model_iter_parent( model, &parent, &child ); - - scene::Node* test; - gtk_tree_model_get_value( model, &parent, 0, (GValue*)&test ); - ASSERT_MESSAGE( test == node2, "test failed!" ); - } - } - - { - GtkTreeIter child; - gtk_tree_model_iter_nth_child( model, &child, &iter, 1 ); - - scene::Node* test; - gtk_tree_model_get_value( model, &child, 0, (GValue*)&test ); - ASSERT_MESSAGE( test == node4, "test failed!" ); - } - } - - { - GtkTreeIter iter; - std::size_t count = 0; - for ( gboolean good = gtk_tree_model_get_iter_first( model, &iter ); good; good = gtk_tree_model_iter_next( model, &iter ) ) - { - scene::Node* test; - gtk_tree_model_get_value( model, &iter, 0, (GValue*)&test ); - - ASSERT_MESSAGE( ( count == 0 && test == node1 ) || ( count == 1 && test == node2 ), "test failed!" ); - ++count; - } - - ASSERT_MESSAGE( count == 2, "test failed!" ); - - } - - { - GtkTreeIter iter; - gtk_tree_model_get_iter_first( model, &iter ); - - scene::Node* test; - gtk_tree_model_get_value( model, &iter, 0, (GValue*)&test ); - ASSERT_MESSAGE( test == node1, "test failed!" ); - } - - { - GtkTreeIter iter; - GtkTreePath* path = gtk_tree_path_new_from_string( "0" ); - gtk_tree_model_get_iter( model, &iter, path ); - gtk_tree_path_free( path ); - - graph_type::iterator i = graph_iterator_read_tree_iter( &iter ); - ASSERT_MESSAGE( ( *i ).first.get().size() == 2 && ( *i ).first.get().top() == node1, "test failed!" ); - } - - { - GtkTreeIter iter; - GtkTreePath* path = gtk_tree_path_new_from_string( "1" ); - gtk_tree_model_get_iter( model, &iter, path ); - gtk_tree_path_free( path ); - - graph_type::iterator i = graph_iterator_read_tree_iter( &iter ); - ASSERT_MESSAGE( ( *i ).first.get().size() == 2 && ( *i ).first.get().top() == node2, "test failed!" ); - } - - { - GtkTreeIter iter; - graph_type::iterator i = graph.begin(); - ++i; - graph_iterator_write_tree_iter( i, &iter ); - - GtkTreePath* path = gtk_tree_model_get_path( model, &iter ); - - gint depth = gtk_tree_path_get_depth( path ); - gint* indices = gtk_tree_path_get_indices( path ); - - ASSERT_MESSAGE( depth == 1 && indices[0] == 0, "test failed!" ); - - gtk_tree_path_free( path ); - } - - { - GtkTreeIter iter; - graph_type::iterator i = graph.begin(); - ++i; - ++i; - graph_iterator_write_tree_iter( i, &iter ); - - GtkTreePath* path = gtk_tree_model_get_path( model, &iter ); - - gint depth = gtk_tree_path_get_depth( path ); - gint* indices = gtk_tree_path_get_indices( path ); - - ASSERT_MESSAGE( depth == 1 && indices[0] == 1, "test failed!" ); - - gtk_tree_path_free( path ); - } + iterator insert( GraphTreeNode* value ){ + value->m_parent = this; + return m_childnodes.insert( std::lower_bound( begin(), end(), value, Compare() ), value ); +//. ASSERT_MESSAGE( inserted, "GraphTreeNode::insert: already added" ); + } + void erase( iterator i ){ + m_childnodes.erase( i ); + } + iterator find( const char *name, const scene::Node* node ){ + return std::lower_bound( begin(), end(), name, [node]( const GraphTreeNode *other, const char *name ){ + const int n = string_compare( other->m_name.c_str(), name ); + return n != 0? n < 0 : other->m_node < node; + } ); + } + // find index of future insertion + int lower_bound( const char *name, const scene::Node* node ){ + return std::distance( begin(), find( name, node ) ); } }; -TestGraphTreeModel g_TestGraphTreeModel; +class GraphTreeModel : public QAbstractItemModel +{ +public: + GraphTreeModel(){ + rootItem = new GraphTreeNode( g_null_instance, "", nullptr ); + } + ~GraphTreeModel(){ + delete rootItem; + } + QVariant data( const QModelIndex &index, int role ) const override { + if ( index.isValid() ){ + GraphTreeNode *item = getNode( index ); + if ( role == Qt::ItemDataRole::DisplayRole ) + return item->m_name.c_str(); + else if( role == c_ItemDataRole_Instance ) + return QVariant::fromValue( static_cast( item->m_instance.get_pointer() ) ); + else if( role == c_ItemDataRole_Node ) + return QVariant::fromValue( static_cast( item->m_node ) ); + else if( role == Qt::ItemDataRole::BackgroundRole ){ + const QColor color = item->m_instance.get().isSelected() + ? qApp->palette().color( QPalette::ColorRole::Highlight ).darker( 200 ) + : item->m_instance.get().childSelected() + ? qApp->palette().color( QPalette::ColorRole::Highlight ).darker( 300 ) + : qApp->palette().color( QPalette::ColorRole::Base ); + return QBrush( color ); + } + } + return QVariant(); + + } + Qt::ItemFlags flags( const QModelIndex &index ) const override { + if ( !index.isValid() ) + return Qt::NoItemFlags; + return QAbstractItemModel::flags( index ); + } + QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override { + return QVariant(); + } + GraphTreeNode* getNode( const QModelIndex &index ) const { + return static_cast( index.internalPointer() ); + } + std::pair findParents( const scene::Path& path ) const { + GraphTreeNode* parent = rootItem; + QModelIndex index; + for ( scene::Path::const_iterator i = path.begin(); i != path.end() - 1; ++i ) + { + GraphTreeNode::iterator child = parent->find( node_get_name_safe( ( *i ).get() ), ( *i ).get_pointer() ); + ASSERT_MESSAGE( child != parent->end(), "ERROR" ); + parent = *child; + index = this->index( ( *child )->getIndex( child ), 0, index ); + ASSERT_MESSAGE( index.isValid(), "index.isValid()" ); + } + return { parent, index }; + } + QModelIndex index( int row, int column, const QModelIndex &parent ) const override { + if ( !hasIndex( row, column, parent ) ) + return QModelIndex(); + + GraphTreeNode *parentItem = parent.isValid()? getNode( parent ) : rootItem; + GraphTreeNode *childItem = parentItem->child( row ); + if ( childItem ) + return createIndex( row, column, childItem ); + return QModelIndex(); + } + QModelIndex parent( const QModelIndex &index ) const override { + if ( !index.isValid() ) + return QModelIndex(); + + GraphTreeNode *childItem = getNode( index ); + GraphTreeNode *parentItem = childItem->m_parent; + + if ( parentItem == rootItem ) + return QModelIndex(); + + return createIndex( parentItem->getIndex(), 0, parentItem ); + } + int rowCount( const QModelIndex &parent ) const override { + if ( parent.column() > 0 ) + return 0; + + GraphTreeNode *parentItem = parent.isValid()? getNode( parent ) : rootItem; + return parentItem->size(); + } + int columnCount( const QModelIndex &parent = QModelIndex() ) const override { + return 1; + } + void insert( const scene::Instance& instance ) { + auto [parent, index] = findParents( instance.path() ); + + const int n = parent->lower_bound( node_get_name_safe( instance.path().top().get() ), instance.path().top().get_pointer() ); + + beginInsertRows( index, n, n ); + parent->insert( new GraphTreeNode( const_cast( instance ), node_get_name_safe( instance.path().top().get() ), instance.path().top().get_pointer() ) ); + endInsertRows(); + + node_attach_name_changed_callback( instance.path().top(), ConstReferenceCaller1( instance ) ); + } + void remove( const scene::Instance& instance ) { + node_detach_name_changed_callback( instance.path().top(), ConstReferenceCaller1( instance ) ); + + auto [parent, index] = findParents( instance.path() ); + + GraphTreeNode::iterator i = parent->find( node_get_name_safe( instance.path().top().get() ), instance.path().top().get_pointer() ); + + const int n = ( *i )->getIndex( i ); + + beginRemoveRows( index, n, n ); + GraphTreeNode* node( *i ); + parent->erase( i ); + delete node; + endRemoveRows(); + } + void rename( const scene::Instance& instance, const char* name ){ + auto [parent, index] = findParents( instance.path() ); + + GraphTreeNode::iterator i = parent->find( node_get_name_safe( instance.path().top().get() ), instance.path().top().get_pointer() ); + + const int n = ( *i )->getIndex( i ); + const int n2 = parent->lower_bound( name, instance.path().top().get_pointer() ); + + if( ( n2 - n ) == 0 || ( n2 - n ) == 1 ){ //rename + ( *i )->m_name = name; + dataChanged( this->index( n, 0, index ), this->index( n, 0, index ), { Qt::ItemDataRole::DisplayRole } ); + } + else{ // move + beginMoveRows( index, n, n, index, n2 ); + GraphTreeNode* node( *i ); + parent->erase( i ); + node->m_name = name; + parent->insert( node ); + endMoveRows(); + } + } +private: + GraphTreeNode *rootItem; +}; + +GraphTreeModel* graph_tree_model_new(){ + return new GraphTreeModel; +} + +void graph_tree_model_delete( GraphTreeModel* model ){ + delete model; +} + +void graph_tree_model_insert( GraphTreeModel* model, const scene::Instance& instance ){ + model->insert( instance ); +} + +void graph_tree_model_erase( GraphTreeModel* model, const scene::Instance& instance ){ + model->remove( instance ); +} + + +GraphTreeModel* scene_graph_get_tree_model(); // temp hack +void graph_tree_model_set_name( const scene::Instance& instance, const char* name ){ + scene_graph_get_tree_model()->rename( instance, name ); +} -#endif diff --git a/radiant/treemodel.h b/radiant/treemodel.h index 3f12bbcb..4b211c10 100644 --- a/radiant/treemodel.h +++ b/radiant/treemodel.h @@ -21,9 +21,7 @@ #pragma once -struct GraphTreeModel; - -GraphTreeModel* graph_tree_model_new(); +class GraphTreeModel* graph_tree_model_new(); void graph_tree_model_delete( GraphTreeModel* model ); namespace scene @@ -32,3 +30,10 @@ class Instance; } void graph_tree_model_insert( GraphTreeModel* model, const scene::Instance& instance ); void graph_tree_model_erase( GraphTreeModel* model, const scene::Instance& instance ); + + +#include +constexpr int c_ItemDataRole_Instance = Qt::ItemDataRole::UserRole + 1; +constexpr int c_ItemDataRole_Node = Qt::ItemDataRole::UserRole + 2; + + diff --git a/radiant/undo.cpp b/radiant/undo.cpp index b671628a..e39b0cf4 100644 --- a/radiant/undo.cpp +++ b/radiant/undo.cpp @@ -22,7 +22,6 @@ #include "undo.h" #include "debugging/debugging.h" -#include "warnings.h" #include "iundo.h" #include "preferencesystem.h" @@ -398,7 +397,7 @@ typedef ConstReferenceCaller1 -#include -bool open_url( const char* url ){ - return ShellExecute( (HWND)GDK_WINDOW_HWND( gtk_widget_get_window( GTK_WIDGET( MainFrame_getWindow() ) ) ), "open", url, 0, 0, SW_SHOW ) > (HINSTANCE)32; -} -#endif - -#if defined( __linux__ ) || defined( __FreeBSD__ ) -#include -bool open_url( const char* url ){ - char command[2 * PATH_MAX]; - snprintf( command, sizeof( command ), - "xdg-open \"%s\" &", url ); - return system( command ) == 0; -} -#endif - -#ifdef __APPLE__ -#include -bool open_url( const char* url ){ - char command[2 * PATH_MAX]; - snprintf( command, sizeof( command ), "open \"%s\" &", url ); - return system( command ) == 0; -} -#endif +#include +#include void OpenURL( const char *url ){ // let's put a little comment globalOutputStream() << "OpenURL: " << url << "\n"; - if ( !open_url( url ) ) { - gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), "Failed to launch browser!" ); + // QUrl::fromUserInput appears to work well for urls and local paths with spaces + // alternatively can prepend file:/// to the latter and use default QUrl contructor + if ( !QDesktopServices::openUrl( QUrl::fromUserInput( url ) ) ) { + qt_MessageBox( MainFrame_getWindow(), "Failed to launch browser!" ); } } diff --git a/radiant/view.h b/radiant/view.h index 79e6c35b..fdaa009a 100644 --- a/radiant/view.h +++ b/radiant/view.h @@ -186,7 +186,7 @@ public: return m_fill; } const Vector3& getViewer() const { - return vector4_to_vector3( m_viewer ); + return m_viewer.vec3(); } const Vector3& getViewDir() const { return m_viewdir; diff --git a/radiant/watchbsp.cpp b/radiant/watchbsp.cpp index 6c247c1e..80757a60 100644 --- a/radiant/watchbsp.cpp +++ b/radiant/watchbsp.cpp @@ -36,7 +36,7 @@ #include "watchbsp.h" #include -#include +#include #include "commandlib.h" #include "convert.h" @@ -51,6 +51,7 @@ #include "feedback.h" #include "mainframe.h" #include "sockets.h" +#include "timer.h" void message_flush( message_info_t* self ){ Sys_Print( self->msg_level, self->m_buffer, self->m_length ); @@ -76,7 +77,6 @@ void message_print( message_info_t* self, const char* characters, std::size_t le } -#include #include "xmlstuff.h" class CWatchBSP @@ -99,8 +99,9 @@ private: netmessage_t msg; GPtrArray *m_pCmd; // used to timeout EBeginStep - GTimer *m_pTimer; + Timer m_timeout_timer; std::size_t m_iCurrentStep; + QTimer m_monitoring_timer; // name of the map so we can run the engine char *m_sBSPName; // buffer we use in push mode to receive data directly from the network @@ -122,16 +123,15 @@ public: m_pListenSocket = NULL; m_pInSocket = NULL; m_eState = EIdle; - m_pTimer = g_timer_new(); m_sBSPName = NULL; m_xmlInputBuffer = NULL; m_bNeedCtxtInit = true; + m_monitoring_timer.callOnTimeout( [this](){ RoutineProcessing(); } ); + m_monitoring_timer.setInterval( 25 ); } virtual ~CWatchBSP(){ EndMonitoringLoop(); Net_Shutdown(); - - g_timer_destroy( m_pTimer ); } bool HasBSPPlugin() const @@ -176,9 +176,9 @@ const int g_WatchBSP_Timeout = 5; void Build_constructPreferences( PreferencesPage& page ){ - GtkWidget* monitorbsp = page.appendCheckBox( "", "Enable Build Process Monitoring", g_WatchBSP_Enabled ); - GtkWidget* leakstop = page.appendCheckBox( "", "Stop Compilation on Leak", g_WatchBSP_LeakStop ); - GtkWidget* runengine = page.appendCheckBox( "", "Run Engine After Compile", g_WatchBSP_RunQuake ); + QCheckBox* monitorbsp = page.appendCheckBox( "", "Enable Build Process Monitoring", g_WatchBSP_Enabled ); + QCheckBox* leakstop = page.appendCheckBox( "", "Stop Compilation on Leak", g_WatchBSP_LeakStop ); + QCheckBox* runengine = page.appendCheckBox( "", "Run Engine After Compile", g_WatchBSP_RunQuake ); Widget_connectToggleDependency( leakstop, monitorbsp ); Widget_connectToggleDependency( runengine, monitorbsp ); page.appendCheckBox( "", "Dump non Monitored Builds Log", g_WatchBSP0_DumpLog ); @@ -470,13 +470,6 @@ static xmlSAXHandler saxParser = { // ------------------------------------------------------------------------------------------------ - -guint s_routine_id = 0; -static gboolean watchbsp_routine( gpointer data ){ - reinterpret_cast( data )->RoutineProcessing(); - return TRUE; -} - void CWatchBSP::Reset(){ if ( m_pInSocket ) { Net_Disconnect( m_pInSocket ); @@ -491,10 +484,7 @@ void CWatchBSP::Reset(){ m_xmlInputBuffer = NULL; } m_eState = EIdle; - if ( s_routine_id != 0 ) { - g_source_remove( s_routine_id ); - s_routine_id = 0; - } + m_monitoring_timer.stop(); } bool CWatchBSP::SetupListening(){ @@ -519,12 +509,11 @@ void CWatchBSP::DoEBeginStep(){ if ( SetupListening() == false ) { const char* msg = "Failed to get a listening socket on port 39000.\nTry running with Build monitoring disabled if you can't fix this.\n"; globalOutputStream() << msg; - gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), msg, "Build monitoring", eMB_OK, eMB_ICONERROR ); + qt_MessageBox( MainFrame_getWindow(), msg, "Build monitoring", EMessageBoxType::Error ); return; } // set the timer for timeouts and step cancellation - g_timer_reset( m_pTimer ); - g_timer_start( m_pTimer ); + m_timeout_timer.start(); if ( !m_bBSPPlugin ) { globalOutputStream() << "=== running build command ===\n" @@ -536,7 +525,7 @@ void CWatchBSP::DoEBeginStep(){ msg << reinterpret_cast( g_ptr_array_index( m_pCmd, m_iCurrentStep ) ); msg << "\nCheck that the file exists and that you don't run out of system resources.\n"; globalOutputStream() << msg.c_str(); - gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), msg.c_str(), "Build monitoring", eMB_OK, eMB_ICONERROR ); + qt_MessageBox( MainFrame_getWindow(), msg.c_str(), "Build monitoring", EMessageBoxType::Error ); return; } // re-initialise the debug window @@ -545,7 +534,7 @@ void CWatchBSP::DoEBeginStep(){ } } m_eState = EBeginStep; - s_routine_id = g_timeout_add( 25, watchbsp_routine, this ); + m_monitoring_timer.start(); } @@ -615,8 +604,10 @@ void CWatchBSP::RoutineProcessing(){ { case EBeginStep: // timeout: if we don't get an incoming connection fast enough, go back to idle - if ( g_timer_elapsed( m_pTimer, NULL ) > g_WatchBSP_Timeout ) { - gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), "The connection timed out, assuming the build process failed\nMake sure you are using a networked version of Q3Map?\nOtherwise you need to disable BSP Monitoring in prefs.", "BSP process monitoring", eMB_OK ); + if ( m_timeout_timer.elapsed_sec() > g_WatchBSP_Timeout ) { + qt_MessageBox( MainFrame_getWindow(), "The connection timed out, assuming the build process failed\n" + "Make sure you are using a networked version of Q3Map?\n" + "Otherwise you need to disable BSP Monitoring in prefs.", "BSP process monitoring" ); EndMonitoringLoop(); #if 0 if ( m_bBSPPlugin ) { @@ -742,7 +733,7 @@ void CWatchBSP::RoutineProcessing(){ StringOutputStream msg; msg << "Failed to execute the following command: " << cmd.c_str() << cmdline.c_str(); globalOutputStream() << msg.c_str(); - gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), msg.c_str(), "Build monitoring", eMB_OK, eMB_ICONERROR ); + qt_MessageBox( MainFrame_getWindow(), msg.c_str(), "Build monitoring", EMessageBoxType::Error ); } } EndMonitoringLoop(); @@ -770,8 +761,8 @@ void CWatchBSP::DoMonitoringLoop( GPtrArray *pCmd, const char *sBSPName ){ if ( m_eState != EIdle ) { globalWarningStream() << "WatchBSP got a monitoring request while not idling...\n"; // prompt the user, should we cancel the current process and go ahead? -// if ( gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), "I am already monitoring a Build process.\nDo you want me to override and start a new compilation?", -// "Build process monitoring", eMB_YESNO ) == eIDYES ) { +// if ( qt_MessageBox( MainFrame_getWindow(), "I am already monitoring a Build process.\nDo you want me to override and start a new compilation?", +// "Build process monitoring", EMessageBoxType::Question ) == eIDYES ) { // disconnect and set EIdle state Reset(); // } diff --git a/radiant/winding.h b/radiant/winding.h index de37cc47..32a35daf 100644 --- a/radiant/winding.h +++ b/radiant/winding.h @@ -272,6 +272,6 @@ inline void Winding_printConnectivity( Winding& winding ){ for ( Winding::iterator i = winding.begin(); i != winding.end(); ++i ) { std::size_t vertexIndex = std::distance( winding.begin(), i ); - globalOutputStream() << "vertex: " << Unsigned( vertexIndex ) << " adjacent: " << Unsigned( ( *i ).adjacent ) << "\n"; + globalOutputStream() << "vertex: " << vertexIndex << " adjacent: " << ( *i ).adjacent << "\n"; } } diff --git a/radiant/windowobservers.cpp b/radiant/windowobservers.cpp index 8738bf3a..5a51299c 100644 --- a/radiant/windowobservers.cpp +++ b/radiant/windowobservers.cpp @@ -22,77 +22,81 @@ #include "windowobservers.h" #include -#include #include "generic/bitfield.h" +#include +#include +#include + namespace { ModifierFlags g_modifier_state = c_modifierNone; } typedef std::vector WindowObservers; +WindowObservers g_window_observers; inline void WindowObservers_OnModifierDown( WindowObservers& observers, ModifierFlags type ){ g_modifier_state = bitfield_enable( g_modifier_state, type ); - for ( WindowObservers::iterator i = observers.begin(); i != observers.end(); ++i ) + for ( auto observer : observers ) { - ( *i )->onModifierDown( type ); + observer->onModifierDown( type ); } } inline void WindowObservers_OnModifierUp( WindowObservers& observers, ModifierFlags type ){ g_modifier_state = bitfield_disable( g_modifier_state, type ); - for ( WindowObservers::iterator i = observers.begin(); i != observers.end(); ++i ) + for ( auto observer : observers ) { - ( *i )->onModifierUp( type ); + observer->onModifierUp( type ); } } -#include -gboolean selection_modifier_key_press( GtkWidget* widget, GdkEventKey* event, WindowObservers& observers ){ - switch ( event->keyval ) - { - case GDK_KEY_Alt_L: - case GDK_KEY_Alt_R: - //globalOutputStream() << "Alt PRESSED\n"; - WindowObservers_OnModifierDown( observers, c_modifierAlt ); - break; - case GDK_KEY_Shift_L: - case GDK_KEY_Shift_R: - //globalOutputStream() << "Shift PRESSED\n"; - WindowObservers_OnModifierDown( observers, c_modifierShift ); - break; - case GDK_KEY_Control_L: - case GDK_KEY_Control_R: - //globalOutputStream() << "Control PRESSED\n"; - WindowObservers_OnModifierDown( observers, c_modifierControl ); - break; +class : public QObject +{ +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::KeyPress ) { + QKeyEvent *keyEvent = static_cast( event ); + switch ( keyEvent->key() ) + { + case Qt::Key_Alt: + //globalOutputStream() << "Alt PRESSED\n"; + WindowObservers_OnModifierDown( g_window_observers, c_modifierAlt ); + break; + case Qt::Key_Shift: + //globalOutputStream() << "Shift PRESSED\n"; + WindowObservers_OnModifierDown( g_window_observers, c_modifierShift ); + break; + case Qt::Key_Control: + //globalOutputStream() << "Control PRESSED\n"; + WindowObservers_OnModifierDown( g_window_observers, c_modifierControl ); + break; + } + } + else if( event->type() == QEvent::KeyRelease ) { + QKeyEvent *keyEvent = static_cast( event ); + switch ( keyEvent->key() ) + { + case Qt::Key_Alt: + //globalOutputStream() << "Alt RELEASED\n"; + WindowObservers_OnModifierUp( g_window_observers, c_modifierAlt ); + break; + case Qt::Key_Shift: + //globalOutputStream() << "Shift RELEASED\n"; + WindowObservers_OnModifierUp( g_window_observers, c_modifierShift ); + break; + case Qt::Key_Control: + //globalOutputStream() << "Control RELEASED\n"; + WindowObservers_OnModifierUp( g_window_observers, c_modifierControl ); + break; + } + } + return QObject::eventFilter( obj, event ); // standard event processing } - return FALSE; -} - -gboolean selection_modifier_key_release( GtkWidget* widget, GdkEventKey* event, WindowObservers& observers ){ - switch ( event->keyval ) - { - case GDK_KEY_Alt_L: - case GDK_KEY_Alt_R: - //globalOutputStream() << "Alt RELEASED\n"; - WindowObservers_OnModifierUp( observers, c_modifierAlt ); - break; - case GDK_KEY_Shift_L: - case GDK_KEY_Shift_R: - //globalOutputStream() << "Shift RELEASED\n"; - WindowObservers_OnModifierUp( observers, c_modifierShift ); - break; - case GDK_KEY_Control_L: - case GDK_KEY_Control_R: - //globalOutputStream() << "Control RELEASED\n"; - WindowObservers_OnModifierUp( observers, c_modifierControl ); - break; - } - return FALSE; } +g_keyboard_event_filter; void WindowObservers_UpdateModifier( WindowObservers& observers, ModifierFlags modifiers, ModifierFlags modifier ){ if ( !bitfield_enabled( g_modifier_state, modifier ) && bitfield_enabled( modifiers, modifier ) ) { @@ -109,43 +113,30 @@ void WindowObservers_UpdateModifiers( WindowObservers& observers, ModifierFlags WindowObservers_UpdateModifier( observers, modifiers, c_modifierControl ); } -gboolean modifiers_button_press( GtkWidget* widget, GdkEventButton* event, WindowObservers* observers ){ - if ( event->type == GDK_BUTTON_PRESS ) { - WindowObservers_UpdateModifiers( *observers, modifiers_for_state( event->state ) ); + +class : public QObject +{ +protected: + bool eventFilter( QObject *obj, QEvent *event ) override { + if( event->type() == QEvent::MouseButtonPress + || event->type() == QEvent::MouseMove + || event->type() == QEvent::MouseButtonRelease ) { + QMouseEvent *mouseEvent = static_cast( event ); + WindowObservers_UpdateModifiers( g_window_observers, modifiers_for_state( mouseEvent->modifiers() ) ); + } + return QObject::eventFilter( obj, event ); // standard event processing } - return FALSE; -} - -gboolean modifiers_button_release( GtkWidget* widget, GdkEventButton* event, WindowObservers* observers ){ - if ( event->type == GDK_BUTTON_RELEASE ) { - WindowObservers_UpdateModifiers( *observers, modifiers_for_state( event->state ) ); - } - return FALSE; -} - -gboolean modifiers_motion( GtkWidget *widget, GdkEventMotion *event, WindowObservers* observers ){ - WindowObservers_UpdateModifiers( *observers, modifiers_for_state( event->state ) ); - return FALSE; -} - - -WindowObservers g_window_observers; - -void GlobalWindowObservers_updateModifiers( ModifierFlags modifiers ){ - WindowObservers_UpdateModifiers( g_window_observers, modifiers ); } +g_mouse_event_filter; void GlobalWindowObservers_add( WindowObserver* observer ){ g_window_observers.push_back( observer ); } -void GlobalWindowObservers_connectTopLevel( GtkWindow* window ){ - g_signal_connect( G_OBJECT( window ), "key_press_event", G_CALLBACK( selection_modifier_key_press ), &g_window_observers ); - g_signal_connect( G_OBJECT( window ), "key_release_event", G_CALLBACK( selection_modifier_key_release ), &g_window_observers ); +void GlobalWindowObservers_connectTopLevel( QWidget* window ){ + window->installEventFilter( &g_keyboard_event_filter ); } -void GlobalWindowObservers_connectWidget( GtkWidget* widget ){ - g_signal_connect( G_OBJECT( widget ), "button_press_event", G_CALLBACK( modifiers_button_press ), &g_window_observers ); - g_signal_connect( G_OBJECT( widget ), "button_release_event", G_CALLBACK( modifiers_button_release ), &g_window_observers ); - g_signal_connect( G_OBJECT( widget ), "motion_notify_event", G_CALLBACK( modifiers_motion ), &g_window_observers ); +void GlobalWindowObservers_connectWidget( QWidget* widget ){ + widget->installEventFilter( &g_mouse_event_filter ); } diff --git a/radiant/windowobservers.h b/radiant/windowobservers.h index 5991e28e..4dd8a700 100644 --- a/radiant/windowobservers.h +++ b/radiant/windowobservers.h @@ -23,39 +23,35 @@ #include "windowobserver.h" -#include +#include -#include "math/vector.h" +void GlobalWindowObservers_add( class WindowObserver* observer ); +void GlobalWindowObservers_connectWidget( class QWidget* widget ); +void GlobalWindowObservers_connectTopLevel( class QWidget* window ); -class WindowObserver; -void GlobalWindowObservers_add( WindowObserver* observer ); -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkWindow GtkWindow; -void GlobalWindowObservers_connectWidget( GtkWidget* widget ); -void GlobalWindowObservers_connectTopLevel( GtkWindow* window ); - -inline ButtonIdentifier button_for_button( unsigned int button ){ +inline ButtonIdentifier button_for_button( Qt::MouseButton button ){ switch ( button ) { - case 1: + case Qt::MouseButton::LeftButton: return c_buttonLeft; - case 2: + case Qt::MouseButton::MiddleButton: return c_buttonMiddle; - case 3: + case Qt::MouseButton::RightButton: return c_buttonRight; + default: + return c_buttonInvalid; } - return c_buttonInvalid; } -inline ModifierFlags modifiers_for_state( unsigned int state ){ +inline ModifierFlags modifiers_for_state( Qt::KeyboardModifiers state ){ ModifierFlags modifiers = c_modifierNone; - if ( state & GDK_SHIFT_MASK ) { + if ( state & Qt::KeyboardModifier::ShiftModifier ) { modifiers |= c_modifierShift; } - if ( state & GDK_CONTROL_MASK ) { + if ( state & Qt::KeyboardModifier::ControlModifier ) { modifiers |= c_modifierControl; } - if ( state & GDK_MOD1_MASK ) { + if ( state & Qt::KeyboardModifier::AltModifier ) { modifiers |= c_modifierAlt; } return modifiers; diff --git a/radiant/xywindow.cpp b/radiant/xywindow.cpp index 6fe11241..42a9275b 100644 --- a/radiant/xywindow.cpp +++ b/radiant/xywindow.cpp @@ -39,7 +39,9 @@ #include "image.h" #include "gtkutil/messagebox.h" -#include +#include +#include +#include #include "generic/callback.h" #include "string/string.h" @@ -51,10 +53,10 @@ #include "moduleobserver.h" #include "gtkutil/menu.h" -#include "gtkutil/container.h" #include "gtkutil/widget.h" #include "gtkutil/glwidget.h" #include "gtkutil/filechooser.h" +#include "gtkutil/fbo.h" #include "gtkmisc.h" #include "select.h" #include "brushmanip.h" @@ -76,45 +78,25 @@ bool g_bCamEntityMenu = false; struct xywindow_globals_private_t { - bool d_showgrid; + bool d_showgrid = true; // these are in the View > Show menu with Show coordinates - bool show_names; - bool show_coordinates; - bool show_angles; - bool show_outline; - bool show_axis; + bool show_names = false; + bool show_coordinates = false; + bool show_angles = true; + bool show_outline = true; + bool show_axis = true; - bool show_workzone; + bool show_workzone = false; - bool show_blocks; + bool show_blocks = false; - bool m_bChaseMouse; - bool m_bShowSize; + bool m_bChaseMouse = true; + bool m_bShowSize = true; - int m_MSAA; - - bool m_bZoomToPointer; - - xywindow_globals_private_t() : - d_showgrid( true ), - - show_names( false ), - show_coordinates( false ), - show_angles( true ), - show_outline( true ), - show_axis( true ), - - show_workzone( false ), - - show_blocks( false ), - - m_bChaseMouse( true ), - m_bShowSize( true ), - m_MSAA( 8 ), - m_bZoomToPointer( true ){ - } + int m_MSAA = 8; + bool m_bZoomToPointer = true; }; xywindow_globals_t g_xywindow_globals; @@ -182,55 +164,56 @@ inline unsigned int buttons_for_button_and_modifiers( ButtonIdentifier button, M return buttons; } -inline unsigned int buttons_for_event_button( GdkEventButton* event ){ +inline unsigned int buttons_for_event_button( QMouseEvent* event ){ unsigned int flags = 0; - switch ( event->button ) + switch ( event->button() ) { - case 1: flags |= RAD_LBUTTON; break; - case 2: flags |= RAD_MBUTTON; break; - case 3: flags |= RAD_RBUTTON; break; + case Qt::MouseButton::LeftButton: flags |= RAD_LBUTTON; break; + case Qt::MouseButton::MiddleButton: flags |= RAD_MBUTTON; break; + case Qt::MouseButton::RightButton: flags |= RAD_RBUTTON; break; + default : break; } - if ( ( event->state & GDK_CONTROL_MASK ) != 0 ) { + if ( event->modifiers() & Qt::KeyboardModifier::ControlModifier ) { flags |= RAD_CONTROL; } - if ( ( event->state & GDK_SHIFT_MASK ) != 0 ) { + if ( event->modifiers() & Qt::KeyboardModifier::ShiftModifier ) { flags |= RAD_SHIFT; } - if ( ( event->state & GDK_MOD1_MASK ) != 0 ) { + if ( event->modifiers() & Qt::KeyboardModifier::AltModifier ) { flags |= RAD_ALT; } return flags; } -inline unsigned int buttons_for_state( guint state ){ +inline unsigned int buttons_for_state( const QMouseEvent& event ){ unsigned int flags = 0; - if ( ( state & GDK_BUTTON1_MASK ) != 0 ) { + if ( event.buttons() & Qt::MouseButton::LeftButton ) { flags |= RAD_LBUTTON; } - if ( ( state & GDK_BUTTON2_MASK ) != 0 ) { + if ( event.buttons() & Qt::MouseButton::MiddleButton ) { flags |= RAD_MBUTTON; } - if ( ( state & GDK_BUTTON3_MASK ) != 0 ) { + if ( event.buttons() & Qt::MouseButton::RightButton ) { flags |= RAD_RBUTTON; } - if ( ( state & GDK_CONTROL_MASK ) != 0 ) { + if ( event.modifiers() & Qt::KeyboardModifier::ControlModifier ) { flags |= RAD_CONTROL; } - if ( ( state & GDK_SHIFT_MASK ) != 0 ) { + if ( event.modifiers() & Qt::KeyboardModifier::ShiftModifier ) { flags |= RAD_SHIFT; } - if ( ( state & GDK_MOD1_MASK ) != 0 ) { + if ( event.modifiers() & Qt::KeyboardModifier::AltModifier ) { flags |= RAD_ALT; } @@ -303,112 +286,22 @@ VIEWTYPE GlobalXYWnd_getCurrentViewType(){ bool g_bCrossHairs = false; -GtkMenu* XYWnd::m_mnuDrop = 0; - -// this is disabled, and broken -// http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=394 -#if 0 -void WXY_Print(){ - long width, height; - width = g_pParentWnd->ActiveXY()->Width(); - height = g_pParentWnd->ActiveXY()->Height(); - unsigned char* img; - const char* filename; - - filename = file_dialog( GTK_WIDGET( MainFrame_getWindow() ), FALSE, "Save Image", 0, FILTER_BMP ); - if ( !filename ) { - return; - } - - g_pParentWnd->ActiveXY()->MakeCurrent(); - img = (unsigned char*)malloc( width * height * 3 ); - glReadPixels( 0,0,width,height,GL_RGB,GL_UNSIGNED_BYTE,img ); - - FILE *fp; - fp = fopen( filename, "wb" ); - if ( fp ) { - unsigned short bits; - unsigned long cmap, bfSize; - - bits = 24; - cmap = 0; - bfSize = 54 + width * height * 3; - - long byteswritten = 0; - long pixoff = 54 + cmap * 4; - short res = 0; - char m1 = 'B', m2 = 'M'; - fwrite( &m1, 1, 1, fp ); byteswritten++; // B - fwrite( &m2, 1, 1, fp ); byteswritten++; // M - fwrite( &bfSize, 4, 1, fp ); byteswritten += 4; // bfSize - fwrite( &res, 2, 1, fp ); byteswritten += 2; // bfReserved1 - fwrite( &res, 2, 1, fp ); byteswritten += 2; // bfReserved2 - fwrite( &pixoff, 4, 1, fp ); byteswritten += 4; // bfOffBits - - unsigned long biSize = 40, compress = 0, size = 0; - long pixels = 0; - unsigned short planes = 1; - fwrite( &biSize, 4, 1, fp ); byteswritten += 4; // biSize - fwrite( &width, 4, 1, fp ); byteswritten += 4; // biWidth - fwrite( &height, 4, 1, fp ); byteswritten += 4; // biHeight - fwrite( &planes, 2, 1, fp ); byteswritten += 2; // biPlanes - fwrite( &bits, 2, 1, fp ); byteswritten += 2; // biBitCount - fwrite( &compress, 4, 1, fp ); byteswritten += 4; // biCompression - fwrite( &size, 4, 1, fp ); byteswritten += 4; // biSizeImage - fwrite( &pixels, 4, 1, fp ); byteswritten += 4; // biXPelsPerMeter - fwrite( &pixels, 4, 1, fp ); byteswritten += 4; // biYPelsPerMeter - fwrite( &cmap, 4, 1, fp ); byteswritten += 4; // biClrUsed - fwrite( &cmap, 4, 1, fp ); byteswritten += 4; // biClrImportant - - unsigned long widthDW = ( ( ( width * 24 ) + 31 ) / 32 * 4 ); - long row, row_size = width * 3; - for ( row = 0; row < height; row++ ) - { - unsigned char* buf = img + row * row_size; - - // write a row - int col; - for ( col = 0; col < row_size; col += 3 ) - { - putc( buf[col + 2], fp ); - putc( buf[col + 1], fp ); - putc( buf[col], fp ); - } - byteswritten += row_size; - - unsigned long count; - for ( count = row_size; count < widthDW; count++ ) - { - putc( 0, fp ); // dummy - byteswritten++; - } - } - - fclose( fp ); - } - - free( img ); -} -#endif +QMenu* XYWnd::m_mnuDrop = 0; #include "timer.h" - -Timer g_chasemouse_timer; +static Timer g_chasemouse_timer; +static QTimer g_chasemouse_caller; void XYWnd::ChaseMouse(){ const float multiplier = g_chasemouse_timer.elapsed_msec() / 10.0f; - Scroll( float_to_integer( multiplier * m_chasemouse_delta_x ), float_to_integer( multiplier * -m_chasemouse_delta_y ) ); + if( multiplier != 0 ){ // a lot of zeros happen = torn, slow, inconsistent motion 🤔 + g_chasemouse_timer.start(); + Scroll( float_to_integer( multiplier * m_chasemouse_delta_x ), float_to_integer( multiplier * -m_chasemouse_delta_y ) ); + //globalOutputStream() << "chasemouse: multiplier=" << multiplier << " x=" << m_chasemouse_delta_x << " y=" << m_chasemouse_delta_y << '\n'; - //globalOutputStream() << "chasemouse: multiplier=" << multiplier << " x=" << m_chasemouse_delta_x << " y=" << m_chasemouse_delta_y << '\n'; - - XY_MouseMoved( m_chasemouse_current_x, m_chasemouse_current_y, getButtonState() ); - g_chasemouse_timer.start(); -} - -gboolean xywnd_chasemouse( gpointer data ){ - reinterpret_cast( data )->ChaseMouse(); - return TRUE; + XY_MouseMoved( m_chasemouse_current_x, m_chasemouse_current_y, getButtonState() ); + } } bool XYWnd::chaseMouseMotion( const int x, const int y ){ @@ -436,29 +329,24 @@ bool XYWnd::chaseMouseMotion( const int x, const int y ){ //globalOutputStream() << "chasemouse motion: x=" << x << " y=" << y << "... "; m_chasemouse_current_x = x; m_chasemouse_current_y = y; - if ( m_chasemouse_handler == 0 ) { + if ( !g_chasemouse_caller.isActive() ) { //globalOutputStream() << "chasemouse timer start... "; g_chasemouse_timer.start(); - m_chasemouse_handler = g_idle_add( xywnd_chasemouse, this ); + g_chasemouse_caller.callOnTimeout( [this](){ ChaseMouse(); } ); + g_chasemouse_caller.start( 4 ); // with 0 consumes entire thread by spamming calls 🤷‍♀️ } return true; } else { - if ( m_chasemouse_handler != 0 ) { - //globalOutputStream() << "chasemouse cancel\n"; - g_source_remove( m_chasemouse_handler ); - m_chasemouse_handler = 0; - } + // if( g_chasemouse_caller.isActive() ) globalOutputStream() << "chasemouse cancel\n"; + g_chasemouse_caller.stop(); } } else { - if ( m_chasemouse_handler != 0 ) { - //globalOutputStream() << "chasemouse cancel\n"; - g_source_remove( m_chasemouse_handler ); - m_chasemouse_handler = 0; - } + // if( g_chasemouse_caller.isActive() ) globalOutputStream() << "chasemouse cancel\n"; + g_chasemouse_caller.stop(); } return false; } @@ -467,234 +355,200 @@ bool XYWnd::chaseMouseMotion( const int x, const int y ){ // XYWnd class Shader* XYWnd::m_state_selected = 0; -//! todo get rid of this completely; is needed for smooth navigation in camera (swapbuffers in overlay update for camera icon takes odd time in certain environments) -#if (defined _M_IX86 || defined __i386__) -#define OVERLAY_GL_FRONT_DRAW_HACK -#endif -bool XYWnd::overlayStart(){ - if ( gtk_widget_get_visible( m_gl_widget ) ) { - if ( glwidget_make_current( m_gl_widget ) ) { - if ( Map_Valid( g_map ) && ScreenUpdates_Enabled() ) { - GlobalOpenGL_debugAssertNoErrors(); -#ifdef OVERLAY_GL_FRONT_DRAW_HACK - glDrawBuffer( GL_FRONT ); -#endif - fbo_get()->blit(); - return true; - } - } - } - return false; -} -void XYWnd::overlayFinish(){ -#ifdef OVERLAY_GL_FRONT_DRAW_HACK - glDrawBuffer( GL_BACK ); -#endif - GlobalOpenGL_debugAssertNoErrors(); -#ifdef OVERLAY_GL_FRONT_DRAW_HACK - glwidget_make_current( m_gl_widget ); -#else - glwidget_swap_buffers( m_gl_widget ); -#endif -} -void XYWnd::overlayUpdate(){ - m_deferredOverlayDraw.queueDraw(); -} +//outline camera crosshair rectangle void XYWnd::overlayDraw(){ - glViewport( 0, 0, m_nWidth, m_nHeight ); + gl().glViewport( 0, 0, m_nWidth, m_nHeight ); - glDisable( GL_LINE_STIPPLE ); - glDisableClientState( GL_TEXTURE_COORD_ARRAY ); - glDisableClientState( GL_NORMAL_ARRAY ); - glDisableClientState( GL_COLOR_ARRAY ); - glDisable( GL_TEXTURE_2D ); - glDisable( GL_LIGHTING ); - glDisable( GL_COLOR_MATERIAL ); - glDisable( GL_DEPTH_TEST ); - glDisable( GL_TEXTURE_1D ); + gl().glDisable( GL_LINE_STIPPLE ); + gl().glDisableClientState( GL_TEXTURE_COORD_ARRAY ); + gl().glDisableClientState( GL_NORMAL_ARRAY ); + gl().glDisableClientState( GL_COLOR_ARRAY ); + gl().glDisable( GL_TEXTURE_2D ); + gl().glDisable( GL_LIGHTING ); + gl().glDisable( GL_COLOR_MATERIAL ); + gl().glDisable( GL_DEPTH_TEST ); + gl().glDisable( GL_TEXTURE_1D ); -// glDisable( GL_BLEND ); - glLineWidth( 1 ); +// gl().glDisable( GL_BLEND ); + gl().glLineWidth( 1 ); if ( g_xywindow_globals_private.show_outline && Active() ) { - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - glOrtho( 0, m_nWidth, 0, m_nHeight, 0, 1 ); + gl().glMatrixMode( GL_PROJECTION ); + gl().glLoadIdentity(); + gl().glOrtho( 0, m_nWidth, 0, m_nHeight, 0, 1 ); - glMatrixMode( GL_MODELVIEW ); - glLoadIdentity(); + gl().glMatrixMode( GL_MODELVIEW ); + gl().glLoadIdentity(); // four view mode doesn't colorize - glColor3fv( vector3_to_array( ( g_pParentWnd->CurrentStyle() == MainFrame::eSplit )? + gl().glColor3fv( vector3_to_array( ( g_pParentWnd->CurrentStyle() == MainFrame::eSplit )? g_xywindow_globals.color_viewname : m_viewType == YZ? g_xywindow_globals.AxisColorX : m_viewType == XZ? g_xywindow_globals.AxisColorY : g_xywindow_globals.AxisColorZ ) ); - glBegin( GL_LINE_LOOP ); - glVertex2f( 0.5, 0.5 ); - glVertex2f( m_nWidth - 0.5, 0.5 ); - glVertex2f( m_nWidth - 0.5, m_nHeight - 0.5 ); - glVertex2f( 0.5, m_nHeight - 0.5 ); - glEnd(); + gl().glBegin( GL_LINE_LOOP ); + gl().glVertex2f( 0.5, 0.5 ); + gl().glVertex2f( m_nWidth - 0.5, 0.5 ); + gl().glVertex2f( m_nWidth - 0.5, m_nHeight - 0.5 ); + gl().glVertex2f( 0.5, m_nHeight - 0.5 ); + gl().glEnd(); } { NDIM1NDIM2( m_viewType ) - glMatrixMode( GL_PROJECTION ); - glLoadMatrixf( reinterpret_cast( &m_projection ) ); + gl().glMatrixMode( GL_PROJECTION ); + gl().glLoadMatrixf( reinterpret_cast( &m_projection ) ); - glMatrixMode( GL_MODELVIEW ); - glLoadIdentity(); - glScalef( m_fScale, m_fScale, 1 ); - glTranslatef( -m_vOrigin[nDim1], -m_vOrigin[nDim2], 0 ); + gl().glMatrixMode( GL_MODELVIEW ); + gl().glLoadIdentity(); + gl().glScalef( m_fScale, m_fScale, 1 ); + gl().glTranslatef( -m_vOrigin[nDim1], -m_vOrigin[nDim2], 0 ); DrawCameraIcon( Camera_getOrigin( *g_pParentWnd->GetCamWnd() ), Camera_getAngles( *g_pParentWnd->GetCamWnd() ) ); } if ( g_bCrossHairs ) { - glMatrixMode( GL_PROJECTION ); - glLoadMatrixf( reinterpret_cast( &m_projection ) ); + gl().glMatrixMode( GL_PROJECTION ); + gl().glLoadMatrixf( reinterpret_cast( &m_projection ) ); - glMatrixMode( GL_MODELVIEW ); - glLoadMatrixf( reinterpret_cast( &m_modelview ) ); + gl().glMatrixMode( GL_MODELVIEW ); + gl().glLoadMatrixf( reinterpret_cast( &m_modelview ) ); NDIM1NDIM2( m_viewType ) Vector3 v( g_vector3_identity ); - glColor4f( 0.2f, 0.9f, 0.2f, 0.8f ); - glBegin( GL_LINES ); + gl().glColor4f( 0.2f, 0.9f, 0.2f, 0.8f ); + gl().glBegin( GL_LINES ); for( int i = 0, dim1 = nDim1, dim2 = nDim2; i < 2; ++i, std::swap( dim1, dim2 ) ){ v[dim1] = m_mousePosition[dim1]; v[dim2] = 2.0f * -GetMaxGridCoord(); - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); v[dim2] = 2.0f * GetMaxGridCoord(); - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); } - glEnd(); + gl().glEnd(); } + + m_XORRectangle.render( m_XORRect, Width(), Height() ); } void xy_update_xor_rectangle( XYWnd& self, rect_t area ){ - if ( self.overlayStart() ) { - self.overlayDraw(); - self.m_XORRectangle.set( area, self.Width(), self.Height() ); - self.overlayFinish(); - } + self.m_XORRect = area; + self.queueDraw(); } -void xy_update_overlay( XYWnd& self ){ - if ( self.overlayStart() ) { - self.overlayDraw(); - self.overlayFinish(); + +class XYGLWidget : public QOpenGLWidget +{ + XYWnd& m_xywnd; + DeferredMotion m_deferred_motion; + FBO *m_fbo{}; +public: + XYGLWidget( XYWnd& xywnd ) : QOpenGLWidget(), m_xywnd( xywnd ), + m_deferred_motion( [this]( const QMouseEvent& event ){ + if ( m_xywnd.chaseMouseMotion( event.x(), event.y() ) ) { + return; + } + m_xywnd.XY_MouseMoved( event.x(), event.y(), buttons_for_state( event ) ); + } ) + { + setMouseTracking( true ); } -} -gboolean xywnd_button_press( GtkWidget* widget, GdkEventButton* event, XYWnd* xywnd ){ - if ( event->type == GDK_BUTTON_PRESS ) { - gtk_widget_grab_focus( xywnd->GetWidget() ); + ~XYGLWidget() override { + delete m_fbo; + glwidget_context_destroyed(); + } - if( !xywnd->Active() ){ - g_pParentWnd->SetActiveXY( xywnd ); +protected: + void initializeGL() override + { + glwidget_context_created( *this ); + } + void resizeGL( int w, int h ) override + { + delete m_fbo; + m_fbo = new FBO( w, h, false, g_xywindow_globals_private.m_MSAA ); + + m_xywnd.m_nWidth = w; + m_xywnd.m_nHeight = h; + m_xywnd.updateProjection(); + m_xywnd.m_window_observer->onSizeChanged( m_xywnd.Width(), m_xywnd.Height() ); + + m_xywnd.m_drawRequired = true; + } + void paintGL() override + { + if( m_fbo->m_samples != g_xywindow_globals_private.m_MSAA ){ + delete m_fbo; + m_fbo = new FBO( m_xywnd.m_nWidth, m_xywnd.m_nHeight, false, g_xywindow_globals_private.m_MSAA ); } - xywnd->ButtonState_onMouseDown( buttons_for_event_button( event ) ); - - xywnd->onMouseDown( WindowVector( event->x, event->y ), button_for_button( event->button ), modifiers_for_state( event->state ) ); - } - return FALSE; -} - -gboolean xywnd_button_release( GtkWidget* widget, GdkEventButton* event, XYWnd* xywnd ){ - if ( event->type == GDK_BUTTON_RELEASE ) { - xywnd->XY_MouseUp( static_cast( event->x ), static_cast( event->y ), buttons_for_event_button( event ) ); - - xywnd->ButtonState_onMouseUp( buttons_for_event_button( event ) ); - - xywnd->chaseMouseMotion( static_cast( event->x ), static_cast( event->y ) ); /* stop chaseMouseMotion this way */ - } - return FALSE; -} - -gboolean xywnd_focus_in( GtkWidget* widget, GdkEventFocus* event, XYWnd* xywnd ){ - if ( event->type == GDK_FOCUS_CHANGE ) { - if ( event->in ) { - if( !xywnd->Active() ){ - g_pParentWnd->SetActiveXY( xywnd ); + if ( Map_Valid( g_map ) && ScreenUpdates_Enabled() && m_fbo->bind() ) { + GlobalOpenGL_debugAssertNoErrors(); + if( m_xywnd.m_drawRequired ){ + m_xywnd.m_drawRequired = false; + m_xywnd.XY_Draw(); + GlobalOpenGL_debugAssertNoErrors(); } + m_fbo->blit(); + m_fbo->release(); + m_xywnd.overlayDraw(); + GlobalOpenGL_debugAssertNoErrors(); } } - return FALSE; -} -void xywnd_motion( gdouble x, gdouble y, guint state, void* data ){ - if ( reinterpret_cast( data )->chaseMouseMotion( static_cast( x ), static_cast( y ) ) ) { - return; - } - reinterpret_cast( data )->XY_MouseMoved( static_cast( x ), static_cast( y ), buttons_for_state( state ) ); -} + void mousePressEvent( QMouseEvent *event ) override { + setFocus(); -gboolean xywnd_wheel_scroll( GtkWidget* widget, GdkEventScroll* event, XYWnd* xywnd ){ - gtk_widget_grab_focus( xywnd->GetWidget() ); - GtkWindow* window = xywnd->m_parent != 0 ? xywnd->m_parent : MainFrame_getWindow(); - if( !gtk_window_is_active( window ) ) - gtk_window_present( window ); - - if( !xywnd->Active() ){ - g_pParentWnd->SetActiveXY( xywnd ); - } - if ( event->direction == GDK_SCROLL_UP ) { - xywnd->ZoomInWithMouse( (int)event->x, (int)event->y ); - } - else if ( event->direction == GDK_SCROLL_DOWN ) { - xywnd->ZoomOutWithMouse( (int)event->x, (int)event->y ); - } - return FALSE; -} - -gboolean xywnd_size_allocate( GtkWidget* widget, GtkAllocation* allocation, XYWnd* xywnd ){ -#if NV_DRIVER_GAMMA_BUG - xywnd->fbo_get()->reset( allocation->width, allocation->height, g_xywindow_globals_private.m_MSAA, true ); -#else - xywnd->fbo_get()->reset( allocation->width, allocation->height, g_xywindow_globals_private.m_MSAA, false ); -#endif - xywnd->m_nWidth = allocation->width; - xywnd->m_nHeight = allocation->height; - xywnd->updateProjection(); - xywnd->m_window_observer->onSizeChanged( xywnd->Width(), xywnd->Height() ); - return FALSE; -} - -gboolean xywnd_expose( GtkWidget* widget, GdkEventExpose* event, XYWnd* xywnd ){ - if ( glwidget_make_current( xywnd->GetWidget() ) ) { - if ( Map_Valid( g_map ) && ScreenUpdates_Enabled() ) { - GlobalOpenGL_debugAssertNoErrors(); - xywnd->XY_Draw(); - GlobalOpenGL_debugAssertNoErrors(); - - //xywnd->m_XORRectangle.set( rect_t() ); + if( !m_xywnd.Active() ){ + g_pParentWnd->SetActiveXY( &m_xywnd ); } - glwidget_swap_buffers( xywnd->GetWidget() ); + + m_xywnd.ButtonState_onMouseDown( buttons_for_event_button( event ) ); + + m_xywnd.onMouseDown( WindowVector( event->x(), event->y() ), button_for_button( event->button() ), modifiers_for_state( event->modifiers() ) ); } - return FALSE; -} + void mouseMoveEvent( QMouseEvent *event ) override { + m_deferred_motion.motion( event ); + } + void mouseReleaseEvent( QMouseEvent *event ) override { + m_xywnd.XY_MouseUp( event->x(), event->y(), buttons_for_event_button( event ) ); + m_xywnd.ButtonState_onMouseUp( buttons_for_event_button( event ) ); -void XYWnd_CameraMoved( XYWnd& xywnd ){ - xywnd.overlayUpdate(); -} + m_xywnd.chaseMouseMotion( event->x(), event->y() ); /* stop chaseMouseMotion this way */ + } + void wheelEvent( QWheelEvent *event ) override { + setFocus(); + QWidget* window = m_xywnd.m_parent != 0 ? m_xywnd.m_parent : MainFrame_getWindow(); + if( !window->isActiveWindow() ){ + window->activateWindow(); + window->raise(); + } + + if( !m_xywnd.Active() ){ + g_pParentWnd->SetActiveXY( &m_xywnd ); + } + if ( event->angleDelta().y() > 0 ) { + m_xywnd.ZoomInWithMouse( event->position().x(), event->position().y() ); + } + else if ( event->angleDelta().y() < 0 ) { + m_xywnd.ZoomOutWithMouse( event->position().x(), event->position().y() ); + } + } + + void focusInEvent( QFocusEvent *event ) override { + if( !m_xywnd.Active() ){ + g_pParentWnd->SetActiveXY( &m_xywnd ); + } + } +}; XYWnd::XYWnd() : -#if NV_DRIVER_GAMMA_BUG - m_gl_widget( glwidget_new( TRUE ) ), -#else - m_gl_widget( glwidget_new( FALSE ) ), -#endif + m_gl_widget( new XYGLWidget( *this ) ), m_deferredDraw( WidgetQueueDrawCaller( *m_gl_widget ) ), - m_deferredOverlayDraw( ReferenceCaller( *this ) ), - m_deferred_motion( xywnd_motion, this ), - m_fbo( 0 ), m_parent( 0 ), - m_window_observer( NewWindowObserver() ), - m_chasemouse_handler( 0 ) + m_window_observer( NewWindowObserver() ) { m_bActive = false; m_buttonstate = 0; @@ -714,38 +568,19 @@ XYWnd::XYWnd() : m_entityCreate = false; - m_mnuDrop = 0; - GlobalWindowObservers_add( m_window_observer ); GlobalWindowObservers_connectWidget( m_gl_widget ); m_window_observer->setRectangleDrawCallback( ReferenceCaller1( *this ) ); m_window_observer->setView( m_view ); - g_object_ref( G_OBJECT( m_gl_widget ) ); - - gtk_widget_set_events( m_gl_widget, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK ); - gtk_widget_set_can_focus( m_gl_widget, TRUE ); - - m_sizeHandler = g_signal_connect( G_OBJECT( m_gl_widget ), "size_allocate", G_CALLBACK( xywnd_size_allocate ), this ); - m_exposeHandler = g_signal_connect( G_OBJECT( m_gl_widget ), "expose_event", G_CALLBACK( xywnd_expose ), this ); - - g_signal_connect( G_OBJECT( m_gl_widget ), "button_press_event", G_CALLBACK( xywnd_button_press ), this ); - g_signal_connect( G_OBJECT( m_gl_widget ), "button_release_event", G_CALLBACK( xywnd_button_release ), this ); - g_signal_connect( G_OBJECT( m_gl_widget ), "focus_in_event", G_CALLBACK( xywnd_focus_in ), this ); - g_signal_connect( G_OBJECT( m_gl_widget ), "motion_notify_event", G_CALLBACK( DeferredMotion::gtk_motion ), &m_deferred_motion ); - - g_signal_connect( G_OBJECT( m_gl_widget ), "scroll_event", G_CALLBACK( xywnd_wheel_scroll ), this ); - - Map_addValidCallback( g_map, DeferredDrawOnMapValidChangedCaller( m_deferredDraw ) ); + Map_addValidCallback( g_map, DeferredDrawOnMapValidChangedCaller( m_deferredDraw ) ); //. correct would be m_drawRequired = true here updateProjection(); updateModelview(); AddSceneChangeCallback( ReferenceCaller( *this ) ); - AddCameraMovedCallback( ReferenceCaller( *this ) ); - - PressedButtons_connect( g_pressedButtons, m_gl_widget ); + AddCameraMovedCallback( MemberCaller( *this ) ); onMouseDown.connectLast( makeSignalHandler3( MouseDownCaller(), *this ) ); } @@ -753,18 +588,6 @@ XYWnd::XYWnd() : XYWnd::~XYWnd(){ onDestroyed(); - delete m_fbo; - - if ( m_mnuDrop != 0 ) { - gtk_widget_destroy( GTK_WIDGET( m_mnuDrop ) ); - m_mnuDrop = 0; - } - - g_signal_handler_disconnect( G_OBJECT( m_gl_widget ), m_sizeHandler ); - g_signal_handler_disconnect( G_OBJECT( m_gl_widget ), m_exposeHandler ); - - g_object_unref( G_OBJECT( m_gl_widget ) ); - m_window_observer->release(); } @@ -796,10 +619,6 @@ void XYWnd::Scroll( int x, int y ){ SetOrigin( m_vOrigin ); } -FBO* XYWnd::fbo_get(){ - return m_fbo = m_fbo? m_fbo : GlobalOpenGL().support_ARB_framebuffer_object? new FBO : new FBO_fallback; -} - void XYWnd::SetCustomPivotOrigin( int x, int y ) const { bool set[3] = { true, true, true }; set[GetViewType()] = false; @@ -924,68 +743,78 @@ void XYWnd::NewBrushDrag( int x, int y, bool square, bool cube ){ Scene_BrushResize_Cuboid( m_NewBrushDrag, aabb_for_minmax( mins, maxs ) ); } -int g_entityCreationOffset = 0; -void entitycreate_activated( GtkMenuItem* item, gpointer user_data ){ - const char* entity_name = gtk_label_get_text( GTK_LABEL( gtk_bin_get_child( GTK_BIN( item ) ) ) ); +static int g_entityCreationOffset = 0; + +void entitycreate_activated( const QAction *action ){ if( g_bCamEntityMenu ){ const Vector3 viewvector = -Camera_getViewVector( *g_pParentWnd->GetCamWnd() ); const float offset_for_multiple = std::max( GetSnapGridSize(), 8.f ) * g_entityCreationOffset; Vector3 point = viewvector * ( 64.f + offset_for_multiple ) + Camera_getOrigin( *g_pParentWnd->GetCamWnd() ); vector3_snap( point, GetSnapGridSize() ); - Entity_createFromSelection( entity_name, point ); + Entity_createFromSelection( action->text().toLatin1().constData(), point ); } else{ - g_pParentWnd->ActiveXY()->OnEntityCreate( entity_name ); + g_pParentWnd->ActiveXY()->OnEntityCreate( action->text().toLatin1().constData() ); } ++g_entityCreationOffset; } -gboolean entitycreate_rightClicked( GtkWidget* widget, GdkEvent* event, gpointer user_data ) { - /* convert entities */ - if ( event->button.button == 3 ) { - Scene_EntitySetClassname_Selected( gtk_label_get_text( GTK_LABEL( gtk_bin_get_child( GTK_BIN( widget ) ) ) ) ); - if( ( event->button.state & GDK_CONTROL_MASK ) == 0 ){ - gtk_menu_popdown( XYWnd::m_mnuDrop ); +class EntityMenu : public QMenu +{ + bool m_mouse_handled{}; + bool m_hide_menu; +public: + EntityMenu( const char* name ) : QMenu( name ){ + } +protected: + void mousePressEvent( QMouseEvent *event ) override { + /* create entities, don't close menu */ + if( event->button() == Qt::MouseButton::LeftButton && event->modifiers() == Qt::KeyboardModifier::ControlModifier ){ + if( QAction *action = actionAt( event->pos() ) ){ + if( action->menu() == nullptr ){ + m_mouse_handled = true; + m_hide_menu = false; + entitycreate_activated( action ); + return; + } + } } - return TRUE; + /* convert entities */ + else if( event->button() == Qt::MouseButton::RightButton ){ + if( QAction *action = actionAt( event->pos() ) ){ + if( action->menu() == nullptr ){ + m_mouse_handled = true; + m_hide_menu = ( event->modifiers() != Qt::KeyboardModifier::ControlModifier ); + Scene_EntitySetClassname_Selected( action->text().toLatin1().constData() ); + return; + } + } + } + m_mouse_handled = false; + m_hide_menu = false; + QMenu::mousePressEvent( event ); } - /* create entities, don't close menu */ - else if ( event->button.button == 1 && ( ( event->button.state & GDK_CONTROL_MASK ) != 0 || gtk_menu_get_tearoff_state( XYWnd::m_mnuDrop ) ) ) { - entitycreate_activated( GTK_MENU_ITEM( widget ), 0 ); - return TRUE; + void mouseReleaseEvent( QMouseEvent *event ) override { + if( m_mouse_handled ){ + m_mouse_handled = false; // reset, so releases w/o press and clicks on non functional items take standard path + if( m_hide_menu ){ + XYWnd::m_mnuDrop->hide(); + } + return; + } + QMenu::mouseReleaseEvent( event ); } - return FALSE; -} - -/* This handles unwanted rightclick release, that can occur with low res display, while activating menu from camera (=activate top menu entry) */ -gboolean entitycreate_rightUnClicked( GtkWidget* widget, GdkEvent* event, gpointer user_data ) { - if ( event->button.button == 3 ) { - return TRUE; - } - else if ( event->button.button == 1 && ( ( event->button.state & GDK_CONTROL_MASK ) != 0 || gtk_menu_get_tearoff_state( XYWnd::m_mnuDrop ) ) ) { - return TRUE; - } - return FALSE; -} - -void EntityClassMenu_addItem( GtkMenu* menu, const char* name ){ - GtkMenuItem* item = GTK_MENU_ITEM( gtk_menu_item_new_with_label( name ) ); - g_signal_connect( G_OBJECT( item ), "button-press-event", G_CALLBACK( entitycreate_rightClicked ), 0 ); - g_signal_connect( G_OBJECT( item ), "button-release-event", G_CALLBACK( entitycreate_rightUnClicked ), 0 ); - g_signal_connect( G_OBJECT( item ), "activate", G_CALLBACK( entitycreate_activated ), 0 ); - gtk_widget_show( GTK_WIDGET( item ) ); - menu_add_item( menu, item ); -} +}; class EntityClassMenuInserter : public EntityClassVisitor { - typedef std::pair MenuPair; + typedef std::pair MenuPair; typedef std::vector MenuStack; MenuStack m_stack; CopiedString m_previous; public: - EntityClassMenuInserter( GtkMenu* menu ){ + EntityClassMenuInserter( QMenu* menu ){ m_stack.reserve( 2 ); m_stack.push_back( MenuPair( menu, "" ) ); } @@ -1002,13 +831,8 @@ public: m_previous = e->name(); } void pushMenu( const CopiedString& name ){ - GtkMenuItem* item = GTK_MENU_ITEM( gtk_menu_item_new_with_label( name.c_str() ) ); - gtk_widget_show( GTK_WIDGET( item ) ); - container_add_widget( GTK_CONTAINER( m_stack.back().first ), GTK_WIDGET( item ) ); - - GtkMenu* submenu = GTK_MENU( gtk_menu_new() ); - gtk_menu_item_set_submenu( item, GTK_WIDGET( submenu ) ); - + QMenu *submenu = new EntityMenu( name.c_str() ); + m_stack.back().first->addMenu( submenu ); m_stack.push_back( MenuPair( submenu, name ) ); } void popMenu(){ @@ -1039,89 +863,58 @@ public: popMenu(); } - EntityClassMenu_addItem( m_stack.back().first, name ); + m_stack.back().first->addAction( name ); } }; void XYWnd::OnContextMenu(){ if ( m_mnuDrop == 0 ) { // first time, load it up - GtkMenu* menu = m_mnuDrop = GTK_MENU( gtk_menu_new() ); -// menu_tearoff( menu ); - g_signal_connect( G_OBJECT( menu_tearoff( menu ) ), "button-release-event", G_CALLBACK( entitycreate_rightUnClicked ), 0 ); - gtk_menu_attach_to_widget( m_mnuDrop, GTK_WIDGET( m_parent != 0 ? m_parent : MainFrame_getWindow() ), NULL ); - gtk_menu_set_title( m_mnuDrop, "" ); + m_mnuDrop = new EntityMenu( "" ); +// m_mnuDrop->setTearOffEnabled( true ); // problematic mouse events override in torn off menu + QObject::connect( m_mnuDrop, &QMenu::triggered, entitycreate_activated ); //will receive submenu actions too - EntityClassMenuInserter inserter( menu ); + EntityClassMenuInserter inserter( m_mnuDrop ); GlobalEntityClassManager().forEach( inserter ); } g_entityCreationOffset = 0; g_bCamEntityMenu = false; - gtk_menu_popup( m_mnuDrop, 0, 0, 0, 0, 1, GDK_CURRENT_TIME ); + m_mnuDrop->popup( QCursor::pos() ); } -FreezePointer g_xywnd_freezePointer; +static FreezePointer g_xywnd_freezePointer; unsigned int Move_buttons(){ return RAD_RBUTTON; } -void XYWnd_moveDelta( int x, int y, unsigned int state, void* data ){ - reinterpret_cast( data )->EntityCreate_MouseMove( x, y ); - reinterpret_cast( data )->Scroll( -x, y ); -} - -gboolean XYWnd_Move_focusOut( GtkWidget* widget, GdkEventFocus* event, XYWnd* xywnd ){ - xywnd->Move_End(); - return FALSE; -} - void XYWnd::Move_Begin(){ if ( m_move_started ) { Move_End(); } m_move_started = true; - g_xywnd_freezePointer.freeze_pointer( m_parent != 0 ? m_parent : MainFrame_getWindow(), m_gl_widget, XYWnd_moveDelta, this ); - m_move_focusOut = g_signal_connect( G_OBJECT( m_gl_widget ), "focus_out_event", G_CALLBACK( XYWnd_Move_focusOut ), this ); + g_xywnd_freezePointer.freeze_pointer( m_gl_widget, + [this]( int x, int y, const QMouseEvent *event ){ + EntityCreate_MouseMove( x, y ); + Scroll( -x, y ); + }, + [this](){ + Move_End(); + } ); } void XYWnd::Move_End(){ m_move_started = false; g_xywnd_freezePointer.unfreeze_pointer( false ); - g_signal_handler_disconnect( G_OBJECT( m_gl_widget ), m_move_focusOut ); } unsigned int Zoom_buttons(){ return RAD_RBUTTON | RAD_ALT; } -int g_dragZoom = 0; -int g_zoom2x = 0; -int g_zoom2y = 0; - -void XYWnd_zoomDelta( int x, int y, unsigned int state, void* data ){ - if ( y != 0 ) { - g_dragZoom += y; - const int threshold = 16; - while ( abs( g_dragZoom ) > threshold ) - { - if ( g_dragZoom > 0 ) { - reinterpret_cast( data )->ZoomOutWithMouse( g_zoom2x, g_zoom2y ); - g_dragZoom -= threshold; - } - else - { - reinterpret_cast( data )->ZoomInWithMouse( g_zoom2x, g_zoom2y ); - g_dragZoom += threshold; - } - } - } -} - -gboolean XYWnd_Zoom_focusOut( GtkWidget* widget, GdkEventFocus* event, XYWnd* xywnd ){ - xywnd->Zoom_End(); - return FALSE; -} +static int g_dragZoom = 0; +static int g_zoom2x = 0; +static int g_zoom2y = 0; void XYWnd::Zoom_Begin( int x, int y ){ if ( m_zoom_started ) { @@ -1131,14 +924,33 @@ void XYWnd::Zoom_Begin( int x, int y ){ g_dragZoom = 0; g_zoom2x = x; g_zoom2y = y; - g_xywnd_freezePointer.freeze_pointer( m_parent != 0 ? m_parent : MainFrame_getWindow(), m_gl_widget, XYWnd_zoomDelta, this ); - m_zoom_focusOut = g_signal_connect( G_OBJECT( m_gl_widget ), "focus_out_event", G_CALLBACK( XYWnd_Zoom_focusOut ), this ); + g_xywnd_freezePointer.freeze_pointer( m_gl_widget, + [this]( int x, int y, const QMouseEvent *event ){ + if ( y != 0 ) { + g_dragZoom += y; + const int threshold = 16; + while ( abs( g_dragZoom ) > threshold ) + { + if ( g_dragZoom > 0 ) { + ZoomOutWithMouse( g_zoom2x, g_zoom2y ); + g_dragZoom -= threshold; + } + else + { + ZoomInWithMouse( g_zoom2x, g_zoom2y ); + g_dragZoom += threshold; + } + } + } + }, + [this](){ + Zoom_End(); + } ); } void XYWnd::Zoom_End(){ m_zoom_started = false; g_xywnd_freezePointer.unfreeze_pointer( false ); - g_signal_handler_disconnect( G_OBJECT( m_gl_widget ), m_zoom_focusOut ); } void XYWnd::SetViewType( VIEWTYPE viewType ){ @@ -1146,7 +958,7 @@ void XYWnd::SetViewType( VIEWTYPE viewType ){ updateModelview(); if ( m_parent != 0 ) { - gtk_window_set_title( m_parent, ViewType_getTitle( m_viewType ) ); + m_parent->setWindowTitle( ViewType_getTitle( m_viewType ) ); } } @@ -1250,8 +1062,7 @@ void XYWnd::XY_MouseMoved( int x, int y, unsigned int buttons ){ } if ( g_bCrossHairs && button_for_flags( buttons ) == c_buttonInvalid ) { // don't update with a button pressed, observer calls update itself -// XYWnd_Update( *this ); - overlayUpdate(); + queueDraw(); } } } @@ -1297,44 +1108,43 @@ Vector3 XYWnd::XY_ToPoint( int x, int y, bool snap /* = false */ ) const { void BackgroundImage::render( const VIEWTYPE viewtype ){ if( viewtype == _viewtype && _tex > 0 ){ -// glPushAttrib( GL_ALL_ATTRIB_BITS ); //bug with intel +// gl().glPushAttrib( GL_ALL_ATTRIB_BITS ); //bug with intel - if ( GlobalOpenGL().GL_1_3() ) { - glActiveTexture( GL_TEXTURE0 ); - glClientActiveTexture( GL_TEXTURE0 ); - } - glEnable( GL_TEXTURE_2D ); - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); -// glPolygonMode( GL_FRONT, GL_FILL ); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glDisable( GL_CULL_FACE ); - glDisable( GL_DEPTH_TEST ); + gl().glActiveTexture( GL_TEXTURE0 ); + gl().glClientActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, _tex ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + gl().glEnable( GL_TEXTURE_2D ); + gl().glEnable( GL_BLEND ); + gl().glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + gl().glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); +// gl().glPolygonMode( GL_FRONT, GL_FILL ); + gl().glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + gl().glDisable( GL_CULL_FACE ); + gl().glDisable( GL_DEPTH_TEST ); - glBegin( GL_QUADS ); + gl().glBindTexture( GL_TEXTURE_2D, _tex ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + gl().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - glColor4f( 1, 1, 1, _alpha ); - glTexCoord2f( 0, 1 ); - glVertex2f( _xmin, _ymin ); + gl().glBegin( GL_QUADS ); - glTexCoord2f( 1, 1 ); - glVertex2f( _xmax, _ymin ); + gl().glColor4f( 1, 1, 1, _alpha ); + gl().glTexCoord2f( 0, 1 ); + gl().glVertex2f( _xmin, _ymin ); - glTexCoord2f( 1, 0 ); - glVertex2f( _xmax, _ymax ); + gl().glTexCoord2f( 1, 1 ); + gl().glVertex2f( _xmax, _ymin ); - glTexCoord2f( 0, 0 ); - glVertex2f( _xmin, _ymax ); + gl().glTexCoord2f( 1, 0 ); + gl().glVertex2f( _xmax, _ymax ); - glEnd(); - glBindTexture( GL_TEXTURE_2D, 0 ); + gl().glTexCoord2f( 0, 0 ); + gl().glVertex2f( _xmin, _ymax ); -// glPopAttrib(); + gl().glEnd(); + gl().glBindTexture( GL_TEXTURE_2D, 0 ); + +// gl().glPopAttrib(); } } @@ -1351,7 +1161,7 @@ const char* BackgroundImage::background_image_dialog(){ buffer << g_qeglobals.m_userGamePath; } - const char *filename = file_dialog( GTK_WIDGET( MainFrame_getWindow() ), true, "Background Image", buffer.c_str() ); + const char *filename = file_dialog( MainFrame_getWindow(), true, "Background Image", buffer.c_str() ); if ( filename != 0 ) { // use VFS to get the correct relative path const char* relative = path_make_relative( filename, GlobalFileSystem().findRoot( filename ) ); @@ -1365,7 +1175,7 @@ const char* BackgroundImage::background_image_dialog(){ void BackgroundImage::free_tex(){ if( _tex > 0 ){ - glDeleteTextures( 1, &_tex ); + gl().glDeleteTextures( 1, &_tex ); _tex = 0; } } @@ -1377,8 +1187,8 @@ void BackgroundImage::set( const VIEWTYPE viewtype ){ const AABB bounds = GlobalSelectionSystem().getBoundsSelected(); NDIM1NDIM2( viewtype ) if( !( bounds.extents[nDim1] > 0 && bounds.extents[nDim2] > 0 ) ){ - gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), "Select some objects to get the bounding box for image.\n", - "No selection", eMB_OK, eMB_ICONERROR ); + qt_MessageBox( MainFrame_getWindow(), "Select some objects to get the bounding box for image.\n", + "No selection", EMessageBoxType::Error ); } else{ free_tex(); @@ -1445,32 +1255,32 @@ void XYWnd::XY_DrawAxis(){ #endif // draw two lines with corresponding axis colors to highlight current view // horizontal line: nDim1 color - glLineWidth( 2 ); - glBegin( GL_LINES ); - glColor3fv( vector3_to_array( colourX ) ); - glVertex2f( m_vOrigin[nDim1] - w + 40 / m_fScale, m_vOrigin[nDim2] + h - 45 / m_fScale ); - glVertex2f( m_vOrigin[nDim1] - w + 65 / m_fScale, m_vOrigin[nDim2] + h - 45 / m_fScale ); - glVertex2f( 0, 0 ); - glVertex2f( 32 / m_fScale, 0 ); - glColor3fv( vector3_to_array( colourY ) ); - glVertex2f( m_vOrigin[nDim1] - w + 40 / m_fScale, m_vOrigin[nDim2] + h - 45 / m_fScale ); - glVertex2f( m_vOrigin[nDim1] - w + 40 / m_fScale, m_vOrigin[nDim2] + h - 20 / m_fScale ); - glVertex2f( 0, 0 ); - glVertex2f( 0, 32 / m_fScale ); - glEnd(); - glLineWidth( 1 ); + gl().glLineWidth( 2 ); + gl().glBegin( GL_LINES ); + gl().glColor3fv( vector3_to_array( colourX ) ); + gl().glVertex2f( m_vOrigin[nDim1] - w + 40 / m_fScale, m_vOrigin[nDim2] + h - 45 / m_fScale ); + gl().glVertex2f( m_vOrigin[nDim1] - w + 65 / m_fScale, m_vOrigin[nDim2] + h - 45 / m_fScale ); + gl().glVertex2f( 0, 0 ); + gl().glVertex2f( 32 / m_fScale, 0 ); + gl().glColor3fv( vector3_to_array( colourY ) ); + gl().glVertex2f( m_vOrigin[nDim1] - w + 40 / m_fScale, m_vOrigin[nDim2] + h - 45 / m_fScale ); + gl().glVertex2f( m_vOrigin[nDim1] - w + 40 / m_fScale, m_vOrigin[nDim2] + h - 20 / m_fScale ); + gl().glVertex2f( 0, 0 ); + gl().glVertex2f( 0, 32 / m_fScale ); + gl().glEnd(); + gl().glLineWidth( 1 ); // now print axis symbols const int fontHeight = GlobalOpenGL().m_font->getPixelHeight(); const float fontWidth = fontHeight * .55f; - glColor3fv( vector3_to_array( colourX ) ); - glRasterPos2f( m_vOrigin[nDim1] - w + ( 65 - 3 - fontWidth ) / m_fScale, m_vOrigin[nDim2] + h - ( 45 + 3 + fontHeight ) / m_fScale ); + gl().glColor3fv( vector3_to_array( colourX ) ); + gl().glRasterPos2f( m_vOrigin[nDim1] - w + ( 65 - 3 - fontWidth ) / m_fScale, m_vOrigin[nDim2] + h - ( 45 + 3 + fontHeight ) / m_fScale ); GlobalOpenGL().drawChar( g_AxisName[nDim1] ); - glRasterPos2f( ( 32 - fontWidth / 2 ) / m_fScale, -( 0 + 3 + fontHeight ) / m_fScale ); + gl().glRasterPos2f( ( 32 - fontWidth / 2 ) / m_fScale, -( 0 + 3 + fontHeight ) / m_fScale ); GlobalOpenGL().drawChar( g_AxisName[nDim1] ); - glColor3fv( vector3_to_array( colourY ) ); - glRasterPos2f( m_vOrigin[nDim1] - w + ( 40 - 4 - fontWidth ) / m_fScale, m_vOrigin[nDim2] + h - ( 20 + 3 + fontHeight ) / m_fScale ); + gl().glColor3fv( vector3_to_array( colourY ) ); + gl().glRasterPos2f( m_vOrigin[nDim1] - w + ( 40 - 4 - fontWidth ) / m_fScale, m_vOrigin[nDim2] + h - ( 20 + 3 + fontHeight ) / m_fScale ); GlobalOpenGL().drawChar( g_AxisName[nDim2] ); - glRasterPos2f( ( 0 - 3 - fontWidth ) / m_fScale, ( 32 - fontHeight / 2 ) / m_fScale ); + gl().glRasterPos2f( ( 0 - 3 - fontWidth ) / m_fScale, ( 32 - fontHeight / 2 ) / m_fScale ); GlobalOpenGL().drawChar( g_AxisName[nDim2] ); } @@ -1501,11 +1311,11 @@ void XYWnd::XY_DrawGrid() { const float a = ( ( GetSnapGridSize() > 0.0f ) ? 1.0f : 0.3f ); - glDisable( GL_TEXTURE_2D ); - glDisable( GL_TEXTURE_1D ); - glDisable( GL_DEPTH_TEST ); - glDisable( GL_BLEND ); - glLineWidth( 1 ); + gl().glDisable( GL_TEXTURE_2D ); + gl().glDisable( GL_TEXTURE_1D ); + gl().glDisable( GL_DEPTH_TEST ); + gl().glDisable( GL_BLEND ); + gl().glLineWidth( 1 ); const float w = ( m_nWidth / 2 / m_fScale ); const float h = ( m_nHeight / 2 / m_fScale ); @@ -1526,48 +1336,48 @@ void XYWnd::XY_DrawGrid() { // draw minor blocks if ( g_xywindow_globals_private.d_showgrid /*|| a < 1.0f*/ ) { if ( a < 1.0f ) { - glEnable( GL_BLEND ); + gl().glEnable( GL_BLEND ); } if ( COLORS_DIFFER( g_xywindow_globals.color_gridminor, g_xywindow_globals.color_gridback ) ) { - glColor4fv( vector4_to_array( Vector4( g_xywindow_globals.color_gridminor, a ) ) ); + gl().glColor4fv( vector4_to_array( Vector4( g_xywindow_globals.color_gridminor, a ) ) ); - glBegin( GL_LINES ); + gl().glBegin( GL_LINES ); int i = 0; for ( x = xb; x < xe; x += minor_step, ++i ) { if ( ( i & mask ) != 0 ) { - glVertex2f( x, yb ); - glVertex2f( x, ye ); + gl().glVertex2f( x, yb ); + gl().glVertex2f( x, ye ); } } i = 0; for ( y = yb; y < ye; y += minor_step, ++i ) { if ( ( i & mask ) != 0 ) { - glVertex2f( xb, y ); - glVertex2f( xe, y ); + gl().glVertex2f( xb, y ); + gl().glVertex2f( xe, y ); } } - glEnd(); + gl().glEnd(); } // draw major blocks if ( COLORS_DIFFER( g_xywindow_globals.color_gridmajor, g_xywindow_globals.color_gridminor ) ) { - glColor4fv( vector4_to_array( Vector4( g_xywindow_globals.color_gridmajor, a ) ) ); + gl().glColor4fv( vector4_to_array( Vector4( g_xywindow_globals.color_gridmajor, a ) ) ); - glBegin( GL_LINES ); + gl().glBegin( GL_LINES ); for ( x = xb; x <= xe; x += step ) { - glVertex2f( x, yb ); - glVertex2f( x, ye ); + gl().glVertex2f( x, yb ); + gl().glVertex2f( x, ye ); } for ( y = yb; y <= ye; y += step ) { - glVertex2f( xb, y ); - glVertex2f( xe, y ); + gl().glVertex2f( xb, y ); + gl().glVertex2f( xe, y ); } - glEnd(); + gl().glEnd(); } if ( a < 1.0f ) { - glDisable( GL_BLEND ); + gl().glDisable( GL_BLEND ); } if( g_region_active ){ @@ -1576,61 +1386,61 @@ void XYWnd::XY_DrawGrid() { const float yb_ = step * floor( std::max( m_vOrigin[nDim2] - h, -GetMaxGridCoord() ) / step ); const float ye_ = step * ceil( std::min( m_vOrigin[nDim2] + h, GetMaxGridCoord() ) / step ); - glEnable( GL_BLEND ); + gl().glEnable( GL_BLEND ); // draw minor blocks if ( COLORS_DIFFER( g_xywindow_globals.color_gridminor, g_xywindow_globals.color_gridback ) ) { - glColor4fv( vector4_to_array( Vector4( g_xywindow_globals.color_gridminor, .5f ) ) ); + gl().glColor4fv( vector4_to_array( Vector4( g_xywindow_globals.color_gridminor, .5f ) ) ); - glBegin( GL_LINES ); + gl().glBegin( GL_LINES ); int i = 0; for ( x = xb_; x < xe_; x += minor_step, ++i ) { if ( ( i & mask ) != 0 ) { - glVertex2f( x, yb_ ); - glVertex2f( x, ye_ ); + gl().glVertex2f( x, yb_ ); + gl().glVertex2f( x, ye_ ); } } i = 0; for ( y = yb_; y < ye_; y += minor_step, ++i ) { if ( ( i & mask ) != 0 ) { - glVertex2f( xb_, y ); - glVertex2f( xe_, y ); + gl().glVertex2f( xb_, y ); + gl().glVertex2f( xe_, y ); } } - glEnd(); + gl().glEnd(); } // draw major blocks if ( COLORS_DIFFER( g_xywindow_globals.color_gridmajor, g_xywindow_globals.color_gridminor ) ) { - glColor4fv( vector4_to_array( Vector4( g_xywindow_globals.color_gridmajor, .5f ) ) ); + gl().glColor4fv( vector4_to_array( Vector4( g_xywindow_globals.color_gridmajor, .5f ) ) ); - glBegin( GL_LINES ); + gl().glBegin( GL_LINES ); for ( x = xb_; x <= xe_; x += step ) { - glVertex2f( x, yb_ ); - glVertex2f( x, ye_ ); + gl().glVertex2f( x, yb_ ); + gl().glVertex2f( x, ye_ ); } for ( y = yb_; y <= ye_; y += step ) { - glVertex2f( xb_, y ); - glVertex2f( xe_, y ); + gl().glVertex2f( xb_, y ); + gl().glVertex2f( xe_, y ); } - glEnd(); + gl().glEnd(); } - glDisable( GL_BLEND ); + gl().glDisable( GL_BLEND ); } } // draw coordinate text if needed if ( g_xywindow_globals_private.show_coordinates ) { - glColor4fv( vector4_to_array( Vector4( g_xywindow_globals.color_gridtext, 1.0f ) ) ); + gl().glColor4fv( vector4_to_array( Vector4( g_xywindow_globals.color_gridtext, 1.0f ) ) ); const float offx = m_vOrigin[nDim2] + h - ( 1 + GlobalOpenGL().m_font->getPixelHeight() ) / m_fScale; const float offy = m_vOrigin[nDim1] - w + 4 / m_fScale; const float fontDescent = ( GlobalOpenGL().m_font->getPixelDescent() - 1 ) / m_fScale; for ( x = xb - fmod( xb, stepx ); x <= xe; x += stepx ) { - glRasterPos2f( x, offx ); + gl().glRasterPos2f( x, offx ); sprintf( text, "%g", x ); GlobalOpenGL().drawString( text ); } for ( y = yb - fmod( yb, stepy ); y <= ye; y += stepy ) { - glRasterPos2f( offy, y - fontDescent ); + gl().glRasterPos2f( offy, y - fontDescent ); sprintf( text, "%g", y ); GlobalOpenGL().drawString( text ); } @@ -1641,25 +1451,25 @@ void XYWnd::XY_DrawGrid() { XY_DrawAxis(); } else{ - glColor3fv( vector3_to_array( Active()? g_xywindow_globals.color_viewname : g_xywindow_globals.color_gridtext ) ); - glRasterPos2f( m_vOrigin[nDim1] - w + 35 / m_fScale, m_vOrigin[nDim2] + h - ( GlobalOpenGL().m_font->getPixelHeight() * 2 ) / m_fScale ); + gl().glColor3fv( vector3_to_array( Active()? g_xywindow_globals.color_viewname : g_xywindow_globals.color_gridtext ) ); + gl().glRasterPos2f( m_vOrigin[nDim1] - w + 35 / m_fScale, m_vOrigin[nDim2] + h - ( GlobalOpenGL().m_font->getPixelHeight() * 2 ) / m_fScale ); GlobalOpenGL().drawString( ViewType_getTitle( m_viewType ) ); } // show current work zone? // the work zone is used to place dropped points and brushes if ( g_xywindow_globals_private.show_workzone ) { - glColor4f( 1.0f, 0.0f, 0.0f, 1.0f ); - glBegin( GL_LINES ); - glVertex2f( xb, Select_getWorkZone().d_work_min[nDim2] ); - glVertex2f( xe, Select_getWorkZone().d_work_min[nDim2] ); - glVertex2f( xb, Select_getWorkZone().d_work_max[nDim2] ); - glVertex2f( xe, Select_getWorkZone().d_work_max[nDim2] ); - glVertex2f( Select_getWorkZone().d_work_min[nDim1], yb ); - glVertex2f( Select_getWorkZone().d_work_min[nDim1], ye ); - glVertex2f( Select_getWorkZone().d_work_max[nDim1], yb ); - glVertex2f( Select_getWorkZone().d_work_max[nDim1], ye ); - glEnd(); + gl().glColor4f( 1.0f, 0.0f, 0.0f, 1.0f ); + gl().glBegin( GL_LINES ); + gl().glVertex2f( xb, Select_getWorkZone().d_work_min[nDim2] ); + gl().glVertex2f( xe, Select_getWorkZone().d_work_min[nDim2] ); + gl().glVertex2f( xb, Select_getWorkZone().d_work_max[nDim2] ); + gl().glVertex2f( xe, Select_getWorkZone().d_work_max[nDim2] ); + gl().glVertex2f( Select_getWorkZone().d_work_min[nDim1], yb ); + gl().glVertex2f( Select_getWorkZone().d_work_min[nDim1], ye ); + gl().glVertex2f( Select_getWorkZone().d_work_max[nDim1], yb ); + gl().glVertex2f( Select_getWorkZone().d_work_max[nDim1], ye ); + gl().glEnd(); } } @@ -1689,10 +1499,10 @@ void XYWnd::XY_DrawBlockGrid(){ if( bs1 <= 0 && bs2 <= 0 ) // zero disables return; - glDisable( GL_TEXTURE_2D ); - glDisable( GL_TEXTURE_1D ); - glDisable( GL_DEPTH_TEST ); - glDisable( GL_BLEND ); + gl().glDisable( GL_TEXTURE_2D ); + gl().glDisable( GL_TEXTURE_1D ); + gl().glDisable( GL_DEPTH_TEST ); + gl().glDisable( GL_BLEND ); const float w = ( m_nWidth / 2 / m_fScale ); const float h = ( m_nHeight / 2 / m_fScale ); @@ -1715,29 +1525,29 @@ void XYWnd::XY_DrawBlockGrid(){ // draw major blocks - glColor3fv( vector3_to_array( g_xywindow_globals.color_gridblock ) ); - glLineWidth( 2 ); + gl().glColor3fv( vector3_to_array( g_xywindow_globals.color_gridblock ) ); + gl().glLineWidth( 2 ); - glBegin( GL_LINES ); + gl().glBegin( GL_LINES ); if( bs1 > 0 ) { for ( float x = xb; x <= xe; x += bs1 ) { - glVertex2f( x, yb ); - glVertex2f( x, ye ); + gl().glVertex2f( x, yb ); + gl().glVertex2f( x, ye ); } } if ( bs2 > 0 ) { for ( float y = yb; y <= ye; y += bs2 ) { - glVertex2f( xb, y ); - glVertex2f( xe, y ); + gl().glVertex2f( xb, y ); + gl().glVertex2f( xe, y ); } } - glEnd(); - glLineWidth( 1 ); + gl().glEnd(); + gl().glLineWidth( 1 ); #if 0 // draw coordinate text if needed @@ -1746,13 +1556,13 @@ void XYWnd::XY_DrawBlockGrid(){ for ( float x = xb; x < xe; x += bs1 ) for ( float y = yb; y < ye; y += bs2 ) { - glRasterPos2f( x + ( bs1 / 2 ), y + ( bs2 / 2 ) ); + gl().glRasterPos2f( x + ( bs1 / 2 ), y + ( bs2 / 2 ) ); sprintf( text, "%i,%i",(int)floor( x / bs1 ), (int)floor( y / bs2 ) ); GlobalOpenGL().drawString( text ); } } #endif - glColor4f( 0, 0, 0, 0 ); + gl().glColor4f( 0, 0, 0, 0 ); } void XYWnd::DrawCameraIcon( const Vector3& origin, const Vector3& angles ){ @@ -1769,21 +1579,21 @@ void XYWnd::DrawCameraIcon( const Vector3& origin, const Vector3& angles ){ degrees_to_radians( ( angles[CAMERA_YAW] > 180 ) ? ( 180.0f - angles[CAMERA_PITCH] ) : angles[CAMERA_PITCH] ) : degrees_to_radians( ( angles[CAMERA_YAW] < 270 && angles[CAMERA_YAW] > 90 ) ? ( 180.0f - angles[CAMERA_PITCH] ) : angles[CAMERA_PITCH] ); - glColor3f( 0.0, 0.0, 1.0 ); - glBegin( GL_LINE_STRIP ); - glVertex3f( x - box,y,0 ); - glVertex3f( x,y + ( box / 2 ),0 ); - glVertex3f( x + box,y,0 ); - glVertex3f( x,y - ( box / 2 ),0 ); - glVertex3f( x - box,y,0 ); - glVertex3f( x + box,y,0 ); - glEnd(); + gl().glColor3f( 0.0, 0.0, 1.0 ); + gl().glBegin( GL_LINE_STRIP ); + gl().glVertex3f( x - box,y,0 ); + gl().glVertex3f( x,y + ( box / 2 ),0 ); + gl().glVertex3f( x + box,y,0 ); + gl().glVertex3f( x,y - ( box / 2 ),0 ); + gl().glVertex3f( x - box,y,0 ); + gl().glVertex3f( x + box,y,0 ); + gl().glEnd(); - glBegin( GL_LINE_STRIP ); - glVertex3f( x + static_cast( fov * cos( a + c_pi / 4 ) ), y + static_cast( fov * sin( a + c_pi / 4 ) ), 0 ); - glVertex3f( x, y, 0 ); - glVertex3f( x + static_cast( fov * cos( a - c_pi / 4 ) ), y + static_cast( fov * sin( a - c_pi / 4 ) ), 0 ); - glEnd(); + gl().glBegin( GL_LINE_STRIP ); + gl().glVertex3f( x + static_cast( fov * cos( a + c_pi / 4 ) ), y + static_cast( fov * sin( a + c_pi / 4 ) ), 0 ); + gl().glVertex3f( x, y, 0 ); + gl().glVertex3f( x + static_cast( fov * cos( a - c_pi / 4 ) ), y + static_cast( fov * sin( a - c_pi / 4 ) ), 0 ); + gl().glEnd(); } @@ -1801,51 +1611,51 @@ void XYWnd::PaintSizeInfo( const int nDim1, const int nDim2 ){ const char* dimStrings[] = {"x:", "y:", "z:"}; - glColor3fv( vector3_to_array( g_xywindow_globals.color_selbrushes * .65f ) ); + gl().glColor3fv( vector3_to_array( g_xywindow_globals.color_selbrushes * .65f ) ); StringOutputStream dimensions( 16 ); Vector3 v( g_vector3_identity ); - glBegin( GL_LINE_STRIP ); + gl().glBegin( GL_LINE_STRIP ); v[nDim1] = min[nDim1]; v[nDim2] = min[nDim2] - 6.f / m_fScale; - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); v[nDim2] = min[nDim2] - 10.f / m_fScale; - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); v[nDim1] = max[nDim1]; - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); v[nDim2] = min[nDim2] - 6.f / m_fScale; - glVertex3fv( vector3_to_array( v ) ); - glEnd(); + gl().glVertex3fv( vector3_to_array( v ) ); + gl().glEnd(); - glBegin( GL_LINE_STRIP ); + gl().glBegin( GL_LINE_STRIP ); v[nDim2] = max[nDim2]; v[nDim1] = max[nDim1] + 6.f / m_fScale; - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); v[nDim1] = max[nDim1] + 10.f / m_fScale; - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); v[nDim2] = min[nDim2]; - glVertex3fv( vector3_to_array( v ) ); + gl().glVertex3fv( vector3_to_array( v ) ); v[nDim1] = max[nDim1] + 6.f / m_fScale; - glVertex3fv( vector3_to_array( v ) ); - glEnd(); + gl().glVertex3fv( vector3_to_array( v ) ); + gl().glEnd(); const int fontHeight = GlobalOpenGL().m_font->getPixelHeight(); v[nDim1] = mid[nDim1]; v[nDim2] = min[nDim2] - ( 10 + 2 + fontHeight ) / m_fScale; - glRasterPos3fv( vector3_to_array( v ) ); + gl().glRasterPos3fv( vector3_to_array( v ) ); GlobalOpenGL().drawString( dimensions( dimStrings[nDim1], size[nDim1] ) ); v[nDim1] = max[nDim1] + 16.f / m_fScale; v[nDim2] = mid[nDim2] - fontHeight / m_fScale / 2; - glRasterPos3fv( vector3_to_array( v ) ); + gl().glRasterPos3fv( vector3_to_array( v ) ); GlobalOpenGL().drawString( dimensions( dimStrings[nDim2], size[nDim2] ) ); v[nDim1] = min[nDim1] + 4.f; v[nDim2] = max[nDim2] + 5.f / m_fScale; - glRasterPos3fv( vector3_to_array( v ) ); + gl().glRasterPos3fv( vector3_to_array( v ) ); GlobalOpenGL().drawString( dimensions( "(", dimStrings[nDim1], min[nDim1], " ", dimStrings[nDim2], max[nDim2], ")" ) ); } @@ -1995,26 +1805,15 @@ void XYWnd::updateModelview(){ void XYWnd::XY_Draw(){ // globalOutputStream() << "XY_Draw()\n"; -/* - int maxSamples; - glGetIntegerv(GL_MAX_SAMPLES,&maxSamples); - globalOutputStream() << maxSamples << " GL_MAX_SAMPLES\n"; - int curSamples; - glGetIntegerv(GL_SAMPLE_BUFFERS,&curSamples); - globalOutputStream() << curSamples << " GL_SAMPLE_BUFFERS\n"; - glGetIntegerv(GL_SAMPLES,&curSamples); - globalOutputStream() << curSamples << " GL_SAMPLES\n"; -*/ - fbo_get()->start(); // // clear // - glViewport( 0, 0, m_nWidth, m_nHeight ); - glClearColor( g_xywindow_globals.color_gridback[0], + gl().glViewport( 0, 0, m_nWidth, m_nHeight ); + gl().glClearColor( g_xywindow_globals.color_gridback[0], g_xywindow_globals.color_gridback[1], g_xywindow_globals.color_gridback[2], 0 ); - glClear( GL_COLOR_BUFFER_BIT ); + gl().glClear( GL_COLOR_BUFFER_BIT ); extern void Renderer_ResetStats(); Renderer_ResetStats(); @@ -2023,24 +1822,24 @@ void XYWnd::XY_Draw(){ // set up viewpoint // - glMatrixMode( GL_PROJECTION ); - glLoadMatrixf( reinterpret_cast( &m_projection ) ); + gl().glMatrixMode( GL_PROJECTION ); + gl().glLoadMatrixf( reinterpret_cast( &m_projection ) ); - glMatrixMode( GL_MODELVIEW ); - glLoadIdentity(); - glScalef( m_fScale, m_fScale, 1 ); + gl().glMatrixMode( GL_MODELVIEW ); + gl().glLoadIdentity(); + gl().glScalef( m_fScale, m_fScale, 1 ); NDIM1NDIM2( m_viewType ) - glTranslatef( -m_vOrigin[nDim1], -m_vOrigin[nDim2], 0 ); + gl().glTranslatef( -m_vOrigin[nDim1], -m_vOrigin[nDim2], 0 ); - glDisable( GL_LINE_STIPPLE ); - glLineWidth( 1 ); - glDisableClientState( GL_TEXTURE_COORD_ARRAY ); - glDisableClientState( GL_NORMAL_ARRAY ); - glDisableClientState( GL_COLOR_ARRAY ); - glDisable( GL_TEXTURE_2D ); - glDisable( GL_LIGHTING ); - glDisable( GL_COLOR_MATERIAL ); - glDisable( GL_DEPTH_TEST ); + gl().glDisable( GL_LINE_STIPPLE ); + gl().glLineWidth( 1 ); + gl().glDisableClientState( GL_TEXTURE_COORD_ARRAY ); + gl().glDisableClientState( GL_NORMAL_ARRAY ); + gl().glDisableClientState( GL_COLOR_ARRAY ); + gl().glDisable( GL_TEXTURE_2D ); + gl().glDisable( GL_LIGHTING ); + gl().glDisable( GL_COLOR_MATERIAL ); + gl().glDisable( GL_DEPTH_TEST ); m_backgroundImage.render( m_viewType ); @@ -2050,9 +1849,9 @@ void XYWnd::XY_Draw(){ XY_DrawBlockGrid(); } - glLoadMatrixf( reinterpret_cast( &m_modelview ) ); + gl().glLoadMatrixf( reinterpret_cast( &m_modelview ) ); - unsigned int globalstate = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_POLYGONSMOOTH | RENDER_LINESMOOTH; + unsigned int globalstate = RENDER_COLOURARRAY | RENDER_COLOURWRITE; if ( !g_xywindow_globals.m_bNoStipple ) { globalstate |= RENDER_LINESTIPPLE; } @@ -2067,32 +1866,30 @@ void XYWnd::XY_Draw(){ GlobalOpenGL_debugAssertNoErrors(); } - glDepthMask( GL_FALSE ); + gl().glDepthMask( GL_FALSE ); GlobalOpenGL_debugAssertNoErrors(); - glLoadMatrixf( reinterpret_cast( &m_modelview ) ); + gl().glLoadMatrixf( reinterpret_cast( &m_modelview ) ); GlobalOpenGL_debugAssertNoErrors(); - glDisable( GL_LINE_STIPPLE ); + gl().glDisable( GL_LINE_STIPPLE ); GlobalOpenGL_debugAssertNoErrors(); - glLineWidth( 1 ); + gl().glLineWidth( 1 ); GlobalOpenGL_debugAssertNoErrors(); - if ( GlobalOpenGL().GL_1_3() ) { - glActiveTexture( GL_TEXTURE0 ); - glClientActiveTexture( GL_TEXTURE0 ); - } - glDisableClientState( GL_TEXTURE_COORD_ARRAY ); + gl().glActiveTexture( GL_TEXTURE0 ); + gl().glClientActiveTexture( GL_TEXTURE0 ); + gl().glDisableClientState( GL_TEXTURE_COORD_ARRAY ); GlobalOpenGL_debugAssertNoErrors(); - glDisableClientState( GL_NORMAL_ARRAY ); + gl().glDisableClientState( GL_NORMAL_ARRAY ); GlobalOpenGL_debugAssertNoErrors(); - glDisableClientState( GL_COLOR_ARRAY ); + gl().glDisableClientState( GL_COLOR_ARRAY ); GlobalOpenGL_debugAssertNoErrors(); - glDisable( GL_TEXTURE_2D ); + gl().glDisable( GL_TEXTURE_2D ); GlobalOpenGL_debugAssertNoErrors(); - glDisable( GL_LIGHTING ); + gl().glDisable( GL_LIGHTING ); GlobalOpenGL_debugAssertNoErrors(); - glDisable( GL_COLOR_MATERIAL ); + gl().glDisable( GL_COLOR_MATERIAL ); GlobalOpenGL_debugAssertNoErrors(); GlobalOpenGL_debugAssertNoErrors(); @@ -2107,36 +1904,28 @@ void XYWnd::XY_Draw(){ { // reset modelview - glLoadIdentity(); - glScalef( m_fScale, m_fScale, 1 ); - glTranslatef( -m_vOrigin[nDim1], -m_vOrigin[nDim2], 0 ); + gl().glLoadIdentity(); + gl().glScalef( m_fScale, m_fScale, 1 ); + gl().glTranslatef( -m_vOrigin[nDim1], -m_vOrigin[nDim2], 0 ); Feedback_draw2D( m_viewType ); } if( g_camwindow_globals.m_showStats ){ - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - glOrtho( 0, m_nWidth, 0, m_nHeight, 0, 1 ); + gl().glMatrixMode( GL_PROJECTION ); + gl().glLoadIdentity(); + gl().glOrtho( 0, m_nWidth, 0, m_nHeight, 0, 1 ); - glMatrixMode( GL_MODELVIEW ); - glLoadIdentity(); + gl().glMatrixMode( GL_MODELVIEW ); + gl().glLoadIdentity(); - glColor3fv( vector3_to_array( g_xywindow_globals.color_viewname ) ); + gl().glColor3fv( vector3_to_array( g_xywindow_globals.color_viewname ) ); - glRasterPos3f( 2.f, 0.f, 0.0f ); + gl().glRasterPos3f( 2.f, 0.f, 0.0f ); extern const char* Renderer_GetStats(); GlobalOpenGL().drawString( StringOutputStream( 64 )( Renderer_GetStats(), " | f2f: ", m_render_time.elapsed_msec() ) ); m_render_time.start(); } - - fbo_get()->save(); - - overlayDraw(); //outline camera crosshair rectangle - - GlobalOpenGL_debugAssertNoErrors(); - - glFinish(); } void XYWnd_MouseToPoint( XYWnd* xywnd, int x, int y, Vector3& point ){ @@ -2153,6 +1942,7 @@ void XYWnd::OnEntityCreate( const char* item ){ const float offset = std::max( 8.f, GetSnapGridSize() ) * g_entityCreationOffset; NDIM1NDIM2( m_viewType ) point += g_vector3_axes[nDim1] * offset; + (void)nDim2; Entity_createFromSelection( item, point ); } @@ -2230,20 +2020,20 @@ void XY_ZoomOut(){ ToggleShown g_xy_top_shown( true ); -void XY_Top_Shown_Construct( GtkWindow* parent ){ - g_xy_top_shown.connect( GTK_WIDGET( parent ) ); +void XY_Top_Shown_Construct( QWidget* parent ){ + g_xy_top_shown.connect( parent ); } ToggleShown g_yz_side_shown( false ); -void YZ_Side_Shown_Construct( GtkWindow* parent ){ - g_yz_side_shown.connect( GTK_WIDGET( parent ) ); +void YZ_Side_Shown_Construct( QWidget* parent ){ + g_yz_side_shown.connect( parent ); } ToggleShown g_xz_front_shown( false ); -void XZ_Front_Shown_Construct( GtkWindow* parent ){ - g_xz_front_shown.connect( GTK_WIDGET( parent ) ); +void XZ_Front_Shown_Construct( QWidget* parent ){ + g_xz_front_shown.connect( parent ); } @@ -2260,7 +2050,7 @@ public: void unrealise(){ if ( ++m_unrealised == 1 ) { if ( XYWnd::m_mnuDrop != 0 ) { - gtk_widget_destroy( GTK_WIDGET( XYWnd::m_mnuDrop ) ); + delete XYWnd::m_mnuDrop; XYWnd::m_mnuDrop = 0; } } @@ -2320,32 +2110,28 @@ void ShowAnglesToggle(){ UpdateAllWindows(); } -BoolExportCaller g_show_blocks_caller( g_xywindow_globals_private.show_blocks ); -ToggleItem g_show_blocks( g_show_blocks_caller ); +ToggleItem g_show_blocks( BoolExportCaller( g_xywindow_globals_private.show_blocks ) ); void ShowBlocksToggle(){ g_xywindow_globals_private.show_blocks ^= 1; g_show_blocks.update(); XY_UpdateAllWindows(); } -BoolExportCaller g_show_coordinates_caller( g_xywindow_globals_private.show_coordinates ); -ToggleItem g_show_coordinates( g_show_coordinates_caller ); +ToggleItem g_show_coordinates( BoolExportCaller( g_xywindow_globals_private.show_coordinates ) ); void ShowCoordinatesToggle(){ g_xywindow_globals_private.show_coordinates ^= 1; g_show_coordinates.update(); XY_UpdateAllWindows(); } -BoolExportCaller g_show_outline_caller( g_xywindow_globals_private.show_outline ); -ToggleItem g_show_outline( g_show_outline_caller ); +ToggleItem g_show_outline( BoolExportCaller( g_xywindow_globals_private.show_outline ) ); void ShowOutlineToggle(){ g_xywindow_globals_private.show_outline ^= 1; g_show_outline.update(); XY_UpdateAllWindows(); } -BoolExportCaller g_show_axes_caller( g_xywindow_globals_private.show_axis ); -ToggleItem g_show_axes( g_show_axes_caller ); +ToggleItem g_show_axes( BoolExportCaller( g_xywindow_globals_private.show_axis ) ); void ShowAxesToggle(){ g_xywindow_globals_private.show_axis ^= 1; g_show_axes.update(); @@ -2353,8 +2139,7 @@ void ShowAxesToggle(){ } -BoolExportCaller g_show_workzone_caller( g_xywindow_globals_private.show_workzone ); -ToggleItem g_show_workzone( g_show_workzone_caller ); +ToggleItem g_show_workzone( BoolExportCaller( g_xywindow_globals_private.show_workzone ) ); void ShowWorkzoneToggle(){ g_xywindow_globals_private.show_workzone ^= 1; g_show_workzone.update(); @@ -2387,24 +2172,21 @@ void Texdef_ToggleMoveLock(){ } */ -BoolExportCaller g_show_size_caller( g_xywindow_globals_private.m_bShowSize ); -ToggleItem g_show_size_item( g_show_size_caller ); +ToggleItem g_show_size_item( BoolExportCaller( g_xywindow_globals_private.m_bShowSize ) ); void ToggleShowSizeInfo(){ g_xywindow_globals_private.m_bShowSize = !g_xywindow_globals_private.m_bShowSize; g_show_size_item.update(); XY_UpdateAllWindows(); } -BoolExportCaller g_show_crosshair_caller( g_bCrossHairs ); -ToggleItem g_show_crosshair_item( g_show_crosshair_caller ); +ToggleItem g_show_crosshair_item{ BoolExportCaller( g_bCrossHairs ) }; void ToggleShowCrosshair(){ g_bCrossHairs ^= 1; g_show_crosshair_item.update(); XY_UpdateAllWindows(); } -BoolExportCaller g_show_grid_caller( g_xywindow_globals_private.d_showgrid ); -ToggleItem g_show_grid_item( g_show_grid_caller ); +ToggleItem g_show_grid_item( BoolExportCaller( g_xywindow_globals_private.d_showgrid ) ); void ToggleShowGrid(){ g_xywindow_globals_private.d_showgrid = !g_xywindow_globals_private.d_showgrid; g_show_grid_item.update(); @@ -2413,13 +2195,6 @@ void ToggleShowGrid(){ void MSAAImport( int value ){ g_xywindow_globals_private.m_MSAA = value ? 1 << value : value; - g_pParentWnd->forEachXYWnd( []( XYWnd* xywnd ){ -#if NV_DRIVER_GAMMA_BUG - xywnd->fbo_get()->reset( xywnd->Width(), xywnd->Height(), g_xywindow_globals_private.m_MSAA, true ); -#else - xywnd->fbo_get()->reset( xywnd->Width(), xywnd->Height(), g_xywindow_globals_private.m_MSAA, false ); -#endif - } ); } typedef FreeCaller1 MSAAImportCaller; @@ -2439,9 +2214,9 @@ typedef FreeCaller1 MSAAExportCaller; void XYShow_registerCommands(){ - GlobalToggles_insert( "ShowSize2d", FreeCaller(), ToggleItem::AddCallbackCaller( g_show_size_item ), Accelerator( 'J' ) ); - GlobalToggles_insert( "ToggleCrosshairs", FreeCaller(), ToggleItem::AddCallbackCaller( g_show_crosshair_item ), Accelerator( 'X', GDK_SHIFT_MASK ) ); - GlobalToggles_insert( "ToggleGrid", FreeCaller(), ToggleItem::AddCallbackCaller( g_show_grid_item ), Accelerator( '0' ) ); + GlobalToggles_insert( "ShowSize2d", FreeCaller(), ToggleItem::AddCallbackCaller( g_show_size_item ), QKeySequence( "J" ) ); + GlobalToggles_insert( "ToggleCrosshairs", FreeCaller(), ToggleItem::AddCallbackCaller( g_show_crosshair_item ), QKeySequence( "Shift+X" ) ); + GlobalToggles_insert( "ToggleGrid", FreeCaller(), ToggleItem::AddCallbackCaller( g_show_grid_item ), QKeySequence( "0" ) ); GlobalToggles_insert( "ShowAngles", FreeCaller(), ToggleItem::AddCallbackCaller( g_show_angles ) ); GlobalToggles_insert( "ShowNames", FreeCaller(), ToggleItem::AddCallbackCaller( g_show_names ) ); @@ -2467,7 +2242,7 @@ void Orthographic_constructPreferences( PreferencesPage& page ){ page.appendCheckBox( "", "Chase mouse during drags", g_xywindow_globals_private.m_bChaseMouse ); page.appendCheckBox( "", "Zoom to Mouse pointer", g_xywindow_globals_private.m_bZoomToPointer ); - if( GlobalOpenGL().support_ARB_framebuffer_object ){ + { const char* samples[] = { "0", "2", "4", "8", "16", "32" }; page.appendCombo( @@ -2495,15 +2270,15 @@ void XYWindow_Construct(){ GlobalToggles_insert( "ToggleView", ToggleShown::ToggleCaller( g_xy_top_shown ), ToggleItem::AddCallbackCaller( g_xy_top_shown.m_item ) ); GlobalToggles_insert( "ToggleSideView", ToggleShown::ToggleCaller( g_yz_side_shown ), ToggleItem::AddCallbackCaller( g_yz_side_shown.m_item ) ); GlobalToggles_insert( "ToggleFrontView", ToggleShown::ToggleCaller( g_xz_front_shown ), ToggleItem::AddCallbackCaller( g_xz_front_shown.m_item ) ); - GlobalCommands_insert( "NextView", FreeCaller(), Accelerator( GDK_KEY_Tab, GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "ZoomIn", FreeCaller(), Accelerator( GDK_KEY_Delete ) ); - GlobalCommands_insert( "ZoomOut", FreeCaller(), Accelerator( GDK_KEY_Insert ) ); - GlobalCommands_insert( "ViewTop", FreeCaller(), Accelerator( GDK_KEY_KP_7 ) ); - GlobalCommands_insert( "ViewFront", FreeCaller(), Accelerator( GDK_KEY_KP_1 ) ); - GlobalCommands_insert( "ViewSide", FreeCaller(), Accelerator( GDK_KEY_KP_3 ) ); + GlobalCommands_insert( "NextView", FreeCaller(), QKeySequence( "Ctrl+Tab" ) ); + GlobalCommands_insert( "ZoomIn", FreeCaller(), QKeySequence( "Delete" ) ); + GlobalCommands_insert( "ZoomOut", FreeCaller(), QKeySequence( "Insert" ) ); + GlobalCommands_insert( "ViewTop", FreeCaller(), QKeySequence( Qt::Key_7 + Qt::KeypadModifier ) ); + GlobalCommands_insert( "ViewFront", FreeCaller(), QKeySequence( Qt::Key_1 + Qt::KeypadModifier ) ); + GlobalCommands_insert( "ViewSide", FreeCaller(), QKeySequence( Qt::Key_3 + Qt::KeypadModifier ) ); GlobalCommands_insert( "Zoom100", FreeCaller() ); - GlobalCommands_insert( "CenterXYView", FreeCaller(), Accelerator( GDK_KEY_Tab, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); - GlobalCommands_insert( "XYFocusOnSelected", FreeCaller(), Accelerator( GDK_KEY_grave ) ); + GlobalCommands_insert( "CenterXYView", FreeCaller(), QKeySequence( "Ctrl+Shift+Tab" ) ); + GlobalCommands_insert( "XYFocusOnSelected", FreeCaller(), QKeySequence( "`" ) ); GlobalPreferenceSystem().registerPreference( "XYMSAA", IntImportStringCaller( g_xywindow_globals_private.m_MSAA ), IntExportStringCaller( g_xywindow_globals_private.m_MSAA ) ); GlobalPreferenceSystem().registerPreference( "2DZoomInToPointer", BoolImportStringCaller( g_xywindow_globals_private.m_bZoomToPointer ), BoolExportStringCaller( g_xywindow_globals_private.m_bZoomToPointer ) ); diff --git a/radiant/xywindow.h b/radiant/xywindow.h index e08a899d..b5896bd5 100644 --- a/radiant/xywindow.h +++ b/radiant/xywindow.h @@ -25,7 +25,6 @@ #include "signal/signal.h" #include "gtkutil/cursor.h" -#include "gtkutil/window.h" #include "gtkutil/xorrectangle.h" #include "view.h" #include "map.h" @@ -40,8 +39,6 @@ namespace scene { class Node; } -typedef struct _GtkWindow GtkWindow; -typedef struct _GtkMenu GtkMenu; inline const char* ViewType_getTitle( VIEWTYPE viewtype ){ if ( viewtype == XY ) { @@ -76,37 +73,30 @@ private: }; #include "timer.h" -#include "gtkutil/idledraw.h" -class FBO; +class QWidget; class XYWnd { - GtkWidget* m_gl_widget; - guint m_sizeHandler; - guint m_exposeHandler; + QWidget* m_gl_widget; DeferredDraw m_deferredDraw; - IdleDraw m_deferredOverlayDraw; - DeferredMotion m_deferred_motion; - FBO* m_fbo; public: - FBO* fbo_get(); - GtkWindow* m_parent; + QWidget* m_parent; XYWnd(); ~XYWnd(); void queueDraw(){ m_deferredDraw.draw(); } - GtkWidget* GetWidget(){ + QWidget* GetWidget(){ return m_gl_widget; } SelectionSystemWindowObserver* m_window_observer; XORRectangle m_XORRectangle; - WindowPositionTracker m_positionTracker; + rect_t m_XORRect; static void captureStates(); static void releaseStates(); @@ -119,11 +109,9 @@ public: void SetOrigin( const Vector3& origin ); void Scroll( int x, int y ); + bool m_drawRequired{}; // whether complete redraw is required, or just overlay update is enough void XY_Draw(); - bool overlayStart(); - void overlayFinish(); void overlayDraw(); - void overlayUpdate(); void DrawCameraIcon( const Vector3& origin, const Vector3& angles ); void XY_DrawBlockGrid(); void XY_DrawAxis(); @@ -142,12 +130,10 @@ public: void Move_Begin(); void Move_End(); bool m_move_started; - guint m_move_focusOut; void Zoom_Begin( int x, int y ); void Zoom_End(); bool m_zoom_started; - guint m_zoom_focusOut; void ZoomIn(); void ZoomOut(); @@ -158,7 +144,7 @@ public: void SetActive( bool b ){ m_bActive = b; - overlayUpdate(); + queueDraw(); }; bool Active(){ return m_bActive; @@ -169,13 +155,12 @@ public: void SetViewType( VIEWTYPE n ); bool m_bActive; - static GtkMenu* m_mnuDrop; + static class QMenu* m_mnuDrop; int m_chasemouse_current_x, m_chasemouse_current_y; int m_chasemouse_delta_x, m_chasemouse_delta_y; - guint m_chasemouse_handler; void ChaseMouse(); bool chaseMouseMotion( int x, int y ); @@ -257,6 +242,7 @@ public: }; inline void XYWnd_Update( XYWnd& xywnd ){ + xywnd.m_drawRequired = true; xywnd.queueDraw(); } @@ -264,38 +250,20 @@ void XY_Centralize(); struct xywindow_globals_t { - Vector3 color_gridback; - Vector3 color_gridminor; - Vector3 color_gridmajor; - Vector3 color_gridblock; - Vector3 color_gridtext; - Vector3 color_brushes; - Vector3 color_selbrushes; - Vector3 color_clipper; - Vector3 color_viewname; - Vector3 AxisColorX; - Vector3 AxisColorY; - Vector3 AxisColorZ; - - bool m_bNoStipple; - - xywindow_globals_t() : - color_gridback( 0.77f, 0.77f, 0.77f ), - color_gridminor( 0.83f, 0.83f, 0.83f ), - color_gridmajor( 0.89f, 0.89f, 0.89f ), - color_gridblock( 1.0f, 1.0f, 1.0f ), - color_gridtext( 0.f, 0.f, 0.f ), - color_brushes( 0.f, 0.f, 0.f ), - color_selbrushes( 1.f, 0.f, 0.f ), - color_clipper( 0.f, 0.f, 1.f ), - color_viewname( 0.5f, 0.f, 0.75f ), - - AxisColorX( 1.f, 0.f, 0.f ), - AxisColorY( 0.f, 1.f, 0.f ), - AxisColorZ( 0.f, 0.f, 1.f ), - m_bNoStipple( true ){ - } + Vector3 color_gridback = { .225803f, .225803f, .225803f }; + Vector3 color_gridminor = { .254902f, .254902f, .254902f }; + Vector3 color_gridmajor = { .294118f, .294118f, .294118f }; + Vector3 color_gridblock = { 1.0f, 1.0f, 1.0f }; + Vector3 color_gridtext = { .972549f, .972549f, .972549f }; + Vector3 color_brushes = { 0.f, 0.f, 0.f }; + Vector3 color_selbrushes = { 1.0f, 0.627451f, 0.0f }; + Vector3 color_clipper = { 0.0f, 0.0f, 1.0f }; + Vector3 color_viewname = { 0.516136f, 0.516136f, 0.516136f }; + Vector3 AxisColorX = { 1.f, 0.f, 0.f }; + Vector3 AxisColorY = { 0.f, 1.f, 0.f }; + Vector3 AxisColorZ = { 0.f, 0.f, 1.f }; + bool m_bNoStipple = true; }; extern xywindow_globals_t g_xywindow_globals; @@ -303,15 +271,13 @@ extern xywindow_globals_t g_xywindow_globals; VIEWTYPE GlobalXYWnd_getCurrentViewType(); -typedef struct _GtkWindow GtkWindow; -void XY_Top_Shown_Construct( GtkWindow* parent ); -void YZ_Side_Shown_Construct( GtkWindow* parent ); -void XZ_Front_Shown_Construct( GtkWindow* parent ); +void XY_Top_Shown_Construct( QWidget* parent ); +void YZ_Side_Shown_Construct( QWidget* parent ); +void XZ_Front_Shown_Construct( QWidget* parent ); void XYWindow_Construct(); void XYWindow_Destroy(); -void WXY_Print(); void WXY_SetBackgroundImage(); void XYShow_registerCommands(); diff --git a/setup/data/tools/.gtkrc-2.0.win b/setup/data/tools/.gtkrc-2.0.win deleted file mode 100644 index c5a20a5e..00000000 --- a/setup/data/tools/.gtkrc-2.0.win +++ /dev/null @@ -1,9 +0,0 @@ -gtk-menu-popup-delay = 10 - -binding "ms-windows-tree-view" -{ - bind "Right" { "expand-collapse-cursor-row" (1,1,0) } - bind "Left" { "expand-collapse-cursor-row" (1,0,0) } -} - -class "GtkTreeView" binding "ms-windows-tree-view" \ No newline at end of file diff --git a/setup/data/tools/bitmaps/MyriadPro-Regular.ttf b/setup/data/tools/bitmaps/MyriadPro-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3d98ec11d3ff394cccd7963ddc7cf3fcfdff0eaa GIT binary patch literal 97260 zcmdSC2Y6dW);B&gSGL@nB+ErEl59!tMb*9c8ryN?6vuWFr;y@=5LyTc326ipdWR4o zu%Rrlp)AX?v<)mTWNFL7!U74|EK6BJ3oOL)|2OwavTVyq_Wi!+|2&_QtE+PF%$YOi zoH=dIC6o{ng%=qi)m7bfK~WhEgkHQ5-!8AO?`bQ4?5{KN`3-#5G}PABN6Qt>geF{o z&jSse9o>(9_+%%c`S{qfu%UZq^;=_??!oWx5u!45bmtXba%~0P)9w8F1uF(e-rM?a z2O(jv5fYfac<|hju`wdx`Vssdw0QZ2!zx$ZvxLMgC*=4~OBM|-eElDr6}UePzuT7J z3;8#J44-T9Ic>>`wHG9kMZd=9&j<-Qx_s4w!Pef(dkKm8iI9M`D+VtZ5g3_?-@kcfY{kNtZrkh~(>g5Uoj8x~t~|Hx15DgF)nE$Je1@oRo3 z6|brkKjTMw7u`bw@Mb4-;=2~FkR?&QDIV{9KzsYFJ<=b!OS8(!YQahy2l3}U9=kaR{#wGc;=**ua$p22q- zQi(%J@5FaK#6N`~=I!t^ zy@8n75t79gl6aO(T3IdHx`njRFLC@6quz?oyGRT98lTq?8NY_UM_Pn5Qp~Qw^^f9r zrTd(K-@YQ5^c%pm4fo~}L1+goC1^W|gs}{gjB(7MGl5-<2mP0EJkV?sOOFygDqgz+_jkaWOtHa^?P_ZZg#^m#W?vmb%u zA92r*z`+gZi{snRAt-^nCiKbi?{ko^$BqN8YMj5u@ddkc%;m*Dp99~6&n^GV=fL;i zbD+RnrI99%Z-0jnfWH5L@p1h79OUz{W0->)oPWY`9P`QNMZ!Oy1K)%9&p%@hd=EYc zn5!o7jIoPzKKTs#6KP<&GiZ~QgP!^LIh}AEaX8O#7U`JN5~pW>=Ur$wYwT-wHBsSw z3ON1+d_Fl&C!K{2Bu$u)?>X;*{@v#+_t`G;Bj*Xu zm;TP+Rn9M*XKA^_7vHgb(m>xB`xcBz4U&J;q!}~u0j@_h$J;B?6EZ}|dd-xgOiDSGO z^Z6*?uLO@^?)f;m+~9O7tRDMW*o5Ei#+bOw4<-V;7@xU3(&00g@%-L(B$T%$XvK4i zNQ;~v`8{1@{}J)!#v{8F*K=HPzU8>$ZT`iLD}K#PQZICnR$&0woDbgp9A_;K2T2wd z;P(^~AXiLN~v1zIA|y`Df18;j{$wQHHVqfy8*>_46IqNpO8DVAJE^ zYmz`;0N#JZJiP{;Lcn*o5sKf^SpYE!g_y?}z!*c?aa7|d$C2v(Y{$6jGz=p$Sg5%oXl1<)0exW3?>bLe?K zG{g0ZRvb%3TxMf#vd2Eg@evLezDviEf+JQs#@>dkRN=is{5@yvGnzB@C9TJ2j&mFs z10M(BbK;#BJ~tQ}KY$YxT?YC09BAxOtPdw~{1$v2L~^-41^j2=eHLrL+=ohskVhi$ zkN*koLnG?eM5g1`1-{b|nJf_J?PMbfgyz11ZlKrDF_y?)W`AOT7d8kxgU1z zg;n&>80;$7#?k$*k!rxF86peFLb8Yqlf`5SSxT0XbI5YC0{Z$&vWkq5)npAhm#ih{k#*#J zasj!JTtqG=>&Yc#1GyA*wuxK@irzvlCtJxjP~Hx*lUzY|kt@knWH;GEt|r%zYsq!w zdU6A~k=#UXCby7V$!+9zatExpz2q*kkK9e}A@`E~o+iJ8{q}qEETr9Y?~=cg_n_JQjeI~pB!4F#k&nqI<7hlhpovsNlV~zcp{Z0$byQE&XgW1eBQ?tXKj}^Z`gZ_ii5$`-n1ql}5=O!yg(5*8(U4~fqJ%_?g=CF` zv`rw1kU>dUTT{UCTCBr*$U^8)#E3OC1Nu@H$tF1@7ZzeZDIkT!Of0aTZNyF-q=*zl z%PS>i&sP@pt0A?dj?}{{XoQ8@3~j5Gw2^kwK|09{(nY#S4?G{eWEOFfJ~Erk zA#=$*(og1-0Wyg3ak|_Fn!Fm+cN=JJFR1Mv(A&MBwO@hSIITSdYU8x_DCq1lP}&oq zwWmR6pfVN+4&eN;1k!jN=yfGo2EAu3SqklVE4c}__-a-NjdGZr$4o4XWzy}igU%rr z(bb^mr@$dYWCdoYg5^UOT~03M8XUN0Gr3-*3m2rbz+?=jJ9!e8*B_{Zg)==1Wnt`b z_5|$Z^BH3Sn9s|=SDV0D+ufYCOXMm7?&AD(Gx>(rLvvY08)*}5CKu2)+5+u`0Qb_r zT3~29c>z>7OxM!w^fvku{Tuy~{=_1fhSjoOww^u4-VumUDs&3B2=59mnNDVtHA6Pv zAp0yJD4;rEIN+*){Q*x091A!V7!s%ptPJc7yex2k;NifN@=STZe2;ve{5kpGg2I9< zL7hQMf-VZ$9&}64!$D66y%NlV9l>*hZwNjVd^{vOq$gw~G(CTU3A4MNxaB-ionIb|_tXQjfL~%kH zr|eO#QSMP5RDPyBrHWFSR9&hqsuxrzVv}RLVy}z+TkQAhLUpfty?Vd;Xq+rAJ8mTI zvAFN!i{r0~Kb}yXus7jvi7|=IiCYujNj#qTlO{@2tl6k}L31K0IjJ*gPtv=|fyuSW zYm@IuelI08r6*;3$~!4PV?AA#`c&$dT8DN>yG#4D_A{ME*RETyJD~eWZ_>}!-==?B ze-O8-};_SY3sD@v^{3~ z(w=6owh!C)*q^a~;s|mSJC-Ca^`WtnBO%a)XFE!$i6R@uq&sB%Yn zYx&ypJ>~n#4_B~?%!1oMdqeG^+Ry4@>RRj8)ZJ5ev_7tWp#G}*XB$|9tzo!feZxHs z?=~E3jA%484mIA?_-x~sO{S*Grh%qCO|Lfnty$KrX&!36sri}a6D@Hq#VyNQwzNFh z@?6VjtzoUnt|WX8KQ{@oSUmDW|=wX*BBu0vh_?$&e< zbU)mEwEL%?)Sj-Ml|480yfl-{w9FiuxohTYGmp*usW+t8(L2(+zxShA%2`9R9-j4v zQ|63uraB9qwa#AWTIV&+N1U%ZzwBdumc9dhPxrmr_gw)&x28e*@Ml4YX+|y+&}onP}or1Q1(#e(DI@ChYk+C zGW6ks+y%7@HZ0h`;I)NpVcNpZg}WB+UHJJT!=eio-LdGAMehwq4O@oi4qr3;;P8pX zX^WREzHRYqi(N|$ONN$QwdCNELrcC~s#{vSbotW#OP^kPYME_W{j&aLTbA9h?3rcX zo})ac^qh6)>^$eSKePJVHDPNy*KAqy^qP;(W#^WkyB_N${^_RMH4y@HIn-Wj8= z(Z4{m$aXPUD~veCejpFSzb)`q?0Ug0=ye9G#bz#yRR&&P8!?bi57?2flx1iDHShG@*O0V%GeGl7yx4CGlNzVtVH%lqM`8V^_OIUMjh| z7|#@KK$-u2k4XRW2{6ZKyNh|?Xl)Uo7G}4=2DBzZZ)f7)pCPg7pPLks*|Zo z87Qam74u5sDmrY{_TuiYuG)$gdwf}y)oQQnZ0T<4UBohLvg}zVhdQ-$y)$&-Ak$Xs zE&BBQByCSs#XuP5AbIS2_8)cwupbYNBoi72MphV$#(_Vh#ir){1-b!I=&4zl_SfIh z+8NH8s$SYxMU6Qu&y<;&A#>169RjWEocsg3et7QCvf+9CE3Dm>6T(K1ve`>QE!}J8k8CNL+gUlYu47$pj1TwRHe+ zbCKN?YHMBDaY>`lTvNTUy~;MrDC{uTZM=U*Om12KI$L*fJ1Z{Auve#+n)DV9ALTSe zc8D}2QV^#eP>%Fl<=8eVhi@#H;}$Tf^#-f$#o9|QsohN369-Nl{mn!F`Vws@$F`9V za9t1~YP~JWXpU6{I;G1le3Tx3g7heRc=*V zjdrz}hL_I2@y3CQGFDkM|GI1Y%gPyhNWY#bYh&1j`dwG1UBnc%3U;yX3iN9Nac9GS z7K--FD$uV=Zv{=$kjkS+@t-NbDE;cIQfVwvV_TpFZUDy;wcJ(#?Y+I+q#TMVI#0gx zvXII>92d#t-_YX`f8pa*>63r_k>*z7dkc8<0a!`Uxv!&@Z ziD_a#utDFWe7@0!8dO(ZLu2bq@ab_rOdI=we#EW^ym3-Xpi{9aqr@)~$&S*&b@Y)JlB%@yHP>L>_GP8Djn$g=WrK^B ztus@-t!C3zb&dvmdG$zJ_sy&G8QRJO{Li5+47GyB7TUnyS=8!*-P@*IB{I2Qml;=c zO9Q2Y^#uj?*+oV5rE&F(W)GAXS9EPyHLR^MwG~uWR~K0`9a)uyv#TsKR4mL{-NmDl zj7vlM1;!Qv8w6Zq)mo`J8k3T42J7enH{H|idW-7j&za+T?=OOoptCqJS=+O8QS$|MA+9~Ub#QcVmDy3PjB3m? zH!^K$c5ZQ0WLai*IdEoj(|#OZCDhhfjw8&YC<-N7lmkzny+BTv zZb>qs+4eG%axkVy>1pS@z~!4EU+DebM#QQuUEp22HC+{ef7SF2*M)T3*S4?g zUScoRN${J<^ zSU3NOm(%A}%H-;PU1~;CZB*;sE4X@|JU`i|FQJ=Jl6;RQxmQdB4gfphwU5fr*SWsx~m<0jc*!b=#vs&}zkY>86*)K*ntzSG7|vNZM}yfY+S z?Zu>5&oURX=;-pb*Z%g!+ZU9@Iyx@cz2m}}bL&$N-gU=|NsXFoFS~> z_AtIecp(=-2Beq+n?bK@>7V=L?18}ruPo5SR$p-)y<%G#V>d?h%)0g7!9g~E^a~li zVaG)~F~RWQ5c)E3$=76+mj8?9uk?P`FEq`yg|2XYLANx1*TnWUVNsN>e*)J-$1sam zLdHk8&~sd0xm>vBlSbE{0Vf~te^@*F6?{;HMq|82iIIH304Iu_L#Hj$~KD5k#FGky+<9DokTESoi5es@jBxZq=cC6ZL zv*XOJiwb4=>E~CkEKFoVNKAL$s&kD=EI#joRhiWEdhe}^T)(AN*RS5P-}N!zc>26m z16ydlIA96>dh`J)Xx2ybM(qYG#~?bA$Exn=8u)8_rV!HQe77e<2*m9VY?wz!?xBf5 zXYb{6>F^^QR#7KnyPz*|Js#GBk9_t~ij=Xmhi<$7*E@FZe{3^dxOVmM;x*@m{{H4W zUwrn)`<`jod%?NAUK{9!})+Y>a0f*3-2%&%3m|)LOSAH!d-! zWA@Bu2fI1KVR6o}HV3-CVRKx+$XjZwYDD<%U{?b^1^k^PKyEM^^y1$w z-|2=Mp2GXUh3Ll%w`du}LhpvEWz@%0Ns53YTbuf~mRlPfjfv?Iv!gVTK z4t7(dBX34UpF)UVbz73=^7<0y`jE}}p}x2R!3eIyouto0ZlD+FaBdA?5-)kQBtxdU zer9z`aouAV4$dx)v$RxHmNoTtU9>uXK-ZX6ZpkZ4DBIMzIJGgg%#`EM=;t(cuZky> zM}+9NpbbecwQ9l9uf0ycJItKT&7=2AG};2Ys1(;kb6q=HToE|=NE%d&v$vsbmh+0W zt2TpjMwTyIww&&9t-Egb71#4Ifd5zl?uCre!eaIiG_4%?`~0P56-zL$nTPuh?(bcC z4dtm~xCfG5;PlFQ!si~(y&eXksyPqL?M#hfq1m(Nbftx|@Ql8`Kg^k_4P_AqPQ^Rt z*Y2l1t^>EU)!$8fK+OHydiyp@eeiWehdv;awOCoPdPGvaLNKd2$8r8LGjYrC(!i zvHF4w)q0~of=aSPZMEbwx4|P=4U+C*x6wP~9YKPsy`aAR#$9q%p1#?tteN-Q-q-W= zIptw8n(=sjZdpo3SCMlb4N+(fv1uilu7f?Y)friNx-j%v2l`dALx_>+C5bN@0HTHs zi&k&51B_&7-d-c1$;r%XX0N%-xx&fE#QGPh{Br)^0|L5zqK19@SmD$CebLKZWda5#5y=#GlCvF#f4Vaap-2!GCN0b373#e3OwLsE%bu{4VS|>uuOx0V|cRsyzjM9-t&7p-^8|d$gxJz9MDo z%8~1HnwruR^3}Py8Yk!i>nCkyZ*tsV9Rlrf^9$-1cQ_@%E1>_Cv!ZkS2ePz zG`6I>v4^QTY_r#1*0(H&3GFgxKzK!7WoJumW=*)94!Hh#dsVTi*4X8=rsZrKKJSX2 zrku}a#YJXV7xpwSEXY)f^URs?ADAC;<>ER49|=$dwZvmdMuUvhri=oO)vk5giZd!< z@*Hx#m7$7PWc8M~KB4N$jzU9(#`Ph_27yl=V0VL;Fd2N6HcC7pTK;!AojFvUoRXiM zOpkS?#>SmP4Mvec>DunDyL5;IbKZuG`cRTSyD3Nm4{QixYd+yBm7D zE+AFa)o&0?9rzeZmQZd(RKPi7xgv@nH%u4Sqjj#=w2 z?_HL~gdUkw7FwHE)6ra)RU0WkM57FO+gEJZ*3)F|9Q}Y^F()=Mt7vg|+hTJL*j>WE z1O0(}eDJSUf%Uo9CAx`EbX0RrP*hAm#^lW|?MklD7&J*bWn7)5nlGK` zBL;mGFejH$3On~xMl0P?5LOJAS@U`~Y^Y9A%5>RfI$cW(D@$Bk<2uzJSQD0R=%ex) zv{4V)eUu*K90@7q5!|^m%EN=`G1pyP=8iO*GG|sP zO?3TmYra;IK;bz>o6sxhU(qJ?sByDE(1-WWPY4&nlKSU9+k^YRX|iN>(MT7cV~hnv z^(O9t9))$-t=M?Zf>-N_nO&uk3nAK$=9YwLAtbSG)@_~5Nf9hEslAgP`{6u8&We-Y zcD0rce&^EsbADB0-*L1ZgbrRr+Z<2cw&fVBTa~g$4b>&a3Na})1NZ)FVS_T21!vX| zK1h!($v|S$;?I9xk!*{qUGXD_Gk7eGz9HdD8e2Jq%_G257sw?V$Ct$zJg_t-g25L( zFmFpiQ?}h2o2k!9lFKpbqj?sgO+_`X`!;Sj=7uzdC+jPs0)ik&MI6vu(KeT=Rs|v) zT*DHet7}y;9~ctA8>`>fC(=YSP0CGX^>)|s+$6?LPTZ@3t|dTM!VD;^qILjJTnXHh z+`k^HiiJfX$0CFepc5Tm%&ZnozBa0(Mj72H528&?G)UeVt-3l`4yR*=Rx^@VU1g^; zBOQeaP9=+(lUV48>ZSG_+JdSm7`VL8UhL|)nf;r~Pp+T!*3__npMrSdzr_O{BEdsd zIuQmXcj|KV7_0_FDeNK)Mv$o}^`SvgG9xJHYLzcM%9@TSEiE>;#5-)79d_Cqm|)277SsI3=_pz` zr=mPhnO)ZC?5nLTjLfQu91bZhKWA`TYff!`HMLeX<>WV1uvk+|ZbM!}Yi@IPYo@6=yS}iY zsjwlpHKSriX-#88gQE-d6NO&Ck$mj%(sTU_hmWa(A##aF)4FfH_14Y5>R%EUB}Bz7 zpZlB3ZoBQaM+%w>Xx?G7DL3ym*PHktjj4C66ZFdcEZjQ^isgO)Zomunx! zT{89p;u;TNowR|fIo+y7k~IdVPlz>gWN<|I#3X?a(S$GDymXG*(6>a9LsMc4>vBp; zsyn+X4I}Lfi{cz@1?84{XK!Lr;1WDVBWpoNYh2ans|EZ`yb;{pIyGS;qonCh_CeEQ|>?9!{dP$!dJeV`^6OS<5{&PCaZLn(%r7l z|Hk(QX3!ye5okt*)=fMbt5E5!+*sfYgAlCfXff!G@UmDfdYye-iipu<@Q#S-rwoR8 zLrkja9I9^^8fu`{re>S9v5|gPbx%Nem|7Fc=IZD!t*z5w^LAUqmTXMP&8W#S_m*lH7mL`R@Fa~#Tj^-a6NvN%4ZWc`pU`4Xbbd`)Sw>oh zWoA=jR*b=(l}pRB6E(V`)RZjtQ(lVAl$;mN0&M98wVJ|&j0C+tH#J3>guWJGrAhMm z4dnXY4_xH&8^Ep@D`t^c$KeZ07nM~b4(*6= z+Uyx+;XzJif;=*+rB!FPm2NG_+)jUT9W86g)2iaB$+a&-Pb=MPfo|*#dVt--eO>Uc zfM<-Bat5-4VAIp|a(V5AG`?hYdz-1eA)gk(FVtLZ3>vktn*e_{a$fJIb({ zV=)3SJox;|c(8>M+n58nt^(K5z%1?{tOuXQZFX%^MoF$o6Pch<#M5@cDi}1G#+b~A z$S6GoEqpBW8SA1_gC1ib17<)5i2hoU9=)CxuiF68 zjo;9QUOKHK08;_(oN<@MAgo=%OkIrumWzL&SLw#r56nmP`x0MC?yuR?Y)9l!`lk9m!x>O;~ngd)1$ z(O3P-^G&6t)yT_K2M$nV^YWpME@FE}&sl67{jQ+k{2*JPF?a*zv7IFJb;#Wpq@D*a zyeDBAK6py%EZ9LWcC4Ag6TaQ0m-w*9%yN-EFur8;$@2u#v8G$N6@PYI!edr`M_&_@ zTU%Cc^01G|%GoDJWS`XR4IC#GzBn1AtRXkm!%~L)T1`Q`DIrZ_DI~l2!4o5P_)%6s z2Mgo2-vl`&hbj-xf#`Yjx_<07<5wQ7EW#6DEX`CqW=R1?`WcVB>Jv5kR}-d082P+# zUu&CyJw=dXh(Sz_+Cc-+PmSEIST?U=LiCOftUYsEJhN(QTOG?bPHyWwZ(9x#F38Hs zaKWy@y6LYydCk)13RXF(&3S9;;N|ePTPU^*I-K0DQPiW=qSP|SLf~O4K&B*a60VSRF#mZ zik;Lqy$)7Rp*h`XNlR5LQ3hV)TK~UpeZTC z6rB?h6{!zui~RLjG%vwm6Qw-XXy2CjD(X(2nm~Eu z?M@=O@#fnm(Hp})MM53|p4@qqh+%?D5#3z`wD1V8P_h1;0;K?ad$A|m#CXI`? z!`_@UB*5T8y!;||0QMPtx&lHn9zB;EL(%E5%DAi$qx*6d>*}BTloJ8|mj^0n*umJU zUDwi`+sZPixgJjN?pb&49~_k9L;VTa^}E*Z2>ukq1U`5SyIv^7EQ7MSe|d5gSm8%1 zO^OUJ@FSA^MT_YJKB5VjLM|QKC6tSLNRod~sU#RgTAvy{&cWPHjUWq*uLoz{w#W-p z+vY6cuWi0QNNtyhaD%4(d3YtbJv8Gd@?GVop{aeaF%R!Z{aD0)a!%WipE>f=r`pdv z`RV`a@mZ3&$7&N{NaOL9(~QjMT$k*JovA-ZU;ZLA%4PX7#qA!K>k>q3HoMfk1Xt}p8*d0ta zjue#lJ+f_nQ;D^F)?=FnnkhBe8<(stpxv(b%`J=8gm3)UHFz4LFr|7qK~ z^p?DP)(m#jVb_xUediBxgOKOtAU+OR6D@f|Cr8LRb@)WdxneUpQqByb96x72CIi+ec<}gEA1vVsrS&SG)^1Z)Nm={ zr&Yg{;nT;RlPF>`9_TYu>4AYJ5nG4M4d+(b#OS)n)e|D@a=ym-MA?}d7?E;Kz7X{U zF#=>(xn(RT3{|uwV0qxKwbxL5UYY%hH5qzMUgxat1_#@>S#B@vT(UCYHv0a_z{c{5 z3ead1eEdHnmI+RQG!^5R+%p04N=ASUp;F$k+mVGZt>hd=`+=&voQ?L`t&7!-5iyDc zP2ylzRYsI4JJ(_}8vBBa@=8nTOSe>-XLsbLC7YvCl*$BcnXbX9s!`^rS77|I z@#f;WOZYqsQal|tGmocdf_b=Ae8z~nC}&R}RsR=)_GgH!Gu`h0BN(7rpB@G)9030t z7;^s`Jct_p>EXDjY@nu?6<41bmj3?nIpO&$1~HTJ?B>KP+u>XX?SNL!fS!BvX_{7< znH(M`N}HOSD)9$j-;W?}nS-6Rm9Q(ce6NdSUi)WNwOI^K3(5e=JsZn| zU}l?`?ZG~B{f_lEG#5uz3{);q3F`jx#*Uk=2vQa38ZD~Y?u)f7&RLXMo1qDDEjgTz zpm}IO=l3+mkx^Rnub#PyQ;b0{YxDN>!9McXpxuJlQFv36G_ z!W=RrWoEz}O4S9mgse4>atZJ&$X5^B1Bxm=RD@w!*UYbN)ppSEZ2!t@ge zIsM>sCv&-9h>lKTZP-A^Ky7!4zF&AWxqSl1q8@oKzvt`Fu{SYO3_H*X`DNlYa(+!9 zUnit%P`ite@5F0h&w1M62*hQw z*fB@3R$piAD7!RvSyxV$sdh%r!cCXYuF7XQP4=bTb2IbSHnc6JFJ;*iboTV@vh2c| zxxFiDmXxJz8(FoTW(iFWK0f5WVSN99-jl$07x`pfOv-#2xBk4VPt(+7m`pz_j{p1^ zX7{c%oS%^=gE`@OGGhEz9I_;p-6^?Zri`eTOv#q11O-gZm|+_@^PYX%qM|sZ?S-J6 zvuiumzeOa%?NO$uX8P#d6z8`Oke~;Co{JubiVS|OE(te&)PpI*37I-SetIU}sS#xY zpPRj6|I^xiZV3F#gDFsGCUc1&7=$To16-I;btfA&tHR(3fuF#g6)Mq*8hINNzCdjb zbyBiAE-C4AzPZNb@_eM5Q{v)NQsU!MZYXvA;(0I8%HJ^7V2_PB9)ah&I*-0vY=S~! zRJC0YeJ&OwRnj_ZrZKDes{RH`c6w&Z_V7bGb91Zy_#s_h?Mxm0T34D_-neG{<+`%u z()!P@aBZjYNvm5L3%+&zOS7!2wov3lF((K-z<0n-pB2P~o}bL1|A<1+e|8WTjo|aM zZ6B-G)Xbw=QGlLh``o)XT~-r^UtF!G_HngW_)gc4$Pdyu_5x4os7rF1o~Buyrgr?= zWOAG?&uXeD2VTY8B+tA}pPj_T%XAq^LlSnU%Ti*yccUL3-&C?YK>5HgENi4k+NA6O zBf@(;X@V<3SV=g2$^(&CXB|)IK4se@{uEFumI?ZBJ?lCy9(T~m?;qv!OYcva|G2H zrVhzz2`wuREu`fal};R5Z$Uv`NilfcGrj}j_>d}awl=>=Kz6g}06N1+-?jv#Cu`FL zORb~)j3&4`#b8Qu)FERSbR0isW<$_7VxhYes^AV0ud&0EoA{1B!Lwa&@juh8Nyz1h zNGZrNmo$7`H|MzJwVDVOQ-_Ma@}e}gCOA7TC(~N@1~&4!*1eF?H5+7%e)O(wMW_FzY9Jt%|1AS4&KurlNsh$M=zjn``5BVeR zLluglr>Qx1rrU{Xcen3nN9q-B*!}HH9hTh9=m&dX*rn{x;vN_=pKe_3K)S09YZJn} zu&qSDh-bGD@-KLpmd9<+up#DG>1oO35wWM+7ei+zoAT2&5y7UodU4MFe~H!caXYYw zLL*j$KnD7_OV>SWF?kbtGgFfEnWJs;9-u$|(b;zIgpEKZ*G!*{K$qDUFLo`TxEsh5 zQ|9$LBDs9k`oyF8N<1FBRi8L99hTB;uiD(K6@-w z(B;P~<96n$GL42B6}zkHFOAFu=L>)t)9;|5A?V{vC8M$Z3o+Ky1 zv!QKML`q>sezryy9k}9BX+xXf+2aJ``A;U&OBZt>c8FL z=K+D9-A=z7JO=5Rcl&|03up#W;?v>CSCsk1QlM9+`NPo)uXyv|=pGSA zMgI#NiS7hZ+?^eM&Ueebvq8-cj~IkJNE_3+Yh#>&ek3)9y8!%RrarnwS7mDT$5Ert zWrSI^nuvsaGkpAB`uU@X8(5J4HD9TD(uAD5sVA~lr*-z)O?~HhHqln*RdzIE6K#aN zEV^A^X>2_U+_32MP+Mw3M0{=m;8A_3N514VpvNFsx2@8DxHqUe+uEEjyuf0y*`04R9^X{VOi=9XdyHyvyD`Vf zFTn6gg()3uj*9pz5l@aodphP=}{fKa3sDPvS#0fF=PKm_;{qembYU8H z7Tkn!#pC{$(RT>9#ohWH7e&}~FuAd{G%h(cKP6c)-l#dBm88b0Q&aL&XSp=q#tR#< zTY{llGa|+NEo}KVT zQ?|7G?2SM50+2_@j8_5*bjyM9F|bD@g+xN3p?q_H%2jUo7rBzfhnGNc|~3nmmCvPf$H1mJ|a zLmy5M|7g2uOy}OqkG2&Pck{c=Wxme%ZtP#`ZhGSW{!?>(nilDUehiY}oTd`1rueH7 zK#zUoEfL_RAIP~Ep;HD(m85trDJi#&rn*juNo^>PB$UAU#l)->ncxJiah?aAaqn4^ zlV^GH$^wEDS4lLfqf(tE&?LW3s|pxL8!x)#`pJVXwEmILK*am?V>Q@-QllS`vpKj?-llujaVV~ZgF+Rv-e!q|Z zB0?^2a<&`v$>otMK^7zrk%wXvEk?~klC!h9TOuPaR2dx|77-LGyJ-q%Dc$9W#Kg8Q>XJizW3;ql(h5iyr46E#XjVgd()&V(B+IVlr+ zxA@vZUq-*-d=G83+{)R?uHxHeUv_Qp>2Yq|N>gcgSxq^e;re{Ac5n>xB^VHYiM~S7 zlYac3d!4nl&V~k>T3lBG72?yfdMLeoY*G$$iL};onK31Y8MHAeXZbH8Jx#4>#S%H; zc;e%aLsx~{?=MhdZge=v_z%Ouc8JcKh9dY3Sn zj_Str?)nzcE2kfak0|jooHD7$X-4$-$$d)mVaC`{VZiTvxNY1?1N$>%D)(GMa80Q+ zM(^U%)puTCcTPVZ)Fcu8qkaZ+gWJBHW;DzonYic+oC3Y;ZOLAlzAralbI&3Ia8rq4 zsUbb3GD20!rt2{-DI-H47aeSjD=*|)PwQBbNE`6*Ou(K}ZbSuyNyXWok0~t=_}fg= z!~$(w-bktqE49)&JNkH;Hq_Y|YZK`JewGO%!CqfpOreZ=)k@zHEa{CtU#d{!1N-q6 z=Y`eBZ9nEy^Td-AACI+DjAT!rB`!dR^OF;;j*!6ZgxV?tEAMoSG^~b5h5SYhk_l)I$I2QP8{PpL~dGS>< zr;e(`SL^gMzH>clDD*1dF(z>9?C&qeIS{>ip%gs>HW|7>6T9q-H zhs3$gE%dqWi^(rn-Td%V*Cmt}M$l>$u!Q%}nN_)J^Vah!o0o}MWN8_;pGpiGxgC`IE@$4Cr62oBeieT~(X zQN;^(*jd7G$3P1V5`$&=TYCW8MCRgln@U?JK)gE5YPvv%5nF7vFGrx~dyW`@1Jm^+6!cgVE!KX=|Gb7I9Mt7pBO zG(yip$)tLephb}q&s>p`6Up>dDUX8`r>{&YxryXyD+rfRh zF~j!cbw(Xxol$t;&d}?`{jl6VfuBnE(^7^@Z#?2_`(E!Y%qeJ8z}ZrxQW48AX^l zPIB{ntACj+mF2Z%i4&?Sn1p&Ys)1EbE(T_`wS?yQ7F^&?6zGZnEp50NZF<`H#Le0s z%uKD&%AWq;(T2P0X=!7Jo7tzQjeM>iV}CVdrc@tRv?o!h1trmZ#H3g(c9mNei#20? zB_ed|u_SjrwN!Ws{8m)+k@k~{t0lSHom^vWw8%%Wi+jN7xA5nPHNoNH5@AGrGtn{- z0SxlUP!U3QNU||_t+!!3S2q^i?u89{gy_2iwQ)DDecU{o*L&%uDQU?nnJz~x{q|IX zA-NKDtR?93^1LPBiu8$jy7+K)ZjOV~vbV-AkEDwgmfRj<07}0-ynem&l1or>mpMNw zc0ETci$B8i?!9&B;1QJW@n$y}4XAc0)o!u^pR{1Z(2%zvU3GO!OYa7H*SWTVJ`o=0 zeA~G-eTi#1{Yv}y3gO{|CIMd{S94H`&buej>%GNh6ZaM*pS^nz`t=G=+$%_*821n} zcTVa)SPEG6r_UMncI)lcPm1dA{W+2SXOfP)mc3(EV$3SPV-`Kl-aVCa+L~DX$z->@?$aTVhj(wcBlqO*f@)O7!qEp>bOVkI&JmwXt&abS(~N`xs>)G`kvUE&~L?l(e|`e zIz9cKu3G0qo|Fc^RXbsfLEVF_3ByYw#wx}wChVsUrJe--345yB+{2;1`>Nwb&4jl% zo+HoKQL)CmzY3n75lojtuJl4bZADMy%JU(B?xiv0VGME7jQP}D59J$0rdH&bScx5p zOB3qc_>PS}Flie)StfWhMy;n4~oV7~D<`o|$+Z;X5U`P^~e=dH*Ii-e?{ zQX$n-*+dyQ0m2vDxet?|EcT{3pj`=H?l}HLSS7v82h3O8+L;fOqJ}mOAIBY!k4&oI z>e2BgKzE~CwVec==To3L>*8wjW@iV-(yq$fjJhfV3$F~h!d&^zkjV|CifM30DZ3*YKQwE8@^kM9U*N!m+X%e__qC%cI`4F4xP zilafS|J|-)ItPX}_f?`^hfssq0k78qTl?%Pc5rSvW7Up}fx9zS?x2MGSz@;nQATh?8xPEH5)h@1RmWvHlk4q{am*aSb+7t9;JVOmD#l&Z*iHh^w^7P=ru)-jksM9-i`nB@S%L43I(mklF zo}QkhLFj{$9%dv*@yto&k#Kplqp!P!Jproc>$r?%&~A6!UDS!?NF#M`G?fbQ!r#x6 zVQy+I$nT`e1Vo<`68=t6I>o@F(6=i!ro=>(248D%65GTp>jZA5*-K{Ry!*i9CxyM* zp|?!farN@89QJHHVg5nNV^W@)o>J!Za+;Wyrb*K4e=%y3jfNBrOe>C8{t}M9{p8J~ z*ME;Eq95(hS;q5xlW%q3yVY|qtOIZE8<#d$^V~6>MYgk3Z-HLv&3R+{-1m}y;a;B{ zDt?c1C%O?cdvF!UH$m>sL9s^d8RB<5BZID=@+2qM=jeWFXowB-=G|lXJ-c7BlNH#8 zA!@Y9=CP}JJ@+KIF8GEGJ_j2k4gK1g3Yls^-=mAH-kK8QjL=;CT!-Gw1{;Jz!~C1B zT#{}MXo$b%{Ko2s9&W7Mbju9%BH{RDj6w7Xr}L84R`FSxV#rC2PiE<%iS8VEbj7UK zj8^xoef9j_iqWf!T7I)_$9=7%w_wH_g*too%?pO_x?|b=yNvcaA@ABbyMO!Sj=>vP zHu{o{{S|xH(~y(Q=Toe!sDQ0wmjY4I+*XsQRpbS;TX67P8ighxGA=7$*HW0*DH3aZ zJcu?v(U6b;JL_s)0<8?N)X)pwxlNS_LPko3`-Jg<5B{Hf#vRW)c^vc?03L_7gD0-h zWv+kYp=(W}_whMH)g{&;{tl@OJ5?TY@|h%J-q1={a?x?kQdGt9klpoa36NyZ!&-*>X}W`AU(8#HhV0ZG(4l>8*tGbFFkwHe*RFj`U|`HQ_*Nm zqcq-WpIz4qJpON=MaSu?UBU}2ToL!;vz^-eZ;Mh0VXB+w9A8Y|C~S8$xR9tQ;U3G) z|0B<*6L|du`X2z!WguvU)1exN9EXiQ6`K z<$mJiQ-z?1mU00DbQtPR24=ZV*X!cr2bpv9ei5-!J+l9M&%T2`fO!f-+u$xc=Mbwx zfE!$^QtYA|T@jyuL=U+hINT;{veE<^SJEW7PKopD^-Tj_kLP^K^WT6=)+ow!c*&=e z=%Ie4`LvRpuSIEN#~B{C4*y`BxXTifTimO|pXeP~6` zn*IA~PVpJ%=0p}kAd9yCA>B_4`o%@xXEKq}R6g_YAX$}YWP zZMWIklsWTP-7WLkz85du6?phCOLh!Ye)#%tgHh#vBw+ZQr@`x7R_z1*!E@rXl1aYM zDN7lPy5>~n%(V*_UEnNtT~pM0aNCakt>O}P`@rzt+n3F~S6srbo3s0=Cw2_n0345f z4j5%Z7Wg5S)5v)CujlCoSR^q7%)MB)1Bt+i``{Vj`(qRDz(X@%cBl9u%Mbt4@kB|n zQYvc{lEgOir)@J}T2lG5+buEPlWUcK>iO-2-ksBE1)P>pV+Qp9Fy190i-U0OMJ?*n zVnKNC;}4`XjsVYQQBfBGvT3rjyX2{+@Yn=-u&Pxq*jCM2wP}{6T_F=(|7a-9ZVC?& zg6r~1+u6grOD_LQmVs8thKIMVIQKepPCha_7B>~f<|4VTX*s5o7@;%VBf`QZ5+D&I zx<=7p&%(f;A|t9Rh`?~o2$}=mUP1bLigR)chM#aKqU&|$vgXo~vbydTNBWGoD9wVx zo(rl0fa{nn#GYntPcIHrn6!F*c}8YNZfrz}BEGRDyB7VIj1|)pV*l`E^8V#gJuy6; zOsbjh%>lzM13Uqq=AhdF&x5Z*dm@nvRuvZLjOd6!cRSrrzj}Rpw&4nzjchPuB%Y~7 z2m3O)x{dx&3z2-xehu8iis2f*+DAvae0ERC47WDKe!aWYNB80OcM)*)5qlDTk`%~q zp1lBz&0QA>$!dTOnQNkR83AB4?fY0Xu5XFf0ho|3>57O|<;||>Sr*b0QJGU-t=iO5 zkT=7vdwt~9y%NrG6fc@*TR5E*o_&m1UIH0PDJ&8kZb3$&FK4?vppw!1ATp8lXbAo)*TZNwynw1dXT4^2X;~NBTO5&? zpa@TliK`mgv~tJhky)1-17get*>y>-k22e~bq>z&T*${G@hIjNaR!CQS~wGX-T}^> zGtV}WH4QV=5^L5_LE_7_5?{WIEEV~(PV93vy^+1beUAY=!&Ay=z_XBfrBJ&WVgPap z_7cYeomm_bOX~{m+`Oit-56}_zAyZOJ1fcx<^&sdM@Kg)L!vDYEc>`!2*y)e%F2$d zZ0U%N31h(-%g~R={}>yxoD`?${G0qTJ-z;PEHC9YeuMc7gVzje$^`wFYDM7^Am-57 zXgFPd(fXAmtIu_f(WIvO%66LUI@(!X+Zg)n6L-A&{Cy7}qPMKxbHjt1ufGY?0@%4M z;m-o&`kRjw@z_%nY$twwIbQyW>l1N3_#p+4x≈M?n%D7{1-Cil9Gh8?&9mtut-G z&d`|=GV@Kri;eeExe(M?a^d1tc(U5XUFztn%L{G~mZja!+vWP(pHRaMx`W$HfvU`R z1aJv1=bNx%)e5?N=>KExJ>cUg&i~<^*(>V3OIGjobf?p)_uehZk}OwQ-Bz=T8^)Lp z#+cqA7}IMgp@t+RBqX7Qk`N%21PFwd&|C1`|NG4Doldgc2*3C9uC%wayR-8=GxIz% z&pgjFGv0n0UFg87pK5jC1u5=27x&=u<(Ut&z?8DEChNc0V_t6VUiGc4N;AII8X)rb z|II!o8sPsZ$^|oARErF)6+pa-VR)Qo%^LSeO?a>=gtg0s6_yT^>!(rc&4#)4Nl{+j z0cE%BT%*)Sl5I2gLwR2Gse#H2ZBVF@#2zByOf4E=`(loSL)Yd}O1#LWy+AtZ}l^x4Zp_O7+ zryBOI9yo2!4crXd?S9J5M`n^R}}qtb4}VYd72Xx5OL~^!1l0 zG?}1kP{2#rRVYR;wpnE58qc_bTytKkd&~wF?0$*Gr>MlWzL^EOm_nOkQ)b)B_osqFLY$f4S%Q4f~bP>;m{Mz@^p_UNN7ySEv8N>X=OpK{yS zSvRWimAfsC{SNtnRu%lIY&q?(mtleOW=Z~jYfsR)C)KaG?e6yTH7wSBRpXuD(Eojt2I3H;0y9e!&Q_1MW^Nu_E_Yf3m7B|ozFfHl91jZ zkeP+BMqRc;!WPY~B41}Qb{fx$Pbo@|?}#&uHDpwJ%SpYp8;!B;aT%q_v3Som{VJ<; zXid#Yv3%J{t-JSRCapMSck^knJZV?MnzdyakI@+BL(q+uUns^K;I6}sVVt^)WrvI~ z>V*iJp2aiB{<(}+;lY3=vfeI^Rx4O3M}}I91hmuh18oCfesIIUm%%gmQ(~S zMq&xdEZz)sfDg(Y_9+_I_z1p-2t1Dy8W!jEGg(YeM?u`;-DV-eAAD(v9cQ_kSCZR_ z-$`yie72YmwD#vN$O*~VB+)N{eG#x%+LQAI?)DMcaZt`E^3rw`>Ot0ic69nt*WmcS z-kSt|ezrNj8F~SX>7n?8ryts466UaNByD4g{x=cr9XbCouKPkRsUIoGS(Df4U6+^@ zmsDSD?s)|2(#KLdYv&HMmU>qC<&=!CGZiOU@8T;#3(DNSdtp}=^ClH7D~+}q*|7D~ zp63;V@xhzP=YWZ|lcJ$lARUG1D@Y4Q{f~WOGH~P3fqBi7d)!&C^=5hR=H@c*vaySP z{;O*@@N=soP8+J;xG%gi=I8q_{v*;8zOVca(o-DWI(c}LXCMh2Vq#gMC++m z=)$|7u2?(S8XR5YvMm3@MC(5^E%gmGqTX%a$-RK9_^B#(A;6~INdXRZJDUfIDW2}# zaRpW5wRw&ETMMjT_OM67GMb0_n-T!+bLMINR-3%GsyD9zThvJ2Kjcl#Em`KC=ooWNe$PXo+h1p9N3ZY&_ms1NCv+UnK1Wy_Q>{nrTPCAHgM!6`M{@t^ zzR_GCp&wm+Zd+z~ceJmIdtjT{#eGeshPHyOblI^5#q(xzi+_hdMkzP^rno~_E6?}^ z^X_FaG0ULYp}w}!*3Pq0J~Td2Ep()mK$++E{NANb{|A~=%U2#;d)Hlv|G(ODX#VJT z*k|GZT7P%~6VDUXDUAxU=})z8Z&{ky4(sc2hK*HSc})je3c5oLYqAq8hBnYx{r%dE zyfLCOw$A#NHYcg5E)hK`IE~W(lHV-+A7HF?tmUR^7pO2Xx0@CoB|U?kteZ;LpIDe* zY|iT_sJyXxS!-p>McEM{*^L`EG;w~ZcXn!XcALNK*;UdoXT z`C@A;9Yi*a8aSCag9e`u?+kx_@IMW0%k-f^9xL7agEZl_jgg&EjkVz{#d9TT7$e&1 zL1;wTbUvwHu{^M~G$O!U=h<3keTtduTIJp05hct0+g89E0k}s&2KX)7a`M_E?())U3zOa zY)G$4sm;$S4y>%pFwJnjIwrf9=wpya z^o57-VGh@=pvIQyO8}hgUhnXG_%EPaiWVOEuy)Bpd=Q2t8fjYOg_f_1PRoXNgQ24@ zzca6|!;sUpK8Ll;P2Jo+HN}5X%oA$1G&Rpv#cN7SHL;bm&8^$3;^l*HvA=7!Y@6D` zUbaT-=4Q8H4hVd#P$|b^3kx^*Jx@&ssY8ne6_|>mWC@+cU2VSmeOkx!Wds%d< zUus7o%1`jTtZ~2;Z8Oq{Y3lkL{tniuJ+SD7mH4)`aw*~q>jbsr;!ohId_#yHL}Mlp zbs&pxX>Y#ogfEfU9Rd;&df$1O&q>bXOcP_+cu`K{{-%OEnI=%M9cj4a#-KSxH%R5>4GP#?46fW)c;$T84&N z!wKEd(QbQ^&Giky7B)(Z{r#1(gugjPC_wGqkX>Z9>}2__+XgFI16Ooianr+lH?;Uy zwvL^mWw|xOr^HkwJ$}V?KaZ`6+6yU4%tJzb+^Oi9sMRjPxCD6z2|$nF8>eiUf!vcn zTw~9G=T%!zzWjz=CtR-G(8K=1R*w#?T{p534EDy}>wa$XkaaKqg6 zbx0p8xUd%?(?pTB!W4(Kgk*>gLd#G3II)*=te(VmW>%q?jALuPy!4@d(f%PZ<((yE zCwDe?mzTx_Mn&m7m@X28xuzjMBq5+ByU0JpoxAr`c4wQt4h~}rra;VKj9?v~yA+id zR#X1s&|lvOJsR!*L>6LlWwe|4X#aKW`9WGQqpWVe4zcDa>v11t*>S*32Fwqjr;QME ztso)MpHsntw{l2C$%PtN)F8@Ms3Y0WH4*hE7}MP3;5Fve(_1zcuQG--#11y}xCNDE zH^hg8m1k6y^XKc`-TmuIHss{*+Pw8_%eslOTl=%k9^P==NpC8uNGnY5su%-Z*Fc_p z7J4FY&>kdAG5?vA#X_6tBuirYx+<;Il=Z%xpPpA~E7Vt5noo&HNr)+2*iB^TQ;`xNhw zAVZpbPh^$Z+A59p9!<3-CCWFVIn*;03mRG1vRALT;#HPu?j0#;9ax^8$pl}CH8@eP zw0`Q5SB5?E%9~5BxQRUJfH>(#NehX&i?n(iJj~R+?n%Hy|3Ct#PERz=EM5cG`F8s5 zANzTpkqb-sP4aTy19Wyolp9_qol%(XIKJFTIpm&>P@CTT}{2 zfER)Jk9*j^Nv_0h-m2^L`kv%kb9s7x;|X2eHNl0| zx#j1+UX&3VofKzD3oc4eEp+9&GE-e$Qc-MXLWf#k?;vmJx6vX6=!M1;6D+aow<1B; zbn4_%pUZ|jbv!dJY}{vvz4LVM=#KF3tP#&HpIcRw_8`P5F6#Xqek;-;P2iF#DL%in zz&_fOLy~PN<1xz$T}$QK!jj@cVengHQ=5v)s;GSG@$)Kh7B&=77sB~P9lQo&8LEH> zHochN9GUFC+B-6|p~x2m_`(aX>Kdy0{c)T77ll@_QXab>>0o6!yG%)=RArH~0k*v7 zrs(v<0@p~tD1Q)N1iNsAvUXvKIJzK7l)0OU!c;-$YKebI*pg6>c+Frn4-{IduD?48FSw?_Q!ZgS|77k{E3m{@}au$XuVQ@vkYZ8rv|}AuUCg zBq>eEXf-`=_K0TsT;v%=Cz@x9Uyi=!7lt^rV zkZq26-x~CId`qi<1!BH>0W5+SQ`3EG_buHAZ&M)=G=(k*w`UN42^muPhA=$%gwuD_ zi6}hdW&1CW!nZ<$ugGIm8H(;ME?DgesaN)TZ&|Kob(N`nZ+h2x@5V-#bQnsKBH26F zYa^NqtJ5rccFj*7*BH!6**>V_TBO^KbV<$wmWw1kM+Y050EVvZiBIj`VXD}j-qjtP znBU%-m&hu*sa$le9W`lrddc><#%Rtpylw@#a7r8fIIZmm3;!aV{hctb?TN`OT32nV zI3EeeMis5fDNRIPuh)h(7gejt8gi4ey-{BgkWp>}Z-L(7;wPjK5`##ag&I?KOSP>1 zT-VuLm={ppHdR(}_SWUaz9ofqt936IS9FFKBve;z8Q&LE64q5GaQu>ACE5j{V+eE- zcZ3gsDn|-2vbL+keYShumYr*RX7$Uv*a@tpqGCsN6?%ZaEoV>7?At#4m)z;5#)+wx zrg5YV8U(H%K!$_{2#QK{ym~KL?RvShIH@NYQn+rQ3uU);mz$P(26^~t^qy;dJ+)zB z{vlC0O=bBTYvqLa7)x4vR$wOkyEXc$aJTqnMt8rU&`7uXET2F<*Oi#7<73{wUhA10 zm72zgcK-joXCHhdY*So|xf?J1{S|X{F1TUuf6X<`wytte8Ii;@Kwlr_%5h z<;8Vfp`}rK$7lAT{AnGMuhcnFN4I+%b{f=S=RYa!LkTXotLvePmEfG6+?-ZCbz0vP zU;Ll!U1)p3mLWX=Ts(D$sa)@@&Mt%Ue!3vdrhe-?%(uMNl;9U`eMiv0kV8TLVm&Uj#WX5dD2Wm~EFq0PCzxY_L~5T) ztjyWI6}6m57?V;GBMKO37D^vvK!Jrpk);nOiY#9!QXf_>;it~a)-|?%_Gi?~d|!{v z1Ck(fzR`1yu15b8wIhwV<{F|Oq3>jm$q|a2i2MtEW4uqfyO?CM<8ejbsK~Ng`En7D z$_Z^n&AT3@x)&i(j^9UvLmHodg}#l(anx(ht1`qGS?D){#iZKY7N7dw@!dOz^Ey)f zW!AxZ>l;4C!ln5Y#g***(&#fMrY_E?t4|2`TG8>Id1W`H4f#N>fsK~@S&z7mfY|IZ zaMkUr;dsH_(|cF7$GdaSl$9%gwQ5C-JNHT)Q1*#G-1-5pL7fM9kbTtk0|e#SB{2I{ zb_ik^IK&-k?SOi*$KaQ9i5cTxeb(Mo)b}|?3hT=2R=%r{%<<%n$nl8lBaA54y~E~h z?s)TtIrP2d5qjAzrnR9l%vW{`ukOCOtznrL_g>c0_O;-HBjinZE~DOZh0Z4XC^ZM^ za*5Rij#QVJv$|lh0qCv{m-p#KOAkQKQ|g%Z=}w}xOy-AxOVqN!O&J@R=J7mI;Y^al zN)Q$RzmWpivWhLedPKpZP5bQYNaUcez{vK{btD$9x9|YS*?Elx9tZ+ z;KS~(*sAP~dAQLK?XO7lEdI`3Vi71!jKRqh0`q}bM3HD)@J@cx>79JX_nr24aqKba zA^tPc&G_p}SSiz;*o%dY^HSK8ZYAf&>86o(EaE(<#<7qCSMC}m4!_M2C(w3|benV% zrK8TGZO%*aL$pcV^fttzvH&dBB+|hw9u->f0-&debd&6`>BBhPM*0>wutvwX3Kpdp z;yI8>x@7@Q8+WUy;oAV)IjmUV2DmDA>ZK_!DFEM{WXIM1nSwI%o@RR%ezL0mUvCLa z@{jY^n}eTkce(2>7y97`UewpQSo7E)U>!$sJALC%HBR3I;>5rd-ubCJ9sf#q|b&{|~f6I`!_u0>c?v;l6mVcdoM(ydRv7bGJ19cOO_irojp;yEh{u;bKz2 zJX|HW2)%`QT;=KGotI$gsxD9VO3seY*&H4jCYM@P@Sv#bg2s^Sz?9fl&9Bt_ndNHa z4q8_hm zy@fT3v8F7ApzIAOd-5|9eh);0P}D1y8K5Toyg}0B%0~5o`oSfb$oXbgP+Hp3T3Xi7 zTw0&QqLbUolj2xpOpPTir~wtO{FDiHIZ^eK~{lve_VK8fWJ9Bi5a6qvi$rq zf-#Cz%ZG3X5pt8O$VucVyF<}g@QvidLNJW-d5D;XHO?Bfj`R1y&lJbTsitGjrHY~Wz~_lU6@c%(i9(=6qT7$nPKWe9a%(K zxB&N1q$TVEDs4I@8!2jj zKfgI<_EgJ;a1i_%{A2LvrAJ{;(!rRdTUgLiyvc%`c@y!@RpJFN;>~9qtckLAMgQ{& z`kyq_hlF(1STh2qD6_Illvoi8?FbgwoCTs4K|AU%R@B4twLECJ9r#7_fS!iTfQ9yTX zQO(d08*Jjz%V(UjrpDTqyuGJE$Nl`XQ+=81l{g&wu7PqXwtvH3b zwyeCPBpKSk-D_KVR<3SqUuSGGnrmt-#s=%woNxI)>(A!~*xWVD{opjK-O<1AY?MP3 zyO6Ji?5GzyA<`a#|FvY+GQ(a@b}ce+1t6ddc}V;=MZMjf+r>+B-58U(k2X8cz`bRe zyX6G5XS%v_=r6Lc&P2xBZ@<0YJ;zgD(MFNJWnSk% z{Q_zl1})KIQ|Af;jUwiBMKtt}UwO^ub;G+>7j$F0$;qbnRjh24yH~TZsI#0873Ti( zh6kQJp?hebIo2)s#JvZ9x~n%SzrVh`QGtn!M)UI_r$MeyVYKK*lDg~zk3RU_pZlI) zy*1Kb_6yya&DR|~5X4sZR@F3GFQfj%)piqK!}kb1IQksr&m6@IKDB zj9r%!li}j(tMPGhDNK#daCPzJ9O1pmF`4#oVOkVL;j*_242)DR$&w#W=Po44C&Xa2 zDm2v=v{lgXq218O@O0~wP35iUKd{pJDKjH_n{_2gV=w+_c?mpFp zbMC^btyja|&~Lqpxx0CKyI8-me(C9^^@W6vIg7Ro{w{oca&SX)I?y!<#k}fCVCPa= zwpyVOwI5r?a1VmvzYa^u-_F7c!aI{(D-vFl=^0ZPQi}q|u{B8xb z$-&qf|In1;1$ZE3B;+QQA+ zq{x(H-wZ5o4{GMf&m$~D9tRZ)|2)wOi2=fbuK16O7e1E94_)Y3@J1+qiUnX_N7AP_ z)`FW~!@GW|g}WDQ<%lx#3J;UNsO*u&kk?vv1E=Br=l7e=(f_yKdS8iIS z$urAK2HZH?Gc1HXKoS7bOjJe}=n6>)pqa&{KxKVSN?x6hd0$3Jf=`+$DlsY{Hzy|} z!w~0_loq`#I^C3IHkb-|s4+YuI4Hu)KRYogS6`UN0QUdh8tp1nVj2`QF`W3X?jeMDW!7v^sc+k-`vesPq}QW zk4^1*J1zN+bFcl!^}EJSNl)*o&R>6S;QbSv54BJ2dFbL3E>>u$33~>!4{zQ>!Sev3clNUyWVU>YE7(JNY(BnUZJ76MIZu;qd$qYFwf zjrhM$#^zL2FV8m5jWwF$(=#oMojBBDOuB__F`d7C^;g!jvd`Py^M2ckD{j2USQ^#X zb=7tEWLKb_!P-_>Tjdg^ogp1Wl4`bah&;MLUC=?+w}qYf^yV!ith}TE_Zn zva>C{`S~?PAvJ@&>q`ns+jmV4#Z)FYXO~q}qJ11v)IV-HKugNRswWZ8l#L9~@axMIlwG~4~ zIcK(Wbg*HYMGk36Z|Xa^zuc5p5#UpoWvb&bMd_IZKHkNt=_M#L@^vP_mllTTjH${HI_X>4>qYi@SW z*>f{{Do5HoMn*c?K_yIT!OuARC(#J3dqVHX#yj~V-Y?a&tJ=#~Q5?v}5Pm-+-P>W> zgxo>~cj(#dt)qp8>dKIg{^s>7drUFe_ZwncCkwJn+4&_M_2uIw2{MfbOKkhtL%<)S z znVV(dWlWow(H2|a7hYd%toN2(8;UzOp}eAPd*LVkkTLXEx`Lxlod+dj(1X`-XB91eXi=@ z*5aO4ShYUNa)*gUxxcdPiptErQ+0i%p4CO^%W~aWRNbYT^7QIeQ%Dc{c!9>>rTGZPY!H0w2qzFF>u0j-po)}X(>vHZs2RnUAFhK z$h48}zPYm|uX*a=JB^ja^=UE2(ryL!O5pwkaL1?!?90*k`dO$Lp2+w~Ye)GViPpce zf97qmKEK0fEh`w{81T!I0rK(1$gk`T z?nUe1h%>?n?@&TPom`Eb`TLv3bbL`jGtHr)`U_w&fk3`65fbQT3$?Z+s0 zP=!B+z$F?;3M76Xx_!FV*&fZ zf(JHEiUsWNA~;;iwH-u$J5bZ`E3ud?*ejkgDo%{K)p0kCz482+5&scmQEz>;RFDSeb2QIhWrsSg(nR$~3Qa;db5QUHqR?&tbLxOIQ zdQc!3J%+t$U2n|S^mVyx?5a%lj~}z>FF8kMB`n?;Sefh-VMz_>8VfB8s4R?#vH18j zrEpPJB+!4vW$Lrh>(i(hCk&G69vh@NAafwg?zsH&%TKywO;@lF*Cei5wg03mue@?5 zyD0m!E7Rg!YcKx{K`Q%R+gKpiqz5n~m!Q7kEcRenfNQ+#?! zW^P-3Ygv9BeAmlTEg5A^HEq@HZ9K8aJ1{9GBEdhbG}~D1vZ6zdD2j~BjSUQ~+RzHY zlHe}4z00oSTFM7#&%PebqQMdLK^J)?7g;(s^tW5`Q+#5IOIunBEhiTS%60XwBc02q zJgO>~f018HX$7h5P{+Zx?^!-ON9ij_K18$P)K@5Dy2Z9u&0%a*!1Eq<2K5ydwXaZZ zRBYZxB{8f%dJeUbmLv40BioVLImc|MQp$&LICdHFXm(`zsCFvJ z_K>t$T1kEp!hJ?(Fob(FL{@4W+jRZlk3j5_J}#{wJ(kLCN{3#~{6j+h142TzVNg?q zVu5>=KQVS=FY-|tdG8Bso~vH{OP_F zgJNC?a1TXVKMsHL+9UEO@UBJPj@i${eKCWQpNEzO!$$T4_>=Ejia(KmGsbm48h`SO zkItW>{`M`wpM2i}{se9Y)Xk5~pZt>J;ZGF@!Jqy=h8>ydkHVm$FO{UXrGROpa{`vyFSMK9gC!Sb!D&w!;_Q_lK-TD4U z;QavGUDDqW4+>!D3w_9KMAxH4Yrls*d-v@hy)W=vZhMfq@V`(Uk{uQ^$4t!S!3U?O z>*Ywx!8Q>m!1kc@loE&5=Ab!G0ThM*<@>iR{B98^0_n(zlT31=5K_>&)2hQHng#_1 zVF<6s3?$qDMl9(W%sCN;7@yY40N*w}76z(kF8Vg#zzbaUEYp+{6EPKDQEp)?yz`7< zJptTrRk$(Fr;Az6j>#_fA#)@07z&t@0+R*C3OE6z)IrioiRMI%3oHT-NqR!gprL@Y z+{NXBKxdc%m90K8tk2XKnwJ}KwuN>1|AC8-C>mFFTCbVPQG&=Djsw;@}Q$b;24Z=&TxDq zJn0g|ui{U~l7(9xt5rUsZy3RWZyv!>p{TxjB4xZsn()n2-aDs7iO~0vkO%|Wc9bV{ z8<;us_1A2BnRuQC|Jh;j+~GevtoqNgH2BZXzZ3qm>brF2FI~^h7rAzlFo*4)mHzQz z5ph&@fN|{lR3?qWUSWW3Sm3FTdjbySwD6fI17}-?x<}B%>K0?l)~~1!SN=SUhfRrm zLZO*=c!Zkfg9VG7wx3_@nvFR)Z}Q)>Hn~WogT8}O5>oVny=!RUYRt9_qpfPbrxmGj zy?JQ1l0UyJAP~zCMyQuflmXfH#<8Ut9OtQ~c~DLB;PCRL(_}U)|Go4(rMzh70f#rX zTsTYR#iaz;k4D5h(gp%onl~}0ZagU$(ngawF!toHGjBP-P8(65d?E+Xnn6LZw*|=+ zCjtSoA^SOxy zVcl}#NUZych67%Iak1^n+;F)}pI^vLms_A5@7%X< zAH|bx|Kgdf6zjVXZK*UNoIDmRxlc3^!UDo00t3Rs|3MW=fpb?+7VzR_$;%=@6ykUH zc_Ph^kY>rz(+tKk{%V@9+0*=Rb<0v|k~}X-A1OLubRpzc=zAI8?7Od#=M`5r9o#~7 z9&a0j%}=7SXYldbudZ6se1$aGeauI0p)`-*CU)PFi6SRJ(v~1?hW&1l{QZ)>Zh5e=RAbP{b=^cCyvps7RSzFA@XK|i!%A&?Ro61V*yNdP*2!F zi;1UIJ7_VfP2g>@O1hJuL(i!nfPIvoLw3GE+lVx7`wj8f(qov*oyRbU58LiI_Ypj) zw2h0#JnR9d57c!`ekA=hhEYtvNPn&G2T z9+&>w?|;%?`$2#G_7U~hZy%HXIv#jmcx3%`{PF0oGodei{W$d3cmEIiYbx_gme5~c zas>T#3h;aR2kWo9e>DAd8uZsMAG7|teJTBQqvaU%*N~3+IQ(ePzK|`4{uX!%2_GS` zI+EhK1DDkk_Oo!?(io%z)sT+zhWO z_q}12;3>djiu$L6C=|Rd&;|d552q+ZBSeTIvNnxzj1y6e= zEK7N;Sq*D2pX~-Utd)9&zX`?HNwIuDeXf^w@hjD^t5hNPs$qA@C_ko#y`(ygmsBZD zN>kEyX<8bUhNTf{R*IHx#c70ZDE&plLv#RfHb{dAcOd2r;tWDpH-r0nX+rA9+i9dh zzkTA}04zcD-5CC&rFKWk^hGHHFXwVvpi? z7%`>F$*Jwrqr)S!(YHn$4F*GW`M~6c!RU_dGqZ!^Gtu=E{gcyElhb{(g9Dk-cr|0(F>4jLphVzufg%u00fB!rjaFk+)UKI3C~CHd=}Z9 zK)G*I-x^7)(ArrOt)Sf25p6I~&`?-8IXy^EGmWOgk;&P)iP3GiH6r>C!{7OZ_`7f~iv$|gLUl!oy8!|2yu-=j0pebLi{!=oUq>A`{M+3CK4 z!STN7P0^D>M)j?m#@WQ`3D z_l;$a%#I@#+Bk98mebtrLl6Eio$cZ0-erF&}uD`eC#d zfbnDydesn&D#I{(ih#B!6870>SW#o)RTd9zdm?)HWbCJ%irFpc*d;s@r9zxQ)Se@m z!L}AqcRtFpP%47lUm}%CWuTu5)KL{!xkjp$>d@vjU^Vt8P<4yciq>H{YPtiwwnFNX zx}_f2IC`a3(rRgqv{qUttw+gRFP$cxF8xBfRQi{6hO|#Q2lI1pm2QysNUut#N*76= zVUE|i(q+9iWU8q!Xo`=nJpIT<2ZVZs}y{BkAALBk<6anFjiQ9n(t(B`b4*e~cUK zB{sN8VXG8)!ZXZ9@nOEqkNL9z=*NO!%L{@1k!IX|%feX%TZXyqQ7oFpuviwy;#mSq zWJxR;J9VT=-@#Wijis{;mdUbU8Oz4RViU_@W|qq=ERW?&Z$T$lfSD0R*t~;gxs3M+6(;c3!1h=t-3{w%J!`;R%_i2&T39Pt(ChYPN>0W$V~_*2gxmet4A+vLQCiMx>v!QMQq7Vq@@NeowjyK0Xs{600e0X4BHk z(m$lXNv}z-OMjPMk=|r8Y?jTjEo>|HzS+)pVBMsh>_oPUoy2xyCgd&b6m}{*jhzlX z<(U}4p3U~Kb1?onm+fQcVg0iUFs8VOT`XM-`TSCL8FsI^f?dh3Vpp?k*iYECY(Kk> z9bngE1a>34iQUZLc?>uncjG*3O|77oCC#iq2_t^*RL-rB-nEjjmhkXL?pwHOn z>1WdY((j~GV4pZsx?Org`la+M z=~2wziNSikaXg+U@I;=3y|v$z4P(HpsmV^RpuI`StEHQv^SxNQM0%JP@Iqe1i+Ks0`^vC>bOo>ERlFK2e%E4$&wAd#8+jA< z9&W*2y={CsZ|5DD>a&7(@owJ3SMpxI3aiSk!K|%yd_DG@*}(hx03YN-e3*~$QN9st z0gqvvF~KMK6!yZH<}-Yj&+#pME8oVq^Bw#IzLTHGcVYj`-TY*J3O|*f#!u&G@H6>Y z{A|95pTqa^bNN1g9zUO7z%S$%@r(H-{8D}yznouz6?3oRSMzK5Px!TbKfjJ2;MemT z_>KG~elx#?--_KtZ|8ULJNaGwr~GcLv3xJT54&C8&mZ6q@`upUJ|_JdUd2Dxmyh@L zPft$h`;@D$e8cqMmO)*gxai9#hbJcnH|hJ7t9xbt=yd%{hIW*T zu0{ENLMh;hzNyKX+3CrtkwLk7VptxW7}mF{nV(cM->PJOQd~S+N9HDm`=;l{$NJ`G zJtv*-bnOZb(+UplPGCKzoo;mP3J%lCr9=5@MqJ!G=8MjKW6C!StkaFIQ%Po4 zTr{0jrL$C}E0ijoQ>t`@nyWcAS1XiU&54V4#WY3?+By35T;ZH2&pGEi{R*|}=aj2^ z_dJH~Tb;ryox$ zh1@nWDp%rcn;G?>bnF;-s}bz?Zhel7dki||zy$~h{9Oru5ek@7-rGMF54GZZ%?3o* z4pU~d1A}9;eR?%5%?`Yf>E*1*5+$bHB(gLnvZPc>MJ1n@5)n0O{Gyg zBQiIO%&7>-Q^;69PT-@Rq>}cabnSR~FT&G9O;q6Pp}rJ1ZsKDRbnP1&9nCfvj3#@? zob3o19ijQRIgV#$M<~}3vN%F{j!?cmlxuK=958b2FtT$T>18`o$#$fY?MTJwNX6(# z1zTa;^WnhH=t$4#z|ZJN+2}~w=t$Y*NZI5_+2lys9afjnft6KKxg z08RT1p=l2*Xgcl$n)W*nLeqXTkEZ>J6Por%n(DdfNm1>&*+!Mza;#+Hp)2ZNp($im3pmKt~J@})u>)g>eZ}XEp)BPHRh|=a`jrFUMtnB zNEh)$y13RT&rJsPD&W*$E}eQW;NU(-z0XsxDjbsv$E3nBsc=jx9Fq#iq{7Kj;pC`r za#T1uDx4e@PL9Y|O>R!E0uPh@ME-JA_&F;492I_!3O`4MpQFOfQQ?|ZxMmfuS%qs> z;hI&rW)-ekg=<#fnpL=F6|Px@YgXZ!Rk&s~-)0rQS%sgg!p~LV=c@2?Rrt9o{9F}& zt_nX_g`ca!&sE{)s_=7F__-?lausg53b#UqTcN_OP~ldna4S@}6)M~c6>fzJw?c(m zp~9_D;Z~?{D^$1@RanNuF)GlO)8Io}NrO6Jg~HXwqe1!Z)luJZ$$g#5K%>Y=C~8@6f&x+^q?WAol(V& zy>amr8L_`o?(FZp1}4X#(YL=;Zyj$(wqxLfW=8XM;J|-J*+fo_B+v}&EKF&v)@pYW)CY(n&VD1Y4$tOq}gxy(2zVdG>Vfn zu(Yco%{i6G3jx|o(#d+@UXRlSfA9u_ZjeDYxC`NvIBZnV;kZd0dYpKK6L1O=6uZ+M~%vgcQ9UDU$wJ(H=W%jwuf9E#lYLH#RF_a62<7Z5f!D z9G7+ujZXAQrwn0GDxEbpI@~8+D1NUTo0uDy_Ty(-x@nTacT7$XOi1^N-$%snZ>H$^ zlQSRz={Z#VjP%khJ$a4#Q|L1ly*HH!<(7WoWrbh(li*Zz*-AZNbr(EWezhV@(_XMU zCw^%!A0PGVt6r7->O>r}EQ&n{@C)BH{Q5yZZh(fn3|j0q)b)C3iKn3d-3`t2`O@Xk z58nlS+b^MCdls7MccK4PaC|~w#@IIHUawd>nadXC-ere+eMh;vDppkHx?a7%TDiJC zp7h0(Y}!$Zk^=9<5(#m4oE}19#GN|c0uXJ!D3J*Yz6IrxE?xt z#DM;N40`uj=-Rh|lTLyLTWGDFG}h+`Z7JzRH?i=2=t=K(0%6dGUT=my2KTbi%xEp%J z^Pwx;4}IX>(D^;a|G=N)FY~|ifALTFH?oTyB*)7}xlC@6SIZmaZSooN#qt69Zuyt; z)AFnGzvQnp8jX)8LKCk^*W_r5G*y}=O{ZqHWSokYBQ%~Xpl1$-rgexnNP6f+Z|7aoc9hTzAI5zX^r79-G_=mMd<6H+(2n*2b2Q%c)Q5Ej9gQmW#pFfDkGPaN30qq@+Ko!lqVUvp}b%X zP>}~2*c0wDYKH1XMy*ht$VyId6}5+}s1sa84dN;!5$#aHV)kda+1P z&u@bV>U`bl#IA<+n$p3~G{{j;I_#ny?5HIjd{#pob)3Rl5HxKjEG&4hqol=Kyv2~%k%T&0-^@Pm@RLNk#n%|wCjmGp^bDE%p1 zDgDio4rLnPC{>~ig%j)?alPPiS><)27-|({wRIrMA)c32-ltTF?`4($b>M#o_XF0o zPMog;=g;%K4tzh)^*V6F?G5umJo{P_rrtS_vv+XdCfg5FAat(1a1bVw%TW35z#mhnWX2Kl%TJqw3C zRwyh*d+a@$+M6xz$rklv!iI!i4E@y-HuL#@4cPX>=G6#zi)>!NzfjoUeH{Ir($_8S z=N9*J)K*g;cPuuueM?!Z09hyGHHNv19DQvB`t*Urq&Fz+Z|l*U-gb!9>vnwYBKmAN z@S+xE)WHDiXb6Aa=$}g^AN0g=@adxR_d^+63y%T;@tDeOsZvAd3`_?hw%vvr^h0Wy zsO2SME}3(DEijb?EkOFFukmED&qDy-A7YP0Y+2+)5;<`d7*HC|O4Qqu?e%(a)2*1n zPkvxCXgB69v)3*8l)kwR-`*^~o)38)^8He2-iU9PdVc+3aKLl46W0Mtg197}$c@jD zc?@k?ENYbaYMCgFBvF)y9gOU1(u$kh;;X+$8m&HMvDvDN3wYEwLMf z)%gJ4--0w3*{sq3?iW_<5WI6(vhkEG)%%h1O^ZUoBDQnPrP90s-!Aq1z+rHp=OOs! zfPlCpp2&^gkxOh*s}ux!J$&h1i_*J}Uni|VEnSZ?ypi9CGQ1f(jrO3%?t@nhhnLDA z+HkU`??l^uBBb%9Y~Yo`Dn5gE&X#fdYN^=teBMq^Qq4k(`cmIi;ftl7ll6TD?<#@c zPGCybf5P*`rD7vL9*fFPX-WFgx|4^EpJ>km(2K@Ofhf5ODOJ#2mY};l(A{RK0(5sD z#$rm@l=5<30ZF|K-T|IV`VEu_Pl92*bM_{nua@#Mpy%`63`2)_AuRPxDZW_hIe9D$ z<6Q~xn}UY~`A86+o0p1>{4DPAj#M_4;K{{hGl;U8MvqsemJoJGL;Fwq2%Y4`A4Hp7 zFEwG`AKFEmR&1hi7(&NCBjh<)YJig}~+8quLnFf4`o{BdDH_8)@y%W(_*~?Tf zp@$-eV%sHByAIM>x;CM$0UGSBV z(;BaPU?1k2LogL9PT2FyVo^dK(p$^}^_B=7PXYWDTcF_~KhiDG@9cq( z(@&&Z;8FD`X?LK%(;%ilYDx`(n(ZMkM=014YIKBFI6^~?&@_cmi)wllQqmJ4k)8;N z^h8LcCqg1U5fbT%&@?ELcJ}e7D?I_WZnzHvPoF5>1kx360wD)e%wW3WJ{To}_5r#| zDZ@RTcY)r0zq+GFa{*qG76=2mlUnG0&dXGZIGPxq_ILz zY7lxY(pV}wL(%~r?vD3Q%}hyNn+B&R9JELLNEAxtqv-XBJ0(eGFX=a$-@r3Bw03TS z7T@?m{<7pXdI~&R$=me|cXjXZs#S()0w(4SA!J0z zC~>w@N@W)U3kpRd1kT4=O&I&)zLRaUeZqFwK4Lpjgv6f;EkD`gjrfAV+EZH z;mI!(1>k8S?gB-6acmkX?6iH#&cnXq7lK~=e+Ydb&DCrZ*8JIK`xvP`kCdvAj}HWP z&gJ&xf^st<9&BR3L66+diP!<`bSWIqA-N*eXoS$$<126c?n18UX(*n$=|kzKINt+py^rgMI6ubu zADo}!{2Zq{zIX*+yn-)Y!56RKi&qf)6~ul8v0p*#R}lLZ#C`=7+9Y}N78~qEyu)twz%e5s7_$+m{ik^c)aoB@KEQf)Hh`E3;MB$|{{M6E^S68XD?a|G!ndD1 z`_F+-|9SA{x3|zJWa0JRExedGh}n`Hau&^Wd) z@%+t0pC9WJP|*<&(20bWRf1$Se~@)nD{lQHU)0GDJbp0V5eh)tdq>0m@QB&|e%Nv4_6P{cX&@n0Af8QLO}zD7!plpO)v*N!0C&?VYOd&_FS+M_Fdi6pt8 zS9ctM^>6it#{5S+Ad3R#hlr+7lM2IL)(RB^?~f>+{Sf^JwQ*$q`Qe9;qjw}vn*|5a zlTubFf6=lmc&*;3r8&v)8kD0mw@Grrs@iQNAFb zn#D&TBtPT`kEw2NV0&TODp6zy#s@C4lD|xc#OetNokM>ekP?+axA4!XJ z?et*BlJZUM2j!dQq%S_^zhC_3==X`XzW{5Zq-0QVgzbLZQJeCZdOl3Df$c@x%eH6G z!n|mE1MTx`2tNaR0@X#V?Y9KP_6VN8td=bBxBVFpU2TusektC*LOHg*iN6=a;o+H z38?u!(4+-*;Ub0G{-}O`{1+ENMQ`InS5TDJ-mf`mMo2`U-378Va6uajY-q$J4uRWW zL9MjUg!1HV$sN7wmqeBJR@+Y1N(|K3lc2xXa3`by+fNbmbJXl3xW0_@XSSzpAER%7 z8+rX2Z{9^od}R9*>N^kp=YO#S%XMl>KjeaTc5yD|lTk1QF7y4oc&XI#!j?t6fCbJ$ z6ObL|Q#y{2z2&#_++jYYvi?6m4(04r0n=qs9sX#DAXjR8e#pp2lm}?=DC74ZiVCGm z?d<<6@63YZDy}emTZ|;jGm?d{wOHQdT{c@NJ9a@#98yW1Nm6-(%0rgQLqb)mcu8JT zl_#oFMP3rN1d1KA6kdY?gCQ6k%nrs7HrvGDO*Xc?NG7V>eE;e0nLDGAG?wfKioVr% z`u6ngKHcZ^Ij2we?T(Zi@|j~gbHe@-E14UV?e#o3<8QGSRq)P0WsO+*#_b{>qlT*G z$K%c@hgK~9BM$88PjlUJaf~c!CYPt*zp6m`vPmTP0TQ&o!V(bWi4vX%m%eTz6JV3v z=PBD~1aW}2N>8qYrXgvDI(Co~vUiw^T57@SP3zz;mozeJy@FWwl`DH|W!cjx4<^|U z(knbiHR&Vm5J_*EO&me+)Q%j;Pe`u^j`a5Q*7W9bfPxND9(lf=8Y*;=^Hol@d^vrr zT69fu7c!dkx~8;{Bz>XyR+s4-gFI{eJ7Pcft)4!FyzDE!o1`y!`I>H|?~#8|ioOB$ z`U_2oUBqql!wdzQ8M8s=)YI9MGfB6?x9X8vIdW(~&nS~E?2MYEf7A=<`gEu1$C`E4 z^9H+bO>ZF#{3#lOw3PIDb{F!O5=_hm&1zhkECS*I>yfj0e_HxLfb%H7uj4l`o(H2| zCJ(o*(6+xwA0Ai9N%~k(Qo-lad&nir&5A7yE`84(UolnR;%vd-q&JPG!NzpiUm!PE z*~_zOMh;6Kr_2+@6hU4WpN9uRTR_*8jCSsy!8;n{=JYhZkK9>H){(a5v zJH+ivuBe@tqQ(k&ymL2O#88nA7_$P2mm`uKos8sF*AA0M&Da4ow#>L}*^=dqBcbpb zTpoLXrPR2c_xgOk^zuQCBQ5R-@%=~?$-)*NS9Vvs1(|0&V7=jIM9WTmH;i+6Oz%}( zx(OL9J(`-C4zb^256MQ5bs5SE(Y0E#EqUJZRvR71e_U+yOcADS9R>$S;2j#5gt2d# zc3^fW#u;>>YbZ_ev}?{hN|u|2PEq)!ICB@Zuwk-`1!1+rQ$_{pp7# z4b7(-=RK4$>f6#CBK8XE73at?YP7NH{%BjM%-4^iieo90FqLV>`y3>1emM0gN7H)y z;6JB>%}h45`U-rHr|8-^dxIoJrZg~cZr#YE5^0Yr+j>PDVNASm)mvUQX=d$66$h`F zY<9teaFz}d)SG3rO3Jf}Vq8IejCb%})QYQSfz?+!7Y@AF(ldPGG4JryN5~VoGTfP- zCGJC8%SvFHA2!Gc$?!MMDkd+>hjJa&&NQ|}KC41&Nh}G0Oo6X(_gZkI@`*w-Mdiao zP2!T=KJptNt9&8)XMu zt~C13$+^<0Y%DQc2cj-onPdXbvEGTKT6GsN?f;A;|LRF=jqTK|1#UsGD@?EYqG)Sj z**|E86Lu}qf#8@|cuV96BWcld556!WeX-(}750~tW@!>xEOKQgWgZW(1_UMFPW|Ou$*IU_$qb@{ua9hueAMx6XL#4>@|3{EoV*YYC>0X*Bc5e^woC4LG&{TFXXzI zuRbmdcV9d8ckRM_uH6zS@aya5(kFY(dyYGgrjQ-TJB4Oha4tP$Ziub?5$7p6&BNyK zy8N%caVWqS{IlX%mr0)&x6z&|;yAG!ah(o$wXPPpj&|g3<*wgO;=EVS5)aoIQ2O#B z`@TJ7ZnEZ;yA_$o?qax!o?g0Q4SYS~U0ldt;-At`bV-u70C)ECHPBsf>ynM46f2!* zYPe+0oJQHQuXxWn5#(R;1;Qiw9Ice~1=`B{PJV}b@ofFCe`3n)Z|MzL<2uXW5KP%T zHS?bJ{;ML+vNfKr)1ZcXX4S3Dh4=QNm&|ImvixkmC8=^-1wUM6Jo8HUpJ=TBPbiR2 zq_!rbv?b)F|CRzvFA}*CePJQbz33E|7~fq+Xa!tG&&vskgRg++B*ZNz_M32Wopf*o z{Q7b@(K7h+N((FW)po)`^pgnBD69A$;6~zp&-Lx(4}AZ$nlGUK&WQnc@x{q?$vSpk z`VITHcdS#tIyug_N#9Eb`8MfV_TK*ytMpUWoZqAqq}elmxjS7~@4myX zH%;zZ?XBQ`s6DvckG1=j`$001s6(c;rJK0`vjEVDM6f)VD1}rCvQpqQ(xU-7F zkI%85sD9*v4^AUWoXt6U8)1(0Ltxle7x{my-~B9A_5WgQal{18WJ;AZDtDP@+VV53 z^;nJ>-|PDetkJZvem}&2>GNUauXn&WlqkE9#x{~|BRcHj5v#E^)fV1n5c1Mm7|TFo zrIM4}AJNgK&ytVUylA#;4e+02uJ%#FjNzH__?&v2!e-VajA`VKJ$RpB3HDK~WVQ8* zI0a~eJCB4}tXY;6X@A$?6kZi6;6X*N!J!4S_@7Stlz`O?ovl=@rNnj;G) z{bnlJizfI!i?+>qaM74<~ufs=r@pXW2w=u6WB^}p{iN?PV*9g5DdLG402cnpsD8(B5k%o$%s0 ziN4h`S6bNxJshTP{Z`*Wn>{^Df75KrzL=U?4_HZR7txz6!3D*X*USD1H{fLj1@v%| zwmW6e8DFu#l@BWvfuhB*t@b^d%p+!q_LY?aI5X`lOa*7_e$~6gRi9G&%xqa~UnoCf zL90-dnzBOOV@{R7)-Uo<+A+Rj+ycye31X}A1j_&`(E5=PTapDxfIfO#fqwo9vSpCx zFPNn~z}(}<^xjTpcmB%S*(2U&OY07qy%4GZR`sy{K&bf6@kdqk?++P@oK+C)y4T^ewLe$^fo_RJ_0|>09GYvI2-V?nO5jWmYg=-q=noIrgQYsPG^i;Z?xHL`eSVlni5}@ zJkvjy#W{XZakO$hDg`7T;+?5($q{e?IFH-~u`E zU>qy=J>=Xc)V^?WbOqBT;RxWr-E$tpBpMh04G3aMcqEdwPHliw>tnp*`EMg_Eq*q@ zv;Xd)woIy~vVL)u{iUz=C4ZJxO_+&9d!FX4cwlCpX>&nuFT$8GH`*3k6aLc8>kUZa zv1mbja4c8q7lqpJkLG^duhXKs#rtv{q6TC}LMhl5>21!7Qp#ZPO#-2}}Cf0gggrmyuHNp|p|6N8Cr!+zf zD+^1qeY>~AqOnf35@wJ;TzNDHjD{89(5T*AxtxV&k41W*OksJ<)=2k|lA6i+(E_#m zFBkkJiB)-EhY&bDH;*PKl+Hj%4|xt?pWSxT0gjpSl>Q@Mp5 z7;bg9@;Uu&?zW_f)A4R+=Z8Do9qeqtDS7ObaHqR7Y1UbJ>|}7ayPMN_?{W9AJHoy0 z-lUC_^X?B6kMz&FX9;h0TY>XA_Z%_LyXOgWIv;s%bK8h{(Y?t23op5sINx`>+s>{Q z|KhCSZqDp`nSD2QxE;xC&hC39>0!s`SNWGS{E`k%@q2@qH{F|r-*RuUm&DudZNl%k zcgSa_+e!Fc_b%aGZdWp$Q~ur~&-dN?$pTLM`!{<{e8369GdT6{LrUS~Khl5VJ|Vo@ z?PgDiJ#G&%d);2boCQce``kWaKI2UB*_;XpN8)6_{p5MT9U%XM?jSo#9CC-)#pAF$ zoGjwBz&`f9;KV?3_`-dW%xACaW59ge9S4Sf&iC%%48aq$;YoLrd``Jjl)`SI>Cgol7p|B*D7mGWJ!tfS4Tnn_SANg7w7Y>+;D`_7yE)32II=jFqtjQ>>*=TDLv~?F0Alhm)s+!DcjQ2w~qM^ie=wot*K3brREzqTCq7gdyClnw$m|}Erq0vE`&TOQm zL;+Kc0=kU?W*Y@`Kmif=ore2)hWj4FeYZ|^mNb= zocTz4VZ95i?kyE9ntF|2oIus+|g-eXvw4%UxAVMoDzkKuks z2KO@!_dSO79>aQvVSTaTd#T}gscf6cBE#_#!?9-aWoMP#6BluYSMAMuHF92Dq~7q_ zV0dkWi=3j5{trs|r7WcE#O`=gmW3Qze%-Hr_VXKld&95Ur8sjg!4lhVYjw~AHTSNO fy-TmNcfAy>E!OYrm+YK>+d@iAHvM3BNBsRic2i4e literal 0 HcmV?d00001 diff --git a/setup/data/tools/bitmaps/radiant.ico b/setup/data/tools/bitmaps/radiant.ico new file mode 100644 index 0000000000000000000000000000000000000000..63de151eeea256483938dc7d62783bc43ea320a4 GIT binary patch literal 55465 zcmeG_2V7Iv*EgH6_i!Z$2#P2!+$JC{a8Fbe+*?tq;sAoXRV$9V2d&#Wunxo-QLENj zw^k*nbys5*i3+^$ocHob0trK~?f+}fkHdZM-h1Y~@4dT22!~h@1P+mshc1Ndhikc< zx%UYoWQ8kxZ$^Ba2|3=25PyFreTx?%&!X6SGqS~+kcCSLkxI4cwuCg?$lgP`86g?_ z2yq3TC~uCKkgt!j_h#gbkPy2wgxCTdrVr&4a{D5CZ$^d+2noCjG#%TwvNA7c4yszU zX&u}db0eAoJqaJTWiTNw+u8&Nc8$67$C~)4CBG+}mWg{;84?}-)wqC%!J%u0F5DEJ zyme!R%m+>#l5cgM?^Nx5a{p7^dpCG^CVZ@-)8>nNdko#@cX!yYbsU=vIJ;(d$5YeI zC-%QEOxR`R@p)xMc3k!0kh>~fQBj`KeWC5EU%7|*tKUs}$$h@>;Ebs0j>%Q! z>eI6OWaYl+Gm>T53x0RYePiFz!M1WjhU8dd>5SHqnmr39^;#2jt9iFM88Y$S5#O2j z6J1y4N{{dS@$tal!rSjW;D0$xk-Rw&Z4dnEpHG>Nl6C8%AuO|>_ua@Rc$KV0Lj z>y>Kzr-$s|&Xl?AsFU&arQCQ8XXmhYu{pvW{l)SIwz+@oNL;D5+PZF2_o|#Z!LuS- zlb{S2dqqdhOup1H&Yfd6^RuGt-1es*{$3dN?TWPLycMzqBuCjnFW$LPzMs6UTf3x6(S4_<)$~+Mz4MDkJ!HkiZ^zq*Em*O$H#ke~ z8s?eMOVtZKb#{r;e%B6a^<=!M5vp?N+aYeuLLel|yb|9gr%w|O-FDTb+mczq7k*#+ zoigoxSjEaCm8-KCN2f<*uN{8=gY>O`kEu6$y??v8*0OC`q|ZrJ=gh8Gjt16RB0q9- zv1DtH=LycLP-W$*-!2JLp58NMg0fO1FG_xhoV{03Jul{j+t=1{9?A9J4jnJec35Ha zQgpP_&iP~e&tBT!lXEFzYPV{;Ga@VwFS-5k(8W;??`+~H`im_mHErm>=s-khy<~^z z?gJOSyZKE+r*LlT<@{Mk)@Cob>EM#vNBLkzT*aH5@%HkcJTE`V9C$h-IH%fvdsRs5 z(}Dv{eyQKKYVPKcB+FK!mI^G$iPD6fI-oVKsz)vwpQ&%QO1uLfGy$Z7TT;*k+I zxAajw`op@3Ds$i`_ouSw?}k(5n$6bq+H~Sv#EkKN?`O$;cmLjQ?c8g?b+M9MUh(4W zNQI(l>MJfCGi@z=4p z?rt7e{g2eJa_inm#mZ4)&mDr8otsCLyJsH%amMQ(de;?7#hzOQkG50SyIeS8YwwuL zIiG0*)nlpLMjgfNr5KVE(d0y~#rJ=jQ9e=i1}#6{i|Zrj)|~2odG}Mt!HX7j6CA#9 zZ$(bvvfhf#6?Uy$u|-|;r7C!~4DdQ|Y~7WOX?=M;UOsxBTMAh%SRB=G2sC zA9SDNnYhJS)%fF>5jiPUv+d=Fy;S2YqQ<>T->(iOZa1N5u}HDX zPdO11>rf-Dj`1UB^TS7Q+Fy@fb)qKcmOJNWFGZcq^!JeQeQV`+&Z@RK6Wz1z6;17< zHVPVaqWXw|WEnqvDCfq__+@E8;>G!`w<0q$eIJsvQSK2mxyEbSe0LwG?l%84zVXLe;VB1%l4+T?Wd3H-l>19 zqL|*dL+-s}-V@p;`FU{q-{AJ|LpjBL;zvo}o?E`;ee#l4q*4U4=SnhK3<1Y1YzC_V3#xllgp3=+axT;p0qyer1 zqd4+@dtUXbIsItA0}n)xYbeKGPyWem^a0!Fn_IliZN7eRkN(jq!}x(c$GT^q@OFw5 zOT+K@ufN!$gU_hNma|%BtmtuJ&g4|B?3OPFYbM?-*4_QFH)j@ zmdu>k_I|y=*V0^MmapSnD#ZL@bK2~v+WkOwlbI1#N$)l&oFm2Rs!0LoU3%0p3urku z_Q}@GgI`mJ-8OX9c#+KmlVgNahqoMd>~6rKX8nE^zKXkH**^D4dIOi-;YkgzHaI=T z{L1pVdp;^EiKXtfx2zj%eY{V-F11}d+_Z~{vwih3)H`k6FH_@l8@=uGXZe^)oVENr z3HR(31Enu5o?`c?)^_@)NG`& z8Y2HKe2+zsDR;JB%CtJM{s?4Lq-^nB#rIUy{v~p<)#1JN!?*2yP}w}*=Xk`FTH%e) zQ3q%J`tb3rx~r^z?!mQ}KMR|C>E7h^M;o@Bc0w{t?NQ;7Pq|%nRt#5sST3&gJahc{ zRmaqm$K9?zQ#S4Ll6sn+-7nOltkjd9D~@yuiTp`;nLpJjx_{e{h*RpVYt45}?YTbJ z%QF7g<71j!efiMEVQTr6^5JRJu1nkN3XaX#d!d^q)N#=d)6=_(Ui3QOqHjNk(^dSB za+=J#^i}&GVuo*1x%^mHUEgihp$qq>SeV6cpDuY)CGp;sUEMV6GnUSE%nd*MW9`=+ z!<@1k1SEWOepPnmJ+)g@%}S|uVf>qI)Z#izXYDyQ?D2SYovPy)S94qE8v6n>dFp>rT$;yz=?^jKr=Rk8U^>)uqn)Upd`6OrCZA+UR}`v;E@C+DYGuLwyyC zQ`fHUGG^q~9ZTmdvWat%- z;#^wLqZ5Oy&Whtwy*hFZbL&33L&cAtIXd3&2d`Le`(ro5+dk}deZg<9T&X!f;tnI2&cv7&^gixhJl z<`1b-N7E@(`sqsj!SB62Id&HJBUas2wW^x%@|^WRPlc!SfjnpLK#{DPxb0zyvfBBo zOV?iOcH;i;gIk8VhqM?HF|N7HZDWH*{$nSrrzClb!cRWB5NW4nHW9e<1A36zaMbmnKZ0^-542zclWKW;V7cqN}1Q9o^vm@m$a z=^pUnT-E+w2_dSKQx~o8nvXm^q}uM4)nXp(@qb;R{^QQtit8V8#vPR(!H#k#fFyP?DK&^br8n0;uCm4;ohK__SG^ z?b_bouSm#tEjQEeUN4(dwQCRFpUv}FJ2!JvP+a=U#Oa&)Kedy#w>NXw3_D+Osch|t zgi*6SiLBC8yBn{sPM$MoNVSl6X*cR7Bu+bKb)dYf@cu8EsUxWA?Ip!X&}q+Ibk2+TJ7QthB1&ATvtk|`ugDk9$rb!+grDjw2vv&qR`=w?wXQ+f) z=46*k7KS99JbuYH``qB;H%^(yUtII+=&;+rr=AHLJg)_Rh-37T_BP3@Dx{e0nxmOr zEtOx{teL!GvWxo2&ttAvxOG6D{&ToxrRg?tH!TwT!**BZpK8`|GOBqO8=hsx4^|lXu2eu+CZby8i{GNa3)&=k_bTqBA;n+LUE= zjZdI`Tk&mVZtCJ5PhZ`<@O13gDH`*5@vXa~HuRD2%NcUM)24eX?(zDqAb&2BPe@7n zP#wPOxlN$ZKDMY(|Drc!J_B~QlKA)d#yNGJuUl9(#bGa7`wzm144W0;>2#Uvt0VSa zJd2-+c{vBOTAIN3Z=7=NyL>mT!%@lox1$?;{5F;N@HcVyD7==p8C`F1WFXHqoxi`o z^^Q~h=I&CrYE5;D*?TkmV6SP>oNJcVZOQV5_ghVy;Wtg?oBirsWQWI>?B%QPxF-t_ zc)X=%`p-(eoYB`@HYqq`VuWzOik9jIkKf(uB$hV2#`RT{SIkmSgI%K+Uaar)YWwc6 z8B}B0%mvq0c}U>6-o+~4o#r60Y>%wq#r=Ulk!efGS}*|yJ#+*vHsTz=;6*2maW!TNmadwvT;7u44@jSe;+dJO6pXUX(A?ESV zo*#3uD5nZ_SwXdQON-?_Zrx(Yx`hk<>Nghm6s}hWjSC-9ljD>9{f+obHeE-(Y7ib` zZJoBb)%j7^tMr{Q=wZbLL5q(2L{-hGFmn-ER3SGhQ|97*b9UCAd6nvCb&H9+oE`p2 zn0@JX%7^_!TKp1ewtW7~iGJHUY989<20f3z#XXQyHQMYaYG_7}=c!SzPjCk%dtc>m z|Dkinf>xU2@s(0KcadEf`D|`#+mwgND;70+IqdomeQhFE@IJ|Gc1^u~_i8QjHeryx zA}t~+Crf;vcpcrIxoL2nrM9!qj9eyPI;)Oqq3;C``HwwY?akT`Z4oos@?V~vn6KQi zG20D3l7ss;*!BA&zH+aE915^n9{L;jRd(&8jQ`SO+KAgHhI49!B#j>|4ZJS}7xcSH zwfg$$&VWgK6(Vs|_HXsX+eg$oB&f8P)B^=1gL7Wb`SXeR7T4NV?diJAGjZFD{i*lo z+D885Dwb#1^rA#xYufHn_^Eze(Pz=gHmYqaj?S$c0woZZNxd1D9nR?`=RHooIrNHW z$0_B`Z^;bb(3jg$vtv6Y*sJJj@1^oMJskL?{FLi*i`)7Ket1&nj2<~QTLrDTApLbv zPR$?kUCO7Xr3chso3UU@PR*Y%O@4Mc=di73c6pcOpPrnuEB`!xp`YA7k%ZXi9^p5* zcyMgO*4(kDW_^?dStLT!>hg(*AyYJ?wo&eTNgFxnGHM6qzOUfrcFKJ}#zG@-)K2z# zFnygu$M@BY+C{lD*X=cZwoqO}Ig1qh#ChsNovG6)ihVA#uW)}3jZE=OY|CjNiRbPwJcCJ8iGDjnWSj6r*O}-AeWB{N4BaiT}iAeam&__MjH8IMMNzuOfJc zEH-V&M|kHCnR$l`FPtHg>LZu&M>@$Xr`ZfXdL$#|-Zsi>Bxh0^m2$))#eD9T4j~#& zr9Z~+%3XE_Q3_|P^=E@vKhS%2&4sTZYD;~$4M-1f(OX#Bg*s%?MZ z`ma0sOOnequxWKMv*rvct~XTE!|`phc&~ZQ*0_~_y1S#<03}g-CUZ2dQJmzj`Ihe| z{hBj5X_lvW$-=H}xz|=qGMlYVwFw$iWkaXBoXhTMx9X7$|4+iHm!8G+J;bwDL?ylx z!^ z_r<15{5}02#dbfv9L67W&!#%K*2wa2an#;5e!$HHyXfDyiGY7c4V8Frd9>_-ysteJ z*8Zp0};ZCoA|GGKg;sr%;`LfBJc0=+ zj_t6i=>{*7F;c^8`_+RW&7PMh!fzaLjMj{M@Wky**IbL*X{~?LxbL%of!5bMK7D(h zcfP4*m*t&u?Od8Aq4g@ugYOgeLUJzO0|#Qcwm~rBF(VC!Zh|s;KtJ_+wJ!{tbksnv zTJDo=eykW{wsYp~-b;^1zFD0(JnKN?Tk|XR(9DdQKUp-wVK-ujRCxn~ z_oPjW_Q5-YBB%MlwH#0Zh*JUo5U2optOtZi3o`H@qSIfg#xEd@(!<4YjdL&m2CxSs zDdJq6B7@IS#Ht+YhkuI?VA2lkm&z%kpeQox_P@;shW7vad{EH-f0qx8+h2A*;KK98 z`v<>BP211sjlV$buJ*wx47X0pvhl$#kW7^ z6)Weo3GEBoUiS857lI;|t`w;=m?CwD77wemr3id4`+M(W?f+4ap1m|~ zd)eEM^_U{%11J)!Vd@vkC=P}tgZ><};X11{gvGbNLIc+R)_U}KY1;O(w;%f@Cjco@ zCA8!|sMwITp(ZL0P(1s?Q&_tEb-!@i%iey}*#Yn}V99;ZdI4+4bYuijJo}B8J!3oe znb>!ov3gkc??2T0^L!Bfhod0Ou?{W*Wco_jXEJ6t8~0`GN8LZq z2bG$z_TV#6wEgAkvib43N81+z7SHxCQ~yDH9-t2{05Z?Q)c1v#1?tmgA!`pl1BKh) zYY&?j%f95ce|h^sEdmQ`$vHrZc(kBMQ9dwy1`4-dSN3gyf62=I%h!KUDGy5K1Kl&w z5;*9_KUkeH)Rp}i$n$x&BOh5DTZba@wEZ#{#rJ{k8Njxzar<>;pGoJz_k2+IHAMmw;GF{PMuBM=amj;ySoL6)e?bz}Wd z9T=RVeTL)wQ;N|>Dym+zTglr03HWA}5xxUH#{jX9pC1ahU0>hHZ<#SCT^XStHUl!g znOeervp#S3I`$()Tx(IpR$6vwmG?aTn$LKh?aoHZoz*FSSkMm?sXf53&g7^0JMUvZ zuyq&f6bmA_!1oIHyCy{@yezr?`hIA?y5#hKg-@_PRqez+Q$J~qN89(7%65I-(GTOF z{qyWMwEY^`>kL@7w(I+$tghpr%u36vpzW|(lZNl$|L52F(&|+l`tI8(f^EpYhd$2_ zrfo+DWD)$HPk8Zpyo;lMY4bFRVV~EM`=M~#(f-GT%cF>Qdx}&KD?6+`5c(&%W#dz9 ze_@2Rc3Yi9`wY%2r~wQ zI-?)@94sgY$Lw+3nz8FLgbskF05?8Y0mSxDX|X%-Py$lK-h(2O-xbuYq|d|HjQl>p zdG5A=IzQmJF^-*Mos0gRB3^BZYdf$hHQ@Lrj`7_BWaQ!;5SGn=Q>C{b{Z-HhI6sbk zQ$s)S&0yS_o_j$(E&&!+?vVW1fb&DM0B-{t+Kgj9IPOu>a%S^S&0^+r*?TrL?gKOc z{eaK$KEV5c7XcN3mVjjq5y0>cpw4EAj3Ob6DT4hqR##(Tary&&;aPU7MiHNm#(A0c zL0Q{rjNb&>ZmiqIwVCw;wx?bFVf`EQD{!0=$2{|oA6M(b_!NE17f}TJnJm42`1kk# z*8zMWA{&Yf`o*|j`a0@g)3!sOf~_+cI(oyqD%+5cZtm+OowxIP!*qR~jYyp}t>4PX* zr?$%q*GXT`g0{&TZ>2&tvJNs#&&j2guuk%64>@R3L_OnuG`%Tqro&7kLwzSZ^ zto<1NH9jc5{l;x?K-+`w_WaL1Ym1@%fpq?&o&lEj%ln{s_8YeyOwpEo*UhG%A4B`G zjaR&9;IHvP(e|6RU9aq6ET7dke`shw`mFfR0L$yk)q}$A$1!4OKlXcsCp7fI8dix?hNkUD+i{$n`M#s=IF8Cf6S!d7bU2SwnEnOr z$7kRP;R#_b`T3#`aLky|$&*#46rpkZ3%4D`Z3Zm5>{0)M_9OjhnjYsj?|^nrP*%7P{@M0pJvu=9fO!s+;9CDZ54R@4 z8d8e(!9Ux6G!EZIIM(HXHzkCkeeln>zl0_i$X>V){{P#L4l(V6e~101eemzG--r)j zo&)FInRlxdX80EX+NlK8-@A45UtqVsi576P7Vr%qww3Dw{$)T>R0be|DxMA~rA!-2 zw4seQ6lp^qbqTMO960-l33+r#av>xa6#k-)72LJH;4(R6mWq{$&v0U{{r|IFlw z_7Vg9t|QRgAjCEsf(;W8iGsP1X%&rU1VIOe77!2K!witD#89FQ!E^LI=u3yJeH^@( zLq-f0&^d_*Z)!sxfqNOH6rnN@+Gs-wdKU7@&`T7hjMs*gg1&!9Dd`Y2(T3o48lV(t zfKs6$7qp=PL!9hHMHGN=05tqB1kAu4QW+tW|Af{2&Q(WB)+f;QVO$B zFk~~~1tE^rV09#P{oBI*$Xn18SxLxLD3z|839Quxp$ed>4wgfS@q`5SFG5e@5zN9u zm&MT=c)TQ}^LpsLKv7HrCpU>9uug%%+ym??TTEcC33TuW55*CfO99^R38~hFz&s(W z5`-?FPe%g#0iovyUK{{T&v6fc7o3-E?*T_#!!WEDEVB>WNno!b$b_l0>S2V`9t68* zKN8Y?8-YF!f&G-As}syPuZFY%Fq`H^VBH_+dWFDRUT6ijAS7TEe9_B;4luMo<{p9d z$b<;twHEUVd?hEO96Zjg7l5o}c(R8=jj9Og@W>B7SBRtkOZv|P|9POe9^iLvRotvb z^R*M&l!`$+Vd)qEeW@5AeQ6lb^g^4?Mx9fPNQPe6#*jf5_M2KH2Q9rJgFx4&MG|T= zu=K(@I*LG7p`Y%q@T)v}TuH(JkQ=8D?4*NoHJHqK^m+1;+&I0+4hu^Q9T^6B^zf;p zfhIRjPwMM4UA3U^fYjz4balJX2iF$VaQF=>uUfX zN@yA|1np`1JaW_Yq`r?7s^4mI=s};z4UMO@9Y3X2uNIy!;z$!Gj zE#pmzzt*cj+)6*EiED;I>o#mzFkz$O5hG952YL)#i?yMgTnSqyHZ@S8Sz z99VKvqg;c6(9qd{7H=%kQ+XWhw64QQV^A+YJrBAV2vz}@VppHJGx@)EfeKhn%YcaL zID10hp-`w{RWrW=LVuP4!3Bzift8<|A+-z_bR8{ua=&ra>!SORqD)Bmf__keff@S@)A|z^ZR>?L z!!7Sw(8{6%v_FrWwVtUzknZ4Utpip^eR2Z!>&Qu7^=IT8N61UcrPE6K24OGR8xSHUw|e0N$qoN`nT2@nMWv0O$i|_ya}){>A4BLl1`> z2ZRAu;syA>1_y~_Rb~%8?lm*M=lY*))32mK6tka|S>O1-W&@)?Jc?xeb9Rm9|B?+l z{b?IuU$G0l&h&r921EVxY^Z^6=Hl334*9+XJObDX@UMn~`lAi>T4&hLgKM-+pSJ@O zJ#f}Jp8bO72omxFko|_h!yHKk;<}0244~TnninN+vIMy3M5iTF~ z`9@EfLiC5dniU#ie%!am0#j#LzoYJ@*Z(B_4f^Uy(Q8m~jWHpafNTfLwEnttT3c$B zH>@+P?xoiszx$8qHRfNzT62BA`LCnyv*!+mX>~HKf5k><>nT8NJZp7_{cU)rRDQmt zt3Rkp6+o~7_P-Qm1G5fl2ND4o*FSte>W+xM$FfSJ&p#e`x}ff*_dl?wL2Co7^)IY0 zwVcP+AsikzqCeJq*ssj^9`h8gd)euaMtA@|pwBeIJp%d58SlrcKsS01G1j4i`s;j; zQ(kHGo=8)EXZe@D{(z`FKpQfMgEzDHigrHF{n7XJ(f4-%i}pLq6ZiKrXHS)` zp9@U1z}SF$0gaVIE4mJ4L0&c8{$%wSa)F}HtH8RC=Y1FDcieZ-V+Z_Nq7&-Bl@(q_ zp|&m=u^|fT5bhJkeayqJ8rC!12ZMSKId2%x+K6Wt^!kY+HT!^#wx~BEENUV4rO?|O zXkj4>-IrPdA={TSU6=Z$8P|{1Q$NJL%y{l`jouXfJTT{G{|a*A0AXymRDe^Pujz9j z&?n5fcb_2c2S9u$6<(M0^)z-p>JIB??5(5DQvuOmWdV%tcoxDWSmTNEu}-#G1a?%! zaz#772gJ5*I=!EF+{5DgowcV{Kjif%VCrWgJ{$Qb9B}^PHGPf)p2NY)VneK_q2Ixo z{j?o8@^XQGZ{k_>Y@XtVqwkjP>=pc78A5&sWT7EkyoU8^I=`FJ1D~?WMz}|cvsbAkdKEV>uKz~aeGeC1hQ@VA{ojzvEtoS^@m$r_uU^U^lJUROe}9BcuxZ-#ap27C;d z1{ehRxgZ9@6@XcE`wack`deu8=hK7L7yAOn`Z{>NU(?CVxxV?&PBSbAw4p3vC9EH& zNQ-ZnGm%(5jfHrIG`5v+Orl&p!!w2I4M!itqG^&1YqJf@0C}Me7S3!rl&0OOZ#(*4 zLyw~v(^o%^)t&hbjr;VNr~dwNM*nlb?-225Sx|rEh3C~W?S5#Nl*u_zj=+Z^J$DuGZ=r`W=Nyce=uD>`RfqNi?)F-hl{|cs6}0nrBEnZf1Te^cUQnv z;sRr}`o2fqbox6(o{yxxkvhcMFbvCqwxP7;P`Lg&-LHdAE`ZpM%BA~%tS)S*(;u>6 z9fEHrn`SI5o4RCLf5SS1x+A30d%}#JBWS4qV8RnH^Bcx=XX8p=myGL==TzhG1TlRl zCt7ntaQ&`v-=jW;`XkLJ61t@DGC(?AUD~acQ<9*d{>F7jp1T>}=NQ+?P=Cz7f$sO> z*>CuMC=8jlK7Pwe3WoZd)*boYBTXk6*S(@t&~(`j+f_#CZKN#pCaeM;o9V;4C%$y7c$?|8xAIwLz~g z{cq`yHXGKZ|2_R#8#3wkCbp-s-SEE$fuQnzKpZQRm9_e?zzJ3h!N-GA$7@5GHk4>X zSmZ>fi_}cWQ^nKwJSBu0;?GlPLqdnPTx|%ep0Kk5-6;rhpcX@l4HepZC4>-3shBVu zvg4?P25uz~sv$&B(f(;<+A-bhm?1dKiYT2cHJqqpJYzeW2T7=?XpkpJ2c1b!Pu+(@D&}U)e0;$B}aEM>$!z@zUndt;sbU=Qs|W?wDt>un9oIjk$f%;h}T zm-~=Fn~vEl9HoMNz0a8a!MLXw_sN<;0S3(=L<-fm!5G-v3&Q}oS68keFmD9;pD=rT zYlJiVk>j!(1;Mc7UmZTK$;)#g0{(y}AQW6PSk~(BB3AQLvY} zKI{+PPoRGdr!3tE`B3P%&-g$1&jbH?z|aG7c+N@!EnLf&Bs*y#s!}3?79vrVlB`aG z{3Rm5{Gv*sc{bQ^^Dd2E(D_BKjkSp(fkh0XG5JOCRz|Q16u~>v066XvcLa%m9w5-> z$9F!w-~vSj^2=+Z#t8HqjLBbv&JNrQ<|pM@f;PC9mB~-DuZG!01@+G(z+80xR>;0u z5N0o+52UaJt=arYsLgIHKatm>Syk5NNA_%Xqxp%}XyA+bwA9NkY68RsL0&rmGQu~) zPb3O<(s38so9HIeDtXm0vjDPypysrGLi4)S3bNM5&??a$r1Oe|mL@Vcu3L^KkugRy zxkb*VID0k{37bffqG@GqUOH$-Gb!*7vI7Vmq>zHT=Yd;ILtvh|>U4I<1Qd<)@*24a zutQPx>*}_Ua7^BD_4oDl z_cw58ZK&OzS_)bjRLBsZF6hA78xxU&U(+yK-d$B^U3QVkgDEi|-|Bf83@&^mUb^gf z=|M{{$dh;DDPaoNs|wOov9hUD2!V||TN9kixp1MB1<ON?fhC$FG)+)~{BST2Q(pQ^3cUt`lJJKv7QbZqVa~2l z1&W(UQ6JcTDjUXY`=v5%DA9&CFnWjmSzUh>?z7=gD3Ef%hv35efQ{TKfYLJblTJSBfa~pWj+oh7pfAP)=FJ|Entd^Cqke*kYg}iz z6mXppoC$F_=YU`+A9cX>0)*V9Q<;B^Y+N&mYeAXcUerrAdbyMYz#aqq?U?*1k4GM- zwNwS=<8Q|?YbY>_PB!XReE9)zcH3Jr^rGQh0P;X|tBo>Xu*Zn~xc-rlU|Kd`_<&w3 z%F-2IK9G}UCUpp&gEA5T4ee+4DV%_KFTxi-qJ788#;|1afemRw#EyTG!THwj;`%ef zxluqqv(I3dQQ4m-A9ZL<#C8RBC|3u4aF~AnkvC)eYm>4u556myI*oiw0tI!zGO+ig z;Cwr#PT;yuoD;?0fJRv?#=z)rr|+5H{pJZ&AQT4YiUj!b(eLyt5aRQSbkTql^lrs5pXD!#hW~vS$X+G zoCjpqsh$Fwc)+QJAifjvJBFZ>tv{EDYXI@LWE{Owk7saBq0YbgWwZDA+fA((6pgrt zgC}?ke6c06ik|Z{^*fxb9{9Udtenz>xZa`e5Ui7%0hbgiyQFgPJsfeww4OTI$silH zU<Do`SO`P5-tI>nD^c zFnbF8#sHpT)|^LKHwU}HdMn)Ti+1CB^ok9cHTSF^ zbUIW8xg~`)^tyMJmwwpqIIanN2@KVF>%`ixLcgA(*U{_e#c#4ejAdbBn82i3DMsHl zI@u$M8VzPIuw+zlU)mV9WwaFvhwk}jNbx%AK-P# zbug44sRW-}Vf{hbP3U^T+OBUuoYq>P3|L)sI$+nNDA37|JO;8YP&PBJiocP7Z8Mgy zp?nUM!F77QC4L|CW5aP+Phc{wNMPg_l#PUs2>$-Garv0;4!905#R%eihaM`1urSy~ z8b#-~o6Wy~UQ@6C8(+HeXY-UctO*R302+ICan^Q|fevLazbO3;b@=P$qkcLaaBmAC zvx`#t3#6kCD`7tP4TQ}w5^W=E0b@w0PTxxh#<5}4i8$xet4s(7ro>^TP+*@}DoSD6WnS<}P4dPnB z8*c0l+8!!G9k3&jTg(Ky`Sy3WNH!3eQkqPt8rrSV1JApwuDUazeo(Jg;OtN7* z&B2vU2l7goTc1CWI6_na&^Mr&!wvTE^`V?V;8Is4sAmtd1!6yVJLLmMK}~;15(sMH zET2AjyVA^D=~VC#+hEh?@va65FrDM8O&3^Jw`ZU_yd#OXgpTJ`W$D>$0s#-2RN7=+ zq(I>0BjDjZuL_V?c4NVV&ErYDY}sTzJ*^o*0)Z_=O3ekpTpz3}ifINsu>g8O`M}x* zwX<|9Cn#URSs*aamkdz=z}HRyhmFA{mXaP=Vls?jS_>eZE-chR2bhjA;Co27$J_=S zL;`^bl7Sr4QGlTiB1R(%CY^BUIW#LBe~}q|jRpdJK@c)g9B`}Abd~}#6q*jb&BD{6 zna=VmUP$Fo&~AtalrilGXsf7QnYN1B%oW-iw$MhA(rpxIjLAMIUo zm8T$F5gZ(_09p_fe5vC#d}yn{N|80}V5iV~cG`g@8ZdcSy4GP#X9r?4wMex#;sp87}@0wA>lqIDYEe z9ja2^>QrrVUeJhC?W8HN_rNbK2XeSUKbY|k^2WX|A=3eYcjMOtd1HLx{83Qb0y1#l z3$#ED_)D6pA+9yVsSU=5isp|pLSW2QX9v#Zi0zN(@n_~W4i(^y`ulW*CV#QUvJ7R^ z=$!+<1@npa0iN|zcbINm3&*kWe4zTHV0=`(1{E{`)$OrAlJ&fTghVd-#qC))rUdwV9K<_m84WG~Bfqpl3z5(*K zE{}5pPQ={#B=HD-WfGfA$jS40ew`bS$GV#aYmMLJjS=J7EmjqNrFp|Y6M&7Wk#xPR z8J~svS;hSp$cmfztf%=Hg74ks7IFEsQkJ zEgPK-95*xu41eV9-U4~c=u9p(9~#slhCh701u$39DVMex?XC{!9*FPTuEv-{oQSx~ zb4cZ2^f$vBGm7mF()+JjJz4&k#=P(Go6I7%xC(1F-(3QFE1WqFhQHh)9aTr@gSGUq2)vKfH-q8MjLjhF$O@72eIT?!mkxD z@j4FB6$h}iWa72|q4RBU&*Rd$^gY6)1An;C3@ z8DHpe2Qz`xoc_;{GMof7Eki_v+A)kgA$&a!d69U5zf5Tqa3G*4fFt#Z{_S!*}X2EHP06BL&Tj9$tWTsjc8UCZoS)m{*-9B5$S{e#79TfBHLS3v^Pz z&m2#vMI{ zG?@&;Dx^DoulrXA_7i3kJc9$V;kY-D)G4ohRJGGFSO*e9I;_#aenspf^wN=PuLRb; z;hd3dx?PAo@T^5VLni|I)*Rk^m_yOfX{P9rjliN8>As!eQL*tWGWre$b3dP8PDV@n zhyp#K(NLg0=S}>2UxhV}dkN1h5$1_L8SHh(GpoEp-hduSK#M+VrbRypeZbz|39dcC zIrE-B!P!D{KNz%cu^o!%HQ+iqee?)^OgvjXpx0MmAB;sjGl^}xvSG-QY!Z1?7vF5^ z3y@tC5J!MRwAc;8B&auU=ySGMT3lb$>4y)X|3cW8dYsfAsDga?hHrsa!lvI6;1C9V-A z!TD(=<%vb93;~Imc_n&&t|1C##(JiDh6V;-iWUM@t?_hm46*P}PLRkt!1y9TKu!9O zzqhAe#s6QHH{1T)-;?;ZK8H<%;qDjt4o4F+hRN(Jf9h*#6$v>DUIxXEfx+<|9{o^+@CALMDQ?9E_yh-1iRvy^?JWupI}hjm8p zNe5m9o=Y4;&5VaOGF)acV(?aY_>E~+aN$yu0*2s86LvX1RMOWkpZR7B&z8N?uYBLU dYzUdmn9((R!Z*Fp|3G&$c)I$ztaD0e0sw-;X5#<= diff --git a/setup/data/tools/gl/lighting_DBS_XY_Z_arbfp1.cg b/setup/data/tools/gl/lighting_DBS_XY_Z_arbfp1.cg deleted file mode 100644 index f535dbb2..00000000 --- a/setup/data/tools/gl/lighting_DBS_XY_Z_arbfp1.cg +++ /dev/null @@ -1,92 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "AUTHORS" for a list of contributors - -This program 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. - -This program 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 this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - -#include "utils.cg" - -struct cg_vertex2fragment -{ - float4 position : TEXCOORD0; - float4 tex_diffuse_bump : TEXCOORD1; - float4 tex_specular : TEXCOORD2; - float4 tex_atten_xy_z : TEXCOORD3; - - float3 tangent : TEXCOORD4; - float3 binormal : TEXCOORD5; - float3 normal : TEXCOORD6; -}; - -struct cg_fragment2final -{ - float4 color : COLOR; -}; - - -cg_fragment2final main(cg_vertex2fragment IN, - uniform sampler2D diffusemap, - uniform sampler2D bumpmap, - uniform sampler2D specularmap, - uniform sampler2D attenuationmap_xy, - uniform sampler2D attenuationmap_z, - uniform float3 view_origin, - uniform float3 light_origin, - uniform float3 light_color, - uniform float bump_scale, - uniform float specular_exponent) -{ - cg_fragment2final OUT; - - // construct object-space-to-tangent-space 3x3 matrix - float3x3 rotation = float3x3(IN.tangent, IN.binormal, IN.normal); - - // compute view direction in tangent space - float3 V = normalize(mul(rotation, view_origin - IN.position.xyz)); - - // compute light direction in tangent space - float3 L = normalize(mul(rotation, (light_origin - IN.position.xyz))); - - // compute half angle in tangent space - float3 H = normalize(L + V); - - // compute normal in tangent space from bumpmap - float3 T = CG_Expand(tex2D(bumpmap, IN.tex_diffuse_bump.zw).xyz); - T.z *= bump_scale; - float3 N = normalize(T); - - // compute the diffuse term - float4 diffuse = tex2D(diffusemap, IN.tex_diffuse_bump.xy); - diffuse.rgb *= light_color * saturate(dot(N, L)); - - // compute the specular term - float3 specular = tex2D(specularmap, IN.tex_specular.xy).rgb * light_color * pow(saturate(dot(N, H)), specular_exponent); - - // compute attenuation - float3 attenuation_xy = tex2Dproj(attenuationmap_xy, float3(IN.tex_atten_xy_z.x, IN.tex_atten_xy_z.y, IN.tex_atten_xy_z.w)).rgb; - float3 attenuation_z = tex2D(attenuationmap_z, float2(IN.tex_atten_xy_z.z, 0)).rgb; - - // compute final color - OUT.color.rgba = diffuse; - OUT.color.rgb += specular; - OUT.color.rgb *= attenuation_xy; - OUT.color.rgb *= attenuation_z; - - return OUT; -} diff --git a/setup/data/tools/gl/lighting_DBS_XY_Z_arbvp1.cg b/setup/data/tools/gl/lighting_DBS_XY_Z_arbvp1.cg deleted file mode 100644 index 59a6fc73..00000000 --- a/setup/data/tools/gl/lighting_DBS_XY_Z_arbvp1.cg +++ /dev/null @@ -1,78 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "AUTHORS" for a list of contributors - -This program 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. - -This program 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 this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - - -struct cg_app2vertex -{ - float4 position : POSITION; - float4 tex0 : ATTR8; - - float3 tangent : ATTR9; - float3 binormal : ATTR10; - float3 normal : ATTR11; -}; - -struct cg_vertex2fragment -{ - float4 hposition : POSITION; - - float4 position : TEXCOORD0; - float4 tex_diffuse_bump : TEXCOORD1; - float4 tex_specular : TEXCOORD2; - float4 tex_atten_xy_z : TEXCOORD3; - - float3 tangent : TEXCOORD4; - float3 binormal : TEXCOORD5; - float3 normal : TEXCOORD6; -}; - - - -cg_vertex2fragment main(cg_app2vertex IN) -{ - cg_vertex2fragment OUT; - - // transform vertex position into homogenous clip-space - OUT.hposition = mul(glstate.matrix.mvp, IN.position); - - // assign position in object space - OUT.position = IN.position; - - // transform texcoords - OUT.tex_diffuse_bump.xy = mul(glstate.matrix.texture[0], IN.tex0).xy; - - // transform texcoords - OUT.tex_diffuse_bump.zw = mul(glstate.matrix.texture[1], IN.tex0).xy; - - // transform texcoords - OUT.tex_specular = mul(glstate.matrix.texture[2], IN.tex0); - - // transform vertex position into light space - OUT.tex_atten_xy_z = mul(glstate.matrix.texture[3], IN.position); - - // assign tangent space vectors - OUT.tangent = IN.tangent; - OUT.binormal = IN.binormal; - OUT.normal = IN.normal; - - return OUT; -} diff --git a/setup/data/tools/gl/lighting_DBS_omni_fp.glp b/setup/data/tools/gl/lighting_DBS_omni_fp.glp deleted file mode 100644 index 88dab8d3..00000000 --- a/setup/data/tools/gl/lighting_DBS_omni_fp.glp +++ /dev/null @@ -1,86 +0,0 @@ -!!ARBfp1.0 -# cgc version 1.3.0001, build date Aug 4 2004 10:01:10 -# command line args: -profile arbfp1 -# source file: ..\..\setup\data\tools\gl\lighting_DBS_XY_Z_arbfp1.cg -# source file: ..\..\setup\data\tools\gl/utils.cg -#vendor NVIDIA Corporation -#version 1.0.02 -#profile arbfp1 -#program main -#semantic main.diffusemap -#semantic main.bumpmap -#semantic main.specularmap -#semantic main.attenuationmap_xy -#semantic main.attenuationmap_z -#semantic main.view_origin -#semantic main.light_origin -#semantic main.light_color -#semantic main.bump_scale -#semantic main.specular_exponent -#var float4 IN.position : $vin.TEX0 : TEX0 : 0 : 1 -#var float4 IN.tex_diffuse_bump : $vin.TEX1 : TEX1 : 0 : 1 -#var float4 IN.tex_specular : $vin.TEX2 : TEX2 : 0 : 1 -#var float4 IN.tex_atten_xy_z : $vin.TEX3 : TEX3 : 0 : 1 -#var float3 IN.tangent : $vin.TEX4 : TEX4 : 0 : 1 -#var float3 IN.binormal : $vin.TEX5 : TEX5 : 0 : 1 -#var float3 IN.normal : $vin.TEX6 : TEX6 : 0 : 1 -#var sampler2D diffusemap : : texunit 0 : 1 : 1 -#var sampler2D bumpmap : : texunit 1 : 2 : 1 -#var sampler2D specularmap : : texunit 2 : 3 : 1 -#var sampler2D attenuationmap_xy : : texunit 3 : 4 : 1 -#var sampler2D attenuationmap_z : : texunit 4 : 5 : 1 -#var float3 view_origin : : c[4] : 6 : 1 -#var float3 light_origin : : c[2] : 7 : 1 -#var float3 light_color : : c[3] : 8 : 1 -#var float bump_scale : : c[1] : 9 : 1 -#var float specular_exponent : : c[5] : 10 : 1 -#var float4 main.color : $vout.COL : COL : -1 : 1 -#const c[0] = 0.5 2 0 -PARAM c[6] = { { 0.5, 2, 0 }, - program.local[1..5] }; -TEMP R0; -TEMP R1; -TEMP R2; -ADD R1.xyz, -fragment.texcoord[0], c[2]; -DP3 R0.z, fragment.texcoord[6], R1; -DP3 R0.x, fragment.texcoord[4], R1; -DP3 R0.y, fragment.texcoord[5], R1; -ADD R1.xyz, -fragment.texcoord[0], c[4]; -DP3 R0.w, R0, R0; -DP3 R2.z, fragment.texcoord[6], R1; -DP3 R2.x, fragment.texcoord[4], R1; -DP3 R2.y, fragment.texcoord[5], R1; -RSQ R0.w, R0.w; -MUL R1.xyz, R0.w, R0; -DP3 R1.w, R2, R2; -RSQ R0.w, R1.w; -MUL R2.xyz, R0.w, R2; -ADD R2.xyz, R1, R2; -DP3 R0.w, R2, R2; -RSQ R2.w, R0.w; -TEX R0.xyz, fragment.texcoord[1].zwzw, texture[1], 2D; -ADD R0.xyz, R0, -c[0].x; -MUL R0.xyz, R0, c[0].y; -MUL R0.z, R0, c[1].x; -DP3 R1.w, R0, R0; -RSQ R0.w, R1.w; -MUL R0.xyz, R0.w, R0; -MUL R2.xyz, R2.w, R2; -DP3_SAT R0.w, R0, R2; -DP3_SAT R0.x, R0, R1; -TEX R2.xyz, fragment.texcoord[2], texture[2], 2D; -MUL R1.xyz, R2, c[3]; -POW R0.w, R0.w, c[5].x; -MUL R2.xyz, R1, R0.w; -MUL R1.xyz, R0.x, c[3]; -TEX R0, fragment.texcoord[1], texture[0], 2D; -MAD R2.xyz, R0, R1, R2; -TXP R0.xyz, fragment.texcoord[3], texture[3], 2D; -MOV R1.y, c[0].z; -MOV R1.x, fragment.texcoord[3].z; -TEX R1.xyz, R1, texture[4], 2D; -MUL R0.xyz, R2, R0; -MUL result.color.xyz, R0, R1; -MOV result.color.w, R0; -END -# 41 instructions, 3 R-regs diff --git a/setup/data/tools/gl/lighting_DBS_omni_vp.glp b/setup/data/tools/gl/lighting_DBS_omni_vp.glp deleted file mode 100644 index b4472d70..00000000 --- a/setup/data/tools/gl/lighting_DBS_omni_vp.glp +++ /dev/null @@ -1,410 +0,0 @@ -!!ARBvp1.0 -# cgc version 1.3.0001, build date Aug 4 2004 10:01:10 -# command line args: -profile arbvp1 -# source file: ..\..\setup\data\tools\gl\lighting_DBS_XY_Z_arbvp1.cg -#vendor NVIDIA Corporation -#version 1.0.02 -#profile arbvp1 -#program main -#semantic glstate : STATE -#var float4 glstate.material.ambient : STATE.MATERIAL.AMBIENT : : -1 : 0 -#var float4 glstate.material.diffuse : STATE.MATERIAL.DIFFUSE : : -1 : 0 -#var float4 glstate.material.specular : STATE.MATERIAL.SPECULAR : : -1 : 0 -#var float4 glstate.material.emission : STATE.MATERIAL.EMISSION : : -1 : 0 -#var float4 glstate.material.shininess : STATE.MATERIAL.SHININESS : : -1 : 0 -#var float4 glstate.material.front.ambient : STATE.MATERIAL.FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.material.front.diffuse : STATE.MATERIAL.FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.material.front.specular : STATE.MATERIAL.FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.material.front.emission : STATE.MATERIAL.FRONT.EMISSION : : -1 : 0 -#var float4 glstate.material.front.shininess : STATE.MATERIAL.FRONT.SHININESS : : -1 : 0 -#var float4 glstate.material.back.ambient : STATE.MATERIAL.BACK.AMBIENT : : -1 : 0 -#var float4 glstate.material.back.diffuse : STATE.MATERIAL.BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.material.back.specular : STATE.MATERIAL.BACK.SPECULAR : : -1 : 0 -#var float4 glstate.material.back.emission : STATE.MATERIAL.BACK.EMISSION : : -1 : 0 -#var float4 glstate.material.back.shininess : STATE.MATERIAL.BACK.SHININESS : : -1 : 0 -#var float4 glstate.light[0].ambient : STATE.LIGHT[0].AMBIENT : : -1 : 0 -#var float4 glstate.light[0].diffuse : STATE.LIGHT[0].DIFFUSE : : -1 : 0 -#var float4 glstate.light[0].specular : STATE.LIGHT[0].SPECULAR : : -1 : 0 -#var float4 glstate.light[0].position : STATE.LIGHT[0].POSITION : : -1 : 0 -#var float4 glstate.light[0].attenuation : STATE.LIGHT[0].ATTENUATION : : -1 : 0 -#var float4 glstate.light[0].spot.direction : STATE.LIGHT[0].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[0].half : STATE.LIGHT[0].HALF : : -1 : 0 -#var float4 glstate.light[1].ambient : STATE.LIGHT[1].AMBIENT : : -1 : 0 -#var float4 glstate.light[1].diffuse : STATE.LIGHT[1].DIFFUSE : : -1 : 0 -#var float4 glstate.light[1].specular : STATE.LIGHT[1].SPECULAR : : -1 : 0 -#var float4 glstate.light[1].position : STATE.LIGHT[1].POSITION : : -1 : 0 -#var float4 glstate.light[1].attenuation : STATE.LIGHT[1].ATTENUATION : : -1 : 0 -#var float4 glstate.light[1].spot.direction : STATE.LIGHT[1].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[1].half : STATE.LIGHT[1].HALF : : -1 : 0 -#var float4 glstate.light[2].ambient : STATE.LIGHT[2].AMBIENT : : -1 : 0 -#var float4 glstate.light[2].diffuse : STATE.LIGHT[2].DIFFUSE : : -1 : 0 -#var float4 glstate.light[2].specular : STATE.LIGHT[2].SPECULAR : : -1 : 0 -#var float4 glstate.light[2].position : STATE.LIGHT[2].POSITION : : -1 : 0 -#var float4 glstate.light[2].attenuation : STATE.LIGHT[2].ATTENUATION : : -1 : 0 -#var float4 glstate.light[2].spot.direction : STATE.LIGHT[2].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[2].half : STATE.LIGHT[2].HALF : : -1 : 0 -#var float4 glstate.light[3].ambient : STATE.LIGHT[3].AMBIENT : : -1 : 0 -#var float4 glstate.light[3].diffuse : STATE.LIGHT[3].DIFFUSE : : -1 : 0 -#var float4 glstate.light[3].specular : STATE.LIGHT[3].SPECULAR : : -1 : 0 -#var float4 glstate.light[3].position : STATE.LIGHT[3].POSITION : : -1 : 0 -#var float4 glstate.light[3].attenuation : STATE.LIGHT[3].ATTENUATION : : -1 : 0 -#var float4 glstate.light[3].spot.direction : STATE.LIGHT[3].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[3].half : STATE.LIGHT[3].HALF : : -1 : 0 -#var float4 glstate.light[4].ambient : STATE.LIGHT[4].AMBIENT : : -1 : 0 -#var float4 glstate.light[4].diffuse : STATE.LIGHT[4].DIFFUSE : : -1 : 0 -#var float4 glstate.light[4].specular : STATE.LIGHT[4].SPECULAR : : -1 : 0 -#var float4 glstate.light[4].position : STATE.LIGHT[4].POSITION : : -1 : 0 -#var float4 glstate.light[4].attenuation : STATE.LIGHT[4].ATTENUATION : : -1 : 0 -#var float4 glstate.light[4].spot.direction : STATE.LIGHT[4].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[4].half : STATE.LIGHT[4].HALF : : -1 : 0 -#var float4 glstate.light[5].ambient : STATE.LIGHT[5].AMBIENT : : -1 : 0 -#var float4 glstate.light[5].diffuse : STATE.LIGHT[5].DIFFUSE : : -1 : 0 -#var float4 glstate.light[5].specular : STATE.LIGHT[5].SPECULAR : : -1 : 0 -#var float4 glstate.light[5].position : STATE.LIGHT[5].POSITION : : -1 : 0 -#var float4 glstate.light[5].attenuation : STATE.LIGHT[5].ATTENUATION : : -1 : 0 -#var float4 glstate.light[5].spot.direction : STATE.LIGHT[5].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[5].half : STATE.LIGHT[5].HALF : : -1 : 0 -#var float4 glstate.light[6].ambient : STATE.LIGHT[6].AMBIENT : : -1 : 0 -#var float4 glstate.light[6].diffuse : STATE.LIGHT[6].DIFFUSE : : -1 : 0 -#var float4 glstate.light[6].specular : STATE.LIGHT[6].SPECULAR : : -1 : 0 -#var float4 glstate.light[6].position : STATE.LIGHT[6].POSITION : : -1 : 0 -#var float4 glstate.light[6].attenuation : STATE.LIGHT[6].ATTENUATION : : -1 : 0 -#var float4 glstate.light[6].spot.direction : STATE.LIGHT[6].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[6].half : STATE.LIGHT[6].HALF : : -1 : 0 -#var float4 glstate.light[7].ambient : STATE.LIGHT[7].AMBIENT : : -1 : 0 -#var float4 glstate.light[7].diffuse : STATE.LIGHT[7].DIFFUSE : : -1 : 0 -#var float4 glstate.light[7].specular : STATE.LIGHT[7].SPECULAR : : -1 : 0 -#var float4 glstate.light[7].position : STATE.LIGHT[7].POSITION : : -1 : 0 -#var float4 glstate.light[7].attenuation : STATE.LIGHT[7].ATTENUATION : : -1 : 0 -#var float4 glstate.light[7].spot.direction : STATE.LIGHT[7].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[7].half : STATE.LIGHT[7].HALF : : -1 : 0 -#var float4 glstate.lightmodel.ambient : STATE.LIGHTMODEL.AMBIENT : : -1 : 0 -#var float4 glstate.lightmodel.scenecolor : STATE.LIGHTMODEL.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightmodel.front.scenecolor : STATE.LIGHTMODEL.FRONT.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightmodel.back.scenecolor : STATE.LIGHTMODEL.BACK.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightprod[0].ambient : STATE.LIGHTPROD[0].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].diffuse : STATE.LIGHTPROD[0].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].specular : STATE.LIGHTPROD[0].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[0].front.ambient : STATE.LIGHTPROD[0].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].front.diffuse : STATE.LIGHTPROD[0].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].front.specular : STATE.LIGHTPROD[0].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[0].back.ambient : STATE.LIGHTPROD[0].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].back.diffuse : STATE.LIGHTPROD[0].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].back.specular : STATE.LIGHTPROD[0].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].ambient : STATE.LIGHTPROD[1].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].diffuse : STATE.LIGHTPROD[1].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].specular : STATE.LIGHTPROD[1].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].front.ambient : STATE.LIGHTPROD[1].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].front.diffuse : STATE.LIGHTPROD[1].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].front.specular : STATE.LIGHTPROD[1].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].back.ambient : STATE.LIGHTPROD[1].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].back.diffuse : STATE.LIGHTPROD[1].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].back.specular : STATE.LIGHTPROD[1].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].ambient : STATE.LIGHTPROD[2].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].diffuse : STATE.LIGHTPROD[2].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].specular : STATE.LIGHTPROD[2].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].front.ambient : STATE.LIGHTPROD[2].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].front.diffuse : STATE.LIGHTPROD[2].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].front.specular : STATE.LIGHTPROD[2].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].back.ambient : STATE.LIGHTPROD[2].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].back.diffuse : STATE.LIGHTPROD[2].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].back.specular : STATE.LIGHTPROD[2].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].ambient : STATE.LIGHTPROD[3].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].diffuse : STATE.LIGHTPROD[3].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].specular : STATE.LIGHTPROD[3].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].front.ambient : STATE.LIGHTPROD[3].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].front.diffuse : STATE.LIGHTPROD[3].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].front.specular : STATE.LIGHTPROD[3].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].back.ambient : STATE.LIGHTPROD[3].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].back.diffuse : STATE.LIGHTPROD[3].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].back.specular : STATE.LIGHTPROD[3].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].ambient : STATE.LIGHTPROD[4].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].diffuse : STATE.LIGHTPROD[4].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].specular : STATE.LIGHTPROD[4].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].front.ambient : STATE.LIGHTPROD[4].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].front.diffuse : STATE.LIGHTPROD[4].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].front.specular : STATE.LIGHTPROD[4].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].back.ambient : STATE.LIGHTPROD[4].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].back.diffuse : STATE.LIGHTPROD[4].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].back.specular : STATE.LIGHTPROD[4].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].ambient : STATE.LIGHTPROD[5].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].diffuse : STATE.LIGHTPROD[5].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].specular : STATE.LIGHTPROD[5].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].front.ambient : STATE.LIGHTPROD[5].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].front.diffuse : STATE.LIGHTPROD[5].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].front.specular : STATE.LIGHTPROD[5].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].back.ambient : STATE.LIGHTPROD[5].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].back.diffuse : STATE.LIGHTPROD[5].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].back.specular : STATE.LIGHTPROD[5].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].ambient : STATE.LIGHTPROD[6].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].diffuse : STATE.LIGHTPROD[6].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].specular : STATE.LIGHTPROD[6].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].front.ambient : STATE.LIGHTPROD[6].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].front.diffuse : STATE.LIGHTPROD[6].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].front.specular : STATE.LIGHTPROD[6].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].back.ambient : STATE.LIGHTPROD[6].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].back.diffuse : STATE.LIGHTPROD[6].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].back.specular : STATE.LIGHTPROD[6].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].ambient : STATE.LIGHTPROD[7].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].diffuse : STATE.LIGHTPROD[7].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].specular : STATE.LIGHTPROD[7].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].front.ambient : STATE.LIGHTPROD[7].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].front.diffuse : STATE.LIGHTPROD[7].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].front.specular : STATE.LIGHTPROD[7].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].back.ambient : STATE.LIGHTPROD[7].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].back.diffuse : STATE.LIGHTPROD[7].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].back.specular : STATE.LIGHTPROD[7].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.texgen[0].eye.s : STATE.TEXGEN[0].EYE.S : : -1 : 0 -#var float4 glstate.texgen[0].eye.t : STATE.TEXGEN[0].EYE.T : : -1 : 0 -#var float4 glstate.texgen[0].eye.r : STATE.TEXGEN[0].EYE.R : : -1 : 0 -#var float4 glstate.texgen[0].eye.q : STATE.TEXGEN[0].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[0].object.s : STATE.TEXGEN[0].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[0].object.t : STATE.TEXGEN[0].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[0].object.r : STATE.TEXGEN[0].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[0].object.q : STATE.TEXGEN[0].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[1].eye.s : STATE.TEXGEN[1].EYE.S : : -1 : 0 -#var float4 glstate.texgen[1].eye.t : STATE.TEXGEN[1].EYE.T : : -1 : 0 -#var float4 glstate.texgen[1].eye.r : STATE.TEXGEN[1].EYE.R : : -1 : 0 -#var float4 glstate.texgen[1].eye.q : STATE.TEXGEN[1].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[1].object.s : STATE.TEXGEN[1].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[1].object.t : STATE.TEXGEN[1].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[1].object.r : STATE.TEXGEN[1].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[1].object.q : STATE.TEXGEN[1].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[2].eye.s : STATE.TEXGEN[2].EYE.S : : -1 : 0 -#var float4 glstate.texgen[2].eye.t : STATE.TEXGEN[2].EYE.T : : -1 : 0 -#var float4 glstate.texgen[2].eye.r : STATE.TEXGEN[2].EYE.R : : -1 : 0 -#var float4 glstate.texgen[2].eye.q : STATE.TEXGEN[2].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[2].object.s : STATE.TEXGEN[2].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[2].object.t : STATE.TEXGEN[2].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[2].object.r : STATE.TEXGEN[2].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[2].object.q : STATE.TEXGEN[2].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[3].eye.s : STATE.TEXGEN[3].EYE.S : : -1 : 0 -#var float4 glstate.texgen[3].eye.t : STATE.TEXGEN[3].EYE.T : : -1 : 0 -#var float4 glstate.texgen[3].eye.r : STATE.TEXGEN[3].EYE.R : : -1 : 0 -#var float4 glstate.texgen[3].eye.q : STATE.TEXGEN[3].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[3].object.s : STATE.TEXGEN[3].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[3].object.t : STATE.TEXGEN[3].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[3].object.r : STATE.TEXGEN[3].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[3].object.q : STATE.TEXGEN[3].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[4].eye.s : STATE.TEXGEN[4].EYE.S : : -1 : 0 -#var float4 glstate.texgen[4].eye.t : STATE.TEXGEN[4].EYE.T : : -1 : 0 -#var float4 glstate.texgen[4].eye.r : STATE.TEXGEN[4].EYE.R : : -1 : 0 -#var float4 glstate.texgen[4].eye.q : STATE.TEXGEN[4].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[4].object.s : STATE.TEXGEN[4].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[4].object.t : STATE.TEXGEN[4].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[4].object.r : STATE.TEXGEN[4].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[4].object.q : STATE.TEXGEN[4].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[5].eye.s : STATE.TEXGEN[5].EYE.S : : -1 : 0 -#var float4 glstate.texgen[5].eye.t : STATE.TEXGEN[5].EYE.T : : -1 : 0 -#var float4 glstate.texgen[5].eye.r : STATE.TEXGEN[5].EYE.R : : -1 : 0 -#var float4 glstate.texgen[5].eye.q : STATE.TEXGEN[5].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[5].object.s : STATE.TEXGEN[5].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[5].object.t : STATE.TEXGEN[5].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[5].object.r : STATE.TEXGEN[5].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[5].object.q : STATE.TEXGEN[5].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[6].eye.s : STATE.TEXGEN[6].EYE.S : : -1 : 0 -#var float4 glstate.texgen[6].eye.t : STATE.TEXGEN[6].EYE.T : : -1 : 0 -#var float4 glstate.texgen[6].eye.r : STATE.TEXGEN[6].EYE.R : : -1 : 0 -#var float4 glstate.texgen[6].eye.q : STATE.TEXGEN[6].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[6].object.s : STATE.TEXGEN[6].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[6].object.t : STATE.TEXGEN[6].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[6].object.r : STATE.TEXGEN[6].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[6].object.q : STATE.TEXGEN[6].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[7].eye.s : STATE.TEXGEN[7].EYE.S : : -1 : 0 -#var float4 glstate.texgen[7].eye.t : STATE.TEXGEN[7].EYE.T : : -1 : 0 -#var float4 glstate.texgen[7].eye.r : STATE.TEXGEN[7].EYE.R : : -1 : 0 -#var float4 glstate.texgen[7].eye.q : STATE.TEXGEN[7].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[7].object.s : STATE.TEXGEN[7].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[7].object.t : STATE.TEXGEN[7].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[7].object.r : STATE.TEXGEN[7].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[7].object.q : STATE.TEXGEN[7].OBJECT.Q : : -1 : 0 -#var float4 glstate.fog.color : STATE.FOG.COLOR : : -1 : 0 -#var float4 glstate.fog.params : STATE.FOG.PARAMS : : -1 : 0 -#var float4 glstate.clip[0].plane : STATE.CLIP[0].PLANE : : -1 : 0 -#var float4 glstate.clip[1].plane : STATE.CLIP[1].PLANE : : -1 : 0 -#var float4 glstate.clip[2].plane : STATE.CLIP[2].PLANE : : -1 : 0 -#var float4 glstate.clip[3].plane : STATE.CLIP[3].PLANE : : -1 : 0 -#var float4 glstate.clip[4].plane : STATE.CLIP[4].PLANE : : -1 : 0 -#var float4 glstate.clip[5].plane : STATE.CLIP[5].PLANE : : -1 : 0 -#var float4 glstate.clip[6].plane : STATE.CLIP[6].PLANE : : -1 : 0 -#var float4 glstate.clip[7].plane : STATE.CLIP[7].PLANE : : -1 : 0 -#var float glstate.point.size : STATE.POINT.SIZE : : -1 : 0 -#var float glstate.point.attenuation : STATE.POINT.ATTENUATION : : -1 : 0 -#var float4x4 glstate.matrix.modelview[0] : STATE.MATRIX.MODELVIEW[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[1] : STATE.MATRIX.MODELVIEW[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[2] : STATE.MATRIX.MODELVIEW[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[3] : STATE.MATRIX.MODELVIEW[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[4] : STATE.MATRIX.MODELVIEW[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[5] : STATE.MATRIX.MODELVIEW[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[6] : STATE.MATRIX.MODELVIEW[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[7] : STATE.MATRIX.MODELVIEW[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.projection : STATE.MATRIX.PROJECTION : , 4 : -1 : 0 -#var float4x4 glstate.matrix.mvp : STATE.MATRIX.MVP : c[0], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[0] : STATE.MATRIX.TEXTURE[0] : c[4], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[1] : STATE.MATRIX.TEXTURE[1] : c[8], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[2] : STATE.MATRIX.TEXTURE[2] : c[12], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[3] : STATE.MATRIX.TEXTURE[3] : c[16], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[4] : STATE.MATRIX.TEXTURE[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[5] : STATE.MATRIX.TEXTURE[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[6] : STATE.MATRIX.TEXTURE[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[7] : STATE.MATRIX.TEXTURE[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[0] : STATE.MATRIX.PALETTE[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[1] : STATE.MATRIX.PALETTE[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[2] : STATE.MATRIX.PALETTE[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[3] : STATE.MATRIX.PALETTE[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[4] : STATE.MATRIX.PALETTE[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[5] : STATE.MATRIX.PALETTE[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[6] : STATE.MATRIX.PALETTE[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[7] : STATE.MATRIX.PALETTE[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[0] : STATE.MATRIX.PROGRAM[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[1] : STATE.MATRIX.PROGRAM[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[2] : STATE.MATRIX.PROGRAM[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[3] : STATE.MATRIX.PROGRAM[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[4] : STATE.MATRIX.PROGRAM[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[5] : STATE.MATRIX.PROGRAM[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[6] : STATE.MATRIX.PROGRAM[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[7] : STATE.MATRIX.PROGRAM[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[0] : STATE.MATRIX.MODELVIEW[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[1] : STATE.MATRIX.MODELVIEW[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[2] : STATE.MATRIX.MODELVIEW[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[3] : STATE.MATRIX.MODELVIEW[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[4] : STATE.MATRIX.MODELVIEW[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[5] : STATE.MATRIX.MODELVIEW[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[6] : STATE.MATRIX.MODELVIEW[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[7] : STATE.MATRIX.MODELVIEW[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.projection : STATE.MATRIX.PROJECTION.INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.mvp : STATE.MATRIX.MVP.INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[0] : STATE.MATRIX.TEXTURE[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[1] : STATE.MATRIX.TEXTURE[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[2] : STATE.MATRIX.TEXTURE[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[3] : STATE.MATRIX.TEXTURE[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[4] : STATE.MATRIX.TEXTURE[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[5] : STATE.MATRIX.TEXTURE[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[6] : STATE.MATRIX.TEXTURE[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[7] : STATE.MATRIX.TEXTURE[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[0] : STATE.MATRIX.PALETTE[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[1] : STATE.MATRIX.PALETTE[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[2] : STATE.MATRIX.PALETTE[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[3] : STATE.MATRIX.PALETTE[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[4] : STATE.MATRIX.PALETTE[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[5] : STATE.MATRIX.PALETTE[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[6] : STATE.MATRIX.PALETTE[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[7] : STATE.MATRIX.PALETTE[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[0] : STATE.MATRIX.PROGRAM[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[1] : STATE.MATRIX.PROGRAM[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[2] : STATE.MATRIX.PROGRAM[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[3] : STATE.MATRIX.PROGRAM[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[4] : STATE.MATRIX.PROGRAM[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[5] : STATE.MATRIX.PROGRAM[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[6] : STATE.MATRIX.PROGRAM[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[7] : STATE.MATRIX.PROGRAM[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[0] : STATE.MATRIX.MODELVIEW[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[1] : STATE.MATRIX.MODELVIEW[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[2] : STATE.MATRIX.MODELVIEW[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[3] : STATE.MATRIX.MODELVIEW[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[4] : STATE.MATRIX.MODELVIEW[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[5] : STATE.MATRIX.MODELVIEW[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[6] : STATE.MATRIX.MODELVIEW[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[7] : STATE.MATRIX.MODELVIEW[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.projection : STATE.MATRIX.PROJECTION.TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.mvp : STATE.MATRIX.MVP.TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[0] : STATE.MATRIX.TEXTURE[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[1] : STATE.MATRIX.TEXTURE[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[2] : STATE.MATRIX.TEXTURE[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[3] : STATE.MATRIX.TEXTURE[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[4] : STATE.MATRIX.TEXTURE[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[5] : STATE.MATRIX.TEXTURE[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[6] : STATE.MATRIX.TEXTURE[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[7] : STATE.MATRIX.TEXTURE[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[0] : STATE.MATRIX.PALETTE[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[1] : STATE.MATRIX.PALETTE[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[2] : STATE.MATRIX.PALETTE[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[3] : STATE.MATRIX.PALETTE[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[4] : STATE.MATRIX.PALETTE[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[5] : STATE.MATRIX.PALETTE[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[6] : STATE.MATRIX.PALETTE[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[7] : STATE.MATRIX.PALETTE[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[0] : STATE.MATRIX.PROGRAM[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[1] : STATE.MATRIX.PROGRAM[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[2] : STATE.MATRIX.PROGRAM[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[3] : STATE.MATRIX.PROGRAM[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[4] : STATE.MATRIX.PROGRAM[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[5] : STATE.MATRIX.PROGRAM[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[6] : STATE.MATRIX.PROGRAM[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[7] : STATE.MATRIX.PROGRAM[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[0] : STATE.MATRIX.MODELVIEW[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[1] : STATE.MATRIX.MODELVIEW[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[2] : STATE.MATRIX.MODELVIEW[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[3] : STATE.MATRIX.MODELVIEW[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[4] : STATE.MATRIX.MODELVIEW[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[5] : STATE.MATRIX.MODELVIEW[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[6] : STATE.MATRIX.MODELVIEW[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[7] : STATE.MATRIX.MODELVIEW[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.projection : STATE.MATRIX.PROJECTION.INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.mvp : STATE.MATRIX.MVP.INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[0] : STATE.MATRIX.TEXTURE[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[1] : STATE.MATRIX.TEXTURE[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[2] : STATE.MATRIX.TEXTURE[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[3] : STATE.MATRIX.TEXTURE[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[4] : STATE.MATRIX.TEXTURE[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[5] : STATE.MATRIX.TEXTURE[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[6] : STATE.MATRIX.TEXTURE[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[7] : STATE.MATRIX.TEXTURE[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[0] : STATE.MATRIX.PALETTE[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[1] : STATE.MATRIX.PALETTE[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[2] : STATE.MATRIX.PALETTE[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[3] : STATE.MATRIX.PALETTE[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[4] : STATE.MATRIX.PALETTE[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[5] : STATE.MATRIX.PALETTE[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[6] : STATE.MATRIX.PALETTE[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[7] : STATE.MATRIX.PALETTE[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[0] : STATE.MATRIX.PROGRAM[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[1] : STATE.MATRIX.PROGRAM[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[2] : STATE.MATRIX.PROGRAM[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[3] : STATE.MATRIX.PROGRAM[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[4] : STATE.MATRIX.PROGRAM[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[5] : STATE.MATRIX.PROGRAM[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[6] : STATE.MATRIX.PROGRAM[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[7] : STATE.MATRIX.PROGRAM[7].INVTRANS : , 4 : -1 : 0 -#var float4 IN.position : $vin.POSITION : POSITION : 0 : 1 -#var float4 IN.tex0 : $vin.ATTR8 : ATTR8 : 0 : 1 -#var float3 IN.tangent : $vin.ATTR9 : ATTR9 : 0 : 1 -#var float3 IN.binormal : $vin.ATTR10 : ATTR10 : 0 : 1 -#var float3 IN.normal : $vin.ATTR11 : ATTR11 : 0 : 1 -#var float4 main.hposition : $vout.HPOS : HPOS : -1 : 1 -#var float4 main.position : $vout.TEX0 : TEX0 : -1 : 1 -#var float4 main.tex_diffuse_bump : $vout.TEX1 : TEX1 : -1 : 1 -#var float4 main.tex_specular : $vout.TEX2 : TEX2 : -1 : 1 -#var float4 main.tex_atten_xy_z : $vout.TEX3 : TEX3 : -1 : 1 -#var float3 main.tangent : $vout.TEX4 : TEX4 : -1 : 1 -#var float3 main.binormal : $vout.TEX5 : TEX5 : -1 : 1 -#var float3 main.normal : $vout.TEX6 : TEX6 : -1 : 1 -PARAM c[20] = { state.matrix.mvp, - state.matrix.texture[0], - state.matrix.texture[1], - state.matrix.texture[2], - state.matrix.texture[3] }; -TEMP R0; -DP4 result.position.w, vertex.position, c[3]; -DP4 result.position.z, vertex.position, c[2]; -DP4 result.position.y, vertex.position, c[1]; -DP4 result.position.x, vertex.position, c[0]; -DP4 R0.y, vertex.attrib[8], c[9]; -DP4 R0.x, vertex.attrib[8], c[8]; -MOV result.texcoord[0], vertex.position; -MOV result.texcoord[1].zw, R0.xyxy; -DP4 result.texcoord[1].y, vertex.attrib[8], c[5]; -DP4 result.texcoord[1].x, vertex.attrib[8], c[4]; -DP4 result.texcoord[2].w, vertex.attrib[8], c[15]; -DP4 result.texcoord[2].z, vertex.attrib[8], c[14]; -DP4 result.texcoord[2].y, vertex.attrib[8], c[13]; -DP4 result.texcoord[2].x, vertex.attrib[8], c[12]; -DP4 result.texcoord[3].w, vertex.position, c[19]; -DP4 result.texcoord[3].z, vertex.position, c[18]; -DP4 result.texcoord[3].y, vertex.position, c[17]; -DP4 result.texcoord[3].x, vertex.position, c[16]; -MOV result.texcoord[4].xyz, vertex.attrib[9]; -MOV result.texcoord[5].xyz, vertex.attrib[10]; -MOV result.texcoord[6].xyz, vertex.attrib[11]; -END -# 21 instructions, 1 R-regs diff --git a/setup/data/tools/gl/utils.cg b/setup/data/tools/gl/utils.cg deleted file mode 100644 index 63bfcb6c..00000000 --- a/setup/data/tools/gl/utils.cg +++ /dev/null @@ -1,36 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "AUTHORS" for a list of contributors - -This program 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. - -This program 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 this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - -// fresnel approximation -float fast_fresnel(float3 I, float3 N, float3 fresnel_values) -{ - float power = fresnel_values.x; - float scale = fresnel_values.y; - float bias = fresnel_values.z; - - return bias + pow(1.0 - dot(I, N), power) * scale; -} - -float3 CG_Expand(float3 v) -{ - return (v - 0.5) * 2; // expand a range-compressed vector -} diff --git a/setup/data/tools/gl/zfill_arbfp1.cg b/setup/data/tools/gl/zfill_arbfp1.cg deleted file mode 100644 index c80189c2..00000000 --- a/setup/data/tools/gl/zfill_arbfp1.cg +++ /dev/null @@ -1,47 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2003 Robert Beckebans -Copyright (C) 2003, 2004 contributors of the XreaL project -Please see the file "AUTHORS" for a list of contributors - -This program 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. - -This program 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 this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - - -struct cg_vertex2fragment -{ - float4 position : POSITION; - float4 tex0 : TEXCOORD0; -}; - -struct cg_fragment2final -{ - float4 color : COLOR; -}; - - -cg_fragment2final main(in cg_vertex2fragment IN, - uniform sampler2D colormap) -{ - cg_fragment2final OUT; - - OUT.color.w = tex2D(colormap, IN.tex0.xy).a; - - OUT.color.xyz = 0; - - return OUT; -} diff --git a/setup/data/tools/gl/zfill_arbvp1.cg b/setup/data/tools/gl/zfill_arbvp1.cg deleted file mode 100644 index 4ffc6e27..00000000 --- a/setup/data/tools/gl/zfill_arbvp1.cg +++ /dev/null @@ -1,49 +0,0 @@ -/// ============================================================================ -/* -Copyright (C) 2003 Robert Beckebans -Copyright (C) 2003, 2004 contributors of the XreaL project -Please see the file "AUTHORS" for a list of contributors - -This program 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. - -This program 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 this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ - - -struct cg_app2vertex -{ - float4 position : ATTR0; - float4 texcoord0 : ATTR8; -}; - -struct cg_vertex2fragment -{ - float4 position : POSITION; - float4 tex0 : TEXCOORD0; -}; - - -cg_vertex2fragment main(cg_app2vertex IN) -{ - cg_vertex2fragment OUT; - - // transform vertex position into homogenous clip-space - OUT.position = mul(glstate.matrix.mvp, IN.position); - - // transform texcoords into 1st texture space - OUT.tex0 = mul(glstate.matrix.texture[0], IN.texcoord0); - - return OUT; -} diff --git a/setup/data/tools/gl/zfill_fp.glp b/setup/data/tools/gl/zfill_fp.glp deleted file mode 100644 index 5eb8b129..00000000 --- a/setup/data/tools/gl/zfill_fp.glp +++ /dev/null @@ -1,19 +0,0 @@ -!!ARBfp1.0 -# cgc version 1.3.0001, build date Aug 4 2004 10:01:10 -# command line args: -profile arbfp1 -# source file: ..\..\setup\data\tools\gl\zfill_arbfp1.cg -#vendor NVIDIA Corporation -#version 1.0.02 -#profile arbfp1 -#program main -#semantic main.colormap -#var float4 IN.position : : : 0 : 0 -#var float4 IN.tex0 : $vin.TEX0 : TEX0 : 0 : 1 -#var sampler2D colormap : : texunit 0 : 1 : 1 -#var float4 main.color : $vout.COL : COL : -1 : 1 -#const c[0] = 0 -PARAM c[1] = { { 0 } }; -MOV result.color.xyz, c[0].x; -TEX result.color.w, fragment.texcoord[0], texture[0], 2D; -END -# 2 instructions, 0 R-regs diff --git a/setup/data/tools/gl/zfill_vp.glp b/setup/data/tools/gl/zfill_vp.glp deleted file mode 100644 index f6eda0c0..00000000 --- a/setup/data/tools/gl/zfill_vp.glp +++ /dev/null @@ -1,384 +0,0 @@ -!!ARBvp1.0 -# cgc version 1.3.0001, build date Aug 4 2004 10:01:10 -# command line args: -profile arbvp1 -# source file: ..\..\setup\data\tools\gl\zfill_arbvp1.cg -#vendor NVIDIA Corporation -#version 1.0.02 -#profile arbvp1 -#program main -#semantic glstate : STATE -#var float4 glstate.material.ambient : STATE.MATERIAL.AMBIENT : : -1 : 0 -#var float4 glstate.material.diffuse : STATE.MATERIAL.DIFFUSE : : -1 : 0 -#var float4 glstate.material.specular : STATE.MATERIAL.SPECULAR : : -1 : 0 -#var float4 glstate.material.emission : STATE.MATERIAL.EMISSION : : -1 : 0 -#var float4 glstate.material.shininess : STATE.MATERIAL.SHININESS : : -1 : 0 -#var float4 glstate.material.front.ambient : STATE.MATERIAL.FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.material.front.diffuse : STATE.MATERIAL.FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.material.front.specular : STATE.MATERIAL.FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.material.front.emission : STATE.MATERIAL.FRONT.EMISSION : : -1 : 0 -#var float4 glstate.material.front.shininess : STATE.MATERIAL.FRONT.SHININESS : : -1 : 0 -#var float4 glstate.material.back.ambient : STATE.MATERIAL.BACK.AMBIENT : : -1 : 0 -#var float4 glstate.material.back.diffuse : STATE.MATERIAL.BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.material.back.specular : STATE.MATERIAL.BACK.SPECULAR : : -1 : 0 -#var float4 glstate.material.back.emission : STATE.MATERIAL.BACK.EMISSION : : -1 : 0 -#var float4 glstate.material.back.shininess : STATE.MATERIAL.BACK.SHININESS : : -1 : 0 -#var float4 glstate.light[0].ambient : STATE.LIGHT[0].AMBIENT : : -1 : 0 -#var float4 glstate.light[0].diffuse : STATE.LIGHT[0].DIFFUSE : : -1 : 0 -#var float4 glstate.light[0].specular : STATE.LIGHT[0].SPECULAR : : -1 : 0 -#var float4 glstate.light[0].position : STATE.LIGHT[0].POSITION : : -1 : 0 -#var float4 glstate.light[0].attenuation : STATE.LIGHT[0].ATTENUATION : : -1 : 0 -#var float4 glstate.light[0].spot.direction : STATE.LIGHT[0].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[0].half : STATE.LIGHT[0].HALF : : -1 : 0 -#var float4 glstate.light[1].ambient : STATE.LIGHT[1].AMBIENT : : -1 : 0 -#var float4 glstate.light[1].diffuse : STATE.LIGHT[1].DIFFUSE : : -1 : 0 -#var float4 glstate.light[1].specular : STATE.LIGHT[1].SPECULAR : : -1 : 0 -#var float4 glstate.light[1].position : STATE.LIGHT[1].POSITION : : -1 : 0 -#var float4 glstate.light[1].attenuation : STATE.LIGHT[1].ATTENUATION : : -1 : 0 -#var float4 glstate.light[1].spot.direction : STATE.LIGHT[1].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[1].half : STATE.LIGHT[1].HALF : : -1 : 0 -#var float4 glstate.light[2].ambient : STATE.LIGHT[2].AMBIENT : : -1 : 0 -#var float4 glstate.light[2].diffuse : STATE.LIGHT[2].DIFFUSE : : -1 : 0 -#var float4 glstate.light[2].specular : STATE.LIGHT[2].SPECULAR : : -1 : 0 -#var float4 glstate.light[2].position : STATE.LIGHT[2].POSITION : : -1 : 0 -#var float4 glstate.light[2].attenuation : STATE.LIGHT[2].ATTENUATION : : -1 : 0 -#var float4 glstate.light[2].spot.direction : STATE.LIGHT[2].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[2].half : STATE.LIGHT[2].HALF : : -1 : 0 -#var float4 glstate.light[3].ambient : STATE.LIGHT[3].AMBIENT : : -1 : 0 -#var float4 glstate.light[3].diffuse : STATE.LIGHT[3].DIFFUSE : : -1 : 0 -#var float4 glstate.light[3].specular : STATE.LIGHT[3].SPECULAR : : -1 : 0 -#var float4 glstate.light[3].position : STATE.LIGHT[3].POSITION : : -1 : 0 -#var float4 glstate.light[3].attenuation : STATE.LIGHT[3].ATTENUATION : : -1 : 0 -#var float4 glstate.light[3].spot.direction : STATE.LIGHT[3].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[3].half : STATE.LIGHT[3].HALF : : -1 : 0 -#var float4 glstate.light[4].ambient : STATE.LIGHT[4].AMBIENT : : -1 : 0 -#var float4 glstate.light[4].diffuse : STATE.LIGHT[4].DIFFUSE : : -1 : 0 -#var float4 glstate.light[4].specular : STATE.LIGHT[4].SPECULAR : : -1 : 0 -#var float4 glstate.light[4].position : STATE.LIGHT[4].POSITION : : -1 : 0 -#var float4 glstate.light[4].attenuation : STATE.LIGHT[4].ATTENUATION : : -1 : 0 -#var float4 glstate.light[4].spot.direction : STATE.LIGHT[4].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[4].half : STATE.LIGHT[4].HALF : : -1 : 0 -#var float4 glstate.light[5].ambient : STATE.LIGHT[5].AMBIENT : : -1 : 0 -#var float4 glstate.light[5].diffuse : STATE.LIGHT[5].DIFFUSE : : -1 : 0 -#var float4 glstate.light[5].specular : STATE.LIGHT[5].SPECULAR : : -1 : 0 -#var float4 glstate.light[5].position : STATE.LIGHT[5].POSITION : : -1 : 0 -#var float4 glstate.light[5].attenuation : STATE.LIGHT[5].ATTENUATION : : -1 : 0 -#var float4 glstate.light[5].spot.direction : STATE.LIGHT[5].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[5].half : STATE.LIGHT[5].HALF : : -1 : 0 -#var float4 glstate.light[6].ambient : STATE.LIGHT[6].AMBIENT : : -1 : 0 -#var float4 glstate.light[6].diffuse : STATE.LIGHT[6].DIFFUSE : : -1 : 0 -#var float4 glstate.light[6].specular : STATE.LIGHT[6].SPECULAR : : -1 : 0 -#var float4 glstate.light[6].position : STATE.LIGHT[6].POSITION : : -1 : 0 -#var float4 glstate.light[6].attenuation : STATE.LIGHT[6].ATTENUATION : : -1 : 0 -#var float4 glstate.light[6].spot.direction : STATE.LIGHT[6].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[6].half : STATE.LIGHT[6].HALF : : -1 : 0 -#var float4 glstate.light[7].ambient : STATE.LIGHT[7].AMBIENT : : -1 : 0 -#var float4 glstate.light[7].diffuse : STATE.LIGHT[7].DIFFUSE : : -1 : 0 -#var float4 glstate.light[7].specular : STATE.LIGHT[7].SPECULAR : : -1 : 0 -#var float4 glstate.light[7].position : STATE.LIGHT[7].POSITION : : -1 : 0 -#var float4 glstate.light[7].attenuation : STATE.LIGHT[7].ATTENUATION : : -1 : 0 -#var float4 glstate.light[7].spot.direction : STATE.LIGHT[7].SPOT.DIRECTION : : -1 : 0 -#var float4 glstate.light[7].half : STATE.LIGHT[7].HALF : : -1 : 0 -#var float4 glstate.lightmodel.ambient : STATE.LIGHTMODEL.AMBIENT : : -1 : 0 -#var float4 glstate.lightmodel.scenecolor : STATE.LIGHTMODEL.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightmodel.front.scenecolor : STATE.LIGHTMODEL.FRONT.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightmodel.back.scenecolor : STATE.LIGHTMODEL.BACK.SCENECOLOR : : -1 : 0 -#var float4 glstate.lightprod[0].ambient : STATE.LIGHTPROD[0].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].diffuse : STATE.LIGHTPROD[0].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].specular : STATE.LIGHTPROD[0].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[0].front.ambient : STATE.LIGHTPROD[0].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].front.diffuse : STATE.LIGHTPROD[0].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].front.specular : STATE.LIGHTPROD[0].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[0].back.ambient : STATE.LIGHTPROD[0].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[0].back.diffuse : STATE.LIGHTPROD[0].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[0].back.specular : STATE.LIGHTPROD[0].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].ambient : STATE.LIGHTPROD[1].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].diffuse : STATE.LIGHTPROD[1].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].specular : STATE.LIGHTPROD[1].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].front.ambient : STATE.LIGHTPROD[1].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].front.diffuse : STATE.LIGHTPROD[1].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].front.specular : STATE.LIGHTPROD[1].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[1].back.ambient : STATE.LIGHTPROD[1].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[1].back.diffuse : STATE.LIGHTPROD[1].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[1].back.specular : STATE.LIGHTPROD[1].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].ambient : STATE.LIGHTPROD[2].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].diffuse : STATE.LIGHTPROD[2].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].specular : STATE.LIGHTPROD[2].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].front.ambient : STATE.LIGHTPROD[2].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].front.diffuse : STATE.LIGHTPROD[2].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].front.specular : STATE.LIGHTPROD[2].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[2].back.ambient : STATE.LIGHTPROD[2].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[2].back.diffuse : STATE.LIGHTPROD[2].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[2].back.specular : STATE.LIGHTPROD[2].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].ambient : STATE.LIGHTPROD[3].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].diffuse : STATE.LIGHTPROD[3].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].specular : STATE.LIGHTPROD[3].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].front.ambient : STATE.LIGHTPROD[3].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].front.diffuse : STATE.LIGHTPROD[3].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].front.specular : STATE.LIGHTPROD[3].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[3].back.ambient : STATE.LIGHTPROD[3].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[3].back.diffuse : STATE.LIGHTPROD[3].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[3].back.specular : STATE.LIGHTPROD[3].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].ambient : STATE.LIGHTPROD[4].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].diffuse : STATE.LIGHTPROD[4].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].specular : STATE.LIGHTPROD[4].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].front.ambient : STATE.LIGHTPROD[4].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].front.diffuse : STATE.LIGHTPROD[4].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].front.specular : STATE.LIGHTPROD[4].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[4].back.ambient : STATE.LIGHTPROD[4].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[4].back.diffuse : STATE.LIGHTPROD[4].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[4].back.specular : STATE.LIGHTPROD[4].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].ambient : STATE.LIGHTPROD[5].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].diffuse : STATE.LIGHTPROD[5].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].specular : STATE.LIGHTPROD[5].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].front.ambient : STATE.LIGHTPROD[5].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].front.diffuse : STATE.LIGHTPROD[5].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].front.specular : STATE.LIGHTPROD[5].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[5].back.ambient : STATE.LIGHTPROD[5].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[5].back.diffuse : STATE.LIGHTPROD[5].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[5].back.specular : STATE.LIGHTPROD[5].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].ambient : STATE.LIGHTPROD[6].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].diffuse : STATE.LIGHTPROD[6].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].specular : STATE.LIGHTPROD[6].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].front.ambient : STATE.LIGHTPROD[6].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].front.diffuse : STATE.LIGHTPROD[6].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].front.specular : STATE.LIGHTPROD[6].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[6].back.ambient : STATE.LIGHTPROD[6].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[6].back.diffuse : STATE.LIGHTPROD[6].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[6].back.specular : STATE.LIGHTPROD[6].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].ambient : STATE.LIGHTPROD[7].AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].diffuse : STATE.LIGHTPROD[7].DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].specular : STATE.LIGHTPROD[7].SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].front.ambient : STATE.LIGHTPROD[7].FRONT.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].front.diffuse : STATE.LIGHTPROD[7].FRONT.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].front.specular : STATE.LIGHTPROD[7].FRONT.SPECULAR : : -1 : 0 -#var float4 glstate.lightprod[7].back.ambient : STATE.LIGHTPROD[7].BACK.AMBIENT : : -1 : 0 -#var float4 glstate.lightprod[7].back.diffuse : STATE.LIGHTPROD[7].BACK.DIFFUSE : : -1 : 0 -#var float4 glstate.lightprod[7].back.specular : STATE.LIGHTPROD[7].BACK.SPECULAR : : -1 : 0 -#var float4 glstate.texgen[0].eye.s : STATE.TEXGEN[0].EYE.S : : -1 : 0 -#var float4 glstate.texgen[0].eye.t : STATE.TEXGEN[0].EYE.T : : -1 : 0 -#var float4 glstate.texgen[0].eye.r : STATE.TEXGEN[0].EYE.R : : -1 : 0 -#var float4 glstate.texgen[0].eye.q : STATE.TEXGEN[0].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[0].object.s : STATE.TEXGEN[0].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[0].object.t : STATE.TEXGEN[0].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[0].object.r : STATE.TEXGEN[0].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[0].object.q : STATE.TEXGEN[0].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[1].eye.s : STATE.TEXGEN[1].EYE.S : : -1 : 0 -#var float4 glstate.texgen[1].eye.t : STATE.TEXGEN[1].EYE.T : : -1 : 0 -#var float4 glstate.texgen[1].eye.r : STATE.TEXGEN[1].EYE.R : : -1 : 0 -#var float4 glstate.texgen[1].eye.q : STATE.TEXGEN[1].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[1].object.s : STATE.TEXGEN[1].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[1].object.t : STATE.TEXGEN[1].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[1].object.r : STATE.TEXGEN[1].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[1].object.q : STATE.TEXGEN[1].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[2].eye.s : STATE.TEXGEN[2].EYE.S : : -1 : 0 -#var float4 glstate.texgen[2].eye.t : STATE.TEXGEN[2].EYE.T : : -1 : 0 -#var float4 glstate.texgen[2].eye.r : STATE.TEXGEN[2].EYE.R : : -1 : 0 -#var float4 glstate.texgen[2].eye.q : STATE.TEXGEN[2].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[2].object.s : STATE.TEXGEN[2].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[2].object.t : STATE.TEXGEN[2].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[2].object.r : STATE.TEXGEN[2].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[2].object.q : STATE.TEXGEN[2].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[3].eye.s : STATE.TEXGEN[3].EYE.S : : -1 : 0 -#var float4 glstate.texgen[3].eye.t : STATE.TEXGEN[3].EYE.T : : -1 : 0 -#var float4 glstate.texgen[3].eye.r : STATE.TEXGEN[3].EYE.R : : -1 : 0 -#var float4 glstate.texgen[3].eye.q : STATE.TEXGEN[3].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[3].object.s : STATE.TEXGEN[3].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[3].object.t : STATE.TEXGEN[3].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[3].object.r : STATE.TEXGEN[3].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[3].object.q : STATE.TEXGEN[3].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[4].eye.s : STATE.TEXGEN[4].EYE.S : : -1 : 0 -#var float4 glstate.texgen[4].eye.t : STATE.TEXGEN[4].EYE.T : : -1 : 0 -#var float4 glstate.texgen[4].eye.r : STATE.TEXGEN[4].EYE.R : : -1 : 0 -#var float4 glstate.texgen[4].eye.q : STATE.TEXGEN[4].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[4].object.s : STATE.TEXGEN[4].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[4].object.t : STATE.TEXGEN[4].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[4].object.r : STATE.TEXGEN[4].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[4].object.q : STATE.TEXGEN[4].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[5].eye.s : STATE.TEXGEN[5].EYE.S : : -1 : 0 -#var float4 glstate.texgen[5].eye.t : STATE.TEXGEN[5].EYE.T : : -1 : 0 -#var float4 glstate.texgen[5].eye.r : STATE.TEXGEN[5].EYE.R : : -1 : 0 -#var float4 glstate.texgen[5].eye.q : STATE.TEXGEN[5].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[5].object.s : STATE.TEXGEN[5].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[5].object.t : STATE.TEXGEN[5].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[5].object.r : STATE.TEXGEN[5].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[5].object.q : STATE.TEXGEN[5].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[6].eye.s : STATE.TEXGEN[6].EYE.S : : -1 : 0 -#var float4 glstate.texgen[6].eye.t : STATE.TEXGEN[6].EYE.T : : -1 : 0 -#var float4 glstate.texgen[6].eye.r : STATE.TEXGEN[6].EYE.R : : -1 : 0 -#var float4 glstate.texgen[6].eye.q : STATE.TEXGEN[6].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[6].object.s : STATE.TEXGEN[6].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[6].object.t : STATE.TEXGEN[6].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[6].object.r : STATE.TEXGEN[6].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[6].object.q : STATE.TEXGEN[6].OBJECT.Q : : -1 : 0 -#var float4 glstate.texgen[7].eye.s : STATE.TEXGEN[7].EYE.S : : -1 : 0 -#var float4 glstate.texgen[7].eye.t : STATE.TEXGEN[7].EYE.T : : -1 : 0 -#var float4 glstate.texgen[7].eye.r : STATE.TEXGEN[7].EYE.R : : -1 : 0 -#var float4 glstate.texgen[7].eye.q : STATE.TEXGEN[7].EYE.Q : : -1 : 0 -#var float4 glstate.texgen[7].object.s : STATE.TEXGEN[7].OBJECT.S : : -1 : 0 -#var float4 glstate.texgen[7].object.t : STATE.TEXGEN[7].OBJECT.T : : -1 : 0 -#var float4 glstate.texgen[7].object.r : STATE.TEXGEN[7].OBJECT.R : : -1 : 0 -#var float4 glstate.texgen[7].object.q : STATE.TEXGEN[7].OBJECT.Q : : -1 : 0 -#var float4 glstate.fog.color : STATE.FOG.COLOR : : -1 : 0 -#var float4 glstate.fog.params : STATE.FOG.PARAMS : : -1 : 0 -#var float4 glstate.clip[0].plane : STATE.CLIP[0].PLANE : : -1 : 0 -#var float4 glstate.clip[1].plane : STATE.CLIP[1].PLANE : : -1 : 0 -#var float4 glstate.clip[2].plane : STATE.CLIP[2].PLANE : : -1 : 0 -#var float4 glstate.clip[3].plane : STATE.CLIP[3].PLANE : : -1 : 0 -#var float4 glstate.clip[4].plane : STATE.CLIP[4].PLANE : : -1 : 0 -#var float4 glstate.clip[5].plane : STATE.CLIP[5].PLANE : : -1 : 0 -#var float4 glstate.clip[6].plane : STATE.CLIP[6].PLANE : : -1 : 0 -#var float4 glstate.clip[7].plane : STATE.CLIP[7].PLANE : : -1 : 0 -#var float glstate.point.size : STATE.POINT.SIZE : : -1 : 0 -#var float glstate.point.attenuation : STATE.POINT.ATTENUATION : : -1 : 0 -#var float4x4 glstate.matrix.modelview[0] : STATE.MATRIX.MODELVIEW[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[1] : STATE.MATRIX.MODELVIEW[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[2] : STATE.MATRIX.MODELVIEW[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[3] : STATE.MATRIX.MODELVIEW[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[4] : STATE.MATRIX.MODELVIEW[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[5] : STATE.MATRIX.MODELVIEW[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[6] : STATE.MATRIX.MODELVIEW[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.modelview[7] : STATE.MATRIX.MODELVIEW[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.projection : STATE.MATRIX.PROJECTION : , 4 : -1 : 0 -#var float4x4 glstate.matrix.mvp : STATE.MATRIX.MVP : c[0], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[0] : STATE.MATRIX.TEXTURE[0] : c[4], 4 : -1 : 1 -#var float4x4 glstate.matrix.texture[1] : STATE.MATRIX.TEXTURE[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[2] : STATE.MATRIX.TEXTURE[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[3] : STATE.MATRIX.TEXTURE[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[4] : STATE.MATRIX.TEXTURE[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[5] : STATE.MATRIX.TEXTURE[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[6] : STATE.MATRIX.TEXTURE[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.texture[7] : STATE.MATRIX.TEXTURE[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[0] : STATE.MATRIX.PALETTE[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[1] : STATE.MATRIX.PALETTE[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[2] : STATE.MATRIX.PALETTE[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[3] : STATE.MATRIX.PALETTE[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[4] : STATE.MATRIX.PALETTE[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[5] : STATE.MATRIX.PALETTE[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[6] : STATE.MATRIX.PALETTE[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.palette[7] : STATE.MATRIX.PALETTE[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[0] : STATE.MATRIX.PROGRAM[0] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[1] : STATE.MATRIX.PROGRAM[1] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[2] : STATE.MATRIX.PROGRAM[2] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[3] : STATE.MATRIX.PROGRAM[3] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[4] : STATE.MATRIX.PROGRAM[4] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[5] : STATE.MATRIX.PROGRAM[5] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[6] : STATE.MATRIX.PROGRAM[6] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.program[7] : STATE.MATRIX.PROGRAM[7] : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[0] : STATE.MATRIX.MODELVIEW[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[1] : STATE.MATRIX.MODELVIEW[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[2] : STATE.MATRIX.MODELVIEW[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[3] : STATE.MATRIX.MODELVIEW[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[4] : STATE.MATRIX.MODELVIEW[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[5] : STATE.MATRIX.MODELVIEW[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[6] : STATE.MATRIX.MODELVIEW[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.modelview[7] : STATE.MATRIX.MODELVIEW[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.projection : STATE.MATRIX.PROJECTION.INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.mvp : STATE.MATRIX.MVP.INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[0] : STATE.MATRIX.TEXTURE[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[1] : STATE.MATRIX.TEXTURE[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[2] : STATE.MATRIX.TEXTURE[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[3] : STATE.MATRIX.TEXTURE[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[4] : STATE.MATRIX.TEXTURE[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[5] : STATE.MATRIX.TEXTURE[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[6] : STATE.MATRIX.TEXTURE[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.texture[7] : STATE.MATRIX.TEXTURE[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[0] : STATE.MATRIX.PALETTE[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[1] : STATE.MATRIX.PALETTE[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[2] : STATE.MATRIX.PALETTE[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[3] : STATE.MATRIX.PALETTE[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[4] : STATE.MATRIX.PALETTE[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[5] : STATE.MATRIX.PALETTE[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[6] : STATE.MATRIX.PALETTE[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.palette[7] : STATE.MATRIX.PALETTE[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[0] : STATE.MATRIX.PROGRAM[0].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[1] : STATE.MATRIX.PROGRAM[1].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[2] : STATE.MATRIX.PROGRAM[2].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[3] : STATE.MATRIX.PROGRAM[3].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[4] : STATE.MATRIX.PROGRAM[4].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[5] : STATE.MATRIX.PROGRAM[5].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[6] : STATE.MATRIX.PROGRAM[6].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.inverse.program[7] : STATE.MATRIX.PROGRAM[7].INVERSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[0] : STATE.MATRIX.MODELVIEW[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[1] : STATE.MATRIX.MODELVIEW[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[2] : STATE.MATRIX.MODELVIEW[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[3] : STATE.MATRIX.MODELVIEW[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[4] : STATE.MATRIX.MODELVIEW[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[5] : STATE.MATRIX.MODELVIEW[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[6] : STATE.MATRIX.MODELVIEW[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.modelview[7] : STATE.MATRIX.MODELVIEW[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.projection : STATE.MATRIX.PROJECTION.TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.mvp : STATE.MATRIX.MVP.TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[0] : STATE.MATRIX.TEXTURE[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[1] : STATE.MATRIX.TEXTURE[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[2] : STATE.MATRIX.TEXTURE[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[3] : STATE.MATRIX.TEXTURE[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[4] : STATE.MATRIX.TEXTURE[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[5] : STATE.MATRIX.TEXTURE[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[6] : STATE.MATRIX.TEXTURE[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.texture[7] : STATE.MATRIX.TEXTURE[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[0] : STATE.MATRIX.PALETTE[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[1] : STATE.MATRIX.PALETTE[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[2] : STATE.MATRIX.PALETTE[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[3] : STATE.MATRIX.PALETTE[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[4] : STATE.MATRIX.PALETTE[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[5] : STATE.MATRIX.PALETTE[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[6] : STATE.MATRIX.PALETTE[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.palette[7] : STATE.MATRIX.PALETTE[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[0] : STATE.MATRIX.PROGRAM[0].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[1] : STATE.MATRIX.PROGRAM[1].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[2] : STATE.MATRIX.PROGRAM[2].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[3] : STATE.MATRIX.PROGRAM[3].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[4] : STATE.MATRIX.PROGRAM[4].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[5] : STATE.MATRIX.PROGRAM[5].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[6] : STATE.MATRIX.PROGRAM[6].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.transpose.program[7] : STATE.MATRIX.PROGRAM[7].TRANSPOSE : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[0] : STATE.MATRIX.MODELVIEW[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[1] : STATE.MATRIX.MODELVIEW[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[2] : STATE.MATRIX.MODELVIEW[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[3] : STATE.MATRIX.MODELVIEW[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[4] : STATE.MATRIX.MODELVIEW[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[5] : STATE.MATRIX.MODELVIEW[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[6] : STATE.MATRIX.MODELVIEW[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.modelview[7] : STATE.MATRIX.MODELVIEW[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.projection : STATE.MATRIX.PROJECTION.INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.mvp : STATE.MATRIX.MVP.INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[0] : STATE.MATRIX.TEXTURE[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[1] : STATE.MATRIX.TEXTURE[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[2] : STATE.MATRIX.TEXTURE[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[3] : STATE.MATRIX.TEXTURE[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[4] : STATE.MATRIX.TEXTURE[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[5] : STATE.MATRIX.TEXTURE[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[6] : STATE.MATRIX.TEXTURE[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.texture[7] : STATE.MATRIX.TEXTURE[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[0] : STATE.MATRIX.PALETTE[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[1] : STATE.MATRIX.PALETTE[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[2] : STATE.MATRIX.PALETTE[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[3] : STATE.MATRIX.PALETTE[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[4] : STATE.MATRIX.PALETTE[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[5] : STATE.MATRIX.PALETTE[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[6] : STATE.MATRIX.PALETTE[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.palette[7] : STATE.MATRIX.PALETTE[7].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[0] : STATE.MATRIX.PROGRAM[0].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[1] : STATE.MATRIX.PROGRAM[1].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[2] : STATE.MATRIX.PROGRAM[2].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[3] : STATE.MATRIX.PROGRAM[3].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[4] : STATE.MATRIX.PROGRAM[4].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[5] : STATE.MATRIX.PROGRAM[5].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[6] : STATE.MATRIX.PROGRAM[6].INVTRANS : , 4 : -1 : 0 -#var float4x4 glstate.matrix.invtrans.program[7] : STATE.MATRIX.PROGRAM[7].INVTRANS : , 4 : -1 : 0 -#var float4 IN.position : $vin.ATTR0 : ATTR0 : 0 : 1 -#var float4 IN.texcoord0 : $vin.ATTR8 : ATTR8 : 0 : 1 -#var float4 main.position : $vout.HPOS : HPOS : -1 : 1 -#var float4 main.tex0 : $vout.TEX0 : TEX0 : -1 : 1 -PARAM c[8] = { state.matrix.mvp, - state.matrix.texture[0] }; -DP4 result.position.w, vertex.attrib[0], c[3]; -DP4 result.position.z, vertex.attrib[0], c[2]; -DP4 result.position.y, vertex.attrib[0], c[1]; -DP4 result.position.x, vertex.attrib[0], c[0]; -DP4 result.texcoord[0].w, vertex.attrib[8], c[7]; -DP4 result.texcoord[0].z, vertex.attrib[8], c[6]; -DP4 result.texcoord[0].y, vertex.attrib[8], c[5]; -DP4 result.texcoord[0].x, vertex.attrib[8], c[4]; -END -# 8 instructions, 0 R-regs