Esempio n. 1
0
        public MidiImportDialog(string file)
        {
            filename   = file;
            trackNames = new MidiFileReader().GetTrackNames(file);

            if (trackNames != null)
            {
                var expNames = new string[ExpansionType.Count - 1];
                for (int i = ExpansionType.Start; i <= ExpansionType.End; i++)
                {
                    expNames[i - ExpansionType.Start] = ExpansionType.Names[i];
                }

                dialog = new PropertyDialog("MIDI Import", 500);
                dialog.Properties.AddDropDownList("Polyphony behavior:", MidiPolyphonyBehavior.Names, MidiPolyphonyBehavior.Names[0]);                                                                                          // 0
                dialog.Properties.AddNumericUpDown("Measures per pattern:", 2, 1, 4, "Maximum number of measures to put in a pattern. Might be less than this number if a tempo or time signature change happens.");            // 1
                dialog.Properties.AddCheckBox("Import velocity as volume:", true);                                                                                                                                              // 2
                dialog.Properties.AddCheckBox("Create PAL project:", false);                                                                                                                                                    // 3
                dialog.Properties.AddCheckBoxList("Expansions :", expNames, new bool[expNames.Length], null, 150);                                                                                                              // 4
                dialog.Properties.AddLabel(null, "Channel mapping:");                                                                                                                                                           // 5
                dialog.Properties.AddMultiColumnList(new[] { new ColumnDesc("NES Channel", 0.25f), new ColumnDesc("MIDI Source", 0.45f, GetSourceNames()), new ColumnDesc("Channel 10 Keys", 0.3f, ColumnType.Button) }, null); // 6
                dialog.Properties.AddLabel(null, "Disclaimer : The NES cannot play multiple notes on the same channel, any kind of polyphony is not supported. MIDI files must be properly curated. Moreover, only blank instruments will be created and will sound nothing like their MIDI counterparts.", true);
                dialog.Properties.Build();
                dialog.Properties.PropertyChanged += Properties_PropertyChanged;
                dialog.Properties.PropertyClicked += Properties_PropertyClicked;

                UpdateListView();
            }
        }
Esempio n. 2
0
        protected override void OnMouseDoubleClick(MouseEventArgs e)
        {
            base.OnMouseDoubleClick(e);

            bool left          = (e.Button & MouseButtons.Left) != 0;
            bool inPatternZone = GetPatternForCoord(e.X, e.Y, out int channelIdx, out int barIdx);

            if (left && inPatternZone)
            {
                var channel = Song.Channels[channelIdx];
                var pattern = channel.PatternInstances[barIdx];

                if (pattern != null)
                {
                    bool multiplePatternSelected = (maxSelectedChannelIdx != minSelectedChannelIdx) || (minSelectedPatternIdx != maxSelectedPatternIdx);

                    var dlg = new PropertyDialog(160)
                    {
                        StartPosition = FormStartPosition.Manual,
                        Location      = PointToScreen(new System.Drawing.Point(e.X, e.Y))
                    };

                    dlg.Properties.AddColoredString(pattern.Name, pattern.Color);
                    dlg.Properties.AddColor(pattern.Color);
                    dlg.Properties.Build();

                    if (dlg.ShowDialog() == DialogResult.OK)
                    {
                        App.UndoRedoManager.BeginTransaction(TransactionScope.Song, Song.Id);

                        var newName  = dlg.Properties.GetPropertyValue <string>(0);
                        var newColor = dlg.Properties.GetPropertyValue <System.Drawing.Color>(1);

                        if (multiplePatternSelected)
                        {
                            for (int i = minSelectedChannelIdx; i <= maxSelectedChannelIdx; i++)
                            {
                                for (int j = minSelectedPatternIdx; j <= maxSelectedPatternIdx; j++)
                                {
                                    Song.Channels[i].PatternInstances[j].Color = newColor;
                                }
                            }
                            App.UndoRedoManager.EndTransaction();
                        }
                        else if (Song.Channels[selectedChannel].RenamePattern(pattern, newName))
                        {
                            pattern.Color = newColor;
                            App.UndoRedoManager.EndTransaction();
                        }
                        else
                        {
                            App.UndoRedoManager.AbortTransaction();
                            SystemSounds.Beep.Play();
                        }

                        ConditionalInvalidate();
                    }
                }
            }
        }
Esempio n. 3
0
        public unsafe PasteSpecialDialog(Channel channel, bool mix = false, bool notes = true, int effectsMask = Note.EffectAllMask)
        {
            dialog = new PropertyDialog("Paste Special", 260);
            dialog.Properties.AddLabelCheckBox("Mix With Existing Notes", mix, 0, "When enabled, will preserve the existing note/effects and only paste if there was nothing already there."); // 0
            dialog.Properties.AddLabelCheckBox("Paste Notes", notes, 0, "When enabled, will paste the musical notes.");                                                                        // 1
            dialog.Properties.AddLabel(null, "Effects to paste:");                                                                                                                             // 2

            var effectList  = new List <string>();
            var checkedList = new List <bool>();

            for (int i = 0; i < Note.EffectCount; i++)
            {
                if (channel.ShouldDisplayEffect(i))
                {
                    checkToEffect.Add(i);
                    effectList.Add(Note.EffectNames[i]);
                    checkedList.Add((effectsMask & (1 << i)) != 0);
                }
            }

            dialog.Properties.AddCheckBoxList(PlatformUtils.IsMobile ? "Effects to paste" : null, effectList.ToArray(), checkedList.ToArray(), "Select the effects to paste."); // 3
            dialog.Properties.AddButton(PlatformUtils.IsMobile ? "Select All Effects" : null, "Select All");                                                                    // 4
            dialog.Properties.AddButton(PlatformUtils.IsMobile ? "De-select All Effects" : null, "Select None");                                                                // 5
            dialog.Properties.AddNumericUpDown("Repeat :", 1, 1, 32, "Number of times to repeat the paste");                                                                    // 6
            dialog.Properties.SetPropertyVisible(2, PlatformUtils.IsDesktop);
            dialog.Properties.Build();
            dialog.Properties.PropertyClicked += Properties_PropertyClicked;
        }
