Mercurial > foo_out_sdl
diff foosdk/sdk/libPPUI/CDialogResizeHelper.cpp @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/libPPUI/CDialogResizeHelper.cpp Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,194 @@ +#include "stdafx.h" +#include "CDialogResizeHelper.h" + +#include "win32_op.h" + +static BOOL GetChildWindowRect2(HWND wnd, HWND wndChild, RECT* child) { + RECT temp; + if (wndChild == NULL) return FALSE; + if (!GetWindowRect(wndChild, &temp)) return FALSE; + if (!MapWindowPoints(NULL, wnd, (POINT*)&temp, 2)) return FALSE; + *child = temp; + return TRUE; +} + +static BOOL GetChildWindowRect(HWND wnd, UINT id, RECT* child) { + return GetChildWindowRect2(wnd, GetDlgItem(wnd, id), child); +} + + +bool CDialogResizeHelper::EvalRect(UINT id, CRect & out) const { + for( auto iter = m_runtime.begin(); iter != m_runtime.end(); ++ iter ) { + if ( iter->initData.id == id ) { + out = _EvalRect(*iter, this->CurrentSize() ); + return true; + } + } + return false; +} + +CRect CDialogResizeHelper::_EvalRect(runtime_t const & rt, CSize wndSize) const { + CRect rc = rt.origRect; + int delta_x = wndSize.cx - rt.origWindowSize.cx, + delta_y = wndSize.cy - rt.origWindowSize.cy; + + const Param & e = rt.initData; + rc.left += pfc::rint32(e.snapLeft * delta_x); + rc.right += pfc::rint32(e.snapRight * delta_x); + rc.top += pfc::rint32(e.snapTop * delta_y); + rc.bottom += pfc::rint32(e.snapBottom * delta_y); + + return rc; +} + +CWindow CDialogResizeHelper::ResolveWnd(runtime_t const & rt) const { + if ( rt.userHWND != NULL ) return rt.userHWND; + return m_thisWnd.GetDlgItem( rt.initData.id ); +} + +CSize CDialogResizeHelper::CurrentSize() const { + CRect rc; + WIN32_OP_D( m_thisWnd.GetClientRect(rc) ); + return rc.Size(); +} + +void CDialogResizeHelper::OnSize(UINT, CSize newSize) +{ + if (m_thisWnd != NULL) { + HDWP hWinPosInfo = BeginDeferWindowPos((int)(m_runtime.size() + (m_sizeGrip != NULL ? 1 : 0))); + for (auto iter = m_runtime.begin(); iter != m_runtime.end(); ++ iter) { + CRect rc = _EvalRect(*iter, newSize); + hWinPosInfo = DeferWindowPos(hWinPosInfo, ResolveWnd(*iter), 0, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS); + } + if (m_sizeGrip != NULL) + { + RECT rc, rc_grip; + if (m_thisWnd.GetClientRect(&rc) && m_sizeGrip.GetWindowRect(&rc_grip)) { + DWORD flags = SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOCOPYBITS; + if (IsZoomed(m_thisWnd)) flags |= SWP_HIDEWINDOW; + else flags |= SWP_SHOWWINDOW; + hWinPosInfo = DeferWindowPos(hWinPosInfo, m_sizeGrip, NULL, rc.right - (rc_grip.right - rc_grip.left), rc.bottom - (rc_grip.bottom - rc_grip.top), 0, 0, flags); + } + } + EndDeferWindowPos(hWinPosInfo); + //RedrawWindow(m_thisWnd, NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN); + } + SetMsgHandled(FALSE); +} + +void CDialogResizeHelper::OnGetMinMaxInfo(LPMINMAXINFO info) const { + CRect r; + const DWORD dwStyle = m_thisWnd.GetWindowLong(GWL_STYLE); + const DWORD dwExStyle = m_thisWnd.GetWindowLong(GWL_EXSTYLE); + if (max_x && max_y) + { + r.left = 0; r.right = max_x; + r.top = 0; r.bottom = max_y; + MapDialogRect(m_thisWnd, &r); + AdjustWindowRectEx(&r, dwStyle, FALSE, dwExStyle); + info->ptMaxTrackSize.x = r.right - r.left; + info->ptMaxTrackSize.y = r.bottom - r.top; + } + if (min_x && min_y) + { + r.left = 0; r.right = min_x; + r.top = 0; r.bottom = min_y; + MapDialogRect(m_thisWnd, &r); + AdjustWindowRectEx(&r, dwStyle, FALSE, dwExStyle); + info->ptMinTrackSize.x = r.right - r.left; + info->ptMinTrackSize.y = r.bottom - r.top; + } +} + +void CDialogResizeHelper::OnInitDialog(CWindow thisWnd) { + + m_thisWnd = thisWnd; + const auto origSize = CurrentSize(); + for( auto initIter = m_initData.begin(); initIter != m_initData.end(); ++ initIter ) { + CRect rc; + if (GetChildWindowRect(m_thisWnd, initIter->id, &rc)) { + runtime_t rt; + rt.origRect = rc; + rt.initData = * initIter; + rt.origWindowSize = origSize; + m_runtime.push_back( std::move(rt) ); + } + } + AddSizeGrip(); + SetMsgHandled(FALSE); +} +void CDialogResizeHelper::OnDestroy() { + m_runtime.clear(); + m_sizeGrip = NULL; m_thisWnd = NULL; + SetMsgHandled(FALSE); +} + +void CDialogResizeHelper::AddSizeGrip() +{ + if ( m_autoSizeGrip && m_thisWnd != NULL && m_sizeGrip == NULL) + { + if (m_thisWnd.GetWindowLong(GWL_STYLE) & WS_POPUP) { + m_sizeGrip = CreateWindowEx(0, WC_SCROLLBAR, _T(""), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SBS_SIZEGRIP | SBS_SIZEBOXBOTTOMRIGHTALIGN, + 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, + m_thisWnd, (HMENU)0, NULL, NULL); + if (m_sizeGrip != NULL) + { + RECT rc, rc_grip; + if (m_thisWnd.GetClientRect(&rc) && m_sizeGrip.GetWindowRect(&rc_grip)) { + m_sizeGrip.SetWindowPos(NULL, rc.right - (rc_grip.right - rc_grip.left), rc.bottom - (rc_grip.bottom - rc_grip.top), 0, 0, SWP_NOZORDER | SWP_NOSIZE); + } + } + } + } +} + + +void CDialogResizeHelper::InitTable(const Param* table, size_t tableSize) { + m_initData.assign( table, table+tableSize ); +} +void CDialogResizeHelper::InitTable(const ParamOld * table, size_t tableSize) { + m_initData.resize(tableSize); + for (size_t walk = 0; walk < tableSize; ++walk) { + const ParamOld in = table[walk]; + Param entry = {}; + entry.id = table[walk].id; + if (in.flags & CDialogResizeHelperCompat::X_MOVE) entry.snapLeft = entry.snapRight = 1; + else if (in.flags & CDialogResizeHelperCompat::X_SIZE) entry.snapRight = 1; + if (in.flags & CDialogResizeHelperCompat::Y_MOVE) entry.snapTop = entry.snapBottom = 1; + else if (in.flags & CDialogResizeHelperCompat::Y_SIZE) entry.snapBottom = 1; + m_initData[walk] = entry; + } +} +void CDialogResizeHelper::InitMinMax(const CRect & range) { + min_x = range.left; min_y = range.top; max_x = range.right; max_y = range.bottom; +} + +void CDialogResizeHelper::AddControl(Param const & initData, CWindow wnd) { + CRect rc; + if ( wnd == NULL ) { + PFC_ASSERT( initData.id != 0 ); + WIN32_OP_D(GetChildWindowRect(m_thisWnd, initData.id, rc)); + } else { + WIN32_OP_D(GetChildWindowRect2(m_thisWnd, wnd, rc)); + } + + runtime_t rt; + rt.initData = initData; + rt.userHWND = wnd; + rt.origRect = rc; + rt.origWindowSize = this->CurrentSize(); + m_runtime.push_back( std::move(rt) ); +} + +bool CDialogResizeHelper::RemoveControl(CWindow wnd) { + return pfc::remove_if_t( m_runtime, [wnd] (runtime_t const & rt) { + return rt.userHWND == wnd; + } ) > 0; +} + +bool CDialogResizeHelper::HaveControl(CWindow wnd) const { + for( auto i = m_runtime.begin(); i != m_runtime.end(); ++ i ) { + if ( i->userHWND == wnd ) return true; + } + return false; +}
