mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-23 20:32:34 +00:00
3d2d9e21ef
Updated model pitch handling to match current GZDoom implementation. Fixed imprecise vertex coordinates generated by Draw Ellipse mode. Fixed a resource loading exception when opened map file wad was located in the root of a Directory resource. Internal: changed output of all InterpolationTools methods from int to float. Fixed, Internal: InterpolationTools.InterpolateColor() delta usage was inverted.
598 lines
18 KiB
C#
598 lines
18 KiB
C#
#region ================== Namespaces
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
using CodeImp.DoomBuilder.Actions;
|
|
using CodeImp.DoomBuilder.Controls;
|
|
using CodeImp.DoomBuilder.Editing;
|
|
using CodeImp.DoomBuilder.Geometry;
|
|
using CodeImp.DoomBuilder.Map;
|
|
using CodeImp.DoomBuilder.Rendering;
|
|
using CodeImp.DoomBuilder.Windows;
|
|
|
|
#endregion
|
|
|
|
namespace CodeImp.DoomBuilder.BuilderModes
|
|
{
|
|
[EditMode(DisplayName = "Draw Grid Mode",
|
|
SwitchAction = "drawgridmode",
|
|
ButtonImage = "DrawGridMode.png", //mxd
|
|
ButtonOrder = int.MinValue + 5, //mxd
|
|
ButtonGroup = "000_drawing", //mxd
|
|
AllowCopyPaste = false,
|
|
Volatile = true,
|
|
Optional = false)]
|
|
|
|
public class DrawGridMode : DrawGeometryMode
|
|
{
|
|
#region ================== Enums
|
|
|
|
public enum GridLockMode
|
|
{
|
|
NONE,
|
|
HORIZONTAL,
|
|
VERTICAL,
|
|
BOTH,
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Variables
|
|
|
|
// Settings
|
|
private int horizontalslices;
|
|
private int verticalslices;
|
|
private bool triangulate;
|
|
private GridLockMode gridlockmode;
|
|
private InterpolationTools.Mode horizontalinterpolation;
|
|
private InterpolationTools.Mode verticalinterpolation;
|
|
|
|
// Drawing
|
|
private readonly List<DrawnVertex[]> gridpoints;
|
|
private HintLabel hintlabel;
|
|
|
|
private int width;
|
|
private int height;
|
|
private int slicesH;
|
|
private int slicesV;
|
|
private Vector2D start;
|
|
private Vector2D end;
|
|
|
|
// Interface
|
|
private DrawGridOptionsPanel panel;
|
|
private Docker docker;
|
|
|
|
#endregion
|
|
|
|
#region ================== Constructor
|
|
|
|
public DrawGridMode()
|
|
{
|
|
snaptogrid = true;
|
|
usefourcardinaldirections = true;
|
|
autoclosedrawing = false;
|
|
gridpoints = new List<DrawnVertex[]>();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Events
|
|
|
|
override public void OnAccept()
|
|
{
|
|
Cursor.Current = Cursors.AppStarting;
|
|
General.Settings.FindDefaultDrawSettings();
|
|
|
|
// When we have a shape...
|
|
if(gridpoints.Count > 0)
|
|
{
|
|
// Make undo for the draw
|
|
General.Map.UndoRedo.CreateUndo("Grid draw");
|
|
|
|
// Make an analysis and show info
|
|
string[] adjectives = { "gloomy", "sad", "unhappy", "lonely", "troubled", "depressed", "heartsick", "glum", "pessimistic", "bitter", "downcast" }; // aaand my english vocabulary ends here :)
|
|
string word = adjectives[new Random().Next(adjectives.Length - 1)];
|
|
string a = (word[0] == 'u' ? "an " : "a ");
|
|
|
|
General.Interface.DisplayStatus(StatusType.Action, "Created " + a + word + " grid.");
|
|
|
|
List<Sector> newsectors = new List<Sector>();
|
|
foreach(DrawnVertex[] shape in gridpoints)
|
|
{
|
|
if(Tools.DrawLines(shape, true, BuilderPlug.Me.AutoAlignTextureOffsetsOnCreate))
|
|
{
|
|
// Update cached values after each step...
|
|
General.Map.Map.Update();
|
|
|
|
newsectors.AddRange(General.Map.Map.GetMarkedSectors(true));
|
|
|
|
// Snap to map format accuracy
|
|
General.Map.Map.SnapAllToAccuracy();
|
|
|
|
// Clear selection
|
|
General.Map.Map.ClearAllSelected();
|
|
|
|
//mxd. Outer sectors may require some splittin...
|
|
Tools.SplitOuterSectors(General.Map.Map.GetMarkedLinedefs(true));
|
|
|
|
// Edit new sectors?
|
|
if(BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))
|
|
General.Interface.ShowEditSectors(newsectors);
|
|
|
|
// Update the used textures
|
|
General.Map.Data.UpdateUsedTextures();
|
|
|
|
//mxd
|
|
General.Map.Renderer2D.UpdateExtraFloorFlag();
|
|
|
|
// Map is changed
|
|
General.Map.IsChanged = true;
|
|
}
|
|
else
|
|
{
|
|
// Drawing failed
|
|
// NOTE: I have to call this twice, because the first time only cancels this volatile mode
|
|
General.Map.UndoRedo.WithdrawUndo();
|
|
General.Map.UndoRedo.WithdrawUndo();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Done
|
|
Cursor.Current = Cursors.Default;
|
|
|
|
if(continuousdrawing)
|
|
{
|
|
// Reset settings
|
|
points.Clear();
|
|
labels.Clear();
|
|
drawingautoclosed = false;
|
|
|
|
// Redraw display
|
|
General.Interface.RedrawDisplay();
|
|
}
|
|
else
|
|
{
|
|
// Return to original mode
|
|
General.Editing.ChangeMode(General.Editing.PreviousStableMode.Name);
|
|
}
|
|
}
|
|
|
|
public override void OnDisengage()
|
|
{
|
|
if(hintlabel != null) hintlabel.Dispose();
|
|
base.OnDisengage();
|
|
}
|
|
|
|
private void OptionsPanelOnValueChanged(object sender, EventArgs eventArgs)
|
|
{
|
|
triangulate = panel.Triangulate;
|
|
horizontalslices = panel.HorizontalSlices + 1;
|
|
verticalslices = panel.VerticalSlices + 1;
|
|
horizontalinterpolation = panel.HorizontalInterpolationMode;
|
|
verticalinterpolation = panel.VerticalInterpolationMode;
|
|
Update();
|
|
}
|
|
|
|
private void OptionsPanelOnGridLockChanged(object sender, EventArgs eventArgs)
|
|
{
|
|
gridlockmode = panel.GridLockMode;
|
|
General.Hints.ShowHints(this.GetType(), ((gridlockmode != GridLockMode.NONE) ? "gridlockhelp" : "general"));
|
|
Update();
|
|
}
|
|
|
|
public override void OnHelp()
|
|
{
|
|
General.ShowHelp("/gzdb/features/classic_modes/mode_drawgrid.html");
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Methods
|
|
|
|
override protected void Update()
|
|
{
|
|
PixelColor stitchcolor = General.Colors.Highlight;
|
|
PixelColor losecolor = General.Colors.Selection;
|
|
|
|
// We WANT snaptogrid and DON'T WANT snaptonearest when lock to grid is enabled
|
|
snaptocardinaldirection = General.Interface.ShiftState && General.Interface.AltState; //mxd
|
|
snaptogrid = (snaptocardinaldirection || gridlockmode != GridLockMode.NONE || (General.Interface.ShiftState ^ General.Interface.SnapToGrid));
|
|
snaptonearest = (gridlockmode == GridLockMode.NONE && (General.Interface.CtrlState ^ General.Interface.AutoMerge));
|
|
|
|
DrawnVertex curp;
|
|
if(points.Count == 1)
|
|
{
|
|
// Handle the case when start point is not on current grid.
|
|
Vector2D gridoffset = General.Map.Grid.SnappedToGrid(points[0].pos) - points[0].pos;
|
|
curp = GetCurrentPosition(mousemappos + gridoffset, snaptonearest, snaptogrid, snaptocardinaldirection, usefourcardinaldirections, renderer, points);
|
|
curp.pos -= gridoffset;
|
|
}
|
|
else
|
|
{
|
|
curp = GetCurrentPosition();
|
|
}
|
|
|
|
float vsize = (renderer.VertexSize + 1.0f) / renderer.Scale;
|
|
|
|
// Render drawing lines
|
|
if(renderer.StartOverlay(true))
|
|
{
|
|
PixelColor color = snaptonearest ? stitchcolor : losecolor;
|
|
|
|
if(points.Count == 1)
|
|
{
|
|
UpdateReferencePoints(points[0], curp);
|
|
List<Vector2D[]> shapes = GetShapes(start, end);
|
|
|
|
//render shape
|
|
foreach(Vector2D[] shape in shapes)
|
|
{
|
|
for(int i = 1; i < shape.Length; i++)
|
|
renderer.RenderLine(shape[i - 1], shape[i], LINE_THICKNESS, color, true);
|
|
}
|
|
|
|
//vertices
|
|
foreach(Vector2D[] shape in shapes)
|
|
{
|
|
for(int i = 0; i < shape.Length; i++)
|
|
renderer.RenderRectangleFilled(new RectangleF(shape[i].x - vsize, shape[i].y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);
|
|
}
|
|
|
|
//and labels
|
|
Vector2D[] labelCoords = new[] { start, new Vector2D(end.x, start.y), end, new Vector2D(start.x, end.y), start };
|
|
for(int i = 1; i < 5; i++)
|
|
{
|
|
labels[i - 1].Move(labelCoords[i], labelCoords[i - 1]);
|
|
renderer.RenderText(labels[i - 1].TextLabel);
|
|
}
|
|
|
|
//render hint
|
|
if(horizontalslices > 1 || verticalslices > 1)
|
|
{
|
|
string text = "H: " + (slicesH - 1) + "; V: " + (slicesV - 1);
|
|
if(width > text.Length * vsize && height > 16 * vsize)
|
|
{
|
|
hintlabel.Text = text;
|
|
hintlabel.Move(start, end);
|
|
renderer.RenderText(hintlabel.TextLabel);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Render vertex at cursor
|
|
renderer.RenderRectangleFilled(new RectangleF(curp.pos.x - vsize, curp.pos.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);
|
|
}
|
|
|
|
// Done
|
|
renderer.Finish();
|
|
}
|
|
|
|
// Done
|
|
renderer.Present();
|
|
}
|
|
|
|
// This draws a point at a specific location
|
|
override public bool DrawPointAt(Vector2D pos, bool stitch, bool stitchline)
|
|
{
|
|
if(pos.x < General.Map.Config.LeftBoundary || pos.x > General.Map.Config.RightBoundary ||
|
|
pos.y > General.Map.Config.TopBoundary || pos.y < General.Map.Config.BottomBoundary)
|
|
return false;
|
|
|
|
DrawnVertex newpoint = new DrawnVertex { pos = pos, stitch = true, stitchline = stitchline };
|
|
points.Add(newpoint);
|
|
|
|
if(points.Count == 1)
|
|
{
|
|
// Add labels
|
|
labels.AddRange(new[] { new LineLengthLabel(false, true), new LineLengthLabel(false, true), new LineLengthLabel(false, true), new LineLengthLabel(false, true) });
|
|
hintlabel = new HintLabel(General.Colors.InfoLine);
|
|
Update();
|
|
}
|
|
else if(points[0].pos == points[1].pos)
|
|
{
|
|
// Nothing is drawn
|
|
FinishDraw();
|
|
}
|
|
else
|
|
{
|
|
// Handle the case when start point is not on current grid.
|
|
Vector2D gridoffset = General.Map.Grid.SnappedToGrid(points[0].pos) - points[0].pos;
|
|
newpoint = GetCurrentPosition(mousemappos + gridoffset, snaptonearest, snaptogrid, snaptocardinaldirection, usefourcardinaldirections, renderer, new List<DrawnVertex> { points[0] });
|
|
newpoint.pos -= gridoffset;
|
|
|
|
// Create vertices for final shape.
|
|
UpdateReferencePoints(points[0], newpoint);
|
|
List<Vector2D[]> shapes = GetShapes(start, end);
|
|
|
|
foreach(Vector2D[] shape in shapes)
|
|
{
|
|
DrawnVertex[] verts = new DrawnVertex[shape.Length];
|
|
for(int i = 0; i < shape.Length; i++)
|
|
{
|
|
newpoint = new DrawnVertex { pos = shape[i], stitch = true, stitchline = stitchline };
|
|
verts[i] = newpoint;
|
|
}
|
|
|
|
gridpoints.Add(verts);
|
|
}
|
|
|
|
FinishDraw();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private List<Vector2D[]> GetShapes(Vector2D s, Vector2D e)
|
|
{
|
|
// No shape
|
|
if(s == e) return new List<Vector2D[]>();
|
|
|
|
// Setup slices
|
|
switch(gridlockmode)
|
|
{
|
|
case GridLockMode.NONE:
|
|
slicesH = horizontalslices;
|
|
slicesV = verticalslices;
|
|
break;
|
|
|
|
case GridLockMode.HORIZONTAL:
|
|
slicesH = width / General.Map.Grid.GridSize;
|
|
slicesV = verticalslices;
|
|
break;
|
|
|
|
case GridLockMode.VERTICAL:
|
|
slicesH = horizontalslices;
|
|
slicesV = height / General.Map.Grid.GridSize;
|
|
break;
|
|
|
|
case GridLockMode.BOTH:
|
|
slicesH = width / General.Map.Grid.GridSize;
|
|
slicesV = height / General.Map.Grid.GridSize;
|
|
break;
|
|
}
|
|
|
|
// Create a segmented line
|
|
List<Vector2D[]> shapes;
|
|
if(width == 0 || height == 0)
|
|
{
|
|
if(slicesH > 0 && width > 0)
|
|
{
|
|
shapes = new List<Vector2D[]>();
|
|
int step = width / slicesH;
|
|
for(int w = 0; w < slicesH; w++)
|
|
{
|
|
shapes.Add(new[] { new Vector2D((int)s.x + step * w, (int)s.y), new Vector2D((int)s.x + step * w + step, (int)s.y) });
|
|
}
|
|
return shapes;
|
|
}
|
|
|
|
if(slicesV > 0 && height > 0)
|
|
{
|
|
shapes = new List<Vector2D[]>();
|
|
int step = height / slicesV;
|
|
for(int h = 0; h < slicesV; h++)
|
|
{
|
|
shapes.Add(new[] {new Vector2D((int) s.x, (int) s.y + step * h), new Vector2D((int) s.x, (int) s.y + step * h + step)});
|
|
}
|
|
return shapes;
|
|
}
|
|
|
|
// Create a line
|
|
return new List<Vector2D[]> {new[] {s, e}};
|
|
}
|
|
|
|
// Create shape
|
|
List<Vector2D> rect = new List<Vector2D> { s, new Vector2D((int)s.x, (int)e.y), e, new Vector2D((int)e.x, (int)s.y), s };
|
|
if(slicesH == 1 && slicesV == 1)
|
|
{
|
|
if(triangulate) rect.AddRange(new[] { s, e });
|
|
return new List<Vector2D[]> { rect.ToArray() };
|
|
}
|
|
|
|
// Create blocks
|
|
shapes = new List<Vector2D[]> { rect.ToArray() };
|
|
RectangleF[,] blocks = new RectangleF[slicesH, slicesV];
|
|
for(int w = 0; w < slicesH; w++)
|
|
{
|
|
for(int h = 0; h < slicesV; h++)
|
|
{
|
|
float left = (float)Math.Round(InterpolationTools.Interpolate(s.x, e.x, (float)w / slicesH, horizontalinterpolation));
|
|
float top = (float)Math.Round(InterpolationTools.Interpolate(s.y, e.y, (float)h / slicesV, verticalinterpolation));
|
|
float right = (float)Math.Round(InterpolationTools.Interpolate(s.x, e.x, (w + 1.0f) / slicesH, horizontalinterpolation));
|
|
float bottom = (float)Math.Round(InterpolationTools.Interpolate(s.y, e.y, (h + 1.0f)/ slicesV, verticalinterpolation));
|
|
blocks[w, h] = RectangleF.FromLTRB(left, top, right, bottom);
|
|
}
|
|
}
|
|
|
|
// Add subdivisions
|
|
if(slicesH > 1)
|
|
{
|
|
for(int w = 1; w < slicesH; w++)
|
|
{
|
|
int px = (int) Math.Round(blocks[w, 0].X);
|
|
shapes.Add(new[] {new Vector2D(px, s.y), new Vector2D(px, e.y)});
|
|
}
|
|
}
|
|
if(slicesV > 1)
|
|
{
|
|
for(int h = 1; h < slicesV; h++)
|
|
{
|
|
int py = (int) Math.Round(blocks[0, h].Y);
|
|
shapes.Add(new[] { new Vector2D(s.x, py), new Vector2D(e.x, py) });
|
|
}
|
|
}
|
|
|
|
// Triangulate?
|
|
if(triangulate)
|
|
{
|
|
bool startflip = ((int)Math.Round(((s.x + e.y) / General.Map.Grid.GridSize) % 2) == 0);
|
|
bool flip = startflip;
|
|
|
|
for(int w = 0; w < slicesH; w++)
|
|
{
|
|
for(int h = slicesV - 1; h > -1; h--)
|
|
{
|
|
if(flip)
|
|
shapes.Add(new[] { new Vector2D(blocks[w, h].X, blocks[w, h].Y), new Vector2D(blocks[w, h].Right, blocks[w, h].Bottom) });
|
|
else
|
|
shapes.Add(new[] { new Vector2D(blocks[w, h].Right, blocks[w, h].Y), new Vector2D(blocks[w, h].X, blocks[w, h].Bottom) });
|
|
|
|
flip = !flip;
|
|
}
|
|
|
|
startflip = !startflip;
|
|
flip = startflip;
|
|
}
|
|
}
|
|
|
|
return shapes;
|
|
}
|
|
|
|
// Update bottom-left and top-right points, which define drawing shape
|
|
private void UpdateReferencePoints(DrawnVertex p1, DrawnVertex p2)
|
|
{
|
|
if(!p1.pos.IsFinite() || !p2.pos.IsFinite()) return;
|
|
|
|
if(p1.pos.x < p2.pos.x)
|
|
{
|
|
start.x = p1.pos.x;
|
|
end.x = p2.pos.x;
|
|
}
|
|
else
|
|
{
|
|
start.x = p2.pos.x;
|
|
end.x = p1.pos.x;
|
|
}
|
|
|
|
if(p1.pos.y < p2.pos.y)
|
|
{
|
|
start.y = p1.pos.y;
|
|
end.y = p2.pos.y;
|
|
}
|
|
else
|
|
{
|
|
start.y = p2.pos.y;
|
|
end.y = p1.pos.y;
|
|
}
|
|
|
|
width = (int)(end.x - start.x);
|
|
height = (int)(end.y - start.y);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Settings panel
|
|
|
|
protected override void SetupInterface()
|
|
{
|
|
// Load stored settings
|
|
triangulate = General.Settings.ReadPluginSetting("drawgridmode.triangulate", false);
|
|
gridlockmode = (GridLockMode)General.Settings.ReadPluginSetting("drawgridmode.gridlockmode", 0);
|
|
horizontalslices = Math.Max(General.Settings.ReadPluginSetting("drawgridmode.horizontalslices", 3), 3);
|
|
verticalslices = Math.Max(General.Settings.ReadPluginSetting("drawgridmode.verticalslices", 3), 3);
|
|
horizontalinterpolation = (InterpolationTools.Mode)General.Settings.ReadPluginSetting("drawgridmode.horizontalinterpolation", 0);
|
|
verticalinterpolation = (InterpolationTools.Mode)General.Settings.ReadPluginSetting("drawgridmode.verticalinterpolation", 0);
|
|
|
|
// Create and setup settings panel
|
|
panel = new DrawGridOptionsPanel();
|
|
panel.MaxHorizontalSlices = (int)General.Map.FormatInterface.MaxCoordinate;
|
|
panel.MaxVerticalSlices = (int)General.Map.FormatInterface.MaxCoordinate;
|
|
panel.Triangulate = triangulate;
|
|
panel.GridLockMode = gridlockmode;
|
|
panel.HorizontalSlices = horizontalslices - 1;
|
|
panel.VerticalSlices = verticalslices - 1;
|
|
panel.HorizontalInterpolationMode = horizontalinterpolation;
|
|
panel.VerticalInterpolationMode = verticalinterpolation;
|
|
|
|
panel.OnValueChanged += OptionsPanelOnValueChanged;
|
|
panel.OnGridLockModeChanged += OptionsPanelOnGridLockChanged;
|
|
panel.OnContinuousDrawingChanged += OnContinuousDrawingChanged;
|
|
|
|
// Needs to be set after adding the OnContinuousDrawingChanged event...
|
|
panel.ContinuousDrawing = General.Settings.ReadPluginSetting("drawgridmode.continuousdrawing", false);
|
|
}
|
|
|
|
protected override void AddInterface()
|
|
{
|
|
// Add docker
|
|
docker = new Docker("drawgrid", "Draw Grid", panel);
|
|
General.Interface.AddDocker(docker, true);
|
|
General.Interface.SelectDocker(docker);
|
|
}
|
|
|
|
protected override void RemoveInterface()
|
|
{
|
|
// Store settings
|
|
General.Settings.WritePluginSetting("drawgridmode.triangulate", triangulate);
|
|
General.Settings.WritePluginSetting("drawgridmode.gridlockmode", (int)gridlockmode);
|
|
General.Settings.WritePluginSetting("drawgridmode.horizontalslices", horizontalslices);
|
|
General.Settings.WritePluginSetting("drawgridmode.verticalslices", verticalslices);
|
|
General.Settings.WritePluginSetting("drawgridmode.horizontalinterpolation", (int)horizontalinterpolation);
|
|
General.Settings.WritePluginSetting("drawgridmode.verticalinterpolation", (int)verticalinterpolation);
|
|
General.Settings.WritePluginSetting("drawgridmode.continuousdrawing", panel.ContinuousDrawing);
|
|
|
|
// Remove docker
|
|
General.Interface.RemoveDocker(docker);
|
|
panel.Dispose();
|
|
panel = null;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Actions
|
|
|
|
[BeginAction("increasebevel")]
|
|
protected void IncreaseBevel()
|
|
{
|
|
if((gridlockmode == GridLockMode.NONE || gridlockmode == GridLockMode.VERTICAL)
|
|
&& (points.Count < 2 || horizontalslices < width - 2)
|
|
&& horizontalslices - 1 < panel.MaxHorizontalSlices)
|
|
{
|
|
horizontalslices++;
|
|
panel.HorizontalSlices = horizontalslices - 1;
|
|
Update();
|
|
}
|
|
}
|
|
|
|
[BeginAction("decreasebevel")]
|
|
protected void DecreaseBevel()
|
|
{
|
|
if((gridlockmode == GridLockMode.NONE || gridlockmode == GridLockMode.VERTICAL) && horizontalslices > 1)
|
|
{
|
|
horizontalslices--;
|
|
panel.HorizontalSlices = horizontalslices - 1;
|
|
Update();
|
|
}
|
|
}
|
|
|
|
[BeginAction("increasesubdivlevel")]
|
|
protected void IncreaseSubdivLevel()
|
|
{
|
|
if((gridlockmode == GridLockMode.NONE || gridlockmode == GridLockMode.HORIZONTAL)
|
|
&& (points.Count < 2 || verticalslices < height - 2)
|
|
&& verticalslices - 1 < panel.MaxVerticalSlices)
|
|
{
|
|
verticalslices++;
|
|
panel.VerticalSlices = verticalslices - 1;
|
|
Update();
|
|
}
|
|
}
|
|
|
|
[BeginAction("decreasesubdivlevel")]
|
|
protected void DecreaseSubdivLevel()
|
|
{
|
|
if((gridlockmode == GridLockMode.NONE || gridlockmode == GridLockMode.HORIZONTAL) && verticalslices > 1)
|
|
{
|
|
verticalslices--;
|
|
panel.VerticalSlices = verticalslices - 1;
|
|
Update();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
}
|