示例#1
0
        public void DiffRuns()
        {
            var styles = new AssembledStyles();
            var root   = new RootBoxFdo(styles);
            var mock1  = new MockData1(23, 23);

            mock1.SimpleThree = "new stuff";
            var mock2 = new MockData1(23, 23);

            mock2.SimpleThree = "old contents";
            var mock3 = new MockData1(23, 23);

            mock3.SimpleThree = "different things";
            var engine = new FakeRenderEngine()
            {
                Ws = 23, SegmentHeight = 13
            };
            var factory = new FakeRendererFactory();

            factory.SetRenderer(23, engine);
            root.Builder.Show(Paragraph.Containing(Display.Of(() => mock1.SimpleThree, 23), Display.Of(() => mock2.SimpleThree, 23), Display.Of(() => mock3.SimpleThree, 23)));
            var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory);

            root.Layout(layoutArgs);
            PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96);
            MockSite       site   = new MockSite();

            site.m_transform  = ptrans;
            site.m_vwGraphics = m_gm.VwGraphics;
            root.Site         = site;

            int            x        = FakeRenderEngine.SimulatedWidth("new stuf") + 2;
            var            location = new Point(x, 8);
            EventArgs      e        = new EventArgs();
            MouseEventArgs m        = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0);

            root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform);
            root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform);
            root.OnDoubleClick(e);
            Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection");
            Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("stuff"));

            x        = FakeRenderEngine.SimulatedWidth("new stuff") + 2;
            location = new Point(x, 8);
            m        = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0);
            root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform);
            root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform);
            root.OnDoubleClick(e);
            Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection");
            Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("old "));

            x        = FakeRenderEngine.SimulatedWidth("new stuff old contents") + 2;
            location = new Point(x, 8);
            m        = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0);
            root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform);
            root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform);
            root.OnDoubleClick(e);
            Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection");
            Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("different "));
        }
示例#2
0
        public void InsertCharInEmptyLine()
        {
            string contents = "";
            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 data1 = new MockData1(34, 35);

            data1.SimpleThree = contents;
            var source = new TextSource(clientRuns, null);
            var para   = new ParaBox(styles, source);
            var hookup = new StringHookup(this, () => data1.SimpleThree, hook => data1.SimpleThreeChanged += hook.StringPropChanged,
                                          hook => data1.SimpleThreeChanged -= hook.StringPropChanged, para);

            hookup.Writer = newVal => data1.SimpleThree = newVal;
            run.Hookup    = hookup;
            var root  = new RootBox(styles);
            var block = new BlockBox(styles, Color.Red, 20000, 10000);

            root.AddBox(block);
            root.AddBox(para);
            var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory);

            root.Layout(layoutArgs);
            Assert.That(root.Height, Is.EqualTo(13 + block.Height));
            Assert.That(para.Width, Is.EqualTo(FakeRenderEngine.SimulatedWidth(contents)));
            Assert.That(root.Width, Is.EqualTo(block.Width));
            int simulatedWidth = FakeRenderEngine.SimulatedWidth("x");

            Assert.That(root.Width, Is.GreaterThan(para.Width + simulatedWidth));
            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;
            var oldRootWidth = root.Width;

            var ip = root.SelectAtEnd();

            ip.InsertText("x");
            Assert.That(root.Height, Is.EqualTo(13 + block.Height));
            Assert.That(root.Width, Is.EqualTo(oldRootWidth));
            Assert.That(para.Width, Is.EqualTo(simulatedWidth));
            var expectedInvalidate = new Rectangle(-RootBox.InvalidateMargin,
                                                   -RootBox.InvalidateMargin + block.Height,
                                                   simulatedWidth + RootBox.InvalidateMargin * 2,
                                                   13 + 2 * RootBox.InvalidateMargin);

            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate));
        }
示例#3
0
        private static IRendererFactory SetupFakeRenderer(int ws)
        {
            var fakeRenderer        = new FakeRenderEngine();
            var fakeRendererFactory = new FakeRendererFactory();

            fakeRendererFactory.SetRenderer(ws, fakeRenderer);
            return(fakeRendererFactory);
        }
示例#4
0
        public void MultiParaCopy()
        {
            var styles = new AssembledStyles();
            var root   = new RootBoxFdo(styles);
            var owner  = new MockData1(23, 23);
            var mock1  = new MockData1(23, 23);
            var mock2  = new MockData1(23, 23);
            var mock3  = new MockData1(23, 23);

            owner.InsertIntoObjSeq1(0, mock1);
            owner.InsertIntoObjSeq1(1, mock2);
            owner.InsertIntoObjSeq1(2, mock3);
            mock1.SimpleThree = "This is the";
            mock2.SimpleThree = "day that the";
            mock3.SimpleThree = "Lord has made";
            var engine = new FakeRenderEngine()
            {
                Ws = 23, SegmentHeight = 13
            };
            var factory = new FakeRendererFactory();

            factory.SetRenderer(23, engine);
            var            layoutInfo = HookupTests.MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 23);
            PaintTransform ptrans     = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96);
            MockSite       site       = new MockSite();

            site.m_transform  = ptrans;
            site.m_vwGraphics = m_gm.VwGraphics;
            root.Site         = site;
            var po = new MockReceiveParagraphOperations();

            root.Builder.Show(Display.Of(() => owner.ObjSeq1).Using((bldr, md) => bldr.AddString(() => md.SimpleThree, 23))
                              .EditParagraphsUsing(po));
            var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory);

            root.Layout(layoutArgs);

            int x        = FakeRenderEngine.SimulatedWidth("This ") + 2;
            var location = new Point(x, 8);

            Clipboard.SetDataObject("");

            MouseEventArgs e = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0);

            root.OnMouseDown(e, Keys.None, site.m_vwGraphics, site.m_transform);
            Assert.That(root.CanCopy(), Is.EqualTo(false), "Should not be able to copy");
            x        = FakeRenderEngine.SimulatedWidth("Lord") + 2;
            location = new Point(x, 29);
            e        = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0);
            root.OnMouseMove(e, Keys.None, site.m_vwGraphics, site.m_transform);

            Assert.That(root.CanCopy(), Is.EqualTo(true), "Should be able to copy");
            root.OnEditCopy();
            Assert.That(owner.ObjSeq1[0].SimpleThree + owner.ObjSeq1[1].SimpleThree + owner.ObjSeq1[2].SimpleThree, Is.EqualTo("This is the" + "day that the" + "Lord has made"));
            Assert.That(Clipboard.GetDataObject().GetData(DataFormats.StringFormat), Is.EqualTo("is the\r\nday that the\r\nLord"), "Selected String should be \"is the\nday that the\nLord \"");
        }
示例#5
0
        public IRenderEngine GetRenderer(int ws, IVwGraphics vg)
        {
            IRenderEngine result;

            if (m_renderers.TryGetValue(ws, out result))
            {
                return(result);
            }
            result          = new FakeRenderEngine();
            m_renderers[ws] = result;
            return(result);
        }
示例#6
0
        public void MlsDelete()
        {
            var styles = new AssembledStyles();
            var root   = new RootBoxFdo(styles.WithWs(23));
            var mock1  = new MockData1(23, 23);

            mock1.MlSimpleOne = new MultiAccessor(23, 23);
            mock1.MlSimpleOne.set_String(23, TsStrFactoryClass.Create().MakeString("This is it", 23));
            var engine = new FakeRenderEngine()
            {
                Ws = 23, SegmentHeight = 13
            };
            var factory = new FakeRendererFactory();

            factory.SetRenderer(23, engine);
            root.Builder.Show(Display.Of(() => mock1.MlSimpleOne, 23));
            var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory);

            root.Layout(layoutArgs);
            PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96);
            MockSite       site   = new MockSite();

            site.m_transform  = ptrans;
            site.m_vwGraphics = m_gm.VwGraphics;
            root.Site         = site;

            SelectionBuilder.In(root).Offset("This ".Length).To.Offset("This is ".Length).Install();
            var sel = root.Selection as RangeSelection;

            // This is currently the main test for SelectionBuilder.In(RootBox) and SelectionBuilder.To in TsStrings
            // This verifies that it makes roughly the right range selection.
            Assert.That(sel.Anchor.LogicalParaPosition, Is.EqualTo("This ".Length));
            Assert.That(sel.DragEnd.LogicalParaPosition, Is.EqualTo("This is ".Length));

            Assert.That(sel.CanDelete(), Is.True);
            root.OnDelete();
            ITsString i = mock1.MlSimpleOne.get_String(23);

            Assert.That(mock1.MlSimpleOne.get_String(23).Text, Is.EqualTo("This it"));
            var ip = root.Selection as InsertionPoint;

            Assert.That(ip.LogicalParaPosition, Is.EqualTo("This ".Length));
            // Enhance JohnT: if there is any reason to prefer associatePrevious to be true or false,
            // clamp that and make it so.
            // A fairly rudimentary check on invalidate, since we elsewhere check general string-edit ops.
            Assert.That(site.RectsInvalidatedInRoot, Is.Not.Empty);
        }
