From 62b6f24775551ff0c362e239d44b92ed24fd8f55 Mon Sep 17 00:00:00 2001 From: Ivan Mogilko Date: Fri, 27 Sep 2024 18:06:44 +0300 Subject: [PATCH] Editor: support arrays on Global Variables panel --- .../Components/GlobalVariablesComponent.cs | 25 +++- .../GUI/GlobalVariableDialog.Designer.cs | 111 +++++++++++++++--- Editor/AGS.Editor/GUI/GlobalVariableDialog.cs | 24 ++++ .../AGS.Editor/GUI/GlobalVariableDialog.resx | 4 +- .../AGS.Editor/Panes/GlobalVariablesEditor.cs | 24 +++- Editor/AGS.Types/GlobalVariable.cs | 40 +++++++ 6 files changed, 200 insertions(+), 28 deletions(-) diff --git a/Editor/AGS.Editor/Components/GlobalVariablesComponent.cs b/Editor/AGS.Editor/Components/GlobalVariablesComponent.cs index 8a14c11862..b7d55aee66 100644 --- a/Editor/AGS.Editor/Components/GlobalVariablesComponent.cs +++ b/Editor/AGS.Editor/Components/GlobalVariablesComponent.cs @@ -60,7 +60,17 @@ private string GenerateGlobalVariablesScriptModule(IList variabl foreach (GlobalVariable variable in variables) { - string declaration = variable.Type + " " + variable.Name; + string declaration = $"{variable.Type} {variable.Name}"; + switch (variable.ArrayType) + { + case VariableArrayType.Array: + declaration = declaration + $"[{variable.ArraySize}]"; + break; + case VariableArrayType.DynamicArray: + declaration = declaration + $"[]"; + break; + } + if (((variable.Type == "int") || (variable.Type == "bool") || (variable.Type == "float")) && @@ -91,7 +101,18 @@ private void UpdateScriptHeader() StringBuilder sb = new StringBuilder(); foreach (GlobalVariable variable in _agsEditor.CurrentGame.GlobalVariables.ToList()) { - sb.AppendLine("import " + variable.Type + " " + variable.Name + ";"); + switch (variable.ArrayType) + { + case VariableArrayType.None: + sb.AppendLine($"import {variable.Type} {variable.Name};"); + break; + case VariableArrayType.Array: + sb.AppendLine($"import {variable.Type} {variable.Name}[{variable.ArraySize}];"); + break; + case VariableArrayType.DynamicArray: + sb.AppendLine($"import {variable.Type} {variable.Name}[];"); + break; + } } _scriptHeader.Text = sb.ToString(); AutoComplete.ConstructCache(_scriptHeader, null); diff --git a/Editor/AGS.Editor/GUI/GlobalVariableDialog.Designer.cs b/Editor/AGS.Editor/GUI/GlobalVariableDialog.Designer.cs index fdbdb0cb6f..af73def62a 100644 --- a/Editor/AGS.Editor/GUI/GlobalVariableDialog.Designer.cs +++ b/Editor/AGS.Editor/GUI/GlobalVariableDialog.Designer.cs @@ -32,6 +32,10 @@ private void InitializeComponent() this.label1 = new System.Windows.Forms.Label(); this.txtName = new System.Windows.Forms.TextBox(); this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.label5 = new System.Windows.Forms.Label(); + this.udArraySize = new System.Windows.Forms.NumericUpDown(); + this.cmbArray = new System.Windows.Forms.ComboBox(); + this.label4 = new System.Windows.Forms.Label(); this.txtDefaultValue = new System.Windows.Forms.TextBox(); this.label3 = new System.Windows.Forms.Label(); this.cmbType = new System.Windows.Forms.ComboBox(); @@ -39,6 +43,7 @@ private void InitializeComponent() this.btnOK = new System.Windows.Forms.Button(); this.btnCancel = new System.Windows.Forms.Button(); this.groupBox1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.udArraySize)).BeginInit(); this.SuspendLayout(); // // label1 @@ -50,56 +55,117 @@ private void InitializeComponent() this.label1.Size = new System.Drawing.Size(367, 26); this.label1.TabIndex = 0; this.label1.Text = "Enter the variable name here. The name can only contain letters, numbers and the " + - "underscore character; and it cannot start with a number."; + "underscore character; and it cannot start with a number."; // // txtName // this.txtName.Location = new System.Drawing.Point(9, 46); this.txtName.Name = "txtName"; - this.txtName.Size = new System.Drawing.Size(288, 21); + this.txtName.Size = new System.Drawing.Size(326, 21); this.txtName.TabIndex = 1; // // groupBox1 // + this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupBox1.Controls.Add(this.label5); + this.groupBox1.Controls.Add(this.udArraySize); + this.groupBox1.Controls.Add(this.cmbArray); + this.groupBox1.Controls.Add(this.label4); this.groupBox1.Controls.Add(this.txtDefaultValue); this.groupBox1.Controls.Add(this.label3); this.groupBox1.Controls.Add(this.cmbType); this.groupBox1.Controls.Add(this.label2); this.groupBox1.Controls.Add(this.txtName); this.groupBox1.Controls.Add(this.label1); - this.groupBox1.Location = new System.Drawing.Point(12, 12); + this.groupBox1.Location = new System.Drawing.Point(12, 16); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(396, 240); - this.groupBox1.TabIndex = 2; + this.groupBox1.Size = new System.Drawing.Size(396, 306); + this.groupBox1.TabIndex = 0; this.groupBox1.TabStop = false; this.groupBox1.Text = "Global variable properties"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(175, 207); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(30, 13); + this.label5.TabIndex = 6; + this.label5.Text = "Size:"; + // + // udArraySize + // + this.udArraySize.Location = new System.Drawing.Point(227, 204); + this.udArraySize.Maximum = new decimal(new int[] { + 2147483647, + 0, + 0, + 0}); + this.udArraySize.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.udArraySize.Name = "udArraySize"; + this.udArraySize.Size = new System.Drawing.Size(108, 21); + this.udArraySize.TabIndex = 7; + this.udArraySize.Value = new decimal(new int[] { + 1, + 0, + 0, + 0}); + // + // cmbArray + // + this.cmbArray.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cmbArray.Items.AddRange(new object[] { + "Normal variable", + "Array", + "Dynamic array"}); + this.cmbArray.Location = new System.Drawing.Point(9, 204); + this.cmbArray.Name = "cmbArray"; + this.cmbArray.Size = new System.Drawing.Size(160, 21); + this.cmbArray.TabIndex = 5; + this.cmbArray.SelectedIndexChanged += new System.EventHandler(this.cmbArray_SelectedIndexChanged); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(6, 159); + this.label4.MaximumSize = new System.Drawing.Size(380, 0); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(380, 39); + this.label4.TabIndex = 4; + this.label4.Text = "Choose if you want your variable to a be a \"array\" kind. Regular arrays have a co" + + "nstant size, dynamic arrays work like pointers and may be recreated with a new s" + + "ize in script.\r\n"; // // txtDefaultValue // - this.txtDefaultValue.Location = new System.Drawing.Point(9, 205); + this.txtDefaultValue.Location = new System.Drawing.Point(9, 272); this.txtDefaultValue.Name = "txtDefaultValue"; - this.txtDefaultValue.Size = new System.Drawing.Size(288, 21); - this.txtDefaultValue.TabIndex = 5; + this.txtDefaultValue.Size = new System.Drawing.Size(326, 21); + this.txtDefaultValue.TabIndex = 9; // // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(6, 165); + this.label3.Location = new System.Drawing.Point(6, 232); this.label3.MaximumSize = new System.Drawing.Size(380, 0); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(371, 39); - this.label3.TabIndex = 4; + this.label3.TabIndex = 8; this.label3.Text = "Type the default value of the variable below. This will be the value that the var" + - "iable is set to when the game starts up. You can change it later in your scripts" + - "."; + "iable is set to when the game starts up. You can change it later in your scripts" + + "."; // // cmbType // this.cmbType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.cmbType.FormattingEnabled = true; this.cmbType.Location = new System.Drawing.Point(9, 126); this.cmbType.Name = "cmbType"; - this.cmbType.Size = new System.Drawing.Size(300, 21); + this.cmbType.Size = new System.Drawing.Size(326, 21); this.cmbType.TabIndex = 3; this.cmbType.SelectedIndexChanged += new System.EventHandler(this.cmbType_SelectedIndexChanged); // @@ -115,21 +181,23 @@ private void InitializeComponent() // // btnOK // - this.btnOK.Location = new System.Drawing.Point(16, 258); + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnOK.Location = new System.Drawing.Point(16, 331); this.btnOK.Name = "btnOK"; this.btnOK.Size = new System.Drawing.Size(111, 27); - this.btnOK.TabIndex = 3; + this.btnOK.TabIndex = 1; this.btnOK.Text = "&OK"; this.btnOK.UseVisualStyleBackColor = true; this.btnOK.Click += new System.EventHandler(this.btnOK_Click); // // btnCancel // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.btnCancel.Location = new System.Drawing.Point(142, 258); + this.btnCancel.Location = new System.Drawing.Point(142, 331); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(111, 27); - this.btnCancel.TabIndex = 4; + this.btnCancel.TabIndex = 2; this.btnCancel.Text = "&Cancel"; this.btnCancel.UseVisualStyleBackColor = true; // @@ -139,7 +207,7 @@ private void InitializeComponent() this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.CancelButton = this.btnCancel; - this.ClientSize = new System.Drawing.Size(420, 295); + this.ClientSize = new System.Drawing.Size(420, 368); this.Controls.Add(this.btnCancel); this.Controls.Add(this.btnOK); this.Controls.Add(this.groupBox1); @@ -152,6 +220,7 @@ private void InitializeComponent() this.Text = "Global variable properties"; this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.udArraySize)).EndInit(); this.ResumeLayout(false); } @@ -167,5 +236,9 @@ private void InitializeComponent() private System.Windows.Forms.ComboBox cmbType; private System.Windows.Forms.Button btnOK; private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.ComboBox cmbArray; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.NumericUpDown udArraySize; } } \ No newline at end of file diff --git a/Editor/AGS.Editor/GUI/GlobalVariableDialog.cs b/Editor/AGS.Editor/GUI/GlobalVariableDialog.cs index e9c69a022b..6eb07156a5 100644 --- a/Editor/AGS.Editor/GUI/GlobalVariableDialog.cs +++ b/Editor/AGS.Editor/GUI/GlobalVariableDialog.cs @@ -35,6 +35,9 @@ public GlobalVariableDialog(GlobalVariable variable, Game game, IEnumerable2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Choose the type of the variable here. This depends on what sort of information you want to store in the variable. If you just want to store a number, choose "int". To store a string of text, choose "String". diff --git a/Editor/AGS.Editor/Panes/GlobalVariablesEditor.cs b/Editor/AGS.Editor/Panes/GlobalVariablesEditor.cs index 7b3e73ecf8..a329f289d2 100644 --- a/Editor/AGS.Editor/Panes/GlobalVariablesEditor.cs +++ b/Editor/AGS.Editor/Panes/GlobalVariablesEditor.cs @@ -96,11 +96,27 @@ private void PopulateScriptTypeList() private ListViewItem CreateListItemFromVariable(GlobalVariable variable) { - ListViewItem newItem = new ListViewItem(new string[] { variable.Name, variable.Type, variable.DefaultValue }); - newItem.Tag = variable; + ListViewItem newItem = new ListViewItem(new string[] { string.Empty, string.Empty, string.Empty }); + FillListItemFromVariable(newItem, variable); return newItem; } + private void FillListItemFromVariable(ListViewItem item, GlobalVariable variable) + { + string varType; + switch (variable.ArrayType) + { + case VariableArrayType.Array: varType = $"{variable.Type}[{variable.ArraySize}]"; break; + case VariableArrayType.DynamicArray: varType = $"{variable.Type}[]"; break; + default: varType = variable.Type; break; + } + + item.SubItems[0].Text = variable.Name; + item.SubItems[1].Text = varType; + item.SubItems[2].Text = variable.DefaultValue; + item.Tag = variable; + } + private void UpdateListItemFromVariableObject(ListViewItem listItem) { GlobalVariable selectedWord = ((GlobalVariable)listItem.Tag); @@ -169,9 +185,7 @@ private void EditSelectedVariable(GlobalVariable variable) _variables.VariableRenamed(variable, nameWas); } - lvwWords.SelectedItems[0].SubItems[0].Text = variable.Name; - lvwWords.SelectedItems[0].SubItems[1].Text = variable.Type; - lvwWords.SelectedItems[0].SubItems[2].Text = variable.DefaultValue; + FillListItemFromVariable(lvwWords.SelectedItems[0], variable); OnGlobalVariableChanged(); } } diff --git a/Editor/AGS.Types/GlobalVariable.cs b/Editor/AGS.Types/GlobalVariable.cs index a37afc2c14..be7e4b7a72 100644 --- a/Editor/AGS.Types/GlobalVariable.cs +++ b/Editor/AGS.Types/GlobalVariable.cs @@ -5,11 +5,39 @@ namespace AGS.Types { + /// + /// VariableTypeQualifier define declaration qualifiers for the variable, + /// such as const, readonly, and so forth. + /// + [Flags] + public enum VariableTypeQualifier + { + None = 0, + Const = 0x0001, + ReadOnly = 0x0002 + } + + /// + /// VariableArrayType provides variable's qualification as an array. + /// + public enum VariableArrayType + { + None, // not an array, regular variable + Array, // static, fixed-sized array + DynamicArray // dynamic, variable sized array + } + public class GlobalVariable { private string _name = string.Empty; private string _type = string.Empty; private string _defaultValue = string.Empty; + private VariableArrayType _arrayType = VariableArrayType.None; + private int _arraySize = 0; + // NOTE: this is reserved, but currently unused, because "const" and "readonly" + // are barely used with the old AGS compiler (they may have more uses with the + // new compiler in AGS 4. + private VariableTypeQualifier _qualifiers = VariableTypeQualifier.None; public GlobalVariable() { } @@ -31,6 +59,18 @@ public string DefaultValue set { _defaultValue = value; } } + public VariableArrayType ArrayType + { + get { return _arrayType; } + set { _arrayType = value; } + } + + public int ArraySize + { + get { return _arraySize; } + set { _arraySize = value; } + } + public GlobalVariable(XmlNode node) { SerializeUtils.DeserializeFromXML(this, node);