(ded4a3e0a) v0.9.0.7
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||
</startup>
|
||||
</configuration>
|
||||
|
After Width: | Height: | Size: 144 KiB |
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.18.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.16"/>
|
||||
<menu id="appmenu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Help</attribute>
|
||||
<attribute name="action">app.help</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_About</attribute>
|
||||
<attribute name="action">app.about</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Quit</attribute>
|
||||
<attribute name="action">app.quit</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
</interface>
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
// 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 System.Linq;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a stack of undo/redo-able actions.
|
||||
/// </summary>
|
||||
public class ActionStack
|
||||
{
|
||||
private readonly PipelineController _controller;
|
||||
private readonly List<IProjectAction> _undoStack;
|
||||
private readonly List<IProjectAction> _redoStack;
|
||||
|
||||
public bool CanUndo { get; private set; }
|
||||
public bool CanRedo { get; private set; }
|
||||
|
||||
public ActionStack(PipelineController controller)
|
||||
{
|
||||
_controller = controller;
|
||||
_undoStack = new List<IProjectAction>();
|
||||
_redoStack = new List<IProjectAction>();
|
||||
}
|
||||
|
||||
public void Add(IProjectAction action)
|
||||
{
|
||||
_undoStack.Add(action);
|
||||
|
||||
if (_redoStack.Count > 0)
|
||||
_redoStack.Clear();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void Undo()
|
||||
{
|
||||
if (!_undoStack.Any())
|
||||
return;
|
||||
|
||||
var action = _undoStack.Last();
|
||||
if (action.Undo())
|
||||
{
|
||||
_undoStack.Remove(action);
|
||||
_redoStack.Add(action);
|
||||
}
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void Redo()
|
||||
{
|
||||
if (!_redoStack.Any())
|
||||
return;
|
||||
|
||||
var action = _redoStack.Last();
|
||||
if (action.Do())
|
||||
{
|
||||
_redoStack.Remove(action);
|
||||
_undoStack.Add(action);
|
||||
}
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_undoStack.Clear();
|
||||
_redoStack.Clear();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
CanUndo = _undoStack.Any();
|
||||
CanRedo = _redoStack.Any();
|
||||
_controller.UpdateMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
// 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.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom converter for the Processor property of a ContentItem.
|
||||
/// </summary>
|
||||
public class ImporterConverter : TypeConverter
|
||||
{
|
||||
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
|
||||
{
|
||||
if (context.Instance is Array)
|
||||
{
|
||||
var array = context.Instance as Array;
|
||||
foreach (var obj in array)
|
||||
{
|
||||
var item = obj as ContentItem;
|
||||
if (item.BuildAction == BuildAction.Copy)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var contentItem = (context.Instance as ContentItem);
|
||||
if (contentItem.BuildAction == BuildAction.Copy)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
|
||||
{
|
||||
return PipelineTypes.ImportersStandardValuesCollection;
|
||||
}
|
||||
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||
{
|
||||
if (sourceType == typeof (string))
|
||||
return true;
|
||||
|
||||
return base.CanConvertFrom(context, sourceType);
|
||||
}
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
if (value is string)
|
||||
{
|
||||
var str = value as string;
|
||||
|
||||
foreach (var i in PipelineTypes.Importers)
|
||||
{
|
||||
if (i.DisplayName.Equals(str))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(str))
|
||||
return PipelineTypes.NullImporter;
|
||||
else
|
||||
return PipelineTypes.MissingImporter;
|
||||
}
|
||||
|
||||
return base.ConvertFrom(context, culture, value);
|
||||
}
|
||||
|
||||
|
||||
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
||||
{
|
||||
var importer = (ImporterTypeDescription)value;// contentItem.Importer;
|
||||
//System.Diagnostics.Debug.Assert(importer == value);
|
||||
|
||||
if (destinationType == typeof (string))
|
||||
{
|
||||
if (importer == PipelineTypes.MissingImporter)
|
||||
{
|
||||
var contentItem = (ContentItem)context.Instance;
|
||||
return string.Format("[missing] {0}", contentItem.ImporterName ?? "[null]");
|
||||
}
|
||||
|
||||
return ((ImporterTypeDescription)value).DisplayName;
|
||||
}
|
||||
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
|
||||
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
// 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.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom converter for the Processor property of a ContentItem.
|
||||
/// </summary>
|
||||
public class ProcessorConverter : TypeConverter
|
||||
{
|
||||
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
|
||||
{
|
||||
if (context.Instance is Array)
|
||||
{
|
||||
var array = context.Instance as Array;
|
||||
foreach (var obj in array)
|
||||
{
|
||||
var item = obj as ContentItem;
|
||||
if (item.BuildAction == BuildAction.Copy)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var contentItem = (context.Instance as ContentItem);
|
||||
if (contentItem.BuildAction == BuildAction.Copy)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
|
||||
{
|
||||
return PipelineTypes.ProcessorsStandardValuesCollection;
|
||||
}
|
||||
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||
{
|
||||
if (sourceType == typeof (string))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.CanConvertFrom(context, sourceType);
|
||||
}
|
||||
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
if (value is string)
|
||||
{
|
||||
foreach (var i in PipelineTypes.Processors)
|
||||
{
|
||||
if (i.DisplayName.Equals(value))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return base.ConvertFrom(context, culture, value);
|
||||
}
|
||||
|
||||
|
||||
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof (string))
|
||||
{
|
||||
var processor = (ProcessorTypeDescription)value;
|
||||
|
||||
if (processor == PipelineTypes.MissingProcessor)
|
||||
{
|
||||
var contentItem = context.Instance as ContentItem;
|
||||
return string.Format("[missing] {0}", contentItem.ProcessorName);
|
||||
}
|
||||
|
||||
return ((ProcessorTypeDescription)value).DisplayName;
|
||||
}
|
||||
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
|
||||
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
|
||||
{
|
||||
var props = new PropertyDescriptorCollection(null);
|
||||
|
||||
var processor = value as ProcessorTypeDescription;
|
||||
|
||||
if (context.Instance is Array)
|
||||
{
|
||||
var array = context.Instance as object[];
|
||||
|
||||
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(value, attributes, true))
|
||||
props.Add(new MultiTargetPropertyDescriptor(prop.Name, prop.PropertyType, prop.ComponentType, prop, array));
|
||||
|
||||
var paramArray = array.Select(e => ((ContentItem)e).ProcessorParams).ToArray();
|
||||
|
||||
foreach (var p in processor.Properties)
|
||||
{
|
||||
var prop = new OpaqueDataDictionaryElementPropertyDescriptor(p.Name,
|
||||
p.Type,
|
||||
null);
|
||||
var prop2 = new MultiTargetPropertyDescriptor(prop.Name,
|
||||
prop.PropertyType,
|
||||
prop.ComponentType,
|
||||
prop,
|
||||
paramArray);
|
||||
props.Add(prop2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var contentItem = context.Instance as ContentItem;
|
||||
|
||||
if (value == PipelineTypes.MissingProcessor)
|
||||
{
|
||||
|
||||
props.Add(new ReadonlyPropertyDescriptor("Name", typeof (string), typeof (ProcessorTypeDescription), contentItem.ProcessorName));
|
||||
|
||||
foreach (var p in contentItem.ProcessorParams)
|
||||
{
|
||||
var desc = new OpaqueDataDictionaryElementPropertyDescriptor(p.Key,
|
||||
p.Value.GetType(),
|
||||
contentItem.ProcessorParams);
|
||||
|
||||
|
||||
props.Add(desc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Emit regular properties.
|
||||
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(value, attributes, true))
|
||||
props.Add(prop);
|
||||
|
||||
// Emit processor parameters.
|
||||
foreach (var p in processor.Properties)
|
||||
{
|
||||
var desc = new OpaqueDataDictionaryElementPropertyDescriptor(p.Name,
|
||||
p.Type,
|
||||
contentItem.ProcessorParams);
|
||||
|
||||
props.Add(desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
|
||||
{
|
||||
if (!GetStandardValuesSupported(context))
|
||||
return false;
|
||||
|
||||
if (context.Instance is Array)
|
||||
{
|
||||
var array = (context.Instance as Array);
|
||||
var first = array.GetValue(0) as ContentItem;
|
||||
|
||||
if (!first.Processor.Properties.Any())
|
||||
return false;
|
||||
|
||||
if (first.Processor == PipelineTypes.MissingProcessor)
|
||||
return false;
|
||||
|
||||
for (var i = 1; i < array.Length; i++)
|
||||
{
|
||||
var item = array.GetValue(i) as ContentItem;
|
||||
if (item.Processor != first.Processor)
|
||||
return false;
|
||||
|
||||
if (!item.Processor.Properties.Any())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var item = context.Instance as ContentItem;
|
||||
if (item.BuildAction == BuildAction.Copy)
|
||||
return false;
|
||||
|
||||
if (!item.Processor.Properties.Any())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
// 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.ComponentModel;
|
||||
using System.Globalization;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline.Builder.Convertors;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public enum BuildAction
|
||||
{
|
||||
Build,
|
||||
Copy,
|
||||
}
|
||||
|
||||
public class ContentItem : IProjectItem
|
||||
{
|
||||
public IContentItemObserver Observer;
|
||||
|
||||
public string ImporterName;
|
||||
public string ProcessorName;
|
||||
public OpaqueDataDictionary ProcessorParams;
|
||||
|
||||
private ImporterTypeDescription _importer;
|
||||
private ProcessorTypeDescription _processor;
|
||||
private BuildAction _buildAction;
|
||||
|
||||
#region IProjectItem
|
||||
|
||||
[Browsable(false)]
|
||||
public string OriginalPath { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public string DestinationPath { get; set; }
|
||||
|
||||
[Category("Common")]
|
||||
[Description("The file name of this item.")]
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return System.IO.Path.GetFileName(OriginalPath);
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Common")]
|
||||
[Description("The folder where this item is located.")]
|
||||
public string Location
|
||||
{
|
||||
get
|
||||
{
|
||||
return System.IO.Path.GetDirectoryName(OriginalPath);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[Category("Settings")]
|
||||
[DisplayName("Build Action")]
|
||||
[Description("The way to process this content item.")]
|
||||
public BuildAction BuildAction
|
||||
{
|
||||
get { return _buildAction; }
|
||||
set
|
||||
{
|
||||
if (_buildAction == value)
|
||||
return;
|
||||
|
||||
_buildAction = value;
|
||||
|
||||
if (Observer != null)
|
||||
Observer.OnItemModified(this);
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Settings")]
|
||||
[Description("The importer used to load the content file.")]
|
||||
[TypeConverter(typeof(ImporterConverter))]
|
||||
public ImporterTypeDescription Importer
|
||||
{
|
||||
get { return _importer; }
|
||||
|
||||
set
|
||||
{
|
||||
if (_importer == value)
|
||||
return;
|
||||
|
||||
_importer = value;
|
||||
ImporterName = _importer.TypeName;
|
||||
|
||||
// Validate that our processor can accept input content of the type output by the new importer.
|
||||
if ((_processor == null || _processor.InputType != _importer.OutputType) && _processor != PipelineTypes.MissingProcessor)
|
||||
{
|
||||
// If it cannot, set the default processor.
|
||||
Processor = PipelineTypes.FindProcessor(_importer.DefaultProcessor, _importer);
|
||||
}
|
||||
|
||||
if (Observer != null)
|
||||
Observer.OnItemModified(this);
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Settings")]
|
||||
[Description("The processor used to transform the content for runtime use.")]
|
||||
[TypeConverter(typeof(ProcessorConverter))]
|
||||
public ProcessorTypeDescription Processor
|
||||
{
|
||||
get { return _processor; }
|
||||
|
||||
set
|
||||
{
|
||||
if (_processor == value)
|
||||
return;
|
||||
|
||||
_processor = value;
|
||||
ProcessorName = _processor.TypeName;
|
||||
|
||||
// When the processor changes reset our parameters
|
||||
// to the default for the processor type.
|
||||
ProcessorParams.Clear();
|
||||
foreach (var p in _processor.Properties)
|
||||
{
|
||||
ProcessorParams.Add(p.Name, p.DefaultValue);
|
||||
}
|
||||
|
||||
if (Observer != null)
|
||||
Observer.OnItemModified(this);
|
||||
|
||||
// Note:
|
||||
// There is no need to validate that the new processor can accept input
|
||||
// of the type output by our importer, because that should be handled by
|
||||
// only showing valid processors in the drop-down (eg, within ProcessConverter).
|
||||
}
|
||||
}
|
||||
|
||||
public void ResolveTypes()
|
||||
{
|
||||
if (BuildAction == BuildAction.Copy)
|
||||
{
|
||||
// Copy items do not have importers or processors.
|
||||
_importer = PipelineTypes.NullImporter;
|
||||
_processor = PipelineTypes.NullProcessor;
|
||||
}
|
||||
else
|
||||
{
|
||||
_importer = PipelineTypes.FindImporter(ImporterName, System.IO.Path.GetExtension(OriginalPath));
|
||||
if (_importer != null && (string.IsNullOrEmpty(ImporterName) || ImporterName != _importer.TypeName))
|
||||
ImporterName = _importer.TypeName;
|
||||
|
||||
if (_importer == null)
|
||||
_importer = PipelineTypes.MissingImporter;
|
||||
|
||||
_processor = PipelineTypes.FindProcessor(ProcessorName, _importer);
|
||||
if (_processor != null && (string.IsNullOrEmpty(ProcessorName) || ProcessorName != _processor.TypeName))
|
||||
ProcessorName = _processor.TypeName;
|
||||
|
||||
if (_processor == null)
|
||||
_processor = PipelineTypes.MissingProcessor;
|
||||
|
||||
// ProcessorParams get deserialized as strings
|
||||
// this code converts them to object(s) of their actual type
|
||||
// so that the correct editor appears within the property grid.
|
||||
foreach (var p in _processor.Properties)
|
||||
{
|
||||
if (!ProcessorParams.ContainsKey(p.Name))
|
||||
{
|
||||
ProcessorParams[p.Name] = p.DefaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
var src = ProcessorParams[p.Name];
|
||||
if (src != null)
|
||||
{
|
||||
var srcType = src.GetType();
|
||||
|
||||
var converter = PipelineTypes.FindConverter(p.Type);
|
||||
|
||||
// Should we throw an exception here?
|
||||
// This property will actually not be editable in the property grid
|
||||
// since we do not have a type converter for it.
|
||||
if (converter.CanConvertFrom(srcType))
|
||||
{
|
||||
var dst = converter.ConvertFrom(null, CultureInfo.InvariantCulture, src);
|
||||
ProcessorParams[p.Name] = dst;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return System.IO.Path.GetFileName(OriginalPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// 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.
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public class ContentItemTemplate
|
||||
{
|
||||
public string Label;
|
||||
public string Icon;
|
||||
public string ImporterName;
|
||||
public string ProcessorName;
|
||||
public string TemplateFile;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Label;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
// 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 Microsoft.Xna.Framework.Content.Pipeline;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
/// <summary>
|
||||
/// PropertyDescriptor for delegating get/set calls to more than one component (object).
|
||||
/// </summary>
|
||||
public class MultiTargetPropertyDescriptor : PropertyDescriptor
|
||||
{
|
||||
private readonly Type _propertyType;
|
||||
private readonly Type _componentType;
|
||||
private readonly object[] _targets;
|
||||
private readonly PropertyDescriptor _property;
|
||||
|
||||
public MultiTargetPropertyDescriptor(string propertyName, Type propertyType, Type componentType, PropertyDescriptor property, object[] targets)
|
||||
: base(propertyName, new Attribute[] { })
|
||||
{
|
||||
_propertyType = propertyType;
|
||||
_componentType = componentType;
|
||||
_targets = targets;
|
||||
_property = property;
|
||||
}
|
||||
|
||||
public override object GetValue(object component)
|
||||
{
|
||||
var val = _property.GetValue(_targets[0]);
|
||||
for (var i = 1; i < _targets.Length; i++)
|
||||
{
|
||||
var v = _property.GetValue(_targets[i]);
|
||||
if (!v.Equals(val))
|
||||
return null;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public override void SetValue(object component, object value)
|
||||
{
|
||||
for (var i = 0; i < _targets.Length; i++)
|
||||
_property.SetValue(_targets[i], value);
|
||||
}
|
||||
|
||||
public override bool CanResetValue(object component) { return true; }
|
||||
public override Type ComponentType { get { return _componentType; } }
|
||||
public override bool IsReadOnly { get { return false; } }
|
||||
public override Type PropertyType { get { return _propertyType; } }
|
||||
public override void ResetValue(object component) { SetValue(component, null); }
|
||||
public override bool ShouldSerializeValue(object component) { return true; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PropertyDescriptor for a named item within an OpaqueDataDictionary.
|
||||
/// </summary>
|
||||
public class OpaqueDataDictionaryElementPropertyDescriptor : PropertyDescriptor
|
||||
{
|
||||
private readonly Type _propertyType;
|
||||
private readonly Type _componentType;
|
||||
private readonly string _propertyName;
|
||||
private readonly OpaqueDataDictionary _target;
|
||||
|
||||
public OpaqueDataDictionaryElementPropertyDescriptor(string propertyName, Type propertyType, OpaqueDataDictionary target)
|
||||
: base(propertyName, new Attribute[] { })
|
||||
{
|
||||
_propertyType = propertyType;
|
||||
_propertyName = propertyName;
|
||||
_componentType = typeof(OpaqueDataDictionary);
|
||||
_target = target;
|
||||
}
|
||||
|
||||
public override object GetValue(object component)
|
||||
{
|
||||
var data = _target ?? (component as OpaqueDataDictionary);
|
||||
if (!data.ContainsKey(_propertyName))
|
||||
return string.Empty;
|
||||
|
||||
return data[_propertyName];
|
||||
}
|
||||
|
||||
public override void SetValue(object component, object value)
|
||||
{
|
||||
var data = _target ?? (component as OpaqueDataDictionary);
|
||||
data[_propertyName] = value;
|
||||
}
|
||||
|
||||
public override bool CanResetValue(object component) { return true; }
|
||||
public override Type ComponentType { get { return _componentType; } }
|
||||
public override bool IsReadOnly { get { return false; } }
|
||||
public override Type PropertyType { get { return _propertyType; } }
|
||||
public override void ResetValue(object component) { SetValue(component, null); }
|
||||
public override bool ShouldSerializeValue(object component) { return true; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PropertyDescriptor which has a fixed value.
|
||||
/// </summary>
|
||||
public class ReadonlyPropertyDescriptor : PropertyDescriptor
|
||||
{
|
||||
private readonly Type _propertyType;
|
||||
private readonly Type _componentType;
|
||||
private readonly object _value;
|
||||
|
||||
public ReadonlyPropertyDescriptor(string propertyName, Type propertyType, Type componentType, object value)
|
||||
: base(propertyName, new Attribute[] {})
|
||||
{
|
||||
_propertyType = propertyType;
|
||||
_componentType = componentType;
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public override object GetValue(object component)
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
public override bool CanResetValue(object component)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override Type ComponentType
|
||||
{
|
||||
get { return _componentType; }
|
||||
}
|
||||
|
||||
public override bool IsReadOnly
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override Type PropertyType
|
||||
{
|
||||
get { return _propertyType; }
|
||||
}
|
||||
|
||||
public override void ResetValue(object component)
|
||||
{
|
||||
}
|
||||
|
||||
public override void SetValue(object component, object value)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool ShouldSerializeValue(object component)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
// 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.ComponentModel;
|
||||
using System.IO;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public class DirectoryItem : IProjectItem
|
||||
{
|
||||
public DirectoryItem(string name, string location) : this(location + Path.DirectorySeparatorChar + name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public DirectoryItem(string path)
|
||||
{
|
||||
OriginalPath = path.Trim(Path.DirectorySeparatorChar).Replace(Path.DirectorySeparatorChar, '/');
|
||||
Exists = true;
|
||||
}
|
||||
|
||||
#region IProjectItem
|
||||
|
||||
[Browsable(false)]
|
||||
public string OriginalPath { get; set; }
|
||||
|
||||
[Category("Common")]
|
||||
[Description("The file name of this item.")]
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.GetFileName(OriginalPath);
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Common")]
|
||||
[Description("The folder where this item is located.")]
|
||||
public string Location
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.GetDirectoryName(OriginalPath);
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public bool Exists { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public bool ExpandToThis { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public bool SelectThis { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public string DestinationPath
|
||||
{
|
||||
get { return OriginalPath; }
|
||||
set { OriginalPath = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static bool NullOrEmpty(this IList list)
|
||||
{
|
||||
if (list == null || list.Count == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// 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.
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public enum FileType
|
||||
{
|
||||
Base,
|
||||
File,
|
||||
Folder
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
// 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;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public interface IContentItemObserver
|
||||
{
|
||||
void OnItemModified(ContentItem item);
|
||||
}
|
||||
|
||||
public interface IController : IContentItemObserver
|
||||
{
|
||||
/// <summary>
|
||||
/// Types of content which can be created and added to a project.
|
||||
/// </summary>
|
||||
IEnumerable<ContentItemTemplate> Templates { get; }
|
||||
|
||||
List<IProjectItem> SelectedItems { get; }
|
||||
|
||||
IProjectItem SelectedItem { get; }
|
||||
|
||||
PipelineProject ProjectItem { get; }
|
||||
|
||||
/// <summary>
|
||||
/// True if there is a project.
|
||||
/// </summary>
|
||||
bool ProjectOpen { get; }
|
||||
|
||||
/// <summary>
|
||||
/// True if the project has unsaved changes.
|
||||
/// </summary>
|
||||
bool ProjectDirty { get; }
|
||||
|
||||
/// <summary>
|
||||
/// True if the project is actively building.
|
||||
/// </summary>
|
||||
bool ProjectBuilding { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The view this controller is attached to.
|
||||
/// </summary>
|
||||
IView View { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when the project starts loading.
|
||||
/// </summary>
|
||||
event Action OnProjectLoading;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when the project finishes loading.
|
||||
/// </summary>
|
||||
event Action OnProjectLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// Notify controller that a property of Project or its contents has been modified.
|
||||
/// </summary>
|
||||
void OnProjectModified();
|
||||
|
||||
/// <summary>
|
||||
/// Notify controller that Project.References has been modified.
|
||||
/// </summary>
|
||||
void OnReferencesModified();
|
||||
|
||||
void NewProject();
|
||||
|
||||
void ImportProject();
|
||||
|
||||
void OpenProject();
|
||||
|
||||
void OpenProject(string projectFilePath);
|
||||
|
||||
void ClearRecentList();
|
||||
|
||||
void CloseProject();
|
||||
|
||||
bool SaveProject(bool saveAs);
|
||||
|
||||
void Build(bool rebuild);
|
||||
|
||||
void RebuildItems();
|
||||
|
||||
void Clean();
|
||||
|
||||
void CancelBuild();
|
||||
|
||||
bool Exit();
|
||||
|
||||
#region ContentItem
|
||||
|
||||
void DragDrop(string initialDirectory, string[] folders, string[] files);
|
||||
|
||||
void Include();
|
||||
|
||||
void IncludeFolder();
|
||||
|
||||
void Exclude(bool delete);
|
||||
|
||||
void NewItem();
|
||||
|
||||
void NewFolder();
|
||||
|
||||
void Rename();
|
||||
|
||||
void AddAction(IProjectAction action);
|
||||
|
||||
void SelectionChanged(List<IProjectItem> items);
|
||||
|
||||
IProjectItem GetItem(string originalPath);
|
||||
|
||||
void CopyAssetPath();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Undo, Redo
|
||||
|
||||
bool CanRedo { get; }
|
||||
|
||||
bool CanUndo { get; }
|
||||
|
||||
void Undo();
|
||||
|
||||
void Redo();
|
||||
|
||||
#endregion
|
||||
|
||||
string GetFullPath(string filePath);
|
||||
|
||||
string GetRelativePath(string filePath);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// 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.
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public interface IProjectAction
|
||||
{
|
||||
bool Do();
|
||||
bool Undo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// 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.
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public interface IProjectItem
|
||||
{
|
||||
string OriginalPath { get; set; }
|
||||
string Name { get; }
|
||||
string Location { get; }
|
||||
string DestinationPath { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// 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.
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public interface IProjectObserver
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// 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.Diagnostics;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public enum AskResult
|
||||
{
|
||||
Yes,
|
||||
No,
|
||||
Cancel
|
||||
}
|
||||
|
||||
public interface IView
|
||||
{
|
||||
void Attach(IController controller);
|
||||
|
||||
void Invoke(Action action);
|
||||
|
||||
AskResult AskSaveOrCancel();
|
||||
|
||||
bool AskSaveName(ref string filePath, string title);
|
||||
|
||||
bool AskOpenProject(out string projectFilePath);
|
||||
|
||||
bool AskImportProject(out string projectFilePath);
|
||||
|
||||
void ShowError(string title, string message);
|
||||
|
||||
void ShowMessage(string message);
|
||||
|
||||
bool ShowDeleteDialog(List<IProjectItem> items);
|
||||
|
||||
bool ShowEditDialog(string title, string text, string oldname, bool file, out string newname);
|
||||
|
||||
void BeginTreeUpdate();
|
||||
|
||||
void SetTreeRoot(IProjectItem item);
|
||||
|
||||
void AddTreeItem(IProjectItem item);
|
||||
|
||||
void RemoveTreeItem(IProjectItem item);
|
||||
|
||||
void UpdateTreeItem(IProjectItem item);
|
||||
|
||||
void EndTreeUpdate();
|
||||
|
||||
void UpdateProperties();
|
||||
|
||||
void OutputAppend(string text);
|
||||
|
||||
void OutputClear();
|
||||
|
||||
bool ChooseContentFile(string initialDirectory, out List<string> files);
|
||||
|
||||
bool ChooseContentFolder(string initialDirectory, out string folder);
|
||||
|
||||
bool ChooseItemTemplate(string folder, out ContentItemTemplate template, out string name);
|
||||
|
||||
bool CopyOrLinkFile(string file, bool exists, out IncludeType action, out bool applyforall);
|
||||
|
||||
bool CopyOrLinkFolder(string folder, bool exists, out IncludeType action, out bool applyforall);
|
||||
|
||||
Process CreateProcess(string exe, string commands);
|
||||
|
||||
void UpdateCommands(MenuInfo info);
|
||||
|
||||
void UpdateRecentList(List<string> recentList);
|
||||
|
||||
void SetClipboard(string text);
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public enum IncludeType
|
||||
{
|
||||
Skip,
|
||||
Copy,
|
||||
Link,
|
||||
Create
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This class is used for IncludeAction file handling.
|
||||
/// </summary>
|
||||
public class IncludeItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the source path.
|
||||
/// </summary>
|
||||
/// <value>The source path, should be an absolute path.</value>
|
||||
public string SourcePath { get; set; }
|
||||
|
||||
public IncludeType IncludeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the relative destination path.
|
||||
/// </summary>
|
||||
/// <value>The relative destination path.</value>
|
||||
public string RelativeDestPath { get; set; }
|
||||
|
||||
public bool IsDirectory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item template.
|
||||
///
|
||||
/// Only usefull if the action is create and the item is not a directory.
|
||||
/// </summary>
|
||||
/// <value>The item template.</value>
|
||||
public ContentItemTemplate ItemTemplate { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// 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.
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public class MenuInfo
|
||||
{
|
||||
public bool New { get; set; }
|
||||
|
||||
public bool Open { get; set; }
|
||||
|
||||
public bool Close { get; set; }
|
||||
|
||||
public bool Import { get; set; }
|
||||
|
||||
public bool Save { get; set; }
|
||||
|
||||
public bool SaveAs { get; set; }
|
||||
|
||||
public bool Exit { get; set; }
|
||||
|
||||
public bool Undo { get; set; }
|
||||
|
||||
public bool Redo { get; set; }
|
||||
|
||||
public bool Add { get; set; }
|
||||
|
||||
public bool Exclude { get; set; }
|
||||
|
||||
public bool Rename { get; set; }
|
||||
|
||||
public bool Delete { get; set; }
|
||||
|
||||
public bool BuildMenu { get; set; }
|
||||
|
||||
public bool Build { get; set; }
|
||||
|
||||
public bool Rebuild { get; set; }
|
||||
|
||||
public bool Clean { get; set; }
|
||||
|
||||
public bool Cancel { get; set; }
|
||||
|
||||
public bool Debug { get; set; }
|
||||
|
||||
public bool OpenItem { get; set; }
|
||||
|
||||
public bool OpenItemWith { get; set; }
|
||||
|
||||
public bool OpenItemLocation { get; set; }
|
||||
|
||||
public bool OpenOutputItemLocation { get; set; }
|
||||
|
||||
public bool CopyAssetPath { get; set; }
|
||||
|
||||
public bool RebuildItem { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
// 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.Text.RegularExpressions;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public enum OutputState
|
||||
{
|
||||
Initialized,
|
||||
BuildBegin,
|
||||
Cleaning,
|
||||
Skipping,
|
||||
BuildAsset,
|
||||
BuildError,
|
||||
BuildWarning,
|
||||
BuildErrorContinue,
|
||||
BuildEnd,
|
||||
BuildTime,
|
||||
BuildTerminated,
|
||||
|
||||
Unknown
|
||||
}
|
||||
|
||||
public class OutputParser
|
||||
{
|
||||
internal OutputState State { get; private set; }
|
||||
internal String Filename { get; private set; }
|
||||
internal String ErrorMessage { get; private set; }
|
||||
internal String BuildBeginTime { get; private set; }
|
||||
internal String BuildInfo { get; private set; }
|
||||
internal String BuildElapsedTime { get; private set; }
|
||||
|
||||
|
||||
Regex _reBuildBegin = new Regex(@"^(Build started)\W+(?<buildBeginTime>.*?)\r?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
Regex _reCleaning = new Regex(@"^(Cleaning)\W(?<filename>.*?)\r?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
Regex _reSkipping = new Regex(@"^(Skipping)\W(?<filename>.*?)\r?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
Regex _reBuildAsset = new Regex(@"^(?<filename>([a-zA-Z]:)?/.+?)\r?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
Regex _reBuildError = new Regex(@"^(?<filename>([a-zA-Z]:)?/.+?)\W*?:\W*?error\W*?:\W*(?<errorMessage>.*?)\r?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
Regex _reFileErrorWithLineNum = new Regex(@"^(?<filename>.+?)(\((?<line>[0-9]+),(?<column>[0-9]+)(-(?<columnEnd>[0-9]+))?\))?:\W*?(error)\W*(?<errorCode>[A-Z][0-9]+):\W*(?<errorMessage>.*?)\r?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
Regex _reFileWarningWithLineNum = new Regex(@"^(?<filename>.+?)(\((?<line>[0-9]+),(?<column>[0-9]+)(-(?<columnEnd>[0-9]+))?\))?:\W*?(warning)\W*(?<warningCode>[A-Z][0-9]+):\W*(?<warningMessage>.*?)\r?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
Regex _reFileError = new Regex(@"^(?<filename>([a-zA-Z]:)?/.+?)\W*?: (?<errorMessage>.*?)\r?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
Regex _reBuildEnd = new Regex(@"^(Build)\W+(?<buildInfo>.*?)\r?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
Regex _reBuildTime = new Regex(@"^(Time elapsed)\W+(?<buildElapsedTime>.*?)\.\r?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
|
||||
public OutputParser()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
internal void Reset()
|
||||
{
|
||||
State = OutputState.Initialized;
|
||||
Filename = null;
|
||||
BuildBeginTime = null;
|
||||
BuildInfo = null;
|
||||
BuildElapsedTime = null;
|
||||
ErrorMessage = null;
|
||||
}
|
||||
|
||||
internal void Parse(string text)
|
||||
{
|
||||
ParseLine(text);
|
||||
}
|
||||
|
||||
|
||||
private void ParseLine(string line)
|
||||
{
|
||||
/*
|
||||
* Line <-- BuildBegin
|
||||
* Line <-- BuildEnd
|
||||
* Line <-- BuildTime
|
||||
* Line <-- Cleaning
|
||||
* Line <-- Skipping
|
||||
* Line <-- BuildError (BuildErrorContinue)+
|
||||
* Line <-- BuildAsset
|
||||
* BuildBegin <-- "Build" "started" buildBeginTime
|
||||
* Cleaning <-- "Cleaning" filenane
|
||||
* Skipping <-- "Skipping" filenane
|
||||
* BuildAsset <-- filename
|
||||
* BuildError <-- filename ':' "Error" ':' errorMessage
|
||||
* BuildErrorContinue <-- errorMessage
|
||||
* BuildEnd <-- "Build" buildInfo
|
||||
* BuildTime <-- "Time" "elapsed" buildElapsedTime
|
||||
*/
|
||||
|
||||
var prevState = State;
|
||||
var prevFilename = Filename;
|
||||
|
||||
State = OutputState.Unknown;
|
||||
Filename = null;
|
||||
BuildBeginTime = null;
|
||||
BuildInfo = null;
|
||||
BuildElapsedTime = null;
|
||||
ErrorMessage = null;
|
||||
|
||||
if (line == "Build terminated!")
|
||||
{
|
||||
State = OutputState.BuildTerminated;
|
||||
}
|
||||
else if (_reBuildBegin.IsMatch(line))
|
||||
{
|
||||
State = OutputState.BuildBegin;
|
||||
var m = _reBuildBegin.Match(line);
|
||||
BuildBeginTime = m.Groups["buildBeginTime"].Value;
|
||||
}
|
||||
else if (_reBuildEnd.IsMatch(line))
|
||||
{
|
||||
State = OutputState.BuildEnd;
|
||||
var m = _reBuildEnd.Match(line);
|
||||
BuildInfo = m.Groups["buildInfo"].Value;
|
||||
}
|
||||
else if (_reBuildTime.IsMatch(line))
|
||||
{
|
||||
State = OutputState.BuildTime;
|
||||
var m = _reBuildTime.Match(line);
|
||||
BuildElapsedTime = m.Groups["buildElapsedTime"].Value;
|
||||
}
|
||||
else if (_reCleaning.IsMatch(line))
|
||||
{
|
||||
State = OutputState.Cleaning;
|
||||
var m = _reCleaning.Match(line);
|
||||
Filename = m.Groups["filename"].Value;
|
||||
}
|
||||
else if (_reSkipping.IsMatch(line))
|
||||
{
|
||||
State = OutputState.Skipping;
|
||||
var m = _reSkipping.Match(line);
|
||||
Filename = m.Groups["filename"].Value;
|
||||
}
|
||||
else if (_reBuildError.IsMatch(line))
|
||||
{
|
||||
State = OutputState.BuildError;
|
||||
var m = _reBuildError.Match(line);
|
||||
Filename = m.Groups["filename"].Value;
|
||||
ErrorMessage = m.Groups["errorMessage"].Value;
|
||||
}
|
||||
else if (_reFileErrorWithLineNum.IsMatch(line))
|
||||
{
|
||||
State = OutputState.BuildError;
|
||||
var m = _reFileErrorWithLineNum.Match(line);
|
||||
var lineNum = m.Groups["line"];
|
||||
var columnBegin = m.Groups["column"];
|
||||
var columnEnd = m.Groups["columnEnd"];
|
||||
var column = columnBegin.Value;
|
||||
if(columnEnd.Success)
|
||||
column += "-" + columnEnd.Value;
|
||||
var errorCode = m.Groups["errorCode"];
|
||||
Filename = m.Groups["filename"].Value.Replace("\\\\","/").Replace("\\", "/");
|
||||
ErrorMessage = string.Format("{0} ({1},{2}): {3}", errorCode, lineNum, column, m.Groups["errorMessage"].Value);
|
||||
}
|
||||
else if (_reFileWarningWithLineNum.IsMatch(line))
|
||||
{
|
||||
State = OutputState.BuildWarning;
|
||||
var m = _reFileWarningWithLineNum.Match(line);
|
||||
var lineNum = m.Groups["line"];
|
||||
var columnBegin = m.Groups["column"];
|
||||
var columnEnd = m.Groups["columnEnd"];
|
||||
var column = columnBegin.Value;
|
||||
if(columnEnd.Success)
|
||||
column += "-" + columnEnd.Value;
|
||||
var errorCode = m.Groups["warningCode"];
|
||||
Filename = m.Groups["filename"].Value.Replace("\\\\", "/").Replace("\\", "/");
|
||||
ErrorMessage = string.Format("{0} ({1},{2}): {3}", errorCode, lineNum, column, m.Groups["warningMessage"].Value);
|
||||
}
|
||||
else if (_reFileError.IsMatch(line))
|
||||
{
|
||||
State = OutputState.BuildError;
|
||||
var m = _reFileError.Match(line);
|
||||
Filename = m.Groups["filename"].Value;
|
||||
ErrorMessage = m.Groups["errorMessage"].Value;
|
||||
}
|
||||
else if (_reBuildAsset.IsMatch(line))
|
||||
{
|
||||
State = OutputState.BuildAsset;
|
||||
var m = _reBuildAsset.Match(line);
|
||||
Filename = m.Groups["filename"].Value;
|
||||
}
|
||||
else if (prevState == OutputState.BuildError || prevState == OutputState.BuildErrorContinue)
|
||||
{
|
||||
State = OutputState.BuildErrorContinue;
|
||||
Filename = prevFilename;
|
||||
ErrorMessage = line.TrimEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
State = OutputState.Unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
// 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 System.Linq;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public partial class PipelineController
|
||||
{
|
||||
private class ExcludeAction : IProjectAction
|
||||
{
|
||||
private readonly PipelineController _con;
|
||||
private readonly List<IProjectItem> _items;
|
||||
private readonly List<ContentItem> _subitems;
|
||||
private readonly bool _delete;
|
||||
|
||||
public ExcludeAction(PipelineController controller, List<IProjectItem> items, bool delete)
|
||||
{
|
||||
_items = new List<IProjectItem>();
|
||||
_subitems = new List<ContentItem>();
|
||||
|
||||
_con = controller;
|
||||
_items.AddRange(items);
|
||||
_delete = delete;
|
||||
|
||||
foreach (var item in items)
|
||||
if (item is DirectoryItem)
|
||||
foreach (var citem in _con._project.ContentItems)
|
||||
if (citem.OriginalPath.StartsWith(item.OriginalPath))
|
||||
_subitems.Add(citem);
|
||||
}
|
||||
|
||||
public bool Do()
|
||||
{
|
||||
_con.View.BeginTreeUpdate();
|
||||
|
||||
foreach (var item in _items)
|
||||
{
|
||||
if (item is ContentItem)
|
||||
_con._project.ContentItems.Remove(item as ContentItem);
|
||||
_con.View.RemoveTreeItem(item);
|
||||
|
||||
if (_delete)
|
||||
{
|
||||
// Only delete if the item is in the project folder, otherwise we may (and have done!) delete files/folders outside of the project
|
||||
if (!item.OriginalPath.Contains(".."))
|
||||
{
|
||||
var fullItemPath = _con.GetFullPath(item.OriginalPath);
|
||||
try
|
||||
{
|
||||
if (item is DirectoryItem)
|
||||
Directory.Delete(_con.GetFullPath(item.OriginalPath), true);
|
||||
else
|
||||
File.Delete(_con.GetFullPath(item.OriginalPath));
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
// No error needed in case file is not found
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_con.View.ShowError("Error while trying to delete the file", ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var sitem in _subitems)
|
||||
_con._project.ContentItems.Remove(sitem);
|
||||
|
||||
//Since these items are removed from the project, manually clear the selection
|
||||
_con.SelectedItems.Clear();
|
||||
_con.SelectionChanged(_con.SelectedItems);
|
||||
|
||||
_con.View.EndTreeUpdate();
|
||||
_con.ProjectDirty = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Undo()
|
||||
{
|
||||
if (_delete)
|
||||
return false;
|
||||
|
||||
_con.View.BeginTreeUpdate();
|
||||
|
||||
foreach (var item in _items)
|
||||
{
|
||||
if(item is ContentItem)
|
||||
_con._project.ContentItems.Add(item as ContentItem);
|
||||
_con.View.AddTreeItem(item);
|
||||
}
|
||||
|
||||
foreach (var item in _subitems)
|
||||
{
|
||||
_con._project.ContentItems.Add(item);
|
||||
_con.View.AddTreeItem(item);
|
||||
}
|
||||
|
||||
_con.View.EndTreeUpdate();
|
||||
_con.ProjectDirty = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
// 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 System.IO;
|
||||
using System;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public partial class PipelineController
|
||||
{
|
||||
private class IncludeAction : IProjectAction
|
||||
{
|
||||
private readonly PipelineController _con;
|
||||
private readonly List<IncludeItem> _includes;
|
||||
private readonly List<IProjectItem> _items;
|
||||
private bool _firsttime;
|
||||
|
||||
public IncludeAction(List<IncludeItem> includes)
|
||||
{
|
||||
_items = new List<IProjectItem>();
|
||||
_con = Instance;
|
||||
_includes = includes;
|
||||
_firsttime = true;
|
||||
}
|
||||
|
||||
public IncludeAction(IncludeItem item) : this(new List<IncludeItem> { item })
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepares the item list and creates all the neccecary files.
|
||||
/// </summary>
|
||||
public void FirstDo()
|
||||
{
|
||||
var parser = new PipelineProjectParser(_con, _con._project);
|
||||
|
||||
for (int i = 0; i < _includes.Count; i++)
|
||||
{
|
||||
var item = _includes[i].IsDirectory ?
|
||||
(IProjectItem)new DirectoryItem("") : new ContentItem();
|
||||
|
||||
if (_includes[i].IncludeType == IncludeType.Create ||
|
||||
_includes[i].IncludeType == IncludeType.Link)
|
||||
{
|
||||
item.OriginalPath = Util.GetRelativePath(_includes[i].SourcePath, _con.ProjectLocation);
|
||||
item.DestinationPath = _includes[i].RelativeDestPath;
|
||||
|
||||
if (_includes[i].IncludeType == IncludeType.Create)
|
||||
{
|
||||
if (_includes[i].IsDirectory)
|
||||
Directory.CreateDirectory(_includes[i].SourcePath);
|
||||
else
|
||||
{
|
||||
var conitem = item as ContentItem;
|
||||
var template = _includes[i].ItemTemplate;
|
||||
|
||||
conitem.ImporterName = template.ImporterName;
|
||||
conitem.ProcessorName = template.ProcessorName;
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(_includes[i].SourcePath));
|
||||
File.Copy(template.TemplateFile, _includes[i].SourcePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!_includes[i].IsDirectory) // This is only a valid action for files
|
||||
{
|
||||
var sourcePath = _includes[i].SourcePath;
|
||||
var destPath = Path.Combine(_con.ProjectLocation, _includes[i].RelativeDestPath);
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destPath));
|
||||
File.Copy(sourcePath, destPath);
|
||||
|
||||
item.OriginalPath = item.DestinationPath = _includes[i].RelativeDestPath;
|
||||
}
|
||||
|
||||
var citem = item as ContentItem;
|
||||
if (citem != null)
|
||||
{
|
||||
citem.ProcessorParams = new Microsoft.Xna.Framework.Content.Pipeline.OpaqueDataDictionary();
|
||||
citem.Observer = _con;
|
||||
|
||||
citem.ResolveTypes();
|
||||
}
|
||||
|
||||
// Always keep Unix slashes in the .mgcb files for cross platform compatibility
|
||||
item.OriginalPath = item.OriginalPath.Replace('\\', '/');
|
||||
item.DestinationPath = item.DestinationPath.Replace('\\', '/');
|
||||
|
||||
_items.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Do()
|
||||
{
|
||||
if (_firsttime)
|
||||
{
|
||||
// Generate file list and populate item list
|
||||
_firsttime = false;
|
||||
|
||||
try
|
||||
{
|
||||
FirstDo();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_con.View.ShowError(
|
||||
"Include Action Error",
|
||||
"The include action has failed for the following reason: " +
|
||||
Environment.NewLine + ex
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_con.View.BeginTreeUpdate();
|
||||
|
||||
foreach (var item in _items)
|
||||
{
|
||||
if (item is ContentItem)
|
||||
_con._project.ContentItems.Add(item as ContentItem);
|
||||
|
||||
_con.View.AddTreeItem(item);
|
||||
}
|
||||
|
||||
_con.View.EndTreeUpdate();
|
||||
_con.ProjectDirty = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Undo()
|
||||
{
|
||||
_con.View.BeginTreeUpdate();
|
||||
|
||||
foreach (var item in _items)
|
||||
{
|
||||
if (item is ContentItem)
|
||||
_con._project.ContentItems.Remove(item as ContentItem);
|
||||
|
||||
_con.View.RemoveTreeItem(item);
|
||||
}
|
||||
|
||||
_con.View.EndTreeUpdate();
|
||||
_con.ProjectDirty = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// 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.IO;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public partial class PipelineController
|
||||
{
|
||||
private class MoveAction : IProjectAction
|
||||
{
|
||||
private IProjectItem _item;
|
||||
private readonly PipelineController _con;
|
||||
private string _oldname, _newname;
|
||||
|
||||
public MoveAction(IProjectItem item, string newname)
|
||||
{
|
||||
_con = PipelineController.Instance;
|
||||
_oldname = Path.GetFileName(item.OriginalPath);
|
||||
_newname = newname;
|
||||
_item = item;
|
||||
}
|
||||
|
||||
public bool Do()
|
||||
{
|
||||
_con.View.RemoveTreeItem(_item);
|
||||
var folder = Path.GetDirectoryName(_item.DestinationPath);
|
||||
_item.DestinationPath = Path.Combine(folder, _newname).Replace('\\', '/');
|
||||
_con.View.AddTreeItem(_item);
|
||||
_con.ProjectDirty = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Undo()
|
||||
{
|
||||
_con.View.RemoveTreeItem(_item);
|
||||
var folder = Path.GetDirectoryName(_item.DestinationPath);
|
||||
_item.DestinationPath = Path.Combine(folder, _oldname).Replace('\\', '/');
|
||||
_con.View.AddTreeItem(_item);
|
||||
_con.ProjectDirty = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.Collections.Generic;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public class UpdateProcessorAction : IProjectAction
|
||||
{
|
||||
private readonly IView _view;
|
||||
private readonly List<ContentItem> _objects;
|
||||
private readonly string _property;
|
||||
|
||||
private List<object> _values;
|
||||
|
||||
public UpdateProcessorAction(IView view, List<ContentItem> objects, string property, object value)
|
||||
{
|
||||
_view = view;
|
||||
_objects = objects;
|
||||
_property = property;
|
||||
|
||||
_values = new List<object>();
|
||||
for (int i = 0; i < _objects.Count; i++)
|
||||
_values.Add(value);
|
||||
}
|
||||
|
||||
public bool Do()
|
||||
{
|
||||
Toggle();
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Undo()
|
||||
{
|
||||
Toggle();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void Toggle()
|
||||
{
|
||||
var oldValues = new List<object>();
|
||||
|
||||
for (int i = 0; i < _objects.Count; i++)
|
||||
{
|
||||
var obj = _objects[i];
|
||||
|
||||
oldValues.Add(obj.ProcessorParams[_property]);
|
||||
obj.ProcessorParams[_property] = _values[i];
|
||||
}
|
||||
|
||||
_view.UpdateProperties();
|
||||
_values = oldValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public class UpdatePropertyAction : IProjectAction
|
||||
{
|
||||
private readonly IView _view;
|
||||
private readonly List<object> _objects;
|
||||
private readonly PropertyInfo _property;
|
||||
|
||||
private List<object> _values;
|
||||
|
||||
public UpdatePropertyAction(IView view, List<object> objects, PropertyInfo property, object value)
|
||||
{
|
||||
_view = view;
|
||||
_objects = objects;
|
||||
_property = property;
|
||||
|
||||
_values = new List<object>();
|
||||
for (int i = 0; i < _objects.Count; i++)
|
||||
_values.Add(value);
|
||||
}
|
||||
|
||||
public bool Do()
|
||||
{
|
||||
Toggle();
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Undo()
|
||||
{
|
||||
Toggle();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void Toggle()
|
||||
{
|
||||
var oldValues = new List<object>();
|
||||
|
||||
for (int i = 0; i < _objects.Count; i++)
|
||||
{
|
||||
var obj = _objects[i];
|
||||
|
||||
oldValues.Add(_property.GetValue(obj, null));
|
||||
_property.SetValue(obj, _values[i], null);
|
||||
}
|
||||
|
||||
_view.UpdateProperties();
|
||||
_values = oldValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// 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.ComponentModel;
|
||||
using System.IO;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public class PipelineProject : IProjectItem
|
||||
{
|
||||
[Browsable(false)]
|
||||
public string OriginalPath { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public string DestinationPath { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public List<ContentItem> ContentItems { get; private set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public bool LaunchDebugger { get; set; }
|
||||
|
||||
public string OutputDir { get; set; }
|
||||
|
||||
public string IntermediateDir { get; set; }
|
||||
|
||||
public List<string> References { get; set; }
|
||||
|
||||
public TargetPlatform Platform { get; set; }
|
||||
|
||||
public GraphicsProfile Profile { get; set; }
|
||||
|
||||
public string Config { get; set; }
|
||||
|
||||
public bool Compress { get; set; }
|
||||
|
||||
#region IPipelineItem
|
||||
|
||||
[Category("Common")]
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(OriginalPath))
|
||||
return "";
|
||||
|
||||
return System.IO.Path.GetFileNameWithoutExtension(OriginalPath);
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Common")]
|
||||
public string Location
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(OriginalPath))
|
||||
return "";
|
||||
|
||||
var idx = OriginalPath.LastIndexOfAny(new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar}, OriginalPath.Length - 1);
|
||||
return OriginalPath.Remove(idx);
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public bool Exists { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public bool ExpandToThis { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public bool SelectThis { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
public PipelineProject()
|
||||
{
|
||||
ContentItems = new List<ContentItem>();
|
||||
References = new List<string>();
|
||||
OutputDir = "bin";
|
||||
IntermediateDir = "obj";
|
||||
Exists = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,586 @@
|
||||
// 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.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using MGCB;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using PathHelper = MonoGame.Framework.Content.Pipeline.Builder.PathHelper;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public class PipelineProjectParser
|
||||
{
|
||||
#region Other Data
|
||||
|
||||
private readonly PipelineProject _project;
|
||||
private readonly IContentItemObserver _observer;
|
||||
private readonly OpaqueDataDictionary _processorParams = new OpaqueDataDictionary();
|
||||
|
||||
private string _processor;
|
||||
|
||||
#endregion
|
||||
|
||||
#region CommandLineParameters
|
||||
|
||||
[CommandLineParameter(
|
||||
Name = "outputDir",
|
||||
ValueName = "directoryPath",
|
||||
Description = "The directory where all content is written.")]
|
||||
public string OutputDir { set { _project.OutputDir = value; } }
|
||||
|
||||
[CommandLineParameter(
|
||||
Name = "intermediateDir",
|
||||
ValueName = "directoryPath",
|
||||
Description = "The directory where all intermediate files are written.")]
|
||||
public string IntermediateDir { set { _project.IntermediateDir = value; } }
|
||||
|
||||
[CommandLineParameter(
|
||||
Name = "reference",
|
||||
ValueName = "assemblyNameOrFile",
|
||||
Description = "Adds an assembly reference for resolving content importers, processors, and writers.")]
|
||||
public List<string> References
|
||||
{
|
||||
set { _project.References = value; }
|
||||
get { return _project.References; }
|
||||
}
|
||||
|
||||
[CommandLineParameter(
|
||||
Name = "platform",
|
||||
ValueName = "targetPlatform",
|
||||
Description = "Set the target platform for this build. Defaults to Windows.")]
|
||||
public TargetPlatform Platform { set { _project.Platform = value; } }
|
||||
|
||||
[CommandLineParameter(
|
||||
Name = "profile",
|
||||
ValueName = "graphicsProfile",
|
||||
Description = "Set the target graphics profile for this build. Defaults to HiDef.")]
|
||||
public GraphicsProfile Profile { set { _project.Profile = value; } }
|
||||
|
||||
[CommandLineParameter(
|
||||
Name = "config",
|
||||
ValueName = "string",
|
||||
Description = "The optional build config string from the build system.")]
|
||||
public string Config { set { _project.Config = value; } }
|
||||
|
||||
#pragma warning disable 414
|
||||
|
||||
// Allow a MGCB file containing the /rebuild parameter to be imported without error
|
||||
[CommandLineParameter(
|
||||
Name = "rebuild",
|
||||
ValueName = "bool",
|
||||
Description = "Forces a rebuild of the project.")]
|
||||
public bool Rebuild { set { _rebuild = value; } }
|
||||
private bool _rebuild;
|
||||
|
||||
// Allow a MGCB file containing the /clean parameter to be imported without error
|
||||
[CommandLineParameter(
|
||||
Name = "clean",
|
||||
ValueName = "bool",
|
||||
Description = "Removes intermediate and output files.")]
|
||||
public bool Clean { set { _clean = value; } }
|
||||
private bool _clean;
|
||||
|
||||
#pragma warning restore 414
|
||||
|
||||
[CommandLineParameter(
|
||||
Name = "compress",
|
||||
ValueName = "bool",
|
||||
Description = "Content files can be compressed for smaller file sizes.")]
|
||||
public bool Compress { set { _project.Compress = value; } }
|
||||
|
||||
[CommandLineParameter(
|
||||
Name = "importer",
|
||||
ValueName = "className",
|
||||
Description = "Defines the class name of the content importer for reading source content.")]
|
||||
public string Importer;
|
||||
|
||||
[CommandLineParameter(
|
||||
Name = "processor",
|
||||
ValueName = "className",
|
||||
Description = "Defines the class name of the content processor for processing imported content.")]
|
||||
public string Processor
|
||||
{
|
||||
get { return _processor; }
|
||||
set
|
||||
{
|
||||
_processor = value;
|
||||
_processorParams.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandLineParameter(
|
||||
Name = "processorParam",
|
||||
ValueName = "name=value",
|
||||
Description = "Defines a parameter name and value to set on a content processor.")]
|
||||
public void AddProcessorParam(string nameAndValue)
|
||||
{
|
||||
var keyAndValue = nameAndValue.Split('=');
|
||||
if (keyAndValue.Length != 2)
|
||||
{
|
||||
// Do we error out or something?
|
||||
return;
|
||||
}
|
||||
|
||||
_processorParams.Remove(keyAndValue[0]);
|
||||
_processorParams.Add(keyAndValue[0], keyAndValue[1]);
|
||||
}
|
||||
|
||||
[CommandLineParameter(
|
||||
Name = "build",
|
||||
ValueName = "sourceFile",
|
||||
Description = "Build the content source file using the previously set switches and options.")]
|
||||
public void OnBuild(string sourceFile)
|
||||
{
|
||||
AddContent(sourceFile, false);
|
||||
}
|
||||
|
||||
[CommandLineParameter(
|
||||
Name = "launchDebugger",
|
||||
ValueName = "sourceFile")]
|
||||
public void OnDebug()
|
||||
{
|
||||
_project.LaunchDebugger = true;
|
||||
}
|
||||
|
||||
public bool AddContent(string sourceFile, bool skipDuplicates)
|
||||
{
|
||||
string link = null;
|
||||
|
||||
if (sourceFile.Contains(";"))
|
||||
{
|
||||
var split = sourceFile.Split(';');
|
||||
sourceFile = split[0];
|
||||
|
||||
if (split.Length > 0)
|
||||
link = split[1];
|
||||
}
|
||||
|
||||
// Make sure the source file is relative to the project.
|
||||
var projectDir = ProjectDirectory + Path.DirectorySeparatorChar;
|
||||
|
||||
sourceFile = PathHelper.GetRelativePath(projectDir, sourceFile);
|
||||
|
||||
// Do we have a duplicate?
|
||||
var previous = _project.ContentItems.FindIndex(e => string.Equals(e.OriginalPath, sourceFile, StringComparison.InvariantCultureIgnoreCase));
|
||||
if (previous != -1)
|
||||
{
|
||||
if (skipDuplicates)
|
||||
return false;
|
||||
|
||||
// Replace the duplicate.
|
||||
_project.ContentItems.RemoveAt(previous);
|
||||
}
|
||||
|
||||
// Create the item for processing later.
|
||||
var item = new ContentItem
|
||||
{
|
||||
Observer = _observer,
|
||||
BuildAction = BuildAction.Build,
|
||||
OriginalPath = sourceFile,
|
||||
DestinationPath = string.IsNullOrEmpty(link) ? sourceFile : link,
|
||||
ImporterName = Importer,
|
||||
ProcessorName = Processor,
|
||||
ProcessorParams = new OpaqueDataDictionary()
|
||||
};
|
||||
_project.ContentItems.Add(item);
|
||||
|
||||
// Copy the current processor parameters blind as we
|
||||
// will validate and remove invalid parameters during
|
||||
// the build process later.
|
||||
foreach (var pair in _processorParams)
|
||||
item.ProcessorParams.Add(pair.Key, pair.Value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[CommandLineParameter(
|
||||
Name = "copy",
|
||||
ValueName = "sourceFile",
|
||||
Description = "Copy the content source file verbatim to the output directory.")]
|
||||
public void OnCopy(string sourceFile)
|
||||
{
|
||||
string link = null;
|
||||
|
||||
if (sourceFile.Contains(";"))
|
||||
{
|
||||
var split = sourceFile.Split(';');
|
||||
sourceFile = split[0];
|
||||
|
||||
if (split.Length > 0)
|
||||
link = split[1];
|
||||
}
|
||||
|
||||
// Make sure the source file is relative to the project.
|
||||
var projectDir = ProjectDirectory + Path.DirectorySeparatorChar;
|
||||
|
||||
sourceFile = PathHelper.GetRelativePath(projectDir, sourceFile);
|
||||
|
||||
// Remove duplicates... keep this new one.
|
||||
var previous = _project.ContentItems.FirstOrDefault(e => e.OriginalPath.Equals(sourceFile));
|
||||
if (previous != null)
|
||||
_project.ContentItems.Remove(previous);
|
||||
|
||||
// Create the item for processing later.
|
||||
var item = new ContentItem
|
||||
{
|
||||
BuildAction = BuildAction.Copy,
|
||||
OriginalPath = sourceFile,
|
||||
DestinationPath = string.IsNullOrEmpty(link) ? sourceFile : link,
|
||||
ProcessorParams = new OpaqueDataDictionary()
|
||||
};
|
||||
_project.ContentItems.Add(item);
|
||||
|
||||
// Copy the current processor parameters blind as we
|
||||
// will validate and remove invalid parameters during
|
||||
// the build process later.
|
||||
foreach (var pair in _processorParams)
|
||||
item.ProcessorParams.Add(pair.Key, pair.Value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public PipelineProjectParser(IContentItemObserver observer, PipelineProject project)
|
||||
{
|
||||
_observer = observer;
|
||||
_project = project;
|
||||
}
|
||||
|
||||
public void OpenProject(string projectFilePath, MGBuildParser.ErrorCallback errorCallback)
|
||||
{
|
||||
_project.ContentItems.Clear();
|
||||
|
||||
// Store the file name for saving later.
|
||||
_project.OriginalPath = projectFilePath;
|
||||
|
||||
var parser = new MGBuildParser(this);
|
||||
parser.Title = "Pipeline";
|
||||
|
||||
if (errorCallback != null)
|
||||
parser.OnError += errorCallback;
|
||||
|
||||
var commands = new string[]
|
||||
{
|
||||
string.Format("/@:{0}", projectFilePath),
|
||||
};
|
||||
parser.Parse(commands);
|
||||
}
|
||||
|
||||
public void SaveProject()
|
||||
{
|
||||
using (var io = File.CreateText(_project.OriginalPath))
|
||||
SaveProject(io, null);
|
||||
}
|
||||
|
||||
public void SaveProject(TextWriter io, Func<ContentItem, bool> filterItem)
|
||||
{
|
||||
const string lineFormat = "/{0}:{1}";
|
||||
const string processorParamFormat = "{0}={1}";
|
||||
string line;
|
||||
|
||||
line = FormatDivider("Global Properties");
|
||||
io.WriteLine(line);
|
||||
|
||||
line = string.Format(lineFormat, "outputDir", _project.OutputDir);
|
||||
io.WriteLine(line);
|
||||
|
||||
line = string.Format(lineFormat, "intermediateDir", _project.IntermediateDir);
|
||||
io.WriteLine(line);
|
||||
|
||||
line = string.Format(lineFormat, "platform", _project.Platform);
|
||||
io.WriteLine(line);
|
||||
|
||||
line = string.Format(lineFormat, "config", _project.Config);
|
||||
io.WriteLine(line);
|
||||
|
||||
line = string.Format(lineFormat, "profile", _project.Profile);
|
||||
io.WriteLine(line);
|
||||
|
||||
line = string.Format(lineFormat, "compress", _project.Compress);
|
||||
io.WriteLine(line);
|
||||
|
||||
if (_project.LaunchDebugger)
|
||||
io.WriteLine("/launchdebugger");
|
||||
|
||||
line = FormatDivider("References");
|
||||
io.WriteLine(line);
|
||||
|
||||
foreach (var i in _project.References)
|
||||
{
|
||||
line = string.Format(lineFormat, "reference", i);
|
||||
io.WriteLine(line);
|
||||
}
|
||||
|
||||
line = FormatDivider("Content");
|
||||
io.WriteLine(line);
|
||||
|
||||
// Sort the items alphabetically to ensure a consistent output
|
||||
// and better mergability of the resulting MGCB file.
|
||||
var sortedItems = _project.ContentItems.OrderBy(c => c.OriginalPath, StringComparer.InvariantCulture);
|
||||
|
||||
foreach (var i in sortedItems)
|
||||
{
|
||||
// Reject any items that don't pass the filter.
|
||||
if (filterItem != null && filterItem(i))
|
||||
continue;
|
||||
|
||||
// Wrap content item lines with a begin comment line
|
||||
// to make them more cohesive (for version control).
|
||||
line = string.Format("#begin {0}", i.OriginalPath);
|
||||
io.WriteLine(line);
|
||||
|
||||
if (i.BuildAction == BuildAction.Copy)
|
||||
{
|
||||
string path = i.OriginalPath;
|
||||
if (i.OriginalPath != i.DestinationPath)
|
||||
path += ";" + i.DestinationPath;
|
||||
line = string.Format(lineFormat, "copy", path);
|
||||
io.WriteLine(line);
|
||||
io.WriteLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Write importer.
|
||||
{
|
||||
line = string.Format(lineFormat, "importer", i.ImporterName);
|
||||
io.WriteLine(line);
|
||||
}
|
||||
|
||||
// Write processor.
|
||||
{
|
||||
line = string.Format(lineFormat, "processor", i.ProcessorName);
|
||||
io.WriteLine(line);
|
||||
}
|
||||
|
||||
// Write processor parameters.
|
||||
{
|
||||
if (i.Processor == PipelineTypes.MissingProcessor)
|
||||
{
|
||||
// Could still be missing the real processor.
|
||||
// If so, write the string parameters from import.
|
||||
foreach (var j in i.ProcessorParams)
|
||||
{
|
||||
line = string.Format(lineFormat, "processorParam", string.Format(processorParamFormat, j.Key, j.Value));
|
||||
io.WriteLine(line);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, write only values which are defined by the real processor.
|
||||
foreach (var j in i.Processor.Properties)
|
||||
{
|
||||
object value = null;
|
||||
if (i.ProcessorParams.ContainsKey(j.Name))
|
||||
value = i.ProcessorParams[j.Name];
|
||||
|
||||
// JCF: I 'think' writting an empty string for null would be appropriate but to be on the safe side
|
||||
// im just not writting the value at all.
|
||||
if (value != null)
|
||||
{
|
||||
var converter = PipelineTypes.FindConverter(value.GetType());
|
||||
var valueStr = converter.ConvertTo(null, CultureInfo.InvariantCulture, value, typeof(string));
|
||||
line = string.Format(lineFormat, "processorParam", string.Format(processorParamFormat, j.Name, valueStr));
|
||||
io.WriteLine(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string buildValue = i.OriginalPath;
|
||||
if (i.OriginalPath != i.DestinationPath)
|
||||
buildValue += ";" + i.DestinationPath;
|
||||
line = string.Format(lineFormat, "build", buildValue);
|
||||
io.WriteLine(line);
|
||||
io.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ImportProject(string projectFilePath)
|
||||
{
|
||||
_project.OriginalPath = projectFilePath.Remove(projectFilePath.LastIndexOf('.')) + ".mgcb";
|
||||
|
||||
using (var io = XmlReader.Create(File.OpenText(projectFilePath)))
|
||||
{
|
||||
while (io.Read())
|
||||
{
|
||||
if (io.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
var buildAction = io.LocalName;
|
||||
if (buildAction.Equals("Reference"))
|
||||
{
|
||||
string include, hintPath;
|
||||
ReadIncludeReference(io, out include, out hintPath);
|
||||
|
||||
if (!string.IsNullOrEmpty(hintPath) &&
|
||||
hintPath.IndexOf("microsoft", StringComparison.CurrentCultureIgnoreCase) == -1 &&
|
||||
hintPath.IndexOf("monogamecontentprocessors", StringComparison.CurrentCultureIgnoreCase) == -1)
|
||||
{
|
||||
_project.References.Add(hintPath);
|
||||
}
|
||||
}
|
||||
else if (buildAction.Equals("Content") || buildAction.Equals("None"))
|
||||
{
|
||||
string include, copyToOutputDirectory;
|
||||
ReadIncludeContent(io, out include, out copyToOutputDirectory);
|
||||
|
||||
if (!string.IsNullOrEmpty(copyToOutputDirectory) && !copyToOutputDirectory.Equals("Never"))
|
||||
{
|
||||
var sourceFilePath = Path.GetDirectoryName(projectFilePath);
|
||||
sourceFilePath += "\\" + include;
|
||||
|
||||
OnCopy(sourceFilePath);
|
||||
}
|
||||
}
|
||||
else if (buildAction.Equals("Compile"))
|
||||
{
|
||||
string include, name, importer, processor;
|
||||
string[] processorParams;
|
||||
ReadIncludeCompile(io, out include, out name, out importer, out processor, out processorParams);
|
||||
|
||||
Importer = importer;
|
||||
Processor = processor;
|
||||
if (processorParams != null)
|
||||
{
|
||||
foreach (var i in processorParams)
|
||||
AddProcessorParam(i);
|
||||
}
|
||||
|
||||
var sourceFilePath = Path.GetDirectoryName(projectFilePath);
|
||||
sourceFilePath += "\\" + include;
|
||||
|
||||
OnBuild(sourceFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string ProjectDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
return _project.Location;
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadIncludeReference(XmlReader io, out string include, out string hintPath)
|
||||
{
|
||||
include = io.GetAttribute("Include").Unescape();
|
||||
hintPath = null;
|
||||
|
||||
if (!io.IsEmptyElement)
|
||||
{
|
||||
var depth = io.Depth;
|
||||
for (io.Read(); io.Depth != depth; io.Read())
|
||||
{
|
||||
// process sub nodes
|
||||
if (io.IsStartElement("HintPath"))
|
||||
{
|
||||
io.Read();
|
||||
hintPath = io.Value.Unescape();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadIncludeContent(XmlReader io, out string include, out string copyToOutputDirectory)
|
||||
{
|
||||
copyToOutputDirectory = null;
|
||||
include = io.GetAttribute("Include").Unescape();
|
||||
|
||||
if (!io.IsEmptyElement)
|
||||
{
|
||||
var depth = io.Depth;
|
||||
for (io.Read(); io.Depth != depth; io.Read())
|
||||
{
|
||||
// process sub nodes here.
|
||||
|
||||
if (io.IsStartElement())
|
||||
{
|
||||
switch (io.LocalName)
|
||||
{
|
||||
case "CopyToOutputDirectory":
|
||||
io.Read();
|
||||
copyToOutputDirectory = io.Value.Unescape();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadIncludeCompile(XmlReader io,
|
||||
out string include,
|
||||
out string name,
|
||||
out string importer,
|
||||
out string processor,
|
||||
out string[] processorParams)
|
||||
{
|
||||
name = null;
|
||||
importer = null;
|
||||
processor = null;
|
||||
|
||||
include = io.GetAttribute("Include").Unescape();
|
||||
var parameters = new List<string>();
|
||||
|
||||
if (!io.IsEmptyElement)
|
||||
{
|
||||
var depth = io.Depth;
|
||||
for (io.Read(); io.Depth != depth; io.Read())
|
||||
{
|
||||
// process sub nodes here.
|
||||
|
||||
if (io.IsStartElement())
|
||||
{
|
||||
switch (io.LocalName)
|
||||
{
|
||||
case "Name":
|
||||
io.Read();
|
||||
name = io.Value.Unescape();
|
||||
break;
|
||||
case "Importer":
|
||||
io.Read();
|
||||
importer = io.Value.Unescape();
|
||||
break;
|
||||
case "Processor":
|
||||
io.Read();
|
||||
processor = io.Value.Unescape();
|
||||
break;
|
||||
default:
|
||||
if (io.LocalName.Contains("ProcessorParameters_"))
|
||||
{
|
||||
var line = io.LocalName.Replace("ProcessorParameters_", "");
|
||||
line += "=";
|
||||
io.Read();
|
||||
line += io.Value;
|
||||
parameters.Add(line.Unescape());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processorParams = parameters.ToArray();
|
||||
}
|
||||
|
||||
private string FormatDivider(string label)
|
||||
{
|
||||
var commentFormat = Environment.NewLine + "#----------------------------------------------------------------------------#" + Environment.NewLine;
|
||||
|
||||
label = " " + label + " ";
|
||||
var src = commentFormat.Length / 2 - label.Length / 2;
|
||||
var dst = src + label.Length;
|
||||
|
||||
return commentFormat.Substring(0, src) + label + commentFormat.Substring(dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
// 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 System.IO;
|
||||
using System.IO.IsolatedStorage;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public class PipelineSettings
|
||||
{
|
||||
private const string SettingsPath = "Settings.xml";
|
||||
private IsolatedStorageFile _isoStore;
|
||||
private bool _isoStoreInit;
|
||||
|
||||
public static PipelineSettings Default { get; private set; }
|
||||
|
||||
public List<string> ProjectHistory;
|
||||
public string StartupProject;
|
||||
public Microsoft.Xna.Framework.Point Size;
|
||||
public int HSeparator, VSeparator;
|
||||
public bool Maximized, DebugMode, PropertyGroupSort;
|
||||
public bool FilterOutput, FilterShowSkipped, FilterShowSuccessful, FilterShowCleaned, AutoScrollBuildOutput;
|
||||
public string ErrorMessage;
|
||||
|
||||
static PipelineSettings()
|
||||
{
|
||||
Default = new PipelineSettings();
|
||||
}
|
||||
|
||||
public PipelineSettings()
|
||||
{
|
||||
ProjectHistory = new List<string>();
|
||||
|
||||
PropertyGroupSort = true;
|
||||
FilterOutput = true;
|
||||
FilterShowSkipped = true;
|
||||
FilterShowSuccessful = true;
|
||||
FilterShowCleaned = true;
|
||||
AutoScrollBuildOutput = true;
|
||||
|
||||
try
|
||||
{
|
||||
_isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null);
|
||||
_isoStoreInit = true;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the project already exists in history, it will be moved to the end.
|
||||
/// </summary>
|
||||
public void AddProjectHistory(string file)
|
||||
{
|
||||
var cleanFile = file.Trim();
|
||||
ProjectHistory.Remove(cleanFile);
|
||||
ProjectHistory.Add(cleanFile);
|
||||
}
|
||||
|
||||
public void RemoveProjectHistory(string file)
|
||||
{
|
||||
var cleanFile = file.Trim();
|
||||
ProjectHistory.Remove(cleanFile);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
ProjectHistory.Clear();
|
||||
StartupProject = null;
|
||||
Save();
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
if (!_isoStoreInit)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
var mode = FileMode.CreateNew;
|
||||
if (_isoStore.FileExists(SettingsPath))
|
||||
mode = FileMode.Truncate;
|
||||
|
||||
using (var isoStream = new IsolatedStorageFileStream(SettingsPath, mode, _isoStore))
|
||||
{
|
||||
using (var writer = new StreamWriter(isoStream))
|
||||
{
|
||||
var serializer = new XmlSerializer(typeof(PipelineSettings));
|
||||
serializer.Serialize(writer, this);
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
public void Load()
|
||||
{
|
||||
if (!_isoStoreInit)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
if (_isoStore.FileExists(SettingsPath))
|
||||
{
|
||||
using (var isoStream = new IsolatedStorageFileStream(SettingsPath, FileMode.Open, _isoStore))
|
||||
{
|
||||
using (var reader = new StreamReader(isoStream))
|
||||
{
|
||||
var serializer = new XmlSerializer(typeof(PipelineSettings));
|
||||
Default = (PipelineSettings)serializer.Deserialize(reader);
|
||||
|
||||
var history = Default.ProjectHistory.ToArray();
|
||||
foreach (var h in history)
|
||||
if (!File.Exists(h))
|
||||
Default.ProjectHistory.Remove(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,548 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline.Builder.Convertors;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System.Diagnostics;
|
||||
using MonoGame.Framework.Content.Pipeline.Builder;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public class ImporterTypeDescription
|
||||
{
|
||||
public string TypeName;
|
||||
public string DisplayName;
|
||||
public string DefaultProcessor;
|
||||
public IEnumerable<string> FileExtensions;
|
||||
public Type OutputType;
|
||||
|
||||
public ImporterTypeDescription()
|
||||
{
|
||||
TypeName = "Invalid / Missing Importer";
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return TypeName;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return TypeName == null ? 0 : TypeName.GetHashCode();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var other = obj as ImporterTypeDescription;
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
if (string.IsNullOrEmpty(other.TypeName) != string.IsNullOrEmpty(TypeName))
|
||||
return false;
|
||||
|
||||
return TypeName.Equals(other.TypeName);
|
||||
}
|
||||
};
|
||||
|
||||
public class ProcessorTypeDescription
|
||||
{
|
||||
#region Supporting Types
|
||||
|
||||
public struct Property
|
||||
{
|
||||
public string Name;
|
||||
public string DisplayName;
|
||||
public Type Type;
|
||||
public object DefaultValue;
|
||||
public bool Browsable;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
|
||||
public class ProcessorPropertyCollection : IEnumerable<Property>
|
||||
{
|
||||
private readonly Property[] _properties;
|
||||
|
||||
public ProcessorPropertyCollection(IEnumerable<Property> properties)
|
||||
{
|
||||
_properties = properties.ToArray();
|
||||
}
|
||||
|
||||
public Property this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _properties[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
_properties[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Property this[string name]
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var p in _properties)
|
||||
{
|
||||
if (p.Name.Equals(name))
|
||||
return p;
|
||||
}
|
||||
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
for (var i = 0; i < _properties.Length; i++)
|
||||
{
|
||||
var p = _properties[i];
|
||||
if (p.Name.Equals(name))
|
||||
{
|
||||
_properties[i] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(string name)
|
||||
{
|
||||
return _properties.Any(e => e.Name == name);
|
||||
}
|
||||
|
||||
public IEnumerator<Property> GetEnumerator()
|
||||
{
|
||||
return _properties.AsEnumerable().GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return _properties.GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public string TypeName;
|
||||
public string DisplayName;
|
||||
public ProcessorPropertyCollection Properties;
|
||||
public Type InputType;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return TypeName;
|
||||
}
|
||||
};
|
||||
|
||||
internal class PipelineTypes
|
||||
{
|
||||
[DebuggerDisplay("ImporterInfo: {Type.Name}")]
|
||||
private struct ImporterInfo
|
||||
{
|
||||
public ContentImporterAttribute Attribute;
|
||||
public Type Type;
|
||||
}
|
||||
|
||||
[DebuggerDisplay("ProcessorInfo: {Type.Name}")]
|
||||
private struct ProcessorInfo
|
||||
{
|
||||
public ContentProcessorAttribute Attribute;
|
||||
public Type Type;
|
||||
}
|
||||
|
||||
private static List<ImporterInfo> _importers;
|
||||
private static List<ProcessorInfo> _processors;
|
||||
private static List<FileSystemWatcher> _watchers;
|
||||
private static string _currentAssemblyDirectory;
|
||||
|
||||
public static ImporterTypeDescription[] Importers { get; private set; }
|
||||
public static ProcessorTypeDescription[] Processors { get; private set; }
|
||||
|
||||
public static ImporterTypeDescription NullImporter { get; private set; }
|
||||
public static ProcessorTypeDescription NullProcessor { get; private set; }
|
||||
|
||||
public static ImporterTypeDescription MissingImporter { get; private set; }
|
||||
public static ProcessorTypeDescription MissingProcessor { get; private set; }
|
||||
|
||||
public static TypeConverter.StandardValuesCollection ImportersStandardValuesCollection { get; private set; }
|
||||
public static TypeConverter.StandardValuesCollection ProcessorsStandardValuesCollection { get; private set; }
|
||||
|
||||
private static readonly Dictionary<string, string> _oldNameRemap = new Dictionary<string, string>()
|
||||
{
|
||||
{ "MGMaterialProcessor", "MaterialProcessor" },
|
||||
{ "MGSongProcessor", "SongProcessor" },
|
||||
{ "MGSoundEffectProcessor", "SoundEffectProcessor" },
|
||||
{ "MGSpriteFontDescriptionProcessor", "FontDescriptionProcessor" },
|
||||
{ "MGSpriteFontTextureProcessor", "FontTextureProcessor" },
|
||||
{ "MGTextureProcessor", "TextureProcessor" },
|
||||
{ "MGEffectProcessor", "EffectProcessor" },
|
||||
};
|
||||
|
||||
private static string RemapOldNames(string name)
|
||||
{
|
||||
if (_oldNameRemap.ContainsKey(name))
|
||||
return _oldNameRemap[name];
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static PipelineTypes()
|
||||
{
|
||||
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
|
||||
|
||||
MissingImporter = new ImporterTypeDescription()
|
||||
{
|
||||
DisplayName = "Invalid / Missing Importer",
|
||||
};
|
||||
|
||||
MissingProcessor = new ProcessorTypeDescription()
|
||||
{
|
||||
DisplayName = "Invalid / Missing Processor",
|
||||
Properties = new ProcessorTypeDescription.ProcessorPropertyCollection(new ProcessorTypeDescription.Property[0]),
|
||||
};
|
||||
|
||||
NullImporter = new ImporterTypeDescription()
|
||||
{
|
||||
DisplayName = "",
|
||||
};
|
||||
|
||||
NullProcessor = new ProcessorTypeDescription()
|
||||
{
|
||||
DisplayName = "",
|
||||
Properties = new ProcessorTypeDescription.ProcessorPropertyCollection(new ProcessorTypeDescription.Property[0]),
|
||||
};
|
||||
|
||||
_watchers = new List<FileSystemWatcher>();
|
||||
}
|
||||
|
||||
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_currentAssemblyDirectory))
|
||||
return null;
|
||||
|
||||
var path = Path.Combine(_currentAssemblyDirectory, (new AssemblyName(args.Name).Name) + ".dll");
|
||||
if (!File.Exists(path))
|
||||
return null;
|
||||
|
||||
return Assembly.Load(File.ReadAllBytes(path));
|
||||
}
|
||||
|
||||
public static void Load(PipelineProject project)
|
||||
{
|
||||
Unload();
|
||||
|
||||
var assemblyPaths = new List<string>();
|
||||
|
||||
var projectRoot = project.Location;
|
||||
|
||||
foreach (var i in project.References)
|
||||
{
|
||||
var path = Path.Combine(projectRoot, i);
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
throw new ArgumentException("assemblyFilePath cannot be null!");
|
||||
if (!Path.IsPathRooted(path))
|
||||
throw new ArgumentException("assemblyFilePath must be absolute!");
|
||||
|
||||
// Make sure we're not adding the same assembly twice.
|
||||
path = PathHelper.Normalize(path);
|
||||
if (!assemblyPaths.Contains(path))
|
||||
assemblyPaths.Add(path);
|
||||
}
|
||||
|
||||
ResolveAssemblies(assemblyPaths);
|
||||
|
||||
var importerDescriptions = new ImporterTypeDescription[_importers.Count];
|
||||
var cur = 0;
|
||||
foreach (var item in _importers)
|
||||
{
|
||||
// Find the abstract base class ContentImporter<T>.
|
||||
var baseType = item.Type.BaseType;
|
||||
while (!baseType.IsAbstract)
|
||||
baseType = baseType.BaseType;
|
||||
|
||||
var outputType = baseType.GetGenericArguments()[0];
|
||||
var name = item.Attribute.DisplayName;
|
||||
if (string.IsNullOrEmpty(name))
|
||||
name = item.GetType().Name;
|
||||
var desc = new ImporterTypeDescription()
|
||||
{
|
||||
TypeName = item.Type.Name,
|
||||
DisplayName = name,
|
||||
DefaultProcessor = item.Attribute.DefaultProcessor,
|
||||
FileExtensions = item.Attribute.FileExtensions,
|
||||
OutputType = outputType,
|
||||
};
|
||||
importerDescriptions[cur] = desc;
|
||||
cur++;
|
||||
}
|
||||
|
||||
Importers = importerDescriptions;
|
||||
ImportersStandardValuesCollection = new TypeConverter.StandardValuesCollection(Importers);
|
||||
|
||||
var processorDescriptions = new ProcessorTypeDescription[_processors.Count];
|
||||
|
||||
const BindingFlags bindings = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
|
||||
|
||||
cur = 0;
|
||||
foreach (var item in _processors)
|
||||
{
|
||||
var obj = Activator.CreateInstance(item.Type);
|
||||
var typeProperties = item.Type.GetProperties(bindings);
|
||||
var properties = new List<ProcessorTypeDescription.Property>();
|
||||
foreach (var i in typeProperties)
|
||||
{
|
||||
var attrs = i.GetCustomAttributes(true);
|
||||
var name = i.Name;
|
||||
var browsable = true;
|
||||
var defvalue = i.GetValue(obj, null);
|
||||
|
||||
foreach (var a in attrs)
|
||||
{
|
||||
if (a is BrowsableAttribute)
|
||||
browsable = (a as BrowsableAttribute).Browsable;
|
||||
else if (a is DisplayNameAttribute)
|
||||
name = (a as DisplayNameAttribute).DisplayName;
|
||||
}
|
||||
|
||||
var p = new ProcessorTypeDescription.Property()
|
||||
{
|
||||
Name = i.Name,
|
||||
DisplayName = name,
|
||||
Type = i.PropertyType,
|
||||
DefaultValue = defvalue,
|
||||
Browsable = browsable
|
||||
};
|
||||
properties.Add(p);
|
||||
}
|
||||
|
||||
var inputType = (obj as IContentProcessor).InputType;
|
||||
var desc = new ProcessorTypeDescription()
|
||||
{
|
||||
TypeName = item.Type.Name,
|
||||
DisplayName = item.Attribute.DisplayName,
|
||||
Properties = new ProcessorTypeDescription.ProcessorPropertyCollection(properties),
|
||||
InputType = inputType,
|
||||
};
|
||||
if (string.IsNullOrEmpty(desc.DisplayName))
|
||||
desc.DisplayName = desc.TypeName;
|
||||
|
||||
processorDescriptions[cur] = desc;
|
||||
cur++;
|
||||
}
|
||||
|
||||
Processors = processorDescriptions;
|
||||
ProcessorsStandardValuesCollection = new TypeConverter.StandardValuesCollection(Processors);
|
||||
}
|
||||
|
||||
public static void Unload()
|
||||
{
|
||||
foreach (var watch in _watchers)
|
||||
watch.Dispose();
|
||||
_watchers.Clear();
|
||||
|
||||
_importers = null;
|
||||
Importers = null;
|
||||
|
||||
_processors = null;
|
||||
Processors = null;
|
||||
|
||||
ImportersStandardValuesCollection = null;
|
||||
ProcessorsStandardValuesCollection = null;
|
||||
}
|
||||
|
||||
public static TypeConverter FindConverter(Type type)
|
||||
{
|
||||
if (type == typeof(Color))
|
||||
return new StringToColorConverter();
|
||||
|
||||
return TypeDescriptor.GetConverter(type);
|
||||
}
|
||||
|
||||
public static ImporterTypeDescription FindImporter(string name, string fileExtension)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
name = RemapOldNames(name);
|
||||
|
||||
foreach (var i in Importers)
|
||||
{
|
||||
if (i.TypeName.Equals(name))
|
||||
return i;
|
||||
}
|
||||
|
||||
foreach (var i in Importers)
|
||||
{
|
||||
if (i.DisplayName.Equals(name))
|
||||
return i;
|
||||
}
|
||||
|
||||
//Debug.Fail(string.Format("Importer not found! name={0}, ext={1}", name, fileExtension));
|
||||
return null;
|
||||
}
|
||||
|
||||
var lowerFileExt = fileExtension.ToLowerInvariant();
|
||||
foreach (var i in Importers)
|
||||
{
|
||||
if (i.FileExtensions.Any(e => e.ToLowerInvariant() == lowerFileExt))
|
||||
return i;
|
||||
}
|
||||
|
||||
//Debug.Fail(string.Format("Importer not found! name={0}, ext={1}", name, fileExtension));
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ProcessorTypeDescription FindProcessor(string name, ImporterTypeDescription importer)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
name = RemapOldNames(name);
|
||||
|
||||
foreach (var i in Processors)
|
||||
{
|
||||
if (i.TypeName.Equals(name))
|
||||
return i;
|
||||
}
|
||||
|
||||
//Debug.Fail(string.Format("Processor not found! name={0}, importer={1}", name, importer));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (importer != null)
|
||||
{
|
||||
foreach (var i in Processors)
|
||||
{
|
||||
if (i.TypeName.Equals(importer.DefaultProcessor))
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
//Debug.Fail(string.Format("Processor not found! name={0}, importer={1}", name, importer));
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void ResolveAssemblies(IEnumerable<string> assemblyPaths)
|
||||
{
|
||||
_importers = new List<ImporterInfo>();
|
||||
_processors = new List<ProcessorInfo>();
|
||||
|
||||
var assemblies = new List<Assembly>(AppDomain.CurrentDomain.GetAssemblies());
|
||||
|
||||
foreach (var asm in assemblies)
|
||||
{
|
||||
#if SHIPPING
|
||||
try
|
||||
#endif
|
||||
{
|
||||
if (!asm.ToString().Contains("MonoGame"))
|
||||
continue;
|
||||
|
||||
var types = asm.GetTypes();
|
||||
ProcessTypes(types);
|
||||
}
|
||||
#if SHIPPING
|
||||
catch (Exception e)
|
||||
{
|
||||
// ??
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
foreach (var watch in _watchers)
|
||||
watch.Dispose();
|
||||
_watchers.Clear();
|
||||
|
||||
foreach (var path in assemblyPaths)
|
||||
{
|
||||
try
|
||||
{
|
||||
_currentAssemblyDirectory = Path.GetDirectoryName(path);
|
||||
|
||||
var a = Assembly.Load(File.ReadAllBytes(path));
|
||||
var types = a.GetTypes();
|
||||
ProcessTypes(types);
|
||||
|
||||
var watch = new FileSystemWatcher();
|
||||
watch.Path = Path.GetDirectoryName(path);
|
||||
watch.EnableRaisingEvents = true;
|
||||
watch.Filter = Path.GetFileName(path);
|
||||
watch.Changed += (sender, e) =>
|
||||
{
|
||||
if (Path.GetFileName(path) == e.Name)
|
||||
PipelineController.Instance.OnReferencesModified();
|
||||
};
|
||||
watch.Created += (sender, e) =>
|
||||
{
|
||||
if (Path.GetFileName(path) == e.Name)
|
||||
PipelineController.Instance.OnReferencesModified();
|
||||
};
|
||||
|
||||
_watchers.Add(watch);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Logger.LogWarning(null, null, "Failed to load assembly '{0}': {1}", assemblyPath, e.Message);
|
||||
// The assembly failed to load... nothing
|
||||
// we can do but ignore it.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
_currentAssemblyDirectory = null;
|
||||
}
|
||||
|
||||
private static void ProcessTypes(IEnumerable<Type> types)
|
||||
{
|
||||
foreach (var t in types)
|
||||
{
|
||||
if (t.IsAbstract)
|
||||
continue;
|
||||
|
||||
if (t.GetInterface(@"IContentImporter") == typeof(IContentImporter))
|
||||
{
|
||||
var attributes = t.GetCustomAttributes(typeof(ContentImporterAttribute), false);
|
||||
if (attributes.Length != 0)
|
||||
{
|
||||
var importerAttribute = attributes[0] as ContentImporterAttribute;
|
||||
_importers.Add(new ImporterInfo { Attribute = importerAttribute, Type = t });
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no attribute specify default one
|
||||
var importerAttribute = new ContentImporterAttribute(".*");
|
||||
importerAttribute.DefaultProcessor = "";
|
||||
importerAttribute.DisplayName = t.Name;
|
||||
_importers.Add(new ImporterInfo { Attribute = importerAttribute, Type = t });
|
||||
}
|
||||
}
|
||||
else if (t.GetInterface(@"IContentProcessor") == typeof(IContentProcessor))
|
||||
{
|
||||
var attributes = t.GetCustomAttributes(typeof(ContentProcessorAttribute), false);
|
||||
if (attributes.Length != 0)
|
||||
{
|
||||
var processorAttribute = attributes[0] as ContentProcessorAttribute;
|
||||
_processors.Add(new ProcessorInfo { Attribute = processorAttribute, Type = t });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.Collections.Generic;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
/// <summary>
|
||||
/// Snapshot of a PipelineProject's state, used for undo/redo.
|
||||
/// </summary>
|
||||
internal class ProjectState
|
||||
{
|
||||
public string OutputDir;
|
||||
public string IntermediateDir;
|
||||
public List<string> References;
|
||||
public TargetPlatform Platform;
|
||||
public GraphicsProfile Profile;
|
||||
public string Config;
|
||||
public string OriginalPath;
|
||||
|
||||
/// <summary>
|
||||
/// Create a ProjectState storing member values of the passed PipelineProject.
|
||||
/// </summary>
|
||||
public static ProjectState Get(PipelineProject proj)
|
||||
{
|
||||
var state = new ProjectState()
|
||||
{
|
||||
OriginalPath = proj.OriginalPath,
|
||||
OutputDir = proj.OutputDir,
|
||||
IntermediateDir = proj.IntermediateDir,
|
||||
References = new List<string>(proj.References),
|
||||
Platform = proj.Platform,
|
||||
Profile = proj.Profile,
|
||||
Config = proj.Config,
|
||||
};
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set a PipelineProject's member values from this state object.
|
||||
/// </summary>
|
||||
public void Apply(PipelineProject proj)
|
||||
{
|
||||
proj.OutputDir = OutputDir;
|
||||
proj.IntermediateDir = IntermediateDir;
|
||||
proj.References = new List<string>(References);
|
||||
proj.Platform = Platform;
|
||||
proj.Profile = Profile;
|
||||
proj.Config = Config;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Security;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public static class StringExtensions
|
||||
{
|
||||
public static string Unescape(this string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return text;
|
||||
|
||||
var result = Uri.UnescapeDataString(text);
|
||||
|
||||
// JCF: XmlReader already does this.
|
||||
/*
|
||||
result = result.Replace("'", "'");
|
||||
result = result.Replace(""", "\"");
|
||||
result = result.Replace(">", ">");
|
||||
result = result.Replace("&", "&");
|
||||
*/
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public static class Util
|
||||
{
|
||||
[DllImport("libc")]
|
||||
private static extern string realpath(string path, IntPtr resolved_path);
|
||||
|
||||
public static string GetRealPath(string path)
|
||||
{
|
||||
// resolve symlinks on Unix systems
|
||||
if (Environment.OSVersion.Platform == PlatformID.Unix)
|
||||
return realpath(path, IntPtr.Zero);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the path 'filspec' made relative path 'folder'.
|
||||
///
|
||||
/// If 'folder' is not an absolute path, throws ArgumentException.
|
||||
/// If 'filespec' is not an absolute path, returns 'filespec' unmodified.
|
||||
/// </summary>
|
||||
public static string GetRelativePath(string filespec, string folder)
|
||||
{
|
||||
if (!Path.IsPathRooted(filespec))
|
||||
return filespec;
|
||||
|
||||
if (!Path.IsPathRooted(folder))
|
||||
throw new ArgumentException("Must be an absolute path.", "folder");
|
||||
|
||||
filespec = Path.GetFullPath(filespec).TrimEnd(new[] { '/', '\\' });
|
||||
folder = Path.GetFullPath(folder).TrimEnd(new[] { '/', '\\' });
|
||||
|
||||
if (filespec == folder)
|
||||
return string.Empty;
|
||||
|
||||
var pathUri = new Uri(filespec);
|
||||
var folderUri = new Uri(folder + Path.DirectorySeparatorChar);
|
||||
var result = folderUri.MakeRelativeUri(pathUri).ToString();
|
||||
result = result.Replace('/', Path.DirectorySeparatorChar);
|
||||
result = Uri.UnescapeDataString(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
// 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
|
||||
{
|
||||
partial class AddItemDialog : Dialog<bool>
|
||||
{
|
||||
public bool ApplyForAll { get; private set; }
|
||||
public IncludeType Responce { get; private set; }
|
||||
|
||||
public AddItemDialog(string fileloc, bool exists, FileType filetype)
|
||||
{
|
||||
InitializeComponent();
|
||||
Responce = IncludeType.Copy;
|
||||
|
||||
Title = "Add " + filetype;
|
||||
|
||||
label1.Text = "The file '" + fileloc + "' is outside of target directory. What would you like to do?";
|
||||
|
||||
radioCopy.Text = "Copy the " + filetype.ToString().ToLower() + " to the directory";
|
||||
radioLink.Text = "Add a link to the " + filetype.ToString().ToLower();
|
||||
radioSkip.Text = "Skip adding the " + filetype.ToString().ToLower();
|
||||
|
||||
checkBox1.Text = "Use the same action for all the selected " + filetype.ToString().ToLower() + "s";
|
||||
|
||||
if (exists)
|
||||
{
|
||||
radioLink.Checked = true;
|
||||
radioCopy.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void RadioButton_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (radioCopy.Checked)
|
||||
Responce = IncludeType.Copy;
|
||||
else if (radioLink.Checked)
|
||||
Responce = IncludeType.Link;
|
||||
else
|
||||
Responce = IncludeType.Skip;
|
||||
}
|
||||
|
||||
private void CheckBox1_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
ApplyForAll = (bool)checkBox1.Checked;
|
||||
}
|
||||
|
||||
private void ButtonOk_Click(object sender, EventArgs e)
|
||||
{
|
||||
Result = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ButtonAdd_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// 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
|
||||
{
|
||||
partial class AddItemDialog : Dialog<bool>
|
||||
{
|
||||
DynamicLayout layout1;
|
||||
Label label1;
|
||||
RadioButton radioCopy, radioLink, radioSkip;
|
||||
CheckBox checkBox1;
|
||||
Button buttonAdd, buttonCancel;
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
DisplayMode = DialogDisplayMode.Attached;
|
||||
Width = 400;
|
||||
Height = 250;
|
||||
|
||||
buttonAdd = new Button();
|
||||
buttonAdd.Text = "Add";
|
||||
PositiveButtons.Add(buttonAdd);
|
||||
DefaultButton = buttonAdd;
|
||||
|
||||
buttonCancel = new Button();
|
||||
buttonCancel.Text = "Cancel";
|
||||
NegativeButtons.Add(buttonCancel);
|
||||
AbortButton = buttonCancel;
|
||||
|
||||
layout1 = new DynamicLayout();
|
||||
layout1.DefaultSpacing = new Size(8, 8);
|
||||
layout1.Padding = new Padding(6);
|
||||
layout1.BeginVertical();
|
||||
|
||||
label1 = new Label();
|
||||
label1.Wrap = WrapMode.Word;
|
||||
label1.Style = "Wrap";
|
||||
layout1.AddRow(label1);
|
||||
|
||||
radioCopy = new RadioButton();
|
||||
radioCopy.Checked = true;
|
||||
layout1.AddRow(radioCopy);
|
||||
|
||||
radioLink = new RadioButton(radioCopy);
|
||||
layout1.AddRow(radioLink);
|
||||
|
||||
radioSkip = new RadioButton(radioCopy);
|
||||
layout1.AddRow(radioSkip);
|
||||
|
||||
var spacing = new Label();
|
||||
spacing.Height = 15;
|
||||
layout1.Add(spacing, true, true);
|
||||
|
||||
checkBox1 = new CheckBox();
|
||||
layout1.AddRow(checkBox1);
|
||||
|
||||
layout1.EndVertical();
|
||||
Content = layout1;
|
||||
|
||||
radioCopy.CheckedChanged += RadioButton_CheckedChanged;
|
||||
radioLink.CheckedChanged += RadioButton_CheckedChanged;
|
||||
radioSkip.CheckedChanged += RadioButton_CheckedChanged;
|
||||
checkBox1.CheckedChanged += CheckBox1_CheckedChanged;
|
||||
buttonAdd.Click += ButtonOk_Click;
|
||||
buttonCancel.Click += ButtonAdd_Click;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
// 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.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
partial class DeleteDialog : Dialog<bool>
|
||||
{
|
||||
private IController _controller;
|
||||
private TreeGridItem _treeBase;
|
||||
|
||||
public DeleteDialog(IController controller, List<IProjectItem> items)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_controller = controller;
|
||||
_treeBase = new TreeGridItem();
|
||||
|
||||
treeView1.Columns.Add(new GridColumn { DataCell = new ImageTextCell(0, 1), AutoSize = true, Resizable = true, Editable = false });
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (item is DirectoryItem)
|
||||
ProcessDirectory(_controller.GetFullPath(item.OriginalPath));
|
||||
else
|
||||
Add(_treeBase, item.OriginalPath, false, _controller.GetFullPath(item.OriginalPath));
|
||||
}
|
||||
|
||||
treeView1.DataStore = _treeBase;
|
||||
}
|
||||
|
||||
private void ProcessDirectory(string directory)
|
||||
{
|
||||
Add(_treeBase, _controller.GetRelativePath(directory), true, "");
|
||||
|
||||
var dirs = Directory.GetDirectories(directory);
|
||||
var files = Directory.GetFiles(directory);
|
||||
|
||||
foreach (var dir in dirs)
|
||||
ProcessDirectory(dir);
|
||||
|
||||
foreach (var file in files)
|
||||
Add(_treeBase, _controller.GetRelativePath(file), false, file);
|
||||
}
|
||||
|
||||
public TreeGridItem GetItem(TreeGridItem root, string text, bool folder, string fullpath)
|
||||
{
|
||||
var enumerator = root.Children.GetEnumerator();
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
var item = enumerator.Current as TreeGridItem;
|
||||
var itemtext = item.GetValue(1).ToString();
|
||||
|
||||
if (itemtext == text)
|
||||
return item;
|
||||
}
|
||||
|
||||
var ret = new TreeGridItem();
|
||||
var icon = folder ? Global.GetEtoDirectoryIcon() : Global.GetEtoFileIcon(fullpath, false);
|
||||
ret.Values = new object[] { icon, text };
|
||||
root.Children.Add(ret);
|
||||
root.Expanded = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void Add(TreeGridItem root, string path, bool folder, string fullpath)
|
||||
{
|
||||
var split = path.Split(Path.DirectorySeparatorChar);
|
||||
var file = split.Length == 1 && !folder;
|
||||
var item = GetItem(root, split[0], !file, fullpath);
|
||||
|
||||
if (path.Contains(Path.DirectorySeparatorChar.ToString()))
|
||||
Add(item, string.Join(Path.DirectorySeparatorChar.ToString(), split, 1, split.Length - 1), folder, fullpath);
|
||||
}
|
||||
|
||||
private void ButtonDelete_Click(object sender, EventArgs e)
|
||||
{
|
||||
Result = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ButtonCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 Eto.Drawing;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
partial class DeleteDialog : Dialog<bool>
|
||||
{
|
||||
DynamicLayout layout1;
|
||||
Label label1;
|
||||
TreeGridView treeView1;
|
||||
Button buttonDelete, buttonCancel;
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
Title = "Delete Items";
|
||||
DisplayMode = DialogDisplayMode.Attached;
|
||||
Resizable = true;
|
||||
Size = new Size(450, 300);
|
||||
MinimumSize = new Size(350, 250);
|
||||
|
||||
buttonDelete = new Button();
|
||||
buttonDelete.Text = "Delete";
|
||||
PositiveButtons.Add(buttonDelete);
|
||||
DefaultButton = buttonDelete;
|
||||
buttonDelete.Style = "Destuctive";
|
||||
|
||||
buttonCancel = new Button();
|
||||
buttonCancel.Text = "Cancel";
|
||||
NegativeButtons.Add(buttonCancel);
|
||||
AbortButton = buttonCancel;
|
||||
|
||||
layout1 = new DynamicLayout();
|
||||
layout1.DefaultSpacing = new Size(2, 2);
|
||||
layout1.BeginVertical();
|
||||
|
||||
label1 = new Label();
|
||||
label1.Wrap = WrapMode.Word;
|
||||
label1.Text = "The following items will be deleted (this action cannot be undone):";
|
||||
layout1.Add(label1, true, false);
|
||||
|
||||
treeView1 = new TreeGridView();
|
||||
treeView1.ShowHeader = false;
|
||||
layout1.Add(treeView1, true, true);
|
||||
|
||||
DefaultButton.Text = "Delete";
|
||||
|
||||
Content = layout1;
|
||||
|
||||
buttonDelete.Click += ButtonDelete_Click;
|
||||
buttonCancel.Click += ButtonCancel_Click;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// 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
|
||||
{
|
||||
partial class EditDialog : Dialog<bool>
|
||||
{
|
||||
public string Text { get; private set; }
|
||||
|
||||
private string _errInvalidName;
|
||||
private bool _file;
|
||||
|
||||
public EditDialog(string title, string label, string text, bool file)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_errInvalidName = "The following characters are not allowed:";
|
||||
for (int i = 0; i < Global.NotAllowedCharacters.Length; i++)
|
||||
_errInvalidName += " " + Global.NotAllowedCharacters[i];
|
||||
|
||||
Title = title;
|
||||
label1.Text = label;
|
||||
textBox1.Text = text;
|
||||
|
||||
Text = text;
|
||||
_file = file;
|
||||
|
||||
TextBox1_TextChanged(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
protected override void OnShown(EventArgs e)
|
||||
{
|
||||
base.OnShown(e);
|
||||
|
||||
var index = textBox1.Text.IndexOf('.');
|
||||
if (_file && index != -1)
|
||||
textBox1.Selection = new Range<int>(0, index - 1);
|
||||
}
|
||||
|
||||
private void TextBox1_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!_file)
|
||||
return;
|
||||
|
||||
var stringOk = Global.CheckString(textBox1.Text);
|
||||
|
||||
DefaultButton.Enabled = (stringOk && (textBox1.Text != ""));
|
||||
label2.Text = !stringOk ? _errInvalidName : "";
|
||||
|
||||
Text = textBox1.Text;
|
||||
}
|
||||
|
||||
private void ButtonOk_Click(object sender, EventArgs e)
|
||||
{
|
||||
Result = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ButtonCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// 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
|
||||
{
|
||||
partial class EditDialog : Dialog<bool>
|
||||
{
|
||||
DynamicLayout layout1;
|
||||
Label label1, label2;
|
||||
TextBox textBox1;
|
||||
Button buttonOk, buttonCancel;
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
DisplayMode = DialogDisplayMode.Attached;
|
||||
Size = new Size(400, 160);
|
||||
|
||||
buttonOk = new Button();
|
||||
buttonOk.Text = "Ok";
|
||||
PositiveButtons.Add(buttonOk);
|
||||
DefaultButton = buttonOk;
|
||||
|
||||
buttonCancel = new Button();
|
||||
buttonCancel.Text = "Cancel";
|
||||
NegativeButtons.Add(buttonCancel);
|
||||
AbortButton = buttonCancel;
|
||||
|
||||
layout1 = new DynamicLayout();
|
||||
layout1.DefaultSpacing = new Size(4, 4);
|
||||
layout1.Padding = new Padding(6);
|
||||
layout1.BeginVertical();
|
||||
|
||||
layout1.Add(null, true, true);
|
||||
|
||||
label1 = new Label();
|
||||
layout1.Add(label1);
|
||||
|
||||
textBox1 = new TextBox();
|
||||
layout1.Add(textBox1);
|
||||
|
||||
label2 = new Label();
|
||||
label2.TextColor = new Color(SystemColors.ControlText, 0.5f);
|
||||
label2.TextAlignment = TextAlignment.Center;
|
||||
layout1.Add(label2);
|
||||
|
||||
layout1.Add(null, true, true);
|
||||
|
||||
layout1.EndVertical();
|
||||
Content = layout1;
|
||||
|
||||
textBox1.TextChanged += TextBox1_TextChanged;
|
||||
buttonOk.Click += ButtonOk_Click;
|
||||
buttonCancel.Click += ButtonCancel_Click;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
// 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
|
||||
{
|
||||
partial class NewItemDialog : Dialog<bool>
|
||||
{
|
||||
public string Name { get; private set; }
|
||||
public ContentItemTemplate Selected { get; private set; }
|
||||
|
||||
private const string _errFileExists = "A file with the same name already exists.";
|
||||
private readonly string _errInvalidName, _dir;
|
||||
|
||||
public NewItemDialog(IEnumerator<ContentItemTemplate> enums, string dir)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_errInvalidName = "The following characters are not allowed:";
|
||||
for (int i = 0; i < Global.NotAllowedCharacters.Length; i++)
|
||||
_errInvalidName += " " + Global.NotAllowedCharacters[i];
|
||||
|
||||
_dir = dir;
|
||||
|
||||
while (enums.MoveNext())
|
||||
{
|
||||
var ret = new ImageListItem();
|
||||
ret.Text = enums.Current.Label + " (" + Path.GetExtension(enums.Current.TemplateFile) + ")";
|
||||
ret.Tag = enums.Current;
|
||||
|
||||
list1.Items.Add(ret);
|
||||
}
|
||||
|
||||
if (list1.Items.Count > 0)
|
||||
list1.SelectedIndex = 0;
|
||||
|
||||
textBox1.Text = "File";
|
||||
}
|
||||
|
||||
protected override void OnShown(EventArgs e)
|
||||
{
|
||||
base.OnShown(e);
|
||||
|
||||
// We need to delay setting of text color because
|
||||
// GTK doesn't load text color during initialization
|
||||
labelError.TextColor = new Color(labelError.TextColor, 0.5f);
|
||||
}
|
||||
|
||||
private void TextBox1_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
ReloadSensitive();
|
||||
Name = textBox1.Text;
|
||||
}
|
||||
|
||||
private void ReloadSensitive()
|
||||
{
|
||||
if (!Global.CheckString(textBox1.Text))
|
||||
{
|
||||
labelError.Text = _errInvalidName;
|
||||
DefaultButton.Enabled = false;
|
||||
}
|
||||
else if (File.Exists(Path.Combine(_dir, textBox1.Text + labelExt.Text)))
|
||||
{
|
||||
labelError.Text = _errFileExists;
|
||||
DefaultButton.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
labelError.Text = "";
|
||||
DefaultButton.Enabled = (textBox1.Text != "") && (list1.SelectedIndex >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void List1_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (list1.SelectedIndex < 0)
|
||||
return;
|
||||
|
||||
Selected = (ContentItemTemplate)((ImageListItem)list1.SelectedValue).Tag;
|
||||
labelExt.Text = Path.GetExtension(Selected.TemplateFile);
|
||||
ReloadSensitive();
|
||||
}
|
||||
|
||||
private void ButtonCreate_Click(object sender, EventArgs e)
|
||||
{
|
||||
Result = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ButtonCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// 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
|
||||
{
|
||||
partial class NewItemDialog : Dialog<bool>
|
||||
{
|
||||
TableLayout table1;
|
||||
DynamicLayout layout1, layout2;
|
||||
Label labelName, labelType, labelExt, labelError;
|
||||
TextBox textBox1;
|
||||
ListBox list1;
|
||||
Button buttonCreate, buttonCancel;
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
Title = "New File";
|
||||
DisplayMode = DialogDisplayMode.Attached;
|
||||
Size = new Size(370, 285);
|
||||
MinimumSize = new Size(370, 200);
|
||||
Resizable = true;
|
||||
|
||||
buttonCreate = new Button();
|
||||
buttonCreate.Text = "Create";
|
||||
PositiveButtons.Add(buttonCreate);
|
||||
DefaultButton = buttonCreate;
|
||||
|
||||
buttonCancel = new Button();
|
||||
buttonCancel.Text = "Cancel";
|
||||
NegativeButtons.Add(buttonCancel);
|
||||
AbortButton = buttonCancel;
|
||||
|
||||
layout1 = new DynamicLayout();
|
||||
layout1.Padding = new Padding(6);
|
||||
|
||||
table1 = new TableLayout(2, 3);
|
||||
table1.Spacing = new Size(4, 4);
|
||||
|
||||
labelName = new Label();
|
||||
labelName.Text = "Name: ";
|
||||
labelName.VerticalAlignment = VerticalAlignment.Center;
|
||||
table1.Add(labelName, 0, 0, false, false);
|
||||
|
||||
layout2 = new DynamicLayout();
|
||||
layout2.DefaultSpacing = new Size(4, 4);
|
||||
layout2.BeginHorizontal();
|
||||
|
||||
textBox1 = new TextBox();
|
||||
layout2.Add(textBox1, true, true);
|
||||
|
||||
labelExt = new Label();
|
||||
labelExt.Text = " .spriteFont";
|
||||
labelExt.VerticalAlignment = VerticalAlignment.Center;
|
||||
labelExt.Width = 80;
|
||||
layout2.Add(labelExt, false, true);
|
||||
|
||||
table1.Add(layout2, 1, 0, true, false);
|
||||
|
||||
labelType = new Label();
|
||||
labelType.Text = "Type: ";
|
||||
labelType.VerticalAlignment = VerticalAlignment.Top;
|
||||
table1.Add(labelType, 0, 1, false, true);
|
||||
|
||||
list1 = new ListBox();
|
||||
table1.Add(list1, 1, 1, true, true);
|
||||
|
||||
layout1.Add(table1, true, true);
|
||||
|
||||
labelError = new Label();
|
||||
labelError.TextAlignment = TextAlignment.Center;
|
||||
table1.Add(labelError, 1, 2, true, false);
|
||||
|
||||
layout1.Add(labelError, true, false);
|
||||
|
||||
Content = layout1;
|
||||
|
||||
textBox1.TextChanged += TextBox1_TextChanged;
|
||||
list1.SelectedIndexChanged += List1_SelectedIndexChanged;
|
||||
buttonCreate.Click += ButtonCreate_Click;
|
||||
buttonCancel.Click += ButtonCancel_Click;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// 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
|
||||
{
|
||||
partial class PathDialog : Dialog<bool>
|
||||
{
|
||||
public string Path { get; set; }
|
||||
|
||||
private readonly string[] symbols = { "Platform", "Configuration", "Config", "Profile" };
|
||||
private IController _controller;
|
||||
|
||||
public PathDialog(IController controller, string path)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_controller = controller;
|
||||
textBox1.Text = path;
|
||||
}
|
||||
|
||||
private void ButtonSymbol_Click(object sender, EventArgs e)
|
||||
{
|
||||
var text = "$(" + (sender as Button).Text + ")";
|
||||
int carret;
|
||||
|
||||
if (!string.IsNullOrEmpty(textBox1.SelectedText))
|
||||
{
|
||||
carret = textBox1.Selection.Start;
|
||||
textBox1.Text = textBox1.Text.Remove(carret, textBox1.Selection.End + 1 - carret);
|
||||
}
|
||||
else
|
||||
carret = textBox1.CaretIndex;
|
||||
|
||||
textBox1.Text = textBox1.Text.Insert(carret, text);
|
||||
textBox1.Focus();
|
||||
textBox1.CaretIndex = carret + text.Length;
|
||||
}
|
||||
|
||||
private void TextBox1_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
Path = textBox1.Text;
|
||||
DefaultButton.Enabled = !string.IsNullOrWhiteSpace(textBox1.Text);
|
||||
}
|
||||
|
||||
private void ButtonBrowse_Click(object sender, EventArgs e)
|
||||
{
|
||||
var dialog = new SelectFolderDialog();
|
||||
dialog.Directory = _controller.GetFullPath(textBox1.Text);
|
||||
|
||||
if (dialog.ShowDialog(this) == DialogResult.Ok)
|
||||
textBox1.Text = _controller.GetRelativePath(dialog.Directory);
|
||||
}
|
||||
|
||||
private void ButtonOk_Click(object sender, EventArgs e)
|
||||
{
|
||||
Result = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ButtonCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// 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
|
||||
{
|
||||
partial class PathDialog : Dialog<bool>
|
||||
{
|
||||
DynamicLayout layout1;
|
||||
StackLayout stack1, stack2;
|
||||
Label label1, label2;
|
||||
TextBox textBox1;
|
||||
Button buttonBrowse;
|
||||
Button buttonOk, buttonCancel;
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
Title = "Select Folder";
|
||||
DisplayMode = DialogDisplayMode.Attached;
|
||||
Size = new Size(370, 200);
|
||||
|
||||
buttonOk = new Button();
|
||||
buttonOk.Text = "Ok";
|
||||
PositiveButtons.Add(buttonOk);
|
||||
DefaultButton = buttonOk;
|
||||
|
||||
buttonCancel = new Button();
|
||||
buttonCancel.Text = "Cancel";
|
||||
NegativeButtons.Add(buttonCancel);
|
||||
AbortButton = buttonCancel;
|
||||
|
||||
layout1 = new DynamicLayout();
|
||||
layout1.DefaultSpacing = new Size(4, 4);
|
||||
layout1.Padding = new Padding(6);
|
||||
layout1.BeginVertical();
|
||||
|
||||
layout1.Add(null, true, true);
|
||||
|
||||
label1 = new Label();
|
||||
label1.Text = "Path to use:";
|
||||
layout1.Add(label1);
|
||||
|
||||
stack1 = new StackLayout();
|
||||
stack1.Spacing = 4;
|
||||
stack1.Orientation = Orientation.Horizontal;
|
||||
|
||||
textBox1 = new TextBox();
|
||||
stack1.Items.Add(new StackLayoutItem(textBox1, VerticalAlignment.Center, true));
|
||||
|
||||
buttonBrowse = new Button();
|
||||
buttonBrowse.Text = "...";
|
||||
buttonBrowse.MinimumSize = new Size(1, 1);
|
||||
stack1.Items.Add(new StackLayoutItem(buttonBrowse, VerticalAlignment.Center, false));
|
||||
|
||||
layout1.Add(stack1);
|
||||
|
||||
label2 = new Label();
|
||||
label2.Text = "Macros:";
|
||||
layout1.Add(label2);
|
||||
|
||||
stack2 = new StackLayout();
|
||||
stack2.Spacing = 4;
|
||||
stack2.Orientation = Orientation.Horizontal;
|
||||
|
||||
foreach (var symbol in symbols)
|
||||
{
|
||||
var buttonSymbol = new Button();
|
||||
buttonSymbol.Text = symbol;
|
||||
buttonSymbol.Click += ButtonSymbol_Click;
|
||||
stack2.Items.Add(new StackLayoutItem(buttonSymbol, true));
|
||||
}
|
||||
|
||||
layout1.Add(stack2);
|
||||
|
||||
layout1.Add(null, true, true);
|
||||
|
||||
Content = layout1;
|
||||
|
||||
textBox1.TextChanged += TextBox1_TextChanged;
|
||||
buttonBrowse.Click += ButtonBrowse_Click;
|
||||
buttonOk.Click += ButtonOk_Click;
|
||||
buttonCancel.Click += ButtonCancel_Click;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
// 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 System.Linq;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
partial class ReferenceDialog : Dialog<bool>
|
||||
{
|
||||
protected class RefItem
|
||||
{
|
||||
public string Assembly { get; set; }
|
||||
public string Location { get; set; }
|
||||
|
||||
public RefItem(string assembly, string location)
|
||||
{
|
||||
Assembly = assembly;
|
||||
Location = location;
|
||||
}
|
||||
}
|
||||
|
||||
public List<string> References { get; private set; }
|
||||
|
||||
private IController _controller;
|
||||
private FileFilter _dllFileFilter, _allFileFilter;
|
||||
private SelectableFilterCollection<RefItem> _dataStore;
|
||||
|
||||
public ReferenceDialog(IController controller, string[] refs)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_controller = controller;
|
||||
|
||||
_dllFileFilter = new FileFilter("Dll Files (*.dll)", new[] { ".dll" });
|
||||
_allFileFilter = new FileFilter("All Files (*.*)", new[] { ".*" });
|
||||
|
||||
var assemblyColumn = new GridColumn();
|
||||
assemblyColumn.HeaderText = "Assembly";
|
||||
assemblyColumn.DataCell = new TextBoxCell("Assembly");
|
||||
assemblyColumn.Sortable = true;
|
||||
grid1.Columns.Add(assemblyColumn);
|
||||
|
||||
var locationColumn = new GridColumn();
|
||||
locationColumn.HeaderText = "Location";
|
||||
locationColumn.DataCell = new TextBoxCell("Location");
|
||||
locationColumn.Sortable = true;
|
||||
grid1.Columns.Add(locationColumn);
|
||||
|
||||
grid1.DataStore = _dataStore = new SelectableFilterCollection<RefItem>(grid1);
|
||||
|
||||
foreach (var rf in refs)
|
||||
_dataStore.Add(new RefItem(Path.GetFileName(rf), _controller.GetFullPath(rf)));
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
References = new List<string>();
|
||||
|
||||
var items = _dataStore.GetEnumerator();
|
||||
while (items.MoveNext())
|
||||
References.Add(_controller.GetRelativePath(items.Current.Location));
|
||||
base.Close();
|
||||
}
|
||||
|
||||
private void Grid1_SelectionChanged(object sender, EventArgs e)
|
||||
{
|
||||
buttonRemove.Enabled = grid1.SelectedItems.ToList().Count > 0;
|
||||
}
|
||||
|
||||
private void Grid1_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Keys.Delete)
|
||||
ButtonRemove_Click(sender, e);
|
||||
}
|
||||
|
||||
private void ButtonAdd_Click(object sender, EventArgs e)
|
||||
{
|
||||
var dialog = new OpenFileDialog();
|
||||
dialog.Directory = new Uri(_controller.ProjectItem.Location);
|
||||
dialog.MultiSelect = true;
|
||||
dialog.Filters.Add(_dllFileFilter);
|
||||
dialog.Filters.Add(_allFileFilter);
|
||||
dialog.CurrentFilter = _dllFileFilter;
|
||||
|
||||
if (dialog.ShowDialog(this) == DialogResult.Ok)
|
||||
foreach (var fileName in dialog.Filenames)
|
||||
_dataStore.Add(new RefItem(Path.GetFileName(fileName), fileName));
|
||||
}
|
||||
|
||||
private void ButtonRemove_Click(object sender, EventArgs e)
|
||||
{
|
||||
var selectedItems = grid1.SelectedItems.ToArray();
|
||||
|
||||
foreach (var item in selectedItems)
|
||||
_dataStore.Remove(item as RefItem);
|
||||
}
|
||||
|
||||
private void ButtonOk_Click(object sender, EventArgs e)
|
||||
{
|
||||
Result = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ButtonCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// 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
|
||||
{
|
||||
partial class ReferenceDialog : Dialog<bool>
|
||||
{
|
||||
DynamicLayout layout1;
|
||||
StackLayout stack1;
|
||||
GridView grid1;
|
||||
Button buttonAdd, buttonRemove;
|
||||
Button buttonOk, buttonCancel;
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
Title = "Reference Editor";
|
||||
DisplayMode = DialogDisplayMode.Attached;
|
||||
Resizable = true;
|
||||
Padding = new Padding(4);
|
||||
Size = new Size(500, 400);
|
||||
MinimumSize = new Size(450, 300);
|
||||
|
||||
buttonOk = new Button();
|
||||
buttonOk.Text = "Ok";
|
||||
PositiveButtons.Add(buttonOk);
|
||||
DefaultButton = buttonOk;
|
||||
|
||||
buttonCancel = new Button();
|
||||
buttonCancel.Text = "Cancel";
|
||||
NegativeButtons.Add(buttonCancel);
|
||||
AbortButton = buttonCancel;
|
||||
|
||||
layout1 = new DynamicLayout();
|
||||
layout1.DefaultSpacing = new Size(4, 4);
|
||||
layout1.BeginHorizontal();
|
||||
|
||||
grid1 = new GridView();
|
||||
grid1.Style = "GridView";
|
||||
layout1.Add(grid1, true, true);
|
||||
|
||||
stack1 = new StackLayout();
|
||||
stack1.Orientation = Orientation.Vertical;
|
||||
stack1.Spacing = 4;
|
||||
|
||||
buttonAdd = new Button();
|
||||
buttonAdd.Text = "Add";
|
||||
stack1.Items.Add(new StackLayoutItem(buttonAdd, false));
|
||||
|
||||
buttonRemove = new Button();
|
||||
buttonRemove.Text = "Remove";
|
||||
stack1.Items.Add(new StackLayoutItem(buttonRemove, false));
|
||||
|
||||
layout1.Add(stack1, false, true);
|
||||
|
||||
Content = layout1;
|
||||
|
||||
grid1.SelectionChanged += Grid1_SelectionChanged;
|
||||
grid1.KeyDown += Grid1_KeyDown;
|
||||
buttonAdd.Click += ButtonAdd_Click;
|
||||
buttonRemove.Click += ButtonRemove_Click;
|
||||
buttonOk.Click += ButtonOk_Click;
|
||||
buttonCancel.Click += ButtonCancel_Click;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
// 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.GtkSharp.Drawing;
|
||||
using Gtk;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
static partial class Global
|
||||
{
|
||||
public static Application Application;
|
||||
|
||||
private static IconTheme _theme;
|
||||
|
||||
private static void PlatformInit()
|
||||
{
|
||||
Linux = true;
|
||||
_theme = IconTheme.Default;
|
||||
|
||||
var linkIcon = new Gdk.Pixbuf(Gdk.Colorspace.Rgb, true, 8, 16, 16);
|
||||
linkIcon.Fill(0x00000000);
|
||||
_theme.LoadIcon("emblem-symbolic-link", 16, 0).Composite(linkIcon, 8, 8, 8, 8, 8, 8, 0.5, 0.5, Gdk.InterpType.Tiles, 255);
|
||||
|
||||
_files["0."] = ToEtoImage(_theme.LoadIcon("text-x-generic", 16, 0));
|
||||
_folder = ToEtoImage(_theme.LoadIcon("folder", 16, 0));
|
||||
_link = ToEtoImage(linkIcon);
|
||||
}
|
||||
|
||||
private static Gdk.Pixbuf PlatformGetFileIcon(string path)
|
||||
{
|
||||
Gdk.Pixbuf icon = null;
|
||||
|
||||
var file = GLib.FileFactory.NewForPath(path);
|
||||
var info = file.QueryInfo("standard::*", GLib.FileQueryInfoFlags.None, null);
|
||||
var sicon = info.Icon.ToString().Split(' ');
|
||||
|
||||
for (int i = sicon.Length - 1; i >= 1; i--)
|
||||
{
|
||||
try
|
||||
{
|
||||
icon = _theme.LoadIcon(sicon[i], 16, 0);
|
||||
if (icon != null)
|
||||
break;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
private static Bitmap ToEtoImage(Gdk.Pixbuf icon)
|
||||
{
|
||||
return new Bitmap(new BitmapHandler(icon));
|
||||
}
|
||||
|
||||
private static Gdk.Pixbuf PlatformGetIcon(string resource)
|
||||
{
|
||||
IconInfo iconInfo = null;
|
||||
Gdk.Pixbuf icon = null;
|
||||
|
||||
try
|
||||
{
|
||||
switch (resource)
|
||||
{
|
||||
case "Commands.New.png":
|
||||
iconInfo = _theme.LookupIcon("document-new", 16, 0);
|
||||
break;
|
||||
case "Commands.Open.png":
|
||||
iconInfo = _theme.LookupIcon("document-open", 16, 0);
|
||||
break;
|
||||
case "Commands.Close.png":
|
||||
iconInfo = _theme.LookupIcon("window-close", 16, 0);
|
||||
break;
|
||||
case "Commands.Save.png":
|
||||
iconInfo = _theme.LookupIcon("document-save", 16, 0);
|
||||
break;
|
||||
case "Commands.SaveAs.png":
|
||||
iconInfo = _theme.LookupIcon("document-save-as", 16, 0);
|
||||
break;
|
||||
case "Commands.Undo.png":
|
||||
iconInfo = _theme.LookupIcon("edit-undo", 16, 0);
|
||||
break;
|
||||
case "Commands.Redo.png":
|
||||
iconInfo = _theme.LookupIcon("edit-redo", 16, 0);
|
||||
break;
|
||||
case "Commands.Delete.png":
|
||||
iconInfo = _theme.LookupIcon("edit-delete", 16, 0);
|
||||
break;
|
||||
case "Commands.NewItem.png":
|
||||
iconInfo = _theme.LookupIcon("document-new", 16, 0);
|
||||
break;
|
||||
case "Commands.NewFolder.png":
|
||||
iconInfo = _theme.LookupIcon("folder-new", 16, 0);
|
||||
break;
|
||||
case "Commands.ExistingItem.png":
|
||||
iconInfo = _theme.LookupIcon("document", 16, 0);
|
||||
break;
|
||||
case "Commands.ExistingFolder.png":
|
||||
iconInfo = _theme.LookupIcon("folder", 16, 0);
|
||||
break;
|
||||
case "Commands.Build.png":
|
||||
iconInfo = _theme.LookupIcon("applications-system", 16, 0);
|
||||
break;
|
||||
case "Commands.Rebuild.png":
|
||||
iconInfo = _theme.LookupIcon("system-run", 16, 0);
|
||||
break;
|
||||
case "Commands.Clean.png":
|
||||
iconInfo = _theme.LookupIcon("edit-clear-all", 16, 0);
|
||||
if (iconInfo == null)
|
||||
iconInfo = _theme.LookupIcon("edit-clear", 16, 0);
|
||||
break;
|
||||
case "Commands.CancelBuild.png":
|
||||
iconInfo = _theme.LookupIcon("process-stop", 16, 0);
|
||||
break;
|
||||
case "Commands.Help.png":
|
||||
iconInfo = _theme.LookupIcon("system-help", 16, 0);
|
||||
break;
|
||||
|
||||
case "Build.Information.png":
|
||||
iconInfo = _theme.LookupIcon("dialog-information", 16, 0);
|
||||
break;
|
||||
case "Build.Fail.png":
|
||||
iconInfo = _theme.LookupIcon("dialog-error", 16, 0);
|
||||
break;
|
||||
case "Build.Processing.png":
|
||||
iconInfo = _theme.LookupIcon("preferences-system-time", 16, 0);
|
||||
break;
|
||||
case "Build.Skip.png":
|
||||
iconInfo = _theme.LookupIcon("emblem-default", 16, 0);
|
||||
break;
|
||||
case "Build.Start.png":
|
||||
iconInfo = _theme.LookupIcon("system-run", 16, 0);
|
||||
break;
|
||||
case "Build.EndSucceed.png":
|
||||
iconInfo = _theme.LookupIcon("system-run", 16, 0);
|
||||
break;
|
||||
case "Build.EndFailed.png":
|
||||
iconInfo = _theme.LookupIcon("system-run", 16, 0);
|
||||
break;
|
||||
case "Build.Succeed.png":
|
||||
iconInfo = _theme.LookupIcon("emblem-default", 16, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (iconInfo != null)
|
||||
icon = iconInfo.LoadIcon();
|
||||
|
||||
if (resource == "Commands.Rename.png" || resource == "Commands.OpenItem.png")
|
||||
icon = new Gdk.Pixbuf(Gdk.Colorspace.Rgb, true, 1, 1, 1);
|
||||
}
|
||||
catch { }
|
||||
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// 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
|
||||
{
|
||||
static partial class Global
|
||||
{
|
||||
private static void PlatformInit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static Bitmap PlatformGetFileIcon(string path)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Bitmap ToEtoImage(Image image)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 Eto.Drawing;
|
||||
using Eto.Wpf.Drawing;
|
||||
using System.IO;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
static partial class Global
|
||||
{
|
||||
private static void PlatformInit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static System.Drawing.Bitmap PlatformGetFileIcon(string path)
|
||||
{
|
||||
return System.Drawing.Icon.ExtractAssociatedIcon(path).ToBitmap();
|
||||
}
|
||||
|
||||
private static Bitmap ToEtoImage(System.Drawing.Bitmap bitmap)
|
||||
{
|
||||
var ret = new BitmapImage();
|
||||
|
||||
using (MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
|
||||
stream.Position = 0;
|
||||
|
||||
ret.BeginInit();
|
||||
ret.DecodePixelHeight = 16;
|
||||
ret.DecodePixelWidth = 16;
|
||||
ret.StreamSource = stream;
|
||||
ret.CacheOption = BitmapCacheOption.OnLoad;
|
||||
ret.EndInit();
|
||||
}
|
||||
|
||||
return new Bitmap(new BitmapHandler(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
// 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;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
static partial class Global
|
||||
{
|
||||
public static string NotAllowedCharacters
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Unix)
|
||||
return Linux ? "/" : ":";
|
||||
|
||||
return "/?<>\\:*|\"";
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Linux { get; private set; }
|
||||
public static bool UseHeaderBar { get; set; }
|
||||
public static bool Unix { get; private set; }
|
||||
|
||||
private static Dictionary<string, Bitmap> _files;
|
||||
private static Image _folder;
|
||||
private static Bitmap _link;
|
||||
|
||||
static Global()
|
||||
{
|
||||
Unix = Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX;
|
||||
|
||||
_link = Bitmap.FromResource("TreeView.Link.png");
|
||||
_files = new Dictionary<string, Bitmap>();
|
||||
_files.Add("0.", Bitmap.FromResource("TreeView.File.png"));
|
||||
|
||||
_folder = Bitmap.FromResource("TreeView.Folder.png");
|
||||
|
||||
PlatformInit();
|
||||
|
||||
// Generate default link file image
|
||||
var linkfile = new Bitmap(_files["0."]);
|
||||
var g = new Graphics(linkfile);
|
||||
g.DrawImage(_link, Point.Empty);
|
||||
g.Flush();
|
||||
_files.Add("1.", linkfile);
|
||||
}
|
||||
|
||||
public static bool CheckString(string s)
|
||||
{
|
||||
var notAllowed = Path.GetInvalidFileNameChars();
|
||||
|
||||
for (int i = 0; i < notAllowed.Length; i++)
|
||||
if (s.Contains(notAllowed[i].ToString()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Image GetEtoDirectoryIcon()
|
||||
{
|
||||
return _folder;
|
||||
}
|
||||
|
||||
public static Image GetEtoFileIcon(string path, bool link)
|
||||
{
|
||||
var key = (link ? '1' : '0') + (File.Exists(path) ? Path.GetExtension(path) : ".");
|
||||
if (_files.ContainsKey(key))
|
||||
return _files[key];
|
||||
|
||||
try
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var platformicon = PlatformGetFileIcon(path);
|
||||
|
||||
if (platformicon != null)
|
||||
{
|
||||
var icon = ToEtoImage(platformicon);
|
||||
|
||||
if (icon != null)
|
||||
{
|
||||
if (link)
|
||||
{
|
||||
var g = new Graphics(icon);
|
||||
g.DrawImage(_link, Point.Empty);
|
||||
g.Flush();
|
||||
}
|
||||
|
||||
_files.Add(key, icon);
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
return _files[(link) ? "1." : "0."];
|
||||
}
|
||||
|
||||
public static Image GetEtoIcon(string resource)
|
||||
{
|
||||
#if LINUX
|
||||
var nativeicon = PlatformGetIcon(resource);
|
||||
|
||||
if (nativeicon != null)
|
||||
return ToEtoImage(nativeicon);
|
||||
#endif
|
||||
|
||||
return Icon.FromResource(resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 224 B |
|
After Width: | Height: | Size: 254 B |
|
After Width: | Height: | Size: 352 B |
|
After Width: | Height: | Size: 251 B |
|
After Width: | Height: | Size: 523 B |
|
After Width: | Height: | Size: 221 B |
|
After Width: | Height: | Size: 165 B |
|
After Width: | Height: | Size: 401 B |
|
After Width: | Height: | Size: 308 B |
|
After Width: | Height: | Size: 214 B |
|
After Width: | Height: | Size: 310 B |
|
After Width: | Height: | Size: 294 B |
|
After Width: | Height: | Size: 422 B |
|
After Width: | Height: | Size: 228 B |
|
After Width: | Height: | Size: 565 B |
|
After Width: | Height: | Size: 144 B |
|
After Width: | Height: | Size: 218 B |
|
After Width: | Height: | Size: 287 B |
|
After Width: | Height: | Size: 478 B |
|
After Width: | Height: | Size: 456 B |
|
After Width: | Height: | Size: 228 B |
|
After Width: | Height: | Size: 262 B |
|
After Width: | Height: | Size: 148 B |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 463 B |
|
After Width: | Height: | Size: 24 KiB |
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>LSEnvironment</key>
|
||||
<dict>
|
||||
<key>MONO_MANAGED_WATCHER</key>
|
||||
<string>false</string>
|
||||
</dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>Pipeline.MacOS</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.7</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>MonoGame Content Pipeline Tool</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.monogame.pipeline</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.3</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>App</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public partial class LogWindow : Form
|
||||
{
|
||||
public static Button ButtonCopy;
|
||||
private Clipboard _clipboard;
|
||||
|
||||
public LogWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ButtonCopy = _buttonCopy;
|
||||
Style = "LogWindow";
|
||||
_clipboard = new Clipboard();
|
||||
}
|
||||
|
||||
public string LogText
|
||||
{
|
||||
get { return _textAreaLog.Text; }
|
||||
set { _textAreaLog.Text = value; }
|
||||
}
|
||||
|
||||
private void LogWindow_Closed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineSettings.Default.ErrorMessage = string.Empty;
|
||||
PipelineSettings.Default.Save();
|
||||
Application.Instance.Quit();
|
||||
}
|
||||
|
||||
private void ButtonCopy_Click(object sender, EventArgs e)
|
||||
{
|
||||
_clipboard.Clear();
|
||||
_clipboard.Text = _textAreaLog.Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using Eto.Forms;
|
||||
using Eto.Drawing;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
public partial class LogWindow : Form
|
||||
{
|
||||
private TextArea _textAreaLog;
|
||||
private Button _buttonCopy;
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
Title = "Crash Report";
|
||||
Size = new Size(800, 400);
|
||||
|
||||
var layout1 = new DynamicLayout();
|
||||
layout1.Padding = new Padding(4);
|
||||
layout1.Spacing = new Size(4, 4);
|
||||
|
||||
var layout2 = new DynamicLayout();
|
||||
layout2.BeginHorizontal();
|
||||
|
||||
var label1 = new Label();
|
||||
label1.VerticalAlignment = VerticalAlignment.Bottom;
|
||||
label1.Text = "Pipeline Tool has crashed, please copy the following exception when reporting the error: ";
|
||||
layout2.Add(label1, true, true);
|
||||
|
||||
_buttonCopy = new Button();
|
||||
_buttonCopy.Text = "Copy to Clipboard";
|
||||
|
||||
if (!Global.UseHeaderBar)
|
||||
layout2.Add(_buttonCopy, false, true);
|
||||
|
||||
layout1.Add(layout2, true, false);
|
||||
|
||||
_textAreaLog = new TextArea();
|
||||
_textAreaLog.ReadOnly = true;
|
||||
_textAreaLog.Wrap = false;
|
||||
layout1.Add(_textAreaLog, true, true);
|
||||
|
||||
Content = layout1;
|
||||
|
||||
Closed += LogWindow_Closed;
|
||||
_buttonCopy.Click += ButtonCopy_Click;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,693 @@
|
||||
// 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 System.Diagnostics;
|
||||
using Eto.Forms;
|
||||
using Eto.Drawing;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MonoGame.Tools.Pipeline
|
||||
{
|
||||
partial class MainWindow : Form, IView
|
||||
{
|
||||
#pragma warning disable 649
|
||||
public EventHandler<EventArgs> RecentChanged;
|
||||
public EventHandler<EventArgs> TitleChanged;
|
||||
#pragma warning restore 649
|
||||
public const string TitleBase = "MonoGame Pipeline Tool";
|
||||
public static MainWindow Instance;
|
||||
|
||||
private List<Pad> _pads;
|
||||
private Clipboard _clipboard;
|
||||
private ContextMenu _contextMenu;
|
||||
private FileFilter _mgcbFileFilter, _allFileFilter, _xnaFileFilter;
|
||||
private string[] monoLocations = {
|
||||
"/usr/bin/mono",
|
||||
"/usr/local/bin/mono",
|
||||
"/Library/Frameworks/Mono.framework/Versions/Current/bin/mono",
|
||||
Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "mono"),
|
||||
};
|
||||
|
||||
int setw = 0;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
_pads = new List<Pad>();
|
||||
_clipboard = new Clipboard();
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
Instance = this;
|
||||
|
||||
// Fill in Pad menu
|
||||
foreach (var pad in _pads)
|
||||
{
|
||||
if (pad.Commands.Count > 0)
|
||||
{
|
||||
var menu = new ButtonMenuItem();
|
||||
menu.Text = pad.Title;
|
||||
|
||||
foreach (var com in pad.Commands)
|
||||
menu.Items.Add(com.CreateMenuItem());
|
||||
|
||||
menuView.Items.Add(menu);
|
||||
}
|
||||
}
|
||||
|
||||
#if MONOMAC
|
||||
splitterVertical.PositionChanged += delegate {
|
||||
setw++;
|
||||
if (setw > 2)
|
||||
{
|
||||
propertyGridControl.SetWidth();
|
||||
setw = 0;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
_contextMenu = new ContextMenu();
|
||||
projectControl.SetContextMenu(_contextMenu);
|
||||
|
||||
_mgcbFileFilter = new FileFilter("MonoGame Content Build Project (*.mgcb)", new[] { ".mgcb" });
|
||||
_allFileFilter = new FileFilter("All Files (*.*)", new[] { ".*" });
|
||||
_xnaFileFilter = new FileFilter("XNA Content Projects (*.contentproj)", new[] { ".contentproj" });
|
||||
}
|
||||
|
||||
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
e.Cancel = !PipelineController.Instance.Exit();
|
||||
|
||||
base.OnClosing(e);
|
||||
}
|
||||
|
||||
#region IView implements
|
||||
|
||||
public void Attach(IController controller)
|
||||
{
|
||||
PipelineController.Instance.OnProjectLoaded += () => projectControl.ExpandBase();
|
||||
|
||||
cmdDebugMode.Checked = PipelineSettings.Default.DebugMode;
|
||||
foreach (var control in _pads)
|
||||
control.LoadSettings();
|
||||
|
||||
Style = "MainWindow";
|
||||
}
|
||||
|
||||
public void Invoke(Action action)
|
||||
{
|
||||
Application.Instance.Invoke(action);
|
||||
}
|
||||
|
||||
public AskResult AskSaveOrCancel()
|
||||
{
|
||||
var result = MessageBox.Show(this, "Do you want to save the project first?", "Save Project", MessageBoxButtons.YesNoCancel, MessageBoxType.Question);
|
||||
|
||||
if (result == DialogResult.Yes)
|
||||
return AskResult.Yes;
|
||||
if (result == DialogResult.No)
|
||||
return AskResult.No;
|
||||
|
||||
return AskResult.Cancel;
|
||||
}
|
||||
|
||||
public bool AskSaveName(ref string filePath, string title)
|
||||
{
|
||||
var dialog = new SaveFileDialog();
|
||||
dialog.Title = title;
|
||||
dialog.Filters.Add(_mgcbFileFilter);
|
||||
dialog.Filters.Add(_allFileFilter);
|
||||
dialog.CurrentFilter = _mgcbFileFilter;
|
||||
|
||||
if (dialog.ShowDialog(this) == DialogResult.Ok)
|
||||
{
|
||||
filePath = dialog.FileName;
|
||||
if (dialog.CurrentFilter == _mgcbFileFilter && !filePath.EndsWith(".mgcb"))
|
||||
filePath += ".mgcb";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool AskOpenProject(out string projectFilePath)
|
||||
{
|
||||
var dialog = new OpenFileDialog();
|
||||
dialog.Filters.Add(_mgcbFileFilter);
|
||||
dialog.Filters.Add(_allFileFilter);
|
||||
dialog.CurrentFilter = _mgcbFileFilter;
|
||||
|
||||
if (dialog.ShowDialog(this) == DialogResult.Ok)
|
||||
{
|
||||
projectFilePath = dialog.FileName;
|
||||
return true;
|
||||
}
|
||||
|
||||
projectFilePath = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool AskImportProject(out string projectFilePath)
|
||||
{
|
||||
var dialog = new OpenFileDialog();
|
||||
dialog.Filters.Add(_xnaFileFilter);
|
||||
dialog.Filters.Add(_allFileFilter);
|
||||
dialog.CurrentFilter = _xnaFileFilter;
|
||||
|
||||
if (dialog.ShowDialog(this) == DialogResult.Ok)
|
||||
{
|
||||
projectFilePath = dialog.FileName;
|
||||
return true;
|
||||
}
|
||||
|
||||
projectFilePath = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
public void ShowError(string title, string message)
|
||||
{
|
||||
MessageBox.Show(this, message, title, MessageBoxButtons.OK, MessageBoxType.Error);
|
||||
}
|
||||
|
||||
public void ShowMessage(string message)
|
||||
{
|
||||
MessageBox.Show(this, message, "Info", MessageBoxButtons.OK, MessageBoxType.Information);
|
||||
}
|
||||
|
||||
public void BeginTreeUpdate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void SetTreeRoot(IProjectItem item)
|
||||
{
|
||||
projectControl.SetRoot(item);
|
||||
}
|
||||
|
||||
public void AddTreeItem(IProjectItem item)
|
||||
{
|
||||
projectControl.AddItem(item);
|
||||
}
|
||||
|
||||
public void RemoveTreeItem(IProjectItem item)
|
||||
{
|
||||
projectControl.RemoveItem(item);
|
||||
}
|
||||
|
||||
public void UpdateTreeItem(IProjectItem item)
|
||||
{
|
||||
projectControl.UpdateItem(item);
|
||||
}
|
||||
|
||||
public void EndTreeUpdate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void UpdateProperties()
|
||||
{
|
||||
propertyGridControl.SetObjects(PipelineController.Instance.SelectedItems);
|
||||
}
|
||||
|
||||
public void OutputAppend(string text)
|
||||
{
|
||||
Application.Instance.AsyncInvoke(() => buildOutput.WriteLine(text));
|
||||
}
|
||||
|
||||
public void OutputClear()
|
||||
{
|
||||
Application.Instance.Invoke(() => buildOutput.ClearOutput());
|
||||
}
|
||||
|
||||
public bool ShowDeleteDialog(List<IProjectItem> items)
|
||||
{
|
||||
var dialog = new DeleteDialog(PipelineController.Instance, items);
|
||||
return dialog.ShowModal(this);
|
||||
}
|
||||
|
||||
public bool ShowEditDialog(string title, string text, string oldname, bool file, out string newname)
|
||||
{
|
||||
var dialog = new EditDialog(title, text, oldname, file);
|
||||
var result = dialog.ShowModal(this);
|
||||
|
||||
newname = dialog.Text;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool ChooseContentFile(string initialDirectory, out List<string> files)
|
||||
{
|
||||
var dialog = new OpenFileDialog();
|
||||
dialog.Directory = new Uri(initialDirectory);
|
||||
dialog.MultiSelect = true;
|
||||
dialog.Filters.Add(_allFileFilter);
|
||||
dialog.CurrentFilter = _allFileFilter;
|
||||
|
||||
var result = dialog.ShowDialog(this) == DialogResult.Ok;
|
||||
|
||||
files = new List<string>();
|
||||
files.AddRange(dialog.Filenames);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool ChooseContentFolder(string initialDirectory, out string folder)
|
||||
{
|
||||
var dialog = new SelectFolderDialog();
|
||||
dialog.Directory = initialDirectory;
|
||||
|
||||
var result = dialog.ShowDialog(this) == DialogResult.Ok;
|
||||
if (result)
|
||||
folder = dialog.Directory;
|
||||
else
|
||||
folder = string.Empty;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool ChooseItemTemplate(string folder, out ContentItemTemplate template, out string name)
|
||||
{
|
||||
var dialog = new NewItemDialog(PipelineController.Instance.Templates.GetEnumerator(), folder);
|
||||
var result = dialog.ShowModal(this);
|
||||
|
||||
template = dialog.Selected;
|
||||
name = dialog.Name + Path.GetExtension(template.TemplateFile);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool CopyOrLinkFile(string file, bool exists, out IncludeType action, out bool applyforall)
|
||||
{
|
||||
var dialog = new AddItemDialog(file, exists, FileType.File);
|
||||
var result = dialog.ShowModal(this);
|
||||
|
||||
action = dialog.Responce;
|
||||
applyforall = dialog.ApplyForAll;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool CopyOrLinkFolder(string folder, bool exists, out IncludeType action, out bool applyforall)
|
||||
{
|
||||
var afd = new AddItemDialog(folder, exists, FileType.Folder);
|
||||
applyforall = false;
|
||||
|
||||
if (afd.ShowModal(this))
|
||||
{
|
||||
action = afd.Responce;
|
||||
return true;
|
||||
}
|
||||
|
||||
action = IncludeType.Link;
|
||||
return false;
|
||||
}
|
||||
|
||||
public Process CreateProcess(string exe, string commands)
|
||||
{
|
||||
var proc = new Process();
|
||||
|
||||
if (!Global.Unix)
|
||||
{
|
||||
proc.StartInfo.FileName = exe;
|
||||
proc.StartInfo.Arguments = commands;
|
||||
}
|
||||
else
|
||||
{
|
||||
string monoLoc = null;
|
||||
|
||||
foreach (var path in monoLocations)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
monoLoc = path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(monoLoc))
|
||||
{
|
||||
monoLoc = "mono";
|
||||
OutputAppend("Could not find mono. Please install the latest version from http://www.mono-project.com");
|
||||
}
|
||||
|
||||
proc.StartInfo.FileName = monoLoc;
|
||||
|
||||
if (PipelineSettings.Default.DebugMode)
|
||||
{
|
||||
var port = Environment.GetEnvironmentVariable("MONO_DEBUGGER_PORT");
|
||||
port = !string.IsNullOrEmpty(port) ? port : "55555";
|
||||
var monodebugger = string.Format("--debug --debugger-agent=transport=dt_socket,server=y,address=127.0.0.1:{0}",
|
||||
port);
|
||||
proc.StartInfo.Arguments = string.Format("{0} \"{1}\" {2}", monodebugger, exe, commands);
|
||||
OutputAppend("************************************************");
|
||||
OutputAppend("RUNNING MGCB IN DEBUG MODE!!!");
|
||||
OutputAppend(string.Format("Attach your Debugger to localhost:{0}", port));
|
||||
OutputAppend("************************************************");
|
||||
}
|
||||
else
|
||||
{
|
||||
proc.StartInfo.Arguments = string.Format("\"{0}\" {1}", exe, commands);
|
||||
}
|
||||
}
|
||||
|
||||
return proc;
|
||||
}
|
||||
|
||||
public void UpdateCommands(MenuInfo info)
|
||||
{
|
||||
// Title
|
||||
|
||||
if (TitleChanged != null)
|
||||
TitleChanged(this, EventArgs.Empty);
|
||||
else
|
||||
{
|
||||
var title = TitleBase;
|
||||
|
||||
if (PipelineController.Instance.ProjectOpen)
|
||||
{
|
||||
title += " - " + Path.GetFileName(PipelineController.Instance.ProjectItem.OriginalPath);
|
||||
|
||||
if (PipelineController.Instance.ProjectDirty)
|
||||
title += "*";
|
||||
}
|
||||
|
||||
Title = title;
|
||||
}
|
||||
|
||||
// Menu
|
||||
|
||||
cmdNew.Enabled = info.New;
|
||||
cmdOpen.Enabled = info.Open;
|
||||
cmdImport.Enabled = info.Import;
|
||||
cmdSave.Enabled = info.Save;
|
||||
cmdSaveAs.Enabled = info.SaveAs;
|
||||
cmdClose.Enabled = info.Close;
|
||||
cmdExit.Enabled = info.Exit;
|
||||
|
||||
cmdUndo.Enabled = info.Undo;
|
||||
cmdRedo.Enabled = info.Redo;
|
||||
cmdAdd.Enabled = info.Add;
|
||||
cmdNewItem.Enabled = info.Add;
|
||||
cmdNewFolder.Enabled = info.Add;
|
||||
cmdExistingItem.Enabled = info.Add;
|
||||
cmdExistingFolder.Enabled = info.Add;
|
||||
cmdExclude.Enabled = info.Exclude;
|
||||
cmdRename.Enabled = info.Rename;
|
||||
cmdDelete.Enabled = info.Delete;
|
||||
|
||||
cmdBuild.Enabled = info.Build;
|
||||
cmdRebuild.Enabled = info.Rebuild;
|
||||
cmdClean.Enabled = info.Clean;
|
||||
cmdCancelBuild.Enabled = info.Cancel;
|
||||
|
||||
cmdOpenItem.Enabled = info.OpenItem;
|
||||
cmdOpenItemWith.Enabled = info.OpenItemWith;
|
||||
cmdOpenItemLocation.Enabled = info.OpenItemLocation;
|
||||
cmdOpenOutputItemLocation.Enabled = info.OpenOutputItemLocation;
|
||||
cmdCopyAssetName.Enabled = info.CopyAssetPath;
|
||||
cmdRebuildItem.Enabled = info.RebuildItem;
|
||||
|
||||
// Visibility of menu items can't be changed so
|
||||
// we need to recreate the context menu each time.
|
||||
|
||||
// Context Menu
|
||||
|
||||
var sep = false;
|
||||
_contextMenu.Items.Clear();
|
||||
|
||||
AddContextMenu(cmOpenItem, ref sep);
|
||||
AddContextMenu(cmOpenItemWith, ref sep);
|
||||
AddContextMenu(cmAdd, ref sep);
|
||||
AddSeparator(ref sep);
|
||||
AddContextMenu(cmOpenItemLocation, ref sep);
|
||||
AddContextMenu(cmOpenOutputItemLocation, ref sep);
|
||||
AddContextMenu(cmCopyAssetPath, ref sep);
|
||||
AddContextMenu(cmRebuildItem, ref sep);
|
||||
AddSeparator(ref sep);
|
||||
AddContextMenu(cmExclude, ref sep);
|
||||
AddSeparator(ref sep);
|
||||
AddContextMenu(cmRename, ref sep);
|
||||
//AddContextMenu(cmDelete, ref sep);
|
||||
|
||||
if (_contextMenu.Items.Count > 0)
|
||||
{
|
||||
var lastItem = _contextMenu.Items[_contextMenu.Items.Count - 1];
|
||||
if (lastItem is SeparatorMenuItem)
|
||||
_contextMenu.Items.Remove(lastItem);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddContextMenu(MenuItem item, ref bool separator)
|
||||
{
|
||||
item.Shortcut = Keys.None;
|
||||
|
||||
if (item.Enabled)
|
||||
_contextMenu.Items.Add(item);
|
||||
|
||||
separator |= item.Enabled;
|
||||
}
|
||||
|
||||
private void AddSeparator(ref bool separator)
|
||||
{
|
||||
if (separator)
|
||||
{
|
||||
if (!(_contextMenu.Items[_contextMenu.Items.Count - 1] is SeparatorMenuItem))
|
||||
_contextMenu.Items.Add(new SeparatorMenuItem());
|
||||
|
||||
separator = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateRecentList(List<string> recentList)
|
||||
{
|
||||
if (RecentChanged != null)
|
||||
{
|
||||
RecentChanged(recentList, EventArgs.Empty);
|
||||
return;
|
||||
}
|
||||
|
||||
menuRecent.Items.Clear();
|
||||
|
||||
foreach (var recent in recentList)
|
||||
{
|
||||
var item = new ButtonMenuItem();
|
||||
item.Text = recent;
|
||||
item.Click += (sender, e) => PipelineController.Instance.OpenProject(recent);
|
||||
|
||||
menuRecent.Items.Insert(0, item);
|
||||
}
|
||||
|
||||
if (menuRecent.Items.Count > 0)
|
||||
{
|
||||
menuRecent.Items.Add(new SeparatorMenuItem());
|
||||
var clearItem = new ButtonMenuItem();
|
||||
clearItem.Text = "Clear";
|
||||
clearItem.Click += (sender, e) => PipelineController.Instance.ClearRecentList();
|
||||
menuRecent.Items.Add(clearItem);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetClipboard(string text)
|
||||
{
|
||||
_clipboard.Clear();
|
||||
_clipboard.Text = text;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Commands
|
||||
|
||||
private void CmdNew_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.NewProject();
|
||||
}
|
||||
|
||||
private void CmdOpen_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.OpenProject();
|
||||
}
|
||||
|
||||
private void CmdClose_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.CloseProject();
|
||||
}
|
||||
|
||||
private void CmdImport_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.ImportProject();
|
||||
}
|
||||
|
||||
private void CmdSave_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.SaveProject(false);
|
||||
}
|
||||
|
||||
private void CmdSaveAs_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.SaveProject(true);
|
||||
}
|
||||
|
||||
private void CmdExit_Executed(object sender, EventArgs e)
|
||||
{
|
||||
Application.Instance.Quit();
|
||||
}
|
||||
|
||||
private void CmdUndo_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.Undo();
|
||||
}
|
||||
|
||||
private void CmdRedo_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.Redo();
|
||||
}
|
||||
|
||||
private void CmdExclude_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.Exclude(false);
|
||||
}
|
||||
|
||||
private void CmdRename_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.Rename();
|
||||
}
|
||||
|
||||
private void CmdDelete_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.Exclude(true);
|
||||
}
|
||||
|
||||
private void CmdNewItem_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.NewItem();
|
||||
}
|
||||
|
||||
private void CmdNewFolder_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.NewFolder();
|
||||
}
|
||||
|
||||
private void CmdExistingItem_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.Include();
|
||||
}
|
||||
|
||||
private void CmdExistingFolder_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.IncludeFolder();
|
||||
}
|
||||
|
||||
private void CmdBuild_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.Build(false);
|
||||
}
|
||||
|
||||
private void CmdRebuild_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.Build(true);
|
||||
}
|
||||
|
||||
private void CmdClean_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.Clean();
|
||||
}
|
||||
|
||||
private void CmdCancelBuild_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.CancelBuild();
|
||||
}
|
||||
|
||||
private void CmdDebugMode_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineSettings.Default.DebugMode = cmdDebugMode.Checked;
|
||||
}
|
||||
|
||||
private void CmdHelp_Executed(object sender, EventArgs e)
|
||||
{
|
||||
Process.Start("http://www.monogame.net/documentation/?page=Pipeline");
|
||||
}
|
||||
|
||||
private void CmdAbout_Executed(object sender, EventArgs e)
|
||||
{
|
||||
var adialog = new AboutDialog();
|
||||
adialog.Logo = Bitmap.FromResource("Icons.monogame.png");
|
||||
adialog.WebsiteLabel = "MonoGame Website";
|
||||
adialog.Website = new Uri("http://www.monogame.net/");
|
||||
|
||||
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("LICENSE.txt"))
|
||||
using (var reader = new StreamReader(stream))
|
||||
adialog.License = reader.ReadToEnd();
|
||||
|
||||
adialog.ShowDialog(this);
|
||||
}
|
||||
|
||||
private void CmdOpenItem_Executed(object sender, EventArgs e)
|
||||
{
|
||||
if (PipelineController.Instance.SelectedItem is ContentItem)
|
||||
Process.Start(PipelineController.Instance.GetFullPath(PipelineController.Instance.SelectedItem.OriginalPath));
|
||||
}
|
||||
|
||||
private void CmdOpenItemWith_Executed(object sender, EventArgs e)
|
||||
{
|
||||
if (PipelineController.Instance.SelectedItem != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var filepath = PipelineController.Instance.GetFullPath(PipelineController.Instance.SelectedItem.OriginalPath);
|
||||
var dialog = new OpenWithDialog(filepath);
|
||||
dialog.ShowDialog(this);
|
||||
}
|
||||
catch
|
||||
{
|
||||
ShowError("Error", "An error occured while trying to launch an open with dialog.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CmdOpenItemLocation_Executed(object sender, EventArgs e)
|
||||
{
|
||||
if (PipelineController.Instance.SelectedItem != null)
|
||||
Process.Start(PipelineController.Instance.GetFullPath(PipelineController.Instance.SelectedItem.Location));
|
||||
}
|
||||
|
||||
private void CmdOpenOutputItemLocation_Executed(object sender, EventArgs e)
|
||||
{
|
||||
if (PipelineController.Instance.SelectedItem != null)
|
||||
{
|
||||
var dir = Path.Combine(
|
||||
PipelineController.Instance.ProjectItem.Location,
|
||||
PipelineController.Instance.ProjectOutputDir,
|
||||
PipelineController.Instance.SelectedItem.Location
|
||||
);
|
||||
|
||||
dir = dir.Replace("$(Platform)", PipelineController.Instance.ProjectItem.Platform.ToString());
|
||||
dir = dir.Replace("$(Configuration)", PipelineController.Instance.ProjectItem.Config);
|
||||
dir = dir.Replace("$(Config)", PipelineController.Instance.ProjectItem.Config);
|
||||
dir = dir.Replace("$(Profile)", PipelineController.Instance.ProjectItem.Profile.ToString());
|
||||
|
||||
if (Directory.Exists(dir))
|
||||
Process.Start(dir);
|
||||
else
|
||||
ShowError("Directory Not Found", "The project output directory was not found, did you forget to build the project?");
|
||||
}
|
||||
}
|
||||
|
||||
private void CmdCopyAssetPath_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.CopyAssetPath();
|
||||
}
|
||||
|
||||
private void CmdRebuildItem_Executed(object sender, EventArgs e)
|
||||
{
|
||||
PipelineController.Instance.RebuildItems();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||