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];
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 (r.ConstantsMapping != null) {
ComboBoxFromConstants comboBox = new ComboBoxFromConstants();
comboBox.SetConstantsMapping(r.ConstantsMapping);
comboBox.Changed += delegate(object sender, EventArgs e) {
r.SetValue(comboBox.ActiveValue);
};
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;
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;
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;
}
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;
}
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;
}
break;
case DataValueType.ByteBits:
{
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)((r.MaxValue+0xf)/0x10);
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;
}
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);
};
}
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();
}