diff --git a/liblpe/controller/AboutController.h b/liblpe/controller/AboutController.h index a461d00..384923e 100644 --- a/liblpe/controller/AboutController.h +++ b/liblpe/controller/AboutController.h @@ -32,9 +32,12 @@ #include -class AboutController : public DockWindow { +class AboutController final : public DockWindow { public: AboutController(); +protected: + LONG getMinWidth() override { return 250; } + LONG getMinHeight() override { return 50; } }; #endif //LPE_ABOUTCONTROLLER_H \ No newline at end of file diff --git a/liblpe/controller/ConfirmationController.cpp b/liblpe/controller/ConfirmationController.cpp index 07aaa69..a9267b6 100644 --- a/liblpe/controller/ConfirmationController.cpp +++ b/liblpe/controller/ConfirmationController.cpp @@ -29,6 +29,9 @@ #include #include +#ifndef _WIN32 + #include +#endif ConfirmationController::ConfirmationController(const std::string& title, std::string* name) : ModalWindow(IDD_CONFIRM, title.data(), "ConfirmationController", 0), mName(name) { diff --git a/liblpe/controller/ConfirmationController.h b/liblpe/controller/ConfirmationController.h index bfb8141..feb0a72 100644 --- a/liblpe/controller/ConfirmationController.h +++ b/liblpe/controller/ConfirmationController.h @@ -33,7 +33,7 @@ #include -class ConfirmationController : public ModalWindow { +class ConfirmationController final : public ModalWindow { public: explicit ConfirmationController(const std::string& title, std::string* name); protected: @@ -43,6 +43,8 @@ class ConfirmationController : public ModalWindow { void onClose() override; LPARAM result() override; int onNotify(WPARAM wParam, LPARAM lParam) override; + LONG getMinHeight() override { return 52; } + LONG getMinWidth() override { return 168; } private: std::string* mName; }; diff --git a/liblpe/controller/ControlViewController.h b/liblpe/controller/ControlViewController.h index e89f81b..b3a5894 100644 --- a/liblpe/controller/ControlViewController.h +++ b/liblpe/controller/ControlViewController.h @@ -23,6 +23,8 @@ class ControlViewController : public DockWindow { void onClose() override; void onResize() override; void onInitDlg() override; + LONG getMinWidth() override { return 416; } + LONG getMinHeight() override { return 180; } private: HWND tabHwnd = nullptr; std::set mControlIds; diff --git a/liblpe/controller/LivePresetEditController.cpp b/liblpe/controller/LivePresetEditController.cpp index 00be0f8..ab86b43 100644 --- a/liblpe/controller/LivePresetEditController.cpp +++ b/liblpe/controller/LivePresetEditController.cpp @@ -249,9 +249,4 @@ void LivePresetEditController::showFilterSettings() { RECT r{}; GetWindowRect(GetDlgItem(mHwnd, IDC_SETTINGS), &r); TrackPopupMenu(menu, TPM_LEFTALIGN | TPM_TOPALIGN, r.left, r.bottom, 0, mHwnd, nullptr); -} - -void LivePresetEditController::getMinMaxInfo(LPMINMAXINFO info) { - info->ptMinTrackSize.x = 1400; - info->ptMinTrackSize.y = 1200; } \ No newline at end of file diff --git a/liblpe/controller/LivePresetEditController.h b/liblpe/controller/LivePresetEditController.h index 2dcac6f..f1e6798 100644 --- a/liblpe/controller/LivePresetEditController.h +++ b/liblpe/controller/LivePresetEditController.h @@ -37,7 +37,7 @@ #include #include -class LivePresetEditController : public ModalWindow { +class LivePresetEditController final : public ModalWindow { public: explicit LivePresetEditController(LivePreset* preset); @@ -49,8 +49,9 @@ class LivePresetEditController : public ModalWindow { int onKey(MSG* msg, int iKeyState) override; void onClose() override; LPARAM result() override; - void getMinMaxInfo(LPMINMAXINFO info) override; int onNotify(WPARAM wParam, LPARAM lParam) override; + LONG getMinWidth() override { return 310; } + LONG getMinHeight() override { return 122; } private: static WNDPROC defWndProc; static LRESULT WINAPI wndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); diff --git a/liblpe/controller/LivePresetsController.cpp b/liblpe/controller/LivePresetsController.cpp index e43048c..7f0768c 100644 --- a/liblpe/controller/LivePresetsController.cpp +++ b/liblpe/controller/LivePresetsController.cpp @@ -285,9 +285,4 @@ void LivePresetsController::reset() const { mList->setAdapter(std::move(adapter)); mList->invalidate(); } -} - -void LivePresetsController::getMinMaxInfo(LPMINMAXINFO info) { - info->ptMinTrackSize.x = 1284; - info->ptMinTrackSize.y = 625; } \ No newline at end of file diff --git a/liblpe/controller/LivePresetsController.h b/liblpe/controller/LivePresetsController.h index e76358e..7077297 100644 --- a/liblpe/controller/LivePresetsController.h +++ b/liblpe/controller/LivePresetsController.h @@ -33,9 +33,8 @@ #include #include #include -#include -class LivePresetsController : public DockWindow { +class LivePresetsController final : public DockWindow { public: LivePresetsController(); std::unique_ptr> mList = nullptr; @@ -53,7 +52,8 @@ class LivePresetsController : public DockWindow { int onNotify(WPARAM wParam, LPARAM lParam) override; void onClose() override; void onInitDlg() override; - void getMinMaxInfo(LPMINMAXINFO info) override; + LONG getMinWidth() override { return 300; } + LONG getMinHeight() override { return 200; } private: static void recallLivePreset(LivePreset* preset); void applyFilterToSelectedTracks(int filterIndex) const; diff --git a/liblpe/controller/SettingsController.h b/liblpe/controller/SettingsController.h index 40b2947..cd05119 100644 --- a/liblpe/controller/SettingsController.h +++ b/liblpe/controller/SettingsController.h @@ -33,7 +33,7 @@ #include #include -class SettingsController : public ModalWindow { +class SettingsController final : public ModalWindow { public: SettingsController(); protected: @@ -43,6 +43,8 @@ class SettingsController : public ModalWindow { void onClose() override; LPARAM result() override; int onNotify(WPARAM wParam, LPARAM lParam) override; + LONG getMinHeight() override { return 278; } + LONG getMinWidth() override { return 200; } private: std::unique_ptr mCombo = nullptr; diff --git a/liblpe/data/models/Control.cpp b/liblpe/data/models/Control.cpp index 93f2e5e..6e6a669 100644 --- a/liblpe/data/models/Control.cpp +++ b/liblpe/data/models/Control.cpp @@ -30,6 +30,6 @@ std::string Control::getChunkId() const { } const char *Control::getName(int index) const { - sprintf(mNameText, "%i: \n", index); + snprintf(mNameText, 256, "%i: \n", index); return (const char*) mNameText; } \ No newline at end of file diff --git a/liblpe/resources/resource.rc b/liblpe/resources/resource.rc index 8ee075d..93e9f3a 100644 --- a/liblpe/resources/resource.rc +++ b/liblpe/resources/resource.rc @@ -1,23 +1,23 @@ -#include +#include "resource.h" #ifdef _WIN32 #include #endif -IDD_LIVEPRESETS DIALOGEX 0, 0, 528, 200 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +IDD_LIVEPRESETS DIALOGEX 0, 0, 450, 200 +STYLE DS_SETFONT | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME FONT DEFAULT_FONT BEGIN - CONTROL "",IDC_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | WS_BORDER,8,8,512,160 - PUSHBUTTON "Add",IDC_ADD,8,176,72,16 - PUSHBUTTON "Update",IDC_UPDATE,88,176,72,16 - PUSHBUTTON "Edit",IDC_EDIT,168,176,72,16 - PUSHBUTTON "Remove",IDC_REMOVE,248,176,72,16 - PUSHBUTTON "Settings", IDC_SETTINGS,448,176,72,16 + CONTROL "",IDC_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | WS_BORDER,8,8,434,160 + PUSHBUTTON "Add",IDC_ADD,8,176,48,16 + PUSHBUTTON "Update",IDC_UPDATE,64,176,48,16 + PUSHBUTTON "Edit",IDC_EDIT,120,176,48,16 + PUSHBUTTON "Remove",IDC_REMOVE,176,176,48,16 + PUSHBUTTON "Settings", IDC_SETTINGS,394,176,48,16 END -IDD_LIVEPRESET DIALOGEX 0, 0, 310, 92 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +IDD_LIVEPRESET DIALOGEX 0, 0, 310, 122 +STYLE DS_SETFONT | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME FONT DEFAULT_FONT BEGIN LTEXT "Name:",IDC_STATIC,8,10,40,8 @@ -27,8 +27,8 @@ BEGIN EDITTEXT IDC_DESC,56,28,128,12,ES_AUTOHSCROLL EDITTEXT IDC_ID,56,48,128,12,ES_AUTOHSCROLL | ES_NUMBER PUSHBUTTON "Set Recall Hotkey",IDC_RECALL,56,68,128,12 - PUSHBUTTON "Cancel",IDC_CANCEL,8,68,72,16 - PUSHBUTTON "OK",IDC_SAVE,88,68,72,16 + PUSHBUTTON "Cancel",IDC_CANCEL,8,98,72,16 + PUSHBUTTON "OK",IDC_SAVE,88,98,72,16 LTEXT "Filter:",IDC_LABEL1,192,10,20,8 COMBOBOX IDC_COMBO,220,8,68,16,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "+",IDC_SETTINGS,292,8,10,10 @@ -36,7 +36,7 @@ BEGIN END IDD_SETTINGS DIALOGEX 0, 0, 200, 278 -STYLE DS_MODALFRAME | DS_SHELLFONT | WS_POPUP | WS_SYSMENU | WS_CAPTION +STYLE DS_SETFONT | DS_CENTER | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME FONT DEFAULT_FONT BEGIN PUSHBUTTON "Bind recall action",IDC_RECALL,8,8,184,16 @@ -54,7 +54,7 @@ BEGIN END IDD_CONFIRM DIALOGEX 0, 0, 168, 52 -STYLE DS_MODALFRAME | DS_SHELLFONT | WS_POPUP | WS_SYSMENU | WS_CAPTION +STYLE DS_SETFONT | DS_CENTER | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME FONT DEFAULT_FONT BEGIN LTEXT "Name:",IDC_STATIC,8,10,40,8 @@ -63,19 +63,19 @@ BEGIN PUSHBUTTON "OK",IDC_SAVE,88,28,72,16 END -IDD_CONTROLVIEW DIALOGEX 0, 0, 616, 380 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +IDD_CONTROLVIEW DIALOGEX 0, 0, 416, 180 +STYLE DS_SETFONT | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME FONT DEFAULT_FONT BEGIN PUSHBUTTON "Add Hardware",IDC_ADD,8,8,72,16 PUSHBUTTON "Remove Hardware",IDC_REMOVE,88,8,72,16 - PUSHBUTTON "Add Control",IDC_ADD2,456,8,72,16 - PUSHBUTTON "Remove Control",IDC_REMOVE2,536,8,72,16 - CONTROL "TabControl", IDC_TAB,"SysTabControl32",WS_TABSTOP,8,72,600,300 + PUSHBUTTON "Add Control",IDC_ADD2,256,8,72,16 + PUSHBUTTON "Remove Control",IDC_REMOVE2,336,8,72,16 + CONTROL "TabControl", IDC_TAB,"SysTabControl32",WS_TABSTOP,8,72,400,300 END -IDD_ABOUT DIALOGEX 0, 0, 500, 250 -STYLE DS_MODALFRAME | DS_SHELLFONT | WS_POPUP | WS_SYSMENU | WS_CAPTION +IDD_ABOUT DIALOGEX 0, 0, 250, 50 +STYLE DS_SETFONT | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME FONT DEFAULT_FONT BEGIN diff --git a/liblpe/ui/base/DockWindow.cpp b/liblpe/ui/base/DockWindow.cpp index b77cc00..39ae47f 100644 --- a/liblpe/ui/base/DockWindow.cpp +++ b/liblpe/ui/base/DockWindow.cpp @@ -30,6 +30,7 @@ #include #ifdef _WIN32 #include + #include #else #include #endif @@ -80,11 +81,57 @@ void DockWindow::initDialog(HWND hwndDlg) { * @param pointer that stores the size infos */ void DockWindow::getMinMaxInfo(LPMINMAXINFO info) { - int w = 150; - int h = 150; + double dpiFactor = 1.5; + int staticX = 0; + int staticY = 0; - info->ptMinTrackSize.x = w; - info->ptMinTrackSize.y = h; +#ifdef _WIN32 + // 310/92 in .rc scales to 465/481/150/189 at 100 %, 930/958/288/359 at 200 %, + // 100 % is 1,5 * x + 0/16 and 1,5 * y + 12/51 (16 width and 39 height for window decorations at 100 %) + // 200 % is 3 * x + 0/28 and 3 * y + 12/83 (28 width and 71 height for window decorations at 200 %) + DPI_AWARENESS dpiAwareness = GetAwarenessFromDpiAwarenessContext(GetThreadDpiAwarenessContext()); + if (dpiAwareness == DPI_AWARENESS_PER_MONITOR_AWARE) { + dpiFactor = 3 * GetDpiForWindow(mHwnd) / 192.0; + } else if (dpiAwareness == DPI_AWARENESS_UNAWARE) { + // only works on DPI_AWARENESS_UNAWARE + auto monitor = MonitorFromWindow(mHwnd, MONITOR_DEFAULTTONEAREST); + DEVICE_SCALE_FACTOR scale; + auto result = GetScaleFactorForMonitor(monitor, &scale); + if (result == S_OK) { + dpiFactor = 3 * scale / 200.0; + } else { + dpiFactor = 1.5; + } + } else { + dpiFactor = 1.5; + } + + staticY = 12; +#elif __APPLE__ + // 310/92 in .rc scales to 527/156/184 at 100 % + // 100 % is 1,7 * x and 1,7 * y + 28 (28 height for window decorations at 100 %) + // TODO + /*RECT wnd, clnt; + GetClientRect(mHwnd, &clnt); + GetWindowRect(mHwnd, &wnd); + + char msg[512]; + snprintf(msg, 512, + "client: %d, %d, %d, %d\nwnd: %d, %d, %d, %d\nfactor: %f\n", + clnt.left, clnt.top, clnt.right - clnt.left, clnt.bottom - clnt.top, + wnd.left, wnd.top, wnd.right - wnd.left, wnd.bottom - wnd.top, + dpiFactor + ); + ShowConsoleMsg(msg);*/ + dpiFactor = 1.7; +#else + // LPMINMAX corresponds to Window rect 1:2 for 100 % and scales linear + // 310/92 in .rc scales to 620/184 at 100 % and 1240/368 at 200 % for client and window rect + dpiFactor = SWELL_GetScaling256() / 128.0; +#endif + + info->ptMinTrackSize.x = getMinWidth() * dpiFactor + staticX; + info->ptMinTrackSize.y = getMinHeight() * dpiFactor + staticY; } /** @@ -106,7 +153,7 @@ void DockWindow::toggleVisibility() { } } -void DockWindow::focus() { +[[maybe_unused]] void DockWindow::focus() { if (isDocked()) { DockWindowActivate(mHwnd); } @@ -235,9 +282,12 @@ int DockWindow::keyHandler(MSG* msg, accelerator_register_t* ctx) { DockWindowState DockWindow::getStateForPersistance() { DockWindowState state{}; state.dockId = DockIsChildOfDock(mHwnd, nullptr); - RECT r = RECT(); - GetWindowRect(mHwnd, &r); - state.pos = r; + auto rect = RECT(); + GetWindowRect(mHwnd, &rect); + state.top = rect.top; + state.left = rect.left, + state.width = rect.right - rect.left; + state.height = rect.bottom - rect.top; state.visible = isVisible(); return state; } @@ -254,9 +304,9 @@ void DockWindow::loadStateFromPersistance(DockWindowState state) { DockWindowAddEx(mHwnd, mTitle.data(), mId.data(), true); Dock_UpdateDockID(mId.data(), state.dockId); } else { - RECT r = state.pos; - EnsureNotCompletelyOffscreen(&r); - SetWindowPos(mHwnd, nullptr, r.left, r.top, r.right - r.left, r.bottom - r.top, 0); + auto rect = RECT{state.left, state.top, state.left + state.width, state.top + state.height}; + EnsureNotCompletelyOffscreen(&rect); + SetWindowPos(mHwnd, nullptr, state.left, state.top, state.width, state.height, 0); } } } diff --git a/liblpe/ui/base/DockWindow.h b/liblpe/ui/base/DockWindow.h index 9adf630..e3f6637 100644 --- a/liblpe/ui/base/DockWindow.h +++ b/liblpe/ui/base/DockWindow.h @@ -45,7 +45,10 @@ typedef struct DockWindowState { int visible = 1; //-1 not saved, 0 hidden, 1 showing int dockId = -1; //-1 not docked, >= 0 dockId - RECT pos = RECT{500, 200, 1000, 500}; // position and size + LONG left = 500; + LONG top = 200; + LONG width = 500; + LONG height = 300; } DockWindowState; class DockWindow { @@ -53,7 +56,7 @@ class DockWindow { explicit DockWindow(int iResource = 0, const char* cWndTitle = "", const char* cId = "", int iCmdID = 0); virtual ~DockWindow(); - void focus(); + [[maybe_unused]] [[maybe_unused]] void focus(); bool isDocked(); bool isVisible(); void show(bool loadState = true); @@ -73,7 +76,8 @@ class DockWindow { virtual void onInitDlg() {} virtual int onKey(MSG* msg, int iKeyState) { return 0; } // return 1 for "processed key" virtual INT_PTR onUnhandledMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) { return 0; } - virtual void getMinMaxInfo(LPMINMAXINFO info); + virtual LONG getMinWidth() { return 150; } + virtual LONG getMinHeight() { return 150; } HWND mHwnd; int mCmdId; @@ -92,6 +96,7 @@ class DockWindow { DockWindowState getStateForPersistance(); void loadStateFromPersistance(DockWindowState state); void showContextMenu(int x, int y, HMENU menu); + virtual void getMinMaxInfo(LPMINMAXINFO info); }; #endif //LPE_DOCKWINDOW_H \ No newline at end of file diff --git a/liblpe/ui/base/ModalWindow.cpp b/liblpe/ui/base/ModalWindow.cpp index 00c642d..139a1d0 100644 --- a/liblpe/ui/base/ModalWindow.cpp +++ b/liblpe/ui/base/ModalWindow.cpp @@ -31,6 +31,7 @@ #ifdef _WIN32 #include #include + #include #else #endif @@ -40,7 +41,8 @@ ModalWindow::ModalWindow(int iResource, const char* cWndTitle, const char* cId, int iCmdID) : mHwnd(nullptr), mCmdId(iCmdID), mLayout(iResource), mTitle(cWndTitle), mId(cId) { - if (cId && *cId) {// e.g. default constructor + // screensets enable reaper to persist layouts + if (cId && *cId) { screenset_unregister((char*) cId); screenset_registerNew((char*) cId, screensetCallback, this); } @@ -65,7 +67,7 @@ void ModalWindow::initDialog(HWND hwndDlg) { SetWindowText(mHwnd, mTitle.data()); - //recall saved state + // recall default saved state ModalWindowState state{}; GetPrivateProfileStruct("LPE", mId.data(), &state, sizeof(state), get_ini_file()); loadStateFromPersistance(state); @@ -76,14 +78,60 @@ void ModalWindow::initDialog(HWND hwndDlg) { /** * Save the minimum and maximum size in the passed pointer. It is not dpi aware. - * @param pointer that stores the size infos + * @param info pointer that stores the size infos */ void ModalWindow::getMinMaxInfo(LPMINMAXINFO info) { - int w = 150; - int h = 150; + double dpiFactor = 1.5; + int staticX = 0; + int staticY = 0; - info->ptMinTrackSize.x = w; - info->ptMinTrackSize.y = h; +#ifdef _WIN32 + // 310/92 in .rc scales to 465/481/150/189 at 100 %, 930/958/288/359 at 200 %, + // 100 % is 1,5 * x + 0/16 and 1,5 * y + 12/51 (16 width and 39 height for window decorations at 100 %) + // 200 % is 3 * x + 0/28 and 3 * y + 12/83 (28 width and 71 height for window decorations at 200 %) + DPI_AWARENESS dpiAwareness = GetAwarenessFromDpiAwarenessContext(GetThreadDpiAwarenessContext()); + if (dpiAwareness == DPI_AWARENESS_PER_MONITOR_AWARE) { + dpiFactor = 3 * GetDpiForWindow(mHwnd) / 192.0; + } else if (dpiAwareness == DPI_AWARENESS_UNAWARE) { + // only works on DPI_AWARENESS_UNAWARE + auto monitor = MonitorFromWindow(mHwnd, MONITOR_DEFAULTTONEAREST); + DEVICE_SCALE_FACTOR scale; + auto result = GetScaleFactorForMonitor(monitor, &scale); + if (result == S_OK) { + dpiFactor = 3 * scale / 200.0; + } else { + dpiFactor = 1.5; + } + } else { + dpiFactor = 1.5; + } + + staticY = 12; +#elif __APPLE__ + // 310/92 in .rc scales to 527/156/184 at 100 % + // 100 % is 1,7 * x and 1,7 * y + 28 (28 height for window decorations at 100 %) + // TODO + /*RECT wnd, clnt; + GetClientRect(mHwnd, &clnt); + GetWindowRect(mHwnd, &wnd); + + char msg[512]; + snprintf(msg, 512, + "client: %d, %d, %d, %d\nwnd: %d, %d, %d, %d\nfactor: %f\n", + clnt.left, clnt.top, clnt.right - clnt.left, clnt.bottom - clnt.top, + wnd.left, wnd.top, wnd.right - wnd.left, wnd.bottom - wnd.top, + dpiFactor + ); + ShowConsoleMsg(msg);*/ + dpiFactor = 1.7; +#else + // LPMINMAX corresponds to Window rect 1:2 for 100 % and scales linear + // 310/92 in .rc scales to 620/184 at 100 % and 1240/368 at 200 % for client and window rect + dpiFactor = SWELL_GetScaling256() / 128.0; +#endif + + info->ptMinTrackSize.x = getMinWidth() * dpiFactor + staticX; + info->ptMinTrackSize.y = getMinHeight() * dpiFactor + staticY; } /** @@ -94,7 +142,7 @@ void ModalWindow::resize() { onResize(); } -void ModalWindow::focus() { +[[maybe_unused]] void ModalWindow::focus() { SetFocus(mHwnd); } @@ -102,7 +150,7 @@ void ModalWindow::focus() { * * @return */ -bool ModalWindow::isActive() { +[[maybe_unused]] bool ModalWindow::isActive() { if (!mHwnd) return false; @@ -111,7 +159,8 @@ bool ModalWindow::isActive() { } /** - * A function called by reaper to implement the screenset functions to this window + * A function called by reaper to implement the screenset functions to this window. Screensets are + * recallable layouts within reaper * @param action The type of action called by screenset * @param id The id of the window to receive information from * @param param User defined value @@ -156,16 +205,19 @@ void ModalWindow::close() { ModalWindowState ModalWindow::getStateForPersistance() { ModalWindowState state{}; - RECT r = RECT(); - GetWindowRect(mHwnd, &r); - state.pos = r; + auto rect = RECT(); + GetWindowRect(mHwnd, &rect); + state.top = rect.top; + state.left = rect.left, + state.width = rect.right - rect.left; + state.height = rect.bottom - rect.top; return state; } -void ModalWindow::loadStateFromPersistance(ModalWindowState state) { - RECT r = state.pos; - EnsureNotCompletelyOffscreen(&r); - SetWindowPos(mHwnd, nullptr, r.left, r.top, r.right - r.left, r.bottom - r.top, 0); +void ModalWindow::loadStateFromPersistance(const ModalWindowState& state) { + auto rect = RECT{state.left, state.top, state.left + state.width, state.top + state.height}; + EnsureNotCompletelyOffscreen(&rect); + SetWindowPos(mHwnd, nullptr, state.left, state.top, state.width, state.height, 0); } /** @@ -202,6 +254,9 @@ int ModalWindow::saveScreensetState(char* cStateBuf, int iMaxLen) { * @param iLen Length of useable data */ void ModalWindow::loadScreensetState(const char* cStateBuf, int iLen) { + if (iLen <= 0) + return; + ModalWindowState state{}; memcpy(&state, cStateBuf, iLen); loadStateFromPersistance(state); @@ -256,6 +311,7 @@ INT_PTR WINAPI ModalWindow::dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPAR RECT rClient, rWnd; GetClientRect(wnd->mHwnd, &rClient); GetWindowRect(wnd->mHwnd, &rWnd); + info->ptMinTrackSize.x += (rWnd.right - rWnd.left) - rClient.right; info->ptMinTrackSize.y += (rWnd.bottom - rWnd.top) - rClient.bottom; break; @@ -270,11 +326,11 @@ INT_PTR WINAPI ModalWindow::dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPAR wnd->onClose(); break; case WM_KEYDOWN: { - //certain keys are used to navigate between controls on windows os and are not passed to the dlgProc + //certain keys are used to navigate between controls on Windows os and are not passed to the dlgProc //VK_UP, VK_LEFT, VK_RIGHT, VK_DOWN, VK_TAB //which keys are passed to dlgProc depends on the control having the focus, the os and a custom wndProc //of that control. On windows controls eat all keys. On linux and mac only used keys are eaten. On linux - //and windows, modal dialogs with controls always give the focus to any control, on mac no control can + //and windows, modal dialogs with controls always give the focus to any control, on Mac no control can //have the focus MSG msg{}; msg.hwnd = hwndDlg; diff --git a/liblpe/ui/base/ModalWindow.h b/liblpe/ui/base/ModalWindow.h index 7c93d97..c918918 100644 --- a/liblpe/ui/base/ModalWindow.h +++ b/liblpe/ui/base/ModalWindow.h @@ -37,11 +37,15 @@ #else #include #endif +// needed for mac #include #include typedef struct ModalWindowState { - RECT pos = RECT{500, 200, 1000, 500}; // position and size + LONG left = 500; + LONG top = 200; + LONG width = 500; + LONG height = 300; } ModalWindowState; class ModalWindow { @@ -49,12 +53,13 @@ class ModalWindow { explicit ModalWindow(int iResource = 0, const char* cWndTitle = "", const char* cId = "", int iCmdID = 0); virtual ~ModalWindow(); - void focus(); + [[maybe_unused]] [[maybe_unused]] void focus(); LPARAM show(); void close(); int saveScreensetState(char* cStateBuf, int iMaxLen); void loadScreensetState(const char* cStateBuf, int iLen); - virtual bool isActive(); + + [[maybe_unused]] virtual bool isActive(); virtual void onCommand(WPARAM wParam, LPARAM lParam) {} protected: virtual int onNotify(WPARAM wParam, LPARAM lParam) { return 0; } @@ -65,7 +70,8 @@ class ModalWindow { virtual void onInitDlg() {} virtual int onKey(MSG* msg, int iKeyState) { return 0; } // return 1 for "processed key" virtual INT_PTR onUnhandledMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) { return 0; } - virtual void getMinMaxInfo(LPMINMAXINFO info); + virtual LONG getMinWidth() { return 150; } + virtual LONG getMinHeight() { return 150; } HWND mHwnd; int mCmdId; @@ -80,8 +86,9 @@ class ModalWindow { void resize(); void onDestroy(); ModalWindowState getStateForPersistance(); - void loadStateFromPersistance(ModalWindowState state); + void loadStateFromPersistance(const ModalWindowState& state); void showContextMenu(int x, int y, HMENU menu); + virtual void getMinMaxInfo(LPMINMAXINFO info); }; diff --git a/meson.build b/meson.build index b1aa22a..19a010a 100644 --- a/meson.build +++ b/meson.build @@ -116,7 +116,7 @@ endif # dependencies win_dep = [] if host_machine.system() == 'windows' - foreach win32_lib : ['User32', 'Gdi32', 'Advapi32', 'Comdlg32', 'Shell32'] + foreach win32_lib : ['User32', 'Gdi32', 'Advapi32', 'Comdlg32', 'Shell32', 'Shcore'] win_dep += cpp.find_library(win32_lib) endforeach endif