Example #1
0
        void SetTileset(Tileset t)
        {
            if (t == tileset)
            {
                return;
            }
            tileset = t;

            tilesetEventWrapper.ReplaceEventSource(tileset);

            subTileEditor.SetTileset(tileset);
            if (tileset != null)
            {
                subTileGfxViewer.SetGraphicsState(tileset.GraphicsState, 0x2000, 0x3000);
            }

            tilesetviewer1.SetTileset(tileset);

            ValueReferenceGroup vrg = tileset.GetValueReferenceGroup();

            if (tilesetVre == null)
            {
                tilesetVre = new ValueReferenceEditor(Project, vrg, 8);
                tilesetVreContainer.Add(tilesetVre);
            }
            else
            {
                tilesetVre.ReplaceValueReferenceGroup(vrg);
            }

            OnPalettesChanged(null, null);

            tilesetSpinButton.Value            = tileset.Index;
            tilesetSpinButton.Adjustment.Upper = Project.NumTilesets - 1;
        }
Example #2
0
 public void SetValueReferences(IList <ValueReference> references)
 {
     valueReferenceGroup = new ValueReferenceGroup(references);
     foreach (ValueReference r in valueReferenceGroup.GetValueReferences())
     {
         r.SetData(this);
     }
 }
Example #3
0
        // ONLY call this function if the new ValueReferenceGroup matches the exact structure of the
        // old one. If there is any mismatch, a new ValueReferenceEditor should be created instead.
        // But when the structures do match exactly, this is preferred, so that we don't need to
        // recreate all of the necessary widgets again.
        public void ReplaceValueReferenceGroup(ValueReferenceGroup vrg)
        {
            RemoveModifiedHandlers();
            this.valueReferenceGroup = vrg;
            AddModifiedHandlers();

            // Even if we're not rebuilding the widgets we can at least check for minor changes like
            // to the "editable" variable
            for (int i = 0; i < ValueReferenceGroup.Count; i++)
            {
                Gtk.Widget w = widgetLists[i][1];
                w.Sensitive = ValueReferenceGroup[i].Editable;
                SetTooltip(i, ValueReferenceGroup[i].Tooltip);
            }

            // Initial values
            if (dataModifiedExternalEvent != null)
            {
                dataModifiedExternalEvent();
            }

            UpdateHelpButtons();
        }
Example #4
0
        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();
        }
Example #5
0
 public ValueReferenceEditor(Project p, ValueReferenceGroup vrg, string frameText = null)
     : this(p, vrg, 50, frameText)
 {
 }
Example #6
0
        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();
        }
Example #7
0
 public ValueReferenceEditor(Project p, ValueReferenceGroup vrg, string frameText=null)
     : this(p, vrg, 50, frameText)
 {
 }
