// Token: 0x06000051 RID: 81 RVA: 0x00003944 File Offset: 0x00001B44 public override void DoWindowContents(Rect inRect) { var listContainer = new ListContainer { spaceBetween = 10f }; listContainer.Add(new TextWidget( "ATTENTION: This feature is highly experimental. Only use it if you're playing with a save you could potentially corrupt.")); var listContainer2 = new ListContainer { drawAlternateBackground = true }; listContainer.Add(new ScrollContainer(listContainer2, scrollPosition, delegate(Vector2 s) { scrollPosition = s; })); using (var enumerator = (from p in Find.CurrentMap.mapPawns.AllPawns where p.RaceProps.Animal && p.Faction == Faction.OfPlayer select p).GetEnumerator()) { while (enumerator.MoveNext()) { var item = enumerator.Current; var listContainer3 = new ListContainer(ListFlow.ROW) { spaceBetween = 10f }; listContainer2.Add(new HeightContainer(listContainer3, 40f)); if (item != null) { listContainer3.Add(new ButtonWidget(item.Label, delegate { OnAnimalClick(item); }, false)); } } } listContainer.Draw(inRect); }
public override void DoWindowContents(Rect inRect) { ListContainer mainCont = new ListContainer(); mainCont.spaceBetween = ListContainer.SPACE; mainCont.Add(new TextWidget("ATTENTION: This feature is highly experimental. Only use it if you're playing with a save you could potentially corrupt.")); //Adds a scrollable container for trading animals. ListContainer columnCont = new ListContainer(); columnCont.drawAlternateBackground = true; mainCont.Add(new ScrollContainer(columnCont, scrollPosition, (s) => { scrollPosition = s; })); float beginY = 0f; //Unused foreach (Pawn animal in Find.VisibleMap.mapPawns.AllPawns.Where(p => p.RaceProps.Animal && p.Faction == Faction.OfPlayer)) { ListContainer rowCont = new ListContainer(ListFlow.ROW); rowCont.spaceBetween = ListContainer.SPACE; columnCont.Add(new HeightContainer(rowCont, 40f)); rowCont.Add(new ButtonWidget(animal.Label, () => OnAnimalClick(animal), false)); } mainCont.Draw(inRect); }
// Token: 0x06000055 RID: 85 RVA: 0x00003AB4 File Offset: 0x00001CB4 public override void DoWindowContents(Rect inRect) { var listContainer = new ListContainer { spaceBetween = 10f }; listContainer.Add(new TextWidget( "ATTENTION: This feature is highly experimental. Only use it if you're playing with a save you could potentially corrupt.")); var listContainer2 = new ListContainer { drawAlternateBackground = true }; listContainer.Add(new ScrollContainer(listContainer2, scrollPosition, delegate(Vector2 s) { scrollPosition = s; })); using (IEnumerator <Pawn> enumerator = Find.CurrentMap.mapPawns.FreeColonists.GetEnumerator()) { while (enumerator.MoveNext()) { var freeColonist = enumerator.Current; var listContainer3 = new ListContainer(ListFlow.ROW) { spaceBetween = 10f }; listContainer2.Add(new HeightContainer(listContainer3, 40f)); listContainer3.Add(new ButtonWidget(freeColonist?.Label, delegate { OnColonistClick(freeColonist); }, false)); } } listContainer.Draw(inRect); }
public override void DoWindowContents(Rect inRect) { base.DoWindowContents(inRect); PhiClient phi = PhiClient.instance; ListContainer mainList = new ListContainer(); mainList.spaceBetween = ListContainer.SPACE; mainList.Add(new TextWidget("Realm", GameFont.Medium, TextAnchor.MiddleCenter)); ListContainer rowBodyContainer = new ListContainer(new List <Displayable>() { DoChat(), new WidthContainer(DoBodyRightBar(), STATUS_AREA_WIDTH) }, ListFlow.ROW); rowBodyContainer.spaceBetween = ListContainer.SPACE; mainList.Add(rowBodyContainer); mainList.Add(new HeightContainer(DoFooter(), 30f)); mainList.Draw(inRect); }
public override void DoWindowContents(Rect inRect) { ListContainer mainCont = new ListContainer(); mainCont.spaceBetween = ListContainer.SPACE; mainCont.Add(new TextWidget("ATTENTION: This feature is highly experimental. Only use it if you're playing with a save you could potentially corrupt.")); //Adds a scrollable container for trading colonists. ListContainer columnCont = new ListContainer(); columnCont.drawAlternateBackground = true; mainCont.Add(new ScrollContainer(columnCont, scrollPosition, (s) => { scrollPosition = s; })); float beginY = 0f; //Unused foreach (Pawn colonist in Find.MapPawns.FreeColonists) { ListContainer rowCont = new ListContainer(ListFlow.ROW); rowCont.spaceBetween = ListContainer.SPACE; columnCont.Add(new HeightContainer(rowCont, ROW_HEIGHT)); rowCont.Add(new ButtonWidget(colonist.Label, () => OnColonistClick(colonist), false)); } cont.Draw(inRect); }
public override void DoWindowContents(Rect inRect) { ListContainer mainCont = new ListContainer(); mainCont.spaceBetween = ListContainer.SPACE; // Title mainCont.Add(new TextWidget("Ship to " + this.user.name, GameFont.Medium, TextAnchor.MiddleCenter)); /** * Draw the search input */ mainCont.Add(new Container(new TextFieldWidget(filterTerm, (s) => { filterTerm = s; FilterInventory(); }), 150f, 30f)); /** * Drawing the inventory */ ListContainer columnCont = new ListContainer(); columnCont.drawAlternateBackground = true; mainCont.Add(new ScrollContainer(columnCont, scrollPosition, (s) => { scrollPosition = s; })); foreach (List <Thing> entry in filteredInventory) { Thing thing = entry[0]; int stackCount = entry.Sum((e) => e.stackCount); int chosenCount = 0; chosenThings.TryGetValue(entry, out chosenCount); ListContainer rowCont = new ListContainer(ListFlow.ROW); rowCont.spaceBetween = ListContainer.SPACE; columnCont.Add(new HeightContainer(rowCont, ROW_HEIGHT)); rowCont.Add(new Container(new ThingIconWidget(thing), ROW_HEIGHT, ROW_HEIGHT)); rowCont.Add(new TextWidget(thing.LabelCapNoCount, GameFont.Small, TextAnchor.MiddleLeft)); rowCont.Add(new TextWidget(stackCount.ToString(), GameFont.Small, TextAnchor.MiddleRight)); // We add the controls for changing the quantity sent ListContainer controlsCont = new ListContainer(ListFlow.ROW); rowCont.Add(new WidthContainer(controlsCont, CONTROLS_WIDTH)); controlsCont.Add(new ButtonWidget("-100", () => ChangeChosenCount(entry, -100))); controlsCont.Add(new ButtonWidget("-10", () => ChangeChosenCount(entry, -10))); controlsCont.Add(new ButtonWidget("-1", () => ChangeChosenCount(entry, -1))); controlsCont.Add(new TextWidget(chosenCount.ToString(), GameFont.Small, TextAnchor.MiddleCenter)); controlsCont.Add(new ButtonWidget("+1", () => ChangeChosenCount(entry, 1))); controlsCont.Add(new ButtonWidget("+10", () => ChangeChosenCount(entry, 10))); controlsCont.Add(new ButtonWidget("+100", () => ChangeChosenCount(entry, 100))); } // We add the send button mainCont.Add(new HeightContainer(new ButtonWidget("Send", OnSendClick), ROW_HEIGHT)); mainCont.Draw(inRect); }
private Displayable DoBodyRightBar() { PhiClient phi = PhiClient.instance; ListContainer cont = new ListContainer(); cont.spaceBetween = ListContainer.SPACE; string status = "Status: "; switch (phi.client.state) { case WebSocketState.Open: status += "Connected"; break; case WebSocketState.Closed: status += "Disconnected"; break; case WebSocketState.Connecting: status += "Connecting"; break; case WebSocketState.Closing: status += "Disconnecting"; break; } cont.Add(new TextWidget(status)); cont.Add(new HeightContainer(new ButtonWidget("Configuration", () => { OnConfigurationClick(); }), 30f)); cont.Add(new Container(new TextFieldWidget(filterName, (s) => { filterName = s; }), 150f, 30f)); if (phi.IsUsable()) { ListContainer usersList = new ListContainer(); foreach (User user in phi.realmData.users.Where((u) => u.connected)) { if (filterName != "") { if (ContainsStringIgnoreCase(user.name, filterName)) { usersList.Add(new ButtonWidget(user.name, () => { OnUserClick(user); }, false)); } } else { usersList.Add(new ButtonWidget(user.name, () => { OnUserClick(user); }, false)); } } cont.Add(new ScrollContainer(usersList, userScrollPosition, (v) => { userScrollPosition = v; })); } return(cont); }
public Displayable DoConnectedContent() { PhiClient client = PhiClient.instance; ListContainer mainCont = new ListContainer(); mainCont.spaceBetween = ListContainer.SPACE; /** * Changing your nickname */ ListContainer changeNickCont = new ListContainer(ListFlow.ROW); changeNickCont.spaceBetween = ListContainer.SPACE; mainCont.Add(new HeightContainer(changeNickCont, 30f)); changeNickCont.Add(new TextFieldWidget(wantedNickname, (s) => wantedNickname = OnWantedNicknameChange(s))); changeNickCont.Add(new WidthContainer(new ButtonWidget("Change nickname", OnChangeNicknameClick), 140f)); /** * Preferences list */ UserPreferences pref = client.currentUser.preferences; ListContainer twoColumn = new ListContainer(ListFlow.ROW); twoColumn.spaceBetween = ListContainer.SPACE; mainCont.Add(twoColumn); ListContainer firstColumn = new ListContainer(); twoColumn.Add(firstColumn); firstColumn.Add(new CheckboxLabeledWidget("Allow receiving items", pref.receiveItems, (b) => { pref.receiveItems = b; client.UpdatePreferences(); })); firstColumn.Add(new CheckboxLabeledWidget("Allow receiving colonists (EXPERIMENTAL)", pref.receiveColonists, (b) => { pref.receiveColonists = b; client.UpdatePreferences(); })); firstColumn.Add(new CheckboxLabeledWidget("Allow receiving animals (EXPERIMENTAL)", pref.receiveAnimals, (b) => { pref.receiveAnimals = b; client.UpdatePreferences(); })); // Just to take spaces while the column is empty ListContainer secondColumn = new ListContainer(); twoColumn.Add(secondColumn); return(mainCont); }
// Token: 0x06000049 RID: 73 RVA: 0x00003504 File Offset: 0x00001704 public override void DoWindowContents(Rect inRect) { var listContainer = new ListContainer { spaceBetween = 10f }; listContainer.Add(new TextWidget("Ship to " + user.name, GameFont.Medium, TextAnchor.MiddleCenter)); listContainer.Add(new Container(new TextFieldWidget(filterTerm, delegate(string s) { filterTerm = s; FilterInventory(); }), 150f, 30f)); var listContainer2 = new ListContainer { drawAlternateBackground = true }; listContainer.Add(new ScrollContainer(listContainer2, scrollPosition, delegate(Vector2 s) { scrollPosition = s; })); using (var enumerator = filteredInventory.GetEnumerator()) { while (enumerator.MoveNext()) { var item = enumerator.Current; if (item == null) { continue; } var thing = item[0]; var num = item.Sum(e => e.stackCount); chosenThings.TryGetValue(item, out var num2); var listContainer3 = new ListContainer(ListFlow.ROW) { spaceBetween = 10f }; listContainer2.Add(new HeightContainer(listContainer3, 30f)); listContainer3.Add(new Container(new ThingIconWidget(thing), 30f, 30f)); listContainer3.Add(new TextWidget(thing.LabelCapNoCount, GameFont.Small, TextAnchor.MiddleLeft)); listContainer3.Add(new TextWidget(num.ToString(), GameFont.Small, TextAnchor.MiddleRight)); var listContainer4 = new ListContainer(ListFlow.ROW); listContainer3.Add(new WidthContainer(listContainer4, 300f)); listContainer4.Add(new ButtonWidget("-100", delegate { ChangeChosenCount(item, -100); })); listContainer4.Add(new ButtonWidget("-10", delegate { ChangeChosenCount(item, -10); })); listContainer4.Add(new ButtonWidget("-1", delegate { ChangeChosenCount(item, -1); })); listContainer4.Add(new TextFieldWidget(num2.ToString(), delegate(string str) { ChangeChosenCount(item, str); })); listContainer4.Add(new ButtonWidget("+1", delegate { ChangeChosenCount(item, 1); })); listContainer4.Add(new ButtonWidget("+10", delegate { ChangeChosenCount(item, 10); })); listContainer4.Add(new ButtonWidget("+100", delegate { ChangeChosenCount(item, 100); })); } } listContainer.Add(new HeightContainer(new ButtonWidget("Send", OnSendClick), 30f)); listContainer.Draw(inRect); }
// Token: 0x06000026 RID: 38 RVA: 0x000028FC File Offset: 0x00000AFC public override void DoWindowContents(Rect inRect) { var instance = PhiClient.instance; var listContainer = new ListContainer { spaceBetween = 10f }; listContainer.Add(new HeightContainer(DoHeader(), 30f)); if (instance.IsUsable()) { listContainer.Add(DoConnectedContent()); } listContainer.Draw(inRect); }
public override void DoWindowContents(Rect inRect) { PhiClient client = PhiClient.instance; ListContainer cont = new ListContainer(); cont.spaceBetween = ListContainer.SPACE; cont.Add(new HeightContainer(DoHeader(), 30f)); if (client.IsUsable()) { cont.Add(DoConnectedContent()); } cont.Draw(inRect); }
// Token: 0x06000028 RID: 40 RVA: 0x00002A0C File Offset: 0x00000C0C public Displayable DoConnectedContent() { var client = PhiClient.instance; var listContainer = new ListContainer { spaceBetween = 10f }; var listContainer2 = new ListContainer(ListFlow.ROW) { spaceBetween = 10f }; listContainer.Add(new HeightContainer(listContainer2, 30f)); listContainer2.Add(new TextFieldWidget(wantedNickname, delegate(string s) { wantedNickname = OnWantedNicknameChange(s); })); listContainer2.Add(new WidthContainer(new ButtonWidget("Change nickname", OnChangeNicknameClick), 140f)); var pref = client.currentUser.preferences; var listContainer3 = new ListContainer(ListFlow.ROW) { spaceBetween = 10f }; listContainer.Add(listContainer3); var listContainer4 = new ListContainer(); listContainer3.Add(listContainer4); listContainer4.Add(new CheckboxLabeledWidget("Allow receiving items", pref.receiveItems, delegate(bool b) { pref.receiveItems = b; client.UpdatePreferences(); })); listContainer4.Add(new CheckboxLabeledWidget("Allow receiving colonists (EXPERIMENTAL)", pref.receiveColonists, delegate(bool b) { pref.receiveColonists = b; client.UpdatePreferences(); })); listContainer4.Add(new CheckboxLabeledWidget("Allow receiving animals (EXPERIMENTAL)", pref.receiveAnimals, delegate(bool b) { pref.receiveAnimals = b; client.UpdatePreferences(); })); var display = new ListContainer(); listContainer3.Add(display); return(listContainer); }
private Displayable DoFooter() { ListContainer footerList = new ListContainer(ListFlow.ROW); footerList.spaceBetween = ListContainer.SPACE; // Enter shorcut if (Event.current.type == EventType.KeyDown && (Event.current.keyCode == KeyCode.KeypadEnter || Event.current.keyCode == KeyCode.Return)) { OnSendClick(); Event.current.Use(); } footerList.Add(new TextFieldWidget(enteredMessage, (s) => { enteredMessage = s; })); footerList.Add(new WidthContainer(new ButtonWidget("Send", OnSendClick), CHAT_INPUT_SEND_BUTTON_WIDTH)); return(footerList); }
private void AddStudentContainer() { StudentDataContainer container = new StudentDataContainer(); container.TextFirstName.MaxLength = m_firstNameLength; container.TextSecondName.MaxLength = m_secondNameLength; container.TextMiddleName.MaxLength = m_middleNameLength; m_studentList.Add(container); }
private SemesterLengthContainer AddSemester() { SemesterLengthContainer container = new SemesterLengthContainer(); container.Number = (short)(m_semestersList.Count + 1); container.IsChanged = false; m_semestersList.Add(container); return(container); }
private TextBoxGroupType AddGroupType() { var groupType = new TextBoxGroupType(); m_listGroupTypes.Add(groupType); groupType.GroupTypeID = -1; groupType.IsChanged = false; return(groupType); }
// Token: 0x06000031 RID: 49 RVA: 0x00002C20 File Offset: 0x00000E20 public override void DoWindowContents(Rect inRect) { var unused = PhiClient.instance; var listContainer = new ListContainer { spaceBetween = 10f }; listContainer.Add(new TextWidget("Realm", GameFont.Medium, TextAnchor.MiddleCenter)); listContainer.Add(new ListContainer(new List <Displayable> { DoChat(), new WidthContainer(DoBodyRightBar(), 160f) }, ListFlow.ROW) { spaceBetween = 10f }); listContainer.Add(new HeightContainer(DoFooter(), 30f)); listContainer.Draw(inRect); }
// Token: 0x06000036 RID: 54 RVA: 0x0000306C File Offset: 0x0000126C private Displayable DoFooter() { var listContainer = new ListContainer(ListFlow.ROW) { spaceBetween = 10f }; if (Event.current.type == EventType.KeyDown && (Event.current.keyCode == KeyCode.KeypadEnter || Event.current.keyCode == KeyCode.Return)) { OnSendClick(); Event.current.Use(); } listContainer.Add(new TextFieldWidget(enteredMessage, delegate(string s) { enteredMessage = OnEnteredMessageChange(s); })); listContainer.Add(new WidthContainer(new ButtonWidget("Send", OnSendClick), 100f)); return(listContainer); }
private SubjectTypeContainer AddSubjectType() { SubjectTypeContainer temp = new SubjectTypeContainer(); temp.SubjectTypeID = -1; temp.IsChanged = false; m_listSubjectTypes.Add(temp); return(temp); }
private TextBoxSubject AddSubject() { TextBoxSubject temp = new TextBoxSubject(); temp.SubjectID = -1; temp.IsChanged = false; m_listSubjects.Add(temp); return(temp); }
private void AddSemesterContainer() { if (m_listSemesters.Count > 7) { return; } SemesterDataContainer container = new SemesterDataContainer(); container.SemesterNumber = (short)(m_listSemesters.Count + 1); m_listSemesters.Add(container); }
public Displayable DoHeader() { PhiClient client = PhiClient.instance; ListContainer cont = new ListContainer(ListFlow.ROW); cont.spaceBetween = ListContainer.SPACE; if (client.IsUsable()) { cont.Add(new TextWidget("Connected to " + client.serverAddress, GameFont.Small, TextAnchor.MiddleLeft)); cont.Add(new WidthContainer(new ButtonWidget("Disconnect", () => { OnDisconnectButtonClick(); }), 140f)); } else { cont.Add(new TextFieldWidget(enteredAddress, (s) => { enteredAddress = s; })); cont.Add(new WidthContainer(new ButtonWidget("Connect", () => { OnConnectButtonClick(); }), 140f)); } return(cont); }
private Displayable DoChat() { PhiClient phi = PhiClient.instance; var cont = new ListContainer(ListFlow.COLUMN, ListDirection.OPPOSITE); foreach (ChatMessage c in phi.realmData.chat.Reverse <ChatMessage>().Take(30)) { int idx = phi.realmData.users.LastIndexOf(c.user); cont.Add(new ButtonWidget(phi.realmData.users[idx].name + ": " + c.message, () => { OnUserClick(phi.realmData.users[idx]); }, false)); } return(new ScrollContainer(cont, chatScroll, (v) => { chatScroll = v; })); }
// Token: 0x06000027 RID: 39 RVA: 0x00002950 File Offset: 0x00000B50 public Displayable DoHeader() { var instance = PhiClient.instance; var listContainer = new ListContainer(ListFlow.ROW) { spaceBetween = 10f }; if (instance.IsUsable()) { listContainer.Add(new TextWidget("Connected to " + instance.serverAddress, GameFont.Small, TextAnchor.MiddleLeft)); listContainer.Add( new WidthContainer(new ButtonWidget("Disconnect", OnDisconnectButtonClick), 140f)); } else { listContainer.Add(new TextFieldWidget(enteredAddress, delegate(string s) { enteredAddress = s; })); listContainer.Add(new WidthContainer(new ButtonWidget("Connect", OnConnectButtonClick), 140f)); } return(listContainer); }
// Token: 0x06000032 RID: 50 RVA: 0x00002CBC File Offset: 0x00000EBC private Displayable DoChat() { var phi = PhiClient.instance; var listContainer = new ListContainer(ListFlow.COLUMN, ListDirection.OPPOSITE); if (!phi.IsUsable()) { return(new ScrollContainer(listContainer, chatScroll, delegate(Vector2 v) { chatScroll = v; })); } foreach (var chatMessage in phi.realmData.chat.Reverse <ChatMessage>().Take(30)) { var idx = phi.realmData.users.LastIndexOf(chatMessage.user); listContainer.Add(new ButtonWidget(phi.realmData.users[idx].name + ": " + chatMessage.message, delegate { OnUserClick(phi.realmData.users[idx]); }, false)); } return(new ScrollContainer(listContainer, chatScroll, delegate(Vector2 v) { chatScroll = v; })); }
public void SetCollapsed(bool value) { Caret.text = value ? "\u25B6" : "\u25BC"; if (value == collapsed) { return; } if (value) { List.RemoveFromHierarchy(); } else { ListContainer.Add(listElement); } collapsed = value; }
public static NBTContent CreateCompoundForChunk(ChunkData chunk, Version version) { var nbt = new NBTContent(); nbt.dataVersion = version.GetDataVersion(); nbt.contents.Add("xPos", chunk.coords.x); nbt.contents.Add("zPos", chunk.coords.z); nbt.contents.Add("Status", "light"); ListContainer sections = new ListContainer(NBTTag.TAG_Compound); nbt.contents.Add("Sections", sections); nbt.contents.Add("TileEntities", new ListContainer(NBTTag.TAG_Compound)); nbt.contents.Add("Entities", new ListContainer(NBTTag.TAG_Compound)); //Add the rest of the tags and leave them empty nbt.contents.Add("Heightmaps", new CompoundContainer()); nbt.contents.Add("Structures", new CompoundContainer()); nbt.contents.Add("LiquidTicks", new ListContainer(NBTTag.TAG_Compound)); nbt.contents.Add("TileTicks", new ListContainer(NBTTag.TAG_Compound)); //Add post processing lists var ppList = new ListContainer(NBTTag.TAG_List); for (int i = 0; i < 16; i++) { ppList.Add(new ListContainer(NBTTag.TAG_Short)); } nbt.contents.Add("PostProcessing", ppList); //Write the actual data chunk.WriteToNBT(nbt.contents, version); /* * ListContainer postprocessing = new ListContainer(NBTTag.TAG_List); * for(int i = 0; i < 16; i++) postprocessing.Add("", new ListContainer(NBTTag.TAG_List)); * nbt.contents.Add("PostProcessing", postprocessing); * nbt.contents.Add("InhabitedTime", 0L); * nbt.contents.Add("LastUpdate", 0L); */ return(nbt); }
private PlanContainer AddPlanContainer() { try { PlanContainer container = new PlanContainer(m_collegeDataSet.Subjects, m_collegeDataSet.SubjectTypes); container.SubjectChanged += (sender, e) => { if (e.OldSubject != null) { foreach (var row in m_collegeDataSet.Subjects) { if (row.RowState == DataRowState.Deleted) { row.RejectChanges(); if (row.subject_id == e.OldSubject.subject_id) { break; } row.Delete(); } } } var deleteRow = m_collegeDataSet.Subjects.Where(row => row.RowState != DataRowState.Deleted && row.subject_id == container.Subject.subject_id).First(); deleteRow.Delete(); }; m_planList.Add(container); return(container); } catch (ApplicationException exc) { MyMessageBox.ShowError(exc.Message); } return(null); }
///<summary>Generates the full NBT data of a chunk</summary> public void WriteToNBT(CompoundContainer level, Version version) { ListContainer sectionsList = level.GetAsList("Sections"); foreach (sbyte secY in sections.Keys) { var section = sections[secY]; //if(IsSectionEmpty(secY)) continue; var comp = GetSectionCompound(sectionsList, secY); if (comp == null) { bool use_1_16_format = version >= Version.Release_1(16); comp = section.CreateCompound(secY, use_1_16_format); } sectionsList.Add(null, comp); } //Make the biomes var finalBiomeArray = MakeBiomeArray(); List <int> biomes = new List <int>(); for (int y = 0; y < 64; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++) { var b = finalBiomeArray != null ? finalBiomeArray[x, y, z] : 1; biomes.Add(b); } } } level.Add("Biomes", biomes.ToArray()); //Add TileEntities var teList = level.GetAsList("TileEntities"); foreach (var te in tileEntities) { teList.Add(te.Value.NBTCompound); } //Add Entities var entitiyList = level.GetAsList("Entities"); foreach (var e in entities) { entitiyList.Add(e.NBTCompound); } //Add "post processing" positions (i.e. block positions that need an update) var ppList = level.GetAsList("PostProcessing"); foreach (var t in blockTicks) { //TODO: section index and coordinate packing is being guessed, trying to find out how to do it. int listIndex = t.y / 16; var x = t.x % 16; var y = t.y % 16; var z = t.z % 16; var list = ppList.Get <ListContainer>(listIndex); short packed = (short)((z << 8) + (y << 4) + x); list.Add(packed); } //Add liquid / tile ticks /* * var tileTickList = level.GetAsList("TileTicks"); * var liquidTickList = level.GetAsList("LiquidTicks"); * foreach (var t in blockTicks) * { * var block = GetBlockAt(t.x, t.y, t.z).block; * bool isLiquid = block.IsLiquid; * var comp = new CompoundContainer(); * string i; * if(isLiquid) * { * //i = block.IsWater ? "minecraft:flowing_water" : "minecraft:flowing_lava"; * //flowing_water and flowing_lava only applies to non-source blocks. * i = block.ID; * } * else * { * i = block.ID; * } * var worldCoord = coords.BlockCoord + t; * comp.Add("i", i); * comp.Add("t", 20); * comp.Add("p", 0); * comp.Add("x", worldCoord.x); * comp.Add("y", worldCoord.y); * comp.Add("z", worldCoord.z); * if(isLiquid) * { * liquidTickList.Add(comp); * } * else * { * tileTickList.Add(comp); * } * }*/ }
public static void Bind(Entity entity, Main main, ListContainer commandQueueContainer) { PCInput input = entity.Get <PCInput>(); Editor editor = entity.Get <Editor>(); EditorGeeUI gui = entity.Get <EditorGeeUI>(); Property <bool> analyticsEnable = new Property <bool>(); ListProperty <SessionEntry> analyticsSessions = new ListProperty <SessionEntry>(); ListProperty <SessionEntry> analyticsActiveSessions = new ListProperty <SessionEntry>(); ListProperty <EventEntry> analyticsEvents = new ListProperty <EventEntry>(); ListProperty <EventEntry> analyticsActiveEvents = new ListProperty <EventEntry>(); ListProperty <PropertyEntry> analyticsProperties = new ListProperty <PropertyEntry>(); ListProperty <PropertyEntry> analyticsActiveProperties = new ListProperty <PropertyEntry>(); Dictionary <Session, ModelInstance> sessionPositionModels = new Dictionary <Session, ModelInstance>(); Dictionary <Session.EventList, List <ModelInstance> > eventPositionModels = new Dictionary <Session.EventList, List <ModelInstance> >(); Property <bool> analyticsPlaying = new Property <bool>(); Property <float> playbackSpeed = new Property <float> { Value = 1.0f }; Property <float> playbackLocation = new Property <float>(); const float timelineHeight = 32.0f; Scroller timelineScroller = new Scroller(); timelineScroller.ScrollAmount.Value = 60.0f; timelineScroller.EnableScissor.Value = false; timelineScroller.DefaultScrollHorizontal.Value = true; timelineScroller.AnchorPoint.Value = new Vector2(0, 1); timelineScroller.ResizeVertical.Value = true; timelineScroller.Add(new Binding <Vector2, Point>(timelineScroller.Position, x => new Vector2(0, x.Y), main.ScreenSize)); timelineScroller.Add(new Binding <Vector2, Point>(timelineScroller.Size, x => new Vector2(x.X, timelineHeight), main.ScreenSize)); timelineScroller.Add(new Binding <bool>(timelineScroller.Visible, () => analyticsEnable && Editor.EditorModelsVisible, analyticsEnable, Editor.EditorModelsVisible)); timelineScroller.Add(new Binding <bool>(timelineScroller.EnableScroll, x => !x, input.GetKey(Keys.LeftAlt))); entity.Add(new CommandBinding(entity.Delete, timelineScroller.Delete)); main.UI.Root.Children.Add(timelineScroller); timelineScroller.Add(new Binding <bool>(editor.EnableCameraDistanceScroll, () => !timelineScroller.Highlighted || editor.VoxelEditMode, timelineScroller.Highlighted, editor.VoxelEditMode)); timelineScroller.Add(new CommandBinding(timelineScroller.Delete, delegate() { editor.EnableCameraDistanceScroll.Value = true; })); ListContainer timelines = new ListContainer(); timelines.Alignment.Value = ListContainer.ListAlignment.Min; timelines.Orientation.Value = ListContainer.ListOrientation.Vertical; timelines.Reversed.Value = true; timelineScroller.Children.Add(timelines); input.Add(new CommandBinding <int>(input.MouseScrolled, () => input.GetKey(Keys.LeftAlt) && timelineScroller.Highlighted && !editor.VoxelEditMode, delegate(int delta) { float newScale = Math.Max(timelines.Scale.Value.X + delta * 6.0f, timelineScroller.Size.Value.X / timelines.Size.Value.X); Matrix absoluteTransform = timelines.GetAbsoluteTransform(); float x = input.Mouse.Value.X + ((absoluteTransform.Translation.X - input.Mouse.Value.X) * (newScale / timelines.Scale.Value.X)); timelines.Position.Value = new Vector2(x, 0.0f); timelines.Scale.Value = new Vector2(newScale, 1.0f); })); Container timeline = new Container(); timeline.Size.Value = new Vector2(0, timelineHeight); timeline.Tint.Value = Microsoft.Xna.Framework.Color.Black; timeline.ResizeHorizontal.Value = false; timeline.ResizeVertical.Value = false; timelines.Children.Add(timeline); EditorFactory.AddCommand ( entity, main, commandQueueContainer, "Load analytics data", new PCInput.Chord(), new Command { Action = delegate() { if (main.MapFile.Value != null) { List <Session> sessions = main.LoadAnalytics(main.MapFile); if (sessions.Count > 0) { analyticsEnable.Value = true; Dictionary <string, bool> distinctEventNames = new Dictionary <string, bool>(); Dictionary <string, bool> distinctPropertyNames = new Dictionary <string, bool>(); foreach (Session s in sessions) { foreach (Session.EventList el in s.Events) { distinctEventNames[el.Name] = true; s.TotalTime = Math.Max(s.TotalTime, el.Events[el.Events.Count - 1].Time); } foreach (Session.ContinuousProperty p in s.ContinuousProperties) { if (p.Independent) { distinctPropertyNames[p.Name] = true; } } analyticsSessions.Add(new SessionEntry { Session = s }); } analyticsEvents.AddAll(distinctEventNames.Keys.Select(x => new EventEntry { Name = x })); analyticsProperties.AddAll(distinctPropertyNames.Keys.Select(x => new PropertyEntry { Name = x })); timeline.Size.Value = new Vector2(analyticsSessions.Max(x => x.Session.TotalTime), timelineScroller.Size.Value.Y); timelines.Scale.Value = new Vector2(timelineScroller.Size.Value.X / timeline.Size.Value.X, 1.0f); } } } }, gui.MapCommands, () => !analyticsEnable && !string.IsNullOrEmpty(main.MapFile) && !gui.PickNextEntity, analyticsEnable, main.MapFile, gui.PickNextEntity ); ListContainer sessionsSidebar = new ListContainer(); sessionsSidebar.AnchorPoint.Value = new Vector2(1, 1); sessionsSidebar.Add(new Binding <Vector2>(sessionsSidebar.Position, () => new Vector2(main.ScreenSize.Value.X - 10, main.ScreenSize.Value.Y - timelineScroller.ScaledSize.Value.Y - 10), main.ScreenSize, timelineScroller.ScaledSize)); sessionsSidebar.Add(new Binding <bool>(sessionsSidebar.Visible, () => analyticsEnable && Editor.EditorModelsVisible, analyticsEnable, Editor.EditorModelsVisible)); sessionsSidebar.Alignment.Value = ListContainer.ListAlignment.Max; sessionsSidebar.Reversed.Value = true; main.UI.Root.Children.Add(sessionsSidebar); entity.Add(new CommandBinding(entity.Delete, sessionsSidebar.Delete)); Func <string, ListContainer> createCheckboxListItem = delegate(string text) { ListContainer layout = new ListContainer(); layout.Orientation.Value = ListContainer.ListOrientation.Horizontal; TextElement label = new TextElement(); label.FontFile.Value = main.Font; label.Text.Value = text; label.Name.Value = "Label"; layout.Children.Add(label); Container checkboxContainer = new Container(); checkboxContainer.PaddingBottom.Value = checkboxContainer.PaddingLeft.Value = checkboxContainer.PaddingRight.Value = checkboxContainer.PaddingTop.Value = 1.0f; layout.Children.Add(checkboxContainer); Container checkbox = new Container(); checkbox.Name.Value = "Checkbox"; checkbox.ResizeHorizontal.Value = checkbox.ResizeVertical.Value = false; checkbox.Size.Value = new Vector2(16.0f, 16.0f); checkboxContainer.Children.Add(checkbox); return(layout); }; Container sessionsContainer = new Container(); sessionsContainer.Tint.Value = Microsoft.Xna.Framework.Color.Black; sessionsContainer.Opacity.Value = UIFactory.Opacity; sessionsContainer.AnchorPoint.Value = new Vector2(1, 1); sessionsSidebar.Children.Add(sessionsContainer); Scroller sessionsScroller = new Scroller(); sessionsScroller.ResizeHorizontal.Value = true; sessionsScroller.ResizeVertical.Value = true; sessionsScroller.MaxVerticalSize.Value = 256; sessionsContainer.Children.Add(sessionsScroller); ListContainer sessionList = new ListContainer(); sessionList.Orientation.Value = ListContainer.ListOrientation.Vertical; sessionList.Alignment.Value = ListContainer.ListAlignment.Max; sessionsScroller.Children.Add(sessionList); Property <bool> allSessions = new Property <bool>(); sessionList.Add(new ListBinding <UIComponent, SessionEntry>(sessionList.Children, analyticsSessions, delegate(SessionEntry entry) { ListContainer item = createCheckboxListItem(string.Format("{0} {1:d} ({2})", entry.Session.UUID.Substring(0, 8), entry.Session.Date, new TimeSpan(0, 0, (int)entry.Session.TotalTime))); Container checkbox = (Container)item.GetChildByName("Checkbox"); checkbox.Add(new Binding <Microsoft.Xna.Framework.Color, bool>(checkbox.Tint, x => x ? Microsoft.Xna.Framework.Color.White : Microsoft.Xna.Framework.Color.Black, entry.Active)); item.Add(new CommandBinding(item.MouseLeftDown, delegate() { if (entry.Active) { allSessions.Value = false; analyticsActiveSessions.Remove(entry); } else { analyticsActiveSessions.Add(entry); } })); return(item); })); ListContainer allSessionsButton = createCheckboxListItem("[All]"); allSessionsButton.Add(new CommandBinding(allSessionsButton.MouseLeftDown, delegate() { if (allSessions) { allSessions.Value = false; foreach (SessionEntry s in analyticsActiveSessions.ToList()) { analyticsActiveSessions.Remove(s); } } else { allSessions.Value = true; foreach (SessionEntry s in analyticsSessions) { if (!s.Active) { analyticsActiveSessions.Add(s); } } } })); Container allSessionsCheckbox = (Container)allSessionsButton.GetChildByName("Checkbox"); allSessionsCheckbox.Add(new Binding <Microsoft.Xna.Framework.Color, bool>(allSessionsCheckbox.Tint, x => x ? Microsoft.Xna.Framework.Color.White : Microsoft.Xna.Framework.Color.Black, allSessions)); sessionList.Children.Add(allSessionsButton); Container eventsContainer = new Container(); eventsContainer.Tint.Value = Microsoft.Xna.Framework.Color.Black; eventsContainer.Opacity.Value = UIFactory.Opacity; eventsContainer.AnchorPoint.Value = new Vector2(1, 1); sessionsSidebar.Children.Add(eventsContainer); Scroller eventsScroller = new Scroller(); eventsScroller.ResizeHorizontal.Value = true; eventsScroller.ResizeVertical.Value = true; eventsScroller.MaxVerticalSize.Value = 256; eventsContainer.Children.Add(eventsScroller); ListContainer eventList = new ListContainer(); eventList.Orientation.Value = ListContainer.ListOrientation.Vertical; eventList.Alignment.Value = ListContainer.ListAlignment.Max; eventsScroller.Children.Add(eventList); Property <bool> allEvents = new Property <bool>(); eventList.Add(new ListBinding <UIComponent, EventEntry>(eventList.Children, analyticsEvents, delegate(EventEntry e) { ListContainer item = createCheckboxListItem(e.Name); Container checkbox = (Container)item.GetChildByName("Checkbox"); checkbox.Add(new Binding <Microsoft.Xna.Framework.Color, bool>(checkbox.Tint, x => x ? Microsoft.Xna.Framework.Color.White : Microsoft.Xna.Framework.Color.Black, e.Active)); TextElement label = (TextElement)item.GetChildByName("Label"); label.Tint.Value = new Microsoft.Xna.Framework.Color(colorHash(e.Name)); item.Add(new CommandBinding(item.MouseLeftDown, delegate() { if (e.Active) { allEvents.Value = false; analyticsActiveEvents.Remove(e); } else { analyticsActiveEvents.Add(e); } })); return(item); })); ListContainer allEventsButton = createCheckboxListItem("[All]"); allEventsButton.Add(new CommandBinding(allEventsButton.MouseLeftDown, delegate() { if (allEvents) { allEvents.Value = false; foreach (EventEntry e in analyticsActiveEvents.ToList()) { analyticsActiveEvents.Remove(e); } } else { allEvents.Value = true; foreach (EventEntry e in analyticsEvents) { if (!e.Active) { analyticsActiveEvents.Add(e); } } } })); Container allEventsCheckbox = (Container)allEventsButton.GetChildByName("Checkbox"); allEventsCheckbox.Add(new Binding <Microsoft.Xna.Framework.Color, bool>(allEventsCheckbox.Tint, x => x ? Microsoft.Xna.Framework.Color.White : Microsoft.Xna.Framework.Color.Black, allEvents)); eventList.Children.Add(allEventsButton); Container propertiesContainer = new Container(); propertiesContainer.Tint.Value = Microsoft.Xna.Framework.Color.Black; propertiesContainer.Opacity.Value = UIFactory.Opacity; propertiesContainer.AnchorPoint.Value = new Vector2(1, 1); sessionsSidebar.Children.Add(propertiesContainer); Scroller propertiesScroller = new Scroller(); propertiesScroller.ResizeHorizontal.Value = true; propertiesScroller.ResizeVertical.Value = true; propertiesScroller.MaxVerticalSize.Value = 256; propertiesContainer.Children.Add(propertiesScroller); ListContainer propertiesList = new ListContainer(); propertiesList.Orientation.Value = ListContainer.ListOrientation.Vertical; propertiesList.Alignment.Value = ListContainer.ListAlignment.Max; propertiesScroller.Children.Add(propertiesList); Property <bool> allProperties = new Property <bool>(); propertiesList.Add(new ListBinding <UIComponent, PropertyEntry>(propertiesList.Children, analyticsProperties, delegate(PropertyEntry e) { ListContainer item = createCheckboxListItem(e.Name); Container checkbox = (Container)item.GetChildByName("Checkbox"); checkbox.Add(new Binding <Microsoft.Xna.Framework.Color, bool>(checkbox.Tint, x => x ? Microsoft.Xna.Framework.Color.White : Microsoft.Xna.Framework.Color.Black, e.Active)); TextElement label = (TextElement)item.GetChildByName("Label"); label.Tint.Value = new Microsoft.Xna.Framework.Color(colorHash(e.Name)); item.Add(new CommandBinding(item.MouseLeftDown, delegate() { if (e.Active) { allProperties.Value = false; analyticsActiveProperties.Remove(e); } else { analyticsActiveProperties.Add(e); } })); return(item); })); ListContainer allPropertiesButton = createCheckboxListItem("[All]"); allPropertiesButton.Add(new CommandBinding(allPropertiesButton.MouseLeftDown, delegate() { if (allProperties) { allProperties.Value = false; foreach (PropertyEntry e in analyticsActiveProperties.ToList()) { analyticsActiveProperties.Remove(e); } } else { allProperties.Value = true; foreach (PropertyEntry e in analyticsProperties) { if (!e.Active) { analyticsActiveProperties.Add(e); } } } })); Container allPropertiesCheckbox = (Container)allPropertiesButton.GetChildByName("Checkbox"); allPropertiesCheckbox.Add(new Binding <Microsoft.Xna.Framework.Color, bool>(allPropertiesCheckbox.Tint, x => x ? Microsoft.Xna.Framework.Color.White : Microsoft.Xna.Framework.Color.Black, allProperties)); propertiesList.Children.Add(allPropertiesButton); Func <Session.EventList, LineDrawer2D> createEventLines = delegate(Session.EventList el) { LineDrawer2D line = new LineDrawer2D(); line.Color.Value = colorHash(el.Name); line.UserData.Value = el; foreach (Session.Event e in el.Events) { line.Lines.Add(new LineDrawer2D.Line { A = new Microsoft.Xna.Framework.Graphics.VertexPositionColor(new Vector3(e.Time, 0.0f, 0.0f), Microsoft.Xna.Framework.Color.White), B = new Microsoft.Xna.Framework.Graphics.VertexPositionColor(new Vector3(e.Time, timeline.Size.Value.Y, 0.0f), Microsoft.Xna.Framework.Color.White), }); } return(line); }; analyticsActiveEvents.ItemAdded += delegate(int index, EventEntry ee) { ee.Active.Value = true; foreach (SessionEntry s in analyticsActiveSessions) { Session.PositionProperty positionProperty = s.Session.PositionProperties[0]; foreach (Session.EventList el in s.Session.Events) { if (el.Name == ee.Name) { List <ModelInstance> models = new List <ModelInstance>(); Vector4 color = colorHash(el.Name); int hash = (int)(new Color(color).PackedValue); foreach (Session.Event e in el.Events) { ModelInstance i = new ModelInstance(); i.Serialize = false; i.Setup("InstancedModels\\position-model", hash); if (i.IsFirstInstance) { i.Model.Color.Value = new Vector3(color.X, color.Y, color.Z); } i.Transform.Value = Matrix.CreateTranslation(positionProperty.GetLastRecordedPosition(e.Time)); models.Add(i); entity.Add(i); } eventPositionModels[el] = models; } } timeline.Children.AddAll(s.Session.Events.Where(x => x.Name == ee.Name).Select(createEventLines)); } }; analyticsActiveEvents.ItemRemoved += delegate(int index, EventEntry e) { e.Active.Value = false; foreach (KeyValuePair <Session.EventList, List <ModelInstance> > pair in eventPositionModels.ToList()) { if (pair.Key.Name == e.Name) { foreach (ModelInstance instance in pair.Value) { instance.Delete.Execute(); } eventPositionModels.Remove(pair.Key); } } timeline.Children.RemoveAll(timeline.Children.Where(x => x.UserData.Value != null && ((Session.EventList)x.UserData.Value).Name == e.Name).ToList()); }; analyticsActiveProperties.ItemAdded += delegate(int index, PropertyEntry e) { e.Active.Value = true; }; analyticsActiveProperties.ItemRemoved += delegate(int index, PropertyEntry e) { e.Active.Value = false; }; ListContainer propertyTimelines = new ListContainer(); propertyTimelines.Alignment.Value = ListContainer.ListAlignment.Min; propertyTimelines.Orientation.Value = ListContainer.ListOrientation.Vertical; timelines.Children.Add(propertyTimelines); Action <Container> refreshPropertyGraph = delegate(Container container) { TextElement label = (TextElement)container.GetChildByName("Label"); LineDrawer2D lines = (LineDrawer2D)container.GetChildByName("Graph"); string propertyName = ((PropertyEntry)lines.UserData.Value).Name; lines.Lines.Clear(); float time = 0.0f, lastTime = 0.0f; float lastValue = 0.0f; bool firstLine = true; float max = float.MinValue, min = float.MaxValue; while (true) { bool stop = true; // Calculate average int count = 0; float sum = 0.0f; foreach (SessionEntry s in analyticsActiveSessions) { if (time < s.Session.TotalTime) { Session.ContinuousProperty prop = s.Session.GetContinuousProperty(propertyName); if (prop != null) { stop = false; sum += prop[time]; count++; } } } if (stop) { break; } else { float value = sum / (float)count; if (firstLine) { firstLine = false; } else { lines.Lines.Add(new LineDrawer2D.Line { A = new Microsoft.Xna.Framework.Graphics.VertexPositionColor { Color = Microsoft.Xna.Framework.Color.White, Position = new Vector3(lastTime, lastValue, 0.0f), }, B = new Microsoft.Xna.Framework.Graphics.VertexPositionColor { Color = Microsoft.Xna.Framework.Color.White, Position = new Vector3(time, value, 0.0f), }, }); } min = Math.Min(min, value); max = Math.Max(max, value); lastValue = value; lastTime = time; time += Session.Recorder.Interval; } if (min < max) { float scale = -timelineHeight / (max - min); lines.Scale.Value = new Vector2(1, scale); lines.Position.Value = new Vector2(0, max * -scale); } else { lines.AnchorPoint.Value = Vector2.Zero; if (min <= 0.0f) { lines.Position.Value = new Vector2(0, timelineHeight); } else { lines.Position.Value = new Vector2(0, timelineHeight * 0.5f); } } label.Text.Value = max.ToString("F"); } }; Action refreshPropertyGraphs = delegate() { foreach (Container propertyTimeline in propertyTimelines.Children) { refreshPropertyGraph(propertyTimeline); } }; propertyTimelines.Add(new ListBinding <UIComponent, PropertyEntry>(propertyTimelines.Children, analyticsActiveProperties, delegate(PropertyEntry e) { Container propertyTimeline = new Container(); propertyTimeline.Add(new Binding <Vector2>(propertyTimeline.Size, timeline.Size)); propertyTimeline.Tint.Value = Microsoft.Xna.Framework.Color.Black; propertyTimeline.Opacity.Value = UIFactory.Opacity; propertyTimeline.ResizeHorizontal.Value = false; propertyTimeline.ResizeVertical.Value = false; LineDrawer2D line = new LineDrawer2D(); line.Name.Value = "Graph"; line.Color.Value = colorHash(e.Name); line.UserData.Value = e; propertyTimeline.Children.Add(line); TextElement label = new TextElement(); label.FontFile.Value = main.Font; label.Name.Value = "Label"; label.Add(new Binding <Vector2>(label.Scale, x => new Vector2(1.0f / x.X, 1.0f / x.Y), timelines.Scale)); label.AnchorPoint.Value = new Vector2(0, 0); label.Position.Value = new Vector2(0, 0); propertyTimeline.Children.Add(label); refreshPropertyGraph(propertyTimeline); return(propertyTimeline); })); analyticsActiveSessions.ItemAdded += delegate(int index, SessionEntry s) { Session.PositionProperty positionProperty = s.Session.PositionProperties[0]; foreach (Session.EventList el in s.Session.Events) { if (analyticsActiveEvents.FirstOrDefault(x => x.Name == el.Name) != null) { List <ModelInstance> models = new List <ModelInstance>(); Vector4 color = colorHash(el.Name); int hash = (int)(new Color(color).PackedValue); foreach (Session.Event e in el.Events) { ModelInstance i = new ModelInstance(); i.Serialize = false; i.Setup("InstancedModels\\position-model", hash); if (i.IsFirstInstance) { i.Model.Color.Value = new Vector3(color.X, color.Y, color.Z); } i.Transform.Value = Matrix.CreateTranslation(positionProperty.GetLastRecordedPosition(e.Time)); entity.Add(i); models.Add(i); } eventPositionModels[el] = models; } } ModelInstance instance = new ModelInstance(); instance.Setup("InstancedModels\\position-model", 0); instance.Serialize = false; entity.Add(instance); sessionPositionModels.Add(s.Session, instance); s.Active.Value = true; timeline.Children.AddAll(s.Session.Events.Where(x => analyticsActiveEvents.FirstOrDefault(y => y.Name == x.Name) != null).Select(createEventLines)); playbackLocation.Reset(); refreshPropertyGraphs(); }; analyticsActiveSessions.ItemRemoved += delegate(int index, SessionEntry s) { ModelInstance instance = sessionPositionModels[s.Session]; instance.Delete.Execute(); foreach (KeyValuePair <Session.EventList, List <ModelInstance> > pair in eventPositionModels.ToList()) { if (pair.Key.Session == s.Session) { foreach (ModelInstance i in pair.Value) { i.Delete.Execute(); } eventPositionModels.Remove(pair.Key); } } sessionPositionModels.Remove(s.Session); s.Active.Value = false; timeline.Children.RemoveAll(timeline.Children.Where(x => x.UserData.Value != null && ((Session.EventList)x.UserData.Value).Session == s.Session).ToList()); refreshPropertyGraphs(); }; entity.Add(new SetBinding <float>(playbackLocation, delegate(float value) { if (analyticsActiveSessions.Length == 0) { return; } if (value < 0.0f) { playbackLocation.Value = 0.0f; } float end = analyticsActiveSessions.Max(x => x.Session.TotalTime); if (value > end) { playbackLocation.Value = end; analyticsPlaying.Value = false; } foreach (KeyValuePair <Session, ModelInstance> pair in sessionPositionModels) { pair.Value.Transform.Value = Matrix.CreateTranslation(pair.Key.PositionProperties[0][playbackLocation]); } })); LineDrawer2D playbackLine = new LineDrawer2D(); playbackLine.Color.Value = Vector4.One; playbackLine.Lines.Add(new LineDrawer2D.Line { A = new Microsoft.Xna.Framework.Graphics.VertexPositionColor { Color = Microsoft.Xna.Framework.Color.White, Position = new Vector3(0.0f, -10.0f, 0.0f), }, B = new Microsoft.Xna.Framework.Graphics.VertexPositionColor { Color = Microsoft.Xna.Framework.Color.White, Position = new Vector3(0.0f, timeline.Size.Value.Y, 0.0f), }, }); playbackLine.Add(new Binding <Vector2, float>(playbackLine.Position, x => new Vector2(x, 0.0f), playbackLocation)); timeline.Children.Add(playbackLine); entity.Add(new NotifyBinding(delegate() { allEventsButton.Detach(); allSessionsButton.Detach(); allPropertiesButton.Detach(); analyticsSessions.Clear(); analyticsEvents.Clear(); analyticsProperties.Clear(); eventList.Children.Add(allEventsButton); sessionList.Children.Add(allSessionsButton); propertiesList.Children.Add(allPropertiesButton); foreach (ModelInstance instance in sessionPositionModels.Values) { instance.Delete.Execute(); } sessionPositionModels.Clear(); foreach (ModelInstance instance in eventPositionModels.Values.SelectMany(x => x)) { instance.Delete.Execute(); } eventPositionModels.Clear(); allEvents.Value = false; allSessions.Value = false; allProperties.Value = false; analyticsEnable.Value = false; analyticsActiveEvents.Clear(); analyticsActiveSessions.Clear(); analyticsActiveProperties.Clear(); propertyTimelines.Children.Clear(); playbackLine.Detach(); timeline.Children.Clear(); timeline.Children.Add(playbackLine); analyticsPlaying.Value = false; playbackLocation.Value = 0.0f; }, main.MapFile)); EditorFactory.AddCommand ( entity, main, commandQueueContainer, "Toggle analytics playback", new PCInput.Chord { Modifier = Keys.LeftAlt, Key = Keys.A }, new Command { Action = delegate() { analyticsPlaying.Value = !analyticsPlaying; } }, gui.MapCommands, () => analyticsEnable && !editor.MovementEnabled && analyticsActiveSessions.Length > 0, analyticsEnable, editor.MovementEnabled, analyticsActiveSessions.Length ); EditorFactory.AddCommand ( entity, main, commandQueueContainer, "Stop analytics playback", new PCInput.Chord { Key = Keys.Escape }, new Command { Action = delegate() { analyticsPlaying.Value = false; } }, gui.MapCommands, () => analyticsPlaying, analyticsPlaying ); Container playbackContainer = new Container(); playbackContainer.Tint.Value = Microsoft.Xna.Framework.Color.Black; playbackContainer.Opacity.Value = UIFactory.Opacity; sessionsSidebar.Children.Add(playbackContainer); playbackContainer.Add(new CommandBinding <int>(playbackContainer.MouseScrolled, delegate(int delta) { playbackSpeed.Value = Math.Max(1.0f, Math.Min(10.0f, playbackSpeed.Value + delta)); })); TextElement playbackLabel = new TextElement(); playbackLabel.FontFile.Value = main.Font; playbackLabel.Add(new Binding <string>(playbackLabel.Text, delegate() { return(string.Format("{0} {1} {2:F}x", TimeTrialUI.SecondsToTimeString(playbackLocation), (analyticsPlaying ? "Playing" : "Stopped"), playbackSpeed)); }, playbackLocation, playbackSpeed, analyticsPlaying)); playbackContainer.Children.Add(playbackLabel); Container descriptionContainer = null; Updater timelineUpdate = new Updater ( delegate(float dt) { bool setTimelinePosition = false; if (timelines.Highlighted || descriptionContainer != null) { if (input.LeftMouseButton) { setTimelinePosition = true; playbackLocation.Value = Vector3.Transform(new Vector3(input.Mouse.Value.X, 0.0f, 0.0f), Matrix.Invert(timeline.GetAbsoluteTransform())).X; } float threshold = 3.0f / timelines.Scale.Value.X; float mouseRelative = Vector3.Transform(new Vector3(input.Mouse, 0.0f), Matrix.Invert(timelines.GetAbsoluteTransform())).X; if (descriptionContainer != null) { if (!timelines.Highlighted || (float)Math.Abs(descriptionContainer.Position.Value.X - mouseRelative) > threshold) { descriptionContainer.Delete.Execute(); descriptionContainer = null; } } if (descriptionContainer == null && timeline.Highlighted) { foreach (UIComponent component in timeline.Children) { LineDrawer2D lines = component as LineDrawer2D; if (lines == null) { continue; } Session.EventList el = lines.UserData.Value as Session.EventList; if (el != null) { bool stop = false; foreach (Session.Event e in el.Events) { if (el != null && (float)Math.Abs(e.Time - mouseRelative) < threshold) { descriptionContainer = new Container(); descriptionContainer.AnchorPoint.Value = new Vector2(0.5f, 1.0f); descriptionContainer.Position.Value = new Vector2(e.Time, 0.0f); descriptionContainer.Opacity.Value = 1.0f; descriptionContainer.Tint.Value = Microsoft.Xna.Framework.Color.Black; descriptionContainer.Add(new Binding <Vector2>(descriptionContainer.Scale, x => new Vector2(1.0f / x.X, 1.0f / x.Y), timelines.Scale)); timeline.Children.Add(descriptionContainer); TextElement description = new TextElement(); description.WrapWidth.Value = 256; if (string.IsNullOrEmpty(e.Data)) { description.Text.Value = el.Name; } else { description.Text.Value = string.Format("{0}\n{1}", el.Name, e.Data); } description.FontFile.Value = main.Font; descriptionContainer.Children.Add(description); stop = true; break; } } if (stop) { break; } } } } } if (analyticsPlaying && !setTimelinePosition) { if (analyticsActiveSessions.Length == 0) { analyticsPlaying.Value = false; } else { playbackLocation.Value += dt * playbackSpeed; } } } ); entity.Add(timelineUpdate); timelineUpdate.EnabledInEditMode = true; }