// If this is the kind of warp which points to another warp, return the // pointed warp, otherwise return null public WarpSourceData GetPointedWarp() { if (WarpSourceType != WarpSourceType.PointerWarp) { return(null); } WarpSourceData data = (WarpSourceData)Project.GetData(GetValue("Pointer")); return(data); }
// Returns the number of PointedWarps there are after and including // this one. This is the number of times (plus one) that you can call // GetNextWarp() before you get a null value. // // If called on a PointerWarp, it returns the corresponding value for // its PointedWarp. public int GetPointedChainLength() { if (WarpSourceType == WarpSourceType.PointerWarp) { return(GetPointedWarp().GetPointedChainLength()); } WarpSourceData next = GetNextWarp(); if (next == null) { return(1); } return(1 + next.GetPointedChainLength()); }
protected void OnAddWarpButtonClicked(object sender, EventArgs e) { WarpSourceData data = new WarpSourceData(Project, WarpSourceData.WarpCommands[(int)WarpSourceType.StandardWarp], WarpSourceData.DefaultValues[(int)WarpSourceType.StandardWarp], sourceGroup.FileParser, new List <int> { -1 }); data.Map = map; data.Transition = 4; sourceGroup.AddWarpSourceData(data); SetWarpIndex((int)indexSpinButton.Adjustment.Upper + 1); }
public bool SetNextWarp(WarpSourceData next) { if (!FileParser.InsertComponentAfter(this, next)) { return(false); } this.Opcode &= ~0x80; if (next.GetNextWarp() == null) { next.Opcode |= 0x80; } else { next.Opcode &= 0x80; } return(true); }
internal WarpSourceGroup(Project p, int id) : base(p, id) { fileParser = Project.GetFileWithLabel("warpSourcesTable"); Data d = fileParser.GetData("warpSourcesTable", id * 2); string label = d.GetValue(0); warpSourceDataList = new List <WarpSourceData>(); WarpSourceData warpData = fileParser.GetData(label) as WarpSourceData; while (warpData != null && warpData.WarpSourceType != WarpSourceType.WarpSourcesEnd) { warpSourceDataList.Add(warpData); warpData = warpData.NextData as WarpSourceData; } if (warpData != null) { warpSourceDataList.Add(warpData); // WarpSourcesEnd } }
protected void OnAddSpecificWarpButtonClicked(object sender, EventArgs e) { // Check if a pointer warp already exists List <WarpSourceData> warps = sourceGroup.GetMapWarpSourceData(map); foreach (WarpSourceData sourceData in warps) { if (sourceData.WarpSourceType == WarpSourceType.PointerWarp) { // Warning dialog Gtk.MessageDialog d = new Gtk.MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Warning, ButtonsType.YesNo, "This map already has specific-position warp data; adding another would be redundant. Continue anyway?"); Gtk.ResponseType response = (ResponseType)d.Run(); d.Destroy(); if (response == ResponseType.Yes) { break; } else { return; } } } WarpSourceData data = new WarpSourceData(Project, WarpSourceData.WarpCommands[(int)WarpSourceType.PointerWarp], WarpSourceData.DefaultValues[(int)WarpSourceType.PointerWarp], sourceGroup.FileParser, new List <int> { -1, 2 }); data.Map = map; sourceGroup.AddWarpSourceData(data); SetWarpIndex((int)indexSpinButton.Adjustment.Upper + 1); }
// Adds the given data to the end of the group and inserts the data // into the FileParser. public void AddWarpSourceData(WarpSourceData data) { if (warpSourceDataList.Contains(data)) { return; } // Assumes the last element of warpSourceDataList is always the // m_WarpSourcesEnd command fileParser.InsertComponentBefore(EndData, data); warpSourceDataList.Insert(warpSourceDataList.Count - 1, data); if (data.WarpSourceType == WarpSourceType.PointerWarp && data.PointerString == ".") { // Create a unique pointer after m_WarpSourcesEnd int nameIndex = 0; string name; do { name = "customWarpSource" + nameIndex.ToString("d2"); nameIndex++; }while (Project.HasLabel(name)); data.PointerString = name; Label newLabel = new Label(FileParser, name); // Insert label after m_WarpSourcesEnd FileParser.InsertComponentAfter(EndData, newLabel); // Create a blank PointedData to go after this label WarpSourceData pointedData = new WarpSourceData(Project, WarpSourceData.WarpCommands[(int)WarpSourceType.PointedWarp], WarpSourceData.DefaultValues[(int)WarpSourceType.PointedWarp], FileParser, new List <int> { -1 }); pointedData.Opcode = 0x80; pointedData.Transition = 4; FileParser.InsertComponentAfter(newLabel, pointedData); } }
// Adds the given data to the end of the group and inserts the data // into the FileParser. public void AddWarpSourceData(WarpSourceData data) { if (warpSourceDataList.Contains(data)) return; // Assumes the last element of warpSourceDataList is always the // m_WarpSourcesEnd command fileParser.InsertComponentBefore(EndData, data); warpSourceDataList.Insert(warpSourceDataList.Count-1, data); if (data.WarpSourceType == WarpSourceType.PointerWarp && data.PointerString == ".") { // Create a unique pointer after m_WarpSourcesEnd int nameIndex = 0; string name; do { name = "customWarpSource" + nameIndex.ToString("d2"); nameIndex++; } while (Project.HasLabel(name)); data.PointerString = name; Label newLabel = new Label(FileParser, name); // Insert label after m_WarpSourcesEnd FileParser.InsertComponentAfter(EndData, newLabel); // Create a blank PointedData to go after this label WarpSourceData pointedData = new WarpSourceData(Project, WarpSourceData.WarpCommands[(int)WarpSourceType.PointedWarp], WarpSourceData.DefaultValues[(int)WarpSourceType.PointedWarp], FileParser, new List<int>{-1}); pointedData.Opcode = 0x80; pointedData.Transition = 4; FileParser.InsertComponentAfter(newLabel, pointedData); } }
public void RemoveWarpSourceData(WarpSourceData data) { if (!warpSourceDataList.Contains(data)) { return; } if (data.WarpSourceType == WarpSourceType.PointerWarp) { WarpSourceData pointedData = data.GetPointedWarp(); // Delete label fileParser.RemoveFileComponent(fileParser.GetDataLabel(pointedData)); // Delete after the label while (pointedData != null) { WarpSourceData next = pointedData.GetNextWarp(); pointedData.FileParser.RemoveFileComponent(pointedData); pointedData = next; } } data.FileParser.RemoveFileComponent(data); warpSourceDataList.Remove(data); }
public void RemoveWarpSourceData(WarpSourceData data) { if (!warpSourceDataList.Contains(data)) return; if (data.WarpSourceType == WarpSourceType.PointerWarp) { WarpSourceData pointedData = data.GetPointedWarp(); // Delete label fileParser.RemoveFileComponent(fileParser.GetDataLabel(pointedData)); // Delete after the label while (pointedData != null) { WarpSourceData next = pointedData.GetNextWarp(); pointedData.FileParser.RemoveFileComponent(pointedData); pointedData = next; } } data.FileParser.RemoveFileComponent(data); warpSourceDataList.Remove(data); }
// Load the i'th warp in the current map. void SetWarpIndex(int i) { List <WarpSourceData> sourceDataList = sourceGroup.GetMapWarpSourceData(map); indexSpinButton.Adjustment.Lower = -1; indexSpinButton.Adjustment.Upper = sourceDataList.Count - 1; if (i > indexSpinButton.Adjustment.Upper) { i = (int)indexSpinButton.Adjustment.Upper; } indexSpinButton.Value = i; valueEditorContainer.Remove(valueEditorContainer.Child); if (i == -1) { SetDestIndex(-1, -1); return; } Gtk.HBox hbox = new Gtk.HBox(); WarpSourceData warpSourceData = sourceDataList[i]; if (warpSourceData.WarpSourceType == WarpSourceType.StandardWarp) { SetDestIndex(warpSourceData.DestGroup, warpSourceData.DestIndex); } sourceEditor = new ValueReferenceEditor(Project, warpSourceData); Alignment a = new Alignment(0, 0, 0, 0); a.Add(sourceEditor); hbox.Add(a); if (warpSourceData.WarpSourceType == WarpSourceType.PointerWarp) { Table table = new Table(1, 1, false); table.ColumnSpacing = 6; table.RowSpacing = 6; SpinButton pointerSpinButton = new SpinButton(0, 10, 1); EventHandler valueChangedHandler = delegate(object sender, EventArgs e) { WarpSourceData pointedData = warpSourceData.GetPointedWarp(); pointerSpinButton.Adjustment.Lower = 0; pointerSpinButton.Adjustment.Upper = warpSourceData.GetPointedChainLength() - 1; if (pointerSpinButton.ValueAsInt > pointerSpinButton.Adjustment.Upper) { pointerSpinButton.Value = pointerSpinButton.Adjustment.Upper; } int index = pointerSpinButton.ValueAsInt; while (index > 0) { pointedData = pointedData.GetNextWarp(); index--; } table.Remove(destEditor); destEditor = new ValueReferenceEditor(Project, pointedData); destEditor.AddDataModifiedHandler(delegate() { SetDestIndex(pointedData.DestGroup, pointedData.DestIndex); }); table.Attach(destEditor, 0, 2, 1, 2); SetDestIndex(pointedData.DestGroup, pointedData.DestIndex); }; pointerSpinButton.ValueChanged += valueChangedHandler; // Button which, when clicked, adds a new PointedData to the // "chain". Gtk.Button addPointedWarpButton = new Gtk.Button(new Gtk.Image(Gtk.Stock.Add, Gtk.IconSize.Button)); addPointedWarpButton.Clicked += delegate(object sender, EventArgs e) { WarpSourceData pointedData = warpSourceData.GetPointedWarp(); while (pointedData.GetNextWarp() != null) { pointedData = pointedData.GetNextWarp(); } WarpSourceData nextData = new WarpSourceData(Project, WarpSourceData.WarpCommands[(int)WarpSourceType.PointedWarp], WarpSourceData.DefaultValues[(int)WarpSourceType.PointedWarp], pointedData.FileParser, new List <int> { -1 }); pointedData.SetNextWarp(nextData); pointerSpinButton.Adjustment.Upper++; pointerSpinButton.Value = warpSourceData.GetPointedChainLength() - 1; valueChangedHandler(null, null); }; // Button which removes a PointedData from the "chain", unless // there is only one remaining. Gtk.Button removePointedWarpButton = new Gtk.Button(new Gtk.Image(Gtk.Stock.Remove, Gtk.IconSize.Button)); removePointedWarpButton.Clicked += delegate(object sender, EventArgs e) { int index = pointerSpinButton.ValueAsInt; WarpSourceData pointedData = warpSourceData.GetPointedWarp(); if (pointedData.GetPointedChainLength() <= 1) // Don't delete the last one { return; } while (index > 0) { pointedData = pointedData.GetNextWarp(); index--; } pointedData.FileParser.RemoveFileComponent(pointedData); valueChangedHandler(null, null); }; table.Attach(new Gtk.Label("Pointer index"), 0, 1, 0, 1); table.Attach(pointerSpinButton, 1, 2, 0, 1); table.Attach(addPointedWarpButton, 2, 3, 0, 1); table.Attach(removePointedWarpButton, 3, 4, 0, 1); // Invoke handler valueChangedHandler(pointerSpinButton, null); Frame frame = new Frame(warpSourceData.PointerString); frame.Add(table); hbox.Add(frame); } else // Not pointerWarp { sourceEditor.AddDataModifiedHandler(delegate() { SetDestIndex(warpSourceData.DestGroup, warpSourceData.DestIndex); }); } valueEditorContainer.Add(hbox); valueEditorContainer.ShowAll(); }
protected void OnAddSpecificWarpButtonClicked(object sender, EventArgs e) { // Check if a pointer warp already exists List<WarpSourceData> warps = sourceGroup.GetMapWarpSourceData(map); foreach (WarpSourceData sourceData in warps) { if (sourceData.WarpSourceType == WarpSourceType.PointerWarp) { // Warning dialog Gtk.MessageDialog d = new Gtk.MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Warning, ButtonsType.YesNo, "This map already has specific-position warp data; adding another would be redundant. Continue anyway?"); Gtk.ResponseType response = (ResponseType)d.Run(); d.Destroy(); if (response == ResponseType.Yes) break; else return; } } WarpSourceData data = new WarpSourceData(Project, WarpSourceData.WarpCommands[(int)WarpSourceType.PointerWarp], WarpSourceData.DefaultValues[(int)WarpSourceType.PointerWarp], sourceGroup.FileParser, new List<int>{-1,2}); data.Map = map; sourceGroup.AddWarpSourceData(data); SetWarpIndex((int)indexSpinButton.Adjustment.Upper+1); }
public void RemoveReference(WarpSourceData data) { referenceSet.Remove(data); }
public void AddReference(WarpSourceData data) { referenceSet.Add(data); }
// Load the i'th warp in the current map. void SetWarpIndex(int i) { List<WarpSourceData> sourceDataList = sourceGroup.GetMapWarpSourceData(map); indexSpinButton.Adjustment.Lower = -1; indexSpinButton.Adjustment.Upper = sourceDataList.Count-1; if (i > indexSpinButton.Adjustment.Upper) i = (int)indexSpinButton.Adjustment.Upper; indexSpinButton.Value = i; valueEditorContainer.Remove(valueEditorContainer.Child); if (i == -1) { SetDestIndex(-1,-1); return; } Gtk.HBox hbox = new Gtk.HBox(); WarpSourceData warpSourceData = sourceDataList[i]; if (warpSourceData.WarpSourceType == WarpSourceType.StandardWarp) SetDestIndex(warpSourceData.DestGroup, warpSourceData.DestIndex); sourceEditor = new ValueReferenceEditor(Project, warpSourceData); Alignment a = new Alignment(0,0,0,0); a.Add(sourceEditor); hbox.Add(a); if (warpSourceData.WarpSourceType == WarpSourceType.PointerWarp) { Table table = new Table(1, 1, false); table.ColumnSpacing = 6; table.RowSpacing = 6; SpinButton pointerSpinButton = new SpinButton(0,10,1); EventHandler valueChangedHandler = delegate(object sender, EventArgs e) { WarpSourceData pointedData = warpSourceData.GetPointedWarp(); pointerSpinButton.Adjustment.Lower = 0; pointerSpinButton.Adjustment.Upper = warpSourceData.GetPointedChainLength()-1; if (pointerSpinButton.ValueAsInt > pointerSpinButton.Adjustment.Upper) { pointerSpinButton.Value = pointerSpinButton.Adjustment.Upper; } int index = pointerSpinButton.ValueAsInt; while (index > 0) { pointedData = pointedData.GetNextWarp(); index--; } table.Remove(destEditor); destEditor = new ValueReferenceEditor(Project, pointedData); destEditor.AddDataModifiedHandler(delegate() { SetDestIndex(pointedData.DestGroup, pointedData.DestIndex); }); table.Attach(destEditor, 0, 2, 1, 2); SetDestIndex(pointedData.DestGroup, pointedData.DestIndex); }; pointerSpinButton.ValueChanged += valueChangedHandler; // Button which, when clicked, adds a new PointedData to the // "chain". Gtk.Button addPointedWarpButton = new Gtk.Button(new Gtk.Image(Gtk.Stock.Add, Gtk.IconSize.Button)); addPointedWarpButton.Clicked += delegate(object sender, EventArgs e) { WarpSourceData pointedData = warpSourceData.GetPointedWarp(); while (pointedData.GetNextWarp() != null) { pointedData = pointedData.GetNextWarp(); } WarpSourceData nextData = new WarpSourceData(Project, WarpSourceData.WarpCommands[(int)WarpSourceType.PointedWarp], WarpSourceData.DefaultValues[(int)WarpSourceType.PointedWarp], pointedData.FileParser, new List<int>{-1}); pointedData.SetNextWarp(nextData); pointerSpinButton.Adjustment.Upper++; pointerSpinButton.Value = warpSourceData.GetPointedChainLength()-1; valueChangedHandler(null, null); }; // Button which removes a PointedData from the "chain", unless // there is only one remaining. Gtk.Button removePointedWarpButton = new Gtk.Button(new Gtk.Image(Gtk.Stock.Remove, Gtk.IconSize.Button)); removePointedWarpButton.Clicked += delegate(object sender, EventArgs e) { int index = pointerSpinButton.ValueAsInt; WarpSourceData pointedData = warpSourceData.GetPointedWarp(); if (pointedData.GetPointedChainLength() <= 1) // Don't delete the last one return; while (index > 0) { pointedData = pointedData.GetNextWarp(); index--; } pointedData.FileParser.RemoveFileComponent(pointedData); valueChangedHandler(null, null); }; table.Attach(new Gtk.Label("Pointer index"), 0, 1, 0, 1); table.Attach(pointerSpinButton, 1, 2, 0, 1); table.Attach(addPointedWarpButton, 2, 3, 0, 1); table.Attach(removePointedWarpButton, 3, 4, 0, 1); // Invoke handler valueChangedHandler(pointerSpinButton, null); Frame frame = new Frame(warpSourceData.PointerString); frame.Add(table); hbox.Add(frame); } else { // Not pointerWarp sourceEditor.AddDataModifiedHandler(delegate() { SetDestIndex(warpSourceData.DestGroup, warpSourceData.DestIndex); }); } valueEditorContainer.Add(hbox); valueEditorContainer.ShowAll(); }
public bool SetNextWarp(WarpSourceData next) { if (!FileParser.InsertComponentAfter(this, next)) return false; this.Opcode &= ~0x80; if (next.GetNextWarp() == null) next.Opcode |= 0x80; else next.Opcode &= 0x80; return true; }
void ParseLine(string pureLine, int i, List<FileComponent> fileStructure, List<string> fileStructureComments) { string[] split = pureLine.Split(';'); string line = split[0]; string comment = pureLine.Substring(split[0].Length); string warningString = "WARNING while parsing \"" + Filename + "\": Line " + (i+1) + ": "; // Helper functions Action<FileComponent,string> AddComponent = (component, c) => { fileStructure.Add(component); fileStructureComments.Add(c); if (component is Label) AddLabelToDictionaries(component as Label); }; Action<Label> AddLabelAndPopFileStructure = (label) => { fileStructure.RemoveAt(fileStructure.Count-1); string c = fileStructureComments[fileStructureComments.Count-1]; fileStructureComments.RemoveAt(fileStructureComments.Count-1); AddComponent(label, c); }; Action<Data> AddDataAndPopFileStructure = (data) => { fileStructure.RemoveAt(fileStructure.Count-1); string c = fileStructureComments[fileStructureComments.Count-1]; fileStructureComments.RemoveAt(fileStructureComments.Count-1); AddComponent(data, c); }; Action PopFileStructure = () => { fileStructure.RemoveAt(fileStructure.Count-1); fileStructureComments.RemoveAt(fileStructureComments.Count-1); }; // Sub-function: returns true if a meaning for the token was found. Func<string[],IList<int>,bool> ParseData = (fTokens,fSpacing) => { List<string> standardValues = new List<string>(); // Variables used for some of the goto's int size=-1; for (int j = 1; j < fTokens.Length; j++) standardValues.Add(fTokens[j]); switch (fTokens[0].ToLower()) { case ".incbin": { Data d = new Data(Project, fTokens[0], standardValues, -1, this, fSpacing); AddDataAndPopFileStructure(d); } break; case ".dw": if (context == "RAMSECTION") break; if (fTokens.Length < 2) { log.Warn(warningString + "Expected .DW to have a value."); break; } size = 2; goto arbitraryLengthData; case ".db": if (context == "RAMSECTION") break; if (fTokens.Length < 2) { log.Warn(warningString + "Expected .DB to have a value."); break; } size = 1; goto arbitraryLengthData; case "dwbe": if (fTokens.Length < 2) { log.Warn(warningString + "Expected dwbe to have a value."); break; } size = 2; goto arbitraryLengthData; case "dbrev": if (fTokens.Length < 2) { log.Warn(warningString + "Expected dbrev to have a value."); break; } size = 1; goto arbitraryLengthData; arbitraryLengthData: PopFileStructure(); for (int j=1; j<fTokens.Length; j++) { // Each value is added as individual data string[] values = { fTokens[j] }; List<int> newfSpacing = new List<int> {fSpacing[0],fSpacing[j],0}; if (j == fTokens.Length-1) newfSpacing[2] = fSpacing[j+1]; Data d = new Data(Project, fTokens[0], values, size, this, newfSpacing); if (j != fTokens.Length-1) d.EndsLine = false; if (j != 1) d.PrintCommand = false; AddComponent(d, ""); } break; case "db": if (context != "RAMSECTION") goto default; address++; break; case "dw": if (context != "RAMSECTION") goto default; address+=2; break; case "dsb": if (context != "RAMSECTION") goto default; address += Project.EvalToInt(fTokens[1]); break; case "dsw": if (context != "RAMSECTION") goto default; address += Project.EvalToInt(fTokens[1])*2; break; case "m_animationloop": { Data d = new Data(Project, fTokens[0], standardValues, 2, this, fSpacing); AddDataAndPopFileStructure(d); break; } case "m_rgb16": if (fTokens.Length != 4) { log.Warn(warningString + "Expected " + fTokens[0] + " to take 3 parameters"); break; } { Data d = new RgbData(Project, fTokens[0], standardValues, this, fSpacing); AddDataAndPopFileStructure(d); break; } case "m_gfxheader": case "m_gfxheaderforcemode": if (fTokens.Length < 4 || fTokens.Length > 5) { log.Warn(warningString + "Expected " + fTokens[0] + " to take 3-4 parameters"); break; } { Data d = new GfxHeaderData(Project, fTokens[0], standardValues, this, fSpacing); AddDataAndPopFileStructure(d); break; } case "m_paletteheaderbg": case "m_paletteheaderspr": if (fTokens.Length != 5) { log.Warn(warningString + "Expected " + fTokens[0] + " to take 4 parameters"); break; } { Data d = new PaletteHeaderData(Project, fTokens[0], standardValues, this, fSpacing); AddDataAndPopFileStructure(d); break; } case "m_tilesetheader": if (fTokens.Length != 6) { log.Warn(warningString + "Expected " + fTokens[0] + " to take 5 parameters"); break; } { Data d = new TilesetHeaderData(Project, fTokens[0], standardValues, this, fSpacing); AddDataAndPopFileStructure(d); break; } case "m_tilesetdata": if (fTokens.Length != 2) { log.Warn(warningString + "Expected " + fTokens[0] + " to take 1 parameter"); break; } { Stream file = Project.GetBinaryFile("tilesets/" + fTokens[1] + ".bin"); Data d = new Data(Project, fTokens[0], standardValues, (Int32)file.Length, this, fSpacing); AddDataAndPopFileStructure(d); break; } case "m_roomlayoutdata": if (fTokens.Length != 2) { log.Warn(warningString + "Expected " + fTokens[0] + " to take 1 parameter"); break; } { Label l = new Label(this, fTokens[1]); l.Fake = true; AddLabelAndPopFileStructure(l); Data d = new Data(Project, fTokens[0], standardValues, -1, this, fSpacing); AddComponent(d, ""); break; } default: { Data d = null; // Try object commands for (int j=0; j<ObjectGroup.ObjectCommands.Length; j++) { string s = ObjectGroup.ObjectCommands[j]; if (s.ToLower() == fTokens[0].ToLower()) { int minParams = ObjectGroup.ObjectCommandMinParams[j]; int maxParams = ObjectGroup.ObjectCommandMaxParams[j]; if (minParams == -1) minParams = maxParams; if (maxParams == -1) maxParams = minParams; if (fTokens.Length-1 < minParams || fTokens.Length-1 > maxParams) { log.Warn(warningString + "Expected " + fTokens[0] + " to take " + minParams + "-" + maxParams + "parameter(s)"); break; } var objectType = (ObjectType)j; d = new ObjectData(Project, fTokens[0], standardValues, this, fSpacing, objectType); break; } } // Try warp sources foreach (string s in WarpSourceData.WarpCommands) { if (s.ToLower() == fTokens[0].ToLower()) { d = new WarpSourceData(Project, fTokens[0], standardValues, this, fSpacing); } } // Try warp dest if (WarpDestData.WarpCommand.ToLower() == fTokens[0].ToLower()) { d = new WarpDestData(Project, fTokens[0], standardValues, this, fSpacing); } if (d != null) { AddDataAndPopFileStructure(d); break; } return false; } } return true; }; // Add raw string to file structure, it'll be removed if // a better representation is found fileStructure.Add(new StringFileComponent(this, line, null)); fileStructureComments.Add(comment); if (line.Trim().Length == 0) return; // TODO: split tokens more intelligently, ie: recognize this as one token: $8000 | $03 //string[] tokens = line.Split(new char[] { ' ', '\t'} ); string[] tokens = Regex.Split(line.Trim(), @"\s+"); List<int> spacing = new List<int>(); int[] tokenStartIndices = new int[tokens.Length]; { // Generate "spacing" list, keeps track of whitespace // between arguments (+'ve = spaces, -'ve = tabs) int index = 0; for (int j=0; j<tokens.Length+1; j++) { int spaces=0; while (index < line.Length && (line[index] == ' ' || line[index] == '\t')) { if (line[index] == ' ' && spaces >= 0) spaces++; else if (line[index] == '\t' && spaces <= 0) spaces--; index++; } if (j<tokens.Length) tokenStartIndices[j] = index; spacing.Add(spaces); while (index < line.Length && line[index] != ' ' && line[index] != '\t') index++; } } string value; if (tokens.Length > 0) { switch (tokens[0].ToLower()) { // Built-in directives case ".ramsection": { context = "RAMSECTION"; // Find the last token which specifies the name int tokenIndex = 1; while (tokens[tokenIndex][tokens[tokenIndex].Length-1] != '"') tokenIndex++; tokenIndex++; while (tokenIndex < tokens.Length) { if (tokens[tokenIndex] == "BANK") { tokenIndex++; bank = Project.EvalToInt(tokens[tokenIndex++]); } else if (tokens[tokenIndex] == "SLOT") { tokenIndex++; string slotString = tokens[tokenIndex++]; int slot = Project.EvalToInt(slotString); if (slot == 2) address = 0xc000; else { // Assuming slot >= 3 address = 0xd000; } } } break; } case ".ends": if (context == "RAMSECTION") context = ""; break; case ".define": if (tokens.Length < 3) { log.Debug(warningString + "Expected .DEFINE to have a string and a value."); break; } value = ""; for (int j = 2; j < tokens.Length; j++) { value += tokens[j]; value += " "; } value = value.Trim(); AddDefinition(tokens[1], value); break; default: if (tokens[0][tokens[0].Length - 1] == ':') { // Label string s = tokens[0].Substring(0, tokens[0].Length - 1); FileComponent addedComponent; if (context == "RAMSECTION") { AddDefinition(s, address.ToString()); AddDefinition(":"+s, bank.ToString()); PopFileStructure(); StringFileComponent sc = new StringFileComponent(this, tokens[0], spacing); fileStructure.Add(sc); fileStructureComments.Add(comment); addedComponent = sc; } else { Label label = new Label(this,s,spacing); AddLabelAndPopFileStructure(label); addedComponent = label; } if (tokens.Length > 1) { // There may be data directly after the label string[] tokens2 = new string[tokens.Length-1]; List<int> spacing2 = new List<int>(); addedComponent.EndsLine = false; // Add raw string to file structure, it'll // be removed if a better representation is // found fileStructure.Add(new StringFileComponent( this, line.Substring(tokenStartIndices[1]), spacing2)); fileStructureComments.Add(comment); for (int j=1; j<tokens.Length; j++) tokens2[j-1] = tokens[j]; for (int j=1; j<spacing.Count; j++) spacing2.Add(spacing[j]); if (!ParseData(tokens2, spacing2)) { log.Debug(warningString + "Error parsing line."); } } } else { if (!ParseData(tokens, spacing)) { // Unknown data log.Debug(warningString + "Did not understand \"" + tokens[0] + "\"."); } } break; } } }
void ParseLine(string pureLine, int i, List <FileComponent> fileStructure, List <string> fileStructureComments) { string[] split = pureLine.Split(';'); string line = split[0]; string comment = pureLine.Substring(split[0].Length); string warningString = "WARNING while parsing \"" + Filename + "\": Line " + (i + 1) + ": "; // Helper functions Action <FileComponent, string> AddComponent = (component, c) => { fileStructure.Add(component); fileStructureComments.Add(c); if (component is Label) { AddLabelToDictionaries(component as Label); } }; Action <Label> AddLabelAndPopFileStructure = (label) => { fileStructure.RemoveAt(fileStructure.Count - 1); string c = fileStructureComments[fileStructureComments.Count - 1]; fileStructureComments.RemoveAt(fileStructureComments.Count - 1); AddComponent(label, c); }; Action <Data> AddDataAndPopFileStructure = (data) => { fileStructure.RemoveAt(fileStructure.Count - 1); string c = fileStructureComments[fileStructureComments.Count - 1]; fileStructureComments.RemoveAt(fileStructureComments.Count - 1); AddComponent(data, c); }; Action PopFileStructure = () => { fileStructure.RemoveAt(fileStructure.Count - 1); fileStructureComments.RemoveAt(fileStructureComments.Count - 1); }; // Sub-function: returns true if a meaning for the token was found. Func <string[], IList <int>, bool> ParseData = (fTokens, fSpacing) => { List <string> standardValues = new List <string>(); // Variables used for some of the goto's int size = -1; for (int j = 1; j < fTokens.Length; j++) { standardValues.Add(fTokens[j]); } switch (fTokens[0].ToLower()) { case ".incbin": { Data d = new Data(Project, fTokens[0], standardValues, -1, this, fSpacing); AddDataAndPopFileStructure(d); } break; case ".dw": if (context == "RAMSECTION" || context == "ENUM") { break; } if (fTokens.Length < 2) { log.Warn(warningString + "Expected .DW to have a value."); break; } size = 2; goto arbitraryLengthData; case ".db": if (context == "RAMSECTION" || context == "ENUM") { break; } if (fTokens.Length < 2) { log.Warn(warningString + "Expected .DB to have a value."); break; } size = 1; goto arbitraryLengthData; case "dwbe": if (fTokens.Length < 2) { log.Warn(warningString + "Expected dwbe to have a value."); break; } size = 2; goto arbitraryLengthData; case "dbrev": if (fTokens.Length < 2) { log.Warn(warningString + "Expected dbrev to have a value."); break; } size = 1; goto arbitraryLengthData; arbitraryLengthData: PopFileStructure(); for (int j = 1; j < fTokens.Length; j++) // Each value is added as individual data { string[] values = { fTokens[j] }; List <int> newfSpacing = new List <int> { fSpacing[0], fSpacing[j], 0 }; if (j == fTokens.Length - 1) { newfSpacing[2] = fSpacing[j + 1]; } Data d = new Data(Project, fTokens[0], values, size, this, newfSpacing); if (j != fTokens.Length - 1) { d.EndsLine = false; } if (j != 1) { d.PrintCommand = false; } AddComponent(d, ""); } break; case "db": if (context != "RAMSECTION" && context != "ENUM") { goto default; } address++; break; case "dw": if (context != "RAMSECTION" && context != "ENUM") { goto default; } address += 2; break; case "dsb": if (context != "RAMSECTION" && context != "ENUM") { goto default; } address += Project.EvalToInt(fTokens[1]); break; case "dsw": if (context != "RAMSECTION" && context != "ENUM") { goto default; } address += Project.EvalToInt(fTokens[1]) * 2; break; case "m_animationloop": { Data d = new Data(Project, fTokens[0], standardValues, 2, this, fSpacing); AddDataAndPopFileStructure(d); break; } case "m_rgb16": if (fTokens.Length != 4) { log.Warn(warningString + "Expected " + fTokens[0] + " to take 3 parameters"); break; } { Data d = new RgbData(Project, fTokens[0], standardValues, this, fSpacing); AddDataAndPopFileStructure(d); break; } case "m_gfxheader": case "m_gfxheaderforcemode": if (fTokens.Length < 4 || fTokens.Length > 5) { log.Warn(warningString + "Expected " + fTokens[0] + " to take 3-4 parameters"); break; } { Data d = new GfxHeaderData(Project, fTokens[0], standardValues, this, fSpacing); AddDataAndPopFileStructure(d); break; } case "m_paletteheaderbg": case "m_paletteheaderspr": if (fTokens.Length != 5) { log.Warn(warningString + "Expected " + fTokens[0] + " to take 4 parameters"); break; } { Data d = new PaletteHeaderData(Project, fTokens[0], standardValues, this, fSpacing); AddDataAndPopFileStructure(d); break; } case "m_tilesetheader": if (fTokens.Length != 6) { log.Warn(warningString + "Expected " + fTokens[0] + " to take 5 parameters"); break; } { Data d = new TilesetHeaderData(Project, fTokens[0], standardValues, this, fSpacing); AddDataAndPopFileStructure(d); break; } case "m_tilesetdata": if (fTokens.Length != 2) { log.Warn(warningString + "Expected " + fTokens[0] + " to take 1 parameter"); break; } { Stream file = Project.GetBinaryFile("tilesets/" + Project.GameString + "/" + fTokens[1] + ".bin"); Data d = new Data(Project, fTokens[0], standardValues, (Int32)file.Length, this, fSpacing); AddDataAndPopFileStructure(d); break; } case "m_roomlayoutdata": if (fTokens.Length != 2) { log.Warn(warningString + "Expected " + fTokens[0] + " to take 1 parameter"); break; } { Label l = new Label(this, fTokens[1]); l.Fake = true; AddLabelAndPopFileStructure(l); Data d = new Data(Project, fTokens[0], standardValues, -1, this, fSpacing); AddComponent(d, ""); break; } case "m_seasonalarea": // In season's "areas.s", the m_SeasonalArea macro points to a label which // contains 4 area definitions (one for each season). if (fTokens.Length != 2) { log.Warn(warningString + "Expected " + fTokens[0] + " to take 1 parameter"); break; } { // Create a data object considered to have a size of 8 bytes Data d = new Data(Project, fTokens[0], standardValues, 8, this, fSpacing); AddDataAndPopFileStructure(d); break; } default: { Data d = null; // Try object commands for (int j = 0; j < ObjectGroup.ObjectCommands.Length; j++) { string s = ObjectGroup.ObjectCommands[j]; if (s.ToLower() == fTokens[0].ToLower()) { int minParams = ObjectGroup.ObjectCommandMinParams[j]; int maxParams = ObjectGroup.ObjectCommandMaxParams[j]; if (minParams == -1) { minParams = maxParams; } if (maxParams == -1) { maxParams = minParams; } if (fTokens.Length - 1 < minParams || fTokens.Length - 1 > maxParams) { log.Warn(warningString + "Expected " + fTokens[0] + " to take " + minParams + "-" + maxParams + "parameter(s)"); break; } var objectType = (ObjectType)j; d = new ObjectData(Project, fTokens[0], standardValues, this, fSpacing, objectType); break; } } // Try warp sources foreach (string s in WarpSourceData.WarpCommands) { if (s.ToLower() == fTokens[0].ToLower()) { d = new WarpSourceData(Project, fTokens[0], standardValues, this, fSpacing); } } // Try warp dest if (WarpDestData.WarpCommand.ToLower() == fTokens[0].ToLower()) { d = new WarpDestData(Project, fTokens[0], standardValues, this, fSpacing); } if (d != null) { AddDataAndPopFileStructure(d); break; } return(false); } } return(true); }; // Add raw string to file structure, it'll be removed if // a better representation is found fileStructure.Add(new StringFileComponent(this, line, null)); fileStructureComments.Add(comment); if (line.Trim().Length == 0) { return; } // TODO: split tokens more intelligently, ie: recognize this as one token: $8000 | $03 //string[] tokens = line.Split(new char[] { ' ', '\t'} ); string[] tokens = Regex.Split(line.Trim(), @"\s+"); List <int> spacing = new List <int>(); int[] tokenStartIndices = new int[tokens.Length]; { // Generate "spacing" list, keeps track of whitespace // between arguments (+'ve = spaces, -'ve = tabs) int index = 0; for (int j = 0; j < tokens.Length + 1; j++) { int spaces = 0; while (index < line.Length && (line[index] == ' ' || line[index] == '\t')) { if (line[index] == ' ' && spaces >= 0) { spaces++; } else if (line[index] == '\t' && spaces <= 0) { spaces--; } index++; } if (j < tokens.Length) { tokenStartIndices[j] = index; } spacing.Add(spaces); while (index < line.Length && line[index] != ' ' && line[index] != '\t') { index++; } } } if (tokens.Length > 0) { // Check if we're currently skipping over stuff because of .ifdefs if (ifdefCondition == false) { if (tokens[0].ToLower() == ".ifdef") { ifdefDepth++; } else if (tokens[0].ToLower() == ".else" && failedIfdefDepth == ifdefDepth - 1) { ifdefCondition = true; } else if (tokens[0].ToLower() == ".endif") { ifdefDepth--; if (ifdefDepth == failedIfdefDepth) { ifdefCondition = true; } } return; } switch (tokens[0].ToLower()) { // Built-in directives case ".ramsection": { context = "RAMSECTION"; // Find the last token which specifies the name int tokenIndex = 1; while (tokens[tokenIndex][tokens[tokenIndex].Length - 1] != '"') { tokenIndex++; } tokenIndex++; while (tokenIndex < tokens.Length) { if (tokens[tokenIndex] == "BANK") { tokenIndex++; bank = Project.EvalToInt(tokens[tokenIndex++]); } else if (tokens[tokenIndex] == "SLOT") { tokenIndex++; string slotString = tokens[tokenIndex++]; int slot = Project.EvalToInt(slotString); if (slot == 2) { address = 0xc000; } else // Assuming slot >= 3 { address = 0xd000; } } } break; } case ".ends": if (context == "RAMSECTION") { context = ""; } break; case ".enum": context = "ENUM"; address = Project.EvalToInt(tokens[1]); break; // Not supported: "DESC" (descreasing order) case ".ende": if (context == "ENUM") { context = ""; } break; case ".define": { if (tokens.Length < 3) { log.Debug(warningString + "Expected .DEFINE to have a string and a value."); break; } string value = ""; for (int j = 2; j < tokens.Length; j++) { value += tokens[j]; value += " "; } value = value.Trim(); AddDefinition(tokens[1], value); break; } case ".ifdef": if (tokens.Length < 2) { log.Warn(warningString + "Expected .IFDEF to have a value."); break; } ifdefDepth++; if (Project.GetDefinition(tokens[1]) != null) { ifdefCondition = true; } else { ifdefCondition = false; failedIfdefDepth = ifdefDepth - 1; } break; case ".else": if (ifdefDepth == 0) { log.Warn(warningString + "Expected .IFDEF before .ENDIF."); break; } ifdefCondition = false; break; case ".endif": if (ifdefDepth == 0) { log.Warn(warningString + "Expected .IFDEF before .ENDIF."); break; } ifdefDepth--; break; default: { bool isData = ParseData(tokens, spacing); // In ramsections or enums, assume any unidentifiable data is a label. // Technically this should be the case in any context, but it's more // useful for the parser to tell me what it doesn't understand. if (!isData && (tokens[0][tokens[0].Length - 1] == ':' || context == "RAMSECTION" || context == "ENUM")) { // Label string s = tokens[0]; if (tokens[0][tokens[0].Length - 1] == ':') { s = tokens[0].Substring(0, tokens[0].Length - 1); } FileComponent addedComponent; if (context == "RAMSECTION" || context == "ENUM") { AddDefinition(s, address.ToString()); if (context == "RAMSECTION") { AddDefinition(":" + s, bank.ToString()); } PopFileStructure(); StringFileComponent sc = new StringFileComponent(this, tokens[0], spacing); fileStructure.Add(sc); fileStructureComments.Add(comment); addedComponent = sc; } else { Label label = new Label(this, s, spacing); AddLabelAndPopFileStructure(label); addedComponent = label; } if (tokens.Length > 1) // There may be data directly after the label { string[] tokens2 = new string[tokens.Length - 1]; List <int> spacing2 = new List <int>(); addedComponent.EndsLine = false; // Add raw string to file structure, it'll be removed if a better // representation is found fileStructure.Add(new StringFileComponent( this, line.Substring(tokenStartIndices[1]), spacing2)); fileStructureComments.Add(comment); for (int j = 1; j < tokens.Length; j++) { tokens2[j - 1] = tokens[j]; } for (int j = 1; j < spacing.Count; j++) { spacing2.Add(spacing[j]); } if (!ParseData(tokens2, spacing2)) { log.Debug(warningString + "Error parsing line."); } } } else { // Unknown data log.Debug(warningString + "Did not understand \"" + tokens[0] + "\"."); } } break; } } }
public ValueReferenceEditor(Project p, ValueReferenceGroup vrg, int rows, string frameText = null) : base(1.0F, 1.0F, 1.0F, 1.0F) { Project = p; valueReferenceGroup = vrg; maxBounds = new int[valueReferenceGroup.GetNumValueReferences()]; widgetPositions = new Tuple <uint, uint> [maxBounds.Count]; widgets = new Gtk.Widget[maxBounds.Count]; helpButtonContainers = new Gtk.Container[maxBounds.Count]; table = new Gtk.Table(2, 2, false); uint x = 0, y = 0; int cnt = 0; foreach (ValueReference r in valueReferenceGroup.GetValueReferences()) { int index = cnt; cnt++; if (y >= rows) { y = 0; x += 3; } widgetPositions[index] = new Tuple <uint, uint>(x, y); // If it has a ConstantsMapping, use a combobox instead of anything else if (r.ConstantsMapping != null) { ComboBoxFromConstants comboBox = new ComboBoxFromConstants(false); comboBox.SetConstantsMapping(r.ConstantsMapping); comboBox.Changed += delegate(object sender, EventArgs e) { r.SetValue(comboBox.ActiveValue); OnDataModifiedInternal(); }; dataModifiedExternalEvent += delegate() { comboBox.ActiveValue = r.GetIntValue(); }; table.Attach(new Gtk.Label(r.Name), x + 0, x + 1, y, y + 1); table.Attach(comboBox, x + 1, x + 2, y, y + 1); widgets[index] = comboBox; helpButtonContainers[index] = new Gtk.HBox(); table.Attach(helpButtonContainers[index], x + 2, x + 3, y, y + 1, 0, Gtk.AttachOptions.Fill, 0, 0); goto loopEnd; } // ConstantsMapping == null switch (r.ValueType) { case DataValueType.String: default: { table.Attach(new Gtk.Label(r.Name), x + 0, x + 1, y, y + 1); Gtk.Entry entry = new Gtk.Entry(); if (!r.Editable) { entry.Sensitive = false; } dataModifiedExternalEvent += delegate() { entry.Text = r.GetStringValue(); OnDataModifiedInternal(); }; table.Attach(entry, x + 1, x + 2, y, y + 1); widgets[index] = entry; helpButtonContainers[index] = new Gtk.HBox(); table.Attach(helpButtonContainers[index], x + 2, x + 3, y, y + 1, 0, Gtk.AttachOptions.Fill, 0, 0); break; } case DataValueType.Byte: case DataValueType.HalfByte: byteCase: { table.Attach(new Gtk.Label(r.Name), x + 0, x + 1, y, y + 1); SpinButtonHexadecimal spinButton = new SpinButtonHexadecimal(0, 255); if (!r.Editable) { spinButton.Sensitive = false; } if (r.ValueType == DataValueType.HalfByte) { spinButton.Digits = 1; spinButton.Adjustment.Upper = 15; } else { spinButton.Digits = 2; } spinButton.ValueChanged += delegate(object sender, EventArgs e) { Gtk.SpinButton button = sender as Gtk.SpinButton; if (maxBounds[index] == 0 || button.ValueAsInt <= maxBounds[index]) { r.SetValue(button.ValueAsInt); } else { button.Value = maxBounds[index]; } OnDataModifiedInternal(); }; dataModifiedExternalEvent += delegate() { spinButton.Value = r.GetIntValue(); }; table.Attach(spinButton, x + 1, x + 2, y, y + 1); widgets[index] = spinButton; helpButtonContainers[index] = new Gtk.HBox(); table.Attach(helpButtonContainers[index], x + 2, x + 3, y, y + 1, 0, Gtk.AttachOptions.Fill, 0, 0); } break; case DataValueType.WarpDestIndex: { Gtk.Button newDestButton = new Gtk.Button("New\nDestination"); newDestButton.Clicked += delegate(object sender, EventArgs e) { WarpSourceData warpData = (WarpSourceData)r.Data; WarpDestGroup destGroup = warpData.GetReferencedDestGroup(); // Check if there's unused destination data // already for (int i = 0; i < destGroup.GetNumWarpDests(); i++) { WarpDestData destData = destGroup.GetWarpDest(i); if (destData.GetNumReferences() == 0) { Gtk.MessageDialog d = new Gtk.MessageDialog(null, Gtk.DialogFlags.DestroyWithParent, Gtk.MessageType.Warning, Gtk.ButtonsType.YesNo, "Destination index " + i.ToString("X2") + " is not used by any sources. Use this index?\n\n(\"No\" will create a new destination instead.)"); Gtk.ResponseType response = (Gtk.ResponseType)d.Run(); d.Destroy(); if (response == Gtk.ResponseType.Yes) { warpData.SetDestData(destGroup.GetWarpDest(i)); } else if (response == Gtk.ResponseType.No) { warpData.SetDestData(destGroup.AddDestData()); } break; } } }; table.Attach(newDestButton, x + 2, x + 3, y, y + 2); } goto byteCase; case DataValueType.Word: { table.Attach(new Gtk.Label(r.Name), x + 0, x + 1, y, y + 1); SpinButtonHexadecimal spinButton = new SpinButtonHexadecimal(0, 0xffff); if (!r.Editable) { spinButton.Sensitive = false; } spinButton.Digits = 4; spinButton.ValueChanged += delegate(object sender, EventArgs e) { Gtk.SpinButton button = sender as Gtk.SpinButton; if (maxBounds[index] == 0 || button.ValueAsInt <= maxBounds[index]) { r.SetValue(button.ValueAsInt); } else { button.Value = maxBounds[index]; } OnDataModifiedInternal(); }; dataModifiedExternalEvent += delegate() { spinButton.Value = r.GetIntValue(); }; table.Attach(spinButton, x + 1, x + 2, y, y + 1); widgets[index] = spinButton; helpButtonContainers[index] = new Gtk.HBox(); table.Attach(helpButtonContainers[index], x + 2, x + 3, y, y + 1, 0, Gtk.AttachOptions.Fill, 0, 0); } break; case DataValueType.ByteBit: { table.Attach(new Gtk.Label(r.Name), x + 0, x + 1, y, y + 1); Gtk.CheckButton checkButton = new Gtk.CheckButton(); checkButton.CanFocus = false; if (!r.Editable) { checkButton.Sensitive = false; } checkButton.Toggled += delegate(object sender, EventArgs e) { Gtk.CheckButton button = sender as Gtk.CheckButton; r.SetValue(button.Active ? 1 : 0); OnDataModifiedInternal(); }; dataModifiedExternalEvent += delegate() { checkButton.Active = r.GetIntValue() == 1; }; table.Attach(checkButton, x + 1, x + 2, y, y + 1); widgets[index] = checkButton; helpButtonContainers[index] = new Gtk.HBox(); table.Attach(helpButtonContainers[index], x + 2, x + 3, y, y + 1, 0, Gtk.AttachOptions.Fill, 0, 0); } break; case DataValueType.ByteBits: case DataValueType.WordBits: { table.Attach(new Gtk.Label(r.Name), x + 0, x + 1, y, y + 1); SpinButtonHexadecimal spinButton = new SpinButtonHexadecimal(0, r.MaxValue); if (!r.Editable) { spinButton.Sensitive = false; } spinButton.Digits = (uint)Math.Pow(r.MaxValue, ((double)1) / 16) + 1; spinButton.ValueChanged += delegate(object sender, EventArgs e) { Gtk.SpinButton button = sender as Gtk.SpinButton; if (maxBounds[index] == 0 || button.ValueAsInt <= maxBounds[index]) { r.SetValue(button.ValueAsInt); } else { button.Value = maxBounds[index]; } OnDataModifiedInternal(); }; dataModifiedExternalEvent += delegate() { spinButton.Value = r.GetIntValue(); }; table.Attach(spinButton, x + 1, x + 2, y, y + 1); widgets[index] = spinButton; helpButtonContainers[index] = new Gtk.HBox(); table.Attach(helpButtonContainers[index], x + 2, x + 3, y, y + 1, 0, Gtk.AttachOptions.Fill, 0, 0); } break; case DataValueType.ObjectPointer: { table.Attach(new Gtk.Label(r.Name), x + 0, x + 1, y, y + 1); Gtk.Entry entry = new Gtk.Entry(); if (!r.Editable) { entry.Sensitive = false; } entry.Changed += delegate(object sender, EventArgs e) { UpdatePointerTextBox(sender as Gtk.Entry, r); OnDataModifiedInternal(); }; table.Attach(entry, x + 1, x + 2, y, y + 1); widgets[index] = entry; pointerFrame = new Gtk.Frame(); pointerFrame.Label = "Pointer data (possibly shared)"; pointerFrame.BorderWidth = 5; y++; table.Attach(pointerFrame, x + 0, x + 2, y, y + 1); dataModifiedExternalEvent += delegate() { entry.Text = r.GetStringValue(); UpdatePointerTextBox(entry, r); }; helpButtonContainers[index] = new Gtk.HBox(); table.Attach(helpButtonContainers[index], x + 2, x + 3, y, y + 1, 0, Gtk.AttachOptions.Fill, 0, 0); } break; } loopEnd: y++; } table.ColumnSpacing = 6; if (frameText != null) { var frame = new Gtk.Frame(frameText); frame.Add(table); this.Add(frame); } else { this.Add(table); } this.ShowAll(); Data lastData = null; foreach (ValueReference r in valueReferenceGroup.GetValueReferences()) { if (lastData != r.Data) { lastData = r.Data; r.Data.AddDataModifiedHandler(OnDataModifiedExternal); // Destroy handler this.Destroyed += delegate(object sender, EventArgs e) { r.Data.RemoveDataModifiedHandler(OnDataModifiedExternal); }; } } // Initial values if (dataModifiedExternalEvent != null) { dataModifiedExternalEvent(); } UpdateHelpButtons(); }
protected void OnAddWarpButtonClicked(object sender, EventArgs e) { WarpSourceData data = new WarpSourceData(Project, WarpSourceData.WarpCommands[(int)WarpSourceType.StandardWarp], WarpSourceData.DefaultValues[(int)WarpSourceType.StandardWarp], sourceGroup.FileParser, new List<int>{-1}); data.Map = map; data.Transition = 4; sourceGroup.AddWarpSourceData(data); SetWarpIndex((int)indexSpinButton.Adjustment.Upper+1); }