Example #1
0
 public void CloseSpecialItemMenu()
 {
     if (Settings.Paradise)
     {
         // NOTE: No possibility to undo yet.
         _paraSpecialItemInterface = null;
     }
     else
     {
         editor.AddToUndoHistory();
         _physicalMapLogic.OverrideGridData(editor.MapGrid);
         _physicalMapLogic     = null;
         _specialItemInterface = null;
     }
 }
Example #2
0
        public void ChangeSpecialItemLocation(Point?newLocation)
        {
            // Note: Can only be a bonus
            _physicalMapLogic = new PhysicalMapLogic(editor.MapGrid);
            if (newLocation.HasValue)
            {
                _physicalMapLogic.Bonus = new PhysicalMapLogic.BonusInfo(_lastBonusId, newLocation.Value.X, newLocation.Value.Y);
            }
            else
            {
                _physicalMapLogic.Bonus = null;
            }

            editor.AddToUndoHistory();
            _physicalMapLogic.OverrideGridData(editor.MapGrid);
            _physicalMapLogic = null;
        }
Example #3
0
 void DrawTile(SpriteBatch sprite_batch, TilesSet sprites, Rectangle dst, int tile, bool overridePalette, bool showSpecial)
 {
     if (type == Levels.MapType.Minimap)
     {
         sprites.Draw(sprite_batch, overridePalette ? sprites.SelectedSet : tile, 0, dst);
     }
     else
     {
         tile = overridePalette ? ChangePalette(tile, sprites.SelectedSet) : tile;
         int           tile_id = tile & 0x3FF;
         int           palette = (tile & 0xF000) >> 12;
         SpriteEffects effects =
             ((tile & 0x400) != 0 ? SpriteEffects.FlipHorizontally : SpriteEffects.None) |
             ((tile & 0x800) != 0 ? SpriteEffects.FlipVertically : SpriteEffects.None);
         if (showSpecial)
         {
             if (Settings.Paradise)
             {
                 if (tile_id >= PhysicalMapLogic.CONTROL_MIN_ID)
                 {
                     // Rendering of non-graphic special elements
                     Color?c = null;
                     if (ParadisePhysicalMapLogic.STARTING_ZONE_IDS.Contains(tile_id))
                     {
                         c = ParadisePhysicalMapLogic.StartingZoneColor(tile_id);
                     }
                     else if (ParadisePhysicalMapLogic.HEALING_ZONE_IDS.Contains(tile_id))
                     {
                         c = ParadisePhysicalMapLogic.HealingZoneColor(tile_id);
                     }
                     else if (ParadisePhysicalMapLogic.ENDING_ZONE_IDS.Contains(tile_id))
                     {
                         c = ParadisePhysicalMapLogic.EndingZoneColor(tile_id);
                     }
                     else if (ParadisePhysicalMapLogic.FIXED_OBJECTS_IDS.Contains(tile_id))
                     {
                         sprite_batch.Draw(ParadisePhysicalMapLogic.TextureOfFixedObjects(tile_id), dst, null, Color.White, 0, Vector2.Zero, effects, 0F);
                     }
                     else if (ParadisePhysicalMapLogic.MOVING_OBJECTS_IDS.Contains(tile_id)) // Flips have no effect on moving objects tiles
                     {
                         sprite_batch.Draw(ParadisePhysicalMapLogic.TextureOfMovingObject(tile_id), dst, null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 0F);
                     }
                     else if (ParadisePhysicalMapLogic.NUMBER_TILES.Contains(tile)) // Palette and flips matters for numbers
                     {
                         sprite_batch.Draw(ParadisePhysicalMapLogic.TextureOfNumber(tile), dst, null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 0F);
                     }
                     else
                     {
                         c = ParadisePhysicalMapLogic.UNSUPPORTED_COLOR;
                     }
                     if (c.HasValue)
                     {
                         sprite_batch.FillRectangle(dst, c.Value);
                     }
                 }
                 if (tile_id <= PhysicalMapLogic.VISIBLE_MAX_ID)
                 {
                     sprites.Draw(sprite_batch, palette, tile_id, dst, effects);
                 }
             }
             else
             {
                 if (tile_id >= PhysicalMapLogic.CONTROL_MIN_ID)
                 {
                     // Rendering of non-graphic special elements
                     Color?c = null;
                     if (PhysicalMapLogic.STARTING_ZONE_IDS.Contains(tile_id))
                     {
                         c = PhysicalMapLogic.StartingZoneColor(tile_id);
                     }
                     else if (PhysicalMapLogic.HEALING_ZONE_IDS.Contains(tile_id))
                     {
                         c = PhysicalMapLogic.HealingZoneColor(tile_id);
                     }
                     else if (PhysicalMapLogic.ENDING_ZONE_IDS.Contains(tile_id))
                     {
                         c = PhysicalMapLogic.EndingZoneColor(tile_id);
                     }
                     else if (PhysicalMapLogic.SPRING_IDS.Contains(tile_id))
                     {
                         sprite_batch.Draw(PhysicalMapLogic.TextureOfSpring(tile_id), dst, null, Color.White, 0, Vector2.Zero, effects, 0F);
                     }
                     else if (PhysicalMapLogic.VISIBLE_CONTROL_TILES.Contains(tile_id))
                     {
                         sprite_batch.Draw(PhysicalMapLogic.UnderlayOfVisibleControlTile(tile_id), dst, null, Color.White, 0, Vector2.Zero, effects, 0F);
                     }
                     else if (PhysicalMapLogic.MOVING_OBJECTS_IDS.Contains(tile_id)) // Flips have no effect on moving objects tiles
                     {
                         sprite_batch.Draw(PhysicalMapLogic.TextureOfMovingObject(tile_id), dst, null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 0F);
                     }
                     else if (PhysicalMapLogic.NUMBER_TILES.Contains(tile)) // Palette and flips matters for numbers
                     {
                         sprite_batch.Draw(PhysicalMapLogic.TextureOfNumber(tile), dst, null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 0F);
                     }
                     else
                     {
                         c = PhysicalMapLogic.UNSUPPORTED_COLOR;
                     }
                     if (c.HasValue)
                     {
                         sprite_batch.FillRectangle(dst, c.Value);
                     }
                 }
                 if (tile_id <= PhysicalMapLogic.VISIBLE_MAX_ID || PhysicalMapLogic.VISIBLE_CONTROL_TILES.Contains(tile_id))
                 {
                     sprites.Draw(sprite_batch, palette, tile_id, dst, effects);
                 }
             }
         }
         else
         {
             sprites.Draw(sprite_batch, palette, tile_id, dst, effects);
         }
     }
 }
