示例#1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RRect" /> class with the specified location and size.
 /// </summary>
 /// <param name="location">A <see cref="RPoint" /> that represents the upper-left corner of the rectangular region.</param>
 /// <param name="size">A <see cref="RSize" /> that represents the width and height of the rectangular region.</param>
 public RRect(RPoint location, RSize size)
 {
     _x = location.X;
     _y = location.Y;
     _width = size.Width;
     _height = size.Height;
 }
示例#2
0
 /// <summary>
 /// Check if the given location is inside the given box deep.<br/>
 /// Check inner boxes and all lines that the given box spans to.
 /// </summary>
 /// <param name="box">the box to check</param>
 /// <param name="location">the location to check</param>
 /// <returns>true - location inside the box, false - otherwise</returns>
 public static bool IsInBox(CssBox box, RPoint location)
 {
     foreach (var line in box.Rectangles)
     {
         if (line.Value.Contains(location))
             return true;
     }
     foreach (var childBox in box.Boxes)
     {
         if (IsInBox(childBox, location))
             return true;
     }
     return false;
 }
示例#3
0
        /// <summary>
        /// Measures the bounds of box and children, recursively.<br/>
        /// Performs layout of the DOM structure creating lines by set bounds restrictions.
        /// </summary>
        /// <param name="g">Device context to use</param>
        protected override void PerformLayoutImp(RGraphics g)
        {
            if (Display == CssConstants.None)
                return;

            RectanglesReset();

            var prevSibling = DomUtils.GetPreviousSibling(this);
            double left = ContainingBlock.Location.X + ContainingBlock.ActualPaddingLeft + ActualMarginLeft + ContainingBlock.ActualBorderLeftWidth;
            double top = (prevSibling == null && ParentBox != null ? ParentBox.ClientTop : ParentBox == null ? Location.Y : 0) + MarginTopCollapse(prevSibling) + (prevSibling != null ? prevSibling.ActualBottom + prevSibling.ActualBorderBottomWidth : 0);
            Location = new RPoint(left, top);
            ActualBottom = top;

            //width at 100% (or auto)
            double minwidth = GetMinimumWidth();
            double width = ContainingBlock.Size.Width
                           - ContainingBlock.ActualPaddingLeft - ContainingBlock.ActualPaddingRight
                           - ContainingBlock.ActualBorderLeftWidth - ContainingBlock.ActualBorderRightWidth
                           - ActualMarginLeft - ActualMarginRight - ActualBorderLeftWidth - ActualBorderRightWidth;

            //Check width if not auto
            if (Width != CssConstants.Auto && !string.IsNullOrEmpty(Width))
            {
                width = CssValueParser.ParseLength(Width, width, this);
            }

            if (width < minwidth || width >= 9999)
                width = minwidth;

            double height = ActualHeight;
            if (height < 1)
            {
                height = Size.Height + ActualBorderTopWidth + ActualBorderBottomWidth;
            }
            if (height < 1)
            {
                height = 2;
            }
            if (height <= 2 && ActualBorderTopWidth < 1 && ActualBorderBottomWidth < 1)
            {
                BorderTopStyle = BorderBottomStyle = CssConstants.Solid;
                BorderTopWidth = "1px";
                BorderBottomWidth = "1px";
            }

            Size = new RSize(width, height);

            ActualBottom = Location.Y + ActualPaddingTop + ActualPaddingBottom + height;
        }
示例#4
0
        /// <summary>
        /// Get css line box under the given sub-tree at the given y location or the nearest line from the top.<br/>
        /// the location must be in correct scroll offset.
        /// </summary>
        /// <param name="box">the box to start search from</param>
        /// <param name="location">the location to find the box at</param>
        /// <returns>css word box if exists or null</returns>
        public static CssLineBox GetCssLineBox(CssBox box, RPoint location)
        {
            CssLineBox line = null;
            if (box != null)
            {
                if (box.LineBoxes.Count > 0)
                {
                    if (box.HtmlTag == null || box.HtmlTag.Name != "td" || box.Bounds.Contains(location))
                    {
                        foreach (var lineBox in box.LineBoxes)
                        {
                            foreach (var rect in lineBox.Rectangles)
                            {
                                if (rect.Value.Top <= location.Y)
                                {
                                    line = lineBox;
                                }

                                if (rect.Value.Top > location.Y)
                                {
                                    return line;
                                }
                            }
                        }
                    }
                }

                foreach (var childBox in box.Boxes)
                {
                    line = GetCssLineBox(childBox, location) ?? line;
                }
            }

            return line;
        }
