diff --git a/.github/workflows/continuous_integration_other.yml b/.github/workflows/continuous_integration_other.yml index a0d14782e35aa753c1d1f9a15f27261451a1faba..06708903cfbc558dd4641d109cbf1678d55c6f2a 100644 --- a/.github/workflows/continuous_integration_other.yml +++ b/.github/workflows/continuous_integration_other.yml @@ -28,7 +28,7 @@ jobs: make mac elif [[ "${{ runner.os }}" == 'Linux' ]]; then sudo apt-get update - sudo apt install mesa-common-dev + sudo apt install mesa-common-dev libxfixes-dev make linux fi diff --git a/Help/e_curvelinedefs.html b/Help/e_curvelinedefs.html index b0e3ca3a9b73b566a06e1d3e972ea9f6b53df3ba..be1138d4e9a02ae8ad8be742426f2f1e2bc6948b 100755 --- a/Help/e_curvelinedefs.html +++ b/Help/e_curvelinedefs.html @@ -32,6 +32,22 @@ <td valign="top"><b>Escape</b></td> <td>Discard the changes and return to the previous mode.</td> </tr> + <tr> + <td valign="top"><b>Ctrl + Mousewheel</b></td> + <td>Increase/decrease the number of dividing vertices.</td> + </tr> + <tr> + <td valign="top"><b>LMB + Drag</b></td> + <td>Change the distance of the curve (when Fixed Circular Curve is not set).</td> + </tr> + <tr> + <td valign="top"><b>RMB + Drag</b></td> + <td>Change the angle of the curve.</td> + </tr> + <tr> + <td valign="top"><b>Ctrl + Alt + RMB + Drag</b></td> + <td>When Fixed Circlar Curve is set, increase/decrease the dividing vertices together with the angle of the curve to maintain a consistent circular curve</td> + </tr> </table> </p> </div> diff --git a/Makefile b/Makefile index 410144606654cfc0bcf1dd2a841924607b243dc6..cdf9308c1b391d19fdaefce0b39d5d6ec2d5ab57 100644 --- a/Makefile +++ b/Makefile @@ -75,6 +75,6 @@ nativemac: $(CXX) -std=c++14 -O2 --shared -g3 -o Build/libBuilderNative.so -fPIC -I Source/Native Source/Native/*.cpp Source/Native/OpenGL/*.cpp Source/Native/OpenGL/gl_load/*.c -ldl native: - $(CXX) -std=c++14 -O2 --shared -g3 -o Build/libBuilderNative.so -fPIC -I Source/Native Source/Native/*.cpp Source/Native/OpenGL/*.cpp Source/Native/OpenGL/gl_load/*.c -lX11 -ldl + $(CXX) -std=c++14 -O2 --shared -g3 -o Build/libBuilderNative.so -fPIC -I Source/Native Source/Native/*.cpp Source/Native/OpenGL/*.cpp Source/Native/OpenGL/gl_load/*.c -DUDB_LINUX=1 -lX11 -lXfixes -ldl -include $(DEPS) diff --git a/README.md b/README.md old mode 100755 new mode 100644 index 3beba4a744a2df531752985dd88810c4c4835ee0..6632a525cf69d86f76120caff4294a0bb46edeae --- a/README.md +++ b/README.md @@ -8,15 +8,15 @@ **Building on Linux:** -These instructions are for Debian-based distros and were tested with Debian 10 and Ubuntu 18.04. For others it should be similar. +These instructions are for Debian-based distros and were tested with Ubuntu 24.04 LTS. For others it should be similar. __Note:__ this is experimental. None of the developers are using Linux as a desktop OS, so you're pretty much on your own if you encounter any problems with running the application. - Install Mono. The `mono-complete` package from the Debian repo doesn't include `msbuild`, so you have to install `mono-complete` by following the instructions on the Mono project's website: https://www.mono-project.com/download/stable/#download-lin -- Install additional required packages: `sudo apt install make g++ git libx11-dev mesa-common-dev` -- Go to a directory of your choice and clone the repository (it'll automatically create an `UltimateZoneBuilder` directory in the current directory): `git clone https://git.do.srb2.org/STJr/UltimateZoneBuilder.git` -- Compile UDB: `cd UltimateZoneBuilder && make` -- Run UDB: `cd Build && ./builder` +- Install additional required packages: `sudo apt install make g++ git libx11-dev libxfixes-dev mesa-common-dev` +- Go to a directory of your choice and clone the repository (it'll automatically create an `UltimateZoneBuilder` directory in the current directory): `git clone https://github.com/jewalky/UltimateDoomBuilder.git` +- Compile UZB: `cd UltimateZoneBuilder && make` +- Run UZB: `cd Build && ./builder` **Links:** - [SRB2MB thread](https://mb.srb2.org/addons/ultimate-zone-builder.6126/) diff --git a/Source/Core/Actions/MouseInput.cs b/Source/Core/Actions/MouseInput.cs index 1b6bb64ee418de5012577e295d17ca000a97dca6..8855872679b6cf56f64494b1eec4aec162def405 100755 --- a/Source/Core/Actions/MouseInput.cs +++ b/Source/Core/Actions/MouseInput.cs @@ -55,6 +55,10 @@ namespace CodeImp.DoomBuilder.Actions mouse = null; } + #if MONO_WINFORMS + MouseInput_ShowCursor(false); + #endif + // We have no destructor GC.SuppressFinalize(this); } @@ -67,6 +71,10 @@ namespace CodeImp.DoomBuilder.Actions mouse.Dispose(); mouse = null; } + + #if MONO_WINFORMS + MouseInput_ShowCursor(true); + #endif } #endregion @@ -113,6 +121,11 @@ namespace CodeImp.DoomBuilder.Actions } #endregion + + #if MONO_WINFORMS + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void MouseInput_ShowCursor(bool show); + #endif } public struct MouseState diff --git a/Source/Core/Controls/ImageSelectorPanel.cs b/Source/Core/Controls/ImageSelectorPanel.cs index 82f0315da16c47ed78f629882b620c1441d3015a..bdd2148431d2988d8eb9c808ddcd87bc8608697d 100755 --- a/Source/Core/Controls/ImageSelectorPanel.cs +++ b/Source/Core/Controls/ImageSelectorPanel.cs @@ -408,6 +408,9 @@ namespace CodeImp.DoomBuilder.Controls protected override void OnMouseDoubleClick(MouseEventArgs e) { base.OnMouseDoubleClick(e); + //TODO: testing this on Windows, it looks like General.Interface.CtrlState and + // General.Interface.ShiftState are always false, because as the main window + // doesn't have focus and won't update these states if(General.Interface.CtrlState || General.Interface.ShiftState || selection.Count != 1) return; diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index d7aa048dbee49a823ddfdd57f64bb4c42231984c..4c06c435f6dc1a311b6f318ca5e83cce27310eb5 100755 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -1573,7 +1573,7 @@ namespace CodeImp.DoomBuilder.Data foreach(string spritefile in files) { ImageData img = new FileImage(Path.GetFileNameWithoutExtension(spritefile).ToLowerInvariant(), spritefile); - img.LoadImageNow(); + img.LoadImageNow(false); img.AllowUnload = false; name = INTERNAL_PREFIX + img.Name; long hash = Lump.MakeLongName(name, true); //mxd diff --git a/Source/Core/Windows/MainForm.cs b/Source/Core/Windows/MainForm.cs index 9ca7342a0a8f0d33b721cb5ea9479ac41f52739d..7e9c68eeab38568cab514291e54c5cb049221254 100755 --- a/Source/Core/Windows/MainForm.cs +++ b/Source/Core/Windows/MainForm.cs @@ -1264,24 +1264,6 @@ namespace CodeImp.DoomBuilder.Windows Cursor.Position = display.PointToScreen(new Point(display.ClientSize.Width / 2, display.ClientSize.Height / 2)); //mxd Cursor.Clip = display.RectangleToScreen(display.ClientRectangle); Cursor.Hide(); - - #if MONO_WINFORMS - // A beautiful transparent cursor, just for you mono! - string emptycursor = - "AAACAAEAICACAAAAAAAwAQAAFgAAACgAAAAgAAAAQAAAAAEAAQAAAAAAgAAAAAAAAAAAAAAAAgAA" + - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////////////////////" + - "////////////////////////////////////////////////////////////////////////////" + - "//////////////////////////////////////////////////////8="; - using (var stream = new MemoryStream(System.Convert.FromBase64String(emptycursor))) - { - var cursor = new Cursor(stream); - Cursor.Current = cursor; - display.Cursor = cursor; - } - Application.DoEvents(); - #endif } } @@ -1298,11 +1280,6 @@ namespace CodeImp.DoomBuilder.Windows // Release and show the mouse Cursor.Clip = Rectangle.Empty; Cursor.Position = display.PointToScreen(new Point(display.ClientSize.Width / 2, display.ClientSize.Height / 2)); - #if MONO_WINFORMS - Cursor.Current = Cursors.Default; - display.Cursor = Cursors.Default; - Application.DoEvents(); - #endif Cursor.Show(); } } @@ -4256,14 +4233,41 @@ namespace CodeImp.DoomBuilder.Windows // Returns the new texture name or the same texture name when cancelled public string BrowseTexture(IWin32Window owner, string initialvalue) { - return TextureBrowserForm.Browse(owner, initialvalue, false);//mxd + + DisableProcessing(); + #if MONO_WINFORMS + //Mono's Winforms treat dialogs a little differently + // they don't implicitly take focus from the parent window + // and keyboard input from focus window isn't reset when the dialog takes focus + BreakExclusiveMouseInput(); + ReleaseAllKeys(); + #endif + string tex = TextureBrowserForm.Browse(owner, initialvalue, false);//mxd + #if MONO_WINFORMS + ResumeExclusiveMouseInput(); + #endif + EnableProcessing(); + return tex; } // This browses for a flat // Returns the new flat name or the same flat name when cancelled public string BrowseFlat(IWin32Window owner, string initialvalue) { - return TextureBrowserForm.Browse(owner, initialvalue, true); //mxd. was FlatBrowserForm + DisableProcessing(); + #if MONO_WINFORMS + //Mono's Winforms treat dialogs a little differently + // they don't implicitly take focus from the parent window + // and keyboard input from focus window isn't reset when the dialog takes focus + BreakExclusiveMouseInput(); + ReleaseAllKeys(); + #endif + string tex = TextureBrowserForm.Browse(owner, initialvalue, true); //mxd. was FlatBrowserForm + #if MONO_WINFORMS + ResumeExclusiveMouseInput(); + #endif + EnableProcessing(); + return tex; } // This browses the lindef types diff --git a/Source/Native/RawMouse.cpp b/Source/Native/RawMouse.cpp index 5cdc0b4e491bb37136f3f5baede84462b7f58309..c0a45a9a3382edd0ad00d47ca8d9f07073455403 100644 --- a/Source/Native/RawMouse.cpp +++ b/Source/Native/RawMouse.cpp @@ -172,7 +172,7 @@ extern "C" RawMouse* RawMouse_New(void* hwnd) { -#ifdef _WIN32 +#if defined(WIN32) return new RawMouse(hwnd); #else return nullptr; @@ -194,4 +194,28 @@ float RawMouse_GetY(RawMouse* mouse) return mouse->GetY(); } +#ifdef UDB_LINUX +#include <X11/extensions/Xfixes.h> + +static Display *display = NULL; +#endif + +void MouseInput_ShowCursor(bool show) +{ +#ifdef UDB_LINUX + if (display == NULL) + { + display = XOpenDisplay(NULL); + if (display == NULL) + return; + } + + if (show) + XFixesShowCursor(display, DefaultRootWindow(display)); + else + XFixesHideCursor(display, DefaultRootWindow(display)); + XSync(display, True); +#endif +} + } diff --git a/Source/Native/exports.def b/Source/Native/exports.def index 8f364f8c2ba7f9fe19f6ba23cbb04ea8869af702..d7ed8f0cbd6fb30121ab3129bcdeea87770de0aa 100644 --- a/Source/Native/exports.def +++ b/Source/Native/exports.def @@ -50,6 +50,7 @@ EXPORTS RawMouse_Delete RawMouse_GetX RawMouse_GetY + MouseInput_ShowCursor Matrix_Null Matrix_Identity Matrix_Translation diff --git a/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs index 62b10977e355836d0ca5c74041a15f65f743475f..b7d7fd662a9f99c351d3f8f5cefc9089d29e95f8 100755 --- a/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs @@ -496,6 +496,7 @@ namespace CodeImp.DoomBuilder.BuilderModes else if(editpressed && prevoffset != 0) { int newangle = 0; + int newvertices = panel.Vertices; if(panel.FixedCurve) { // Flip required? @@ -513,7 +514,9 @@ namespace CodeImp.DoomBuilder.BuilderModes //TODO: there surely is a way to get new angle without iteration... double targetoffset = radius.GetLength() * u; double prevdiff = double.MaxValue; - int increment = (clampvalue ? panel.AngleIncrement : 1); + bool clampToKeyEllipseSegments = General.Interface.CtrlState && General.Interface.AltState; + + int increment = (clampToKeyEllipseSegments ? 15 : clampvalue ? panel.AngleIncrement : 1); for(int i = 1; i < panel.MaximumAngle; i += increment) { // Calculate diameter for current angle... @@ -530,7 +533,19 @@ namespace CodeImp.DoomBuilder.BuilderModes } // Clamp to 5 deg increments - if(clampvalue) newangle = (newangle / panel.AngleIncrement) * panel.AngleIncrement; + if(clampvalue) newangle = (newangle / increment) * increment; + + if(clampToKeyEllipseSegments) + { + newvertices = Math.Abs(newangle) / increment - 1; + + if(newvertices < 1) + newvertices = 1; + if(newangle < 30) + { + newangle = 0; + } + } } else { @@ -543,7 +558,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } // Set new angle without triggering the update... - panel.SetValues(panel.Vertices, panel.Distance, newangle, panel.FixedCurve, panel.FixedCurveOutwards); + panel.SetValues(newvertices, panel.Distance, newangle, panel.FixedCurve, panel.FixedCurveOutwards); // Update hint text hintlabel.Text = "Angle: " + panel.Angle; diff --git a/Source/Plugins/BuilderModes/Resources/Hints.cfg b/Source/Plugins/BuilderModes/Resources/Hints.cfg index 85317da910094b10758836eb5f90144d58aeb79a..ca70331117aab20389213e11747cdd147d7bb2e3 100755 --- a/Source/Plugins/BuilderModes/Resources/Hints.cfg +++ b/Source/Plugins/BuilderModes/Resources/Hints.cfg @@ -242,5 +242,6 @@ group general "<b>LMB-drag</b> or use <k>buildermodes_increasebevel</k> and <k>buildermodes_decreasebevel</k> to change curve depth. Hold <b>Shift</b> while dragging to change by 1 map unit" "<b>RMB-drag</b> or use <k>buildermodes_rotateclockwise</k> and <k>buildermodes_rotatecounterclockwise</k> to change curve bulginess. Hold <b>Shift</b> while dragging to change by 1 degree" "<b>LMB+RMB-drag</b> or use <k>buildermodes_increasesubdivlevel</k> and <k>buildermodes_decreasesubdivlevel</k> to change the number of points in the curve" +"When <b>CTRL+ALT+RMB-drag</b> When Fixed Circlar Curve is set, increase/decrease the dividing vertices together with the angle of the curve to maintain a consistent circular curve." "Press <k>builder_acceptmode</k> to accept" -"Press <k>builder_cancelmode</k> or <k>builder_classicedit</k> to cancel" \ No newline at end of file +"Press <k>builder_cancelmode</k> or <k>builder_classicedit</k> to cancel"