studio uses SDL

This commit is contained in:
Mikulas Florek 2016-05-24 21:14:34 +02:00
parent 244ffe2634
commit 0080f14107
13 changed files with 250 additions and 1166 deletions

View file

@ -445,7 +445,7 @@ solution "LumixEngine"
"NoRTTI", "NoRTTI",
"NoEditAndContinue" "NoEditAndContinue"
} }
includedirs {"../src", "../external"} includedirs {"../src", "../external", "../external/sdl/include" }
location(LOCATION) location(LOCATION)
language "C++" language "C++"
startproject "studio" startproject "studio"
@ -660,9 +660,6 @@ if build_app then
configuration { "vs*" } configuration { "vs*" }
links { "psapi", "dxguid", "winmm" } links { "psapi", "dxguid", "winmm" }
configuration { "asmjs" }
links { "SDL" }
configuration {} configuration {}
else else
links { "renderer", "editor", "engine" } links { "renderer", "editor", "engine" }
@ -692,6 +689,11 @@ if build_app then
configuration {} configuration {}
linkLib "SDL"
configuration {"vs*"}
links { "winmm", "imm32", "version" }
configuration {}
useLua() useLua()
defaultConfigurations() defaultConfigurations()
strip() strip()
@ -768,6 +770,12 @@ if build_studio then
links { "renderer", "editor", "engine" } links { "renderer", "editor", "engine" }
end end
linkLib "SDL"
configuration {"vs*"}
links { "winmm", "imm32", "version" }
configuration {}
useLua() useLua()
defaultConfigurations() defaultConfigurations()

View file

