229 lines
6.4 KiB
C++
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;
|
|
}
|