/* =========================================================================== IceTech GPL Source Code Copyright (C) 2026 Justin Marshall =========================================================================== */ #include "precompiled.h" #pragma hdrstop #include "qe3.h" #include "Radiant.h" #include "GLWidget.h" #include "ConsoleDlg.h" #include "InspectorDialog.h" #include "OutlinerDlg.h" #include "TabsDlg.h" #include CInspectorDialog* g_Inspectors = NULL; static const COLORREF INSPECTOR_BG = RGB(17, 19, 23); static const COLORREF INSPECTOR_PANEL_BG = RGB(23, 26, 31); static const COLORREF INSPECTOR_TEXT = RGB(226, 232, 240); static const COLORREF INSPECTOR_MUTED_TEXT = RGB(151, 163, 184); static const COLORREF INSPECTOR_BORDER = RGB(58, 64, 72); static const int INSPECTOR_MARGIN = 6; static const int INSPECTOR_TAB_HEIGHT = 36; static const int INSPECTOR_DIVIDER_HEIGHT = 1; static const COLORREF INSPECTOR_TAB_BG = RGB(17, 19, 23); static const COLORREF INSPECTOR_TAB_INACTIVE = RGB(28, 31, 36); static const COLORREF INSPECTOR_TAB_ACTIVE = RGB(24, 27, 32); static const COLORREF INSPECTOR_ACCENT = RGB(87, 166, 255); static const char* INSPECTOR_DARK_TAB_OLDPROC = "IceTech.Inspector.DarkTabOldProc"; static const char* INSPECTOR_DARK_PARENT_OLDPROC = "IceTech.Inspector.DarkParentOldProc"; static const char* INSPECTOR_DARK_FIELD_OLDPROC = "IceTech.Inspector.DarkFieldOldProc"; #ifndef TCM_GETITEMA #define TCM_GETITEMA TCM_GETITEM #endif #ifndef TCITEMA #define TCITEMA TCITEM #endif #ifndef TCM_INSERTITEMA #define TCM_INSERTITEMA TCM_INSERTITEM #endif static void InspectorDark_FillRect(HDC hDC, const RECT& rc, COLORREF color) { HBRUSH brush = ::CreateSolidBrush(color); ::FillRect(hDC, &rc, brush); ::DeleteObject(brush); } static void InspectorDark_FrameRect(HDC hDC, const RECT& rc, COLORREF color) { HBRUSH brush = ::CreateSolidBrush(color); ::FrameRect(hDC, &rc, brush); ::DeleteObject(brush); } static void InspectorDark_ApplyNativeTheme(HWND hWnd) { if (!hWnd) { return; } typedef HRESULT (WINAPI *SetWindowThemeProc)(HWND, LPCWSTR, LPCWSTR); typedef BOOL (WINAPI *AllowDarkModeForWindowProc)(HWND, BOOL); static HMODULE hUxTheme = ::LoadLibraryA("uxtheme.dll"); static SetWindowThemeProc pSetWindowTheme = hUxTheme ? (SetWindowThemeProc)::GetProcAddress(hUxTheme, "SetWindowTheme") : NULL; static AllowDarkModeForWindowProc pAllowDarkModeForWindow = hUxTheme ? (AllowDarkModeForWindowProc)::GetProcAddress(hUxTheme, MAKEINTRESOURCEA(133)) : NULL; if (pAllowDarkModeForWindow) { pAllowDarkModeForWindow(hWnd, TRUE); } if (pSetWindowTheme) { pSetWindowTheme(hWnd, L"DarkMode_Explorer", NULL); } ::SendMessage(hWnd, WM_THEMECHANGED, 0, 0); } static void InspectorDark_DrawTabControl(HWND hWnd, HDC hDC) { RECT client; ::GetClientRect(hWnd, &client); InspectorDark_FillRect(hDC, client, INSPECTOR_TAB_BG); HFONT font = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0); HFONT oldFont = font ? (HFONT)::SelectObject(hDC, font) : NULL; ::SetBkMode(hDC, TRANSPARENT); const int count = (int)::SendMessage(hWnd, TCM_GETITEMCOUNT, 0, 0); const int sel = (int)::SendMessage(hWnd, TCM_GETCURSEL, 0, 0); for (int i = 0; i < count; i++) { RECT item; if (!::SendMessage(hWnd, TCM_GETITEMRECT, (WPARAM)i, (LPARAM)&item)) { continue; } const bool active = (i == sel); RECT fill = item; fill.bottom += active ? 2 : 0; InspectorDark_FillRect(hDC, fill, active ? INSPECTOR_TAB_ACTIVE : INSPECTOR_TAB_INACTIVE); InspectorDark_FrameRect(hDC, fill, active ? INSPECTOR_ACCENT : INSPECTOR_BORDER); char text[128]; text[0] = '\0'; TCITEMA ti; memset(&ti, 0, sizeof(ti)); ti.mask = TCIF_TEXT; ti.pszText = text; ti.cchTextMax = sizeof(text); ::SendMessageA(hWnd, TCM_GETITEMA, (WPARAM)i, (LPARAM)&ti); ::SetTextColor(hDC, active ? RGB(245, 249, 255) : INSPECTOR_TEXT); ::DrawTextA(hDC, text, -1, &item, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); } RECT line = client; line.top = client.bottom - 1; InspectorDark_FillRect(hDC, line, INSPECTOR_BORDER); if (oldFont) { ::SelectObject(hDC, oldFont); } } static LRESULT CALLBACK InspectorDarkTabProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { WNDPROC oldProc = (WNDPROC)::GetPropA(hWnd, INSPECTOR_DARK_TAB_OLDPROC); if (!oldProc) { return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } switch (uMsg) { case WM_ERASEBKGND: return 1; case WM_PAINT: { PAINTSTRUCT ps; HDC hDC = ::BeginPaint(hWnd, &ps); InspectorDark_DrawTabControl(hWnd, hDC); ::EndPaint(hWnd, &ps); return 0; } case WM_PRINTCLIENT: InspectorDark_DrawTabControl(hWnd, (HDC)wParam); return 0; case WM_LBUTTONDOWN: case WM_LBUTTONUP: case TCM_INSERTITEMA: case TCM_DELETEITEM: case TCM_DELETEALLITEMS: case TCM_SETCURSEL: { LRESULT result = ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); ::InvalidateRect(hWnd, NULL, FALSE); return result; } case WM_NCDESTROY: { ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)oldProc); ::RemovePropA(hWnd, INSPECTOR_DARK_TAB_OLDPROC); return ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); } } return ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); } static void InspectorDark_SubclassTab(HWND hWnd) { if (!hWnd || ::GetPropA(hWnd, INSPECTOR_DARK_TAB_OLDPROC)) { return; } WNDPROC oldProc = (WNDPROC)::GetWindowLongPtr(hWnd, GWLP_WNDPROC); ::SetPropA(hWnd, INSPECTOR_DARK_TAB_OLDPROC, (HANDLE)oldProc); ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)InspectorDarkTabProc); ::InvalidateRect(hWnd, NULL, TRUE); } static HBRUSH InspectorDark_BgBrush() { static HBRUSH hBrush = ::CreateSolidBrush(INSPECTOR_BG); return hBrush; } static HBRUSH InspectorDark_FieldBrush() { static HBRUSH hBrush = ::CreateSolidBrush(RGB(14, 16, 20)); return hBrush; } static void InspectorDark_RemoveClientEdge(HWND hWnd) { if (!hWnd) { return; } LONG exStyle = ::GetWindowLong(hWnd, GWL_EXSTYLE); if (exStyle & WS_EX_CLIENTEDGE) { ::SetWindowLong(hWnd, GWL_EXSTYLE, exStyle & ~WS_EX_CLIENTEDGE); ::SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); } } static void InspectorDark_DrawWindowFrame(HWND hWnd) { HDC hDC = ::GetWindowDC(hWnd); if (!hDC) { return; } RECT rc; ::GetWindowRect(hWnd, &rc); ::OffsetRect(&rc, -rc.left, -rc.top); InspectorDark_FrameRect(hDC, rc, INSPECTOR_BORDER); ::ReleaseDC(hWnd, hDC); } static LRESULT CALLBACK InspectorDarkFieldProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { WNDPROC oldProc = (WNDPROC)::GetPropA(hWnd, INSPECTOR_DARK_FIELD_OLDPROC); if (!oldProc) { return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } switch (uMsg) { case WM_NCPAINT: case WM_PAINT: { LRESULT result = ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); InspectorDark_DrawWindowFrame(hWnd); return result; } case WM_SETFOCUS: case WM_KILLFOCUS: case WM_ENABLE: { LRESULT result = ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); ::RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW); return result; } case WM_NCDESTROY: { ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)oldProc); ::RemovePropA(hWnd, INSPECTOR_DARK_FIELD_OLDPROC); return ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); } } return ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); } static LRESULT CALLBACK InspectorDarkParentProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { WNDPROC oldProc = (WNDPROC)::GetPropA(hWnd, INSPECTOR_DARK_PARENT_OLDPROC); if (!oldProc) { return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } switch (uMsg) { case WM_ERASEBKGND: { RECT rc; ::GetClientRect(hWnd, &rc); InspectorDark_FillRect((HDC)wParam, rc, INSPECTOR_BG); return 1; } case WM_CTLCOLORDLG: return (LRESULT)InspectorDark_BgBrush(); case WM_CTLCOLORSTATIC: { HDC hDC = (HDC)wParam; ::SetTextColor(hDC, INSPECTOR_MUTED_TEXT); ::SetBkMode(hDC, TRANSPARENT); return (LRESULT)InspectorDark_BgBrush(); } case WM_CTLCOLOREDIT: case WM_CTLCOLORLISTBOX: { HDC hDC = (HDC)wParam; ::SetTextColor(hDC, INSPECTOR_TEXT); ::SetBkColor(hDC, RGB(14, 16, 20)); return (LRESULT)InspectorDark_FieldBrush(); } case WM_CTLCOLORBTN: { HDC hDC = (HDC)wParam; ::SetTextColor(hDC, INSPECTOR_TEXT); ::SetBkColor(hDC, INSPECTOR_BG); return (LRESULT)InspectorDark_BgBrush(); } case WM_NCDESTROY: { ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)oldProc); ::RemovePropA(hWnd, INSPECTOR_DARK_PARENT_OLDPROC); return ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); } } return ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); } static bool InspectorDark_IsClass(HWND hWnd, const char* className) { char actual[128]; actual[0] = '\0'; ::GetClassNameA(hWnd, actual, sizeof(actual)); return ::lstrcmpiA(actual, className) == 0; } static bool InspectorDark_IsKnownControl(HWND hWnd) { return InspectorDark_IsClass(hWnd, "Button") || InspectorDark_IsClass(hWnd, "Edit") || InspectorDark_IsClass(hWnd, "ComboBox") || InspectorDark_IsClass(hWnd, "ListBox") || InspectorDark_IsClass(hWnd, "SysTreeView32") || InspectorDark_IsClass(hWnd, "SysListView32") || InspectorDark_IsClass(hWnd, "SysTabControl32"); } static void InspectorDark_SubclassParent(HWND hWnd) { if (!hWnd || ::GetPropA(hWnd, INSPECTOR_DARK_PARENT_OLDPROC)) { return; } WNDPROC oldProc = (WNDPROC)::GetWindowLongPtr(hWnd, GWLP_WNDPROC); ::SetPropA(hWnd, INSPECTOR_DARK_PARENT_OLDPROC, (HANDLE)oldProc); ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)InspectorDarkParentProc); } static void InspectorDark_SubclassField(HWND hWnd) { if (!hWnd || ::GetPropA(hWnd, INSPECTOR_DARK_FIELD_OLDPROC)) { return; } WNDPROC oldProc = (WNDPROC)::GetWindowLongPtr(hWnd, GWLP_WNDPROC); ::SetPropA(hWnd, INSPECTOR_DARK_FIELD_OLDPROC, (HANDLE)oldProc); ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)InspectorDarkFieldProc); } static void InspectorDark_ApplyToWindowAndChildren(HWND hWnd) { if (!hWnd) { return; } InspectorDark_ApplyNativeTheme(hWnd); InspectorDark_RemoveClientEdge(hWnd); if (InspectorDark_IsClass(hWnd, "Edit") || InspectorDark_IsClass(hWnd, "ListBox") || InspectorDark_IsClass(hWnd, "SysTreeView32") || InspectorDark_IsClass(hWnd, "SysListView32")) { InspectorDark_SubclassField(hWnd); } else if (!InspectorDark_IsKnownControl(hWnd)) { InspectorDark_SubclassParent(hWnd); } if (InspectorDark_IsClass(hWnd, "SysTreeView32")) { ::SendMessage(hWnd, TVM_SETBKCOLOR, 0, (LPARAM)RGB(14, 16, 20)); ::SendMessage(hWnd, TVM_SETTEXTCOLOR, 0, (LPARAM)INSPECTOR_TEXT); } if (InspectorDark_IsClass(hWnd, "SysListView32")) { ::SendMessage(hWnd, LVM_SETBKCOLOR, 0, (LPARAM)RGB(14, 16, 20)); ::SendMessage(hWnd, LVM_SETTEXTBKCOLOR, 0, (LPARAM)RGB(14, 16, 20)); ::SendMessage(hWnd, LVM_SETTEXTCOLOR, 0, (LPARAM)INSPECTOR_TEXT); } for (HWND child = ::GetWindow(hWnd, GW_CHILD); child != NULL; child = ::GetWindow(child, GW_HWNDNEXT)) { InspectorDark_ApplyToWindowAndChildren(child); } } static void InspectorDark_ApplyToDialog(CWnd* wnd) { if (wnd && wnd->GetSafeHwnd()) { InspectorDark_ApplyToWindowAndChildren(wnd->GetSafeHwnd()); } } void InspectorsDockingCallback(bool docked, int ID, CWnd* wnd) { if (g_Inspectors) { g_Inspectors->SetDockedTabs(docked, ID); } } // CInspectorDialog dialog CInspectorDialog::CInspectorDialog(CWnd* pParent /*=NULL*/) : CTabsDlg(CInspectorDialog::IDD, pParent) { initialized = false; dockedTabs = W_CONSOLE | W_TEXTURE | W_MEDIA | W_OUTLINER; } CInspectorDialog::~CInspectorDialog() { if (modernFont.GetSafeHandle()) { modernFont.DeleteObject(); } if (bgBrush.GetSafeHandle()) { bgBrush.DeleteObject(); } if (editBrush.GetSafeHandle()) { editBrush.DeleteObject(); } if (staticBrush.GetSafeHandle()) { staticBrush.DeleteObject(); } } BEGIN_MESSAGE_MAP(CInspectorDialog, CTabsDlg) ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_INSPECTOR, OnTcnSelchange) ON_WM_SIZE() ON_WM_DESTROY() ON_WM_CLOSE() ON_WM_CTLCOLOR() ON_WM_ERASEBKGND() ON_WM_PAINT() END_MESSAGE_MAP() BOOL CInspectorDialog::OnInitDialog() { CTabsDlg::OnInitDialog(); ASSERT(m_Tabs.GetSafeHwnd()); LoadWindowPlacement(GetSafeHwnd(), "radiant_InspectorsWindow"); consoleWnd.Create(IDD_DIALOG_CONSOLE, this); texWnd.Create(TEXTURE_WINDOW_CLASS, "", QE3_SPLITTER_STYLE, CRect(5, 5, 10, 10), this, 1299); mediaDlg.Create(IDD_DIALOG_TEXTURELIST, this); entityDlg.Create(IDD_DIALOG_ENTITY, this); outlinerDlg.Create(this); dockedTabs = GetCvarInt("radiant_InspectorDockedDialogs", W_CONSOLE | W_TEXTURE | W_MEDIA | W_OUTLINER); AddDockedWindow(&consoleWnd, W_CONSOLE, 1, "Console", (dockedTabs & W_CONSOLE) != 0, InspectorsDockingCallback); AddDockedWindow(&texWnd, W_TEXTURE, 2, "Textures", (dockedTabs & W_TEXTURE) != 0, InspectorsDockingCallback); AddDockedWindow(&mediaDlg, W_MEDIA, 3, "Media", (dockedTabs & W_MEDIA) != 0, InspectorsDockingCallback); AddDockedWindow(&entityDlg, W_ENTITY, 4, "Entity", (dockedTabs & W_ENTITY) != 0, InspectorsDockingCallback); AddDockedWindow(&outlinerDlg, W_OUTLINER, 5, "Outliner", (dockedTabs & W_OUTLINER) != 0, InspectorsDockingCallback); ApplyModernTheme(); SetMode(W_CONSOLE); initialized = true; CRect rc; GetClientRect(&rc); LayoutModern(rc.Width(), rc.Height()); return TRUE; } void CInspectorDialog::ApplyModernTheme() { if (!modernFont.GetSafeHandle()) { LOGFONT lf; memset(&lf, 0, sizeof(lf)); HDC hDC = ::GetDC(GetSafeHwnd()); const int dpiY = GetDeviceCaps(hDC, LOGPIXELSY); ::ReleaseDC(GetSafeHwnd(), hDC); lf.lfHeight = -MulDiv(9, dpiY, 72); lf.lfWeight = FW_NORMAL; lf.lfQuality = CLEARTYPE_QUALITY; strncpy(lf.lfFaceName, "Segoe UI", sizeof(lf.lfFaceName) - 1); lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0'; modernFont.CreateFontIndirect(&lf); } if (!bgBrush.GetSafeHandle()) { bgBrush.CreateSolidBrush(INSPECTOR_BG); } if (!editBrush.GetSafeHandle()) { editBrush.CreateSolidBrush(INSPECTOR_PANEL_BG); } if (!staticBrush.GetSafeHandle()) { staticBrush.CreateSolidBrush(INSPECTOR_BG); } SetFont(&modernFont, FALSE); if (m_Tabs.GetSafeHwnd()) { m_Tabs.SetFont(&modernFont, FALSE); m_Tabs.ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_FRAMECHANGED); InspectorDark_ApplyNativeTheme(m_Tabs.GetSafeHwnd()); InspectorDark_SubclassTab(m_Tabs.GetSafeHwnd()); } ApplyModernFontRecursive(&consoleWnd); ApplyModernFontRecursive(&mediaDlg); ApplyModernFontRecursive(&entityDlg); ApplyModernFontRecursive(&outlinerDlg); InspectorDark_ApplyToDialog(&consoleWnd); InspectorDark_ApplyToDialog(&mediaDlg); InspectorDark_ApplyNativeTheme(entityDlg.GetSafeHwnd()); InspectorDark_ApplyToDialog(&outlinerDlg); ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_FRAMECHANGED); Invalidate(TRUE); } void CInspectorDialog::ApplyModernFontRecursive(CWnd* wnd) { if (!wnd || !wnd->GetSafeHwnd() || !modernFont.GetSafeHandle()) { return; } wnd->SetFont(&modernFont, FALSE); CWnd* child = wnd->GetWindow(GW_CHILD); while (child) { child->SetFont(&modernFont, FALSE); child = child->GetNextWindow(); } } void CInspectorDialog::SetMode(int mode, bool updateTabs) { FocusWindow(mode); } void CInspectorDialog::UpdateEntitySel(eclass_t* ent) { entityDlg.UpdateEntitySel(ent); } void CInspectorDialog::FillClassList() { entityDlg.AddClassNames(); } void CInspectorDialog::UpdateSelectedEntity() { entityDlg.SetKeyValPairs(); outlinerDlg.RefreshIfNeeded(); } bool CInspectorDialog::GetSelectAllCriteria(idStr& key, idStr& val) { CString k; CString v; entityDlg.editKey.GetWindowText(k); entityDlg.editVal.GetWindowText(v); key = k; val = v; return true; } void CInspectorDialog::LayoutModern(int cx, int cy) { if (!initialized || cx <= 0 || cy <= 0) { return; } const int margin = INSPECTOR_MARGIN; CRect tabRect; tabRect.left = margin; tabRect.right = cx - margin; tabRect.bottom = cy - margin; tabRect.top = tabRect.bottom - INSPECTOR_TAB_HEIGHT; if (tabRect.top < margin) { tabRect.top = margin; } if (m_Tabs.GetSafeHwnd()) { m_Tabs.SetWindowPos( NULL, tabRect.left, tabRect.top, tabRect.Width(), tabRect.Height(), SWP_NOZORDER | SWP_NOACTIVATE ); } CRect childRect; childRect.left = margin; childRect.top = margin; childRect.right = cx - margin; childRect.bottom = tabRect.top - margin; if (childRect.right < childRect.left) { childRect.right = childRect.left; } if (childRect.bottom < childRect.top) { childRect.bottom = childRect.top; } DockedWindowInfo* info = NULL; POSITION pos; WORD wID; for (pos = m_Windows.GetStartPosition(); pos != NULL; ) { m_Windows.GetNextAssoc(pos, wID, (void*&)info); if (info && info->m_Window && info->m_Window->GetSafeHwnd() && info->m_State == DockedWindowInfo::DOCKED) { info->m_Window->SetWindowPos( NULL, childRect.left, childRect.top, childRect.Width(), childRect.Height(), SWP_NOZORDER | SWP_NOACTIVATE ); info->m_Window->ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_FRAMECHANGED); } } } void CInspectorDialog::OnSize(UINT nType, int cx, int cy) { CTabsDlg::OnSize(nType, cx, cy); if (!initialized) { return; } LayoutModern(cx, cy); Invalidate(FALSE); } BOOL CInspectorDialog::OnEraseBkgnd(CDC* pDC) { CRect rc; GetClientRect(&rc); pDC->FillSolidRect(&rc, INSPECTOR_BG); return TRUE; } void CInspectorDialog::OnPaint() { CPaintDC dc(this); CRect rc; GetClientRect(&rc); dc.FillSolidRect(&rc, INSPECTOR_BG); if (m_Tabs.GetSafeHwnd()) { CRect tabRect; m_Tabs.GetWindowRect(&tabRect); ScreenToClient(&tabRect); CRect lineRect; lineRect.left = INSPECTOR_MARGIN; lineRect.right = rc.Width() - INSPECTOR_MARGIN; lineRect.top = tabRect.top - (INSPECTOR_MARGIN / 2); lineRect.bottom = lineRect.top + INSPECTOR_DIVIDER_HEIGHT; dc.FillSolidRect(&lineRect, INSPECTOR_BORDER); } } HBRUSH CInspectorDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CTabsDlg::OnCtlColor(pDC, pWnd, nCtlColor); if (!pDC) { return hbr; } pDC->SetTextColor(INSPECTOR_TEXT); switch (nCtlColor) { case CTLCOLOR_DLG: pDC->SetBkColor(INSPECTOR_BG); return (HBRUSH)bgBrush.GetSafeHandle(); case CTLCOLOR_STATIC: pDC->SetBkColor(INSPECTOR_BG); pDC->SetTextColor(INSPECTOR_MUTED_TEXT); return (HBRUSH)staticBrush.GetSafeHandle(); case CTLCOLOR_EDIT: case CTLCOLOR_LISTBOX: pDC->SetBkColor(INSPECTOR_PANEL_BG); pDC->SetTextColor(INSPECTOR_TEXT); return (HBRUSH)editBrush.GetSafeHandle(); case CTLCOLOR_BTN: pDC->SetBkColor(INSPECTOR_BG); pDC->SetTextColor(INSPECTOR_TEXT); return (HBRUSH)bgBrush.GetSafeHandle(); default: break; } return hbr; } void CInspectorDialog::OnDestroy() { ::SaveWindowPlacement(GetSafeHwnd(), "radiant_InspectorsWindow"); SetCvarInt("radiant_InspectorDockedDialogs", dockedTabs); CTabsDlg::OnDestroy(); } void CInspectorDialog::OnClose() { CTabsDlg::OnClose(); } BOOL CInspectorDialog::PreTranslateMessage(MSG* pMsg) { if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP) { g_pParentWnd->PostMessage(pMsg->message, pMsg->wParam, pMsg->lParam); } return CTabsDlg::PreTranslateMessage(pMsg); } void CInspectorDialog::SetDockedTabs(bool docked, int ID) { if (docked) { dockedTabs |= ID; } else { dockedTabs &= ~ID; } } void CInspectorDialog::AssignModel() { entityDlg.AssignModel(); }