Example #4
0
        void LoadInterface()
        {
            // ===== MAIN MENU =====
            var grid = new Grid
            {
                RowSpacing    = 10,
                ColumnSpacing = 20
            };

            grid.ColumnsProportions.Add(new Proportion(ProportionType.Auto));
            grid.HorizontalAlignment = HorizontalAlignment.Center;
            grid.RowsProportions.Add(new Proportion(ProportionType.Auto));
            grid.VerticalAlignment = VerticalAlignment.Center;

            var labelType = new Label
            {
                Id         = "labelType",
                Text       = "Choose the element to modify:",
                GridColumn = 0,
                GridRow    = 0,
            };

            grid.Widgets.Add(labelType);

            var comboType = new ComboBox
            {
                GridColumn = 1,
                GridRow    = 0,
                Width      = 150
            };

            comboType.Items.Add(new ListItem("Walls", Color.White));
            comboType.Items.Add(new ListItem("Ground", Color.White));
            if (Settings.Paradise)
            {
                comboType.Items.Add(new ListItem("Ground 2", Color.White));
            }
            comboType.Items.Add(new ListItem("Background", Color.White));
            comboType.Items.Add(new ListItem("MiniMap", Color.White));
            grid.Widgets.Add(comboType);

            var labelMap = new Label
            {
                Id         = "labelMap",
                Text       = "Choose the map to modify:",
                GridColumn = 0,
                GridRow    = 1,
            };

            grid.Widgets.Add(labelMap);

            var comboMap = new ComboBox
            {
                GridColumn = 1,
                GridRow    = 1,
                Width      = 150
            };

            foreach (string name in Levels.AllLevels)
            {
                comboMap.Items.Add(new ListItem(name, Color.White));
            }
            grid.Widgets.Add(comboMap);

            var buttonEdit = new TextButton
            {
                GridColumn  = 2,
                GridRow     = 0,
                GridRowSpan = 2,
                Text        = "Edit map",
                Width       = 150,
                Height      = 60
            };

            buttonEdit.Click += (s, a) =>
            {
                if (comboMap.SelectedIndex == null || comboType.SelectedIndex == null)
                {
                    PleaseSelectMapMsg();
                }
                else
                {
                    mode = IndexToSelectedMode(comboType.SelectedIndex);
                    map  = comboMap.SelectedItem.Text;
                    if (!LoadGrid())
                    {
                        mode = Mode.Menu;
                    }
                }
            };

            grid.Widgets.Add(buttonEdit);

            // Edit times
            var buttonEditTimesF = new TextButton
            {
                GridColumn = 3,
                GridRow    = 0,
                Text       = "Edit times (in frame)",
                Width      = 150,
                Height     = 25
            };

            buttonEditTimesF.Click += (s, a) =>
            {
                _timesEditor = new TimesEditor(this, false);
            };
            grid.Widgets.Add(buttonEditTimesF);

            var buttonEditTimesS = new TextButton
            {
                GridColumn = 3,
                GridRow    = 1,
                Text       = "Edit times",
                Width      = 150,
                Height     = 25
            };

            buttonEditTimesS.Click += (s, a) =>
            {
                _timesEditor = new TimesEditor(this, true);
            };
            grid.Widgets.Add(buttonEditTimesS);

            // Edit overworld data (Paradise only for now)
            if (Settings.Paradise)
            {
                var buttonEditOverworld = new TextButton
                {
                    GridColumn = 3,
                    GridRow    = 2,
                    Text       = "Edit overworld",
                    Width      = 150,
                    Height     = 25
                };

                buttonEditOverworld.Click += (s, a) =>
                {
                    _overworldEditor = new OverworldEditor(this);
                };
                grid.Widgets.Add(buttonEditOverworld);
            }

            // Reset
            var buttonReset = new TextButton
            {
                GridColumn = 4,
                GridRow    = 0,
                Text       = "Reset this map",
                Width      = 150,
                Height     = 25
            };

            buttonReset.Click += (s, a) =>
            {
                if (comboMap.SelectedIndex == null || comboType.SelectedIndex == null)
                {
                    PleaseSelectMapMsg();
                }
                else
                {
                    var messageBox = Dialog.CreateMessageBox("Confirmation", "Are you sure ? This level will be reset.");
                    messageBox.Closed += (s, a) =>
                    {
                        if (messageBox.Result)
                        {
                            Task.Factory.StartNew(() => {
                                try
                                {
                                    mode = Mode.Loading;
                                    File.Delete(Levels.GetLevelPath(comboMap.SelectedItem.Text,
                                                                    MapType(IndexToSelectedMode(comboType.SelectedIndex))));
                                    Settings.RunExtractor("");
                                    mode = Mode.Menu;
                                }
                                catch { Exit(); }
                            });
                        }
                    };
                    messageBox.ShowModal(_mainMenuDesktop);
                }
            };
            grid.Widgets.Add(buttonReset);

            var buttonResetAll = new TextButton
            {
                GridColumn = 4,
                GridRow    = 1,
                Text       = "Reset ALL maps",
                Width      = 150,
                Height     = 25
            };

            buttonResetAll.Click += (s, a) =>
            {
                var messageBox = Dialog.CreateMessageBox("Confirmation", "Are you sure ? ALL levels will be reset.");
                messageBox.Closed += (s, a) =>
                {
                    if (messageBox.Result)
                    {
                        Task.Factory.StartNew(() => {
                            try
                            {
                                mode = Mode.Loading;
                                Levels.DeleteAllLevels();
                                Settings.RunExtractor("");
                                reloadAtNextFrame = true;
                            }
                            catch { Exit(); }
                        });
                    }
                };
                messageBox.ShowModal(_mainMenuDesktop);
            };
            grid.Widgets.Add(buttonResetAll);
            // Build
            var buttonBuild = new TextButton
            {
                GridColumn  = 2,
                GridRow     = 2,
                GridRowSpan = 1,
                Text        = "Build",
                Width       = 150,
                Height      = 25
            };

            buttonBuild.Click += (s, a) =>
            {
                Task.Factory.StartNew(() => {
                    try
                    {
                        mode = Mode.Loading;
                        Settings.RunExtractor("");
                        mode = Mode.Menu;
                    }
                    catch { Exit(); }
                });
            };
            grid.Widgets.Add(buttonBuild);

            var buttonBuildAndRun = new TextButton
            {
                GridColumn  = 2,
                GridRow     = 3,
                GridRowSpan = 1,
                Text        = "Build and run",
                Width       = 150,
                Height      = 25
            };

            buttonBuildAndRun.Click += (s, a) =>
            {
                Task.Factory.StartNew(() => {
                    try
                    {
                        mode = Mode.Loading;
                        Settings.RunExtractor("");
                        mode = Mode.Menu;
                        Settings.RunEmulator();
                    }
                    catch { Exit(); }
                });
            };
            grid.Widgets.Add(buttonBuildAndRun);

            _mainMenuDesktop      = new Desktop();
            _mainMenuDesktop.Root = grid;

            // ===== LATERAL MENU =====
            Panel panel = new Panel()
            {
                Left       = 0,
                Padding    = new Thickness(10, 10, 10, 10),
                Width      = LATERAL_PANEL_WIDTH,
                Background = new SolidBrush(Color.Transparent),
            };

            var lateral = new Grid
            {
                RowSpacing    = 10,
                ColumnSpacing = 10
            };

            lateral.ColumnsProportions.Add(new Proportion(ProportionType.Auto));
            lateral.HorizontalAlignment = HorizontalAlignment.Left;
            lateral.RowsProportions.Add(new Proportion(ProportionType.Part));
            lateral.VerticalAlignment = VerticalAlignment.Top;

            var buttonSave = new TextButton
            {
                GridColumn = 0,
                GridRow    = 0,
                Text       = "Save",
                Width      = 40,
                Height     = 30
            };

            buttonSave.Click += (s, a) =>
            {
                SaveGrid();
                _inventories.Save();
            };
            lateral.Widgets.Add(buttonSave);

            var buttonSaveQuit = new TextButton
            {
                GridColumn     = 1,
                GridRow        = 0,
                Text           = "Save + quit",
                Width          = 90,
                Height         = 30,
                GridColumnSpan = 2
            };

            buttonSaveQuit.Click += (s, a) =>
            {
                SaveGrid();
                QuitEditor();
            };
            lateral.Widgets.Add(buttonSaveQuit);

            var buttonQuit = new TextButton
            {
                GridColumn = 3,
                GridRow    = 0,
                Text       = "Quit",
                Width      = 40,
                Height     = 30
            };

            buttonQuit.Click += (s, a) =>
            {
                QuitEditor();
            };
            lateral.Widgets.Add(buttonQuit);

            var buttonWP = new TextButton
            {
                GridColumn = 0,
                GridRow    = 1,
                Text       = "W+",
                Width      = 40,
                Height     = 30
            };

            buttonWP.Click += (s, a) =>
            {
                editor.IncreaseWidth();
            };
            lateral.Widgets.Add(buttonWP);
            var buttonWM = new TextButton
            {
                GridColumn = 1,
                GridRow    = 1,
                Text       = "W-",
                Width      = 40,
                Height     = 30
            };

            buttonWM.Click += (s, a) =>
            {
                editor.DecreaseWidth();
            };
            lateral.Widgets.Add(buttonWM);
            var buttonHP = new TextButton
            {
                GridColumn = 2,
                GridRow    = 1,
                Text       = "H+",
                Width      = 40,
                Height     = 30
            };

            buttonHP.Click += (s, a) =>
            {
                editor.IncreaseHeight();
            };
            lateral.Widgets.Add(buttonHP);
            var buttonHM = new TextButton
            {
                GridColumn = 3,
                GridRow    = 1,
                Text       = "H-",
                Width      = 40,
                Height     = 30
            };

            buttonHM.Click += (s, a) =>
            {
                editor.DecreaseHeight();
            };
            lateral.Widgets.Add(buttonHM);

            var buttonOP = new TextButton
            {
                GridColumn     = 0,
                GridRow        = 2,
                Text           = "Overlay +",
                Width          = 90,
                Height         = 30,
                GridColumnSpan = 2
            };

            buttonOP.Click += (s, a) =>
            {
                List <GridEditor.OverlayGrid> overlays = new List <GridEditor.OverlayGrid>();
                overlays.AddRange(editor.Underlays);
                overlays.AddRange(editor.Overlays);
                overlays.Reverse();
                foreach (GridEditor.OverlayGrid overlay in overlays)
                {
                    if (!overlay.enabled)
                    {
                        overlay.enabled = true;
                        break;
                    }
                }
            };
            lateral.Widgets.Add(buttonOP);
            var buttonOM = new TextButton
            {
                GridColumn     = 2,
                GridRow        = 2,
                Text           = "Overlay -",
                Width          = 90,
                Height         = 30,
                GridColumnSpan = 2
            };

            buttonOM.Click += (s, a) =>
            {
                List <GridEditor.OverlayGrid> overlays = new List <GridEditor.OverlayGrid>();
                overlays.AddRange(editor.Underlays);
                overlays.AddRange(editor.Overlays);
                foreach (GridEditor.OverlayGrid overlay in overlays)
                {
                    if (overlay.enabled)
                    {
                        overlay.enabled = false;
                        break;
                    }
                }
            };
            lateral.Widgets.Add(buttonOM);

            var buttonGOn = new TextButton
            {
                GridColumn     = 0,
                GridRow        = 3,
                Text           = "Grid On",
                Width          = 90,
                Height         = 30,
                GridColumnSpan = 2
            };

            buttonGOn.Click += (s, a) =>
            {
                editor.GridEnabled = true;
            };
            lateral.Widgets.Add(buttonGOn);
            var buttonGOff = new TextButton
            {
                GridColumn     = 2,
                GridRow        = 3,
                Text           = "Grid Off",
                Width          = 90,
                Height         = 30,
                GridColumnSpan = 2
            };

            buttonGOff.Click += (s, a) =>
            {
                editor.GridEnabled = false;
            };
            lateral.Widgets.Add(buttonGOff);

            var buttonSpecial = new TextButton
            {
                GridColumn     = 0,
                GridRow        = 4,
                Text           = "Special Objects",
                Width          = 180,
                Height         = 30,
                GridColumnSpan = 4
            };

            buttonSpecial.Click += (s, a) =>
            {
                if (mode == Mode.Physical)
                {
                    if (Settings.Paradise)
                    {
                        _paraSpecialItemInterface = new ParadiseSpecialItems(this, _paraPhysicalMapLogic);
                    }
                    else
                    {
                        _physicalMapLogic     = new PhysicalMapLogic(editor.MapGrid);
                        _specialItemInterface = new SpecialItems(this, _physicalMapLogic);
                    }
                }
                else
                {
                    var messageBox = Dialog.CreateMessageBox("Error", "Special items can only be edited in Wall edition mode.");
                    messageBox.ShowModal(_lateralMenuDesktop);
                }
            };
            lateral.Widgets.Add(buttonSpecial);

            var buttonHelp = new TextButton
            {
                GridColumn     = 0,
                GridRow        = 5,
                Text           = "Help",
                Width          = 180,
                Height         = 30,
                GridColumnSpan = 4
            };

            buttonHelp.Click += (s, a) =>
            {
                var messageBox = Dialog.CreateMessageBox("Commands",
                                                         "Move: CTRL+LeftClick or Arrows\n" +
                                                         "Zoom: CTRL+Wheel or CTRL+[+/-]\n" +
                                                         "Next / Previous palette: Wheel\n" +
                                                         "Make a selection: ALT+LeftClick\n" +
                                                         "Brush size: ALT+Wheel or ALT+[+/-]\n" +
                                                         "Flip selection: SHIFT+Wheel or SHIFT+Arrows\n" +
                                                         "Force palette of selection: SHIFT+Space\n" +
                                                         "Open/Close inventory: Space\n" +
                                                         "Open/Close custom inventory: Enter\n" +
                                                         "Undo / Redo: CTRL+Z / CTRL+Y"
                                                         );
                messageBox.ShowModal(_lateralMenuDesktop);
            };
            lateral.Widgets.Add(buttonHelp);

            var buttonSBR = new TextButton
            {
                GridColumn     = 0,
                GridRow        = 17,
                Text           = "Save, build and run",
                Width          = 180,
                Height         = 30,
                GridColumnSpan = 4
            };

            buttonSBR.Click += (s, a) =>
            {
                SaveGrid();
                _inventories.Save();
                Task.Factory.StartNew(() => {
                    try
                    {
                        Mode mode_bkp = mode;
                        mode          = Mode.Loading;
                        Settings.RunExtractor("");
                        mode = mode_bkp;
                        Settings.RunEmulator();
                    }
                    catch { Exit(); }
                });
            };
            lateral.Widgets.Add(buttonSBR);

            panel.Widgets.Add(lateral);
            _lateralMenuDesktop      = new Desktop();
            _lateralMenuDesktop.Root = panel;

            mode = Mode.Menu;
        }