@ -9,50 +9,6 @@
namespace PlatformInterface namespace PlatformInterface
{ {
struct PlatformData
{
PlatformData()
{
is_quit_requested = false;
for (int i = 0; i < Lumix::lengthOf(key_map); ++i)
{
key_map[i] = -1;
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(key_map); ++i)
{
if (key_map[i] != -1) system_key_map[key_map[i]] = i;
}
}
Window window_handle;
Display* display;
bool is_mouse_tracked;
bool is_quit_requested;
SystemEventHandler* handler;
int key_map[512];
int system_key_map[512];
};
struct FileIterator struct FileIterator
{ {
/* HANDLE handle; /* HANDLE handle;
@ -95,374 +51,11 @@ namespace PlatformInterface
} }
static PlatformData g_platform_data;
static int getSystemKey(int key)
{
if (g_platform_data.key_map[key] != -1)
{
return g_platform_data.key_map[key];
}
else
{
return key;
}
}
static int getKeyFromSystem(int key)
{
if (g_platform_data.system_key_map[key] != -1)
{
return g_platform_data.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) void getCurrentDirectory(char* buffer, int buffer_size)
{ {
//GetCurrentDirectory(buffer_size, buffer); //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()
{
}
bool isWindowActive()
{
//return GetActiveWindow() == g_platform_data.m_hwnd;
return false;
}
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)
{
/*if (show)
{
while (ShowCursor(true) < 0);
}
else
{
while (ShowCursor(false) >= 0);
}*/
}
void unclipCursor()
{
//ClipCursor(NULL);
}
int getWindowX()
{
/*RECT rect;
GetClientRect(g_platform_data.m_hwnd, &rect);
return int(rect.left);*/
return 0;
}
int getWindowY()
{
/*RECT rect;
GetClientRect(g_platform_data.m_hwnd, &rect);
return int(rect.top);*/
return 0;
}
int getWindowWidth()
{
/*RECT rect;
GetClientRect(g_platform_data.m_hwnd, &rect);
return int(rect.right - rect.left);*/
return 0;
}
int getWindowHeight()
{
/*RECT rect;
GetClientRect(g_platform_data.m_hwnd, &rect);
return int(rect.bottom - rect.top);*/
return 0;
}
/*
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));
}
}
*/
void clearQuitRequest()
{
//g_platform_data.m_is_quit_requested = false;
}
bool isQuitRequested()
{
//return g_platform_data.m_is_quit_requested;
return false;
}
/*
static LRESULT WINAPI msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (!g_platform_data.m_handler) return DefWindowProc(hWnd, msg, wParam, 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_MBUTTONUP:
g_platform_data.m_handler->onMouseButtonUp(SystemEventHandler::MouseButton::MIDDLE);
break;
case WM_MBUTTONDOWN:
g_platform_data.m_handler->onMouseButtonDown(SystemEventHandler::MouseButton::MIDDLE);
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;
RECT screen_rect;
GetWindowRect(g_platform_data.m_hwnd, &screen_rect);
GetClientRect(g_platform_data.m_hwnd, &rect);
g_platform_data.m_handler->onWindowTransformed(
screen_rect.left, screen_rect.top, rect.right - rect.left, rect.bottom - rect.top);
}
break;
case WM_CLOSE: g_platform_data.m_is_quit_requested = true; return true;
case WM_MOUSELEAVE:
{
g_platform_data.m_is_mouse_tracked = false;
g_platform_data.m_handler->onMouseLeftWindow();
}
break;
case WM_SYSCOMMAND:
{
bool is_alt_key_menu = wParam == SC_KEYMENU && (lParam >> 16) <= 0;
if (is_alt_key_menu) return 0;
break;
}
case WM_KEYUP:
case WM_SYSKEYUP: g_platform_data.m_handler->onKeyUp(getKeyFromSystem((int)wParam)); break;
case WM_KEYDOWN:
case WM_SYSKEYDOWN: g_platform_data.m_handler->onKeyDown(getKeyFromSystem((int)wParam)); break;
case WM_CHAR: g_platform_data.m_handler->onChar((int)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:
case VK_PRIOR:
case VK_NEXT:
case VK_END:
case VK_HOME:
case VK_INSERT:
case VK_DELETE:
case VK_DIVIDE:
case VK_NUMLOCK:
{
scanCode |= 0x100;
break;
}
}
GetKeyNameText(scanCode << 16, out, max_size);*/
}
bool processSystemEvents()
{
bool want_quit = false;
XEvent e;
while (XPending(g_platform_data.display) > 0)
{
XNextEvent(g_platform_data.display, &e);
if (e.type == KeyPress) want_quit = true;
}
return !want_quit;
}
void setSystemEventHandler(SystemEventHandler* handler)
{
g_platform_data.handler = handler;
}
Lumix::Engine::PlatformData getPlatformData()
{
Lumix::Engine::PlatformData ret = {};
ret.window_handle = (void*)(uintptr_t)g_platform_data.window_handle;
ret.display = g_platform_data.display;
return ret;
}
void* getWindowHandle()
{
return (void*)(uintptr_t)g_platform_data.window_handle;
}
void createWindow(SystemEventHandler* handler)
{
Display* display = XOpenDisplay(nullptr);
if (!display) return;
int s = DefaultScreen(display);
Window window = XCreateSimpleWindow(display, RootWindow(display, s), 10, 10, 100, 100, 1
, BlackPixel(display, s), WhitePixel(display, s));
XSelectInput(display, window, ExposureMask | KeyPressMask);
XMapWindow(display, window);
g_platform_data.display = display;
g_platform_data.window_handle = window;
}
void setWindowTitle(const char* title)
{
//SetWindowTextA(g_platform_data.m_hwnd, title);
}
bool isPressed(int key)
{
//return (GetKeyState(getSystemKey(key)) & 0x8000) != 0;
return false;
}
void setCursor(Cursor cursor)
{
/*switch (cursor)
{
case Cursor::NONE:
SetCursor(NULL);
break;
default:
SetCursor(LoadCursor(NULL, IDC_ARROW));
break;
}*/
}
struct Process struct Process
{ {

View file

@ -13,34 +13,6 @@ namespace Lumix
namespace PlatformInterface 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 FileInfo struct FileInfo
{ {
bool is_directory; bool is_directory;
@ -53,56 +25,9 @@ namespace PlatformInterface
LUMIX_EDITOR_API void destroyFileIterator(FileIterator* iterator); LUMIX_EDITOR_API void destroyFileIterator(FileIterator* iterator);
LUMIX_EDITOR_API bool getNextFile(FileIterator* iterator, FileInfo* info); LUMIX_EDITOR_API bool getNextFile(FileIterator* iterator, FileInfo* info);
struct SystemEventHandler
{
enum class MouseButton
{
LEFT,
RIGHT,
MIDDLE
};
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;
};
LUMIX_EDITOR_API bool isWindowActive();
LUMIX_EDITOR_API bool processSystemEvents();
LUMIX_EDITOR_API void clipCursor(float min_x, float min_y, float max_x, float max_y);
LUMIX_EDITOR_API void showCursor(bool show);
LUMIX_EDITOR_API void unclipCursor();
LUMIX_EDITOR_API int getWindowX();
LUMIX_EDITOR_API int getWindowY();
LUMIX_EDITOR_API int getWindowWidth();
LUMIX_EDITOR_API int getWindowHeight();
LUMIX_EDITOR_API void createWindow(SystemEventHandler* handler);
LUMIX_EDITOR_API void* getWindowHandle();
LUMIX_EDITOR_API Lumix::Engine::PlatformData getPlatformData();
LUMIX_EDITOR_API void setSystemEventHandler(SystemEventHandler* handler);
LUMIX_EDITOR_API void setWindowTitle(const char* title);
LUMIX_EDITOR_API bool isMaximized();
LUMIX_EDITOR_API void maximizeWindow();
LUMIX_EDITOR_API void moveWindow(int x, int y, int w, int h);
LUMIX_EDITOR_API void getCurrentDirectory(char* buffer, int buffer_size); LUMIX_EDITOR_API void getCurrentDirectory(char* buffer, int buffer_size);
LUMIX_EDITOR_API void shutdown();
LUMIX_EDITOR_API bool isPressed(int key);
LUMIX_EDITOR_API void getKeyName(int key, char* out, int max_size);
LUMIX_EDITOR_API void setCursor(Cursor cursor);
LUMIX_EDITOR_API bool getOpenFilename(char* out, int max_size, const char* filter, const char* starting_file); LUMIX_EDITOR_API bool getOpenFilename(char* out, int max_size, const char* filter, const char* starting_file);
LUMIX_EDITOR_API bool getSaveFilename(char* out, LUMIX_EDITOR_API bool getSaveFilename(char* out, int max_size, const char* filter, const char* default_extension);
int max_size,
const char* filter,
const char* default_extension);
LUMIX_EDITOR_API bool getOpenDirectory(char* out, int max_size, const char* starting_dir); LUMIX_EDITOR_API bool getOpenDirectory(char* out, int max_size, const char* starting_dir);
LUMIX_EDITOR_API bool shellExecuteOpen(const char* path); LUMIX_EDITOR_API bool shellExecuteOpen(const char* path);
@ -122,7 +47,5 @@ namespace PlatformInterface
LUMIX_EDITOR_API bool isProcessFinished(Process& process); LUMIX_EDITOR_API bool isProcessFinished(Process& process);
LUMIX_EDITOR_API int getProcessExitCode(Process& process); LUMIX_EDITOR_API int getProcessExitCode(Process& process);
LUMIX_EDITOR_API int getProcessOutput(Process& process, char* buf, int buf_size); LUMIX_EDITOR_API int getProcessOutput(Process& process, char* buf, int buf_size);
LUMIX_EDITOR_API bool isQuitRequested();
LUMIX_EDITOR_API void clearQuitRequest();
} // namespace PlatformInterface } // namespace PlatformInterface

View file

@ -9,6 +9,7 @@
#include "utils.h" #include "utils.h"
#include <cstdio> #include <cstdio>
#include <lua.hpp> #include <lua.hpp>
#include <SDL.h>
static const char DEFAULT_SETTINGS_PATH[] = "studio_default.ini"; static const char DEFAULT_SETTINGS_PATH[] = "studio_default.ini";
@ -20,20 +21,19 @@ static void shortcutInput(int& shortcut)
Lumix::StaticString<50> popup_name(""); Lumix::StaticString<50> popup_name("");
popup_name << (Lumix::int64)&shortcut; popup_name << (Lumix::int64)&shortcut;
char key_string[30]; Lumix::StaticString<50> button_label(SDL_GetKeyName(SDL_GetKeyFromScancode((SDL_Scancode)shortcut)));
PlatformInterface::getKeyName(shortcut, key_string, 30);
Lumix::StaticString<50> button_label(key_string);
button_label << "###" << (Lumix::int64)&shortcut; button_label << "###" << (Lumix::int64)&shortcut;
if (ImGui::Button(button_label, ImVec2(50, 0))) shortcut = -1; if (ImGui::Button(button_label, ImVec2(50, 0))) shortcut = -1;
auto& io = ImGui::GetIO(); auto& io = ImGui::GetIO();
int key_count;
auto* state = SDL_GetKeyboardState(&key_count);
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
{ {
for (int i = 0; i < Lumix::lengthOf(ImGui::GetIO().KeysDown); ++i) for (int i = 0; i < key_count; ++i)
{ {
if (io.KeysDown[i]) if (state[i])
{ {
shortcut = i; shortcut = i;
break; break;

View file

@ -34,6 +34,8 @@
#include "settings.h" #include "settings.h"
#include "studio_app.h" #include "studio_app.h"
#include "utils.h" #include "utils.h"
#include <SDL.h>
#include <SDL_syswm.h>
class StudioAppImpl* g_app; class StudioAppImpl* g_app;
@ -97,18 +99,13 @@ public:
PROFILE_FUNCTION(); PROFILE_FUNCTION();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2((float)PlatformInterface::getWindowWidth(), int w, h;
(float)PlatformInterface::getWindowHeight()); SDL_GetWindowSize(m_window, &w, &h);
io.DisplaySize = ImVec2((float)w, (float)h);
io.DeltaTime = m_engine->getLastTimeDelta(); io.DeltaTime = m_engine->getLastTimeDelta();
io.KeyCtrl = PlatformInterface::isPressed((int)PlatformInterface::Keys::CONTROL); io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0);
io.KeyShift = PlatformInterface::isPressed((int)PlatformInterface::Keys::SHIFT); io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0);
io.KeyAlt = PlatformInterface::isPressed((int)PlatformInterface::Keys::ALT); io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0);
io.KeysDown[(int)PlatformInterface::Keys::ALT] = io.KeyAlt;
io.KeysDown[(int)PlatformInterface::Keys::SHIFT] = io.KeyShift;
io.KeysDown[(int)PlatformInterface::Keys::CONTROL] = io.KeyCtrl;
PlatformInterface::setCursor(io.MouseDrawCursor ? PlatformInterface::Cursor::NONE
: PlatformInterface::Cursor::DEFAULT);
ImGui::NewFrame(); ImGui::NewFrame();
} }
@ -174,8 +171,9 @@ public:
{ {
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings; ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings;
ImVec2 size((float)PlatformInterface::getWindowWidth(), int w, h;
(float)PlatformInterface::getWindowHeight()); SDL_GetWindowSize(m_window, &w, &h);
ImVec2 size((float)w, (float)h);
if (ImGui::Begin("Welcome", nullptr, size, -1, flags)) if (ImGui::Begin("Welcome", nullptr, size, -1, flags))
{ {
ImGui::Text("Welcome to Lumix Studio"); ImGui::Text("Welcome to Lumix Studio");
@ -212,14 +210,12 @@ public:
{ {
if (ImGui::Button("Wiki")) if (ImGui::Button("Wiki"))
{ {
PlatformInterface::shellExecuteOpen( PlatformInterface::shellExecuteOpen("https://github.com/nem0/LumixEngine/wiki");
"https://github.com/nem0/LumixEngine/wiki");
} }
if (ImGui::Button("Download new version")) if (ImGui::Button("Download new version"))
{ {
PlatformInterface::shellExecuteOpen( PlatformInterface::shellExecuteOpen("https://github.com/nem0/lumixengine_data/archive/master.zip");
"https://github.com/nem0/lumixengine_data/archive/master.zip");
} }
if (ImGui::Button("Show major releases")) if (ImGui::Button("Show major releases"))
@ -313,7 +309,7 @@ public:
char tmp[100]; char tmp[100];
Lumix::copyString(tmp, "Lumix Studio - "); Lumix::copyString(tmp, "Lumix Studio - ");
Lumix::catString(tmp, title); Lumix::catString(tmp, title);
PlatformInterface::setWindowTitle(tmp); SDL_SetWindowTitle(m_window, tmp);
} }
@ -322,8 +318,7 @@ public:
buf[0] = 0; buf[0] = 0;
for (int i = 0; i < Lumix::lengthOf(action.shortcut); ++i) for (int i = 0; i < Lumix::lengthOf(action.shortcut); ++i)
{ {
char str[30]; const char* str = SDL_GetKeyName(action.shortcut[i]);
PlatformInterface::getKeyName(action.shortcut[i], str, Lumix::lengthOf(str));
if (str[0] == 0) return; if (str[0] == 0) return;
if (i > 0) Lumix::catString(buf, max_size, " - "); if (i > 0) Lumix::catString(buf, max_size, " - ");
Lumix::catString(buf, max_size, str); Lumix::catString(buf, max_size, str);
@ -358,14 +353,12 @@ public:
else else
{ {
char filename[Lumix::MAX_PATH_LENGTH]; char filename[Lumix::MAX_PATH_LENGTH];
if (PlatformInterface::getSaveFilename( if (PlatformInterface::getSaveFilename(filename, sizeof(filename), "Universes\0*.unv\0", "unv"))
filename, sizeof(filename), "Universes\0*.unv\0", "unv"))
{ {
m_editor->saveUniverse(Lumix::Path(filename), true); m_editor->saveUniverse(Lumix::Path(filename), true);
setTitle(filename); setTitle(filename);
} }
} }
} }
@ -386,7 +379,8 @@ public:
} }
void exit() { void exit()
{
if (m_editor->isUniverseChanged()) if (m_editor->isUniverseChanged())
{ {
m_confirm_exit = true; m_confirm_exit = true;
@ -480,8 +474,7 @@ public:
void saveUndoStack() void saveUndoStack()
{ {
char filename[Lumix::MAX_PATH_LENGTH]; char filename[Lumix::MAX_PATH_LENGTH];
if (PlatformInterface::getSaveFilename( if (PlatformInterface::getSaveFilename(filename, Lumix::lengthOf(filename), "JSON files\0*.json\0", "json"))
filename, Lumix::lengthOf(filename), "JSON files\0*.json\0", "json"))
{ {
m_editor->saveUndoStack(Lumix::Path(filename)); m_editor->saveUndoStack(Lumix::Path(filename));
} }
@ -729,7 +722,7 @@ public:
if (m_engine->getFileSystem().hasWork()) stats << "Loading... | "; if (m_engine->getFileSystem().hasWork()) stats << "Loading... | ";
stats << "FPS: "; stats << "FPS: ";
stats << m_engine->getFPS(); stats << m_engine->getFPS();
if (!PlatformInterface::isWindowActive()) stats << " - inactive window"; if ((SDL_GetWindowFlags(m_window) & SDL_WINDOW_INPUT_FOCUS) == 0) stats << " - inactive window";
auto stats_size = ImGui::CalcTextSize(stats); auto stats_size = ImGui::CalcTextSize(stats);
ImGui::SameLine(ImGui::GetContentRegionMax().x - stats_size.x); ImGui::SameLine(ImGui::GetContentRegionMax().x - stats_size.x);
ImGui::Text("%s", (const char*)stats); ImGui::Text("%s", (const char*)stats);
@ -955,7 +948,8 @@ public:
m_engine = nullptr; m_engine = nullptr;
m_editor = nullptr; m_editor = nullptr;
PlatformInterface::shutdown(); SDL_DestroyWindow(m_window);
SDL_Quit();
} }
@ -964,25 +958,25 @@ public:
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("bin/VeraMono.ttf", 13); io.Fonts->AddFontFromFileTTF("bin/VeraMono.ttf", 13);
io.KeyMap[ImGuiKey_Tab] = (int)PlatformInterface::Keys::TAB; io.KeyMap[ImGuiKey_Tab] = SDLK_TAB;
io.KeyMap[ImGuiKey_LeftArrow] = (int)PlatformInterface::Keys::LEFT; io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = (int)PlatformInterface::Keys::RIGHT; io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = (int)PlatformInterface::Keys::UP; io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP;
io.KeyMap[ImGuiKey_DownArrow] = (int)PlatformInterface::Keys::DOWN; io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN;
io.KeyMap[ImGuiKey_PageUp] = (int)PlatformInterface::Keys::PAGE_UP; io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP;
io.KeyMap[ImGuiKey_PageDown] = (int)PlatformInterface::Keys::PAGE_DOWN; io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN;
io.KeyMap[ImGuiKey_Home] = (int)PlatformInterface::Keys::HOME; io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME;
io.KeyMap[ImGuiKey_End] = (int)PlatformInterface::Keys::END; io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END;
io.KeyMap[ImGuiKey_Delete] = (int)PlatformInterface::Keys::DEL; io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE;
io.KeyMap[ImGuiKey_Backspace] = (int)PlatformInterface::Keys::BACKSPACE; io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE;
io.KeyMap[ImGuiKey_Enter] = (int)PlatformInterface::Keys::ENTER; io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN;
io.KeyMap[ImGuiKey_Escape] = (int)PlatformInterface::Keys::ESCAPE; io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE;
io.KeyMap[ImGuiKey_A] = 'A'; io.KeyMap[ImGuiKey_A] = SDLK_a;
io.KeyMap[ImGuiKey_C] = 'C'; io.KeyMap[ImGuiKey_C] = SDLK_c;
io.KeyMap[ImGuiKey_V] = 'V'; io.KeyMap[ImGuiKey_V] = SDLK_v;
io.KeyMap[ImGuiKey_X] = 'X'; io.KeyMap[ImGuiKey_X] = SDLK_x;
io.KeyMap[ImGuiKey_Y] = 'Y'; io.KeyMap[ImGuiKey_Y] = SDLK_y;
io.KeyMap[ImGuiKey_Z] = 'Z'; io.KeyMap[ImGuiKey_Z] = SDLK_z;
} }
@ -1011,12 +1005,12 @@ public:
if (m_settings.m_is_maximized) if (m_settings.m_is_maximized)
{ {
PlatformInterface::maximizeWindow(); SDL_MaximizeWindow(m_window);
} }
else if (m_settings.m_window.w > 0) else if (m_settings.m_window.w > 0)
{ {
PlatformInterface::moveWindow( SDL_SetWindowPosition(m_window, m_settings.m_window.x, m_settings.m_window.y);
m_settings.m_window.x, m_settings.m_window.y, m_settings.m_window.w, m_settings.m_window.h); SDL_SetWindowSize(m_window, m_settings.m_window.w, m_settings.m_window.h);
} }
} }
@ -1024,23 +1018,22 @@ public:
void addActions() void addActions()
{ {
addAction<&StudioAppImpl::newUniverse>("New", "newUniverse"); addAction<&StudioAppImpl::newUniverse>("New", "newUniverse");
addAction<&StudioAppImpl::save>("Save", "save", (int)PlatformInterface::Keys::CONTROL, 'S', -1); addAction<&StudioAppImpl::save>("Save", "save", KMOD_CTRL, 'S', -1);
addAction<&StudioAppImpl::saveAs>("Save As", addAction<&StudioAppImpl::saveAs>("Save As",
"saveAs", "saveAs",
(int)PlatformInterface::Keys::CONTROL, MOD_CONTROL,
(int)PlatformInterface::Keys::SHIFT, KMOD_SHIFT,
'S'); 'S');
addAction<&StudioAppImpl::exit>("Exit", "exit", (int)PlatformInterface::Keys::CONTROL, 'X', -1); addAction<&StudioAppImpl::exit>("Exit", "exit", KMOD_CTRL, 'X', -1);
addAction<&StudioAppImpl::redo>("Redo", addAction<&StudioAppImpl::redo>("Redo",
"redo", "redo",
(int)PlatformInterface::Keys::CONTROL, KMOD_CTRL,
(int)PlatformInterface::Keys::SHIFT, KMOD_SHIFT,
'Z'); 'Z');
addAction<&StudioAppImpl::undo>("Undo", "undo", (int)PlatformInterface::Keys::CONTROL, 'Z', -1); addAction<&StudioAppImpl::undo>("Undo", "undo", KMOD_CTRL, 'Z', -1);
addAction<&StudioAppImpl::copy>("Copy", "copy", (int)PlatformInterface::Keys::CONTROL, 'C', -1); addAction<&StudioAppImpl::copy>("Copy", "copy", KMOD_CTRL, 'C', -1);
addAction<&StudioAppImpl::paste>( addAction<&StudioAppImpl::paste>("Paste", "paste", KMOD_CTRL, 'V', -1);
"Paste", "paste", (int)PlatformInterface::Keys::CONTROL, 'V', -1);
addAction<&StudioAppImpl::toggleOrbitCamera>("Orbit camera", "orbitCamera"); addAction<&StudioAppImpl::toggleOrbitCamera>("Orbit camera", "orbitCamera");
addAction<&StudioAppImpl::toggleGizmoMode>("Translate/Rotate", "toggleGizmoMode"); addAction<&StudioAppImpl::toggleGizmoMode>("Translate/Rotate", "toggleGizmoMode");
addAction<&StudioAppImpl::setTopView>("Top", "viewTop"); addAction<&StudioAppImpl::setTopView>("Top", "viewTop");
@ -1050,8 +1043,7 @@ public:
addAction<&StudioAppImpl::toggleCoordSystem>("Local/Global", "toggleCoordSystem"); addAction<&StudioAppImpl::toggleCoordSystem>("Local/Global", "toggleCoordSystem");
addAction<&StudioAppImpl::createEntity>("Create", "createEntity"); addAction<&StudioAppImpl::createEntity>("Create", "createEntity");
addAction<&StudioAppImpl::destroyEntity>( addAction<&StudioAppImpl::destroyEntity>("Destroy", "destroyEntity", SDLK_DELETE, -1, -1);
"Destroy", "destroyEntity", (int)PlatformInterface::Keys::DEL, -1, -1);
addAction<&StudioAppImpl::showEntities>("Show", "showEntities"); addAction<&StudioAppImpl::showEntities>("Show", "showEntities");
addAction<&StudioAppImpl::hideEntities>("Hide", "hideEntities"); addAction<&StudioAppImpl::hideEntities>("Hide", "hideEntities");
@ -1282,16 +1274,16 @@ public:
{ {
auto* iter = PlatformInterface::createFileIterator(dir_path, m_allocator); auto* iter = PlatformInterface::createFileIterator(dir_path, m_allocator);
PlatformInterface::FileInfo info; PlatformInterface::FileInfo info;
while(PlatformInterface::getNextFile(iter, &info)) while (PlatformInterface::getNextFile(iter, &info))
{ {
char normalized_path[Lumix::MAX_PATH_LENGTH]; char normalized_path[Lumix::MAX_PATH_LENGTH];
Lumix::PathUtils::normalize(info.filename, normalized_path, Lumix::lengthOf(normalized_path)); Lumix::PathUtils::normalize(info.filename, normalized_path, Lumix::lengthOf(normalized_path));
if(info.is_directory) if (info.is_directory)
{ {
if(!includeDirInPack(normalized_path)) continue; if (!includeDirInPack(normalized_path)) continue;
char dir[Lumix::MAX_PATH_LENGTH] = { 0 }; char dir[Lumix::MAX_PATH_LENGTH] = {0};
if(dir_path[0] != '.') Lumix::copyString(dir, dir_path); if (dir_path[0] != '.') Lumix::copyString(dir, dir_path);
Lumix::catString(dir, info.filename); Lumix::catString(dir, info.filename);
Lumix::catString(dir, "/"); Lumix::catString(dir, "/");
packDataScan(dir, infos, paths); packDataScan(dir, infos, paths);
@ -1410,6 +1402,83 @@ public:
} }
bool processSystemEvents()
{
bool want_quit = false;
SDL_Event event;
auto& io = ImGui::GetIO();
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_WINDOWEVENT:
switch (event.window.event)
{
case SDL_WINDOWEVENT_MOVED:
case SDL_WINDOWEVENT_SIZE_CHANGED:
{
int x, y, w, h;
SDL_GetWindowSize(m_window, &w, &h);
SDL_GetWindowPosition(m_window, &x, &y);
onWindowTransformed(x, y, w, h);
}
break;
}
break;
case SDL_QUIT: exit(); break;
case SDL_MOUSEBUTTONDOWN:
m_editor->setAdditiveSelection(io.KeyCtrl);
m_editor->setSnapMode(io.KeyShift);
switch (event.button.button)
{
case SDL_BUTTON_LEFT: io.MouseDown[0] = true; break;
case SDL_BUTTON_RIGHT: io.MouseDown[1] = true; break;
case SDL_BUTTON_MIDDLE: io.MouseDown[2] = true; break;
}
break;
case SDL_MOUSEBUTTONUP:
switch (event.button.button)
{
case SDL_BUTTON_LEFT: io.MouseDown[0] = false; break;
case SDL_BUTTON_RIGHT: io.MouseDown[1] = false; break;
case SDL_BUTTON_MIDDLE: io.MouseDown[2] = false; break;
}
break;
case SDL_MOUSEMOTION:
{
auto& input_system = m_editor->getEngine().getInputSystem();
input_system.injectMouseXMove(float(event.motion.xrel));
input_system.injectMouseYMove(float(event.motion.yrel));
if (SDL_GetRelativeMouseMode() == SDL_FALSE)
{
io.MousePos.x = (float)event.motion.x;
io.MousePos.y = (float)event.motion.y;
}
}
break;
case SDL_TEXTINPUT: io.AddInputCharactersUTF8(event.text.text); break;
case SDL_KEYDOWN:
case SDL_KEYUP:
{
int key = event.key.keysym.sym & ~SDLK_SCANCODE_MASK;
io.KeysDown[key] = (event.type == SDL_KEYDOWN);
io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0);
io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0);
io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0);
checkShortcuts();
}
break;
case SDL_MOUSEWHEEL:
{
io.MouseWheel = float(event.wheel.x != 0 ? event.wheel.x : event.wheel.y);
break;
}
}
}
return !want_quit;
}
void run() override void run() override
{ {
checkScriptCommandLine(); checkScriptCommandLine();
@ -1423,24 +1492,12 @@ public:
float frame_time; float frame_time;
{ {
PROFILE_BLOCK("tick"); PROFILE_BLOCK("tick");
if (PlatformInterface::isQuitRequested()) m_finished = m_finished || !processSystemEvents();
{
PlatformInterface::clearQuitRequest();
if (m_editor->isUniverseChanged())
{
m_confirm_exit = true;
}
else
{
m_finished = true;
}
}
m_finished = m_finished || !PlatformInterface::processSystemEvents();
if (!m_finished) update(); if (!m_finished) update();
frame_time = timer->tick(); frame_time = timer->tick();
} }
float wanted_fps = PlatformInterface::isWindowActive() ? 60.0f : 5.0f; float wanted_fps = (SDL_GetWindowFlags(m_window) & SDL_WINDOW_INPUT_FOCUS) != 0 ? 60.0f : 5.0f;
if (frame_time < 1 / wanted_fps) if (frame_time < 1 / wanted_fps)
{ {
PROFILE_BLOCK("sleep"); PROFILE_BLOCK("sleep");
@ -1470,107 +1527,14 @@ public:
} }
struct SystemEventHandler : public PlatformInterface::SystemEventHandler
{
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 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));
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);
m_app->m_editor->setSnapMode(ImGui::GetIO().KeyShift);
ImGui::GetIO().MouseDown[0] = true;
break;
case PlatformInterface::SystemEventHandler::MouseButton::RIGHT:
ImGui::GetIO().MouseDown[1] = true;
break;
case PlatformInterface::SystemEventHandler::MouseButton::MIDDLE:
ImGui::GetIO().MouseDown[2] = true;
break;
}
}
void onMouseButtonUp(MouseButton button) override
{
switch (button)
{
case PlatformInterface::SystemEventHandler::MouseButton::LEFT:
ImGui::GetIO().MouseDown[0] = false;
break;
case PlatformInterface::SystemEventHandler::MouseButton::RIGHT:
ImGui::GetIO().MouseDown[1] = false;
break;
case PlatformInterface::SystemEventHandler::MouseButton::MIDDLE:
ImGui::GetIO().MouseDown[2] = 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) override
{
ImGui::GetIO().AddInputCharacter(key);
}
int m_mouse_x;
int m_mouse_y;
StudioAppImpl* m_app;
};
SystemEventHandler m_handler;
void init() void init()
{ {
checkWorkingDirector(); SDL_SetMainReady();
m_handler.m_app = this; SDL_Init(SDL_INIT_VIDEO);
PlatformInterface::createWindow(nullptr);
checkWorkingDirector();
m_window = SDL_CreateWindow("test", 0, 0, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
char current_dir[Lumix::MAX_PATH_LENGTH]; char current_dir[Lumix::MAX_PATH_LENGTH];
PlatformInterface::getCurrentDirectory(current_dir, Lumix::lengthOf(current_dir)); PlatformInterface::getCurrentDirectory(current_dir, Lumix::lengthOf(current_dir));
@ -1578,7 +1542,17 @@ public:
checkDataDirCommandLine(data_dir_path, Lumix::lengthOf(data_dir_path)); checkDataDirCommandLine(data_dir_path, Lumix::lengthOf(data_dir_path));
m_engine = Lumix::Engine::create(current_dir, data_dir_path, nullptr, m_allocator); m_engine = Lumix::Engine::create(current_dir, data_dir_path, nullptr, m_allocator);
createLua(); createLua();
m_engine->setPlatformData(PlatformInterface::getPlatformData());
SDL_SysWMinfo window_info;
SDL_VERSION(&window_info.version);
SDL_GetWindowWMInfo(m_window, &window_info);
Lumix::Engine::PlatformData platform_data = {};
#ifdef _WIN32
platform_data.window_handle = window_info.info.win.window;
ImGui::GetIO().ImeWindowHandle = window_info.info.win.window;
#endif
m_engine->setPlatformData(platform_data);
m_editor = Lumix::WorldEditor::create(current_dir, *m_engine, m_allocator); m_editor = Lumix::WorldEditor::create(current_dir, *m_engine, m_allocator);
m_settings.m_editor = m_editor; m_settings.m_editor = m_editor;
loadUserPlugins(); loadUserPlugins();
@ -1593,8 +1567,6 @@ public:
initIMGUI(); initIMGUI();
PlatformInterface::setSystemEventHandler(&m_handler);
if (!m_metadata.load()) Lumix::g_log_info.log("Editor") << "Could not load metadata"; if (!m_metadata.load()) Lumix::g_log_info.log("Editor") << "Could not load metadata";
setStudioApp(); setStudioApp();
@ -1603,16 +1575,13 @@ public:
} }
void checkShortcuts() void checkShortcuts()
{ {
if (ImGui::IsAnyItemActive()) return; if (ImGui::IsAnyItemActive()) return;
auto& io = ImGui::GetIO(); int key_count;
bool* keysDown = io.KeysDown; auto* state = SDL_GetKeyboardState(&key_count);
Lumix::uint8 pressed_modifiers = io.KeyCtrl ? 1 : 0; Lumix::uint32 pressed_modifiers = SDL_GetModState() & (KMOD_CTRL | KMOD_ALT | KMOD_SHIFT);
pressed_modifiers |= io.KeyAlt ? 2 : 0;
pressed_modifiers |= io.KeyShift ? 4 : 0;
for (auto* a : m_actions) for (auto* a : m_actions)
{ {
if (!a->is_global || a->shortcut[0] == -1) continue; if (!a->is_global || a->shortcut[0] == -1) continue;
@ -1620,18 +1589,23 @@ public:
Lumix::uint8 action_modifiers = 0; Lumix::uint8 action_modifiers = 0;
for (int i = 0; i < Lumix::lengthOf(a->shortcut) + 1; ++i) for (int i = 0; i < Lumix::lengthOf(a->shortcut) + 1; ++i)
{ {
if ((a->shortcut[i] == -1 || i == Lumix::lengthOf(a->shortcut)) && if ((i == Lumix::lengthOf(a->shortcut) || a->shortcut[i] == -1) &&
action_modifiers == pressed_modifiers) action_modifiers == pressed_modifiers)
{ {
a->func.invoke(); a->func.invoke();
return; return;
} }
if (i == Lumix::lengthOf(a->shortcut)) break;
if (a->shortcut[i] == -1) break; if (a->shortcut[i] == -1) break;
if (!keysDown[a->shortcut[i]]) break; if (a->shortcut[i] >= key_count) break;
if (a->shortcut[i] == (int)PlatformInterface::Keys::CONTROL) action_modifiers |= 1; if (!state[a->shortcut[i]]) break;
else if (a->shortcut[i] == (int)PlatformInterface::Keys::ALT) action_modifiers |= 2; if (a->shortcut[i] == SDL_SCANCODE_LCTRL) action_modifiers |= KMOD_LCTRL;
else if (a->shortcut[i] == (int)PlatformInterface::Keys::SHIFT) action_modifiers |= 4; else if (a->shortcut[i] == SDL_SCANCODE_LALT) action_modifiers |= KMOD_LALT;
else if (a->shortcut[i] == SDL_SCANCODE_LSHIFT) action_modifiers |= KMOD_LSHIFT;
else if (a->shortcut[i] == SDL_SCANCODE_RCTRL) action_modifiers |= KMOD_RCTRL;
else if (a->shortcut[i] == SDL_SCANCODE_RALT) action_modifiers |= KMOD_RALT;
else if (a->shortcut[i] == SDL_SCANCODE_RSHIFT) action_modifiers |= KMOD_RSHIFT;
} }
} }
} }
@ -1645,7 +1619,7 @@ public:
m_settings.m_window.y = y; m_settings.m_window.y = y;
m_settings.m_window.w = width; m_settings.m_window.w = width;
m_settings.m_window.h = height; m_settings.m_window.h = height;
m_settings.m_is_maximized = PlatformInterface::isMaximized(); m_settings.m_is_maximized = (SDL_GetWindowFlags(m_window) & SDL_WINDOW_MAXIMIZED) != 0;
} }
@ -1660,6 +1634,12 @@ public:
} }
SDL_Window* getWindow() override
{
return m_window;
}
Lumix::WorldEditor* getWorldEditor() override Lumix::WorldEditor* getWorldEditor() override
{ {
return m_editor; return m_editor;
@ -1668,6 +1648,7 @@ public:
Lumix::DefaultAllocator m_allocator; Lumix::DefaultAllocator m_allocator;
Lumix::Engine* m_engine; Lumix::Engine* m_engine;
SDL_Window* m_window;
float m_time_to_autosave; float m_time_to_autosave;
Lumix::Array<Action*> m_actions; Lumix::Array<Action*> m_actions;

View file

@ -16,6 +16,9 @@
#endif #endif
struct SDL_Window;
namespace Lumix namespace Lumix
{ {
class WorldEditor; class WorldEditor;
@ -63,6 +66,7 @@ public:
virtual int getExitCode() const = 0; virtual int getExitCode() const = 0;
virtual void runScript(const char* src, const char* script_name) = 0; virtual void runScript(const char* src, const char* script_name) = 0;
virtual Lumix::Array<Action*>& getActions() = 0; virtual Lumix::Array<Action*>& getActions() = 0;
virtual SDL_Window* getWindow() = 0;
virtual ~StudioApp() {} virtual ~StudioApp() {}
virtual void run() = 0; virtual void run() = 0;

View file

@ -5,6 +5,7 @@
#include "engine/delegate.h" #include "engine/delegate.h"
#include "engine/string.h" #include "engine/string.h"
#include "imgui/imgui.h" #include "imgui/imgui.h"
#include <SDL.h>
struct Action struct Action
@ -35,10 +36,11 @@ struct Action
bool isActive() bool isActive()
{ {
if (ImGui::IsAnyItemActive()) return false; if (ImGui::IsAnyItemActive()) return false;
bool* keysDown = ImGui::GetIO().KeysDown;
if (shortcut[0] == -1) return false; if (shortcut[0] == -1) return false;
int key_count;
auto* state = SDL_GetKeyboardState(&key_count);
for (int i = 0; i < Lumix::lengthOf(shortcut) + 1; ++i) for (int i = 0; i < Lumix::lengthOf(shortcut) + 1; ++i)
{ {
if (shortcut[i] == -1 || i == Lumix::lengthOf(shortcut)) if (shortcut[i] == -1 || i == Lumix::lengthOf(shortcut))
@ -46,7 +48,7 @@ struct Action
return true; return true;
} }
if (!keysDown[shortcut[i]]) return false; if (shortcut[i] >= key_count || !state[shortcut[i]]) return false;
} }
return false; return false;
} }

View file

@ -11,49 +11,6 @@
namespace PlatformInterface namespace PlatformInterface
{ {
struct PlatformData
{
PlatformData()
{
m_is_quit_requested = false;
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;
bool m_is_quit_requested;
SystemEventHandler* m_handler;
int m_key_map[512];
int m_system_key_map[512];
};
struct FileIterator struct FileIterator
{ {
HANDLE handle; HANDLE handle;
@ -95,391 +52,11 @@ namespace PlatformInterface
} }
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) void getCurrentDirectory(char* buffer, int buffer_size)
{ {
GetCurrentDirectory(buffer_size, buffer); 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 isWindowActive()
{
return GetActiveWindow() == 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)
{
if (show)
{
while (ShowCursor(true) < 0);
}
else
{
while (ShowCursor(false) >= 0);
}
}
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));
}
}
void clearQuitRequest()
{
g_platform_data.m_is_quit_requested = false;
}
bool isQuitRequested()
{
return g_platform_data.m_is_quit_requested;
}
static LRESULT WINAPI msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (!g_platform_data.m_handler) return DefWindowProc(hWnd, msg, wParam, 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_MBUTTONUP:
g_platform_data.m_handler->onMouseButtonUp(SystemEventHandler::MouseButton::MIDDLE);
break;
case WM_MBUTTONDOWN:
g_platform_data.m_handler->onMouseButtonDown(SystemEventHandler::MouseButton::MIDDLE);
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;
RECT screen_rect;
GetWindowRect(g_platform_data.m_hwnd, &screen_rect);
GetClientRect(g_platform_data.m_hwnd, &rect);
g_platform_data.m_handler->onWindowTransformed(
screen_rect.left, screen_rect.top, rect.right - rect.left, rect.bottom - rect.top);
}
break;
case WM_CLOSE: g_platform_data.m_is_quit_requested = true; return true;
case WM_MOUSELEAVE:
{
g_platform_data.m_is_mouse_tracked = false;
g_platform_data.m_handler->onMouseLeftWindow();
}
break;
case WM_SYSCOMMAND:
{
bool is_alt_key_menu = wParam == SC_KEYMENU && (lParam >> 16) <= 0;
if (is_alt_key_menu) return 0;
break;
}
case WM_KEYUP:
case WM_SYSKEYUP: g_platform_data.m_handler->onKeyUp(getKeyFromSystem((int)wParam)); break;
case WM_KEYDOWN:
case WM_SYSKEYDOWN: g_platform_data.m_handler->onKeyDown(getKeyFromSystem((int)wParam)); break;
case WM_CHAR: g_platform_data.m_handler->onChar((int)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:
case VK_PRIOR:
case VK_NEXT:
case VK_END:
case VK_HOME:
case VK_INSERT:
case VK_DELETE:
case VK_DIVIDE:
case VK_NUMLOCK:
{
scanCode |= 0x100;
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 setSystemEventHandler(SystemEventHandler* handler)
{
g_platform_data.m_handler = handler;
}
Lumix::Engine::PlatformData getPlatformData()
{
Lumix::Engine::PlatformData ret = {};
ret.window_handle = g_platform_data.m_hwnd;
return ret;
}
void* getWindowHandle()
{
return g_platform_data.m_hwnd;
}
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);
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();
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;
}
}
struct Process struct Process
{ {
@ -582,8 +159,6 @@ namespace PlatformInterface
} }
bool getSaveFilename(char* out, int max_size, const char* filter, const char* default_extension) bool getSaveFilename(char* out, int max_size, const char* filter, const char* default_extension)
{ {
OPENFILENAME ofn; OPENFILENAME ofn;

View file

@ -247,6 +247,7 @@ namespace Lumix
virtual void reportError(physx::PxErrorCode::Enum code, const char* message, const char* file, int line); virtual void reportError(physx::PxErrorCode::Enum code, const char* message, const char* file, int line);
}; };
IScene* PhysicsSystemImpl::createScene(Universe& ctx) IScene* PhysicsSystemImpl::createScene(Universe& ctx)
{ {
return PhysicsScene::create(*this, ctx, m_engine, m_allocator); return PhysicsScene::create(*this, ctx, m_engine, m_allocator);
@ -312,23 +313,20 @@ namespace Lumix
bool PhysicsSystemImpl::connect2VisualDebugger() bool PhysicsSystemImpl::connect2VisualDebugger()
{ {
if (m_physics->getPvdConnectionManager() == nullptr) if (m_physics->getPvdConnectionManager() == nullptr) return false;
return false;
const char* pvd_host_ip = "127.0.0.1"; const char* pvd_host_ip = "127.0.0.1";
int port = 5425; int port = 5425;
unsigned int timeout = 100; unsigned int timeout = 100;
physx::PxVisualDebuggerConnectionFlags connectionFlags = physx::PxVisualDebuggerExt::getAllConnectionFlags(); physx::PxVisualDebuggerConnectionFlags connectionFlags = physx::PxVisualDebuggerExt::getAllConnectionFlags();
auto* theConnection = physx::PxVisualDebuggerExt::createConnection(m_physics->getPvdConnectionManager(), pvd_host_ip, port, timeout, connectionFlags); auto* theConnection = physx::PxVisualDebuggerExt::createConnection(
m_physics->getPvdConnectionManager(), pvd_host_ip, port, timeout, connectionFlags);
return theConnection != nullptr; return theConnection != nullptr;
} }
void CustomErrorCallback::reportError(physx::PxErrorCode::Enum, void CustomErrorCallback::reportError(physx::PxErrorCode::Enum, const char* message, const char*, int)
const char* message,
const char*,
int)
{ {
g_log_error.log("Physics") << message; g_log_error.log("Physics") << message;
} }

View file

@ -1,5 +1,5 @@
#include "game_view.h" #include "game_view.h"
#include "editor/platform_interface.h" #include "editor/studio_app.h"
#include "engine/crc32.h" #include "engine/crc32.h"
#include "engine/input_system.h" #include "engine/input_system.h"
#include "engine/profiler.h" #include "engine/profiler.h"
@ -12,10 +12,12 @@
#include "renderer/render_scene.h" #include "renderer/render_scene.h"
#include "renderer/renderer.h" #include "renderer/renderer.h"
#include "renderer/texture.h" #include "renderer/texture.h"
#include <SDL.h>
GameView::GameView() GameView::GameView(StudioApp& app)
: m_is_opened(true) : m_studio_app(app)
, m_is_opened(true)
, m_pipeline(nullptr) , m_pipeline(nullptr)
, m_is_mouse_captured(false) , m_is_mouse_captured(false)
, m_editor(nullptr) , m_editor(nullptr)
@ -78,8 +80,8 @@ void GameView::captureMouse(bool capture)
{ {
m_is_mouse_captured = capture; m_is_mouse_captured = capture;
m_editor->getEngine().getInputSystem().enable(m_is_mouse_captured); m_editor->getEngine().getInputSystem().enable(m_is_mouse_captured);
PlatformInterface::showCursor(!m_is_mouse_captured); SDL_ShowCursor(m_is_mouse_captured ? 0 : 1);
if (!m_is_mouse_captured) PlatformInterface::unclipCursor(); SDL_SetRelativeMouseMode(capture ? SDL_TRUE : SDL_FALSE);
} }
@ -90,9 +92,9 @@ void GameView::onGui()
auto& io = ImGui::GetIO(); auto& io = ImGui::GetIO();
bool is_foreground_win = PlatformInterface::isWindowActive(); bool is_focus = (SDL_GetWindowFlags(m_studio_app.getWindow()) & SDL_WINDOW_INPUT_FOCUS) != 0;
if (m_is_mouse_captured && (io.KeysDown[ImGui::GetKeyIndex(ImGuiKey_Escape)] || if (m_is_mouse_captured &&
!m_editor->isGameMode() || !is_foreground_win)) (io.KeysDown[ImGui::GetKeyIndex(ImGuiKey_Escape)] || !m_editor->isGameMode() || !is_focus))
{ {
captureMouse(false); captureMouse(false);
} }
@ -138,9 +140,6 @@ void GameView::onGui()
if (m_is_mouse_captured) if (m_is_mouse_captured)
{ {
PlatformInterface::clipCursor(
content_min.x, content_min.y, content_max.x, content_max.y);
if (io.KeysDown[ImGui::GetKeyIndex(ImGuiKey_Escape)] || !m_editor->isGameMode()) if (io.KeysDown[ImGui::GetKeyIndex(ImGuiKey_Escape)] || !m_editor->isGameMode())
{ {
captureMouse(false); captureMouse(false);

View file

@ -6,6 +6,7 @@
struct PlatformData; struct PlatformData;
class StudioApp;
namespace Lumix namespace Lumix
@ -19,7 +20,7 @@ namespace Lumix
class GameView class GameView
{ {
public: public:
GameView(); GameView(StudioApp& app);
~GameView(); ~GameView();
void init(Lumix::WorldEditor& editor); void init(Lumix::WorldEditor& editor);
@ -27,12 +28,12 @@ public:
void onGui(); void onGui();
void setScene(Lumix::RenderScene* scene); void setScene(Lumix::RenderScene* scene);
bool isMouseCaptured() const { return m_is_mouse_captured; } bool isMouseCaptured() const { return m_is_mouse_captured; }
void captureMouse(bool capture);
public: public:
bool m_is_opened; bool m_is_opened;
private: private:
void captureMouse(bool capture);
void onUniverseCreated(); void onUniverseCreated();
void onUniverseDestroyed(); void onUniverseDestroyed();
@ -44,4 +45,5 @@ private:
bool m_is_mouse_hovering_window; bool m_is_mouse_hovering_window;
float m_time_multiplier; float m_time_multiplier;
bool m_paused; bool m_paused;
StudioApp& m_studio_app;
}; };

View file

@ -39,6 +39,7 @@
#include "shader_compiler.h" #include "shader_compiler.h"
#include "terrain_editor.h" #include "terrain_editor.h"
#include <cmath> #include <cmath>
#include <SDL.h>
using namespace Lumix; using namespace Lumix;
@ -482,8 +483,8 @@ struct ModelPlugin : public AssetBrowser::IPlugin
if (m_is_mouse_captured && !mouse_down) if (m_is_mouse_captured && !mouse_down)
{ {
m_is_mouse_captured = false; m_is_mouse_captured = false;
PlatformInterface::showCursor(true); SDL_ShowCursor(1);
PlatformInterface::unclipCursor(); SDL_SetRelativeMouseMode(SDL_FALSE);
} }
if (ImGui::IsItemHovered() && mouse_down) if (ImGui::IsItemHovered() && mouse_down)
@ -494,10 +495,10 @@ struct ModelPlugin : public AssetBrowser::IPlugin
if (!m_is_mouse_captured) if (!m_is_mouse_captured)
{ {
m_is_mouse_captured = true; m_is_mouse_captured = true;
PlatformInterface::showCursor(false); SDL_ShowCursor(0);
} }
PlatformInterface::clipCursor(content_min.x, content_min.y, content_max.x, content_max.y); SDL_SetRelativeMouseMode(SDL_TRUE);
if (delta.x != 0 || delta.y != 0) if (delta.x != 0 || delta.y != 0)
{ {
@ -1163,6 +1164,7 @@ struct GameViewPlugin : public StudioApp::IPlugin
explicit GameViewPlugin(StudioApp& app) explicit GameViewPlugin(StudioApp& app)
: m_app(app) : m_app(app)
, m_game_view(app)
{ {
m_width = m_height = -1; m_width = m_height = -1;
auto& editor = *app.getWorldEditor(); auto& editor = *app.getWorldEditor();
@ -1178,8 +1180,8 @@ struct GameViewPlugin : public StudioApp::IPlugin
m_gui_pipeline = Pipeline::create(*renderer, path, m_engine->getAllocator()); m_gui_pipeline = Pipeline::create(*renderer, path, m_engine->getAllocator());
m_gui_pipeline->load(); m_gui_pipeline->load();
int w = PlatformInterface::getWindowWidth(); int w, h;
int h = PlatformInterface::getWindowHeight(); SDL_GetWindowSize(m_app.getWindow(), &w, &h);
m_gui_pipeline->setViewport(0, 0, w, h); m_gui_pipeline->setViewport(0, 0, w, h);
renderer->resize(w, h); renderer->resize(w, h);
onUniverseCreated(); onUniverseCreated();
@ -1237,8 +1239,8 @@ struct GameViewPlugin : public StudioApp::IPlugin
if (!m_material || !m_material->isReady()) return; if (!m_material || !m_material->isReady()) return;
if (!m_material->getTexture(0)) return; if (!m_material->getTexture(0)) return;
int w = PlatformInterface::getWindowWidth(); int w, h;
int h = PlatformInterface::getWindowHeight(); SDL_GetWindowSize(m_app.getWindow(), &w, &h);
if (w != m_width || h != m_height) if (w != m_width || h != m_height)
{ {
m_width = w; m_width = w;

View file

@ -1,14 +1,14 @@
#include "scene_view.h" #include "scene_view.h"
#include "editor/gizmo.h"
#include "editor/log_ui.h"
#include "editor/platform_interface.h"
#include "editor/settings.h"
#include "engine/crc32.h" #include "engine/crc32.h"
#include "engine/input_system.h" #include "engine/input_system.h"
#include "engine/path.h" #include "engine/path.h"
#include "engine/profiler.h" #include "engine/profiler.h"
#include "engine/resource_manager.h" #include "engine/resource_manager.h"
#include "engine/string.h" #include "engine/string.h"
#include "editor/gizmo.h"
#include "editor/log_ui.h"
#include "editor/platform_interface.h"
#include "editor/settings.h"
#include "engine/engine.h" #include "engine/engine.h"
#include "engine/plugin_manager.h" #include "engine/plugin_manager.h"
#include "imgui/imgui.h" #include "imgui/imgui.h"
@ -16,6 +16,7 @@
#include "renderer/pipeline.h" #include "renderer/pipeline.h"
#include "renderer/render_scene.h" #include "renderer/render_scene.h"
#include "renderer/renderer.h" #include "renderer/renderer.h"
#include <SDL.h>
SceneView::SceneView() SceneView::SceneView()
@ -127,14 +128,14 @@ void SceneView::update()
if (!m_is_opened) return; if (!m_is_opened) return;
if (ImGui::GetIO().KeyCtrl) return; if (ImGui::GetIO().KeyCtrl) return;
m_camera_speed = Lumix::Math::maximum(0.01f, m_camera_speed + ImGui::GetIO().MouseWheel / 20.0f);
int screen_x = int(ImGui::GetIO().MousePos.x); int screen_x = int(ImGui::GetIO().MousePos.x);
int screen_y = int(ImGui::GetIO().MousePos.y); int screen_y = int(ImGui::GetIO().MousePos.y);
bool is_inside = screen_x >= m_screen_x && screen_y >= m_screen_y && screen_x <= m_screen_x + m_width && bool is_inside = screen_x >= m_screen_x && screen_y >= m_screen_y && screen_x <= m_screen_x + m_width &&
screen_y <= m_screen_y + m_height; screen_y <= m_screen_y + m_height;
if (!is_inside) return; if (!is_inside) return;
m_camera_speed = Lumix::Math::maximum(0.01f, m_camera_speed + ImGui::GetIO().MouseWheel / 20.0f);
float speed = m_camera_speed; float speed = m_camera_speed;
if (ImGui::GetIO().KeyShift) speed *= 10; if (ImGui::GetIO().KeyShift) speed *= 10;
if (m_move_forward_action->isActive()) m_editor->navigate(1.0f, 0, 0, speed); if (m_move_forward_action->isActive()) m_editor->navigate(1.0f, 0, 0, speed);
@ -162,8 +163,8 @@ void SceneView::captureMouse(bool capture)
{ {
if(m_is_mouse_captured == capture) return; if(m_is_mouse_captured == capture) return;
m_is_mouse_captured = capture; m_is_mouse_captured = capture;
PlatformInterface::showCursor(!m_is_mouse_captured); SDL_ShowCursor(m_is_mouse_captured ? 0 : 1);
if(!m_is_mouse_captured) PlatformInterface::unclipCursor(); SDL_SetRelativeMouseMode(capture ? SDL_TRUE : SDL_FALSE);
} }
@ -178,7 +179,7 @@ void SceneView::onGUI()
title = "Scene View | errors in log###Scene View"; title = "Scene View | errors in log###Scene View";
} }
if (ImGui::BeginDock(title)) if (ImGui::BeginDock(title, nullptr, ImGuiWindowFlags_NoScrollWithMouse))
{ {
m_is_opened = true; m_is_opened = true;
auto size = ImGui::GetContentRegionAvail(); auto size = ImGui::GetContentRegionAvail();
@ -209,7 +210,7 @@ void SceneView::onGUI()
if (ImGui::IsMouseClicked(i)) if (ImGui::IsMouseClicked(i))
{ {
ImGui::ResetActiveID(); ImGui::ResetActiveID();
captureMouse(true); if(i == 1) captureMouse(true);
m_editor->onMouseDown((int)rel_mp.x, (int)rel_mp.y, (Lumix::MouseButton::Value)i); m_editor->onMouseDown((int)rel_mp.x, (int)rel_mp.y, (Lumix::MouseButton::Value)i);
break; break;
} }
@ -224,19 +225,15 @@ void SceneView::onGUI()
m_editor->onMouseMove((int)rel_mp.x, (int)rel_mp.y, (int)delta.x, (int)delta.y); m_editor->onMouseMove((int)rel_mp.x, (int)rel_mp.y, (int)delta.x, (int)delta.y);
} }
} }
if(m_is_mouse_captured) for (int i = 0; i < 3; ++i)
{ {
PlatformInterface::clipCursor(content_min.x, content_min.y, content_max.x, content_max.y); auto rel_mp = ImGui::GetMousePos();
for (int i = 0; i < 3; ++i) rel_mp.x -= m_screen_x;
rel_mp.y -= m_screen_y;
if (ImGui::IsMouseReleased(i))
{ {
auto rel_mp = ImGui::GetMousePos(); if (i == 1) captureMouse(false);
rel_mp.x -= m_screen_x; m_editor->onMouseUp((int)rel_mp.x, (int)rel_mp.y, (Lumix::MouseButton::Value)i);
rel_mp.y -= m_screen_y;
if (ImGui::IsMouseReleased(i))
{
captureMouse(false);
m_editor->onMouseUp((int)rel_mp.x, (int)rel_mp.y, (Lumix::MouseButton::Value)i);
}
} }
} }
m_pipeline->render(); m_pipeline->render();