2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
|
|
|
* This program is released under GNU General Public License
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Namespaces
|
|
|
|
|
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Windows.Forms;
|
|
|
|
using CodeImp.DoomBuilder.Map;
|
|
|
|
using CodeImp.DoomBuilder.Rendering;
|
|
|
|
using CodeImp.DoomBuilder.Geometry;
|
|
|
|
using System.Drawing;
|
|
|
|
using CodeImp.DoomBuilder.Editing;
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
namespace CodeImp.DoomBuilder.BuilderModes
|
|
|
|
{
|
|
|
|
// No action or button for this mode, it is automatic.
|
|
|
|
// The EditMode attribute does not have to be specified unless the
|
|
|
|
// mode must be activated by class name rather than direct instance.
|
|
|
|
// In that case, just specifying the attribute like this is enough:
|
|
|
|
// [EditMode]
|
|
|
|
|
2013-03-18 13:52:27 +00:00
|
|
|
[EditMode(DisplayName = "Drag Things",
|
2011-12-03 14:49:53 +00:00
|
|
|
AllowCopyPaste = false,
|
2009-04-19 18:07:22 +00:00
|
|
|
Volatile = true)]
|
|
|
|
|
|
|
|
public sealed class DragThingsMode : BaseClassicMode
|
|
|
|
{
|
|
|
|
#region ================== Constants
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Variables
|
|
|
|
|
|
|
|
// Mode to return to
|
2014-07-18 15:11:37 +00:00
|
|
|
private readonly EditMode basemode;
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Mouse position on map where dragging started
|
2014-07-18 15:11:37 +00:00
|
|
|
private readonly Vector2D dragstartmappos;
|
|
|
|
|
|
|
|
//mxd. Offset from nearest grid intersection to dragstartmappos
|
|
|
|
private Vector2D dragstartoffset;
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Item used as reference for snapping to the grid
|
2014-07-18 15:11:37 +00:00
|
|
|
private readonly Thing dragitem;
|
|
|
|
private readonly Vector2D dragitemposition;
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// List of old thing positions
|
2014-07-18 15:11:37 +00:00
|
|
|
private readonly List<Vector2D> oldpositions;
|
2009-04-19 18:07:22 +00:00
|
|
|
|
2013-03-18 13:52:27 +00:00
|
|
|
//mxd
|
|
|
|
private class AlignData
|
|
|
|
{
|
2015-09-16 20:22:20 +00:00
|
|
|
public readonly int InitialAngle;
|
2013-03-18 13:52:27 +00:00
|
|
|
public int CurrentAngle;
|
2015-09-16 20:22:20 +00:00
|
|
|
public readonly float InitialHeight;
|
2013-03-18 13:52:27 +00:00
|
|
|
public float CurrentHeight;
|
|
|
|
public PointF Position = PointF.Empty;
|
|
|
|
public bool Active;
|
|
|
|
|
2014-12-03 23:15:26 +00:00
|
|
|
public AlignData(Thing t)
|
|
|
|
{
|
2013-03-18 13:52:27 +00:00
|
|
|
InitialAngle = t.AngleDoom;
|
|
|
|
InitialHeight = t.Position.z;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-16 20:22:20 +00:00
|
|
|
private AlignData aligndata;
|
2013-03-18 13:52:27 +00:00
|
|
|
|
2009-04-19 18:07:22 +00:00
|
|
|
// List of selected items
|
2014-07-18 15:11:37 +00:00
|
|
|
private readonly ICollection<Thing> selectedthings;
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// List of non-selected items
|
2014-07-18 15:11:37 +00:00
|
|
|
private readonly ICollection<Thing> unselectedthings;
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Keep track of view changes
|
|
|
|
private float lastoffsetx;
|
|
|
|
private float lastoffsety;
|
|
|
|
private float lastscale;
|
|
|
|
|
|
|
|
// Options
|
|
|
|
private bool snaptogrid; // SHIFT to toggle
|
|
|
|
private bool snaptonearest; // CTRL to enable
|
2014-07-18 15:11:37 +00:00
|
|
|
private bool snaptogridincrement; //mxd. ALT to toggle
|
2015-07-09 22:32:12 +00:00
|
|
|
private bool snaptocardinaldirection; //mxd. ALT-SHIFT to enable
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Properties
|
|
|
|
|
|
|
|
// Just keep the base mode button checked
|
|
|
|
public override string EditModeButtonName { get { return basemode.GetType().Name; } }
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Constructor / Disposer
|
|
|
|
|
|
|
|
// Constructor to start dragging immediately
|
|
|
|
public DragThingsMode(EditMode basemode, Vector2D dragstartmappos)
|
|
|
|
{
|
|
|
|
// Initialize
|
|
|
|
this.dragstartmappos = dragstartmappos;
|
|
|
|
this.basemode = basemode;
|
|
|
|
|
|
|
|
Cursor.Current = Cursors.AppStarting;
|
|
|
|
|
|
|
|
// Mark what we are dragging
|
|
|
|
General.Map.Map.ClearAllMarks(false);
|
|
|
|
General.Map.Map.MarkSelectedThings(true, true);
|
|
|
|
|
|
|
|
// Get selected things
|
|
|
|
selectedthings = General.Map.Map.GetMarkedThings(true);
|
|
|
|
unselectedthings = new List<Thing>();
|
|
|
|
foreach(Thing t in General.Map.ThingsFilter.VisibleThings) if(!t.Marked) unselectedthings.Add(t);
|
|
|
|
|
|
|
|
// Get the nearest thing for snapping
|
|
|
|
dragitem = MapSet.NearestThing(selectedthings, dragstartmappos);
|
|
|
|
|
|
|
|
// Make old positions list
|
|
|
|
// We will use this as reference to move the vertices, or to move them back on cancel
|
|
|
|
oldpositions = new List<Vector2D>(selectedthings.Count);
|
|
|
|
foreach(Thing t in selectedthings) oldpositions.Add(t.Position);
|
|
|
|
|
|
|
|
// Also keep old position of the dragged item
|
|
|
|
dragitemposition = dragitem.Position;
|
|
|
|
|
2014-07-18 15:11:37 +00:00
|
|
|
//mxd. Get drag offset
|
2014-09-30 19:46:33 +00:00
|
|
|
dragstartoffset = General.Map.Grid.SnappedToGrid(dragitem.Position) - dragitemposition;
|
2014-07-18 15:11:37 +00:00
|
|
|
|
2009-04-19 18:07:22 +00:00
|
|
|
// Keep view information
|
|
|
|
lastoffsetx = renderer.OffsetX;
|
|
|
|
lastoffsety = renderer.OffsetY;
|
|
|
|
lastscale = renderer.Scale;
|
|
|
|
|
|
|
|
Cursor.Current = Cursors.Default;
|
|
|
|
|
|
|
|
// We have no destructor
|
|
|
|
GC.SuppressFinalize(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Disposer
|
|
|
|
public override void Dispose()
|
|
|
|
{
|
|
|
|
// Not already disposed?
|
|
|
|
if(!isdisposed)
|
|
|
|
{
|
|
|
|
// Clean up
|
|
|
|
|
|
|
|
// Done
|
|
|
|
base.Dispose();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Methods
|
|
|
|
|
|
|
|
// This moves the selected things relatively
|
|
|
|
// Returns true when things has actually moved
|
2015-07-09 22:32:12 +00:00
|
|
|
private bool MoveThingsRelative(Vector2D offset, bool snapgrid, bool snapgridincrement, bool snapnearest, bool snapcardinal)
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
2015-07-09 22:32:12 +00:00
|
|
|
//mxd. If snap to cardinal directions is enabled, modify the offset
|
|
|
|
if(snapcardinal)
|
|
|
|
{
|
Fixed, Draw Lines/Rectangle/Circle/Curve modes: line length labels displayed incorrect length.
Changed, Drag Linedefs/Vertices/Sectors/Things modes: line length labels are now displayed the same way as in Draw modes.
Changed, Drag Linedefs/Vertices/Sectors/Things modes: "lock movement to cardinal directions" mode (Alt-Shift-Drag) now locks movement in 4 directions instead of 8 and doesn't snap map elements to nearest grid intersections when they are not aligned to it.
Added, Visual mode, GZDoom, DECORATE: FORCEXYBILLBOARD flag is now supported.
Added, Visual mode, GLOOME, DECORATE: FLOORSPRITE, CEILSPRITE, WALLSPRITE, ROLLSPRITE and STICKTOPLANE flags are now supported (implementation is somewhat broken ATM and probably doesn't work the same way as in GLOOME, because Windows build with most these features is nowhere to be found...).
Fixed, Visual mode: in some cases Thing brightness was calculated incorrectly.
Updated ZDoom_DECORATE.cfg.
2015-08-25 22:05:14 +00:00
|
|
|
float angle = Angle2D.DegToRad((General.ClampAngle((int)Angle2D.RadToDeg(offset.GetAngle()) + 44)) / 90 * 90);
|
2015-07-09 22:32:12 +00:00
|
|
|
offset = new Vector2D(0, -offset.GetLength()).GetRotated(angle);
|
Fixed, Draw Lines/Rectangle/Circle/Curve modes: line length labels displayed incorrect length.
Changed, Drag Linedefs/Vertices/Sectors/Things modes: line length labels are now displayed the same way as in Draw modes.
Changed, Drag Linedefs/Vertices/Sectors/Things modes: "lock movement to cardinal directions" mode (Alt-Shift-Drag) now locks movement in 4 directions instead of 8 and doesn't snap map elements to nearest grid intersections when they are not aligned to it.
Added, Visual mode, GZDoom, DECORATE: FORCEXYBILLBOARD flag is now supported.
Added, Visual mode, GLOOME, DECORATE: FLOORSPRITE, CEILSPRITE, WALLSPRITE, ROLLSPRITE and STICKTOPLANE flags are now supported (implementation is somewhat broken ATM and probably doesn't work the same way as in GLOOME, because Windows build with most these features is nowhere to be found...).
Fixed, Visual mode: in some cases Thing brightness was calculated incorrectly.
Updated ZDoom_DECORATE.cfg.
2015-08-25 22:05:14 +00:00
|
|
|
snapgridincrement = true; // We don't want to move Things away from the cardinal directions
|
2015-07-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
|
2009-04-19 18:07:22 +00:00
|
|
|
Vector2D oldpos = dragitem.Position;
|
2010-08-13 18:32:21 +00:00
|
|
|
Vector2D tl, br;
|
2010-01-02 22:06:40 +00:00
|
|
|
|
|
|
|
// don't move if the offset contains invalid data
|
2015-12-28 15:01:53 +00:00
|
|
|
if(!offset.IsFinite()) return false;
|
2010-08-13 18:32:21 +00:00
|
|
|
|
|
|
|
// Find the outmost things
|
|
|
|
tl = br = oldpositions[0];
|
2015-12-28 15:01:53 +00:00
|
|
|
for(int i = 0; i < oldpositions.Count; i++)
|
2010-08-13 18:32:21 +00:00
|
|
|
{
|
2015-12-28 15:01:53 +00:00
|
|
|
if(oldpositions[i].x < tl.x) tl.x = (int)oldpositions[i].x;
|
|
|
|
if(oldpositions[i].x > br.x) br.x = (int)oldpositions[i].x;
|
|
|
|
if(oldpositions[i].y > tl.y) tl.y = (int)oldpositions[i].y;
|
|
|
|
if(oldpositions[i].y < br.y) br.y = (int)oldpositions[i].y;
|
2010-08-13 18:32:21 +00:00
|
|
|
}
|
|
|
|
|
2009-04-19 18:07:22 +00:00
|
|
|
// Snap to nearest?
|
|
|
|
if(snapnearest)
|
|
|
|
{
|
|
|
|
// Find nearest unselected item within selection range
|
2015-09-16 20:22:20 +00:00
|
|
|
Thing nearest = MapSet.NearestThingSquareRange(unselectedthings, mousemappos, BuilderPlug.Me.StitchRange / renderer.Scale);
|
2009-04-19 18:07:22 +00:00
|
|
|
if(nearest != null)
|
|
|
|
{
|
|
|
|
// Move the dragged item
|
|
|
|
dragitem.Move((Vector2D)nearest.Position);
|
|
|
|
|
|
|
|
// Adjust the offset
|
|
|
|
offset = (Vector2D)nearest.Position - dragitemposition;
|
|
|
|
|
|
|
|
// Do not snap to grid!
|
|
|
|
snapgrid = false;
|
2014-07-18 15:11:37 +00:00
|
|
|
snapgridincrement = false; //mxd
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Snap to grid?
|
2014-07-18 15:11:37 +00:00
|
|
|
if(snapgrid || snapgridincrement)
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
|
|
|
// Move the dragged item
|
|
|
|
dragitem.Move(dragitemposition + offset);
|
|
|
|
|
2014-09-30 19:46:33 +00:00
|
|
|
// Snap item to grid increment (mxd)
|
|
|
|
if(snapgridincrement)
|
2014-07-18 15:11:37 +00:00
|
|
|
{
|
2014-09-30 19:46:33 +00:00
|
|
|
dragitem.Move(General.Map.Grid.SnappedToGrid(dragitemposition + offset) - dragstartoffset);
|
2014-07-18 15:11:37 +00:00
|
|
|
}
|
|
|
|
else // Or to the grid itself
|
|
|
|
{
|
|
|
|
dragitem.SnapToGrid();
|
|
|
|
}
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Adjust the offset
|
|
|
|
offset += (Vector2D)dragitem.Position - (dragitemposition + offset);
|
|
|
|
}
|
|
|
|
|
2010-08-13 18:32:21 +00:00
|
|
|
// Make sure the offset is inside the map boundaries
|
2015-12-28 15:01:53 +00:00
|
|
|
if(offset.x + tl.x < General.Map.Config.LeftBoundary) offset.x = General.Map.Config.LeftBoundary - tl.x;
|
|
|
|
if(offset.x + br.x > General.Map.Config.RightBoundary) offset.x = General.Map.Config.RightBoundary - br.x;
|
|
|
|
if(offset.y + tl.y > General.Map.Config.TopBoundary) offset.y = General.Map.Config.TopBoundary - tl.y;
|
|
|
|
if(offset.y + br.y < General.Map.Config.BottomBoundary) offset.y = General.Map.Config.BottomBoundary - br.y;
|
2010-08-13 18:32:21 +00:00
|
|
|
|
2009-04-19 18:07:22 +00:00
|
|
|
// Drag item moved?
|
2014-07-18 15:11:37 +00:00
|
|
|
if((!snapgrid && !snapgridincrement) || ((Vector2D)dragitem.Position != oldpos))
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
2010-08-13 18:32:21 +00:00
|
|
|
int i = 0;
|
|
|
|
|
2009-04-19 18:07:22 +00:00
|
|
|
// Move selected geometry
|
|
|
|
foreach(Thing t in selectedthings)
|
|
|
|
{
|
|
|
|
// Move vertex from old position relative to the
|
|
|
|
// mouse position change since drag start
|
|
|
|
t.Move(oldpositions[i] + offset);
|
|
|
|
|
|
|
|
// Next
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Moved
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// No changes
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// This redraws the display
|
|
|
|
public override void OnRedrawDisplay()
|
|
|
|
{
|
2013-12-23 12:02:58 +00:00
|
|
|
if(CheckViewChanged())
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
|
|
|
renderer.RedrawSurface();
|
|
|
|
|
|
|
|
// Render lines and vertices
|
|
|
|
if(renderer.StartPlotter(true))
|
|
|
|
{
|
|
|
|
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
|
|
|
|
renderer.PlotVerticesSet(General.Map.Map.Vertices);
|
|
|
|
renderer.Finish();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-06-11 21:21:20 +00:00
|
|
|
// Render things
|
|
|
|
UpdateRedraw();
|
|
|
|
|
|
|
|
renderer.Present();
|
|
|
|
}
|
|
|
|
|
|
|
|
// This redraws only changed things
|
|
|
|
private void UpdateRedraw()
|
|
|
|
{
|
2014-02-03 11:19:12 +00:00
|
|
|
//mxd. Added, so grid can be rendered properly if the user changes grid size while dragging (very useful and important, I know)
|
2015-12-28 15:01:53 +00:00
|
|
|
if(renderer.StartPlotter(true))
|
2014-02-03 11:19:12 +00:00
|
|
|
{
|
|
|
|
// Render lines and vertices
|
|
|
|
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
|
|
|
|
renderer.PlotVerticesSet(General.Map.Map.Vertices);
|
|
|
|
|
|
|
|
// Done
|
|
|
|
renderer.Finish();
|
|
|
|
}
|
|
|
|
|
2009-04-19 18:07:22 +00:00
|
|
|
// Render things
|
|
|
|
if(renderer.StartThings(true))
|
|
|
|
{
|
|
|
|
// Render things
|
|
|
|
renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, Presentation.THINGS_HIDDEN_ALPHA);
|
2015-08-03 22:02:39 +00:00
|
|
|
renderer.RenderThingSet(unselectedthings, Presentation.THINGS_ALPHA);
|
|
|
|
renderer.RenderThingSet(selectedthings, Presentation.THINGS_ALPHA);
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Draw the dragged item highlighted
|
|
|
|
// This is important to know, because this item is used
|
|
|
|
// for snapping to the grid and snapping to nearest items
|
2015-08-03 22:02:39 +00:00
|
|
|
renderer.RenderThing(dragitem, General.Colors.Highlight, Presentation.THINGS_ALPHA);
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Done
|
|
|
|
renderer.Finish();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cancelled
|
|
|
|
public override void OnCancel()
|
|
|
|
{
|
|
|
|
// Move geometry back to original position
|
2015-07-09 22:32:12 +00:00
|
|
|
MoveThingsRelative(new Vector2D(0f, 0f), false, false, false, false);
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// If only a single vertex was selected, deselect it now
|
|
|
|
if(selectedthings.Count == 1) General.Map.Map.ClearSelectedThings();
|
|
|
|
|
|
|
|
// Update cached values
|
|
|
|
General.Map.Map.Update();
|
|
|
|
|
|
|
|
// Cancel base class
|
|
|
|
base.OnCancel();
|
|
|
|
|
|
|
|
// Return to vertices mode
|
|
|
|
General.Editing.ChangeMode(basemode);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Mode engages
|
|
|
|
public override void OnEngage()
|
|
|
|
{
|
|
|
|
base.OnEngage();
|
2014-01-17 13:48:06 +00:00
|
|
|
renderer.SetPresentation(Presentation.Things);
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Disenagaging
|
|
|
|
public override void OnDisengage()
|
|
|
|
{
|
|
|
|
base.OnDisengage();
|
|
|
|
Cursor.Current = Cursors.AppStarting;
|
|
|
|
|
|
|
|
// When not cancelled
|
|
|
|
if(!cancelled)
|
|
|
|
{
|
|
|
|
// Move geometry back to original position
|
2015-07-09 22:32:12 +00:00
|
|
|
MoveThingsRelative(new Vector2D(0f, 0f), false, false, false, false);
|
2009-04-19 18:07:22 +00:00
|
|
|
|
2015-09-16 20:22:20 +00:00
|
|
|
//mxd. Revert aligning
|
|
|
|
if(aligndata != null && aligndata.Active)
|
2014-12-03 23:15:26 +00:00
|
|
|
{
|
2015-09-16 20:22:20 +00:00
|
|
|
aligndata.CurrentAngle = dragitem.AngleDoom; //mxd
|
|
|
|
dragitem.Rotate(aligndata.InitialAngle);
|
|
|
|
aligndata.CurrentHeight = dragitem.Position.z; //mxd
|
|
|
|
dragitem.Move(dragitem.Position.x, dragitem.Position.y, aligndata.InitialHeight);
|
2013-03-18 13:52:27 +00:00
|
|
|
}
|
|
|
|
|
2009-04-19 18:07:22 +00:00
|
|
|
// Make undo for the dragging
|
2015-09-25 13:20:53 +00:00
|
|
|
General.Map.UndoRedo.CreateUndo((selectedthings.Count == 1 ? "Drag thing" : "Drag " + selectedthings.Count + " things"));
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Move selected geometry to final position
|
2015-09-16 20:22:20 +00:00
|
|
|
if(aligndata != null && aligndata.Active) //mxd. Apply aligning
|
2014-12-03 23:15:26 +00:00
|
|
|
{
|
2015-09-16 20:22:20 +00:00
|
|
|
if(!aligndata.Position.IsEmpty)
|
|
|
|
dragitem.Move(aligndata.Position.X, aligndata.Position.Y, aligndata.CurrentHeight);
|
2013-03-18 13:52:27 +00:00
|
|
|
else
|
2015-09-16 20:22:20 +00:00
|
|
|
dragitem.Move(dragitem.Position.x, dragitem.Position.y, aligndata.CurrentHeight);
|
|
|
|
dragitem.Rotate(aligndata.CurrentAngle);
|
2014-12-03 23:15:26 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-07-09 22:32:12 +00:00
|
|
|
MoveThingsRelative(mousemappos - dragstartmappos, snaptogrid, snaptogridincrement, snaptonearest, snaptocardinaldirection);
|
2013-03-18 13:52:27 +00:00
|
|
|
}
|
2009-04-19 18:07:22 +00:00
|
|
|
|
2015-09-16 20:22:20 +00:00
|
|
|
//mxd. Snap selected things to map format accuracy
|
|
|
|
foreach(Thing thing in selectedthings) thing.SnapToAccuracy(false);
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Map is changed
|
|
|
|
General.Map.IsChanged = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Hide highlight info
|
|
|
|
General.Interface.HideInfo();
|
|
|
|
|
|
|
|
// Done
|
|
|
|
Cursor.Current = Cursors.Default;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This checks if the view offset/zoom changed and updates the check
|
|
|
|
private bool CheckViewChanged()
|
|
|
|
{
|
|
|
|
// View changed?
|
2013-12-23 12:02:58 +00:00
|
|
|
bool viewchanged = (renderer.OffsetX != lastoffsetx || renderer.OffsetY != lastoffsety || renderer.Scale != lastscale);
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Keep view information
|
|
|
|
lastoffsetx = renderer.OffsetX;
|
|
|
|
lastoffsety = renderer.OffsetY;
|
|
|
|
lastscale = renderer.Scale;
|
|
|
|
|
|
|
|
// Return result
|
|
|
|
return viewchanged;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This updates the dragging
|
|
|
|
private void Update()
|
|
|
|
{
|
2015-07-09 22:32:12 +00:00
|
|
|
snaptocardinaldirection = (General.Interface.ShiftState && General.Interface.AltState); //mxd
|
|
|
|
snaptogrid = (snaptocardinaldirection || General.Interface.ShiftState ^ General.Interface.SnapToGrid);
|
2009-04-19 18:07:22 +00:00
|
|
|
snaptonearest = General.Interface.CtrlState;
|
2015-07-09 22:32:12 +00:00
|
|
|
snaptogridincrement = (!snaptocardinaldirection && General.Interface.AltState); //mxd
|
2013-03-18 13:52:27 +00:00
|
|
|
|
|
|
|
//mxd. Snap to nearest linedef
|
2015-07-09 22:32:12 +00:00
|
|
|
if(selectedthings.Count == 1 && dragitem.IsModel && snaptonearest && !snaptocardinaldirection && MoveThingsRelative(mousemappos - dragstartmappos, snaptogrid, snaptogridincrement, false, false))
|
2014-12-03 23:15:26 +00:00
|
|
|
{
|
2013-03-18 13:52:27 +00:00
|
|
|
Linedef l = General.Map.Map.NearestLinedefRange(oldpositions[0] + mousemappos - dragstartmappos, BuilderPlug.Me.StitchRange / renderer.Scale);
|
2015-09-16 20:22:20 +00:00
|
|
|
bool restoresettings = false;
|
|
|
|
if(aligndata == null) aligndata = new AlignData(dragitem);
|
2013-03-18 13:52:27 +00:00
|
|
|
|
2014-12-03 23:15:26 +00:00
|
|
|
if(l != null)
|
|
|
|
{
|
|
|
|
if(Tools.TryAlignThingToLine(dragitem, l))
|
|
|
|
{
|
2015-09-16 20:22:20 +00:00
|
|
|
aligndata.Position = new PointF(dragitem.Position.x, dragitem.Position.y);
|
|
|
|
aligndata.Active = true;
|
2014-12-03 23:15:26 +00:00
|
|
|
}
|
2015-09-16 20:22:20 +00:00
|
|
|
else if(dragitem.AngleDoom != aligndata.InitialAngle) //restore initial angle?
|
2014-12-03 23:15:26 +00:00
|
|
|
{
|
2015-09-16 20:22:20 +00:00
|
|
|
restoresettings = true;
|
2013-03-18 13:52:27 +00:00
|
|
|
}
|
|
|
|
|
2014-12-03 23:15:26 +00:00
|
|
|
}
|
2015-09-16 20:22:20 +00:00
|
|
|
else if(dragitem.AngleDoom != aligndata.InitialAngle) //restore initial angle?
|
2014-12-03 23:15:26 +00:00
|
|
|
{
|
2015-09-16 20:22:20 +00:00
|
|
|
restoresettings = true;
|
2013-03-18 13:52:27 +00:00
|
|
|
}
|
|
|
|
|
2015-09-16 20:22:20 +00:00
|
|
|
if(restoresettings)
|
2014-12-03 23:15:26 +00:00
|
|
|
{
|
2015-09-16 20:22:20 +00:00
|
|
|
aligndata.Position = PointF.Empty;
|
|
|
|
aligndata.Active = false;
|
|
|
|
dragitem.Rotate(aligndata.InitialAngle);
|
2013-03-18 13:52:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
UpdateRedraw();// Redraw
|
|
|
|
renderer.Present();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Move selected geometry
|
2015-07-09 22:32:12 +00:00
|
|
|
if(MoveThingsRelative(mousemappos - dragstartmappos, snaptogrid, snaptogridincrement, snaptonearest, snaptocardinaldirection))
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
|
|
|
// Redraw
|
2009-06-11 21:21:20 +00:00
|
|
|
UpdateRedraw();
|
|
|
|
renderer.Present();
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// When edit button is released
|
|
|
|
protected override void OnEditEnd()
|
|
|
|
{
|
|
|
|
// Just return to vertices mode, geometry will be merged on disengage.
|
|
|
|
General.Editing.ChangeMode(basemode);
|
|
|
|
|
|
|
|
base.OnEditEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Mouse moving
|
|
|
|
public override void OnMouseMove(MouseEventArgs e)
|
|
|
|
{
|
|
|
|
base.OnMouseMove(e);
|
|
|
|
Update();
|
|
|
|
}
|
|
|
|
|
|
|
|
// When a key is released
|
|
|
|
public override void OnKeyUp(KeyEventArgs e)
|
|
|
|
{
|
|
|
|
base.OnKeyUp(e);
|
2014-07-18 15:11:37 +00:00
|
|
|
if(snaptogrid != General.Interface.ShiftState ^ General.Interface.SnapToGrid ||
|
|
|
|
snaptonearest != General.Interface.CtrlState ||
|
2015-07-09 22:32:12 +00:00
|
|
|
snaptogridincrement != General.Interface.AltState ||
|
|
|
|
snaptocardinaldirection != (General.Interface.AltState && General.Interface.ShiftState)) Update();
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// When a key is pressed
|
|
|
|
public override void OnKeyDown(KeyEventArgs e)
|
|
|
|
{
|
|
|
|
base.OnKeyDown(e);
|
2014-07-18 15:11:37 +00:00
|
|
|
if(snaptogrid != General.Interface.ShiftState ^ General.Interface.SnapToGrid ||
|
|
|
|
snaptonearest != General.Interface.CtrlState ||
|
2015-07-09 22:32:12 +00:00
|
|
|
snaptogridincrement != General.Interface.AltState ||
|
|
|
|
snaptocardinaldirection != (General.Interface.AltState && General.Interface.ShiftState)) Update();
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|