From 8e77126afa6c1db75e178e00b60fd38ac859e869 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Mon, 11 Feb 2019 21:41:10 +1100 Subject: [PATCH] simplify window API even more --- src/Camera.c | 5 +- src/Game.c | 11 ++- src/Game.h | 2 +- src/Launcher.c | 4 +- src/Program.c | 4 +- src/Widgets.c | 8 +- src/Window.c | 197 +++++++++++++++++++------------------------------ src/Window.h | 14 ++-- 8 files changed, 94 insertions(+), 151 deletions(-) diff --git a/src/Camera.c b/src/Camera.c index 8cc0c34bd..4ffc14450 100644 --- a/src/Camera.c +++ b/src/Camera.c @@ -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. */ diff --git a/src/Game.c b/src/Game.c index 0e91e354c..15847fa76 100644 --- a/src/Game.c +++ b/src/Game.c @@ -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); diff --git a/src/Game.h b/src/Game.h index 53a6bb178..1296bd272 100644 --- a/src/Game.h +++ b/src/Game.h @@ -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. */ diff --git a/src/Launcher.c b/src/Launcher.c index c15fde207..67b2f3d2b 100644 --- a/src/Launcher.c +++ b/src/Launcher.c @@ -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; diff --git a/src/Program.c b/src/Program.c index 8575e5b11..d8f21b89c 100644 --- a/src/Program.c +++ b/src/Program.c @@ -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(); diff --git a/src/Widgets.c b/src/Widgets.c index 538ec7213..9719b5818 100644 --- a/src/Widgets.c +++ b/src/Widgets.c @@ -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; diff --git a/src/Window.c b/src/Window.c index 1baab7c61..6d926ba60 100644 --- a/src/Window.c +++ b/src/Window.c @@ -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; + invisible_since_creation = true; + 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 (loc.X != Window_Bounds.X || loc.Y != Window_Bounds.Y) { - Window_Bounds.X = loc.X; Window_Bounds.Y = loc.Y; + if (e->x != Window_ClientBounds.X || e->y != Window_ClientBounds.Y) { + Window_ClientBounds.X = e->x; Window_ClientBounds.Y = e->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; } diff --git a/src/Window.h b/src/Window.h index a19ebd597..f07379cd6 100644 --- a/src/Window.h +++ b/src/Window.h @@ -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);