示例#7
0
        public void BasicCopy()
        {
            var styles = new AssembledStyles();
            var root   = new RootBoxFdo(styles);
            var mock1  = new MockData1(23, 23);

            mock1.SimpleThree = "old contents";
            var engine = new FakeRenderEngine()
            {
                Ws = 23, SegmentHeight = 13
            };
            var factory = new FakeRendererFactory();

            factory.SetRenderer(23, engine);
            root.Builder.Show(Display.Of(() => mock1.SimpleThree, 23));
            var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory);

            root.Layout(layoutArgs);
            PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96);
            MockSite       site   = new MockSite();

            site.m_transform  = ptrans;
            site.m_vwGraphics = m_gm.VwGraphics;
            root.Site         = site;

            int x        = FakeRenderEngine.SimulatedWidth("old ") + 2;
            var location = new Point(x, 8);

            Clipboard.SetDataObject("");

            Assert.That(root.CanCopy(), Is.EqualTo(false), "Should not be able to copy");
            root.OnEditCopy();
            Assert.That(mock1.SimpleThree, Is.EqualTo("old contents"), "Nothing should have changed");
            Assert.That(Clipboard.GetDataObject().GetData(DataFormats.StringFormat), Is.EqualTo(""), "Nothing should have been copied");

            MouseEventArgs e = new MouseEventArgs(MouseButtons.Left, 1, 2, location.Y, 0);

            root.OnMouseDown(e, Keys.None, site.m_vwGraphics, site.m_transform);
            Assert.That(root.CanCopy(), Is.EqualTo(false), "Should not be able to copy");
            e = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0);
            root.OnMouseMove(e, Keys.None, site.m_vwGraphics, site.m_transform);

            Assert.That(root.CanCopy(), Is.EqualTo(true), "Should be able to copy");
            root.OnEditCopy();
            Assert.That(mock1.SimpleThree, Is.EqualTo("old contents"), "Selected String should be \"old contents\"");
            Assert.That(Clipboard.GetDataObject().GetData(DataFormats.StringFormat), Is.EqualTo("old "), "Selected String should be \"old \"");
        }
示例#8
0
        public void PointToChar(int ichBase, IVwGraphics vg, Rect rcSrc, Rect rcDst, Point tdClickPosition,
                                out int ichOut, out bool fAssocPrev)
        {
            LastPointToCharArgs = new PointToCharArgs()
            {
                IchBase = ichBase, Vg = vg, RcSrc = rcSrc, RcDst = rcDst, ClickPosition = tdClickPosition
            };
            int xpos = tdClickPosition.X + rcSrc.left - rcDst.left;             // Enhance: not sure this is right for rcDst, and ignores zoom
            int ich  = 0;

            fAssocPrev = false;
            if (xpos < 0)
            {
                ichOut = ich + ichBase;
                return;
            }
            int lastCharWidth = 0;

            while (xpos >= 0 & ich < Length)
            {
                lastCharWidth = FakeRenderEngine.CharWidth(Text[ich]);
                xpos         -= lastCharWidth;
                ich++;
            }
            if (xpos >= 0 && ich > 0)
            {
                fAssocPrev = true;                 // click to right of last char
                {
                    ichOut = ich + ichBase;
                    return;
                }
            }
            // We clicked somewhere in the last character, of width lastCharWidth.
            // If we clicked in the first half of it, treat as a click before it.
            // -xpos is the distance we clicked left of its right edge.
            if ((-xpos) < lastCharWidth / 2)
            {
                fAssocPrev = true;                 // click on right half, return current index and assoc prev
            }
            else if (ich > 0)
            {
                ich--;                 // click on left half, return previous index and assoc prev false.
            }
            ichOut = ich + ichBase;
        }
示例#9
0
        public void ParaObjTest()
        {
            var owner        = new MockData1(55, 77);
            var child1       = new MockData1(55, 77);
            var child1String = "Hello world, this is a wide string";

            child1.SimpleThree = child1String;
            owner.SimpleFour   = child1;
            var styles     = new AssembledStyles();
            var root       = new RootBoxFdo(styles);
            var layoutInfo = MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 55);

            SetupFakeRootSite(root);
            var      engine = layoutInfo.RendererFactory.GetRenderer(55, m_gm.VwGraphics) as FakeRenderEngine;
            MockSite site   = new MockSite();

            root.Site = site;
            PaintTransform ptrans = new PaintTransform(2, 4, 96, 100, 0, 10, 120, 128);

            site.m_transform  = ptrans;
            site.m_vwGraphics = m_gm.VwGraphics;
            root.Builder.Show(Display.OfObj(() => owner.SimpleFour).Using((bldr, md) => bldr.AddString(() => md.SimpleThree, 55)));
            root.Layout(layoutInfo);
            VerifyParagraphs(root, new[] { child1String });

            Assert.That(owner.SimpleFourHookupCount, Is.EqualTo(1), "Builder.AddString should set up a hookup for the string");
            Assert.That(child1.SimpleThreeHookupCount, Is.EqualTo(1), "Builder.AddString should set up a hookup for the string");
            int invalidateWidth = FakeRenderEngine.SimulatedWidth(child1String) + 2 * RootBox.InvalidateMargin;

            // Change item and check side effects.
            var child2 = new MockData1(55, 77);

            child2.SimpleThree = "Another world";
            site.RectsInvalidated.Clear();
            owner.SimpleFour = child2;
            VerifyParagraphs(root, new string[] { "Another world" });
            Assert.That(child2.SimpleThreeHookupCount, Is.EqualTo(1), "Builder.AddString should set up a hookup for the string");
            var expectedInvalidate1 = new Rectangle(-RootBox.InvalidateMargin, -RootBox.InvalidateMargin,
                                                    invalidateWidth, engine.SegmentHeight + 2 * RootBox.InvalidateMargin);

            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate1));
        }
示例#10
0
 public void PositionsOfIP(int ichBase, IVwGraphics _vg, Rect rcSrc, Rect rcDst, int ich, bool fAssocPrev, LgIPDrawMode dm,
                           out Rect rectPrimary, out Rect rectSecondary, out bool fPrimaryHere, out bool fSecHere)
 {
     LastPosIpCall           = new MockSegment.PositionsOfIpArgs();
     LastPosIpCall.IchBase   = ichBase;
     LastPosIpCall.Graphics  = _vg;
     LastPosIpCall.RcSrc     = rcSrc;
     LastPosIpCall.RcDst     = rcDst;
     LastPosIpCall.Ich       = ich;
     LastPosIpCall.AssocPrev = fAssocPrev;
     LastPosIpCall.DrawMode  = dm;
     if (NextPosIpResult != null)
     {
         rectPrimary   = NextPosIpResult.RectPrimary;
         rectSecondary = new Rect();       // NextPosIpResult.RectSecondary;
         fPrimaryHere  = NextPosIpResult.PrimaryHere;
         fSecHere      = false;            // NextPosIpResult.SecHere;
     }
     else
     {
         rectPrimary   = new Rect(0, 0, 0, 0);
         rectSecondary = new Rect(0, 0, 0, 0);
         fSecHere      = false;
         if (ich < ichBase || ich > ichBase + Length)
         {
             fPrimaryHere = false;
             return;
         }
         fPrimaryHere = true;                 // useful result when we don't care to prepare for this call.
         int width = 0;
         for (int i = 0; i < ich - ichBase; i++)
         {
             width += FakeRenderEngine.CharWidth(Text[i]);
         }
         rectPrimary = PaintTransform.ConvertToPaint(new Rect(width - 1, 0, width + 1, Height),
                                                     rcSrc, rcDst);
     }
 }
