UltimateZoneBuilder/Source/Core/Controls/NumericTextbox.cs
MaxED 7ab0a86a92 Added, Find & Replace mode, UDMF: added Linedef activation flags to the "Find Linedef flags" search mode flags list.
Changed, Sound Propagation mode: all sound zones are now shown when no sector is highlighted.
Changed, Sound Environments mode: the mode is now available only in UDMF map format.
Changed, Color Picker plugin: the plugin functionality is no longer available in Doom map format.
Restored the ability to create superimposed lines by dragging them with "Snap to Geometry" mode disabled.
Fixed, Sound Propagation mode: fixed a crash when a single-sided linedef had "Block Sound" flag.
Fixed, Find & Replace mode: in some cases "Find Sector/Sidedef/Linedef/Thing flags" search modes failed to find map elements with required flags.
Fixed, Edit Selection mode: in some cases incorrect geometry was created after applying multipart sector edit when "Replace with Dragged Geometry" mode was enabled.
Fixed a crash caused by eventual GDI font objects overflow.
2016-07-02 22:27:20 +00:00

406 lines
12 KiB
C#

#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.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.Windows.Forms;
#endregion
namespace CodeImp.DoomBuilder.Controls
{
public class NumericTextbox : AutoSelectTextbox
{
#region ================== Constants
#endregion
#region ================== Variables
private bool allownegative; // Allow negative numbers
private bool allowrelative; // Allow ++, --, * and / prefix for relative changes
private bool allowdecimal; // Allow decimal (float) numbers
private bool controlpressed;
private int incrementstep; //mxd. Step for +++ and --- prefixes
private ToolTip tooltip; //mxd
#endregion
#region ================== Properties
public bool AllowNegative { get { return allownegative; } set { allownegative = value; } }
public bool AllowRelative { get { return allowrelative; } set { allowrelative = value; UpdateTextboxStyle(); } }
public bool AllowDecimal { get { return allowdecimal; } set { allowdecimal = value; } }
#endregion
#region ================== Constructor / Disposer
// Constructor
public NumericTextbox()
{
this.ImeMode = ImeMode.Off;
//mxd. Setup tooltip
this.tooltip = new ToolTip { AutomaticDelay = 100, AutoPopDelay = 8000, InitialDelay = 100, ReshowDelay = 100 };
}
//mxd
protected override void Dispose(bool disposing)
{
if(disposing)
{
tooltip.Dispose();
tooltip = null;
}
base.Dispose(disposing);
}
#endregion
#region ================== Methods
// Key pressed
protected override void OnKeyDown(KeyEventArgs e)
{
controlpressed = e.Control;
base.OnKeyDown(e);
}
// Key released
protected override void OnKeyUp(KeyEventArgs e)
{
controlpressed = e.Control;
base.OnKeyUp(e);
}
// When a key is pressed
protected override void OnKeyPress(KeyPressEventArgs e)
{
incrementstep = 0; //mxd
string allowedchars = "0123456789\b";
// Determine allowed chars
if(allownegative) allowedchars += CultureInfo.CurrentCulture.NumberFormat.NegativeSign;
if(allowrelative) allowedchars += "+-*/"; //mxd
if(controlpressed) allowedchars += "\u0018\u0003\u0016";
if(allowdecimal || this.Text.StartsWith("*") || this.Text.StartsWith("/")) //mxd
allowedchars += CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
// Check if key is not allowed
if(allowedchars.IndexOf(e.KeyChar) == -1)
{
// Cancel this
e.Handled = true;
}
else
{
//mxd. Check if * or / is pressed
if(e.KeyChar == '*' || e.KeyChar == '/')
{
if(this.SelectionStart - 1 > -1) e.Handled = true; //only valid when at the start of the text
}
// Check if + or - is pressed
else if((e.KeyChar == '+') || (e.KeyChar == '-'))
{
string nonselectedtext;
// Determine non-selected text
if(this.SelectionLength > 0)
{
nonselectedtext = this.Text.Substring(0, this.SelectionStart) +
this.Text.Substring(this.SelectionStart + this.SelectionLength);
}
else if(this.SelectionLength < 0)
{
nonselectedtext = this.Text.Substring(0, this.SelectionStart + this.SelectionLength) +
this.Text.Substring(this.SelectionStart);
}
else
{
nonselectedtext = this.Text;
}
// Not at the start?
int selectionpos = this.SelectionStart - 1;
if(this.SelectionLength < 0) selectionpos = (this.SelectionStart + this.SelectionLength) - 1;
if(selectionpos > -1)
{
// Find any other characters before the insert position
string textpart = this.Text.Substring(0, selectionpos + 1);
textpart = textpart.Replace("+", "");
textpart = textpart.Replace("-", "");
if(textpart.Length > 0)
{
// Cancel this
e.Handled = true;
}
}
// Determine other prefix
char otherprefix = (e.KeyChar == '+' ? '-' : '+');
// Limit the number of + and - allowed
int numprefixes = nonselectedtext.Split(e.KeyChar, otherprefix).Length;
if(numprefixes > 3)
{
// Can't have more than 3 prefixes (mxd)
e.Handled = true;
}
else if(numprefixes > 1)
{
// Must have 2 or 3 same prefixes
if(this.Text.IndexOf(e.KeyChar) == -1) e.Handled = true;
// Double or triple prefix must be allowed
if(!allowrelative) e.Handled = true;
}
}
}
// Call base
base.OnKeyPress(e);
}
// Validate contents
protected override void OnValidating(CancelEventArgs e)
{
//mxd. We may want "++" and "--" on their own...
if(allowrelative && (this.Text == "++" || this.Text == "--"))
{
// Call base and bail out
base.OnValidating(e);
return;
}
// Strip prefixes
string textpart = this.Text.Replace("+", "").Replace("*", "").Replace("/", ""); //mxd
if(!allownegative) textpart = textpart.Replace("-", "");
// No numbers left?
if(textpart.Length == 0)
{
// Make the textbox empty
this.Text = "";
}
// Call base
base.OnValidating(e);
}
// This checks if the number is relative
public bool CheckIsRelative()
{
// Prefixed with +++, ---, ++, --, * or /?
return ( (this.Text.Length > 3 && (this.Text.StartsWith("+++") || this.Text.StartsWith("---"))) || //mxd
(this.Text.Length > 2 && (this.Text.StartsWith("++") || this.Text.StartsWith("--") || this.Text.StartsWith("**") || this.Text.StartsWith("//"))) || //mxd
(this.Text.Length > 1 && (this.Text.StartsWith("*") || this.Text.StartsWith("/"))) ); //mxd
}
//mxd. This determines the result value
public int GetResult(int original)
{
return GetResult(original, incrementstep++);
}
//mxd. This determines the result value
public int GetResult(int original, int step)
{
string textpart = this.Text;
// Strip prefixes
textpart = textpart.Replace("+", "").Replace("-", "").Replace("*", "").Replace("/", ""); //mxd
// Any numbers left?
if(textpart.Length > 0)
{
int result;
//mxd. Prefixed with +++?
if(this.Text.StartsWith("+++"))
{
// Add number to original
int.TryParse(textpart, out result);
return original + result * step;
}
//mxd. Prefixed with ---?
if(this.Text.StartsWith("---"))
{
// Subtract number from original
int.TryParse(textpart, out result);
int newvalue = original - result * step;
if(!allownegative && (newvalue < 0)) newvalue = 0;
return newvalue;
}
// Prefixed with ++?
if(this.Text.StartsWith("++"))
{
// Add number to original
int.TryParse(textpart, out result);
return original + result;
}
// Prefixed with --?
if(this.Text.StartsWith("--"))
{
// Subtract number from original
int.TryParse(textpart, out result);
int newvalue = original - result;
if(!allownegative && (newvalue < 0)) newvalue = 0;
return newvalue;
}
//mxd. Prefixed with *?
if(this.Text.StartsWith("*"))
{
// Multiply original by number
float resultf;
float.TryParse(textpart, NumberStyles.Float, CultureInfo.CurrentCulture, out resultf);
int newvalue = (int)Math.Round(original * resultf);
if(!allownegative && (newvalue < 0)) newvalue = 0;
return newvalue;
}
//mxd. Prefixed with /?
if(this.Text.StartsWith("/"))
{
// Divide original by number
float resultf;
float.TryParse(textpart, NumberStyles.Float, CultureInfo.CurrentCulture, out resultf);
if(resultf == 0) return original;
int newvalue = (int)Math.Round(original / resultf);
if(!allownegative && (newvalue < 0)) newvalue = 0;
return newvalue;
}
//mxd. Return the new value
if(!int.TryParse(this.Text, out result)) return original;
if(!allownegative && (result < 0)) return 0;
return result;
}
// Nothing given, keep original value
return original;
}
//mxd. This determines the result value
public float GetResultFloat(float original)
{
return GetResultFloat(original, incrementstep++);
}
// This determines the result value
public float GetResultFloat(float original, int step)
{
// Strip prefixes
string textpart = this.Text.Replace("+", "").Replace("-", "").Replace("*", "").Replace("/", ""); //mxd;
// Any numbers left?
if(textpart.Length > 0)
{
float result;
//mxd. Prefixed with +++?
if(this.Text.StartsWith("+++"))
{
// Add number to original
if(!float.TryParse(textpart, NumberStyles.Float, CultureInfo.CurrentCulture, out result)) result = 0;
return original + result * step;
}
//mxd. Prefixed with ---?
if(this.Text.StartsWith("---"))
{
// Subtract number from original
if(!float.TryParse(textpart, NumberStyles.Float, CultureInfo.CurrentCulture, out result)) result = 0;
float newvalue = original - result * step;
if(!allownegative && (newvalue < 0)) newvalue = 0;
return newvalue;
}
// Prefixed with ++?
if(this.Text.StartsWith("++"))
{
// Add number to original
if(!float.TryParse(textpart, NumberStyles.Float, CultureInfo.CurrentCulture, out result)) result = 0;
return original + result;
}
// Prefixed with --?
if(this.Text.StartsWith("--"))
{
// Subtract number from original
if(!float.TryParse(textpart, NumberStyles.Float, CultureInfo.CurrentCulture, out result)) result = 0;
float newvalue = original - result;
if(!allownegative && (newvalue < 0)) newvalue = 0;
return newvalue;
}
//mxd. Prefixed with *?
if(this.Text.StartsWith("*"))
{
// Multiply original by number
if(!float.TryParse(textpart, NumberStyles.Float, CultureInfo.CurrentCulture, out result)) result = 0;
float newvalue = original * result;
if(!allownegative && (newvalue < 0)) newvalue = 0;
return newvalue;
}
//mxd. Prefixed with /?
if(this.Text.StartsWith("/"))
{
// Divide original by number
if(!float.TryParse(textpart, NumberStyles.Float, CultureInfo.CurrentCulture, out result) || result == 0) return original;
float newvalue = (float)Math.Round(original / result, 3);
if(!allownegative && (newvalue < 0)) newvalue = 0;
return newvalue;
}
//mxd. Return the new value
if(!float.TryParse(this.Text, NumberStyles.Float, CultureInfo.CurrentCulture, out result)) return original;
if(!allownegative && (result < 0)) return 0;
return result;
}
// Nothing given, keep original value
return original;
}
//mxd
public void UpdateTextboxStyle()
{
UpdateTextboxStyle(string.Empty);
}
//mxd
public void UpdateTextboxStyle(string tip)
{
this.ForeColor = (allowrelative ? SystemColors.HotTrack : SystemColors.WindowText);
if(allowrelative)
{
tooltip.SetToolTip(this, "Use ++ or -- prefixes to change by given value." + Environment.NewLine +
"Use +++ or --- prefixes to incrementally change by given value." + Environment.NewLine +
"Use * or / prefixes to multiply or divide by given value." + Environment.NewLine + tip);
}
else if(!string.IsNullOrEmpty(tip))
{
tooltip.SetToolTip(this, tip);
}
else
{
tooltip.RemoveAll();
}
}
#endregion
}
}