Esempio n. 4
0
        public unsafe DeleteSpecialDialog(Channel channel, bool notes = true, int effectsMask = Note.EffectAllMask)
        {
            dialog = new PropertyDialog("Delete Special", 260);
            dialog.Properties.AddLabelCheckBox("Delete Notes", notes, 0, "When enabled, will delete the musical notes."); // 0
            dialog.Properties.AddLabel(null, "Effects to paste:");                                                        // 1

            var effectList  = new List <string>();
            var checkedList = new List <bool>();

            for (int i = 0; i < Note.EffectCount; i++)
            {
                if (channel.ShouldDisplayEffect(i))
                {
                    checkToEffect.Add(i);
                    effectList.Add(Note.EffectNames[i]);
                    checkedList.Add((effectsMask & (1 << i)) != 0);
                }
            }


            dialog.Properties.AddCheckBoxList(PlatformUtils.IsMobile ? "Effects to delete" : null, effectList.ToArray(), checkedList.ToArray(), "Select the effects to delete."); // 2
            dialog.Properties.AddButton(PlatformUtils.IsMobile ? "Select All Effects" : null, "Select All");                                                                      // 3
            dialog.Properties.AddButton(PlatformUtils.IsMobile ? "De-select All Effects" : null, "Select None");                                                                  // 4
            dialog.Properties.SetPropertyVisible(1, PlatformUtils.IsDesktop);
            dialog.Properties.Build();
            dialog.Properties.PropertyClicked += Properties_PropertyClicked;
        }
Esempio n. 5
0
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            var info = FamiStudioForm.Instance != null ? FamiStudioForm.Instance.ActiveDialog as PropertyDialogActivityInfo : null;

            if (savedInstanceState != null || info == null)
            {
                Finish();
                return;
            }

            dlg = info.Dialog;
            dlg.CloseRequested += Dlg_CloseRequested;

            var appBarLayoutParams = new AppBarLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, DroidUtils.GetSizeAttributeInPixel(this, Android.Resource.Attribute.ActionBarSize));

            appBarLayoutParams.ScrollFlags = 0;

            toolbar = new AndroidX.AppCompat.Widget.Toolbar(new ContextThemeWrapper(this, Resource.Style.ToolbarTheme));
            toolbar.LayoutParameters = appBarLayoutParams;
            toolbar.SetTitleTextAppearance(this, Resource.Style.LightGrayTextMediumBold);
            SetSupportActionBar(toolbar);

            ActionBar actionBar = SupportActionBar;

            if (actionBar != null)
            {
                actionBar.SetDisplayHomeAsUpEnabled(true);
                actionBar.SetHomeButtonEnabled(true);
                actionBar.SetHomeAsUpIndicator(Android.Resource.Drawable.IcMenuCloseClearCancel);
                actionBar.Title = dlg.Title;
            }

            appBarLayout = new AppBarLayout(this);
            appBarLayout.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent);
            appBarLayout.AddView(toolbar);

            fragmentView = new FragmentContainerView(this);
            fragmentView.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
            fragmentView.Id = FragmentViewId;

            var scrollViewLayoutParams = new CoordinatorLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);

            scrollViewLayoutParams.Behavior = new AppBarLayout.ScrollingViewBehavior(this, null);

            scrollView = new NestedScrollView(new ContextThemeWrapper(this, Resource.Style.DarkBackgroundStyle));
            scrollView.LayoutParameters = scrollViewLayoutParams;
            scrollView.AddView(fragmentView);

            coordLayout = new CoordinatorLayout(this);
            coordLayout.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
            coordLayout.AddView(appBarLayout);
            coordLayout.AddView(scrollView);

            SetContentView(coordLayout);

            SupportFragmentManager.BeginTransaction().SetReorderingAllowed(true).Add(fragmentView.Id, dlg.Properties, "PropertyDialog").Commit();
        }
Esempio n. 6
0
        public unsafe LogDialog(FamiStudioForm parentForm)
        {
            this.parentForm = parentForm;

            dialog = new PropertyDialog(800, false);
            dialog.Properties.AddMultilineString(null, ""); // 0
            dialog.Properties.Build();
        }
Esempio n. 7
0
        public LogDialog(FamiStudioForm parentForm)
        {
            this.parentForm = parentForm;

            dialog = new PropertyDialog("Log", 800, false);
            dialog.Properties.AddMultilineTextBox(null, ""); // 0
            dialog.Properties.Build();
        }
Esempio n. 8
0
        public unsafe LogProgressDialog(FamiStudioForm parentForm)
        {
            this.parentForm = parentForm;

            dialog = new PropertyDialog("Log", 800, false);
            dialog.Properties.AddMultilineTextBox(null, ""); // 0
            dialog.Properties.AddProgressBar(null, 0.0f);    // 1
            dialog.Properties.Build();
        }
Esempio n. 9
0
        private void QwertyPage_PropertyClicked(PropertyPage props, ClickType click, int propIdx, int rowIdx, int colIdx)
        {
            if (propIdx == 1 && colIdx >= 2)
            {
                if (click == ClickType.Double)
                {
                    var dlg = new PropertyDialog("", 300, false, true, dialog);
                    dlg.Properties.AddLabel(null, "Press the new key or ESC to cancel.");
                    dlg.Properties.Build();

                    // TODO : Make this cross-platform.
#if FAMISTUDIO_WINDOWS
                    dlg.KeyDown += (sender, e) =>
                    {
                        if (PlatformUtils.KeyCodeToString((int)e.KeyCode) != null)
                        {
                            if (e.KeyCode != Keys.Escape)
                            {
                                AssignQwertyKey(rowIdx, colIdx - 2, (int)e.KeyCode);
                            }
                            dlg.Close();
                        }
                    };
#elif FAMISTUDIO_LINUX || FAMISTUDIO_MACOS
                    dlg.KeyPressEvent += (o, args) =>
                    {
                        // These 2 keys are used by the QWERTY input.
                        if (args.Event.Key != Gdk.Key.Tab &&
                            args.Event.Key != Gdk.Key.BackSpace &&
                            PlatformUtils.KeyCodeToString((int)args.Event.Key) != null)
                        {
                            if (args.Event.Key != Gdk.Key.Escape)
                            {
                                AssignQwertyKey(rowIdx, colIdx - 2, (int)args.Event.Key);
                            }
                            dlg.Accept();
                        }
                    };
#endif
                    dlg.ShowDialogAsync(null, (r) => { });

                    pages[(int)ConfigSection.QWERTY].UpdateMultiColumnList(1, GetQwertyMappingStrings());
                }
                else if (click == ClickType.Right)
                {
                    qwertyKeys[rowIdx, colIdx - 2] = -1;
                    pages[(int)ConfigSection.QWERTY].UpdateMultiColumnList(1, GetQwertyMappingStrings());
                }
            }
            else if (propIdx == 2 && click == ClickType.Button)
            {
                Array.Copy(Settings.DefaultQwertyKeys, qwertyKeys, Settings.DefaultQwertyKeys.Length);
                pages[(int)ConfigSection.QWERTY].UpdateMultiColumnList(1, GetQwertyMappingStrings());
            }
        }