示例#11
0
        public void ParaSequenceTest()
        {
            var owner      = new MockData1(55, 77);
            var styles     = new AssembledStyles();
            var root       = new RootBoxFdo(styles);
            var layoutInfo = MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 55);

            SetupFakeRootSite(root);
            var      engine = layoutInfo.RendererFactory.GetRenderer(55, m_gm.VwGraphics) as FakeRenderEngine;
            MockSite site   = new MockSite();

            root.Site = site;
            PaintTransform ptrans = new PaintTransform(2, 4, 96, 100, 0, 10, 120, 128);

            site.m_transform  = ptrans;
            site.m_vwGraphics = m_gm.VwGraphics;
            root.Builder.Show(Display.Of(() => owner.ObjSeq1).Using((bldr, md) => bldr.AddString(() => md.SimpleThree, 55)));
            root.Layout(layoutInfo);
            VerifyParagraphs(root, new string[0]);
            //var seqHookup = new IndependentSequenceHookup<MockData1>(owner);

            // Tell seqHookup how to make a display of one MockData1:
            //  - make a paragraph
            //  - make it display the SimpleDataThree property of the item (editable)
            //  - Make an item hookup that knows about the paragraph and the StringHookup for SimpleDataThree
            //  - that hookup should be connected to the Item Hookup

            // Tell seqHookup how it relates to the root box
            //  - Somehow the item hookup for each item gets inserted into the right place in seqHookup's children,
            //  - and the paragraph for the item gets inserted into the right place in the rootbox.

            // Tell seqHookup to get its items from ObjSeq1 and to listen for ObjSeq1Changed.

            // (Eventually I'd like to be able to do all the above something like this:
            // root.Builder.AddObjSeq(()=>owner.ObjSeq1, (md, bldr)=>bldr.AddString(()=>md.SimpleThree);

            // Insert the first item into owner.ObjSeq1 and check all the right connections appear
            var child1       = new MockData1(55, 77);
            var child1String = "Hello world, this is a wide string";

            child1.SimpleThree = child1String;
            owner.InsertIntoObjSeq1(0, child1);
            // The first string we insert is deliberately the widest. After that, the width of the pile
            // remains constant, allowing us to test smarter, smaller invalidate rectangles; when the width
            // changes we invalidate the whole pile.
            VerifyParagraphs(root, new string[] { child1String });
            Assert.That(child1.SimpleThreeHookupCount, Is.EqualTo(1), "Builder.AddString should set up a hookup for the string");
            int invalidateWidth     = FakeRenderEngine.SimulatedWidth(child1String) + 2 * RootBox.InvalidateMargin;
            var expectedInvalidate1 = new Rectangle(-RootBox.InvalidateMargin, -RootBox.InvalidateMargin,
                                                    invalidateWidth,
                                                    engine.SegmentHeight + 2 * RootBox.InvalidateMargin);

            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate1));

            // Insert a second item and check again.
            var child2 = new MockData1(55, 77);

            child2.SimpleThree = "Another world";
            site.RectsInvalidated.Clear();
            owner.InsertIntoObjSeq1(1, child2);
            VerifyParagraphs(root, new string[] { child1String, "Another world" });
            Assert.That(child2.SimpleThreeHookupCount, Is.EqualTo(1), "Builder.AddString should set up a hookup for the string");
            var expectedInvalidate2 = new Rectangle(-RootBox.InvalidateMargin,
                                                    engine.SegmentHeight - RootBox.InvalidateMargin,
                                                    invalidateWidth,
                                                    engine.SegmentHeight + 2 * RootBox.InvalidateMargin);

            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate2));

            // Insert a third item between the first two.
            var child3 = new MockData1(55, 77);

            child3.SimpleThree = "Inserted world";
            owner.InsertIntoObjSeq1(1, child3);
            VerifyParagraphs(root, new string[] { child1String, "Inserted world", "Another world" });
            var expectedInvalidate3 = new Rectangle(-RootBox.InvalidateMargin,
                                                    engine.SegmentHeight - RootBox.InvalidateMargin,
                                                    invalidateWidth,
                                                    engine.SegmentHeight * 2 + 2 * RootBox.InvalidateMargin);

            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate3));

            // Insert a fourth item at the start.
            var child4 = new MockData1(55, 77);

            child4.SimpleThree = "Beginning of world";
            owner.InsertIntoObjSeq1(0, child4);
            VerifyParagraphs(root, new string[] { "Beginning of world", child1String, "Inserted world", "Another world" });
            var expectedInvalidate4 = new Rectangle(-RootBox.InvalidateMargin,
                                                    -RootBox.InvalidateMargin,
                                                    invalidateWidth,
                                                    engine.SegmentHeight * 4 + 2 * RootBox.InvalidateMargin);

            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate4));

            // Delete the first item.
            //var topHookup = root.RootHookup as IndependentSequenceHookup<MockData1>;
            //Assert.That(topHookup, Is.Not.Null);
            owner.RemoveAtObjSeq1(0);
            VerifyParagraphs(root, new string[] { child1String, "Inserted world", "Another world" });
            Assert.That(child4.SimpleThreeHookupCount, Is.EqualTo(0), "The hookup for a deleted object should be disposed.");
            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate4));

            // Delete a middle item.
            owner.RemoveAtObjSeq1(1);
            VerifyParagraphs(root, new string[] { child1String, "Another world" });
            Assert.That(child3.SimpleThreeHookupCount, Is.EqualTo(0), "The hookup for a deleted object should be disposed.");
            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate3));

            // Delete the last item.
            owner.RemoveAtObjSeq1(1);
            VerifyParagraphs(root, new string[] { child1String });
            Assert.That(child2.SimpleThreeHookupCount, Is.EqualTo(0), "The hookup for a deleted object should be disposed.");
            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate2));

            // Delete the only remaining item.
            owner.RemoveAtObjSeq1(0);
            VerifyParagraphs(root, new string[0]);
            Assert.That(child1.SimpleThreeHookupCount, Is.EqualTo(0), "The hookup for a deleted object should be disposed.");
            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate1));

            // Eventually add some operations that allow inserting and deleting multiple items.

            // We also need to be able to insert two or more object sequences into the same containing box.
            // That's probably another test, perhaps a view of the root where for each data item,
            // we insert its subitems, then for those insert paragraphs.
            // Let's assume there's always one top-level hookup for the root.
        }
示例#12
0
        public void DiffWS()
        {
            var tsf    = TsStrFactoryClass.Create();
            var styles = new AssembledStyles();
            var root   = new RootBoxFdo(styles);
            var mock1  = new MockData1(23, 23);

            mock1.SimpleTwo = tsf.MakeString("newoldcontents", 23);
            var bldr = mock1.SimpleTwo.GetBldr();

            bldr.SetIntPropValues(3, 6, (int)FwTextPropType.ktptWs,
                                  (int)FwTextPropVar.ktpvDefault, 24);
            bldr.SetIntPropValues(6, 14, (int)FwTextPropType.ktptWs,
                                  (int)FwTextPropVar.ktpvDefault, 25);
            mock1.SimpleTwo = bldr.GetString();
            var engine = new FakeRenderEngine()
            {
                Ws = 23, SegmentHeight = 13
            };
            var factory = new FakeRendererFactory();

            factory.SetRenderer(23, engine);
            root.Builder.Show(Display.Of(() => mock1.SimpleTwo));
            var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory);

            root.Layout(layoutArgs);
            PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96);
            MockSite       site   = new MockSite();

            site.m_transform  = ptrans;
            site.m_vwGraphics = m_gm.VwGraphics;
            root.Site         = site;

            int            x        = FakeRenderEngine.SimulatedWidth("ne") + 2;
            var            location = new Point(x, 8);
            EventArgs      e        = new EventArgs();
            MouseEventArgs m        = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0);

            root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform);
            root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform);
            root.OnDoubleClick(e);
            Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection");
            Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("new"));

            x        = FakeRenderEngine.SimulatedWidth("new") + 2;
            location = new Point(x, 8);
            m        = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0);
            root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform);
            root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform);
            root.OnDoubleClick(e);
            Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection");
            Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("old"));

            x        = FakeRenderEngine.SimulatedWidth("newold") + 2;
            location = new Point(x, 8);
            m        = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0);
            root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform);
            root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform);
            root.OnDoubleClick(e);
            Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection");
            Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("contents"));

            x        = FakeRenderEngine.SimulatedWidth("newold");
            location = new Point(x, 8);             // at the right edge of the d at the end of newold
            m        = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0);
            root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform);
            root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform);
            root.OnDoubleClick(e);
            Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection");
            Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("old"));
        }