Example #8
0
        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()];
            widgetGrids         = new List <Gtk.Grid>();
            widgetPositions     = new Tuple <int, int> [maxBounds.Count];
            widgetLists         = new List <IList <Gtk.Widget> >();

            Gtk.Box hbox = new Gtk.HBox();
            hbox.Spacing = 6;

            Func <Gtk.Grid> newGrid = () => {
                Gtk.Grid g = new Gtk.Grid();
                g.ColumnSpacing = 6;
                g.RowSpacing    = 2;
                hbox.Add(g);
                return(g);
            };

            Gtk.Grid grid = newGrid();
            int      x = 0, y = 0;


            // Do not use "foreach" here. The "valueReferenceGroup" may be changed. So, whenever we
            // access a ValueReference from within an event handler, we must do so though the
            // "valueReferenceGroup" class variable, and NOT though an alias (like with foreach).
            for (int tmpCounter = 0; tmpCounter < valueReferenceGroup.Count; tmpCounter++)
            {
                int i = tmpCounter; // Variable must be distinct within each closure

                if (y >= rows)
                {
                    y    = 0;
                    x    = 0;
                    grid = newGrid();
                }

                // Each ValueReference may use up to 3 widgets in the grid row
                Gtk.Widget[] widgetList = new Gtk.Widget[3];

                widgetPositions[i] = new Tuple <int, int>(x, y);

                Action <Gtk.SpinButton> setSpinButtonLimits = (spinButton) => {
                    if (valueReferenceGroup[i].MaxValue < 0x10)
                    {
                        spinButton.Digits = 1;
                    }
                    else if (valueReferenceGroup[i].MaxValue < 0x100)
                    {
                        spinButton.Digits = 2;
                    }
                    else if (valueReferenceGroup[i].MaxValue < 0x1000)
                    {
                        spinButton.Digits = 3;
                    }
                    else
                    {
                        spinButton.Digits = 4;
                    }
                    spinButton.Adjustment.Lower = valueReferenceGroup[i].MinValue;
                    spinButton.Adjustment.Upper = valueReferenceGroup[i].MaxValue;
                };

                int entryWidgetWidth = 1;

                // If it has a ConstantsMapping, use a combobox instead of anything else
                if (valueReferenceGroup[i].ConstantsMapping != null)
                {
                    ComboBoxFromConstants comboBox = new ComboBoxFromConstants(showHelp: true, vertical: true);
                    comboBox.SetConstantsMapping(valueReferenceGroup[i].ConstantsMapping);

                    // Must put this before the "Changed" handler below to avoid
                    // it being fired (for some reason?)
                    setSpinButtonLimits(comboBox.SpinButton);

                    comboBox.Changed += delegate(object sender, EventArgs e) {
                        valueReferenceGroup[i].SetValue(comboBox.ActiveValue);
                        OnDataModifiedInternal();
                    };

                    dataModifiedExternalEvent += delegate() {
                        comboBox.ActiveValue = valueReferenceGroup[i].GetIntValue();
                    };

                    /*
                     * comboBox.MarginTop = 4;
                     * comboBox.MarginBottom = 4;
                     */

                    widgetList[0] = new Gtk.Label(valueReferenceGroup[i].Name);
                    widgetList[1] = comboBox;

                    entryWidgetWidth = 2;

                    goto loopEnd;
                }
                // ConstantsMapping == null

                switch (valueReferenceGroup[i].ValueType)
                {
                case ValueReferenceType.String:
                {
                    widgetList[0] = new Gtk.Label(valueReferenceGroup[i].Name);

                    Gtk.Entry entry = new Gtk.Entry();
                    if (!valueReferenceGroup[i].Editable)
                    {
                        entry.Sensitive = false;
                    }
                    dataModifiedExternalEvent += delegate() {
                        entry.Text = valueReferenceGroup[i].GetStringValue();
                        OnDataModifiedInternal();
                    };

                    widgetList[1] = entry;
                    break;
                }

                case ValueReferenceType.Int:
                {
                    widgetList[0] = new Gtk.Label(valueReferenceGroup[i].Name);

                    SpinButtonHexadecimal spinButton =
                        new SpinButtonHexadecimal(valueReferenceGroup[i].MinValue, valueReferenceGroup[i].MaxValue);
                    if (!valueReferenceGroup[i].Editable)
                    {
                        spinButton.Sensitive = false;
                    }
                    setSpinButtonLimits(spinButton);
                    spinButton.ValueChanged += delegate(object sender, EventArgs e) {
                        Gtk.SpinButton button = sender as Gtk.SpinButton;
                        if (maxBounds[i] == 0 || button.ValueAsInt <= maxBounds[i])
                        {
                            valueReferenceGroup[i].SetValue(button.ValueAsInt);
                        }
                        else
                        {
                            button.Value = maxBounds[i];
                        }
                        OnDataModifiedInternal();
                    };
                    dataModifiedExternalEvent += delegate() {
                        spinButton.Value = valueReferenceGroup[i].GetIntValue();
                    };

                    widgetList[1] = spinButton;
                }
                break;

                case ValueReferenceType.Bool:
                {
                    widgetList[0] = new Gtk.Label(valueReferenceGroup[i].Name);

                    Gtk.CheckButton checkButton = new Gtk.CheckButton();
                    checkButton.FocusOnClick = false;
                    if (!valueReferenceGroup[i].Editable)
                    {
                        checkButton.Sensitive = false;
                    }
                    checkButton.Toggled += delegate(object sender, EventArgs e) {
                        Gtk.CheckButton button = sender as Gtk.CheckButton;
                        valueReferenceGroup[i].SetValue(button.Active ? 1 : 0);
                        OnDataModifiedInternal();
                    };
                    dataModifiedExternalEvent += delegate() {
                        checkButton.Active = valueReferenceGroup[i].GetIntValue() == 1;
                    };

                    widgetList[1] = checkButton;
                }
                break;
                }

loopEnd:
                grid.Attach(widgetList[0], x, y, 1, 1);
                grid.Attach(widgetList[1], x + 1, y, entryWidgetWidth, 1);

                widgetList[2]         = new Gtk.Alignment(0, 0.5f, 0, 0); // Container for help button
                widgetList[2].Hexpand = true;                             // Let this absorb any extra space
                grid.Attach(widgetList[2], x + 2, y, 1, 1);

                widgetGrids.Add(grid);
                widgetLists.Add(widgetList);

                if (valueReferenceGroup[i].Tooltip != null)
                {
                    SetTooltip(i, valueReferenceGroup[i].Tooltip);
                }
                y++;
            }

            if (frameText != null)
            {
                var frame = new Gtk.Frame(frameText);
                frame.Add(hbox);
                this.Add(frame);
            }
            else
            {
                this.Add(hbox);
            }

            this.ShowAll();

            // Initial values
            if (dataModifiedExternalEvent != null)
            {
                dataModifiedExternalEvent();
            }

            UpdateHelpButtons();

            AddModifiedHandlers();
            this.Destroyed += (sender, args) => RemoveModifiedHandlers();
        }
