summaryrefslogtreecommitdiff
path: root/hammer/ToolBlock.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /hammer/ToolBlock.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'hammer/ToolBlock.cpp')
-rw-r--r--hammer/ToolBlock.cpp517
1 files changed, 517 insertions, 0 deletions
diff --git a/hammer/ToolBlock.cpp b/hammer/ToolBlock.cpp
new file mode 100644
index 0000000..c5ed3fd
--- /dev/null
+++ b/hammer/ToolBlock.cpp
@@ -0,0 +1,517 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "stdafx.h"
+#include "History.h"
+#include "MainFrm.h"
+#include "MapDefs.h"
+#include "MapDoc.h"
+#include "MapView2D.h"
+#include "MapView3D.h"
+#include "Options.h"
+#include "StatusBarIDs.h"
+#include "ToolBlock.h"
+#include "ToolManager.h"
+#include "vgui/Cursor.h"
+#include "Selection.h"
+
+
+class CToolBlockMessageWnd : public CWnd
+{
+ public:
+
+ bool Create(void);
+ void PreMenu2D(CToolBlock *pTool, CMapView2D *pView);
+
+ protected:
+
+ //{{AFX_MSG_MAP(CToolBlockMessageWnd)
+ afx_msg void OnCreateObject();
+ //}}AFX_MSG
+
+ DECLARE_MESSAGE_MAP()
+
+ private:
+
+ CToolBlock *m_pToolBlock;
+ CMapView2D *m_pView2D;
+};
+
+
+static CToolBlockMessageWnd s_wndToolMessage;
+static const char *g_pszClassName = "ValveEditor_BlockToolWnd";
+
+
+BEGIN_MESSAGE_MAP(CToolBlockMessageWnd, CWnd)
+ //{{AFX_MSG_MAP(CToolMessageWnd)
+ ON_COMMAND(ID_CREATEOBJECT, OnCreateObject)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Creates the hidden window that receives context menu commands for the
+// block tool.
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CToolBlockMessageWnd::Create(void)
+{
+ WNDCLASS wndcls;
+ memset(&wndcls, 0, sizeof(WNDCLASS));
+ wndcls.lpfnWndProc = AfxWndProc;
+ wndcls.hInstance = AfxGetInstanceHandle();
+ wndcls.lpszClassName = g_pszClassName;
+
+ if (!AfxRegisterClass(&wndcls))
+ {
+ return(false);
+ }
+
+ return(CWnd::CreateEx(0, g_pszClassName, g_pszClassName, 0, CRect(0, 0, 10, 10), NULL, 0) == TRUE);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Attaches the block tool to this window before activating the context
+// menu.
+//-----------------------------------------------------------------------------
+void CToolBlockMessageWnd::PreMenu2D(CToolBlock *pToolBlock, CMapView2D *pView)
+{
+ Assert(pToolBlock != NULL);
+ m_pToolBlock = pToolBlock;
+ m_pView2D = pView;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CToolBlockMessageWnd::OnCreateObject()
+{
+ m_pToolBlock->CreateMapObject(m_pView2D);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor.
+//-----------------------------------------------------------------------------
+CToolBlock::CToolBlock(void)
+{
+ // We always show our dimensions when we render.
+ SetDrawFlags(GetDrawFlags() | Box3D::boundstext);
+ SetDrawColors(Options.colors.clrToolHandle, Options.colors.clrToolBlock);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor.
+//-----------------------------------------------------------------------------
+CToolBlock::~CToolBlock(void)
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles key down events in the 2D view.
+// Input : Per CWnd::OnKeyDown.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool CToolBlock::OnKeyDown2D(CMapView2D *pView, UINT nChar, UINT nRepCnt, UINT nFlags)
+{
+ switch (nChar)
+ {
+ case VK_RETURN:
+ {
+ if ( !IsEmpty() )
+ {
+ CreateMapObject(pView);
+ }
+
+ return true;
+ }
+
+ case VK_ESCAPE:
+ {
+ OnEscape();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles context menu events in the 2D view.
+// Input : Per CWnd::OnContextMenu.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool CToolBlock::OnContextMenu2D(CMapView2D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ static CMenu menu, menuCreate;
+ static bool bInit = false;
+
+ if (!bInit)
+ {
+ bInit = true;
+
+ // Create the menu.
+ menu.LoadMenu(IDR_POPUPS);
+ menuCreate.Attach(::GetSubMenu(menu.m_hMenu, 1));
+
+ // Create the window that handles menu messages.
+ s_wndToolMessage.Create();
+ }
+
+ if ( !pView->PointInClientRect(vPoint) )
+ {
+ return false;
+ }
+
+ if ( !IsEmpty() )
+ {
+ if ( HitTest(pView, vPoint, false) )
+ {
+ CPoint ptScreen( vPoint.x,vPoint.y);
+ pView->ClientToScreen(&ptScreen);
+
+ s_wndToolMessage.PreMenu2D(this, pView);
+ menuCreate.TrackPopupMenu(TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_LEFTALIGN, ptScreen.x, ptScreen.y, &s_wndToolMessage);
+ }
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles left mouse button down events in the 2D view.
+// Input : Per CWnd::OnLButtonDown.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool CToolBlock::OnLMouseDown3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ Tool3D::OnLMouseDown3D(pView, nFlags, vPoint);
+
+ //
+ // If we have a box, see if they clicked on any part of it.
+ //
+ if ( !IsEmpty() )
+ {
+ if ( HitTest( pView, vPoint, true ) )
+ {
+ // just update current block
+ StartTranslation( pView, vPoint, m_LastHitTestHandle );
+ return true;
+ }
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles left mouse button down events in the 2D view.
+// Input : Per CWnd::OnLButtonDown.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool CToolBlock::OnLMouseDown2D(CMapView2D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ Tool3D::OnLMouseDown2D(pView, nFlags, vPoint);
+
+ // If we have a box, see if they clicked on any part of it.
+ if ( !IsEmpty() )
+ {
+ if ( HitTest( pView, vPoint, true ) )
+ {
+ // just update current block
+ StartTranslation( pView, vPoint, m_LastHitTestHandle );
+ return true;
+ }
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles left mouse button up events in the 2D view.
+// Input : Per CWnd::OnLButtonUp.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool CToolBlock::OnLMouseUp2D(CMapView2D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ Tool3D::OnLMouseUp2D(pView, nFlags, vPoint);
+
+ if (IsTranslating())
+ {
+ FinishTranslation(true);
+ }
+
+ m_pDocument->UpdateStatusbar();
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles left mouse button up events in the 2D view.
+// Input : Per CWnd::OnLButtonUp.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool CToolBlock::OnLMouseUp3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ Tool3D::OnLMouseUp3D(pView, nFlags, vPoint);
+
+ if (IsTranslating())
+ {
+ FinishTranslation(true);
+ }
+
+ m_pDocument->UpdateStatusbar();
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles mouse move events in the 2D view.
+// Input : Per CWnd::OnMouseMove.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool CToolBlock::OnMouseMove2D(CMapView2D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ vgui::HCursor hCursor = vgui::dc_arrow;
+
+ // Snap it to the grid.
+ unsigned int uConstraints = GetConstraints( nFlags );
+
+ Tool3D::OnMouseMove2D(pView, nFlags, vPoint);
+
+ //
+ //
+ // Convert to world coords.
+ //
+ Vector vecWorld;
+ pView->ClientToWorld(vecWorld, vPoint);
+
+ //
+ // Update status bar position display.
+ //
+ char szBuf[128];
+
+ if ( uConstraints & constrainSnap )
+ m_pDocument->Snap(vecWorld,uConstraints);
+
+ sprintf(szBuf, " @%.0f, %.0f ", vecWorld[pView->axHorz], vecWorld[pView->axVert]);
+ SetStatusText(SBI_COORDS, szBuf);
+
+ if ( IsTranslating() )
+ {
+ Tool3D::UpdateTranslation( pView, vPoint, uConstraints);
+
+ hCursor = vgui::dc_none;
+ }
+ else if ( m_bMouseDragged[MOUSE_LEFT] )
+ {
+ // Starting a new box. Build a starting point for the drag.
+ pView->SetCursor( "Resource/block.cur" );
+
+ Vector vecStart;
+ pView->ClientToWorld(vecStart, m_vMouseStart[MOUSE_LEFT] );
+
+ // Snap it to the grid.
+ if ( uConstraints & constrainSnap )
+ m_pDocument->Snap( vecStart, uConstraints);
+
+ // Start the new box with the extents of the last selected thing.
+
+ m_pDocument->GetSelection()->GetLastValidBounds(bmins, bmaxs);
+
+ vecStart[pView->axThird] = bmins[pView->axThird];
+
+ StartNew(pView, vPoint, vecStart, pView->GetViewAxis() * (bmaxs-bmins) );
+ }
+ else if ( !IsEmpty() )
+ {
+ // If the cursor is on a handle, set it to a cross.
+ if ( HitTest(pView, vPoint, true) )
+ {
+ hCursor = UpdateCursor( pView, m_LastHitTestHandle, m_TranslateMode );
+ }
+ }
+
+
+ if ( hCursor != vgui::dc_none )
+ pView->SetCursor( hCursor );
+
+ return true;
+}
+
+bool CToolBlock::OnMouseMove3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ Tool3D::OnMouseMove3D(pView, nFlags, vPoint);
+
+ if ( IsTranslating() )
+ {
+ unsigned int uConstraints = GetConstraints( nFlags );
+
+ // If they are dragging with a valid handle, update the views.
+ Tool3D::UpdateTranslation( pView, vPoint, uConstraints );
+ }
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles key down events in the 3D view.
+// Input : Per CWnd::OnKeyDown.
+// Output : Returns true if the message was handled, false if not.
+//-----------------------------------------------------------------------------
+bool CToolBlock::OnKeyDown3D(CMapView3D *pView, UINT nChar, UINT nRepCnt, UINT nFlags)
+{
+ switch (nChar)
+ {
+ case VK_RETURN:
+ {
+ if ( !IsEmpty() )
+ {
+ CreateMapObject(pView);
+ }
+
+ return true;
+ }
+
+ case VK_ESCAPE:
+ {
+ OnEscape();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the escape key in the 2D or 3D views.
+//-----------------------------------------------------------------------------
+void CToolBlock::OnEscape(void)
+{
+ //
+ // If we have nothing blocked, go back to the pointer tool.
+ //
+ if ( IsEmpty() )
+ {
+ ToolManager()->SetTool(TOOL_POINTER);
+ }
+ //
+ // We're blocking out a region, so clear it.
+ //
+ else
+ {
+ SetEmpty();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Creates a solid in the given view.
+//-----------------------------------------------------------------------------
+void CToolBlock::CreateMapObject(CMapView *pView)
+{
+ CMapWorld *pWorld = m_pDocument->GetMapWorld();
+
+ if (!(bmaxs[0] - bmins[0]) || !(bmaxs[1] - bmins[1]) || !(bmaxs[2] - bmins[2]))
+ {
+ AfxMessageBox("The box is empty.");
+ SetEmpty();
+ return;
+ }
+
+ BoundBox NewBox = *this;
+ if (Options.view2d.bOrientPrimitives)
+ {
+ switch (pView->GetDrawType())
+ {
+ case VIEW2D_XY:
+ {
+ break;
+ }
+
+ case VIEW2D_YZ:
+ {
+ NewBox.Rotate90(AXIS_Y);
+ break;
+ }
+
+ case VIEW2D_XZ:
+ {
+ NewBox.Rotate90(AXIS_X);
+ break;
+ }
+ }
+ }
+
+ // Create the object within the given bounding box.
+ CMapClass *pObject = GetMainWnd()->m_ObjectBar.CreateInBox(&NewBox, pView);
+ if (pObject == NULL)
+ {
+ SetEmpty();
+ return;
+ }
+
+ m_pDocument->ExpandObjectKeywords(pObject, pWorld);
+
+ GetHistory()->MarkUndoPosition(m_pDocument->GetSelection()->GetList(), "New Object");
+
+ m_pDocument->AddObjectToWorld(pObject);
+
+ //
+ // Do we need to rotate this object based on the view we created it in?
+ //
+ if (Options.view2d.bOrientPrimitives)
+ {
+ Vector center;
+ pObject->GetBoundsCenter( center );
+
+ QAngle angles(0, 0, 0);
+ switch (pView->GetDrawType())
+ {
+ case VIEW2D_XY:
+ {
+ break;
+ }
+
+ case VIEW2D_YZ:
+ {
+ angles[1] = 90.f;
+ pObject->TransRotate(center, angles);
+ break;
+ }
+
+ case VIEW2D_XZ:
+ {
+ angles[0] = 90.f;
+ pObject->TransRotate(center, angles);
+ break;
+ }
+ }
+ }
+
+ GetHistory()->KeepNew(pObject);
+
+ // Select the new object.
+ m_pDocument->SelectObject(pObject, scClear|scSelect|scSaveChanges);
+
+ m_pDocument->SetModifiedFlag();
+
+ SetEmpty();
+ ResetBounds();
+}
+
+
+
+
+