示例#13
0
        public void MouseEvents()
        {
            var string1 = "This is the day that the Lord has made.";

            var engine = new FakeRenderEngine()
            {
                Ws = 34, SegmentHeight = 13
            };
            var factory = new FakeRendererFactory();

            factory.SetRenderer(34, engine);
            var runStyle = new AssembledStyles().WithWs(34);

            var style = new AssembledStyles();
            var root  = new RootBox(style);
            var para1 = MakePara(style, runStyle, string1);

            root.AddBox(para1);
            PaintTransform ptrans     = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96);
            var            layoutArgs = new LayoutInfo(2, 2, 96, 96, FakeRenderEngine.SimulatedWidth("This is the day "), m_gm.VwGraphics, factory);

            root.Layout(layoutArgs);
            var mouseArgs = new MouseEventArgs(MouseButtons.Left, 1, 2, 5, 0);

            root.OnMouseDown(mouseArgs, Keys.None, m_gm.VwGraphics, ptrans);
            Assert.That(root.Selection, Is.TypeOf(typeof(InsertionPoint)));
            Assert.That(((InsertionPoint)root.Selection).LogicalParaPosition, Is.EqualTo(0));
            Assert.That(((InsertionPoint)root.Selection).AssociatePrevious, Is.False);

            // In a different place, tests moving the selection and also getting AssociatePrevious true.
            int widthThis  = FakeRenderEngine.SimulatedWidth("This");
            var mouseArgs2 = new MouseEventArgs(MouseButtons.Left, 1, 2 + widthThis - 1, 5, 0);

            root.OnMouseDown(mouseArgs2, Keys.None, m_gm.VwGraphics, ptrans);
            Assert.That(root.Selection, Is.TypeOf(typeof(InsertionPoint)));
            Assert.That(((InsertionPoint)root.Selection).LogicalParaPosition, Is.EqualTo(4));
            Assert.That(((InsertionPoint)root.Selection).AssociatePrevious, Is.True);

            // A click in the same place should not make a new selection.
            var sel = root.Selection;

            root.OnMouseDown(mouseArgs2, Keys.None, m_gm.VwGraphics, ptrans);             // no change
            Assert.That(root.Selection, Is.EqualTo(sel));

            // A shift-click close enough to the same place to be the same character position but difference AssocPrevious
            // should make the appropriate new IP, not a range.
            var mouseArgs2b = new MouseEventArgs(MouseButtons.Left, 1, 2 + widthThis + 1, 5, 0);

            root.OnMouseDown(mouseArgs2b, Keys.Shift, m_gm.VwGraphics, ptrans);
            Assert.That(root.Selection, Is.TypeOf(typeof(InsertionPoint)));
            Assert.That(((InsertionPoint)root.Selection).LogicalParaPosition, Is.EqualTo(4));
            Assert.That(((InsertionPoint)root.Selection).AssociatePrevious, Is.False);

            // A shift-click should make a range.
            root.OnMouseDown(mouseArgs, Keys.Shift, m_gm.VwGraphics, ptrans);
            Assert.That(root.Selection, Is.TypeOf(typeof(RangeSelection)));
            var anchor = ((RangeSelection)root.Selection).Anchor;
            var drag   = ((RangeSelection)root.Selection).DragEnd;

            Assert.That(anchor.LogicalParaPosition, Is.EqualTo(4));
            Assert.That(drag.LogicalParaPosition, Is.EqualTo(0));

            // shift-click further right: should move the drag end
            var mouseArgs3 = new MouseEventArgs(MouseButtons.Left, 1, 2 + 4, 5, 0);

            root.OnMouseDown(mouseArgs3, Keys.Shift, m_gm.VwGraphics, ptrans);
            Assert.That(root.Selection, Is.TypeOf(typeof(RangeSelection)));
            anchor = ((RangeSelection)root.Selection).Anchor;
            drag   = ((RangeSelection)root.Selection).DragEnd;
            Assert.That(anchor.LogicalParaPosition, Is.EqualTo(4));
            Assert.That(drag.LogicalParaPosition, Is.EqualTo(1));

            // mouse move, to a different position
            root.OnMouseMove(mouseArgs, Keys.None, m_gm.VwGraphics, ptrans);
            sel = root.Selection;
            Assert.That(sel, Is.TypeOf(typeof(RangeSelection)));
            anchor = ((RangeSelection)root.Selection).Anchor;
            drag   = ((RangeSelection)root.Selection).DragEnd;
            Assert.That(anchor.LogicalParaPosition, Is.EqualTo(4));
            Assert.That(drag.LogicalParaPosition, Is.EqualTo(0));

            // mouse move to the same position: no new selection.
            root.OnMouseMove(mouseArgs, Keys.None, m_gm.VwGraphics, ptrans);             // no actual movement
            Assert.That(root.Selection, Is.EqualTo(sel));
            Assert.That(((RangeSelection)root.Selection).DragEnd, Is.EqualTo(drag));

            // mouse move to an IP at the anchor should return us to an IP
            root.OnMouseMove(mouseArgs2b, Keys.None, m_gm.VwGraphics, ptrans);
            Assert.That(root.Selection, Is.TypeOf(typeof(InsertionPoint)));
            Assert.That(((InsertionPoint)root.Selection).LogicalParaPosition, Is.EqualTo(4));
            Assert.That(((InsertionPoint)root.Selection).AssociatePrevious, Is.False);

            // mouse down on next line makes a selection there. Confirm proper passing of srcRect for vertical offset
            var mouseArgs4 = new MouseEventArgs(MouseButtons.Left, 1, 2 + 4, 2 + 16, 0);

            root.OnMouseDown(mouseArgs4, Keys.None, m_gm.VwGraphics, ptrans);
            var paraBox = (ParaBox)root.FirstBox;
            var seg2    = ((StringBox)paraBox.FirstBox.Next).Segment as FakeSegment;

            Assert.That(seg2, Is.Not.Null);
            Assert.That(seg2.LastPointToCharArgs, Is.Not.Null);
            var topOfseg2 = paraBox.FirstBox.Height;

            Assert.That(seg2.LastPointToCharArgs.RcSrc, Is.EqualTo(new Rect(-2, -2 - topOfseg2, 94, 94 - topOfseg2)));
        }
示例#14
0
        public void DrawingBordersandBackground()
        {
            var root = new RootBoxFdo(new AssembledStyles());

            SetupFakeRootSite(root);
            var layoutInfo = HookupTests.MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 55);

            root.RendererFactory = layoutInfo.RendererFactory;
            var mock1 = new MockData1()
            {
                SimpleThree = "This is the first paragraph."
            };
            // The length of the second paragraph is found by experiment to be enough so that
            // despite its lacking borders it also breaks into 2 lines in the second step.
            var mock2 = new MockData1()
            {
                SimpleThree = "Here is another paragraph. It needs to be a bit longer."
            };

            root.Builder.Show(
                Paragraph.Containing(Display.Of(() => mock1.SimpleThree)).BackColor(Color.Red)
                .Margins(1.Points(), 2.Points(), 3.Points(), 4.Points())
                .Borders(5.Points(), 6.Points(), 7.Points(), 8.Points(), Color.Blue)
                .Pads(9.Points(), 10.Points(), 11.Points(), 12.Points()),
                Paragraph.Containing(Display.Of(() => mock2.SimpleThree)).BackColor(Color.Yellow)
                .Margins(1.Points(), 2.Points(), 3.Points(), 4.Points()));
            root.Layout(layoutInfo);
            // We want to keep track of the sequence of paint operations in all three segments.
            var drawActions = new List <object>();
            var vg          = new MockGraphics();

            vg.DrawActions = drawActions;
            var para1      = (ParaBox)root.FirstBox;
            var stringbox1 = (StringBox)para1.FirstBox;
            var seg1       = (FakeSegment)stringbox1.Segment;

            seg1.DrawActions = drawActions;
            var para2      = (ParaBox)para1.Next;
            var stringbox2 = (StringBox)para2.FirstBox;
            var seg2       = (FakeSegment)stringbox2.Segment;

            seg2.DrawActions = drawActions;

            var site = (MockSite)root.Site;

            root.Paint(vg, site.m_transform);
            var paintTrans = site.m_transform;
            int position   = 0;

            int red      = (int)ColorUtil.ConvertColorToBGR(Color.Red);
            int margLeft = layoutInfo.MpToPixelsX(1000);

            Assert.That(margLeft, Is.EqualTo(1));
            int bordLeft = layoutInfo.MpToPixelsX(5000);

            Assert.That(bordLeft, Is.EqualTo(7));
            int xOffset = 2 - 100;             // how far it is pushed over by the offsets of the layoutInfo
            int margTop = layoutInfo.MpToPixelsY(2000);

            Assert.That(margTop, Is.EqualTo(3));
            int bordTop = layoutInfo.MpToPixelsY(6000);

            Assert.That(bordTop, Is.EqualTo(8));
            int yOffset = 2 - 200;             // how far it is pushed down by the offsets of the layoutInfo
            int padLeft = layoutInfo.MpToPixelsX(9000);

            Assert.That(padLeft, Is.EqualTo(12));
            int padRight = layoutInfo.MpToPixelsX(11000);

            Assert.That(padRight, Is.EqualTo(15));
            int padTop = layoutInfo.MpToPixelsY(10000);

            Assert.That(padTop, Is.EqualTo(13));
            int padBottom = layoutInfo.MpToPixelsY(12000);

            Assert.That(padBottom, Is.EqualTo(16));
            // First it should draw a background rectangle for the first paragraph.
            // It is indented by the left margin and the left border, and down by the top margin and border.
            // The other side is determined by the size of the embedded box and the two pads.
            VerifyRect(drawActions, ref position, margLeft + bordLeft + xOffset, margTop + bordTop + yOffset,
                       margLeft + bordLeft + xOffset + stringbox1.Width + padLeft + padRight,
                       margTop + bordTop + yOffset + stringbox1.Height + padTop + padBottom,
                       red);
            int bordBottom = layoutInfo.MpToPixelsY(8000);

            Assert.That(bordBottom, Is.EqualTo(11));
            int blue = (int)ColorUtil.ConvertColorToBGR(Color.Blue);

            // It's arbitrary what order we draw the borders, and I wish the test didn't specify it,
            // but in fact the current implementation draws the left border first.
            VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset,
                       margLeft + bordLeft + xOffset,
                       margTop + bordTop + yOffset + padTop + stringbox1.Height + padBottom + bordBottom,
                       blue);
            int bordRight = layoutInfo.MpToPixelsX(7000);

            Assert.That(bordRight, Is.EqualTo(9));
            // Then the top border
            VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset,
                       margLeft + bordLeft + xOffset + padLeft + stringbox1.Width + padRight + bordRight,
                       margTop + bordTop + yOffset,
                       blue);
            // Then the right border
            VerifyRect(drawActions, ref position,
                       margLeft + bordLeft + xOffset + padLeft + stringbox1.Width + padRight,
                       margTop + yOffset,
                       margLeft + bordLeft + xOffset + padLeft + stringbox1.Width + padRight + bordRight,
                       margTop + bordTop + yOffset + padTop + stringbox1.Height + padBottom + bordBottom,
                       blue);
            // Then the bottom border
            VerifyRect(drawActions, ref position,
                       margLeft + xOffset,
                       margTop + bordTop + yOffset + padTop + stringbox1.Height + padBottom,
                       margLeft + bordLeft + xOffset + padLeft + stringbox1.Width + padRight + bordRight,
                       margTop + bordTop + yOffset + padTop + stringbox1.Height + padBottom + bordBottom,
                       blue);
            // Figure an adjusted y offset for the second paragraph. Everything is down by the height
            // of the first paragraph, except that the top and bottom margins overlap by the
            // height of the smaller.
            int yOffset2 = yOffset + para1.Height - margTop;
            int yellow   = (int)ColorUtil.ConvertColorToBGR(Color.Yellow);

            // Next a background block for the second paragraph.
            // (Background color should be reset for the embedded string boxes, so they should not draw their own
            // background.)
            VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset2,
                       margLeft + xOffset + stringbox2.Width,
                       margTop + yOffset2 + stringbox2.Height,
                       yellow);
            // Verify the position where the text is drawn
            VerifyDraw(drawActions, ref position, seg1, margLeft + bordLeft + padLeft + 2, margTop + bordTop + padTop + 2);
            VerifyDraw(drawActions, ref position, seg2, margLeft + 2, para1.Height + 2);             //margTop cancels out
            // And that should be all!
            Assert.That(position, Is.EqualTo(drawActions.Count));

            // Verify that multi-lines in a paragraph are appropriately laid out with margin etc.
            int maxWidth = para1.Width - FakeRenderEngine.SimulatedWidth("paragraph");

            // This maxWidth should force each paragraph to make two segments.
            layoutInfo = HookupTests.MakeLayoutInfo(maxWidth, m_gm.VwGraphics, 55);
            root.Layout(layoutInfo);
            drawActions.Clear();
            position = 0;
            var stringbox1a = (StringBox)para1.FirstBox;
            var seg1a       = (FakeSegment)stringbox1a.Segment;

            seg1a.DrawActions = drawActions;
            var stringbox1b = (StringBox)stringbox1a.Next;
            var seg1b       = (FakeSegment)stringbox1b.Segment;

            seg1b.DrawActions = drawActions;
            var stringbox2a = (StringBox)para2.FirstBox;
            var seg2a       = (FakeSegment)stringbox2a.Segment;

            seg2a.DrawActions = drawActions;
            var stringbox2b = (StringBox)stringbox2a.Next;
            var seg2b       = (FakeSegment)stringbox2b.Segment;

            seg2b.DrawActions = drawActions;

            root.Paint(vg, site.m_transform);
            int margRight = layoutInfo.MpToPixelsX(3000);

            Assert.That(margRight, Is.EqualTo(4));
            // First it should draw a background rectangle for the first paragraph.
            // It is indented by the left margin and the left border, and down by the top margin and border.
            // The other side is determined by maxWidth minus the right margin and border.
            int contentHeight1 = stringbox1a.Height + stringbox1b.Height;

            VerifyRect(drawActions, ref position, margLeft + bordLeft + xOffset, margTop + bordTop + yOffset,
                       maxWidth - margRight - bordRight + xOffset,
                       margTop + bordTop + yOffset + contentHeight1 + padTop + padBottom,
                       red);
            // It's arbitrary what order we draw the borders, and I wish the test didn't specify it,
            // but in fact the current implementation draws the left border first.
            VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset,
                       margLeft + bordLeft + xOffset,
                       margTop + bordTop + yOffset + padTop + contentHeight1 + padBottom + bordBottom,
                       blue);
            // Then the top border
            VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset,
                       maxWidth - margRight + xOffset,
                       margTop + bordTop + yOffset,
                       blue);
            // Then the right border
            VerifyRect(drawActions, ref position,
                       maxWidth - margRight - bordRight + xOffset,
                       margTop + yOffset,
                       maxWidth - margRight + xOffset,
                       margTop + bordTop + yOffset + padTop + contentHeight1 + padBottom + bordBottom,
                       blue);
            // Then the bottom border
            VerifyRect(drawActions, ref position,
                       margLeft + xOffset,
                       margTop + bordTop + yOffset + padTop + contentHeight1 + padBottom,
                       maxWidth - margRight + xOffset,
                       margTop + bordTop + yOffset + padTop + contentHeight1 + padBottom + bordBottom,
                       blue);
            // Figure an adjusted y offset for the second paragraph. Everything is down by the height
            // of the first paragraph, except that the top and bottom margins overlap by the
            // height of the smaller.
            yOffset2 = yOffset + para1.Height - margTop;
            // Next a background block for the second paragraph.
            // (Background color should be reset for the embedded string boxes, so they should not draw their own
            // background.)
            VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset2,
                       maxWidth - margRight + xOffset,
                       margTop + yOffset2 + stringbox2a.Height + stringbox2b.Height,
                       yellow);
            // Verify the position where the text is drawn
            VerifyDraw(drawActions, ref position, seg1a, margLeft + bordLeft + padLeft + 2, margTop + bordTop + padTop + 2);
            VerifyDraw(drawActions, ref position, seg1b, margLeft + bordLeft + padLeft + 2,
                       margTop + bordTop + padTop + 2 + stringbox1a.Height);
            VerifyDraw(drawActions, ref position, seg2a, margLeft + 2, para1.Height + 2);                      //margTop cancels out
            VerifyDraw(drawActions, ref position, seg2b, margLeft + 2, para1.Height + 2 + stringbox2a.Height); //margTop cancels out
            // And that should be all!
            Assert.That(position, Is.EqualTo(drawActions.Count));

            // A quick check that Relayout puts things in the same places.
            drawActions.Clear();
            position = 0;
            var fixupMap = new Dictionary <Box, Rectangle>();

            fixupMap[para1] = new Rectangle(0, 0, 10, 10);
            var oldstring1aLeft = stringbox1a.Left;
            var oldstring1bTop  = stringbox1b.Top;

            using (var lcb = new LayoutCallbacks(root))
                root.Relayout(layoutInfo, fixupMap, lcb);
            Assert.That(drawActions.Count, Is.EqualTo(0));
            Assert.That(para1.FirstBox.Left, Is.EqualTo(oldstring1aLeft));
            Assert.That(para1.FirstBox.Next.Top, Is.EqualTo(oldstring1bTop));
        }
