private IEnumerable <Tuple <string, string, string> > SortHierarchyLevels(IEnumerable <IViewModelNode> hierarchyLevelNodes) { List <Tuple <string, string, string> > list = new List <Tuple <string, string, string> >(); foreach (IViewModelNode node in hierarchyLevelNodes) { list.Add(new Tuple <string, string, string>(ViewModelNode.GetTopAncestor(node).Text, node.ParentNode.Text, node.Text)); } return(list); }
private async Task RefreshAsync(ViewModelNode node) { if (!node.CanReload) { // Try reloading parent instead. await RefreshAsync(node.Parent) .ConfigureAwait(true); } else { // Force-reload children and discard result. await node.GetFilteredNodesAsync(true) .ConfigureAwait(true); } }
private IViewModelNode CreateProperty(object obj) { var context = new ViewModelContext(); var contextUI = new ViewModelContext(); context.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); // add some more here... var testModel = new ViewModelNode("Root", obj); var view = ObservableViewModelNode.CreateObservableViewModel(contextUI, testModel); ObservableViewModelNode.Refresh(contextUI, context, new ViewModelState()); return(view); }
private IViewModelNode CreateProperty(object obj) { var context = new ViewModelContext(); var contextUI = new ViewModelContext(); context.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); // add some more here... var testModel = new ViewModelNode("Root", obj); var view = ObservableViewModelNode.CreateObservableViewModel(contextUI, testModel); ObservableViewModelNode.Refresh(contextUI, context, new ViewModelState()); return view; }
private IViewModelNode CreateSampleTree() { MyDateTime now = MyDateTime.FromDateTime(DateTime.Now); var context = new ViewModelContext(new ViewModelGlobalContext()); var contextUI = new ViewModelContext(new ViewModelGlobalContext()); context.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); // add some more here... var testModel = new ViewModelNode("Root", now); var view = ObservableViewModelNode.CreateObservableViewModel(contextUI, testModel); ObservableViewModelNode.Refresh(contextUI, context, new ViewModelState()); return(view); }
private IViewModelNode CreateSampleTree() { MyDateTime now = MyDateTime.FromDateTime(DateTime.Now); var context = new ViewModelContext(new ViewModelGlobalContext()); var contextUI = new ViewModelContext(new ViewModelGlobalContext()); context.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); // add some more here... var testModel = new ViewModelNode("Root", now); var view = ObservableViewModelNode.CreateObservableViewModel(contextUI, testModel); ObservableViewModelNode.Refresh(contextUI, context, new ViewModelState()); return view; }
protected void OnNewViewModel(object sender, EventArgs args) { var dlg = new NewFrm(); if (dlg.ShowDialog() != DialogResult.OK) { return; } var newName = dlg.GetName(); if (string.IsNullOrWhiteSpace(newName)) { MessageBox.Show("名称不能为空"); return; } var fileName = System.IO.Path.Combine(this.Path, newName) + Dict.Extenstions.ViewModel_Extension; if (File.Exists(fileName)) { MessageBox.Show("文件已经存在"); return; } var writer = File.CreateText(fileName); writer.Flush(); writer.Close(); var dataModel = new ViewModelNode(); dataModel.Parent = this; dataModel.FileName = System.IO.Path.GetFileNameWithoutExtension(fileName); dataModel.Name = dataModel.Text = System.IO.Path.GetFileNameWithoutExtension(fileName); dataModel.FullName = fileName; this.TreeNode.Expand(); var cmd = CommandHostManager.Instance().Get<NewViewModelCommand> (CommandHostManager.HostType.ViewModel, Dict.Commands.NewViewModel); cmd.File = dataModel.FullName; cmd.Execute(); //cmdHost.RunCommand(Dict.Commands.NewXmlModel); }
protected override void LoadFile() { //var dir = new DirectoryInfo(this.Path); //foreach (var f in dir.GetFiles()) //{ // if (f.Extension == Dict.Extenstion.XmlModel_Extension) // { // var file_node = NodeFactory.Create(Dict.NodeType.XmlModel, f.Name, f.Name); // file_node.Parent = this; // } //} var directory = new DirectoryInfo(Path); foreach (var dm in directory.GetFiles("*" + Dict.Extenstions.ViewModel_Extension)) { var dmNode = new ViewModelNode(); dmNode.FullName = dm.FullName; dmNode.Parent = this; } }
public void GenerateChildren(ViewModelContext context, IViewModelNode viewModelNode, ref bool handled) { bool handleValueType = false; if (viewModelNode.NodeValue is MicroThread) { var microThread = (MicroThread)viewModelNode.NodeValue; var script = microThread.Get(ScriptManager.ScriptProperty); viewModelNode.Content = new EnumerableViewModelContent <ViewModelReference>(() => new[] { new ViewModelReference(script, true) }); handled = true; } else if (viewModelNode.NodeValue is IScript) { var script = (IScript)viewModelNode.NodeValue; // Expose all variables of IScript (defined by user) foreach (var property in script.GetType().GetProperties()) { if (property.PropertyType != typeof(int) && property.PropertyType != typeof(float)) { continue; } viewModelNode.Children.Add(new ViewModelNode(property.Name, new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), property))); } handled = true; } else if (viewModelNode.NodeValue is Entity) { ViewModelNode componentsViewModelNode; viewModelNode.Children.Add(new ViewModelNode("Name", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(Entity).GetProperty("Name")))); viewModelNode.Children.Add(new ViewModelNode("Guid", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(Entity).GetProperty("Guid")))); viewModelNode.Children.Add(componentsViewModelNode = new ViewModelNode("Components", EnumerableViewModelContent.FromUnaryLambda <ViewModelReference, Entity>(new ParentNodeValueViewModelContent(), (entity) => entity.Properties .Select(x => x.Value) .OfType <EntityComponent>() .Select(x => new ViewModelReference(x, true))))); var availableKeysContent = new RootViewModelContent(null, typeof(string[])); componentsViewModelNode.Children.Add(new ViewModelNode("AvailableKeys", availableKeysContent)); componentsViewModelNode.Children.Add(new ViewModelNode("RequestKeys", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { var availableComponentKeys = new List <string>(); // TODO: Improve component keys enumeration (maybe need a registry?) // For now, scan assemblies for all types inheriting from EntityComponent foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { foreach (var type in assembly.GetTypes()) { if (type.IsSubclassOf(typeof(EntityComponent)) && type.GetField("Key", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy) != null) { availableComponentKeys.Add(type.AssemblyQualifiedName); } } } availableKeysContent.Value = availableComponentKeys.ToArray(); })))); componentsViewModelNode.Children.Add(new ViewModelNode("Add", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { var entity = (Entity)viewModel2.Parent.Parent.NodeValue; var componentType = Type.GetType((string)parameter); // For now, assume it will be stored in a PropertyKey inside the actual component named "Key" var componentKeyField = componentType.GetField("Key", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); entity.SetObject((PropertyKey)componentKeyField.GetValue(null), Activator.CreateInstance(componentType)); })))); handled = true; } else if (viewModelNode.NodeValue is EntityComponent) { viewModelNode.PropertyName = "EntityComponent"; var component = (EntityComponent)viewModelNode.NodeValue; // Would be better higher in the hierarchy, but it would complicate model var propertyKey = component.Entity.Properties.First(x => x.Value == component).Key; var propertyKeyName = propertyKey.OwnerType.Name; viewModelNode.Children.Add(new ViewModelNode("PropertyKeyName", new RootViewModelContent(propertyKeyName))); viewModelNode.Children.Add(new ViewModelNode("Remove", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { component.Entity.SetObject(propertyKey, null); })))); var componentViewModel = new ViewModelNode("Component", component); viewModelNode.Children.Add(componentViewModel); if (component is TransformationComponent) { componentViewModel.Children.Add(new ViewModelNode("WorldMatrix", new FieldInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(TransformationComponent).GetField("WorldMatrix"))).GenerateChildren(context)); // TODO: How to switch view model depending on TransformationComponent.Values type? Or should we always expose everything? componentViewModel.Children.Add(new ViewModelNode("LocalMatrix", new FieldInfoViewModelContent(new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(TransformationComponent).GetProperty("Value")), typeof(TransformationValue).GetField("LocalMatrix"))).GenerateChildren(context)); //if (((TransformationComponent)component).Values is TransformationTRS) { componentViewModel.Children.Add(new ViewModelNode("Translation", new FieldInfoViewModelContent(new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(TransformationComponent).GetProperty("Value")), typeof(TransformationTRS).GetField("Translation"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("Rotation", new FieldInfoViewModelContent(new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(TransformationComponent).GetProperty("Value")), typeof(TransformationTRS).GetField("Rotation"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("Scaling", new FieldInfoViewModelContent(new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(TransformationComponent).GetProperty("Value")), typeof(TransformationTRS).GetField("Scaling"))).GenerateChildren(context)); } componentViewModel.Children.Add(new ViewModelNode("Parent", LambdaViewModelContent <ViewModelReference> .FromOperand <EntityComponent>(new ParentNodeValueViewModelContent(), x => new ViewModelReference(x.Entity, false)))); componentViewModel.Children.Last().Children.Add(new ViewModelNode("SetAsRoot", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { context.ViewModelByGuid.Clear(); context.Root = context.GetModelView(((TransformationComponent)component).Parent.Entity).Children.First(x => x.PropertyName == "Components"); })))); } if (component is ModelComponent) { componentViewModel.Children.Add(new ViewModelNode("Parameters", ((ModelComponent)component).MeshParameters).GenerateChildren(context)); //componentViewModel.Children.Add(new ViewModelNode( // "MeshParameters", // EnumerableViewModelContent.FromUnaryLambda<ViewModelReference, ModelComponent>( // new ParentNodeValueViewModelContent(), // (ModelComponent) => ModelComponent.MeshParameters.Keys.Select(key => new ViewModelReference(Tuple.Create(ModelComponent.MeshParameters, key), true))))); } if (component is LightComponent) { componentViewModel.Children.Add(new ViewModelNode("Type", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightComponent).GetProperty("Type"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("ShadowMap", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightComponent).GetProperty("ShadowMap"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("Deferred", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightComponent).GetProperty("Deferred"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("Intensity", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightComponent).GetProperty("Intensity"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("DecayStart", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightComponent).GetProperty("DecayStart"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("Color", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightComponent).GetProperty("Color"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("LightDirection", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightComponent).GetProperty("LightDirection"))).GenerateChildren(context)); } if (component is LightShaftsComponent) { componentViewModel.Children.Add(new ViewModelNode("Color", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightShaftsComponent).GetProperty("Color"))).GenerateChildren(context)); //componentViewModel.Children.Add(new ViewModelNode("LightShaftsBoundingBoxes", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightShaftsComponent).GetProperty("LightShaftsBoundingBoxes"))).GenerateChildren(context)); } // Else try to display it using auto-display AutoDisplayComponent(context, viewModelNode, component); handled = true; } else if (viewModelNode.NodeValue is ParameterCollection) { viewModelNode.Content = EnumerableViewModelContent.FromUnaryLambda <ViewModelReference, ParameterCollection>(new NodeValueViewModelContent(), (parameterCollection) => parameterCollection.Keys.Where(key => key.PropertyType.IsValueType).Select(key => { if (key.PropertyType.IsValueType) { // For value type, generated tree won't change so make value based on key only. return(new ViewModelReference(Tuple.Create(parameterCollection, key), true)); } else { // TODO: resources currently ignored (until fixed) // For reference type, make value dependent on actual value reference and source. // This will trigger a regeneration for reference change (i.e. new texture bound). // Useful since asset type/state might be different. var value = parameterCollection.GetObject(key); var valueSource = engineContext.AssetManager.Url.Get(value); return(new ViewModelReference(Tuple.Create(parameterCollection, key, valueSource), true)); } })); var availableKeysContent = new RootViewModelContent(null, typeof(string[])); viewModelNode.Children.Add(new ViewModelNode("AvailableKeys", availableKeysContent)); viewModelNode.Children.Add(new ViewModelNode("RequestKeys", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { var parameterCollection = (ParameterCollection)viewModel2.Parent.NodeValue; var effectMesh = viewModel2.Parent.Parent.NodeValue as EffectMesh; if (effectMesh != null) { var availableKeys = effectMesh.Effect.Passes.SelectMany(x => x.DefaultParameters.Parameters.Select(y => y.Key)).Distinct().Where(x => !parameterCollection.IsValueOwner(x)).Select(x => x.Name).ToArray(); availableKeysContent.Value = availableKeys; } })))); viewModelNode.Children.Add(new ViewModelNode("Add", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { var effectMesh = viewModel2.Parent.Parent.NodeValue as EffectMesh; if (effectMesh != null) { var key = effectMesh.Effect.Passes.SelectMany(x => x.DefaultParameters.Parameters.Select(y => y.Key)).FirstOrDefault(x => x.Name == (string)parameter); if (key != null) { effectMesh.Parameters.SetDefault(key); } } })))); } else if (viewModelNode.NodeValue is EffectMesh) { viewModelNode.PropertyName = "Mesh"; viewModelNode.Children.Add(new ViewModelNode("Effect", LambdaViewModelContent <string> .FromParent <EffectMesh>(x => x.EffectMeshData.EffectData.Name, (x, effectName) => x.EffectMeshData.EffectData.Name = effectName))); viewModelNode.Children.Add(new ViewModelNode("Parameters", ((EffectMesh)viewModelNode.NodeValue).Parameters).GenerateChildren(context)); //viewModelNode.Children.Add(new ViewModelNode("MeshData", LambdaViewModelContent<ViewModelReference>.FromParent<MeshData>(effectMeshData => new ViewModelReference(effectMeshData.MeshData, true)))); handled = true; } else if (viewModelNode.NodeValue is ContentData || typeof(ContentData).IsAssignableFrom(viewModelNode.Type)) { if (viewModelNode.NodeValue is ContentData) { viewModelNode.Content = new NodeValueViewModelContent(); } if (viewModelNode.Value != null) { viewModelNode.Children.Add(new ViewModelNode("Url", new LambdaViewModelContent <string>(new ParentValueViewModelContent(), x => engineContext.AssetManager.Url.Get((x.Value)), (x, y) => { var nodeValue = x.OwnerNode.Parent.NodeValue; }))); viewModelNode.Children.Add(new ViewModelNode("ChangeUrl", new RootViewModelContent((ExecuteCommand)(async(viewModel2, parameter) => { var dropParameters = (DropCommandParameters)parameter; var parameterInfo = (Tuple <ParameterCollection, ParameterKey, ContentData>)viewModel2.Parent.Parent.NodeValue; var parameterCollection = parameterInfo.Item1; var textureData = await engineContext.AssetManager.LoadAsync <Image>((string)dropParameters.Data); //parameter.Item1.SetObject(parameter.Item2, ); //parameterCollection.Remove(parameterInfo.Item2); //var texture = engineContext.ContentManager.Convert<ITexture, Image>(textureData); Texture texture; throw new NotImplementedException(); parameterCollection.SetObject(parameterInfo.Item2, texture); })))); if (viewModelNode.Type == typeof(Image)) { Image thumbnail = null; Task <Image> textureData = null; viewModelNode.Children.Add(new ViewModelNode("Thumbnail", new LambdaViewModelContent <Image>(new ParentValueViewModelContent(), (viewModelContent) => { if (textureData == null) { var textureDataNew = viewModelContent.Value as Image; if (engineContext.AssetManager.Url.Get(textureDataNew) != null) { textureData = engineContext.AssetManager.LoadAsync <Image>(engineContext.AssetManager.Url.Get(textureDataNew)); textureData.ContinueWith(task => { thumbnail = task.Result; viewModelContent.OwnerNode.Content.SerializeFlags |= ViewModelContentSerializeFlags.Static; }); } } return(thumbnail); }))); } } handled = true; } else if (viewModelNode.NodeValue is MeshData) { handled = true; } else if (viewModelNode.NodeValue is Tuple <ParameterCollection, ParameterKey, ContentData> ) { var value = (Tuple <ParameterCollection, ParameterKey, ContentData>)viewModelNode.NodeValue; // Ignore namespace and class name for key name viewModelNode.PropertyName = value.Item2.Name; if (viewModelNode.PropertyName.Contains('.')) { viewModelNode.PropertyName = viewModelNode.PropertyName.Substring(viewModelNode.PropertyName.LastIndexOf('.') + 1); } viewModelNode.Content = new NullViewModelContent(typeof(Image)); if (value.Item3 != null) { viewModelNode.Children.Add(new ViewModelNode("ObjectRef", new RootViewModelContent(value.Item3) { SerializeFlags = ViewModelContentSerializeFlags.None }).GenerateChildren(context)); } handled = true; } else if (viewModelNode.NodeValue is Tuple <ParameterCollection, ParameterKey> ) { var value = (Tuple <ParameterCollection, ParameterKey>)viewModelNode.NodeValue; // Ignore namespace and class name for key name viewModelNode.PropertyName = value.Item2.Name; if (viewModelNode.PropertyName.Contains('.')) { viewModelNode.PropertyName = viewModelNode.PropertyName.Substring(viewModelNode.PropertyName.LastIndexOf('.') + 1); } if (value.Item2.PropertyType.IsValueType) { viewModelNode.Content = new LambdaViewModelContent <object>(() => value.Item1.GetObject(value.Item2), newValue => value.Item1.SetObject(value.Item2, newValue)) { Type = value.Item2.PropertyType }; handleValueType = true; } handled = true; } else if (viewModelNode.Type == typeof(Matrix) || viewModelNode.Type == typeof(Vector3) || viewModelNode.Type == typeof(Color)) { handled = true; } else if (viewModelNode.Type.IsValueType) { handleValueType = true; } if (handleValueType) { if (!(viewModelNode.Type == typeof(Matrix) || viewModelNode.Type == typeof(Vector3) || viewModelNode.Type == typeof(Color) || viewModelNode.Type == typeof(Color3))) { if (viewModelNode.Type.IsValueType && !viewModelNode.Type.IsPrimitive && !viewModelNode.Type.IsEnum) { viewModelNode.Content.SerializeFlags = ViewModelContentSerializeFlags.None; // Use default for those types foreach (var fieldinfo in viewModelNode.Type.GetFields(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance)) { IViewModelContent viewModelContent = new FieldInfoViewModelContent(new ParentValueViewModelContent(viewModelNode.Type), fieldinfo); //if (fieldinfo.FieldType.IsValueType && !fieldinfo.FieldType.IsPrimitive && !fieldinfo.FieldType.IsEnum) // viewModelContent.Flags = ViewModelFlags.None; // Doesn't support array if (fieldinfo.FieldType.IsArray) { continue; } viewModelNode.Children.Add(new ViewModelNode(fieldinfo.Name, viewModelContent).GenerateChildren(context)); } handled = true; } } } }
public void GenerateChildren(ViewModelContext context, IViewModelNode viewModelNode, ref bool handled) { bool handleValueType = false; if (viewModelNode.NodeValue is MicroThread) { var microThread = (MicroThread)viewModelNode.NodeValue; var script = microThread.Get(ScriptManager.ScriptProperty); viewModelNode.Content = new EnumerableViewModelContent<ViewModelReference>(() => new[] { new ViewModelReference(script, true) }); handled = true; } else if (viewModelNode.NodeValue is IScript) { var script = (IScript)viewModelNode.NodeValue; // Expose all variables of IScript (defined by user) foreach (var property in script.GetType().GetProperties()) { if (property.PropertyType != typeof(int) && property.PropertyType != typeof(float)) continue; viewModelNode.Children.Add(new ViewModelNode(property.Name, new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), property))); } handled = true; } else if (viewModelNode.NodeValue is Entity) { ViewModelNode componentsViewModelNode; viewModelNode.Children.Add(new ViewModelNode("Name", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(Entity).GetProperty("Name")))); viewModelNode.Children.Add(new ViewModelNode("Guid", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(Entity).GetProperty("Guid")))); viewModelNode.Children.Add(componentsViewModelNode = new ViewModelNode("Components", EnumerableViewModelContent.FromUnaryLambda<ViewModelReference, Entity>(new ParentNodeValueViewModelContent(), (entity) => entity.Properties .Select(x => x.Value) .OfType<EntityComponent>() .Select(x => new ViewModelReference(x, true))))); var availableKeysContent = new RootViewModelContent(null, typeof(string[])); componentsViewModelNode.Children.Add(new ViewModelNode("AvailableKeys", availableKeysContent)); componentsViewModelNode.Children.Add(new ViewModelNode("RequestKeys", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { var availableComponentKeys = new List<string>(); // TODO: Improve component keys enumeration (maybe need a registry?) // For now, scan assemblies for all types inheriting from EntityComponent foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { foreach (var type in assembly.GetTypes()) { if (type.IsSubclassOf(typeof(EntityComponent)) && type.GetField("Key", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy) != null) { availableComponentKeys.Add(type.AssemblyQualifiedName); } } } availableKeysContent.Value = availableComponentKeys.ToArray(); })))); componentsViewModelNode.Children.Add(new ViewModelNode("Add", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { var entity = (Entity)viewModel2.Parent.Parent.NodeValue; var componentType = Type.GetType((string)parameter); // For now, assume it will be stored in a PropertyKey inside the actual component named "Key" var componentKeyField = componentType.GetField("Key", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); entity.SetObject((PropertyKey)componentKeyField.GetValue(null), Activator.CreateInstance(componentType)); })))); handled = true; } else if (viewModelNode.NodeValue is EntityComponent) { viewModelNode.PropertyName = "EntityComponent"; var component = (EntityComponent)viewModelNode.NodeValue; // Would be better higher in the hierarchy, but it would complicate model var propertyKey = component.Entity.Properties.First(x => x.Value == component).Key; var propertyKeyName = propertyKey.OwnerType.Name; viewModelNode.Children.Add(new ViewModelNode("PropertyKeyName", new RootViewModelContent(propertyKeyName))); viewModelNode.Children.Add(new ViewModelNode("Remove", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { component.Entity.SetObject(propertyKey, null); })))); var componentViewModel = new ViewModelNode("Component", component); viewModelNode.Children.Add(componentViewModel); if (component is TransformationComponent) { componentViewModel.Children.Add(new ViewModelNode("WorldMatrix", new FieldInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(TransformationComponent).GetField("WorldMatrix"))).GenerateChildren(context)); // TODO: How to switch view model depending on TransformationComponent.Values type? Or should we always expose everything? componentViewModel.Children.Add(new ViewModelNode("LocalMatrix", new FieldInfoViewModelContent(new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(TransformationComponent).GetProperty("Value")), typeof(TransformationValue).GetField("LocalMatrix"))).GenerateChildren(context)); //if (((TransformationComponent)component).Values is TransformationTRS) { componentViewModel.Children.Add(new ViewModelNode("Translation", new FieldInfoViewModelContent(new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(TransformationComponent).GetProperty("Value")), typeof(TransformationTRS).GetField("Translation"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("Rotation", new FieldInfoViewModelContent(new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(TransformationComponent).GetProperty("Value")), typeof(TransformationTRS).GetField("Rotation"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("Scaling", new FieldInfoViewModelContent(new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(TransformationComponent).GetProperty("Value")), typeof(TransformationTRS).GetField("Scaling"))).GenerateChildren(context)); } componentViewModel.Children.Add(new ViewModelNode("Parent", LambdaViewModelContent<ViewModelReference>.FromOperand<EntityComponent>(new ParentNodeValueViewModelContent(), x => new ViewModelReference(x.Entity, false)))); componentViewModel.Children.Last().Children.Add(new ViewModelNode("SetAsRoot", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { context.ViewModelByGuid.Clear(); context.Root = context.GetModelView(((TransformationComponent)component).Parent.Entity).Children.First(x => x.PropertyName == "Components"); })))); } if (component is ModelComponent) { componentViewModel.Children.Add(new ViewModelNode("Parameters", ((ModelComponent)component).MeshParameters).GenerateChildren(context)); //componentViewModel.Children.Add(new ViewModelNode( // "MeshParameters", // EnumerableViewModelContent.FromUnaryLambda<ViewModelReference, ModelComponent>( // new ParentNodeValueViewModelContent(), // (ModelComponent) => ModelComponent.MeshParameters.Keys.Select(key => new ViewModelReference(Tuple.Create(ModelComponent.MeshParameters, key), true))))); } if (component is LightComponent) { componentViewModel.Children.Add(new ViewModelNode("Type", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightComponent).GetProperty("Type"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("ShadowMap", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightComponent).GetProperty("ShadowMap"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("Deferred", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightComponent).GetProperty("Deferred"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("Intensity", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightComponent).GetProperty("Intensity"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("DecayStart", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightComponent).GetProperty("DecayStart"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("Color", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightComponent).GetProperty("Color"))).GenerateChildren(context)); componentViewModel.Children.Add(new ViewModelNode("LightDirection", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightComponent).GetProperty("LightDirection"))).GenerateChildren(context)); } if (component is LightShaftsComponent) { componentViewModel.Children.Add(new ViewModelNode("Color", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightShaftsComponent).GetProperty("Color"))).GenerateChildren(context)); //componentViewModel.Children.Add(new ViewModelNode("LightShaftsBoundingBoxes", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(LightShaftsComponent).GetProperty("LightShaftsBoundingBoxes"))).GenerateChildren(context)); } // Else try to display it using auto-display AutoDisplayComponent(context, viewModelNode, component); handled = true; } else if (viewModelNode.NodeValue is ParameterCollection) { viewModelNode.Content = EnumerableViewModelContent.FromUnaryLambda<ViewModelReference, ParameterCollection>(new NodeValueViewModelContent(), (parameterCollection) => parameterCollection.Keys.Where(key => key.PropertyType.IsValueType).Select(key => { if (key.PropertyType.IsValueType) { // For value type, generated tree won't change so make value based on key only. return new ViewModelReference(Tuple.Create(parameterCollection, key), true); } else { // TODO: resources currently ignored (until fixed) // For reference type, make value dependent on actual value reference and source. // This will trigger a regeneration for reference change (i.e. new texture bound). // Useful since asset type/state might be different. var value = parameterCollection.GetObject(key); var valueSource = engineContext.AssetManager.Url.Get(value); return new ViewModelReference(Tuple.Create(parameterCollection, key, valueSource), true); } })); var availableKeysContent = new RootViewModelContent(null, typeof(string[])); viewModelNode.Children.Add(new ViewModelNode("AvailableKeys", availableKeysContent)); viewModelNode.Children.Add(new ViewModelNode("RequestKeys", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { var parameterCollection = (ParameterCollection)viewModel2.Parent.NodeValue; var effectMesh = viewModel2.Parent.Parent.NodeValue as EffectMesh; if (effectMesh != null) { var availableKeys = effectMesh.Effect.Passes.SelectMany(x => x.DefaultParameters.Parameters.Select(y => y.Key)).Distinct().Where(x => !parameterCollection.IsValueOwner(x)).Select(x => x.Name).ToArray(); availableKeysContent.Value = availableKeys; } })))); viewModelNode.Children.Add(new ViewModelNode("Add", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { var effectMesh = viewModel2.Parent.Parent.NodeValue as EffectMesh; if (effectMesh != null) { var key = effectMesh.Effect.Passes.SelectMany(x => x.DefaultParameters.Parameters.Select(y => y.Key)).FirstOrDefault(x => x.Name == (string)parameter); if (key != null) { effectMesh.Parameters.SetDefault(key); } } })))); } else if (viewModelNode.NodeValue is EffectMesh) { viewModelNode.PropertyName = "Mesh"; viewModelNode.Children.Add(new ViewModelNode("Effect", LambdaViewModelContent<string>.FromParent<EffectMesh>(x => x.EffectMeshData.EffectData.Name, (x, effectName) => x.EffectMeshData.EffectData.Name = effectName))); viewModelNode.Children.Add(new ViewModelNode("Parameters", ((EffectMesh)viewModelNode.NodeValue).Parameters).GenerateChildren(context)); //viewModelNode.Children.Add(new ViewModelNode("MeshData", LambdaViewModelContent<ViewModelReference>.FromParent<MeshData>(effectMeshData => new ViewModelReference(effectMeshData.MeshData, true)))); handled = true; } else if (viewModelNode.NodeValue is ContentData || typeof(ContentData).IsAssignableFrom(viewModelNode.Type)) { if (viewModelNode.NodeValue is ContentData) viewModelNode.Content = new NodeValueViewModelContent(); if (viewModelNode.Value != null) { viewModelNode.Children.Add(new ViewModelNode("Url", new LambdaViewModelContent<string>(new ParentValueViewModelContent(), x => engineContext.AssetManager.Url.Get((x.Value)), (x, y) => { var nodeValue = x.OwnerNode.Parent.NodeValue; }))); viewModelNode.Children.Add(new ViewModelNode("ChangeUrl", new RootViewModelContent((ExecuteCommand)(async (viewModel2, parameter) => { var dropParameters = (DropCommandParameters)parameter; var parameterInfo = (Tuple<ParameterCollection, ParameterKey, ContentData>)viewModel2.Parent.Parent.NodeValue; var parameterCollection = parameterInfo.Item1; var textureData = await engineContext.AssetManager.LoadAsync<Image>((string)dropParameters.Data); //parameter.Item1.SetObject(parameter.Item2, ); //parameterCollection.Remove(parameterInfo.Item2); //var texture = engineContext.ContentManager.Convert<ITexture, Image>(textureData); Texture texture; throw new NotImplementedException(); parameterCollection.SetObject(parameterInfo.Item2, texture); })))); if (viewModelNode.Type == typeof(Image)) { Image thumbnail = null; Task<Image> textureData = null; viewModelNode.Children.Add(new ViewModelNode("Thumbnail", new LambdaViewModelContent<Image>(new ParentValueViewModelContent(), (viewModelContent) => { if (textureData == null) { var textureDataNew = viewModelContent.Value as Image; if (engineContext.AssetManager.Url.Get(textureDataNew) != null) { textureData = engineContext.AssetManager.LoadAsync<Image>(engineContext.AssetManager.Url.Get(textureDataNew)); textureData.ContinueWith(task => { thumbnail = task.Result; viewModelContent.OwnerNode.Content.SerializeFlags |= ViewModelContentSerializeFlags.Static; }); } } return thumbnail; }))); } } handled = true; } else if (viewModelNode.NodeValue is MeshData) { handled = true; } else if (viewModelNode.NodeValue is Tuple<ParameterCollection, ParameterKey, ContentData>) { var value = (Tuple<ParameterCollection, ParameterKey, ContentData>)viewModelNode.NodeValue; // Ignore namespace and class name for key name viewModelNode.PropertyName = value.Item2.Name; if (viewModelNode.PropertyName.Contains('.')) viewModelNode.PropertyName = viewModelNode.PropertyName.Substring(viewModelNode.PropertyName.LastIndexOf('.') + 1); viewModelNode.Content = new NullViewModelContent(typeof(Image)); if (value.Item3 != null) viewModelNode.Children.Add(new ViewModelNode("ObjectRef", new RootViewModelContent(value.Item3) { SerializeFlags = ViewModelContentSerializeFlags.None }).GenerateChildren(context)); handled = true; } else if (viewModelNode.NodeValue is Tuple<ParameterCollection, ParameterKey>) { var value = (Tuple<ParameterCollection, ParameterKey>)viewModelNode.NodeValue; // Ignore namespace and class name for key name viewModelNode.PropertyName = value.Item2.Name; if (viewModelNode.PropertyName.Contains('.')) viewModelNode.PropertyName = viewModelNode.PropertyName.Substring(viewModelNode.PropertyName.LastIndexOf('.') + 1); if (value.Item2.PropertyType.IsValueType) { viewModelNode.Content = new LambdaViewModelContent<object>(() => value.Item1.GetObject(value.Item2), newValue => value.Item1.SetObject(value.Item2, newValue)) { Type = value.Item2.PropertyType }; handleValueType = true; } handled = true; } else if (viewModelNode.Type == typeof(Matrix) || viewModelNode.Type == typeof(Vector3) || viewModelNode.Type == typeof(Color)) { handled = true; } else if (viewModelNode.Type.IsValueType) { handleValueType = true; } if (handleValueType) { if (!(viewModelNode.Type == typeof(Matrix) || viewModelNode.Type == typeof(Vector3) || viewModelNode.Type == typeof(Color) || viewModelNode.Type == typeof(Color3))) { if (viewModelNode.Type.IsValueType && !viewModelNode.Type.IsPrimitive && !viewModelNode.Type.IsEnum) { viewModelNode.Content.SerializeFlags = ViewModelContentSerializeFlags.None; // Use default for those types foreach (var fieldinfo in viewModelNode.Type.GetFields(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance)) { IViewModelContent viewModelContent = new FieldInfoViewModelContent(new ParentValueViewModelContent(viewModelNode.Type), fieldinfo); //if (fieldinfo.FieldType.IsValueType && !fieldinfo.FieldType.IsPrimitive && !fieldinfo.FieldType.IsEnum) // viewModelContent.Flags = ViewModelFlags.None; // Doesn't support array if (fieldinfo.FieldType.IsArray) continue; viewModelNode.Children.Add(new ViewModelNode(fieldinfo.Name, viewModelContent).GenerateChildren(context)); } handled = true; } } } }
public void GenerateChildren(ViewModelContext context, IViewModelNode viewModelNode, ref bool handled) { if ((viewModelNode.NodeValue as string) == "Root") { viewModelNode.Children.Add(new ViewModelNode("SearchResults", new EnumerableViewModelContent <ViewModelReference>(() => searchResults != null && searchResults.IsCompleted ? searchResults.Result.Select(searchResult => new ViewModelReference(KeyValuePair.Create(UrlType.SearchResult, searchResult), true)) : new ViewModelReference[] { }))); viewModelNode.Children.Add(new ViewModelNode("SearchFilter", new LambdaViewModelContent <string>( () => searchFilter, (newFilter) => { searchFilter = newFilter; StartSearch(); }))); viewModelNode.Children.Add(new ViewModelNode("Packages", new EnumerableViewModelContent <ViewModelReference>(() => engineContext.PackageManager.Packages.Select(package => new ViewModelReference(package, true))))); fileTracker = new FileTracker(); fileTracker.Setup("/global_data"); fileTracker.Setup("/global_data2"); viewModelNode.Children.Add(new ViewModelNode("FileTracker", new RootViewModelContent(fileTracker)).GenerateChildren(context)); } if (viewModelNode.Type == typeof(FileTracker)) { viewModelNode.Content.SerializeFlags = ViewModelContentSerializeFlags.None; viewModelNode.Children.Add(new ViewModelNode("RootFolder", KeyValuePair.Create(UrlType.FileTracker, "/")).GenerateChildren(context)); handled = true; } if (viewModelNode.NodeValue is Package) { viewModelNode.Children.Add(new ViewModelNode("Name", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(Package).GetProperty("Name")))); handled = true; } if (viewModelNode.NodeValue is Tuple <UrlType, string> ) { var nodeValue = (Tuple <UrlType, string>)viewModelNode.NodeValue; var url = nodeValue.Item2; if (nodeValue.Item1 == UrlType.SearchResult) { // Load thumbnail (not cached yet) if (url.EndsWith(".png") || url.EndsWith(".jpg")) { //var textureData = engineContext.ContentManager.LoadAsync<Image>(url); var thumbnail = new ViewModelNode("Thumbnail", new AsyncViewModelContent <Image>(new NullViewModelContent(), operand => engineContext.AssetManager.Load <Image>(url))); viewModelNode.Children.Add(thumbnail); /*textureData.ContinueWith(task => * { * thumbnail.Value = task.Result; * thumbnail.Content.Flags |= ViewModelFlags.Static; * });*/ } /*else * { * throw new NotImplementedException(); * }*/ viewModelNode.Content = new RootViewModelContent(url); viewModelNode.Content.SerializeFlags = ViewModelContentSerializeFlags.Serialize; } else if (nodeValue.Item1 == UrlType.FileTracker) { viewModelNode.Content = new RootViewModelContent(url); viewModelNode.Content.SerializeFlags = ViewModelContentSerializeFlags.Serialize; viewModelNode.Children.Add(new ViewModelNode("SetAsSearchFilter", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { searchRoot = url; StartSearch(); })))); if (url.EndsWith("/")) { viewModelNode.Children.Add(new ViewModelNode("Folders", new EnumerableViewModelContent <ViewModelReference>(() => fileTracker.Files .Where(file => file.StartsWith(url)) .GroupBy(file => { var separatorIndex = file.IndexOf('/', url.Length + 1); return(file.Substring(url.Length, separatorIndex != -1 ? separatorIndex - url.Length + 1 : file.Length - url.Length)); }) .Where(x => x.Key.EndsWith("/") || x.Key.EndsWith(".dat") || x.Key.EndsWith(".xksl")) .Select(x => new ViewModelReference(KeyValuePair.Create(UrlType.FileTracker, url + x.Key), this)) ))); } } handled = true; } }
public void GenerateChildren(ViewModelContext context, IViewModelNode viewModelNode, ref bool handled) { if ((viewModelNode.NodeValue as string) == "Root") { viewModelNode.Children.Add(new ViewModelNode("SearchResults", new EnumerableViewModelContent<ViewModelReference>(() => searchResults != null && searchResults.IsCompleted ? searchResults.Result.Select(searchResult => new ViewModelReference(KeyValuePair.Create(UrlType.SearchResult, searchResult), true)) : new ViewModelReference[] { }))); viewModelNode.Children.Add(new ViewModelNode("SearchFilter", new LambdaViewModelContent<string>( () => searchFilter, (newFilter) => { searchFilter = newFilter; StartSearch(); }))); viewModelNode.Children.Add(new ViewModelNode("Packages", new EnumerableViewModelContent<ViewModelReference>(() => engineContext.PackageManager.Packages.Select(package => new ViewModelReference(package, true))))); fileTracker = new FileTracker(); fileTracker.Setup("/global_data"); fileTracker.Setup("/global_data2"); viewModelNode.Children.Add(new ViewModelNode("FileTracker", new RootViewModelContent(fileTracker)).GenerateChildren(context)); } if (viewModelNode.Type == typeof(FileTracker)) { viewModelNode.Content.SerializeFlags = ViewModelContentSerializeFlags.None; viewModelNode.Children.Add(new ViewModelNode("RootFolder", KeyValuePair.Create(UrlType.FileTracker, "/")).GenerateChildren(context)); handled = true; } if (viewModelNode.NodeValue is Package) { viewModelNode.Children.Add(new ViewModelNode("Name", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(Package).GetProperty("Name")))); handled = true; } if (viewModelNode.NodeValue is Tuple<UrlType, string>) { var nodeValue = (Tuple<UrlType, string>)viewModelNode.NodeValue; var url = nodeValue.Item2; if (nodeValue.Item1 == UrlType.SearchResult) { // Load thumbnail (not cached yet) if (url.EndsWith(".png") || url.EndsWith(".jpg")) { //var textureData = engineContext.ContentManager.LoadAsync<Image>(url); var thumbnail = new ViewModelNode("Thumbnail", new AsyncViewModelContent<Image>(new NullViewModelContent(), operand => engineContext.AssetManager.Load<Image>(url))); viewModelNode.Children.Add(thumbnail); /*textureData.ContinueWith(task => { thumbnail.Value = task.Result; thumbnail.Content.Flags |= ViewModelFlags.Static; });*/ } /*else { throw new NotImplementedException(); }*/ viewModelNode.Content = new RootViewModelContent(url); viewModelNode.Content.SerializeFlags = ViewModelContentSerializeFlags.Serialize; } else if (nodeValue.Item1 == UrlType.FileTracker) { viewModelNode.Content = new RootViewModelContent(url); viewModelNode.Content.SerializeFlags = ViewModelContentSerializeFlags.Serialize; viewModelNode.Children.Add(new ViewModelNode("SetAsSearchFilter", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { searchRoot = url; StartSearch(); })))); if (url.EndsWith("/")) { viewModelNode.Children.Add(new ViewModelNode("Folders", new EnumerableViewModelContent<ViewModelReference>(() => fileTracker.Files .Where(file => file.StartsWith(url)) .GroupBy(file => { var separatorIndex = file.IndexOf('/', url.Length + 1); return file.Substring(url.Length, separatorIndex != -1 ? separatorIndex - url.Length + 1 : file.Length - url.Length); }) .Where(x => x.Key.EndsWith("/") || x.Key.EndsWith(".dat") || x.Key.EndsWith(".xksl")) .Select(x => new ViewModelReference(KeyValuePair.Create(UrlType.FileTracker, url + x.Key), this)) ))); } } handled = true; } }