// // MainPage.xaml.cpp // MainPage 类的实现。 // #include "pch.h" #include "MainPage.xaml.h" #include "StringHelper.h" #include "AsyncHelper.h" #include "../../global.h" #include "../../palcfg.h" #include "../../generated.h" using namespace SDLPal; using namespace Platform; using namespace Windows::Foundation; using namespace Windows::Foundation::Collections; 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::Input; using namespace Windows::UI::Xaml::Media; using namespace Windows::UI::Xaml::Navigation; static Platform::String^ msg_file_exts[] = { ".msg" }; static Platform::String^ font_file_exts[] = { ".bdf" }; static Platform::String^ log_file_exts[] = { ".log" }; MainPage::MainPage() { InitializeComponent(); m_controls = ref new Platform::Collections::Map(); m_controls->Insert(btnBrowseMsgFile->Name, ref new ButtonAttribute(tbMsgFile, ref new Platform::Array(msg_file_exts, sizeof(msg_file_exts) / sizeof(msg_file_exts[0])))); m_controls->Insert(btnBrowseFontFile->Name, ref new ButtonAttribute(tbFontFile, ref new Platform::Array(font_file_exts, sizeof(font_file_exts) / sizeof(font_file_exts[0])))); m_controls->Insert(btnBrowseLogFile->Name, ref new ButtonAttribute(tbLogFile, ref new Platform::Array(log_file_exts, sizeof(log_file_exts) / sizeof(log_file_exts[0])))); m_controls->Insert(cbUseMsgFile->Name, ref new ButtonAttribute(gridMsgFile, nullptr)); m_controls->Insert(cbUseFontFile->Name, ref new ButtonAttribute(gridFontFile, nullptr)); m_controls->Insert(cbUseLogFile->Name, ref new ButtonAttribute(gridLogFile, nullptr)); m_acl[PALCFG_GAMEPATH] = ref new AccessListEntry(tbGamePath, nullptr, ConvertString(PAL_ConfigName(PALCFG_GAMEPATH))); m_acl[PALCFG_SAVEPATH] = ref new AccessListEntry(tbGamePath, nullptr, ConvertString(PAL_ConfigName(PALCFG_SAVEPATH))); m_acl[PALCFG_MESSAGEFILE] = ref new AccessListEntry(tbMsgFile, cbUseMsgFile, ConvertString(PAL_ConfigName(PALCFG_MESSAGEFILE))); m_acl[PALCFG_FONTFILE] = ref new AccessListEntry(tbFontFile, cbUseFontFile, ConvertString(PAL_ConfigName(PALCFG_FONTFILE))); m_acl[PALCFG_LOGFILE] = ref new AccessListEntry(tbLogFile, cbUseLogFile, ConvertString(PAL_ConfigName(PALCFG_LOGFILE))); tbGitRevision->Text = " " PAL_GIT_REVISION; LoadControlContents(); m_resLdr = Windows::ApplicationModel::Resources::ResourceLoader::GetForCurrentView(); if (static_cast(Application::Current)->LastCrashed) { (ref new Windows::UI::Popups::MessageDialog(m_resLdr->GetString("MBCrashContent")))->ShowAsync(); } } void SDLPal::MainPage::LoadControlContents(bool loadDefault) { for (auto i = m_acl.begin(); i != m_acl.end(); i++) { auto item = i->second; item->text->Text = ""; item->text->Tag = nullptr; if (item->check) { item->check->IsChecked = false; m_controls->Lookup(item->check->Name)->Object->Visibility = Windows::UI::Xaml::Visibility::Collapsed; } } if (!loadDefault) { // Always load folder/files from FutureAccessList std::list invalid_tokens; auto fal = Windows::Storage::AccessCache::StorageApplicationPermissions::FutureAccessList; for each (auto entry in fal->Entries) { auto& ace = m_acl[PAL_ConfigIndex(ConvertString(entry.Token).c_str())]; ace->text->Tag = AWait(fal->GetItemAsync(entry.Token), g_eventHandle); if (ace->text->Tag) ace->text->Text = entry.Metadata; else invalid_tokens.push_back(entry.Token); if (ace->check) { auto grid = m_controls->Lookup(ace->check->Name)->Object; ace->check->IsChecked = (ace->text->Tag != nullptr); grid->Visibility = ace->check->IsChecked->Value ? Windows::UI::Xaml::Visibility::Visible : Windows::UI::Xaml::Visibility::Collapsed; } } for (auto i = invalid_tokens.begin(); i != invalid_tokens.end(); fal->Remove(*i++)); } tsKeepAspect->IsOn = (gConfig.fKeepAspectRatio == TRUE); tsStereo->IsOn = (gConfig.iAudioChannels == 2); tsSurroundOPL->IsOn = (gConfig.fUseSurroundOPL == TRUE); tsTouchOverlay->IsOn = (gConfig.fUseTouchOverlay == TRUE); tsEnableAVI->IsOn = (gConfig.fEnableAviPlay == TRUE); slMusicVolume->Value = gConfig.iMusicVolume; slSoundVolume->Value = gConfig.iSoundVolume; slQuality->Value = gConfig.iResampleQuality; cbLogLevel->SelectedIndex = (int)gConfig.iLogLevel; cbCD->SelectedIndex = (gConfig.eCDType == MUSIC_MP3) ? 0 : 1; cbBGM->SelectedIndex = (gConfig.eMusicType <= MUSIC_OGG) ? gConfig.eMusicType : MUSIC_RIX; cbOPL->SelectedIndex = (int)gConfig.eOPLType; if (gConfig.iSampleRate <= 11025) cbSampleRate->SelectedIndex = 0; else if (gConfig.iSampleRate <= 22050) cbSampleRate->SelectedIndex = 1; else cbSampleRate->SelectedIndex = 2; auto wValue = gConfig.wAudioBufferSize >> 10; unsigned int index = 0; while (wValue) { index++; wValue >>= 1; } if (index >= cbAudioBuffer->Items->Size) cbAudioBuffer->SelectedIndex = cbAudioBuffer->Items->Size - 1; else cbAudioBuffer->SelectedIndex = index; if (gConfig.iOPLSampleRate <= 12429) cbOPLSR->SelectedIndex = 0; else if (gConfig.iSampleRate <= 24858) cbOPLSR->SelectedIndex = 1; else cbOPLSR->SelectedIndex = 2; } void SDLPal::MainPage::SaveControlContents() { // All folders/files are not stored in config file, as they are store in FutureAcessList if (gConfig.pszGamePath) { free(gConfig.pszGamePath); gConfig.pszGamePath = nullptr; } if (gConfig.pszMsgFile) { free(gConfig.pszMsgFile); gConfig.pszMsgFile = nullptr; } if (gConfig.pszFontFile) { free(gConfig.pszFontFile); gConfig.pszFontFile = nullptr; } if (gConfig.pszLogFile) { free(gConfig.pszLogFile); gConfig.pszLogFile = nullptr; } gConfig.fKeepAspectRatio = tsKeepAspect->IsOn ? TRUE : FALSE; gConfig.iAudioChannels = tsStereo->IsOn ? 2 : 1; gConfig.fUseSurroundOPL = tsSurroundOPL->IsOn ? TRUE : FALSE; gConfig.fUseTouchOverlay = tsTouchOverlay->IsOn ? TRUE : FALSE; gConfig.fEnableAviPlay = tsEnableAVI->IsOn ? TRUE : FALSE; gConfig.iMusicVolume = (int)slMusicVolume->Value; gConfig.iSoundVolume = (int)slSoundVolume->Value; gConfig.iResampleQuality = (int)slQuality->Value; gConfig.iLogLevel = (LOGLEVEL)cbLogLevel->SelectedIndex; gConfig.eCDType = (MUSICTYPE)(MUSIC_MP3 + cbCD->SelectedIndex); gConfig.eMusicType = (MUSICTYPE)cbBGM->SelectedIndex; gConfig.eOPLType = (OPLTYPE)cbOPL->SelectedIndex; gConfig.iSampleRate = wcstoul(static_cast(static_cast(cbSampleRate->SelectedItem)->Content)->Data(), nullptr, 10); gConfig.iOPLSampleRate = wcstoul(static_cast(static_cast(cbOPLSR->SelectedItem)->Content)->Data(), nullptr, 10); gConfig.wAudioBufferSize = wcstoul(static_cast(static_cast(cbAudioBuffer->SelectedItem)->Content)->Data(), nullptr, 10); } void SDLPal::MainPage::cbBGM_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e) { auto visibility = (cbBGM->SelectedIndex == MUSIC_RIX) ? Windows::UI::Xaml::Visibility::Visible : Windows::UI::Xaml::Visibility::Collapsed; cbOPL->Visibility = visibility; cbOPLSR->Visibility = visibility; tsSurroundOPL->Visibility = visibility; } void SDLPal::MainPage::btnDefault_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { PAL_LoadConfig(FALSE); LoadControlContents(true); } void SDLPal::MainPage::btnReset_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { PAL_LoadConfig(TRUE); LoadControlContents(); } void SDLPal::MainPage::btnFinish_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { if (tbGamePath->Text->Length() > 0) { auto fal = Windows::Storage::AccessCache::StorageApplicationPermissions::FutureAccessList; for (auto i = m_acl.begin(); i != m_acl.end(); i++) { auto item = i->second; auto check = item->check ? item->check->IsChecked->Value : true; if (check && item->text->Tag) fal->AddOrReplace(item->token, safe_cast(item->text->Tag), item->text->Text); else if (fal->ContainsItem(item->token)) fal->Remove(item->token); } SaveControlContents(); gConfig.fLaunchSetting = FALSE; PAL_SaveConfig(); auto dlg = ref new Windows::UI::Popups::MessageDialog(m_resLdr->GetString("MBExitContent")); dlg->Title = m_resLdr->GetString("MBExitTitle"); concurrency::create_task(dlg->ShowAsync()).then([] (Windows::UI::Popups::IUICommand^ command) { Application::Current->Exit(); }); } else { (ref new Windows::UI::Popups::MessageDialog(m_resLdr->GetString("MBEmptyContent")))->ShowAsync(); } } void SDLPal::MainPage::btnClearFile_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { tbMsgFile->Text = ""; tbMsgFile->Tag = nullptr; } void SDLPal::MainPage::SetPath(Windows::Storage::StorageFolder^ folder) { if (folder) { tbGamePath->Text = folder->Path; tbGamePath->Tag = folder; } } void SDLPal::MainPage::SetFile(Windows::UI::Xaml::Controls::TextBox^ target, Windows::Storage::StorageFile^ file) { if (target && file) { target->Text = file->Path; target->Tag = file; } } void SDLPal::MainPage::btnBrowseFolder_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { auto picker = ref new Windows::Storage::Pickers::FolderPicker(); picker->FileTypeFilter->Append("*"); #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP picker->ContinuationData->Insert("Page", this); picker->PickFolderAndContinue(); #else concurrency::create_task(picker->PickSingleFolderAsync()).then([this](Windows::Storage::StorageFolder^ folder) { SetPath(folder); }); #endif } void SDLPal::MainPage::btnBrowseFileOpen_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { auto button = static_cast(sender); auto target = m_controls->Lookup(button->Name); auto picker = ref new Windows::Storage::Pickers::FileOpenPicker(); picker->FileTypeFilter->ReplaceAll(target->Filter); #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP picker->ContinuationData->Insert("Page", this); picker->ContinuationData->Insert("Target", target->Object); picker->PickSingleFileAndContinue(); #else concurrency::create_task(picker->PickSingleFileAsync()).then( [this, target](Windows::Storage::StorageFile^ file) { SetFile(static_cast(target->Object), file); } ); #endif } void SDLPal::MainPage::btnBrowseFileSave_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { auto button = static_cast(sender); auto target = m_controls->Lookup(button->Name); auto picker = ref new Windows::Storage::Pickers::FileSavePicker(); picker->FileTypeChoices->Insert(m_resLdr->GetString("LogFileType"), ref new Platform::Collections::Vector(target->Filter)); #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP picker->ContinuationData->Insert("Page", this); picker->ContinuationData->Insert("Target", target->Object); picker->PickSaveFileAndContinue(); #else concurrency::create_task(picker->PickSaveFileAsync()).then( [this, target](Windows::Storage::StorageFile^ file) { SetFile(static_cast(target->Object), file); } ); #endif } void SDLPal::MainPage::cbUseFile_CheckChanged(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { auto checker = static_cast(sender); auto attr = m_controls->Lookup(checker->Name); attr->Object->Visibility = checker->IsChecked->Value ? Windows::UI::Xaml::Visibility::Visible : Windows::UI::Xaml::Visibility::Collapsed; } void SDLPal::MainPage::Page_Loaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { #if NTDDI_VERSION >= NTDDI_WIN10 if (!Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.UI.ViewManagement.StatusBar")) return; #endif #if NTDDI_VERSION >= NTDDI_WIN10 || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP auto statusBar = Windows::UI::ViewManagement::StatusBar::GetForCurrentView(); concurrency::create_task(statusBar->ShowAsync()).then([statusBar]() { statusBar->BackgroundOpacity = 1.0; }); #endif }