Esempio n. 10
0
        private bool ShowConvertTempoDialog()
        {
            var messageDlg = new PropertyDialog(400, true, false);

            messageDlg.Properties.AddLabel(null, "You changed the BPM enough so that the number of frames in a note has changed.", true);                                                                                   // 0
            messageDlg.Properties.AddRadioButton(null, "Resize notes to reflect the new BPM. This is the most sensible option if you just want to change the tempo of the song.", true);                                    // 1
            messageDlg.Properties.AddRadioButton(null, "Leave the notes exactly where they are, just move the grid lines around the notes. This option is useful if you want to change how the notes are grouped.", false); // 2
            messageDlg.Properties.Build();
            messageDlg.ShowDialog(null);

            return(messageDlg.Properties.GetPropertyValue <bool>(1));
        }
Esempio n. 11
0
        public unsafe PasteSpecialDialog(Rectangle mainWinRect)
        {
            int width  = 200;
            int height = 300;
            int x      = mainWinRect.Left + (mainWinRect.Width - width) / 2;
            int y      = mainWinRect.Top + (mainWinRect.Height - height) / 2;

            dialog = new PropertyDialog(x, y, width, height);
            dialog.Properties.AddLabelBoolean("Paste Notes", true);
            dialog.Properties.AddLabelBoolean("Paste Volumes", true);
            dialog.Properties.AddLabelBoolean("Paste Effects", true);
            dialog.Properties.Build();
        }
Esempio n. 12
0
        private void MidiInstrumentDoubleClick(PropertyPage props, int propertyIndex, int itemIndex, int columnIndex)
        {
            Debug.Assert(midiInstrumentMapping != null);

            var dlg = new PropertyDialog(400, true, true, dialog);

            dlg.Properties.AddDropDownList("MIDI Instrument:", MidiFileReader.MidiInstrumentNames, MidiFileReader.MidiInstrumentNames[midiInstrumentMapping[itemIndex]]); // 0
            dlg.Properties.Build();

            if (dlg.ShowDialog(null) == DialogResult.OK)
            {
                midiInstrumentMapping[itemIndex] = dlg.Properties.GetSelectedIndex(0);
                UpdateMidiInstrumentMapping();
            }
        }
Esempio n. 13
0
        public NsfImportDialog(string file)
        {
            filename  = file;
            songNames = NsfFile.GetSongNames(filename);

            if (songNames != null && songNames.Length > 0)
            {
                dialog = new PropertyDialog(350);
                dialog.Properties.AddStringList("Song:", songNames, songNames[0]); // 0
                dialog.Properties.AddIntegerRange("Duration (s):", 120, 1, 600);   // 1
                dialog.Properties.AddIntegerRange("Pattern Length:", 256, 4, 256); // 2
                dialog.Properties.AddIntegerRange("Start frame:", 0, 0, 256);      // 3
                dialog.Properties.AddBoolean("Remove intro silence:", true);       // 4
                dialog.Properties.AddBoolean("Reverse DPCM bits:", false);         // 5
                dialog.Properties.Build();
            }
        }
Esempio n. 14
0
        void QwertyListDoubleClicked(PropertyPage props, int propertyIndex, int itemIndex, int columnIndex)
        {
            if (columnIndex < 2)
            {
                return;
            }

            var dlg = new PropertyDialog(300, false, true, dialog);

            dlg.Properties.AddLabel(null, "Press the new key or ESC to cancel.");
            dlg.Properties.Build();

            // TODO : Make this cross-platform.
#if FAMISTUDIO_WINDOWS
            dlg.KeyDown += (sender, e) =>
            {
                if (PlatformUtils.KeyCodeToString((int)e.KeyCode) != null)
                {
                    if (e.KeyCode != Keys.Escape)
                    {
                        AssignQwertyKey(itemIndex, columnIndex - 2, (int)e.KeyCode);
                    }
                    dlg.Close();
                }
            };
#else
            dlg.KeyPressEvent += (o, args) =>
            {
                // These 2 keys are used by the QWERTY input.
                if (args.Event.Key != Gdk.Key.Tab &&
                    args.Event.Key != Gdk.Key.BackSpace &&
                    PlatformUtils.KeyCodeToString((int)args.Event.Key) != null)
                {
                    if (args.Event.Key != Gdk.Key.Escape)
                    {
                        AssignQwertyKey(itemIndex, columnIndex - 2, (int)args.Event.Key);
                    }
                    dlg.Accept();
                }
            };
#endif
            dlg.ShowDialog(null);

            pages[(int)ConfigSection.QWERTY].UpdateMultiColumnList(1, GetQwertyMappingStrings());
        }
Esempio n. 15
0
        public unsafe LogProgressDialog(FamiStudioForm parentForm)
        {
            this.parentForm = parentForm;

            MainThread.InvokeOnMainThreadAsync(() =>
            {
                // HACK : We only use this for video export on mobile.
                dialog = new PropertyDialog("Exporting Video", 100, false);
                dialog.Properties.AddProgressBar("Export progress", 0.0f,
                                                 "Exporting videos may take a very long time, especially at high resolutions. " +
                                                 "Make sure FamiStudio remains open, clicking BACK or closing this window will abort the operation. " +
                                                 "FamiStudio is currently preventing the screen from going to sleep.\n\n" +
                                                 "Also please note that for reasons outside of our control, the video encoding quality on mobile " +
                                                 "is inferior to the desktop version of FamiStudio."); // 0
                dialog.Properties.AddLabel("Current Step", "");                                        // 1
                dialog.Properties.Build();
            });
        }
