(ded4a3e0a) v0.9.0.7
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Eto.Drawing;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
class BuildItem
|
||||
{
|
||||
private const int CellHeight = 32;
|
||||
private const int Spacing = 10;
|
||||
private const int Margin = 10;
|
||||
private const string ArrowCollapse = "▲";
|
||||
private const string ArrowExpand = "▼";
|
||||
private const int ButtonSpacing = 3;
|
||||
|
||||
public string Text { get; set; }
|
||||
public Image Icon { get; set; }
|
||||
public int Height { get; set; }
|
||||
public int RequestedWidth { get; set; }
|
||||
|
||||
public string Description
|
||||
{
|
||||
set
|
||||
{
|
||||
_description.Clear();
|
||||
_description.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly float _arrowWidth;
|
||||
private readonly float _textOffset;
|
||||
private readonly float _imageOffset;
|
||||
private readonly float _descSize;
|
||||
|
||||
private List<string> _description;
|
||||
private float _descriptionOffset;
|
||||
private bool _expanded;
|
||||
private bool _selected;
|
||||
|
||||
public BuildItem()
|
||||
{
|
||||
_arrowWidth = SystemFonts.Default().MeasureString(ArrowExpand).Width;
|
||||
_textOffset = (CellHeight - DrawInfo.TextHeight) / 2;
|
||||
_imageOffset = (CellHeight - 16) / 2;
|
||||
_descSize = SystemFonts.Default().LineHeight + 4;
|
||||
|
||||
_description = new List<string>();
|
||||
|
||||
Height = CellHeight;
|
||||
RequestedWidth = 0;
|
||||
}
|
||||
|
||||
public void AddDescription(string text)
|
||||
{
|
||||
_description.Add(text);
|
||||
}
|
||||
|
||||
public void OnClick()
|
||||
{
|
||||
if (_selected && _description.Count != 0)
|
||||
{
|
||||
_expanded = !_expanded;
|
||||
|
||||
if (_expanded)
|
||||
{
|
||||
_descriptionOffset = (_descSize - DrawInfo.TextHeight) / 2;
|
||||
Height = (int)(CellHeight + _descSize * _description.Count);
|
||||
|
||||
foreach (var des in _description)
|
||||
{
|
||||
var width = SystemFonts.Default().MeasureString(des).Width + 4 * Spacing + 16;
|
||||
if (width > RequestedWidth)
|
||||
RequestedWidth = (int)width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Height = CellHeight;
|
||||
RequestedWidth = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(Graphics g, int y, int width)
|
||||
{
|
||||
var x = Margin;
|
||||
_selected = BuildOutput.MouseLocation.Y > y && BuildOutput.MouseLocation.Y < y + CellHeight;
|
||||
|
||||
// Draw Background
|
||||
g.FillRectangle(DrawInfo.BorderColor, 0, y, width, Height);
|
||||
g.FillRectangle(_selected ? DrawInfo.HoverBackColor : DrawInfo.BorderColor, 0, y, width, CellHeight);
|
||||
|
||||
// Draw Icon
|
||||
g.DrawImage(Icon, x, y + _imageOffset);
|
||||
x += 16 + Spacing;
|
||||
|
||||
// Draw Text
|
||||
g.DrawText(SystemFonts.Default(), DrawInfo.GetTextColor(_selected, false), x, y + _textOffset, Text);
|
||||
|
||||
// Draw Expander
|
||||
if (_description.Count != 0)
|
||||
{
|
||||
//g.FillRectangle(_expandSelected ? DrawInfo.HoverBackColor : DrawInfo.BorderColor, rectangle);
|
||||
g.DrawText(SystemFonts.Default(), DrawInfo.GetTextColor(_selected, false), width - Margin - _arrowWidth, y + _textOffset, _expanded ? ArrowCollapse : ArrowExpand);
|
||||
}
|
||||
|
||||
// Draw Description
|
||||
if (_expanded)
|
||||
{
|
||||
for (int i = 0; i < _description.Count; i++)
|
||||
g.DrawText(SystemFonts.Default(), DrawInfo.DisabledTextColor, x + Spacing, y + CellHeight + _descriptionOffset + _descSize * i, _description[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Eto.Drawing;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public partial class BuildOutput
|
||||
{
|
||||
public static Point MouseLocation;
|
||||
public static int Count;
|
||||
|
||||
private bool _tryScroll, _setHeight;
|
||||
private int _reqWidth = 0;
|
||||
private OutputParser _output;
|
||||
private List<BuildItem> _items;
|
||||
private CheckCommand _cmdFilterOutput, _cmdAutoScroll, _cmdShowSkipped, _cmdShowSuccessful, _cmdShowCleaned;
|
||||
private Image _iconInformation, _iconFail, _iconProcessing, _iconSkip, _iconSucceed, _iconSucceedWithWarnings, _iconStart, _iconEndSucceed, _iconEndFailed;
|
||||
private BuildItem _selectedItem;
|
||||
private Eto.Drawing.Point _scrollPosition;
|
||||
|
||||
public BuildOutput()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_output = new OutputParser();
|
||||
|
||||
_iconInformation = Global.GetEtoIcon("Build.Information.png");
|
||||
_iconFail = Global.GetEtoIcon("Build.Fail.png");
|
||||
_iconProcessing = Global.GetEtoIcon("Build.Processing.png");
|
||||
_iconSkip = Global.GetEtoIcon("Build.Skip.png");
|
||||
_iconStart = Global.GetEtoIcon("Build.Start.png");
|
||||
_iconEndSucceed = Global.GetEtoIcon("Build.EndSucceed.png");
|
||||
_iconEndFailed = Global.GetEtoIcon("Build.EndFailed.png");
|
||||
_iconSucceed = Global.GetEtoIcon("Build.Succeed.png");
|
||||
_iconSucceedWithWarnings = Global.GetEtoIcon("Build.SucceedWithWarnings.png");
|
||||
|
||||
_items = new List<BuildItem>();
|
||||
|
||||
_cmdFilterOutput = new CheckCommand();
|
||||
_cmdFilterOutput.MenuText = "Filter Output";
|
||||
_cmdFilterOutput.CheckedChanged += CmdFilterOutput_CheckedChanged;
|
||||
AddCommand(_cmdFilterOutput);
|
||||
|
||||
_cmdShowSkipped = new CheckCommand();
|
||||
_cmdShowSkipped.MenuText = "Show Skipped Files";
|
||||
_cmdShowSkipped.CheckedChanged += CmdShowSkipped_CheckedChanged;
|
||||
AddCommand(_cmdShowSkipped);
|
||||
|
||||
_cmdShowSuccessful = new CheckCommand();
|
||||
_cmdShowSuccessful.MenuText = "Show Successfully Built Files";
|
||||
_cmdShowSuccessful.CheckedChanged += CmdShowSuccessful_CheckedChanged;
|
||||
AddCommand(_cmdShowSuccessful);
|
||||
|
||||
_cmdShowCleaned = new CheckCommand();
|
||||
_cmdShowCleaned.MenuText = "Show Cleaned Files";
|
||||
_cmdShowCleaned.CheckedChanged += CmdShowCleaned_CheckedChanged;
|
||||
AddCommand(_cmdShowCleaned);
|
||||
|
||||
_cmdAutoScroll = new CheckCommand();
|
||||
_cmdAutoScroll.MenuText = "Auto Scroll";
|
||||
_cmdAutoScroll.CheckedChanged += CmdAutoScroll_CheckedChanged;
|
||||
AddCommand(_cmdAutoScroll);
|
||||
|
||||
MouseLocation = new Point(-1, -1);
|
||||
}
|
||||
|
||||
public override void LoadSettings()
|
||||
{
|
||||
_cmdFilterOutput.Checked = PipelineSettings.Default.FilterOutput;
|
||||
_cmdShowSkipped.Checked = PipelineSettings.Default.FilterShowSkipped;
|
||||
_cmdShowSuccessful.Checked = PipelineSettings.Default.FilterShowSuccessful;
|
||||
_cmdShowCleaned.Checked = PipelineSettings.Default.FilterShowCleaned;
|
||||
_cmdAutoScroll.Checked = PipelineSettings.Default.AutoScrollBuildOutput;
|
||||
}
|
||||
|
||||
private void CmdFilterOutput_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (_cmdFilterOutput.Checked)
|
||||
drawable.Paint -= Drawable_Paint;
|
||||
|
||||
panel.Content = _cmdFilterOutput.Checked ? (Control)scrollable : textArea;
|
||||
PipelineSettings.Default.FilterOutput = _cmdFilterOutput.Checked;
|
||||
|
||||
if (_cmdFilterOutput.Checked)
|
||||
drawable.Paint += Drawable_Paint;
|
||||
|
||||
drawable.Invalidate();
|
||||
}
|
||||
|
||||
private void CmdShowSkipped_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
PipelineSettings.Default.FilterShowSkipped = _cmdShowSkipped.Checked;
|
||||
drawable.Invalidate();
|
||||
}
|
||||
|
||||
private void CmdShowSuccessful_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
PipelineSettings.Default.FilterShowSuccessful = _cmdShowSuccessful.Checked;
|
||||
drawable.Invalidate();
|
||||
}
|
||||
|
||||
private void CmdShowCleaned_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
PipelineSettings.Default.FilterShowCleaned = _cmdShowCleaned.Checked;
|
||||
drawable.Invalidate();
|
||||
}
|
||||
|
||||
private void CmdAutoScroll_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
PipelineSettings.Default.AutoScrollBuildOutput = _cmdAutoScroll.Checked;
|
||||
}
|
||||
|
||||
public void ClearOutput()
|
||||
{
|
||||
drawable.Width = _reqWidth = 0;
|
||||
scrollable.ScrollPosition = new Point(0, 0);
|
||||
textArea.Text = "";
|
||||
_items.Clear();
|
||||
drawable.Invalidate();
|
||||
}
|
||||
|
||||
public void WriteLine(string line)
|
||||
{
|
||||
textArea.Append(line + Environment.NewLine, _cmdAutoScroll.Checked);
|
||||
|
||||
if (string.IsNullOrEmpty(line))
|
||||
return;
|
||||
|
||||
_output.Parse(line);
|
||||
line = line.Trim(new[] { ' ', '\n', '\r', '\t' });
|
||||
|
||||
switch (_output.State)
|
||||
{
|
||||
case OutputState.BuildBegin:
|
||||
_items.Add(new BuildItem { Text = line, Icon = _iconStart });
|
||||
Count = -1;
|
||||
break;
|
||||
case OutputState.Cleaning:
|
||||
_items.Add(new BuildItem
|
||||
{
|
||||
Text = "Cleaning " + PipelineController.Instance.GetRelativePath(_output.Filename),
|
||||
Icon = _iconInformation,
|
||||
Description = line
|
||||
});
|
||||
break;
|
||||
case OutputState.Skipping:
|
||||
if (_items[_items.Count - 1].Icon == _iconProcessing)
|
||||
_items[_items.Count - 1].Icon = _iconSucceed;
|
||||
|
||||
_items.Add(new BuildItem
|
||||
{
|
||||
Text = "Skipping " + PipelineController.Instance.GetRelativePath(_output.Filename),
|
||||
Icon = _iconSkip,
|
||||
Description = _output.Filename
|
||||
});
|
||||
break;
|
||||
case OutputState.BuildAsset:
|
||||
if (_items[_items.Count - 1].Icon == _iconProcessing)
|
||||
_items[_items.Count - 1].Icon = _iconSucceed;
|
||||
|
||||
_items.Add(new BuildItem
|
||||
{
|
||||
Text = "Building " + PipelineController.Instance.GetRelativePath(_output.Filename),
|
||||
Icon = _iconProcessing,
|
||||
Description = _output.Filename
|
||||
});
|
||||
break;
|
||||
case OutputState.BuildError:
|
||||
_items[_items.Count - 1].Icon = _iconFail;
|
||||
_items[_items.Count - 1].AddDescription(_output.ErrorMessage);
|
||||
break;
|
||||
case OutputState.BuildErrorContinue:
|
||||
_items[_items.Count - 1].AddDescription(_output.ErrorMessage);
|
||||
break;
|
||||
case OutputState.BuildWarning:
|
||||
if (_items[_items.Count - 1].Icon == _iconProcessing)
|
||||
_items[_items.Count - 1].Icon = _iconSucceedWithWarnings;
|
||||
_items[_items.Count - 1].AddDescription(_output.ErrorMessage);
|
||||
break;
|
||||
case OutputState.BuildEnd:
|
||||
if (_items.Count > 0 && _items[_items.Count - 1].Icon == _iconProcessing)
|
||||
_items[_items.Count - 1].Icon = _iconSucceed;
|
||||
|
||||
_items.Add(new BuildItem
|
||||
{
|
||||
Text = line,
|
||||
Icon = line.Contains("0 failed") ? _iconEndSucceed : _iconEndFailed
|
||||
});
|
||||
break;
|
||||
case OutputState.BuildTime:
|
||||
var text = _items[_items.Count - 1].Text.TrimEnd(new[] { '.', ' ' }) + ", " + line;
|
||||
_items[_items.Count - 1].Text = text;
|
||||
Count = _items.Count * 35 - 3;
|
||||
break;
|
||||
case OutputState.BuildTerminated:
|
||||
_items.Add(new BuildItem { Text = line, Icon = _iconEndFailed });
|
||||
break;
|
||||
}
|
||||
|
||||
_setHeight = true;
|
||||
drawable.Invalidate();
|
||||
}
|
||||
|
||||
private void Drawable_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
MouseLocation = new Point((int)e.Location.X, (int)e.Location.Y);
|
||||
drawable.Invalidate();
|
||||
}
|
||||
|
||||
private void Drawable_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
_selectedItem = null;
|
||||
MouseLocation = new Point(-1, -1);
|
||||
drawable.Invalidate();
|
||||
}
|
||||
|
||||
private void Drawable_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (_selectedItem != null)
|
||||
_selectedItem.OnClick();
|
||||
|
||||
_reqWidth = 0;
|
||||
foreach (var item in _items)
|
||||
if (item.RequestedWidth > _reqWidth)
|
||||
_reqWidth = item.RequestedWidth;
|
||||
|
||||
drawable.Width = _reqWidth;
|
||||
_setHeight = true;
|
||||
drawable.Invalidate();
|
||||
}
|
||||
|
||||
private void Drawable_SizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (_tryScroll)
|
||||
{
|
||||
_tryScroll = false;
|
||||
|
||||
if (PipelineSettings.Default.AutoScrollBuildOutput)
|
||||
scrollable.ScrollPosition = new Point(0, drawable.Height + 10 - scrollable.Height);
|
||||
}
|
||||
}
|
||||
|
||||
private void Scrollable1_SizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
drawable.Invalidate();
|
||||
}
|
||||
|
||||
private void Scrollable1_Scroll(object sender, EventArgs e)
|
||||
{
|
||||
_scrollPosition = scrollable.ScrollPosition;
|
||||
drawable.Invalidate();
|
||||
}
|
||||
|
||||
private void Drawable_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
var g = e.Graphics;
|
||||
var count = _items.Count;
|
||||
var y = 0;
|
||||
|
||||
g.Clear(DrawInfo.BackColor);
|
||||
|
||||
for (int i = 0; i < _items.Count; i++)
|
||||
{
|
||||
var item = _items[i];
|
||||
|
||||
// Skip Skipped items
|
||||
if (!PipelineSettings.Default.FilterShowSkipped && item.Icon == _iconSkip)
|
||||
continue;
|
||||
|
||||
// Skip Successful items
|
||||
if (!PipelineSettings.Default.FilterShowSuccessful && item.Icon == _iconSucceed)
|
||||
continue;
|
||||
|
||||
// Skip Cleaned items
|
||||
if (!PipelineSettings.Default.FilterShowCleaned && item.Icon == _iconInformation)
|
||||
continue;
|
||||
|
||||
// Check if the item is in the visible rectangle
|
||||
if (y + item.Height >= _scrollPosition.Y && y < _scrollPosition.Y + scrollable.Height)
|
||||
{
|
||||
// Check if the item is selected
|
||||
if (MouseLocation.Y > y && MouseLocation.Y < y + item.Height)
|
||||
_selectedItem = item;
|
||||
|
||||
// Draw item
|
||||
item.Draw(g, y, drawable.Width);
|
||||
}
|
||||
|
||||
// Add border
|
||||
y += item.Height + 3;
|
||||
}
|
||||
|
||||
if (_setHeight)
|
||||
{
|
||||
_setHeight = false;
|
||||
drawable.Size = new Size(_reqWidth, Math.Max(y - 3, 1));
|
||||
}
|
||||
|
||||
if (Count == -1)
|
||||
_tryScroll = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using System;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public partial class BuildOutput : Pad
|
||||
{
|
||||
Panel panel;
|
||||
TextArea textArea;
|
||||
Scrollable scrollable;
|
||||
Drawable drawable;
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
Title = "Build Output";
|
||||
|
||||
panel = new Panel();
|
||||
|
||||
textArea = new TextArea();
|
||||
textArea.Wrap = false;
|
||||
textArea.ReadOnly = true;
|
||||
|
||||
scrollable = new Scrollable();
|
||||
scrollable.BackgroundColor = DrawInfo.BackColor;
|
||||
scrollable.ExpandContentWidth = true;
|
||||
scrollable.ExpandContentHeight = true;
|
||||
drawable = new Drawable();
|
||||
scrollable.Content = drawable;
|
||||
|
||||
panel.Content = textArea;
|
||||
CreateContent(panel);
|
||||
|
||||
drawable.MouseDown += Drawable_MouseDown;
|
||||
drawable.MouseMove += Drawable_MouseMove;
|
||||
drawable.MouseLeave += Drawable_MouseLeave;
|
||||
drawable.SizeChanged += Drawable_SizeChanged;
|
||||
drawable.Paint += Drawable_Paint;
|
||||
scrollable.SizeChanged += Scrollable1_SizeChanged;
|
||||
scrollable.Scroll += Scrollable1_Scroll;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using Eto.Drawing;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
static class DrawInfo
|
||||
{
|
||||
private static bool once;
|
||||
|
||||
public static int TextHeight;
|
||||
public static Color TextColor, BackColor, HoverTextColor, HoverBackColor, DisabledTextColor, BorderColor;
|
||||
|
||||
static DrawInfo()
|
||||
{
|
||||
TextHeight = (int)SystemFonts.Default().LineHeight;
|
||||
TextColor = SystemColors.ControlText;
|
||||
BackColor = SystemColors.ControlBackground;
|
||||
HoverTextColor = SystemColors.HighlightText;
|
||||
HoverBackColor = SystemColors.Highlight;
|
||||
DisabledTextColor = SystemColors.ControlText;
|
||||
DisabledTextColor.A = 0.4f;
|
||||
BorderColor = Global.Unix ? SystemColors.WindowBackground : SystemColors.Control;
|
||||
}
|
||||
|
||||
public static void SetPixelsPerPoint(Graphics g)
|
||||
{
|
||||
if (!once && !Global.Unix)
|
||||
{
|
||||
once = true;
|
||||
TextHeight = (int)(SystemFonts.Default().LineHeight * g.PixelsPerPoint + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
public static Color GetTextColor(bool selected, bool disabled)
|
||||
{
|
||||
if (disabled)
|
||||
return DisabledTextColor;
|
||||
|
||||
return selected ? HoverTextColor : TextColor;
|
||||
}
|
||||
|
||||
public static Color GetBackgroundColor(bool selected)
|
||||
{
|
||||
return selected ? HoverBackColor : BackColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public partial class Pad
|
||||
{
|
||||
public string Title
|
||||
{
|
||||
get { return label.Text; }
|
||||
set { label.Text = value; }
|
||||
}
|
||||
|
||||
public List<Command> Commands;
|
||||
private ContextMenu _contextMenu;
|
||||
|
||||
public Pad()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Commands = new List<Command>();
|
||||
_contextMenu = new ContextMenu();
|
||||
}
|
||||
|
||||
public virtual void LoadSettings()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void ImageSettings_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
_contextMenu.Show(imageSettings);
|
||||
}
|
||||
|
||||
public void CreateContent(Control control)
|
||||
{
|
||||
layout.AddRow(control);
|
||||
}
|
||||
|
||||
public void AddCommand(Command com)
|
||||
{
|
||||
imageSettings.Visible = true;
|
||||
|
||||
Commands.Add(com);
|
||||
_contextMenu.Items.Add(com.CreateMenuItem());
|
||||
}
|
||||
|
||||
public void AddCommand(RadioCommand com)
|
||||
{
|
||||
imageSettings.Visible = true;
|
||||
|
||||
Commands.Add(com);
|
||||
_contextMenu.Items.Add(com);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using Eto.Drawing;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
#if LINUX
|
||||
public partial class Pad : GroupBox
|
||||
#else
|
||||
public partial class Pad : Panel
|
||||
#endif
|
||||
{
|
||||
private DynamicLayout layout;
|
||||
private StackLayout stack;
|
||||
private ImageView imageSettings;
|
||||
private Panel panelLabel;
|
||||
private Label label;
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
layout = new DynamicLayout();
|
||||
|
||||
panelLabel = new Panel();
|
||||
panelLabel.Padding = new Padding(5);
|
||||
|
||||
if (!Global.Unix)
|
||||
panelLabel.Height = 25;
|
||||
|
||||
stack = new StackLayout();
|
||||
stack.Orientation = Orientation.Horizontal;
|
||||
|
||||
label = new Label();
|
||||
label.Font = new Font(label.Font.Family, label.Font.Size - 1, FontStyle.Bold);
|
||||
stack.Items.Add(new StackLayoutItem(label, true));
|
||||
|
||||
imageSettings = new ImageView();
|
||||
imageSettings.Image = Global.GetEtoIcon("Icons.Settings.png");
|
||||
imageSettings.Visible = false;
|
||||
stack.Items.Add(new StackLayoutItem(imageSettings, false));
|
||||
|
||||
panelLabel.Content = stack;
|
||||
|
||||
layout.AddRow(panelLabel);
|
||||
|
||||
Content = layout;
|
||||
|
||||
imageSettings.MouseDown += ImageSettings_MouseDown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Eto.Drawing;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public partial class ProjectControl : Pad
|
||||
{
|
||||
private TreeGridView _treeView;
|
||||
private Image _iconRoot;
|
||||
private TreeGridItem _treeBase, _treeRoot;
|
||||
private bool _rootExists;
|
||||
private ContextMenu _contextMenu;
|
||||
|
||||
public ProjectControl()
|
||||
{
|
||||
Title = "Project";
|
||||
_treeView = new TreeGridView();
|
||||
_treeView.ShowHeader = false;
|
||||
_treeView.AllowMultipleSelection = true;
|
||||
_treeView.Columns.Add(new GridColumn { DataCell = new ImageTextCell(0, 1), AutoSize = true });
|
||||
_treeView.DataStore = _treeBase = new TreeGridItem();
|
||||
CreateContent(_treeView);
|
||||
|
||||
_iconRoot = Bitmap.FromResource("TreeView.Root.png").WithSize(16, 16);
|
||||
|
||||
_treeView.SelectionChanged += TreeView_SelectedItemChanged;
|
||||
}
|
||||
|
||||
private void TreeView_SelectedItemChanged(object sender, EventArgs e)
|
||||
{
|
||||
var items = new List<IProjectItem>();
|
||||
|
||||
foreach (TreeGridItem selected in _treeView.SelectedItems)
|
||||
if (selected.Tag is IProjectItem)
|
||||
items.Add(selected.Tag as IProjectItem);
|
||||
|
||||
PipelineController.Instance.SelectionChanged(items);
|
||||
}
|
||||
|
||||
public void SetContextMenu(ContextMenu contextMenu)
|
||||
{
|
||||
_contextMenu = contextMenu;
|
||||
}
|
||||
|
||||
public void ExpandBase()
|
||||
{
|
||||
_treeRoot.Expanded = true;
|
||||
}
|
||||
|
||||
public void SetRoot(IProjectItem item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
_treeView.DataStore = _treeBase = new TreeGridItem();
|
||||
_rootExists = false;
|
||||
_treeView.ContextMenu = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_rootExists)
|
||||
{
|
||||
_treeRoot = new TreeGridItem();
|
||||
_treeBase.Children.Add(_treeRoot);
|
||||
|
||||
_rootExists = true;
|
||||
}
|
||||
|
||||
_treeRoot.SetValue(0, _iconRoot);
|
||||
_treeRoot.SetValue(1, item.Name);
|
||||
_treeRoot.Tag = item;
|
||||
_treeRoot.Expanded = true;
|
||||
|
||||
_treeView.ReloadItem(_treeRoot);
|
||||
_treeView.ContextMenu = _contextMenu;
|
||||
}
|
||||
|
||||
public void AddItem(IProjectItem citem)
|
||||
{
|
||||
AddItem(_treeRoot, citem, citem.DestinationPath, "");
|
||||
}
|
||||
|
||||
public void AddItem(TreeGridItem root, IProjectItem citem, string path, string currentPath)
|
||||
{
|
||||
var split = path.Split('/');
|
||||
var item = GetorAddItem(root, split.Length > 1 ? new DirectoryItem(split[0], currentPath) : citem);
|
||||
|
||||
if (path.Contains("/"))
|
||||
AddItem(item, citem, string.Join("/", split, 1, split.Length - 1), (currentPath + Path.DirectorySeparatorChar + split[0]));
|
||||
}
|
||||
|
||||
public void RemoveItem(IProjectItem item)
|
||||
{
|
||||
TreeGridItem titem;
|
||||
if (FindItem(_treeRoot, item.DestinationPath, out titem))
|
||||
{
|
||||
var parrent = titem.Parent as TreeGridItem;
|
||||
parrent.Children.Remove(titem);
|
||||
_treeView.ReloadItem(parrent);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateItem(IProjectItem item)
|
||||
{
|
||||
// Does nothing right now
|
||||
}
|
||||
|
||||
private bool FindItem(TreeGridItem root, string path, out TreeGridItem item)
|
||||
{
|
||||
var split = path.Split('/');
|
||||
|
||||
if (GetItem(root, split[0], out item))
|
||||
{
|
||||
if (split.Length != 1)
|
||||
return FindItem(item, string.Join("/", split, 1, split.Length - 1), out item);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool GetItem(TreeGridItem root, string text, out TreeGridItem item)
|
||||
{
|
||||
var enumerator = root.Children.GetEnumerator();
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
var citem = enumerator.Current as TreeGridItem;
|
||||
|
||||
if (citem.GetValue(1).ToString() == text)
|
||||
{
|
||||
item = citem;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
item = _treeRoot;
|
||||
return false;
|
||||
}
|
||||
|
||||
private TreeGridItem GetorAddItem(TreeGridItem root, IProjectItem item)
|
||||
{
|
||||
var enumerator = root.Children.GetEnumerator();
|
||||
var folder = item is DirectoryItem;
|
||||
|
||||
var items = new List<string>();
|
||||
int pos = 0;
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
var citem = enumerator.Current as TreeGridItem;
|
||||
|
||||
if (citem.GetValue(1).ToString() == Path.GetFileName(item.DestinationPath))
|
||||
return citem;
|
||||
|
||||
if (folder)
|
||||
{
|
||||
if (citem.Tag is DirectoryItem)
|
||||
items.Add(citem.GetValue(1).ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (citem.Tag is DirectoryItem)
|
||||
pos++;
|
||||
else
|
||||
items.Add(citem.GetValue(1).ToString());
|
||||
}
|
||||
}
|
||||
|
||||
items.Add(Path.GetFileName(item.DestinationPath));
|
||||
items.Sort();
|
||||
pos += items.IndexOf(Path.GetFileName(item.DestinationPath));
|
||||
|
||||
var ret = new TreeGridItem();
|
||||
|
||||
if (item is DirectoryItem)
|
||||
ret.SetValue(0, Global.GetEtoDirectoryIcon());
|
||||
else
|
||||
ret.SetValue(0, Global.GetEtoFileIcon(PipelineController.Instance.GetFullPath(item.OriginalPath), item.OriginalPath != item.DestinationPath));
|
||||
|
||||
ret.SetValue(1, Path.GetFileName(item.DestinationPath));
|
||||
ret.Tag = item;
|
||||
|
||||
root.Children.Insert(pos, ret);
|
||||
_treeView.ReloadItem(root);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using System;
|
||||
using Eto.Drawing;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)]
|
||||
public class CellAttribute : Attribute
|
||||
{
|
||||
public string Name;
|
||||
public Type Type;
|
||||
|
||||
public CellAttribute(Type type)
|
||||
{
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
|
||||
public class CellBase
|
||||
{
|
||||
public string Category { get; set; }
|
||||
public object Value { get; set; }
|
||||
public string DisplayValue { get; set; }
|
||||
public string Text { get; set; }
|
||||
public bool Editable { get; set; }
|
||||
public int Height { get; set; }
|
||||
public Action OnKill;
|
||||
|
||||
protected EventHandler _eventHandler;
|
||||
protected Rectangle _lastRec;
|
||||
protected Type _type;
|
||||
|
||||
public void Create(string category, string name, object value, Type type, EventHandler eventHandler = null)
|
||||
{
|
||||
Category = category;
|
||||
Value = value;
|
||||
DisplayValue = (value == null) ? "" : value.ToString();
|
||||
Text = name;
|
||||
Editable = true;
|
||||
Height = DrawInfo.TextHeight;
|
||||
|
||||
_eventHandler = eventHandler;
|
||||
_type = type;
|
||||
|
||||
OnCreate();
|
||||
}
|
||||
|
||||
public virtual void OnCreate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void Edit(PixelLayout control)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void Draw(Graphics g, Rectangle rec, int separatorPos, bool selected)
|
||||
{
|
||||
if (selected)
|
||||
g.FillRectangle(SystemColors.Highlight, rec);
|
||||
|
||||
g.DrawText(SystemFonts.Default(), DrawInfo.GetTextColor(selected, false), rec.X + 5, rec.Y + (rec.Height - Height) / 2, Text);
|
||||
g.FillRectangle(DrawInfo.GetBackgroundColor(selected), separatorPos - 6, rec.Y, rec.Width, rec.Height);
|
||||
DrawCell(g, rec, separatorPos, selected);
|
||||
}
|
||||
|
||||
public virtual void DrawCell(Graphics g, Rectangle rec, int separatorPos, bool selected)
|
||||
{
|
||||
_lastRec = rec;
|
||||
_lastRec.X += separatorPos;
|
||||
_lastRec.Width -= separatorPos - 1;
|
||||
|
||||
g.DrawText(SystemFonts.Default(), DrawInfo.GetTextColor(selected, !Editable), separatorPos + 5, rec.Y + (rec.Height - Height) / 2, DisplayValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using System;
|
||||
using Eto.Drawing;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
[CellAttribute(typeof(bool))]
|
||||
public class CellBool : CellBase
|
||||
{
|
||||
private bool _draw;
|
||||
|
||||
public CellBool()
|
||||
{
|
||||
_draw = true;
|
||||
}
|
||||
|
||||
public override void Edit(PixelLayout control)
|
||||
{
|
||||
_draw = false;
|
||||
|
||||
var checkbox = new CheckBox();
|
||||
checkbox.Tag = this;
|
||||
checkbox.Checked = (bool?)Value;
|
||||
checkbox.ThreeState = (Value == null);
|
||||
checkbox.Text = (checkbox.Checked == null) ? "Not Set" : checkbox.Checked.ToString();
|
||||
checkbox.Width = _lastRec.Width - 10;
|
||||
checkbox.Height = _lastRec.Height;
|
||||
control.Add(checkbox, _lastRec.X + 10, _lastRec.Y);
|
||||
|
||||
checkbox.CheckedChanged += (sender, e) => checkbox.Text = (checkbox.Checked == null) ? "Not Set" : checkbox.Checked.ToString();
|
||||
|
||||
OnKill += delegate
|
||||
{
|
||||
OnKill = null;
|
||||
|
||||
if (_eventHandler == null || checkbox.Checked == null)
|
||||
return;
|
||||
|
||||
_draw = true;
|
||||
Value = checkbox.Checked;
|
||||
_eventHandler(Value, EventArgs.Empty);
|
||||
};
|
||||
}
|
||||
|
||||
public override void DrawCell(Graphics g, Rectangle rec, int separatorPos, bool selected)
|
||||
{
|
||||
if (_draw)
|
||||
base.DrawCell(g, rec, separatorPos, selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using System;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
[CellAttribute(typeof(char))]
|
||||
public class CellChar : CellBase
|
||||
{
|
||||
public override void OnCreate()
|
||||
{
|
||||
DisplayValue = ((int)(char)Value) + " (" + Value + ")";
|
||||
}
|
||||
|
||||
public override void Edit(PixelLayout control)
|
||||
{
|
||||
var editText = new TextBox();
|
||||
editText.Tag = this;
|
||||
editText.Style = "OverrideSize";
|
||||
editText.Width = _lastRec.Width;
|
||||
editText.Height = _lastRec.Height;
|
||||
|
||||
char value;
|
||||
char.TryParse(Value.ToString(), out value);
|
||||
|
||||
editText.Text = ((int)value).ToString();
|
||||
|
||||
control.Add(editText, _lastRec.X, _lastRec.Y);
|
||||
|
||||
editText.Focus();
|
||||
editText.CaretIndex = editText.Text.Length;
|
||||
|
||||
OnKill += delegate
|
||||
{
|
||||
OnKill = null;
|
||||
|
||||
if (_eventHandler == null)
|
||||
return;
|
||||
|
||||
int num;
|
||||
if (!int.TryParse(editText.Text, out num))
|
||||
return;
|
||||
|
||||
_eventHandler((char)num, EventArgs.Empty);
|
||||
};
|
||||
|
||||
editText.KeyDown += (sender, e) =>
|
||||
{
|
||||
if (e.Key == Keys.Enter)
|
||||
OnKill.Invoke();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using System;
|
||||
using Eto.Drawing;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
[CellAttribute(typeof(Microsoft.Xna.Framework.Color))]
|
||||
public class CellColor : CellBase
|
||||
{
|
||||
private Color color;
|
||||
|
||||
public override void OnCreate()
|
||||
{
|
||||
if (Value != null)
|
||||
{
|
||||
var tmp = (Microsoft.Xna.Framework.Color)Value;
|
||||
color = new Color(tmp.R / 255f, tmp.G / 255f, tmp.B / 255f, tmp.A / 255f);
|
||||
}
|
||||
else
|
||||
color = new Color();
|
||||
}
|
||||
|
||||
public override void Edit(PixelLayout control)
|
||||
{
|
||||
var dialog = new ColorDialog();
|
||||
dialog.Color = color;
|
||||
|
||||
if (dialog.ShowDialog(control) == DialogResult.Ok && _eventHandler != null && dialog.Color != color)
|
||||
{
|
||||
var col = new Microsoft.Xna.Framework.Color(dialog.Color.Rb, dialog.Color.Gb, dialog.Color.Bb, dialog.Color.Ab);
|
||||
_eventHandler(col, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public override void DrawCell(Graphics g, Rectangle rec, int separatorPos, bool selected)
|
||||
{
|
||||
var border = rec.Height / 5;
|
||||
g.FillRectangle(color, separatorPos + border, rec.Y + border, rec.Width - separatorPos - 2 * border, rec.Height - 2 * border);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using System;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
[CellAttribute(typeof(Enum))]
|
||||
[CellAttribute(typeof(ImporterTypeDescription))]
|
||||
[CellAttribute(typeof(ProcessorTypeDescription))]
|
||||
public class CellCombo : CellBase
|
||||
{
|
||||
public override void OnCreate()
|
||||
{
|
||||
if (Value is ImporterTypeDescription)
|
||||
DisplayValue = (Value as ImporterTypeDescription).DisplayName;
|
||||
else if (Value is ProcessorTypeDescription)
|
||||
DisplayValue = (Value as ProcessorTypeDescription).DisplayName;
|
||||
}
|
||||
|
||||
public override void Edit(PixelLayout control)
|
||||
{
|
||||
var combo = new DropDown();
|
||||
|
||||
if (_type.IsSubclassOf(typeof(Enum)))
|
||||
{
|
||||
var values = Enum.GetValues(_type);
|
||||
foreach (var v in values)
|
||||
{
|
||||
combo.Items.Add(v.ToString());
|
||||
|
||||
if (Value != null && v.ToString() == Value.ToString())
|
||||
combo.SelectedIndex = combo.Items.Count - 1;
|
||||
}
|
||||
}
|
||||
else if (_type == typeof(ImporterTypeDescription))
|
||||
{
|
||||
foreach (var v in PipelineTypes.Importers)
|
||||
{
|
||||
combo.Items.Add(v.DisplayName);
|
||||
|
||||
if (Value != null && v.DisplayName == (Value as ImporterTypeDescription).DisplayName)
|
||||
combo.SelectedIndex = combo.Items.Count - 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var v in PipelineTypes.Processors)
|
||||
{
|
||||
combo.Items.Add(v.DisplayName);
|
||||
|
||||
if (Value != null && v.DisplayName == (Value as ProcessorTypeDescription).DisplayName)
|
||||
combo.SelectedIndex = combo.Items.Count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
combo.Style = "OverrideSize";
|
||||
combo.Width = _lastRec.Width;
|
||||
combo.Height = _lastRec.Height;
|
||||
control.Add(combo, _lastRec.X, _lastRec.Y);
|
||||
|
||||
combo.SelectedIndexChanged += delegate
|
||||
{
|
||||
if (_eventHandler == null || combo.SelectedIndex < 0)
|
||||
return;
|
||||
|
||||
if (_type.IsSubclassOf(typeof(Enum)))
|
||||
_eventHandler(Enum.Parse(_type, combo.SelectedValue.ToString()), EventArgs.Empty);
|
||||
else if (_type == typeof(ImporterTypeDescription))
|
||||
_eventHandler(PipelineTypes.Importers[combo.SelectedIndex], EventArgs.Empty);
|
||||
else
|
||||
_eventHandler(PipelineTypes.Processors[combo.SelectedIndex], EventArgs.Empty);
|
||||
|
||||
combo.Enabled = true;
|
||||
control.Add(combo, _lastRec.X, _lastRec.Y);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
[CellAttribute(typeof(short))]
|
||||
[CellAttribute(typeof(int))]
|
||||
[CellAttribute(typeof(long))]
|
||||
[CellAttribute(typeof(ushort))]
|
||||
[CellAttribute(typeof(uint))]
|
||||
[CellAttribute(typeof(ulong))]
|
||||
[CellAttribute(typeof(float))]
|
||||
[CellAttribute(typeof(double))]
|
||||
[CellAttribute(typeof(decimal))]
|
||||
public class CellNumber : CellBase
|
||||
{
|
||||
private TypeConverter _converter;
|
||||
|
||||
public override void OnCreate()
|
||||
{
|
||||
_converter = TypeDescriptor.GetConverter(_type);
|
||||
|
||||
if (_type == typeof(float) || _type == typeof(double) || _type == typeof(decimal))
|
||||
{
|
||||
if (_type == typeof(float))
|
||||
DisplayValue = ((float)Value).ToString("0.00");
|
||||
else if (_type == typeof(double))
|
||||
DisplayValue = ((double)Value).ToString("0.00");
|
||||
else
|
||||
DisplayValue = ((decimal)Value).ToString("0.00");
|
||||
|
||||
DisplayValue = (DisplayValue.Length > Value.ToString().Length) ? DisplayValue : Value.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Edit(PixelLayout control)
|
||||
{
|
||||
var editText = new TextBox();
|
||||
editText.Tag = this;
|
||||
editText.Style = "OverrideSize";
|
||||
editText.Width = _lastRec.Width;
|
||||
editText.Height = _lastRec.Height;
|
||||
editText.Text = DisplayValue;
|
||||
editText.Tag = this;
|
||||
|
||||
control.Add(editText, _lastRec.X, _lastRec.Y);
|
||||
|
||||
editText.Focus();
|
||||
editText.CaretIndex = editText.Text.Length;
|
||||
|
||||
OnKill += delegate
|
||||
{
|
||||
OnKill = null;
|
||||
|
||||
if (_eventHandler == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
_eventHandler(_converter.ConvertFrom(editText.Text), EventArgs.Empty);
|
||||
}
|
||||
catch { }
|
||||
};
|
||||
|
||||
editText.KeyDown += (sender, e) =>
|
||||
{
|
||||
if (e.Key == Keys.Enter)
|
||||
OnKill.Invoke();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using System;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
[CellAttribute(typeof(string), Name = "IntermediateDir")]
|
||||
[CellAttribute(typeof(string), Name = "OutputDir")]
|
||||
public class CellPath : CellBase
|
||||
{
|
||||
public override void OnCreate()
|
||||
{
|
||||
if (Value == null)
|
||||
Value = "";
|
||||
}
|
||||
|
||||
public override void Edit(PixelLayout control)
|
||||
{
|
||||
var dialog = new PathDialog(PipelineController.Instance, Value.ToString());
|
||||
if (dialog.ShowModal(control) && _eventHandler != null)
|
||||
_eventHandler(dialog.Path, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using Eto.Forms;
|
||||
using Eto.Drawing;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
[CellAttribute(typeof(List<string>), Name = "References")]
|
||||
public class CellRefs : CellBase
|
||||
{
|
||||
public override void OnCreate()
|
||||
{
|
||||
if (Value == null)
|
||||
Value = new List<string>();
|
||||
|
||||
var list = Value as List<string>;
|
||||
var displayValue = "";
|
||||
|
||||
foreach (var value in list)
|
||||
displayValue += Environment.NewLine + Path.GetFileNameWithoutExtension (value);
|
||||
|
||||
DisplayValue = (Value as List<string>).Count > 0 ? displayValue.Trim(Environment.NewLine.ToCharArray()) : "None";
|
||||
Height = Height * Math.Max(list.Count, 1);
|
||||
}
|
||||
|
||||
public override void Edit(PixelLayout control)
|
||||
{
|
||||
var dialog = new ReferenceDialog(PipelineController.Instance, (Value as List<string>).ToArray());
|
||||
if (dialog.ShowModal(control) && _eventHandler != null)
|
||||
{
|
||||
_eventHandler(dialog.References, EventArgs.Empty);
|
||||
PipelineController.Instance.OnReferencesModified();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using System;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
[CellAttribute(typeof(string))]
|
||||
public class CellText : CellBase
|
||||
{
|
||||
public override void Edit(PixelLayout control)
|
||||
{
|
||||
var editText = new TextBox();
|
||||
editText.Tag = this;
|
||||
editText.Style = "OverrideSize";
|
||||
editText.Width = _lastRec.Width;
|
||||
editText.Height = _lastRec.Height;
|
||||
editText.Text = (Value == null) ? "" : Value.ToString();
|
||||
|
||||
control.Add(editText, _lastRec.X, _lastRec.Y);
|
||||
|
||||
editText.Focus();
|
||||
editText.CaretIndex = editText.Text.Length;
|
||||
|
||||
OnKill += delegate
|
||||
{
|
||||
OnKill = null;
|
||||
|
||||
if (_eventHandler == null)
|
||||
return;
|
||||
|
||||
_eventHandler(editText.Text, EventArgs.Empty);
|
||||
};
|
||||
|
||||
editText.KeyDown += (sender, e) =>
|
||||
{
|
||||
if (e.Key == Keys.Enter)
|
||||
OnKill.Invoke();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.ComponentModel;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public partial class PropertyGridControl
|
||||
{
|
||||
private RadioCommand _cmdSortAbc, _cmdSortGroup;
|
||||
private List<object> _objects;
|
||||
|
||||
public PropertyGridControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_cmdSortAbc = new RadioCommand();
|
||||
_cmdSortAbc.MenuText = "Sort Alphabetically";
|
||||
_cmdSortAbc.CheckedChanged += CmdSort_CheckedChanged;
|
||||
AddCommand(_cmdSortAbc);
|
||||
|
||||
_cmdSortGroup = new RadioCommand();
|
||||
_cmdSortGroup.Controller = _cmdSortAbc;
|
||||
_cmdSortGroup.MenuText = "Sort by Category";
|
||||
_cmdSortGroup.CheckedChanged += CmdSort_CheckedChanged;
|
||||
AddCommand(_cmdSortGroup);
|
||||
|
||||
_objects = new List<object>();
|
||||
}
|
||||
|
||||
public override void LoadSettings()
|
||||
{
|
||||
if (PipelineSettings.Default.PropertyGroupSort)
|
||||
_cmdSortGroup.Checked = true;
|
||||
else
|
||||
_cmdSortAbc.Checked = true;
|
||||
}
|
||||
|
||||
private void CmdSort_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
PipelineSettings.Default.PropertyGroupSort = _cmdSortGroup.Checked;
|
||||
propertyTable.Group = _cmdSortGroup.Checked;
|
||||
propertyTable.Update();
|
||||
}
|
||||
|
||||
private void BtnGroup_Click(object sender, EventArgs e)
|
||||
{
|
||||
propertyTable.Group = true;
|
||||
propertyTable.Update();
|
||||
}
|
||||
|
||||
public void SetObjects(List<IProjectItem> objects)
|
||||
{
|
||||
_objects = objects.Cast<object>().ToList();
|
||||
Reload();
|
||||
}
|
||||
|
||||
public void Reload()
|
||||
{
|
||||
propertyTable.Clear();
|
||||
|
||||
if (_objects.Count != 0)
|
||||
LoadProps(_objects);
|
||||
|
||||
propertyTable.Update();
|
||||
}
|
||||
|
||||
private bool CompareVariables(ref object a, object b, PropertyInfo p)
|
||||
{
|
||||
var prop = b.GetType().GetProperty(p.Name);
|
||||
if (prop == null)
|
||||
return false;
|
||||
|
||||
if (a == null || !a.Equals(prop.GetValue(b, null)))
|
||||
a = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void LoadProps(List<object> objects)
|
||||
{
|
||||
var props = objects[0].GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
|
||||
|
||||
foreach (var p in props)
|
||||
{
|
||||
var attrs = p.GetCustomAttributes(true);
|
||||
var name = p.Name;
|
||||
var browsable = true;
|
||||
var category = "Mics";
|
||||
|
||||
foreach (var a in attrs)
|
||||
{
|
||||
if (a is BrowsableAttribute)
|
||||
browsable = (a as BrowsableAttribute).Browsable;
|
||||
else if (a is CategoryAttribute)
|
||||
category = (a as CategoryAttribute).Category;
|
||||
else if (a is DisplayNameAttribute)
|
||||
name = (a as DisplayNameAttribute).DisplayName;
|
||||
}
|
||||
|
||||
object value = p.GetValue(objects[0], null);
|
||||
foreach (object o in objects)
|
||||
{
|
||||
if (!CompareVariables(ref value, o, p))
|
||||
{
|
||||
browsable = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!browsable)
|
||||
continue;
|
||||
|
||||
propertyTable.AddEntry(category, name, value, p.PropertyType, (sender, e) =>
|
||||
{
|
||||
var action = new UpdatePropertyAction(MainWindow.Instance, objects, p, sender);
|
||||
PipelineController.Instance.AddAction(action);
|
||||
action.Do();
|
||||
}, p.CanWrite);
|
||||
|
||||
if (value is ProcessorTypeDescription)
|
||||
LoadProcessorParams(_objects.Cast<ContentItem>().ToList());
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadProcessorParams(List<ContentItem> objects)
|
||||
{
|
||||
foreach (var p in objects[0].Processor.Properties)
|
||||
{
|
||||
if (!p.Browsable)
|
||||
continue;
|
||||
|
||||
object value = objects[0].ProcessorParams[p.Name];
|
||||
foreach (ContentItem o in objects)
|
||||
{
|
||||
if (value == null || !value.Equals(o.ProcessorParams[p.Name]))
|
||||
{
|
||||
value = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
propertyTable.AddEntry("Processor Parameters", p.DisplayName, value, p.Type, (sender, e) =>
|
||||
{
|
||||
var action = new UpdateProcessorAction(MainWindow.Instance, objects.Cast<ContentItem>().ToList(), p.Name, sender);
|
||||
PipelineController.Instance.AddAction(action);
|
||||
action.Do();
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetWidth()
|
||||
{
|
||||
propertyTable.SetWidth();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
partial class PropertyGridControl : Pad
|
||||
{
|
||||
DynamicLayout layout;
|
||||
StackLayout subLayout;
|
||||
PropertyGridTable propertyTable;
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
Title = "Properties";
|
||||
|
||||
layout = new DynamicLayout();
|
||||
layout.BeginVertical();
|
||||
|
||||
subLayout = new StackLayout();
|
||||
subLayout.Orientation = Orientation.Horizontal;
|
||||
|
||||
layout.Add(subLayout);
|
||||
|
||||
propertyTable = new PropertyGridTable();
|
||||
layout.Add(propertyTable);
|
||||
|
||||
CreateContent(layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Eto.Drawing;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public partial class PropertyGridTable
|
||||
{
|
||||
private const int _spacing = 12;
|
||||
private const int _separatorWidth = 8;
|
||||
private const int _separatorSafeDistance = 30;
|
||||
|
||||
public bool Group { get; set; }
|
||||
|
||||
private IEnumerable<Type> _cellTypes;
|
||||
private CursorType _currentCursor;
|
||||
private CellBase _selectedCell;
|
||||
private List<CellBase> _cells;
|
||||
private Point _mouseLocation;
|
||||
private int _separatorPos;
|
||||
private int _moveSeparator;
|
||||
private int _height;
|
||||
private bool _skipEdit;
|
||||
|
||||
public PropertyGridTable()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_cellTypes = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsClass && t.IsSubclassOf(typeof(CellBase)));
|
||||
_separatorPos = 100;
|
||||
_mouseLocation = new Point(-1, -1);
|
||||
_cells = new List<CellBase>();
|
||||
_moveSeparator = -_separatorWidth / 2 - 1;
|
||||
_skipEdit = false;
|
||||
|
||||
Group = true;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_cells.Clear();
|
||||
ClearChildren();
|
||||
}
|
||||
|
||||
private bool ClearChildren()
|
||||
{
|
||||
var children = pixel1.Children.ToList();
|
||||
var ret = children.Count > 1;
|
||||
|
||||
foreach (var control in children)
|
||||
{
|
||||
if (control != drawable)
|
||||
{
|
||||
if (control.Tag is CellBase && (control.Tag as CellBase).OnKill != null)
|
||||
(control.Tag as CellBase).OnKill();
|
||||
|
||||
pixel1.Remove(control);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Type GetCellType(IEnumerable<Type> types, string name, Type type)
|
||||
{
|
||||
Type ret = null;
|
||||
|
||||
foreach (var ct in types)
|
||||
{
|
||||
var attrs = ct.GetCustomAttributes(typeof(CellAttribute), true);
|
||||
|
||||
foreach (CellAttribute a in attrs)
|
||||
{
|
||||
if (a.Type == type || type.IsSubclassOf(a.Type))
|
||||
{
|
||||
if (a.Name == name)
|
||||
{
|
||||
ret = ct;
|
||||
break;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(a.Name) && ret == null)
|
||||
ret = ct;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void AddEntry(string category, string name, object value, Type type, EventHandler eventHandler = null, bool editable = true)
|
||||
{
|
||||
var cellType = GetCellType(_cellTypes, name, type);
|
||||
|
||||
var cell = (cellType == null) ? new CellText() : (CellBase)Activator.CreateInstance(cellType);
|
||||
cell.Create(category, name, value, type, eventHandler);
|
||||
cell.Editable = (cellType != null) && editable;
|
||||
|
||||
_cells.Add(cell);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (Group)
|
||||
_cells.Sort((x, y) => string.Compare(x.Category + x.Text, y.Category + y.Text) + (x.Category.Contains("Proc") ? 100 : 0) + (y.Category.Contains("Proc") ? -100 : 0));
|
||||
else
|
||||
_cells.Sort((x, y) => string.Compare(x.Text, y.Text) + (x.Category.Contains("Proc") ? 100 : 0) + (y.Category.Contains("Proc") ? -100 : 0));
|
||||
|
||||
drawable.Invalidate();
|
||||
}
|
||||
|
||||
private void SetCursor(CursorType cursor)
|
||||
{
|
||||
if (_currentCursor != cursor)
|
||||
{
|
||||
_currentCursor = cursor;
|
||||
Cursor = new Cursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawGroup(Graphics g, Rectangle rec, string text)
|
||||
{
|
||||
var font = SystemFonts.Default();
|
||||
font = new Font(font.Family, font.Size, FontStyle.Bold);
|
||||
|
||||
g.FillRectangle(DrawInfo.BorderColor, rec);
|
||||
g.DrawText(SystemFonts.Default(), DrawInfo.TextColor, rec.X + 1, rec.Y + (rec.Height - font.LineHeight) / 2, text);
|
||||
}
|
||||
|
||||
private void Drawable_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
var g = e.Graphics;
|
||||
DrawInfo.SetPixelsPerPoint(g);
|
||||
var rec = new Rectangle(0, 0, drawable.Width - 1, DrawInfo.TextHeight + _spacing);
|
||||
var overGroup = false;
|
||||
string prevCategory = null;
|
||||
|
||||
_separatorPos = Math.Min(Width - _separatorSafeDistance, Math.Max(_separatorSafeDistance, _separatorPos));
|
||||
_selectedCell = null;
|
||||
|
||||
g.Clear(DrawInfo.BackColor);
|
||||
|
||||
if (_cells.Count == 0)
|
||||
{
|
||||
if (_height != 10)
|
||||
drawable.Height = _height = 10;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw separator for not filled rows
|
||||
g.FillRectangle(DrawInfo.BorderColor, _separatorPos - 1, 0, 1, Height);
|
||||
|
||||
foreach (var c in _cells)
|
||||
{
|
||||
rec.Height = c.Height + _spacing;
|
||||
|
||||
// Draw group
|
||||
if (prevCategory != c.Category)
|
||||
{
|
||||
if (c.Category.Contains("Proc") || Group)
|
||||
{
|
||||
DrawGroup(g, rec, c.Category);
|
||||
prevCategory = c.Category;
|
||||
overGroup |= rec.Contains(_mouseLocation);
|
||||
rec.Y += DrawInfo.TextHeight + _spacing;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw cell
|
||||
var selected = rec.Contains(_mouseLocation);
|
||||
if (selected)
|
||||
_selectedCell = c;
|
||||
c.Draw(g, rec, _separatorPos, selected);
|
||||
|
||||
// Draw separator for the current row
|
||||
g.FillRectangle(DrawInfo.BorderColor, _separatorPos - 1, rec.Y, 1, rec.Height);
|
||||
|
||||
rec.Y += c.Height + _spacing;
|
||||
}
|
||||
|
||||
if (_height != rec.Y + 1)
|
||||
{
|
||||
drawable.Height = _height = rec.Y + 1;
|
||||
SetWidth();
|
||||
}
|
||||
|
||||
if (overGroup) // TODO: Group collapsing/expanding?
|
||||
SetCursor(CursorType.Default);
|
||||
else if ((new Rectangle(_separatorPos - _separatorWidth / 2, 0, _separatorWidth, Height)).Contains(_mouseLocation))
|
||||
SetCursor(CursorType.VerticalSplit);
|
||||
else
|
||||
SetCursor(CursorType.Default);
|
||||
}
|
||||
|
||||
private void Drawable_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
_skipEdit = ClearChildren();
|
||||
if (_currentCursor == CursorType.VerticalSplit)
|
||||
_moveSeparator = (int)e.Location.X - _separatorPos;
|
||||
}
|
||||
|
||||
private void Drawable_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
_moveSeparator = -_separatorWidth / 2 - 1;
|
||||
|
||||
if (e.Location.X >= _separatorPos && _selectedCell != null && _selectedCell.Editable && !_skipEdit)
|
||||
{
|
||||
var action = new Action(() => _selectedCell.Edit(pixel1));
|
||||
|
||||
#if WINDOWS
|
||||
(drawable.ControlObject as System.Windows.Controls.Canvas).Dispatcher.BeginInvoke(action,
|
||||
System.Windows.Threading.DispatcherPriority.ContextIdle, null);
|
||||
#else
|
||||
action.Invoke();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private void Drawable_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
_mouseLocation = new Point((int)e.Location.X, (int)e.Location.Y);
|
||||
|
||||
if (_moveSeparator > -_separatorWidth / 2 - 1)
|
||||
_separatorPos = _moveSeparator + _mouseLocation.X;
|
||||
|
||||
drawable.Invalidate();
|
||||
}
|
||||
|
||||
private void Drawable_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
_mouseLocation = new Point(-1, -1);
|
||||
drawable.Invalidate();
|
||||
|
||||
_moveSeparator = -_separatorWidth / 2 - 1;
|
||||
}
|
||||
|
||||
private void PropertyGridTable_SizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
#if WINDOWS
|
||||
SetWidth();
|
||||
#endif
|
||||
|
||||
#if LINUX
|
||||
// force size reallocation
|
||||
drawable.Width = pixel1.Width - 2;
|
||||
|
||||
foreach (var child in pixel1.Children)
|
||||
if (child != drawable)
|
||||
child.Width = drawable.Width - _separatorPos;
|
||||
#endif
|
||||
|
||||
drawable.Invalidate();
|
||||
}
|
||||
|
||||
public void SetWidth()
|
||||
{
|
||||
#if WINDOWS
|
||||
var action = new Action(() =>
|
||||
{
|
||||
var scrollsize = (_height >= Height) ? System.Windows.SystemParameters.VerticalScrollBarWidth : 0.0;
|
||||
drawable.Width = (int)(Width - scrollsize - System.Windows.SystemParameters.BorderWidth * 2);
|
||||
|
||||
foreach (var child in pixel1.Children)
|
||||
if (child != drawable)
|
||||
child.Width = drawable.Width - _separatorPos;
|
||||
});
|
||||
|
||||
(drawable.ControlObject as System.Windows.Controls.Canvas).Dispatcher.BeginInvoke(action,
|
||||
System.Windows.Threading.DispatcherPriority.ContextIdle, null);
|
||||
|
||||
#elif MONOMAC
|
||||
drawable.Width = Width; // TODO: Subtract sctollbar size
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// MonoGame - Copyright (C) The MonoGame Team
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// file 'LICENSE.txt', which is part of this source code package.
|
||||
|
||||
using Eto.Drawing;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public partial class PropertyGridTable : Scrollable
|
||||
{
|
||||
PixelLayout pixel1;
|
||||
Drawable drawable;
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
BackgroundColor = DrawInfo.BackColor;
|
||||
|
||||
pixel1 = new PixelLayout();
|
||||
pixel1.BackgroundColor = DrawInfo.BackColor;
|
||||
|
||||
drawable = new Drawable();
|
||||
drawable.Height = 100;
|
||||
pixel1.Add(drawable, 0, 0);
|
||||
|
||||
Content = pixel1;
|
||||
|
||||
pixel1.Style = "Stretch";
|
||||
drawable.Style = "Stretch";
|
||||
|
||||
#if MONOMAC
|
||||
drawable.Width = 10;
|
||||
#endif
|
||||
|
||||
drawable.Paint += Drawable_Paint;
|
||||
drawable.MouseDown += Drawable_MouseDown;
|
||||
drawable.MouseUp += Drawable_MouseUp;
|
||||
drawable.MouseMove += Drawable_MouseMove;
|
||||
drawable.MouseLeave += Drawable_MouseLeave;
|
||||
SizeChanged += PropertyGridTable_SizeChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user