Added new decl editor.

This commit is contained in:
Justin Marshall
2026-05-18 14:02:06 -07:00
parent 222cccc1f0
commit 119058a96e
10 changed files with 2351 additions and 1439 deletions
File diff suppressed because it is too large Load Diff
+56 -35
View File
@@ -31,83 +31,104 @@ If you have questions concerning this license or the applicable additional terms
#pragma once
// DialogDeclBrowser dialog
#include "../comafx/CPathTreeCtrl.h"
#include "DialogDeclEditor.h"
class DialogDeclBrowser : public CDialog {
// Legacy class name retained for source compatibility. This is now a dockable
// child window instead of a floating editor.
class DialogDeclBrowser : public CWnd {
DECLARE_DYNAMIC(DialogDeclBrowser)
public:
DialogDeclBrowser( CWnd* pParent = NULL ); // standard constructor
DialogDeclBrowser();
virtual ~DialogDeclBrowser();
BOOL Create( CWnd *parent, UINT id = 0 );
void ReloadDeclarations( void );
bool CompareDecl( HTREEITEM item, const char *name ) const;
//{{AFX_VIRTUAL(DialogDeclBrowser)
virtual BOOL OnInitDialog();
virtual void DoDataExchange( CDataExchange* pDX ); // DDX/DDV support
//}}AFX_VIRTUAL
const idDecl * GetSelectedDecl( void ) const;
DialogDeclEditor & GetEditor( void ) { return declEditor; }
void FocusDeclEditor( void );
protected:
//{{AFX_MSG(DialogDeclBrowser)
afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct );
afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult );
afx_msg HBRUSH OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor );
afx_msg BOOL OnEraseBkgnd( CDC* pDC );
afx_msg void OnPaint();
afx_msg void OnSetFocus( CWnd *pOldWnd );
afx_msg void OnDestroy();
afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
afx_msg void OnMove( int x, int y );
afx_msg void OnSize( UINT nType, int cx, int cy );
afx_msg void OnSizing( UINT nSide, LPRECT lpRect );
afx_msg void OnTreeSelChanged( NMHDR* pNMHDR, LRESULT* pResult );
afx_msg void OnTreeDblclk( NMHDR *pNMHDR, LRESULT *pResult );
afx_msg void OnBnClickedFind();
afx_msg void OnBnClickedEdit();
afx_msg void OnBnClickedNew();
afx_msg void OnBnClickedLoad();
afx_msg void OnBnClickedCreate();
afx_msg void OnBnClickedReload();
afx_msg void OnBnClickedOk();
afx_msg void OnBnClickedCancel();
//}}AFX_MSG
afx_msg void OnTypeChanged();
DECLARE_MESSAGE_MAP()
private:
//{{AFX_DATA(DialogDeclBrowser)
enum { IDD = IDD_DIALOG_DECLBROWSER };
CStatusBarCtrl statusBar;
CPathTreeCtrl declTree;
CPathTreeCtrl baseDeclTree;
CStatic findNameStatic;
CStatic findTextStatic;
CEdit findNameEdit;
CEdit findTextEdit;
CButton findButton;
CButton editButton;
CButton newButton;
CButton loadButton;
CButton reloadButton;
CButton cancelButton;
//}}AFX_DATA
CStatic newTypeStatic;
CStatic newNameStatic;
CStatic newFileStatic;
CComboBox newTypeCombo;
CEdit newNameEdit;
CEdit newFileEdit;
CButton createButton;
CStatic statusText;
DialogDeclEditor declEditor;
static toolTip_t toolTips[];
CRect initialRect;
CPathTreeCtrl baseDeclTree;
int numListedDecls;
idStr findNameString;
idStr findTextString;
bool controlsCreated;
bool reloadingTree;
TCHAR * m_pchTip;
char * m_pchTip;
WCHAR * m_pwchTip;
private:
void AddDeclTypeToTree( declType_t type, const char *root, CPathTreeCtrl &tree );
void AddScriptsToTree( CPathTreeCtrl &tree );
void AddGUIsToTree( CPathTreeCtrl &tree );
void InitBaseDeclTree( void );
CFont modernFont;
CBrush bgBrush;
CBrush panelBrush;
CBrush editBrush;
CBrush staticBrush;
private:
void CreateChildControls( void );
void PopulateTypeCombo( void );
void AddDeclTypeToTree( declType_t type, const char *root, CPathTreeCtrl &tree );
void InitBaseDeclTree( void );
void GetDeclName( HTREEITEM item, idStr &typeName, idStr &declName ) const;
const idDecl * GetDeclFromTreeItem( HTREEITEM item ) const;
const idDecl * GetSelectedDecl( void ) const;
void EditSelected( void ) const;
void LoadSelectedDecl( void );
void SelectDeclInTree( declType_t type, const char *name );
void ApplyDarkTheme( void );
void ApplyModernFontRecursive( CWnd *wnd );
void LayoutBrowser( int cx, int cy );
void SetBrowserStatus( const char *text );
declType_t GetSelectedNewType( void );
void SetCreateDefaultsFromSelection( const idDecl *decl );
void GetDefaultFileForType( declType_t type, idStr &fileName ) const;
};
void DeclBrowserInit( const idDict *spawnArgs );
void DeclBrowserRun( void );
void DeclBrowserShutdown( void );
void DeclBrowserReloadDeclarations( void );
#endif /* !__DIALOGDECLBROWSER_H__ */
File diff suppressed because it is too large Load Diff
+80 -38
View File
@@ -31,75 +31,117 @@ If you have questions concerning this license or the applicable additional terms
#pragma once
#include "../comafx/CSyntaxRichEditCtrl.h"
#include "afxcmn.h"
// DialogDeclEditor dialog
// Despite the legacy file/class name this is no longer a dialog. It is a
// dockable child-window editor used by the inspector declaration tab. It uses
// only stock MFC controls and no custom syntax edit widget.
class DialogDeclEditor : public CDialog {
class DialogDeclEditor : public CWnd {
DECLARE_DYNAMIC(DialogDeclEditor)
public:
DialogDeclEditor( CWnd* pParent = NULL ); // standard constructor
DialogDeclEditor();
virtual ~DialogDeclEditor();
BOOL Create( CWnd *parent, UINT id = 0 );
void LoadDecl( idDecl *decl );
void ClearDecl( void );
bool IsModified( void ) const { return modified; }
idDecl * GetDecl( void ) const { return decl; }
//{{AFX_VIRTUAL(DialogDeclEditor)
virtual BOOL OnInitDialog();
virtual void DoDataExchange( CDataExchange* pDX ); // DDX/DDV support
virtual BOOL PreTranslateMessage( MSG* pMsg );
//}}AFX_VIRTUAL
protected:
//{{AFX_MSG(DialogDeclEditor)
afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct );
afx_msg BOOL OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult );
afx_msg HBRUSH OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor );
afx_msg BOOL OnEraseBkgnd( CDC* pDC );
afx_msg void OnPaint();
afx_msg void OnSetFocus( CWnd *pOldWnd );
afx_msg void OnDestroy();
afx_msg void OnActivate( UINT nState, CWnd* pWndOther, BOOL bMinimized );
afx_msg void OnMove( int x, int y );
afx_msg void OnSize( UINT nType, int cx, int cy );
afx_msg void OnSizing( UINT nSide, LPRECT lpRect );
afx_msg void OnEditGoToLine();
afx_msg void OnEditFind();
afx_msg void OnEditFindNext();
afx_msg void OnEditReplace();
afx_msg LRESULT OnFindDialogMessage( WPARAM wParam, LPARAM lParam );
afx_msg void OnEnChangeEdit( NMHDR *pNMHDR, LRESULT *pResult );
afx_msg void OnEnInputEdit( NMHDR *pNMHDR, LRESULT *pResult );
afx_msg void OnNameChange();
afx_msg void OnRawBodyChange();
afx_msg void OnPropertyItemChanged( NMHDR *pNMHDR, LRESULT *pResult );
afx_msg void OnPropertyCustomDraw( NMHDR *pNMHDR, LRESULT *pResult );
afx_msg void OnBnClickedAddProperty();
afx_msg void OnBnClickedRemoveProperty();
afx_msg void OnBnClickedParseRaw();
afx_msg void OnBnClickedDeleteDecl();
afx_msg void OnBnClickedTest();
afx_msg void OnBnClickedOk();
afx_msg void OnBnClickedCancel();
//}}AFX_MSG
afx_msg void OnBnClickedSave();
afx_msg void OnBnClickedRevert();
DECLARE_MESSAGE_MAP()
private:
//{{AFX_DATA(DialogDeclEditor)
enum { IDD = IDD_DIALOG_DECLEDITOR };
CStatusBarCtrl statusBar;
CSyntaxRichEditCtrl declEdit;
CStatic typeLabel;
CStatic fileLabel;
CStatic nameLabel;
CStatic propertiesLabel;
CStatic keyLabel;
CStatic valueLabel;
CStatic rawBodyLabel;
CStatic statusText;
CEdit nameEdit;
CEdit keyEdit;
CEdit valueEdit;
CEdit rawBodyEdit;
CListCtrl propertyList;
CButton addPropertyButton;
CButton removePropertyButton;
CButton parseRawButton;
CButton deleteDeclButton;
CButton testButton;
CButton okButton;
CButton cancelButton;
//}}AFX_DATA
CButton saveButton;
CButton revertButton;
struct declProperty_t {
idStr key;
idStr value;
int lineIndex;
bool quotedKey;
bool quotedValue;
};
static toolTip_t toolTips[];
HACCEL m_hAccel;
CRect initialRect;
CFindReplaceDialog *findDlg;
CString findStr;
CString replaceStr;
bool matchCase;
bool matchWholeWords;
bool searchForward;
idDecl * decl;
int firstLine;
bool modified;
bool updatingControls;
bool controlsCreated;
CFont modernFont;
CFont monoFont;
CBrush bgBrush;
CBrush panelBrush;
CBrush editBrush;
CBrush staticBrush;
idList<declProperty_t> properties;
private:
void CreateChildControls( void );
void ApplyDarkTheme( void );
void ApplyFontRecursive( CWnd *wnd );
void SetControlsEnabled( bool enabled );
void SetModified( bool isModified );
void LoadBodyText( const char *declText );
void GetBodyText( idStr &bodyText ) const;
void SetBodyText( const idStr &bodyText );
void BuildDeclText( idStr &declText ) const;
void SyncPropertiesFromBody( void );
void RefreshPropertyList( void );
void SelectProperty( int listIndex );
int FindProperty( const char *key ) const;
bool UpsertPropertyInBody( const char *oldKey, const char *newKey, const char *value );
bool RemovePropertyFromBody( const char *key );
bool GetEditedDeclName( idStr &name ) const;
bool TestDecl( const idStr &declText );
bool SaveDeclText( void );
void UpdateStatusBar( void );
};
+3 -2
View File
@@ -29,8 +29,9 @@ If you have questions concerning this license or the applicable additional terms
#include "precompiled.h"
#pragma hdrstop
#include "../radiant/qe3.h"
#include "../../sys/win32/rc/DeclEditor_resource.h"
#include "../radiant/qe3.h"
#include "../comafx/CPathTreeCtrl.h"
#include "DialogDeclBrowser.h"
#include "DialogDeclNew.h"
@@ -203,7 +204,7 @@ void DialogDeclNew::OnBnClickedFile() {
case DECL_TABLE: folder = "materials"; ext = "(*.mtr)|*.mtr|(*.*)|*.*||"; break;
case DECL_MATERIAL: folder = "materials"; ext = "(*.mtr)|*.mtr|(*.*)|*.*||"; break;
case DECL_SKIN: folder = "skins"; ext = "(*.skin)|*.skin|(*.*)|*.*||"; break;
case DECL_SOUND: folder = "sound"; ext = "(*.sndshd|*.sndshd|(*.*)|*.*||"; break;
case DECL_SOUND: folder = "sound"; ext = "(*.sndshd)|*.sndshd|(*.*)|*.*||"; break;
case DECL_ENTITYDEF: folder = "def"; ext = "(*.def)|*.def|(*.decl)|*.decl|(*.*)|*.*||"; break;
case DECL_MODELDEF: folder = "def"; ext = "(*.def)|*.def|(*.*)|*.*||"; break;
case DECL_FX: folder = "fx"; ext = "(*.fx)|*.fx|(*.*)|*.*||"; break;
@@ -63,6 +63,7 @@ DialogEntityDefEditor::DialogEntityDefEditor
*/
DialogEntityDefEditor::DialogEntityDefEditor( CWnd* pParent /*=NULL*/ )
: CDialog(DialogEntityDefEditor::IDD, pParent)
, m_hAccel(NULL)
, decl(NULL)
, firstLine(0)
{
@@ -212,8 +213,11 @@ void DialogEntityDefEditor::LoadDecl( idDeclEntityDef *decl ) {
DialogEntityDefEditor::PopulateLists
=================
*/
void DialogEntityDefEditor::PopulateLists( const char *declText, const int textLength )
void DialogEntityDefEditor::PopulateLists( const char *declText, int textLength )
{
if ( textLength < 0 ) {
textLength = declText ? idStr::Length( declText ) : 0;
}
idLexer src;
idToken token, token2;
@@ -798,7 +802,7 @@ void DialogEntityDefEditor::OnBnClickedAdd() {
if (pItem) {
// Items with a * in front are inherited and shouldn't be written out
if (pItem->m_propName[0] == '*') {
if (newKey = pItem->m_propName.Mid(1)) {
if (newKey == pItem->m_propName.Mid(1)) {
matchedInherit = i;
}
}
@@ -839,7 +843,7 @@ void DialogEntityDefEditor::OnBnClickedDelete() {
if (pItem) {
// Items with a * in front are inherited and shouldn't be written out
if (pItem->m_propName[0] == '*') {
if (delKey = pItem->m_propName.Mid(1)) {
if (delKey == pItem->m_propName.Mid(1)) {
matchedInherit = i;
}
}
@@ -854,7 +858,7 @@ void DialogEntityDefEditor::OnBnClickedDelete() {
delete keyValsList.GetItemDataPtr(matchedKey);
keyValsList.DeleteString(matchedKey);
}
else if (matchedInherit) {
else if (matchedInherit >= 0) {
MessageBox("Cannot delete an inherited value");
}
}
@@ -107,7 +107,7 @@ private:
int firstLine;
private:
void PopulateLists(idStr &declText);
void PopulateLists( const char *declText, int textLength = -1 );
void SetInherit(idStr &inherit);
void BuildDeclText(idStr &declText);
bool TestDecl( const idStr &declText );
+30 -3
View File
@@ -17,6 +17,7 @@ Copyright (C) 2026 Justin Marshall
#include "InspectorDialog.h"
#include "OutlinerDlg.h"
#include "TabsDlg.h"
#include "../../sys/win32/rc/DeclEditor_resource.h"
#include <commctrl.h>
CInspectorDialog* g_Inspectors = NULL;
@@ -379,7 +380,7 @@ void InspectorsDockingCallback(bool docked, int ID, CWnd* wnd) {
CInspectorDialog::CInspectorDialog(CWnd* pParent /*=NULL*/)
: CTabsDlg(CInspectorDialog::IDD, pParent) {
initialized = false;
dockedTabs = W_CONSOLE | W_TEXTURE | W_MEDIA | W_OUTLINER;
dockedTabs = W_CONSOLE | W_TEXTURE | W_MEDIA | W_OUTLINER | W_DECLS;
}
CInspectorDialog::~CInspectorDialog() {
@@ -421,14 +422,17 @@ BOOL CInspectorDialog::OnInitDialog() {
mediaDlg.Create(IDD_DIALOG_TEXTURELIST, this);
entityDlg.Create(IDD_DIALOG_ENTITY, this);
outlinerDlg.Create(this);
declBrowserDlg.Create(this);
dockedTabs = GetCvarInt("radiant_InspectorDockedDialogs", W_CONSOLE | W_TEXTURE | W_MEDIA | W_OUTLINER);
dockedTabs = GetCvarInt("radiant_InspectorDockedDialogs", W_CONSOLE | W_TEXTURE | W_MEDIA | W_OUTLINER | W_DECLS);
dockedTabs |= W_DECLS;
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);
AddDockedWindow(&declBrowserDlg, W_DECLS, 6, "Decls", (dockedTabs & W_DECLS) != 0, InspectorsDockingCallback);
ApplyModernTheme();
@@ -485,11 +489,13 @@ void CInspectorDialog::ApplyModernTheme() {
ApplyModernFontRecursive(&mediaDlg);
ApplyModernFontRecursive(&entityDlg);
ApplyModernFontRecursive(&outlinerDlg);
ApplyModernFontRecursive(&declBrowserDlg);
InspectorDark_ApplyToDialog(&consoleWnd);
InspectorDark_ApplyToDialog(&mediaDlg);
InspectorDark_ApplyNativeTheme(entityDlg.GetSafeHwnd());
InspectorDark_ApplyToDialog(&outlinerDlg);
InspectorDark_ApplyToDialog(&declBrowserDlg);
ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_FRAMECHANGED);
@@ -694,9 +700,30 @@ void CInspectorDialog::OnClose() {
CTabsDlg::OnClose();
}
static bool InspectorIsTextInputClass(HWND hWnd) {
if (!hWnd) {
return false;
}
char className[128];
className[0] = '\0';
::GetClassNameA(hWnd, className, sizeof(className));
return ::lstrcmpiA(className, "Edit") == 0 ||
::lstrcmpiA(className, "ComboBox") == 0 ||
::lstrcmpiA(className, "ComboLBox") == 0 ||
::lstrcmpiA(className, "SysTreeView32") == 0 ||
::lstrcmpiA(className, "SysListView32") == 0;
}
BOOL CInspectorDialog::PreTranslateMessage(MSG* pMsg) {
if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP) {
g_pParentWnd->PostMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
HWND focus = ::GetFocus();
const bool inDecls = declBrowserDlg.GetSafeHwnd() &&
(focus == declBrowserDlg.GetSafeHwnd() || ::IsChild(declBrowserDlg.GetSafeHwnd(), focus));
const bool editingText = InspectorIsTextInputClass(focus);
if (!inDecls && !editingText && g_pParentWnd) {
g_pParentWnd->PostMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
}
}
return CTabsDlg::PreTranslateMessage(pMsg);
@@ -32,6 +32,11 @@ If you have questions concerning this license or the applicable additional terms
#include "ConsoleDlg.h"
#include "TabsDlg.h"
#include "OutlinerDlg.h"
#include "../decl/DialogDeclBrowser.h"
#ifndef W_DECLS
#define W_DECLS 0x0020
#endif
// CInspectorDialog dialog
@@ -75,6 +80,8 @@ public:
CDialogTextures mediaDlg;
CEntityDlg entityDlg;
COutlinerDlg outlinerDlg;
DialogDeclBrowser declBrowserDlg;
DialogDeclBrowser &GetDeclBrowser() { return declBrowserDlg; }
void SetMode(int mode, bool updateTabs = true);
void UpdateEntitySel(eclass_t *ent);
void UpdateSelectedEntity();
+11 -11
View File
@@ -665,17 +665,17 @@ void CDialogSound::OnCheckPlay()
void CDialogSound::OnBtnEdit()
{
const idDecl *decl = declManager->FindDeclWithoutParsing( DECL_SOUND, strShader, false );
if ( decl ) {
DialogDeclEditor *declEditor;
declEditor = new DialogDeclEditor;
declEditor->Create( IDD_DIALOG_DECLEDITOR, GetParent() );
declEditor->LoadDecl( const_cast<idDecl *>( decl ) );
declEditor->ShowWindow( SW_SHOW );
declEditor->SetFocus();
}
//const idDecl *decl = declManager->FindDeclWithoutParsing( DECL_SOUND, strShader, false );
//
//if ( decl ) {
// DialogDeclEditor *declEditor;
//
// declEditor = new DialogDeclEditor;
// declEditor->Create( IDD_DIALOG_DECLEDITOR, GetParent() );
// declEditor->LoadDecl( const_cast<idDecl *>( decl ) );
// declEditor->ShowWindow( SW_SHOW );
// declEditor->SetFocus();
//}
}
void CDialogSound::OnBtnDrop()