Example #5
0
        public SpecialItems(Game1 game, PhysicalMapLogic logic)
        {
            _game  = game;
            _logic = logic;

            Panel panel = new Panel()
            {
                Background = new SolidBrush(Color.Black),
                Padding    = new Myra.Graphics2D.Thickness(20, 20, 20, 20)
            };

            var grid = new Grid
            {
                RowSpacing    = 10,
                ColumnSpacing = 10
            };

            grid.ColumnsProportions.Add(new Proportion(ProportionType.Auto));
            grid.HorizontalAlignment = HorizontalAlignment.Left;
            grid.RowsProportions.Add(new Proportion(ProportionType.Part));
            grid.VerticalAlignment = VerticalAlignment.Top;

            // --- BONUS ---

            PhysicalMapLogic.BonusInfo?bonus = _logic.Bonus;
            Label labelBonus = new Label()
            {
                Id         = "labelBonus",
                Text       = "Bonus (ID/X/Y)",
                GridColumn = 0,
                GridRow    = 0
            };

            grid.Widgets.Add(labelBonus);
            bonusId = new TextBox()
            {
                GridRow    = 0,
                GridColumn = 1,
                HintText   = "ID",
                Width      = 150,
                Text       = bonus.HasValue ? bonus.Value.ID.ToString() : null
            };
            grid.Widgets.Add(bonusId);
            bonusX = new TextBox()
            {
                GridRow    = 0,
                GridColumn = 2,
                HintText   = "X",
                Width      = 150,
                Text       = bonus.HasValue ? bonus.Value.x.ToString() : null
            };
            grid.Widgets.Add(bonusX);
            bonusY = new TextBox()
            {
                GridRow    = 0,
                GridColumn = 3,
                HintText   = "Y",
                Width      = 150,
                Text       = bonus.HasValue ? bonus.Value.y.ToString() : null
            };
            grid.Widgets.Add(bonusY);

            var bonusRemove = new TextButton
            {
                GridColumn = 4,
                GridRow    = 0,
                Text       = "Remove",
                Width      = 150,
            };

            bonusRemove.Click += (s, a) =>
            {
                bonusId.Text = "";
                bonusX.Text  = "";
                bonusY.Text  = "";
            };
            grid.Widgets.Add(bonusRemove);

            var bonusShow = new TextButton
            {
                GridColumn = 5,
                GridRow    = 0,
                Text       = "Show/Set on map",
                Width      = 150,
            };

            bonusShow.Click += (s, a) =>
            {
                try
                {
                    if (!string.IsNullOrWhiteSpace(bonusId.Text))
                    {
                        int   id  = Convert.ToInt32(bonusId.Text);
                        Point?loc = null;
                        if (!string.IsNullOrWhiteSpace(bonusX.Text) && !string.IsNullOrWhiteSpace(bonusY.Text))
                        {
                            loc = new Point(Convert.ToInt32(bonusX.Text), Convert.ToInt32(bonusY.Text));
                        }

                        saveChanges();
                        _game.SetBonusLocation(id, loc);
                    }
                }
                catch { }
            };
            grid.Widgets.Add(bonusShow);

            // --- MOVING OBJECTS ---
            scroll = new ScrollViewer()
            {
                GridRow                 = 2,
                GridColumn              = 0,
                GridColumnSpan          = 6,
                GridRowSpan             = 14,
                ShowHorizontalScrollBar = false,
                ShowVerticalScrollBar   = true
            };
            movingObjects = new TextBox()
            {
                Multiline = true,
                Font      = Load.Monospace
            };
            scroll.Content = movingObjects;
            grid.Widgets.Add(scroll);

            Label labelShooter = new Label()
            {
                Id         = "labelShooter",
                Text       = "Shooter",
                GridColumn = 0,
                GridRow    = 16
            };

            grid.Widgets.Add(labelShooter);
            TextBox shooterId = new TextBox()
            {
                GridRow    = 16,
                GridColumn = 1,
                HintText   = "ID",
                Width      = 150
            };

            grid.Widgets.Add(shooterId);
            TextBox shooterMinDir = new TextBox()
            {
                GridRow    = 16,
                GridColumn = 2,
                HintText   = "MinDir",
                Width      = 150
            };

            grid.Widgets.Add(shooterMinDir);
            TextBox shooterMaxDir = new TextBox()
            {
                GridRow    = 16,
                GridColumn = 3,
                HintText   = "MaxDir",
                Width      = 150
            };

            grid.Widgets.Add(shooterMaxDir);
            TextBox shooterStartTime = new TextBox()
            {
                GridRow    = 16,
                GridColumn = 4,
                HintText   = "StartTime",
                Width      = 150
            };

            grid.Widgets.Add(shooterStartTime);
            TextBox shooterPeriod = new TextBox()
            {
                GridRow    = 16,
                GridColumn = 5,
                HintText   = "Period",
                Width      = 150
            };

            grid.Widgets.Add(shooterPeriod);
            var shooterAdd = new TextButton
            {
                GridColumn = 6,
                GridRow    = 16,
                Text       = "Add shooter",
                Width      = 150,
            };

            shooterAdd.Click += (s, a) =>
            {
                add4pToMovingObjectsBox(shooterId.Text, "S", shooterMinDir.Text, shooterMaxDir.Text, shooterStartTime.Text, shooterPeriod.Text,
                                        0, 0, 0, PhysicalMapLogic.ShooterInfo.DEFAULT_PERIOD);
            };
            grid.Widgets.Add(shooterAdd);

            Label labelPiston = new Label()
            {
                Id         = "labelPiston",
                Text       = "Piston",
                GridColumn = 0,
                GridRow    = 17
            };

            grid.Widgets.Add(labelPiston);
            TextBox pistonId = new TextBox()
            {
                GridRow    = 17,
                GridColumn = 1,
                HintText   = "ID",
                Width      = 150
            };

            grid.Widgets.Add(pistonId);
            TextBox pistonDir = new TextBox()
            {
                GridRow    = 17,
                GridColumn = 2,
                HintText   = "Dir",
                Width      = 150
            };

            grid.Widgets.Add(pistonDir);
            TextBox pistonStartTime = new TextBox()
            {
                GridRow    = 17,
                GridColumn = 3,
                HintText   = "StartTime",
                Width      = 150
            };

            grid.Widgets.Add(pistonStartTime);
            TextBox pistonWaitPeriod = new TextBox()
            {
                GridRow    = 17,
                GridColumn = 4,
                HintText   = "WaitPeriod",
                Width      = 150
            };

            grid.Widgets.Add(pistonWaitPeriod);
            TextBox pistonMovePeriod = new TextBox()
            {
                GridRow    = 17,
                GridColumn = 5,
                HintText   = "MovePeriod",
                Width      = 150
            };

            grid.Widgets.Add(pistonMovePeriod);
            var pistonAdd = new TextButton
            {
                GridColumn = 6,
                GridRow    = 17,
                Text       = "Add piston",
                Width      = 150,
            };

            pistonAdd.Click += (s, a) =>
            {
                add4pToMovingObjectsBox(pistonId.Text, "P", pistonDir.Text, pistonStartTime.Text, pistonWaitPeriod.Text, pistonMovePeriod.Text,
                                        0, 0, PhysicalMapLogic.PistonInfo.DEFAULT_WAIT_PERIOD, PhysicalMapLogic.PistonInfo.DEFAULT_MOVE_PERIOD);
            };
            grid.Widgets.Add(pistonAdd);

            Label labelRoller = new Label()
            {
                Id         = "labelRoller",
                Text       = "Roller",
                GridColumn = 0,
                GridRow    = 18
            };

            grid.Widgets.Add(labelRoller);
            TextBox rollerId = new TextBox()
            {
                GridRow    = 18,
                GridColumn = 1,
                HintText   = "ID",
                Width      = 150
            };

            grid.Widgets.Add(rollerId);
            TextBox rollerDir = new TextBox()
            {
                GridRow    = 18,
                GridColumn = 2,
                HintText   = "Dir",
                Width      = 150
            };

            grid.Widgets.Add(rollerDir);
            TextBox rollerStartTime = new TextBox()
            {
                GridRow    = 18,
                GridColumn = 3,
                HintText   = "StartTime",
                Width      = 150
            };

            grid.Widgets.Add(rollerStartTime);
            TextBox rollerPeriod = new TextBox()
            {
                GridRow    = 18,
                GridColumn = 4,
                HintText   = "Period",
                Width      = 150
            };

            grid.Widgets.Add(rollerPeriod);
            TextBox rollerSpeed = new TextBox()
            {
                GridRow    = 18,
                GridColumn = 5,
                HintText   = "Speed",
                Width      = 150
            };

            grid.Widgets.Add(rollerSpeed);
            var rollerAdd = new TextButton
            {
                GridColumn = 6,
                GridRow    = 18,
                Text       = "Add roller",
                Width      = 150,
            };

            rollerAdd.Click += (s, a) =>
            {
                add4pToMovingObjectsBox(rollerId.Text, "R", rollerDir.Text, rollerStartTime.Text, rollerPeriod.Text, rollerSpeed.Text,
                                        0, 0, 120, PhysicalMapLogic.RollerInfo.DEFAULT_SPEED);
            };
            grid.Widgets.Add(rollerAdd);

            Label labelCatcher = new Label()
            {
                Id         = "labelCatcher",
                Text       = "Roller Catcher",
                GridColumn = 0,
                GridRow    = 19
            };

            grid.Widgets.Add(labelCatcher);
            TextBox catcherId = new TextBox()
            {
                GridRow    = 19,
                GridColumn = 1,
                HintText   = "ID",
                Width      = 150
            };

            grid.Widgets.Add(catcherId);
            TextBox catcherDir = new TextBox()
            {
                GridRow    = 19,
                GridColumn = 2,
                HintText   = "Dir",
                Width      = 150
            };

            grid.Widgets.Add(catcherDir);
            var catcherAdd = new TextButton
            {
                GridColumn = 6,
                GridRow    = 19,
                Text       = "Add catcher",
                Width      = 150,
            };

            catcherAdd.Click += (s, a) =>
            {
                add1pToMovingObjectsBox(catcherId.Text, "C", catcherDir.Text, 0);
            };
            grid.Widgets.Add(catcherAdd);

            foreach (object o in _logic.MovingObjects)
            {
                int    id;
                string type;
                int[]  param;
                if (o is PhysicalMapLogic.CatcherInfo)
                {
                    PhysicalMapLogic.CatcherInfo ci = (PhysicalMapLogic.CatcherInfo)o;
                    id    = ci.ID;
                    type  = "C";
                    param = ci.Params();
                    add1pToMovingObjectsBox(id.ToString(), type, param[0].ToString(), 0);
                }
                else
                {
                    if (o is PhysicalMapLogic.ShooterInfo)
                    {
                        PhysicalMapLogic.ShooterInfo si = (PhysicalMapLogic.ShooterInfo)o;
                        id    = si.ID;
                        type  = "S";
                        param = si.Params();
                    }
                    else if (o is PhysicalMapLogic.PistonInfo)
                    {
                        PhysicalMapLogic.PistonInfo pi = (PhysicalMapLogic.PistonInfo)o;
                        id    = pi.ID;
                        type  = "P";
                        param = pi.Params();
                    }
                    else // if (o is PhysicalMapLogic.RollerInfo)
                    {
                        PhysicalMapLogic.RollerInfo ri = (PhysicalMapLogic.RollerInfo)o;
                        id    = ri.ID;
                        type  = "R";
                        param = ri.Params();
                    }
                    add4pToMovingObjectsBox(id.ToString(), type, param[0].ToString(), param[1].ToString(), param[2].ToString(),
                                            param[3].ToString(), 0, 0, 0, 0);
                }
            }

            // --- SUBMIT ---

            var buttonQuit = new TextButton
            {
                GridColumn = 1,
                GridRow    = 21,
                Text       = "Quit",
                Width      = 150,
            };

            buttonQuit.Click += (s, a) =>
            {
                saveChanges();
                _game.CloseSpecialItemMenu();
            };
            grid.Widgets.Add(buttonQuit);

            panel.Widgets.Add(grid);
            _desktop      = new Desktop();
            _desktop.Root = panel;
        }