Cemu/src/gui/PadViewFrame.cpp
2022-08-26 04:03:26 +02:00

190 lines
No EOL
5.5 KiB
C++

#include "gui/wxgui.h"
#include "gui/guiWrapper.h"
#include "gui/PadViewFrame.h"
#include <wx/display.h>
#include "config/ActiveSettings.h"
#include "Cafe/OS/libs/swkbd/swkbd.h"
#include "gui/canvas/OpenGLCanvas.h"
#include "gui/canvas/VulkanCanvas.h"
#include "config/CemuConfig.h"
#include "gui/MainWindow.h"
#include "gui/helpers/wxHelpers.h"
#include "input/InputManager.h"
#if BOOST_OS_LINUX || BOOST_OS_MACOS
#include "resource/embedded/resources.h"
#endif
#include "wxHelper.h"
extern WindowInfo g_window_info;
PadViewFrame::PadViewFrame(wxFrame* parent)
: wxFrame(nullptr, wxID_ANY, "GamePad View", wxDefaultPosition, wxSize(854, 480), wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN | wxRESIZE_BORDER | wxCLOSE_BOX | wxWANTS_CHARS)
{
gui_initHandleContextFromWxWidgetsWindow(g_window_info.window_pad, this);
SetIcon(wxICON(M_WND_ICON128));
wxWindow::EnableTouchEvents(wxTOUCH_PAN_GESTURES);
SetMinClientSize({ 320, 180 });
SetPosition({ g_window_info.restored_pad_x, g_window_info.restored_pad_y });
SetSize({ g_window_info.restored_pad_width, g_window_info.restored_pad_height });
if (g_window_info.pad_maximized)
Maximize();
Bind(wxEVT_SIZE, &PadViewFrame::OnSizeEvent, this);
Bind(wxEVT_MOVE, &PadViewFrame::OnMoveEvent, this);
Bind(wxEVT_MOTION, &PadViewFrame::OnMouseMove, this);
Bind(wxEVT_SET_WINDOW_TITLE, &PadViewFrame::OnSetWindowTitle, this);
g_window_info.pad_open = true;
}
PadViewFrame::~PadViewFrame()
{
g_window_info.pad_open = false;
}
bool PadViewFrame::Initialize()
{
const wxSize client_size = GetClientSize();
g_window_info.pad_width = client_size.GetWidth();
g_window_info.pad_height = client_size.GetHeight();
return true;
}
void PadViewFrame::InitializeRenderCanvas()
{
auto sizer = new wxBoxSizer(wxVERTICAL);
{
if (ActiveSettings::GetGraphicsAPI() == kVulkan)
m_render_canvas = new VulkanCanvas(this, wxSize(854, 480), false);
else
m_render_canvas = GLCanvas_Create(this, wxSize(854, 480), false);
sizer->Add(m_render_canvas, 1, wxEXPAND, 0, nullptr);
}
SetSizer(sizer);
Layout();
m_render_canvas->Bind(wxEVT_KEY_UP, &PadViewFrame::OnKeyUp, this);
m_render_canvas->Bind(wxEVT_CHAR, &PadViewFrame::OnChar, this);
m_render_canvas->Bind(wxEVT_MOTION, &PadViewFrame::OnMouseMove, this);
m_render_canvas->Bind(wxEVT_LEFT_DOWN, &PadViewFrame::OnMouseLeft, this);
m_render_canvas->Bind(wxEVT_LEFT_UP, &PadViewFrame::OnMouseLeft, this);
m_render_canvas->Bind(wxEVT_RIGHT_DOWN, &PadViewFrame::OnMouseRight, this);
m_render_canvas->Bind(wxEVT_RIGHT_UP, &PadViewFrame::OnMouseRight, this);
m_render_canvas->Bind(wxEVT_GESTURE_PAN, &PadViewFrame::OnGesturePan, this);
m_render_canvas->SetFocus();
}
void PadViewFrame::OnSizeEvent(wxSizeEvent& event)
{
if (!IsMaximized() && !IsFullScreen())
{
g_window_info.restored_pad_width = GetSize().x;
g_window_info.restored_pad_height = GetSize().y;
}
g_window_info.pad_maximized = IsMaximized() && !IsFullScreen();
const wxSize client_size = GetClientSize();
g_window_info.pad_width = client_size.GetWidth();
g_window_info.pad_height = client_size.GetHeight();
event.Skip();
}
void PadViewFrame::OnMoveEvent(wxMoveEvent& event)
{
if (!IsMaximized() && !IsFullScreen())
{
g_window_info.restored_pad_x = GetPosition().x;
g_window_info.restored_pad_y = GetPosition().y;
}
}
void PadViewFrame::OnKeyUp(wxKeyEvent& event)
{
event.Skip();
if (swkbd_hasKeyboardInputHook())
return;
const auto code = event.GetKeyCode();
if (code == WXK_ESCAPE)
ShowFullScreen(false);
else if (code == WXK_RETURN && event.AltDown())
ShowFullScreen(!IsFullScreen());
}
void PadViewFrame::OnGesturePan(wxPanGestureEvent& event)
{
auto& instance = InputManager::instance();
std::scoped_lock lock(instance.m_pad_touch.m_mutex);
instance.m_pad_touch.position = { event.GetPosition().x, event.GetPosition().y };
instance.m_pad_touch.left_down = event.IsGestureStart() || !event.IsGestureEnd();
if (event.IsGestureStart() || !event.IsGestureEnd())
instance.m_pad_touch.left_down_toggle = true;
}
void PadViewFrame::OnChar(wxKeyEvent& event)
{
if (swkbd_hasKeyboardInputHook())
swkbd_keyInput(event.GetUnicodeKey());
event.Skip();
}
void PadViewFrame::OnMouseMove(wxMouseEvent& event)
{
auto& instance = InputManager::instance();
std::scoped_lock lock(instance.m_pad_touch.m_mutex);
instance.m_pad_mouse.position = { event.GetPosition().x, event.GetPosition().y };
event.Skip();
}
void PadViewFrame::OnMouseLeft(wxMouseEvent& event)
{
auto& instance = InputManager::instance();
std::scoped_lock lock(instance.m_pad_mouse.m_mutex);
instance.m_pad_mouse.left_down = event.ButtonDown(wxMOUSE_BTN_LEFT);
instance.m_pad_mouse.position = { event.GetPosition().x, event.GetPosition().y };
if (event.ButtonDown(wxMOUSE_BTN_LEFT))
instance.m_pad_mouse.left_down_toggle = true;
}
void PadViewFrame::OnMouseRight(wxMouseEvent& event)
{
auto& instance = InputManager::instance();
std::scoped_lock lock(instance.m_pad_mouse.m_mutex);
instance.m_pad_mouse.right_down = event.ButtonDown(wxMOUSE_BTN_LEFT);
instance.m_pad_mouse.position = { event.GetPosition().x, event.GetPosition().y };
if (event.ButtonDown(wxMOUSE_BTN_RIGHT))
instance.m_pad_mouse.right_down_toggle = true;
}
void PadViewFrame::OnSetWindowTitle(wxCommandEvent& event)
{
this->SetTitle(event.GetString());
}
void PadViewFrame::AsyncSetTitle(std::string_view windowTitle)
{
wxCommandEvent set_title_event(wxEVT_SET_WINDOW_TITLE);
set_title_event.SetString(wxHelper::FromUtf8(windowTitle));
QueueEvent(set_title_event.Clone());
}