Files
WickedEngine/Template_UWP/Main.cpp
T
2022-08-02 11:36:15 +02:00

229 lines
6.4 KiB
C++

#include "pch.h"
// Use the C++ standard templated min/max
#define NOMINMAX
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <exception>
#include <future>
#include <iterator>
#include <memory>
#include <stdexcept>
#include "winrt/Windows.ApplicationModel.h"
#include "winrt/Windows.ApplicationModel.Core.h"
#include "winrt/Windows.ApplicationModel.Activation.h"
#include "winrt/Windows.Foundation.h"
#include "winrt/Windows.Graphics.Display.h"
#include "winrt/Windows.System.h"
#include "winrt/Windows.UI.Core.h"
#include "winrt/Windows.UI.Input.h"
#include "winrt/Windows.UI.ViewManagement.h"
using namespace winrt::Windows::ApplicationModel;
using namespace winrt::Windows::ApplicationModel::Core;
using namespace winrt::Windows::ApplicationModel::Activation;
using namespace winrt::Windows::UI::Core;
using namespace winrt::Windows::UI::Input;
using namespace winrt::Windows::UI::ViewManagement;
using namespace winrt::Windows::System;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Graphics::Display;
class ViewProvider : public winrt::implements<ViewProvider, IFrameworkView>
{
public:
// IFrameworkView methods
void Initialize(CoreApplicationView const & applicationView)
{
applicationView.Activated({ this, &ViewProvider::OnActivated });
CoreApplication::Suspending({ this, &ViewProvider::OnSuspending });
CoreApplication::Resuming({ this, &ViewProvider::OnResuming });
application.infoDisplay.active = true;
application.infoDisplay.watermark = true;
application.infoDisplay.resolution = true;
application.infoDisplay.fpsinfo = true;
}
void Uninitialize() noexcept
{
}
void SetWindow(CoreWindow const & window)
{
window.SizeChanged({ this, &ViewProvider::OnWindowSizeChanged });
window.VisibilityChanged({ this, &ViewProvider::OnVisibilityChanged });
window.Closed([this](auto&&, auto&&) { m_exit = true; });
auto dispatcher = CoreWindow::GetForCurrentThread().Dispatcher();
dispatcher.AcceleratorKeyActivated({ this, &ViewProvider::OnAcceleratorKeyActivated });
auto navigation = SystemNavigationManager::GetForCurrentView();
// UWP on Xbox One triggers a back request whenever the B button is pressed
// which can result in the app being suspended if unhandled
navigation.BackRequested([](const winrt::Windows::Foundation::IInspectable&, const BackRequestedEventArgs& args)
{
args.Handled(true);
});
auto currentDisplayInformation = DisplayInformation::GetForCurrentView();
currentDisplayInformation.DpiChanged({ this, &ViewProvider::OnDpiChanged });
DisplayInformation::DisplayContentsInvalidated({ this, &ViewProvider::OnDisplayContentsInvalidated });
m_DPI = currentDisplayInformation.LogicalDpi();
m_logicalWidth = window.Bounds().Width;
m_logicalHeight = window.Bounds().Height;
application.SetWindow(&window);
}
void Load(winrt::hstring const &) noexcept
{
}
void Run()
{
while (!m_exit)
{
if (m_visible)
{
application.Run();
CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
}
else
{
CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
}
}
}
protected:
// Event handlers
void OnActivated(CoreApplicationView const & /*applicationView*/, IActivatedEventArgs const & args)
{
CoreWindow::GetForCurrentThread().Activate();
}
void OnSuspending(IInspectable const & /*sender*/, SuspendingEventArgs const & args)
{
auto deferral = args.SuspendingOperation().GetDeferral();
auto f = std::async(std::launch::async, [this, deferral]()
{
deferral.Complete();
});
}
void OnResuming(IInspectable const & /*sender*/, IInspectable const & /*args*/)
{
}
void OnWindowSizeChanged(CoreWindow const & sender, WindowSizeChangedEventArgs const & /*args*/)
{
application.SetWindow(&sender);
}
void OnVisibilityChanged(CoreWindow const & /*sender*/, VisibilityChangedEventArgs const & args)
{
m_visible = args.Visible();
}
void OnAcceleratorKeyActivated(CoreDispatcher const &, AcceleratorKeyEventArgs const & args)
{
if (args.EventType() == CoreAcceleratorKeyEventType::SystemKeyDown
&& args.VirtualKey() == VirtualKey::Enter
&& args.KeyStatus().IsMenuKeyDown
&& !args.KeyStatus().WasKeyDown)
{
// Implements the classic ALT+ENTER fullscreen toggle
auto view = ApplicationView::GetForCurrentView();
if (view.IsFullScreenMode())
view.ExitFullScreenMode();
else
view.TryEnterFullScreenMode();
args.Handled(true);
}
if (args.EventType() == CoreAcceleratorKeyEventType::Character && args.VirtualKey() != VirtualKey::Enter)
{
wchar_t c = (wchar_t)args.VirtualKey();
if (c == '\b')
{
wi::gui::TextInputField::DeleteFromInput();
}
else
{
wi::gui::TextInputField::AddInput(c);
}
}
}
void OnDpiChanged(DisplayInformation const & sender, IInspectable const & /*args*/)
{
application.SetWindow(&CoreWindow::GetForCurrentThread());
}
void OnDisplayContentsInvalidated(DisplayInformation const & /*sender*/, IInspectable const & /*args*/)
{
}
private:
bool m_exit = false;
bool m_visible = true;
float m_DPI = 96;
float m_logicalWidth = 800;
float m_logicalHeight = 600;
wi::Application application;
inline int ConvertDipsToPixels(float dips) const noexcept
{
return int(dips * m_DPI / 96.f + 0.5f);
}
inline float ConvertPixelsToDips(int pixels) const noexcept
{
return (float(pixels) * 96.f / m_DPI);
}
};
class ViewProviderFactory : public winrt::implements<ViewProviderFactory, IFrameworkViewSource>
{
public:
IFrameworkView CreateView()
{
return winrt::make<ViewProvider>();
}
};
// Entry point
int WINAPI wWinMain(
_In_ HINSTANCE /*hInstance*/,
_In_ HINSTANCE /*hPrevInstance*/,
_In_ LPWSTR /*lpCmdLine*/,
_In_ int /*nCmdShow*/
)
{
auto viewProviderFactory = winrt::make<ViewProviderFactory>();
CoreApplication::Run(viewProviderFactory);
return 0;
}