/// <summary> /// cTor. /// </summary> internal SearchDialog(GeneralGFF f) { InitializeComponent(); DontBeepEvent += SearchDontBeep; _f = f; _tl = _f._tl; if (_x != -1) { Location = new Point(_x, _y); ClientSize = new Size(_w, _h); } else { Location = new Point(_f.Left + 20, _f.Top + 20); } tb_Search.Text = _text; if (_substring) { rb_Substring.Checked = true; } else { rb_Wholeword.Checked = true; } tb_Search.Select(); tb_Search.SelectionStart = tb_Search.Text.Length; }
/// <summary> /// cTor. /// </summary> /// <param name="f"></param> /// <param name="fwType"></param> internal FileWatchDialog(GeneralGFF f, int fwType) { InitializeComponent(); _f = f; if (_f.WindowState == FormWindowState.Minimized) { _f.WindowState = FormWindowState.Normal; } tb_Path.Text = _f.GffData.Pfe; Width = TextRenderer.MeasureText(tb_Path.Text, tb_Path.Font).Width + 20; string text = String.Empty; switch (_fwType = fwType) { case FILE_DEL: text = "The file cannot be found on disk."; btn_Action.Text = "Save"; break; case FILE_WSC: text = "The file on disk has changed."; btn_Action.Text = "Reload"; break; } la_Info.Text = text; btn_Action.Select(); }
/// <summary> /// Loads a GFF file into a TreeList. /// </summary> /// <param name="f"></param> /// <param name="pfe"></param> internal static void LoadGFFfile(GeneralGFF f, string pfe) { f._tl.BeginUpdate(); f._tl.Nodes.Clear(); f.ResetEditPanel(); f.GffData = GffReader.ReadGFFfile(pfe); if (f.GffData != null && GffReader.Structs.Count != 0) { // Load the TopLevelStruct - all else follows -> // NOTE: The TLS has no Field ... thus the rootnode of the // TreeList has no Tag. string label = Path.GetFileNameWithoutExtension(f.GffData.Pfe).ToUpper(); TreeNode root = f._tl.Nodes.Add(label); // NOTE: TreeView doesn't like the root to be a Sortable. or bleh // instantiate the TLS's fieldids as treenodes -> List <uint> fieldids = GffReader.Structs[0].fieldids; for (int i = 0; i != fieldids.Count; ++i) { AddField(GffReader.Fields[(int)fieldids[i]], root); } f._tl.Nodes[0].Expand(); f._tl.SelectedNode = f._tl.Nodes[0]; } f._tl.EndUpdate(); GffReader.Structs.Clear(); GffReader.Fields.Clear(); }
/// <summary> /// Adds a field to the TreeList and selects it. /// </summary> /// <param name="field"></param> /// <param name="locale"></param> void AddField(GffData.Field field, GffData.Locale locale = null) { string text = GeneralGFF.ConstructNodetext(field, locale); var node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes.Add(node); SelectedNode = node; _f.GffData.Changed = true; _f.GffData = _f.GffData; }
/// <summary> /// Opens a dialog to edit a Locale's languageid. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void contextclick_EditLocale(object sender, EventArgs e) { var parent = (GffData.Field)SelectedNode.Parent.Tag; if (parent.localeflags != LocaleDialog.Loc_ALL) { var field = (GffData.Field)SelectedNode.Tag; GffData.Locale locale; locale = parent.Locales[(int)field.localeid]; _langid = locale.langid; _langf = locale.F; using (var f = new LocaleDialog(parent.localeflags, true)) { if (f.ShowDialog(this) == DialogResult.OK && (locale.langid != _langid || locale.F != _langf)) { LocaleDialog.ClearLocaleFlag(ref parent.localeflags, locale.langid, locale.F); field.label = GffData.Locale.GetLanguageString(locale.langid = _langid, locale.F = _langf); ((Sortable)SelectedNode)._label = field.label; LocaleDialog.SetLocaleFlag(ref parent.localeflags, _langid, _langf); SelectedNode.Text = GeneralGFF.ConstructNodetext(field, locale); _f.GffData.Changed = true; _f.GffData = _f.GffData; } } } else { using (var f = new InfoDialog(Globals.Error, "All locales are taken.")) f.ShowDialog(this); } }
/// <summary> /// Adds a Struct (a Feat structure) to the "FeatList" List. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void contextclick_AddFeat(object sender, EventArgs e) { BeginUpdate(); TreeNode top = TopNode; var field = new GffData.Field(); field.type = FieldTypes.Struct; field.label = SelectedNode.Nodes.Count.ToString(); // Structs in Lists do not have a Label field.Struct = new Struct(); field.Struct.typeid = 1; // <- that's what's in the UTCs I've looked at. string text = GeneralGFF.ConstructNodetext(field); var node = new Sortable(text, field.label); node.Tag = field; int id = SelectedNode.Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.WORD; field.label = "Feat"; field.WORD = 0; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); SelectedNode = SelectedNode.Nodes[id]; SelectedNode.Expand(); TopNode = top; _f.GffData.Changed = true; _f.GffData = _f.GffData; EndUpdate(); node.EnsureVisible(); // yes those calls are in a specific sequence. }
/// <summary> /// Opens a dialog to edit a Field's Label. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void contextclick_EditLabel(object sender, EventArgs e) { using (var f = new LabelDialog(((GffData.Field)SelectedNode.Tag).label)) { if (f.ShowDialog(this) == DialogResult.OK) { var field = (GffData.Field)SelectedNode.Tag; if (field.label != f.tb_Label.Text) { bool abort = false; var parent = (GffData.Field)SelectedNode.Parent.Tag; if (parent == null || // ie. 'parent' is TopLevelStruct parent.type == FieldTypes.Struct) { for (int i = 0; i != SelectedNode.Parent.Nodes.Count; ++i) { if (SelectedNode.Parent.Nodes[i] != SelectedNode && ((Sortable)SelectedNode.Parent.Nodes[i])._label == f.tb_Label.Text) { using (var g = new InfoDialog(Globals.Error, "Duplicate labels detected.")) g.ShowDialog(this); abort = true; break; } } } if (!abort) { field.label = (((Sortable)SelectedNode)._label = f.tb_Label.Text); SelectedNode.Text = GeneralGFF.ConstructNodetext(field); _f.GffData.Changed = true; _f.GffData = _f.GffData; } } } } }
/// <summary> /// cTor. /// </summary> internal TreeList(GeneralGFF f) { _f = f; BackColor = Color.PaleTurquoise; Dock = DockStyle.Fill; Width = 500; HideSelection = false; BorderStyle = BorderStyle.None; Indent = 12; AllowDrop = true; TreeViewNodeSorter = new NodeSorter(); DontBeepEvent += Toggle; // NOTE: ContextMenuStrip fails to invoke on first RMB-click // that's why ContextMenu (because it works as advertised). ContextMenu = new ContextMenu(); ContextMenu.Popup += contextpop; }
/// <summary> /// Adds the three Structs of a tint to a specified node. /// </summary> /// <param name="node"></param> void AddTints(TreeNode node) { GffData.Field field; Sortable part, val; for (int i = 1; i != 4; ++i) { field = new GffData.Field(); field.type = FieldTypes.Struct; field.label = i.ToString(); field.Struct = new Struct(); field.Struct.typeid = 0; // <- that's what's in the UTCs I've looked at. string text = GeneralGFF.ConstructNodetext(field); part = new Sortable(text, field.label); part.Tag = field; node.Nodes.Add(part); var colors = new List <string>() { "a", "b", "g", "r" }; foreach (var color in colors) { field = new GffData.Field(); field.type = FieldTypes.BYTE; field.BYTE = Byte.MaxValue; field.label = color; text = GeneralGFF.ConstructNodetext(field); val = new Sortable(text, field.label); val.Tag = field; part.Nodes.Add(val); } part.Expand(); } node.Expand(); }
/// <summary> /// Deletes a field in the TreeList along with any of its subnodes. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> internal void contextclick_Delete(object sender, EventArgs e) { bool delete; if (SelectedNode.Tag == null) // is TopLevelStruct's node { delete = false; using (var f = new DeleteDialog("Confirm delete TopLevelStruct")) { f.cb_Bypass.Visible = false; if (f.ShowDialog(this) == DialogResult.Yes) { delete = true; if (_f.GffData.Pfe == Globals.TopLevelStruct) { _f.GffData = null; } } } } else if (!_bypassDeleteWarning) { string head = "Confirm delete"; if (SelectedNode.Nodes.Count != 0) { head += " multiple fields"; } delete = false; using (var f = new DeleteDialog(head)) { f.cb_Bypass.Visible = true; if (f.ShowDialog(this) == DialogResult.Yes) { delete = true; _bypassDeleteWarning = f.cb_Bypass.Checked; } } } else { delete = true; } if (delete) { if (SelectedNode.Tag != null) { switch (((GffData.Field)SelectedNode.Tag).type) { case FieldTypes.Struct: { // Structs in Lists do not have a Label so keep their pseudo-labels' sequential order var parent = SelectedNode.Parent; if (parent.Tag != null && // parent is NOT TopLevelStruct ((GffData.Field)parent.Tag).type == FieldTypes.List) { Sortable node; var field = (GffData.Field)SelectedNode.Tag; int id = Int32.Parse(field.label); while (++id != parent.Nodes.Count) { node = parent.Nodes[id] as Sortable; field = (GffData.Field)node.Tag; node._label = field.label = (id - 1).ToString(); node.Text = GeneralGFF.ConstructNodetext(field); } } break; } case FieldTypes.locale: { var parent = (GffData.Field)SelectedNode.Parent.Tag; var locales = parent.Locales; int localeid = (int)((GffData.Field)SelectedNode.Tag).localeid; GffData.Locale locale = locales[localeid]; LocaleDialog.ClearLocaleFlag(ref parent.localeflags, locale.langid, locale.F); for (int i = 0; i != SelectedNode.Parent.Nodes.Count; ++i) { var field = (GffData.Field)SelectedNode.Parent.Nodes[i].Tag; if (field.localeid > localeid) { --field.localeid; } } locales.Remove(locale); break; } } } SelectedNode.Remove(); if (SelectedNode == null) { _f.ResetEditPanel(); } if (_f.GffData != null) { _f.GffData.Changed = true; } _f.GffData = _f.GffData; } }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void contextclick_AddDamageReduction(object sender, EventArgs e) { BeginUpdate(); TreeNode top = TopNode; var field = new GffData.Field(); field.type = FieldTypes.Struct; field.label = SelectedNode.Nodes.Count.ToString(); // Structs in Lists do not have a Label field.Struct = new Struct(); field.Struct.typeid = 2; // <- that's what's in the UTCs I've looked at. string text = GeneralGFF.ConstructNodetext(field); var node = new Sortable(text, field.label); node.Tag = field; int id = SelectedNode.Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.SHORT; field.label = "DmgRedctAmt"; field.SHORT = 0; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.SHORT; field.label = "DmgRedctFlags"; field.SHORT = 0; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.List; field.label = "DmgRedctSubList"; text = GeneralGFF.ConstructNodetext(field); var list = new Sortable(text, field.label); list.Tag = field; SelectedNode.Nodes[id].Nodes.Add(list); field = new GffData.Field(); field.type = FieldTypes.Struct; field.label = "0"; // Structs in Lists do not have a Label field.Struct = new Struct(); field.Struct.typeid = 2; // <- that's what's in the UTCs I've looked at. text = GeneralGFF.ConstructNodetext(field); var @struct = new Sortable(text, field.label); @struct.Tag = field; list.Nodes.Add(@struct); field = new GffData.Field(); field.type = FieldTypes.SHORT; field.label = "DmgRedctSubType"; field.SHORT = 0; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; @struct.Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.SHORT; field.label = "DmgRedctType"; field.SHORT = 0; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; @struct.Nodes.Add(node); SelectedNode = SelectedNode.Nodes[id]; SelectedNode.Expand(); list.Expand(); @struct.Expand(); TopNode = top; _f.GffData.Changed = true; _f.GffData = _f.GffData; EndUpdate(); node.EnsureVisible(); // yes those calls are in a specific sequence. }
/// <summary> /// Adds a Struct (a Variable structure) to the "VarTable" List. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void contextclick_AddVariable(object sender, EventArgs e) { using (var dialog = new VariableDialog()) { if (dialog.ShowDialog(this) == DialogResult.OK) { BeginUpdate(); TreeNode top = TopNode; var field = new GffData.Field(); field.type = FieldTypes.Struct; field.label = SelectedNode.Nodes.Count.ToString(); // Structs in Lists do not have a Label field.Struct = new Struct(); field.Struct.typeid = 0; // <- that's what's in the UTCs I've looked at. string text = GeneralGFF.ConstructNodetext(field); var node = new Sortable(text, field.label); node.Tag = field; int id = SelectedNode.Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.CExoString; field.label = "Name"; field.CExoString = _varLabel; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.DWORD; field.label = "Type"; field.DWORD = _varType; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); field = new GffData.Field(); field.label = "Value"; switch (_varType) // TODO: delete the nodes above or put this above there { case VariableDialog.Type_non: // not stable in toolset. is Disabled in the dialog return; case VariableDialog.Type_INT: field.type = FieldTypes.INT; field.INT = Int32.Parse(_varValue); break; case VariableDialog.Type_FLOAT: field.type = FieldTypes.FLOAT; field.FLOAT = Single.Parse(_varValue); break; case VariableDialog.Type_STRING: field.type = FieldTypes.CExoString; field.CExoString = _varValue; break; case VariableDialog.Type_LOCATION: // not stable in toolset. is Disabled in the dialog return; case VariableDialog.Type_UINT: // and I can't see this being useful at all. field.type = FieldTypes.DWORD; field.DWORD = UInt32.Parse(_varValue); break; } text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); SelectedNode = SelectedNode.Nodes[id]; SelectedNode.Expand(); TopNode = top; _f.GffData.Changed = true; _f.GffData = _f.GffData; EndUpdate(); node.EnsureVisible(); // yes those calls are in a specific sequence. } } }
/// <summary> /// Adds a Struct (an EquippedItem structure) to the "Equip_ItemList" List. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void contextclick_AddEquippedItem(object sender, EventArgs e) { GffData.Field field; _bitslot = 0; for (int i = 0; i != SelectedNode.Nodes.Count; ++i) { field = (GffData.Field)SelectedNode.Nodes[i].Tag; _bitslot |= field.Struct.typeid; } using (var f = new EquippedItemDialog(_bitslot)) { _bitslot = 0; if (f.ShowDialog(this) == DialogResult.OK) { BeginUpdate(); TreeNode top = TopNode; field = new GffData.Field(); field.type = FieldTypes.Struct; field.label = SelectedNode.Nodes.Count.ToString(); // Structs in Lists do not have a Label field.Struct = new Struct(); field.Struct.typeid = _bitslot; // <- that's what's in the UTCs I've looked at. string text = GeneralGFF.ConstructNodetext(field); var node = new Sortable(text, field.label); node.Tag = field; int id = SelectedNode.Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.BYTE; field.label = "Dropable"; field.BYTE = 0; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.CResRef; field.label = "EquippedRes"; field.CResRef = String.Empty; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.BYTE; field.label = "Pickpocketable"; field.BYTE = 0; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.WORD; field.label = "Repos_PosX"; field.WORD = 0; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.WORD; field.label = "Repos_PosY"; field.WORD = 0; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); // keep the List's nodes in the correct sequence -> // they are arranged by Struct.typeid ascending int i; // iterator for the sortables int j; // tracker for the node # added // store all the sortable Structs in the List -> // NOTE: This is not an ideal routine. Because it adds all // the nodes to the tree, then removes them, then adds them // all again. It should, rather, just construct the Struct // and its fields, then add the Struct to the tree. var sortables = new List <Sortable>(); for (i = 0; i != SelectedNode.Nodes.Count; ++i) { sortables.Add((Sortable)SelectedNode.Nodes[i]); } SelectedNode.Nodes.Clear(); // NOTE: 'SelectedNode' is the "Equip_ItemList" list-field. // re-add the sortables before the added sortable -> i = j = 0; while (i != sortables.Count) { field = (GffData.Field)sortables[i].Tag; if (field.Struct.typeid < _bitslot) { // NOTE: 'field.label' doesn't need to be changed here sortables[i].Text = GeneralGFF.ConstructNodetextEquipped(field); SelectedNode.Nodes.Add(sortables[i]); j = i; } ++i; } id = ++j; // re-add the last sortable into the sequence -> // replace vals that were set above for the Struct's label and its Sortable's text and label field = (GffData.Field)sortables[sortables.Count - 1].Tag; field.label = sortables[sortables.Count - 1]._label = j.ToString(); sortables[sortables.Count - 1].Text = GeneralGFF.ConstructNodetextEquipped(field); SelectedNode.Nodes.Add(sortables[sortables.Count - 1]); // re-add the sortables that go after the added sortable -> i = 0; while (i != sortables.Count) { field = (GffData.Field)sortables[i].Tag; if (field.Struct.typeid > _bitslot) { field.label = sortables[i]._label = (++j).ToString(); sortables[i].Text = GeneralGFF.ConstructNodetextEquipped(field); SelectedNode.Nodes.Add(sortables[i]); } ++i; } SelectedNode = SelectedNode.Nodes[id]; SelectedNode.Expand(); TopNode = top; _f.GffData.Changed = true; _f.GffData = _f.GffData; EndUpdate(); node.EnsureVisible(); // yes those calls are in a specific sequence. } } }
/// <summary> /// Adds a Struct (an InventoryItem structure) to the "ItemList" List. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void contextclick_AddInventoryItem(object sender, EventArgs e) { BeginUpdate(); TreeNode top = TopNode; int id = SelectedNode.Nodes.Count; var field = new GffData.Field(); field.type = FieldTypes.Struct; field.label = id.ToString(); // Structs in Lists do not have a Label field.Struct = new Struct(); field.Struct.typeid = (uint)id; // <- that's what's in the UTCs I've looked at. string text = GeneralGFF.ConstructNodetext(field); var node = new Sortable(text, field.label); node.Tag = field; id = SelectedNode.Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.BYTE; field.label = "Dropable"; field.BYTE = 0; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.CResRef; field.label = "EquippedRes"; field.CResRef = String.Empty; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.BYTE; field.label = "Pickpocketable"; field.BYTE = 0; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.WORD; field.label = "Repos_PosX"; field.WORD = 0; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.WORD; field.label = "Repos_PosY"; field.WORD = 0; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); SelectedNode = SelectedNode.Nodes[id]; SelectedNode.Expand(); TopNode = top; _f.GffData.Changed = true; _f.GffData = _f.GffData; EndUpdate(); node.EnsureVisible(); // yes those calls are in a specific sequence. }
/// <summary> /// Adds a Field to a treenode. /// </summary> /// <param name="field">a Field to add</param> /// <param name="parent">a treenode to add it to</param> /// <param name="locale">a locale if applicable</param> static void AddField(GffData.Field field, TreeNode parent, GffData.Locale locale = null) { // TODO: Refactor things throughout the code such that the Tag of a // treenode is *either* a GffData.Field *or* a GffData.Locale. string text = GeneralGFF.ConstructNodetext(field, locale); var node = new Sortable(text, field.label); node.Tag = field; parent.Nodes.Add(node); switch (field.type) { case FieldTypes.Struct: // childs can be of any Type. { List <uint> fieldids = field.Struct.fieldids; for (int i = 0; i != fieldids.Count; ++i) { AddField(GffReader.Fields[(int)fieldids[i]], node); } break; } case FieldTypes.List: // childs are Structs. { List <uint> list = field.List; for (int i = 0; i != list.Count; ++i) { // NOTE: Structs in Lists do not have a Label inside a GFF-file. // so give Structs in Lists a pseudo-label for their treenode(s) field = new GffData.Field(); field.type = FieldTypes.Struct; field.label = i.ToString(); field.Struct = GffReader.Structs[(int)list[i]]; AddField(field, node); } break; } case FieldTypes.CExoLocString: // childs are Locales. if (field.Locales != null) { int locales = field.Locales.Count; for (int i = 0; i != locales; ++i) { locale = field.Locales[i]; var fieldloc = new GffData.Field(); fieldloc.type = FieldTypes.locale; fieldloc.localeid = (uint)i; fieldloc.label = GffData.Locale.GetLanguageString(locale.langid, locale.F); AddField(fieldloc, node, locale); LocaleDialog.SetLocaleFlag(ref field.localeflags, locale.langid, locale.F); } } break; } }
/// <summary> /// Adds a Struct (a Class structure) to the "ClassList" List. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void contextclick_AddClass(object sender, EventArgs e) { BeginUpdate(); TreeNode top = TopNode; var field = new GffData.Field(); field.type = FieldTypes.Struct; field.label = SelectedNode.Nodes.Count.ToString(); // Structs in Lists do not have a Label field.Struct = new Struct(); field.Struct.typeid = 2; // <- that's what's in the UTCs I've looked at. string text = GeneralGFF.ConstructNodetext(field); var node = new Sortable(text, field.label); node.Tag = field; int id = SelectedNode.Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.INT; field.label = "Class"; field.INT = 0; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.SHORT; field.label = "ClassLevel"; field.SHORT = 1; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); for (int i = 0; i != 10; ++i) { field = new GffData.Field(); field.type = FieldTypes.List; field.label = LABEL_PREFIX_KNOWN + i; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); } for (int i = 0; i != 10; ++i) { field = new GffData.Field(); field.type = FieldTypes.List; field.label = LABEL_PREFIX_MEMORIZED + i; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); } SelectedNode = SelectedNode.Nodes[id]; SelectedNode.Expand(); TopNode = top; _f.GffData.Changed = true; _f.GffData = _f.GffData; EndUpdate(); node.EnsureVisible(); // yes those calls are in a specific sequence. }
/// <summary> /// Adds an apparel-type. /// </summary> void AddApparel(string label) { BeginUpdate(); TreeNode top = TopNode; var field = new GffData.Field(); field.type = FieldTypes.Struct; field.label = label; field.Struct = new Struct(); field.Struct.typeid = 0; // <- that's what's in the UTCs I've looked at. string text = GeneralGFF.ConstructNodetext(field); var node = new Sortable(text, field.label); node.Tag = field; int id = SelectedNode.Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.Struct; field.label = "ArmorTint"; field.Struct = new Struct(); field.Struct.typeid = 0; // <- that's what's in the UTCs I've looked at. text = GeneralGFF.ConstructNodetext(field); var tint = new Sortable(text, field.label); tint.Tag = field; SelectedNode.Nodes[id].Nodes.Add(tint); AddTints(tint); field = new GffData.Field(); field.type = FieldTypes.BYTE; field.BYTE = 0; field.label = "ArmorVisualType"; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); field = new GffData.Field(); field.type = FieldTypes.BYTE; field.BYTE = 0; field.label = "Variation"; text = GeneralGFF.ConstructNodetext(field); node = new Sortable(text, field.label); node.Tag = field; SelectedNode.Nodes[id].Nodes.Add(node); SelectedNode = SelectedNode.Nodes[id]; SelectedNode.Expand(); TopNode = top; _f.GffData.Changed = true; _f.GffData = _f.GffData; EndUpdate(); node.EnsureVisible(); // yes those calls are in a specific sequence. }
/// <summary> /// Opens a dialog for the user to pick a color. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void contextclick_PickColor(object sender, EventArgs e) { using (var f = new ColorDialog()) { f.CustomColors = _usercolors; f.FullOpen = true; // f.AnyColor = true; f.Color = getCurrentTintColor(); int a = f.Color.A; if (f.ShowDialog(this) == DialogResult.OK) { bool changed = false; TreeNode node; GffData.Field field; for (int i = 0; i != SelectedNode.Nodes.Count; ++i) { node = SelectedNode.Nodes[i]; field = node.Tag as GffData.Field; switch (field.label) { case "a": if (a != (int)field.BYTE) { field.BYTE = (byte)a; changed = true; } break; case "r": if (f.Color.R != field.BYTE) { field.BYTE = f.Color.R; changed = true; } break; case "g": if (f.Color.G != field.BYTE) { field.BYTE = f.Color.G; changed = true; } break; case "b": if (f.Color.B != field.BYTE) { field.BYTE = f.Color.B; changed = true; } break; } node.Text = GeneralGFF.ConstructNodetext(field); } if (changed) { _f.GffData.Changed = true; _f.GffData = _f.GffData; } } _usercolors = f.CustomColors; // NOTE: Does not set on Cancel. dipsh*ts ... } }