Example #9
0
 public void SetValueReferences(IList<ValueReference> references)
 {
     valueReferenceGroup = new ValueReferenceGroup(references);
     foreach (ValueReference r in valueReferenceGroup.GetValueReferences())
         r.SetData(this);
 }
Example #10
0
        public override void Clicked()
        {
            Box tmpBox, tmpBox2;
            Alignment tmpAlign;
            Box vbox = new Gtk.VBox();
            vbox.Spacing = 3;
            Box hbox = new Gtk.HBox();
            hbox.Spacing = 3;

            Box dungeonVreContainer = new Gtk.VBox();
            Box roomVreContainer = new Gtk.VBox();
            ValueReferenceEditor dungeonVre = null;
            ValueReferenceEditor roomVre = null;

            Alignment frame = new Alignment(0,0,0,0);
            var dungeonSpinButton = new SpinButton(0,15,1);
            var floorSpinButton = new SpinButton(0,15,1);
            var roomSpinButton = new SpinButtonHexadecimal(0,255,1);
            roomSpinButton.Digits = 2;
            Minimap minimap = null;

            System.Action RoomChanged = () => {
                Dungeon dungeon = minimap.Map as Dungeon;
                Room room = minimap.GetRoom();

                roomSpinButton.Value = room.Index&0xff;

                var vrs = new List<ValueReference>();
                vrs.Add(new StreamValueReference("Up", room.Index&0xff, 0,0, DataValueType.ByteBit));
                vrs.Add(new StreamValueReference("Right", room.Index&0xff, 1,1, DataValueType.ByteBit));
                vrs.Add(new StreamValueReference("Down", room.Index&0xff, 2,2, DataValueType.ByteBit));
                vrs.Add(new StreamValueReference("Left", room.Index&0xff, 3,3, DataValueType.ByteBit));
                vrs.Add(new StreamValueReference("Key", room.Index&0xff, 4,4, DataValueType.ByteBit));
                vrs.Add(new StreamValueReference("Chest", room.Index&0xff, 5,5, DataValueType.ByteBit));
                vrs.Add(new StreamValueReference("Boss", room.Index&0xff, 6,6, DataValueType.ByteBit));
                vrs.Add(new StreamValueReference("Dark", room.Index&0xff, 7,7, DataValueType.ByteBit));

                Stream stream = Project.GetBinaryFile("rooms/group" + dungeon.Group + "DungeonProperties.bin");
                foreach (StreamValueReference r in vrs)
                    r.SetStream(stream);

                if (roomVre != null)
                    roomVreContainer.Remove(roomVre);

                var vrg = new ValueReferenceGroup(vrs);
                roomVre = new ValueReferenceEditor(Project, vrg, 4, "Minimap Data");

                roomVreContainer.Add(roomVre);
            };

            System.Action DungeonChanged = () => {
                Dungeon dungeon = Project.GetIndexedDataType<Dungeon>(dungeonSpinButton.ValueAsInt);

                floorSpinButton.Adjustment.Upper = dungeon.NumFloors-1;
                if (floorSpinButton.ValueAsInt >= dungeon.NumFloors)
                    floorSpinButton.Value = dungeon.NumFloors-1;

                var vrs = new List<ValueReference>();
                vrs.Add(new ValueReference("Group", 0, DataValueType.String, false));
                vrs.Add(new ValueReference("Wallmaster dest room", 0, DataValueType.Byte));
                vrs.Add(new ValueReference("Bottom floor layout", 0, DataValueType.Byte, false));
                vrs.Add(new ValueReference("# of floors", 0, DataValueType.Byte, false));
                vrs.Add(new ValueReference("Base floor name", 0, DataValueType.Byte));
                vrs.Add(new ValueReference("Floors unlocked with compass", 0, DataValueType.Byte));

                Data data = dungeon.DataStart;
                foreach (ValueReference r in vrs) {
                    r.SetData(data);
                    data = data.NextData;
                }

                // Remove last ValueReferenceEditor
                if (dungeonVre != null)
                    dungeonVreContainer.Remove(dungeonVre);

                var vrg = new ValueReferenceGroup(vrs);
                dungeonVre = new ValueReferenceEditor(Project, vrg, "Base Data");

                dungeonVre.AddDataModifiedHandler(() => {
                            floorSpinButton.Adjustment.Upper = dungeon.NumFloors;
                            minimap.GenerateImage();
                            RoomChanged();
                        });

                // Replace the "group" option with a custom widget for finer
                // control.
                SpinButton groupSpinButton = new SpinButton(4,5,1);
                groupSpinButton.Value = dungeon.Group;
                groupSpinButton.ValueChanged += (c,d) => {
                    vrg.SetValue("Group", ">wGroup" + groupSpinButton.ValueAsInt + "Flags");
                };
                dungeonVre.ReplaceWidget(0, groupSpinButton);
                dungeonVre.ShowAll();

                // Tooltips
                dungeonVre.AddTooltip(0, "Also known as the high byte of the room index.");
                dungeonVre.AddTooltip(1, "The low byte of the room index wallmasters will send you to.");
                dungeonVre.AddTooltip(2, "The index of the layout for the bottom floor. Subsequent floors will use subsequent indices.");
                dungeonVre.AddTooltip(4, "Determines what the game will call the bottom floor. For a value of:\n$00: The bottom floor is 'B3'.\n$01: The bottom floor is 'B2'.\n$02: The bottom floor is 'B1'.\n$03: The bottom floor is 'F1'.");
                dungeonVre.AddTooltip(5, "A bitset of floors that will appear on the map when the compass is obtained.\n\nEg. If this is $05, then floors 0 and 2 will be unlocked (bits 0 and 2 are set).");

                dungeonVreContainer.Add(dungeonVre);
                minimap.SetMap(dungeon);
                minimap.Floor = floorSpinButton.ValueAsInt;

                RoomChanged();
            };

            dungeonSpinButton.ValueChanged += (a,b) => { DungeonChanged(); };
            floorSpinButton.ValueChanged += (a,b) => { DungeonChanged(); };

            frame.Add(vbox);

            tmpBox = new Gtk.HBox();
            tmpBox.Add(new Gtk.Label("Dungeon "));
            tmpBox.Add(dungeonSpinButton);
            tmpBox.Add(new Gtk.Label("Floor "));
            tmpBox.Add(floorSpinButton);
            tmpAlign = new Alignment(0,0,0,0);
            tmpAlign.Add(tmpBox);

            vbox.Add(tmpAlign);
            vbox.Add(hbox);

            // Leftmost column

            tmpBox = new VBox();
            tmpBox.Add(dungeonVreContainer);

            var addFloorButton = new Button("Add Floor");
            addFloorButton.Image = new Gtk.Image(Gtk.Stock.Add, Gtk.IconSize.Button);
            addFloorButton.Clicked += (a,b) => {
                Dungeon dungeon = minimap.Map as Dungeon;

                int newFloorIndex = dungeon.FirstLayoutIndex + dungeon.NumFloors;

                // Shift all subsequent layouts 64 bytes down in the data file
                Stream layoutFile = Project.GetBinaryFile("rooms/dungeonLayouts.bin");
                layoutFile.SetLength(layoutFile.Length+64);
                for (int i=(int)layoutFile.Length/64-1; i>newFloorIndex; i--) {
                    var buf = new byte[64];
                    layoutFile.Position = (i-1)*64;
                    layoutFile.Read(buf, 0, 64);
                    layoutFile.Write(buf, 0, 64);
                }

                // Clear the new floor
                layoutFile.Position = newFloorIndex*64;
                for (int j=0;j<64;j++)
                    layoutFile.WriteByte(0);

                // Shift each dungeon's "FirstLayoutIndex" to match the shifted layouts.
                for (int i=0; i<Project.GetNumDungeons(); i++) {
                    Dungeon d2 = Project.GetIndexedDataType<Dungeon>(i);
                    if (d2.FirstLayoutIndex >= newFloorIndex)
                        d2.FirstLayoutIndex++;
                }

                dungeon.NumFloors = dungeon.NumFloors+1;
                floorSpinButton.Value = dungeon.NumFloors-1;
                DungeonChanged();
            };
            tmpAlign = new Gtk.Alignment(0.5f,0,0,0);
            tmpAlign.Add(addFloorButton);
            tmpBox.PackStart(tmpAlign);

            var removeFloorButton = new Button("Remove Top Floor");
            removeFloorButton.Image = new Gtk.Image(Gtk.Stock.Remove, Gtk.IconSize.Button);
            removeFloorButton.Clicked += (a,b) => {
                Dungeon dungeon = minimap.Map as Dungeon;

                if (dungeon.NumFloors <= 1)
                    return;

                Gtk.MessageDialog d = new MessageDialog(null,
                        DialogFlags.DestroyWithParent,
                        MessageType.Warning,
                        ButtonsType.YesNo,
                        "Are you quite certain that you wish to delete the top floor of this dungeon?");
                var response = (ResponseType)d.Run();
                d.Destroy();

                if (response == Gtk.ResponseType.Yes) {
                    int deletedFloorIndex = dungeon.FirstLayoutIndex + dungeon.NumFloors-1;

                    // Shift all subsequent layouts 64 bytes up in the data file
                    Stream layoutFile = Project.GetBinaryFile("rooms/dungeonLayouts.bin");
                    for (int i=deletedFloorIndex; i<layoutFile.Length/64-1; i++) {
                        var buf = new byte[64];
                        layoutFile.Position = (i+1)*64;
                        layoutFile.Read(buf, 0, 64);
                        layoutFile.Position = i*64;
                        layoutFile.Write(buf, 0, 64);
                    }

                    layoutFile.SetLength(layoutFile.Length-64);

                    // Shift each dungeon's "FirstLayoutIndex" to match the shifted layouts.
                    for (int i=0; i<Project.GetNumDungeons(); i++) {
                        Dungeon d2 = Project.GetIndexedDataType<Dungeon>(i);
                        if (d2.FirstLayoutIndex > deletedFloorIndex)
                            d2.FirstLayoutIndex--;
                    }

                    dungeon.NumFloors = dungeon.NumFloors-1;

                    DungeonChanged();
                }
            };
            tmpAlign = new Gtk.Alignment(0.5f,0,0,0);
            tmpAlign.Add(removeFloorButton);
            tmpBox.PackStart(tmpAlign);

            hbox.PackStart(tmpBox);

            // Middle column (minimap)

            minimap = new Minimap();
            minimap.TileSelectedEvent += (sender) => {
                RoomChanged();
            };

            hbox.PackStart(minimap);

            // Rightmost column

            tmpAlign = new Alignment(0,0,0,0);
            tmpAlign.Add(roomVreContainer);

            tmpBox2 = new HBox();
            tmpBox2.Add(new Gtk.Label("Room "));
            roomSpinButton.ValueChanged += (a,b) => {
                (minimap.Map as Dungeon).SetRoom(minimap.SelectedX, minimap.SelectedY,
                        minimap.Floor, roomSpinButton.ValueAsInt);
                minimap.GenerateImage();
                RoomChanged();
            };
            tmpBox2.Add(roomSpinButton);

            tmpBox = new VBox();
            tmpBox.Add(tmpBox2);
            tmpBox.Add(tmpAlign);

            hbox.PackStart(tmpBox);

            Window w = new Window(null);
            w.Add(frame);
            w.ShowAll();

            Map map = manager.GetActiveMap();
            if (map is Dungeon)
                dungeonSpinButton.Value = map.Index;

            DungeonChanged();
        }