Esempio n. 16
0
        public NsfImportDialog(string file)
        {
            filename  = file;
            songNames = NsfFile.GetSongNames(filename);

            if (songNames != null && songNames.Length > 0)
            {
                dialog = new PropertyDialog("NSF Import", 350);
                dialog.Properties.AddDropDownList("Song:", songNames, songNames[0]); // 0
                dialog.Properties.AddNumericUpDown("Duration (s):", 120, 1, 600);    // 1
                dialog.Properties.AddNumericUpDown("Pattern Length:", 256, 4, 256);  // 2
                dialog.Properties.AddNumericUpDown("Start frame:", 0, 0, 256);       // 3
                dialog.Properties.AddCheckBox("Remove intro silence:", true);        // 4
                dialog.Properties.AddCheckBox("Reverse DPCM bits:", false);          // 5
                dialog.Properties.AddCheckBox("Preserve DPCM padding byte:", false); // 6
                dialog.Properties.Build();
            }
        }
Esempio n. 17
0
        public unsafe DeleteSpecialDialog(Channel channel, bool notes = true, int effectsMask = Note.EffectAllMask)
        {
            dialog = new PropertyDialog(200);
            dialog.Properties.AddLabelCheckBox("Delete Notes", notes);
            dialog.Properties.AddLabelCheckBox("Delete Effects", effectsMask == Note.EffectAllMask);

            for (int i = 0; i < Note.EffectCount; i++)
            {
                if (channel.SupportsEffect(i))
                {
                    propToEffect[dialog.Properties.PropertyCount] = i;
                    dialog.Properties.AddLabelCheckBox(Note.EffectNames[i], (effectsMask & (1 << i)) != 0, (int)(24 * RenderTheme.DialogScaling));
                }
            }

            dialog.Properties.Build();
            dialog.Properties.PropertyChanged += Properties_PropertyChanged;
            dialog.Name = "DeleteSpecialDialog";
        }
Esempio n. 18
0
        void MappingListDoubleClicked(PropertyPage props, int propertyIndex, int itemIndex, int columnIndex)
        {
            var src      = channelSources[itemIndex];
            var srcNames = GetSourceNames(src.type);
            var allowChannel10Mapping = src.type == MidiSourceType.Channel && src.index == 9;

            var dlg = new PropertyDialog(300, true, true, dialog);

            dlg.Properties.AddDropDownList("Source Type:", MidiSourceType.Names, MidiSourceType.Names[src.type]); // 0
            dlg.Properties.AddDropDownList("Source:", srcNames, srcNames[src.index]);                             // 1
            dlg.Properties.AddLabel(null, "Channel 10 keys:");                                                    // 2
            dlg.Properties.AddCheckBoxList(null, MidiFileReader.MidiDrumKeyNames, GetSelectedChannel10Keys(src)); // 3
            dlg.Properties.AddButton(null, "Select All", SelectClicked);                                          // 4
            dlg.Properties.AddButton(null, "Select None", SelectClicked);                                         // 5
            dlg.Properties.Build();
            dlg.Properties.PropertyChanged += MappingProperties_PropertyChanged;
            dlg.Properties.SetPropertyEnabled(1, src.type != MidiSourceType.None);
            dlg.Properties.SetPropertyEnabled(3, src.type != MidiSourceType.None && allowChannel10Mapping);
            dlg.Properties.SetPropertyEnabled(4, src.type != MidiSourceType.None && allowChannel10Mapping);
            dlg.Properties.SetPropertyEnabled(5, src.type != MidiSourceType.None && allowChannel10Mapping);

            if (dlg.ShowDialog(null) == DialogResult.OK)
            {
                var sourceType = MidiSourceType.GetValueForName(dlg.Properties.GetPropertyValue <string>(0));
                var sourceName = dlg.Properties.GetPropertyValue <string>(1);
                var keysBool   = dlg.Properties.GetPropertyValue <bool[]>(3);

                src.type  = sourceType;
                src.index = sourceType == MidiSourceType.None ? 0 : (Utils.ParseIntWithTrailingGarbage(sourceName.Substring(sourceType == MidiSourceType.Track ? 6 : 8)) - 1);
                src.keys  = 0ul;

                for (int i = 0; i < keysBool.Length; i++)
                {
                    if (keysBool[i])
                    {
                        src.keys |= (1ul << i);
                    }
                }

                UpdateListView();
            }
        }
Esempio n. 19
0
        private void Properties_PropertyClicked(PropertyPage props, ClickType click, int propIdx, int rowIdx, int colIdx)
        {
            if (click == ClickType.Button && colIdx == 2)
            {
                var src = channelSources[rowIdx];

                if (src.type == MidiSourceType.Channel && src.index == 9)
                {
                    var dlg = new PropertyDialog("MIDI Source", 300, true, true, dialog);
                    dlg.Properties.AddLabel(null, "Channel 10 keys:");                                                    // 0
                    dlg.Properties.AddCheckBoxList(null, MidiFileReader.MidiDrumKeyNames, GetSelectedChannel10Keys(src)); // 1
                    dlg.Properties.AddButton(null, "Select All");                                                         // 2
                    dlg.Properties.AddButton(null, "Select None");                                                        // 3
                    dlg.Properties.Build();
                    dlg.Properties.PropertyClicked += MappingProperties_PropertyClicked;

                    dlg.ShowDialogAsync(null, (r) =>
                    {
                        if (r == DialogResult.OK)
                        {
                            var keysBool = dlg.Properties.GetPropertyValue <bool[]>(1);

                            src.keys = 0ul;
                            for (int i = 0; i < keysBool.Length; i++)
                            {
                                if (keysBool[i])
                                {
                                    src.keys |= (1ul << i);
                                }
                            }

                            UpdateListView();
                        }
                    });
                }
                else
                {
                    PlatformUtils.Beep();
                }
            }
        }
