Пример #1
0
        internal void FinalRefreshAfterUpdate()
        {
            UpdateBackgroundGrid();

            PlaceWordStatus status = RecolorizeAllWords();

            viewModel.UpdateStatus(status);
        }
Пример #2
0
        private void RecolorizeWord(WordAndCanvas wac, PlaceWordStatus status)
        {
            bool isInSelection = m_Sel.WordAndCanvasList?.Contains(wac) ?? false;

            switch (status)
            {
            case PlaceWordStatus.Valid:
                if (isInSelection)
                {
                    wac.WordCanvas.SetColor(SelectedValidForeground, SelectedValidBackground);
                }
                else
                {
                    wac.WordCanvas.SetColor(NormalValidForeground, NormalValidBackground);
                }
                break;

            case PlaceWordStatus.TooClose:
                if (isInSelection)
                {
                    wac.WordCanvas.SetColor(SelectedTooCloseForeground, SelectedTooCloseBackground);
                }
                else
                {
                    wac.WordCanvas.SetColor(NormalTooCloseForeground, NormalTooCloseBackground);
                }
                break;

            case PlaceWordStatus.Invalid:
                if (isInSelection)
                {
                    wac.WordCanvas.SetColor(SelectedInvalidForeground, SelectedInvalidBackground);
                }
                else
                {
                    wac.WordCanvas.SetColor(NormalInvalidForeground, NormalInvalidBackground);
                }
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(status), status, null);
            }
        }
Пример #3
0
        internal PlaceWordStatus RecolorizeWordAndCanvasList(List <WordAndCanvas> wordAndCanvasList)
        {
            PlaceWordStatus result = PlaceWordStatus.Valid;

            foreach (WordAndCanvas wac in wordAndCanvasList)
            {
                var             layout = viewModel.GetLayoutExcludingWordPosition(wac.WordPosition);
                PlaceWordStatus status = EditorViewModel.CanPlaceWordInLayout(layout, wac);
                RecolorizeWord(wac, status);
                if (status == PlaceWordStatus.TooClose && result == PlaceWordStatus.Valid)
                {
                    result = PlaceWordStatus.TooClose;
                }
                else if (status == PlaceWordStatus.Invalid && result != PlaceWordStatus.Invalid)
                {
                    result = PlaceWordStatus.Invalid;
                }
            }
            return(result);
        }
Пример #4
0
        // Separate from MainGrid_MouseDown to reduce complexity
        private Action <Point> GetMouseDownMoveAction()
        {
            // Need a layout without moved word to validate placement
            m_FixedLayout = viewModel.GetLayoutExcludingWordPositionList(m_Sel.WordAndCanvasList.Select(wac => wac.WordPosition));

            // Reverse-transform mouse Grid coordinates into DrawingCanvas coordinates
            Matrix m = MainMatrixTransform.Matrix;

            m.Invert();     // To convert from screen transformed coordinates into ideal grid
                            // coordinates starting at (0,0) with a square side of UnitSize
            List <Vector> clickOffsetList = new List <Vector>(m_Sel.WordAndCanvasList.Count);

            clickOffsetList.AddRange(m_Sel.WordAndCanvasList
                                     .Select(wac => new Point((double)wac.WordCanvas.GetValue(Canvas.LeftProperty), (double)wac.WordCanvas.GetValue(Canvas.TopProperty)))
                                     .Select(canvasTopLeft => canvasTopLeft - m.Transform(previousMousePosition)));

            // When moving, point is current mouse in ideal grid coordinates
            return(point =>
            {
                // Just move selected WordCanvas
                for (int i = 0; i < m_Sel.WordAndCanvasList.Count; i++)
                {
                    double preciseTop = point.Y + clickOffsetList[i].Y;
                    double preciseLeft = point.X + clickOffsetList[i].X;

                    WordCanvas wc = m_Sel.WordAndCanvasList[i].WordCanvas;
                    wc.SetValue(Canvas.TopProperty, preciseTop);
                    wc.SetValue(Canvas.LeftProperty, preciseLeft);

                    // Round position to closest square on the grid
                    int top = (int)Math.Floor(preciseTop / UnitSize + 0.5);
                    int left = (int)Math.Floor(preciseLeft / UnitSize + 0.5);

                    PlaceWordStatus status = EditorViewModel.CanPlaceWordAtPositionInLayout(m_FixedLayout, m_Sel.WordAndCanvasList[i].WordPosition, new PositionOrientation(top, left, m_Sel.WordAndCanvasList[i].WordPosition.IsVertical));
                    RecolorizeWord(m_Sel.WordAndCanvasList[i], status);
                }
            });
        }
Пример #5
0
        // Helper to reduce cyclomatic complexity
        private PlaceWordStatus CanPlaceHorizontalWord(WordPosition wordPosition, bool withTooClose)
        {
            PlaceWordStatus result = PlaceWordStatus.Valid;
            int             row    = wordPosition.StartRow;
            int             column = wordPosition.StartColumn;

            // Free cell left
            if (IsOccupiedSquare(row, column - 1))
            {
                if (withTooClose)
                {
                    result = PlaceWordStatus.TooClose;
                }
                else
                {
                    return(PlaceWordStatus.Invalid);
                }
            }
            // Free cell right
            if (IsOccupiedSquare(row, column + wordPosition.Word.Length))
            {
                if (withTooClose)
                {
                    result = PlaceWordStatus.TooClose;
                }
                else
                {
                    return(PlaceWordStatus.Invalid);
                }
            }

            for (int i = 0; i < wordPosition.Word.Length; i++)
            {
                char l = GetLetter(row, column + i);
                if (l == wordPosition.Word[i])
                {
                    // It's OK to already have a matching letter only if it only belongs to a crossing word (of opposite direction)
                    foreach (WordPosition loop in GetWordPositionsFromSquare(row, column + i))
                    {
                        if (loop.IsVertical == wordPosition.IsVertical)
                        {
                            return(PlaceWordStatus.Invalid);
                        }
                    }
                }
                else
                {
                    // We need an empty cell for this letter
                    if (l != '\0')
                    {
                        return(PlaceWordStatus.Invalid);
                    }

                    // We need a free cell above and below, or else we're too close
                    if (IsOccupiedSquare(row - 1, column + i) || IsOccupiedSquare(row + 1, column + i))
                    {
                        if (withTooClose)
                        {
                            result = PlaceWordStatus.TooClose;
                        }
                        else
                        {
                            return(PlaceWordStatus.Invalid);
                        }
                    }
                }
            }

            return(result);
        }