示例#15
0
        public void BasicDrop()
        {
            var styles = new AssembledStyles();
            var root   = new RootBoxFdo(styles);
            var mock1  = new MockData1(23, 23);

            mock1.SimpleThree = "old contents";
            var engine = new FakeRenderEngine()
            {
                Ws = 23, SegmentHeight = 13
            };
            var factory = new FakeRendererFactory();

            factory.SetRenderer(23, engine);
            root.Builder.Show(Display.Of(() => mock1.SimpleThree, 23));
            var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory);

            root.Layout(layoutArgs);
            PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96);
            MockSite       site   = new MockSite();

            site.m_transform  = ptrans;
            site.m_vwGraphics = m_gm.VwGraphics;
            root.Site         = site;

            var dataObj  = new DataObject(DataFormats.StringFormat, "new ");
            int x        = FakeRenderEngine.SimulatedWidth("old ") + 2;
            var location = new Point(x, 8);

            // A drag to where we can drop, allowing both copy and move, no keys held
            var dragArgs = new DragEventArgs(dataObj, (int)DragDropKeyStates.None, 200, 300,
                                             DragDropEffects.Copy | DragDropEffects.Move,
                                             DragDropEffects.None);

            root.OnDragEnter(dragArgs, location, m_gm.VwGraphics, ptrans);
            Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.Move));
            Assert.That(root.DragState, Is.EqualTo(WindowDragState.DraggingHere));
            root.OnDragLeave();
            Assert.That(root.DragState, Is.EqualTo(WindowDragState.None));

            // Though other factors would favor move, only copy is allowed here.
            dragArgs = new DragEventArgs(dataObj, (int)DragDropKeyStates.None, 200, 300,
                                         DragDropEffects.Copy,
                                         DragDropEffects.None);
            root.OnDragEnter(dragArgs, location, m_gm.VwGraphics, ptrans);
            Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.Copy));

            // Though otherwise we could copy, there is no text data in the data object.
            dragArgs = new DragEventArgs(new DataObject(), (int)DragDropKeyStates.None, 200, 300,
                                         DragDropEffects.Copy | DragDropEffects.Move,
                                         DragDropEffects.None);
            root.OnDragEnter(dragArgs, location, m_gm.VwGraphics, ptrans);
            Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.None));

            dragArgs = new DragEventArgs(dataObj, (int)DragDropKeyStates.ControlKey, 200, 300,
                                         DragDropEffects.Copy | DragDropEffects.Move,
                                         DragDropEffects.None);
            root.OnDragEnter(dragArgs, location, m_gm.VwGraphics, ptrans);
            Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.Copy));

            root.OnDragDrop(dragArgs, location, m_gm.VwGraphics, ptrans);
            Assert.That(mock1.SimpleThree, Is.EqualTo("old new contents"));
        }
示例#16
0
        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));
        }
示例#17
0
        public void InsertGrowsPara()
        {
            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 data1 = new MockData1(34, 35);

            data1.SimpleThree = contents;
            var source = new TextSource(clientRuns, null);
            var para   = new ParaBox(styles, source);
            var hookup = new StringHookup(this, () => data1.SimpleThree, hook => data1.SimpleThreeChanged += hook.StringPropChanged,
                                          hook => data1.SimpleThreeChanged -= hook.StringPropChanged, para);

            hookup.Writer = newVal => data1.SimpleThree = newVal;
            run.Hookup    = hookup;
            var extraBox = new BlockBox(styles, Color.Red, 50, 72000);
            var root     = new RootBoxFdo(styles);

            root.SizeChanged += root_SizeChanged;
            root.AddBox(para);
            root.AddBox(extraBox);
            var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory);

            root.Layout(layoutArgs);
            Assert.IsTrue(m_sizeChangedCalled);
            Assert.That(root.Height, Is.EqualTo(13 + 96));
            Assert.That(root.Width, Is.EqualTo(FakeRenderEngine.SimulatedWidth(contents)));

            int widthThisIsThe = FakeRenderEngine.SimulatedWidth("This is the");

            layoutArgs = MakeLayoutInfo(widthThisIsThe + 2, m_gm.VwGraphics, factory);
            root.Layout(layoutArgs);
            Assert.That(root.Height, Is.EqualTo(26 + 96), "two line para is twice the height");
            Assert.That(root.Width, Is.EqualTo(widthThisIsThe + 2), "two-line para occupies full available width");
            Assert.That(extraBox.Top, Is.EqualTo(26));

            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;
            m_sizeChangedCalled = false;
            var ip = para.SelectAtEnd();

            ip.InsertText(" We will be");
            Assert.That(para.Height, Is.EqualTo(39), "inserted text makes para a line higher");
            Assert.That(root.Height, Is.EqualTo(39 + 96), "root grows when para does");
            Assert.That(root.Width, Is.EqualTo(widthThisIsThe + 2), "three-line para occupies full available width");
            Assert.That(extraBox.Top, Is.EqualTo(39));
            Assert.IsTrue(m_sizeChangedCalled);
        }
