/* =========================================================================== IceTech GPL Source Code Copyright (C) 2026 Justin Marshall 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 the Free Software Foundation, either version 3 of the License, or (at your option) any later version. IceTech Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with IceTech Source Code. If not, see . =========================================================================== */ #pragma once #include "afxwin.h" #include "afxcmn.h" #include "afxtempl.h" struct entity_s; typedef struct entity_s entity_t; class idVec3; class COutlinerDlg : public CWnd { DECLARE_DYNAMIC(COutlinerDlg) public: enum { IDC_OUTLINER_ROOT = 0x7300, IDC_OUTLINER_FILTER_LABEL = 0x7301, IDC_OUTLINER_FILTER = 0x7302, IDC_OUTLINER_TREE = 0x7303, ID_OUTLINER_OPEN_PROPERTIES = 0x7310, ID_OUTLINER_MOVE_TO_ENTITY = 0x7311, ID_OUTLINER_REFRESH = 0x7312, ID_OUTLINER_TOGGLE_VISIBILITY = 0x7313, ID_OUTLINER_TOGGLE_VISIBILITY_CHILDREN = 0x7314, ID_OUTLINER_SHOW_ONLY_THIS_AND_CHILDREN = 0x7315, ID_OUTLINER_SHOW_ALL = 0x7316, OUTLINER_REFRESH_TIMER = 0x7320, WM_OUTLINER_APPLY_CHECK = WM_APP + 0x321 }; COutlinerDlg(); virtual ~COutlinerDlg(); BOOL Create(CWnd* pParentWnd); void Refresh(bool force = false); void RefreshIfNeeded(); void OpenEntityProperties(entity_t* ent); void MoveToEntity(entity_t* ent); void SelectEntityInMap(entity_t* ent, bool updateInspector = false); protected: DECLARE_MESSAGE_MAP() afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnDestroy(); afx_msg void OnTimer(UINT_PTR nIDEvent); afx_msg void OnPaint(); afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); afx_msg void OnFilterChanged(); void OnTreeDblClick(NMHDR* pNMHDR, LRESULT* pResult); void OnTreeRightClick(NMHDR* pNMHDR, LRESULT* pResult); void OnTreeClick(NMHDR* pNMHDR, LRESULT* pResult); afx_msg LRESULT OnApplyTreeCheck(WPARAM wParam, LPARAM lParam); virtual BOOL PreTranslateMessage(MSG* pMsg); private: struct outlinerEdge_t { entity_t* source; entity_t* target; }; struct outlinerItemData_t { entity_t* entity; bool cycleRef; }; CStatic m_filterLabel; CEdit m_filter; CTreeCtrl m_tree; CFont m_font; CBrush m_bgBrush; CBrush m_editBrush; CBrush m_staticBrush; CPtrArray m_entities; CArray m_incoming; CArray m_covered; CArray m_edges; CPtrArray m_itemData; CString m_filterText; CString m_lastMapName; int m_lastMapModified; int m_lastEntityCount; entity_t* m_lastWorldEntity; void BuildGraph(); void AddEntityNode(entity_t* ent); void AddEdge(entity_t* source, entity_t* target); bool HasEdge(entity_t* source, entity_t* target) const; int FindNode(entity_t* ent) const; int FindNodeByName(const char* name) const; bool IsTargetKey(const char* key) const; void ClearItemData(); outlinerItemData_t* AllocItemData(entity_t* ent, bool cycleRef); entity_t* EntityFromItem(HTREEITEM item) const; entity_t* SelectedEntity() const; CString EntityDisplayName(entity_t* ent) const; bool EntityMatchesFilter(entity_t* ent) const; bool EntityOrDescendantMatches(entity_t* ent, CPtrArray& stack) const; bool ArrayContains(const CPtrArray& array, entity_t* ent) const; HTREEITEM InsertEntityRecursive(entity_t* ent, HTREEITEM parent, CPtrArray& stack); HTREEITEM FindTreeItemForEntity(entity_t* ent, HTREEITEM start) const; void ExpandAll(HTREEITEM start); void CollectEntityAndChildren(entity_t* ent, CPtrArray& out, CPtrArray& stack) const; void SetEntityVisibility(entity_t* ent, bool visible, bool includeChildren); void ToggleEntityVisibility(entity_t* ent, bool includeChildren); void ShowOnlyEntityAndChildren(entity_t* ent); void ShowAllEntities(); void UpdateAllCheckmarks(HTREEITEM start); void ApplyVisibilityChange(); bool NeedsRefresh() const; bool GetEntityCenter(entity_t* ent, idVec3& center) const; void ApplyFont(); }; bool Outliner_IsEntityVisible(entity_t* ent); void Outliner_SetEntityVisible(entity_t* ent, bool visible); void Outliner_ResetEntityVisibility(); bool Outliner_HasHiddenEntities(); bool Outliner_IsEntityLinkVisible(entity_t* source, entity_t* target);