Ejemplo n.º 1
0
        /// <summary>
        /// Occurs when a menu item is clicked.
        /// </summary>
        /// <param name="sender">The sender of the event.</param>
        /// <param name="e">The <see cref="RoutedEventArgs"/> that contains data related to this event.</param>
        private void OnRemoveNote(object sender, RoutedEventArgs e)
        {
            MenuItem item = (MenuItem)sender;

            // Get the tag range
            TagSnapshotRange <IntraTextNoteTag> tagRange = (TagSnapshotRange <IntraTextNoteTag>)item.Tag;

            // Get the tagger from the code document
            ICodeDocument document = tagRange.SnapshotRange.Snapshot.Document as ICodeDocument;

            if (document != null)
            {
                IntraTextNoteTagger tagger = null;
                if (document.Properties.TryGetValue(typeof(IntraTextNoteTagger), out tagger))
                {
                    // Try and find the tag version range that contains the tag
                    TagVersionRange <IIntraTextSpacerTag> tagVersionRange = tagger[tagRange.Tag];
                    if (tagVersionRange != null)
                    {
                        // Remove the tag version range from the tagger
                        tagger.Remove(tagVersionRange);
                    }
                }
            }
        }
        /////////////////////////////////////////////////////////////////////////////////////////////////////
        // PUBLIC PROCEDURES
        /////////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Adds an adornment to the <see cref="AdornmentLayer"/>.
        /// </summary>
        /// <param name="viewLine">The current <see cref="ITextViewLine"/> being examined.</param>
        /// <param name="tagRange">The <see cref="ITag"/> and the range it covers.</param>
        protected override void AddAdornment(ITextViewLine viewLine, TagSnapshotRange <IntraLineViewportTag> tagRange)
        {
            // Determine the bounds
            var bounds     = this.GetAdornmentBounds(tagRange.Tag);
            var charBounds = viewLine.GetCharacterBounds(tagRange.SnapshotRange.StartOffset);

            bounds.Y = charBounds.Bottom;

            // See if a cached version of the element for the tag is available
            var element = this.GetCachedElement(tagRange.Tag);

            if (element == null)
            {
                // Create the element
                element = new AdornmentElement();
            }

            // Update the size
            element.Width  = bounds.Width;
            element.Height = bounds.Height;
            element.Tag    = tagRange.Tag;

            // Add the adornment
            this.AdornmentLayer.AddAdornment(AdornmentChangeReason.Other, element, bounds.Location, tagRange.Tag.Key, OnAdornmentRemoved);
        }
Ejemplo n.º 3
0
        /////////////////////////////////////////////////////////////////////////////////////////////////////
        // NON-PUBLIC PROCEDURES
        /////////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Changes the status of the specified note tag.
        /// </summary>
        /// <param name="tagRange">The tag range.</param>
        /// <param name="status">The new status.</param>
        private void ChangeNoteStatus(TagSnapshotRange <IntraTextNoteTag> tagRange, ReviewStatus status)
        {
            // Get the tagger from the code document
            ICodeDocument document = tagRange.SnapshotRange.Snapshot.Document as ICodeDocument;

            if (document != null)
            {
                IntraTextNoteTagger tagger = null;
                if (document.Properties.TryGetValue(typeof(IntraTextNoteTagger), out tagger))
                {
                    // Change the tag's status and raise an event so the UI knows to update
                    tagRange.Tag.Status = status;
                    tagger.RaiseTagsChanged(new TagsChangedEventArgs(tagRange.SnapshotRange));
                }
            }
        }
Ejemplo n.º 4
0
        public override FrameworkElement CreateGlyph(IEditorViewLine viewLine, TagSnapshotRange<IIndicatorTag> tagRange, Rect bounds)
        {
            var foreground = new SolidColorBrush(Color.FromArgb(0xff, 0xff, 0x40, 0x00));
            var background = new SolidColorBrush(Color.FromArgb(0xff, 0xff, 0xbb, 0xbb));
            foreground.Freeze();
            background.Freeze();

            var diameter = Math.Max(8.0, Math.Min(13, Math.Round(Math.Min(bounds.Width, bounds.Height) - 2.0)));
            var grid = new Grid {Width = diameter, Height = diameter};
            var outerBorder = new Ellipse() {
                Fill = background,
                Stroke = foreground,
                StrokeThickness = 1.0,
            };
            grid.Children.Add(outerBorder);
            return grid;
        }