示例#5
0
 /// <summary>
 ///     Translates a given <see cref="RPoint" /> by a specified
 ///     <see
 ///         cref="T:System.Drawing.SizeF" />
 ///     .
 /// </summary>
 /// <returns>
 ///     The translated <see cref="RPoint" />.
 /// </returns>
 /// <param name="pt">
 ///     The <see cref="RPoint" /> to translate.
 /// </param>
 /// <param name="sz">
 ///     The <see cref="T:System.Drawing.SizeF" /> that specifies the numbers to add to the coordinates of
 ///     <paramref
 ///         name="pt" />
 ///     .
 /// </param>
 public static RPoint Add(RPoint pt, RSize sz)
 {
     return new RPoint(pt.X + sz.Width, pt.Y + sz.Height);
 }
示例#6
0
 /// <summary>
 ///     Adjusts the location of this rectangle by the specified amount.
 /// </summary>
 /// <param name="pos">The amount to offset the location. </param>
 public void Offset(RPoint pos)
 {
     Offset(pos.X, pos.Y);
 }
示例#7
0
 /// <summary>
 /// Draw the given string using the given font and foreground color at given location.
 /// </summary>
 /// <param name="str">the string to draw</param>
 /// <param name="font">the font to use to draw the string</param>
 /// <param name="color">the text color to set</param>
 /// <param name="point">the location to start string draw (top-left)</param>
 /// <param name="size">used to know the size of the rendered text for transparent text support</param>
 /// <param name="rtl">is to render the string right-to-left (true - RTL, false - LTR)</param>
 public abstract void DrawString(String str, RFont font, RColor color, RPoint point, RSize size, bool rtl);
示例#8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RSize" /> structure from the specified <see cref="RPoint" /> structure.
 /// </summary>
 /// <param name="pt">The <see cref="RPoint" /> structure from which to initialize this <see cref="RSize" /> structure.</param>
 public RSize(RPoint pt)
 {
     _width = pt.X;
     _height = pt.Y;
 }
        /// <summary>
        /// Calculate the character index and offset by characters for the given word and given offset.<br/>
        /// If the location is below the word line then set the selection to the end.<br/>
        /// If the location is to the right of the word then set the selection to the end.<br/>
        /// If the offset is to the left of the word set the selection to the beginning.<br/>
        /// Otherwise calculate the width of each substring to find the char the location is on.
        /// </summary>
        /// <param name="control">used to create graphics to measure string</param>
        /// <param name="word">the word to calculate its index and offset</param>
        /// <param name="loc">the location to calculate for</param>
        /// <param name="inclusive">is to include the first character in the calculation</param>
        /// <param name="selectionIndex">return the index of the char under the location</param>
        /// <param name="selectionOffset">return the offset of the char under the location</param>
        private static void CalculateWordCharIndexAndOffset(RControl control, CssRect word, RPoint loc, bool inclusive, out int selectionIndex, out double selectionOffset)
        {
            selectionIndex = 0;
            selectionOffset = 0f;
            var offset = loc.X - word.Left;
            if (word.Text == null)
            {
                // not a text word - set full selection
                selectionIndex = -1;
                selectionOffset = -1;
            }
            else if (offset > word.Width - word.OwnerBox.ActualWordSpacing || loc.Y > DomUtils.GetCssLineBoxByWord(word).LineBottom)
            {
                // mouse under the line, to the right of the word - set to the end of the word
                selectionIndex = word.Text.Length;
                selectionOffset = word.Width;
            }
            else if (offset > 0)
            {
                // calculate partial word selection
                int charFit;
                double charFitWidth;
                var maxWidth = offset + (inclusive ? 0 : 1.5f * word.LeftGlyphPadding);
                control.MeasureString(word.Text, word.OwnerBox.ActualFont, maxWidth, out charFit, out charFitWidth);

                selectionIndex = charFit;
                selectionOffset = charFitWidth;
            }
        }