Esempio n. 20
0
        public NsfImportDialog(string file, Rectangle mainWinRect)
        {
            int width  = 350;
            int height = 300;
            int x      = mainWinRect.Left + (mainWinRect.Width - width) / 2;
            int y      = mainWinRect.Top + (mainWinRect.Height - height) / 2;

            filename  = file;
            songNames = NsfFile.GetSongNames(filename);

            if (songNames != null && songNames.Length > 0)
            {
                dialog = new PropertyDialog(x, y, width, height);
                dialog.Properties.AddStringList("Song:", songNames, songNames[0]); // 0
                dialog.Properties.AddIntegerRange("Duration (s):", 120, 1, 600);   // 1
                dialog.Properties.AddIntegerRange("Pattern Length:", 256, 4, 256); // 2
                dialog.Properties.AddIntegerRange("Start frame:", 0, 0, 256);      // 3
                dialog.Properties.AddBoolean("Remove intro silence:", true);       // 4
                dialog.Properties.Build();
            }
        }
Esempio n. 21
0
        public unsafe PasteSpecialDialog(Channel channel, bool mix = false, bool notes = true, int effectsMask = Note.EffectAllMask)
        {
            dialog = new PropertyDialog(200);
            dialog.Properties.AddLabelCheckBox("Mix With Existing Notes", mix);
            dialog.Properties.AddLabelCheckBox("Paste Notes", notes);
            dialog.Properties.AddLabelCheckBox("Paste Effects", effectsMask == Note.EffectAllMask);

            for (int i = 0; i < Note.EffectCount; i++)
            {
                if (channel.SupportsEffect(i))
                {
                    propToEffect[dialog.Properties.PropertyCount] = i;
                    dialog.Properties.AddLabelCheckBox(Note.EffectNames[i], (effectsMask & (1 << i)) != 0, (int)(24 * RenderTheme.DialogScaling));
                }
            }

            dialog.Properties.AddIntegerRange("Repeat :", 1, 1, 32);
            dialog.Properties.Build();
            dialog.Properties.PropertyChanged += Properties_PropertyChanged;
            dialog.Name = "PasteSpecialDialog";
        }
Esempio n. 22
0
        public MidiImportDialog(string file)
        {
            filename   = file;
            trackNames = new MidiFileReader().GetTrackNames(file);

            if (trackNames != null)
            {
                dialog = new PropertyDialog(500);
                dialog.Properties.AddDropDownList("Expansion:", ExpansionType.Names, ExpansionType.Names[0]);                                                                                                       // 0
                dialog.Properties.AddDropDownList("Polyphony behavior:", MidiPolyphonyBehavior.Names, MidiPolyphonyBehavior.Names[0]);                                                                              // 1
                dialog.Properties.AddIntegerRange("Measures per pattern:", 2, 1, 4, "Maximum number of measures to put in a pattern. Might be less than this number if a tempo or time signature change happens."); // 2
                dialog.Properties.AddCheckBox("Import velocity as volume:", true);                                                                                                                                  // 3
                dialog.Properties.AddCheckBox("Create PAL project:", false);                                                                                                                                        // 4
                dialog.Properties.AddLabel(null, "Channel mapping (double-click on a row to change)");                                                                                                              // 5
                dialog.Properties.AddMultiColumnList(new[] { "NES Channel", "MIDI Source" }, null, MappingListDoubleClicked, null);                                                                                 // 6
                dialog.Properties.AddLabel(null, "Disclaimer : The NES cannot play multiple notes on the same channel, any kind of polyphony is not supported. MIDI files must be properly curated. Moreover, only blank instruments will be created and will sound nothing like their MIDI counterparts.", true);
                dialog.Properties.Build();
                dialog.Properties.PropertyChanged += Properties_PropertyChanged;

                UpdateListView();
            }
        }
Esempio n. 23
0
        private void ShowConvertTempoDialogAsync(bool conversionNeeded, Action <bool> callback)
        {
            if (conversionNeeded)
            {
                const string label = "You changed the BPM enough so that the number of frames in a note has changed. What do you want to do?";

                var messageDlg = new PropertyDialog("Tempo Conversion", 400, true, false);
                messageDlg.Properties.AddLabel(null, label, true);                                                                                                                                                                                               // 0
                messageDlg.Properties.AddRadioButton(PlatformUtils.IsMobile ? label : null, "Resize notes to reflect the new BPM. This is the most sensible option if you just want to change the tempo of the song.", true);                                    // 1
                messageDlg.Properties.AddRadioButton(PlatformUtils.IsMobile ? label : null, "Leave the notes exactly where they are, just move the grid lines around the notes. This option is useful if you want to change how the notes are grouped.", false); // 2
                messageDlg.Properties.SetPropertyVisible(0, PlatformUtils.IsDesktop);
                messageDlg.Properties.Build();
                messageDlg.ShowDialogAsync(null, (r) =>
                {
                    callback(messageDlg.Properties.GetPropertyValue <bool>(1));
                });
            }
            else
            {
                callback(false);
            }
        }
