Encapsulated platform dependent part of studio in an interface - closes #593
This commit is contained in:
parent
db8475909d
commit
202dd3d339
9 changed files with 675 additions and 327 deletions
|
@ -27,8 +27,6 @@
|
|||
#include "renderer/texture_manager.h"
|
||||
#include "universe/universe.h"
|
||||
#include <bgfx/bgfx.h>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
|
@ -198,10 +196,10 @@ struct RendererImpl : public Renderer
|
|||
, m_frame_allocator(m_allocator, 10 * 1024 * 1024)
|
||||
{
|
||||
bgfx::PlatformData d;
|
||||
if (s_hwnd)
|
||||
if (s_platform_data)
|
||||
{
|
||||
memset(&d, 0, sizeof(d));
|
||||
d.nwh = s_hwnd;
|
||||
d.nwh = s_platform_data;
|
||||
bgfx::setPlatformData(d);
|
||||
}
|
||||
bgfx::init(bgfx::RendererType::Count, 0, 0, &m_callback_stub/*, &m_bgfx_allocator*/);
|
||||
|
@ -569,16 +567,16 @@ struct RendererImpl : public Renderer
|
|||
int m_view_counter;
|
||||
BGFXAllocator m_bgfx_allocator;
|
||||
|
||||
static HWND s_hwnd;
|
||||
static void* s_platform_data;
|
||||
};
|
||||
|
||||
|
||||
HWND RendererImpl::s_hwnd = nullptr;
|
||||
void* RendererImpl::s_platform_data = nullptr;
|
||||
|
||||
|
||||
void Renderer::setInitData(void* data)
|
||||
{
|
||||
RendererImpl::s_hwnd = (HWND)data;
|
||||
RendererImpl::s_platform_data = data;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "core/resource_manager.h"
|
||||
#include "engine/engine.h"
|
||||
#include "ocornut-imgui/imgui.h"
|
||||
#include "platform_interface.h"
|
||||
#include "renderer/frame_buffer.h"
|
||||
#include "renderer/pipeline.h"
|
||||
#include "renderer/render_scene.h"
|
||||
|
@ -18,7 +19,6 @@ GameView::GameView()
|
|||
, m_is_mouse_captured(false)
|
||||
, m_editor(nullptr)
|
||||
, m_is_mouse_hovering_window(false)
|
||||
, m_hwnd(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -41,9 +41,8 @@ void GameView::onUniverseDestroyed()
|
|||
}
|
||||
|
||||
|
||||
void GameView::init(HWND hwnd, Lumix::WorldEditor& editor)
|
||||
void GameView::init(Lumix::WorldEditor& editor)
|
||||
{
|
||||
m_hwnd = hwnd;
|
||||
m_editor = &editor;
|
||||
auto& engine = editor.getEngine();
|
||||
auto* pipeline_manager = engine.getResourceManager().get(Lumix::ResourceManager::PIPELINE);
|
||||
|
@ -79,8 +78,8 @@ void GameView::captureMouse(bool capture)
|
|||
{
|
||||
m_is_mouse_captured = capture;
|
||||
m_editor->getEngine().getInputSystem().enable(m_is_mouse_captured);
|
||||
ShowCursor(!m_is_mouse_captured);
|
||||
if (!m_is_mouse_captured) ClipCursor(NULL);
|
||||
PlatformInterface::showCursor(!m_is_mouse_captured);
|
||||
if (!m_is_mouse_captured) PlatformInterface::unclipCursor();
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,9 +91,9 @@ void GameView::onGui()
|
|||
|
||||
auto& io = ImGui::GetIO();
|
||||
|
||||
HWND foreground_win = GetForegroundWindow();
|
||||
if (m_is_mouse_captured &&
|
||||
(io.KeysDown[VK_ESCAPE] || !m_editor->isGameMode() || foreground_win != m_hwnd))
|
||||
bool is_foreground_win = PlatformInterface::isForegroundWindow();
|
||||
if (m_is_mouse_captured && (io.KeysDown[ImGui::GetKeyIndex(ImGuiKey_Escape)] ||
|
||||
!m_editor->isGameMode() || !is_foreground_win))
|
||||
{
|
||||
captureMouse(false);
|
||||
}
|
||||
|
@ -122,21 +121,13 @@ void GameView::onGui()
|
|||
|
||||
if (m_is_mouse_captured)
|
||||
{
|
||||
POINT min;
|
||||
POINT max;
|
||||
min.x = LONG(content_min.x);
|
||||
min.y = LONG(content_min.y);
|
||||
max.x = LONG(content_max.x);
|
||||
max.y = LONG(content_max.y);
|
||||
ClientToScreen(m_hwnd, &min);
|
||||
ClientToScreen(m_hwnd, &max);
|
||||
RECT rect;
|
||||
rect.left = min.x;
|
||||
rect.right = max.x;
|
||||
rect.top = min.y;
|
||||
rect.bottom = max.y;
|
||||
ClipCursor(&rect);
|
||||
if (io.KeysDown[VK_ESCAPE] || !m_editor->isGameMode()) captureMouse(false);
|
||||
PlatformInterface::clipCursor(
|
||||
content_min.x, content_min.y, content_max.x, content_max.y);
|
||||
|
||||
if (io.KeysDown[ImGui::GetKeyIndex(ImGuiKey_Escape)] || !m_editor->isGameMode())
|
||||
{
|
||||
captureMouse(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::IsMouseHoveringRect(content_min, content_max) && m_is_mouse_hovering_window &&
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
|
||||
#include "editor/world_editor.h"
|
||||
#include <bgfx/bgfx.h>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
|
||||
struct PlatformData;
|
||||
|
||||
|
||||
namespace Lumix
|
||||
|
@ -21,7 +22,7 @@ public:
|
|||
GameView();
|
||||
~GameView();
|
||||
|
||||
void init(HWND hwnd, Lumix::WorldEditor& editor);
|
||||
void init(Lumix::WorldEditor& editor);
|
||||
void shutdown();
|
||||
void onGui();
|
||||
void setScene(Lumix::RenderScene* scene);
|
||||
|
@ -42,5 +43,4 @@ private:
|
|||
bgfx::TextureHandle m_texture_handle;
|
||||
Lumix::WorldEditor* m_editor;
|
||||
bool m_is_mouse_hovering_window;
|
||||
HWND m_hwnd;
|
||||
};
|
|
@ -24,6 +24,7 @@
|
|||
#include "log_ui.h"
|
||||
#include "metadata.h"
|
||||
#include "ocornut-imgui/imgui.h"
|
||||
#include "platform_interface.h"
|
||||
#include "profiler_ui.h"
|
||||
#include "property_grid.h"
|
||||
#include "renderer/frame_buffer.h"
|
||||
|
@ -39,16 +40,12 @@
|
|||
#include "utils.h"
|
||||
|
||||
#include <bgfx/bgfx.h>
|
||||
#include <cstdio>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
|
||||
// http://prideout.net/blog/?p=36
|
||||
|
||||
|
||||
void imGuiCallback(ImDrawData* draw_data);
|
||||
LRESULT WINAPI msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
class StudioApp
|
||||
|
@ -70,7 +67,6 @@ public:
|
|||
, m_metadata(m_allocator)
|
||||
, m_gui_pipeline(nullptr)
|
||||
, m_is_welcome_screen_opened(true)
|
||||
, m_is_mouse_tracked(false)
|
||||
{
|
||||
m_entity_list_search[0] = '\0';
|
||||
m_template_name[0] = '\0';
|
||||
|
@ -119,10 +115,8 @@ public:
|
|||
{
|
||||
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings;
|
||||
RECT client_rect;
|
||||
GetClientRect(m_hwnd, &client_rect);
|
||||
ImVec2 size(float(client_rect.right - client_rect.left),
|
||||
float(client_rect.bottom - client_rect.top));
|
||||
ImVec2 size((float)PlatformInterface::getWindowWidth(),
|
||||
(float)PlatformInterface::getWindowHeight());
|
||||
if (ImGui::Begin("Welcome", nullptr, size, -1, flags))
|
||||
{
|
||||
ImGui::Text("Welcome to Lumix Studio");
|
||||
|
@ -210,18 +204,18 @@ public:
|
|||
if (!m_gui_pipeline_source->isReady()) return;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
RECT rect;
|
||||
GetClientRect(m_hwnd, &rect);
|
||||
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));
|
||||
io.DisplaySize = ImVec2((float)PlatformInterface::getWindowWidth(),
|
||||
(float)PlatformInterface::getWindowHeight());
|
||||
io.DeltaTime = m_engine->getLastTimeDelta();
|
||||
io.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
|
||||
io.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0;
|
||||
io.KeyAlt = (GetKeyState(VK_MENU) & 0x8000) != 0;
|
||||
io.KeysDown[VK_MENU] = io.KeyAlt;
|
||||
io.KeysDown[VK_SHIFT] = io.KeyShift;
|
||||
io.KeysDown[VK_CONTROL] = io.KeyCtrl;
|
||||
io.KeyCtrl = PlatformInterface::isPressed((int)PlatformInterface::Keys::CONTROL);
|
||||
io.KeyShift = PlatformInterface::isPressed((int)PlatformInterface::Keys::SHIFT);
|
||||
io.KeyAlt = PlatformInterface::isPressed((int)PlatformInterface::Keys::ALT);
|
||||
io.KeysDown[(int)PlatformInterface::Keys::ALT] = io.KeyAlt;
|
||||
io.KeysDown[(int)PlatformInterface::Keys::SHIFT] = io.KeyShift;
|
||||
io.KeysDown[(int)PlatformInterface::Keys::CONTROL] = io.KeyCtrl;
|
||||
|
||||
SetCursor(io.MouseDrawCursor ? NULL : LoadCursor(NULL, IDC_ARROW));
|
||||
PlatformInterface::setCursor(io.MouseDrawCursor ? PlatformInterface::Cursor::NONE
|
||||
: PlatformInterface::Cursor::DEFAULT);
|
||||
|
||||
ImGui::NewFrame();
|
||||
|
||||
|
@ -255,7 +249,7 @@ public:
|
|||
char tmp[100];
|
||||
Lumix::copyString(tmp, "Lumix Studio - ");
|
||||
Lumix::catString(tmp, title);
|
||||
SetWindowTextA(m_hwnd, tmp);
|
||||
PlatformInterface::setWindowTitle(tmp);
|
||||
}
|
||||
|
||||
|
||||
|
@ -265,7 +259,7 @@ public:
|
|||
for (int i = 0; i < Lumix::lengthOf(action.shortcut); ++i)
|
||||
{
|
||||
char str[30];
|
||||
getKeyName(action.shortcut[i], str, Lumix::lengthOf(str));
|
||||
PlatformInterface::getKeyName(action.shortcut[i], str, Lumix::lengthOf(str));
|
||||
if (str[0] == 0) return;
|
||||
if (i > 0) Lumix::catString(buf, max_size, " - ");
|
||||
Lumix::catString(buf, max_size, str);
|
||||
|
@ -316,7 +310,7 @@ public:
|
|||
}
|
||||
|
||||
|
||||
void exit() { PostQuitMessage(0); }
|
||||
void exit() { m_finished = true; }
|
||||
|
||||
void newUniverse()
|
||||
{
|
||||
|
@ -709,7 +703,7 @@ public:
|
|||
m_gui_pipeline_source = nullptr;
|
||||
m_editor = nullptr;
|
||||
|
||||
UnregisterClassA("lmxa", m_instance);
|
||||
PlatformInterface::shutdown();
|
||||
}
|
||||
|
||||
|
||||
|
@ -726,20 +720,8 @@ public:
|
|||
}
|
||||
|
||||
|
||||
void trackMouse()
|
||||
{
|
||||
TRACKMOUSEEVENT track_event;
|
||||
track_event.cbSize = sizeof(TRACKMOUSEEVENT);
|
||||
track_event.dwFlags = TME_LEAVE;
|
||||
track_event.hwndTrack = m_hwnd;
|
||||
m_is_mouse_tracked = TrackMouseEvent(&track_event) == TRUE;
|
||||
}
|
||||
|
||||
|
||||
void initIMGUI()
|
||||
{
|
||||
trackMouse();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts->AddFontFromFileTTF("editor/VeraMono.ttf", 13);
|
||||
|
||||
|
@ -749,19 +731,19 @@ public:
|
|||
.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
|
||||
.end();
|
||||
|
||||
io.KeyMap[ImGuiKey_Tab] = VK_TAB;
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN;
|
||||
io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR;
|
||||
io.KeyMap[ImGuiKey_PageDown] = VK_NEXT;
|
||||
io.KeyMap[ImGuiKey_Home] = VK_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = VK_END;
|
||||
io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
|
||||
io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_Tab] = (int)PlatformInterface::Keys::TAB;
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = (int)PlatformInterface::Keys::LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = (int)PlatformInterface::Keys::RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = (int)PlatformInterface::Keys::UP;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = (int)PlatformInterface::Keys::DOWN;
|
||||
io.KeyMap[ImGuiKey_PageUp] = (int)PlatformInterface::Keys::PAGE_UP;
|
||||
io.KeyMap[ImGuiKey_PageDown] = (int)PlatformInterface::Keys::PAGE_DOWN;
|
||||
io.KeyMap[ImGuiKey_Home] = (int)PlatformInterface::Keys::HOME;
|
||||
io.KeyMap[ImGuiKey_End] = (int)PlatformInterface::Keys::END;
|
||||
io.KeyMap[ImGuiKey_Delete] = (int)PlatformInterface::Keys::DEL;
|
||||
io.KeyMap[ImGuiKey_Backspace] = (int)PlatformInterface::Keys::BACKSPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = (int)PlatformInterface::Keys::ENTER;
|
||||
io.KeyMap[ImGuiKey_Escape] = (int)PlatformInterface::Keys::ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = 'A';
|
||||
io.KeyMap[ImGuiKey_C] = 'C';
|
||||
io.KeyMap[ImGuiKey_V] = 'V';
|
||||
|
@ -770,7 +752,6 @@ public:
|
|||
io.KeyMap[ImGuiKey_Z] = 'Z';
|
||||
|
||||
io.RenderDrawListsFn = ::imGuiCallback;
|
||||
io.ImeWindowHandle = m_hwnd;
|
||||
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
|
@ -819,16 +800,14 @@ public:
|
|||
|
||||
if (m_settings.m_is_maximized)
|
||||
{
|
||||
ShowWindow(m_hwnd, SW_MAXIMIZE);
|
||||
PlatformInterface::maximizeWindow();
|
||||
}
|
||||
else if (m_settings.m_window.w > 0)
|
||||
{
|
||||
MoveWindow(m_hwnd,
|
||||
m_settings.m_window.x,
|
||||
PlatformInterface::moveWindow(m_settings.m_window.x,
|
||||
m_settings.m_window.y,
|
||||
m_settings.m_window.w,
|
||||
m_settings.m_window.h,
|
||||
FALSE);
|
||||
m_settings.m_window.h);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -836,21 +815,31 @@ public:
|
|||
void addActions()
|
||||
{
|
||||
addAction<&StudioApp::newUniverse>("New", "newUniverse");
|
||||
addAction<&StudioApp::save>("Save", "save", VK_CONTROL, 'S', -1);
|
||||
addAction<&StudioApp::saveAs>("Save As", "saveAs", VK_CONTROL, VK_SHIFT, 'S');
|
||||
addAction<&StudioApp::exit>("Exit", "exit", VK_CONTROL, 'X', -1);
|
||||
addAction<&StudioApp::save>("Save", "save", (int)PlatformInterface::Keys::CONTROL, 'S', -1);
|
||||
addAction<&StudioApp::saveAs>("Save As",
|
||||
"saveAs",
|
||||
(int)PlatformInterface::Keys::CONTROL,
|
||||
(int)PlatformInterface::Keys::SHIFT,
|
||||
'S');
|
||||
addAction<&StudioApp::exit>("Exit", "exit", (int)PlatformInterface::Keys::CONTROL, 'X', -1);
|
||||
|
||||
addAction<&StudioApp::redo>("Redo", "redo", VK_CONTROL, VK_SHIFT, 'Z');
|
||||
addAction<&StudioApp::undo>("Undo", "undo", VK_CONTROL, 'Z', -1);
|
||||
addAction<&StudioApp::copy>("Copy", "copy", VK_CONTROL, 'C', -1);
|
||||
addAction<&StudioApp::paste>("Paste", "paste", VK_CONTROL, 'V', -1);
|
||||
addAction<&StudioApp::redo>("Redo",
|
||||
"redo",
|
||||
(int)PlatformInterface::Keys::CONTROL,
|
||||
(int)PlatformInterface::Keys::SHIFT,
|
||||
'Z');
|
||||
addAction<&StudioApp::undo>("Undo", "undo", (int)PlatformInterface::Keys::CONTROL, 'Z', -1);
|
||||
addAction<&StudioApp::copy>("Copy", "copy", (int)PlatformInterface::Keys::CONTROL, 'C', -1);
|
||||
addAction<&StudioApp::paste>(
|
||||
"Paste", "paste", (int)PlatformInterface::Keys::CONTROL, 'V', -1);
|
||||
addAction<&StudioApp::toggleOrbitCamera>("Orbit camera", "orbitCamera");
|
||||
addAction<&StudioApp::toggleGizmoMode>("Translate/Rotate", "toggleGizmoMode");
|
||||
addAction<&StudioApp::togglePivotMode>("Center/Pivot", "togglePivotMode");
|
||||
addAction<&StudioApp::toggleCoordSystem>("Local/Global", "toggleCoordSystem");
|
||||
|
||||
addAction<&StudioApp::createEntity>("Create", "createEntity");
|
||||
addAction<&StudioApp::destroyEntity>("Destroy", "destroyEntity", VK_DELETE, -1, -1);
|
||||
addAction<&StudioApp::destroyEntity>(
|
||||
"Destroy", "destroyEntity", (int)PlatformInterface::Keys::DEL, -1, -1);
|
||||
addAction<&StudioApp::showEntities>("Show", "showEntities");
|
||||
addAction<&StudioApp::hideEntities>("Hide", "hideEntities");
|
||||
|
||||
|
@ -889,22 +878,6 @@ public:
|
|||
}
|
||||
|
||||
|
||||
void processSystemEvents()
|
||||
{
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
{
|
||||
m_finished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void run()
|
||||
{
|
||||
Lumix::Timer* timer = Lumix::Timer::create(m_allocator);
|
||||
|
@ -916,7 +889,7 @@ public:
|
|||
float frame_time;
|
||||
{
|
||||
PROFILE_BLOCK("tick");
|
||||
processSystemEvents();
|
||||
m_finished = !PlatformInterface::processSystemEvents();
|
||||
update();
|
||||
frame_time = timer->tick();
|
||||
}
|
||||
|
@ -951,38 +924,119 @@ public:
|
|||
}
|
||||
|
||||
|
||||
void createWindow(HINSTANCE hInst)
|
||||
struct SystemEventHandler : public PlatformInterface::SystemEventHandler
|
||||
{
|
||||
WNDCLASSEX wnd;
|
||||
memset(&wnd, 0, sizeof(wnd));
|
||||
wnd.cbSize = sizeof(wnd);
|
||||
wnd.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wnd.lpfnWndProc = msgProc;
|
||||
wnd.hInstance = hInst;
|
||||
wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wnd.lpszClassName = "lmxa";
|
||||
wnd.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||||
auto x = RegisterClassExA(&wnd);
|
||||
m_hwnd = CreateWindowA(
|
||||
"lmxa", "lmxa", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 800, 600, NULL, NULL, hInst, 0);
|
||||
ASSERT(m_hwnd);
|
||||
SetWindowTextA(m_hwnd, "Lumix Studio");
|
||||
}
|
||||
void onWindowTransformed(int x, int y, int w, int h) override
|
||||
{
|
||||
m_app->onWindowTransformed(x, y, w, h);
|
||||
}
|
||||
|
||||
|
||||
void onMouseLeftWindow() override { m_app->clearInputs(); }
|
||||
|
||||
|
||||
void init(HINSTANCE hInst)
|
||||
void onMouseMove(int x, int y, int rel_x, int rel_y) override
|
||||
{
|
||||
m_mouse_x = x;
|
||||
m_mouse_y = y;
|
||||
auto& input_system = m_app->m_editor->getEngine().getInputSystem();
|
||||
input_system.injectMouseXMove(float(rel_x));
|
||||
input_system.injectMouseYMove(float(rel_y));
|
||||
|
||||
if (m_app->m_gameview.isMouseCaptured()) return;
|
||||
|
||||
m_app->m_sceneview.onMouseMove(x, y, rel_x, rel_y);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MousePos.x = (float)x;
|
||||
io.MousePos.y = (float)y;
|
||||
}
|
||||
|
||||
|
||||
void onMouseWheel(int amount) override
|
||||
{
|
||||
ImGui::GetIO().MouseWheel = amount / 600.0f;
|
||||
}
|
||||
|
||||
|
||||
void onMouseButtonDown(MouseButton button) override
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case PlatformInterface::SystemEventHandler::MouseButton::LEFT:
|
||||
m_app->m_editor->setAdditiveSelection(ImGui::GetIO().KeyCtrl);
|
||||
if (!m_app->m_sceneview.onMouseDown(
|
||||
m_mouse_x, m_mouse_y, Lumix::MouseButton::LEFT) &&
|
||||
!m_app->m_gameview.isMouseCaptured())
|
||||
{
|
||||
ImGui::GetIO().MouseDown[0] = true;
|
||||
}
|
||||
break;
|
||||
case PlatformInterface::SystemEventHandler::MouseButton::RIGHT:
|
||||
if (!m_app->m_sceneview.onMouseDown(
|
||||
m_mouse_x, m_mouse_y, Lumix::MouseButton::RIGHT) &&
|
||||
!m_app->m_gameview.isMouseCaptured())
|
||||
{
|
||||
ImGui::GetIO().MouseDown[1] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void onMouseButtonUp(MouseButton button) override
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case PlatformInterface::SystemEventHandler::MouseButton::LEFT:
|
||||
m_app->m_sceneview.onMouseUp(Lumix::MouseButton::LEFT);
|
||||
ImGui::GetIO().MouseDown[0] = false;
|
||||
break;
|
||||
case PlatformInterface::SystemEventHandler::MouseButton::RIGHT:
|
||||
m_app->m_sceneview.onMouseUp(Lumix::MouseButton::RIGHT);
|
||||
ImGui::GetIO().MouseDown[1] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void onKeyDown(int key) override
|
||||
{
|
||||
ImGui::GetIO().KeysDown[key] = true;
|
||||
m_app->checkShortcuts();
|
||||
}
|
||||
|
||||
|
||||
void onKeyUp(int key) override
|
||||
{
|
||||
ImGui::GetIO().KeysDown[key] = false;
|
||||
}
|
||||
|
||||
|
||||
void onChar(int key)
|
||||
{
|
||||
ImGui::GetIO().AddInputCharacter(key);
|
||||
}
|
||||
|
||||
|
||||
int m_mouse_x;
|
||||
int m_mouse_y;
|
||||
StudioApp* m_app;
|
||||
};
|
||||
|
||||
|
||||
SystemEventHandler m_handler;
|
||||
|
||||
|
||||
void init()
|
||||
{
|
||||
checkWorkingDirector();
|
||||
m_handler.m_app = this;
|
||||
PlatformInterface::createWindow(&m_handler);
|
||||
|
||||
m_instance = hInst;
|
||||
createWindow(hInst);
|
||||
|
||||
Lumix::Renderer::setInitData(m_hwnd);
|
||||
m_engine = Lumix::Engine::create(nullptr, m_allocator);
|
||||
char current_dir[MAX_PATH];
|
||||
GetCurrentDirectory(sizeof(current_dir), current_dir);
|
||||
char current_dir[Lumix::MAX_PATH_LENGTH];
|
||||
PlatformInterface::getCurrentDirectory(current_dir, Lumix::lengthOf(current_dir));
|
||||
m_editor = Lumix::WorldEditor::create(current_dir, *m_engine, m_allocator);
|
||||
loadUserPlugins();
|
||||
|
||||
|
@ -1009,28 +1063,20 @@ public:
|
|||
Lumix::PipelineInstance::create(*m_gui_pipeline_source, m_engine->getAllocator());
|
||||
|
||||
m_sceneview.init(*m_editor, m_actions);
|
||||
m_gameview.init(m_hwnd, *m_editor);
|
||||
m_gameview.init(*m_editor);
|
||||
|
||||
RECT rect;
|
||||
GetClientRect(m_hwnd, &rect);
|
||||
m_gui_pipeline->setViewport(0, 0, rect.right, rect.bottom);
|
||||
int w = PlatformInterface::getWindowWidth();
|
||||
int h = PlatformInterface::getWindowHeight();
|
||||
m_gui_pipeline->setViewport(0, 0, w, h);
|
||||
auto& plugin_manager = m_editor->getEngine().getPluginManager();
|
||||
auto* renderer = static_cast<Lumix::Renderer*>(plugin_manager.getPlugin("renderer"));
|
||||
renderer->resize(rect.right, rect.bottom);
|
||||
renderer->resize(w, h);
|
||||
onUniverseCreated();
|
||||
initIMGUI();
|
||||
|
||||
loadSettings();
|
||||
|
||||
if (!m_metadata.load()) Lumix::g_log_info.log("studio") << "Could not load metadata";
|
||||
timeBeginPeriod(1);
|
||||
|
||||
RAWINPUTDEVICE Rid;
|
||||
Rid.usUsagePage = 0x01;
|
||||
Rid.usUsage = 0x02;
|
||||
Rid.dwFlags = 0;
|
||||
Rid.hwndTarget = 0;
|
||||
RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1057,146 +1103,25 @@ public:
|
|||
}
|
||||
|
||||
|
||||
void onWindowTransformed()
|
||||
void onWindowTransformed(int x, int y, int width, int height)
|
||||
{
|
||||
RECT rect;
|
||||
GetWindowRect(m_hwnd, &rect);
|
||||
m_settings.m_window.x = rect.left;
|
||||
m_settings.m_window.y = rect.top;
|
||||
m_settings.m_window.w = rect.right - rect.left;
|
||||
m_settings.m_window.h = rect.bottom - rect.top;
|
||||
|
||||
WINDOWPLACEMENT wndpl;
|
||||
wndpl.length = sizeof(wndpl);
|
||||
if (GetWindowPlacement(m_hwnd, &wndpl))
|
||||
{
|
||||
m_settings.m_is_maximized = wndpl.showCmd == SW_MAXIMIZE;
|
||||
}
|
||||
}
|
||||
m_settings.m_window.x = x;
|
||||
m_settings.m_window.y = y;
|
||||
m_settings.m_window.w = width;
|
||||
m_settings.m_window.h = height;
|
||||
|
||||
m_settings.m_is_maximized = PlatformInterface::isMaximized();
|
||||
|
||||
void handleRawInput(LPARAM lParam)
|
||||
{
|
||||
UINT dwSize;
|
||||
char data[sizeof(RAWINPUT) * 10];
|
||||
|
||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
|
||||
if (dwSize > sizeof(data)) return;
|
||||
|
||||
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &dwSize, sizeof(RAWINPUTHEADER)) !=
|
||||
dwSize) return;
|
||||
|
||||
RAWINPUT* raw = (RAWINPUT*)data;
|
||||
if (raw->header.dwType == RIM_TYPEMOUSE &&
|
||||
raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE)
|
||||
{
|
||||
m_editor->getEngine().getInputSystem().injectMouseXMove(float(raw->data.mouse.lLastX));
|
||||
m_editor->getEngine().getInputSystem().injectMouseYMove(float(raw->data.mouse.lLastY));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LRESULT windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
int x = LOWORD(lParam);
|
||||
int y = HIWORD(lParam);
|
||||
static int old_x = x;
|
||||
static int old_y = y;
|
||||
if (!m_gui_pipeline)
|
||||
{
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INPUT: handleRawInput(lParam); break;
|
||||
case WM_CLOSE: PostQuitMessage(0); break;
|
||||
case WM_MOVE: onWindowTransformed(); break;
|
||||
case WM_SIZE:
|
||||
{
|
||||
onWindowTransformed();
|
||||
|
||||
uint32_t width = ((int)(short)LOWORD(lParam));
|
||||
uint32_t height = ((int)(short)HIWORD(lParam));
|
||||
|
||||
m_gui_pipeline->setViewport(0, 0, width, height);
|
||||
auto& plugin_manager = m_editor->getEngine().getPluginManager();
|
||||
auto* renderer =
|
||||
static_cast<Lumix::Renderer*>(plugin_manager.getPlugin("renderer"));
|
||||
renderer->resize(width, height);
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEWHEEL:
|
||||
ImGui::GetIO().MouseWheel = GET_WHEEL_DELTA_WPARAM(wParam) / 600.0f;
|
||||
break;
|
||||
case WM_ERASEBKGND: return 1;
|
||||
case WM_LBUTTONUP:
|
||||
m_sceneview.onMouseUp(Lumix::MouseButton::LEFT);
|
||||
ImGui::GetIO().MouseDown[0] = false;
|
||||
break;
|
||||
case WM_LBUTTONDOWN:
|
||||
m_editor->setAdditiveSelection(ImGui::GetIO().KeyCtrl);
|
||||
if (!m_sceneview.onMouseDown(old_x, old_y, Lumix::MouseButton::LEFT) &&
|
||||
!m_gameview.isMouseCaptured())
|
||||
{
|
||||
ImGui::GetIO().MouseDown[0] = true;
|
||||
}
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
if (!m_sceneview.onMouseDown(old_x, old_y, Lumix::MouseButton::RIGHT) &&
|
||||
!m_gameview.isMouseCaptured())
|
||||
{
|
||||
ImGui::GetIO().MouseDown[1] = true;
|
||||
}
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
m_sceneview.onMouseUp(Lumix::MouseButton::RIGHT);
|
||||
ImGui::GetIO().MouseDown[1] = false;
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
if (!m_is_mouse_tracked) trackMouse();
|
||||
|
||||
if (!m_gameview.isMouseCaptured())
|
||||
{
|
||||
POINT p;
|
||||
p.x = x;
|
||||
p.y = y;
|
||||
ClientToScreen(m_hwnd, &p);
|
||||
|
||||
m_sceneview.onMouseMove(old_x, old_y, x - old_x, y - old_y);
|
||||
|
||||
old_x = x;
|
||||
old_y = y;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MousePos.x = (float)x;
|
||||
io.MousePos.y = (float)y;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_MOUSELEAVE:
|
||||
clearInputs();
|
||||
break;
|
||||
case WM_CHAR: ImGui::GetIO().AddInputCharacter((ImWchar)wParam); break;
|
||||
case WM_KEYUP: ImGui::GetIO().KeysDown[wParam] = false; break;
|
||||
case WM_SYSKEYDOWN: ImGui::GetIO().KeysDown[wParam] = true; break;
|
||||
case WM_SYSKEYUP: ImGui::GetIO().KeysDown[wParam] = false; break;
|
||||
case WM_KEYDOWN:
|
||||
{
|
||||
ImGui::GetIO().KeysDown[wParam] = true;
|
||||
checkShortcuts();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
m_gui_pipeline->setViewport(0, 0, width, height);
|
||||
auto& plugin_manager = m_editor->getEngine().getPluginManager();
|
||||
auto* renderer =
|
||||
static_cast<Lumix::Renderer*>(plugin_manager.getPlugin("renderer"));
|
||||
renderer->resize(width, height);
|
||||
}
|
||||
|
||||
|
||||
void clearInputs()
|
||||
{
|
||||
m_is_mouse_tracked = false;
|
||||
auto& io = ImGui::GetIO();
|
||||
io.KeyAlt = false;
|
||||
io.KeyCtrl = false;
|
||||
|
@ -1284,8 +1209,6 @@ public:
|
|||
|
||||
|
||||
Lumix::DefaultAllocator m_allocator;
|
||||
HWND m_hwnd;
|
||||
HINSTANCE m_instance;
|
||||
bgfx::VertexDecl m_decl;
|
||||
Lumix::Material* m_material;
|
||||
Lumix::Engine* m_engine;
|
||||
|
@ -1319,7 +1242,6 @@ public:
|
|||
bool m_is_entity_template_list_opened;
|
||||
bool m_is_style_editor_opened;
|
||||
bool m_is_wireframe;
|
||||
bool m_is_mouse_tracked;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1332,18 +1254,12 @@ static void imGuiCallback(ImDrawData* draw_data)
|
|||
}
|
||||
|
||||
|
||||
static LRESULT WINAPI msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return g_app->windowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
|
||||
int studioMain()
|
||||
{
|
||||
StudioApp app;
|
||||
g_app = &app;
|
||||
|
||||
app.init(hInst);
|
||||
app.init();
|
||||
app.run();
|
||||
app.shutdown();
|
||||
|
||||
|
|
400
src/studio/platform_interface.cpp
Normal file
400
src/studio/platform_interface.cpp
Normal file
|
@ -0,0 +1,400 @@
|
|||
#include "platform_interface.h"
|
||||
#include "ocornut-imgui/imgui.h"
|
||||
#include "renderer/renderer.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
|
||||
namespace PlatformInterface
|
||||
{
|
||||
|
||||
struct PlatformData
|
||||
{
|
||||
PlatformData()
|
||||
{
|
||||
for (int i = 0; i < Lumix::lengthOf(m_key_map); ++i)
|
||||
{
|
||||
m_key_map[i] = -1;
|
||||
m_system_key_map[i] = -1;
|
||||
}
|
||||
|
||||
m_key_map[(int)Keys::ALT] = VK_MENU;
|
||||
m_key_map[(int)Keys::CONTROL] = VK_CONTROL;
|
||||
m_key_map[(int)Keys::SHIFT] = VK_SHIFT;
|
||||
m_key_map[(int)Keys::TAB] = VK_TAB;
|
||||
m_key_map[(int)Keys::LEFT] = VK_LEFT;
|
||||
m_key_map[(int)Keys::RIGHT] = VK_RIGHT;
|
||||
m_key_map[(int)Keys::UP] = VK_UP;
|
||||
m_key_map[(int)Keys::DOWN] = VK_DOWN;
|
||||
m_key_map[(int)Keys::PAGE_UP] = VK_PRIOR;
|
||||
m_key_map[(int)Keys::PAGE_DOWN] = VK_NEXT;
|
||||
m_key_map[(int)Keys::HOME] = VK_HOME;
|
||||
m_key_map[(int)Keys::END] = VK_END;
|
||||
m_key_map[(int)Keys::DEL] = VK_DELETE;
|
||||
m_key_map[(int)Keys::BACKSPACE] = VK_BACK;
|
||||
m_key_map[(int)Keys::ENTER] = VK_RETURN;
|
||||
m_key_map[(int)Keys::ESCAPE] = VK_ESCAPE;
|
||||
|
||||
for (int i = 0; i < Lumix::lengthOf(m_key_map); ++i)
|
||||
{
|
||||
if (m_key_map[i] != -1) m_system_key_map[m_key_map[i]] = i;
|
||||
}
|
||||
}
|
||||
|
||||
HWND m_hwnd;
|
||||
bool m_is_mouse_tracked;
|
||||
SystemEventHandler* m_handler;
|
||||
int m_key_map[512];
|
||||
int m_system_key_map[512];
|
||||
};
|
||||
|
||||
|
||||
static PlatformData g_platform_data;
|
||||
|
||||
|
||||
static int getSystemKey(int key)
|
||||
{
|
||||
if (g_platform_data.m_key_map[key] != -1)
|
||||
{
|
||||
return g_platform_data.m_key_map[key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int getKeyFromSystem(int key)
|
||||
{
|
||||
if (g_platform_data.m_system_key_map[key] != -1)
|
||||
{
|
||||
return g_platform_data.m_system_key_map[key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void trackMouse()
|
||||
{
|
||||
TRACKMOUSEEVENT track_event;
|
||||
track_event.cbSize = sizeof(TRACKMOUSEEVENT);
|
||||
track_event.dwFlags = TME_LEAVE;
|
||||
track_event.hwndTrack = g_platform_data.m_hwnd;
|
||||
g_platform_data.m_is_mouse_tracked = TrackMouseEvent(&track_event) == TRUE;
|
||||
}
|
||||
|
||||
|
||||
void getCurrentDirectory(char* buffer, int buffer_size)
|
||||
{
|
||||
GetCurrentDirectory(buffer_size, buffer);
|
||||
}
|
||||
|
||||
|
||||
void shutdown()
|
||||
{
|
||||
HINSTANCE hInst = GetModuleHandle(NULL);
|
||||
UnregisterClassA("lmxa", hInst);
|
||||
}
|
||||
|
||||
|
||||
void moveWindow(int x, int y, int w, int h)
|
||||
{
|
||||
MoveWindow(g_platform_data.m_hwnd, x, y, w, h, FALSE);
|
||||
}
|
||||
|
||||
|
||||
bool isMaximized()
|
||||
{
|
||||
WINDOWPLACEMENT wndpl;
|
||||
wndpl.length = sizeof(wndpl);
|
||||
if (GetWindowPlacement(g_platform_data.m_hwnd, &wndpl))
|
||||
{
|
||||
return wndpl.showCmd == SW_MAXIMIZE;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void maximizeWindow()
|
||||
{
|
||||
ShowWindow(g_platform_data.m_hwnd, SW_MAXIMIZE);
|
||||
}
|
||||
|
||||
|
||||
bool isForegroundWindow()
|
||||
{
|
||||
return GetForegroundWindow() == g_platform_data.m_hwnd;
|
||||
}
|
||||
|
||||
|
||||
void clipCursor(float min_x, float min_y, float max_x, float max_y)
|
||||
{
|
||||
POINT min;
|
||||
POINT max;
|
||||
min.x = LONG(min_x);
|
||||
min.y = LONG(min_y);
|
||||
max.x = LONG(max_x);
|
||||
max.y = LONG(max_y);
|
||||
ClientToScreen(g_platform_data.m_hwnd, &min);
|
||||
ClientToScreen(g_platform_data.m_hwnd, &max);
|
||||
RECT rect;
|
||||
rect.left = min.x;
|
||||
rect.right = max.x;
|
||||
rect.top = min.y;
|
||||
rect.bottom = max.y;
|
||||
ClipCursor(&rect);
|
||||
}
|
||||
|
||||
|
||||
void showCursor(bool show)
|
||||
{
|
||||
ShowCursor(show);
|
||||
}
|
||||
|
||||
|
||||
void unclipCursor()
|
||||
{
|
||||
ClipCursor(NULL);
|
||||
}
|
||||
|
||||
|
||||
int getWindowX()
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(g_platform_data.m_hwnd, &rect);
|
||||
return int(rect.left);
|
||||
}
|
||||
|
||||
|
||||
int getWindowY()
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(g_platform_data.m_hwnd, &rect);
|
||||
return int(rect.top);
|
||||
}
|
||||
|
||||
|
||||
int getWindowWidth()
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(g_platform_data.m_hwnd, &rect);
|
||||
return int(rect.right - rect.left);
|
||||
}
|
||||
|
||||
|
||||
int getWindowHeight()
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(g_platform_data.m_hwnd, &rect);
|
||||
return int(rect.bottom - rect.top);
|
||||
}
|
||||
|
||||
|
||||
void handleRawInput(LPARAM lParam)
|
||||
{
|
||||
UINT dwSize;
|
||||
char data[sizeof(RAWINPUT) * 10];
|
||||
|
||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
|
||||
if (dwSize > sizeof(data)) return;
|
||||
|
||||
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &dwSize, sizeof(RAWINPUTHEADER)) !=
|
||||
dwSize) return;
|
||||
|
||||
RAWINPUT* raw = (RAWINPUT*)data;
|
||||
if (raw->header.dwType == RIM_TYPEMOUSE &&
|
||||
raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE)
|
||||
{
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
ScreenToClient(g_platform_data.m_hwnd, &p);
|
||||
|
||||
g_platform_data.m_handler->onMouseMove(
|
||||
int(p.x), int(p.y), int(raw->data.mouse.lLastX), int(raw->data.mouse.lLastY));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static LRESULT WINAPI msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (!g_platform_data.m_handler) return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
|
||||
int x = LOWORD(lParam);
|
||||
int y = HIWORD(lParam);
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_LBUTTONUP:
|
||||
g_platform_data.m_handler->onMouseButtonUp(SystemEventHandler::MouseButton::LEFT);
|
||||
break;
|
||||
case WM_LBUTTONDOWN:
|
||||
g_platform_data.m_handler->onMouseButtonDown(SystemEventHandler::MouseButton::LEFT);
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
g_platform_data.m_handler->onMouseButtonDown(SystemEventHandler::MouseButton::RIGHT);
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
g_platform_data.m_handler->onMouseButtonUp(SystemEventHandler::MouseButton::RIGHT);
|
||||
break;
|
||||
case WM_MOUSEWHEEL:
|
||||
g_platform_data.m_handler->onMouseWheel(GET_WHEEL_DELTA_WPARAM(wParam));
|
||||
break;
|
||||
case WM_INPUT: handleRawInput(lParam); break;
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
if (!g_platform_data.m_is_mouse_tracked) trackMouse();
|
||||
}
|
||||
break;
|
||||
case WM_ERASEBKGND: return 1;
|
||||
case WM_MOVE:
|
||||
case WM_SIZE:
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(g_platform_data.m_hwnd, &rect);
|
||||
g_platform_data.m_handler->onWindowTransformed(
|
||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
|
||||
}
|
||||
break;
|
||||
case WM_CLOSE: PostQuitMessage(0); break;
|
||||
case WM_MOUSELEAVE:
|
||||
{
|
||||
g_platform_data.m_is_mouse_tracked = false;
|
||||
g_platform_data.m_handler->onMouseLeftWindow();
|
||||
}
|
||||
break;
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP: g_platform_data.m_handler->onKeyUp(getKeyFromSystem(wParam)); break;
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN: g_platform_data.m_handler->onKeyDown(getKeyFromSystem(wParam)); break;
|
||||
case WM_CHAR: g_platform_data.m_handler->onChar(getKeyFromSystem(wParam)); break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
void getKeyName(int key, char* out, int max_size)
|
||||
{
|
||||
int virtualKey = getSystemKey(key);
|
||||
unsigned int scanCode = MapVirtualKey(virtualKey, MAPVK_VK_TO_VSC);
|
||||
|
||||
// because MapVirtualKey strips the extended bit for some keys
|
||||
switch (virtualKey)
|
||||
{
|
||||
case VK_LEFT:
|
||||
case VK_UP:
|
||||
case VK_RIGHT:
|
||||
case VK_DOWN: // arrow keys
|
||||
case VK_PRIOR:
|
||||
case VK_NEXT: // page up and page down
|
||||
case VK_END:
|
||||
case VK_HOME:
|
||||
case VK_INSERT:
|
||||
case VK_DELETE:
|
||||
case VK_DIVIDE: // numpad slash
|
||||
case VK_NUMLOCK:
|
||||
{
|
||||
scanCode |= 0x100; // set extended bit
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GetKeyNameText(scanCode << 16, out, max_size);
|
||||
}
|
||||
|
||||
|
||||
bool processSystemEvents()
|
||||
{
|
||||
bool want_quit = false;
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
{
|
||||
want_quit = true;
|
||||
}
|
||||
}
|
||||
return !want_quit;
|
||||
}
|
||||
|
||||
|
||||
void createWindow(SystemEventHandler* handler)
|
||||
{
|
||||
g_platform_data.m_handler = handler;
|
||||
|
||||
HINSTANCE hInst = GetModuleHandle(NULL);
|
||||
WNDCLASSEX wnd;
|
||||
memset(&wnd, 0, sizeof(wnd));
|
||||
wnd.cbSize = sizeof(wnd);
|
||||
wnd.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wnd.lpfnWndProc = msgProc;
|
||||
wnd.hInstance = hInst;
|
||||
wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wnd.lpszClassName = "lmxa";
|
||||
wnd.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||||
auto x = RegisterClassExA(&wnd);
|
||||
g_platform_data.m_hwnd = CreateWindowA(
|
||||
"lmxa", "lmxa", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 800, 600, NULL, NULL, hInst, 0);
|
||||
SetWindowTextA(g_platform_data.m_hwnd, "Lumix Studio");
|
||||
|
||||
RAWINPUTDEVICE Rid;
|
||||
Rid.usUsagePage = 0x01;
|
||||
Rid.usUsage = 0x02;
|
||||
Rid.dwFlags = 0;
|
||||
Rid.hwndTarget = 0;
|
||||
RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
|
||||
|
||||
timeBeginPeriod(1);
|
||||
trackMouse();
|
||||
|
||||
Lumix::Renderer::setInitData(g_platform_data.m_hwnd);
|
||||
ImGui::GetIO().ImeWindowHandle = g_platform_data.m_hwnd;
|
||||
}
|
||||
|
||||
|
||||
void setWindowTitle(const char* title)
|
||||
{
|
||||
SetWindowTextA(g_platform_data.m_hwnd, title);
|
||||
}
|
||||
|
||||
|
||||
bool isPressed(int key)
|
||||
{
|
||||
return (GetKeyState(getSystemKey(key)) & 0x8000) != 0;
|
||||
}
|
||||
|
||||
|
||||
void setCursor(Cursor cursor)
|
||||
{
|
||||
switch (cursor)
|
||||
{
|
||||
case Cursor::NONE:
|
||||
SetCursor(NULL);
|
||||
break;
|
||||
default:
|
||||
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace PlatformInterface
|
||||
|
||||
|
||||
INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, INT)
|
||||
{
|
||||
int studioMain();
|
||||
return studioMain();
|
||||
}
|
74
src/studio/platform_interface.h
Normal file
74
src/studio/platform_interface.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
namespace PlatformInterface
|
||||
{
|
||||
enum class Keys
|
||||
{
|
||||
CONTROL,
|
||||
ALT,
|
||||
SHIFT,
|
||||
TAB,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
UP,
|
||||
DOWN,
|
||||
PAGE_UP,
|
||||
PAGE_DOWN,
|
||||
HOME,
|
||||
END,
|
||||
DEL,
|
||||
BACKSPACE,
|
||||
ENTER,
|
||||
ESCAPE
|
||||
};
|
||||
|
||||
|
||||
enum class Cursor
|
||||
{
|
||||
NONE,
|
||||
DEFAULT
|
||||
};
|
||||
|
||||
|
||||
struct SystemEventHandler
|
||||
{
|
||||
enum class MouseButton
|
||||
{
|
||||
LEFT,
|
||||
RIGHT
|
||||
};
|
||||
|
||||
virtual void onWindowTransformed(int x, int y, int w, int h) = 0;
|
||||
virtual void onMouseLeftWindow() = 0;
|
||||
virtual void onMouseMove(int x, int y, int rel_x, int rel_y) = 0;
|
||||
virtual void onMouseWheel(int amount) = 0;
|
||||
virtual void onMouseButtonDown(MouseButton button) = 0;
|
||||
virtual void onMouseButtonUp(MouseButton button) = 0;
|
||||
virtual void onKeyDown(int key) = 0;
|
||||
virtual void onKeyUp(int key) = 0;
|
||||
virtual void onChar(int key) = 0;
|
||||
};
|
||||
|
||||
|
||||
bool processSystemEvents();
|
||||
bool isForegroundWindow();
|
||||
void clipCursor(float min_x, float min_y, float max_x, float max_y);
|
||||
void showCursor(bool show);
|
||||
void unclipCursor();
|
||||
int getWindowX();
|
||||
int getWindowY();
|
||||
int getWindowWidth();
|
||||
int getWindowHeight();
|
||||
void createWindow(SystemEventHandler* handler);
|
||||
void setWindowTitle(const char* title);
|
||||
bool isMaximized();
|
||||
void maximizeWindow();
|
||||
void moveWindow(int x, int y, int w, int h);
|
||||
void getCurrentDirectory(char* buffer, int buffer_size);
|
||||
void shutdown();
|
||||
bool isPressed(int key);
|
||||
void getKeyName(int key, char* out, int max_size);
|
||||
void setCursor(Cursor cursor);
|
||||
|
||||
} // namespace PlatformInterface
|
|
@ -2,6 +2,7 @@
|
|||
#include "core/log.h"
|
||||
#include "debug/debug.h"
|
||||
#include "ocornut-imgui/imgui.h"
|
||||
#include "platform_interface.h"
|
||||
#include "utils.h"
|
||||
#include <cstdio>
|
||||
#include <lua.hpp>
|
||||
|
@ -16,7 +17,7 @@ static void shortcutInput(int& shortcut)
|
|||
popup_name << (int64_t)&shortcut;
|
||||
|
||||
char key_string[30];
|
||||
getKeyName(shortcut, key_string, 30);
|
||||
PlatformInterface::getKeyName(shortcut, key_string, 30);
|
||||
|
||||
StringBuilder<50> button_label(key_string);
|
||||
button_label << "##" << (int64_t)&shortcut;
|
||||
|
|
|
@ -6,37 +6,6 @@
|
|||
#include "ocornut-imgui/imgui.h"
|
||||
#include "renderer/render_scene.h"
|
||||
#include "universe/universe.h"
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
|
||||
void getKeyName(int virtualKey, char* out, int max_size)
|
||||
{
|
||||
unsigned int scanCode = MapVirtualKey(virtualKey, MAPVK_VK_TO_VSC);
|
||||
|
||||
// because MapVirtualKey strips the extended bit for some keys
|
||||
switch (virtualKey)
|
||||
{
|
||||
case VK_LEFT:
|
||||
case VK_UP:
|
||||
case VK_RIGHT:
|
||||
case VK_DOWN: // arrow keys
|
||||
case VK_PRIOR:
|
||||
case VK_NEXT: // page up and page down
|
||||
case VK_END:
|
||||
case VK_HOME:
|
||||
case VK_INSERT:
|
||||
case VK_DELETE:
|
||||
case VK_DIVIDE: // numpad slash
|
||||
case VK_NUMLOCK:
|
||||
{
|
||||
scanCode |= 0x100; // set extended bit
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GetKeyNameText(scanCode << 16, out, max_size);
|
||||
}
|
||||
|
||||
|
||||
void getEntityListDisplayName(Lumix::WorldEditor& editor,
|
||||
|
|
|
@ -165,7 +165,6 @@ namespace Lumix
|
|||
}
|
||||
|
||||
bool ColorPicker(const char* label, float col[3]);
|
||||
void getKeyName(int virtualKey, char* out, int max_size);
|
||||
void getEntityListDisplayName(Lumix::WorldEditor& editor,
|
||||
char* buf,
|
||||
int max_size,
|
||||
|
|
Loading…
Reference in a new issue