implement cursor change for win32
This commit is contained in:
parent
bd63bde722
commit
f21927e8d9
2
TODO
2
TODO
|
@ -41,8 +41,6 @@ review usage of x,y/width,height in lua instead of point/size
|
||||||
|
|
||||||
== Platform
|
== Platform
|
||||||
port to MacOs and iphone
|
port to MacOs and iphone
|
||||||
change win32 mouse cursor icon
|
|
||||||
rework win32 key input system
|
|
||||||
|
|
||||||
== UI
|
== UI
|
||||||
[bart] multiline rich text widget
|
[bart] multiline rich text widget
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
function setTargetCursor()
|
function setTargetCursor()
|
||||||
g_window.setMouseCursor('/core_styles/icons/targetcursor.png')
|
g_window.setMouseCursor('/core_styles/icons/targetcursor.png', {x=9,y=9})
|
||||||
end
|
end
|
||||||
|
|
||||||
function restoreCursor()
|
function restoreCursor()
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 256 B After Width: | Height: | Size: 266 B |
|
@ -1,7 +1,7 @@
|
||||||
function UIItem:onDragEnter(mousePos)
|
function UIItem:onDragEnter(mousePos)
|
||||||
local item = self:getItem()
|
local item = self:getItem()
|
||||||
if not item then return false end
|
if not item then return false end
|
||||||
|
|
||||||
self.currentDragThing = item
|
self.currentDragThing = item
|
||||||
setTargetCursor()
|
setTargetCursor()
|
||||||
return true
|
return true
|
||||||
|
@ -15,10 +15,10 @@ end
|
||||||
|
|
||||||
function UIItem:onDrop(widget, mousePos)
|
function UIItem:onDrop(widget, mousePos)
|
||||||
if not widget or not widget.currentDragThing then return false end
|
if not widget or not widget.currentDragThing then return false end
|
||||||
|
|
||||||
local pos = self.position
|
local pos = self.position
|
||||||
local count = 1 -- todo make a window for it
|
local count = 1 -- todo make a window for it
|
||||||
|
|
||||||
Game.move(widget.currentDragThing, pos, count)
|
Game.move(widget.currentDragThing, pos, count)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
|
@ -391,7 +391,7 @@ void Application::registerLuaFunctions()
|
||||||
g_lua.bindClassStaticFunction("g_window", "showMouse", std::bind(&PlatformWindow::showMouse, &g_window));
|
g_lua.bindClassStaticFunction("g_window", "showMouse", std::bind(&PlatformWindow::showMouse, &g_window));
|
||||||
g_lua.bindClassStaticFunction("g_window", "hideMouse", std::bind(&PlatformWindow::hideMouse, &g_window));
|
g_lua.bindClassStaticFunction("g_window", "hideMouse", std::bind(&PlatformWindow::hideMouse, &g_window));
|
||||||
g_lua.bindClassStaticFunction("g_window", "setTitle", std::bind(&PlatformWindow::setTitle, &g_window, _1));
|
g_lua.bindClassStaticFunction("g_window", "setTitle", std::bind(&PlatformWindow::setTitle, &g_window, _1));
|
||||||
g_lua.bindClassStaticFunction("g_window", "setMouseCursor", std::bind(&PlatformWindow::setMouseCursor, &g_window, _1));
|
g_lua.bindClassStaticFunction("g_window", "setMouseCursor", std::bind(&PlatformWindow::setMouseCursor, &g_window, _1, _2));
|
||||||
g_lua.bindClassStaticFunction("g_window", "setMinimumSize", std::bind(&PlatformWindow::setMinimumSize, &g_window, _1));
|
g_lua.bindClassStaticFunction("g_window", "setMinimumSize", std::bind(&PlatformWindow::setMinimumSize, &g_window, _1));
|
||||||
g_lua.bindClassStaticFunction("g_window", "setFullscreen", std::bind(&PlatformWindow::setFullscreen, &g_window, _1));
|
g_lua.bindClassStaticFunction("g_window", "setFullscreen", std::bind(&PlatformWindow::setFullscreen, &g_window, _1));
|
||||||
g_lua.bindClassStaticFunction("g_window", "setVerticalSync", std::bind(&PlatformWindow::setVerticalSync, &g_window, _1));
|
g_lua.bindClassStaticFunction("g_window", "setVerticalSync", std::bind(&PlatformWindow::setVerticalSync, &g_window, _1));
|
||||||
|
|
|
@ -53,7 +53,7 @@ public:
|
||||||
virtual void hideMouse() = 0;
|
virtual void hideMouse() = 0;
|
||||||
virtual void displayFatalError(const std::string& message) { }
|
virtual void displayFatalError(const std::string& message) { }
|
||||||
|
|
||||||
virtual void setMouseCursor(const std::string& file) = 0;
|
virtual void setMouseCursor(const std::string& file, const Point& hotSpot) = 0;
|
||||||
virtual void setTitle(const std::string& title) = 0;
|
virtual void setTitle(const std::string& title) = 0;
|
||||||
virtual void setMinimumSize(const Size& minimumSize) = 0;
|
virtual void setMinimumSize(const Size& minimumSize) = 0;
|
||||||
virtual void setFullscreen(bool fullscreen) = 0;
|
virtual void setFullscreen(bool fullscreen) = 0;
|
||||||
|
|
|
@ -33,6 +33,7 @@ WIN32Window::WIN32Window()
|
||||||
m_instance = 0;
|
m_instance = 0;
|
||||||
m_deviceContext = 0;
|
m_deviceContext = 0;
|
||||||
m_glContext = 0;
|
m_glContext = 0;
|
||||||
|
m_cursor = 0;
|
||||||
m_maximized = false;
|
m_maximized = false;
|
||||||
m_minimumSize = Size(16,16);
|
m_minimumSize = Size(16,16);
|
||||||
m_size = m_minimumSize;
|
m_size = m_minimumSize;
|
||||||
|
@ -226,6 +227,11 @@ void WIN32Window::terminate()
|
||||||
m_deviceContext = NULL;
|
m_deviceContext = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(m_cursor) {
|
||||||
|
DestroyCursor(m_cursor);
|
||||||
|
m_cursor = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if(m_window) {
|
if(m_window) {
|
||||||
if(!DestroyWindow(m_window))
|
if(!DestroyWindow(m_window))
|
||||||
logError("ERROR: Destroy window failed.");
|
logError("ERROR: Destroy window failed.");
|
||||||
|
@ -248,6 +254,7 @@ struct WindowProcProxy {
|
||||||
|
|
||||||
void WIN32Window::internalRegisterWindowClass()
|
void WIN32Window::internalRegisterWindowClass()
|
||||||
{
|
{
|
||||||
|
m_defaultCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
WNDCLASSA wc;
|
WNDCLASSA wc;
|
||||||
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
||||||
wc.lpfnWndProc = (WNDPROC)WindowProcProxy::call;
|
wc.lpfnWndProc = (WNDPROC)WindowProcProxy::call;
|
||||||
|
@ -255,7 +262,7 @@ void WIN32Window::internalRegisterWindowClass()
|
||||||
wc.cbWndExtra = 0;
|
wc.cbWndExtra = 0;
|
||||||
wc.hInstance = m_instance;
|
wc.hInstance = m_instance;
|
||||||
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
|
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
|
||||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
wc.hCursor = m_defaultCursor;
|
||||||
wc.hbrBackground = NULL;
|
wc.hbrBackground = NULL;
|
||||||
wc.lpszMenuName = NULL;
|
wc.lpszMenuName = NULL;
|
||||||
wc.lpszClassName = g_app->getAppName().c_str();
|
wc.lpszClassName = g_app->getAppName().c_str();
|
||||||
|
@ -352,12 +359,16 @@ void *WIN32Window::getExtensionProcAddress(const char *ext)
|
||||||
|
|
||||||
void WIN32Window::move(const Point& pos)
|
void WIN32Window::move(const Point& pos)
|
||||||
{
|
{
|
||||||
MoveWindow(m_window, pos.x, pos.y, m_size.width(), m_size.height(), TRUE);
|
RECT windowRect = {pos.x, pos.y, m_pos.x + m_size.width(), m_pos.y + m_size.height()};
|
||||||
|
AdjustWindowRectEx(&windowRect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE);
|
||||||
|
MoveWindow(m_window, windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WIN32Window::resize(const Size& size)
|
void WIN32Window::resize(const Size& size)
|
||||||
{
|
{
|
||||||
MoveWindow(m_window, m_pos.x, m_pos.y, size.width(), size.height(), TRUE);
|
RECT windowRect = {m_pos.x, m_pos.y, m_pos.x + size.width(), m_pos.y + size.height()};
|
||||||
|
AdjustWindowRectEx(&windowRect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE);
|
||||||
|
MoveWindow(m_window, windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WIN32Window::show()
|
void WIN32Window::show()
|
||||||
|
@ -399,6 +410,13 @@ LRESULT WIN32Window::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
||||||
{
|
{
|
||||||
switch(uMsg)
|
switch(uMsg)
|
||||||
{
|
{
|
||||||
|
case WM_SETCURSOR: {
|
||||||
|
if(m_cursor)
|
||||||
|
SetCursor(m_cursor);
|
||||||
|
else
|
||||||
|
SetCursor(m_defaultCursor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case WM_ACTIVATE: {
|
case WM_ACTIVATE: {
|
||||||
m_focused = !(wParam == WA_INACTIVE);
|
m_focused = !(wParam == WA_INACTIVE);
|
||||||
break;
|
break;
|
||||||
|
@ -518,16 +536,24 @@ void WIN32Window::swapBuffers()
|
||||||
|
|
||||||
void WIN32Window::restoreMouseCursor()
|
void WIN32Window::restoreMouseCursor()
|
||||||
{
|
{
|
||||||
//TODO
|
logTraceDebug();
|
||||||
|
if(m_cursor) {
|
||||||
|
DestroyCursor(m_cursor);
|
||||||
|
m_cursor = NULL;
|
||||||
|
SetCursor(m_defaultCursor);
|
||||||
|
ShowCursor(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WIN32Window::showMouse()
|
void WIN32Window::showMouse()
|
||||||
{
|
{
|
||||||
|
logTraceDebug();
|
||||||
ShowCursor(true);
|
ShowCursor(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WIN32Window::hideMouse()
|
void WIN32Window::hideMouse()
|
||||||
{
|
{
|
||||||
|
logTraceDebug();
|
||||||
ShowCursor(false);
|
ShowCursor(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,9 +562,60 @@ void WIN32Window::displayFatalError(const std::string& message)
|
||||||
MessageBoxA(m_window, message.c_str(), "FATAL ERROR", MB_OK | MB_ICONERROR);
|
MessageBoxA(m_window, message.c_str(), "FATAL ERROR", MB_OK | MB_ICONERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WIN32Window::setMouseCursor(const std::string& file)
|
#define LSB_BIT_SET(p, n) (p[(n)/8] |= (1 <<((n)%8)))
|
||||||
{
|
#define HSB_BIT_SET(p, n) (p[(n)/8] |= (128 >>((n)%8)))
|
||||||
|
|
||||||
|
void WIN32Window::setMouseCursor(const std::string& file, const Point& hotSpot)
|
||||||
|
{
|
||||||
|
logTraceDebug();
|
||||||
|
std::stringstream fin;
|
||||||
|
g_resources.loadFile(file, fin);
|
||||||
|
|
||||||
|
apng_data apng;
|
||||||
|
if(load_apng(fin, &apng) != 0) {
|
||||||
|
logTraceError("unable to load png file ", file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(apng.bpp != 4) {
|
||||||
|
logError("the cursor png must have 4 channels");
|
||||||
|
free_apng(&apng);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(apng.width != 32|| apng.height != 32) {
|
||||||
|
logError("the cursor png must have 32x32 dimension");
|
||||||
|
free_apng(&apng);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_cursor != NULL)
|
||||||
|
DestroyCursor(m_cursor);
|
||||||
|
|
||||||
|
int width = apng.width;
|
||||||
|
int height = apng.height;
|
||||||
|
int numbits = width * height;
|
||||||
|
int numbytes = (width * height)/8;
|
||||||
|
|
||||||
|
std::vector<uchar> andMask(numbytes, 0);
|
||||||
|
std::vector<uchar> xorMask(numbytes, 0);
|
||||||
|
|
||||||
|
for(int i=0;i<numbits;++i) {
|
||||||
|
uchar r = apng.pdata[i*4+0];
|
||||||
|
uchar g = apng.pdata[i*4+1];
|
||||||
|
uchar b = apng.pdata[i*4+2];
|
||||||
|
uchar a = apng.pdata[i*4+3];
|
||||||
|
Color color(r,g,b,a);
|
||||||
|
if(color == Fw::white) { //white
|
||||||
|
HSB_BIT_SET(xorMask, i);
|
||||||
|
} else if(color == Fw::alpha) { //alpha
|
||||||
|
HSB_BIT_SET(andMask, i);
|
||||||
|
} //otherwise black
|
||||||
|
}
|
||||||
|
free_apng(&apng);
|
||||||
|
|
||||||
|
m_cursor = CreateCursor(m_instance, hotSpot.x, hotSpot.y, width, height, &andMask[0], &xorMask[0]);
|
||||||
|
SetCursor(m_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WIN32Window::setTitle(const std::string& title)
|
void WIN32Window::setTitle(const std::string& title)
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
void hideMouse();
|
void hideMouse();
|
||||||
void displayFatalError(const std::string& message);
|
void displayFatalError(const std::string& message);
|
||||||
|
|
||||||
void setMouseCursor(const std::string& file);
|
void setMouseCursor(const std::string& file, const Point& hotSpot);
|
||||||
void setTitle(const std::string& title);
|
void setTitle(const std::string& title);
|
||||||
void setMinimumSize(const Size& minimumSize);
|
void setMinimumSize(const Size& minimumSize);
|
||||||
void setFullscreen(bool fullscreen);
|
void setFullscreen(bool fullscreen);
|
||||||
|
@ -80,6 +80,8 @@ private:
|
||||||
HINSTANCE m_instance;
|
HINSTANCE m_instance;
|
||||||
HDC m_deviceContext;
|
HDC m_deviceContext;
|
||||||
HGLRC m_glContext;
|
HGLRC m_glContext;
|
||||||
|
HCURSOR m_cursor;
|
||||||
|
HCURSOR m_defaultCursor;
|
||||||
bool m_maximized;
|
bool m_maximized;
|
||||||
Size m_minimumSize;
|
Size m_minimumSize;
|
||||||
};
|
};
|
||||||
|
|
|
@ -769,7 +769,7 @@ void X11Window::restoreMouseCursor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Window::setMouseCursor(const std::string& file)
|
void X11Window::setMouseCursor(const std::string& file, const Point& hotSpot)
|
||||||
{
|
{
|
||||||
std::stringstream fin;
|
std::stringstream fin;
|
||||||
g_resources.loadFile(file, fin);
|
g_resources.loadFile(file, fin);
|
||||||
|
@ -786,8 +786,8 @@ void X11Window::setMouseCursor(const std::string& file)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(apng.width % 8 != 0 || apng.height % 8 != 0) {
|
if(apng.width != 32|| apng.height != 32) {
|
||||||
logError("the cursor png must have dimensions multiple of 8");
|
logError("the cursor png must have 32x32 dimension");
|
||||||
free_apng(&apng);
|
free_apng(&apng);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -828,7 +828,7 @@ void X11Window::setMouseCursor(const std::string& file)
|
||||||
|
|
||||||
Pixmap cp = XCreateBitmapFromData(m_display, m_window, (char*)&mapBits[0], width, height);
|
Pixmap cp = XCreateBitmapFromData(m_display, m_window, (char*)&mapBits[0], width, height);
|
||||||
Pixmap mp = XCreateBitmapFromData(m_display, m_window, (char*)&maskBits[0], width, height);
|
Pixmap mp = XCreateBitmapFromData(m_display, m_window, (char*)&maskBits[0], width, height);
|
||||||
m_cursor = XCreatePixmapCursor(m_display, cp, mp, &fg, &bg, width/2, height/2);
|
m_cursor = XCreatePixmapCursor(m_display, cp, mp, &fg, &bg, hotSpot.x, hotSpot.y);
|
||||||
XDefineCursor(m_display, m_window, m_cursor);
|
XDefineCursor(m_display, m_window, m_cursor);
|
||||||
XFreePixmap(m_display, cp);
|
XFreePixmap(m_display, cp);
|
||||||
XFreePixmap(m_display, mp);
|
XFreePixmap(m_display, mp);
|
||||||
|
|
|
@ -67,7 +67,7 @@ public:
|
||||||
void showMouse();
|
void showMouse();
|
||||||
void hideMouse();
|
void hideMouse();
|
||||||
|
|
||||||
void setMouseCursor(const std::string& file);
|
void setMouseCursor(const std::string& file, const Point& hotSpot);
|
||||||
void setTitle(const std::string& title);
|
void setTitle(const std::string& title);
|
||||||
void setMinimumSize(const Size& minimumSize);
|
void setMinimumSize(const Size& minimumSize);
|
||||||
void setFullscreen(bool fullscreen);
|
void setFullscreen(bool fullscreen);
|
||||||
|
|
Loading…
Reference in New Issue