/// <summary> /// Move the camera so that its focusing on the found location /// </summary> /// <param Name="foundLocation">The location to focus on</param> protected void NavigateToFoundPage(Location foundLocation) { Page foundPage = foundLocation.Page; //The camera should first zoom out so that it is looking at both the start location and the found page //And then zoom in so that it is only looking at the found page RectangleF planeBounds = RectangleF.Union(Window.Canvas.Camera.ViewBounds, foundPage.GlobalBounds); RectangleF pageBounds = foundPage.GlobalBounds; PTransformActivity zoomOut = Window.Canvas.Camera.AnimateViewToCenterBounds(planeBounds, true, 400); PTransformActivity zoomIn = Window.Canvas.Camera.AnimateViewToCenterBounds(pageBounds, true, 400); //The camera action can happen faster without causing the user to lose track of where they are //or getting motion sick if the zoom accelerates toward the middle of each animation //and decelerates toward the end of the animation than if the animation moves at constant speed zoomOut.SlowInSlowOut = true; zoomIn.SlowInSlowOut = true; //Order the animations zoomIn.StartAfter(zoomOut); }
/// <summary> /// Recursively search every page in an array for a phrase, returning when it has been found /// </summary> /// <param Name="pages">The list of pages to search</param> /// <param Name="location">Where to start the search</param> /// <param Name="phrase">The phrase to search for</param> /// <param Name="reverse">Whether the search should be backwards</param> /// <returns>The location the phrase was found in, or null if it wasn't found</returns> protected static Location SearchPages(Page[] pages, Location location, string phrase, bool reverse) { //Search for the phrase, and return it if found Location output = SearchPage(location, phrase, reverse); if (output != null) { return output; } //Remove the first item of the array and return null if no pages remain Page[] newPages = pages.Skip(1).ToArray(); if (newPages.Length == 0) { return null; } //Start the next recursion Location newLocation = new Location(location.Window, location.Document, newPages[0], null); return SearchPages(newPages, newLocation, phrase, reverse); }
/// <summary> /// Set the keyboard focus to be the found location /// </summary> /// <param Name="foundLocation">The location to focus on</param> protected void ActivateFoundPage(Location foundLocation) { Window.FindHandler.KeyFocus = foundLocation.Page.ToPickPath(); foundLocation.Page.Model.Select((int)foundLocation.CharIndex, 0); }
/// <summary> /// Search a page for a specific phrase /// </summary> /// <param Name="location">The location to begin the search at.</param> /// <param Name="phrase">The phrase to search for</param> /// <param Name="reverse">Whether the search should be forwards or backwards</param> /// <returns>The location of the start of the phrase, or null if not found</returns> protected static Location SearchPage(Location location, string phrase, bool reverse) { int startLoc = GetCharIndexFromLocation(location, reverse); int phraseLocation, minFind; if (reverse == false) //If the search is forwards { minFind = startLoc; //Take the part of the text following the start location string textPart = location.Page.Text.Substring(startLoc).ToLower(); //Find the first instance of the phrase within that text part phraseLocation = startLoc + textPart.IndexOf(phrase); } else //If the search is backwards { minFind = 0; //Take the part of the text preceding the start location string textPart = location.Page.Text.Substring(0, startLoc).ToLower(); //Find the last instance of the phrase within that text part phraseLocation = textPart.LastIndexOf(phrase); } //If the phrase was found, return the location of the if (phraseLocation >= minFind) { return new Location(location.Window, location.Document, location.Page, phraseLocation); } //IF the phrase wasn't found, return null else { return null; } }
/// <summary> /// Recursively search all documents for a phrase /// </summary> /// <param Name="documents">The list of documents to search</param> /// <param Name="location">The location to start searching in</param> /// <param Name="phrase">The phrase to search for</param> /// <param Name="reverse">Whether the search should be backwards</param> /// <returns>The location of the phrase, or null if not found</returns> protected static Location SearchDocuments(Document[] documents, Location location, string phrase, bool reverse) { //Search for the phrase, and return if found Location output = SearchDocument(location, phrase, reverse); if (output != null) { return output; } //Remove the first document fro the array, and exit if no documents remain Document[] newDocuments = documents.Skip(1).ToArray(); if (newDocuments.Length == 0) { return null; } //Begin the next recursion Location newLocation = new Location(location.Window, newDocuments[0], null, null); return SearchDocuments(newDocuments, newLocation, phrase, reverse); }
/// <summary> /// Search every page of a document for a specific phrase /// </summary> /// <param Name="location">The location to start searching in</param> /// <param Name="phrase">The phrase to search for</param> /// <param Name="reverse">Whether the search should be backwards</param> /// <returns>The found location, or null if nothing is found</returns> protected static Location SearchDocument(Location location, string phrase, bool reverse) { //Get the list of pages of the document Page[] pages = location.Document.Pages; //If the document had no pages, exit if (pages.Length == 0) { return null; } //Put the pages in the correct order for searching Page[] newPages = OrderPages(pages, location.PageIndex, reverse); //Search the list of pages for the phrase Location newLocation = new Location(location.Window, location.Document, newPages[0], location.CharIndex); return SearchPages(newPages, newLocation, phrase, reverse); }
/// <summary> /// Find what character index the location object says to begin at /// </summary> /// <remarks>Because null is used as a wildcard, that can mean multiple things, it isn't as simple as just reading location.charindex</remarks> /// <param Name="location">The location to check</param> /// <param Name="reverse">Whether the search is backwards</param> /// <returns>The location to begin searching at</returns> protected static int GetCharIndexFromLocation(Location location, bool reverse) { //Ensure the user is searching a real page if (location.Page == null) { throw new ArgumentException("Cannot find a character index from a null page"); } //If an actual value has been provided, return that if (location.CharIndex != null) { return (int)location.CharIndex; } else //If the wildcard value was used { //If it's a forwards search, return the start of the document if (reverse == false) { return 0; } //If it's a backwards search, return the end of the document else { return location.Page.Text.Length; } } }
/// <summary> /// Find the next space before or after a specific location /// </summary> /// <param Name="location">Where to start searching</param> /// <param Name="reverse">True if it should search backwards, false if it should search forwards</param> /// <returns>The location of the next space in the relevant direction</returns> protected static Location FindNearestWordEnd(Location location, bool reverse) { //Try to find a space in the current page in the relevant direction Location output = SearchPage(location, " ", reverse); //If it fails take either the start, or end, of the document as appropriate if (output == null) { int newCharIndex; if (reverse) { newCharIndex = 0; } else { newCharIndex = location.Page.Text.Length; } output = new Location(location.Window, location.Document, location.Page, newCharIndex); } return output; }