예제 #1
0
        /// <summary>
        /// Sets the width and height of the base symbol based on the symbol code,
        /// as well as the top and left properties,
        /// checking first to see if the canvas already has such limits.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code for the symbol.
        /// </param>
        private void SetLimits(string symbolCode)
        {
            this.SetValue(Canvas.TopProperty, 0.0);
            this.SetValue(Canvas.LeftProperty, 0.0);

            if (this.ApplyTemplate())
            {
                if (VisualTreeHelper.GetChild(this, 0) is Canvas canvas &&
                    !double.IsNaN(canvas.Height))
                {
                    this.Height = canvas.Height;
                    this.Width  = canvas.Width;
                    this.SetValue(Canvas.TopProperty, canvas.GetValue(Canvas.TopProperty));
                    this.SetValue(Canvas.LeftProperty, canvas.GetValue(Canvas.LeftProperty));
                    return;
                }
            }

            // Need to handle those symbols that still don't have bounds
            Rect rect = SymbolData.GetBounds(symbolCode);

            if (!rect.IsEmpty)
            {
                this.Height = rect.Height;
                this.Width  = rect.Width;
            }
            else
            {
                this.Height = this.Width = 0.0;
            }
        }
예제 #2
0
        /// <summary>
        /// Generate the Joker, Faker, or "eXercise" character.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code for which to generate the large character string.
        /// </param>
        /// <param name="labels">
        /// A dictionary of the labels to be drawn.
        /// </param>
        /// <param name="style">
        /// The style to apply to the labels.
        /// </param>
        /// <returns>
        /// The TextBlock that incorporates the labels.
        /// </returns>
        internal static TextBlock GenerateJokerFakerExercise(string symbolCode, IDictionary <string, string> labels, Style style)
        {
            // Check for matching code
            char theChar = StandardIdentity.GetExerciseAmplifyingDescriptor(symbolCode);

            if (theChar == (char)0)
            {
                return(null);
            }
#if WINDOWS_UWP
            string theString = theChar.ToString();
#else
            string theString = theChar.ToString(Culture);
#endif
            if (labels != null && labels.ContainsKey("F"))
            {
                theString += " " + labels["F"];
            }

            Rect r  = SymbolData.GetBounds(symbolCode);
            var  tb = new TextBlock
            {
                Style = style, // BigLabels,
                Text  = theString
            };
            tb.FindTextExtent();
            tb.SetValue(Canvas.TopProperty, r.Top - tb.Height);
            tb.SetValue(Canvas.LeftProperty, r.Right);
            return(tb);
        }
예제 #3
0
        /// <summary>
        /// Generate the right labels for the symbol.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code for which to generate the labels.
        /// </param>
        /// <param name="labels">
        /// The dictionary of labels to generate.
        /// </param>
        /// <param name="style">
        /// The style with which to render the labels.
        /// </param>
        /// <returns>
        /// A TextBlock that represents the rendered labels.
        /// </returns>
        internal static TextBlock GenerateRight(string symbolCode, IDictionary <string, string> labels, Style style)
        {
            // Pick off the left-oriented strings and write them out
            if (labels == null)
            {
                return(null);
            }

            var right = new TextBlock {
                Style = style                         /*RightLabels*/
            };
            bool gotLine = false;

            // If we have an X, J, or K modifier character, skip label F because it is already written out.
            if (StandardIdentity.GetExerciseAmplifyingDescriptor(symbolCode) != (char)0)
            {
                ProcessLabels(labels, false, new[] { string.Empty }, right, ref gotLine);
            }
            else
            {
                ProcessLabels(labels, false, new[] { "F" }, right, ref gotLine);
            }

            var height = gotLine ? (double)right.GetValue(TextBlock.LineHeightProperty) : 0.0;

            // At this point we need to process the remaining labels as if each row has a label.
            // Otherwise some label lines may appear in the wrong position
            // if other label lines are empty.
            // Setting "gotLine" to true forces a new line for each of the label lines.
            // More complicated logic might consider the height of the text block, prior to
            // the elimination of the empty lines.
            gotLine = true;

            ProcessLabels(labels, false, new[] { "G" }, right, ref gotLine);
            ProcessLabels(labels, false, new[] { "H" }, right, ref gotLine);
            ProcessLabels(labels, false, new[] { "M" }, right, ref gotLine);
            ProcessLabels(labels, true, new[] { "J", "K", "L", "N", "P" }, right, ref gotLine);
            TruncateNewLines(right);

            Rect b = SymbolData.GetBounds(symbolCode);

            SetTopLeft(right, b.Right + (height / 5.0), b.Top - height);
            return(right);
        }