Example #11
0
        public void SetTreasure(int index)
        {
            int hIndex = index>>8;
            int lIndex = index&0xff;

            int hMax = Treasure.GetNumHighIndices();
            if (hIndex >= hMax)
                hIndex = hMax-1;

            int lMax = Treasure.GetNumLowIndices(hIndex);
            if (lIndex >= lMax)
                lIndex = lMax-1;

            highIndexButton.Adjustment.Upper = hMax-1;
            lowIndexButton.Adjustment.Upper = lMax-1;
            highIndexButton.Value = hIndex;
            lowIndexButton.Value = lIndex;

            index = hIndex<<8|lIndex;

            vrContainer.Remove(vrEditor);

            Data data = Treasure.GetTreasureDataBase(index);
            ValueReference v1 = new ValueReference("Spawn Mode", 0, 4,6, DataValueType.ByteBits);
            v1.SetData(data);
            ValueReference v5 = new ValueReference("Grab Mode", 0, 0,2, DataValueType.ByteBits);
            v5.SetData(data);
            ValueReference v6 = new ValueReference("Unknown", 0, 3,3, DataValueType.ByteBit);
            v6.SetData(data);

            data = data.NextData;
            ValueReference v2 = new ValueReference("Parameter", 0, DataValueType.Byte);
            v2.SetData(data);
            data = data.NextData;
            ValueReference v3 = new ValueReference("Text ID", 0, DataValueType.Byte);
            v3.SetData(data);
            data = data.NextData;
            ValueReference v4 = new ValueReference("Gfx", 0, DataValueType.Byte);
            v4.SetData(data);
            data = data.NextData;

            // Byte 1 is sometimes set to 0x80 for unused treasures?
            v1.SetValue(v1.GetIntValue()&0x7f);

            ValueReferenceGroup vrGroup = new ValueReferenceGroup(new ValueReference[] {v1, v5, v6, v2, v3, v4});

            var vr = new ValueReferenceEditor(
                    Project,
                    vrGroup,
                    "Data");
            vr.SetMaxBound(0, 0x7f); // Max bound for Spawn Mode

            vr.AddDataModifiedHandler(() => {
                    if (TreasureChangedEvent != null)
                        TreasureChangedEvent();
                });

            vrEditor = vr;
            vrContainer.Add(vrEditor);

            if (TreasureChangedEvent != null)
                TreasureChangedEvent();
        }
