-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathFormMainMemories.cs
More file actions
322 lines (289 loc) · 12.8 KB
/
FormMainMemories.cs
File metadata and controls
322 lines (289 loc) · 12.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
#if DEBUG
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LabNation.DeviceInterface;
using LabNation.DeviceInterface.Memories;
using System.Reflection;
using LabNation.Common;
namespace ESuite
{
public partial class FormMain : Form
{
private List<TextBox> textBoxes = new List<TextBox>();
private class TextBoxTag
{
public DeviceMemory memory;
public MemoryRegister register;
public Button wrButton;
public Button rdButton;
public TextBoxTag(DeviceMemory memory, MemoryRegister register, Button wrButton, Button rdButton)
{
this.memory = memory;
this.register = register;
this.wrButton = wrButton;
this.rdButton = rdButton;
}
}
private void ClearMemories(Control container)
{
if (InvokeRequired)
this.Invoke((MethodInvoker)delegate { this.ClearMemories(container); });
container.Controls.Clear();
}
private void AddMemories(Control container)
{
if (InvokeRequired)
{
this.Invoke((MethodInvoker)delegate { AddMemories(container); });
return;
}
this.SuspendLayout();
container.Controls.Clear();
Control previousControl = null;
Size requiredContainerSize = new Size(0, 0);
//list groupboxes for all memories in the device
List<DeviceMemory> memories = device.GetMemories();
if (memories == null) return;
foreach (DeviceMemory mem in memories)
{
GroupBox groupBox = new GroupBox();
//have "Write all" and "Read all" buttons
//for each register:
// ID, Name, textbox, "Wr" "Rd" buttons
int methodYOffset = 20;
int maxFormHeight = 700;
foreach(MemoryRegister register in mem.Registers.Values)
{
//add to form
AddGuiForRegister(groupBox, ref methodYOffset, register.Address, mem);
//hook update method to event which gets fired in case a memory register gets updated
//FIXME: make this an "invalidate" delegate and have UI update itself from memory
register.OnInternalValueChanged += RegisterValueChanged;
}
//increase height of containing groupbox
PlaceMemoryGroupbox(container, groupBox, previousControl, device.Serial, mem, methodYOffset, maxFormHeight);
//pass reference on, so next groupbox can be positioned below this one
previousControl = groupBox;
//updated required form size
requiredContainerSize.Width = groupBox.Right;
if (groupBox.Bottom > requiredContainerSize.Height)
requiredContainerSize.Height = groupBox.Bottom;
}
this.ResumeLayout(true);
}
//adds a groupbox for one memory implemented by the DeviceImplementation
private void PlaceMemoryGroupbox(Control container, GroupBox groupBox, Control aboveControl, string name, DeviceMemory mem, int contentHeight, int maxFormHeight)
{
int margin = 3;
int groupBoxWidth = 300;
//position this groupbox relative to the previous one
Point location;
if (aboveControl == null)
location = new Point(margin, margin);
else
{
//Check if we have some space below
if (aboveControl.Bottom + contentHeight < maxFormHeight)
location = new Point(aboveControl.Left, aboveControl.Bottom + margin);
else // Put it to the right
location = new Point(aboveControl.Right + margin, margin);
}
groupBox.Location = location;
groupBox.Size = new System.Drawing.Size(groupBoxWidth, contentHeight + margin);
//name for groupbox: last section after the .
string[] splitString = { "." };
string[] splitResult = mem.ToString().Split(splitString, StringSplitOptions.None);
groupBox.Text = name + " : " + splitResult[splitResult.Length - 1];
if(InvokeRequired)
this.Invoke((MethodInvoker) delegate {
container.Controls.Add(groupBox);
});
else
container.Controls.Add(groupBox);
}
//adds one pair of ID, name, textbox, and buttons for a register
private void AddGuiForRegister(Control parentControl, ref int methodYOffset, uint registerAddress, DeviceMemory mem)
{
int height = 20;
int idWidth = 20;
int labelWidth = 150;
int textBoxWidth = 30;
int buttonWidth = 40;
//add ID
Label lblID = new Label();
lblID.Text = mem.Registers[registerAddress].Address.ToString();
lblID.Location = new Point(3, methodYOffset);
lblID.Size = new System.Drawing.Size(idWidth, height);
parentControl.Controls.Add(lblID);
//add name
Label lblName = new Label();
lblName.Text = mem.Registers[registerAddress].Name;
lblName.Location = new Point(lblID.Right, methodYOffset);
lblName.Size = new System.Drawing.Size(labelWidth, height);
parentControl.Controls.Add(lblName);
//add textbox
TextBox textBox = new TextBox();
//textBox.Text = eFunctionality.InternalValue.ToString("#.##");
if(mem.Registers.Values.First().GetType().Equals(typeof(ByteRegister)))
textBox.Text = ((ByteRegister)mem.Registers[registerAddress]).GetByte().ToString();
else if (mem.Registers.Values.First().GetType().Equals(typeof(BoolRegister)))
textBox.Text = ((BoolRegister)mem.Registers[registerAddress]).GetBool() ? "1" : "0";
textBox.Click += new EventHandler(textBoxSelectAll);
textBox.LostFocus += TextboxValueChanged;
textBox.Size = new Size(textBoxWidth, height);
textBox.Location = new Point(lblName.Right, methodYOffset);
//textBox.Show();
parentControl.Controls.Add(textBox);
this.textBoxes.Add(textBox);
//add Wr button
Button wrButton = new Button();
wrButton.Text = "Wr";
wrButton.Tag = textBox; //store textbox in tag, so when clicked the value can be used
wrButton.Click += WriteButtonClicked;
wrButton.Size = new Size(buttonWidth, height);
wrButton.Location = new Point(textBox.Right, methodYOffset);
wrButton.TabStop = false;
//wrButton.Show();
parentControl.Controls.Add(wrButton);
//add Rd button
Button rdButton = new Button();
rdButton.Text = "Rd";
rdButton.Tag = textBox;
rdButton.Click += ReadButtonClicked;
rdButton.Size = new Size(buttonWidth, height);
rdButton.Location = new Point(wrButton.Right, methodYOffset);
rdButton.TabStop = false;
//rdButton.Show();
parentControl.Controls.Add(rdButton);
textBox.Tag = new TextBoxTag(mem, mem.Registers[registerAddress], wrButton, rdButton);
textBox.KeyDown += new KeyEventHandler(registerTextboxKeyhandler);
//increment Y position
methodYOffset += height; //putting this line here allows to have multiple parameters per method
}
void textBoxSelectAll(object sender, EventArgs e)
{
((TextBox)sender).SelectAll();
}
void registerTextboxKeyhandler(object sender, KeyEventArgs e)
{
TextBox t = (TextBox)sender;
TextBoxTag tag = (TextBoxTag)t.Tag;
if (e.KeyCode == Keys.Return)
{
tag.wrButton.PerformClick();
t.SelectAll();
}
}
//method which is invoked each time one of the "Wr" buttons is clicked
//value from correct textbox should be fetched, and send to the Write method of the correct memory
private void WriteButtonClicked(object sender, EventArgs e)
{
//get all required object to read value, and invoke method
Button button = (Button)sender;
TextBox textBox = (TextBox)button.Tag;
TextBoxTag t = (TextBoxTag)textBox.Tag;
//invoke method
object parsed = null;
if(t.register.GetType().Equals(typeof(ByteRegister))) {
byte bytevalue;
byte.TryParse(textBox.Text, out bytevalue);
parsed = bytevalue;
}
else if (t.register.GetType().Equals(typeof(BoolRegister)))
{
int bytevalue;
int.TryParse(textBox.Text, out bytevalue);
parsed = bytevalue > 0;
}
t.register.Set(parsed);
try
{
Logger.Debug(String.Format("Immediately writing {0} to {1}:{2}({3}) of memory {2}", parsed, t.register.Memory.GetType().Name, t.register.Name, t.register.Address));
t.memory[t.register.Address].WriteImmediate();
}
catch (Exception ex)
{
MessageBox.Show("Couldn't write: [" + ex.GetType().Name + "]" + ex.Message);
}
}
//method which is invoked each time one of the "Rd" buttons is clicked
//value from correct textbox should be fetched, and send to the Read method of the correct memory
private void ReadButtonClicked(object sender, EventArgs e)
{
//get all required object to read value, and invoke method
Button button = (Button)sender;
TextBox textBox = (TextBox)button.Tag;
TextBoxTag t = (TextBoxTag)textBox.Tag;
try
{
t.register.Read();
}
catch (Exception ex)
{
MessageBox.Show("Couldn't read: [" + ex.GetType().Name + "]" + ex.Message);
}
}
//called each time a textbox value is updated
private void TextboxValueChanged(object sender, EventArgs e)
{
//get all required object to read value, and invoke method
//Button button = (Button)sender;
//TextBox textBox = (TextBox)button.Tag;
TextBox textBox = (TextBox)sender;
TextBoxTag t = (TextBoxTag)textBox.Tag;
//try to parse the value from the textbox
float parsed;
if (!float.TryParse(textBox.Text, out parsed))
Logger.Error("could not parse textbox value into float " + textBox.Text + t.memory.GetType().ToString() + t.register.Address.ToString());
//clamp value within range
if (parsed > t.register.MaxValue) parsed = t.register.MaxValue;
//update textbox
//textBox.Text = parsed.ToString("#.##");
textBox.Text = parsed.ToString();
}
//update method: called each time one of the register values is changed
private void RegisterValueChanged(object sender, EventArgs e)
{
try
{
//scan through all items of this form.
//if the correct memory and regIndex was found, update the textbox value
foreach (TextBox textBox in this.textBoxes)
{
TextBoxTag t = (TextBoxTag)textBox.Tag;
if(t.register == sender)
UpdateRegisterTextbox(textBox);
}
}
catch
{
Logger.Error("error in RegisterValueChanged method in FormMemories! " + sender.GetType().ToString());
}
}
private delegate void UpdateRegisterTextboxDelegate(TextBox textBox);
private static void UpdateRegisterTextbox(TextBox textBox)
{
TextBoxTag t = (TextBoxTag)textBox.Tag;
if (textBox.InvokeRequired)
{
UpdateRegisterTextboxDelegate del = UpdateRegisterTextbox;
textBox.Invoke(del, new object[] { textBox });
}
else
{
object register = t.register.Get();
if (register.GetType().Equals(typeof(bool)))
textBox.Text = (bool)register ? "1" : "0";
else
textBox.Text = t.register.Get().ToString();
}
}
}
}
#endif