Esempio n. 24
0
        protected override void OnMouseDoubleClick(MouseEventArgs e)
        {
            base.OnMouseDoubleClick(e);

            var buttonIdx = GetButtonAtCoord(e.X, e.Y, out var subButtonType);

            if (buttonIdx >= 0)
            {
                var button = buttons[buttonIdx];

                if (button.type == ButtonType.ProjectSettings)
                {
                    var project = App.Project;

                    var dlg = new PropertyDialog(PointToScreen(new Point(e.X, e.Y)), 250, true);
                    dlg.Properties.AddString("Title :", project.Name, 31);          // 0
                    dlg.Properties.AddString("Author :", project.Author, 31);       // 1
                    dlg.Properties.AddString("Copyright :", project.Copyright, 31); // 2
                    dlg.Properties.Build();

                    if (dlg.ShowDialog() == DialogResult.OK)
                    {
                        App.UndoRedoManager.BeginTransaction(TransactionScope.Project);
                        project.Name      = dlg.Properties.GetPropertyValue <string>(0);
                        project.Author    = dlg.Properties.GetPropertyValue <string>(1);
                        project.Copyright = dlg.Properties.GetPropertyValue <string>(2);
                        App.UndoRedoManager.EndTransaction();
                        ConditionalInvalidate();
                    }
                }
                else if (button.type == ButtonType.Song)
                {
                    var song = button.song;

                    var dlg = new PropertyDialog(PointToScreen(new Point(e.X, e.Y)), 200, true);
                    dlg.Properties.AddColoredString(song.Name, song.Color);                                                // 0
                    dlg.Properties.AddIntegerRange("Tempo :", song.Tempo, 32, 255);                                        // 1
                    dlg.Properties.AddIntegerRange("Speed :", song.Speed, 1, 31);                                          // 2
                    dlg.Properties.AddIntegerRange("Pattern Length :", song.PatternLength, 16, 256);                       // 3
                    dlg.Properties.AddDomainRange("Bar Length :", GenerateBarLengths(song.PatternLength), song.BarLength); // 4
                    dlg.Properties.AddIntegerRange("Song Length :", song.Length, 1, 128);                                  // 5
                    dlg.Properties.AddColor(song.Color);                                                                   // 6
                    dlg.Properties.Build();
                    dlg.Properties.PropertyChanged += Properties_PropertyChanged;

                    if (dlg.ShowDialog() == DialogResult.OK)
                    {
                        App.UndoRedoManager.BeginTransaction(TransactionScope.Project);

                        App.Stop();
                        App.Seek(0);

                        var newName = dlg.Properties.GetPropertyValue <string>(0);

                        if (App.Project.RenameSong(song, newName))
                        {
                            song.Color         = dlg.Properties.GetPropertyValue <System.Drawing.Color>(6);
                            song.Tempo         = dlg.Properties.GetPropertyValue <int>(1);
                            song.Speed         = dlg.Properties.GetPropertyValue <int>(2);
                            song.Length        = dlg.Properties.GetPropertyValue <int>(5);
                            song.PatternLength = dlg.Properties.GetPropertyValue <int>(3);
                            song.BarLength     = dlg.Properties.GetPropertyValue <int>(4);
                            SongModified?.Invoke(song);
                            App.UndoRedoManager.EndTransaction();
                            RefreshButtons();
                        }
                        else
                        {
                            App.UndoRedoManager.AbortTransaction();
                            SystemSounds.Beep.Play();
                        }

                        ConditionalInvalidate();
                    }
                }
                else if (button.type == ButtonType.Instrument && button.instrument != null)
                {
                    var instrument = button.instrument;

                    if (subButtonType == SubButtonType.Max)
                    {
                        var dlg = new PropertyDialog(PointToScreen(new Point(e.X, e.Y)), 160, true);
                        dlg.Properties.AddColoredString(instrument.Name, instrument.Color);
                        dlg.Properties.AddColor(instrument.Color);
                        dlg.Properties.Build();

                        if (dlg.ShowDialog() == DialogResult.OK)
                        {
                            var newName = dlg.Properties.GetPropertyValue <string>(0);

                            App.UndoRedoManager.BeginTransaction(TransactionScope.Project);

                            if (App.Project.RenameInstrument(instrument, newName))
                            {
                                instrument.Color = dlg.Properties.GetPropertyValue <System.Drawing.Color>(1);
                                InstrumentColorChanged?.Invoke(instrument);
                                RefreshButtons();
                                ConditionalInvalidate();
                                App.UndoRedoManager.EndTransaction();
                            }
                            else
                            {
                                App.UndoRedoManager.AbortTransaction();
                                SystemSounds.Beep.Play();
                            }
                        }
                    }
                }
            }
        }
