예제 #1
0
        public static Game CreateGame(this PgnEditor pgnEditor, PgnGameSyntax gameSyntax)
        {
            var game = new Game();

            foreach (PgnPlySyntax ply in gameSyntax.PlyList.Plies)
            {
                // For now, invalidate the remainder of the game if seeing a null or unrecognized move.
                if (ply.Move == null)
                {
                    break;
                }
                PgnMoveSyntax moveSyntax = ply.Move.PlyContentNode.ContentNode;
                if (moveSyntax.IsUnrecognizedMove)
                {
                    break;
                }

                var      sideToMove = game.SideToMove;
                MoveInfo moveInfo   = GetMoveInfo(game, pgnEditor.GetTextRange(moveSyntax.AbsoluteStart, moveSyntax.Length), sideToMove);
                game.TryMakeMove(ref moveInfo, true);

                // Also invalidate on illegal move.
                if (sideToMove == game.SideToMove)
                {
                    break;
                }
            }

            return(game);
        }
 public UIActionState TryOpenNewPlayingBoard(PgnEditor pgnEditor, bool perform)
 {
     if (perform)
     {
         OpenChessBoard(pgnEditor, new Chess.Game(), null, null, null, null).EnsureActivated();
     }
     return(UIActionVisibility.Enabled);
 }
예제 #3
0
        internal void RemovePgnEditor(string key, PgnEditor pgnEditor)
        {
            // Remove from the list it's currently in, and remove the list from the index altogether once it's empty.
            var pgnEditors = OpenPgnEditors[key ?? string.Empty];

            pgnEditors.Remove(pgnEditor);
            if (pgnEditors.Count == 0)
            {
                OpenPgnEditors.Remove(key ?? string.Empty);
            }
        }
예제 #4
0
        private PgnEditor NewPgnEditor(string normalizedPgnFileName, bool isReadOnly)
        {
            var pgnFile = WorkingCopyTextFile.Open(normalizedPgnFileName, null);

            var pgnEditor = new PgnEditor(
                isReadOnly ? SyntaxEditorCodeAccessOption.ReadOnly : SyntaxEditorCodeAccessOption.Default,
                PgnSyntaxDescriptor.Instance,
                pgnFile,
                SettingKeys.PgnZoom);

            pgnEditor.BindAction(OpenNewPlayingBoard, perform => TryOpenNewPlayingBoard(pgnEditor, perform));
            pgnEditor.BindAction(OpenGame, perform => TryOpenGame(pgnEditor, perform));
            pgnEditor.BindActions(pgnEditor.StandardSyntaxEditorUIActionBindings);
            UIMenu.AddTo(pgnEditor);

            pgnEditor.DoubleClick += (_, __) => TryOpenGame(pgnEditor, true);

            PgnStyleSelector.InitializeStyles(pgnEditor);

            // Don't index read-only pgn editors.
            if (!isReadOnly)
            {
                Program.MainForm.AddPgnEditor(normalizedPgnFileName, pgnEditor);

                // Re-index when pgnFile.OpenTextFilePath changes.
                pgnFile.OpenTextFilePathChanged += (_, e) =>
                {
                    Program.MainForm.RemovePgnEditor(e.PreviousOpenTextFilePath, pgnEditor);
                    Program.MainForm.AddPgnEditor(pgnFile.OpenTextFilePath, pgnEditor);
                };

                // Remove from index when pgnEditor is closed.
                pgnEditor.Disposed += (_, __) =>
                {
                    Program.MainForm.RemovePgnEditor(pgnFile.OpenTextFilePath, pgnEditor);
                };
            }

            // Open as new tab page.
            DockedControl.TabPages.Add(new MdiTabPage <PgnEditor>(pgnEditor));

            return(pgnEditor);
        }