示例#10
0
        /// <summary>
        /// Deeply offsets the top of the box and its contents
        /// </summary>
        /// <param name="amount"></param>
        internal void OffsetTop(double amount)
        {
            List<CssLineBox> lines = new List<CssLineBox>();
            foreach (CssLineBox line in Rectangles.Keys)
                lines.Add(line);

            foreach (CssLineBox line in lines)
            {
                RRect r = Rectangles[line];
                Rectangles[line] = new RRect(r.X, r.Y + amount, r.Width, r.Height);
            }

            foreach (CssRect word in Words)
            {
                word.Top += amount;
            }

            foreach (CssBox b in Boxes)
            {
                b.OffsetTop(amount);
            }

            if (_listItemBox != null)
                _listItemBox.OffsetTop(amount);

            Location = new RPoint(Location.X, Location.Y + amount);
        }
 /// <summary>
 /// Init.
 /// </summary>
 /// <param name="location">the location to scroll to</param>
 public HtmlScrollEventArgs(RPoint location)
 {
     _location = location;
 }
示例#12
0
        /// <summary>
        /// Draw video image over the iframe if found.
        /// </summary>
        private void DrawImage(RGraphics g, RPoint offset, RRect rect)
        {
            if (_imageWord.Image != null)
            {
                if (rect.Width > 0 && rect.Height > 0)
                {
                    if (_imageWord.ImageRectangle == RRect.Empty)
                        g.DrawImage(_imageWord.Image, rect);
                    else
                        g.DrawImage(_imageWord.Image, rect, _imageWord.ImageRectangle);

                    if (_imageWord.Selected)
                    {
                        g.DrawRectangle(GetSelectionBackBrush(g, true), _imageWord.Left + offset.X, _imageWord.Top + offset.Y, _imageWord.Width + 2, DomUtils.GetCssLineBoxByWord(_imageWord).LineHeight);
                    }
                }
            }
            else if (_isVideo && !_imageLoadingComplete)
            {
                RenderUtils.DrawImageLoadingIcon(g, HtmlContainer, rect);
                if (rect.Width > 19 && rect.Height > 19)
                {
                    g.DrawRectangle(g.GetPen(RColor.LightGray), rect.X, rect.Y, rect.Width, rect.Height);
                }
            }
        }
示例#13
0
 /// <summary>
 /// Show the context menu in the given parent control at the given location.
 /// </summary><param name="parent">the parent control to show in</param><param name="location">the location to show at relative to the parent control</param>
 public abstract void Show(RControl parent, RPoint location);
示例#14
0
 /// <summary>
 /// Get css word box under the given sub-tree at the given x,y location.<br/>
 /// the location must be in correct scroll offset.
 /// </summary>
 /// <param name="lineBox">the line box to search in</param>
 /// <param name="location">the location to find the box at</param>
 /// <returns>css word box if exists or null</returns>
 public static CssRect GetCssBoxWord(CssLineBox lineBox, RPoint location)
 {
     foreach (var rects in lineBox.Rectangles)
     {
         foreach (var word in rects.Key.Words)
         {
             // add word spacing to word width so sentence won't have hols in it when moving the mouse
             var rect = word.Rectangle;
             rect.Width += word.OwnerBox.ActualWordSpacing;
             if (rect.Contains(location))
             {
                 return word;
             }
         }
     }
     return null;
 }
