public override void PaintBackground(Common.COMInterfaces.IVwGraphics vg, PaintTransform ptrans) { base.PaintBackground(vg, ptrans); // might paint some pad or border around the block. Rectangle paintRect = ptrans.ToPaint(new Rectangle(Left + GapLeading(ptrans), Top + GapTop(ptrans), ptrans.MpToPixelsX(MpWidth), ptrans.MpToPixelsY(MpHeight))); vg.BackColor = (int) ColorUtil.ConvertColorToBGR(BlockColor); vg.DrawRectangle(paintRect.Left, paintRect.Top, paintRect.Right, paintRect.Bottom); }
/// <summary> /// We paint images as "background" so that any adjacent text can overlap them slightly if necessary. /// </summary> public override void PaintBackground(Common.COMInterfaces.IVwGraphics vg, PaintTransform ptrans) { base.PaintBackground(vg, ptrans); // might paint some pad or border around the block. Rect bounds = ptrans.ToPaint(new Rect(Left + GapLeading(ptrans), Top + GapTop(ptrans), Right - GapTrailing(ptrans),Bottom - GapBottom(ptrans))); int hmHeight = Picture.Height; // "HiMetric" height and width int hmWidth = Picture.Width; vg.RenderPicture(Picture, bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top, 0, hmHeight, hmWidth, -hmHeight, ref bounds); }
/// <summary> /// If there is a leaf box at the specified position, return it. Also return the paint transform that should be /// passed to operations on that box. By default we return this if the point is inside the box, and the transform /// we are passed. /// Where is in drawing coords. /// Todo JohnT: verify the point actually is in the box. /// </summary> public virtual LeafBox FindBoxAt(Point where, PaintTransform ptrans, out PaintTransform leafBoxTransform) { leafBoxTransform = ptrans; return(this as LeafBox); }
/// <summary> /// Implement dragging to this view. /// </summary> public void OnDragDrop(DragEventArgs drgevent, Point location, IVwGraphics vg, PaintTransform ptrans) { var sel = GetSelectionAt(location, vg, ptrans) as InsertionPoint; if (sel == null) return; var rtf = drgevent.Data.GetData(DataFormats.Rtf); var data = drgevent.Data.GetData(DataFormats.StringFormat); if (data == null) return; var text = data.ToString(); // MS example of GetData does this, though for DataFormats.Text. if (DragState == WindowDragState.InternalMove) { DragState = WindowDragState.None; // We are dragging our own selection. Is it in the same property? var range = (RangeSelection)Selection; // Enhance JohnT: when we can drag a range that isn't all in one property, this needs more work. if (!Selection.IsInsertionPoint) { if (Selection.Contains(sel)) { Selection = sel; return; // Can't drag to inside own selection. } } if (range.End.Hookup == sel.Hookup && range.End.StringPosition < sel.StringPosition) { // Dragging to later in the same property. If we delete first, we will mess up the insert // position. However, a simple solution is to insert first. //Log("Inserted dropped " + text + " before deleted range"); if (rtf == null) sel.InsertText(text); else if (!sel.InsertRtfString(rtf.ToString())) sel.InsertText(text); range.Delete(); return; } // The bit we're moving comes after the place to insert, or they are in separate properties. // We can just go ahead and delete the source first, since we already have a copy of the // text to insert. // Enhance JohnT: do we need to consider a special case where the source and destination are // different occurrences of the same property? //Log("Deleted selection"); range.Delete(); } DragState = WindowDragState.None; //Log("Dropped text: " + text); if (rtf == null) sel.InsertText(text); else if (!sel.InsertRtfString(rtf.ToString())) sel.InsertText(text); }
/// <summary> /// Any box knows how to paint itself. Most subclasses should override. /// </summary> public virtual void PaintForeground(IVwGraphics vg, PaintTransform ptrans) { }
/// <summary> /// This is basically the common logic of MouseDown and MouseMove, when the left mouse button is pressed. /// If makeRange is true, as for shift-click or mouse move, we try to move the drag end of a range; /// otherwise, we make the selection where it is. /// </summary> private void ExtendSelection(MouseEventArgs e, bool makeRange, IVwGraphics vg, PaintTransform ptrans) { // Enhance JohnT: if the new selection is exactly the same don't change it. var sel = GetSelectionAt(e.Location, vg, ptrans); if (!(sel is InsertionPoint)) return; ExtendSelection(sel, makeRange); }
/// <summary> /// Places an insertion point within a ranged selection, only if the mouse down occured within the selection. /// OnMouseDown takes care of all other situations. /// </summary> public virtual void OnMouseClick(MouseEventArgs e, Keys keys, IVwGraphics vg, PaintTransform ptrans) { if (e.Button != MouseButtons.Left) return; var sel = GetSelectionAt(e.Location, vg, ptrans); if (Selection != null && Site != null && Selection.Contains((InsertionPoint)sel) && SelectionCanBeDragged) { sel.Install(); SelectionCanBeDragged = false; } }
/// <summary> /// Return true if the argument (child) box and all subsequent boxes need not be painted, /// typically because they occur after the end of the clip rectangle specified in the VwGraphics. /// It is acceptable to answer false, if no clipping is wanted, or for the first box for which /// we answer true to be later than the optimal one; this is an optional optimization. /// </summary> internal virtual bool IsAfterVisibleBoxes(Box box, IVwGraphics vg, PaintTransform ptrans) { return false; }
/// <summary> /// Determine how far we need to scroll to make the current selection visible within the target rectangle /// (typically the clientRect of the view). Currently the goal is /// - if the selection is entirely within the rectangle return 0,0 (don't move) /// - otherwise if possible move the smallest distance that will put the selection at least 10 pixels /// inside the rectangle on both sides /// - if that is not possible move the smallest distance that will put the selection entirely inside the rectangle /// - if that is not possible move so that the primary rectangle of the IP at the DragEnd of the selection /// is inside the rectangle, at the top if it is the start and at the bottom if it is at the end. /// - if it is not possible to display even the primary rectangle of one IP, move so that equal amounts of it /// are above and below the rectangle. /// Eventually when we do horizontal scrolling the two directions will be independent. For example, even if we must move /// vertically, don't move horizontally to get the 10 pixel margin unless we must to see it at all. /// </summary> public void ScrollToShowSelection(IVwGraphics vg, PaintTransform ptrans, Rectangle targetRect, out int dx, out int dy) { dx = 0; dy = 0; if (Selection == null) return; var rect = Selection.GetSelectionLocation(vg, ptrans); if (rect.Top < targetRect.Top) { if (rect.Height < targetRect.Height - 2 * kMargin) dy = targetRect.Top - rect.Top + kMargin; else if (rect.Height < targetRect.Height) dy = targetRect.Top - rect.Top; else dy = targetRect.Top - rect.Top - (rect.Height - targetRect.Height) / 2; } else if (rect.Bottom > targetRect.Bottom) { if (rect.Height < targetRect.Height - 2 * kMargin) dy = targetRect.Bottom - rect.Bottom - kMargin; // negative result by kMargin more than difference. else if (rect.Height < targetRect.Height) dy = targetRect.Bottom - rect.Bottom; else dy = targetRect.Bottom - rect.Bottom + (rect.Height - targetRect.Height) / 2; } }
/// <summary> /// Places an insertion point within a ranged selection, only if the mouse down occured within the selection. /// OnMouseDown takes care of all other situations. /// </summary> public virtual void OnMouseClick(MouseEventArgs e, Keys keys, IVwGraphics vg, PaintTransform ptrans) { if (e.Button != MouseButtons.Left) { return; } var sel = GetSelectionAt(e.Location, vg, ptrans); if (Selection != null && Site != null && Selection.Contains((InsertionPoint)sel) && SelectionCanBeDragged) { sel.Install(); SelectionCanBeDragged = false; } }
/// <summary> /// Any box knows how to paint itself. Most subclasses should override. /// </summary> public virtual void PaintForeground(IVwGraphics vg, PaintTransform ptrans) { }
/// <summary> /// Since this IS the root, by definition the root transform is its transform. /// </summary> public override PaintTransform ChildTransformFromRootTransform(PaintTransform rootTransform) { return(rootTransform); }
/// <summary> /// This is basically the common logic of MouseDown and MouseMove, when the left mouse button is pressed. /// If makeRange is true, as for shift-click or mouse move, we try to move the drag end of a range; /// otherwise, we make the selection where it is. /// </summary> private void ExtendSelection(MouseEventArgs e, bool makeRange, IVwGraphics vg, PaintTransform ptrans) { // Enhance JohnT: if the new selection is exactly the same don't change it. var sel = GetSelectionAt(e.Location, vg, ptrans); if (!(sel is InsertionPoint)) { return; } ExtendSelection(sel, makeRange); }
/// <summary> /// Given the transform currently used to draw the root, give the transform used to draw your children. /// </summary> public virtual PaintTransform ChildTransformFromRootTransform(PaintTransform rootTransform) { // This terminates because the top of the box stack is always a RootBox, which overrides. return Container.ChildTransformFromRootTransform(rootTransform).PaintTransformOffsetBy(Left, Top); }
public override void PaintBackground(IVwGraphics vg, PaintTransform ptrans) { base.PaintBackground(vg, ptrans); PaintTransform childTrans = ptrans.PaintTransformOffsetBy(Left, Top); for (Box box = FirstVisibleBox(vg, ptrans); box != null && !IsAfterVisibleBoxes(box, vg, ptrans); box = box.Next) box.PaintBackground(vg, childTrans); }
public override void PaintForeground(IVwGraphics vg, PaintTransform ptrans) { base.PaintForeground(vg, ptrans); PaintTransform childTrans = ptrans.PaintTransformOffsetBy(Left, Top); for (Box box = FirstVisibleBox(vg, ptrans); box != null && !IsAfterVisibleBoxes(box, vg, ptrans); box = box.Next) { //vg.PushClipRect(new Rect(box.Left, box.Top, box.Right, box.Bottom)); box.PaintForeground(vg, childTrans); } }
/// <summary> /// If there is a leaf box at the specified position, return it. Also return the paint transform that should be /// passed to operations on that box. /// Enhance JohnT: should probably always return something, if box contains any leaf? /// Where is in drawing coords. /// </summary> public override LeafBox FindBoxAt(Point where, PaintTransform ptrans, out PaintTransform leafBoxTransform) { var childTransform = ptrans.PaintTransformOffsetBy(Left, Top); var hit = childTransform.ToLayout(where); Box best = null; // if we don't find a box containing the point, this is the closest on the same line. int bestDistance = int.MaxValue; for (Box current = FirstBox; current != null; current = current.Next) { // If we're not even on the current line, keep trying. if (hit.Y > current.Bottom) continue; if (hit.Y < current.Top) continue; // If it's within the borders of this box, return it unconditionally. if (hit.X <= current.Right && hit.X >= current.Left) return current.FindBoxAt(where, childTransform, out leafBoxTransform); // If we're on the right line, we'll return this if we don't find a better. int distance = hit.X - current.Right; if (hit.X < current.Left) distance = current.Left - hit.X; if (distance < bestDistance) { bestDistance = distance; best = current; } } if (best != null) return best.FindBoxAt(where, childTransform, out leafBoxTransform); leafBoxTransform = ptrans; // arbitrary. return null; }
/// <summary> /// If there is a leaf box at the specified position, return it. Also return the paint transform that should be /// passed to operations on that box. By default we return this if the point is inside the box, and the transform /// we are passed. /// Where is in drawing coords. /// Todo JohnT: verify the point actually is in the box. /// </summary> public virtual LeafBox FindBoxAt(Point where, PaintTransform ptrans, out PaintTransform leafBoxTransform) { leafBoxTransform = ptrans; return this as LeafBox; }
/// <summary> /// Returns information about possible drops with these arguments. /// </summary> public void OnDragEnter(DragEventArgs drgevent, Point location, IVwGraphics vg, PaintTransform ptrans) { if (DragState == WindowDragState.InternalMove) { // On a simple click (at least), Windows calls OnDragEnter AFTER OnQueryContinueDrag, attempting to drop // right where we clicked. OnQueryContinueDrag detects this; we must not reset it. return; } drgevent.Effect = DragDropEffects.None; // default var sel = GetSelectionAt(location, vg, ptrans) as InsertionPoint; if (sel == null) { return; } if (!sel.CanInsertText) { return; } var data = drgevent.Data.GetData(DataFormats.StringFormat); if (data == null) { return; } DragState = WindowDragState.DraggingHere; // We will copy if control is held down or move is not allowed.) if ((drgevent.KeyState & (int)DragDropKeyStates.ControlKey) != 0 || (drgevent.AllowedEffect & DragDropEffects.Move) == 0) { //Log("DragEnter/Move: set effect to copy"); drgevent.Effect = DragDropEffects.Copy; } else { //Log("DragEnter/Move: set effect to move"); drgevent.Effect = DragDropEffects.Move; } }
/// <summary> /// Return the first box that actually needs to be painted, that is, that intersects the /// clip rectangle specified in the VwGraphics. It is acceptable to answer the FirstBox, /// as here, if clipping is not needed; this is an optional optimization. /// </summary> internal virtual Box FirstVisibleBox(IVwGraphics vg, PaintTransform ptrans) { return FirstBox; }
/// <summary> /// Any box knows how to paint its background. Some subclasses may override. /// </summary> public virtual void PaintBackground(IVwGraphics vg, PaintTransform ptrans) { if (BorderTop == 0 && BorderBottom == 0 && BorderLeading == 0 && BorderTrailing == 0 && Style.BackColor.ToArgb() == Color.Transparent.ToArgb()) return; // Margin thicknesses int dxsMLeft = ptrans.MpToPixelsX(Style.Margins.LeadingMp); int dysMTop = ptrans.MpToPixelsY(Style.Margins.TopMp); int dxsMRight = ptrans.MpToPixelsX(Style.Margins.TrailingMp); int dysMBottom = ptrans.MpToPixelsY(Style.Margins.BottomMp); SwapIfRightToLeft(ref dxsMLeft, ref dxsMRight); // outside of border rectangle int xdLeftBord = ptrans.ToPaintX(dxsMLeft + Left); int ydTopBord = ptrans.ToPaintY(dysMTop + Top); int xdRightBord = ptrans.ToPaintX(Right - dxsMRight); int ydBottomBord = ptrans.ToPaintY(Bottom - dysMBottom); // Border thickness in pixels. int dxdLeftBord = ptrans.MpToBorderPixelsX(BorderLeading); int dydTopBord = ptrans.MpToBorderPixelsY(BorderTop); int dxdRightBord = ptrans.MpToBorderPixelsX(BorderTrailing); int dydBottomBord = ptrans.MpToBorderPixelsY(BorderBottom); SwapIfRightToLeft(ref dxdLeftBord, ref dxdRightBord); // inside of border rectangle, outside of pad rectangle int xdLeftPad = xdLeftBord + dxdLeftBord; int ydTopPad = ydTopBord + dydTopBord; int xdRightPad = xdRightBord - dxdRightBord; int ydBottomPad = ydBottomBord - dydBottomBord; // Wanted this in the old Views version, not sure if it may become relevant here. //// no pad, border, or margin to left of extension box. //if (IsBoxFromTsString()) // xdLeftPad = xdLeftBord = rcSrc.MapXTo(m_xsLeft, rcDst); //// no pad, border, or margin to right of box followed by //// extension //if (m_pboxNext && m_pboxNext->IsBoxFromTsString()) // xdRightPad = xdRightBord = rcSrc.MapXTo(m_xsLeft + m_dxsWidth, rcDst); // Draw background if (Style.BackColor.ToArgb() != Color.Transparent.ToArgb()) { vg.BackColor = (int) ColorUtil.ConvertColorToBGR(Style.BackColor); vg.DrawRectangle(xdLeftPad, ydTopPad, xdRightPad, ydBottomPad); } // Draw border lines. We initially set the background color because we draw the // borders using rectangles, and DrawRectangle uses the background color vg.BackColor = (int) ColorUtil.ConvertColorToBGR(Style.BorderColor); if (xdLeftPad != xdLeftBord) vg.DrawRectangle(xdLeftBord, ydTopBord, xdLeftPad, ydBottomBord); if (ydTopBord != ydTopPad) vg.DrawRectangle(xdLeftBord, ydTopBord, xdRightBord, ydTopPad); if (xdRightPad != xdRightBord) vg.DrawRectangle(xdRightPad, ydTopBord, xdRightBord, ydBottomBord); if (ydBottomPad != ydBottomBord) vg.DrawRectangle(xdLeftBord, ydBottomPad, xdRightBord, ydBottomBord); }
/// <summary> /// Implement dragging to this view. /// </summary> public void OnDragDrop(DragEventArgs drgevent, Point location, IVwGraphics vg, PaintTransform ptrans) { var sel = GetSelectionAt(location, vg, ptrans) as InsertionPoint; if (sel == null) { return; } var rtf = drgevent.Data.GetData(DataFormats.Rtf); var data = drgevent.Data.GetData(DataFormats.StringFormat); if (data == null) { return; } var text = data.ToString(); // MS example of GetData does this, though for DataFormats.Text. if (DragState == WindowDragState.InternalMove) { DragState = WindowDragState.None; // We are dragging our own selection. Is it in the same property? var range = (RangeSelection)Selection; // Enhance JohnT: when we can drag a range that isn't all in one property, this needs more work. if (!Selection.IsInsertionPoint) { if (Selection.Contains(sel)) { Selection = sel; return; // Can't drag to inside own selection. } } if (range.End.Hookup == sel.Hookup && range.End.StringPosition < sel.StringPosition) { // Dragging to later in the same property. If we delete first, we will mess up the insert // position. However, a simple solution is to insert first. //Log("Inserted dropped " + text + " before deleted range"); if (rtf == null) { sel.InsertText(text); } else if (!sel.InsertRtfString(rtf.ToString())) { sel.InsertText(text); } range.Delete(); return; } // The bit we're moving comes after the place to insert, or they are in separate properties. // We can just go ahead and delete the source first, since we already have a copy of the // text to insert. // Enhance JohnT: do we need to consider a special case where the source and destination are // different occurrences of the same property? //Log("Deleted selection"); range.Delete(); } DragState = WindowDragState.None; //Log("Dropped text: " + text); if (rtf == null) { sel.InsertText(text); } else if (!sel.InsertRtfString(rtf.ToString())) { sel.InsertText(text); } }
/// <summary> /// Since this IS the root, by definition the root transform is its transform. /// </summary> public override PaintTransform ChildTransformFromRootTransform(PaintTransform rootTransform) { return rootTransform; }
/// <summary> /// Return the first box that actually needs to be painted, that is, that intersects the /// clip rectangle specified in the VwGraphics. It is acceptable to answer the FirstBox, /// as here, if clipping is not needed; this is an optional optimization. /// </summary> internal virtual Box FirstVisibleBox(IVwGraphics vg, PaintTransform ptrans) { return(FirstBox); }
/// <summary> /// Places an insertion point unless it would be placed within a ranged selection. Also determines sets whether /// the mouse down occured within a ranged selection, so that OnMouseMove can know if it can drag and so that /// OnMouseClick can know if can place an insertion point within the ranged selection. /// </summary> public virtual void OnMouseDown(MouseEventArgs e, Keys keys, IVwGraphics vg, PaintTransform ptrans) { if (e.Button != MouseButtons.Left) return; var sel = GetSelectionAt(e.Location, vg, ptrans); if (!(sel is InsertionPoint)) { return; } // Site is unlikely to be null in real life but it makes the code a little more robust // simplifies testing. if (Selection != null && Site != null && Selection.Contains((InsertionPoint)sel)) { SelectionCanBeDragged = true; return; } SelectionCanBeDragged = false; ExtendSelection(sel, (keys & Keys.Shift) == Keys.Shift); }
/// <summary> /// Return true if the argument (child) box and all subsequent boxes need not be painted, /// typically because they occur after the end of the clip rectangle specified in the VwGraphics. /// It is acceptable to answer false, if no clipping is wanted, or for the first box for which /// we answer true to be later than the optimal one; this is an optional optimization. /// </summary> internal virtual bool IsAfterVisibleBoxes(Box box, IVwGraphics vg, PaintTransform ptrans) { return(false); }
/// <summary> /// Allows for text to be selected and dragged. This method starts the drag instead of OnMouseDown because once /// the drag is started, OnMouseClick/DoubleClick is overridden. OnMouseDown would start the drag too early. /// </summary> public virtual void OnMouseMove(MouseEventArgs e, Keys keys, IVwGraphics vg, PaintTransform ptrans) { if (e.Button != MouseButtons.Left) return; var sel = GetSelectionAt(e.Location, vg, ptrans); // Site is unlikely to be null in real life but it makes the code a little more robust // simplifies testing. if (Selection != null && Site != null && Selection.Contains((InsertionPoint)sel) && SelectionCanBeDragged) { DragState = WindowDragState.DraggingHere; Site.DoDragDrop(Selection.DragDropData, DragDropEffects.Copy); SelectionCanBeDragged = false; return; } ExtendSelection(e, true, vg, ptrans); }
/// <summary> /// Given the transform currently used to draw the root, give the transform used to draw your children. /// </summary> public virtual PaintTransform ChildTransformFromRootTransform(PaintTransform rootTransform) { // This terminates because the top of the box stack is always a RootBox, which overrides. return(Container.ChildTransformFromRootTransform(rootTransform).PaintTransformOffsetBy(Left, Top)); }
/// <summary> /// Returns information about possible drops with these arguments. /// </summary> public void OnDragEnter(DragEventArgs drgevent, Point location, IVwGraphics vg, PaintTransform ptrans) { if (DragState == WindowDragState.InternalMove) { // On a simple click (at least), Windows calls OnDragEnter AFTER OnQueryContinueDrag, attempting to drop // right where we clicked. OnQueryContinueDrag detects this; we must not reset it. return; } drgevent.Effect = DragDropEffects.None; // default var sel = GetSelectionAt(location, vg, ptrans) as InsertionPoint; if (sel == null) return; if (!sel.CanInsertText) return; var data = drgevent.Data.GetData(DataFormats.StringFormat); if (data == null) return; DragState = WindowDragState.DraggingHere; // We will copy if control is held down or move is not allowed.) if ((drgevent.KeyState & (int)DragDropKeyStates.ControlKey) != 0 || (drgevent.AllowedEffect & DragDropEffects.Move) == 0) { //Log("DragEnter/Move: set effect to copy"); drgevent.Effect = DragDropEffects.Copy; } else { //Log("DragEnter/Move: set effect to move"); drgevent.Effect = DragDropEffects.Move; } }
/// <summary> /// Make whatever selection is appropriate for the given click. The transformation is the usual one passed to this box, /// that is, it transforms where (which is in paint coords) into a point in the same coordinate system as our own top, left. /// </summary> internal virtual Selections.Selection MakeSelectionAt(Point where, IVwGraphics vg, PaintTransform leafTrans) { return(null); }
/// <summary> /// The root box handles the overall paint. /// </summary> /// <param name="vg"></param> /// <param name="ptrans"></param> public void Paint(IVwGraphics vg, PaintTransform ptrans) { if (m_layoutCallbacks != null) { // In a state where we can't paint. Arrange for an invalidate AFTER the dangerous operation is over, // so what needs painting eventually does get painted. var bounds = Bounds; bounds.Inflate(10, 10); m_layoutCallbacks.Invalidate(bounds); return; } // First we paint the overall background. This basically covers everything but text. PaintBackground(vg, ptrans); // Then the text. PaintForeground(vg, ptrans); // And finally the selection. if (Selection != null && m_selectionShowing) { if (Selection.IsValid) Selection.Draw(vg, ptrans); else Selection = null; } }
/// <summary> /// Answer the first box whose bottom comes below the top of the clip rectangle. /// Enhance JohnT: Could refine this to skip a box if only its margin is visible. /// Enhance JohnT: if we do separate page drawing, as in print preview, we may need /// a more precise way to eliminate boxes not on the page. /// Enhance JohnT: may need to include a box that is just out of sight, in case exceptionally /// long descenders or stacked diacritics extend below the bottom of the box? /// </summary> internal override Box FirstVisibleBox(IVwGraphics vg, PaintTransform ptrans) { int left, top, right, bottom; vg.GetClipRect(out left, out top, out right, out bottom); for (Box box = FirstBox; box != null; box = box.Next) if (ptrans.ToPaintY(box.Bottom) > top) return box; return null; }
/// <summary> /// Any box knows how to paint its background. Some subclasses may override. /// </summary> public virtual void PaintBackground(IVwGraphics vg, PaintTransform ptrans) { if (BorderTop == 0 && BorderBottom == 0 && BorderLeading == 0 && BorderTrailing == 0 && Style.BackColor.ToArgb() == Color.Transparent.ToArgb()) { return; } // Margin thicknesses int dxsMLeft = ptrans.MpToPixelsX(Style.Margins.LeadingMp); int dysMTop = ptrans.MpToPixelsY(Style.Margins.TopMp); int dxsMRight = ptrans.MpToPixelsX(Style.Margins.TrailingMp); int dysMBottom = ptrans.MpToPixelsY(Style.Margins.BottomMp); SwapIfRightToLeft(ref dxsMLeft, ref dxsMRight); // outside of border rectangle int xdLeftBord = ptrans.ToPaintX(dxsMLeft + Left); int ydTopBord = ptrans.ToPaintY(dysMTop + Top); int xdRightBord = ptrans.ToPaintX(Right - dxsMRight); int ydBottomBord = ptrans.ToPaintY(Bottom - dysMBottom); // Border thickness in pixels. int dxdLeftBord = ptrans.MpToBorderPixelsX(BorderLeading); int dydTopBord = ptrans.MpToBorderPixelsY(BorderTop); int dxdRightBord = ptrans.MpToBorderPixelsX(BorderTrailing); int dydBottomBord = ptrans.MpToBorderPixelsY(BorderBottom); SwapIfRightToLeft(ref dxdLeftBord, ref dxdRightBord); // inside of border rectangle, outside of pad rectangle int xdLeftPad = xdLeftBord + dxdLeftBord; int ydTopPad = ydTopBord + dydTopBord; int xdRightPad = xdRightBord - dxdRightBord; int ydBottomPad = ydBottomBord - dydBottomBord; // Wanted this in the old Views version, not sure if it may become relevant here. //// no pad, border, or margin to left of extension box. //if (IsBoxFromTsString()) // xdLeftPad = xdLeftBord = rcSrc.MapXTo(m_xsLeft, rcDst); //// no pad, border, or margin to right of box followed by //// extension //if (m_pboxNext && m_pboxNext->IsBoxFromTsString()) // xdRightPad = xdRightBord = rcSrc.MapXTo(m_xsLeft + m_dxsWidth, rcDst); // Draw background if (Style.BackColor.ToArgb() != Color.Transparent.ToArgb()) { vg.BackColor = (int)ColorUtil.ConvertColorToBGR(Style.BackColor); vg.DrawRectangle(xdLeftPad, ydTopPad, xdRightPad, ydBottomPad); } // Draw border lines. We initially set the background color because we draw the // borders using rectangles, and DrawRectangle uses the background color vg.BackColor = (int)ColorUtil.ConvertColorToBGR(Style.BorderColor); if (xdLeftPad != xdLeftBord) { vg.DrawRectangle(xdLeftBord, ydTopBord, xdLeftPad, ydBottomBord); } if (ydTopBord != ydTopPad) { vg.DrawRectangle(xdLeftBord, ydTopBord, xdRightBord, ydTopPad); } if (xdRightPad != xdRightBord) { vg.DrawRectangle(xdRightPad, ydTopBord, xdRightBord, ydBottomBord); } if (ydBottomPad != ydBottomBord) { vg.DrawRectangle(xdLeftBord, ydBottomPad, xdRightBord, ydBottomBord); } }
/// <summary> /// Answer true if the box is entirely below the clip rectangle. /// Enhance JohnT: Could refine this to skip a box if only its margin is visible. /// Enhance JohnT: if we do separate page drawing, as in print preview, we may need /// a more precise way to eliminate boxes not on the page. /// Enhance JohnT: may need to include a box that is just out of sight, in case exceptionally /// high stacked diacritics extend above the top of the box? /// </summary> internal override bool IsAfterVisibleBoxes(Box box, IVwGraphics vg, PaintTransform ptrans) { int left, top, right, bottom; vg.GetClipRect(out left, out top, out right, out bottom); return ptrans.ToPaintY(box.Top) > bottom; }
/// <summary> /// Make whatever selection is appropriate for the given click. The transformation is the usual one passed to this box, /// that is, it transforms where (which is in paint coords) into a point in the same coordinate system as our own top, left. /// </summary> internal virtual Selections.Selection MakeSelectionAt(Point where, IVwGraphics vg, PaintTransform leafTrans) { return null; }
public Selection GetSelectionAt(Point where, IVwGraphics vg, PaintTransform ptrans) { PaintTransform leafTrans; var targetBox = FindBoxAt(where, ptrans, out leafTrans); if (targetBox == null) return null; // TODO: possibly try surrounding points? return targetBox.MakeSelectionAt(where, vg, leafTrans); }