示例#18
0
        public void GetCharPlacement(int ichBase, IVwGraphics vg, int ichMin, int ichLim, Rect rcSrc, Rect rcDst,
                                     bool fSkipSpace, int cxdMax, out int cxd,
                                     [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ArrayPtrMarshaler),
                                                SizeParamIndex = 1)] ArrayPtr /*int[]*/ rgxdLefts,
                                     [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ArrayPtrMarshaler),
                                                SizeParamIndex = 1)] ArrayPtr /*int[]*/ rgxdRights,
                                     [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ArrayPtrMarshaler),
                                                SizeParamIndex = 1)] ArrayPtr /*int[]*/ rgydUnderTops)
        {
            if (cxdMax == 0)
            {
                // don't count this call; it's a preliminary query to get the length.
                if (NextCharPlacementResults.Count == 0)
                {
                    cxd = 1;
                }
                else
                {
                    cxd = NextCharPlacementResults[0].Lefts.Length;
                }
                return;
            }
            PrevCharPlacementArgs.Add(new CharPlacementArgs()
            {
                IchBase   = ichBase,
                Vg        = vg,
                IchMin    = ichMin,
                IchLim    = ichLim,
                RcSrc     = rcSrc,
                RcDst     = rcDst,
                SkipSpace = fSkipSpace,
                CxdMax    = cxdMax
            });
            var lefts  = new int[1];
            var rights = new int[1];
            var tops   = new int[1];

            if (NextCharPlacementResults.Count == 0)
            {
                // This is a plausible algorithm which is not currently used and hasn't been tried.
                cxd = 1;
                if (cxdMax < 1)
                {
                    return;
                }

                int cchMin = ichMin - ichBase;
                if (cchMin <= 0 || cchMin >= Length)
                {
                    cxd = 0;
                    return;
                }
                int cch = ichLim - ichMin;
                if (ichLim > ichBase + Length)
                {
                    cch = Length - (ichMin - ichBase);
                }

                int left  = FakeRenderEngine.SimulatedWidth(Text.Substring(cchMin));
                int right = left + FakeRenderEngine.SimulatedWidth(Text.Substring(cchMin, cch));
                lefts[0]  = MapXTo(left, rcSrc, rcDst);
                rights[0] = MapXTo(right, rcSrc, rcDst);
                tops[0]   = MapYTo(Ascent + 1, rcSrc, rcDst);
            }
            else
            {
                var nextResult = NextCharPlacementResults[0];
                NextCharPlacementResults.RemoveAt(0);
                cxd = nextResult.Lefts.Length;
                if (cxdMax == 0)
                {
                    return;
                }
                lefts  = nextResult.Lefts;
                rights = nextResult.Rights;
                tops   = nextResult.Tops;
            }

            MarshalEx.ArrayToNative(rgxdLefts, cxdMax, lefts);
            MarshalEx.ArrayToNative(rgxdRights, cxdMax, rights);
            MarshalEx.ArrayToNative(rgydUnderTops, cxdMax, tops);
        }
示例#19
0
        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)));
        }
示例#20
0
        public void BasicDragMove()
        {
            var styles = new AssembledStyles();
            var root   = new RootBoxFdo(styles);
            var mock1  = new MockData1(23, 23);

            mock1.SimpleThree = "This is the day";
            var engine = new FakeRenderEngine()
            {
                Ws = 23, SegmentHeight = 13
            };
            var factory = new FakeRendererFactory();

            factory.SetRenderer(23, engine);
            root.Builder.Show(Display.Of(() => mock1.SimpleThree, 23));
            var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory);

            root.Layout(layoutArgs);
            PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96);
            MockSite       site   = new MockSite();

            site.m_transform  = ptrans;
            site.m_vwGraphics = m_gm.VwGraphics;
            root.Site         = site;

            SelectionBuilder.In(root).Offset("This ".Length).To.Offset("This is ".Length).Install();

            var dataObj  = new DataObject(DataFormats.StringFormat, "is ");
            int x        = FakeRenderEngine.SimulatedWidth("This is the ") + 2;
            var location = new Point(x, 8);

            // A drag to where we can drop, allowing both copy and move, no keys held
            var dragArgs = new DragEventArgs(dataObj, (int)DragDropKeyStates.None, 200, 300,
                                             DragDropEffects.Copy | DragDropEffects.Move,
                                             DragDropEffects.None);

            root.OnDragEnter(dragArgs, location, m_gm.VwGraphics, ptrans);
            Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.Move));
            Assert.That(root.DragState, Is.EqualTo(WindowDragState.DraggingHere));

            var qcdArgs = new QueryContinueDragEventArgs((int)DragDropKeyStates.None, false, DragAction.Drop);

            root.OnQueryContinueDrag(qcdArgs);
            Assert.That(root.DragState, Is.EqualTo(WindowDragState.InternalMove));
            root.OnDragLeave();
            Assert.That(root.DragState, Is.EqualTo(WindowDragState.InternalMove), "DragLeave should not clear InternalMove");

            root.OnDragDrop(dragArgs, location, m_gm.VwGraphics, ptrans);
            Assert.That(mock1.SimpleThree, Is.EqualTo("This the is day"));
            Assert.That(root.DragState, Is.EqualTo(WindowDragState.None));

            // Now let's drag the 'is' out to another window.
            SelectionBuilder.In(root).Offset("This the ".Length).To.Offset("This the is ".Length).Install();
            qcdArgs = new QueryContinueDragEventArgs((int)DragDropKeyStates.None, false, DragAction.Drop);
            root.OnQueryContinueDrag(qcdArgs);
            Assert.That(root.DragState, Is.EqualTo(WindowDragState.None),
                        "We should only set InternalMove if this window is the destination");
            Assert.That(mock1.SimpleThree, Is.EqualTo("This the day"));

            // Check that we can't drag inside our own selection.
            SelectionBuilder.In(root).Offset("This ".Length).To.Offset("This the".Length).Install();
            x        = FakeRenderEngine.SimulatedWidth("This t") + 2;
            location = new Point(x, 8);
            dragArgs = new DragEventArgs(dataObj, (int)DragDropKeyStates.None, 200, 300,
                                         DragDropEffects.Copy | DragDropEffects.Move,
                                         DragDropEffects.None);
            root.DragState = WindowDragState.InternalMove;
            root.OnDragDrop(dragArgs, location, m_gm.VwGraphics, ptrans);
            Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.None));
            Assert.That(mock1.SimpleThree, Is.EqualTo("This the day"));
        }
