mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-17 11:00:38 +02:00
Added new editor layout similar to idTech 5.
Cleaned up the entity inspector. Fixed numerous radiant bugs.
This commit is contained in:
+932
-2
@@ -32,11 +32,16 @@ If you have questions concerning this license or the applicable additional terms
|
||||
#include "qe3.h"
|
||||
#include "Radiant.h"
|
||||
#include "XYWnd.h"
|
||||
#include "ZWnd.h"
|
||||
#include "DialogInfo.h"
|
||||
#include "splines.h"
|
||||
#include "../../renderer/tr_local.h"
|
||||
#include "../../renderer/model_local.h" // for idRenderModelLiquid
|
||||
|
||||
#ifndef WM_IDLEUPDATECMDUI
|
||||
#define WM_IDLEUPDATECMDUI 0x0363
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
@@ -110,6 +115,926 @@ CMemFile g_PatchClipboard(4096);
|
||||
extern int pressx;
|
||||
extern int pressy;
|
||||
|
||||
//=============================================================================
|
||||
// CXYMenuBar
|
||||
//=============================================================================
|
||||
IMPLEMENT_DYNAMIC(CXYMenuBar, CWnd)
|
||||
|
||||
BEGIN_MESSAGE_MAP(CXYMenuBar, CWnd)
|
||||
ON_WM_PAINT()
|
||||
ON_WM_LBUTTONDOWN()
|
||||
ON_WM_MOUSEMOVE()
|
||||
ON_WM_ERASEBKGND()
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CXYMenuBar::CXYMenuBar() {
|
||||
m_nItemRects = 0;
|
||||
m_nHotItem = -1;
|
||||
}
|
||||
|
||||
CXYMenuBar::~CXYMenuBar() {
|
||||
if (m_menu.GetSafeHmenu()) {
|
||||
m_menu.DestroyMenu();
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CXYMenuBar::Create(CWnd *pParent, UINT nID) {
|
||||
CString className = AfxRegisterWndClass(
|
||||
CS_HREDRAW | CS_VREDRAW,
|
||||
::LoadCursor(NULL, IDC_ARROW),
|
||||
(HBRUSH)(COLOR_MENU + 1),
|
||||
NULL
|
||||
);
|
||||
return CWnd::CreateEx(
|
||||
0,
|
||||
className,
|
||||
"RadiantEmbeddedMenuBar",
|
||||
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
|
||||
CRect(0, 0, 0, 0),
|
||||
pParent,
|
||||
nID
|
||||
);
|
||||
}
|
||||
|
||||
BOOL CXYMenuBar::AttachMenu(HMENU hMenu) {
|
||||
if (!hMenu) {
|
||||
return FALSE;
|
||||
}
|
||||
if (m_menu.GetSafeHmenu()) {
|
||||
m_menu.DestroyMenu();
|
||||
}
|
||||
m_menu.Attach(hMenu);
|
||||
Invalidate(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CXYMenuBar::LoadMenu(UINT nID) {
|
||||
if (m_menu.GetSafeHmenu()) {
|
||||
m_menu.DestroyMenu();
|
||||
}
|
||||
BOOL result = m_menu.LoadMenu(nID);
|
||||
Invalidate(FALSE);
|
||||
return result;
|
||||
}
|
||||
|
||||
CMenu *CXYMenuBar::GetMenu() {
|
||||
return m_menu.GetSafeHmenu() ? &m_menu : NULL;
|
||||
}
|
||||
|
||||
HMENU CXYMenuBar::GetMenuHandle() const {
|
||||
return m_menu.GetSafeHmenu();
|
||||
}
|
||||
|
||||
int CXYMenuBar::PreferredHeight() const {
|
||||
int h = ::GetSystemMetrics(SM_CYMENU) + 4;
|
||||
return (h < 22) ? 22 : h;
|
||||
}
|
||||
|
||||
void CXYMenuBar::RebuildItemRects(CDC &dc) {
|
||||
m_nItemRects = 0;
|
||||
|
||||
if (!m_menu.GetSafeHmenu()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int x = 4;
|
||||
const int y = 1;
|
||||
const int h = PreferredHeight() - 2;
|
||||
const int count = m_menu.GetMenuItemCount();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
CString text;
|
||||
m_menu.GetMenuString(i, text, MF_BYPOSITION);
|
||||
if (m_nItemRects >= 64) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (text.IsEmpty()) {
|
||||
m_itemRects[m_nItemRects++] = CRect(x, y, x + 8, y + h);
|
||||
x += 8;
|
||||
continue;
|
||||
}
|
||||
|
||||
CSize size = dc.GetTextExtent(text);
|
||||
CRect rect(x, y, x + size.cx + 20, y + h);
|
||||
m_itemRects[m_nItemRects++] = rect;
|
||||
x = rect.right + 1;
|
||||
}
|
||||
}
|
||||
|
||||
int CXYMenuBar::HitTest(const CPoint &point) const {
|
||||
for (int i = 0; i < m_nItemRects; i++) {
|
||||
if (m_itemRects[i].PtInRect(point)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CXYMenuBar::TrackTopLevelMenu(int nIndex) {
|
||||
if (!m_menu.GetSafeHmenu() || nIndex < 0 || nIndex >= m_menu.GetMenuItemCount()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CMenu *subMenu = m_menu.GetSubMenu(nIndex);
|
||||
if (!subMenu || !subMenu->GetSafeHmenu()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CRect rect;
|
||||
if (nIndex < m_nItemRects) {
|
||||
rect = m_itemRects[nIndex];
|
||||
} else {
|
||||
GetClientRect(rect);
|
||||
}
|
||||
|
||||
CPoint pt(rect.left, rect.bottom);
|
||||
ClientToScreen(&pt);
|
||||
|
||||
m_nHotItem = nIndex;
|
||||
Invalidate(FALSE);
|
||||
UpdateWindow();
|
||||
|
||||
CWnd *commandTarget = GetCommandTarget();
|
||||
CWnd *popupOwner = (commandTarget && commandTarget->GetSafeHwnd()) ? commandTarget : static_cast<CWnd *>(this);
|
||||
|
||||
if (popupOwner && popupOwner->GetSafeHwnd()) {
|
||||
CWnd *topLevelOwner = popupOwner->GetTopLevelParent();
|
||||
if (topLevelOwner && topLevelOwner->GetSafeHwnd()) {
|
||||
topLevelOwner->SetForegroundWindow();
|
||||
} else {
|
||||
popupOwner->SetForegroundWindow();
|
||||
}
|
||||
}
|
||||
|
||||
// The popup owner must be the frame, not this embedded menu-bar window.
|
||||
// That keeps WM_INITMENUPOPUP, WM_MENUSELECT, command routing, MRU updates,
|
||||
// and ON_UPDATE_COMMAND_UI handling in CMainFrame where the old menu used them.
|
||||
UINT command = subMenu->TrackPopupMenu(
|
||||
TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD,
|
||||
pt.x,
|
||||
pt.y,
|
||||
popupOwner
|
||||
);
|
||||
|
||||
if (command != 0 && commandTarget && commandTarget->GetSafeHwnd()) {
|
||||
commandTarget->SendMessage(WM_COMMAND, MAKEWPARAM(command, 0), 0);
|
||||
}
|
||||
|
||||
m_nHotItem = -1;
|
||||
Invalidate(FALSE);
|
||||
if (popupOwner && popupOwner->GetSafeHwnd()) {
|
||||
popupOwner->PostMessage(WM_NULL, 0, 0);
|
||||
} else {
|
||||
PostMessage(WM_NULL, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
CWnd *CXYMenuBar::GetCommandTarget() const {
|
||||
CWnd *commandTarget = AfxGetMainWnd();
|
||||
if (commandTarget && commandTarget->GetSafeHwnd() && commandTarget != this) {
|
||||
return commandTarget;
|
||||
}
|
||||
|
||||
for (CWnd *parent = GetParent(); parent && parent->GetSafeHwnd(); parent = parent->GetParent()) {
|
||||
if (parent != this && parent->IsKindOf(RUNTIME_CLASS(CFrameWnd))) {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int XYMenuBarUpper(int ch) {
|
||||
if (ch >= 'a' && ch <= 'z') {
|
||||
return ch - 'a' + 'A';
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
BOOL CXYMenuBar::TrackMnemonic(UINT nChar) {
|
||||
if (!m_menu.GetSafeHmenu()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (nChar == VK_F10) {
|
||||
TrackTopLevelMenu(0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (nChar > 255) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const int wanted = XYMenuBarUpper(static_cast<int>(nChar));
|
||||
const int count = m_menu.GetMenuItemCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
CString text;
|
||||
m_menu.GetMenuString(i, text, MF_BYPOSITION);
|
||||
const int len = text.GetLength();
|
||||
for (int j = 0; j < len; j++) {
|
||||
if (text[j] != '&') {
|
||||
continue;
|
||||
}
|
||||
if (j + 1 >= len) {
|
||||
break;
|
||||
}
|
||||
if (text[j + 1] == '&') {
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
if (XYMenuBarUpper(static_cast<unsigned char>(text[j + 1])) == wanted) {
|
||||
TrackTopLevelMenu(i);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CXYMenuBar::OnPaint() {
|
||||
CPaintDC dc(this);
|
||||
CRect client;
|
||||
GetClientRect(client);
|
||||
|
||||
CBrush backBrush(::GetSysColor(COLOR_MENU));
|
||||
dc.FillRect(client, &backBrush);
|
||||
|
||||
RebuildItemRects(dc);
|
||||
|
||||
if (m_menu.GetSafeHmenu()) {
|
||||
const int count = m_menu.GetMenuItemCount();
|
||||
for (int i = 0; i < count && i < m_nItemRects; i++) {
|
||||
CString text;
|
||||
m_menu.GetMenuString(i, text, MF_BYPOSITION);
|
||||
CRect itemRect = m_itemRects[i];
|
||||
|
||||
if (i == m_nHotItem) {
|
||||
dc.Draw3dRect(itemRect, ::GetSysColor(COLOR_3DHILIGHT), ::GetSysColor(COLOR_3DSHADOW));
|
||||
itemRect.DeflateRect(1, 1);
|
||||
}
|
||||
|
||||
dc.SetBkMode(TRANSPARENT);
|
||||
dc.SetTextColor(::GetSysColor(COLOR_MENUTEXT));
|
||||
dc.DrawText(text, itemRect, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
|
||||
}
|
||||
}
|
||||
|
||||
CPen shadowPen(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));
|
||||
CPen *oldPen = dc.SelectObject(&shadowPen);
|
||||
dc.MoveTo(client.left, client.bottom - 1);
|
||||
dc.LineTo(client.right, client.bottom - 1);
|
||||
dc.SelectObject(oldPen);
|
||||
}
|
||||
|
||||
void CXYMenuBar::OnLButtonDown(UINT nFlags, CPoint point) {
|
||||
CClientDC dc(this);
|
||||
RebuildItemRects(dc);
|
||||
TrackTopLevelMenu(HitTest(point));
|
||||
}
|
||||
|
||||
void CXYMenuBar::OnMouseMove(UINT nFlags, CPoint point) {
|
||||
CClientDC dc(this);
|
||||
RebuildItemRects(dc);
|
||||
int hotItem = HitTest(point);
|
||||
if (hotItem != m_nHotItem) {
|
||||
m_nHotItem = hotItem;
|
||||
Invalidate(FALSE);
|
||||
}
|
||||
CWnd::OnMouseMove(nFlags, point);
|
||||
}
|
||||
|
||||
BOOL CXYMenuBar::OnEraseBkgnd(CDC *pDC) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CXYMenuBar::OnCommand(WPARAM wParam, LPARAM lParam) {
|
||||
CWnd *commandTarget = GetCommandTarget();
|
||||
if (commandTarget && commandTarget->GetSafeHwnd() && commandTarget != this) {
|
||||
return static_cast<BOOL>(commandTarget->SendMessage(WM_COMMAND, wParam, lParam));
|
||||
}
|
||||
return CWnd::OnCommand(wParam, lParam);
|
||||
}
|
||||
|
||||
BOOL CXYMenuBar::OnCmdMsg(UINT nID, int nCode, void *pExtra, AFX_CMDHANDLERINFO *pHandlerInfo) {
|
||||
if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CWnd *commandTarget = GetCommandTarget();
|
||||
if (commandTarget && commandTarget->GetSafeHwnd() && commandTarget != this) {
|
||||
return commandTarget->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// CXYMDIContainerWnd
|
||||
//=============================================================================
|
||||
IMPLEMENT_DYNAMIC(CXYMDIContainerWnd, CWnd)
|
||||
|
||||
BEGIN_MESSAGE_MAP(CXYMDIContainerWnd, CWnd)
|
||||
ON_WM_SIZE()
|
||||
ON_WM_PAINT()
|
||||
ON_WM_LBUTTONDOWN()
|
||||
ON_WM_LBUTTONUP()
|
||||
ON_WM_MOUSEMOVE()
|
||||
ON_WM_SETCURSOR()
|
||||
ON_WM_ERASEBKGND()
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CXYMDIContainerWnd::CXYMDIContainerWnd() {
|
||||
m_pXYWnd = NULL;
|
||||
m_pZWnd = NULL;
|
||||
m_nZDockPercent = 5;
|
||||
m_nZWidth = 0;
|
||||
m_nSplitterWidth = 5;
|
||||
m_bZStartupSized = false;
|
||||
m_bInLayout = false;
|
||||
m_bTrackingSplitter = false;
|
||||
m_nDragStartX = 0;
|
||||
m_nDragStartZWidth = 0;
|
||||
m_rcSplitter.SetRectEmpty();
|
||||
}
|
||||
|
||||
CXYMDIContainerWnd::~CXYMDIContainerWnd() {
|
||||
}
|
||||
|
||||
BOOL CXYMDIContainerWnd::Create(CWnd *pParent, UINT nID) {
|
||||
CLIENTCREATESTRUCT clientCreate;
|
||||
memset(&clientCreate, 0, sizeof(clientCreate));
|
||||
clientCreate.hWindowMenu = NULL;
|
||||
clientCreate.idFirstChild = 0x7B00;
|
||||
|
||||
return CWnd::CreateEx(
|
||||
0,
|
||||
"MDICLIENT",
|
||||
"RadiantXYMDIContainer",
|
||||
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
|
||||
CRect(0, 0, 0, 0),
|
||||
pParent,
|
||||
nID,
|
||||
&clientCreate
|
||||
);
|
||||
}
|
||||
|
||||
void CXYMDIContainerWnd::AttachChild(CWnd *pWnd) {
|
||||
if (!pWnd || !pWnd->GetSafeHwnd() || !GetSafeHwnd()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (::GetParent(pWnd->GetSafeHwnd()) != GetSafeHwnd()) {
|
||||
pWnd->SetParent(this);
|
||||
}
|
||||
|
||||
LONG style = ::GetWindowLong(pWnd->GetSafeHwnd(), GWL_STYLE);
|
||||
style &= ~(WS_POPUP | WS_CAPTION | WS_THICKFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
|
||||
style |= WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||
::SetWindowLong(pWnd->GetSafeHwnd(), GWL_STYLE, style);
|
||||
::SetWindowPos(
|
||||
pWnd->GetSafeHwnd(),
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED
|
||||
);
|
||||
}
|
||||
|
||||
void CXYMDIContainerWnd::SetChildWindows(CXYWnd *pXYWnd, CZWnd *pZWnd) {
|
||||
m_pXYWnd = pXYWnd;
|
||||
m_pZWnd = pZWnd;
|
||||
AttachChild(m_pZWnd);
|
||||
AttachChild(m_pXYWnd);
|
||||
LayoutChildren();
|
||||
}
|
||||
|
||||
void CXYMDIContainerWnd::SetEmbeddedWindows(CWnd *pZWnd, CWnd *pXYWnd) {
|
||||
m_pZWnd = pZWnd;
|
||||
m_pXYWnd = pXYWnd;
|
||||
AttachChild(m_pZWnd);
|
||||
AttachChild(m_pXYWnd);
|
||||
LayoutChildren();
|
||||
}
|
||||
|
||||
bool CXYMDIContainerWnd::IsZVisible() const {
|
||||
return m_pZWnd && m_pZWnd->GetSafeHwnd() && m_pZWnd->IsWindowVisible();
|
||||
}
|
||||
|
||||
int CXYMDIContainerWnd::ClampZWidth(int zWidth, const CRect &client) const {
|
||||
const int width = client.Width();
|
||||
if (width <= m_nSplitterWidth + 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const int minZ = 1;
|
||||
const int minXY = 64;
|
||||
const int available = width - m_nSplitterWidth;
|
||||
int maxZ = available - minXY;
|
||||
if (maxZ < minZ) {
|
||||
maxZ = available - 1;
|
||||
}
|
||||
if (maxZ < minZ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (zWidth < minZ) {
|
||||
zWidth = minZ;
|
||||
}
|
||||
if (zWidth > maxZ) {
|
||||
zWidth = maxZ;
|
||||
}
|
||||
return zWidth;
|
||||
}
|
||||
|
||||
int CXYMDIContainerWnd::ComputeInitialZWidth(const CRect &client) const {
|
||||
const int width = client.Width();
|
||||
if (width <= 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int zWidth = (width * m_nZDockPercent) / 100;
|
||||
if (zWidth < 1) {
|
||||
zWidth = 1;
|
||||
}
|
||||
return ClampZWidth(zWidth, client);
|
||||
}
|
||||
|
||||
void CXYMDIContainerWnd::SetZDockPercent(int percent) {
|
||||
// Keep legacy MainFrm calls such as SetZDockPercent(20) from changing the
|
||||
// required startup size. The embedded Z pane starts at 5%, then the user can
|
||||
// drag the splitter to any practical width.
|
||||
m_nZDockPercent = 5;
|
||||
|
||||
if (!m_bZStartupSized) {
|
||||
LayoutChildren();
|
||||
}
|
||||
}
|
||||
|
||||
int CXYMDIContainerWnd::GetZDockPercent() const {
|
||||
return m_nZDockPercent;
|
||||
}
|
||||
|
||||
int CXYMDIContainerWnd::GetZWidth() const {
|
||||
return m_nZWidth;
|
||||
}
|
||||
|
||||
int CXYMDIContainerWnd::GetFixedZWidth() const {
|
||||
return GetZWidth();
|
||||
}
|
||||
|
||||
bool CXYMDIContainerWnd::HitTestSplitter(const CPoint &point) const {
|
||||
return !m_rcSplitter.IsRectEmpty() && m_rcSplitter.PtInRect(point);
|
||||
}
|
||||
|
||||
void CXYMDIContainerWnd::DrawSplitter(CDC *pDC) {
|
||||
if (!pDC || m_rcSplitter.IsRectEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CRect rc = m_rcSplitter;
|
||||
CBrush brush(::GetSysColor(COLOR_BTNFACE));
|
||||
pDC->FillRect(rc, &brush);
|
||||
pDC->Draw3dRect(rc, ::GetSysColor(COLOR_3DHILIGHT), ::GetSysColor(COLOR_3DSHADOW));
|
||||
|
||||
int x = rc.left + rc.Width() / 2;
|
||||
CPen pen(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));
|
||||
CPen *oldPen = pDC->SelectObject(&pen);
|
||||
pDC->MoveTo(x, rc.top + 3);
|
||||
pDC->LineTo(x, rc.bottom - 3);
|
||||
pDC->SelectObject(oldPen);
|
||||
}
|
||||
|
||||
void CXYMDIContainerWnd::LayoutChildren() {
|
||||
if (!GetSafeHwnd() || m_bInLayout) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_bInLayout = true;
|
||||
|
||||
CRect client;
|
||||
GetClientRect(client);
|
||||
|
||||
if (client.Width() < 1 || client.Height() < 1) {
|
||||
m_rcSplitter.SetRectEmpty();
|
||||
m_bInLayout = false;
|
||||
return;
|
||||
}
|
||||
|
||||
bool zVisible = IsZVisible();
|
||||
int zWidth = 0;
|
||||
int splitterWidth = 0;
|
||||
|
||||
if (zVisible) {
|
||||
if (!m_bZStartupSized) {
|
||||
m_nZWidth = ComputeInitialZWidth(client);
|
||||
m_bZStartupSized = true;
|
||||
}
|
||||
|
||||
zWidth = ClampZWidth(m_nZWidth, client);
|
||||
m_nZWidth = zWidth;
|
||||
if (zWidth > 0 && client.Width() > zWidth + m_nSplitterWidth) {
|
||||
splitterWidth = m_nSplitterWidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pZWnd && m_pZWnd->GetSafeHwnd()) {
|
||||
if (zVisible && zWidth > 0) {
|
||||
m_pZWnd->MoveWindow(client.left, client.top, zWidth, client.Height(), TRUE);
|
||||
m_pZWnd->Invalidate(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (zVisible && zWidth > 0 && splitterWidth > 0) {
|
||||
m_rcSplitter.SetRect(client.left + zWidth, client.top, client.left + zWidth + splitterWidth, client.bottom);
|
||||
} else {
|
||||
m_rcSplitter.SetRectEmpty();
|
||||
}
|
||||
|
||||
if (m_pXYWnd && m_pXYWnd->GetSafeHwnd()) {
|
||||
int xyLeft = client.left + zWidth + splitterWidth;
|
||||
if (xyLeft > client.right - 1) {
|
||||
xyLeft = client.left;
|
||||
}
|
||||
CRect xyRect(xyLeft, client.top, client.right, client.bottom);
|
||||
m_pXYWnd->MoveWindow(xyRect, TRUE);
|
||||
m_pXYWnd->Invalidate(FALSE);
|
||||
}
|
||||
|
||||
Invalidate(FALSE);
|
||||
m_bInLayout = false;
|
||||
}
|
||||
|
||||
void CXYMDIContainerWnd::OnSize(UINT nType, int cx, int cy) {
|
||||
CWnd::OnSize(nType, cx, cy);
|
||||
LayoutChildren();
|
||||
}
|
||||
|
||||
void CXYMDIContainerWnd::OnPaint() {
|
||||
CPaintDC dc(this);
|
||||
DrawSplitter(&dc);
|
||||
}
|
||||
|
||||
void CXYMDIContainerWnd::OnLButtonDown(UINT nFlags, CPoint point) {
|
||||
if (HitTestSplitter(point)) {
|
||||
m_bTrackingSplitter = true;
|
||||
m_nDragStartX = point.x;
|
||||
m_nDragStartZWidth = m_nZWidth;
|
||||
SetCapture();
|
||||
::SetCursor(::LoadCursor(NULL, IDC_SIZEWE));
|
||||
return;
|
||||
}
|
||||
|
||||
CWnd::OnLButtonDown(nFlags, point);
|
||||
}
|
||||
|
||||
void CXYMDIContainerWnd::OnLButtonUp(UINT nFlags, CPoint point) {
|
||||
if (m_bTrackingSplitter) {
|
||||
m_bTrackingSplitter = false;
|
||||
if (GetCapture() == this) {
|
||||
ReleaseCapture();
|
||||
}
|
||||
LayoutChildren();
|
||||
return;
|
||||
}
|
||||
|
||||
CWnd::OnLButtonUp(nFlags, point);
|
||||
}
|
||||
|
||||
void CXYMDIContainerWnd::OnMouseMove(UINT nFlags, CPoint point) {
|
||||
if (m_bTrackingSplitter) {
|
||||
CRect client;
|
||||
GetClientRect(client);
|
||||
m_nZWidth = ClampZWidth(m_nDragStartZWidth + point.x - m_nDragStartX, client);
|
||||
LayoutChildren();
|
||||
::SetCursor(::LoadCursor(NULL, IDC_SIZEWE));
|
||||
return;
|
||||
}
|
||||
|
||||
if (HitTestSplitter(point)) {
|
||||
::SetCursor(::LoadCursor(NULL, IDC_SIZEWE));
|
||||
}
|
||||
|
||||
CWnd::OnMouseMove(nFlags, point);
|
||||
}
|
||||
|
||||
BOOL CXYMDIContainerWnd::OnSetCursor(CWnd *pWnd, UINT nHitTest, UINT message) {
|
||||
CPoint point;
|
||||
GetCursorPos(&point);
|
||||
ScreenToClient(&point);
|
||||
if (m_bTrackingSplitter || HitTestSplitter(point)) {
|
||||
::SetCursor(::LoadCursor(NULL, IDC_SIZEWE));
|
||||
return TRUE;
|
||||
}
|
||||
return CWnd::OnSetCursor(pWnd, nHitTest, message);
|
||||
}
|
||||
|
||||
BOOL CXYMDIContainerWnd::OnEraseBkgnd(CDC *pDC) {
|
||||
DrawSplitter(pDC);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CXYMDIContainerWnd::OnCommand(WPARAM wParam, LPARAM lParam) {
|
||||
CWnd *commandTarget = AfxGetMainWnd();
|
||||
if (commandTarget && commandTarget->GetSafeHwnd() && commandTarget != this) {
|
||||
return static_cast<BOOL>(commandTarget->SendMessage(WM_COMMAND, wParam, lParam));
|
||||
}
|
||||
return CWnd::OnCommand(wParam, lParam);
|
||||
}
|
||||
|
||||
BOOL CXYMDIContainerWnd::OnCmdMsg(UINT nID, int nCode, void *pExtra, AFX_CMDHANDLERINFO *pHandlerInfo) {
|
||||
if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) {
|
||||
return TRUE;
|
||||
}
|
||||
CWnd *commandTarget = AfxGetMainWnd();
|
||||
if (commandTarget && commandTarget->GetSafeHwnd() && commandTarget != this) {
|
||||
return commandTarget->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// CXYDockWnd
|
||||
//=============================================================================
|
||||
IMPLEMENT_DYNAMIC(CXYDockWnd, CWnd)
|
||||
|
||||
BEGIN_MESSAGE_MAP(CXYDockWnd, CWnd)
|
||||
ON_WM_CREATE()
|
||||
ON_WM_SIZE()
|
||||
ON_WM_ERASEBKGND()
|
||||
ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CXYDockWnd::CXYDockWnd() {
|
||||
m_pToolBar = NULL;
|
||||
m_bInLayout = false;
|
||||
}
|
||||
|
||||
CXYDockWnd::~CXYDockWnd() {
|
||||
}
|
||||
|
||||
BOOL CXYDockWnd::Create(CWnd *pParent, UINT nID) {
|
||||
CRect rect(0, 0, 0, 0);
|
||||
return Create(rect, pParent, nID);
|
||||
}
|
||||
|
||||
BOOL CXYDockWnd::Create(const RECT &rect, CWnd *pParent, UINT nID) {
|
||||
CString className = AfxRegisterWndClass(
|
||||
CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS,
|
||||
::LoadCursor(NULL, IDC_ARROW),
|
||||
(HBRUSH)(COLOR_BTNFACE + 1),
|
||||
NULL
|
||||
);
|
||||
return CWnd::CreateEx(
|
||||
0,
|
||||
className,
|
||||
"RadiantXYDockWnd",
|
||||
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
|
||||
rect,
|
||||
pParent,
|
||||
nID
|
||||
);
|
||||
}
|
||||
|
||||
int CXYDockWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) {
|
||||
if (CWnd::OnCreate(lpCreateStruct) == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (!m_wndMenuBar.Create(this, 0x7A01)) {
|
||||
return -1;
|
||||
}
|
||||
if (!m_wndMDIContainer.Create(this, 0x7A02)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CXYDockWnd::SetChildWindows(CXYWnd *pXYWnd, CZWnd *pZWnd) {
|
||||
m_wndMDIContainer.SetChildWindows(pXYWnd, pZWnd);
|
||||
LayoutChildren();
|
||||
}
|
||||
|
||||
void CXYDockWnd::SetEmbeddedWindows(CWnd *pZWnd, CWnd *pXYWnd) {
|
||||
m_wndMDIContainer.SetEmbeddedWindows(pZWnd, pXYWnd);
|
||||
LayoutChildren();
|
||||
}
|
||||
|
||||
void CXYDockWnd::SetToolBar(CToolBar *pToolBar) {
|
||||
m_pToolBar = pToolBar;
|
||||
if (m_pToolBar && m_pToolBar->GetSafeHwnd()) {
|
||||
CWnd *commandTarget = GetCommandTarget();
|
||||
if (!commandTarget || !commandTarget->GetSafeHwnd()) {
|
||||
commandTarget = this;
|
||||
}
|
||||
|
||||
m_pToolBar->SetParent(this);
|
||||
m_pToolBar->SetOwner(this);
|
||||
m_pToolBar->SetDlgCtrlID(AFX_IDW_TOOLBAR);
|
||||
m_pToolBar->ModifyStyle(WS_POPUP | WS_CAPTION | WS_THICKFRAME | WS_SYSMENU, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
|
||||
}
|
||||
LayoutChildren();
|
||||
}
|
||||
|
||||
void CXYDockWnd::SetEmbeddedToolBar(CToolBar *pToolBar) {
|
||||
SetToolBar(pToolBar);
|
||||
}
|
||||
|
||||
CWnd *CXYDockWnd::GetCommandTarget() const {
|
||||
CWnd *commandTarget = AfxGetMainWnd();
|
||||
if (commandTarget && commandTarget->GetSafeHwnd() && commandTarget != this) {
|
||||
return commandTarget;
|
||||
}
|
||||
|
||||
for (CWnd *parent = GetParent(); parent && parent->GetSafeHwnd(); parent = parent->GetParent()) {
|
||||
if (parent != this && parent->IsKindOf(RUNTIME_CLASS(CFrameWnd))) {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CXYDockWnd::UpdateToolBarCmdUI(BOOL bDisableIfNoHndler) {
|
||||
if (!m_pToolBar || !m_pToolBar->GetSafeHwnd() || !m_pToolBar->IsWindowVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CWnd *commandTarget = GetCommandTarget();
|
||||
if (!commandTarget || !commandTarget->GetSafeHwnd()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (commandTarget->IsKindOf(RUNTIME_CLASS(CFrameWnd))) {
|
||||
m_pToolBar->OnUpdateCmdUI(static_cast<CFrameWnd *>(commandTarget), bDisableIfNoHndler);
|
||||
}
|
||||
}
|
||||
|
||||
void CXYDockWnd::ShowEmbeddedToolBar(BOOL bShow) {
|
||||
if (m_pToolBar && m_pToolBar->GetSafeHwnd()) {
|
||||
m_pToolBar->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
|
||||
}
|
||||
LayoutChildren();
|
||||
}
|
||||
|
||||
BOOL CXYDockWnd::AttachMenu(HMENU hMenu) {
|
||||
BOOL result = m_wndMenuBar.AttachMenu(hMenu);
|
||||
LayoutChildren();
|
||||
return result;
|
||||
}
|
||||
|
||||
void CXYDockWnd::SetMenuHandle(HMENU hMenu) {
|
||||
AttachMenu(hMenu);
|
||||
}
|
||||
|
||||
BOOL CXYDockWnd::LoadMenu(UINT nID) {
|
||||
BOOL result = m_wndMenuBar.LoadMenu(nID);
|
||||
LayoutChildren();
|
||||
return result;
|
||||
}
|
||||
|
||||
CMenu *CXYDockWnd::GetEmbeddedMenu() {
|
||||
return m_wndMenuBar.GetMenu();
|
||||
}
|
||||
|
||||
HMENU CXYDockWnd::GetEmbeddedMenuHandle() const {
|
||||
return m_wndMenuBar.GetMenuHandle();
|
||||
}
|
||||
|
||||
HMENU CXYDockWnd::GetMenuHandle() const {
|
||||
return GetEmbeddedMenuHandle();
|
||||
}
|
||||
|
||||
void CXYDockWnd::SetZDockPercent(int percent) {
|
||||
m_wndMDIContainer.SetZDockPercent(percent);
|
||||
}
|
||||
|
||||
void CXYDockWnd::SetZPercent(int percent) {
|
||||
SetZDockPercent(percent);
|
||||
}
|
||||
|
||||
int CXYDockWnd::GetZDockPercent() const {
|
||||
return m_wndMDIContainer.GetZDockPercent();
|
||||
}
|
||||
|
||||
int CXYDockWnd::GetZPercent() const {
|
||||
return GetZDockPercent();
|
||||
}
|
||||
|
||||
void CXYDockWnd::LayoutChildren() {
|
||||
if (!GetSafeHwnd() || m_bInLayout) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_bInLayout = true;
|
||||
|
||||
CRect client;
|
||||
GetClientRect(client);
|
||||
|
||||
int y = client.top;
|
||||
const int width = client.Width();
|
||||
|
||||
if (m_wndMenuBar.GetSafeHwnd()) {
|
||||
if (m_wndMenuBar.GetMenuHandle()) {
|
||||
m_wndMenuBar.ShowWindow(SW_SHOW);
|
||||
const int menuHeight = m_wndMenuBar.PreferredHeight();
|
||||
m_wndMenuBar.MoveWindow(client.left, y, width, menuHeight, TRUE);
|
||||
y += menuHeight;
|
||||
} else {
|
||||
m_wndMenuBar.ShowWindow(SW_HIDE);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pToolBar && m_pToolBar->GetSafeHwnd()) {
|
||||
if (m_pToolBar->IsWindowVisible()) {
|
||||
CSize toolbarSize = m_pToolBar->CalcFixedLayout(FALSE, TRUE);
|
||||
int toolbarHeight = toolbarSize.cy;
|
||||
if (toolbarHeight < 24) {
|
||||
toolbarHeight = 24;
|
||||
}
|
||||
m_pToolBar->MoveWindow(client.left, y, width, toolbarHeight, TRUE);
|
||||
y += toolbarHeight;
|
||||
}
|
||||
}
|
||||
|
||||
CRect content(client.left, y, client.right, client.bottom);
|
||||
if (content.Width() < 1 || content.Height() < 1) {
|
||||
m_bInLayout = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_wndMDIContainer.GetSafeHwnd()) {
|
||||
m_wndMDIContainer.MoveWindow(content, TRUE);
|
||||
m_wndMDIContainer.LayoutChildren();
|
||||
}
|
||||
|
||||
m_bInLayout = false;
|
||||
}
|
||||
|
||||
void CXYDockWnd::RecalcLayout() {
|
||||
LayoutChildren();
|
||||
}
|
||||
|
||||
BOOL CXYDockWnd::TrackMenuMnemonic(UINT nChar) {
|
||||
if (m_wndMenuBar.GetSafeHwnd()) {
|
||||
return m_wndMenuBar.TrackMnemonic(nChar);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CXYDockWnd::OnSize(UINT nType, int cx, int cy) {
|
||||
CWnd::OnSize(nType, cx, cy);
|
||||
LayoutChildren();
|
||||
}
|
||||
|
||||
BOOL CXYDockWnd::OnEraseBkgnd(CDC *pDC) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LRESULT CXYDockWnd::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM lParam) {
|
||||
UpdateToolBarCmdUI(static_cast<BOOL>(wParam));
|
||||
return 0L;
|
||||
}
|
||||
|
||||
BOOL CXYDockWnd::OnCommand(WPARAM wParam, LPARAM lParam) {
|
||||
CWnd *commandTarget = GetCommandTarget();
|
||||
if (commandTarget && commandTarget->GetSafeHwnd() && commandTarget != this) {
|
||||
return static_cast<BOOL>(commandTarget->SendMessage(WM_COMMAND, wParam, lParam));
|
||||
}
|
||||
return CWnd::OnCommand(wParam, lParam);
|
||||
}
|
||||
|
||||
BOOL CXYDockWnd::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT *pResult) {
|
||||
CWnd *commandTarget = GetCommandTarget();
|
||||
if (commandTarget && commandTarget->GetSafeHwnd() && commandTarget != this) {
|
||||
LRESULT result = commandTarget->SendMessage(WM_NOTIFY, wParam, lParam);
|
||||
if (pResult) {
|
||||
*pResult = result;
|
||||
}
|
||||
if (result != 0) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return CWnd::OnNotify(wParam, lParam, pResult);
|
||||
}
|
||||
|
||||
BOOL CXYDockWnd::OnCmdMsg(UINT nID, int nCode, void *pExtra, AFX_CMDHANDLERINFO *pHandlerInfo) {
|
||||
if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CWnd *commandTarget = GetCommandTarget();
|
||||
if (commandTarget && commandTarget->GetSafeHwnd() && commandTarget != this) {
|
||||
return commandTarget->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=======================================================================================================================
|
||||
=======================================================================================================================
|
||||
@@ -594,6 +1519,7 @@ BOOL CXYWnd::PreCreateWindow(CREATESTRUCT &cs) {
|
||||
if (cs.style != QE3_CHILDSTYLE) {
|
||||
cs.style = QE3_SPLITTER_STYLE;
|
||||
}
|
||||
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
||||
|
||||
return CWnd::PreCreateWindow(cs);
|
||||
}
|
||||
@@ -2732,7 +3658,7 @@ bool CXYWnd::XY_MouseMoved(int x, int y, int buttons) {
|
||||
|
||||
/*
|
||||
=======================================================================================================================
|
||||
DRAWING £
|
||||
DRAWING £
|
||||
XY_DrawGrid
|
||||
=======================================================================================================================
|
||||
*/
|
||||
@@ -3304,7 +4230,7 @@ bool FilterBrush(brush_t *pb) {
|
||||
|
||||
/*
|
||||
=======================================================================================================================
|
||||
PATH LINES £
|
||||
PATH LINES £
|
||||
DrawPathLines Draws connections between entities. Needs to consider all entities, not just ones on screen, because
|
||||
the lines can be visible when neither end is. Called for both camera view and xy view.
|
||||
=======================================================================================================================
|
||||
@@ -3535,6 +4461,10 @@ extern void DrawBrushEntityName(brush_t *b);
|
||||
=======================================================================================================================
|
||||
*/
|
||||
void CXYWnd::XY_Draw() {
|
||||
if (m_nWidth <= 0 || m_nHeight <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
brush_t *brush;
|
||||
float w, h;
|
||||
entity_t *e;
|
||||
|
||||
Reference in New Issue
Block a user