mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 14:31:50 +00:00
- changed a lot around the actions
- no more mousebutton-specific code in the editing modes (now all bound by actions) - some progress on the drawing editing mode
This commit is contained in:
parent
175f645e5e
commit
4ae985d630
30 changed files with 1468 additions and 767 deletions
BIN
Resources/Icons/Pencil.png
Normal file
BIN
Resources/Icons/Pencil.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 442 B |
|
@ -59,6 +59,8 @@
|
|||
<Compile Include="Config\UniversalFieldInfo.cs" />
|
||||
<Compile Include="Config\UniversalFieldType.cs" />
|
||||
<Compile Include="Controls\ActionAttribute.cs" />
|
||||
<Compile Include="Controls\BeginActionAttribute.cs" />
|
||||
<Compile Include="Controls\EndActionAttribute.cs" />
|
||||
<Compile Include="Controls\KeyControl.cs" />
|
||||
<Compile Include="Controls\MouseInput.cs" />
|
||||
<Compile Include="Data\DirectoryReader.cs" />
|
||||
|
|
|
@ -299,26 +299,21 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
}
|
||||
}
|
||||
|
||||
// When edit button is released
|
||||
protected override void EndEdit()
|
||||
{
|
||||
// Just return to base mode, Disengage will be called automatically.
|
||||
General.Map.ChangeMode(basemode);
|
||||
|
||||
base.EndEdit();
|
||||
}
|
||||
|
||||
// Mouse moving
|
||||
public override void MouseMove(MouseEventArgs e)
|
||||
{
|
||||
base.MouseMove(e);
|
||||
Update();
|
||||
}
|
||||
|
||||
// Mouse button released
|
||||
public override void MouseUp(MouseEventArgs e)
|
||||
{
|
||||
base.MouseUp(e);
|
||||
|
||||
// Is the editing button released?
|
||||
if(e.Button == EditMode.EDIT_BUTTON)
|
||||
{
|
||||
// Just return to vertices mode, geometry will be merged on disengage.
|
||||
General.Map.ChangeMode(basemode);
|
||||
}
|
||||
}
|
||||
|
||||
// When a key is released
|
||||
public override void KeyUp(KeyEventArgs e)
|
||||
{
|
||||
|
|
|
@ -334,6 +334,15 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
}
|
||||
}
|
||||
|
||||
// When edit button is released
|
||||
protected override void EndEdit()
|
||||
{
|
||||
// Just return to vertices mode, geometry will be merged on disengage.
|
||||
General.Map.ChangeMode(basemode);
|
||||
|
||||
base.EndEdit();
|
||||
}
|
||||
|
||||
// Mouse moving
|
||||
public override void MouseMove(MouseEventArgs e)
|
||||
{
|
||||
|
@ -341,19 +350,6 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
Update();
|
||||
}
|
||||
|
||||
// Mouse button released
|
||||
public override void MouseUp(MouseEventArgs e)
|
||||
{
|
||||
base.MouseUp(e);
|
||||
|
||||
// Is the editing button released?
|
||||
if(e.Button == EditMode.EDIT_BUTTON)
|
||||
{
|
||||
// Just return to vertices mode, geometry will be merged on disengage.
|
||||
General.Map.ChangeMode(basemode);
|
||||
}
|
||||
}
|
||||
|
||||
// When a key is released
|
||||
public override void KeyUp(KeyEventArgs e)
|
||||
{
|
||||
|
|
|
@ -31,20 +31,20 @@ using CodeImp.DoomBuilder.Rendering;
|
|||
using CodeImp.DoomBuilder.Geometry;
|
||||
using System.Drawing;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.Controls;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
||||
{
|
||||
[EditMode(SwitchAction = "drawlinesmode", // Action name used to switch to this mode
|
||||
ButtonDesc = "Draw Lines Mode", // Description on the button in toolbar/menu
|
||||
ButtonImage = "LinesMode.png", // Image resource name for the button
|
||||
ButtonOrder = int.MinValue + 1)] // Position of the button (lower is more to the left)
|
||||
[EditMode(SwitchAction = "drawlinesmode")]
|
||||
|
||||
public class DrawGeometryMode : ClassicMode
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
private const float LINE_THICKNESS = 0.6f;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
@ -110,6 +110,8 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
base.Cancel();
|
||||
|
||||
// Return to original mode
|
||||
Type t = basemode.GetType();
|
||||
basemode = (EditMode)Activator.CreateInstance(t);
|
||||
General.Map.ChangeMode(basemode);
|
||||
}
|
||||
|
||||
|
@ -119,12 +121,14 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
base.Disengage();
|
||||
Cursor.Current = Cursors.AppStarting;
|
||||
|
||||
// When not cancelled
|
||||
if(!cancelled)
|
||||
// When not cancelled and points have been drawn
|
||||
if(!cancelled && (points.Count > 0))
|
||||
{
|
||||
// Make undo for the draw
|
||||
General.Map.UndoRedo.CreateUndo("line draw", UndoGroup.None, 0);
|
||||
|
||||
|
||||
|
||||
// Update cached values
|
||||
General.Map.Map.Update();
|
||||
|
||||
|
@ -143,7 +147,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
protected bool CheckViewChanged()
|
||||
{
|
||||
bool viewchanged = false;
|
||||
|
||||
|
||||
// View changed?
|
||||
if(renderer.OffsetX != lastoffsetx) viewchanged = true;
|
||||
if(renderer.OffsetY != lastoffsety) viewchanged = true;
|
||||
|
@ -187,10 +191,36 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
snaptogrid = General.Interface.ShiftState ^ General.Interface.SnapToGrid;
|
||||
snaptonearest = General.Interface.CtrlState;
|
||||
|
||||
Vector2D lastp = new Vector2D(0, 0);
|
||||
Vector2D curp = GetCurrentPosition();
|
||||
float vsize = ((float)renderer.VertexSize + 1.0f) / renderer.Scale;
|
||||
|
||||
// Render drawing lines
|
||||
if(renderer.StartOverlay(true))
|
||||
{
|
||||
RenderSelection();
|
||||
// Go for all points to draw lines
|
||||
if(points.Count > 0)
|
||||
{
|
||||
// Render lines
|
||||
lastp = points[0];
|
||||
for(int i = 1; i < points.Count; i++)
|
||||
{
|
||||
renderer.RenderLine(lastp, points[i], LINE_THICKNESS, General.Colors.Selection, true);
|
||||
lastp = points[i];
|
||||
}
|
||||
|
||||
// Render line to cursor
|
||||
renderer.RenderLine(lastp, curp, LINE_THICKNESS, General.Colors.Highlight, true);
|
||||
|
||||
// Render vertices
|
||||
for(int i = 0; i < points.Count; i++)
|
||||
renderer.RenderRectangleFilled(new RectangleF(points[i].x - vsize, points[i].y - vsize, vsize * 2.0f, vsize * 2.0f), General.Colors.Selection, true);
|
||||
}
|
||||
|
||||
// Render vertex at cursor
|
||||
renderer.RenderRectangleFilled(new RectangleF(curp.x - vsize, curp.y - vsize, vsize * 2.0f, vsize * 2.0f), General.Colors.Highlight, true);
|
||||
|
||||
// Done
|
||||
renderer.Finish();
|
||||
}
|
||||
|
||||
|
@ -198,6 +228,57 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
renderer.Present();
|
||||
}
|
||||
|
||||
// This gets the aligned and snapped draw position
|
||||
private Vector2D GetCurrentPosition()
|
||||
{
|
||||
// Snap to nearest?
|
||||
if(snaptonearest)
|
||||
{
|
||||
float vrange = VerticesMode.VERTEX_HIGHLIGHT_RANGE / renderer.Scale;
|
||||
|
||||
// Go for all drawn points
|
||||
foreach(Vector2D v in points)
|
||||
{
|
||||
Vector2D delta = mousemappos - v;
|
||||
if(delta.GetLengthSq() < (vrange * vrange)) return v;
|
||||
}
|
||||
|
||||
// Try the nearest vertex
|
||||
Vertex nv = General.Map.Map.NearestVertexSquareRange(mousemappos, vrange);
|
||||
if(nv != null) return nv.Position;
|
||||
|
||||
// Try the nearest linedef
|
||||
Linedef nl = General.Map.Map.NearestLinedefRange(mousemappos, LinedefsMode.LINEDEF_HIGHLIGHT_RANGE / renderer.Scale);
|
||||
if(nl != null)
|
||||
{
|
||||
// Snap to grid?
|
||||
if(snaptogrid)
|
||||
{
|
||||
// Aligned to line and grid
|
||||
// TODO: Find nearest horzontal and vertical grid intersections and align there
|
||||
return nl.NearestOnLine(mousemappos);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Aligned to line
|
||||
return nl.NearestOnLine(mousemappos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Snap to grid?
|
||||
if(snaptogrid)
|
||||
{
|
||||
// Aligned to grid
|
||||
return General.Map.Grid.SnappedToGrid(mousemappos);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal position
|
||||
return mousemappos;
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse moving
|
||||
public override void MouseMove(MouseEventArgs e)
|
||||
{
|
||||
|
@ -205,26 +286,46 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
Update();
|
||||
}
|
||||
|
||||
// Mouse button released
|
||||
public override void MouseUp(MouseEventArgs e)
|
||||
// Drawing a point
|
||||
[BeginAction("drawpoint")]
|
||||
public void DrawPoint()
|
||||
{
|
||||
base.MouseUp(e);
|
||||
// Mouse inside window?
|
||||
if(General.Interface.MouseInDisplay)
|
||||
{
|
||||
points.Add(GetCurrentPosition());
|
||||
Update();
|
||||
}
|
||||
}
|
||||
|
||||
// Remove a point
|
||||
[BeginAction("removepoint")]
|
||||
public void RemovePoint()
|
||||
{
|
||||
if(points.Count > 0) points.RemoveAt(points.Count - 1);
|
||||
Update();
|
||||
}
|
||||
|
||||
// Finish drawing
|
||||
[BeginAction("finishdraw")]
|
||||
public void FinishDraw()
|
||||
{
|
||||
// Just return to base mode, Disengage will be called automatically.
|
||||
General.Map.ChangeMode(basemode);
|
||||
}
|
||||
|
||||
// When a key is released
|
||||
public override void KeyUp(KeyEventArgs e)
|
||||
{
|
||||
base.KeyUp(e);
|
||||
if(snaptogrid != General.Interface.ShiftState ^ General.Interface.SnapToGrid) Update();
|
||||
if(snaptonearest != General.Interface.CtrlState) Update();
|
||||
Update();
|
||||
}
|
||||
|
||||
// When a key is pressed
|
||||
public override void KeyDown(KeyEventArgs e)
|
||||
{
|
||||
base.KeyDown(e);
|
||||
if(snaptogrid != General.Interface.ShiftState ^ General.Interface.SnapToGrid) Update();
|
||||
if(snaptonearest != General.Interface.CtrlState) Update();
|
||||
Update();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
{
|
||||
#region ================== Constants
|
||||
|
||||
protected const float LINEDEF_HIGHLIGHT_RANGE = 20f;
|
||||
public const float LINEDEF_HIGHLIGHT_RANGE = 20f;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -150,7 +150,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
// Render selection
|
||||
if(renderer.StartOverlay(true))
|
||||
{
|
||||
RenderSelection();
|
||||
RenderMultiSelection();
|
||||
renderer.Finish();
|
||||
}
|
||||
}
|
||||
|
@ -195,39 +195,108 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
General.Interface.HideInfo();
|
||||
}
|
||||
|
||||
// This is called wheh selection ends
|
||||
protected override void EndSelection()
|
||||
// Selection
|
||||
protected override void Select()
|
||||
{
|
||||
// Go for all lines
|
||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
l.Selected = ((l.Start.Position.x >= selectionrect.Left) &&
|
||||
(l.Start.Position.y >= selectionrect.Top) &&
|
||||
(l.Start.Position.x <= selectionrect.Right) &&
|
||||
(l.Start.Position.y <= selectionrect.Bottom) &&
|
||||
(l.End.Position.x >= selectionrect.Left) &&
|
||||
(l.End.Position.y >= selectionrect.Top) &&
|
||||
(l.End.Position.x <= selectionrect.Right) &&
|
||||
(l.End.Position.y <= selectionrect.Bottom));
|
||||
// Flip selection
|
||||
highlighted.Selected = !highlighted.Selected;
|
||||
|
||||
// Update display
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
// Redraw highlight to show selection
|
||||
renderer.PlotLinedef(highlighted, renderer.DetermineLinedefColor(highlighted));
|
||||
renderer.PlotVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start));
|
||||
renderer.PlotVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End));
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
|
||||
base.EndSelection();
|
||||
if(renderer.StartOverlay(true)) renderer.Finish();
|
||||
General.Interface.RedrawDisplay();
|
||||
else
|
||||
{
|
||||
// Start rectangular selection
|
||||
StartMultiSelection();
|
||||
}
|
||||
|
||||
base.Select();
|
||||
}
|
||||
|
||||
// This is called when the selection is updated
|
||||
protected override void UpdateSelection()
|
||||
// End selection
|
||||
protected override void EndSelect()
|
||||
{
|
||||
base.UpdateSelection();
|
||||
|
||||
// Render selection
|
||||
if(renderer.StartOverlay(true))
|
||||
// Not stopping from multiselection?
|
||||
if(!selecting)
|
||||
{
|
||||
RenderSelection();
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Update display
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
// Render highlighted item
|
||||
renderer.PlotLinedef(highlighted, General.Colors.Highlight);
|
||||
renderer.PlotVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start));
|
||||
renderer.PlotVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End));
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.EndSelect();
|
||||
}
|
||||
|
||||
// Start editing
|
||||
protected override void Edit()
|
||||
{
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Highlighted item not selected?
|
||||
if(!highlighted.Selected)
|
||||
{
|
||||
// Make this the only selection
|
||||
General.Map.Map.ClearSelectedLinedefs();
|
||||
highlighted.Selected = true;
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
// Update display
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
// Redraw highlight to show selection
|
||||
renderer.PlotLinedef(highlighted, renderer.DetermineLinedefColor(highlighted));
|
||||
renderer.PlotVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start));
|
||||
renderer.PlotVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End));
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
|
||||
base.Edit();
|
||||
}
|
||||
|
||||
// Done editing
|
||||
protected override void EndEdit()
|
||||
{
|
||||
// Anything selected?
|
||||
ICollection<Linedef> selected = General.Map.Map.GetLinedefsSelection(true);
|
||||
if(selected.Count > 0)
|
||||
{
|
||||
// Show line edit dialog
|
||||
General.Interface.ShowEditLinedefs(selected);
|
||||
|
||||
// When a single line was selected, deselect it now
|
||||
if(selected.Count == 1) General.Map.Map.ClearSelectedLinedefs();
|
||||
|
||||
// Update entire display
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
base.EndEdit();
|
||||
}
|
||||
|
||||
// Mouse moves
|
||||
|
@ -255,114 +324,13 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
Highlight(null);
|
||||
}
|
||||
|
||||
// Mouse button pressed
|
||||
public override void MouseDown(MouseEventArgs e)
|
||||
{
|
||||
base.MouseDown(e);
|
||||
|
||||
// Select button?
|
||||
if(e.Button == EditMode.SELECT_BUTTON)
|
||||
{
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Flip selection
|
||||
highlighted.Selected = !highlighted.Selected;
|
||||
|
||||
// Update display
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
// Redraw highlight to show selection
|
||||
renderer.PlotLinedef(highlighted, renderer.DetermineLinedefColor(highlighted));
|
||||
renderer.PlotVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start));
|
||||
renderer.PlotVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End));
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start making a selection
|
||||
StartSelection();
|
||||
}
|
||||
}
|
||||
// Edit button?
|
||||
else if(e.Button == EditMode.EDIT_BUTTON)
|
||||
{
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Highlighted item not selected?
|
||||
if(!highlighted.Selected)
|
||||
{
|
||||
// Make this the only selection
|
||||
General.Map.Map.ClearSelectedLinedefs();
|
||||
highlighted.Selected = true;
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
// Update display
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
// Redraw highlight to show selection
|
||||
renderer.PlotLinedef(highlighted, renderer.DetermineLinedefColor(highlighted));
|
||||
renderer.PlotVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start));
|
||||
renderer.PlotVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End));
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse released
|
||||
public override void MouseUp(MouseEventArgs e)
|
||||
{
|
||||
ICollection<Linedef> selected;
|
||||
|
||||
base.MouseUp(e);
|
||||
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Update display
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
// Render highlighted item
|
||||
renderer.PlotLinedef(highlighted, General.Colors.Highlight);
|
||||
renderer.PlotVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start));
|
||||
renderer.PlotVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End));
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
|
||||
// Edit button?
|
||||
if(e.Button == EditMode.EDIT_BUTTON)
|
||||
{
|
||||
// Anything selected?
|
||||
selected = General.Map.Map.GetLinedefsSelection(true);
|
||||
if(selected.Count > 0)
|
||||
{
|
||||
// Show line edit dialog
|
||||
General.Interface.ShowEditLinedefs(selected);
|
||||
|
||||
// When a single line was selected, deselect it now
|
||||
if(selected.Count == 1) General.Map.Map.ClearSelectedLinedefs();
|
||||
|
||||
// Update entire display
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse wants to drag
|
||||
protected override void DragStart(MouseEventArgs e)
|
||||
{
|
||||
base.DragStart(e);
|
||||
|
||||
// Edit button used?
|
||||
if(e.Button == EditMode.EDIT_BUTTON)
|
||||
if(General.Interface.CheckActionActive(null, "classicedit"))
|
||||
{
|
||||
// Anything highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
|
@ -380,6 +348,45 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is called wheh selection ends
|
||||
protected override void EndMultiSelection()
|
||||
{
|
||||
// Go for all lines
|
||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||
{
|
||||
l.Selected = ((l.Start.Position.x >= selectionrect.Left) &&
|
||||
(l.Start.Position.y >= selectionrect.Top) &&
|
||||
(l.Start.Position.x <= selectionrect.Right) &&
|
||||
(l.Start.Position.y <= selectionrect.Bottom) &&
|
||||
(l.End.Position.x >= selectionrect.Left) &&
|
||||
(l.End.Position.y >= selectionrect.Top) &&
|
||||
(l.End.Position.x <= selectionrect.Right) &&
|
||||
(l.End.Position.y <= selectionrect.Bottom));
|
||||
}
|
||||
|
||||
base.EndMultiSelection();
|
||||
|
||||
// Clear overlay
|
||||
if(renderer.StartOverlay(true)) renderer.Finish();
|
||||
|
||||
// Redraw
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
// This is called when the selection is updated
|
||||
protected override void UpdateMultiSelection()
|
||||
{
|
||||
base.UpdateMultiSelection();
|
||||
|
||||
// Render selection
|
||||
if(renderer.StartOverlay(true))
|
||||
{
|
||||
RenderMultiSelection();
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -165,7 +165,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
// Render selection
|
||||
if(renderer.StartOverlay(true))
|
||||
{
|
||||
RenderSelection();
|
||||
RenderMultiSelection();
|
||||
renderer.Finish();
|
||||
}
|
||||
}
|
||||
|
@ -216,61 +216,107 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
General.Interface.HideInfo();
|
||||
}
|
||||
|
||||
// This is called wheh selection ends
|
||||
protected override void EndSelection()
|
||||
// Selection
|
||||
protected override void Select()
|
||||
{
|
||||
// Go for all lines
|
||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
l.Selected = ((l.Start.Position.x >= selectionrect.Left) &&
|
||||
(l.Start.Position.y >= selectionrect.Top) &&
|
||||
(l.Start.Position.x <= selectionrect.Right) &&
|
||||
(l.Start.Position.y <= selectionrect.Bottom) &&
|
||||
(l.End.Position.x >= selectionrect.Left) &&
|
||||
(l.End.Position.y >= selectionrect.Top) &&
|
||||
(l.End.Position.x <= selectionrect.Right) &&
|
||||
(l.End.Position.y <= selectionrect.Bottom));
|
||||
}
|
||||
// Flip selection
|
||||
SelectSector(highlighted, !highlighted.Selected);
|
||||
|
||||
// Go for all sectors
|
||||
foreach(Sector s in General.Map.Map.Sectors)
|
||||
{
|
||||
// Go for all sidedefs
|
||||
bool allselected = true;
|
||||
foreach(Sidedef sd in s.Sidedefs)
|
||||
// Update display
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
if(!sd.Line.Selected)
|
||||
{
|
||||
allselected = false;
|
||||
break;
|
||||
}
|
||||
// Redraw highlight to show selection
|
||||
renderer.PlotSector(highlighted);
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
|
||||
// Sector completely selected?
|
||||
s.Selected = allselected;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start making a selection
|
||||
StartMultiSelection();
|
||||
}
|
||||
|
||||
// Make sure all linedefs reflect selected sectors
|
||||
foreach(Sector s in General.Map.Map.Sectors)
|
||||
SelectSector(s, s.Selected);
|
||||
|
||||
base.EndSelection();
|
||||
if(renderer.StartOverlay(true)) renderer.Finish();
|
||||
General.Interface.RedrawDisplay();
|
||||
base.Select();
|
||||
}
|
||||
|
||||
// This is called when the selection is updated
|
||||
protected override void UpdateSelection()
|
||||
// End selection
|
||||
protected override void EndSelect()
|
||||
{
|
||||
base.UpdateSelection();
|
||||
|
||||
// Render selection
|
||||
if(renderer.StartOverlay(true))
|
||||
// Not stopping from multiselection?
|
||||
if(!selecting)
|
||||
{
|
||||
RenderSelection();
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Update display
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
// Render highlighted item
|
||||
renderer.PlotSector(highlighted, General.Colors.Highlight);
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.EndSelect();
|
||||
}
|
||||
|
||||
// Start editing
|
||||
protected override void Edit()
|
||||
{
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Highlighted item not selected?
|
||||
if(!highlighted.Selected)
|
||||
{
|
||||
// Make this the only selection
|
||||
General.Map.Map.ClearSelectedSectors();
|
||||
General.Map.Map.ClearSelectedLinedefs();
|
||||
SelectSector(highlighted, true);
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
// Update display
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
// Redraw highlight to show selection
|
||||
renderer.PlotSector(highlighted);
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
|
||||
base.Edit();
|
||||
}
|
||||
|
||||
// Done editing
|
||||
protected override void EndEdit()
|
||||
{
|
||||
// Anything selected?
|
||||
ICollection<Sector> selected = General.Map.Map.GetSectorsSelection(true);
|
||||
if(selected.Count > 0)
|
||||
{
|
||||
// Show sector edit dialog
|
||||
General.Interface.ShowEditSectors(selected);
|
||||
|
||||
// When a single sector was selected, deselect it now
|
||||
if(selected.Count == 1)
|
||||
{
|
||||
General.Map.Map.ClearSelectedSectors();
|
||||
General.Map.Map.ClearSelectedLinedefs();
|
||||
}
|
||||
|
||||
// Update entire display
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
base.EndEdit();
|
||||
}
|
||||
|
||||
// Mouse moves
|
||||
|
@ -326,113 +372,13 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
Highlight(null);
|
||||
}
|
||||
|
||||
// Mouse button pressed
|
||||
public override void MouseDown(MouseEventArgs e)
|
||||
{
|
||||
base.MouseDown(e);
|
||||
|
||||
// Select button?
|
||||
if(e.Button == EditMode.SELECT_BUTTON)
|
||||
{
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Flip selection
|
||||
SelectSector(highlighted, !highlighted.Selected);
|
||||
|
||||
// Update display
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
// Redraw highlight to show selection
|
||||
renderer.PlotSector(highlighted);
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start making a selection
|
||||
StartSelection();
|
||||
}
|
||||
}
|
||||
// Edit button?
|
||||
else if(e.Button == EditMode.EDIT_BUTTON)
|
||||
{
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Highlighted item not selected?
|
||||
if(!highlighted.Selected)
|
||||
{
|
||||
// Make this the only selection
|
||||
General.Map.Map.ClearSelectedSectors();
|
||||
General.Map.Map.ClearSelectedLinedefs();
|
||||
SelectSector(highlighted, true);
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
// Update display
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
// Redraw highlight to show selection
|
||||
renderer.PlotSector(highlighted);
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse released
|
||||
public override void MouseUp(MouseEventArgs e)
|
||||
{
|
||||
ICollection<Sector> selected;
|
||||
|
||||
base.MouseUp(e);
|
||||
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Update display
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
// Render highlighted item
|
||||
renderer.PlotSector(highlighted, General.Colors.Highlight);
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
|
||||
// Edit button?
|
||||
if(e.Button == EditMode.EDIT_BUTTON)
|
||||
{
|
||||
// Anything selected?
|
||||
selected = General.Map.Map.GetSectorsSelection(true);
|
||||
if(selected.Count > 0)
|
||||
{
|
||||
// Show sector edit dialog
|
||||
General.Interface.ShowEditSectors(selected);
|
||||
|
||||
// When a single sector was selected, deselect it now
|
||||
if(selected.Count == 1)
|
||||
{
|
||||
General.Map.Map.ClearSelectedSectors();
|
||||
General.Map.Map.ClearSelectedLinedefs();
|
||||
}
|
||||
|
||||
// Update entire display
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse wants to drag
|
||||
protected override void DragStart(MouseEventArgs e)
|
||||
{
|
||||
base.DragStart(e);
|
||||
|
||||
// Edit button used?
|
||||
if(e.Button == EditMode.EDIT_BUTTON)
|
||||
if(General.Interface.CheckActionActive(null, "classicedit"))
|
||||
{
|
||||
// Anything highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
|
@ -450,6 +396,63 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is called wheh selection ends
|
||||
protected override void EndMultiSelection()
|
||||
{
|
||||
// Go for all lines
|
||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||
{
|
||||
l.Selected = ((l.Start.Position.x >= selectionrect.Left) &&
|
||||
(l.Start.Position.y >= selectionrect.Top) &&
|
||||
(l.Start.Position.x <= selectionrect.Right) &&
|
||||
(l.Start.Position.y <= selectionrect.Bottom) &&
|
||||
(l.End.Position.x >= selectionrect.Left) &&
|
||||
(l.End.Position.y >= selectionrect.Top) &&
|
||||
(l.End.Position.x <= selectionrect.Right) &&
|
||||
(l.End.Position.y <= selectionrect.Bottom));
|
||||
}
|
||||
|
||||
// Go for all sectors
|
||||
foreach(Sector s in General.Map.Map.Sectors)
|
||||
{
|
||||
// Go for all sidedefs
|
||||
bool allselected = true;
|
||||
foreach(Sidedef sd in s.Sidedefs)
|
||||
{
|
||||
if(!sd.Line.Selected)
|
||||
{
|
||||
allselected = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Sector completely selected?
|
||||
s.Selected = allselected;
|
||||
}
|
||||
|
||||
// Make sure all linedefs reflect selected sectors
|
||||
foreach(Sector s in General.Map.Map.Sectors)
|
||||
SelectSector(s, s.Selected);
|
||||
|
||||
base.EndMultiSelection();
|
||||
if(renderer.StartOverlay(true)) renderer.Finish();
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
// This is called when the selection is updated
|
||||
protected override void UpdateMultiSelection()
|
||||
{
|
||||
base.UpdateMultiSelection();
|
||||
|
||||
// Render selection
|
||||
if(renderer.StartOverlay(true))
|
||||
{
|
||||
RenderMultiSelection();
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
// Render selection
|
||||
if(renderer.StartOverlay(true))
|
||||
{
|
||||
RenderSelection();
|
||||
RenderMultiSelection();
|
||||
renderer.Finish();
|
||||
}
|
||||
}
|
||||
|
@ -171,35 +171,102 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
General.Interface.HideInfo();
|
||||
}
|
||||
|
||||
// This is called wheh selection ends
|
||||
protected override void EndSelection()
|
||||
// Selection
|
||||
protected override void Select()
|
||||
{
|
||||
// Go for all things
|
||||
foreach(Thing t in General.Map.Map.Things)
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
t.Selected = ((t.Position.x >= selectionrect.Left) &&
|
||||
(t.Position.y >= selectionrect.Top) &&
|
||||
(t.Position.x <= selectionrect.Right) &&
|
||||
(t.Position.y <= selectionrect.Bottom));
|
||||
// Flip selection
|
||||
highlighted.Selected = !highlighted.Selected;
|
||||
|
||||
// Update display
|
||||
if(renderer.StartThings(false))
|
||||
{
|
||||
// Redraw highlight to show selection
|
||||
renderer.RenderThing(highlighted, renderer.DetermineThingColor(highlighted));
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start making a selection
|
||||
StartMultiSelection();
|
||||
}
|
||||
|
||||
base.EndSelection();
|
||||
if(renderer.StartOverlay(true)) renderer.Finish();
|
||||
General.Interface.RedrawDisplay();
|
||||
base.Select();
|
||||
}
|
||||
|
||||
// This is called when the selection is updated
|
||||
protected override void UpdateSelection()
|
||||
// End selection
|
||||
protected override void EndSelect()
|
||||
{
|
||||
base.UpdateSelection();
|
||||
|
||||
// Render selection
|
||||
if(renderer.StartOverlay(true))
|
||||
// Not ending from a multi-selection?
|
||||
if(!selecting)
|
||||
{
|
||||
RenderSelection();
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Update display
|
||||
if(renderer.StartThings(false))
|
||||
{
|
||||
// Render highlighted item
|
||||
renderer.RenderThing(highlighted, General.Colors.Highlight);
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.EndSelect();
|
||||
}
|
||||
|
||||
// Start editing
|
||||
protected override void Edit()
|
||||
{
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Highlighted item not selected?
|
||||
if(!highlighted.Selected)
|
||||
{
|
||||
// Make this the only selection
|
||||
General.Map.Map.ClearSelectedThings();
|
||||
highlighted.Selected = true;
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
// Update display
|
||||
if(renderer.StartThings(false))
|
||||
{
|
||||
// Redraw highlight to show selection
|
||||
renderer.RenderThing(highlighted, renderer.DetermineThingColor(highlighted));
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
|
||||
base.Edit();
|
||||
}
|
||||
|
||||
// Done editing
|
||||
protected override void EndEdit()
|
||||
{
|
||||
// Anything selected?
|
||||
ICollection<Thing> selected = General.Map.Map.GetThingsSelection(true);
|
||||
if(selected.Count > 0)
|
||||
{
|
||||
// Show thing edit dialog
|
||||
// TODO
|
||||
|
||||
// When a single thing was selected, deselect it now
|
||||
if(selected.Count == 1) General.Map.Map.ClearSelectedThings();
|
||||
|
||||
// Update entire display
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
base.EndEdit();
|
||||
}
|
||||
|
||||
// Mouse moves
|
||||
|
@ -227,108 +294,13 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
Highlight(null);
|
||||
}
|
||||
|
||||
// Mouse button pressed
|
||||
public override void MouseDown(MouseEventArgs e)
|
||||
{
|
||||
base.MouseDown(e);
|
||||
|
||||
// Select button?
|
||||
if(e.Button == EditMode.SELECT_BUTTON)
|
||||
{
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Flip selection
|
||||
highlighted.Selected = !highlighted.Selected;
|
||||
|
||||
// Update display
|
||||
if(renderer.StartThings(false))
|
||||
{
|
||||
// Redraw highlight to show selection
|
||||
renderer.RenderThing(highlighted, renderer.DetermineThingColor(highlighted));
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start making a selection
|
||||
StartSelection();
|
||||
}
|
||||
}
|
||||
// Edit button?
|
||||
else if(e.Button == EditMode.EDIT_BUTTON)
|
||||
{
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Highlighted item not selected?
|
||||
if(!highlighted.Selected)
|
||||
{
|
||||
// Make this the only selection
|
||||
General.Map.Map.ClearSelectedThings();
|
||||
highlighted.Selected = true;
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
// Update display
|
||||
if(renderer.StartThings(false))
|
||||
{
|
||||
// Redraw highlight to show selection
|
||||
renderer.RenderThing(highlighted, renderer.DetermineThingColor(highlighted));
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse released
|
||||
public override void MouseUp(MouseEventArgs e)
|
||||
{
|
||||
ICollection<Thing> selected;
|
||||
|
||||
base.MouseUp(e);
|
||||
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Update display
|
||||
if(renderer.StartThings(false))
|
||||
{
|
||||
// Render highlighted item
|
||||
renderer.RenderThing(highlighted, General.Colors.Highlight);
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
|
||||
// Edit button?
|
||||
if(e.Button == EditMode.EDIT_BUTTON)
|
||||
{
|
||||
// Anything selected?
|
||||
selected = General.Map.Map.GetThingsSelection(true);
|
||||
if(selected.Count > 0)
|
||||
{
|
||||
// Show thing edit dialog
|
||||
// TODO
|
||||
|
||||
// When a single thing was selected, deselect it now
|
||||
if(selected.Count == 1) General.Map.Map.ClearSelectedThings();
|
||||
|
||||
// Update entire display
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse wants to drag
|
||||
protected override void DragStart(MouseEventArgs e)
|
||||
{
|
||||
base.DragStart(e);
|
||||
|
||||
// Edit button used?
|
||||
if(e.Button == EditMode.EDIT_BUTTON)
|
||||
if(General.Interface.CheckActionActive(null, "classicedit"))
|
||||
{
|
||||
// Anything highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
|
@ -346,6 +318,41 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is called wheh selection ends
|
||||
protected override void EndMultiSelection()
|
||||
{
|
||||
// Go for all things
|
||||
foreach(Thing t in General.Map.Map.Things)
|
||||
{
|
||||
t.Selected = ((t.Position.x >= selectionrect.Left) &&
|
||||
(t.Position.y >= selectionrect.Top) &&
|
||||
(t.Position.x <= selectionrect.Right) &&
|
||||
(t.Position.y <= selectionrect.Bottom));
|
||||
}
|
||||
|
||||
base.EndMultiSelection();
|
||||
|
||||
// Clear overlay
|
||||
if(renderer.StartOverlay(true)) renderer.Finish();
|
||||
|
||||
// Redraw
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
// This is called when the selection is updated
|
||||
protected override void UpdateMultiSelection()
|
||||
{
|
||||
base.UpdateMultiSelection();
|
||||
|
||||
// Render selection
|
||||
if(renderer.StartOverlay(true))
|
||||
{
|
||||
RenderMultiSelection();
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
// Render selection
|
||||
if(renderer.StartOverlay(true))
|
||||
{
|
||||
RenderSelection();
|
||||
RenderMultiSelection();
|
||||
renderer.Finish();
|
||||
}
|
||||
}
|
||||
|
@ -186,36 +186,65 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
else
|
||||
General.Interface.HideInfo();
|
||||
}
|
||||
|
||||
// This is called wheh selection ends
|
||||
protected override void EndSelection()
|
||||
|
||||
// Selection
|
||||
protected override void Select()
|
||||
{
|
||||
// Go for all vertices
|
||||
foreach(Vertex v in General.Map.Map.Vertices)
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
v.Selected = ((v.Position.x >= selectionrect.Left) &&
|
||||
(v.Position.y >= selectionrect.Top) &&
|
||||
(v.Position.x <= selectionrect.Right) &&
|
||||
(v.Position.y <= selectionrect.Bottom));
|
||||
// Flip selection
|
||||
highlighted.Selected = !highlighted.Selected;
|
||||
|
||||
// Redraw highlight to show selection
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
renderer.PlotVertex(highlighted, renderer.DetermineVertexColor(highlighted));
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start making a selection
|
||||
StartMultiSelection();
|
||||
}
|
||||
|
||||
base.EndSelection();
|
||||
if(renderer.StartOverlay(true)) renderer.Finish();
|
||||
General.Interface.RedrawDisplay();
|
||||
base.Select();
|
||||
}
|
||||
|
||||
// This is called when the selection is updated
|
||||
protected override void UpdateSelection()
|
||||
|
||||
// End selection
|
||||
protected override void EndSelect()
|
||||
{
|
||||
base.UpdateSelection();
|
||||
|
||||
// Render selection
|
||||
if(renderer.StartOverlay(true))
|
||||
// Not stopping from multiselection?
|
||||
if(!selecting)
|
||||
{
|
||||
RenderSelection();
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Render highlighted item
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
renderer.PlotVertex(highlighted, ColorCollection.HIGHLIGHT);
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.EndSelect();
|
||||
}
|
||||
|
||||
// Start editing
|
||||
protected override void Edit()
|
||||
{
|
||||
base.Edit();
|
||||
}
|
||||
|
||||
// Done editing
|
||||
protected override void EndEdit()
|
||||
{
|
||||
base.EndEdit();
|
||||
}
|
||||
|
||||
// Mouse moves
|
||||
|
@ -242,54 +271,6 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
// Highlight nothing
|
||||
Highlight(null);
|
||||
}
|
||||
|
||||
// Mouse button pressed
|
||||
public override void MouseDown(MouseEventArgs e)
|
||||
{
|
||||
base.MouseDown(e);
|
||||
|
||||
// Which button is used?
|
||||
if(e.Button == EditMode.SELECT_BUTTON)
|
||||
{
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Flip selection
|
||||
highlighted.Selected = !highlighted.Selected;
|
||||
|
||||
// Redraw highlight to show selection
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
renderer.PlotVertex(highlighted, renderer.DetermineVertexColor(highlighted));
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start making a selection
|
||||
StartSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse released
|
||||
public override void MouseUp(MouseEventArgs e)
|
||||
{
|
||||
base.MouseUp(e);
|
||||
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Render highlighted item
|
||||
if(renderer.StartPlotter(false))
|
||||
{
|
||||
renderer.PlotVertex(highlighted, ColorCollection.HIGHLIGHT);
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse wants to drag
|
||||
protected override void DragStart(MouseEventArgs e)
|
||||
|
@ -297,7 +278,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
base.DragStart(e);
|
||||
|
||||
// Edit button used?
|
||||
if(e.Button == EditMode.EDIT_BUTTON)
|
||||
if(General.Interface.CheckActionActive(null, "classicedit"))
|
||||
{
|
||||
// Anything highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
|
@ -315,6 +296,41 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is called wheh selection ends
|
||||
protected override void EndMultiSelection()
|
||||
{
|
||||
// Go for all vertices
|
||||
foreach(Vertex v in General.Map.Map.Vertices)
|
||||
{
|
||||
v.Selected = ((v.Position.x >= selectionrect.Left) &&
|
||||
(v.Position.y >= selectionrect.Top) &&
|
||||
(v.Position.x <= selectionrect.Right) &&
|
||||
(v.Position.y <= selectionrect.Bottom));
|
||||
}
|
||||
|
||||
base.EndMultiSelection();
|
||||
|
||||
// Clear overlay
|
||||
if(renderer.StartOverlay(true)) renderer.Finish();
|
||||
|
||||
// Redraw
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
// This is called when the selection is updated
|
||||
protected override void UpdateMultiSelection()
|
||||
{
|
||||
base.UpdateMultiSelection();
|
||||
|
||||
// Render selection
|
||||
if(renderer.StartOverlay(true))
|
||||
{
|
||||
RenderMultiSelection();
|
||||
renderer.Finish();
|
||||
renderer.Present();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -2,8 +2,21 @@
|
|||
Doom Builder Actions Configuration
|
||||
\******************************************/
|
||||
|
||||
// This just defines which actions there are and what description they have
|
||||
// The source code will bind to these actions with delegates (function pointers)
|
||||
// This just defines which actions there are, what description they have and
|
||||
// some behaviour options. The Doom Builder core will bind to these actions
|
||||
// with delegates (function pointers) where you use the BeginAction and
|
||||
// EndAction attributes.
|
||||
|
||||
// Behaviour options:
|
||||
//
|
||||
// allowkeys: Allows the user to bind standard keys to this action.
|
||||
// allowmouse: Allows the user to bind mouse buttons to this action.
|
||||
// allowscroll: Allows the user to bind the scrollwheel to this action.
|
||||
// disregardshift: This action will be triggered regardless if Shift or Control are used.
|
||||
// repeat: BeginAction will be called for automatic key repetition.
|
||||
//
|
||||
// allowkeys and allowmouse are true by default, the others are false by default.
|
||||
//
|
||||
|
||||
verticesmode
|
||||
{
|
||||
|
@ -43,8 +56,36 @@ thingsmode
|
|||
|
||||
drawlinesmode
|
||||
{
|
||||
title = "Edit: Draw Lines";
|
||||
description = "Starts drawing lines.";
|
||||
title = "2D: Draw Lines";
|
||||
description = "Starts drawing lines. See the Drawing category for actions available during drawing mode.";
|
||||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = true;
|
||||
}
|
||||
|
||||
drawpoint
|
||||
{
|
||||
title = "Drawing: Draws Vertex";
|
||||
description = "Draws a vertex at the mousecursor position.";
|
||||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = true;
|
||||
disregardshift = true;
|
||||
}
|
||||
|
||||
removepoint
|
||||
{
|
||||
title = "Drawing: Remove Previous Vertex";
|
||||
description = "Removes the previously drawn vertex from the drawing session.";
|
||||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = true;
|
||||
}
|
||||
|
||||
finishdraw
|
||||
{
|
||||
title = "Drawing: Finish Drawing";
|
||||
description = "Finishes the drawing and creates the geometry.";
|
||||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = true;
|
||||
|
|
|
@ -232,8 +232,8 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
base.MouseDown(e);
|
||||
bool front, back;
|
||||
|
||||
// Which button is used?
|
||||
if(e.Button == EditMode.SELECT_BUTTON)
|
||||
// Edit button is used?
|
||||
if(General.Interface.CheckActionActive(null, "classicedit"))
|
||||
{
|
||||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
|
@ -272,8 +272,8 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
// Item highlighted?
|
||||
if((highlighted != null) && !highlighted.IsDisposed)
|
||||
{
|
||||
// Which button is used?
|
||||
if(e.Button == EditMode.SELECT_BUTTON)
|
||||
// Edit button is used?
|
||||
if(General.Interface.CheckActionActive(null, "classicedit"))
|
||||
{
|
||||
// Anything selected?
|
||||
selected = General.Map.Map.GetSectorsSelection(true);
|
||||
|
|
|
@ -39,14 +39,18 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
|
||||
// Shortcut key
|
||||
private int key;
|
||||
private int keymask;
|
||||
|
||||
// Shortcut options
|
||||
private bool allowkeys;
|
||||
private bool allowmouse;
|
||||
private bool allowscroll;
|
||||
private bool disregardshift;
|
||||
private bool repeat;
|
||||
|
||||
// Delegate
|
||||
private List<ActionDelegate> delegates;
|
||||
private List<ActionDelegate> begindelegates;
|
||||
private List<ActionDelegate> enddelegates;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -57,9 +61,12 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
public string Title { get { return title; } }
|
||||
public string Description { get { return description; } }
|
||||
public int ShortcutKey { get { return key; } }
|
||||
public int ShortcutMask { get { return keymask; } }
|
||||
public bool AllowKeys { get { return allowkeys; } }
|
||||
public bool AllowMouse { get { return allowmouse; } }
|
||||
public bool AllowScroll { get { return allowscroll; } }
|
||||
public bool DisregardShift { get { return disregardshift; } }
|
||||
public bool Repeat { get { return repeat; } }
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -67,18 +74,32 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
|
||||
// Constructor
|
||||
public Action(string name, string shortname, string title, string description, int key,
|
||||
bool allowkeys, bool allowmouse, bool allowscroll)
|
||||
bool allowkeys, bool allowmouse, bool allowscroll, bool disregardshift, bool repeat)
|
||||
{
|
||||
// Initialize
|
||||
this.name = name;
|
||||
this.shortname = shortname;
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.delegates = new List<ActionDelegate>();
|
||||
this.begindelegates = new List<ActionDelegate>();
|
||||
this.enddelegates = new List<ActionDelegate>();
|
||||
this.allowkeys = allowkeys;
|
||||
this.allowmouse = allowmouse;
|
||||
this.allowscroll = allowscroll;
|
||||
this.key = key;
|
||||
this.disregardshift = disregardshift;
|
||||
this.repeat = repeat;
|
||||
|
||||
if(disregardshift)
|
||||
{
|
||||
keymask = (int)Keys.Shift | (int)Keys.Control;
|
||||
keymask = ~keymask;
|
||||
}
|
||||
else
|
||||
{
|
||||
keymask = ~0;
|
||||
}
|
||||
|
||||
this.key = key & keymask;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
@ -166,42 +187,71 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
public void SetShortcutKey(int key)
|
||||
{
|
||||
// Make it so.
|
||||
this.key = key;
|
||||
this.key = key & keymask;
|
||||
}
|
||||
|
||||
// This binds a delegate to this action
|
||||
public void Bind(ActionDelegate method)
|
||||
public void BindBegin(ActionDelegate method)
|
||||
{
|
||||
delegates.Add(method);
|
||||
begindelegates.Add(method);
|
||||
}
|
||||
|
||||
// This removes a delegate from this action
|
||||
public void Unbind(ActionDelegate method)
|
||||
public void UnbindBegin(ActionDelegate method)
|
||||
{
|
||||
delegates.Remove(method);
|
||||
begindelegates.Remove(method);
|
||||
}
|
||||
|
||||
// This binds a delegate to this action
|
||||
public void BindEnd(ActionDelegate method)
|
||||
{
|
||||
enddelegates.Add(method);
|
||||
}
|
||||
|
||||
// This removes a delegate from this action
|
||||
public void UnbindEnd(ActionDelegate method)
|
||||
{
|
||||
enddelegates.Remove(method);
|
||||
}
|
||||
|
||||
// This raises events for this action
|
||||
public void Invoke()
|
||||
public void Begin()
|
||||
{
|
||||
List<ActionDelegate> delegateslist;
|
||||
|
||||
// No method bound?
|
||||
if(delegates.Count == 0)
|
||||
{
|
||||
// Ignore this since keys can also be handled through KeyDown and KeyUp in editing modes
|
||||
//General.WriteLogLine("Called action '" + name + "' has no methods bound");
|
||||
}
|
||||
else
|
||||
// Method bound?
|
||||
if(begindelegates.Count > 0)
|
||||
{
|
||||
// Copy delegates list
|
||||
delegateslist = new List<ActionDelegate>(delegates);
|
||||
delegateslist = new List<ActionDelegate>(begindelegates);
|
||||
|
||||
// Invoke all the delegates
|
||||
foreach(ActionDelegate ad in delegateslist) ad.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
// This raises events for this action
|
||||
public void End()
|
||||
{
|
||||
List<ActionDelegate> delegateslist;
|
||||
|
||||
// Method bound?
|
||||
if(enddelegates.Count > 0)
|
||||
{
|
||||
// Copy delegates list
|
||||
delegateslist = new List<ActionDelegate>(enddelegates);
|
||||
|
||||
// Invoke all the delegates
|
||||
foreach(ActionDelegate ad in delegateslist) ad.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
// This checks if the action qualifies for a key combination
|
||||
public bool KeyMatches(int pressedkey)
|
||||
{
|
||||
return (key == (pressedkey & keymask));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,15 +30,15 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
/// <summary>
|
||||
/// This binds a method to an action.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method, Inherited=true, AllowMultiple=true)]
|
||||
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
|
||||
public class ActionAttribute : Attribute
|
||||
{
|
||||
#region ================== Variables
|
||||
|
||||
// The action to bind to
|
||||
private string action;
|
||||
private bool baseaction;
|
||||
|
||||
protected string action;
|
||||
protected bool baseaction;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
@ -47,6 +47,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
/// Set to true to indicate this is a core Doom Builder action when used within a plugin.
|
||||
/// </summary>
|
||||
public bool BaseAction { get { return baseaction; } set { baseaction = value; } }
|
||||
internal string ActionName { get { return action; } }
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -71,19 +72,15 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
public string GetFullActionName(Assembly asm)
|
||||
{
|
||||
string asmname;
|
||||
|
||||
|
||||
if(baseaction)
|
||||
asmname = General.ThisAssembly.GetName().Name.ToLowerInvariant();
|
||||
else
|
||||
asmname = asm.GetName().Name.ToLowerInvariant();
|
||||
|
||||
|
||||
return asmname + "_" + action;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Static Methods
|
||||
|
||||
// This makes the proper name
|
||||
public string GetFullActionName(Assembly asm, bool baseaction, string actionname)
|
||||
{
|
||||
|
@ -97,134 +94,6 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
return asmname + "_" + actionname;
|
||||
}
|
||||
|
||||
// This binds all methods marked with this attribute
|
||||
internal static void BindMethods(Type type)
|
||||
{
|
||||
// Bind static methods
|
||||
BindMethods(null, type);
|
||||
}
|
||||
|
||||
// This binds all methods marked with this attribute
|
||||
internal static void BindMethods(object obj)
|
||||
{
|
||||
// Bind instance methods
|
||||
BindMethods(obj, obj.GetType());
|
||||
}
|
||||
|
||||
// This binds all methods marked with this attribute
|
||||
private static void BindMethods(object obj, Type type)
|
||||
{
|
||||
MethodInfo[] methods;
|
||||
ActionAttribute[] attrs;
|
||||
ActionDelegate del;
|
||||
string actionname;
|
||||
|
||||
if(obj == null)
|
||||
General.WriteLogLine("Binding static action methods for class " + type.Name + "...");
|
||||
else
|
||||
General.WriteLogLine("Binding action methods for " + type.Name + " object...");
|
||||
|
||||
// Go for all methods on obj
|
||||
methods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
|
||||
foreach(MethodInfo m in methods)
|
||||
{
|
||||
// Check if the method has this attribute
|
||||
attrs = (ActionAttribute[])m.GetCustomAttributes(typeof(ActionAttribute), true);
|
||||
|
||||
// Go for all attributes
|
||||
foreach(ActionAttribute a in attrs)
|
||||
{
|
||||
// Create a delegate for this method
|
||||
del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m);
|
||||
|
||||
// Make proper name
|
||||
actionname = a.GetFullActionName(type.Assembly);
|
||||
|
||||
// Bind method to action
|
||||
if(General.Actions.Exists(actionname))
|
||||
General.Actions[actionname].Bind(del);
|
||||
else
|
||||
throw new ArgumentException("Could not bind " + m.ReflectedType.Name + "." + m.Name + " to action \"" + actionname + "\", that action does not exist! Refer to, or edit Actions.cfg for all available application actions.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This binds a delegate manually
|
||||
internal static void BindDelegate(Assembly asm, ActionDelegate d, ActionAttribute a)
|
||||
{
|
||||
string actionname;
|
||||
|
||||
// Make proper name
|
||||
actionname = a.GetFullActionName(asm);
|
||||
|
||||
// Bind delegate to action
|
||||
if(General.Actions.Exists(actionname))
|
||||
General.Actions[actionname].Bind(d);
|
||||
else
|
||||
General.WriteLogLine("WARNING: Could not bind delegate for " + d.Method.Name + " to action \"" + a.action + "\" (" + actionname + "), that action does not exist! Refer to, or edit Actions.cfg for all available application actions.");
|
||||
}
|
||||
|
||||
// This unbinds all methods marked with this attribute
|
||||
internal static void UnbindMethods(Type type)
|
||||
{
|
||||
// Unbind static methods
|
||||
UnbindMethods(null, type);
|
||||
}
|
||||
|
||||
// This unbinds all methods marked with this attribute
|
||||
internal static void UnbindMethods(object obj)
|
||||
{
|
||||
// Unbind instance methods
|
||||
UnbindMethods(obj, obj.GetType());
|
||||
}
|
||||
|
||||
// This unbinds all methods marked with this attribute
|
||||
private static void UnbindMethods(object obj, Type type)
|
||||
{
|
||||
MethodInfo[] methods;
|
||||
ActionAttribute[] attrs;
|
||||
ActionDelegate del;
|
||||
string actionname;
|
||||
|
||||
if(obj == null)
|
||||
General.WriteLogLine("Unbinding static action methods for class " + type.Name + "...");
|
||||
else
|
||||
General.WriteLogLine("Unbinding action methods for " + type.Name + " object...");
|
||||
|
||||
// Go for all methods on obj
|
||||
methods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
|
||||
foreach(MethodInfo m in methods)
|
||||
{
|
||||
// Check if the method has this attribute
|
||||
attrs = (ActionAttribute[])m.GetCustomAttributes(typeof(ActionAttribute), true);
|
||||
|
||||
// Go for all attributes
|
||||
foreach(ActionAttribute a in attrs)
|
||||
{
|
||||
// Create a delegate for this method
|
||||
del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m);
|
||||
|
||||
// Make proper name
|
||||
actionname = a.GetFullActionName(type.Assembly);
|
||||
|
||||
// Unbind method from action
|
||||
General.Actions[actionname].Unbind(del);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This unbinds a delegate manually
|
||||
internal static void UnbindDelegate(Assembly asm, ActionDelegate d, ActionAttribute a)
|
||||
{
|
||||
string actionname;
|
||||
|
||||
// Make proper name
|
||||
actionname = a.GetFullActionName(asm);
|
||||
|
||||
// Unbind delegate to action
|
||||
General.Actions[actionname].Unbind(d);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ using System.IO;
|
|||
using CodeImp.DoomBuilder.IO;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -44,6 +45,13 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
// Actions
|
||||
private Dictionary<string, Action> actions;
|
||||
|
||||
// Keys state
|
||||
private int modifiers;
|
||||
private List<int> pressedkeys;
|
||||
|
||||
// Begun actions
|
||||
private List<Action> activeactions;
|
||||
|
||||
// Disposing
|
||||
private bool isdisposed = false;
|
||||
|
||||
|
@ -64,7 +72,9 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
// Initialize
|
||||
General.WriteLogLine("Starting action manager...");
|
||||
actions = new Dictionary<string, Action>();
|
||||
|
||||
pressedkeys = new List<int>();
|
||||
activeactions = new List<Action>();
|
||||
|
||||
// Load all actions in this assembly
|
||||
LoadActions(General.ThisAssembly);
|
||||
|
||||
|
@ -96,7 +106,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
StreamReader actionsreader;
|
||||
Configuration cfg;
|
||||
string name, title, desc, shortname;
|
||||
bool amouse, akeys, ascroll, debugonly;
|
||||
bool amouse, akeys, ascroll, debugonly, noshift, repeat;
|
||||
string[] resnames;
|
||||
AssemblyName asmname = asm.GetName();
|
||||
|
||||
|
@ -127,16 +137,18 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
name = asmname.Name.ToLowerInvariant() + "_" + shortname;
|
||||
title = cfg.ReadSetting(a.Key + ".title", "[" + name + "]");
|
||||
desc = cfg.ReadSetting(a.Key + ".description", "");
|
||||
akeys = cfg.ReadSetting(a.Key + ".allowkeys", false);
|
||||
amouse = cfg.ReadSetting(a.Key + ".allowmouse", false);
|
||||
akeys = cfg.ReadSetting(a.Key + ".allowkeys", true);
|
||||
amouse = cfg.ReadSetting(a.Key + ".allowmouse", true);
|
||||
ascroll = cfg.ReadSetting(a.Key + ".allowscroll", false);
|
||||
noshift = cfg.ReadSetting(a.Key + ".disregardshift", false);
|
||||
repeat = cfg.ReadSetting(a.Key + ".repeat", false);
|
||||
debugonly = cfg.ReadSetting(a.Key + ".debugonly", false);
|
||||
|
||||
// Check if action should be included
|
||||
if(General.DebugBuild || !debugonly)
|
||||
{
|
||||
// Create an action
|
||||
CreateAction(name, shortname, title, desc, akeys, amouse, ascroll);
|
||||
CreateAction(name, shortname, title, desc, akeys, amouse, ascroll, noshift, repeat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -144,7 +156,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
}
|
||||
|
||||
// This manually creates an action
|
||||
private void CreateAction(string name, string shortname, string title, string desc, bool allowkeys, bool allowmouse, bool allowscroll)
|
||||
private void CreateAction(string name, string shortname, string title, string desc, bool allowkeys, bool allowmouse, bool allowscroll, bool disregardshift, bool repeat)
|
||||
{
|
||||
// Action does not exist yet?
|
||||
if(!actions.ContainsKey(name))
|
||||
|
@ -153,7 +165,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
int key = General.Settings.ReadSetting("shortcuts." + name, 0);
|
||||
|
||||
// Create an action
|
||||
actions.Add(name, new Action(name, shortname, title, desc, key, allowkeys, allowmouse, allowscroll));
|
||||
actions.Add(name, new Action(name, shortname, title, desc, key, allowkeys, allowmouse, allowscroll, disregardshift, repeat));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -161,6 +173,196 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
General.WriteLogLine("WARNING: Action '" + name + "' already exists. Action names must be unique!");
|
||||
}
|
||||
}
|
||||
|
||||
// This binds all methods marked with this attribute
|
||||
internal void BindMethods(Type type)
|
||||
{
|
||||
// Bind static methods
|
||||
BindMethods(null, type);
|
||||
}
|
||||
|
||||
// This binds all methods marked with this attribute
|
||||
internal void BindMethods(object obj)
|
||||
{
|
||||
// Bind instance methods
|
||||
BindMethods(obj, obj.GetType());
|
||||
}
|
||||
|
||||
// This binds all methods marked with this attribute
|
||||
private void BindMethods(object obj, Type type)
|
||||
{
|
||||
MethodInfo[] methods;
|
||||
ActionAttribute[] attrs;
|
||||
ActionDelegate del;
|
||||
string actionname;
|
||||
|
||||
if(obj == null)
|
||||
General.WriteLogLine("Binding static action methods for class " + type.Name + "...");
|
||||
else
|
||||
General.WriteLogLine("Binding action methods for " + type.Name + " object...");
|
||||
|
||||
// Go for all methods on obj
|
||||
methods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
|
||||
foreach(MethodInfo m in methods)
|
||||
{
|
||||
// Check if the method has this attribute
|
||||
attrs = (ActionAttribute[])m.GetCustomAttributes(typeof(BeginActionAttribute), true);
|
||||
|
||||
// Go for all attributes
|
||||
foreach(ActionAttribute a in attrs)
|
||||
{
|
||||
// Create a delegate for this method
|
||||
del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m);
|
||||
|
||||
// Make proper name
|
||||
actionname = a.GetFullActionName(type.Assembly);
|
||||
|
||||
// Bind method to action
|
||||
if(Exists(actionname))
|
||||
actions[actionname].BindBegin(del);
|
||||
else
|
||||
throw new ArgumentException("Could not bind " + m.ReflectedType.Name + "." + m.Name + " to action \"" + actionname + "\", that action does not exist! Refer to, or edit Actions.cfg for all available application actions.");
|
||||
}
|
||||
|
||||
// Check if the method has this attribute
|
||||
attrs = (ActionAttribute[])m.GetCustomAttributes(typeof(EndActionAttribute), true);
|
||||
|
||||
// Go for all attributes
|
||||
foreach(ActionAttribute a in attrs)
|
||||
{
|
||||
// Create a delegate for this method
|
||||
del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m);
|
||||
|
||||
// Make proper name
|
||||
actionname = a.GetFullActionName(type.Assembly);
|
||||
|
||||
// Bind method to action
|
||||
if(Exists(actionname))
|
||||
actions[actionname].BindEnd(del);
|
||||
else
|
||||
throw new ArgumentException("Could not bind " + m.ReflectedType.Name + "." + m.Name + " to action \"" + actionname + "\", that action does not exist! Refer to, or edit Actions.cfg for all available application actions.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This binds a delegate manually
|
||||
internal void BindBeginDelegate(Assembly asm, ActionDelegate d, BeginActionAttribute a)
|
||||
{
|
||||
string actionname;
|
||||
|
||||
// Make proper name
|
||||
actionname = a.GetFullActionName(asm);
|
||||
|
||||
// Bind delegate to action
|
||||
if(Exists(actionname))
|
||||
actions[actionname].BindBegin(d);
|
||||
else
|
||||
General.WriteLogLine("WARNING: Could not bind delegate for " + d.Method.Name + " to action \"" + a.ActionName + "\" (" + actionname + "), that action does not exist! Refer to, or edit Actions.cfg for all available application actions.");
|
||||
}
|
||||
|
||||
// This binds a delegate manually
|
||||
internal void BindEndDelegate(Assembly asm, ActionDelegate d, EndActionAttribute a)
|
||||
{
|
||||
string actionname;
|
||||
|
||||
// Make proper name
|
||||
actionname = a.GetFullActionName(asm);
|
||||
|
||||
// Bind delegate to action
|
||||
if(Exists(actionname))
|
||||
actions[actionname].BindEnd(d);
|
||||
else
|
||||
General.WriteLogLine("WARNING: Could not bind delegate for " + d.Method.Name + " to action \"" + a.ActionName + "\" (" + actionname + "), that action does not exist! Refer to, or edit Actions.cfg for all available application actions.");
|
||||
}
|
||||
|
||||
// This unbinds all methods marked with this attribute
|
||||
internal void UnbindMethods(Type type)
|
||||
{
|
||||
// Unbind static methods
|
||||
UnbindMethods(null, type);
|
||||
}
|
||||
|
||||
// This unbinds all methods marked with this attribute
|
||||
internal void UnbindMethods(object obj)
|
||||
{
|
||||
// Unbind instance methods
|
||||
UnbindMethods(obj, obj.GetType());
|
||||
}
|
||||
|
||||
// This unbinds all methods marked with this attribute
|
||||
private void UnbindMethods(object obj, Type type)
|
||||
{
|
||||
MethodInfo[] methods;
|
||||
ActionAttribute[] attrs;
|
||||
ActionDelegate del;
|
||||
string actionname;
|
||||
|
||||
if(obj == null)
|
||||
General.WriteLogLine("Unbinding static action methods for class " + type.Name + "...");
|
||||
else
|
||||
General.WriteLogLine("Unbinding action methods for " + type.Name + " object...");
|
||||
|
||||
// Go for all methods on obj
|
||||
methods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
|
||||
foreach(MethodInfo m in methods)
|
||||
{
|
||||
// Check if the method has this attribute
|
||||
attrs = (ActionAttribute[])m.GetCustomAttributes(typeof(BeginActionAttribute), true);
|
||||
|
||||
// Go for all attributes
|
||||
foreach(ActionAttribute a in attrs)
|
||||
{
|
||||
// Create a delegate for this method
|
||||
del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m);
|
||||
|
||||
// Make proper name
|
||||
actionname = a.GetFullActionName(type.Assembly);
|
||||
|
||||
// Unbind method from action
|
||||
actions[actionname].UnbindBegin(del);
|
||||
}
|
||||
|
||||
// Check if the method has this attribute
|
||||
attrs = (ActionAttribute[])m.GetCustomAttributes(typeof(EndActionAttribute), true);
|
||||
|
||||
// Go for all attributes
|
||||
foreach(ActionAttribute a in attrs)
|
||||
{
|
||||
// Create a delegate for this method
|
||||
del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m);
|
||||
|
||||
// Make proper name
|
||||
actionname = a.GetFullActionName(type.Assembly);
|
||||
|
||||
// Unbind method from action
|
||||
actions[actionname].UnbindEnd(del);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This unbinds a delegate manually
|
||||
internal void UnbindBeginDelegate(Assembly asm, ActionDelegate d, BeginActionAttribute a)
|
||||
{
|
||||
string actionname;
|
||||
|
||||
// Make proper name
|
||||
actionname = a.GetFullActionName(asm);
|
||||
|
||||
// Unbind delegate to action
|
||||
actions[actionname].UnbindBegin(d);
|
||||
}
|
||||
|
||||
// This unbinds a delegate manually
|
||||
internal void UnbindEndDelegate(Assembly asm, ActionDelegate d, EndActionAttribute a)
|
||||
{
|
||||
string actionname;
|
||||
|
||||
// Make proper name
|
||||
actionname = a.GetFullActionName(asm);
|
||||
|
||||
// Unbind delegate to action
|
||||
actions[actionname].UnbindEnd(d);
|
||||
}
|
||||
|
||||
// This checks if a given action exists
|
||||
public bool Exists(string action)
|
||||
|
@ -190,7 +392,21 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
#endregion
|
||||
|
||||
#region ================== Shortcut Keys
|
||||
|
||||
// This checks if a given action is active
|
||||
public bool CheckActionActive(Assembly asm, string actionname)
|
||||
{
|
||||
// Find active action
|
||||
string fullname = asm.GetName().Name.ToLowerInvariant() + "_" + actionname;
|
||||
foreach(Action a in activeactions)
|
||||
{
|
||||
if(a.Name == fullname) return true;
|
||||
}
|
||||
|
||||
// No such active action
|
||||
return false;
|
||||
}
|
||||
|
||||
// Removes all shortcut keys
|
||||
public void RemoveShortcutKeys()
|
||||
{
|
||||
|
@ -199,23 +415,95 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
a.Value.SetShortcutKey(0);
|
||||
}
|
||||
|
||||
// This notifies a key has been pressed
|
||||
public void KeyPressed(int key)
|
||||
{
|
||||
int strippedkey = key & ~((int)Keys.Alt | (int)Keys.Shift | (int)Keys.Control);
|
||||
if((strippedkey == (int)Keys.ShiftKey) || (strippedkey == (int)Keys.ControlKey)) key = strippedkey;
|
||||
bool repeat = pressedkeys.Contains(strippedkey);
|
||||
|
||||
// Invoke event
|
||||
BeginActionByKey(key, repeat);
|
||||
Action[] acts = GetActionsByKey(key);
|
||||
foreach(Action a in acts) if(!activeactions.Contains(a)) activeactions.Add(a);
|
||||
|
||||
// Update pressed keys
|
||||
if(!repeat) pressedkeys.Add(strippedkey);
|
||||
}
|
||||
|
||||
// This notifies a key has been released
|
||||
public void KeyReleased(int key)
|
||||
{
|
||||
int strippedkey = key & ~((int)Keys.Alt | (int)Keys.Shift | (int)Keys.Control);
|
||||
List<Action> keepactions = new List<Action>();
|
||||
|
||||
// Update pressed keys
|
||||
if(pressedkeys.Contains(strippedkey)) pressedkeys.Remove(strippedkey);
|
||||
|
||||
// End actions that no longer match
|
||||
EndActiveActions();
|
||||
}
|
||||
|
||||
// This updates the modifiers
|
||||
public void UpdateModifiers(int mods)
|
||||
{
|
||||
// Update modifiers
|
||||
modifiers = mods;
|
||||
|
||||
// End actions that no longer match
|
||||
EndActiveActions();
|
||||
}
|
||||
|
||||
// This will call the associated actions for a keypress
|
||||
public void InvokeByKey(int key)
|
||||
private void BeginActionByKey(int key, bool repeated)
|
||||
{
|
||||
// Go for all actions
|
||||
foreach(KeyValuePair<string, Action> a in actions)
|
||||
{
|
||||
// This action is associated with this key?
|
||||
if(a.Value.ShortcutKey == key)
|
||||
if(a.Value.KeyMatches(key) && (a.Value.Repeat || !repeated))
|
||||
{
|
||||
// Invoke action
|
||||
a.Value.Invoke();
|
||||
a.Value.Begin();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This will end active actions for which the pressed keys do not match
|
||||
private void EndActiveActions()
|
||||
{
|
||||
List<Action> keepactions = new List<Action>();
|
||||
|
||||
// Go for all active actions
|
||||
foreach(Action a in activeactions)
|
||||
{
|
||||
// Go for all pressed keys
|
||||
bool stillactive = false;
|
||||
foreach(int k in pressedkeys)
|
||||
{
|
||||
if((k == (int)Keys.ShiftKey) || (k == (int)Keys.ControlKey))
|
||||
stillactive |= a.KeyMatches(k);
|
||||
else
|
||||
stillactive |= a.KeyMatches(k | modifiers);
|
||||
}
|
||||
|
||||
// End the action if no longer matches any of the keys
|
||||
if(!stillactive)
|
||||
{
|
||||
a.End();
|
||||
}
|
||||
else
|
||||
{
|
||||
keepactions.Add(a);
|
||||
}
|
||||
}
|
||||
|
||||
// Update list of activate actions
|
||||
activeactions = keepactions;
|
||||
}
|
||||
|
||||
// This returns all action names for a given key
|
||||
public string[] GetActionsByKey(int key)
|
||||
public string[] GetActionNamesByKey(int key)
|
||||
{
|
||||
List<string> actionnames = new List<string>();
|
||||
|
||||
|
@ -223,7 +511,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
foreach(KeyValuePair<string, Action> a in actions)
|
||||
{
|
||||
// This action is associated with this key?
|
||||
if(a.Value.ShortcutKey == key)
|
||||
if(a.Value.KeyMatches(key))
|
||||
{
|
||||
// List short name
|
||||
actionnames.Add(a.Value.ShortName);
|
||||
|
@ -233,6 +521,26 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
// Return result;
|
||||
return actionnames.ToArray();
|
||||
}
|
||||
|
||||
// This returns all action names for a given key
|
||||
public Action[] GetActionsByKey(int key)
|
||||
{
|
||||
List<Action> actionnames = new List<Action>();
|
||||
|
||||
// Go for all actions
|
||||
foreach(KeyValuePair<string, Action> a in actions)
|
||||
{
|
||||
// This action is associated with this key?
|
||||
if(a.Value.KeyMatches(key))
|
||||
{
|
||||
// List short name
|
||||
actionnames.Add(a.Value);
|
||||
}
|
||||
}
|
||||
|
||||
// Return result;
|
||||
return actionnames.ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
43
Source/Controls/BeginActionAttribute.cs
Normal file
43
Source/Controls/BeginActionAttribute.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
|
||||
#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.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// This binds a method to an action which is then called when the action is started.
|
||||
/// </summary>
|
||||
public class BeginActionAttribute : ActionAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// This binds a method to an action which is then called when the action is started.
|
||||
/// </summary>
|
||||
/// <param name="action">The action name as defined in Actions.cfg resource.</param>
|
||||
public BeginActionAttribute(string action) : base(action)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
43
Source/Controls/EndActionAttribute.cs
Normal file
43
Source/Controls/EndActionAttribute.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
|
||||
#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.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// This binds a method to an action which is then called when the action is stopped.
|
||||
/// </summary>
|
||||
public class EndActionAttribute : ActionAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// This binds a method to an action which is then called when the action is stopped.
|
||||
/// </summary>
|
||||
/// <param name="action">The action name as defined in Actions.cfg resource.</param>
|
||||
public EndActionAttribute(string action) : base(action)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -109,7 +109,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
#region ================== Scroll / Zoom
|
||||
|
||||
// This scrolls the view north
|
||||
[Action("scrollnorth", BaseAction = true)]
|
||||
[BeginAction("scrollnorth", BaseAction = true)]
|
||||
public virtual void ScrollNorth()
|
||||
{
|
||||
// Scroll
|
||||
|
@ -117,7 +117,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
}
|
||||
|
||||
// This scrolls the view south
|
||||
[Action("scrollsouth", BaseAction = true)]
|
||||
[BeginAction("scrollsouth", BaseAction = true)]
|
||||
public virtual void ScrollSouth()
|
||||
{
|
||||
// Scroll
|
||||
|
@ -125,7 +125,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
}
|
||||
|
||||
// This scrolls the view west
|
||||
[Action("scrollwest", BaseAction = true)]
|
||||
[BeginAction("scrollwest", BaseAction = true)]
|
||||
public virtual void ScrollWest()
|
||||
{
|
||||
// Scroll
|
||||
|
@ -133,7 +133,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
}
|
||||
|
||||
// This scrolls the view east
|
||||
[Action("scrolleast", BaseAction = true)]
|
||||
[BeginAction("scrolleast", BaseAction = true)]
|
||||
public virtual void ScrollEast()
|
||||
{
|
||||
// Scroll
|
||||
|
@ -141,7 +141,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
}
|
||||
|
||||
// This zooms in
|
||||
[Action("zoomin", BaseAction = true)]
|
||||
[BeginAction("zoomin", BaseAction = true)]
|
||||
public virtual void ZoomIn()
|
||||
{
|
||||
// Zoom
|
||||
|
@ -149,7 +149,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
}
|
||||
|
||||
// This zooms out
|
||||
[Action("zoomout", BaseAction = true)]
|
||||
[BeginAction("zoomout", BaseAction = true)]
|
||||
public virtual void ZoomOut()
|
||||
{
|
||||
// Zoom
|
||||
|
@ -232,7 +232,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
}
|
||||
|
||||
// This zooms and scrolls to fit the map in the window
|
||||
[Action("centerinscreen", BaseAction = true)]
|
||||
[BeginAction("centerinscreen", BaseAction = true)]
|
||||
public void CenterInScreen()
|
||||
{
|
||||
float left = float.MaxValue;
|
||||
|
@ -318,8 +318,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
General.MainWindow.UpdateCoordinates(mousemappos);
|
||||
|
||||
// Holding a button?
|
||||
if((e.Button == EditMode.EDIT_BUTTON) ||
|
||||
(e.Button == EditMode.SELECT_BUTTON))
|
||||
if(e.Button != MouseButtons.None)
|
||||
{
|
||||
// Not dragging?
|
||||
if(mousedragging == MouseButtons.None)
|
||||
|
@ -337,7 +336,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
}
|
||||
|
||||
// Selecting?
|
||||
if(selecting) UpdateSelection();
|
||||
if(selecting) UpdateMultiSelection();
|
||||
|
||||
// Let the base class know
|
||||
base.MouseMove(e);
|
||||
|
@ -364,24 +363,23 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
DragStop(e);
|
||||
mousedragging = MouseButtons.None;
|
||||
}
|
||||
|
||||
// Selection stops
|
||||
if(selecting) EndSelection();
|
||||
|
||||
// Let the base class know
|
||||
base.MouseUp(e);
|
||||
}
|
||||
|
||||
// This is called when the mouse is moved enough pixels and holding one or more buttons
|
||||
|
||||
/// <summary>
|
||||
/// Automatically called when dragging operation starts.
|
||||
/// </summary>
|
||||
protected virtual void DragStart(MouseEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// This is called when a drag is ended because the mouse buton is released
|
||||
/// <summary>
|
||||
/// Automatically called when dragging operation stops.
|
||||
/// </summary>
|
||||
protected virtual void DragStop(MouseEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -398,23 +396,85 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
|
||||
#region ================== Methods
|
||||
|
||||
// Cancelling
|
||||
/// <summary>
|
||||
/// Automatically called by the core when this editing mode is engaged.
|
||||
/// </summary>
|
||||
public override void Engage()
|
||||
{
|
||||
// Clear display overlay
|
||||
renderer.StartOverlay(true);
|
||||
renderer.Finish();
|
||||
base.Engage();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the user requests to cancel this editing mode.
|
||||
/// </summary>
|
||||
public override void Cancel()
|
||||
{
|
||||
cancelled = true;
|
||||
base.Cancel();
|
||||
}
|
||||
|
||||
// This starts a selection
|
||||
protected virtual void StartSelection()
|
||||
|
||||
/// <summary>
|
||||
/// This is called automatically when the Edit button is pressed.
|
||||
/// (in Doom Builder 1, this was always the right mousebutton)
|
||||
/// </summary>
|
||||
[BeginAction("classicedit", BaseAction = true)]
|
||||
protected virtual void Edit()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called automatically when the Edit button is released.
|
||||
/// (in Doom Builder 1, this was always the right mousebutton)
|
||||
/// </summary>
|
||||
[EndAction("classicedit", BaseAction = true)]
|
||||
protected virtual void EndEdit()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called automatically when the Select button is pressed.
|
||||
/// (in Doom Builder 1, this was always the left mousebutton)
|
||||
/// </summary>
|
||||
[BeginAction("classicselect", BaseAction = true)]
|
||||
protected virtual void Select()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called automatically when the Select button is released.
|
||||
/// (in Doom Builder 1, this was always the left mousebutton)
|
||||
/// </summary>
|
||||
[EndAction("classicselect", BaseAction = true)]
|
||||
protected virtual void EndSelect()
|
||||
{
|
||||
if(selecting) EndMultiSelection();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called automatically when a rectangular multi-selection ends.
|
||||
/// </summary>
|
||||
protected virtual void EndMultiSelection()
|
||||
{
|
||||
selecting = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this to initiate a rectangular multi-selection.
|
||||
/// </summary>
|
||||
protected virtual void StartMultiSelection()
|
||||
{
|
||||
selecting = true;
|
||||
selectstart = mousemappos;
|
||||
selectionrect = new RectangleF(selectstart.x, selectstart.y, 0, 0);
|
||||
}
|
||||
|
||||
// This updates a selection
|
||||
protected virtual void UpdateSelection()
|
||||
|
||||
/// <summary>
|
||||
/// This is called automatically when a multi-selection is updated.
|
||||
/// </summary>
|
||||
protected virtual void UpdateMultiSelection()
|
||||
{
|
||||
selectionrect.X = selectstart.x;
|
||||
selectionrect.Y = selectstart.y;
|
||||
|
@ -434,15 +494,11 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
}
|
||||
}
|
||||
|
||||
// This is called when a selection is released
|
||||
protected virtual void EndSelection()
|
||||
{
|
||||
selecting = false;
|
||||
}
|
||||
|
||||
// This draws the selection on the overlay layer
|
||||
// Must call renderer.StartOverlay first!
|
||||
protected virtual void RenderSelection()
|
||||
/// <summary>
|
||||
/// Call this to draw the selection on the overlay layer.
|
||||
/// Must call renderer.StartOverlay first!
|
||||
/// </summary>
|
||||
protected virtual void RenderMultiSelection()
|
||||
{
|
||||
renderer.RenderRectangle(selectionrect, SELECTION_BORDER_SIZE,
|
||||
General.Colors.Highlight.WithAlpha(SELECTION_ALPHA), true);
|
||||
|
|
|
@ -44,8 +44,6 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
#region ================== Constants
|
||||
|
||||
public const int DRAG_START_MOVE_PIXELS = 5;
|
||||
public const MouseButtons EDIT_BUTTON = MouseButtons.Right;
|
||||
public const MouseButtons SELECT_BUTTON = MouseButtons.Left;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -133,18 +131,18 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
public virtual void Engage()
|
||||
{
|
||||
// Bind any methods
|
||||
ActionAttribute.BindMethods(this);
|
||||
General.Actions.BindMethods(this);
|
||||
}
|
||||
|
||||
// Mode disengages
|
||||
public virtual void Disengage()
|
||||
{
|
||||
// Unbind any methods
|
||||
ActionAttribute.UnbindMethods(this);
|
||||
General.Actions.UnbindMethods(this);
|
||||
}
|
||||
|
||||
// This forces the mode to cancel and return to the "parent" mode
|
||||
[Action("cancelmode", BaseAction = true)]
|
||||
[BeginAction("cancelmode", BaseAction = true)]
|
||||
public virtual void Cancel() { }
|
||||
|
||||
// Optional interface methods
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
private bool configspecific;
|
||||
|
||||
// Mode switching
|
||||
private ActionAttribute switchactionattr = null;
|
||||
private BeginActionAttribute switchactionattr = null;
|
||||
private ActionDelegate switchactiondel = null;
|
||||
|
||||
// Mode button
|
||||
|
@ -61,7 +61,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
|
||||
public Plugin Plugin { get { return plugin; } }
|
||||
public Type Type { get { return type; } }
|
||||
public ActionAttribute SwitchAction { get { return switchactionattr; } }
|
||||
public BeginActionAttribute SwitchAction { get { return switchactionattr; } }
|
||||
public Image ButtonImage { get { return buttonimage; } }
|
||||
public string ButtonDesc { get { return buttondesc; } }
|
||||
public bool ConfigSpecific { get { return configspecific; } }
|
||||
|
@ -81,11 +81,11 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
// Make switch action info
|
||||
if((attr.SwitchAction != null) && (attr.SwitchAction.Length > 0))
|
||||
{
|
||||
switchactionattr = new ActionAttribute(attr.SwitchAction);
|
||||
switchactionattr = new BeginActionAttribute(attr.SwitchAction);
|
||||
switchactiondel = new ActionDelegate(SwitchToMode);
|
||||
|
||||
// Bind switch action
|
||||
ActionAttribute.BindDelegate(plugin.Assembly, switchactiondel, switchactionattr);
|
||||
General.Actions.BindBeginDelegate(plugin.Assembly, switchactiondel, switchactionattr);
|
||||
}
|
||||
|
||||
// Make button info
|
||||
|
@ -108,7 +108,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
public void Dispose()
|
||||
{
|
||||
// Unbind switch action
|
||||
if(switchactiondel != null) ActionAttribute.UnbindDelegate(plugin.Assembly, switchactiondel, switchactionattr);
|
||||
if(switchactiondel != null) General.Actions.UnbindBeginDelegate(plugin.Assembly, switchactiondel, switchactionattr);
|
||||
buttonimage.Dispose();
|
||||
buttonimagestream.Dispose();
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
redos = new List<UndoSnapshot>(General.Settings.UndoLevels + 1);
|
||||
|
||||
// Bind any methods
|
||||
ActionAttribute.BindMethods(this);
|
||||
General.Actions.BindMethods(this);
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
|
@ -91,7 +91,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
if(!isdisposed)
|
||||
{
|
||||
// Unbind any methods
|
||||
ActionAttribute.UnbindMethods(this);
|
||||
General.Actions.UnbindMethods(this);
|
||||
|
||||
// Clean up
|
||||
ClearUndos();
|
||||
|
@ -199,7 +199,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
}
|
||||
|
||||
// This performs an undo
|
||||
[Action("undo")]
|
||||
[BeginAction("undo")]
|
||||
public void PerformUndo()
|
||||
{
|
||||
UndoSnapshot u, r;
|
||||
|
@ -235,7 +235,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
}
|
||||
|
||||
// This performs a redo
|
||||
[Action("redo")]
|
||||
[BeginAction("redo")]
|
||||
public void PerformRedo()
|
||||
{
|
||||
UndoSnapshot u, r;
|
||||
|
|
|
@ -184,6 +184,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
|
||||
base.KeyDown(e);
|
||||
|
||||
/* WRONG
|
||||
// Get the actions for this key
|
||||
actions = General.Actions.GetActionsByKey((int)e.KeyData);
|
||||
foreach(string a in actions)
|
||||
|
@ -197,6 +198,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
case "moveright": keyright = true; break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Key up
|
||||
|
@ -206,6 +208,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
|
||||
base.KeyUp(e);
|
||||
|
||||
/* WRONG
|
||||
// Get the actions for this key
|
||||
actions = General.Actions.GetActionsByKey((int)e.KeyData);
|
||||
foreach(string a in actions)
|
||||
|
@ -219,6 +222,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
case "moveright": keyright = false; break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -436,7 +436,7 @@ namespace CodeImp.DoomBuilder
|
|||
actions = new ActionManager();
|
||||
|
||||
// Bind static methods to actions
|
||||
ActionAttribute.BindMethods(typeof(General));
|
||||
General.Actions.BindMethods(typeof(General));
|
||||
|
||||
// Create main window
|
||||
General.WriteLogLine("Loading main interface window...");
|
||||
|
@ -504,7 +504,7 @@ namespace CodeImp.DoomBuilder
|
|||
General.WriteLogLine("Termination requested");
|
||||
|
||||
// Unbind static methods from actions
|
||||
ActionAttribute.UnbindMethods(typeof(General));
|
||||
General.Actions.UnbindMethods(typeof(General));
|
||||
|
||||
// Clean up
|
||||
if(map != null) map.Dispose();
|
||||
|
@ -545,7 +545,7 @@ namespace CodeImp.DoomBuilder
|
|||
#region ================== Management
|
||||
|
||||
// This creates a new map
|
||||
[Action("newmap")]
|
||||
[BeginAction("newmap")]
|
||||
internal static void NewMap()
|
||||
{
|
||||
MapOptions newoptions = new MapOptions();
|
||||
|
@ -594,7 +594,7 @@ namespace CodeImp.DoomBuilder
|
|||
}
|
||||
|
||||
// This closes the current map
|
||||
[Action("closemap")]
|
||||
[BeginAction("closemap")]
|
||||
internal static void CloseMap()
|
||||
{
|
||||
// Ask the user to save changes (if any)
|
||||
|
@ -622,7 +622,7 @@ namespace CodeImp.DoomBuilder
|
|||
}
|
||||
|
||||
// This loads a map from file
|
||||
[Action("openmap")]
|
||||
[BeginAction("openmap")]
|
||||
internal static void OpenMap()
|
||||
{
|
||||
OpenFileDialog openfile;
|
||||
|
@ -694,7 +694,7 @@ namespace CodeImp.DoomBuilder
|
|||
}
|
||||
|
||||
// This saves the current map
|
||||
[Action("savemap")]
|
||||
[BeginAction("savemap")]
|
||||
internal static void SaveMap()
|
||||
{
|
||||
// Check if a wad file is known
|
||||
|
@ -724,7 +724,7 @@ namespace CodeImp.DoomBuilder
|
|||
}
|
||||
|
||||
// This saves the current map as a different file
|
||||
[Action("savemapas")]
|
||||
[BeginAction("savemapas")]
|
||||
internal static void SaveMapAs()
|
||||
{
|
||||
SaveFileDialog savefile;
|
||||
|
@ -1011,7 +1011,7 @@ namespace CodeImp.DoomBuilder
|
|||
|
||||
#endregion
|
||||
|
||||
[Action("testaction")]
|
||||
[BeginAction("testaction")]
|
||||
internal static void TestAction()
|
||||
{
|
||||
TextureBrowserForm t = new TextureBrowserForm();
|
||||
|
|
|
@ -114,7 +114,7 @@ namespace CodeImp.DoomBuilder
|
|||
{
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
|
||||
// Basic objects
|
||||
grid = new GridSetup();
|
||||
undoredo = new UndoManager();
|
||||
|
@ -130,7 +130,7 @@ namespace CodeImp.DoomBuilder
|
|||
ChangeMode((EditMode)null);
|
||||
|
||||
// Unbind any methods
|
||||
ActionAttribute.UnbindMethods(this);
|
||||
General.Actions.UnbindMethods(this);
|
||||
|
||||
// Dispose
|
||||
if(undoredo != null) undoredo.Dispose();
|
||||
|
@ -222,7 +222,7 @@ namespace CodeImp.DoomBuilder
|
|||
data.Load(configinfo.Resources, options.Resources);
|
||||
|
||||
// Bind any methods
|
||||
ActionAttribute.BindMethods(this);
|
||||
General.Actions.BindMethods(this);
|
||||
|
||||
// Set default mode
|
||||
ChangeMode("VerticesMode");
|
||||
|
@ -309,7 +309,7 @@ namespace CodeImp.DoomBuilder
|
|||
data.Load(configinfo.Resources, options.Resources, maplocation);
|
||||
|
||||
// Bind any methods
|
||||
ActionAttribute.BindMethods(this);
|
||||
General.Actions.BindMethods(this);
|
||||
|
||||
// Set default mode
|
||||
ChangeMode("VerticesMode");
|
||||
|
@ -877,7 +877,7 @@ namespace CodeImp.DoomBuilder
|
|||
#region ================== Methods
|
||||
|
||||
// This clears the selection
|
||||
[Action("clearselection")]
|
||||
[BeginAction("clearselection")]
|
||||
public void ClearSelection()
|
||||
{
|
||||
// Clear selection
|
||||
|
@ -900,7 +900,7 @@ namespace CodeImp.DoomBuilder
|
|||
}
|
||||
|
||||
// This reloads resources
|
||||
[Action("reloadresources")]
|
||||
[BeginAction("reloadresources")]
|
||||
internal void ReloadResources()
|
||||
{
|
||||
DataLocation maplocation;
|
||||
|
@ -946,7 +946,7 @@ namespace CodeImp.DoomBuilder
|
|||
}
|
||||
|
||||
// Game Configuration action
|
||||
[Action("mapoptions")]
|
||||
[BeginAction("mapoptions")]
|
||||
internal void ShowMapOptions()
|
||||
{
|
||||
// Show map options dialog
|
||||
|
|
|
@ -65,5 +65,6 @@ namespace CodeImp.DoomBuilder.Interface
|
|||
void SetProcessorState(bool on);
|
||||
void StartExclusiveMouseInput();
|
||||
void StopExclusiveMouseInput();
|
||||
bool CheckActionActive(Assembly assembly, string actionname);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@ using CodeImp.DoomBuilder.Editing;
|
|||
using System.Collections;
|
||||
using System.IO;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using System.Reflection;
|
||||
using CodeImp.DoomBuilder.Plugins;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -102,7 +104,7 @@ namespace CodeImp.DoomBuilder.Interface
|
|||
buttongrid.DropDownDirection = ToolStripDropDownDirection.AboveLeft;
|
||||
|
||||
// Bind any methods
|
||||
ActionAttribute.BindMethods(this);
|
||||
General.Actions.BindMethods(this);
|
||||
|
||||
// Apply shortcut keys
|
||||
ApplyShortcutKeys();
|
||||
|
@ -154,7 +156,7 @@ namespace CodeImp.DoomBuilder.Interface
|
|||
|
||||
this.Update();
|
||||
asmname = General.ThisAssembly.GetName().Name.ToLowerInvariant();
|
||||
General.Actions[asmname + "_" + (sender as ToolStripItem).Tag.ToString()].Invoke();
|
||||
General.Actions[asmname + "_" + (sender as ToolStripItem).Tag.ToString()].Begin();
|
||||
this.Update();
|
||||
}
|
||||
|
||||
|
@ -227,7 +229,7 @@ namespace CodeImp.DoomBuilder.Interface
|
|||
SetProcessorState(false);
|
||||
|
||||
// Unbind methods
|
||||
ActionAttribute.UnbindMethods(this);
|
||||
General.Actions.UnbindMethods(this);
|
||||
|
||||
// Determine window state to save
|
||||
if(this.WindowState != FormWindowState.Minimized)
|
||||
|
@ -467,7 +469,7 @@ namespace CodeImp.DoomBuilder.Interface
|
|||
}
|
||||
|
||||
// This shows the grid setup dialog
|
||||
[Action("gridsetup")]
|
||||
[BeginAction("gridsetup")]
|
||||
internal void ShowGridSetup()
|
||||
{
|
||||
// Only when a map is open
|
||||
|
@ -573,7 +575,7 @@ namespace CodeImp.DoomBuilder.Interface
|
|||
|
||||
this.Update();
|
||||
modeinfo = (EditModeInfo)((sender as ToolStripItem).Tag);
|
||||
General.Actions[modeinfo.SwitchAction.GetFullActionName(modeinfo.Plugin.Assembly)].Invoke();
|
||||
General.Actions[modeinfo.SwitchAction.GetFullActionName(modeinfo.Plugin.Assembly)].Begin();
|
||||
this.Update();
|
||||
}
|
||||
|
||||
|
@ -671,7 +673,26 @@ namespace CodeImp.DoomBuilder.Interface
|
|||
private void display_MouseDoubleClick(object sender, MouseEventArgs e) { if((General.Map != null) && (General.Map.Mode != null)) General.Map.Mode.MouseDoubleClick(e); }
|
||||
|
||||
// Mouse down
|
||||
private void display_MouseDown(object sender, MouseEventArgs e) { if((General.Map != null) && (General.Map.Mode != null)) General.Map.Mode.MouseDown(e); }
|
||||
private void display_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
int key = 0;
|
||||
|
||||
// Create key
|
||||
switch(e.Button)
|
||||
{
|
||||
case MouseButtons.Left: key = (int)Keys.LButton; break;
|
||||
case MouseButtons.Middle: key = (int)Keys.MButton; break;
|
||||
case MouseButtons.Right: key = (int)Keys.RButton; break;
|
||||
case MouseButtons.XButton1: key = (int)Keys.XButton1; break;
|
||||
case MouseButtons.XButton2: key = (int)Keys.XButton2; break;
|
||||
}
|
||||
|
||||
// Invoke any actions associated with this key
|
||||
General.Actions.KeyPressed(key);
|
||||
|
||||
// Invoke on editing mode
|
||||
if((General.Map != null) && (General.Map.Mode != null)) General.Map.Mode.MouseDown(e);
|
||||
}
|
||||
|
||||
// Mouse enters
|
||||
private void display_MouseEnter(object sender, EventArgs e)
|
||||
|
@ -694,12 +715,40 @@ namespace CodeImp.DoomBuilder.Interface
|
|||
}
|
||||
|
||||
// Mouse up
|
||||
private void display_MouseUp(object sender, MouseEventArgs e) { if((General.Map != null) && (General.Map.Mode != null)) General.Map.Mode.MouseUp(e); }
|
||||
private void display_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
int key = 0;
|
||||
|
||||
// Create key
|
||||
switch(e.Button)
|
||||
{
|
||||
case MouseButtons.Left: key = (int)Keys.LButton; break;
|
||||
case MouseButtons.Middle: key = (int)Keys.MButton; break;
|
||||
case MouseButtons.Right: key = (int)Keys.RButton; break;
|
||||
case MouseButtons.XButton1: key = (int)Keys.XButton1; break;
|
||||
case MouseButtons.XButton2: key = (int)Keys.XButton2; break;
|
||||
}
|
||||
|
||||
// Invoke any actions associated with this key
|
||||
General.Actions.KeyReleased(key);
|
||||
|
||||
// Invoke on editing mode
|
||||
if((General.Map != null) && (General.Map.Mode != null)) General.Map.Mode.MouseUp(e);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Input
|
||||
|
||||
// This checks if a given action is active
|
||||
public bool CheckActionActive(Assembly assembly, string actionname)
|
||||
{
|
||||
if(assembly == null)
|
||||
return General.Actions.CheckActionActive(General.ThisAssembly, actionname);
|
||||
else
|
||||
return General.Actions.CheckActionActive(assembly, actionname);
|
||||
}
|
||||
|
||||
// This requests exclusive mouse input
|
||||
public void StartExclusiveMouseInput()
|
||||
{
|
||||
|
@ -739,26 +788,21 @@ namespace CodeImp.DoomBuilder.Interface
|
|||
// When the mouse wheel is changed
|
||||
protected override void OnMouseWheel(MouseEventArgs e)
|
||||
{
|
||||
int mod = 0;
|
||||
|
||||
// Create modifiers
|
||||
if(alt) mod |= (int)Keys.Alt;
|
||||
if(shift) mod |= (int)Keys.Shift;
|
||||
if(ctrl) mod |= (int)Keys.Control;
|
||||
|
||||
// Scrollwheel up?
|
||||
if(e.Delta > 0)
|
||||
{
|
||||
// Invoke actions for scrollwheel
|
||||
//for(int i = 0; i < e.Delta; i += 120)
|
||||
General.Actions.InvokeByKey(mod | (int)SpecialKeys.MScrollUp);
|
||||
General.Actions.KeyPressed((int)SpecialKeys.MScrollUp);
|
||||
General.Actions.KeyReleased((int)SpecialKeys.MScrollUp);
|
||||
}
|
||||
// Scrollwheel down?
|
||||
else if(e.Delta < 0)
|
||||
{
|
||||
// Invoke actions for scrollwheel
|
||||
//for(int i = 0; i > e.Delta; i -= 120)
|
||||
General.Actions.InvokeByKey(mod | (int)SpecialKeys.MScrollDown);
|
||||
General.Actions.KeyPressed((int)SpecialKeys.MScrollDown);
|
||||
General.Actions.KeyReleased((int)SpecialKeys.MScrollDown);
|
||||
}
|
||||
|
||||
// Let the base know
|
||||
|
@ -768,13 +812,19 @@ namespace CodeImp.DoomBuilder.Interface
|
|||
// When a key is pressed
|
||||
private void MainForm_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
int mod = 0;
|
||||
|
||||
// Keep key modifiers
|
||||
alt = e.Alt;
|
||||
shift = e.Shift;
|
||||
ctrl = e.Control;
|
||||
if(alt) mod |= (int)Keys.Alt;
|
||||
if(shift) mod |= (int)Keys.Shift;
|
||||
if(ctrl) mod |= (int)Keys.Control;
|
||||
|
||||
// Invoke any actions associated with this key
|
||||
General.Actions.InvokeByKey((int)e.KeyData);
|
||||
General.Actions.UpdateModifiers(mod);
|
||||
General.Actions.KeyPressed((int)e.KeyData);
|
||||
|
||||
// Invoke on editing mode
|
||||
if((General.Map != null) && (General.Map.Mode != null)) General.Map.Mode.KeyDown(e);
|
||||
|
@ -783,10 +833,19 @@ namespace CodeImp.DoomBuilder.Interface
|
|||
// When a key is released
|
||||
private void MainForm_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
int mod = 0;
|
||||
|
||||
// Keep key modifiers
|
||||
alt = e.Alt;
|
||||
shift = e.Shift;
|
||||
ctrl = e.Control;
|
||||
if(alt) mod |= (int)Keys.Alt;
|
||||
if(shift) mod |= (int)Keys.Shift;
|
||||
if(ctrl) mod |= (int)Keys.Control;
|
||||
|
||||
// Invoke any actions associated with this key
|
||||
General.Actions.UpdateModifiers(mod);
|
||||
General.Actions.KeyReleased((int)e.KeyData);
|
||||
|
||||
// Invoke on editing mode
|
||||
if((General.Map != null) && (General.Map.Mode != null)) General.Map.Mode.KeyUp(e);
|
||||
|
@ -1035,7 +1094,7 @@ namespace CodeImp.DoomBuilder.Interface
|
|||
}
|
||||
|
||||
// Action to toggle snap to grid
|
||||
[Action("togglesnap")]
|
||||
[BeginAction("togglesnap")]
|
||||
internal void ToggleSnapToGrid()
|
||||
{
|
||||
buttonsnaptogrid.Checked = !buttonsnaptogrid.Checked;
|
||||
|
@ -1043,7 +1102,7 @@ namespace CodeImp.DoomBuilder.Interface
|
|||
}
|
||||
|
||||
// Action to toggle auto merge
|
||||
[Action("toggleautomerge")]
|
||||
[BeginAction("toggleautomerge")]
|
||||
internal void ToggleAutoMerge()
|
||||
{
|
||||
buttonautomerge.Checked = !buttonautomerge.Checked;
|
||||
|
@ -1078,7 +1137,7 @@ namespace CodeImp.DoomBuilder.Interface
|
|||
}
|
||||
|
||||
// Game Configuration action
|
||||
[Action("configuration")]
|
||||
[BeginAction("configuration")]
|
||||
internal void ShowConfiguration()
|
||||
{
|
||||
// Show configuration dialog
|
||||
|
@ -1100,7 +1159,7 @@ namespace CodeImp.DoomBuilder.Interface
|
|||
}
|
||||
|
||||
// Preferences action
|
||||
[Action("preferences")]
|
||||
[BeginAction("preferences")]
|
||||
internal void ShowPreferences()
|
||||
{
|
||||
// Show preferences dialog
|
||||
|
|
|
@ -319,6 +319,14 @@ namespace CodeImp.DoomBuilder.Map
|
|||
}
|
||||
}
|
||||
|
||||
// This returns the closest coordinates ON the line
|
||||
public Vector2D NearestOnLine(Vector2D pos)
|
||||
{
|
||||
float u = Line2D.GetNearestOnLine(start.Position, end.Position, pos);
|
||||
if(u < 0f) u = 0f; else if(u > 1f) u = 1f;
|
||||
return Line2D.GetCoordinatesAt(start.Position, end.Position, u);
|
||||
}
|
||||
|
||||
// This returns the shortest distance from given coordinates to line
|
||||
public float SafeDistanceToSq(Vector2D p, bool bounded)
|
||||
{
|
||||
|
|
|
@ -23,6 +23,7 @@ using System.Globalization;
|
|||
using System.Text;
|
||||
using System.IO;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using System.Reflection;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -159,6 +160,19 @@ namespace CodeImp.DoomBuilder.Plugins
|
|||
}
|
||||
}
|
||||
|
||||
// This returns a plugin by assembly, or null when plugin cannot be found
|
||||
public Plugin FindPluginByAssembly(Assembly assembly)
|
||||
{
|
||||
// Go for all plugins the find the one with matching assembly
|
||||
foreach(Plugin p in plugins)
|
||||
{
|
||||
if(p.Assembly == assembly) return p;
|
||||
}
|
||||
|
||||
// Nothing found
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
float OffsetX { get; }
|
||||
float OffsetY { get; }
|
||||
float Scale { get; }
|
||||
|
||||
int VertexSize { get; }
|
||||
|
||||
// Color methods
|
||||
PixelColor DetermineLinedefColor(Linedef l);
|
||||
PixelColor DetermineThingColor(Thing t);
|
||||
|
@ -72,6 +73,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
void RenderThingSet(ICollection<Thing> things);
|
||||
void RenderRectangle(RectangleF rect, float bordersize, PixelColor c, bool transformrect);
|
||||
void RenderRectangleFilled(RectangleF rect, PixelColor c, bool transformrect);
|
||||
void RenderLine(Vector2D start, Vector2D end, float thickness, PixelColor c, bool transformcoords);
|
||||
void RenderText(string text, Vector2D pos, PixelColor c, bool transformpos);
|
||||
void RenderTextCentered(string text, Vector2D pos, PixelColor c, bool transformpos);
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
private const byte DOUBLESIDED_LINE_ALPHA = 130;
|
||||
private const float FSAA_PLOTTER_BLEND_FACTOR = 0.6f;
|
||||
private const float FSAA_OVERLAY_BLEND_FACTOR = 0.2f;
|
||||
private const float FSAA_OVERLAY_BLEND_FACTOR = 0.6f;
|
||||
private const float THING_ARROW_SIZE = 1.5f;
|
||||
private const float THING_ARROW_SHRINK = 2f;
|
||||
private const float THING_CIRCLE_SIZE = 1f;
|
||||
|
@ -137,6 +137,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
public float OffsetX { get { return offsetx; } }
|
||||
public float OffsetY { get { return offsety; } }
|
||||
public float Scale { get { return scale; } }
|
||||
public int VertexSize { get { return vertexsize; } }
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -1181,6 +1182,59 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.Shaders.Color2D.End();
|
||||
}
|
||||
|
||||
// This renders a line with given color
|
||||
public void RenderLine(Vector2D start, Vector2D end, float thickness, PixelColor c, bool transformcoords)
|
||||
{
|
||||
FlatVertex[] verts = new FlatVertex[4];
|
||||
|
||||
// Calculate positions
|
||||
if(transformcoords)
|
||||
{
|
||||
start = start.GetTransformed(translatex, translatey, scale, -scale);
|
||||
end = end.GetTransformed(translatex, translatey, scale, -scale);
|
||||
}
|
||||
|
||||
// Calculate offsets
|
||||
Vector2D delta = end - start;
|
||||
Vector2D dn = delta.GetNormal() * thickness;
|
||||
|
||||
// Make vertices
|
||||
verts[0].x = start.x - dn.x + dn.y;
|
||||
verts[0].y = start.y - dn.y - dn.x;
|
||||
verts[0].z = 0.0f;
|
||||
verts[0].w = 1.0f;
|
||||
verts[0].c = c.ToInt();
|
||||
verts[1].x = start.x - dn.x - dn.y;
|
||||
verts[1].y = start.y - dn.y + dn.x;
|
||||
verts[1].z = 0.0f;
|
||||
verts[1].w = 1.0f;
|
||||
verts[1].c = c.ToInt();
|
||||
verts[2].x = end.x + dn.x + dn.y;
|
||||
verts[2].y = end.y + dn.y - dn.x;
|
||||
verts[2].z = 0.0f;
|
||||
verts[2].w = 1.0f;
|
||||
verts[2].c = c.ToInt();
|
||||
verts[3].x = end.x + dn.x - dn.y;
|
||||
verts[3].y = end.y + dn.y + dn.x;
|
||||
verts[3].z = 0.0f;
|
||||
verts[3].w = 1.0f;
|
||||
verts[3].c = c.ToInt();
|
||||
|
||||
// Set renderstates for rendering
|
||||
graphics.Device.SetRenderState(RenderState.CullMode, Cull.None);
|
||||
graphics.Device.SetRenderState(RenderState.ZEnable, false);
|
||||
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, false);
|
||||
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, false);
|
||||
graphics.Device.SetRenderState(RenderState.TextureFactor, -1);
|
||||
|
||||
// Draw
|
||||
graphics.Shaders.Color2D.Begin();
|
||||
graphics.Shaders.Color2D.BeginPass(0);
|
||||
graphics.Device.DrawUserPrimitives<FlatVertex>(PrimitiveType.TriangleStrip, 0, 2, verts);
|
||||
graphics.Shaders.Color2D.EndPass();
|
||||
graphics.Shaders.Color2D.End();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Geometry
|
||||
|
|
|
@ -113,6 +113,24 @@ cancelmode
|
|||
allowscroll = true;
|
||||
}
|
||||
|
||||
classicselect
|
||||
{
|
||||
title = "2D: Select";
|
||||
description = "Selects the highlighted item. Also allows selection by drawing a rectangle.";
|
||||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = false;
|
||||
}
|
||||
|
||||
classicedit
|
||||
{
|
||||
title = "2D: Edit";
|
||||
description = "Edits the properties of the selected items or drags the selected items. Also initiates drawing or inserts new things when no selection is made.";
|
||||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = false;
|
||||
}
|
||||
|
||||
scrollwest
|
||||
{
|
||||
title = "2D: Scroll West";
|
||||
|
@ -120,6 +138,7 @@ scrollwest
|
|||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = true;
|
||||
repeat = true;
|
||||
}
|
||||
|
||||
scrolleast
|
||||
|
@ -129,6 +148,7 @@ scrolleast
|
|||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = true;
|
||||
repeat = true;
|
||||
}
|
||||
|
||||
scrollnorth
|
||||
|
@ -138,6 +158,7 @@ scrollnorth
|
|||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = true;
|
||||
repeat = true;
|
||||
}
|
||||
|
||||
scrollsouth
|
||||
|
@ -147,6 +168,7 @@ scrollsouth
|
|||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = true;
|
||||
repeat = true;
|
||||
}
|
||||
|
||||
zoomin
|
||||
|
@ -156,6 +178,7 @@ zoomin
|
|||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = true;
|
||||
repeat = true;
|
||||
}
|
||||
|
||||
zoomout
|
||||
|
@ -165,6 +188,7 @@ zoomout
|
|||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = true;
|
||||
repeat = true;
|
||||
}
|
||||
|
||||
centerinscreen
|
||||
|
|
Loading…
Reference in a new issue