示例#21
0
        public void SubParaSequenceTest()
        {
            var owner      = new MockData1(55, 77);
            var styles     = new AssembledStyles();
            var root       = new RootBoxFdo(styles);
            var layoutInfo = MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 55);

            SetupFakeRootSite(root);
            var      engine = layoutInfo.RendererFactory.GetRenderer(55, m_gm.VwGraphics) as FakeRenderEngine;
            MockSite site   = new MockSite();

            root.Site = site;
            PaintTransform ptrans = new PaintTransform(2, 4, 96, 100, 0, 10, 120, 128);

            site.m_transform  = ptrans;
            site.m_vwGraphics = m_gm.VwGraphics;
            root.Builder.Show(Paragraph.Containing(Display.Of(() => owner.ObjSeq1).Using((bldr, md) => bldr.AddString(() => md.SimpleThree, 55))));
            root.Layout(layoutInfo);
            VerifyParagraphs(root, new [] { "" });

            //// Insert the first item into owner.ObjSeq1 and check all the right connections appear
            var child1       = new MockData1(55, 77);
            var child1String = "Hello world, this is a wide string";

            child1.SimpleThree = child1String;
            owner.InsertIntoObjSeq1(0, child1);
            VerifyParagraphs(root, new string[] { child1String });
            Assert.That(child1.SimpleThreeHookupCount, Is.EqualTo(1), "Builder.AddString should set up a hookup for the string");
            int invalidateWidth     = FakeRenderEngine.SimulatedWidth(child1String) + 2 * RootBox.InvalidateMargin;
            var expectedInvalidate1 = new Rectangle(-RootBox.InvalidateMargin, -RootBox.InvalidateMargin,
                                                    invalidateWidth,
                                                    engine.SegmentHeight + 2 * RootBox.InvalidateMargin);

            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate1));

            // Insert a second item and check again.
            var child2 = new MockData1(55, 77);

            child2.SimpleThree = "Another world";
            invalidateWidth   += FakeRenderEngine.SimulatedWidth("Another world");
            site.RectsInvalidated.Clear();
            owner.InsertIntoObjSeq1(1, child2);
            VerifyParagraphs(root, new string[] { child1String + "Another world" });
            Assert.That(child2.SimpleThreeHookupCount, Is.EqualTo(1), "Builder.AddString should set up a hookup for the string");
            var expectedInvalidate2 = new Rectangle(-RootBox.InvalidateMargin, -RootBox.InvalidateMargin,
                                                    invalidateWidth,
                                                    engine.SegmentHeight + 2 * RootBox.InvalidateMargin);

            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate2));

            // Insert a third item between the first two.
            var child3 = new MockData1(55, 77);

            child3.SimpleThree = "Inserted world";
            invalidateWidth   += FakeRenderEngine.SimulatedWidth("Inserted world");
            site.RectsInvalidated.Clear();
            owner.InsertIntoObjSeq1(1, child3);
            VerifyParagraphs(root, new string[] { child1String + "Inserted world" + "Another world" });
            var expectedInvalidate3 = new Rectangle(-RootBox.InvalidateMargin, -RootBox.InvalidateMargin,
                                                    invalidateWidth,
                                                    engine.SegmentHeight + 2 * RootBox.InvalidateMargin);

            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate3));

            // Insert a fourth item at the start.
            var child4 = new MockData1(55, 77);

            child4.SimpleThree = "Beginning of world";
            invalidateWidth   += FakeRenderEngine.SimulatedWidth("Beginning of world");
            site.RectsInvalidated.Clear();
            owner.InsertIntoObjSeq1(0, child4);
            VerifyParagraphs(root, new string[] { "Beginning of world" + child1String + "Inserted world" + "Another world" });
            var expectedInvalidate4 = new Rectangle(-RootBox.InvalidateMargin, -RootBox.InvalidateMargin,
                                                    invalidateWidth,
                                                    engine.SegmentHeight + 2 * RootBox.InvalidateMargin);

            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate4));

            // Delete the first item.
            site.RectsInvalidated.Clear();
            owner.RemoveAtObjSeq1(0);
            VerifyParagraphs(root, new string[] { child1String + "Inserted world" + "Another world" });
            Assert.That(child4.SimpleThreeHookupCount, Is.EqualTo(0), "The hookup for a deleted object should be disposed.");
            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate4));

            // Delete a middle item.
            site.RectsInvalidated.Clear();
            owner.RemoveAtObjSeq1(1);
            VerifyParagraphs(root, new string[] { child1String + "Another world" });
            Assert.That(child3.SimpleThreeHookupCount, Is.EqualTo(0), "The hookup for a deleted object should be disposed.");
            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate3));

            // Delete the last item.
            site.RectsInvalidated.Clear();
            owner.RemoveAtObjSeq1(1);
            VerifyParagraphs(root, new string[] { child1String });
            Assert.That(child2.SimpleThreeHookupCount, Is.EqualTo(0), "The hookup for a deleted object should be disposed.");
            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate2));

            // Delete the only remaining item.
            site.RectsInvalidated.Clear();
            owner.RemoveAtObjSeq1(0);
            VerifyParagraphs(root, new string[] { "" });
            Assert.That(child1.SimpleThreeHookupCount, Is.EqualTo(0), "The hookup for a deleted object should be disposed.");
            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate1));

            // Eventually add some operations that allow inserting and deleting multiple items.

            // We also need to be able to insert two or more object sequences into the same containing box.
            // That's probably another test, perhaps a view of the root where for each data item,
            // we insert its subitems, then for those insert paragraphs.
            // Let's assume there's always one top-level hookup for the root.
        }
示例#22
0
        public void DragCopyRtf()
        {
            var stylesheet  = new MockStylesheet();
            var styleFirst  = stylesheet.AddStyle("first", false);
            var styleSecond = stylesheet.AddStyle("second", false);
            var propsTrue   = new MockStyleProp <bool>()
            {
                Value = true, ValueIsSet = true
            };
            var charInfo = new MockCharStyleInfo();

            styleFirst.DefaultCharacterStyleInfo = charInfo;
            charInfo.Bold = propsTrue;
            // Todo: make styleSecond have pretty much everything else.
            var charInfo2 = new MockCharStyleInfo();

            styleSecond.DefaultCharacterStyleInfo = charInfo2;
            charInfo2.FontColor      = MakeColorProp(Color.Red);
            charInfo2.BackColor      = MakeColorProp(Color.Yellow);
            charInfo2.UnderlineColor = MakeColorProp(Color.Green);
            charInfo2.Italic         = propsTrue;
            charInfo2.FontName       = new MockStyleProp <string>()
            {
                Value = "Arial", ValueIsSet = true
            };

            var styles = new AssembledStyles(stylesheet);
            var root   = new RootBoxFdo(styles);
            var mock1  = new MockData1(23, 23);

            mock1.SimpleThree = "This is";
            var mock2 = new MockData1(23, 23);

            mock2.SimpleThree = " the day";
            var mock3 = new MockData1(23, 23);

            mock3.SimpleThree = " that the";
            var engine = new FakeRenderEngine()
            {
                Ws = 23, SegmentHeight = 13
            };
            var factory = new FakeRendererFactory();
            var wsf     = new MockWsf();

            engine.WritingSystemFactory = wsf;
            var wsEngine = wsf.MakeMockEngine(23, "en", engine);

            factory.SetRenderer(23, engine);
            root.Builder.Show(
                Paragraph.Containing(
                    Display.Of(() => mock1.SimpleThree, 23).Style("first"),
                    Display.Of(() => mock2.SimpleThree, 23).Style("second"),
                    Display.Of(() => mock3.SimpleThree, 23).Style("first")
                    ));
            var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory);

            root.Layout(layoutArgs);
            PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96);
            MockSite       site   = new MockSite();

            site.m_transform  = ptrans;
            site.m_vwGraphics = m_gm.VwGraphics;
            root.Site         = site;

            SelectionBuilder.In(root).Offset("This ".Length).To.Offset("This is the day that".Length).Install();
            int indent = FakeRenderEngine.SimulatedWidth("This ");

            root.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, indent + 5, 4, 0), Keys.None, m_gm.VwGraphics, ptrans);
            root.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 1, indent + 5, 4, 0), Keys.None, m_gm.VwGraphics, ptrans);
            Assert.That(GetStringDropData(site), Is.EqualTo("is the day that"));
            // The order of the font and colors in the color table is arbitrary. This happens to be what the code does now. For some reason
            // Color.Green has green only 128.
            // The order of items in the definition of a style is arbitrary.
            // We're not doing anything yet for background color. \highlightN can specify background color for a character run,
            // but it can't be part of a style definition.
            Assert.That(GetRtfDropData(site), Is.EqualTo(
                            RangeSelection.RtfPrefix
                            + @"{\fonttbl{\f0 MockFont;}{\f1 Arial;}}"
                            + @"{\colortbl ;\red0\green0\blue0;\red255\green255\blue255;\red255\green0\blue0;\red255\green255\blue0;\red0\green128\blue0;}"
                            + @"{\stylesheet{\*\cs1\b\additive first;\*\cs2\i\f1\cf3\ulc5\additive second;}}"
                            + RangeSelection.RtfDataPrefix
                            + @"{\*\cs1\b is}{\*\cs2\i\f1\cf3\ulc5\highlight4  the day}{\*\cs1\b  that\par}"
                            + @"}"));

            // Todo: handle styles that depend on WS
            // Todo: handle more than two runs
            // Todo: handle runs where actual formatting differs from style-specified formatting
            // Todo: handle multiple paragraphs
            // Todo: handle paragraph styles
        }
