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;
+}