static bool FindCommonGround(CssBoxHitChain startChain, CssBoxHitChain endChain, out int breakAtLevel) { //find common ground of startChain and endChain int startChainCount = startChain.Count; int endChainCount = endChain.Count; int lim = Math.Min(startChainCount, endChainCount); //from root to leave breakAtLevel = 0; for (int i = 0; i < lim; ++i) { HitInfo startHitInfo = startChain.GetHitInfo(i); HitInfo endHitInfo = endChain.GetHitInfo(i); if (startHitInfo.hitObject != endHitInfo.hitObject) { //found diff here breakAtLevel = i; break; } } //---------------------------- //check //return isDeepDown = endChainCount > startChainCount && (breakAtLevel == startChainCount - 1); return(endChainCount > startChainCount && (breakAtLevel == startChainCount - 1)); }
void SetupStartHitPoint(CssBoxHitChain startChain, ITextService textService) { //find global location of start point HitInfo startHit = startChain.GetLastHit(); //----------------------------- _startHitRun = null; _startHitRunCharIndex = 0; switch (startHit.hitObjectKind) { case HitObjectKind.Run: { CssRun run = (CssRun)startHit.hitObject; //------------------------------------------------------- int sel_index; int sel_offset; run.FindSelectionPoint(textService, startHit.localX, out sel_index, out sel_offset); _startHitRunCharIndex = sel_index; //modify hitpoint _startHitHostLine = (CssLineBox)startChain.GetHitInfo(startChain.Count - 2).hitObject; _startLineBeginSelectionAtPixel = (int)(run.Left + sel_offset); _startHitRun = run; } break; case HitObjectKind.LineBox: { _startHitHostLine = (CssLineBox)startHit.hitObject; _startLineBeginSelectionAtPixel = startHit.localX; //make global } break; case HitObjectKind.CssBox: { CssBox box = (CssBox)startHit.hitObject; //find first nearest line at point CssLineBox startHitLine = FindNearestLine(box, startChain.RootGlobalY, 5); _startLineBeginSelectionAtPixel = 0; if (startHitLine != null) { _startHitHostLine = startHitLine; } else { //if not found? _startHitHostLine = null; } } break; default: { throw new NotSupportedException(); } } }
static void SetEventOrigin(UIEventArgs e, CssBoxHitChain hitChain) { int count = hitChain.Count; if (count > 0) { e.SetExactHitObject(hitChain.GetHitInfo(count - 1).hitObject); } }
static void SetEventOrigin(UIEventArgs e, CssBoxHitChain hitChain) { int count = hitChain.Count; if (count > 0) { var hitInfo = hitChain.GetHitInfo(count - 1); e.ExactHitObject = hitInfo.hitObject; } }
static void ForEachEventListenerBubbleUp(UIEventArgs e, CssBoxHitChain hitChain, EventListenerAction listenerAction) { for (int i = hitChain.Count - 1; i >= 0; --i) { //propagate up var hitInfo = hitChain.GetHitInfo(i); IEventListener controller = null; switch (hitInfo.hitObjectKind) { default: { continue; } case HitObjectKind.Run: { CssRun run = (CssRun)hitInfo.hitObject; controller = CssBox.UnsafeGetController(run.OwnerBox) as IEventListener; } break; case HitObjectKind.CssBox: { CssBox box = (CssBox)hitInfo.hitObject; controller = CssBox.UnsafeGetController(box) as IEventListener; } break; } //--------------------- if (controller != null) { //found controller if (e.SourceHitElement == null) { e.SourceHitElement = controller; } e.CurrentContextElement = controller; e.SetLocation(hitInfo.localX, hitInfo.localY); if (listenerAction()) { return; } } } }
static void ForEachOnlyEventPortalBubbleUp(UIEventArgs e, CssBoxHitChain hitPointChain, EventPortalAction eventPortalAction) { //only listener that need tunnel down for (int i = hitPointChain.Count - 1; i >= 0; --i) { //propagate up var hitInfo = hitPointChain.GetHitInfo(i); IEventPortal controller = null; switch (hitInfo.hitObjectKind) { default: { continue; } case HitObjectKind.Run: { CssRun run = (CssRun)hitInfo.hitObject; controller = CssBox.UnsafeGetController(run.OwnerBox) as IEventPortal; } break; case HitObjectKind.CssBox: { CssBox box = (CssBox)hitInfo.hitObject; controller = CssBox.UnsafeGetController(box) as IEventPortal; } break; } //--------------------- if (controller != null) { e.SetLocation(hitInfo.localX, hitInfo.localY); if (eventPortalAction(controller)) { return; } } } }
void SetupEndHitPoint(CssBoxHitChain startChain, CssBoxHitChain endChain, ITextService textService) { //find global location of end point HitInfo endHit = endChain.GetLastHit(); int xposOnEndLine = 0; CssLineBox endline = null; //find endline first _endHitRunCharIndex = 0; _endHitRun = null; switch (endHit.hitObjectKind) { default: { throw new NotSupportedException(); } case HitObjectKind.Run: { CssRun endRun = (CssRun)endHit.hitObject; #if DEBUG //if (endRun.Text != null && endRun.Text.Contains("Jose")) //{ //} if (endHit.localX > 23) { } System.Diagnostics.Debug.WriteLine(endHit.localX); #endif endRun.FindSelectionPoint(textService, endHit.localX, out int run_sel_index, out int run_sel_offset); endline = endRun.HostLine; xposOnEndLine = (int)(endRun.Left + run_sel_offset); _endHitRunCharIndex = run_sel_index; #if DEBUG System.Diagnostics.Debug.WriteLine(_endHitRunCharIndex); #endif _endHitRun = endRun; } break; case HitObjectKind.LineBox: { endline = (CssLineBox)endHit.hitObject; xposOnEndLine = endHit.localX; } break; case HitObjectKind.CssBox: { CssBox hitBox = (CssBox)endHit.hitObject; endline = FindNearestLine(hitBox, endChain.RootGlobalY, 5); xposOnEndLine = endHit.localX; } break; } #if DEBUG if (xposOnEndLine == 0) { } #endif //---------------------------------- _selectedLines = new List <CssLineBox>(); if (_startHitHostLine == endline) { _selectedLines.Add(endline); _startHitHostLine.Select(_startLineBeginSelectionAtPixel, xposOnEndLine, _startHitRun, _startHitRunCharIndex, _endHitRun, _endHitRunCharIndex); return; //early exit here *** } //---------------------------------- //select on different line LineWalkVisitor lineWalkVisitor = null; if (FindCommonGround(startChain, endChain, out int breakAtLevel) && breakAtLevel > 0) { CssBlockRun hitBlockRun = endChain.GetHitInfo(breakAtLevel).hitObject as CssBlockRun; //multiple select //1. first part if (hitBlockRun != null) { _startHitHostLine.Select(_startLineBeginSelectionAtPixel, (int)hitBlockRun.Left, _startHitRun, _startHitRunCharIndex, _endHitRun, _endHitRunCharIndex); _selectedLines.Add(_startHitHostLine); lineWalkVisitor = new LineWalkVisitor(hitBlockRun); } else { _startHitHostLine.SelectPartialToEnd(_startLineBeginSelectionAtPixel, _startHitRun, _startHitRunCharIndex); _selectedLines.Add(_startHitHostLine); lineWalkVisitor = new LineWalkVisitor(_startHitHostLine); } } else { _startHitHostLine.SelectPartialToEnd(_startLineBeginSelectionAtPixel, _startHitRun, _startHitRunCharIndex); _selectedLines.Add(_startHitHostLine); lineWalkVisitor = new LineWalkVisitor(_startHitHostLine); } lineWalkVisitor.SetWalkTargetPosition(endChain.RootGlobalX, endChain.RootGlobalY); #if DEBUG int dbugExpectedId = 1; #endif lineWalkVisitor.Walk(endline, (lineCoverage, linebox, partialLineRun) => { #if DEBUG //System.Diagnostics.Debug.WriteLine("sel:" + linebox.dbugId); if (dbugExpectedId != linebox.dbugId) { } dbugExpectedId++; #endif switch (lineCoverage) { case LineCoverage.EndLine: { //found end line linebox.SelectPartialFromStart(xposOnEndLine, _endHitRun, _endHitRunCharIndex); _selectedLines.Add(linebox); } break; case LineCoverage.PartialLine: { linebox.SelectPartialFromStart((int)partialLineRun.Right, _endHitRun, _endHitRunCharIndex); _selectedLines.Add(linebox); } break; case LineCoverage.FullLine: { //check if hitpoint is in the line area linebox.SelectFull(); _selectedLines.Add(linebox); } break; } }); }
void SetupEndHitPoint(CssBoxHitChain startChain, CssBoxHitChain endChain, ITextService ifonts) { //find global location of end point HitInfo endHit = endChain.GetLastHit(); int xposOnEndLine = 0; CssLineBox endline = null; int run_sel_offset = 0; //find endline first this.endHitRunCharIndex = 0; this.endHitRun = null; switch (endHit.hitObjectKind) { default: { throw new NotSupportedException(); } case HitObjectKind.Run: { CssRun endRun = (CssRun)endHit.hitObject; //if (endRun.Text != null && endRun.Text.Contains("Jose")) //{ //} int run_sel_index; endRun.FindSelectionPoint(ifonts, endHit.localX, out run_sel_index, out run_sel_offset); endline = endRun.HostLine; xposOnEndLine = (int)(endRun.Left + run_sel_offset); this.endHitRunCharIndex = run_sel_index; this.endHitRun = endRun; } break; case HitObjectKind.LineBox: { endline = (CssLineBox)endHit.hitObject; xposOnEndLine = endHit.localX; } break; case HitObjectKind.CssBox: { CssBox hitBox = (CssBox)endHit.hitObject; endline = FindNearestLine(hitBox, endChain.RootGlobalY, 5); xposOnEndLine = endHit.localX; } break; } #if DEBUG if (xposOnEndLine == 0) { } #endif //---------------------------------- this.selectedLines = new List <CssLineBox>(); if (startHitHostLine == endline) { this.selectedLines.Add(endline); startHitHostLine.Select(startLineBeginSelectionAtPixel, xposOnEndLine, this.startHitRun, this.startHitRunCharIndex, this.endHitRun, this.endHitRunCharIndex); return; //early exit here *** } //---------------------------------- //select on different line LineWalkVisitor lineWalkVisitor = null; int breakAtLevel; if (FindCommonGround(startChain, endChain, out breakAtLevel) && breakAtLevel > 0) { var hit1 = endChain.GetHitInfo(breakAtLevel).hitObject; var hitBlockRun = hit1 as CssBlockRun; //multiple select //1. first part if (hitBlockRun != null) { startHitHostLine.Select(startLineBeginSelectionAtPixel, (int)hitBlockRun.Left, this.startHitRun, this.startHitRunCharIndex, this.endHitRun, this.endHitRunCharIndex); selectedLines.Add(this.startHitHostLine); lineWalkVisitor = new LineWalkVisitor(hitBlockRun); } else { startHitHostLine.SelectPartialToEnd(startLineBeginSelectionAtPixel, this.startHitRun, this.startHitRunCharIndex); selectedLines.Add(this.startHitHostLine); lineWalkVisitor = new LineWalkVisitor(startHitHostLine); } } else { startHitHostLine.SelectPartialToEnd(startLineBeginSelectionAtPixel, this.startHitRun, this.startHitRunCharIndex); selectedLines.Add(this.startHitHostLine); lineWalkVisitor = new LineWalkVisitor(startHitHostLine); } lineWalkVisitor.SetWalkTargetPosition(endChain.RootGlobalX, endChain.RootGlobalY); lineWalkVisitor.Walk(endline, (lineCoverage, linebox, partialLineRun) => { switch (lineCoverage) { case LineCoverage.EndLine: { //found end line linebox.SelectPartialFromStart(xposOnEndLine, this.endHitRun, this.endHitRunCharIndex); selectedLines.Add(linebox); } break; case LineCoverage.PartialLine: { linebox.SelectPartialFromStart((int)partialLineRun.Right, this.endHitRun, this.endHitRunCharIndex); selectedLines.Add(linebox); } break; case LineCoverage.FullLine: { //check if hitpoint is in the line area linebox.SelectFull(); selectedLines.Add(linebox); } break; } }); }
static bool FindCommonGround(CssBoxHitChain startChain, CssBoxHitChain endChain, out int breakAtLevel) { //find common ground of startChain and endChain int startChainCount = startChain.Count; int endChainCount = endChain.Count; int lim = Math.Min(startChainCount, endChainCount); //from root to leave breakAtLevel = 0; for (int i = 0; i < lim; ++i) { var startHitInfo = startChain.GetHitInfo(i); var endHitInfo = endChain.GetHitInfo(i); if (startHitInfo.hitObject != endHitInfo.hitObject) { //found diff here breakAtLevel = i; break; } } //---------------------------- //check //return isDeepDown = endChainCount > startChainCount && (breakAtLevel == startChainCount - 1); return endChainCount > startChainCount && (breakAtLevel == startChainCount - 1); }
void SetupEndHitPoint(CssBoxHitChain startChain, CssBoxHitChain endChain, IFonts ifonts) { //find global location of end point HitInfo endHit = endChain.GetLastHit(); int xposOnEndLine = 0; CssLineBox endline = null; int run_sel_offset = 0; //find endline first this.endHitRunCharIndex = 0; this.endHitRun = null; switch (endHit.hitObjectKind) { default: { throw new NotSupportedException(); } case HitObjectKind.Run: { CssRun endRun = (CssRun)endHit.hitObject; //if (endRun.Text != null && endRun.Text.Contains("Jose")) //{ //} int run_sel_index; endRun.FindSelectionPoint(ifonts, endHit.localX, out run_sel_index, out run_sel_offset); endline = endRun.HostLine; xposOnEndLine = (int)(endRun.Left + run_sel_offset); this.endHitRunCharIndex = run_sel_index; this.endHitRun = endRun; } break; case HitObjectKind.LineBox: { endline = (CssLineBox)endHit.hitObject; xposOnEndLine = endHit.localX; } break; case HitObjectKind.CssBox: { CssBox hitBox = (CssBox)endHit.hitObject; endline = FindNearestLine(hitBox, endChain.RootGlobalY, 5); xposOnEndLine = endHit.localX; } break; } #if DEBUG if (xposOnEndLine == 0) { } #endif //---------------------------------- this.selectedLines = new List<CssLineBox>(); if (startHitHostLine == endline) { this.selectedLines.Add(endline); startHitHostLine.Select(startLineBeginSelectionAtPixel, xposOnEndLine, this.startHitRun, this.startHitRunCharIndex, this.endHitRun, this.endHitRunCharIndex); return; //early exit here *** } //---------------------------------- //select on different line LineWalkVisitor lineWalkVisitor = null; int breakAtLevel; if (FindCommonGround(startChain, endChain, out breakAtLevel) && breakAtLevel > 0) { var hit1 = endChain.GetHitInfo(breakAtLevel).hitObject; var hitBlockRun = hit1 as CssBlockRun; //multiple select //1. first part if (hitBlockRun != null) { startHitHostLine.Select(startLineBeginSelectionAtPixel, (int)hitBlockRun.Left, this.startHitRun, this.startHitRunCharIndex, this.endHitRun, this.endHitRunCharIndex); selectedLines.Add(this.startHitHostLine); lineWalkVisitor = new LineWalkVisitor(hitBlockRun); } else { startHitHostLine.SelectPartialToEnd(startLineBeginSelectionAtPixel, this.startHitRun, this.startHitRunCharIndex); selectedLines.Add(this.startHitHostLine); lineWalkVisitor = new LineWalkVisitor(startHitHostLine); } } else { startHitHostLine.SelectPartialToEnd(startLineBeginSelectionAtPixel, this.startHitRun, this.startHitRunCharIndex); selectedLines.Add(this.startHitHostLine); lineWalkVisitor = new LineWalkVisitor(startHitHostLine); } lineWalkVisitor.SetWalkTargetPosition(endChain.RootGlobalX, endChain.RootGlobalY); lineWalkVisitor.Walk(endline, (lineCoverage, linebox, partialLineRun) => { switch (lineCoverage) { case LineCoverage.EndLine: { //found end line linebox.SelectPartialFromStart(xposOnEndLine, this.endHitRun, this.endHitRunCharIndex); selectedLines.Add(linebox); } break; case LineCoverage.PartialLine: { linebox.SelectPartialFromStart((int)partialLineRun.Right, this.endHitRun, this.endHitRunCharIndex); selectedLines.Add(linebox); } break; case LineCoverage.FullLine: { //check if hitpoint is in the line area linebox.SelectFull(); selectedLines.Add(linebox); } break; } }); }
void SetupStartHitPoint(CssBoxHitChain startChain, IFonts ifonts) { //find global location of start point HitInfo startHit = startChain.GetLastHit(); //----------------------------- this.startHitRun = null; this.startHitRunCharIndex = 0; switch (startHit.hitObjectKind) { case HitObjectKind.Run: { CssRun run = (CssRun)startHit.hitObject; //------------------------------------------------------- int sel_index; int sel_offset; run.FindSelectionPoint(ifonts, startHit.localX, out sel_index, out sel_offset); this.startHitRunCharIndex = sel_index; //modify hitpoint this.startHitHostLine = (CssLineBox)startChain.GetHitInfo(startChain.Count - 2).hitObject; this.startLineBeginSelectionAtPixel = (int)(run.Left + sel_offset); this.startHitRun = run; } break; case HitObjectKind.LineBox: { this.startHitHostLine = (CssLineBox)startHit.hitObject; this.startLineBeginSelectionAtPixel = startHit.localX; //make global } break; case HitObjectKind.CssBox: { CssBox box = (CssBox)startHit.hitObject; //find first nearest line at point CssLineBox startHitLine = FindNearestLine(box, startChain.RootGlobalY, 5); this.startLineBeginSelectionAtPixel = 0; if (startHitLine != null) { this.startHitHostLine = startHitLine; } else { //if not found? this.startHitHostLine = null; } } break; default: { throw new NotSupportedException(); } } }