예제 #4
0
        /// <summary>
        /// Returns the arrow representing a direction of travel for a mil symbol
        /// </summary>
        /// <param name="symbolCode">Code for the mil symbol</param>
        /// <param name="labels">The labels for the symbol, we're looking for "Q"</param>
        /// <param name="extraOffset">An extra offset for tactical graphics</param>
        /// <returns>The arrow shape representing the direction of travel</returns>
        internal static Shape GenerateQ(
            string symbolCode,
            IDictionary <string, string> labels,
            double extraOffset)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return(null);
            }

            string q;

            if (!labels.TryGetValue("Q", out q))
            {
                return(null);
            }

            double angle;

            if (!double.TryParse(q, out angle))
            {
                return(null);
            }

            double off = 0.0;

            if (CategoryBattleDimension.GetCode(symbolCode) == CategoryBattleDimension.BdGround)
            {
                off = SymbolData.GetBounds(symbolCode).Bottom;
            }

            off += extraOffset;
            return(new Path
            {
                Style = SymbolData.GetStyle("BS10"),
                Data = new PathGeometry
                {
                    Figures = new PathFigureCollection
                    {
                        GenerateArrowPoints(off, angle)
                    }
                }
            });
        }
예제 #5
0
        /// <summary>
        /// Generate the left labels for the symbol.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code for which to generate the labels.
        /// </param>
        /// <param name="labels">
        /// The dictionary of labels to generate.
        /// </param>
        /// <param name="style">
        /// The style with which to render the labels.
        /// </param>
        /// <returns>
        /// A TextBlock that represents the rendered labels.
        /// </returns>
        internal static TextBlock GenerateLeft(string symbolCode, IDictionary <string, string> labels, Style style)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return(null);
            }

            // Pick off the left-oriented strings and write them out
            if (labels == null)
            {
                return(null);
            }

            var left = new TextBlock {
                Style = style                        /*LeftLabels*/
            };

            bool gotLine = false;

            ProcessLabels(labels, false, new[] { "W" }, left, ref gotLine);
            var height = gotLine ? (double)left.GetValue(TextBlock.LineHeightProperty) : 0.0;

            // At this point we need to process the remaining labels as if each row has a label.
            // Otherwise some label lines may appear in the wrong position
            // if other label lines are empty.
            // Setting "gotLine" to true forces a new line for each of the label lines.
            // More complicated logic might consider the height of the text block, prior to
            // the elimination of the empty lines.
            gotLine = true;

            ProcessLabels(labels, false, new[] { "X", "Y" }, left, ref gotLine);
            ProcessLabels(labels, false, new[] { "V" }, left, ref gotLine);
            ProcessLabels(labels, false, new[] { "T" }, left, ref gotLine);
            ProcessLabels(labels, true, new[] { "Z" }, left, ref gotLine);
            TruncateNewLines(left);

            Rect b = SymbolData.GetBounds(symbolCode);

            left.FindTextExtent();
            SetTopLeft(left, b.Left - left.Width - 10, b.Top - height);
            return(left); // we're only doing this to support unit test
        }
예제 #6
0
        /// <summary>
        /// Generates barge mobility object.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code containing the mobility indicator for which to create a mobility Shape.
        /// </param>
        /// <returns>
        /// A Shape object representing the mobility object.
        /// </returns>
        public static Shape GenerateMobility(string symbolCode)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return(null);
            }

            if (!Mobility.IsMobility(symbolCode))
            {
                return(null);
            }

            Rect         b      = SymbolData.GetBounds(symbolCode);
            double       bottom = b.Bottom + HalfWidth;
            bool         flat   = SymbolData.IsBaseFlat(symbolCode);
            const double X      = End - Rad;

            switch (Mobility.GetCode(symbolCode))
            {
            case Mobility.WheeledLimited:
                return(GenerateWheels(new[] { -X, X }, bottom));

            case Mobility.WheeledCrossCountry:
                return(GenerateWheels(new[] { -X, 0, X }, bottom));

            case Mobility.Tracked:
                return(GenerateTracked(bottom));

            case Mobility.WheeledTracked:
                return(GenerateWheeledTracked(bottom));

            case Mobility.Towed:
                if (flat)
                {
                    bottom += Rad;
                }

                return(GenerateTowed(bottom));

            case Mobility.Railway:
                return(GenerateWheels(new[] { -X, -X + TwoRad, X - TwoRad, X }, bottom));

            case Mobility.OverSnow:
                if (flat)
                {
                    bottom += TwoRad;
                }

                return(GenerateOverSnow(bottom));

            case Mobility.Sled:
                if (!flat)
                {
                    bottom -= TwoRad;
                }

                return(GenerateSled(bottom));

            case Mobility.PackAnimals:
                return(GeneratePackAnimals(bottom));

            case Mobility.Barge:
                return(GenerateBarge(bottom));

            case Mobility.Amphibious:
                return(GenerateAmphibious(bottom));

            case Mobility.TowedArrayShort:
                return(GenerateArray(new[] { -End - TwoSqr, 0.0, End + TwoSqr }, bottom + ThreeSqr - HalfWidth));

            case Mobility.TowedArrayLong:
                if (!flat)
                {
                    bottom -= Sqr + HalfWidth;
                }

                return(GenerateArray(
                           new[]
                {
                    -End - TwoSqr, -HalfEnd - Sqr, 0.0, HalfEnd + Sqr, End + TwoSqr
                },
                           bottom + ThreeSqr - HalfWidth));
            }

            return(null);
        }