示例#15
0
        /// <summary>
        /// Get css word box under the given sub-tree at the given x,y location.<br/>
        /// the location must be in correct scroll offset.
        /// </summary>
        /// <param name="box">the box to start search from</param>
        /// <param name="location">the location to find the box at</param>
        /// <returns>css word box if exists or null</returns>
        public static CssRect GetCssBoxWord(CssBox box, RPoint location)
        {
            if (box != null && box.Visibility == CssConstants.Visible)
            {
                if (box.LineBoxes.Count > 0)
                {
                    foreach (var lineBox in box.LineBoxes)
                    {
                        var wordBox = GetCssBoxWord(lineBox, location);
                        if (wordBox != null)
                            return wordBox;
                    }
                }

                if (box.ClientRectangle.IsEmpty || box.ClientRectangle.Contains(location))
                {
                    foreach (var childBox in box.Boxes)
                    {
                        var foundWord = GetCssBoxWord(childBox, location);
                        if (foundWord != null)
                        {
                            return foundWord;
                        }
                    }
                }
            }

            return null;
        }
        /// <summary>
        /// Check if the current selection is non empty, has some selection data.
        /// </summary>
        /// <param name="loc"></param>
        /// <param name="allowPartialSelect">true - partial word selection allowed, false - only full words selection</param>
        /// <returns>true - is non empty selection, false - empty selection</returns>
        private bool CheckNonEmptySelection(RPoint loc, bool allowPartialSelect)
        {
            // full word selection is never empty
            if (!allowPartialSelect)
                return true;

            // if end selection location is near starting location then the selection is empty
            if (Math.Abs(_selectionStartPoint.X - loc.X) <= 1 && Math.Abs(_selectionStartPoint.Y - loc.Y) < 5)
                return false;

            // selection is empty if on same word and same index
            return _selectionStart != _selectionEnd || _selectionStartIndex != _selectionEndIndex;
        }
        /// <summary>
        /// Calculate the character index and offset by characters for the given word and given offset.<br/>
        /// <seealso cref="CalculateWordCharIndexAndOffset(RControl,CssRect,RPoint,bool)"/>.
        /// </summary>
        /// <param name="control">used to create graphics to measure string</param>
        /// <param name="word">the word to calculate its index and offset</param>
        /// <param name="loc">the location to calculate for</param>
        /// <param name="selectionStart">to set the starting or ending char and offset data</param>
        private void CalculateWordCharIndexAndOffset(RControl control, CssRect word, RPoint loc, bool selectionStart)
        {
            int selectionIndex;
            double selectionOffset;
            CalculateWordCharIndexAndOffset(control, word, loc, selectionStart, out selectionIndex, out selectionOffset);

            if (selectionStart)
            {
                _selectionStartIndex = selectionIndex;
                _selectionStartOffset = selectionOffset;
            }
            else
            {
                _selectionEndIndex = selectionIndex;
                _selectionEndOffset = selectionOffset;
            }
        }