Esempio n. 25
0
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            bool left   = e.Button.HasFlag(MouseButtons.Left);
            bool middle = e.Button.HasFlag(MouseButtons.Middle) || (e.Button.HasFlag(MouseButtons.Left) && ModifierKeys.HasFlag(Keys.Alt));
            bool right  = e.Button.HasFlag(MouseButtons.Right);

            var buttonIdx = GetButtonAtCoord(e.X, e.Y, out var subButtonType);

            if (buttonIdx >= 0)
            {
                var button = buttons[buttonIdx];

                if (left)
                {
                    if (button.type == ButtonType.SongHeader)
                    {
                        if (subButtonType == SubButtonType.Add)
                        {
                            App.UndoRedoManager.BeginTransaction(TransactionScope.Project);
                            App.Project.CreateSong();
                            App.UndoRedoManager.EndTransaction();
                            RefreshButtons();
                            ConditionalInvalidate();
                        }
                    }
                    else if (button.type == ButtonType.Song)
                    {
                        if (button.song != selectedSong)
                        {
                            selectedSong = button.song;
                            SongSelected?.Invoke(selectedSong);
                            ConditionalInvalidate();
                        }
                    }
                    else if (button.type == ButtonType.InstrumentHeader)
                    {
                        if (subButtonType == SubButtonType.Add)
                        {
                            var instrumentType = Project.ExpansionNone;

                            if (App.Project.NeedsExpansionInstruments)
                            {
                                var expNames = new[] { Project.ExpansionNames[Project.ExpansionNone], App.Project.ExpansionAudioName };
                                var dlg      = new PropertyDialog(PointToScreen(new Point(e.X, e.Y)), 240, true);
                                dlg.Properties.AddStringList("Expansion:", expNames, Project.ExpansionNames[Project.ExpansionNone]);  // 0
                                dlg.Properties.Build();

                                if (dlg.ShowDialog() == DialogResult.OK)
                                {
                                    instrumentType = dlg.Properties.GetPropertyValue <string>(0) == Project.ExpansionNames[Project.ExpansionNone] ? Project.ExpansionNone : App.Project.ExpansionAudio;
                                }
                                else
                                {
                                    return;
                                }
                            }

                            App.UndoRedoManager.BeginTransaction(TransactionScope.Project);
                            App.Project.CreateInstrument(instrumentType);
                            App.UndoRedoManager.EndTransaction();
                            RefreshButtons();
                            ConditionalInvalidate();
                        }
                        if (subButtonType == SubButtonType.LoadInstrument)
                        {
                            var filename = PlatformUtils.ShowOpenFileDialog("Open File", "Fami Tracker Instrument (*.fti)|*.fti");
                            if (filename != null)
                            {
                                App.UndoRedoManager.BeginTransaction(TransactionScope.Project);
                                var instrument = FamitrackerInstrumentFile.CreateFromFile(App.Project, filename);
                                if (instrument == null)
                                {
                                    App.UndoRedoManager.AbortTransaction();
                                }
                                else
                                {
                                    App.UndoRedoManager.EndTransaction();
                                }
                            }

                            RefreshButtons();
                            ConditionalInvalidate();
                        }
                    }
                    else if (button.type == ButtonType.Instrument)
                    {
                        selectedInstrument = button.instrument;

                        if (selectedInstrument != null)
                        {
                            instrumentDrag = selectedInstrument;
                            mouseDragY     = e.Y;
                        }

                        if (subButtonType == SubButtonType.Volume)
                        {
                            InstrumentEdited?.Invoke(selectedInstrument, Envelope.Volume);
                            envelopeDragIdx = Envelope.Volume;
                        }
                        else if (subButtonType == SubButtonType.Pitch)
                        {
                            InstrumentEdited?.Invoke(selectedInstrument, Envelope.Pitch);
                            envelopeDragIdx = Envelope.Pitch;
                        }
                        else if (subButtonType == SubButtonType.Arpeggio)
                        {
                            InstrumentEdited?.Invoke(selectedInstrument, Envelope.Arpeggio);
                            envelopeDragIdx = Envelope.Arpeggio;
                        }
                        else if (subButtonType == SubButtonType.DPCM)
                        {
                            InstrumentEdited?.Invoke(selectedInstrument, Envelope.Max);
                        }
                        else if (subButtonType == SubButtonType.DutyCycle)
                        {
                            selectedInstrument.DutyCycle = (selectedInstrument.DutyCycle + 1) % selectedInstrument.DutyCycleRange;
                        }

                        InstrumentSelected?.Invoke(selectedInstrument);
                        ConditionalInvalidate();
                    }
                }
                else if (right)
                {
                    if (button.type == ButtonType.Song && App.Project.Songs.Count > 1)
                    {
                        var song = button.song;
                        if (PlatformUtils.MessageBox($"Are you sure you want to delete '{song.Name}' ?", "Delete song", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        {
                            bool selectNewSong = song == selectedSong;
                            App.Stop();
                            App.UndoRedoManager.BeginTransaction(TransactionScope.Project);
                            App.Project.DeleteSong(song);
                            if (selectNewSong)
                            {
                                selectedSong = App.Project.Songs[0];
                            }
                            SongSelected?.Invoke(selectedSong);
                            App.UndoRedoManager.EndTransaction();
                            RefreshButtons();
                            ConditionalInvalidate();
                        }
                    }
                    else if (button.type == ButtonType.Instrument && button.instrument != null)
                    {
                        var instrument = button.instrument;

                        if (subButtonType == SubButtonType.Arpeggio ||
                            subButtonType == SubButtonType.Pitch ||
                            subButtonType == SubButtonType.Volume)
                        {
                            int envType = Envelope.Volume;

                            switch (subButtonType)
                            {
                            case SubButtonType.Arpeggio: envType = Envelope.Arpeggio; break;

                            case SubButtonType.Pitch: envType = Envelope.Pitch;    break;
                            }

                            App.UndoRedoManager.BeginTransaction(TransactionScope.Instrument, instrument.Id);
                            instrument.Envelopes[envType].Length = 0;
                            App.UndoRedoManager.EndTransaction();
                            ConditionalInvalidate();
                        }
                        else if (subButtonType == SubButtonType.Max)
                        {
                            if (PlatformUtils.MessageBox($"Are you sure you want to delete '{instrument.Name}' ? All notes using this instrument will be deleted.", "Delete intrument", MessageBoxButtons.YesNo) == DialogResult.Yes)
                            {
                                bool selectNewInstrument = instrument == selectedInstrument;
                                App.StopInstrumentNoteAndWait();
                                App.UndoRedoManager.BeginTransaction(TransactionScope.Project);
                                App.Project.DeleteInstrument(instrument);
                                if (selectNewInstrument)
                                {
                                    selectedInstrument = App.Project.Instruments.Count > 0 ? App.Project.Instruments[0] : null;
                                }
                                SongSelected?.Invoke(selectedSong);
                                InstrumentDeleted?.Invoke(instrument);
                                App.UndoRedoManager.EndTransaction();
                                RefreshButtons();
                                ConditionalInvalidate();
                            }
                        }
                    }
                }
            }

            if (middle)
            {
                mouseLastY = e.Y;
            }
        }
Esempio n. 26
0
        public MobileProjectDialog(FamiStudio fami, string title, bool save, bool allowStorage = true)
        {
            famistudio = fami;
            saveMode   = save;

            dialog = new PropertyDialog(title, 100);
            dialog.SetVerb(save ? "Save" : "Open");

            // User files.
            var userProjectsDir = PlatformUtils.UserProjectsDirectory;

            Directory.CreateDirectory(userProjectsDir);

            userProjects.AddRange(Directory.GetFiles(userProjectsDir, "*.fms"));
            for (int i = 0; i < userProjects.Count; i++)
            {
                userProjects[i] = Path.GetFileNameWithoutExtension(userProjects[i]);
            }

            var hasUserProjects = userProjects != null && userProjects.Count > 0;
            var newProjectName  = (string)null;

            if (save)
            {
                userProjects.Add("Save to a New Project.");

                // Generate unique name
                for (int i = 1; ; i++)
                {
                    newProjectName = $"NewProject{i}";
                    if (userProjects.Find(p => p.ToLower() == newProjectName.ToLower()) == null)
                    {
                        break;
                    }
                }
            }
            else
            {
                // Demo songs.
                var assembly = Assembly.GetExecutingAssembly();
                var files    = assembly.GetManifestResourceNames();

                foreach (var file in files)
                {
                    if (file.ToLowerInvariant().EndsWith(".fms"))
                    {
                        // Filename will be in the for 'FamiStudio.Ducktales.fms'.
                        var trimmedFilename = Path.GetFileNameWithoutExtension(file.Substring(file.IndexOf('.') + 1));
                        demoProjects.Add(trimmedFilename);
                    }
                }
            }

            dialog.Properties.AddRadioButtonList("User Projects", userProjects.ToArray(), userProjects.Count - 1, save ? UserProjectSaveTooltip : UserProjectLoadTooltip); // 0

            if (save)
            {
                dialog.Properties.AddTextBox("New Project Name", newProjectName, 0, "Enter the name of the new project."); // 1
                dialog.Properties.AddButton("Delete Selected Project", "Delete");                                          // 2
                dialog.Properties.SetPropertyEnabled(1, true);
                dialog.Properties.SetPropertyEnabled(2, false);
                dialog.Properties.AddLabel("Note", "To export your project to your device's storage or to share them (email, messaging, etc.), please use the 'Share' option from the Export dialog."); // 3
            }
            else
            {
                dialog.Properties.AddRadioButtonList("Demo Projects", demoProjects.ToArray(), hasUserProjects ? -1 : 0, DemoProjectLoadTooltip); // 1
                if (allowStorage)
                {
                    dialog.Properties.AddButton("Open project from storage", "Open From Storage", StorageTooltip); // 2
                }
            }

            dialog.Properties.PropertyClicked += Properties_PropertyClicked;
            dialog.Properties.PropertyChanged += Properties_PropertyChanged;
            dialog.Properties.Build();
        }
Esempio n. 27
0
        protected override void OnMouseDoubleClick(MouseEventArgs e)
        {
            base.OnMouseDoubleClick(e);

            var buttonIdx = GetButtonAtCoord(e.X, e.Y, out var subButtonType);

            if (buttonIdx >= 0)
            {
                var button = buttons[buttonIdx];

                if (button.type == ButtonType.ProjectSettings)
                {
                    var project = App.Project;

                    var dlg = new PropertyDialog(PointToScreen(new Point(e.X, e.Y)), 280, true);
                    dlg.Properties.AddString("Title :", project.Name, 31);                                                // 0
                    dlg.Properties.AddString("Author :", project.Author, 31);                                             // 1
                    dlg.Properties.AddString("Copyright :", project.Copyright, 31);                                       // 2
                    dlg.Properties.AddStringList("Expansion Audio:", Project.ExpansionNames, project.ExpansionAudioName); // 3
                    dlg.Properties.Build();

                    if (dlg.ShowDialog() == DialogResult.OK)
                    {
                        App.UndoRedoManager.BeginTransaction(TransactionScope.Project);

                        project.Name      = dlg.Properties.GetPropertyValue <string>(0);
                        project.Author    = dlg.Properties.GetPropertyValue <string>(1);
                        project.Copyright = dlg.Properties.GetPropertyValue <string>(2);

                        var expansion = Array.IndexOf(Project.ExpansionNames, dlg.Properties.GetPropertyValue <string>(3));
                        if (expansion != project.ExpansionAudio)
                        {
                            if (project.ExpansionAudio == Project.ExpansionNone ||
                                PlatformUtils.MessageBox($"Switching expansion audio will delete all instruments and channels using the old expansion?", "Change expansion audio", MessageBoxButtons.YesNo) == DialogResult.Yes)
                            {
                                App.StopInstrumentPlayer();
                                project.SetExpansionAudio(expansion);
                                ExpansionAudioChanged?.Invoke();
                                App.StartInstrumentPlayer();
                                Reset();
                            }
                        }

                        App.UndoRedoManager.EndTransaction();
                        ConditionalInvalidate();
                    }
                }
                else if (button.type == ButtonType.Song)
                {
                    var song = button.song;

                    var dlg = new PropertyDialog(PointToScreen(new Point(e.X, e.Y)), 200, true);
                    dlg.Properties.AddColoredString(song.Name, song.Color);                                                // 0
                    dlg.Properties.AddIntegerRange("Tempo :", song.Tempo, 32, 255);                                        // 1
                    dlg.Properties.AddIntegerRange("Speed :", song.Speed, 1, 31);                                          // 2
                    dlg.Properties.AddIntegerRange("Pattern Length :", song.PatternLength, 16, 256);                       // 3
                    dlg.Properties.AddDomainRange("Bar Length :", GenerateBarLengths(song.PatternLength), song.BarLength); // 4
                    dlg.Properties.AddIntegerRange("Song Length :", song.Length, 1, 128);                                  // 5
                    dlg.Properties.AddColor(song.Color);                                                                   // 6
                    dlg.Properties.Build();
                    dlg.Properties.PropertyChanged += Properties_PropertyChanged;

                    if (dlg.ShowDialog() == DialogResult.OK)
                    {
                        App.UndoRedoManager.BeginTransaction(TransactionScope.Project);

                        App.Stop();
                        App.Seek(0);

                        var newName = dlg.Properties.GetPropertyValue <string>(0);

                        if (App.Project.RenameSong(song, newName))
                        {
                            song.Color = dlg.Properties.GetPropertyValue <System.Drawing.Color>(6);
                            song.Tempo = dlg.Properties.GetPropertyValue <int>(1);
                            song.Speed = dlg.Properties.GetPropertyValue <int>(2);
                            song.SetLength(dlg.Properties.GetPropertyValue <int>(5));
                            song.SetPatternLength(dlg.Properties.GetPropertyValue <int>(3));
                            song.SetBarLength(dlg.Properties.GetPropertyValue <int>(4));
                            SongModified?.Invoke(song);
                            App.UndoRedoManager.EndTransaction();
                            RefreshButtons();
                        }
                        else
                        {
                            App.UndoRedoManager.AbortTransaction();
                            SystemSounds.Beep.Play();
                        }

                        ConditionalInvalidate();
                    }
                }
                else if (button.type == ButtonType.Instrument && button.instrument != null)
                {
                    var instrument = button.instrument;

                    if (subButtonType == SubButtonType.Max)
                    {
                        var dlg = new PropertyDialog(PointToScreen(new Point(e.X, e.Y)), 160, true);
                        dlg.Properties.AddColoredString(instrument.Name, instrument.Color);                          // 0
                        dlg.Properties.AddColor(instrument.Color);                                                   // 1
                        dlg.Properties.AddBoolean("Relative pitch:", instrument.Envelopes[Envelope.Pitch].Relative); // 2
                        dlg.Properties.Build();

                        if (dlg.ShowDialog() == DialogResult.OK)
                        {
                            var newName = dlg.Properties.GetPropertyValue <string>(0);

                            App.UndoRedoManager.BeginTransaction(TransactionScope.Project);

                            if (App.Project.RenameInstrument(instrument, newName))
                            {
                                instrument.Color = dlg.Properties.GetPropertyValue <System.Drawing.Color>(1);
                                instrument.Envelopes[Envelope.Pitch].Relative = dlg.Properties.GetPropertyValue <bool>(2);
                                InstrumentColorChanged?.Invoke(instrument);
                                RefreshButtons();
                                ConditionalInvalidate();
                                App.UndoRedoManager.EndTransaction();
                            }
                            else
                            {
                                App.UndoRedoManager.AbortTransaction();
                                SystemSounds.Beep.Play();
                            }
                        }
                    }
                }
            }
        }