Refactoring window stuff. Still needs some work.
This commit is contained in:
22
src/xenia/ui/menu_item.cc
Normal file
22
src/xenia/ui/menu_item.cc
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/ui/menu_item.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::ui;
|
||||
|
||||
|
||||
MenuItem::MenuItem(Window* window, MenuItem* parent_item) :
|
||||
window_(window), parent_item_(parent_item) {
|
||||
}
|
||||
|
||||
MenuItem::~MenuItem() {
|
||||
}
|
||||
41
src/xenia/ui/menu_item.h
Normal file
41
src/xenia/ui/menu_item.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_UI_MENU_ITEM_H_
|
||||
#define XENIA_UI_MENU_ITEM_H_
|
||||
|
||||
#include <xenia/core.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace ui {
|
||||
|
||||
class Window;
|
||||
|
||||
|
||||
class MenuItem {
|
||||
public:
|
||||
MenuItem(Window* window, MenuItem* parent_item = NULL);
|
||||
virtual ~MenuItem();
|
||||
|
||||
Window* window() const { return window_; }
|
||||
MenuItem* parent_item() const { return parent_item_; }
|
||||
|
||||
private:
|
||||
Window* window_;
|
||||
MenuItem* parent_item_;
|
||||
// children
|
||||
};
|
||||
|
||||
|
||||
} // namespace ui
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_UI_MENU_ITEM_H_
|
||||
18
src/xenia/ui/sources.gypi
Normal file
18
src/xenia/ui/sources.gypi
Normal file
@@ -0,0 +1,18 @@
|
||||
# Copyright 2014 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'menu_item.cc',
|
||||
'menu_item.h',
|
||||
'ui_event.h',
|
||||
'window.cc',
|
||||
'window.h',
|
||||
],
|
||||
|
||||
'conditions': [
|
||||
['OS == "win"', {
|
||||
'includes': [
|
||||
'win32/sources.gypi',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}
|
||||
74
src/xenia/ui/ui_event.h
Normal file
74
src/xenia/ui/ui_event.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_UI_UI_EVENT_H_
|
||||
#define XENIA_UI_UI_EVENT_H_
|
||||
|
||||
#include <xenia/core.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace ui {
|
||||
|
||||
class App;
|
||||
class Window;
|
||||
|
||||
|
||||
class UIEvent {
|
||||
public:
|
||||
UIEvent(Window* window = NULL) :
|
||||
window_(window) {}
|
||||
virtual ~UIEvent() {}
|
||||
|
||||
Window* window() const { return window_; }
|
||||
|
||||
private:
|
||||
Window* window_;
|
||||
};
|
||||
|
||||
|
||||
class MouseEvent : public UIEvent {
|
||||
public:
|
||||
enum Button {
|
||||
MOUSE_BUTTON_NONE = 0,
|
||||
MOUSE_BUTTON_LEFT,
|
||||
MOUSE_BUTTON_RIGHT,
|
||||
MOUSE_BUTTON_MIDDLE,
|
||||
MOUSE_BUTTON_X1,
|
||||
MOUSE_BUTTON_X2,
|
||||
};
|
||||
|
||||
public:
|
||||
MouseEvent(Window* window,
|
||||
Button button, int32_t x, int32_t y,
|
||||
int32_t dx = 0, int32_t dy = 0) :
|
||||
button_(button), x_(x), y_(y), dx_(dx), dy_(dy),
|
||||
UIEvent(window) {}
|
||||
virtual ~MouseEvent() {}
|
||||
|
||||
Button button() const { return button_; }
|
||||
int32_t x() const { return x_; }
|
||||
int32_t y() const { return y_; }
|
||||
int32_t dx() const { return dx_; }
|
||||
int32_t dy() const { return dy_; }
|
||||
|
||||
private:
|
||||
Button button_;
|
||||
int32_t x_;
|
||||
int32_t y_;
|
||||
int32_t dx_;
|
||||
int32_t dy_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace ui
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_UI_UI_EVENT_H_
|
||||
9
src/xenia/ui/win32/sources.gypi
Normal file
9
src/xenia/ui/win32/sources.gypi
Normal file
@@ -0,0 +1,9 @@
|
||||
# Copyright 2014 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'win32_menu_item.cc',
|
||||
'win32_menu_item.h',
|
||||
'win32_window.cc',
|
||||
'win32_window.h',
|
||||
],
|
||||
}
|
||||
23
src/xenia/ui/win32/win32_menu_item.cc
Normal file
23
src/xenia/ui/win32/win32_menu_item.cc
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/ui/win32/win32_menu_item.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::ui;
|
||||
using namespace xe::ui::win32;
|
||||
|
||||
|
||||
Win32MenuItem::Win32MenuItem(Window* window, MenuItem* parent_item) :
|
||||
MenuItem(window, parent_item) {
|
||||
}
|
||||
|
||||
Win32MenuItem::~Win32MenuItem() {
|
||||
}
|
||||
37
src/xenia/ui/win32/win32_menu_item.h
Normal file
37
src/xenia/ui/win32/win32_menu_item.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_UI_WIN32_WIN32_MENU_ITEM_H_
|
||||
#define XENIA_UI_WIN32_WIN32_MENU_ITEM_H_
|
||||
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/ui/menu_item.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace ui {
|
||||
namespace win32 {
|
||||
|
||||
|
||||
class Win32MenuItem : public MenuItem {
|
||||
public:
|
||||
Win32MenuItem(Window* window, MenuItem* parent_item = NULL);
|
||||
virtual ~Win32MenuItem();
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
} // namespace win32
|
||||
} // namespace ui
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_UI_WIN32_WIN32_MENU_ITEM_H_
|
||||
371
src/xenia/ui/win32/win32_window.cc
Normal file
371
src/xenia/ui/win32/win32_window.cc
Normal file
@@ -0,0 +1,371 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/ui/win32/win32_window.h>
|
||||
|
||||
#include <dwmapi.h>
|
||||
#include <tpcshrd.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::ui;
|
||||
using namespace xe::ui::win32;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
static LRESULT CALLBACK Win32WindowWndProc(
|
||||
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
Win32Window* window = 0;
|
||||
if (message == WM_NCCREATE) {
|
||||
LPCREATESTRUCT create_struct = (LPCREATESTRUCT)lParam;
|
||||
window = (Win32Window*)create_struct->lpCreateParams;
|
||||
SetWindowLongPtr(hWnd, GWLP_USERDATA, (__int3264)(LONG_PTR)window);
|
||||
} else {
|
||||
window = (Win32Window*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||
}
|
||||
if (window) {
|
||||
return window->WndProc(hWnd, message, wParam, lParam);
|
||||
} else {
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
Win32Window::Win32Window(xe_run_loop_ref run_loop) :
|
||||
handle_(0), closing_(false),
|
||||
Window(run_loop) {
|
||||
}
|
||||
|
||||
Win32Window::~Win32Window() {
|
||||
if (handle_) {
|
||||
CloseWindow(handle_);
|
||||
handle_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int Win32Window::Initialize(const char* title, uint32_t width, uint32_t height) {
|
||||
int result = Window::Initialize(title, width, height);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
|
||||
WNDCLASSEX wcex;
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = 0;
|
||||
wcex.lpfnWndProc = Win32WindowWndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = hInstance;
|
||||
wcex.hIcon = NULL; // LoadIcon(hInstance, (LPCTSTR)IDI_TUTORIAL1);
|
||||
wcex.hIconSm = NULL; // LoadIcon(hInstance, (LPCTSTR)IDI_TUTORIAL1);
|
||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
||||
wcex.lpszMenuName = NULL;
|
||||
wcex.lpszClassName = L"XeniaWindowClass";
|
||||
if (!RegisterClassEx(&wcex)) {
|
||||
XELOGE("RegisterClassEx failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Setup initial size.
|
||||
DWORD window_style = WS_OVERLAPPEDWINDOW;
|
||||
DWORD window_ex_style = WS_EX_APPWINDOW;
|
||||
RECT rc = {
|
||||
0, 0,
|
||||
width, height
|
||||
};
|
||||
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
|
||||
|
||||
// Create window.
|
||||
handle_ = CreateWindowEx(
|
||||
window_ex_style,
|
||||
L"XeniaWindowClass",
|
||||
L"Xenia",
|
||||
window_style,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
rc.right - rc.left, rc.bottom - rc.top,
|
||||
NULL,
|
||||
NULL,
|
||||
hInstance,
|
||||
this);
|
||||
if (!handle_) {
|
||||
XELOGE("CreateWindow failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Disable flicks.
|
||||
ATOM atom = GlobalAddAtom(L"MicrosoftTabletPenServiceProperty");
|
||||
const DWORD_PTR dwHwndTabletProperty =
|
||||
TABLET_DISABLE_PRESSANDHOLD | // disables press and hold (right-click) gesture
|
||||
TABLET_DISABLE_PENTAPFEEDBACK | // disables UI feedback on pen up (waves)
|
||||
TABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen button down (circle)
|
||||
TABLET_DISABLE_FLICKS | // disables pen flicks (back, forward, drag down, drag up)
|
||||
TABLET_DISABLE_TOUCHSWITCH |
|
||||
TABLET_DISABLE_SMOOTHSCROLLING |
|
||||
TABLET_DISABLE_TOUCHUIFORCEON |
|
||||
TABLET_ENABLE_MULTITOUCHDATA;
|
||||
SetProp(
|
||||
handle_,
|
||||
L"MicrosoftTabletPenServiceProperty",
|
||||
reinterpret_cast<HANDLE>(dwHwndTabletProperty));
|
||||
GlobalDeleteAtom(atom);
|
||||
|
||||
// Enable DWM elevation.
|
||||
EnableMMCSS();
|
||||
|
||||
ShowWindow(handle_, SW_SHOWNORMAL);
|
||||
UpdateWindow(handle_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Win32Window::EnableMMCSS() {
|
||||
HMODULE hLibrary = LoadLibrary(L"DWMAPI.DLL");
|
||||
if (!hLibrary) {
|
||||
return;
|
||||
}
|
||||
|
||||
typedef HRESULT (__stdcall *PDwmEnableMMCSS)(BOOL);
|
||||
PDwmEnableMMCSS pDwmEnableMMCSS =
|
||||
(PDwmEnableMMCSS)GetProcAddress(
|
||||
hLibrary, "DwmEnableMMCSS");
|
||||
if (pDwmEnableMMCSS) {
|
||||
pDwmEnableMMCSS(TRUE);
|
||||
}
|
||||
|
||||
typedef HRESULT (__stdcall *PDwmSetPresentParameters)(HWND, DWM_PRESENT_PARAMETERS*);
|
||||
PDwmSetPresentParameters pDwmSetPresentParameters =
|
||||
(PDwmSetPresentParameters)GetProcAddress(
|
||||
hLibrary, "DwmSetPresentParameters");
|
||||
if (pDwmSetPresentParameters) {
|
||||
DWM_PRESENT_PARAMETERS pp;
|
||||
memset(&pp, 0, sizeof(DWM_PRESENT_PARAMETERS));
|
||||
pp.cbSize = sizeof(DWM_PRESENT_PARAMETERS);
|
||||
pp.fQueue = FALSE;
|
||||
pp.cBuffer = 2;
|
||||
pp.fUseSourceRate = FALSE;
|
||||
pp.cRefreshesPerFrame = 1;
|
||||
pp.eSampling = DWM_SOURCE_FRAME_SAMPLING_POINT;
|
||||
pDwmSetPresentParameters(handle_, &pp);
|
||||
}
|
||||
|
||||
FreeLibrary(hLibrary);
|
||||
}
|
||||
|
||||
bool Win32Window::set_title(const char* title) {
|
||||
if (!Window::set_title(title)) {
|
||||
return false;
|
||||
}
|
||||
XEIGNORE(SetWindowTextA(handle_, title));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Win32Window::set_cursor_visible(bool value) {
|
||||
if (!Window::set_cursor_visible(value)) {
|
||||
return false;
|
||||
}
|
||||
if (value) {
|
||||
ShowCursor(TRUE);
|
||||
SetCursor(NULL);
|
||||
} else {
|
||||
ShowCursor(FALSE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Win32Window::SetSize(uint32_t width, uint32_t height) {
|
||||
RECT rc = {
|
||||
0, 0,
|
||||
width, height
|
||||
};
|
||||
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
|
||||
// TODO(benvanik): center?
|
||||
MoveWindow(handle_, 0, 0, rc.right - rc.left, rc.bottom - rc.top, TRUE);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Win32Window::OnClose() {
|
||||
if (!closing_ && handle_) {
|
||||
closing_ = true;
|
||||
CloseWindow(handle_);
|
||||
handle_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool Win32Window::HandleMouse(UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
int32_t x = GET_X_LPARAM(lParam);
|
||||
int32_t y = GET_Y_LPARAM(lParam);
|
||||
if (message == WM_MOUSEWHEEL) {
|
||||
POINT pt = { x, y };
|
||||
ScreenToClient(handle_, &pt);
|
||||
x = pt.x;
|
||||
y = pt.y;
|
||||
}
|
||||
|
||||
MouseEvent::Button button = MouseEvent::MOUSE_BUTTON_NONE;
|
||||
int32_t dx = 0;
|
||||
int32_t dy = 0;
|
||||
switch (message) {
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
button = MouseEvent::MOUSE_BUTTON_LEFT;
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONUP:
|
||||
button = MouseEvent::MOUSE_BUTTON_RIGHT;
|
||||
break;
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_MBUTTONUP:
|
||||
button = MouseEvent::MOUSE_BUTTON_MIDDLE;
|
||||
break;
|
||||
case WM_XBUTTONDOWN:
|
||||
case WM_XBUTTONUP:
|
||||
switch (GET_XBUTTON_WPARAM(wParam)) {
|
||||
case XBUTTON1:
|
||||
button = MouseEvent::MOUSE_BUTTON_X1;
|
||||
break;
|
||||
case XBUTTON2:
|
||||
button = MouseEvent::MOUSE_BUTTON_X2;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
button = MouseEvent::MOUSE_BUTTON_NONE;
|
||||
break;
|
||||
case WM_MOUSEWHEEL:
|
||||
button = MouseEvent::MOUSE_BUTTON_NONE;
|
||||
dx = 0; // ?
|
||||
dy = GET_WHEEL_DELTA_WPARAM(wParam);
|
||||
break;
|
||||
default:
|
||||
// Double click/etc?
|
||||
return true;
|
||||
}
|
||||
|
||||
auto e = MouseEvent(this, button, x, y, dx, dy);
|
||||
switch (message) {
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_XBUTTONDOWN:
|
||||
mouse_down(e);
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_XBUTTONUP:
|
||||
mouse_up(e);
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
mouse_move(e);
|
||||
break;
|
||||
case WM_MOUSEWHEEL:
|
||||
mouse_wheel(e);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Win32Window::HandleKeyboard(UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
switch (message) {
|
||||
case WM_KEYDOWN:
|
||||
(byte)wParam;
|
||||
return true;
|
||||
case WM_KEYUP:
|
||||
(byte)wParam;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT Win32Window::WndProc(HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam) {
|
||||
if (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) {
|
||||
if (HandleMouse(message, wParam, lParam)) {
|
||||
return 0;
|
||||
} else {
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
} else if (message >= WM_KEYFIRST && message <= WM_KEYLAST) {
|
||||
if (HandleKeyboard(message, wParam, lParam)) {
|
||||
return 0;
|
||||
} else {
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
switch (message) {
|
||||
case WM_NCCREATE:
|
||||
handle_ = hWnd;
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
case WM_ACTIVATEAPP:
|
||||
if (wParam) {
|
||||
// Made active.
|
||||
OnShow();
|
||||
} else {
|
||||
// Made inactive.
|
||||
OnHide();
|
||||
}
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
case WM_CLOSE:
|
||||
closing_ = true;
|
||||
Close();
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
case WM_DESTROY:
|
||||
return 0;
|
||||
|
||||
case WM_PAINT:
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc = BeginPaint(hWnd, &ps);
|
||||
EndPaint(hWnd, &ps);
|
||||
}
|
||||
return 0;
|
||||
case WM_ERASEBKGND:
|
||||
return 0; // ignore
|
||||
case WM_DISPLAYCHANGE:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
|
||||
case WM_MOVE:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
case WM_SIZING:
|
||||
BeginResizing();
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
case WM_SIZE:
|
||||
{
|
||||
RECT frame;
|
||||
GetClientRect(handle_, &frame);
|
||||
OnResize(frame.right - frame.left, frame.bottom - frame.top);
|
||||
EndResizing();
|
||||
}
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
|
||||
case WM_TABLET_QUERYSYSTEMGESTURESTATUS:
|
||||
return
|
||||
TABLET_DISABLE_PRESSANDHOLD | // disables press and hold (right-click) gesture
|
||||
TABLET_DISABLE_PENTAPFEEDBACK | // disables UI feedback on pen up (waves)
|
||||
TABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen button down (circle)
|
||||
TABLET_DISABLE_FLICKS | // disables pen flicks (back, forward, drag down, drag up)
|
||||
TABLET_DISABLE_TOUCHSWITCH |
|
||||
TABLET_DISABLE_SMOOTHSCROLLING |
|
||||
TABLET_DISABLE_TOUCHUIFORCEON |
|
||||
TABLET_ENABLE_MULTITOUCHDATA;
|
||||
default:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
}
|
||||
55
src/xenia/ui/win32/win32_window.h
Normal file
55
src/xenia/ui/win32/win32_window.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_UI_WIN32_WIN32_WINDOW_H_
|
||||
#define XENIA_UI_WIN32_WIN32_WINDOW_H_
|
||||
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/ui/window.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace ui {
|
||||
namespace win32 {
|
||||
|
||||
|
||||
class Win32Window : public Window {
|
||||
public:
|
||||
Win32Window(xe_run_loop_ref run_loop);
|
||||
virtual ~Win32Window();
|
||||
|
||||
virtual int Initialize(const char* title, uint32_t width, uint32_t height);
|
||||
|
||||
virtual bool set_title(const char* title);
|
||||
virtual bool set_cursor_visible(bool value);
|
||||
HWND handle() const { return handle_; }
|
||||
|
||||
LRESULT WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
protected:
|
||||
virtual bool SetSize(uint32_t width, uint32_t height);
|
||||
virtual void OnClose();
|
||||
|
||||
private:
|
||||
void EnableMMCSS();
|
||||
bool HandleMouse(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
bool HandleKeyboard(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
HWND handle_;
|
||||
bool closing_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace win32
|
||||
} // namespace ui
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_UI_WIN32_WIN32_WINDOW_H_
|
||||
120
src/xenia/ui/window.cc
Normal file
120
src/xenia/ui/window.cc
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/ui/window.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::ui;
|
||||
|
||||
|
||||
Window::Window(xe_run_loop_ref run_loop) :
|
||||
title_(0), is_visible_(true), is_cursor_visible_(true),
|
||||
width_(0), height_(0) {
|
||||
run_loop_ = xe_run_loop_retain(run_loop);
|
||||
}
|
||||
|
||||
Window::~Window() {
|
||||
if (title_) {
|
||||
xe_free(title_);
|
||||
}
|
||||
xe_run_loop_release(run_loop_);
|
||||
}
|
||||
|
||||
int Window::Initialize(const char* title, uint32_t width, uint32_t height) {
|
||||
title_ = xestrdupa(title);
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Window::set_title(const char* title) {
|
||||
if (title == title_) {
|
||||
return false;
|
||||
}
|
||||
if (title_) {
|
||||
xe_free(title_);
|
||||
}
|
||||
title_ = xestrdupa(title);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Window::set_cursor_visible(bool value) {
|
||||
if (value == is_cursor_visible_) {
|
||||
return false;
|
||||
}
|
||||
is_cursor_visible_ = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Window::OnShow() {
|
||||
if (is_visible_) {
|
||||
return;
|
||||
}
|
||||
is_visible_ = true;
|
||||
auto e = UIEvent(this);
|
||||
shown(e);
|
||||
}
|
||||
|
||||
void Window::OnHide() {
|
||||
if (!is_visible_) {
|
||||
return;
|
||||
}
|
||||
is_visible_ = false;
|
||||
auto e = UIEvent(this);
|
||||
hidden(e);
|
||||
}
|
||||
|
||||
void Window::Resize(uint32_t width, uint32_t height) {
|
||||
BeginResizing();
|
||||
SetSize(width, height);
|
||||
OnResize(width, height); // redundant?
|
||||
EndResizing();
|
||||
}
|
||||
|
||||
void Window::BeginResizing() {
|
||||
if (resizing_) {
|
||||
return;
|
||||
}
|
||||
resizing_ = true;
|
||||
auto e = UIEvent(this);
|
||||
resizing(e);
|
||||
}
|
||||
|
||||
bool Window::OnResize(uint32_t width, uint32_t height) {
|
||||
if (!resizing_) {
|
||||
BeginResizing();
|
||||
}
|
||||
if (width == width_ && height == height_) {
|
||||
return false;
|
||||
}
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Window::EndResizing() {
|
||||
XEASSERT(resizing_);
|
||||
resizing_ = false;
|
||||
auto e = UIEvent(this);
|
||||
resized(e);
|
||||
}
|
||||
|
||||
void Window::Close() {
|
||||
auto e = UIEvent(this);
|
||||
closing(e);
|
||||
|
||||
OnClose();
|
||||
|
||||
e = UIEvent(this);
|
||||
closed(e);
|
||||
}
|
||||
|
||||
void Window::OnClose() {
|
||||
}
|
||||
82
src/xenia/ui/window.h
Normal file
82
src/xenia/ui/window.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_UI_WINDOW_H_
|
||||
#define XENIA_UI_WINDOW_H_
|
||||
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <alloy/delegate.h>
|
||||
#include <xenia/ui/ui_event.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace ui {
|
||||
|
||||
|
||||
class Window {
|
||||
public:
|
||||
Window(xe_run_loop_ref run_loop);
|
||||
virtual ~Window();
|
||||
|
||||
virtual int Initialize(const char* title, uint32_t width, uint32_t height);
|
||||
|
||||
xe_run_loop_ref run_loop() const { return run_loop_; }
|
||||
|
||||
const char* title() const { return title_; }
|
||||
virtual bool set_title(const char* title);
|
||||
bool is_visible() const { return is_visible_; }
|
||||
bool is_cursor_visible() const { return is_cursor_visible_; }
|
||||
virtual bool set_cursor_visible(bool value);
|
||||
uint32_t width() const { return width_; }
|
||||
uint32_t height() const { return height_; }
|
||||
void Resize(uint32_t width, uint32_t height);
|
||||
|
||||
void Close();
|
||||
|
||||
public:
|
||||
alloy::Delegate<UIEvent> shown;
|
||||
alloy::Delegate<UIEvent> hidden;
|
||||
alloy::Delegate<UIEvent> resizing;
|
||||
alloy::Delegate<UIEvent> resized;
|
||||
alloy::Delegate<UIEvent> closing;
|
||||
alloy::Delegate<UIEvent> closed;
|
||||
|
||||
alloy::Delegate<MouseEvent> mouse_down;
|
||||
alloy::Delegate<MouseEvent> mouse_move;
|
||||
alloy::Delegate<MouseEvent> mouse_up;
|
||||
alloy::Delegate<MouseEvent> mouse_wheel;
|
||||
|
||||
protected:
|
||||
void OnShow();
|
||||
void OnHide();
|
||||
|
||||
void BeginResizing();
|
||||
virtual bool OnResize(uint32_t width, uint32_t height);
|
||||
void EndResizing();
|
||||
virtual bool SetSize(uint32_t width, uint32_t height) = 0;
|
||||
|
||||
virtual void OnClose();
|
||||
|
||||
private:
|
||||
xe_run_loop_ref run_loop_;
|
||||
char* title_;
|
||||
bool is_visible_;
|
||||
bool is_cursor_visible_;
|
||||
bool resizing_;
|
||||
uint32_t width_;
|
||||
uint32_t height_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace ui
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_UI_WINDOW_H_
|
||||
Reference in New Issue
Block a user