simplify window API even more

This commit is contained in:
UnknownShadow200 2019-02-11 21:41:10 +11:00
parent 1bb2e71518
commit 8e77126afa
8 changed files with 94 additions and 151 deletions

View File

@ -39,9 +39,8 @@ static void PerspectiveCamera_GetPickedBlock(struct PickedPos* pos) {
static Point2D cam_prev, cam_delta;
static void PerspectiveCamera_CentreMousePosition(void) {
Point2D topLeft = Window_PointToScreen(0, 0);
int cenX = topLeft.X + Game.Width / 2;
int cenY = topLeft.Y + Game.Height / 2;
int cenX = Window_ClientBounds.X + Game.Width / 2;
int cenY = Window_ClientBounds.Y + Game.Height / 2;
Cursor_SetScreenPos(cenX, cenY);
/* Fixes issues with large DPI displays on Windows >= 8.0. */

View File

@ -260,14 +260,13 @@ bool Game_ValidateBitmap(const String* file, Bitmap* bmp) {
return true;
}
void Game_UpdateClientSize(void) {
Size2D size = Window_ClientSize;
Game.Width = max(size.Width, 1);
Game.Height = max(size.Height, 1);
void Game_UpdateDimensions(void) {
Game.Width = max(Window_ClientBounds.Width, 1);
Game.Height = max(Window_ClientBounds.Height, 1);
}
static void Game_OnResize(void* obj) {
Game_UpdateClientSize();
Game_UpdateDimensions();
Gfx_OnWindowResize();
Game_UpdateProjection();
Gui_OnResize();
@ -431,7 +430,7 @@ static void Game_Load(void) {
Gfx_MakeApiInfo();
Gfx.Mipmaps = Options_GetBool(OPT_MIPMAPS, false);
Game_UpdateClientSize();
Game_UpdateDimensions();
Game_LoadOptions();
Event_RegisterVoid(&WorldEvents.NewMap, NULL, Game_OnNewMapCore);

View File

@ -85,7 +85,7 @@ bool Game_UpdateTexture(GfxResourceID* texId, struct Stream* src, const String*
/* (must be power of two size and be <= Gfx_MaxTexWidth/Gfx_MaxHeight) */
bool Game_ValidateBitmap(const String* file, Bitmap* bmp);
/* Updates Game_Width and Game_Height. */
void Game_UpdateClientSize(void);
void Game_UpdateDimensions(void);
/* Sets the strategy/method used to limit frames per second. */
void Game_SetFpsLimit(enum FpsLimit method);
/* Returns max time process sleeps for when limiting frames using the given method. */

View File

@ -101,7 +101,7 @@ static void Launcher_ReqeustRedraw(void* obj) {
}
static void Launcher_OnResize(void* obj) {
Game_UpdateClientSize();
Game_UpdateDimensions();
Launcher_Framebuffer.Width = Game.Width;
Launcher_Framebuffer.Height = Game.Height;
@ -219,7 +219,7 @@ void Launcher_Run(void) {
Window_SetVisible(true);
Drawer2D_Component.Init();
Game_UpdateClientSize();
Game_UpdateDimensions();
Drawer2D_BitmappedText = false;
Drawer2D_BlackTextShadows = true;

View File

@ -114,9 +114,9 @@ int main(int argc, char** argv) {
argsCount = Platform_GetCommandLineArgs(argc, argv, args);
/* NOTE: Make sure to comment this out before pushing a commit */
/* String rawArgs = String_FromConst("UnknownShadow200 fffff 127.0.0.1 25565"); */
String rawArgs = String_FromConst("UnknownShadow200 fffff 127.0.0.1 25565");
/* String rawArgs = String_FromConst("UnknownShadow200"); */
/* argsCount = String_UNSAFE_Split(&rawArgs, ' ', args, 4); */
argsCount = String_UNSAFE_Split(&rawArgs, ' ', args, 4);
if (argsCount == 0) {
Launcher_Run();

View File

@ -536,7 +536,6 @@ static void TableWidget_UpdateScrollbarPos(struct TableWidget* w) {
}
static void TableWidget_MoveCursorToSelected(struct TableWidget* w) {
Point2D topLeft;
int x, y, idx;
if (w->SelectedIndex == -1) return;
@ -544,8 +543,8 @@ static void TableWidget_MoveCursorToSelected(struct TableWidget* w) {
TableWidget_GetCoords(w, idx, &x, &y);
x += w->CellSize / 2; y += w->CellSize / 2;
topLeft = Window_PointToScreen(0, 0);
x += topLeft.X; y += topLeft.Y;
x += Window_ClientBounds.X;
y += Window_ClientBounds.Y;
Cursor_SetScreenPos(x, y);
}
@ -1162,9 +1161,6 @@ static bool InputWidget_OtherKey(struct InputWidget* w, Key key) {
String_InitArray(text, textBuffer);
Window_GetClipboardText(&text);
String_UNSAFE_TrimStart(&text);
String_UNSAFE_TrimEnd(&text);
if (!text.length) return true;
InputWidget_AppendString(w, &text);
return true;

View File

@ -6,8 +6,7 @@
#include "Funcs.h"
bool Window_Exists, Window_Focused;
Rect2D Window_Bounds;
Size2D Window_ClientSize;
Rect2D Window_Bounds, Window_ClientBounds;
static bool win_cursorVisible = true;
bool Cursor_GetVisible(void) { return win_cursorVisible; }
@ -136,11 +135,26 @@ static void Window_SetHiddenBorder(bool hidden) {
suppress_resize--;
}
static void Window_UpdateClientSize(HWND handle) {
static CC_INLINE void Window_SetRect(Rect2D* dst, const RECT* src) {
dst->X = src->left;
dst->Y = src->top;
dst->Width = src->right - src->left;
dst->Height = src->bottom - src->top;
}
static void Window_RefreshBounds(void) {
RECT rect;
GetClientRect(handle, &rect);
Window_ClientSize.Width = Rect_Width(rect);
Window_ClientSize.Height = Rect_Height(rect);
POINT topLeft = { 0, 0 };
GetWindowRect(win_handle, &rect);
Window_SetRect(&Window_Bounds, &rect);
GetClientRect(win_handle, &rect);
Window_SetRect(&Window_ClientBounds, &rect);
/* MSDN says GetClientRect always returns 0,0 for top left */
ClientToScreen(win_handle, &topLeft);
Window_ClientBounds.X = topLeft.x;
Window_ClientBounds.Y = topLeft.y;
}
static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wParam, LPARAM lParam) {
@ -167,15 +181,16 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara
WINDOWPOS* pos = (WINDOWPOS*)lParam;
if (pos->hwnd != win_handle) break;
if (pos->x != Window_Bounds.X || pos->y != Window_Bounds.Y) {
Window_Bounds.X = pos->x; Window_Bounds.Y = pos->y;
bool moved = pos->x != Window_Bounds.X || pos->y != Window_Bounds.Y;
bool sized = pos->cx != Window_Bounds.Width || pos->cy != Window_Bounds.Height;
if (moved) {
Window_RefreshBounds();
Event_RaiseVoid(&WindowEvents.Moved);
}
if (pos->cx != Window_Bounds.Width || pos->cy != Window_Bounds.Height) {
Window_Bounds.Width = pos->cx; Window_Bounds.Height = pos->cy;
Window_UpdateClientSize(handle);
if (sized) {
Window_RefreshBounds();
SetWindowPos(win_handle, NULL,
Window_Bounds.X, Window_Bounds.Y, Window_Bounds.Width, Window_Bounds.Height,
SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
@ -317,15 +332,8 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara
break;
case WM_CREATE:
{
CREATESTRUCT* cs = (CREATESTRUCT*)lParam;
if (!cs->hwndParent) {
Window_Bounds.X = cs->x; Window_Bounds.Width = cs->cx;
Window_Bounds.Y = cs->y; Window_Bounds.Height = cs->cy;
Window_UpdateClientSize(handle);
invisible_since_creation = true;
}
} break;
break;
case WM_CLOSE:
Event_RaiseVoid(&WindowEvents.Closing);
@ -363,7 +371,7 @@ void Window_Create(int x, int y, int width, int height, struct GraphicsMode* mod
wc.hIcon = (HICON)LoadImage(win_instance, MAKEINTRESOURCE(1), IMAGE_ICON,
GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0);
wc.hIconSm = (HICON)LoadImage(win_instance,MAKEINTRESOURCE(1), IMAGE_ICON,
wc.hIconSm = (HICON)LoadImage(win_instance, MAKEINTRESOURCE(1), IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
@ -373,7 +381,9 @@ void Window_Create(int x, int y, int width, int height, struct GraphicsMode* mod
win_handle = CreateWindowEx(0, atom, NULL, CC_WIN_STYLE,
rect.left, rect.top, Rect_Width(rect), Rect_Height(rect),
NULL, NULL, win_instance, NULL);
if (!win_handle) Logger_Abort2(GetLastError(), "Failed to create window");
Window_RefreshBounds();
win_DC = GetDC(win_handle);
if (!win_DC) Logger_Abort2(GetLastError(), "Failed to get device context");
@ -537,22 +547,6 @@ void Window_SetWindowState(int state) {
}
}
Point2D Window_PointToClient(int x, int y) {
Point2D point = { x, y };
if (!ScreenToClient(win_handle, &point)) {
Logger_Abort2(GetLastError(), "Converting point from client to screen coordinates");
}
return point;
}
Point2D Window_PointToScreen(int x, int y) {
Point2D point = { x, y };
if (!ClientToScreen(win_handle, &point)) {
Logger_Abort2(GetLastError(), "Converting point from screen to client coordinates");
}
return point;
}
void Window_ProcessEvents(void) {
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, 1)) {
@ -853,27 +847,25 @@ static void Window_RefreshBorders(void) {
XFree(borders);
}
static void Window_RefreshBounds(XEvent* e) {
Point2D loc;
Size2D size;
static void Window_RefreshBounds(const XConfigureEvent* e) {
Window_RefreshBorders();
loc.X = e->xconfigure.x - borderLeft;
loc.Y = e->xconfigure.y - borderTop;
if (e->x != Window_ClientBounds.X || e->y != Window_ClientBounds.Y) {
Window_ClientBounds.X = e->x; Window_ClientBounds.Y = e->y;
if (loc.X != Window_Bounds.X || loc.Y != Window_Bounds.Y) {
Window_Bounds.X = loc.X; Window_Bounds.Y = loc.Y;
/* To get the external (window) position, need to add the border */
Window_Bounds.X = e->x - borderLeft;
Window_Bounds.Y = e->y - borderTop;
Event_RaiseVoid(&WindowEvents.Moved);
}
/* Note: width and height denote the internal (client) size.
To get the external (window) size, we need to add the border size. */
size.Width = e->xconfigure.width + borderLeft + borderRight;
size.Height = e->xconfigure.height + borderTop + borderBottom;
if (e->width != Window_ClientBounds.Width || e->height != Window_ClientBounds.Height) {
Window_ClientBounds.Width = e->width;
Window_ClientBounds.Height = e->height;
if (size.Width != Window_Bounds.Width || size.Height != Window_Bounds.Height) {
Window_ClientSize.Width = e->xconfigure.width; Window_Bounds.Width = size.Width;
Window_ClientSize.Height = e->xconfigure.height; Window_Bounds.Height = size.Height;
/* To get the external (window) size, need to add the border size */
Window_Bounds.Width = e->width + borderLeft + borderRight;
Window_Bounds.Height = e->height + borderTop + borderBottom;
Event_RaiseVoid(&WindowEvents.Resized);
}
}
@ -924,12 +916,12 @@ void Window_Create(int x, int y, int width, int height, struct GraphicsMode* mod
/* Set the initial window size to ensure X, Y, Width, Height and the rest
return the correct values inside the constructor and the Load event. */
XEvent e = { 0 };
XEvent e;
e.xconfigure.x = x;
e.xconfigure.y = y;
e.xconfigure.width = width;
e.xconfigure.height = height;
Window_RefreshBounds(&e);
Window_RefreshBounds(&e.configure);
/* Request that auto-repeat is only set on devices that support it physically.
This typically means that it's turned off for keyboards (which is what we want).
@ -1166,7 +1158,7 @@ void Window_ProcessEvents(void) {
break;
case ConfigureNotify:
Window_RefreshBounds(&e);
Window_RefreshBounds(&e.xonfigure);
break;
case Expose:
@ -1301,20 +1293,6 @@ void Window_ProcessEvents(void) {
}
}
Point2D Window_PointToClient(int x, int y) {
Point2D p;
Window child;
XTranslateCoordinates(win_display, win_rootWin, win_handle, x, y, &p.X, &p.Y, &child);
return p;
}
Point2D Window_PointToScreen(int x, int y) {
Point2D p;
Window child;
XTranslateCoordinates(win_display, win_handle, win_rootWin, x, y, &p.X, &p.Y, &child);
return p;
}
Point2D Cursor_GetScreenPos(void) {
Window rootW, childW;
Point2D root, child;
@ -1790,22 +1768,26 @@ static void Window_Destroy(void) {
Window_Exists = false;
}
static void Window_UpdateSize(void) {
static CC_INLINE void Window_SetRect(Rect2D* dst, const Rect* src) {
dst->X = src->left;
dst->Y = src->top;
dst->Width = src->right - src->left;
dst->Height = src->bottom - src->top;
}
static void Window_RefreshBounds(void) {
Rect r;
OSStatus res;
if (win_state == WINDOW_STATE_FULLSCREEN) return;
res = GetWindowBounds(win_handle, kWindowStructureRgn, &r);
if (res) Logger_Abort2(res, "Getting window bounds");
Window_Bounds.X = r.left;
Window_Bounds.Y = r.top;
Window_Bounds.Width = Rect_Width(r);
Window_Bounds.Height = Rect_Height(r);
Window_SetRect(&Window_Bounds, r);
/* TODO: kWindowContentRgn ??? */
res = GetWindowBounds(win_handle, kWindowGlobalPortRgn, &r);
if (res) Logger_Abort2(res, "Getting window clientsize");
Window_ClientSize.Width = Rect_Width(r);
Window_ClientSize.Height = Rect_Height(r);
if (res) Logger_Abort2(res, "Getting window clientbounds");
Window_SetRect(&Window_ClientBounds, r);
}
static void Window_UpdateWindowState(void) {
@ -1840,7 +1822,7 @@ static void Window_UpdateWindowState(void) {
}
Event_RaiseVoid(&WindowEvents.StateChanged);
Window_UpdateSize();
Window_RefreshBounds();
Event_RaiseVoid(&WindowEvents.Resized);
}
@ -1917,11 +1899,11 @@ static OSStatus Window_ProcessWindowEvent(EventHandlerCallRef inCaller, EventRef
return 0;
case kEventWindowBoundsChanged:
width = Window_ClientSize.Width;
height = Window_ClientSize.Height;
Window_UpdateSize();
width = Window_ClientBounds.Width;
height = Window_ClientBounds.Height;
Window_RefreshBounds();
if (width != Window_ClientSize.Width || height != Window_ClientSize.Height) {
if (width != Window_ClientBounds.Width || height != Window_ClientBounds.Height) {
Event_RaiseVoid(&WindowEvents.Resized);
}
return eventNotHandledErr;
@ -2082,10 +2064,10 @@ void Window_Create(int x, int y, int width, int height, struct GraphicsMode* mod
r.top = y; r.bottom = y + height;
res = CreateNewWindow(kDocumentWindowClass,
kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute |
kWindowInWindowMenuAttribute | kWindowLiveResizeAttribute,
&r, &win_handle);
kWindowInWindowMenuAttribute | kWindowLiveResizeAttribute, &r, &win_handle);
if (res) Logger_Abort2(res, "Failed to create window");
Window_UpdateSize();
Window_RefreshBounds();
res = GetWindowBounds(win_handle, kWindowTitleBarRgn, &r);
if (res) Logger_Abort2(res, "Failed to get titlebar size");
@ -2219,15 +2201,6 @@ void Window_SetLocation(int x, int y) {
MoveWindow(win_handle, x, y, false);
}
static void Window_SetExternalSize(int width, int height) {
/* SizeWindow works in client size */
/* But SetSize is window size, so reduce it */
width -= (Window_Bounds.Width - Window_ClientSize.Width);
height -= (Window_Bounds.Height - Window_ClientSize.Height);
SizeWindow(win_handle, width, height, true);
}
void Window_SetSize(int width, int height) {
SizeWindow(win_handle, width, height, true);
}
@ -2257,24 +2230,6 @@ void Window_ProcessEvents(void) {
}
}
Point2D Window_PointToClient(int x, int y) {
Rect r;
Point2D p;
GetWindowBounds(win_handle, kWindowContentRgn, &r);
p.X = x - r.left; p.Y = y - r.top;
return p;
}
Point2D Window_PointToScreen(int x, int y) {
Rect r;
Point2D p;
GetWindowBounds(win_handle, kWindowContentRgn, &r);
p.X = x + r.left; p.Y = y + r.top;
return p;
}
Point2D Cursor_GetScreenPos(void) {
HIPoint point;
Point2D p;
@ -2350,8 +2305,8 @@ void Window_DrawRaw(Rect2D r) {
// TODO: Only update changed bit..
rect.origin.x = 0; rect.origin.y = 0;
rect.size.width = Window_ClientSize.Width;
rect.size.height = Window_ClientSize.Height;
rect.size.width = Window_ClientBounds.Width;
rect.size.height = Window_ClientBounds.Height;
CGContextDrawImage(context, rect, win_image);
CGContextSynchronize(context);
@ -2388,8 +2343,8 @@ void Window_DrawRaw(Rect2D r) {
/* TODO: Only update changed bit.. */
rect.origin.x = 0; rect.origin.y = 0;
rect.size.width = Window_ClientSize.Width;
rect.size.height = Window_ClientSize.Height;
rect.size.width = Window_ClientBounds.Width;
rect.size.height = Window_ClientBounds.Height;
provider = CGDataProviderCreateWithData(NULL, bmp_->Scan0,
Bitmap_DataSize(bmp_->Width, bmp_->Height), NULL);
@ -2467,7 +2422,7 @@ static void GLContext_UnsetFullscreen(void) {
ctx_fullscreen = false;
Window_UpdateWindowState();
Window_SetExternalSize(ctx_windowedBounds.Width, ctx_windowedBounds.Height);
Window_SetSize(ctx_windowedBounds.Width, ctx_windowedBounds.Height);
}
static void GLContext_SetFullscreen(void) {
@ -2493,11 +2448,9 @@ static void GLContext_SetFullscreen(void) {
}
ctx_fullscreen = true;
ctx_windowedBounds = Window_Bounds;
Window_ClientSize.Width = displayWidth;
Window_ClientSize.Width = displayHeight;
ctx_windowedBounds = Window_ClientBounds;
Window_ClientBounds = DisplayDevice_Default.Bounds;
Window_Bounds = DisplayDevice_Default.Bounds;
win_state = WINDOW_STATE_FULLSCREEN;
}

View File

@ -67,12 +67,12 @@ int Window_GetWindowState(void);
/* Sets the current state of the window, see WindowState enum. */
void Window_SetWindowState(int state);
/* The external bounds of the window in screen coordinates. */
/* Size of external bounds is client size + borders + title */
/* External bounds of the window in screen coordinates. */
/* Essentially, this is client bounds + borders + titlebar */
extern Rect2D Window_Bounds;
/* Size of the internal bounds of the window. */
/* This is the size of area that can be drawn on. (i.e. content size) */
extern Size2D Window_ClientSize;
/* Client bounds of the window in screen coordinates. */
/* Essentially, this is the area that can draw to (i.e. content area) */
extern Rect2D Window_ClientBounds;
/* Sets the position of the window on the screen. */
void Window_SetLocation(int x, int y);
/* Sets the size of the internal bounds of the window. */
@ -84,10 +84,6 @@ void Window_SetSize(int width, int height);
void Window_Close(void);
/* Processes all pending window messages/events. */
void Window_ProcessEvents(void);
/* Converts the specified point from screen to client coordinates. */
Point2D Window_PointToClient(int x, int y);
/* Converts the specified point from client to screen coordinates. */
Point2D Window_PointToScreen(int x, int y);
/* Gets the position of the cursor in screen coordinates. */
Point2D Cursor_GetScreenPos(void);