示例#18
0
        /// <summary>
        /// Paint all the words in the box.
        /// </summary>
        /// <param name="g">the device to draw into</param>
        /// <param name="offset">the current scroll offset to offset the words</param>
        private void PaintWords(RGraphics g, RPoint offset)
        {
            if (Width.Length > 0)
            {
                var isRtl = Direction == CssConstants.Rtl;
                foreach (var word in Words)
                {
                    if (!word.IsLineBreak)
                    {
                        var wordPoint = new RPoint(word.Left + offset.X, word.Top + offset.Y);
                        if (word.Selected)
                        {
                            // handle paint selected word background and with partial word selection
                            var wordLine = DomUtils.GetCssLineBoxByWord(word);
                            var left = word.SelectedStartOffset > -1 ? word.SelectedStartOffset : (wordLine.Words[0] != word && word.HasSpaceBefore ? -ActualWordSpacing : 0);
                            var padWordRight = word.HasSpaceAfter && !wordLine.IsLastSelectedWord(word);
                            var width = word.SelectedEndOffset > -1 ? word.SelectedEndOffset : word.Width + (padWordRight ? ActualWordSpacing : 0);
                            var rect = new RRect(word.Left + offset.X + left, word.Top + offset.Y, width - left, wordLine.LineHeight);

                            g.DrawRectangle(GetSelectionBackBrush(g, false), rect.X, rect.Y, rect.Width, rect.Height);

                            if (HtmlContainer.SelectionForeColor != RColor.Empty && (word.SelectedStartOffset > 0 || word.SelectedEndIndexOffset > -1))
                            {
                                g.PushClipExclude(rect);
                                g.DrawString(word.Text, ActualFont, ActualColor, wordPoint, new RSize(word.Width, word.Height), isRtl);
                                g.PopClip();
                                g.PushClip(rect);
                                g.DrawString(word.Text, ActualFont, GetSelectionForeBrush(), wordPoint, new RSize(word.Width, word.Height), isRtl);
                                g.PopClip();
                            }
                            else
                            {
                                g.DrawString(word.Text, ActualFont, GetSelectionForeBrush(), wordPoint, new RSize(word.Width, word.Height), isRtl);
                            }
                        }
                        else
                        {
                            //                            g.DrawRectangle(HtmlContainer.Adapter.GetPen(RColor.Black), wordPoint.X, wordPoint.Y, word.Width - 1, word.Height - 1);
                            g.DrawString(word.Text, ActualFont, ActualColor, wordPoint, new RSize(word.Width, word.Height), isRtl);
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Set rectangle for inset/outset border as it need diagonal connection to other borders.
 /// </summary>
 /// <param name="border">Desired border</param>
 /// <param name="b">Box which the border corresponds</param>
 /// <param name="r">the rectangle the border is enclosing</param>
 /// <param name="isLineStart">Specifies if the border is for a starting line (no bevel on left)</param>
 /// <param name="isLineEnd">Specifies if the border is for an ending line (no bevel on right)</param>
 /// <returns>Beveled border path, null if there is no rounded corners</returns>
 private static void SetInOutsetRectanglePoints(Border border, CssBox b, RRect r, bool isLineStart, bool isLineEnd)
 {
     switch (border)
     {
         case Border.Top:
             _borderPts[0] = new RPoint(r.Left, r.Top);
             _borderPts[1] = new RPoint(r.Right, r.Top);
             _borderPts[2] = new RPoint(r.Right, r.Top + b.ActualBorderTopWidth);
             _borderPts[3] = new RPoint(r.Left, r.Top + b.ActualBorderTopWidth);
             if (isLineEnd)
                 _borderPts[2].X -= b.ActualBorderRightWidth;
             if (isLineStart)
                 _borderPts[3].X += b.ActualBorderLeftWidth;
             break;
         case Border.Right:
             _borderPts[0] = new RPoint(r.Right - b.ActualBorderRightWidth, r.Top + b.ActualBorderTopWidth);
             _borderPts[1] = new RPoint(r.Right, r.Top);
             _borderPts[2] = new RPoint(r.Right, r.Bottom);
             _borderPts[3] = new RPoint(r.Right - b.ActualBorderRightWidth, r.Bottom - b.ActualBorderBottomWidth);
             break;
         case Border.Bottom:
             _borderPts[0] = new RPoint(r.Left, r.Bottom - b.ActualBorderBottomWidth);
             _borderPts[1] = new RPoint(r.Right, r.Bottom - b.ActualBorderBottomWidth);
             _borderPts[2] = new RPoint(r.Right, r.Bottom);
             _borderPts[3] = new RPoint(r.Left, r.Bottom);
             if (isLineStart)
                 _borderPts[0].X += b.ActualBorderLeftWidth;
             if (isLineEnd)
                 _borderPts[1].X -= b.ActualBorderRightWidth;
             break;
         case Border.Left:
             _borderPts[0] = new RPoint(r.Left, r.Top);
             _borderPts[1] = new RPoint(r.Left + b.ActualBorderLeftWidth, r.Top + b.ActualBorderTopWidth);
             _borderPts[2] = new RPoint(r.Left + b.ActualBorderLeftWidth, r.Bottom - b.ActualBorderBottomWidth);
             _borderPts[3] = new RPoint(r.Left, r.Bottom);
             break;
     }
 }
示例#20
0
        /// <summary>
        /// Measures the bounds of box and children, recursively.<br/>
        /// Performs layout of the DOM structure creating lines by set bounds restrictions.<br/>
        /// </summary>
        /// <param name="g">Device context to use</param>
        protected virtual void PerformLayoutImp(RGraphics g)
        {
            if (Display != CssConstants.None)
            {
                RectanglesReset();
                MeasureWordsSize(g);
            }

            if (IsBlock || Display == CssConstants.ListItem || Display == CssConstants.Table || Display == CssConstants.InlineTable || Display == CssConstants.TableCell)
            {
                // Because their width and height are set by CssTable
                if (Display != CssConstants.TableCell && Display != CssConstants.Table)
                {
                    double width = ContainingBlock.Size.Width
                                   - ContainingBlock.ActualPaddingLeft - ContainingBlock.ActualPaddingRight
                                   - ContainingBlock.ActualBorderLeftWidth - ContainingBlock.ActualBorderRightWidth;

                    if (Width != CssConstants.Auto && !string.IsNullOrEmpty(Width))
                    {
                        width = CssValueParser.ParseLength(Width, width, this);
                    }

                    Size = new RSize(width, Size.Height);

                    // must be separate because the margin can be calculated by percentage of the width
                    Size = new RSize(width - ActualMarginLeft - ActualMarginRight, Size.Height);
                }

                if (Display != CssConstants.TableCell)
                {
                    var prevSibling = DomUtils.GetPreviousSibling(this);
                    double left = ContainingBlock.Location.X + ContainingBlock.ActualPaddingLeft + ActualMarginLeft + ContainingBlock.ActualBorderLeftWidth;
                    double top = (prevSibling == null && ParentBox != null ? ParentBox.ClientTop : ParentBox == null ? Location.Y : 0) + MarginTopCollapse(prevSibling) + (prevSibling != null ? prevSibling.ActualBottom + prevSibling.ActualBorderBottomWidth : 0);
                    Location = new RPoint(left, top);
                    ActualBottom = top;
                }

                //If we're talking about a table here..
                if (Display == CssConstants.Table || Display == CssConstants.InlineTable)
                {
                    CssLayoutEngineTable.PerformLayout(g, this);
                }
                else
                {
                    //If there's just inline boxes, create LineBoxes
                    if (DomUtils.ContainsInlinesOnly(this))
                    {
                        ActualBottom = Location.Y;
                        CssLayoutEngine.CreateLineBoxes(g, this); //This will automatically set the bottom of this block
                    }
                    else if (_boxes.Count > 0)
                    {
                        foreach (var childBox in Boxes)
                        {
                            childBox.PerformLayout(g);
                        }
                        ActualRight = CalculateActualRight();
                        ActualBottom = MarginBottomCollapse();
                    }
                }
            }
            else
            {
                var prevSibling = DomUtils.GetPreviousSibling(this);
                if (prevSibling != null)
                {
                    if (Location == RPoint.Empty)
                        Location = prevSibling.Location;
                    ActualBottom = prevSibling.ActualBottom;
                }
            }
            ActualBottom = Math.Max(ActualBottom, Location.Y + ActualHeight);

            CreateListItemBox(g);

            var actualWidth = Math.Max(GetMinimumWidth() + GetWidthMarginDeep(this), Size.Width < 90999 ? ActualRight - HtmlContainer.Root.Location.X : 0);
            HtmlContainer.ActualSize = CommonUtils.Max(HtmlContainer.ActualSize, new RSize(actualWidth, ActualBottom - HtmlContainer.Root.Location.Y));
        }
示例#21
0
 /// <summary>
 /// Get TextureBrush object that uses the specified image and bounding rectangle.
 /// </summary>
 /// <param name="image">The Image object with which this TextureBrush object fills interiors.</param>
 /// <param name="dstRect">A Rectangle structure that represents the bounding rectangle for this TextureBrush object.</param>
 /// <param name="translateTransformLocation">The dimension by which to translate the transformation</param>
 public abstract RBrush GetTextureBrush(RImage image, RRect dstRect, RPoint translateTransformLocation);
 /// <summary>
 /// Select the word at the given location if found.
 /// </summary>
 /// <param name="control">the control hosting the html to invalidate</param>
 /// <param name="loc">the location to select word at</param>
 public void SelectWord(RControl control, RPoint loc)
 {
     if (_root.HtmlContainer.IsSelectionEnabled)
     {
         var word = DomUtils.GetCssBoxWord(_root, loc);
         if (word != null)
         {
             word.Selection = this;
             _selectionStartPoint = loc;
             _selectionStart = _selectionEnd = word;
             control.Invalidate();
         }
     }
 }
示例#23
0
 /// <summary>
 /// Fills the interior of a polygon defined by an array of points specified by Point structures.
 /// </summary>
 /// <param name="brush">Brush that determines the characteristics of the fill. </param>
 /// <param name="points">Array of Point structures that represent the vertices of the polygon to fill. </param>
 public abstract void DrawPolygon(RBrush brush, RPoint[] points);
        /// <summary>
        /// Handle mouse down to handle selection.
        /// </summary>
        /// <param name="parent">the control hosting the html to invalidate</param>
        /// <param name="loc">the location of the mouse on the html</param>
        /// <param name="isMouseInContainer"> </param>
        public void HandleMouseDown(RControl parent, RPoint loc, bool isMouseInContainer)
        {
            bool clear = !isMouseInContainer;
            if (isMouseInContainer)
            {
                _mouseDownInControl = true;
                _isDoubleClickSelect = (DateTime.Now - _lastMouseDown).TotalMilliseconds < 400;
                _lastMouseDown = DateTime.Now;
                _mouseDownOnSelectedWord = false;

                if (_root.HtmlContainer.IsSelectionEnabled && parent.LeftMouseButton)
                {
                    var word = DomUtils.GetCssBoxWord(_root, loc);
                    if (word != null && word.Selected)
                    {
                        _mouseDownOnSelectedWord = true;
                    }
                    else
                    {
                        clear = true;
                    }
                }
                else if (parent.RightMouseButton)
                {
                    var rect = DomUtils.GetCssBoxWord(_root, loc);
                    var link = DomUtils.GetLinkBox(_root, loc);
                    if (_root.HtmlContainer.IsContextMenuEnabled)
                    {
                        _contextMenuHandler.ShowContextMenu(parent, rect, link);
                    }
                    clear = rect == null || !rect.Selected;
                }
            }

            if (clear)
            {
                ClearSelection();
                parent.Invalidate();
            }
        }
示例#25
0
 /// <summary>
 ///     Determines if the specified point is contained within this <see cref="RRect" /> structure.
 /// </summary>
 /// <returns>
 ///     This method returns true if the point represented by the <paramref name="pt" /> parameter is contained within this
 ///     <see cref="RRect" />
 ///     structure; otherwise false.
 /// </returns>
 /// <param name="pt">The <see cref="RPoint" /> to test.</param>
 public bool Contains(RPoint pt)
 {
     return Contains(pt.X, pt.Y);
 }
 /// <summary>
 /// Handle mouse move to handle hover cursor and text selection.
 /// </summary>
 /// <param name="parent">the control hosting the html to set cursor and invalidate</param>
 /// <param name="loc">the location of the mouse on the html</param>
 public void HandleMouseMove(RControl parent, RPoint loc)
 {
     if (_root.HtmlContainer.IsSelectionEnabled && _mouseDownInControl && parent.LeftMouseButton)
     {
         if (_mouseDownOnSelectedWord)
         {
             // make sure not to start drag-drop on click but when it actually moves as it f***s mouse-up
             if ((DateTime.Now - _lastMouseDown).TotalMilliseconds > 200)
                 StartDragDrop(parent);
         }
         else
         {
             HandleSelection(parent, loc, !_isDoubleClickSelect);
             _inSelection = _selectionStart != null && _selectionEnd != null && (_selectionStart != _selectionEnd || _selectionStartIndex != _selectionEndIndex);
         }
     }
     else
     {
         // Handle mouse hover over the html to change the cursor depending if hovering word, link of other.
         var link = DomUtils.GetLinkBox(_root, loc);
         if (link != null)
         {
             _cursorChanged = true;
             parent.SetCursorHand();
         }
         else if (_root.HtmlContainer.IsSelectionEnabled)
         {
             var word = DomUtils.GetCssBoxWord(_root, loc);
             _cursorChanged = word != null && !word.IsImage && !(word.Selected && (word.SelectedStartIndex < 0 || word.Left + word.SelectedStartOffset <= loc.X) && (word.SelectedEndOffset < 0 || word.Left + word.SelectedEndOffset >= loc.X));
             if (_cursorChanged)
                 parent.SetCursorIBeam();
             else
                 parent.SetCursorDefault();
         }
         else if (_cursorChanged)
         {
             parent.SetCursorDefault();
         }
     }
 }
        /// <summary>
        /// Clear the current selection.
        /// </summary>
        public void ClearSelection()
        {
            // clear drag and drop
            _dragDropData = null;

            ClearSelection(_root);

            _selectionStartOffset = -1;
            _selectionStartIndex = -1;
            _selectionEndOffset = -1;
            _selectionEndIndex = -1;

            _selectionStartPoint = RPoint.Empty;
            _selectionStart = null;
            _selectionEnd = null;
        }
        /// <summary>
        /// Handle html text selection by mouse move over the html with left mouse button pressed.<br/>
        /// Calculate the words in the selected range and set their selected property.
        /// </summary>
        /// <param name="control">the control hosting the html to invalidate</param>
        /// <param name="loc">the mouse location</param>
        /// <param name="allowPartialSelect">true - partial word selection allowed, false - only full words selection</param>
        private void HandleSelection(RControl control, RPoint loc, bool allowPartialSelect)
        {
            // get the line under the mouse or nearest from the top
            var lineBox = DomUtils.GetCssLineBox(_root, loc);
            if (lineBox != null)
            {
                // get the word under the mouse
                var word = DomUtils.GetCssBoxWord(lineBox, loc);

                // if no word found under the mouse use the last or the first word in the line
                if (word == null && lineBox.Words.Count > 0)
                {
                    if (loc.Y > lineBox.LineBottom)
                    {
                        // under the line
                        word = lineBox.Words[lineBox.Words.Count - 1];
                    }
                    else if (loc.X < lineBox.Words[0].Left)
                    {
                        // before the line
                        word = lineBox.Words[0];
                    }
                    else if (loc.X > lineBox.Words[lineBox.Words.Count - 1].Right)
                    {
                        // at the end of the line
                        word = lineBox.Words[lineBox.Words.Count - 1];
                    }
                }

                // if there is matching word
                if (word != null)
                {
                    if (_selectionStart == null)
                    {
                        // on start set the selection start word
                        _selectionStartPoint = loc;
                        _selectionStart = word;
                        if (allowPartialSelect)
                            CalculateWordCharIndexAndOffset(control, word, loc, true);
                    }

                    // always set selection end word
                    _selectionEnd = word;
                    if (allowPartialSelect)
                        CalculateWordCharIndexAndOffset(control, word, loc, false);

                    ClearSelection(_root);
                    if (CheckNonEmptySelection(loc, allowPartialSelect))
                    {
                        CheckSelectionDirection();
                        SelectWordsInRange(_root, _backwardSelection ? _selectionEnd : _selectionStart, _backwardSelection ? _selectionStart : _selectionEnd);
                    }
                    else
                    {
                        _selectionEnd = null;
                    }

                    _cursorChanged = true;
                    control.SetCursorIBeam();
                    control.Invalidate();
                }
            }
        }
示例#29
0
 /// <summary>
 ///     Translates a <see cref="RPoint" /> by the negative of a specified size.
 /// </summary>
 /// <returns>
 ///     The translated <see cref="RPoint" />.
 /// </returns>
 /// <param name="pt">
 ///     The <see cref="RPoint" /> to translate.
 /// </param>
 /// <param name="sz">
 ///     The <see cref="T:System.Drawing.SizeF" /> that specifies the numbers to subtract from the coordinates of
 ///     <paramref
 ///         name="pt" />
 ///     .
 /// </param>
 public static RPoint Subtract(RPoint pt, RSize sz)
 {
     return new RPoint(pt.X - sz.Width, pt.Y - sz.Height);
 }
示例#30
0
        /// <summary>
        /// Get css link box under the given sub-tree at the given x,y location.<br/>
        /// the location must be in correct scroll offset.
        /// </summary>
        /// <param name="box">the box to start search from</param>
        /// <param name="location">the location to find the box by</param>
        /// <returns>css link box if exists or null</returns>
        public static CssBox GetLinkBox(CssBox box, RPoint location)
        {
            if (box != null)
            {
                if (box.IsClickable && box.Visibility == CssConstants.Visible)
                {
                    if (IsInBox(box, location))
                        return box;
                }

                if (box.ClientRectangle.IsEmpty || box.ClientRectangle.Contains(location))
                {
                    foreach (var childBox in box.Boxes)
                    {
                        var foundBox = GetLinkBox(childBox, location);
                        if (foundBox != null)
                            return foundBox;
                    }
                }
            }

            return null;
        }