Example #12
0
        public void SetRoom(int room)
        {
            indexSpinButton.Value = room;

            vrContainer.Remove(vrEditor);
            vrEditor = null;
            v1 = null;
            v2 = null;
            v3 = null;
            v4 = null;

            Data data = Chest.GetChestData(room);

            if (data == null) {
                VBox vbox = new VBox();

                Button addButton = new Button("Add");
                addButton.Clicked += (a,b) => {
                    Chest.AddChestData(RoomIndex);
                    SetRoom(RoomIndex);
                };
                addButton.Label = "gtk-add";
                addButton.UseStock = true;

                var l = new Gtk.Label("No chest data\nexists for this room.");
                vbox.Add(l);
                var btnAlign = new Alignment(0.5f,0.5f,0.0f,0.2f);
                btnAlign.TopPadding = 3;
                btnAlign.Add(addButton);
                vbox.Add(btnAlign);

                vrEditor = vbox;
            }
            else {

                v1 = new ValueReference("YX", 0, DataValueType.Byte);
                v1.SetData(data);
                data = data.NextData;
                v2 = new ValueReference("Room", 0, DataValueType.Byte, false);
                v2.SetData(data);
                data = data.NextData;
                v3 = new ValueReference("ID1", 0, DataValueType.Byte);
                v3.SetData(data);
                data = data.NextData;
                v4 = new ValueReference("ID2", 0, DataValueType.Byte);
                v4.SetData(data);
                data = data.NextData;

                ValueReferenceGroup vrGroup = new ValueReferenceGroup(new ValueReference[] {v1, v2, v3, v4});

                var vr = new ValueReferenceEditor(
                        Project,
                        vrGroup,
                        "Data");
                vr.SetMaxBound(0, 0xfe); // Max bound for YX

                vr.AddDataModifiedHandler(() => {
                        if (ChestChangedEvent != null)
                            ChestChangedEvent();
                        });

                VBox vbox = new VBox();
                vbox.Add(vr);

                Button delButton = new Button("Remove");
                delButton.Clicked += (a,b) => {
                    Chest.DeleteChestData(RoomIndex);
                    SetRoom(RoomIndex);
                };
                delButton.Label = "gtk-delete";
                delButton.UseStock = true;

                Alignment btnAlign = new Alignment(0.5f,0.5f,0.0f,0.2f);
                btnAlign.TopPadding = 3;
                btnAlign.Add(delButton);
                vbox.Add(btnAlign);

                vrEditor = vbox;
            }

            if (ChestChangedEvent != null)
                ChestChangedEvent();

            vrContainer.Add(vrEditor);
            vrContainer.ShowAll();
        }