예제 #5
0
        internal void OpenCommandLineArgs(string[] commandLineArgs, bool isReadOnly = false)
        {
            PgnEditor lastOpenedPgnEditor = null;

            // Interpret each command line argument as a file to open.
            commandLineArgs.ForEach(pgnFileName =>
            {
                // Catch exception for each open action individually.
                try
                {
                    lastOpenedPgnEditor = NewOrExistingPgnEditor(pgnFileName, isReadOnly);
                }
                catch (Exception exception)
                {
                    // For now, show the exception to the user.
                    // Maybe user has no access to the path, or the given file name is not a valid.
                    // TODO: analyze what error conditions can occur and handle them appropriately.
                    MessageBox.Show(
                        $"Attempt to open code file '{pgnFileName}' failed with message: '{exception.Message}'",
                        pgnFileName,
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                }
            });

            if (lastOpenedPgnEditor != null)
            {
                // Only activate the last opened PGN editor.
                lastOpenedPgnEditor.EnsureActivated();
            }
            else if (DockedControl.TabPages.Count == 0)
            {
                // Open default new untitled file.
                OpenNewPgnEditor();
            }
            else
            {
                // If no arguments were given, just activate the form.
                DockedControl.EnsureActivated();
            }
        }
예제 #6
0
        public static PgnGameSyntax GameAtOrBeforePosition(this PgnEditor pgnEditor, int position)
        {
            // We're looking for the symbols before and after the position.
            // If the position is right at the edge between two games, return the previous game; any trivia is part of the next game,
            // and so it's more likely we're closer to the previous game.
            // Hence, take the first symbol from the enumeration.
            if (pgnEditor.SyntaxTree != null &&
                pgnEditor.SyntaxTree.GameListSyntax.TerminalSymbolsInRange(position - 1, 2).Any(out IPgnSymbol symbolAtCursor))
            {
                PgnSyntax pgnSyntax = symbolAtCursor.ToSyntax();
                while (pgnSyntax != null)
                {
                    pgnSyntax = pgnSyntax.ParentSyntax;
                    if (pgnSyntax is PgnGameSyntax pgnGameSyntax)
                    {
                        return(pgnGameSyntax);
                    }
                }
            }

            return(null);
        }
예제 #7
0
 public override Style GetStyle(PgnEditor pgnEditor, IPgnSymbol terminalSymbol)
 => PgnStyleSelector.Instance.Visit(terminalSymbol, pgnEditor);
예제 #8
0
 internal void AddPgnEditor(string key, PgnEditor pgnEditor)
 {
     OpenPgnEditors.GetOrAdd(key ?? string.Empty, _ => new List <PgnEditor>()).Add(pgnEditor);
 }
예제 #9
0
        /// <summary>
        /// Opens a chess board for a certain game at a current position.
        /// </summary>
        private StandardChessBoard OpenChessBoard(PgnEditor ownerPgnEditor, Chess.Game game, string white, string black, string whiteElo, string blackElo)
        {
            var newChessBoard = new StandardChessBoard
            {
                Game        = game,
                PieceImages = PieceImages.ImageArray
            };

            newChessBoard.PlayingBoard.ForegroundImageRelativeSize = 0.9f;

            newChessBoard.PlayingBoard.BindActions(new UIActionBindings
            {
                { StandardChessBoard.GotoStart, newChessBoard.TryGotoStart },
                { StandardChessBoard.GotoFirstMove, newChessBoard.TryGotoFirstMove },
                { StandardChessBoard.FastNavigateBackward, newChessBoard.TryFastNavigateBackward },
                { StandardChessBoard.GotoPreviousMove, newChessBoard.TryGotoPreviousMove },
                { StandardChessBoard.GotoNextMove, newChessBoard.TryGotoNextMove },
                { StandardChessBoard.FastNavigateForward, newChessBoard.TryFastNavigateForward },
                { StandardChessBoard.GotoLastMove, newChessBoard.TryGotoLastMove },
                { StandardChessBoard.GotoEnd, newChessBoard.TryGotoEnd },

                { StandardChessBoard.GotoPreviousVariation, newChessBoard.TryGotoPreviousVariation },
                { StandardChessBoard.GotoNextVariation, newChessBoard.TryGotoNextVariation },

                { StandardChessBoard.PromoteActiveVariation, newChessBoard.TryPromoteActiveVariation },
                { StandardChessBoard.DemoteActiveVariation, newChessBoard.TryDemoteActiveVariation },
                { StandardChessBoard.BreakActiveVariation, newChessBoard.TryBreakActiveVariation },
                { StandardChessBoard.DeleteActiveVariation, newChessBoard.TryDeleteActiveVariation },

                { StandardChessBoard.FlipBoard, newChessBoard.TryFlipBoard },
                { StandardChessBoard.TakeScreenshot, newChessBoard.TryTakeScreenshot },

                { SharedUIAction.ZoomIn, newChessBoard.TryZoomIn },
                { SharedUIAction.ZoomOut, newChessBoard.TryZoomOut },
            });

            UIMenu.AddTo(newChessBoard.PlayingBoard);

            if (string.IsNullOrWhiteSpace(white))
            {
                white = "?";
            }
            if (string.IsNullOrWhiteSpace(black))
            {
                black = "?";
            }
            if (!string.IsNullOrWhiteSpace(whiteElo))
            {
                white = $"{white} ({whiteElo})";
            }
            if (!string.IsNullOrWhiteSpace(blackElo))
            {
                black = $"{black} ({blackElo})";
            }

            newChessBoard.DockProperties.CaptionText   = $"{white} - {black}";
            newChessBoard.DockProperties.CaptionHeight = 24;
            newChessBoard.DockProperties.Icon          = Session.Current.ApplicationIcon;

            var newChessBoardForm = new MenuCaptionBarForm <StandardChessBoard>(newChessBoard)
            {
                Owner       = ownerPgnEditor.FindForm(),
                MaximizeBox = false,
                ClientSize  = new Size(400, 400),
            };

            StandardChessBoard.ConstrainClientSize(newChessBoardForm);

            return(newChessBoard);
        }
        public UIActionState TryOpenGame(PgnEditor pgnEditor, bool perform)
        {
            PgnGameSyntax gameSyntax = pgnEditor.GameAtOrBeforePosition(pgnEditor.SelectionStart);

            if (gameSyntax == null)
            {
                return(UIActionVisibility.Disabled);
            }

            if (perform)
            {
                StandardChessBoard chessBoard = OpenGames.GetOrAdd(gameSyntax, key =>
                {
                    const string WhiteTagName    = "White";
                    const string BlackTagName    = "Black";
                    const string WhiteEloTagName = "WhiteElo";
                    const string BlackEloTagName = "BlackElo";

                    // Look in the game's tags for these 4 values.
                    string white    = null;
                    string black    = null;
                    string whiteElo = null;
                    string blackElo = null;

                    foreach (PgnTagPairSyntax tagPairSyntax in gameSyntax.TagSection.TagPairNodes)
                    {
                        string tagName  = null;
                        string tagValue = null;

                        foreach (PgnTagElementSyntax tagElementSyntax in tagPairSyntax.TagElementNodes.Select(x => x.ContentNode))
                        {
                            if (tagElementSyntax is PgnTagNameSyntax tagNameSyntax)
                            {
                                tagName = pgnEditor.GetTextRange(tagNameSyntax.AbsoluteStart, tagNameSyntax.Length);
                            }
                            else if (tagElementSyntax is PgnTagValueSyntax tagValueSyntax)
                            {
                                tagValue = tagValueSyntax.Value;
                            }
                        }

                        if (tagName != null && tagValue != null)
                        {
                            if (tagName.Equals(WhiteTagName, StringComparison.OrdinalIgnoreCase))
                            {
                                white = tagValue;
                            }
                            else if (tagName.Equals(BlackTagName, StringComparison.OrdinalIgnoreCase))
                            {
                                black = tagValue;
                            }
                            else if (tagName.Equals(WhiteEloTagName, StringComparison.OrdinalIgnoreCase))
                            {
                                whiteElo = tagValue;
                            }
                            else if (tagName.Equals(BlackEloTagName, StringComparison.OrdinalIgnoreCase))
                            {
                                blackElo = tagValue;
                            }
                        }
                    }

                    StandardChessBoard newChessBoard = OpenChessBoard(pgnEditor, pgnEditor.CreateGame(gameSyntax), white, black, whiteElo, blackElo);
                    newChessBoard.Disposed          += (_, __) => OpenGames.Remove(gameSyntax);
                    return(newChessBoard);
                });

                chessBoard.EnsureActivated();
            }

            return(UIActionVisibility.Enabled);
        }