/// <summary> /// The index of the first beat determined by which starting point produces a sequence of highest intensity /// </summary> /// <param name="spec">Spectrogram data</param> /// <param name="del">How far between beats</param> /// <returns>First beat index</returns> public static int firstbeatindex(RangeSelection <double> spec, double del) { int highestindex = 0; double highestsum = 0; int len = spec.Length; for (int i = 0; i < del; i++) { double sum = 0; int index = i; int x = 0; while (index < len) { sum += spec[index]; x++; index = (int)Math.Round(i + x * del); } if (sum > highestsum) { highestsum = sum; highestindex = i; } } return(highestindex); }
public void MakeSimpleRange() { ParaBox para; RootBox root = ParaBuilderTests.MakeTestParaSimpleString(m_gm.VwGraphics, ParaBuilderTests.MockBreakOption.ThreeFullLines, out para); InsertionPoint ip = root.SelectAtEnd(); InsertionPoint ip2 = new InsertionPoint(ip.Hookup, ip.StringPosition - 2, false); RangeSelection range = new RangeSelection(ip, ip2); Assert.AreEqual(ip, range.Anchor); Assert.AreEqual(ip2, range.DragEnd); Assert.That(range.EndBeforeAnchor, Is.True); Assert.That(range.Start, Is.EqualTo(ip2)); Assert.That(range.End, Is.EqualTo(ip)); StringBox first = para.FirstBox as StringBox; StringBox second = para.FirstBox.Next as StringBox; StringBox third = second.Next as StringBox; MockSegment seg3 = third.Segment as MockSegment; seg3.DrawRangeLeft = 17; seg3.DrawRangeRight = 23; PaintTransform ptrans = new PaintTransform(2, 4, 96, 100, 0, 10, 120, 128); range.Draw(m_gm.VwGraphics, ptrans); // All three segments should be invited to draw it, though only one will. // The top of rsSrc gets more negative each line; the destination rectangle where we actually draw keeps getting lower. // Remember the effect of 10 pixels of scroll offset. VerifyRangeSegmentDrawing(para, first, first.Segment as MockSegment, range, -4, -6, 4); VerifyRangeSegmentDrawing(para, second, second.Segment as MockSegment, range, -14, 4, 14); VerifyRangeSegmentDrawing(para, third, seg3, range , -24, 14, 24); }
private void VerifyRangeSegmentDrawing(ParaBox para, StringBox stringBox, RangeSelection range, int top, int ydTop, int bottom) { var seg = stringBox.Segment as FakeSegment; Assert.AreEqual(stringBox.IchMin, seg.LastDrawRangeCall.IchBase); Assert.AreEqual(m_gm.VwGraphics, seg.LastDrawRangeCall.Graphics); int startPosition = range.Start.StringPosition; if (range.Start.Para != stringBox.Container) // If we're painting this string box but it isn't in the start paragraph, { startPosition = 0; // the we paint from the start of it. } Assert.AreEqual(startPosition, seg.LastDrawRangeCall.IchMin); var endPosition = range.End.StringPosition; if (range.End.Para != stringBox.Container) // If we're painting this string box but it isn't in the end paragraph, { endPosition = ((ParaBox)stringBox.Container).Source.RenderText.Length; // then we paint to the end of the paragraph. } Assert.AreEqual(endPosition, seg.LastDrawRangeCall.IchLim); ParaTests.VerifySimpleRect(seg.LastDrawRangeCall.RcSrc, -2, top, 96, 96); ParaTests.VerifySimpleRect(seg.LastDrawRangeCall.RcDst, 0, 0, 96, 96); Assert.AreEqual(ydTop, seg.LastDrawRangeCall.YdTop); Assert.AreEqual(bottom, seg.LastDrawRangeCall.YdBottom); Assert.AreEqual(seg.LastDrawRangeCall.On, true, "Should currently always pass true to segment drawRange On argument"); // The old Views code appears to always pass true for this argument, so we should too, until I figure out what it's // really supposed to be, if anything. Assert.AreEqual(true, seg.LastDrawRangeCall.IsLastLineOfSelection); }
public void MakeSimpleRange() { ParaBox para; RootBox root = ParaBuilderTests.MakeTestParaSimpleString(m_gm.VwGraphics, ParaBuilderTests.MockBreakOption.ThreeFullLines, out para); InsertionPoint ip = root.SelectAtEnd(); InsertionPoint ip2 = new InsertionPoint(ip.Hookup, ip.StringPosition - 2, false); RangeSelection range = new RangeSelection(ip, ip2); Assert.AreEqual(ip, range.Anchor); Assert.AreEqual(ip2, range.DragEnd); Assert.That(range.EndBeforeAnchor, Is.True); Assert.That(range.Start, Is.EqualTo(ip2)); Assert.That(range.End, Is.EqualTo(ip)); StringBox first = para.FirstBox as StringBox; StringBox second = para.FirstBox.Next as StringBox; StringBox third = second.Next as StringBox; MockSegment seg3 = third.Segment as MockSegment; seg3.DrawRangeLeft = 17; seg3.DrawRangeRight = 23; PaintTransform ptrans = new PaintTransform(2, 4, 96, 100, 0, 10, 120, 128); range.Draw(m_gm.VwGraphics, ptrans); // All three segments should be invited to draw it, though only one will. // The top of rsSrc gets more negative each line; the destination rectangle where we actually draw keeps getting lower. // Remember the effect of 10 pixels of scroll offset. VerifyRangeSegmentDrawing(para, first, first.Segment as MockSegment, range, -4, -6, 4); VerifyRangeSegmentDrawing(para, second, second.Segment as MockSegment, range, -14, 4, 14); VerifyRangeSegmentDrawing(para, third, seg3, range, -24, 14, 24); }
public virtual bool InsertFollowingParagraph(RangeSelection range, out Action makeSelection) { int index = ItemIndex(range.Start) + 1; DeleteItems(range.Start.StringPosition, range.End.StringPosition); MakeListItem(index, false); makeSelection = () => SelectionBuilder.In(Hookup)[index].Offset(0).Install(); return(true); }
public static byte Max(this RangeSelection <byte> r) { byte max = byte.MinValue; for (int i = 0; i < r.Length; ++i) { max = Math.Max(max, r[i]); } return(max); }
public static ushort Max(this RangeSelection <ushort> r) { ushort max = ushort.MinValue; for (int i = 0; i < r.Length; ++i) { max = Math.Max(max, r[i]); } return(max); }
public static uint Sum(this RangeSelection <uint> r) { uint sum = 0; for (int i = 0; i < r.Length; ++i) { sum += r[i]; } return(sum); }
public static byte Min(this RangeSelection <byte> r) { byte min = byte.MaxValue; for (int i = 0; i < r.Length; ++i) { min = Math.Min(min, r[i]); } return(min); }
public static ushort Min(this RangeSelection <ushort> r) { ushort min = ushort.MaxValue; for (int i = 0; i < r.Length; ++i) { min = Math.Min(min, r[i]); } return(min); }
public static ulong Min(this RangeSelection <ulong> r) { ulong min = ulong.MaxValue; for (int i = 0; i < r.Length; ++i) { min = Math.Min(min, r[i]); } return(min); }
public static int Min(this RangeSelection <int> r) { int min = int.MaxValue; for (int i = 0; i < r.Length; ++i) { min = Math.Min(min, r[i]); } return(min); }
public static decimal Min(this RangeSelection <decimal> r) { decimal min = decimal.MaxValue; for (int i = 0; i < r.Length; ++i) { min = Math.Min(min, r[i]); } return(min); }
public static double Min(this RangeSelection <double> r) { double min = double.MaxValue; for (int i = 0; i < r.Length; ++i) { min = Math.Min(min, r[i]); } return(min); }
public static float Min(this RangeSelection <float> r) { float min = float.MaxValue; for (int i = 0; i < r.Length; ++i) { min = Math.Min(min, r[i]); } return(min); }
public static double Sum(this RangeSelection <double> r) { double sum = 0; for (int i = 0; i < r.Length; ++i) { sum += r[i]; } return(sum); }
public static decimal Sum(this RangeSelection <decimal> r) { decimal sum = 0; for (int i = 0; i < r.Length; ++i) { sum += r[i]; } return(sum); }
public static float Max(this RangeSelection <float> r) { float max = float.MinValue; for (int i = 0; i < r.Length; ++i) { max = Math.Max(max, r[i]); } return(max); }
/// <summary> /// Move the selection at the position specified by RangeSelection and filename /// Still depends on TheoFx to set the window to the foreground. /// </summary> /// <param name="click">Position where to move the cursor.</param> public static void moveSelectionTo(RangeSelection click, String filename) { // Globals.ThisAddIn.Application.Workbooks[click.] string sheet = click.Sheet; Microsoft.Office.Interop.Excel.Workbook wb = Globals.ThisAddIn.Application.Workbooks[filename.Substring(filename.LastIndexOf("/") + 1)]; Microsoft.Office.Interop.Excel.Worksheet ws = wb.Sheets[sheet]; ws.Select(); Microsoft.Office.Interop.Excel.Range range = wb.Sheets[sheet].Cells[click.StartRow + 1, click.StartCol + 1]; // Globals.ThisAddIn.Application.ActiveSheet.Cells[click.StartRow + 1, click.StartCol + 1].Select(); range.Select(); range.Activate(); }
public static double Max(this RangeSelection <double> r) { double max = double.MinValue; for (int i = 0; i < r.Length; ++i) { max = Math.Max(max, r[i]); } return(max); }
public static decimal Max(this RangeSelection <decimal> r) { decimal max = decimal.MinValue; for (int i = 0; i < r.Length; ++i) { max = Math.Max(max, r[i]); } return(max); }
public static int Max(this RangeSelection <int> r) { int max = int.MinValue; for (int i = 0; i < r.Length; ++i) { max = Math.Max(max, r[i]); } return(max); }
public static byte Sum(this RangeSelection <byte> r) { byte sum = 0; for (int i = 0; i < r.Length; ++i) { sum += r[i]; } return(sum); }
public static ulong Max(this RangeSelection <ulong> r) { ulong max = ulong.MinValue; for (int i = 0; i < r.Length; ++i) { max = Math.Max(max, r[i]); } return(max); }
public static long Sum(this RangeSelection <long> r) { long sum = 0; for (int i = 0; i < r.Length; ++i) { sum += r[i]; } return(sum); }
/// <summary> /// Get the location where a range selection is drawn within this paragraph. This is a rectangle that contains /// anything this paragraph draws for DrawRange with the same arguments. It is not critical that it contains /// nothing more, but is important that it contains nothing less. It should be fairly close (e.g., close enough /// to estimate a scroll position to show the selection). This rectangle may need to be combined with those /// from other paragraphs involved in a selection to get a rectangle covering the whole selection. /// </summary> internal Rectangle GetRangeLocation(RangeSelection sel, IVwGraphics vg1, PaintTransform ptrans) { var bounds = new Rect(); bool first = true; DoRangePaintingOp(sel, vg1, ptrans, (box, vg, childTrans, top, bottom, ichMin, ichLim) => { first = GetRangeLocationInBox(box, vg, childTrans, top, bottom, ichMin, ichLim, first, ref bounds); }); return(new Rectangle(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top)); }
public void DragStartsOnMoveInSelection() { string contents = "This is the day."; var engine = new FakeRenderEngine() {Ws = 34, SegmentHeight = 13}; var factory = new FakeRendererFactory(); factory.SetRenderer(34, engine); var styles = new AssembledStyles().WithWs(34); var clientRuns = new List<IClientRun>(); var run = new StringClientRun(contents, styles); clientRuns.Add(run); var source = new TextSource(clientRuns, null); var para = new ParaBox(styles, source); var extraBox = new BlockBox(styles, Color.Red, 50, 72000); // tall, narrow spacer at top var root = new RootBoxFdo(styles); root.AddBox(extraBox); root.AddBox(para); var layoutArgs = MakeLayoutInfo(Int32.MaxValue/2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); Assert.That(root.Height, Is.EqualTo(96 + 13)); Assert.That(root.Width, Is.EqualTo(FakeRenderEngine.SimulatedWidth(contents))); var ip1 = run.SelectAt(para, 5, false); var ip2 = run.SelectAt(para, 7, true); var range = new RangeSelection(ip1, ip2); range.Install(); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); var sbox = para.FirstBox as StringBox; MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; int indent = FakeRenderEngine.SimulatedWidth("This "); root.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, indent + 5, 100, 0), Keys.None, m_gm.VwGraphics, ptrans); root.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 1, indent + 5, 100, 0), Keys.None, m_gm.VwGraphics, ptrans); Assert.That(GetStringDropData(site), Is.EqualTo("is")); Assert.That(site.LastDoDragDropArgs.AllowedEffects, Is.EqualTo(DragDropEffects.Copy), "editing not possible in this paragraph, we can only copy"); Assert.That(root.Selection, Is.EqualTo(range), "selection should not be changed by drag drop"); site.LastDoDragDropArgs = null; root.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 3, 100, 0), Keys.None, m_gm.VwGraphics, ptrans); Assert.That(site.LastDoDragDropArgs, Is.Null, "click outside selection should not initiate drag"); // Tack on an extra check that a read-only view does not handle drop. var dataObj = new DataObject(DataFormats.StringFormat, "new "); var dragArgs = new DragEventArgs(dataObj, (int)DragDropKeyStates.ControlKey, 10, 8, DragDropEffects.Copy | DragDropEffects.Move, DragDropEffects.None); root.OnDragEnter(dragArgs, new Point(14, 8), m_gm.VwGraphics, ptrans); Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.None)); Assert.That(root.DragState, Is.EqualTo(WindowDragState.DraggingHere)); }
private void VerifyRangeSegmentDrawing(ParaBox para, StringBox stringBox, MockSegment seg, RangeSelection range, int top, int ydTop, int bottom) { Assert.AreEqual(stringBox.IchMin, seg.LastDrawRangeCall.IchBase); Assert.AreEqual(m_gm.VwGraphics, seg.LastDrawRangeCall.Graphics); Assert.AreEqual(range.Start.StringPosition, seg.LastDrawRangeCall.IchMin); Assert.AreEqual(range.End.StringPosition, seg.LastDrawRangeCall.IchLim); ParaTests.VerifySimpleRect(seg.LastDrawRangeCall.RcSrc, -2, top, 96, 100); ParaTests.VerifySimpleRect(seg.LastDrawRangeCall.RcDst, 0, -10, 120, 128); Assert.AreEqual(ydTop, seg.LastDrawRangeCall.YdTop); Assert.AreEqual(bottom, seg.LastDrawRangeCall.YdBottom); Assert.AreEqual(seg.LastDrawRangeCall.On, true, "Should currently always pass true to segment drawRange On argument"); // The old Views code appears to always pass true for this argument, so we should too, until I figure out what it's // really supposed to be, if anything. Assert.AreEqual(true, seg.LastDrawRangeCall.IsLastLineOfSelection); }
public void GetMinAndMaxForNamedItemsFromAttributesSelector() { var result = new RangeSelection(); result.Maximum = 92; result.Minimum = 66; mockRangeDataSelector.Setup(s => s.SelectFrom(TableNameConstants.Collections.Set.ChargeLimits, "name")).Returns(result); SetUpRoll(66, 92, 9266); var charges = generator.GenerateFor(string.Empty, "name"); Assert.That(charges, Is.EqualTo(9266)); }
// Do a range-painting operation (actual painting, or measuring, which involve much of the same work // except for the innermost step) for a given range selection. private void DoRangePaintingOp(RangeSelection range, IVwGraphics vg, PaintTransform ptrans, RangePaintingOp op) { int ichMin = range.Start.RenderParaPosition; // appropriate if the selection starts in THIS paragraph int ichLim = range.End.RenderParaPosition; // appropriate if the selection ends in THIS paragraph if (range.Start.Para != this) { ichMin = 0; // It presumably starts before this paragraph, or it would not have been asked to draw it } if (range.End.Para != this) { ichLim = Source.Length; // It presumably ends after this paragraph, or it would not have been asked to draw it. } DoRangePaintingOp(ichMin, ichLim, vg, ptrans, op); }
public RangeSelection SelectFrom(string tableName, string name) { var data = innerSelector.SelectFrom(tableName, name).ToArray(); if (data.Count() != 2) { throw new Exception("Data is not in format for range"); } var selection = new RangeSelection(); selection.Minimum = Convert.ToInt32(data[DataIndexConstants.Range.Minimum]); selection.Maximum = Convert.ToInt32(data[DataIndexConstants.Range.Maximum]); return(selection); }
public TextArea(TentacleControl panel_) : base() { panel = panel_; Paint += new PaintEventHandler(Contents_Paint); MouseDown += new MouseEventHandler(Me_MouseDown); MouseMove += new MouseEventHandler(Me_MouseMove); MouseUp += new MouseEventHandler(Me_MouseUp); MouseWheel += new MouseEventHandler(Me_MouseWheel); KeyDown += new KeyEventHandler(Me_KeyDown); KeyPress += new KeyPressEventHandler(Me_KeyPressed); SizeChanged += new EventHandler(Me_Resize); GotFocus += new EventHandler(FocusGained); LostFocus += new EventHandler(FocusLost); backgroundTimer = new Timer(); backgroundTimer.Tick += new EventHandler(Me_Background); backgroundTimer.Interval = 50; backgroundTimer.Start(); EventHandler clicky = new EventHandler(this.MenuClick); ContextMenu = new ContextMenu(); ContextMenu.MenuItems.Clear(); ContextMenu.MenuItems.Add(new MenuItem("Undo", clicky)); ContextMenu.MenuItems.Add(new MenuItem("Redo", clicky)); ContextMenu.MenuItems.Add(new MenuItem("-", clicky)); ContextMenu.MenuItems.Add(new MenuItem("Cut", clicky)); ContextMenu.MenuItems.Add(new MenuItem("Copy", clicky)); ContextMenu.MenuItems.Add(new MenuItem("Paste", clicky)); ContextMenu.MenuItems.Add(new MenuItem("Delete", clicky)); ContextMenu.MenuItems.Add(new MenuItem("-", clicky)); ContextMenu.MenuItems.Add(new MenuItem("Select All", clicky)); tv = new TextView(); sr = new RangeSelection(); //SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true); SetStyle(ControlStyles.ResizeRedraw | ControlStyles.Opaque | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true); }
/// <summary> /// Replace the text in the range, presumed to extend across more than one paragraph, /// with the supplied text. /// This one serves also for backspace at start of paragraph and delete at end, since /// these can readily be transformed into deleting a range from the end of one para /// to the start of the next. The given range is replace by a simple string. /// Enhance JohnT: it would probably make sense to break this up, more like SplitParagraph, /// into further virtual methods that subclasses could override. But I haven't figured out how yet. /// </summary> public bool InsertString(RangeSelection range, string insert, out Action makeSelection) { makeSelection = () => DoNothing(); // a default. var firstIp = range.Start; var lastIp = range.End; int firstItemIndex = ItemIndex(firstIp); int lastItemIndex = ItemIndex(lastIp); if (firstItemIndex == lastItemIndex) { throw new ArgumentException("Should not need to use ParagraphOps.InsertString for range in same item"); } int startPosition = firstIp.StringPosition; if (!MergeTextAfterSecondIntoFirst(firstIp, lastIp, insert)) { return(false); } DeleteItems(firstItemIndex + 1, lastItemIndex); makeSelection = () => SelectionBuilder.In(Hookup)[firstItemIndex].Offset(startPosition + insert.Length).Install(); return(true); }
private void ExtendSelection(Selection sel, bool makeRange) { var dragEnd = sel as InsertionPoint; var oldIP = Selection as InsertionPoint; if (dragEnd.SameLocation(oldIP)) { if (oldIP.AssociatePrevious == dragEnd.AssociatePrevious) { return; } // otherwise, keep sel, we want to install it because the direction changed. // But don't even think about changing it to a range. } else if (makeRange && Selection != null) { // See if we can make a range selection based on the old anchor and new dragEnd. var start = Selection as InsertionPoint; if (Selection is RangeSelection) { var range = (RangeSelection)Selection; if (range.DragEnd.Para == dragEnd.Para && range.DragEnd.LogicalParaPosition == dragEnd.LogicalParaPosition) { return; } start = range.Anchor; } if (start != null && !start.SameLocation(dragEnd)) { sel = new RangeSelection(start, dragEnd); } // If they ARE the same location, replace the range with the new (IP) selection. } if (sel != null) { sel.Install(); } }
private void VerifyRangeSegmentDrawing(ParaBox para, StringBox stringBox, RangeSelection range, int top, int ydTop, int bottom) { var seg = stringBox.Segment as FakeSegment; Assert.AreEqual(stringBox.IchMin, seg.LastDrawRangeCall.IchBase); Assert.AreEqual(m_gm.VwGraphics, seg.LastDrawRangeCall.Graphics); int startPosition = range.Start.StringPosition; if (range.Start.Para != stringBox.Container)// If we're painting this string box but it isn't in the start paragraph, startPosition = 0; // the we paint from the start of it. Assert.AreEqual(startPosition, seg.LastDrawRangeCall.IchMin); var endPosition = range.End.StringPosition; if (range.End.Para != stringBox.Container) // If we're painting this string box but it isn't in the end paragraph, endPosition = ((ParaBox) stringBox.Container).Source.RenderText.Length; // then we paint to the end of the paragraph. Assert.AreEqual(endPosition, seg.LastDrawRangeCall.IchLim); ParaTests.VerifySimpleRect(seg.LastDrawRangeCall.RcSrc, -2, top, 96, 96); ParaTests.VerifySimpleRect(seg.LastDrawRangeCall.RcDst, 0, 0, 96, 96); Assert.AreEqual(ydTop, seg.LastDrawRangeCall.YdTop); Assert.AreEqual(bottom, seg.LastDrawRangeCall.YdBottom); Assert.AreEqual(seg.LastDrawRangeCall.On, true, "Should currently always pass true to segment drawRange On argument"); // The old Views code appears to always pass true for this argument, so we should too, until I figure out what it's // really supposed to be, if anything. Assert.AreEqual(true, seg.LastDrawRangeCall.IsLastLineOfSelection); }
public void Contains() { var styles = new AssembledStyles(); var runStyle = styles.WithWs(32); var root = new RootBoxFdo(styles); var para1 = MakePara(styles, runStyle, "This is the day"); var para2 = MakePara(styles, runStyle, "that the Lord has made"); var para3 = MakePara(styles, runStyle, "We will rejoice"); var div = new DivBox(styles); var para4 = MakePara(styles, runStyle, "and be glad in it"); var para5 = MakePara(styles, runStyle, ""); var para6 = MakePara(styles, runStyle, "Rejoice!"); root.AddBox(para1); root.AddBox(para2); div.AddBox(para3); div.AddBox(para4); root.AddBox(div); root.AddBox(para5); root.AddBox(para6); var run1 = para1.Source.ClientRuns[0] as StringClientRun; var ip1_0 = run1.SelectAt(para1, 0, false); var ip1_2p = run1.SelectAt(para1, 2, true); var range1_0_2 = new RangeSelection(ip1_0, ip1_2p); Assert.That(range1_0_2.Contains(ip1_0), Is.True, "selection at start of range is included"); Assert.That(range1_0_2.Contains(ip1_2p), Is.True, "selection at end of range is included"); var ip1_1p = run1.SelectAt(para1, 1, true); Assert.That(range1_0_2.Contains(ip1_1p), Is.True, "selection in middle of 1-para range is included"); var ip1_3p = run1.SelectAt(para1, 3, true); Assert.That(range1_0_2.Contains(ip1_3p), Is.False); var ip1_2a = run1.SelectAt(para1, 2, false); Assert.That(range1_0_2.Contains(ip1_2a), Is.False, "ip at end associated following is not included"); var ip1_5p = run1.SelectAt(para1, 5, true); var range1_2_5 = new RangeSelection(ip1_2a, ip1_5p); Assert.That(range1_2_5.Contains(ip1_0), Is.False, "IP before start in same para not included"); Assert.That(range1_2_5.Contains(ip1_2p), Is.False, "IP at start associated previous not included"); Assert.That(range1_2_5.Contains(ip1_2a), Is.True, "IP at start not associated previous is included"); var run2 = para2.Source.ClientRuns[0] as StringClientRun; var ip2_2p = run2.SelectAt(para2, 2, true); Assert.That(range1_2_5.Contains(ip2_2p), Is.False, "IP in following paragraph not included"); var ip2_5p = run2.SelectAt(para2, 5, true); var ip2_2a = run2.SelectAt(para2, 2, false); var range2_5_2 = new RangeSelection(ip2_5p, ip2_2a); var ip2_3a = run2.SelectAt(para2, 3, false); Assert.That(range2_5_2.Contains(ip2_3a), Is.True, "IP in middle of backwards selection is included"); Assert.That(range2_5_2.Contains(ip1_2a), Is.False, "IP in previous para not included"); var run6 = para6.Source.ClientRuns[0] as StringClientRun; var ip6_2p = run6.SelectAt(para6, 2, true); var ip1_5a = run1.SelectAt(para1, 5, false); var range1_5_6_2 = new RangeSelection(ip1_5a, ip6_2p); Assert.That(range1_5_6_2.Contains(ip1_0), Is.False, "IP before multi-para not included"); Assert.That(range1_5_6_2.Contains(ip1_3p), Is.False, "IP before multi-para not included, even with offset > end offset"); var ip6_4a = run6.SelectAt(para6, 4, false); Assert.That(range1_5_6_2.Contains(ip6_4a), Is.False, "IP after multi-para not included, even with offset < start offset"); Assert.That(range1_5_6_2.Contains(ip2_3a), Is.True, "IP middle para of multi is included"); var run4 = para4.Source.ClientRuns[0] as StringClientRun; var ip40 = run4.SelectAt(para4, 0, false); Assert.That(range1_5_6_2.Contains(ip40), Is.True, "IP in div within multi is included"); var run5 = para5.Source.ClientRuns[0] as StringClientRun; var ip50a = run5.SelectAt(para5, 0, false); Assert.That(range1_5_6_2.Contains(ip50a), Is.True, "IP in empty para within multi is included"); // I'm not absolutely sure this is the right design, but it's rather arbitrary whether an IP in an empty // paragraph associates forward or backward. If a range extends to the empty paragraph, I think it should // be included either way. var range1_5_5_0 = new RangeSelection(ip1_5a, ip50a); Assert.That(range1_5_5_0.Contains(ip50a), Is.True, "IP (ap false) in empty para at end of multi is included"); var range5_0_6_2 = new RangeSelection(ip50a, ip6_2p); Assert.That(range5_0_6_2.Contains(ip50a), Is.True, "IP (ap false) in empty para at start of multi is included"); var ip50p = run5.SelectAt(para5, 0, true); Assert.That(range1_5_5_0.Contains(ip50p), Is.True, "IP (ap true) in empty para at end of multi is included"); Assert.That(range5_0_6_2.Contains(ip50p), Is.True, "IP (ap true) in empty para at end of multi is included"); }
public RangeRestoreData(RangeSelection rangeSelection) { StartRestoreData = new InsertionPointRestoreData(rangeSelection.Start); EndRestoreData = new InsertionPointRestoreData(rangeSelection.End); }
public void ComplexRangeDrawing() { var string1 = "This is the day that the Lord has made."; var string2 = "We will rejoice and be glad in it."; var string3 = "Love the Lord your God with all your heart."; var engine = new FakeRenderEngine() { Ws = 34, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(34, engine); var runStyle = new AssembledStyles().WithWs(34); var lineHeightMp = 20000; var style = new AssembledStyles().WithLineHeight(lineHeightMp); var root = new RootBox(style); var para1 = MakePara(style, runStyle, string1); root.AddBox(para1); var div = new DivBox(style); root.AddBox(div); var para2 = MakePara(style, runStyle, string2); div.AddBox(para2); var para3 = MakePara(style, runStyle, string3); div.AddBox(para3); // This width makes each paragraph take three lines. var layoutArgs = new LayoutInfo(2, 2, 96, 96, FakeRenderEngine.SimulatedWidth("This is the day "), m_gm.VwGraphics, factory); root.Layout(layoutArgs); var ip1 = para1.SelectAt(1, false); var ip2 = para1.SelectAt(3, true); var range1 = new RangeSelection(ip1, ip2); Assert.That(range1.EndBeforeAnchor, Is.False); Assert.That(range1.Start, Is.EqualTo(ip1)); Assert.That(range1.End, Is.EqualTo(ip2)); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); var sbox1_1 = para1.FirstBox as StringBox; range1.Draw(m_gm.VwGraphics, ptrans); int topOffset = -2; // top of RcSrc for top of root box. int topYd = 2; // destination coord corresponding to top of root box. int leftXd = 2; // destination coord corresponding to left of root box. int bottomOfFirstLine = topYd + engine.SegmentHeight; int lineHeight = ptrans.MpToPixelsY(lineHeightMp); int bottomOfFirstHilite = bottomOfFirstLine + (lineHeight - engine.SegmentHeight)/2; VerifyRangeSegmentDrawing(para1, sbox1_1, range1, topOffset, topYd, bottomOfFirstHilite); var sbox1_2 = sbox1_1.Next as StringBox; int bottomOfSecondHilite = bottomOfFirstHilite + lineHeight; VerifyRangeSegmentDrawing(para1, sbox1_2, range1, topOffset - lineHeight, bottomOfFirstHilite, bottomOfSecondHilite); var sbox1_3 = sbox1_2.Next as StringBox; int bottomOfThirddHilite = bottomOfSecondHilite + lineHeight - para1.Ascent; VerifyRangeSegmentDrawing(para1, sbox1_3, range1, topOffset - lineHeight * 2, bottomOfSecondHilite, bottomOfThirddHilite); // A two-line selection has much the same results. var ip3 = para1.SelectAt(sbox1_2.IchMin + 2, true); var range2 = new RangeSelection(ip1, ip3); range2.Draw(m_gm.VwGraphics, ptrans); VerifyRangeSegmentDrawing(para1, sbox1_1, range2, topOffset, topYd, bottomOfFirstHilite); VerifyRangeSegmentDrawing(para1, sbox1_2, range2, topOffset - lineHeight, bottomOfFirstHilite, bottomOfSecondHilite); VerifyRangeSegmentDrawing(para1, sbox1_3, range2, topOffset - lineHeight * 2, bottomOfSecondHilite, bottomOfThirddHilite); // Try multi-para selection in paras in same div. var ip2_3 = para2.SelectAt(3, false); var ip3_4 = para3.SelectAt(4, true); var range3 = new RangeSelection(ip2_3, ip3_4); range3.Draw(m_gm.VwGraphics, ptrans); var sbox2_1 = para2.FirstBox as StringBox; int topOfPara2 = topYd + para1.Height; int bottomOfFirstLineP2 = topOfPara2 + engine.SegmentHeight; int bottomOfFirstHiliteP2 = bottomOfFirstLineP2 + (lineHeight - engine.SegmentHeight) / 2; VerifyRangeSegmentDrawing(para2, sbox2_1, range3, topOffset - para1.Height, topOfPara2, bottomOfFirstHiliteP2); var sbox2_2 = sbox2_1.Next as StringBox; int bottomOfSecondHiliteP2 = bottomOfFirstHiliteP2 + lineHeight; VerifyRangeSegmentDrawing(para2, sbox2_2, range3, topOffset - para1.Height - lineHeight, bottomOfFirstHiliteP2, bottomOfSecondHiliteP2); var sbox2_3 = sbox2_2.Next as StringBox; int bottomOfThirddHiliteP2 = bottomOfSecondHiliteP2 + lineHeight - para2.Ascent; VerifyRangeSegmentDrawing(para2, sbox2_3, range3, topOffset - para1.Height - lineHeight * 2, bottomOfSecondHiliteP2, bottomOfThirddHiliteP2); var sbox3_1 = para3.FirstBox as StringBox; int topOfPara3 = topOfPara2 + para2.Height; var bottomOfFirstLineP3 = topOfPara3 + engine.SegmentHeight; var bottomOfFirstHiliteP3 = bottomOfFirstLineP3 + (lineHeight - engine.SegmentHeight) / 2; VerifyRangeSegmentDrawing(para3, sbox3_1, range3, topOffset - para1.Height - para2.Height, topOfPara3, bottomOfFirstHiliteP3); // Currently the other two segments of para3 will also be asked to draw it, but we've already checked how tops and bottoms // are worked out, and we don't care if these beyond-the-end segments draw it or not. Better not to test, then we can // optimize freely. // Now try a range that is (backwards and) across a div boundary var range4 = new RangeSelection(ip3_4, ip2); Assert.That(range4.EndBeforeAnchor, Is.True); Assert.That(range4.Start.SameLocation(ip2), Is.True); Assert.That(range4.End.SameLocation(ip3_4), Is.True); ClearSegmentDrawing(sbox1_3); ClearSegmentDrawing(sbox2_1); ClearSegmentDrawing(sbox3_1); range4.Draw(m_gm.VwGraphics, ptrans); // Several others should get drawn as well, but I think it's sufficient to verify tha something gets done correct in each para. VerifyRangeSegmentDrawing(para1, sbox1_3, range4, topOffset - lineHeight * 2, bottomOfSecondHilite, bottomOfThirddHilite); VerifyRangeSegmentDrawing(para2, sbox2_1, range4, topOffset - para1.Height, topOfPara2, bottomOfFirstHiliteP2); VerifyRangeSegmentDrawing(para3, sbox3_1, range4, topOffset - para1.Height - para2.Height, topOfPara3, bottomOfFirstHiliteP3); var range5 = new RangeSelection(ip2, ip3_4); Assert.That(range5.EndBeforeAnchor, Is.False); Assert.That(range5.Start.SameLocation(ip2), Is.True); Assert.That(range5.End.SameLocation(ip3_4), Is.True); // While we've got these selections, it's a good chance to check out GetSelectionLocation // The first one is a simple rectangle in the first string box. SetSelectionLocation(sbox1_1, 15, 20); Assert.That(range1.GetSelectionLocation(m_gm.VwGraphics, ptrans), Is.EqualTo( new Rectangle(15, topYd, 20 - 15, bottomOfFirstHilite - topYd))); SetSelectionLocation(sbox1_2, 18, 25); Assert.That(range2.GetSelectionLocation(m_gm.VwGraphics, ptrans), Is.EqualTo( new Rectangle(15, topYd, 25 - 15, bottomOfSecondHilite - topYd))); SetSelectionLocation(sbox3_1, 22, 27); Assert.That(range4.GetSelectionLocation(m_gm.VwGraphics, ptrans), Is.EqualTo( new Rectangle(leftXd, topYd, para2.Width, bottomOfFirstHiliteP3 - topYd))); }
private void BackspaceDeleteLineBreak() { if (Hookup is StringHookup || Hookup is TssHookup) { IParagraphOperations paragraphOps; GroupHookup parentHookup; int index; if(!GetParagraphOps(out paragraphOps, out parentHookup, out index)) return; if (index == 0) { // at the start of the sequence. // Enhance JohnT: could look for another paragraph ops higher? additional interface on paragraphOps? return; } var prevItem = parentHookup.Children[index - 1]; var prevIp = prevItem.SelectAtEnd(); if (prevIp == null) return; // for some reason we can't do it (maybe a box at end of last para?) var range = new RangeSelection(prevIp, this); Action makeSelection; paragraphOps.InsertString(range, "", out makeSelection); RootBox.Site.PerformAfterNotifications(makeSelection); } }
/// <summary> /// Get the location where a range selection is drawn within this paragraph. This is a rectangle that contains /// anything this paragraph draws for DrawRange with the same arguments. It is not critical that it contains /// nothing more, but is important that it contains nothing less. It should be fairly close (e.g., close enough /// to estimate a scroll position to show the selection). This rectangle may need to be combined with those /// from other paragraphs involved in a selection to get a rectangle covering the whole selection. /// </summary> internal Rectangle GetRangeLocation(RangeSelection sel, IVwGraphics vg1, PaintTransform ptrans) { var bounds = new Rect(); bool first = true; DoRangePaintingOp(sel, vg1, ptrans, (box, vg, childTrans, top, bottom, ichMin, ichLim) => { first = GetRangeLocationInBox(box, vg, childTrans, top, bottom, ichMin, ichLim, first, ref bounds); }); return new Rectangle(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top); }
// Do a range-painting operation (actual painting, or measuring, which involve much of the same work // except for the innermost step) for a given range selection. private void DoRangePaintingOp(RangeSelection range, IVwGraphics vg, PaintTransform ptrans, RangePaintingOp op) { int ichMin = range.Start.RenderParaPosition; // appropriate if the selection starts in THIS paragraph int ichLim = range.End.RenderParaPosition; // appropriate if the selection ends in THIS paragraph if (range.Start.Para != this) ichMin = 0; // It presumably starts before this paragraph, or it would not have been asked to draw it if (range.End.Para != this) ichLim = Source.Length; // It presumably ends after this paragraph, or it would not have been asked to draw it. DoRangePaintingOp(ichMin, ichLim, vg, ptrans, op); }
/// <summary> /// Draw a range selection. For now we assume the range is entirely within this paragraph, but this will eventually change. /// Todo JohnT: handle non-string-box children and ranges that don't start or end in this paragraph. /// Optimize JohnT: there may be a safe way to skip string boxes outside the selection. /// </summary> public void DrawRange(RangeSelection range, IVwGraphics vg, PaintTransform ptrans) { DoRangePaintingOp(range, vg, ptrans, DrawSelectionInBox); }
/// <summary> /// Move the cursor at the position specified by RangeSelection /// </summary> /// <param name="click">Position where to move the cursor.</param> public static void moveCursorAt(RangeSelection click) { // Globals.ThisAddIn.Application.Workbooks[click.] Microsoft.Office.Interop.Excel.Range range = Globals.ThisAddIn.Application.ActiveSheet.Cells[click.StartRow + 1, click.StartCol + 1].Select(); }
public void ArrowKeys() { var engine = new FakeRenderEngine() { Ws = 34, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(34, engine); var styles = new AssembledStyles().WithWs(34); var root = new RootBoxFdo(styles); var para1 = AddPara("This i~^s the~ day", styles, root); var para2 = AddPara("", styles, root); var para3 = AddPara(new string[] {"that" + MUSICAL_SYMBOL_SEMIBREVIS_WHITE + " the Lord", "has made"}, styles, root); var para4 = AddPara(new string[] { "we will", "", "rejoice" }, styles, root); int widthThisIsThe = FakeRenderEngine.SimulatedWidth("This is the"); var layoutArgs = MakeLayoutInfo(widthThisIsThe + 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); Assert.That(root.Height, Is.EqualTo(13 * 8), "A two-line and a one-line and a three-line and a two-line paragraph"); PaintTransform ptrans = new PaintTransform(2, 4, 96, 100, 0, 10, 120, 128); MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; // Simple left movement. var ipThisIsTheDay = para1.SelectAtEnd(); var ipThisIsTheDa = ipThisIsTheDay.MoveByKey(new KeyEventArgs(Keys.Left)); VerifyIp(ipThisIsTheDa, para1, "This i~^s the~ da", false, "left from end"); var ipThisIsTheD = ipThisIsTheDa.MoveByKey(new KeyEventArgs(Keys.Left)); VerifyIp(ipThisIsTheD, para1, "This i~^s the~ d", false, "left from no special plae"); // Left from one run into an adjacent non-empty run var ipThatTheLord2 = ((TextClientRun) para3.Source.ClientRuns[1]).SelectAt(para3, 0, false); var ipThatTheLor = ipThatTheLord2.MoveByKey(new KeyEventArgs(Keys.Left)); VerifyIp(ipThatTheLor, para3, "that" + MUSICAL_SYMBOL_SEMIBREVIS_WHITE + " the Lor", false, "left from start run2"); // Left from one run into an adjacent empty run. Is this right or should we skip over it into // another run so we actually move a character? var ipStartOfRejoice = ((TextClientRun)para4.Source.ClientRuns[2]).SelectAt(para4, 0, false); var ipEmptyPara4 = ipStartOfRejoice.MoveByKey(new KeyEventArgs(Keys.Left)); VerifyIp(ipEmptyPara4, para4, "we will", false, "left from start run into empty"); // Out of the empty run into the previous one. var ipWeWil = ipEmptyPara4.MoveByKey(new KeyEventArgs(Keys.Left)); VerifyIp(ipWeWil, para4, "we wil", false, "left from empty run"); // back from one para into another. var ipPara2 = para2.SelectAtStart(); var ipEndPara1 = ipPara2.MoveByKey(new KeyEventArgs(Keys.Left)); VerifyIp(ipEndPara1, para1, "This i~^s the~ day", true, "left from one para to another"); // back at the very start. var ipStart = para1.SelectAtStart(); Assert.That(ipStart.MoveByKey(new KeyEventArgs(Keys.Left)), Is.Null); // back after a surrogate pair should not stop in the middle. var ipThatSurrogate = ((TextClientRun)para3.Source.ClientRuns[0]).SelectAt(para3, ("that" + MUSICAL_SYMBOL_SEMIBREVIS_WHITE).Length, false); var ipThat = ipThatSurrogate.MoveByKey(new KeyEventArgs(Keys.Left)); VerifyIp(ipThat, para3, "that", false, "left over surrogate pair"); // Back to a place between diacritic and base should not stop. var ipThisI_Diacritics = ((TextClientRun)para1.Source.ClientRuns[0]).SelectAt(para1, "This i~^".Length, false); var ipThisSpace = ipThisI_Diacritics.MoveByKey(new KeyEventArgs(Keys.Left)); VerifyIp(ipThisSpace, para1, "This ", false, "left over diacritics"); // We can use many of the same ones to check right movement. var ipThisIsTheDa_r = ipThisIsTheD.MoveByKey(new KeyEventArgs(Keys.Right)); VerifyIp(ipThisIsTheDa_r, para1, "This i~^s the~ da", true, "simple right"); // Move right into an empty paragraph. // Review JohnT: should this IP in an empty para associate forward or back? var ipStartP2 = ipThisIsTheDay.MoveByKey(new KeyEventArgs(Keys.Right)); VerifyIp(ipStartP2, para2, "", false, "right into empty para"); // Should definitely associate with the character following, not the nonexistent preceding one. var ipStartP3 = ipStartP2.MoveByKey(new KeyEventArgs(Keys.Right)); VerifyIp(ipStartP3, para3, "", false, "right to start of non-empty para"); var ipP3_t = ipStartP3.MoveByKey(new KeyEventArgs(Keys.Right)); VerifyIp(ipP3_t, para3, "t", true, "simple right"); var ipThatSurrogate2 = ipThat.MoveByKey(new KeyEventArgs(Keys.Right)); VerifyIp(ipThatSurrogate2, para3, "that" + MUSICAL_SYMBOL_SEMIBREVIS_WHITE, true, "right over surrogate pair"); var ipThatTheLord_left = ((TextClientRun)para3.Source.ClientRuns[0]).SelectAt(para3, ("that" + MUSICAL_SYMBOL_SEMIBREVIS_WHITE + " the Lord").Length, true); var ipThatTheLord_space = ipThatTheLord_left.MoveByKey(new KeyEventArgs(Keys.Right)); VerifyIp(ipThatTheLord_space, para3, "that" + MUSICAL_SYMBOL_SEMIBREVIS_WHITE + " the Lord ", true, "right from end run1"); var ipEnd = para4.SelectAtEnd(); Assert.That(ipEnd.MoveByKey(new KeyEventArgs(Keys.Right)), Is.Null); // Also can't make range by moving right from end. Assert.That(ipEnd.MoveByKey(new KeyEventArgs(Keys.Right | Keys.Shift)), Is.Null); var rangeThatSurrogate2 = ipThat.MoveByKey(new KeyEventArgs(Keys.Right | Keys.Shift)); VerifyRange(rangeThatSurrogate2, para3, "that", para3, "that" + MUSICAL_SYMBOL_SEMIBREVIS_WHITE, "shift-right over surrogate pair"); var rangeThatTha = ipThat.MoveByKey(new KeyEventArgs(Keys.Left | Keys.Shift)); VerifyRange(rangeThatTha, para3, "that", para3, "tha", "shift-left end before anchor"); // left from a range puts us at the start of the range var ipThat2 = rangeThatSurrogate2.MoveByKey(new KeyEventArgs(Keys.Left)); VerifyIp(ipThat2, para3, "that", false, "left from range to IP"); // right from a range puts us at the end of the range var ipThatSurrrogate2 = rangeThatSurrogate2.MoveByKey(new KeyEventArgs(Keys.Right)); VerifyIp(ipThatSurrrogate2, para3, "that" + MUSICAL_SYMBOL_SEMIBREVIS_WHITE, true, "right from range"); // shift-left from a 1-char range collapses it to an IP var ipThat3 = rangeThatSurrogate2.MoveByKey(new KeyEventArgs(Keys.Left | Keys.Shift)); VerifyIp(ipThat3, para3, "that", false, "left over surrogate pair"); // shift-right from a range makes one with the same anchor but an extended end var rangeThatSurrogateSpace = rangeThatSurrogate2.MoveByKey(new KeyEventArgs(Keys.Right | Keys.Shift)); VerifyRange(rangeThatSurrogateSpace, para3, "that", para3, "that" + MUSICAL_SYMBOL_SEMIBREVIS_WHITE + " ", "shift-right from range"); // shift-right from a range that can't grow returns null. var ipWeWillRejoic = (InsertionPoint) ipEnd.MoveByKey(new KeyEventArgs(Keys.Left)); var range1AtEnd = new RangeSelection(ipWeWillRejoic, ipEnd); Assert.That(range1AtEnd.MoveByKey(new KeyEventArgs(Keys.Right | Keys.Shift)), Is.Null); // Home key. var ipStartP2_2 = ipThat.MoveByKey(new KeyEventArgs(Keys.Home)); VerifyIp(ipStartP2_2, para3, "", false, "home in Para 3"); var ipStart_2 = ipThat.MoveByKey(new KeyEventArgs(Keys.Home | Keys.Control)); VerifyIp(ipStart_2, para1, "", false, "ctrl-home in Para 3"); // End key. var ipEndP2 = ipThat.MoveByKey(new KeyEventArgs(Keys.End)); VerifyIp(ipEndP2, para3, "that" + MUSICAL_SYMBOL_SEMIBREVIS_WHITE + " the Lord" + "has made", true, "end in Para 3"); var ipEnd_2 = ipThat.MoveByKey(new KeyEventArgs(Keys.End | Keys.Control)); VerifyIp(ipEnd_2, para4, "we will" + "rejoice", true, "ctrl-end in Para 3"); // Down key var ipThisIsThe_R = ipStart.MoveByKey(new KeyEventArgs(Keys.Down)); VerifyIp(ipThisIsThe_R, para1, "This i~^s the~ ", false, "down from start line 1"); var ipTh = para1.SelectAt(2, true); var ipThisIsTheDa2 = ipTh.MoveByKey(new KeyEventArgs(Keys.Down)); VerifyIp(ipThisIsTheDa2, para1, "This i~^s the~ da", false, "down from 2 chars into line 1"); var ipThisIdTh = para1.SelectAt("This i~^s th".Length, false); var ipThisIsTheDay2 = ipThisIdTh.MoveByKey(new KeyEventArgs(Keys.Down)); VerifyIp(ipThisIsTheDay2, para1, "This i~^s the~ day", true, "down from near end line 1"); // Empty para: arbitrary which way it associates. var ipPara2Down = ipThisIsTheDay2.MoveByKey(new KeyEventArgs(Keys.Down)); VerifyIp(ipPara2Down, para2, "", true, "down twice from near end line 1"); // Going on down, we should remember the starting X position and end up about that // far into the next full-length line. The 'i' characters in the first line make it // a bit iffy; might be closer to the start of the 'e' at the end of 'the'. // The other complication is that our fake render engine is not smart about surrogate pairs, // and treats the musical semibrevis as two ordinary characters. // Omitting the diacritics in the first paragraph, our selection starts 10 characters in. // The result string here is 9 characters, since with no narrow letters on this para, // we end up closer to the left of the 'e'. var ipThatTheSpaceDown = ipPara2Down.MoveByKey(new KeyEventArgs(Keys.Down)); VerifyIp(ipThatTheSpaceDown, para3, "that" + MUSICAL_SYMBOL_SEMIBREVIS_WHITE + " th", false, "down 3x from near end line 1"); Assert.That(ipEnd.MoveByKey(new KeyEventArgs(Keys.Down)), Is.Null); var ipPara2Up = ipThatTheSpaceDown.MoveByKey(new KeyEventArgs(Keys.Up)); VerifyIp(ipPara2Up, para2, "", true, "back up aligned with near end line 1"); var ipThisIsTheDayUp = ipPara2Up.MoveByKey(new KeyEventArgs(Keys.Up)); VerifyIp(ipThisIsTheDayUp, para1, "This i~^s the~ day", true, "up from para2 aligned near end line 1"); // It's going to be looking for a position right at the boundary...either assocPrev would be // reasonable. var ipThisIdTh2Up = ipThisIsTheDayUp.MoveByKey(new KeyEventArgs(Keys.Up)); VerifyIp(ipThisIdTh2Up, para1, "This i~^s th", false, "up from end para 1 aligned near end line 1"); //var ipPara2_2 = ipThisIsTheDay.MoveByKey(new KeyEventArgs(Keys.Down)); //VerifyIp(ipPara2_2, para2, "", true, "down from end para 1"); // Todo: // HandleSpecialKey is called from OnKeyDown and should handle at least these: //case Keys.PageUp: //case Keys.PageDown: //case Keys.End: //case Keys.Home: //case Keys.Left: // done //case Keys.Up: //case Keys.Right: // done //case Keys.Down: //case Keys.F7: // the only two function keys currently known to the Views code, //case Keys.F8: // used for left and right arrow by string character amounts. // Test Left: (done) // - char to char in same line // - skipping diacritics // - skipping surrogate pairs // - to another line in same paragraph // - to previous (empty?) paragraph // - at very start (nothing happens) // - range collapses to start // - anything special to test if there are multiple runs? e.g., at boundary // - skip over embedded pictures // - eventually drop into embedded boxes that contain text? // Similarly right (done) // Down: // - same para, there is text below // - same para, no text immediately below on same line (goes to end of previous line) // - eventually: what should happen if logical and physical end of next line don't coincide? // - down again to a longer line: should stay aligned with start position (what resets this??) // etc for others. }
private void ExtendSelection(Selection sel, bool makeRange) { var dragEnd = sel as InsertionPoint; var oldIP = Selection as InsertionPoint; if (dragEnd.SameLocation(oldIP)) { if (oldIP.AssociatePrevious == dragEnd.AssociatePrevious) return; // otherwise, keep sel, we want to install it because the direction changed. // But don't even think about changing it to a range. } else if (makeRange && Selection != null) { // See if we can make a range selection based on the old anchor and new dragEnd. var start = Selection as InsertionPoint; if (Selection is RangeSelection) { var range = (RangeSelection)Selection; if (range.DragEnd.Para == dragEnd.Para && range.DragEnd.LogicalParaPosition == dragEnd.LogicalParaPosition) return; start = range.Anchor; } if (start != null && !start.SameLocation(dragEnd)) sel = new RangeSelection(start, dragEnd); // If they ARE the same location, replace the range with the new (IP) selection. } if (sel != null) sel.Install(); }
public RangeSelection ExpandToWord() { var cpe = LgIcuCharPropEngineClass.Create(); RangeSelection rangeSel = new RangeSelection(this, new InsertionPoint(Hookup, StringPosition + 1, AssociatePrevious)); var backwardSel = new InsertionPoint(Hookup, StringPosition, AssociatePrevious); var forwardSel = new InsertionPoint(Hookup, StringPosition, AssociatePrevious); while (true) { if (backwardSel.StringPosition == 0) { break; } backwardSel.StringPosition--; char testChar = backwardSel.ContainingRun.Text[backwardSel.StringPosition]; int testInt = testChar; if (Surrogates.IsTrailSurrogate(testChar)) { backwardSel.StringPosition--; testInt = Surrogates.Int32FromSurrogates(backwardSel.ContainingRun.Text[backwardSel.StringPosition], testChar); } else if (Surrogates.IsLeadSurrogate(testChar)) { testInt = Surrogates.Int32FromSurrogates(testChar, backwardSel.ContainingRun.Text[backwardSel.StringPosition+1]); } if (!cpe.get_IsNumber(testInt) && !cpe.get_IsWordForming(testInt) || backwardSel.ContainingRun.WritingSystemAt(backwardSel.StringPosition) != ContainingRun.WritingSystemAt(StringPosition)) { backwardSel.StringPosition++; break; } rangeSel = new RangeSelection(backwardSel, this); } backwardSel = rangeSel.Anchor; while (true) { if (forwardSel.StringPosition == forwardSel.ContainingRun.Length) { if (backwardSel.StringPosition == forwardSel.StringPosition) return null; break; } char testChar = forwardSel.ContainingRun.Text[forwardSel.StringPosition]; int testInt = testChar; if (Surrogates.IsLeadSurrogate(testChar)) { forwardSel.StringPosition++; testInt = Surrogates.Int32FromSurrogates(testChar, forwardSel.ContainingRun.Text[forwardSel.StringPosition]); testChar = (char)testInt; } else if (Surrogates.IsTrailSurrogate(testChar)) { testInt = Surrogates.Int32FromSurrogates(forwardSel.ContainingRun.Text[forwardSel.StringPosition-1], testChar); testChar = (char)testInt; } if (!cpe.get_IsNumber(testInt) && !cpe.get_IsWordForming(testInt) || forwardSel.ContainingRun.WritingSystemAt(forwardSel.StringPosition) != ContainingRun.WritingSystemAt(StringPosition)) { if (testChar.Equals(" ".ToCharArray()[0])) { forwardSel.StringPosition++; rangeSel = new RangeSelection(backwardSel, forwardSel); } break; } forwardSel.StringPosition++; rangeSel = new RangeSelection(backwardSel, forwardSel); } return rangeSel; }