Ejemplo n.º 5
0
        /////////////////////////////////////////////////////////////////////////////////////////////////////
        // PUBLIC PROCEDURES
        /////////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Adds an adornment to the <see cref="AdornmentLayer"/>.
        /// </summary>
        /// <param name="reason">An <see cref="AdornmentChangeReason"/> indicating the add reason.</param>
        /// <param name="viewLine">The current <see cref="ITextViewLine"/> being examined.</param>
        /// <param name="tagRange">The <see cref="ITag"/> and the range it covers.</param>
        /// <param name="bounds">The text bounds in which to render an adornment.</param>
        protected override void AddAdornment(AdornmentChangeReason reason, ITextViewLine viewLine, TagSnapshotRange <IntraTextNoteTag> tagRange, TextBounds bounds)
        {
            // Create the adornment
            var image = new DynamicImage();

            image.Width  = 16;
            image.Height = 16;
            image.SnapsToDevicePixels = true;
            image.Source  = new BitmapImage(new Uri("/Images/Icons/Notes16.png", UriKind.Relative));
            image.Stretch = Stretch.Fill;

            // Create a popup button
            PopupButton button = new PopupButton();

            button.Content     = image;
            button.Cursor      = Cursors.Arrow;
            button.DisplayMode = PopupButtonDisplayMode.Merged;
            button.Focusable   = false;
            button.IsTabStop   = false;
            button.IsTransparencyModeEnabled = true;
            button.Margin  = new Thickness(0);
            button.Padding = new Thickness(-1);
            button.ToolTip = new HtmlContentProvider(String.Format("<span style=\"color: green;\">{0}</span><br/>Created at <b>{1}</b> by <span style=\"color: blue;\">{2}</span><br/>Status: <b>{3}</b>",
                                                                   tagRange.Tag.Message, tagRange.Tag.Created.ToShortTimeString(), tagRange.Tag.Author, tagRange.Tag.Status)).GetContent();

            // Add a context menu
            ContextMenu contextMenu = new ContextMenu();

            button.PopupMenu = contextMenu;

            MenuItem removeItem = new MenuItem();

            removeItem.Header = "Remove Note";
            removeItem.Tag    = tagRange;
            removeItem.Click += new RoutedEventHandler(OnRemoveNote);
            contextMenu.Items.Add(removeItem);

            contextMenu.Items.Add(new Separator());

            MenuItem pendingItem = new MenuItem();

            pendingItem.Header    = "Mark as Pending";
            pendingItem.IsChecked = (tagRange.Tag.Status == ReviewStatus.Pending);
            pendingItem.Tag       = tagRange;
            pendingItem.Click    += new RoutedEventHandler(OnMarkNoteAsPending);
            contextMenu.Items.Add(pendingItem);

            MenuItem acceptedItem = new MenuItem();

            acceptedItem.Header    = "Mark as Accepted";
            acceptedItem.IsChecked = (tagRange.Tag.Status == ReviewStatus.Accepted);
            acceptedItem.Tag       = tagRange;
            acceptedItem.Click    += new RoutedEventHandler(OnMarkNoteAsAccpeted);
            contextMenu.Items.Add(acceptedItem);

            MenuItem rejectedItem = new MenuItem();

            rejectedItem.Header    = "Mark as Rejected";
            rejectedItem.IsChecked = (tagRange.Tag.Status == ReviewStatus.Rejected);
            rejectedItem.Tag       = tagRange;
            rejectedItem.Click    += new RoutedEventHandler(OnMarkNoteAsRejected);
            contextMenu.Items.Add(rejectedItem);

            // Get the location
            Point location = new Point(Math.Round(bounds.Left) + 1, Math.Round(bounds.Top + (bounds.Height - tagRange.Tag.Size.Height) / 2));

            // Add the adornment to the layer
            this.AdornmentLayer.AddAdornment(reason, button, location, tagRange.Tag.Key, null);
        }
        /// <summary>
        /// Draws the indicator's glyph in an editor view margin.
        /// </summary>
        /// <param name="context">The <see cref="TextViewDrawContext"/> to use for rendering.</param>
        /// <param name="viewLine">The <see cref="ITextViewLine"/> for which the glyph is rendered.</param>
        /// <param name="tagRange">The <see cref="ITag"/> and the range it covers.</param>
        /// <param name="bounds">The bounds in which the indicator will be rendered.</param>
        public override void DrawGlyph(TextViewDrawContext context, ITextViewLine viewLine, TagSnapshotRange <IIndicatorTag> tagRange, Rect bounds)
        {
            var diameter = Math.Max(8.0, Math.Min(13, Math.Round(Math.Min(bounds.Width, bounds.Height) - 2.0)));
            var x        = bounds.X + (bounds.Width - diameter) / 2.0;
            var y        = bounds.Y + (bounds.Height - diameter) / 2.0;

            context.FillEllipse(new Rect(x, y, diameter, diameter), Color.FromArgb(0xff, 0x8a, 0xf3, 0x82));
            context.DrawEllipse(new Rect(x, y, diameter, diameter), Color.FromArgb(0xff, 0x00, 0x40, 0x00), LineKind.Solid, 1);
        }
        /////////////////////////////////////////////////////////////////////////////////////////////////////
        // PUBLIC PROCEDURES
        /////////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Adds an adornment to the <see cref="AdornmentLayer"/>.
        /// </summary>
        /// <param name="reason">An <see cref="AdornmentChangeReason"/> indicating the add reason.</param>
        /// <param name="viewLine">The current <see cref="ITextViewLine"/> being examined.</param>
        /// <param name="tagRange">The <see cref="ITag"/> and the range it covers.</param>
        /// <param name="bounds">The text bounds in which to render an adornment.</param>
        protected override void AddAdornment(AdornmentChangeReason reason, ITextViewLine viewLine, TagSnapshotRange <ColorPreviewTag> tagRange, TextBounds bounds)
        {
            // Round off the bounds to integers to help ensure crispness
            var adornmentBounds = new Rect(Math.Round(bounds.Left, MidpointRounding.AwayFromZero), Math.Round(bounds.Top, MidpointRounding.AwayFromZero),
                                           Math.Round(bounds.Width, MidpointRounding.AwayFromZero), Math.Round(bounds.Height, MidpointRounding.AwayFromZero));

            // Add the adornment to the layer
            this.AdornmentLayer.AddAdornment(reason, OnDrawHighlightAdornment, adornmentBounds, tagRange.Tag, viewLine, tagRange.SnapshotRange, TextRangeTrackingModes.ExpandBothEdges, null);
        }