From 1a6bc0c447e99b92f1ab86acb7be75a9b659e1f7 Mon Sep 17 00:00:00 2001 From: Justin Marshall Date: Wed, 6 May 2026 23:43:11 -0700 Subject: [PATCH] Fixed up the wait dialog. --- neo/tools/radiant/WaitDlg.cpp | 638 ++++++++++++++++++++++++++++++---- neo/tools/radiant/WaitDlg.h | 103 ++++-- 2 files changed, 645 insertions(+), 96 deletions(-) diff --git a/neo/tools/radiant/WaitDlg.cpp b/neo/tools/radiant/WaitDlg.cpp index 5ce476c2..03ac77f2 100644 --- a/neo/tools/radiant/WaitDlg.cpp +++ b/neo/tools/radiant/WaitDlg.cpp @@ -2,9 +2,9 @@ =========================================================================== IceTech GPL Source Code -Copyright (C) 2026 Justin Marshall +Copyright (C) 2026 Justin Marshall -This file is part of the IceTech GPL Source Code (?IceTech Source Code?). +This file is part of the IceTech GPL Source Code (?IceTech Source Code?). IceTech Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -38,101 +38,615 @@ If you have questions concerning this license or the applicable additional terms static char THIS_FILE[] = __FILE__; #endif +#define WAITDLG_TIMER_ANIMATE 1001 +#define WAITDLG_TIMER_MS 33 + +// Runtime size. This makes the old tiny resource dialog larger without +// needing to edit the .rc file. +#define WAITDLG_WIDTH 560 +#define WAITDLG_HEIGHT 260 + ///////////////////////////////////////////////////////////////////////////// // CWaitDlg dialog +CWaitDlg::CWaitDlg(CWnd* pParent, const char* msg) + : CDialog(CWaitDlg::IDD, pParent) { + waitStr = msg ? msg : "Wait..."; + text = waitStr; + + titleStr = "IceTech Radiant"; -CWaitDlg::CWaitDlg(CWnd* pParent, const char *msg) - : CDialog(CWaitDlg::IDD, pParent) -{ - //{{AFX_DATA_INIT(CWaitDlg) - waitStr = msg; - //}}AFX_DATA_INIT cancelPressed = false; - Create(CWaitDlg::IDD); - //g_pParentWnd->SetBusy(true); + cancelAllowed = false; + + progressPercent = -1; + marqueeOffset = 0; + pulseFrame = 0; + + colorBackTop = RGB(13, 17, 26); + colorBackBottom = RGB(24, 30, 45); + colorPanel = RGB(28, 35, 52); + colorPanelBorder = RGB(62, 78, 112); + colorText = RGB(236, 242, 255); + colorMutedText = RGB(148, 162, 190); + colorAccent = RGB(83, 169, 255); + colorAccent2 = RGB(127, 96, 255); + colorProgressBack = RGB(15, 20, 31); + colorDanger = RGB(255, 92, 112); + + InitModernResources(); + + Create(CWaitDlg::IDD, pParent); } CWaitDlg::~CWaitDlg() { - g_pParentWnd->SetBusy(false); + KillTimer(WAITDLG_TIMER_ANIMATE); + FreeModernResources(); + + if (g_pParentWnd) { + g_pParentWnd->SetBusy(false); + } } -void CWaitDlg::DoDataExchange(CDataExchange* pDX) -{ +void CWaitDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CWaitDlg) - DDX_Text(pDX, IDC_WAITSTR, waitStr); - //}}AFX_DATA_MAP -} + // Keep the original DDX mapping alive for old resource compatibility. + DDX_Text(pDX, IDC_WAITSTR, waitStr); +} BEGIN_MESSAGE_MAP(CWaitDlg, CDialog) - //{{AFX_MSG_MAP(CWaitDlg) - //}}AFX_MSG_MAP + ON_WM_PAINT() + ON_WM_ERASEBKGND() + ON_WM_TIMER() + ON_WM_SIZE() + ON_WM_CTLCOLOR() END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// -// CWaitDlg message handlers +// Modern resources -BOOL CWaitDlg::OnInitDialog() -{ +void CWaitDlg::InitModernResources(void) { + LOGFONT lf; + memset(&lf, 0, sizeof(lf)); + + lf.lfHeight = -23; + lf.lfWeight = FW_SEMIBOLD; + lf.lfQuality = CLEARTYPE_QUALITY; + strcpy(lf.lfFaceName, "Segoe UI"); + titleFont.CreateFontIndirect(&lf); + + memset(&lf, 0, sizeof(lf)); + lf.lfHeight = -15; + lf.lfWeight = FW_NORMAL; + lf.lfQuality = CLEARTYPE_QUALITY; + strcpy(lf.lfFaceName, "Segoe UI"); + messageFont.CreateFontIndirect(&lf); + + memset(&lf, 0, sizeof(lf)); + lf.lfHeight = -12; + lf.lfWeight = FW_NORMAL; + lf.lfQuality = CLEARTYPE_QUALITY; + strcpy(lf.lfFaceName, "Segoe UI"); + smallFont.CreateFontIndirect(&lf); + + transparentBrush.CreateStockObject(NULL_BRUSH); +} + +void CWaitDlg::FreeModernResources(void) { + if (titleFont.GetSafeHandle()) { + titleFont.DeleteObject(); + } + if (messageFont.GetSafeHandle()) { + messageFont.DeleteObject(); + } + if (smallFont.GetSafeHandle()) { + smallFont.DeleteObject(); + } + if (transparentBrush.GetSafeHandle()) { + transparentBrush.DeleteObject(); + } +} + +///////////////////////////////////////////////////////////////////////////// +// Dialog init + +BOOL CWaitDlg::OnInitDialog() { CDialog::OnInitDialog(); - //GetDlgItem(IDC_WAITSTR)->SetWindowText(waitStr); - GetDlgItem(IDC_WAITSTR)->SetFocus(); + + ModifyStyleEx(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE, 0); + ModifyStyle(WS_THICKFRAME, 0); + + SetWindowText("Please wait"); + + ResizeAndCenterDialog(); + + CWnd* pWaitText = GetDlgItem(IDC_WAITSTR); + if (pWaitText && pWaitText->GetSafeHwnd()) { + pWaitText->ShowWindow(SW_HIDE); + } + + CWnd* pCancelButton = GetDlgItem(IDCANCEL); + if (pCancelButton && pCancelButton->GetSafeHwnd()) { + pCancelButton->SetFont(&messageFont); + pCancelButton->SetWindowText("Cancel"); + } + UpdateData(FALSE); + + AllowCancel(false); + LayoutModernControls(); + + SetTimer(WAITDLG_TIMER_ANIMATE, WAITDLG_TIMER_MS, NULL); + ShowWindow(SW_SHOW); - - // cancel disabled by default - AllowCancel( false ); - - // TODO: Add extra initialization here - - return TRUE; // return TRUE unless you set the focus to a control - // EXCEPTION: OCX Property Pages should return FALSE -} - -void CWaitDlg::SetText(const char *msg, bool append) { - if (append) { - waitStr = text; - waitStr += "\r\n"; - waitStr += msg; - } else { - waitStr = msg; - text = msg; - } - UpdateData(FALSE); - Invalidate(); + Invalidate(FALSE); UpdateWindow(); - ShowWindow (SW_SHOWNORMAL); + + return TRUE; } -void CWaitDlg::AllowCancel( bool enable ) { - // this shows or hides the Cancel button - CWnd* pCancelButton = GetDlgItem (IDCANCEL); - ASSERT (pCancelButton); - if ( enable ) { - pCancelButton->ShowWindow (SW_NORMAL); - } else { - pCancelButton->ShowWindow (SW_HIDE); +void CWaitDlg::ResizeAndCenterDialog(void) { + CRect rcWindow; + GetWindowRect(&rcWindow); + + int width = WAITDLG_WIDTH; + int height = WAITDLG_HEIGHT; + + CWnd* pParent = GetParent(); + CRect rcParent; + + if (pParent && pParent->GetSafeHwnd()) { + pParent->GetWindowRect(&rcParent); } + else { + SystemParametersInfo(SPI_GETWORKAREA, 0, &rcParent, 0); + } + + int x = rcParent.left + ((rcParent.Width() - width) / 2); + int y = rcParent.top + ((rcParent.Height() - height) / 2); + + SetWindowPos(NULL, x, y, width, height, SWP_NOZORDER | SWP_NOACTIVATE); } -bool CWaitDlg::CancelPressed( void ) { +///////////////////////////////////////////////////////////////////////////// +// Public API + +void CWaitDlg::SetText(const char* msg, bool append) { + if (append) { + waitStr = text.c_str(); + waitStr += "\r\n"; + waitStr += msg ? msg : ""; + + text = waitStr; + } + else { + waitStr = msg ? msg : ""; + text = waitStr; + } + + UpdateData(FALSE); + Invalidate(FALSE); + UpdateWindow(); + ShowWindow(SW_SHOWNORMAL); +} + +void CWaitDlg::SetTitleText(const char* title) { + titleStr = title ? title : ""; + Invalidate(FALSE); + UpdateWindow(); +} + +void CWaitDlg::SetProgress(int percent) { + if (percent < 0) { + progressPercent = -1; + } + else { + if (percent > 100) { + percent = 100; + } + progressPercent = percent; + } + + Invalidate(FALSE); + UpdateWindow(); +} + +void CWaitDlg::StepProgress(int amount) { + if (progressPercent < 0) { + progressPercent = 0; + } + + progressPercent += amount; + + if (progressPercent < 0) { + progressPercent = 0; + } + if (progressPercent > 100) { + progressPercent = 100; + } + + Invalidate(FALSE); + UpdateWindow(); +} + +int CWaitDlg::GetProgress(void) const { + return progressPercent; +} + +void CWaitDlg::AllowCancel(bool enable) { + cancelAllowed = enable; + + CWnd* pCancelButton = GetDlgItem(IDCANCEL); + ASSERT(pCancelButton); + + if (pCancelButton && pCancelButton->GetSafeHwnd()) { + pCancelButton->ShowWindow(enable ? SW_SHOW : SW_HIDE); + } + + LayoutModernControls(); + Invalidate(FALSE); +} + +bool CWaitDlg::CancelPressed(void) { + PumpMessages(); + return cancelPressed; +} + +void CWaitDlg::PumpMessages(void) { #if _MSC_VER >= 1300 - MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!! + MSG* msg = AfxGetCurrentMessage(); #else - MSG *msg = &m_msgCur; + MSG* msg = &m_msgCur; #endif - while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) { - // pump message - if ( !AfxGetApp()->PumpMessage() ) { + while (::PeekMessage(msg, NULL, 0, 0, PM_NOREMOVE)) { + if (!AfxGetApp()->PumpMessage()) { + break; } } - - return cancelPressed; } void CWaitDlg::OnCancel() { cancelPressed = true; } + +///////////////////////////////////////////////////////////////////////////// +// Layout + +void CWaitDlg::OnSize(UINT nType, int cx, int cy) { + CDialog::OnSize(nType, cx, cy); + LayoutModernControls(); + Invalidate(FALSE); +} + +void CWaitDlg::LayoutModernControls(void) { + if (!GetSafeHwnd()) { + return; + } + + CRect rcClient; + GetClientRect(&rcClient); + + CWnd* pCancelButton = GetDlgItem(IDCANCEL); + if (pCancelButton && pCancelButton->GetSafeHwnd()) { + const int buttonW = 112; + const int buttonH = 32; + const int margin = 26; + + CRect rcButton; + rcButton.left = rcClient.right - margin - buttonW; + rcButton.top = rcClient.bottom - margin - buttonH; + rcButton.right = rcButton.left + buttonW; + rcButton.bottom = rcButton.top + buttonH; + + pCancelButton->MoveWindow(rcButton); + } +} + +///////////////////////////////////////////////////////////////////////////// +// Paint + +BOOL CWaitDlg::OnEraseBkgnd(CDC* pDC) { + return TRUE; +} + +HBRUSH CWaitDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { + pDC->SetBkMode(TRANSPARENT); + pDC->SetTextColor(colorText); + return (HBRUSH)transparentBrush.GetSafeHandle(); +} + +void CWaitDlg::OnTimer(UINT_PTR nIDEvent) { + if (nIDEvent == WAITDLG_TIMER_ANIMATE) { + pulseFrame++; + + marqueeOffset += 5; + if (marqueeOffset > 10000) { + marqueeOffset = 0; + } + + Invalidate(FALSE); + return; + } + + CDialog::OnTimer(nIDEvent); +} + +void CWaitDlg::OnPaint() { + CPaintDC dcPaint(this); + + CRect rcClient; + GetClientRect(&rcClient); + + CDC memDC; + CBitmap memBmp; + CBitmap* oldBmp = NULL; + + memDC.CreateCompatibleDC(&dcPaint); + memBmp.CreateCompatibleBitmap(&dcPaint, rcClient.Width(), rcClient.Height()); + oldBmp = memDC.SelectObject(&memBmp); + + DrawModernBackground(memDC, rcClient); + DrawHeader(memDC, rcClient); + DrawMessage(memDC, rcClient); + DrawProgress(memDC, rcClient); + + dcPaint.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &memDC, 0, 0, SRCCOPY); + + if (oldBmp) { + memDC.SelectObject(oldBmp); + } +} + +void CWaitDlg::DrawModernBackground(CDC& dc, const CRect& rcClient) { + TRIVERTEX vertex[2]; + + vertex[0].x = rcClient.left; + vertex[0].y = rcClient.top; + vertex[0].Red = GetRValue(colorBackTop) << 8; + vertex[0].Green = GetGValue(colorBackTop) << 8; + vertex[0].Blue = GetBValue(colorBackTop) << 8; + vertex[0].Alpha = 0x0000; + + vertex[1].x = rcClient.right; + vertex[1].y = rcClient.bottom; + vertex[1].Red = GetRValue(colorBackBottom) << 8; + vertex[1].Green = GetGValue(colorBackBottom) << 8; + vertex[1].Blue = GetBValue(colorBackBottom) << 8; + vertex[1].Alpha = 0x0000; + + GRADIENT_RECT gRect; + gRect.UpperLeft = 0; + gRect.LowerRight = 1; + + dc.GradientFill(vertex, 2, &gRect, 1, GRADIENT_FILL_RECT_V); + + CRect panel = rcClient; + panel.DeflateRect(14, 14, 14, 14); + + DrawRoundedRect(dc, panel, colorPanel, colorPanelBorder, 18); + + // Top glass sheen. + CRect sheen = panel; + sheen.bottom = sheen.top + 70; + + TRIVERTEX sheenVertex[2]; + + sheenVertex[0].x = sheen.left; + sheenVertex[0].y = sheen.top; + sheenVertex[0].Red = 60 << 8; + sheenVertex[0].Green = 78 << 8; + sheenVertex[0].Blue = 118 << 8; + sheenVertex[0].Alpha = 0x0000; + + sheenVertex[1].x = sheen.right; + sheenVertex[1].y = sheen.bottom; + sheenVertex[1].Red = GetRValue(colorPanel) << 8; + sheenVertex[1].Green = GetGValue(colorPanel) << 8; + sheenVertex[1].Blue = GetBValue(colorPanel) << 8; + sheenVertex[1].Alpha = 0x0000; + + dc.GradientFill(sheenVertex, 2, &gRect, 1, GRADIENT_FILL_RECT_V); + + // Header separator. + CRect accent = panel; + accent.left += 24; + accent.right -= 24; + accent.top += 66; + accent.bottom = accent.top + 1; + + CPen accentPen(PS_SOLID, 1, RGB(72, 91, 130)); + CPen* oldPen = dc.SelectObject(&accentPen); + dc.MoveTo(accent.left, accent.top); + dc.LineTo(accent.right, accent.top); + dc.SelectObject(oldPen); +} + +void CWaitDlg::DrawHeader(CDC& dc, const CRect& rcClient) { + CRect panel = rcClient; + panel.DeflateRect(14, 14, 14, 14); + + CRect iconRc; + iconRc.left = panel.left + 26; + iconRc.top = panel.top + 20; + iconRc.right = iconRc.left + 30; + iconRc.bottom = iconRc.top + 30; + + int glow = 20 + (pulseFrame % 50); + if (glow > 45) { + glow = 70 - glow; + } + + COLORREF coreColor = RGB( + min(255, GetRValue(colorAccent) + glow), + min(255, GetGValue(colorAccent) + glow / 2), + min(255, GetBValue(colorAccent)) + ); + + DrawRoundedRect(dc, iconRc, coreColor, RGB(155, 205, 255), 8); + + CRect inner = iconRc; + inner.DeflateRect(7, 7, 7, 7); + DrawRoundedRect(dc, inner, RGB(18, 25, 38), RGB(150, 220, 255), 4); + + CFont* oldFont = dc.SelectObject(&titleFont); + dc.SetBkMode(TRANSPARENT); + dc.SetTextColor(colorText); + + CRect titleRc; + titleRc.left = iconRc.right + 14; + titleRc.top = panel.top + 17; + titleRc.right = panel.right - 26; + titleRc.bottom = titleRc.top + 30; + + dc.DrawText(titleStr, &titleRc, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); + + dc.SelectObject(&smallFont); + dc.SetTextColor(colorMutedText); + + CRect subRc = titleRc; + subRc.top += 28; + subRc.bottom = subRc.top + 20; + + CString subText = "Working on the current Radiant task"; + dc.DrawText(subText, &subRc, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); + + dc.SelectObject(oldFont); +} + +void CWaitDlg::DrawMessage(CDC& dc, const CRect& rcClient) { + CRect panel = rcClient; + panel.DeflateRect(14, 14, 14, 14); + + // Move status text higher and reserve a larger footer. + const int headerBottom = panel.top + 70; + const int footerHeight = cancelAllowed ? 138 : 108; + + CRect textRc; + textRc.left = panel.left + 28; + textRc.top = headerBottom + 6; + textRc.right = panel.right - 28; + textRc.bottom = panel.bottom - footerHeight; + + if (textRc.bottom < textRc.top + 26) { + textRc.bottom = textRc.top + 26; + } + + CFont* oldFont = dc.SelectObject(&messageFont); + dc.SetBkMode(TRANSPARENT); + dc.SetTextColor(colorText); + + CString drawText = waitStr; + if (drawText.IsEmpty()) { + drawText = "Please wait..."; + } + + dc.DrawText(drawText, &textRc, DT_LEFT | DT_TOP | DT_WORDBREAK | DT_END_ELLIPSIS); + + dc.SelectObject(oldFont); +} + +void CWaitDlg::DrawProgress(CDC& dc, const CRect& rcClient) { + CRect panel = rcClient; + panel.DeflateRect(14, 14, 14, 14); + + // Push progress lower so it never overlaps the status text. + CRect barRc; + barRc.left = panel.left + 28; + barRc.right = panel.right - 28; + + if (cancelAllowed) { + barRc.bottom = panel.bottom - 54; + } + else { + barRc.bottom = panel.bottom - 28; + } + + barRc.top = barRc.bottom - 18; + + DrawRoundedRect(dc, barRc, colorProgressBack, RGB(54, 68, 96), 9); + + CRect fillRc = barRc; + fillRc.DeflateRect(2, 2, 2, 2); + + if (progressPercent >= 0) { + int fillW = MulDiv(fillRc.Width(), progressPercent, 100); + + CRect filled = fillRc; + filled.right = filled.left + fillW; + + if (filled.Width() > 0) { + DrawRoundedRect(dc, filled, colorAccent, RGB(125, 205, 255), 8); + } + + CString percentText; + percentText.Format("%d%%", progressPercent); + + CFont* oldFont = dc.SelectObject(&smallFont); + dc.SetBkMode(TRANSPARENT); + dc.SetTextColor(colorMutedText); + + CRect labelRc = barRc; + labelRc.top = barRc.bottom + 6; + labelRc.bottom = labelRc.top + 18; + + dc.DrawText(percentText, &labelRc, DT_RIGHT | DT_VCENTER | DT_SINGLELINE); + + dc.SelectObject(oldFont); + } + else { + const int chunkW = max(64, fillRc.Width() / 4); + const int travelW = fillRc.Width() + chunkW; + const int x = fillRc.left - chunkW + (marqueeOffset % travelW); + + CRect chunk; + chunk.left = x; + chunk.right = x + chunkW; + chunk.top = fillRc.top; + chunk.bottom = fillRc.bottom; + + CRect clipped; + clipped.IntersectRect(&chunk, &fillRc); + + if (!clipped.IsRectEmpty()) { + DrawRoundedRect(dc, clipped, colorAccent, RGB(125, 205, 255), 8); + } + + CRect glowChunk = chunk; + glowChunk.OffsetRect(-chunkW / 2, 0); + + CRect glowClip; + glowClip.IntersectRect(&glowChunk, &fillRc); + + if (!glowClip.IsRectEmpty()) { + DrawRoundedRect(dc, glowClip, colorAccent2, RGB(140, 120, 255), 8); + } + + CFont* oldFont = dc.SelectObject(&smallFont); + dc.SetBkMode(TRANSPARENT); + dc.SetTextColor(colorMutedText); + + CRect labelRc = barRc; + labelRc.top = barRc.bottom + 6; + labelRc.bottom = labelRc.top + 18; + + CString label = "Processing..."; + dc.DrawText(label, &labelRc, DT_RIGHT | DT_VCENTER | DT_SINGLELINE); + + dc.SelectObject(oldFont); + } +} + +void CWaitDlg::DrawRoundedRect(CDC& dc, const CRect& rc, COLORREF fill, COLORREF outline, int radius) { + CBrush brush(fill); + CPen pen(PS_SOLID, 1, outline); + + CBrush* oldBrush = dc.SelectObject(&brush); + CPen* oldPen = dc.SelectObject(&pen); + + dc.RoundRect(&rc, CPoint(radius, radius)); + + dc.SelectObject(oldBrush); + dc.SelectObject(oldPen); +} \ No newline at end of file diff --git a/neo/tools/radiant/WaitDlg.h b/neo/tools/radiant/WaitDlg.h index f18b0f71..701041db 100644 --- a/neo/tools/radiant/WaitDlg.h +++ b/neo/tools/radiant/WaitDlg.h @@ -2,9 +2,9 @@ =========================================================================== IceTech GPL Source Code -Copyright (C) 2026 Justin Marshall +Copyright (C) 2026 Justin Marshall -This file is part of the IceTech GPL Source Code (?IceTech Source Code?). +This file is part of the IceTech GPL Source Code (?IceTech Source Code?). IceTech Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,58 +25,93 @@ If you have questions concerning this license or the applicable additional terms =========================================================================== */ + #if !defined(AFX_WAITDLG_H__2B7A6C91_8D3F_4BEE_B564_33A0CFFA241B__INCLUDED_) #define AFX_WAITDLG_H__2B7A6C91_8D3F_4BEE_B564_33A0CFFA241B__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 -// WaitDlg.h : header file -// ///////////////////////////////////////////////////////////////////////////// // CWaitDlg dialog -class CWaitDlg : public CDialog -{ -// Construction +class CWaitDlg : public CDialog { public: - CWaitDlg(CWnd* pParent = NULL, const char *msg = "Wait..."); // standard constructor - ~CWaitDlg(); - void SetText(const char *msg, bool append = false); - void AllowCancel( bool enable ); - bool CancelPressed( void ); + CWaitDlg(CWnd* pParent = NULL, const char* msg = "Wait..."); + virtual ~CWaitDlg(); + + void SetText(const char* msg, bool append = false); + void AllowCancel(bool enable); + bool CancelPressed(void); + + // New progress API. + // SetProgress(-1) = animated indeterminate marquee. + // SetProgress(0..100) = fixed progress amount. + void SetProgress(int percent); + void StepProgress(int amount = 1); + int GetProgress(void) const; + + void SetTitleText(const char* title); -// Dialog Data - //{{AFX_DATA(CWaitDlg) enum { IDD = IDD_DLG_WAIT }; - CString waitStr; - //}}AFX_DATA + CString waitStr; -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CWaitDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation protected: - - // Generated message map functions - //{{AFX_MSG(CWaitDlg) + virtual void DoDataExchange(CDataExchange* pDX); virtual BOOL OnInitDialog(); virtual void OnCancel(); - //}}AFX_MSG + + afx_msg void OnPaint(); + afx_msg BOOL OnEraseBkgnd(CDC* pDC); + afx_msg void OnTimer(UINT_PTR nIDEvent); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); + DECLARE_MESSAGE_MAP() private: - idStr text; - bool cancelPressed; + void InitModernResources(void); + void FreeModernResources(void); + void LayoutModernControls(void); + void ResizeAndCenterDialog(void); + + void DrawModernBackground(CDC& dc, const CRect& rcClient); + void DrawHeader(CDC& dc, const CRect& rcClient); + void DrawMessage(CDC& dc, const CRect& rcClient); + void DrawProgress(CDC& dc, const CRect& rcClient); + void DrawRoundedRect(CDC& dc, const CRect& rc, COLORREF fill, COLORREF outline, int radius); + + void PumpMessages(void); + +private: + idStr text; + bool cancelPressed; + bool cancelAllowed; + + CString titleStr; + + int progressPercent; // -1 = indeterminate / marquee + int marqueeOffset; + int pulseFrame; + + CFont titleFont; + CFont messageFont; + CFont smallFont; + + CBrush transparentBrush; + + COLORREF colorBackTop; + COLORREF colorBackBottom; + COLORREF colorPanel; + COLORREF colorPanelBorder; + COLORREF colorText; + COLORREF colorMutedText; + COLORREF colorAccent; + COLORREF colorAccent2; + COLORREF colorProgressBack; + COLORREF colorDanger; }; -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_WAITDLG_H__2B7A6C91_8D3F_4BEE_B564_33A0CFFA241B__INCLUDED_) +#endif // !defined(AFX_WAITDLG_H__2B7A6C91_8D3F_4BEE_B564_33A0CFFA241B__INCLUDED_) \ No newline at end of file