diff options
Diffstat (limited to 'winrt/mupdf_cpp/MainPage.xaml.cpp')
-rw-r--r-- | winrt/mupdf_cpp/MainPage.xaml.cpp | 1565 |
1 files changed, 1565 insertions, 0 deletions
diff --git a/winrt/mupdf_cpp/MainPage.xaml.cpp b/winrt/mupdf_cpp/MainPage.xaml.cpp new file mode 100644 index 00000000..2af4a552 --- /dev/null +++ b/winrt/mupdf_cpp/MainPage.xaml.cpp @@ -0,0 +1,1565 @@ +// +// MainPage.xaml.cpp +// Implementation of the MainPage class. +// + +#include "pch.h" +#include "MainPage.xaml.h" +#include "LVContents.h" + +#define LOOK_AHEAD 1 /* A +/- count on the pages to pre-render */ +#define MIN_SCALE 0.5 +#define MAX_SCALE 4 +#define MARGIN_BUFF 400 +#define MAX_SEARCH 500 +#define SCALE_THUMB 0.1 + +#define BLANK_WIDTH 17 +#define BLANK_HEIGHT 22 + +static float screenScale = 1; + +int linkPage[MAX_SEARCH]; +char *linkUrl[MAX_SEARCH]; + +using namespace mupdf_cpp; + +using namespace Windows::Foundation; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +using namespace Windows::UI::Xaml::Controls::Primitives; +using namespace Windows::UI::Xaml::Data; +using namespace Windows::UI::Xaml::Media; +using namespace Windows::UI::Xaml::Navigation; +using namespace Windows::Graphics::Display; +using namespace ListViewContents; + +//****************** Added ***************** +using namespace Windows::Storage::Pickers; +using namespace Windows::Devices::Enumeration; +using namespace concurrency; +using namespace Windows::Graphics::Imaging; +//****************** End Add **************** + +#ifndef NDEBUG +unsigned int _mainThreadId = 0U; + +#ifdef __cplusplus +extern "C" { +#endif + + // The IsMainThread function returns true if the current thread is the app's main thread and false otherwise. + bool IsMainThread() + { + return (_mainThreadId == GetCurrentThreadId()); + } + + // The IsBackgroundThread function returns false if the current thread is the app's main thread and true otherwise. + bool IsBackgroundThread() + { + return (_mainThreadId != GetCurrentThreadId()); + } + + // The RecordMainThread function registers the main thread ID for use by the IsMainThread and IsBackgroundThread functions. + void RecordMainThread() + { + _mainThreadId = GetCurrentThreadId(); + } + +#ifdef __cplusplus +} +#endif + +#endif /* not NDEBUG */ + +MainPage::MainPage() +{ + InitializeComponent(); + + Windows::UI::Color color; + color.R = 0x00; + color.G = 0x00; + color.B = 0xFF; + color.A = 0x40; + m_textcolor_brush = ref new SolidColorBrush(color); + + color.R = 0xAC; + color.G = 0x72; + color.B = 0x25; + color.A = 0x40; + m_linkcolor_brush = ref new SolidColorBrush(color); + + // Create the image brush + m_renderedImage = ref new ImageBrush(); + m_content.num = 0; + mu_doc = nullptr; + m_docPages = ref new Platform::Collections::Vector<DocumentPage^>(); + CleanUp(); + RecordMainThread(); + mu_doc = ref new mudocument(); + if (mu_doc == nullptr) + throw ref new FailureException("Document allocation failed!"); +} + +/// <summary> +/// Invoked when this page is about to be displayed in a Frame. +/// </summary> +/// <param name="e">Event data that describes how this page was reached. The Parameter +/// property is typically used to configure the page.</param> +void MainPage::OnNavigatedTo(NavigationEventArgs^ e) +{ + (void) e; // Unused parameter +} + +void mupdf_cpp::MainPage::ExitInvokedHandler(Windows::UI::Popups::IUICommand^ command) +{ + +} + +void mupdf_cpp::MainPage::OKInvokedHandler(Windows::UI::Popups::IUICommand^ command) +{ + +} + +void mupdf_cpp::MainPage::NotifyUser(String^ strMessage, NotifyType_t type) +{ + MessageDialog^ msg = ref new MessageDialog(strMessage); + UICommand^ ExitCommand = nullptr; + UICommand^ OKCommand = nullptr; + + switch (type) + { + case StatusMessage: + OKCommand = ref new UICommand("OK", + ref new UICommandInvokedHandler(this, &mupdf_cpp::MainPage::OKInvokedHandler)); + msg->Commands->Append(OKCommand); + /// Set the command that will be invoked by default + msg->DefaultCommandIndex = 0; + // Set the command to be invoked when escape is pressed + msg->CancelCommandIndex = 1; + break; + case ErrorMessage: + ExitCommand = ref new UICommand("Exit", + ref new UICommandInvokedHandler(this, &mupdf_cpp::MainPage::ExitInvokedHandler)); + msg->Commands->Append(ExitCommand); + /// Set the command that will be invoked by default + msg->DefaultCommandIndex = 0; + // Set the command to be invoked when escape is pressed + msg->CancelCommandIndex = 1; + break; + default: + break; + } + // Show the message dialog + msg->ShowAsync(); +} + +bool mupdf_cpp::MainPage::EnsureUnsnapped() +{ + // FilePicker APIs will not work if the application is in a snapped state. + // If an app wants to show a FilePicker while snapped, it must attempt to unsnap first + + bool unsnapped = (ApplicationView::Value != ApplicationViewState::Snapped || + ApplicationView::TryUnsnap()); + if (!unsnapped) + { + NotifyUser("Cannot unsnap the application", StatusMessage); + } + return unsnapped; +} + +void mupdf_cpp::MainPage::Picker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) +{ + if (!EnsureUnsnapped()) + return; + + FileOpenPicker^ openPicker = ref new FileOpenPicker(); + openPicker->ViewMode = PickerViewMode::List; + openPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary; + openPicker->FileTypeFilter->Append(".pdf"); + openPicker->FileTypeFilter->Append(".xps"); + openPicker->FileTypeFilter->Append(".oxps"); + + create_task(openPicker->PickSingleFileAsync()).then([this](StorageFile^ file) + { + if (file) + { + this->OpenDocumentPrep(file); + } + else + { + /* Nothing selected */ + } + }); +} + +/* Set the page with the new raster information */ +void MainPage::UpdatePage(int page_num, InMemoryRandomAccessStream^ ras, + Point ras_size, Page_Content_t content_type) +{ + assert(IsMainThread()); + + WriteableBitmap ^bmp = ref new WriteableBitmap(ras_size.X, ras_size.Y); + bmp->SetSource(ras); + + DocumentPage^ doc_page = ref new DocumentPage(); + doc_page->Image = bmp; + + if (content_type == THUMBNAIL) + { + doc_page->Height = ras_size.Y / SCALE_THUMB; + doc_page->Width = ras_size.X / SCALE_THUMB; + } + else + { + doc_page->Height = ras_size.Y; + doc_page->Width = ras_size.X; + } + doc_page->Content = content_type; + + /* We do not want flipview change notification to occur for ourselves */ + m_page_update = true; + this->m_docPages->SetAt(page_num, doc_page); + m_page_update = false; + +} + +Point MainPage::ComputePageSize(spatial_info_t spatial_info, int page_num) +{ + Point screenSize; + Point pageSize; + Point size = mu_doc->GetPageSize(page_num); + + screenSize = spatial_info.size; + screenSize.Y *= screenScale; + screenSize.X *= screenScale; + + float hscale = screenSize.X / size.X; + float vscale = screenSize.Y / size.Y; + float scale = min(hscale, vscale); + pageSize.X = size.X * scale * spatial_info.scale_factor; + pageSize.Y = size.Y * scale * spatial_info.scale_factor; + + return pageSize; +} + +Point MainPage::currPageSize(int page) +{ + Point Size; + + FlipViewItem ^flipview_temp = (FlipViewItem^) m_curr_flipView->Items->GetAt(page); + + Size.Y = flipview_temp->ActualHeight; + Size.X = flipview_temp->ActualWidth; + return Size; +} + +static Point fitPageToScreen(Point page, Point screen) +{ + Point pageSize; + + float hscale = screen.X / page.X; + float vscale = screen.Y / page.Y; + float scale = fz_min(hscale, vscale); + pageSize.X = floorf(page.X * scale) / page.X; + pageSize.Y = floorf(page.Y * scale) / page.Y; + return pageSize; +} + +spatial_info_t MainPage::InitSpatial(double scale) +{ + spatial_info_t value; + + value.size.Y = this->ActualHeight; + value.size.X = this->ActualWidth; + value.scale_factor = scale; + return value; +} + +void Prepare_bmp(int width, int height, DataWriter ^dw) +{ + int row_size = width * 4; + int bmp_size = row_size * height + 54; + + dw->WriteString("BM"); + dw->ByteOrder = ByteOrder::LittleEndian; + dw->WriteInt32(bmp_size); + dw->WriteInt16(0); + dw->WriteInt16(0); + dw->WriteInt32(54); + dw->WriteInt32(40); + dw->WriteInt32(width); + dw->WriteInt32(height); + dw->WriteInt16(1); + dw->WriteInt16(32); + dw->WriteInt32(0); + dw->WriteInt32(row_size * height); + dw->WriteInt32(2835); + dw->WriteInt32(2835); + dw->WriteInt32(0); + dw->WriteInt32(0); +} + +void MainPage::ReleasePages(int old_page, int new_page) +{ + if (old_page == new_page) return; + /* To keep from having memory issue reset the page back to + the thumb if we are done rendering the thumbnails */ + for (int k = old_page - LOOK_AHEAD; k <= old_page + LOOK_AHEAD; k++) + { + if (k < new_page - LOOK_AHEAD || k > new_page + LOOK_AHEAD) + { + if (k >= 0 && k < this->m_num_pages) + { + SetThumb(k, true); + } + } + } +} + +void MainPage::InitThumbnails() +{ + this->m_thumbnails.raster = ref new Array<InMemoryRandomAccessStream^>(m_num_pages); + this->m_thumbnails.scale = ref new Array<double>(m_num_pages); + this->m_thumbnails.size = ref new Array<Point>(m_num_pages); +} + +/* Return this page from a full res image to the thumb image or only set to thumb + if it has not already been set */ +void MainPage::SetThumb(int page_num, bool replace) +{ + /* See what is there now */ + auto doc = this->m_docPages->GetAt(page_num); + if (doc->Content == THUMBNAIL) return; + + if ((replace || doc->Content == DUMMY) && this->m_thumbnails.raster[page_num] != nullptr) + UpdatePage(page_num, this->m_thumbnails.raster[page_num], + this->m_thumbnails.size[page_num], THUMBNAIL); +} + +/* Create white image for us to use as place holder in large document for flip + view filling instead of the thumbnail image */ +void MainPage::CreateBlank(int width, int height) +{ + Array<unsigned char>^ bmp_data = ref new Array<unsigned char>(height * 4 * width); + /* Set up the memory stream */ + WriteableBitmap ^bmp = ref new WriteableBitmap(width, height); + InMemoryRandomAccessStream ^ras = ref new InMemoryRandomAccessStream(); + DataWriter ^dw = ref new DataWriter(ras->GetOutputStreamAt(0)); + /* Go ahead and write our header data into the memory stream */ + Prepare_bmp(width, height, dw); + + /* Set the data to all white */ + memset(bmp_data->Data, 255, height * 4 * width); + + /* Write the data */ + dw->WriteBytes(bmp_data); + + DataWriterStoreOperation^ result = dw->StoreAsync(); + /* Block on the Async call */ + while(result->Status != AsyncStatus::Completed) { + } + /* And store in a the image brush */ + bmp->SetSource(ras); + m_BlankBmp = bmp; +} + +void mupdf_cpp::MainPage::SetFlipView() +{ + int height = this->ActualHeight; + int width = this->ActualWidth; + + CreateBlank(BLANK_WIDTH, BLANK_HEIGHT); + /* Set the current flip view mode */ + if (height > width) + this->m_curr_flipView = xaml_vert_flipView; + else + this->m_curr_flipView = xaml_horiz_flipView; +} + +/* Clean up everything as we are opening a new document after having another + one open */ +void mupdf_cpp::MainPage::CleanUp() +{ + /* Remove current pages in the flipviews */ + if (xaml_vert_flipView->Items->Size) + xaml_vert_flipView->Items->Clear(); + + if (xaml_horiz_flipView->Items->Size) + xaml_horiz_flipView->Items->Clear(); + + this->m_curr_flipView = nullptr; + m_currpage = -1; + m_file_open = false; + m_slider_min = 0; + m_slider_max = 0; + m_init_done = false; + m_memory_use = 0; + m_from_doubleflip = false; + m_first_time = false; + m_insearch = false; + m_search_active = false; + m_sliderchange = false; + m_flip_from_searchlink = false; + m_num_pages = -1; + m_search_rect_count = 0; + ResetSearch(); + m_ren_status = REN_AVAILABLE; + m_thumb_page_start = 0; + m_thumb_page_stop = 0; + m_links_on = false; + + if (m_content.num) + { + //m_content.page->; + // m_content.string_margin->Dispose(); + //m_content.string_orig->Dispose(); + m_content.num = 0; + } + + m_curr_zoom = 1.0; + m_canvas_translate.X = 0; + m_canvas_translate.Y = 0; + + this->xaml_PageSlider->Minimum = m_slider_min; + this->xaml_PageSlider->Maximum = m_slider_max; + this->xaml_PageSlider->IsEnabled = false; +} + +/* Create the thumbnail images */ +void mupdf_cpp::MainPage::RenderThumbs() +{ + spatial_info_t spatial_info = this->InitSpatial(1); + int num_pages = this->m_num_pages; + int thumb_pages = this->m_thumb_page_start; + cancellation_token_source cts; + auto token = cts.get_token(); + m_ThumbCancel = cts; + + this->m_ren_status = REN_THUMBS; + thumbs_t thumbnails = m_thumbnails; + DWORD thread0_id = GetCurrentThreadId(); + + create_task([spatial_info, num_pages, thumb_pages, thumbnails, this, thread0_id]()-> int + { + spatial_info_t spatial_info_local = spatial_info; + spatial_info_local.scale_factor = SCALE_THUMB; + + InMemoryRandomAccessStream ^ras = ref new InMemoryRandomAccessStream(); + + for (int k = thumb_pages; k < num_pages; k++) + { + Point ras_size = ComputePageSize(spatial_info_local, k); + bool done = false; + DWORD thread1_id = GetCurrentThreadId(); + auto task = create_task(mu_doc->RenderPage(k, ras_size.X, ras_size.Y)).then([this, k, ras_size, thumbnails, &done, thread1_id, thread0_id] (InMemoryRandomAccessStream^ ras) + { + DWORD thread2_id = GetCurrentThreadId(); + thumbnails.raster[k] = ras; + thumbnails.scale[k] = SCALE_THUMB; + thumbnails.size[k] = ras_size; + done = true; + }, task_continuation_context::use_current()); + + + try + { + task.get(); // get exception + } + catch (Exception^ exception) + { + } + + /* Don't start new thumb until this one is finished, lest we launch a + thousand thumbnail renderings */ + while (!done) + { + } + + /* If cancelled then save the last one as the continuation will not + have occured. */ + if (is_task_cancellation_requested()) + { + thumbnails.raster[k] = ras; + thumbnails.scale[k] = SCALE_THUMB; + thumbnails.size[k] = ras_size; + this->m_thumb_page_stop = k + 1; + + cancel_current_task(); + } + } + return num_pages; /* all done with thumbnails! */ + }, token).then([this](task<int> the_task) + { + int new_end; + try + { + new_end = the_task.get(); + } + catch (const task_canceled& e) + { + new_end = this->m_thumb_page_stop; + } + + int old_end = this->m_thumb_page_start; + + /* Now go ahead and create the proper stuctures */ + this->m_ren_status = REN_UPDATE_THUMB_CANVAS; + this->m_thumb_page_start = new_end; + + for (int k = old_end; k < new_end; k++) + { + assert(IsMainThread()); + SetThumb(k, false); + } + this->m_ren_status = REN_AVAILABLE; + }, task_continuation_context::use_current()); +} + +void mupdf_cpp::MainPage::OpenDocumentPrep(StorageFile^ file) +{ + if (this->m_num_pages != -1) + { + m_init_done = false; + /* If the thumbnail thread is running then we need to end that first */ + RenderingStatus_t *ren_status = &m_ren_status; + cancellation_token_source *ThumbCancel = &m_ThumbCancel; + + /* Create a task to wait until the renderer is available, then clean up then open */ + auto t = create_task([ren_status, ThumbCancel]()->int + { + if (*ren_status == REN_THUMBS) + ThumbCancel->cancel(); + while (*ren_status != REN_AVAILABLE) { + } + return 0; + }).then([this](task<int> the_task) + { + CleanUp(); + return 0; + }, task_continuation_context::use_current()).then([this, file](task<int> the_task) + { + OpenDocument(file); + }, task_continuation_context::use_current()); + } + else + { + OpenDocument(file); + } +} + +void mupdf_cpp::MainPage::OpenDocument(StorageFile^ file) +{ + String^ path = file->Path; + const wchar_t *w = path->Data(); + int cb = WideCharToMultiByte(CP_UTF8, 0, w, -1, nullptr, 0, nullptr, nullptr); + char* name = new char[cb]; + + WideCharToMultiByte(CP_UTF8, 0, w ,-1 ,name ,cb ,nullptr, nullptr); + char *ext = strrchr(name, '.'); + + this->SetFlipView(); + + /* Open document and when open, push on */ + auto open_task = create_task(mu_doc->OpenFile(file)); + + open_task.then([this] + { + assert(IsMainThread()); + + m_num_pages = mu_doc->GetNumPages(); + if ((m_currpage) >= m_num_pages) + { + m_currpage = m_num_pages - 1; + } + else if (m_currpage < 0) + { + m_currpage = 0; + } + + /* Initialize all the flipvew items with blanks */ + for (int k = 0; k < m_num_pages; k++) + { + DocumentPage^ doc_page = ref new DocumentPage(); + doc_page->Image = this->m_BlankBmp; + doc_page->Height = BLANK_HEIGHT; + doc_page->Width = BLANK_WIDTH; + doc_page->Content = DUMMY; + this->m_docPages->Append(doc_page); + } + + this->xaml_horiz_flipView->ItemsSource = m_docPages; + this->xaml_vert_flipView->ItemsSource = m_docPages; + + /* Do the first few pages, then start the thumbs */ + spatial_info_t spatial_info = InitSpatial(1); + + for (int k = 0; k < LOOK_AHEAD + 2; k++) + { + if (m_num_pages > k ) + { + Point ras_size = ComputePageSize(spatial_info, k); + + auto render_task = + create_task(mu_doc->RenderPage(k, ras_size.X, ras_size.Y)); + + render_task.then([this, k, ras_size] (InMemoryRandomAccessStream^ ras) + { + /* Set up the image brush when rendering is completed, must be on + UI thread */ + UpdatePage(k, ras, ras_size, FULL_RESOLUTION); + }, task_continuation_context::use_current()); + } + } + + /* Update the slider settings, if more than one page */ + if (m_num_pages > 1) + { + this->xaml_PageSlider->Maximum = m_num_pages; + this->xaml_PageSlider->Minimum = 1; + this->xaml_PageSlider->IsEnabled = true; + } + else + { + this->xaml_PageSlider->Maximum = 0; + this->xaml_PageSlider->Minimum = 0; + this->xaml_PageSlider->IsEnabled = false; + } + /* All done with initial pages */ + this->m_init_done = true; + }).then([this] + { + InitThumbnails(); + this->RenderThumbs(); + }, task_continuation_context::use_current()); +} + +task<int> mupdf_cpp::MainPage::RenderRange(int curr_page) +{ + /* Render +/- the look ahead from where we are if blank page is present */ + spatial_info_t spatial_info = InitSpatial(1); + + RenderingStatus_t *ren_status = &m_ren_status; + cancellation_token_source *ThumbCancel = &m_ThumbCancel; + + /* Create a task to wait until the renderer is available */ + auto t = create_task([ren_status, ThumbCancel]() + { + if (*ren_status == REN_THUMBS) + ThumbCancel->cancel(); + while (*ren_status != REN_AVAILABLE) { + } + }); + + return t.then([this, curr_page, spatial_info]() + { + assert(IsMainThread()); + int val = 0; + /* This runs on the main ui thread */ + for (int k = curr_page - LOOK_AHEAD; k <= curr_page + LOOK_AHEAD; k++) + { + if (k >= 0 && k < m_num_pages) + { + /* Check if page is already rendered */ + auto doc = this->m_docPages->GetAt(k); + if (doc->Content != FULL_RESOLUTION) + { + Point ras_size = ComputePageSize(spatial_info, k); + auto render_task = + create_task(mu_doc->RenderPage(k, ras_size.X, ras_size.Y)); + + render_task.then([this, k, ras_size] (InMemoryRandomAccessStream^ ras) + { + /* Set up the image brush when rendering is completed, must be on + UI thread */ + UpdatePage(k, ras, ras_size, FULL_RESOLUTION); + this->m_ren_status = REN_AVAILABLE; + }, task_continuation_context::use_current()); + } + } + } + Canvas^ link_canvas = (Canvas^) (this->FindName("linkCanvas")); + if (link_canvas != nullptr) + { + Canvas^ Parent_Canvas = (Canvas^) link_canvas->Parent; + if (Parent_Canvas != nullptr) + { + Parent_Canvas->Children->RemoveAtEnd(); + delete link_canvas; + } + } + m_currpage = curr_page; + if (this->m_links_on) + { + AddLinkCanvas(); + } + /* Check if thumb rendering is done. If not then restart */ + if (this->m_num_pages != this->m_thumb_page_start) + this->RenderThumbs(); + return val; + }, task_continuation_context::use_current()); +} + +void mupdf_cpp::MainPage::Slider_Released(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e) +{ + /* Check if thumb rendering is done. If not then restart */ + if (this->m_num_pages != this->m_thumb_page_start) + this->RenderThumbs(); +} + +void mupdf_cpp::MainPage::Slider_ValueChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e) +{ + int newValue = (int) this->xaml_PageSlider->Value - 1; /* zero based */ + RenderingStatus_t *ren_status = &m_ren_status; + cancellation_token_source *ThumbCancel = &m_ThumbCancel; + + if (m_update_flip) + { + m_update_flip = false; + return; + } + if (m_init_done && this->xaml_PageSlider->IsEnabled) + { + auto doc = this->m_docPages->GetAt(newValue); + if (doc->Content != FULL_RESOLUTION) + { + create_task([ren_status, ThumbCancel]() + { + if (*ren_status == REN_THUMBS) + ThumbCancel->cancel(); + while (*ren_status != REN_AVAILABLE) { + } + }).then([this, newValue]() + { + spatial_info_t spatial_info = InitSpatial(1); + Point ras_size = ComputePageSize(spatial_info, newValue); + auto render_task = + create_task(mu_doc->RenderPage(newValue, ras_size.X, ras_size.Y)); + + render_task.then([this, newValue, ras_size] (InMemoryRandomAccessStream^ ras) + { + UpdatePage(newValue, ras, ras_size, FULL_RESOLUTION); + this->m_ren_status = REN_AVAILABLE; + this->m_currpage = newValue; + m_sliderchange = true; + this->m_curr_flipView->SelectedIndex = newValue; + ResetSearch(); + }, task_continuation_context::use_current()); + }, task_continuation_context::use_current()); + } + } +} + +void mupdf_cpp::MainPage::FlipView_SelectionChanged(Object^ sender, SelectionChangedEventArgs^ e) +{ + if (m_init_done && !m_page_update) + { + int pos = this->m_curr_flipView->SelectedIndex; + + m_update_flip = true; + if (xaml_PageSlider->IsEnabled) + { + xaml_PageSlider->Value = pos; + } + if (pos >= 0) + { + if (m_flip_from_searchlink) + { + m_flip_from_searchlink = false; + return; + } + else if (m_sliderchange) + { + m_sliderchange = false; + return; + } + else + { + ResetSearch(); + } + /* Get the current page */ + int curr_page = this->m_currpage; + task<int> task = this->RenderRange(pos); + task.then([this, curr_page, pos](int val) + { + this->ReleasePages(curr_page, pos); + }, task_continuation_context::use_current()); + } + } +} + +/* Search Related Code */ + +void mupdf_cpp::MainPage::Searcher(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) +{ + /* Update the app bar so that we can do the search */ + StackPanel^ leftPanel = (StackPanel^) this->TopAppBar->FindName("LeftPanel"); + + if (leftPanel != nullptr && m_insearch) + { + m_insearch = false; + leftPanel->Children->RemoveAtEnd(); + leftPanel->Children->RemoveAtEnd(); + leftPanel->Children->RemoveAtEnd(); + } + else if (leftPanel != nullptr && !m_insearch) + { + /* Search is not going to work in snapped view for now to simplify UI + in this cramped case. So see if we can get out of snapped mode. */ + + if (!EnsureUnsnapped()) + return; + + m_insearch = true; + Windows::UI::Xaml::Controls::Button^ PrevButton = ref new Button(); + PrevButton->Style = safe_cast<Windows::UI::Xaml::Style^>(App::Current->Resources->Lookup("PreviousAppBarButtonStyle")); + PrevButton->Click += ref new RoutedEventHandler(this, &mupdf_cpp::MainPage::SearchPrev); + + Windows::UI::Xaml::Controls::Button^ NextButton = ref new Button(); + NextButton->Style = safe_cast<Windows::UI::Xaml::Style^>(App::Current->Resources->Lookup("NextAppBarButtonStyle")); + NextButton->Click += ref new RoutedEventHandler(this, &mupdf_cpp::MainPage::SearchNext); + + Windows::UI::Xaml::Controls::TextBox^ SearchBox = ref new TextBox(); + SearchBox->Name = "findBox"; + SearchBox->Width = 200; + SearchBox->Height = 20; + + leftPanel->Children->Append(SearchBox); + leftPanel->Children->Append(PrevButton); + leftPanel->Children->Append(NextButton); + } +} + +void mupdf_cpp::MainPage::ShowSearchResults(SearchResult_t result) +{ + int height, width; + int old_page = this->m_currpage; + int new_page = result.page_num; + spatial_info_t spatial_info = InitSpatial(1); + return; + + /* This will be fixed and turned on when I determine how best to show the + canvas and bind to the xmal content */ +#if 0 + this->m_ren_status = REN_PAGE; + task<Canvas^> the_task = RenderPage_Task(m_doc, new_page, &width, &height, + spatial_info, &m_renderedImage); + the_task.then([this, old_page, new_page](task<Canvas^> the_task) + { + assert(IsMainThread()); + + try + { + this->m_renderedCanvas = the_task.get(); + } + catch (const task_canceled& e) + { + this->m_renderedCanvas = nullptr; + } + ReplacePage(new_page); + this->m_ren_status = REN_AVAILABLE; + this->ReleasePages(old_page, new_page); + }, task_continuation_context::use_current()).then([this, result]() + + { + /* Once the rendering is done launch this task to show the result */ + Point screenSize; + Point pageSize; + Point scale; + + if (this->m_links_on) + { + fz_drop_link(ctx, this->m_links); + AddLinkCanvas(); + } + fz_page *page = fz_load_page(m_doc, result.page_num); + FlipViewItem ^flipview_temp = (FlipViewItem^) m_curr_flipView->Items->GetAt(result.page_num); + Canvas^ results_Canvas = (Canvas^) (flipview_temp->Content); + + m_searchpage = result.page_num; + + screenSize.Y = this->ActualHeight; + screenSize.X = this->ActualWidth; + + screenSize.X *= screenScale; + screenSize.Y *= screenScale; + + pageSize = measurePage(m_doc, page); + scale = fitPageToScreen(pageSize, screenSize); + + /* Now add the rects */ + for (int k = 0; k < result.box_count && k < MAX_SEARCH; k++) + { + /* Create a new ref counted Rectangle */ + Rectangle^ a_rectangle = ref new Rectangle(); + TranslateTransform ^trans_transform = ref new TranslateTransform(); + a_rectangle->Width = hit_bbox[k].x1 - hit_bbox[k].x0; + a_rectangle->Height = hit_bbox[k].y1 - hit_bbox[k].y0; + trans_transform->X = hit_bbox[k].x0 * scale.X; + trans_transform->Y = hit_bbox[k].y0 * scale.Y; + a_rectangle->Width *= scale.X; + a_rectangle->Height *= scale.Y; + a_rectangle->RenderTransform = trans_transform; + a_rectangle->Fill = m_textcolor_brush; + results_Canvas->Children->Append(a_rectangle); + m_search_rect_count += 1; + } + if (result.box_count > 0) + { + m_flip_from_searchlink = true; + this->m_curr_flipView->SelectedIndex = result.page_num; + m_currpage = result.page_num; + } + }, task_continuation_context::use_current()); +#endif +} + +void mupdf_cpp::MainPage::SearchNext(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) +{ + StackPanel^ leftPanel = (StackPanel^) this->TopAppBar->FindName("LeftPanel"); + TextBox^ findBox = (TextBox^) leftPanel->FindName("findBox"); + String^ textToFind = findBox->Text; + RenderingStatus_t *ren_status = &m_ren_status; + cancellation_token_source *ThumbCancel = &m_ThumbCancel; + + /* Create a task to wait until the renderer is available */ + create_task([ren_status, ThumbCancel]() + { + if (*ren_status == REN_THUMBS) + ThumbCancel->cancel(); + while (*ren_status != REN_AVAILABLE) { + } + }).then([this, textToFind]() + { + if (this->m_search_active == false) + SearchInDirection(1, textToFind); + }, task_continuation_context::use_current()); +} + +void mupdf_cpp::MainPage::SearchPrev(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) +{ + StackPanel^ leftPanel = (StackPanel^) this->TopAppBar->FindName("LeftPanel"); + TextBox^ findBox = (TextBox^) leftPanel->FindName("findBox"); + String^ textToFind = findBox->Text; + RenderingStatus_t *ren_status = &m_ren_status; + cancellation_token_source *ThumbCancel = &m_ThumbCancel; + + /* Create a task to wait until the renderer is available */ + create_task([ren_status, ThumbCancel]() + { + if (*ren_status == REN_THUMBS) + ThumbCancel->cancel(); + while (*ren_status != REN_AVAILABLE) { + } + }).then([this, textToFind]() + { + if (this->m_search_active == false) + SearchInDirection(-1, textToFind); + }, task_continuation_context::use_current()); +} + +void mupdf_cpp::MainPage::CancelSearch(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) +{ + m_searchcts.cancel(); +} + +void mupdf_cpp::MainPage::ResetSearch(void) +{ + m_searchpage = -1; +#if 0 + wchar_t buf[20]; + String^ TempString = ref new String(buf); + + /* Remove all the rects */ + for (int k = 0; k < this->m_search_rect_count; k++) + { + unsigned int index; + int len = swprintf_s(buf, 20, L"%s_%d", L"Rect",k); + Rectangle^ curr_rect = (Rectangle^) (m_curr_flipView->FindName(TempString)); + if (curr_rect != nullptr) + { + Canvas^ results_Canvas = (Canvas^) curr_rect->Parent; + results_Canvas->Children->IndexOf(curr_rect, &index); + results_Canvas->Children->RemoveAt(index); + } + } +#endif +} + +void mupdf_cpp::MainPage::SearchInDirection(int dir, String^ textToFind) +{ + cancellation_token_source cts; + auto token = cts.get_token(); + m_searchcts = cts; + int pos = m_currpage; + int start; + SearchResult_t result; + + result.box_count = 0; + result.page_num = -1; + + if (m_searchpage == pos) + start = pos + dir; + else + start = pos; + + /* ProgressBar^ my_xaml_Progress = (ProgressBar^) (this->FindName("xaml_Progress")); + my_xaml_Progress->Value = start; + my_xaml_Progress->IsEnabled = true; + my_xaml_Progress->Opacity = 1.0; */ + + /* ProgressBar^ my_bar = (ProgressBar^) (xaml_MainGrid->FindName("search_progress")); + + if (my_bar == nullptr) + { + my_bar = ref new ProgressBar(); + my_bar->Name = "search_progress"; + my_bar->Maximum = this->m_num_pages; + my_bar->Value = start; + my_bar->IsIndeterminate = false; + my_bar->Height = 10; + my_bar->Width = 400; + xaml_MainGrid->Children->Append(my_bar); + } + else + { + my_bar->Value = start; + } */ + this->m_search_active = true; + + /* Do task lambdas here to avoid UI blocking issues */ + auto search_task = create_task([this, textToFind, dir, start, &result]()->SearchResult_t + { + for (int i = start; i >= 0 && i < this->m_num_pages; i += dir) + { + result.box_count = this->mu_doc->ComputeTextSearch(textToFind, i); + result.page_num = i; + + //my_xaml_Progress->Value = i; + if (result.box_count > 0) + { + return result; + } + if (is_task_cancellation_requested()) + { + } + } + /* Todo no matches found alert */ + return result; + }, token); + /* Do the continuation on the ui thread */ + search_task.then([this](task<SearchResult_t> the_task) + { + SearchResult_t the_result = the_task.get(); + if (the_result.box_count > 0) + { + // ProgressBar^ xaml_Progress = (ProgressBar^) (this->FindName("xaml_Progress")); + // xaml_Progress->IsEnabled = false; + // xaml_Progress->Opacity = 0.0; + this->ShowSearchResults(the_result); + } + this->m_search_active = false; + }, task_continuation_context::use_current()); +} + +/* This is here to handle when we rotate or go into the snapview mode + ToDo add in data binding to change the scroll direction */ +void mupdf_cpp::MainPage::GridSizeChanged() +{ + int height = this->ActualHeight; + int width = this->ActualWidth; + FlipView^ old_flip = m_curr_flipView; + + + if (TopAppBar1->IsOpen) + { + UpdateAppBarButtonViewState(); + } + + if (height > width) + { + m_curr_flipView = this->xaml_vert_flipView; + if (!m_zoom_mode) + { + this->xaml_zoomCanvas->Height = height; + this->xaml_zoomCanvas->Width = width; + this->m_curr_flipView->Height = height; + this->m_curr_flipView->Width = width; + } + xaml_vert_flipView->IsEnabled = true; + xaml_vert_flipView->Opacity = 1; + xaml_horiz_flipView->IsEnabled = false; + xaml_horiz_flipView->Opacity = 0; } + else + { + m_curr_flipView = this->xaml_horiz_flipView; + if (!m_zoom_mode) + { + this->xaml_zoomCanvas->Height = height; + this->xaml_zoomCanvas->Width = width; + this->m_curr_flipView->Height = height; + this->m_curr_flipView->Width = width; + } + xaml_horiz_flipView->IsEnabled = true; + xaml_horiz_flipView->Opacity = 1; + xaml_vert_flipView->IsEnabled = false; + xaml_vert_flipView->Opacity = 0; + } + + if (xaml_RichText->Visibility == Windows::UI::Xaml::Visibility::Visible) + { + int height = xaml_OutsideGrid->ActualHeight; + int height_app = TopAppBar1->ActualHeight; + + xaml_RichText->Height = height - height_app; + } + + UpDatePageSizes(); + + if (m_num_pages > 0 && old_flip != m_curr_flipView && old_flip != nullptr) + { + if ((this->m_curr_flipView->SelectedIndex == this->m_currpage) && this->m_links_on) + FlipView_SelectionChanged(nullptr, nullptr); + else + this->m_curr_flipView->SelectedIndex = this->m_currpage; + } +} + +void mupdf_cpp::MainPage::UpDatePageSizes() +{ + /* Render our current pages at the new resolution and rescale the thumbnail + canvas if needed */ + if (m_num_pages > 0) + { + for (int i = 0; i < m_num_pages; i++) + { + FlipViewItem ^flipview_temp = (FlipViewItem^) m_curr_flipView->Items->GetAt(i); + if (flipview_temp != nullptr && flipview_temp->Content != nullptr) + { + Canvas^ curr_canvas = (Canvas^) flipview_temp->Content; + int curr_canvas_height = curr_canvas->Height; + int curr_canvas_width = curr_canvas->Width; + + double scale_x = (double) curr_canvas_height / (double) this->xaml_zoomCanvas->Height; + double scale_y = (double) curr_canvas_width / (double) this->xaml_zoomCanvas->Width; + + double min_scale = max(scale_x, scale_y); + curr_canvas->Height = curr_canvas_height / min_scale; + curr_canvas->Width = curr_canvas_width / min_scale; + } + } + } +}; + +void mupdf_cpp::MainPage::ClearLinksCanvas() +{ + Canvas^ link_canvas = (Canvas^) (this->FindName("linkCanvas")); + if (link_canvas != nullptr) + { + Canvas^ Parent_Canvas = (Canvas^) link_canvas->Parent; + if (Parent_Canvas != nullptr) + { + Parent_Canvas->Children->RemoveAtEnd(); + delete link_canvas; + } + } +} + +/* Link related code */ +void mupdf_cpp::MainPage::Linker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) +{ + m_links_on = !m_links_on; + RenderingStatus_t *ren_status = &m_ren_status; + cancellation_token_source *ThumbCancel = &m_ThumbCancel; + + if (m_links_on) + { + auto t = create_task([ren_status, ThumbCancel]() + { + if (*ren_status == REN_THUMBS) + ThumbCancel->cancel(); + while (*ren_status != REN_AVAILABLE) { + } + }); + + t.then([this]() + { + AddLinkCanvas(); + }, task_continuation_context::use_current()); + } + else + ClearLinksCanvas(); +} + +void mupdf_cpp::MainPage::AddLinkCanvas() +{ + return; + /* This is disabled for now until I figure out how to add the canvas + with rects into the data template for the scroll view object */ + if (m_links_on) + { + ClearLinksCanvas(); + + int num_links = mu_doc->ComputeLinks(m_currpage); + if (num_links == 0) return; + + Point screenSize; + Point pageSize; + Point scale; + + screenSize.Y = this->ActualHeight; + screenSize.X = this->ActualWidth; + screenSize.X *= screenScale; + screenSize.Y *= screenScale; + pageSize = mu_doc->GetPageSize(m_currpage); + scale = fitPageToScreen(pageSize, screenSize); + + /* A new canvas */ + Canvas^ link_canvas = ref new Canvas(); + link_canvas->Name = "linkCanvas"; + + /* Get current scrollview item */ + auto currItem = m_curr_flipView->ItemContainerGenerator->ContainerFromItem(m_curr_flipView->SelectedItem); + if (currItem == nullptr) + { + return; + } + + FlipViewItem ^flipview_temp = (FlipViewItem^) m_curr_flipView->Items->GetAt(m_currpage); + Canvas^ curr_canvas = (Canvas^) flipview_temp->Content; + + link_canvas->Height = curr_canvas->Height; + link_canvas->Width = curr_canvas->Width; + curr_canvas->Children->Append(link_canvas); + + /* Now add the rects */ + for (int k = 0; k < num_links; k++) + { + auto curr_link = mu_doc->GetLink(k); + if (curr_link->Type != NOT_SET) + { + Rectangle^ a_rectangle = ref new Rectangle(); + TranslateTransform ^trans_transform = ref new TranslateTransform(); + + a_rectangle->IsTapEnabled = true; + a_rectangle->Width = curr_link->LowerRight.X - curr_link->UpperLeft.X; + a_rectangle->Height = curr_link->UpperLeft.Y - curr_link->LowerRight.Y; + trans_transform->X = curr_link->UpperLeft.X * scale.X; + trans_transform->Y = curr_link->UpperLeft.Y * scale.Y; + a_rectangle->Width *= scale.X; + a_rectangle->Height *= scale.Y; + a_rectangle->RenderTransform = trans_transform; + a_rectangle->Fill = m_linkcolor_brush; + link_canvas->Children->Append(a_rectangle); + } + } + } +} + +bool mupdf_cpp::MainPage::CheckRect(Rectangle^ curr_rect, Point pt) +{ + TranslateTransform ^trans_transform = (TranslateTransform^) curr_rect->RenderTransform; + Point rect_start; + Point rect_end; + + rect_start.X = trans_transform->X; + rect_start.Y = trans_transform->Y; + rect_end.X = rect_start.X + curr_rect->Width; + rect_end.Y = rect_start.Y + curr_rect->Height; + if ((rect_start.X < pt.X) && (pt.X < rect_end.X) && (rect_start.Y < pt.Y) && (pt.Y < rect_end.Y)) + return true; + return false; +} + +void mupdf_cpp::MainPage::Canvas_Single_Tap(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e) +{ + /* See if we are currently viewing any links */ + if (m_links_on) + { + Point pt; + Canvas^ link_canvas = (Canvas^) (m_curr_flipView->FindName("linkCanvas")); + if (link_canvas != nullptr) + { + pt = e->GetPosition(link_canvas); + IIterator<UIElement^> ^it = link_canvas->Children->First(); + int count = 0; + while (it->HasCurrent) + { + Rectangle^ curr_rect = (Rectangle^) (it->Current); + if (CheckRect(curr_rect, pt)) + { + int page = JumpToLink(count); + if (page >= 0) + this->m_curr_flipView->SelectedIndex = page; + return; + } + it->MoveNext(); + count += 1; + } + } + } +} + +/* Window string hurdles.... */ +static String^ char_to_String(char *char_in) +{ + size_t size = MultiByteToWideChar(CP_UTF8, 0, char_in, -1, NULL, 0); + wchar_t *pw; + pw = new wchar_t[size]; + if (!pw) + { + delete []pw; + return nullptr; + } + MultiByteToWideChar (CP_UTF8, 0, char_in, -1, pw, size ); + String^ str_out = ref new String(pw); + delete []pw; + return str_out; +} + +int mupdf_cpp::MainPage::JumpToLink(int index) +{ + auto link = mu_doc->GetLink(index); + + if (link->Type == LINK_GOTO) + { + return link->PageNum; + } + else if (link->Type == LINK_URI) + { + // Set the option to show a warning + auto launchOptions = ref new Windows::System::LauncherOptions(); + launchOptions->TreatAsUntrusted = true; + + // Launch the URI with a warning prompt + concurrency::task<bool> launchUriOperation(Windows::System::Launcher::LaunchUriAsync(link->Uri, launchOptions)); + launchUriOperation.then([](bool success) + { + if (success) + { + // URI launched + } + else + { + // URI launch failed + } + }); + return -1; + } + return 0; +} + +void mupdf_cpp::MainPage::FlattenOutline(fz_outline *outline, int level) +{ +#if 0 + char indent[8*4+1]; + if (level > 8) + level = 8; + memset(indent, ' ', level * 4); + indent[level * 4] = 0; + + String^ indent_str = char_to_String(indent); + String^ str_indent; + + while (outline) + { + if (outline->dest.kind == FZ_LINK_GOTO) + { + int page = outline->dest.ld.gotor.page; + if (page >= 0 && outline->title) + { + /* Add to the contents */ + m_content.page->Append(page); + String^ str = char_to_String(outline->title); + m_content.string_orig->Append(str); + str_indent = str_indent->Concat(indent_str, str); + m_content.string_margin->Append(str_indent); + m_content.num += 1; + } + } + FlattenOutline(outline->down, level + 1); + outline = outline->next; + } +#endif +} + +/* Bring up the contents */ +void mupdf_cpp::MainPage::ContentDisplay(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) +{ +#if 0 + if (this->m_num_pages < 0 || m_zoom_mode) return; + + if (this->xaml_ListView->IsEnabled) + { + this->xaml_ListView->Opacity = 0.0; + this->xaml_ListView->IsEnabled = false; + this->m_curr_flipView->Opacity = 1.0; + this->m_curr_flipView->IsEnabled = true; + } + else + { + if (!m_content.num) + { + /* Make sure we are good to go */ + RenderingStatus_t *ren_status = &m_ren_status; + cancellation_token_source *ThumbCancel = &m_ThumbCancel; + fz_outline *root = NULL; + + /* Create a task to wait until the renderer is available */ + auto t = create_task([ren_status, ThumbCancel]() + { + if (*ren_status == REN_THUMBS) + ThumbCancel->cancel(); + while (*ren_status != REN_AVAILABLE) { + } + }).then([this, &root]() + { + root = fz_load_outline(m_doc); + if (root) + { + /* Flatten here if needed */ + m_content.page = ref new Vector<int>; + m_content.string_margin = ref new Vector<String^>; + m_content.string_orig = ref new Vector<String^>; + + + FlattenOutline(root, 0); + fz_free_outline(ctx, root); + + /* Bring up the content now */ + for (int k = 0; k < m_content.num; k++) + { + auto content_val = ref new LVContents; + content_val->Page = m_content.page->GetAt(k); + content_val->ContentItem = m_content.string_margin->GetAt(k); + this->xaml_ListView->Items->Append(content_val); + } + } + if (m_content.num) + { + this->xaml_ListView->Opacity = 1.0; + this->xaml_ListView->IsEnabled = true; + this->m_curr_flipView->Opacity = 0.0; + this->m_curr_flipView->IsEnabled = false; + } + /* Check if thumb rendering is done. If not then restart */ + if (this->m_num_pages != this->m_thumb_page_start) + this->RenderThumbs(); + }, task_continuation_context::use_current()); + } + else + { + this->xaml_ListView->Opacity = 1.0; + this->xaml_ListView->IsEnabled = true; + this->m_curr_flipView->Opacity = 0.0; + this->m_curr_flipView->IsEnabled = false; + } + } +#endif +} + +void mupdf_cpp::MainPage::ContentSelected(Platform::Object^ sender, Windows::UI::Xaml::Controls::ItemClickEventArgs^ e) +{ + + LVContents^ b = safe_cast<LVContents^>(e->ClickedItem); + int newpage = b->Page; + + if (newpage > -1 && newpage < this->m_num_pages) + { + this->xaml_ListView->Opacity = 0.0; + this->xaml_ListView->IsEnabled = false; + this->m_curr_flipView->Opacity = 1.0; + this->m_curr_flipView->IsEnabled = true; + + int old_page = this->m_currpage; + this->m_curr_flipView->SelectedIndex = newpage; + this->m_currpage = newpage; + } +} + +void mupdf_cpp::MainPage::Reflower(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) +{ +#if 0 + if (this->m_num_pages < 0) return; + + if (xaml_RichText->Visibility == Windows::UI::Xaml::Visibility::Visible) + { + /* Go back to flip view */ + xaml_RichText->Visibility = Windows::UI::Xaml::Visibility::Collapsed; + this->xaml_MainGrid->Opacity = 1.0; + this->m_curr_flipView->IsEnabled = true; + xaml_RichGrid->Visibility = Windows::UI::Xaml::Visibility::Collapsed; + xaml_RichGrid->Opacity = 0.0; + + } + else if (this->m_curr_flipView->IsEnabled) + { + /* Only go from flip view to reflow */ + RenderingStatus_t *ren_status = &m_ren_status; + cancellation_token_source *ThumbCancel = &m_ThumbCancel; + /* Create a task to wait until the renderer is available */ + auto t = create_task([ren_status, ThumbCancel]() + { + if (*ren_status == REN_THUMBS) + ThumbCancel->cancel(); + while (*ren_status != REN_AVAILABLE) { + } + }).then([this]() + { + fz_rect bounds; + fz_output *out; + fz_page *page = fz_load_page(m_doc, this->m_currpage); + fz_text_sheet *sheet = fz_new_text_sheet(ctx); + fz_text_page *text = fz_new_text_page(ctx, &fz_empty_rect); + fz_device *dev = fz_new_text_device(ctx, sheet, text); + + fz_run_page(m_doc, page, dev, &fz_identity, NULL); + fz_free_device(dev); + dev = NULL; + fz_text_analysis(ctx, sheet, text); + fz_buffer *buf = fz_new_buffer(ctx, 256); + out = fz_new_output_buffer(ctx, buf); + fz_print_text_page(ctx, out, text); + xaml_RichText->Visibility = Windows::UI::Xaml::Visibility::Visible; + this->xaml_MainGrid->Opacity = 0.0; + this->m_curr_flipView->IsEnabled = false; + String^ html_string = char_to_String((char*) buf->data); + + xaml_RichGrid->Visibility = Windows::UI::Xaml::Visibility::Visible; + xaml_RichGrid->Opacity = 1.0; + int height = xaml_OutsideGrid->ActualHeight; + int height_app = TopAppBar1->ActualHeight; + + xaml_RichText->Height = height - height_app; + this->xaml_RichText->Document->SetText(Windows::UI::Text::TextSetOptions::FormatRtf, html_string); + + /* Check if thumb rendering is done. If not then restart */ + if (this->m_num_pages != this->m_thumb_page_start) + this->RenderThumbs(); + }, task_continuation_context::use_current()); + } +#endif +} + +/* Need to handle resizing of app bar to make sure everything fits */ + +void mupdf_cpp::MainPage::topAppBar_Loaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) +{ + UpdateAppBarButtonViewState(); +} + +void mupdf_cpp::MainPage::UpdateAppBarButtonViewState() +{ + String ^viewState = Windows::UI::ViewManagement::ApplicationView::Value.ToString(); + VisualStateManager::GoToState(Search, viewState, true); + VisualStateManager::GoToState(Contents, viewState, true); + VisualStateManager::GoToState(Links, viewState, true); + VisualStateManager::GoToState(Reflow, viewState, true); + VisualStateManager::GoToState(Help, viewState, true); +} + +void mupdf_cpp::MainPage::ScrollChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::ScrollViewerViewChangedEventArgs^ e) +{ + + int zz = 1; +} |