示例#23
0
        private void BodyofUserPromptTest(MockData1 data1, Flow promptField, Func <string> reader)
        {
            var engine = new FakeRenderEngine()
            {
                Ws = 34, SegmentHeight = 13
            };
            var factory = new FakeRendererFactory();

            factory.SetRenderer(34, engine);
            factory.SetRenderer(35, engine);
            factory.SetRenderer(0, engine);             // for literals
            var styles = new AssembledStyles().WithWs(34);

            var root = new RootBoxFdo(styles);

            root.Builder.Show(
                Paragraph.Containing(
                    Display.Of("lead in ", 34),
                    promptField,
                    Display.Of("trailing", 34)
                    )
                );
            var para = (ParaBox)root.FirstBox;

            Assert.That(para.Source.RenderText, Is.EqualTo("lead in type here trailing"));

            int width      = FakeRenderEngine.SimulatedWidth("lead in type her");        // should make it take 2 lines and split prompt.
            var layoutArgs = MakeLayoutInfo(width, m_gm.VwGraphics, factory);

            root.Layout(layoutArgs);
            MockSite       site   = new MockSite();
            PaintTransform ptrans = new PaintTransform(2, 4, 96, 96, 0, 10, 96, 96);

            site.m_transform  = ptrans;
            site.m_vwGraphics = m_gm.VwGraphics;
            root.Site         = site;

            // Click on "type here" produces an IP in the empty string.
            int leadWidth = FakeRenderEngine.SimulatedWidth("lead in ");
            var mouseArgs = new MouseEventArgs(MouseButtons.Left, 1, 2 + leadWidth + 3, 0, 0);

            root.OnMouseDown(mouseArgs, Keys.None, m_gm.VwGraphics, ptrans);
            var ip = root.Selection as InsertionPoint;

            Assert.That(ip, Is.Not.Null);
            Assert.That(ip.LogicalParaPosition, Is.EqualTo("lead in ".Length));
            Assert.That(ip.StringPosition, Is.EqualTo(0));

            // IP is drawn as range covering "type here"
            ip.Draw(m_gm.VwGraphics, ptrans);
            var first = (StringBox)para.FirstBox;

            VerifyRangeSegmentDrawing(para, first, (FakeSegment)first.Segment, "lead in ".Length, "lead in type here ".Length,
                                      -4, 4 - 10, 4 - 10 + 13);
            var second = (StringBox)first.Next;

            VerifyRangeSegmentDrawing(para, second, (FakeSegment)second.Segment, "lead in ".Length, "lead in type here ".Length,
                                      -4 - 13, 4 - 10 + 13, 4 - 10 + 13 * 2);
            // Check that we get a sensible answer for the selection's containing rectangle.
            ((FakeSegment)first.Segment).LeftPositionOfRangeResult   = 17;
            ((FakeSegment)first.Segment).RightPositionOfRangeResult  = 29;
            ((FakeSegment)second.Segment).LeftPositionOfRangeResult  = 5;
            ((FakeSegment)second.Segment).RightPositionOfRangeResult = 13;
            var rect = ip.GetSelectionLocation(m_gm.VwGraphics, ptrans);

            Assert.That(rect.Top, Is.EqualTo(4 - 10));
            Assert.That(rect.Bottom, Is.EqualTo(4 - 10 + 13 * 2));
            Assert.That(rect.Left, Is.EqualTo(5));
            Assert.That(rect.Right, Is.EqualTo(29));
            VerifyRangeSegmentQuery(para, first, (FakeSegment)first.Segment, "lead in ".Length, "lead in type here ".Length,
                                    -4, 4 - 10, 4 - 10 + 13);
            VerifyRangeSegmentQuery(para, second, (FakeSegment)second.Segment, "lead in ".Length, "lead in type here ".Length,
                                    -4 - 13, 4 - 10 + 13, 4 - 10 + 13 * 2);
            Assert.That(second.IchMin, Is.EqualTo("lead in type ".Length));
            // When the IP is drawn like this, it doesn't flash!
            site.RectsInvalidatedInRoot.Clear();
            site.RectsInvalidated.Clear();
            root.FlashInsertionPoint();             // Call twice just in case somehow only some invalidates worked.
            root.FlashInsertionPoint();
            Assert.That(site.RectsInvalidated, Is.Empty);
            Assert.That(site.RectsInvalidatedInRoot, Is.Empty);
            // Typing something else makes "type here" go away and produces a normal IP after it.
            ip.InsertText("x");
            Assert.That(reader(), Is.EqualTo("x"));
            Assert.That(para.Source.RenderText, Is.EqualTo("lead in xtrailing"));
            ip = root.Selection as InsertionPoint;
            Assert.That(ip, Is.Not.Null);
            Assert.That(ip.ShouldFlash, Is.True);
            Assert.That(ip.LogicalParaPosition, Is.EqualTo("lead in x".Length));
            // Deleting back to empty string makes "type here" reappear.
            ip.Backspace();
            Assert.That(reader(), Is.EqualTo(""));
            Assert.That(para.Source.RenderText, Is.EqualTo("lead in type here trailing"));
            ip = root.Selection as InsertionPoint;
            Assert.That(ip, Is.Not.Null);
            Assert.That(ip.ShouldFlash, Is.False);
            Assert.That(ip.LogicalParaPosition, Is.EqualTo("lead in ".Length));
            Assert.That(ip.LastRenderParaPosition, Is.EqualTo("lead in type here ".Length));
            second = (StringBox)para.FirstBox.Next;
            Assert.That(second.IchMin, Is.EqualTo("lead in type ".Length));
            // Click after "type here" produces an IP at the right place in the following string.
            // We've arranged for the prompt to be split, so this is after the word 'here' on the second line.
            int hereTWidth = FakeRenderEngine.SimulatedWidth("here t");

            mouseArgs = new MouseEventArgs(MouseButtons.Left, 1, 2 + hereTWidth - 1, 4 - 10 + 13 + 2, 0);
            root.OnMouseDown(mouseArgs, Keys.None, m_gm.VwGraphics, ptrans);
            ip = root.Selection as InsertionPoint;
            Assert.That(ip, Is.Not.Null);
            Assert.That(ip.LogicalParaPosition, Is.EqualTo("lead in t".Length));
            Assert.That(ip.AssociatePrevious, Is.True);
            Assert.That(ip.StringPosition, Is.EqualTo(1));
            Assert.That(ip.RenderParaPosition, Is.EqualTo("lead in type here t".Length));
            // Also try a click in the second-line part of the prompt.
            int herWidth = FakeRenderEngine.SimulatedWidth("her");

            mouseArgs = new MouseEventArgs(MouseButtons.Left, 1, 2 + herWidth - 1, 4 - 10 + 13 + 2, 0);
            root.OnMouseDown(mouseArgs, Keys.None, m_gm.VwGraphics, ptrans);
            ip = root.Selection as InsertionPoint;
            Assert.That(ip, Is.Not.Null);
            Assert.That(ip.LogicalParaPosition, Is.EqualTo("lead in ".Length));
            Assert.That(ip.StringPosition, Is.EqualTo(0));
            Assert.That(ip.RenderParaPosition, Is.EqualTo("lead in ".Length));
            Assert.That(ip.LastRenderParaPosition, Is.EqualTo("lead in type here ".Length));
        }
示例#24
0
        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.
        }
示例#25
0
        public void NullObjChecker()
        {
            var owner  = new MockData1(55, 77);
            var child1 = new MockData1(55, 77);

            child1.SimpleThree = "This is a Test";
            owner.SimpleFour   = null;
            var styles     = new AssembledStyles();
            var root       = new RootBoxFdo(styles);
            var layoutInfo = MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 55);

            SetupFakeRootSite(root);
            var      engine = layoutInfo.RendererFactory.GetRenderer(55, m_gm.VwGraphics) as FakeRenderEngine;
            MockSite site   = new MockSite();

            root.Site = site;
            PaintTransform ptrans = new PaintTransform(2, 4, 96, 100, 0, 10, 120, 128);

            site.m_transform  = ptrans;
            site.m_vwGraphics = m_gm.VwGraphics;
            root.Builder.Show(Display.OfObj(() => owner.SimpleFour).Using((bldr, md) => bldr.AddString(() => md.SimpleThree, 55)));
            root.Layout(layoutInfo);

            int invalidateWidth1    = FakeRenderEngine.SimulatedWidth(child1.SimpleThree) + 2 * RootBox.InvalidateMargin;
            var expectedInvalidate1 = new Rectangle(-RootBox.InvalidateMargin, -RootBox.InvalidateMargin,
                                                    invalidateWidth1, engine.SegmentHeight + 2 * RootBox.InvalidateMargin);

            VerifyParagraphs(root, new string[0]);
            Assert.That(child1.SimpleThreeHookupCount, Is.EqualTo(0), "The hookup for this unconnected object should not exist");
            Assert.That(owner.SimpleFourHookupCount, Is.EqualTo(1), "The hookup for this null object should exist");

            site.RectsInvalidatedInRoot.Clear();
            owner.SimpleFour = child1;
            int invalidateWidth2    = FakeRenderEngine.SimulatedWidth(child1.SimpleThree) + 2 * RootBox.InvalidateMargin;
            var expectedInvalidate2 = new Rectangle(-RootBox.InvalidateMargin, -RootBox.InvalidateMargin,
                                                    invalidateWidth2, engine.SegmentHeight + 2 * RootBox.InvalidateMargin);

            VerifyParagraphs(root, new[] { child1.SimpleThree });
            Assert.That(child1.SimpleThreeHookupCount, Is.EqualTo(1), "The hookup for this object should exist");
            Assert.That(owner.SimpleFourHookupCount, Is.EqualTo(1), "The hookup for this object should exist");
            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate2));

            site.RectsInvalidatedInRoot.Clear();
            owner.SimpleFour = null;
            int invalidateWidth3    = FakeRenderEngine.SimulatedWidth(child1.SimpleThree) + 2 * RootBox.InvalidateMargin;
            var expectedInvalidate3 = new Rectangle(-RootBox.InvalidateMargin, -RootBox.InvalidateMargin,
                                                    invalidateWidth3, engine.SegmentHeight + 2 * RootBox.InvalidateMargin);

            VerifyParagraphs(root, new string[0]);
            Assert.That(child1.SimpleThreeHookupCount, Is.EqualTo(0), "The hookup for this unconnected object should not exist");
            Assert.That(owner.SimpleFourHookupCount, Is.EqualTo(1), "The hookup for this null object should exist");
            Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate3));

            site.RectsInvalidatedInRoot.Clear();
            owner.SimpleFour = null;
            int invalidateWidth4    = FakeRenderEngine.SimulatedWidth(child1.SimpleThree) + 2 * RootBox.InvalidateMargin;
            var expectedInvalidate4 = new Rectangle(-RootBox.InvalidateMargin, -RootBox.InvalidateMargin,
                                                    invalidateWidth3, engine.SegmentHeight + 2 * RootBox.InvalidateMargin);

            VerifyParagraphs(root, new string[0]);
            Assert.That(child1.SimpleThreeHookupCount, Is.EqualTo(0), "The hookup for this unconnected object should not exist");
            Assert.That(owner.SimpleFourHookupCount, Is.EqualTo(1), "The hookup for this null object should exist");
            Assert.That(site.RectsInvalidatedInRoot, Is.Empty, "Nothing changed, so nothing should be invalidated");
        }