summaryrefslogtreecommitdiff
path: root/hammer/toolpickface.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/toolpickface.cpp
downloadarchived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.tar.xz
archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.zip
Diffstat (limited to 'hammer/toolpickface.cpp')
-rw-r--r--hammer/toolpickface.cpp483
1 files changed, 483 insertions, 0 deletions
diff --git a/hammer/toolpickface.cpp b/hammer/toolpickface.cpp
new file mode 100644
index 0000000..2599e48
--- /dev/null
+++ b/hammer/toolpickface.cpp
@@ -0,0 +1,483 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Tool used for picking brush faces.
+//
+// Left click - single select face
+// +Ctrl - multiselect a single face
+// +Shift - all faces on the brush
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "stdafx.h"
+#include "MapFace.h"
+#include "resource.h"
+#include "ToolPickFace.h"
+#include "MapSolid.h"
+#include "MapView3D.h"
+#include "mapdoc.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include <tier0/memdbgon.h>
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor. Inits data members.
+//-----------------------------------------------------------------------------
+CToolPickFace::CToolPickFace(void)
+{
+ m_pNotifyTarget = NULL;
+ m_bAllowMultiSelect = false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor.
+//-----------------------------------------------------------------------------
+CToolPickFace::~CToolPickFace(void)
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Enables or disables multiselect for this tool.
+//-----------------------------------------------------------------------------
+void CToolPickFace::AllowMultiSelect(bool bAllow)
+{
+ m_bAllowMultiSelect = bAllow;
+
+ //
+ // Shouldn't ever happen, but you never know.
+ //
+ if ((!bAllow) && (m_Faces.Count() > 1))
+ {
+ CMapFace *pFace = m_Faces[0].pFace;
+ DeselectAll();
+ SelectFace(pFace);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Called when the tool is deactivated.
+// Input : eNewTool - The ID of the tool that is being activated.
+//-----------------------------------------------------------------------------
+void CToolPickFace::OnDeactivate()
+{
+ DeselectAll();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the left mouse button up message in the 3D view.
+// Input : pView - The view that the event occurred in.
+// nFlags - Flags per the Windows mouse message.
+// point - Point in client coordinates where the event occurred.
+// Output : Returns true if the message was handled by the tool, false if not.
+//-----------------------------------------------------------------------------
+bool CToolPickFace::OnLMouseUp3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the left mouse button up message in the 3D view.
+// Input : pView - The view that the event occurred in.
+// nFlags - Flags per the Windows mouse message.
+// point - Point in client coordinates where the event occurred.
+// Output : Returns true if the message was handled by the tool, false if not.
+//-----------------------------------------------------------------------------
+bool CToolPickFace::OnLMouseDown3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ bool bControl = ((nFlags & MK_CONTROL) != 0);
+ bool bShift = ((nFlags & MK_SHIFT) != 0);
+
+ if (!m_bAllowMultiSelect)
+ {
+ // Ignore shift click for single selection mode.
+ bShift = false;
+ }
+
+ unsigned long uFace;
+ CMapClass *pObject = pView->NearestObjectAt( vPoint, uFace);
+ if (pObject != NULL)
+ {
+ CMapSolid *pSolid = dynamic_cast <CMapSolid *>(pObject);
+ if (pSolid != NULL)
+ {
+ //
+ // We clicked on a solid.
+ //
+ if (!bShift)
+ {
+ //
+ // Get the face that we clicked on.
+ //
+ CMapFace *pFace = pSolid->GetFace(uFace);
+ Assert(pFace != NULL);
+
+ if (pFace != NULL)
+ {
+ if ((!m_bAllowMultiSelect) || (!bControl))
+ {
+ // Single select.
+ DeselectAll();
+ SelectFace(pFace);
+ }
+ else
+ {
+ // Multiselect.
+ CycleSelectFace(pFace);
+ }
+ }
+ }
+ else
+ {
+ //
+ // Holding down shift. Select or deselect all the faces on the solid.
+ // Only deselect if all the faces in the solid were selected.
+ //
+ bool bAllSelected = true;
+ int nFaceCount = pSolid->GetFaceCount();
+ for (int nFace = 0; nFace < nFaceCount; nFace++)
+ {
+ CMapFace *pFace = pSolid->GetFace(nFace);
+ int nIndex = FindFace(pFace);
+ if ((nIndex == -1) || (m_Faces[nIndex].eState != FaceState_Select))
+ {
+ bAllSelected = false;
+ break;
+ }
+ }
+
+ if (!bControl)
+ {
+ DeselectAll();
+ }
+
+ nFaceCount = pSolid->GetFaceCount();
+ for (int nFace = 0; nFace < nFaceCount; nFace++)
+ {
+ CMapFace *pFace = pSolid->GetFace(nFace);
+ if (bAllSelected)
+ {
+ DeselectFace(pFace);
+ }
+ else
+ {
+ SelectFace(pFace);
+ }
+ }
+ }
+
+ if (m_pNotifyTarget)
+ {
+ m_pNotifyTarget->OnNotifyPickFace(this);
+ }
+ }
+ }
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the left mouse button double click message in the 3D view.
+// Input : pView - The view that the event occurred in.
+// nFlags - Flags per the Windows mouse message.
+// point - Point in client coordinates where the event occurred.
+// Output : Returns true if the message was handled by the tool, false if not.
+//-----------------------------------------------------------------------------
+bool CToolPickFace::OnLMouseDblClk3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the right mouse button up message in the 3D view.
+// Input : pView - The view that the event occurred in.
+// nFlags - Flags per the Windows mouse message.
+// point - Point in client coordinates where the event occurred.
+// Output : Returns true if the message was handled by the tool, false if not.
+//-----------------------------------------------------------------------------
+bool CToolPickFace::OnRMouseUp3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the mouse button up message in the 3D view.
+// Input : pView - The view that the event occurred in.
+// nFlags - Flags per the Windows mouse message.
+// point - Point in client coordinates where the event occurred.
+// Output : Returns true if the message was handled by the tool, false if not.
+//-----------------------------------------------------------------------------
+bool CToolPickFace::OnRMouseDown3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the mouse move message in the 3D view.
+// Input : pView - The view that the event occurred in.
+// nFlags - Flags per the Windows mouse message.
+// point - Point in client coordinates where the event occurred.
+// Output : Returns true if the message was handled by the tool, false if not.
+//-----------------------------------------------------------------------------
+bool CToolPickFace::OnMouseMove3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
+{
+ SetEyedropperCursor();
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the cursor to the eyedropper cursor.
+//-----------------------------------------------------------------------------
+void CToolPickFace::SetEyedropperCursor(void)
+{
+ static HCURSOR hcurEyedropper = NULL;
+
+ if (!hcurEyedropper)
+ {
+ hcurEyedropper = LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_EYEDROPPER));
+ }
+
+ SetCursor(hcurEyedropper);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pFace -
+//-----------------------------------------------------------------------------
+void CToolPickFace::CycleSelectFace(CMapFace *pFace)
+{
+ int nIndex = FindFace(pFace);
+ if (nIndex != -1)
+ {
+ //
+ // The face is in our list, update its selection state.
+ //
+ if (m_Faces[nIndex].eState == FaceState_Partial)
+ {
+ DeselectFace(nIndex);
+ }
+ else if (m_Faces[nIndex].eState == FaceState_Select)
+ {
+ if (m_Faces[nIndex].eOriginalState == FaceState_Partial)
+ {
+ m_Faces[nIndex].eState = FaceState_Partial;
+ pFace->SetSelectionState(SELECT_MULTI_PARTIAL);
+ }
+ else
+ {
+ DeselectFace(nIndex);
+ }
+ }
+ else if (m_Faces[nIndex].eState == FaceState_None)
+ {
+ m_Faces[nIndex].eState = FaceState_Select;
+ pFace->SetSelectionState(SELECT_NORMAL);
+ }
+ }
+ else
+ {
+ //
+ // The face is not in our list, add it.
+ //
+ AddToList(pFace, FaceState_Select);
+ pFace->SetSelectionState(SELECT_NORMAL);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the fully selected and partially selected faces for the picker.
+// Input : FaceListFull -
+// FaceListPartial -
+//-----------------------------------------------------------------------------
+void CToolPickFace::SetSelectedFaces(CMapFaceList &FaceListFull, CMapFaceList &FaceListPartial)
+{
+ m_Faces.RemoveAll();
+
+ for (int i = 0; i < FaceListFull.Count(); i++)
+ {
+ CMapFace *pFace = FaceListFull.Element(i);
+
+ AddToList(pFace, FaceState_Select);
+ pFace->SetSelectionState(SELECT_NORMAL);
+ }
+
+ for (int i = 0; i < FaceListPartial.Count(); i++)
+ {
+ CMapFace *pFace = FaceListPartial.Element(i);
+
+ AddToList(pFace, FaceState_Partial);
+ pFace->SetSelectionState(SELECT_MULTI_PARTIAL);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pFace -
+//-----------------------------------------------------------------------------
+int CToolPickFace::FindFace(CMapFace *pFace)
+{
+ for (int i = 0; i < m_Faces.Count(); i++)
+ {
+ if (m_Faces[i].pFace == pFace)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Clears the selection set.
+//-----------------------------------------------------------------------------
+void CToolPickFace::DeselectAll(void)
+{
+ for (int i = 0; i < m_Faces.Count(); i++)
+ {
+ m_Faces[i].pFace->SetSelectionState(SELECT_NONE);
+ }
+
+ m_Faces.RemoveAll();
+
+ m_pDocument->UpdateAllViews( MAPVIEW_UPDATE_ONLY_3D );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Selects the face unconditionally.
+// Input : pFace - face to select.
+//-----------------------------------------------------------------------------
+void CToolPickFace::SelectFace(CMapFace *pFace)
+{
+ int nIndex = FindFace(pFace);
+ if (nIndex != -1)
+ {
+ //
+ // The face is in our list, update its selection state.
+ //
+ m_Faces[nIndex].eState = FaceState_Select;
+ pFace->SetSelectionState(SELECT_NORMAL);
+ }
+ else
+ {
+ //
+ // The face is not in our list, add it.
+ //
+ AddToList(pFace, FaceState_Select);
+ pFace->SetSelectionState(SELECT_NORMAL);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Deselects the given face.
+//-----------------------------------------------------------------------------
+void CToolPickFace::DeselectFace(CMapFace *pFace)
+{
+ int nIndex = FindFace(pFace);
+ if (nIndex != -1)
+ {
+ DeselectFace(nIndex);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Removes the face at the given index from the selection set.
+// Input : nIndex - Index of the face in the selection list.
+//-----------------------------------------------------------------------------
+void CToolPickFace::DeselectFace(int nIndex)
+{
+ Assert(m_Faces.IsValidIndex(nIndex));
+
+ if (m_Faces.IsValidIndex(nIndex))
+ {
+ if (m_Faces[nIndex].eOriginalState != FaceState_Partial)
+ {
+ m_Faces[nIndex].pFace->SetSelectionState(SELECT_NONE);
+
+ //
+ // Remove the face from our list.
+ //
+ RemoveFromList(nIndex);
+ }
+ else
+ {
+ //
+ // Just set the state to deselected so we can cycle back to partial selection.
+ //
+ m_Faces[nIndex].pFace->SetSelectionState(SELECT_NONE);
+ m_Faces[nIndex].eState = FaceState_None;
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pFace -
+// eState -
+//-----------------------------------------------------------------------------
+void CToolPickFace::AddToList(CMapFace *pFace, FaceState_t eState)
+{
+ int nIndex = m_Faces.AddToTail();
+ m_Faces[nIndex].pFace = pFace;
+ m_Faces[nIndex].eState = eState;
+ m_Faces[nIndex].eOriginalState = eState;
+
+ m_pDocument->UpdateAllViews( MAPVIEW_UPDATE_ONLY_3D );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : nIndex -
+//-----------------------------------------------------------------------------
+void CToolPickFace::RemoveFromList(int nIndex)
+{
+ Assert(m_Faces.IsValidIndex(nIndex));
+
+ if (m_Faces.IsValidIndex(nIndex))
+ {
+ m_Faces.FastRemove(nIndex);
+
+ m_pDocument->UpdateAllViews( MAPVIEW_UPDATE_ONLY_3D );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns lists of fully selected and partially selected faces.
+//-----------------------------------------------------------------------------
+void CToolPickFace::GetSelectedFaces(CMapFaceList &FaceListFull, CMapFaceList &FaceListPartial)
+{
+ FaceListFull.RemoveAll();
+ FaceListPartial.RemoveAll();
+
+ for (int i = 0; i < m_Faces.Count(); i++)
+ {
+ if (m_Faces[i].eState == FaceState_Select)
+ {
+ FaceListFull.AddToTail(m_Faces[i].pFace);
+ }
+ else if (m_Faces[i].eState == FaceState_Partial)
+ {
+ FaceListPartial.AddToTail(m_Faces[i].pFace);
+ }
+ }
+}
+