BizHawk/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs

863 lines
27 KiB
C#
Raw Normal View History

2014-07-09 23:04:22 +00:00
using System;
using System.Drawing;
using System.Linq;
2014-07-09 23:04:22 +00:00
using System.Windows.Forms;
using System.Collections.Generic;
2014-07-09 23:04:22 +00:00
using BizHawk.Emulation.Common.IEmulatorExtensions;
2014-07-09 23:04:22 +00:00
using BizHawk.Client.Common;
namespace BizHawk.Client.EmuHawk
{
public partial class TAStudio
{
// Input Painting
2014-07-11 16:26:19 +00:00
private string _startBoolDrawColumn = string.Empty;
private string _startFloatDrawColumn = string.Empty;
private bool _boolPaintState;
2014-07-11 16:26:19 +00:00
private float _floatPaintState;
private bool _patternPaint = false;
private bool _startMarkerDrag;
private bool _startFrameDrag;
private bool _frameDragState;
private bool _supressContextMenu;
// SuuperW: For editing analog input
private string _floatEditColumn = string.Empty;
private int _floatEditRow = -1;
private string _floatTypedValue;
private int _floatEditYPos = -1;
// Right-click dragging
private string[] _rightClickInput = null;
private string[] _rightClickOverInput = null;
private int _rightClickFrame = -1;
private int _rightClickLastFrame = -1;
private bool _rightClickShift, _rightClickControl;
private bool _leftButtonHeld = false;
private bool mouseButtonHeld
{
get
{ // Need a left click
return _rightClickFrame != -1 || _leftButtonHeld;
}
}
private bool _triggerAutoRestore; // If true, autorestore will be called on mouse up
private int? _triggerAutoRestoreFromFrame; // If set and _triggerAutoRestore is true, will call GoToFrameIfNecessary() with this value
// public static Color CurrentFrame_FrameCol = Color.FromArgb(0xCFEDFC); Why?
public static Color CurrentFrame_InputLog = Color.FromArgb(0xB5E7F7);
2014-07-16 00:10:37 +00:00
public static Color GreenZone_FrameCol = Color.FromArgb(0xDDFFDD);
public static Color GreenZone_Invalidated_FrameCol = Color.FromArgb(0xFFFFFF);
public static Color GreenZone_InputLog = Color.FromArgb(0xC4F7C8);
public static Color GreenZone_Invalidated_InputLog = Color.FromArgb(0xE0FBE0);
2014-07-16 00:10:37 +00:00
public static Color LagZone_FrameCol = Color.FromArgb(0xFFDCDD);
public static Color LagZone_Invalidated_FrameCol = Color.FromArgb(0xFFE9E9);
public static Color LagZone_InputLog = Color.FromArgb(0xF0D0D2);
public static Color LagZone_Invalidated_InputLog = Color.FromArgb(0xF7E5E5);
2014-07-16 00:10:37 +00:00
public static Color Marker_FrameCol = Color.FromArgb(0xF7FFC9);
public static Color AnalogEdit_Col = Color.FromArgb(0x909070); // SuuperW: When editing an analog value, it will be a gray color.
2014-07-16 00:10:37 +00:00
private Emulation.Common.ControllerDefinition controllerType
{ get { return Global.MovieSession.MovieControllerAdapter.Type; } }
public AutoPatternBool[] BoolPatterns;
public AutoPatternFloat[] FloatPatterns;
2014-07-09 23:04:22 +00:00
#region Query callbacks
private void TasView_QueryItemIcon(int index, InputRoll.RollColumn column, ref Bitmap bitmap)
{
var overrideIcon = GetIconOverride(index, column);
if (overrideIcon != null)
{
bitmap = overrideIcon;
return;
}
var columnName = column.Name;
if (columnName == MarkerColumnName)
{
if (index == Emulator.Frame && index == GlobalWin.MainForm.PauseOnFrame)
2014-09-16 19:20:19 +00:00
{
bitmap = TasView.HorizontalOrientation ?
Properties.Resources.ts_v_arrow_green_blue :
Properties.Resources.ts_h_arrow_green_blue;
2014-09-16 19:20:19 +00:00
}
else if (index == Emulator.Frame)
{
bitmap = TasView.HorizontalOrientation ?
Properties.Resources.ts_v_arrow_blue :
Properties.Resources.ts_h_arrow_blue;
}
2014-09-16 19:20:19 +00:00
else if (index == GlobalWin.MainForm.PauseOnFrame)
{
bitmap = TasView.HorizontalOrientation ?
Properties.Resources.ts_v_arrow_green :
Properties.Resources.ts_h_arrow_green;
2014-09-16 19:20:19 +00:00
}
}
}
private void TasView_QueryItemBkColor(int index, InputRoll.RollColumn column, ref Color color)
2014-07-09 23:04:22 +00:00
{
var overrideColor = GetColorOverride(index, column);
if (overrideColor.HasValue)
{
color = overrideColor.Value;
return;
}
string columnName = column.Name;
2014-07-16 00:10:37 +00:00
if (columnName == MarkerColumnName)
{ // For debugging purposes, let's visually show the state frames
if (VersionInfo.DeveloperBuild && CurrentTasMovie.TasStateManager.HasState(index))
color = Color.FromArgb(0xEEEEEE);
else
color = Color.FromArgb(0xFEFFFF);
return;
2014-07-09 23:04:22 +00:00
}
if (columnName == FrameColumnName)
2014-07-09 23:04:22 +00:00
{
if (Emulator.Frame != index && CurrentTasMovie.Markers.IsMarker(index))
2014-07-16 00:10:37 +00:00
color = Marker_FrameCol;
}
else if (index == _floatEditRow && columnName == _floatEditColumn)
{ // SuuperW: Analog editing is indicated by a color change.
color = AnalogEdit_Col;
}
}
private void TasView_QueryRowBkColor(int index, ref Color color)
{
TasMovieRecord record = CurrentTasMovie[index];
if (Emulator.Frame == index)
{
color = CurrentFrame_InputLog;
}
else if (record.Lagged.HasValue)
{
color = record.Lagged.Value ?
LagZone_InputLog :
GreenZone_InputLog;
}
else if (record.WasLagged.HasValue)
{
color = record.WasLagged.Value ?
LagZone_Invalidated_InputLog :
GreenZone_Invalidated_FrameCol;
2014-07-16 00:10:37 +00:00
}
else
{
color = Color.FromArgb(0xFFFEEE);
2014-07-09 23:04:22 +00:00
}
}
private void TasView_QueryItemText(int index, InputRoll.RollColumn column, out string text)
2014-07-09 23:04:22 +00:00
{
var overrideText = GetTextOverride(index, column);
if (overrideText != null)
{
text = overrideText;
return;
}
2014-07-09 23:04:22 +00:00
try
{
text = string.Empty;
var columnName = column.Name;
2014-07-09 23:04:22 +00:00
if (columnName == MarkerColumnName)
{
// Do nothing
2014-07-09 23:04:22 +00:00
}
else if (columnName == FrameColumnName)
{
text = (index).ToString().PadLeft(CurrentTasMovie.InputLogLength.ToString().Length, '0');
2014-07-09 23:04:22 +00:00
}
else
{
if (index < CurrentTasMovie.InputLogLength)
text = CurrentTasMovie.DisplayValue(index, columnName);
2014-07-09 23:04:22 +00:00
}
}
catch (Exception ex)
{
text = string.Empty;
MessageBox.Show("oops\n" + ex);
}
}
// SuuperW: Used in InputRoll.cs to hide lag frames.
private bool TasView_QueryFrameLag(int index, bool hideWasLag)
{
TasMovieRecord lag = CurrentTasMovie[index];
return (lag.Lagged.HasValue && lag.Lagged.Value) || (hideWasLag && lag.WasLagged.HasValue && lag.WasLagged.Value);
}
2014-07-09 23:04:22 +00:00
#endregion
#region Events
private void TasView_ColumnClick(object sender, InputRoll.ColumnClickEventArgs e)
{
if (TasView.SelectedRows.Any())
{
var columnName = e.Column.Name;
if (columnName == FrameColumnName)
{
CurrentTasMovie.Markers.Add(TasView.LastSelectedIndex.Value, "");
RefreshDialog();
}
else if (columnName != MarkerColumnName) // TODO: what about float?
{
foreach (var index in TasView.SelectedRows)
{
CurrentTasMovie.ToggleBoolState(index, columnName);
_triggerAutoRestore = true;
_triggerAutoRestoreFromFrame = TasView.SelectedRows.Min();
}
RefreshDialog();
}
}
}
private void TasView_ColumnRightClick(object sender, InputRoll.ColumnClickEventArgs e)
{
e.Column.Emphasis ^= true;
UpdateAutoFire(e.Column.Name, e.Column.Emphasis);
RefreshTasView();
}
private void UpdateAutoFire()
{
for (int i = 2; i < TasView.AllColumns.Count; i++)
UpdateAutoFire(TasView.AllColumns[i].Name, TasView.AllColumns[i].Emphasis);
}
public void UpdateAutoFire(string button, bool? isOn)
{
if (!isOn.HasValue) // No value means don't change whether it's on or off.
isOn = TasView.AllColumns.Find(c => c.Name == button).Emphasis;
int index = 0;
if (autoHoldToolStripMenuItem.Checked) index = 1;
if (autoFireToolStripMenuItem.Checked) index = 2;
if (controllerType.BoolButtons.Contains(button))
{
if (index == 0)
index = controllerType.BoolButtons.IndexOf(button);
else
index += controllerType.BoolButtons.Count - 1;
AutoPatternBool p = BoolPatterns[index];
Global.AutofireStickyXORAdapter.SetSticky(button, isOn.Value, p);
}
else
{
if (index == 0)
index = controllerType.FloatControls.IndexOf(button);
else
index += controllerType.FloatControls.Count - 1;
float? value = null;
if (isOn.Value) value = 0f;
AutoPatternFloat p = FloatPatterns[index];
Global.AutofireStickyXORAdapter.SetFloat(button, value, p);
}
}
private void TasView_ColumnReordered(object sender, InputRoll.ColumnReorderedEventArgs e)
{
CurrentTasMovie.FlagChanges();
}
2014-10-17 17:40:11 +00:00
private void TasView_MouseEnter(object sender, EventArgs e)
{
if (this.ContainsFocus)
TasView.Focus();
2014-10-17 17:40:11 +00:00
}
2014-07-09 23:04:22 +00:00
private void TasView_MouseDown(object sender, MouseEventArgs e)
{
// Clicking with left while right is held or vice versa does weird stuff
if (mouseButtonHeld)
return;
if (e.Button == MouseButtons.Middle)
{
TogglePause();
return;
}
// SuuperW: Moved these.
if (TasView.CurrentCell == null || !TasView.CurrentCell.RowIndex.HasValue || TasView.CurrentCell.Column == null)
return;
int frame = TasView.CurrentCell.RowIndex.Value;
string buttonName = TasView.CurrentCell.Column.Name;
if (e.Button == MouseButtons.Left)
2014-07-09 23:04:22 +00:00
{
CurrentTasMovie.SupressGreenzonging = true; // This is necessary because we will invalidate, but we won't navigate until mouse up, during that time the user may have emulated frames and we don't want to caputre states for those
_leftButtonHeld = true;
// SuuperW: Exit float editing mode, or re-enter mouse editing
if (_floatEditRow != -1)
{
if (_floatEditColumn != buttonName || _floatEditRow != frame)
{
_floatEditRow = -1;
RefreshTasView();
}
else
{
_floatEditYPos = e.Y;
_floatPaintState = CurrentTasMovie.GetFloatState(frame, buttonName);
_triggerAutoRestore = true;
_triggerAutoRestoreFromFrame = TasView.CurrentCell.RowIndex.Value;
return;
}
}
if (TasView.CurrentCell.Column.Name == MarkerColumnName)
2014-07-09 23:04:22 +00:00
{
_startMarkerDrag = true;
GoToFrame(TasView.CurrentCell.RowIndex.Value);
}
else if (TasView.CurrentCell.Column.Name == FrameColumnName)
{
_startFrameDrag = true;
_frameDragState = TasView.SelectedRows.Contains(frame);
}
else // User changed input
{
if (Global.MovieSession.MovieControllerAdapter.Type.BoolButtons.Contains(buttonName))
2014-07-11 16:26:19 +00:00
{
CurrentTasMovie.ChangeLog.BeginNewBatch("Paint Bool");
CurrentTasMovie.ToggleBoolState(TasView.CurrentCell.RowIndex.Value, buttonName);
_triggerAutoRestore = true;
_triggerAutoRestoreFromFrame = TasView.CurrentCell.RowIndex.Value;
RefreshDialog();
_startBoolDrawColumn = buttonName;
_boolPaintState = CurrentTasMovie.BoolIsPressed(frame, buttonName);
if (applyPatternToPaintedInputToolStripMenuItem.Checked &&
(!onlyOnAutoFireColumnsToolStripMenuItem.Checked || TasView.CurrentCell.Column.Emphasis))
{
BoolPatterns[controllerType.BoolButtons.IndexOf(buttonName)].Reset();
BoolPatterns[controllerType.BoolButtons.IndexOf(buttonName)].GetNextValue();
_patternPaint = true;
}
else
_patternPaint = false;
}
else
{
if (frame >= CurrentTasMovie.InputLogLength)
{
CurrentTasMovie.SetFloatState(frame, buttonName, 0);
RefreshDialog();
}
_triggerAutoRestoreFromFrame = TasView.CurrentCell.RowIndex.Value;
_floatPaintState = CurrentTasMovie.GetFloatState(frame, buttonName);
if (applyPatternToPaintedInputToolStripMenuItem.Checked &&
(!onlyOnAutoFireColumnsToolStripMenuItem.Checked || TasView.CurrentCell.Column.Emphasis))
{
FloatPatterns[controllerType.FloatControls.IndexOf(buttonName)].Reset();
CurrentTasMovie.SetFloatState(frame, buttonName,
FloatPatterns[controllerType.FloatControls.IndexOf(buttonName)].GetNextValue());
_patternPaint = true;
}
else
_patternPaint = false;
if (e.Clicks != 2)
{
CurrentTasMovie.ChangeLog.BeginNewBatch("Paint Float");
_startFloatDrawColumn = buttonName;
}
else // Double-click enters float editing mode
{
if (_floatEditColumn == buttonName && _floatEditRow == frame)
_floatEditRow = -1;
else
{
CurrentTasMovie.ChangeLog.BeginNewBatch("Float Edit: " + frame);
_floatEditColumn = buttonName;
_floatEditRow = frame;
_floatTypedValue = "";
_floatEditYPos = e.Y;
_triggerAutoRestore = true;
_triggerAutoRestoreFromFrame = frame;
}
RefreshDialog();
}
2014-07-11 16:26:19 +00:00
}
2014-07-09 23:04:22 +00:00
}
}
else if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
if (TasView.CurrentCell.Column.Name == FrameColumnName && frame < CurrentTasMovie.InputLogLength)
{
_rightClickControl = (Control.ModifierKeys | Keys.Control) == Control.ModifierKeys;
_rightClickShift = (Control.ModifierKeys | Keys.Shift) == Control.ModifierKeys;
if (TasView.SelectedRows.Contains(frame))
{
_rightClickInput = new string[TasView.SelectedRows.Count()];
_rightClickFrame = TasView.FirstSelectedIndex.Value;
CurrentTasMovie.GetLogEntries().CopyTo(_rightClickFrame, _rightClickInput, 0, TasView.SelectedRows.Count());
if (_rightClickControl && _rightClickShift)
_rightClickFrame += _rightClickInput.Length;
}
else
{
_rightClickInput = new string[1];
_rightClickInput[0] = CurrentTasMovie.GetLogEntries()[frame];
_rightClickFrame = frame;
}
_rightClickLastFrame = -1;
_triggerAutoRestoreFromFrame = TasView.CurrentCell.RowIndex.Value;
// TODO: Turn off ChangeLog.IsRecording and handle the GeneralUndo here.
CurrentTasMovie.ChangeLog.BeginNewBatch("Right-Click Edit");
}
}
2014-07-09 23:04:22 +00:00
}
private void TasView_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right && !TasView.IsPointingAtColumnHeader && !_supressContextMenu)
{
RightClickMenu.Show(TasView, e.X, e.Y);
}
else if (e.Button == MouseButtons.Left)
{
CurrentTasMovie.SupressGreenzonging = false;
_startMarkerDrag = false;
_startFrameDrag = false;
_startBoolDrawColumn = string.Empty;
_startFloatDrawColumn = string.Empty;
// Exit float editing if value was changed with cursor
if (_floatEditRow != -1 && _floatPaintState != CurrentTasMovie.GetFloatState(_floatEditRow, _floatEditColumn))
{
_floatEditRow = -1;
RefreshDialog();
}
_floatPaintState = 0;
_floatEditYPos = -1;
_leftButtonHeld = false;
if (_floatEditRow == -1)
CurrentTasMovie.ChangeLog.EndBatch();
}
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
if (_rightClickFrame != -1)
{
_rightClickInput = null;
_rightClickFrame = -1;
CurrentTasMovie.ChangeLog.EndBatch();
}
}
_supressContextMenu = false;
DoTriggeredAutoRestoreIfNeeded();
2014-07-09 23:04:22 +00:00
}
private void TasView_MouseWheel(object sender, MouseEventArgs e)
{
if (TasView.RightButtonHeld && TasView.CurrentCell.RowIndex.HasValue)
{
_supressContextMenu = true;
if (e.Delta < 0)
{
GoToNextFrame();
}
else
{
GoToPreviousFrame();
}
}
}
private void TasView_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
var buttonName = TasView.CurrentCell.Column.Name;
if (TasView.CurrentCell.RowIndex.HasValue &&
buttonName == FrameColumnName)
{
if (Settings.EmptyMarkers)
{
CurrentTasMovie.Markers.Add(TasView.CurrentCell.RowIndex.Value, string.Empty);
RefreshDialog();
}
else
{
CallAddMarkerPopUp(TasView.CurrentCell.RowIndex.Value);
}
}
}
}
private void TasView_PointedCellChanged(object sender, InputRoll.CellEventArgs e)
2014-07-09 23:04:22 +00:00
{
// TODO: think about nullability
// For now return if a null because this happens OnEnter which doesn't have any of the below behaviors yet?
// Most of these are stupid but I got annoyed at null crashes
if (e.OldCell == null || e.OldCell.Column == null || e.OldCell.RowIndex == null ||
e.NewCell == null || e.NewCell.RowIndex == null || e.NewCell.Column == null)
{
return;
}
int startVal, endVal;
int frame = e.NewCell.RowIndex.Value;
if (e.OldCell.RowIndex.Value < e.NewCell.RowIndex.Value)
{
startVal = e.OldCell.RowIndex.Value;
endVal = e.NewCell.RowIndex.Value;
}
else
{
startVal = e.NewCell.RowIndex.Value;
endVal = e.OldCell.RowIndex.Value;
}
2014-07-09 23:04:22 +00:00
if (_startMarkerDrag)
{
if (e.NewCell.RowIndex.HasValue)
2014-07-09 23:04:22 +00:00
{
GoToFrame(e.NewCell.RowIndex.Value);
2014-07-09 23:04:22 +00:00
}
}
else if (_startFrameDrag)
{
if (e.OldCell.RowIndex.HasValue && e.NewCell.RowIndex.HasValue)
2014-07-09 23:04:22 +00:00
{
for (var i = startVal; i <= endVal; i++)
2014-07-09 23:04:22 +00:00
{
TasView.SelectRow(i, _frameDragState);
2014-07-09 23:04:22 +00:00
}
RefreshTasView();
2014-07-09 23:04:22 +00:00
}
}
else if (_rightClickFrame != -1)
{
_triggerAutoRestore = true;
_supressContextMenu = true;
if (frame > CurrentTasMovie.InputLogLength - _rightClickInput.Length)
frame = CurrentTasMovie.InputLogLength - _rightClickInput.Length;
if (_rightClickShift)
{
if (_rightClickControl) // Insert
{
// If going backwards, delete!
bool shouldInsert = true;
if (startVal < _rightClickFrame)
{ // Cloning to a previous frame makes no sense.
startVal = _rightClickFrame - 1;
}
if (startVal < _rightClickLastFrame)
shouldInsert = false;
if (shouldInsert)
{
for (int i = startVal + 1; i <= endVal; i++)
CurrentTasMovie.InsertInput(i, _rightClickInput[(i - _rightClickFrame) % _rightClickInput.Length]);
}
else
{
CurrentTasMovie.RemoveFrames(startVal + 1, endVal + 1);
}
_rightClickLastFrame = frame;
}
else // Overwrite
{
for (int i = startVal; i <= endVal; i++)
CurrentTasMovie.SetFrame(i, _rightClickInput[(_rightClickFrame - i) % _rightClickInput.Length]);
if (startVal < _triggerAutoRestoreFromFrame)
_triggerAutoRestoreFromFrame = startVal;
}
}
else
{
if (_rightClickControl)
{
for (int i = 0; i < _rightClickInput.Length; i++) // Re-set initial range, just to verify it's still there.
CurrentTasMovie.SetFrame(_rightClickFrame + i, _rightClickInput[i]);
if (_rightClickOverInput != null) // Restore overwritten input from previous movement
{
for (int i = 0; i < _rightClickOverInput.Length; i++)
CurrentTasMovie.SetFrame(_rightClickLastFrame + i, _rightClickOverInput[i]);
}
else
_rightClickOverInput = new string[_rightClickInput.Length];
_rightClickLastFrame = frame; // Set new restore log
CurrentTasMovie.GetLogEntries().CopyTo(frame, _rightClickOverInput, 0, _rightClickOverInput.Length);
for (int i = 0; i < _rightClickInput.Length; i++) // Place copied input
CurrentTasMovie.SetFrame(frame + i, _rightClickInput[i]);
}
else
{
int shiftBy = _rightClickFrame - frame;
string[] shiftInput = new string[Math.Abs(shiftBy)];
int shiftFrom = frame;
if (shiftBy < 0)
shiftFrom = _rightClickFrame + _rightClickInput.Length;
CurrentTasMovie.GetLogEntries().CopyTo(shiftFrom, shiftInput, 0, shiftInput.Length);
int shiftTo = shiftFrom + (_rightClickInput.Length * Math.Sign(shiftBy));
for (int i = 0; i < shiftInput.Length; i++)
CurrentTasMovie.SetFrame(shiftTo + i, shiftInput[i]);
for (int i = 0; i < _rightClickInput.Length; i++)
CurrentTasMovie.SetFrame(frame + i, _rightClickInput[i]);
_rightClickFrame = frame;
}
if (frame < _triggerAutoRestoreFromFrame)
_triggerAutoRestoreFromFrame = frame;
}
RefreshTasView();
}
else if (TasView.IsPaintDown && e.NewCell.RowIndex.HasValue && !string.IsNullOrEmpty(_startBoolDrawColumn))
2014-07-11 16:26:19 +00:00
{
if (e.OldCell.RowIndex.HasValue && e.NewCell.RowIndex.HasValue)
2014-07-11 16:26:19 +00:00
{
for (var i = startVal + 1; i <= endVal; i++) // SuuperW: <= so that it will edit the cell you are hovering over. (Inclusive)
2014-07-11 16:26:19 +00:00
{
bool setVal = _boolPaintState;
if (_patternPaint && _boolPaintState)
{
if (CurrentTasMovie[frame].Lagged.HasValue && CurrentTasMovie[frame].Lagged.Value)
setVal = CurrentTasMovie.BoolIsPressed(i - 1, _startBoolDrawColumn);
else
setVal = BoolPatterns[controllerType.BoolButtons.IndexOf(_startBoolDrawColumn)].GetNextValue();
}
CurrentTasMovie.SetBoolState(i, _startBoolDrawColumn, setVal); // Notice it uses new row, old column, you can only paint across a single column
if (TasView.CurrentCell.RowIndex.Value < _triggerAutoRestoreFromFrame)
_triggerAutoRestoreFromFrame = TasView.CurrentCell.RowIndex.Value;
2014-07-11 16:26:19 +00:00
}
RefreshTasView();
2014-07-11 16:26:19 +00:00
}
}
else if (TasView.IsPaintDown && e.NewCell.RowIndex.HasValue && !string.IsNullOrEmpty(_startFloatDrawColumn))
2014-07-09 23:04:22 +00:00
{
if (e.OldCell.RowIndex.HasValue && e.NewCell.RowIndex.HasValue)
{
for (var i = startVal + 1; i <= endVal; i++) // SuuperW: <= so that it will edit the cell you are hovering over. (Inclusive)
{
float setVal = _floatPaintState;
if (_patternPaint)
{
if (CurrentTasMovie[frame].Lagged.HasValue && CurrentTasMovie[frame].Lagged.Value)
setVal = CurrentTasMovie.GetFloatState(i - 1, _startFloatDrawColumn);
else
setVal = FloatPatterns[controllerType.FloatControls.IndexOf(_startFloatDrawColumn)].GetNextValue();
}
CurrentTasMovie.SetFloatState(i, _startFloatDrawColumn, setVal); // Notice it uses new row, old column, you can only paint across a single column
if (TasView.CurrentCell.RowIndex.Value < _triggerAutoRestoreFromFrame)
_triggerAutoRestoreFromFrame = TasView.CurrentCell.RowIndex.Value;
}
2014-07-11 16:26:19 +00:00
RefreshTasView();
}
2014-07-09 23:04:22 +00:00
}
}
private void TasView_MouseMove(object sender, MouseEventArgs e)
{
// For float editing
int increment = (_floatEditYPos - e.Y) / 3;
if (_floatEditYPos == -1)
return;
float value = _floatPaintState + increment;
Emulation.Common.ControllerDefinition.FloatRange range = Global.MovieSession.MovieControllerAdapter.Type.FloatRanges
[Global.MovieSession.MovieControllerAdapter.Type.FloatControls.IndexOf(_floatEditColumn)];
// Range for N64 Y axis has max -128 and min 127. That should probably be fixed in ControllerDefinition.cs.
// SuuperW: I really don't think changing it would break anything, but adelikat isn't so sure.
float rMax = range.Max;
float rMin = range.Min;
if (rMax < rMin)
{
rMax = range.Min;
rMin = range.Max;
}
if (value > rMax)
value = rMax;
else if (value < rMin)
value = rMin;
CurrentTasMovie.SetFloatState(_floatEditRow, _floatEditColumn, value);
RefreshDialog();
}
2014-07-09 23:04:22 +00:00
private void TasView_SelectedIndexChanged(object sender, EventArgs e)
{
SetSplicer();
}
private void TasView_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.Left) // Ctrl + Left
{
GoToPreviousMarker();
}
else if (e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.Right) // Ctrl + Left
{
GoToNextMarker();
}
else if (e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.Up) // Ctrl + Up
{
GoToPreviousFrame();
}
else if (e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.Down) // Ctrl + Down
{
GoToNextFrame();
2014-10-17 19:31:42 +00:00
}
else if (e.Control && !e.Alt && e.Shift && e.KeyCode == Keys.R) // Ctrl + Shift + R
{
TasView.HorizontalOrientation ^= true;
}
// SuuperW: Float Editing
if (_floatEditRow != -1)
{
float value = CurrentTasMovie.GetFloatState(_floatEditRow, _floatEditColumn);
float prev = value;
string prevTyped = _floatTypedValue;
Emulation.Common.ControllerDefinition.FloatRange range = Global.MovieSession.MovieControllerAdapter.Type.FloatRanges
[Global.MovieSession.MovieControllerAdapter.Type.FloatControls.IndexOf(_floatEditColumn)];
// Range for N64 Y axis has max -128 and min 127. That should probably be fixed ControllerDefinition.cs, but I'll put a quick fix here anyway.
float rMax = range.Max;
float rMin = range.Min;
if (rMax < rMin)
{
rMax = range.Min;
rMin = range.Max;
}
if (e.KeyCode == Keys.Right)
value = rMax;
else if (e.KeyCode == Keys.Left)
value = rMin;
else if (e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9)
_floatTypedValue += e.KeyCode - Keys.D0;
else if (e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9)
_floatTypedValue += e.KeyCode - Keys.NumPad0;
else if (e.KeyCode == Keys.OemMinus)
{
if (_floatTypedValue.StartsWith("-"))
_floatTypedValue = _floatTypedValue.Substring(1);
else
_floatTypedValue = "-" + _floatTypedValue;
}
else if (e.KeyCode == Keys.Back)
{
if (_floatTypedValue == "") // Very first key press is backspace?
_floatTypedValue = value.ToString();
_floatTypedValue = _floatTypedValue.Substring(0, _floatTypedValue.Length - 1);
if (_floatTypedValue == "" || _floatTypedValue == "-")
value = 0f;
else
value = Convert.ToSingle(_floatTypedValue);
}
else if (e.KeyCode == Keys.Escape)
{
if (_floatEditYPos != -1) // Cancel change from dragging cursor
{
_floatEditYPos = -1;
CurrentTasMovie.SetFloatState(_floatEditRow, _floatEditColumn, _floatPaintState);
}
_floatEditRow = -1;
}
else
{
float changeBy = 0;
if (e.KeyCode == Keys.Up)
changeBy = 1; // We're assuming for now that ALL float controls should contain integers.
else if (e.KeyCode == Keys.Down)
changeBy = -1;
if (e.Shift)
changeBy *= 10;
value += changeBy;
if (changeBy != 0)
_floatTypedValue = value.ToString();
}
if (_floatEditRow == -1)
CurrentTasMovie.ChangeLog.EndBatch();
else
{
if (_floatTypedValue == "")
{
if (prevTyped != "")
{
value = 0f;
CurrentTasMovie.SetFloatState(_floatEditRow, _floatEditColumn, value);
}
}
else
{
value = Convert.ToSingle(_floatTypedValue);
if (value > rMax)
value = rMax;
else if (value < rMin)
value = rMin;
CurrentTasMovie.SetFloatState(_floatEditRow, _floatEditColumn, value);
}
if (value != prev) // Auto-restore
{
_triggerAutoRestore = true;
_triggerAutoRestoreFromFrame = _floatEditRow;
DoTriggeredAutoRestoreIfNeeded();
}
}
}
RefreshDialog();
}
/// <summary>
/// This allows arrow keys to be detected by KeyDown.
/// </summary>
private void TasView_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Left || e.KeyCode == Keys.Right || e.KeyCode == Keys.Up || e.KeyCode == Keys.Down)
e.IsInputKey = true;
}
2014-07-09 23:04:22 +00:00
#endregion
}
}