mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-18 14:31:58 +00:00
upload "kind" alien swarm
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
#include "kv_combo_leaf_panel.h"
|
||||
#include <vgui_controls/TextEntry.h>
|
||||
#include <vgui_controls/Button.h>
|
||||
#include <vgui_controls/ComboBox.h>
|
||||
#include "KeyValues.h"
|
||||
#include "kv_editor.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
DECLARE_BUILD_FACTORY( CKV_Combo_Leaf_Panel )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CKV_Combo_Leaf_Panel::CKV_Combo_Leaf_Panel( Panel *parent, const char *name ) : BaseClass( parent, name )
|
||||
{
|
||||
m_bIntegerChoice = false;
|
||||
m_pLabel = new vgui::Label( this, "Label", "" );
|
||||
m_pLabel->SetMouseInputEnabled( false );
|
||||
m_pCombo = new vgui::ComboBox( this, "Combo", 8, false );
|
||||
m_pCombo->SetAutoLocalize( false );
|
||||
m_pDeleteButton = new vgui::Button( this, "DeleteButton", "X", this, "Delete" );
|
||||
}
|
||||
|
||||
void CKV_Combo_Leaf_Panel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
m_pLabel->SetBounds( 0, 0, 100, 20 );
|
||||
m_pLabel->SizeToContents();
|
||||
m_pLabel->InvalidateLayout( true );
|
||||
int iLabelSpace = MAX( m_pLabel->GetWide() + 5, 100 );
|
||||
|
||||
int iExtraHeight = 0;
|
||||
int iTextEntryX = iLabelSpace;
|
||||
|
||||
if ( m_pFileSpecNode && m_pFileSpecNode->FindKey( "TextEntryNewLine" ) )
|
||||
{
|
||||
iExtraHeight = m_pLabel->GetTall();
|
||||
iTextEntryX = 0;
|
||||
}
|
||||
|
||||
if ( m_pFileSpecNode && m_pFileSpecNode->FindKey( "Tall" ) )
|
||||
{
|
||||
m_pCombo->SetBounds( iTextEntryX, iExtraHeight, 390 - iTextEntryX, m_pFileSpecNode->GetInt( "Tall" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pCombo->SetBounds( iTextEntryX, iExtraHeight, 390 - iTextEntryX, 20 );
|
||||
}
|
||||
|
||||
SetSize( 420, m_pCombo->GetTall() + iExtraHeight );
|
||||
|
||||
int iDeleteWidth = 20;
|
||||
m_pDeleteButton->SetBounds( GetWide() - (iDeleteWidth + 5), 2, iDeleteWidth, 16 );
|
||||
}
|
||||
|
||||
void CKV_Combo_Leaf_Panel::ApplySchemeSettings(vgui::IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
m_pLabel->SetPaintBackgroundEnabled( false );
|
||||
SetPaintBackgroundEnabled( false );
|
||||
}
|
||||
|
||||
void CKV_Combo_Leaf_Panel::UpdatePanel()
|
||||
{
|
||||
if ( m_pFileSpecNode )
|
||||
{
|
||||
m_pDeleteButton->SetVisible( !!m_pFileSpecNode->FindKey( "Deletable" ) );
|
||||
m_bIntegerChoice = m_pFileSpecNode->GetBool( "IntegerChoice" );
|
||||
m_pCombo->RemoveAll();
|
||||
int iChoices = 0;
|
||||
const char *szCurrentChoice = m_pKey ? m_pKey->GetString() : "0";
|
||||
int iCurrentChoice = atoi( szCurrentChoice );
|
||||
for ( KeyValues *pKey = m_pFileSpecNode->GetFirstSubKey(); pKey; pKey = pKey->GetNextKey() )
|
||||
{
|
||||
if ( !Q_stricmp( pKey->GetName(), "Choice" ) )
|
||||
{
|
||||
const char* szValue = pKey->GetString();
|
||||
int iIndex = m_pCombo->AddItem( szValue, NULL );
|
||||
if ( m_bIntegerChoice && iCurrentChoice == iChoices )
|
||||
{
|
||||
m_pCombo->ActivateItem( iIndex );
|
||||
}
|
||||
else if ( !m_bIntegerChoice && !Q_stricmp( szValue, pKey->GetString() ) )
|
||||
{
|
||||
m_pCombo->ActivateItem( iIndex );
|
||||
}
|
||||
iChoices++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !m_pKey )
|
||||
{
|
||||
m_pLabel->SetText( "INVALID KEY" );
|
||||
m_pCombo->SetText( "INVALID KEY" );
|
||||
return;
|
||||
}
|
||||
if ( m_pFileSpecNode && m_pFileSpecNode->FindKey( "FriendlyName" ) )
|
||||
{
|
||||
m_pLabel->SetText( m_pFileSpecNode->GetString( "FriendlyName" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLabel->SetText( m_pKey->GetName() );
|
||||
}
|
||||
//m_pCombo->SetText( m_pKey->GetString() );
|
||||
if ( m_pFileSpecNode && m_pFileSpecNode->GetInt( "ReadOnly", 0 ) == 1 )
|
||||
{
|
||||
m_pCombo->SetEditable( false );
|
||||
m_pCombo->SetEnabled( false );
|
||||
}
|
||||
}
|
||||
|
||||
// update our key when the text entry changes
|
||||
void CKV_Combo_Leaf_Panel::OnTextChanged( vgui::Panel* pTextEntry )
|
||||
{
|
||||
if ( pTextEntry != m_pCombo )
|
||||
return;
|
||||
|
||||
if ( !m_pKey )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_bIntegerChoice )
|
||||
{
|
||||
int iChoice = m_pCombo->GetActiveItem();
|
||||
|
||||
m_pKey->SetInt( NULL, iChoice );
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[ 2048 ];
|
||||
m_pCombo->GetText( buf, 2048 );
|
||||
|
||||
m_pKey->SetStringValue( buf );
|
||||
}
|
||||
|
||||
PostActionSignal( new KeyValues( "command", "command", "KeyValuesChanged" ) );
|
||||
}
|
||||
|
||||
void CKV_Combo_Leaf_Panel::OnCommand( const char *command )
|
||||
{
|
||||
if ( !Q_stricmp( command, "Delete" ) && m_pKeyParent )
|
||||
{
|
||||
m_pKeyParent->RemoveSubKey( m_pKey );
|
||||
m_pKey->deleteThis();
|
||||
m_pEditor->OnKeyDeleted();
|
||||
return;
|
||||
}
|
||||
BaseClass::OnCommand( command );
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef _INCLUDED_KV_COMBO_LEAF_PANEL_H
|
||||
#define _INCLUDED_KV_COMBO_LEAF_PANEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "kv_editor_base_panel.h"
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class TextEntry;
|
||||
class Label;
|
||||
class ComboBox;
|
||||
};
|
||||
|
||||
// a vgui panel for showing a generic leaf
|
||||
class CKV_Combo_Leaf_Panel : public CKV_Editor_Base_Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CKV_Combo_Leaf_Panel, CKV_Editor_Base_Panel );
|
||||
|
||||
public:
|
||||
CKV_Combo_Leaf_Panel( Panel *parent, const char *name);
|
||||
|
||||
virtual void PerformLayout();
|
||||
virtual void UpdatePanel();
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
||||
virtual void OnCommand( const char *command );
|
||||
|
||||
MESSAGE_FUNC_PTR( OnTextChanged, "TextChanged", panel );
|
||||
vgui::ComboBox *m_pCombo;
|
||||
vgui::Label *m_pLabel;
|
||||
vgui::Button* m_pDeleteButton;
|
||||
bool m_bIntegerChoice; // if set to true, this combo box represents an enum or some choice of integers, rather than a list of strings
|
||||
};
|
||||
|
||||
|
||||
#endif // _INCLUDED_KV_COMBO_LEAF_PANEL_H
|
||||
@@ -0,0 +1,375 @@
|
||||
#include "kv_editor.h"
|
||||
#include "kv_editor_base_panel.h"
|
||||
#include "kv_fit_children_panel.h"
|
||||
#include "ScrollingWindow.h"
|
||||
#include "filesystem.h"
|
||||
#include <vgui/ILocalize.h>
|
||||
#include <vgui_controls/MenuBar.h>
|
||||
#include <vgui_controls/MenuButton.h>
|
||||
#include <vgui_controls/Menu.h>
|
||||
#include "vgui/ISurface.h"
|
||||
#include <vgui_controls/FileOpenDialog.h>
|
||||
#include <vgui_controls/MessageBox.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//bool g_bAddedKVEditorLocalization = false;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CKV_Editor::CKV_Editor( Panel *parent, const char *name ) : BaseClass( parent, name )
|
||||
{
|
||||
//if ( !g_bAddedKVEditorLocalization )
|
||||
//{
|
||||
//g_pVGuiLocalize->AddFile( "resource/kv_editor_english.txt" );
|
||||
//g_bAddedKVEditorLocalization = true;
|
||||
//}
|
||||
|
||||
m_pKeys = NULL;
|
||||
m_pFileSpec = NULL;
|
||||
m_bRequireFileSpec = true;
|
||||
m_bShowSiblings = true;
|
||||
|
||||
m_pScrollingWindow = new CScrollingWindow( this, "ScrollingWindow" );
|
||||
m_pContainer = new CKV_Fit_Children_Panel( this, "Container" );
|
||||
|
||||
m_pScrollingWindow->SetChildPanel( m_pContainer );
|
||||
m_pScrollingWindow->InvalidateLayout( true );
|
||||
|
||||
m_szFileDirectory[0] = 0;
|
||||
m_szFileFilter[0] = 0;
|
||||
m_szFileFilterName[0] = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CKV_Editor::~CKV_Editor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CKV_Editor::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
m_pScrollingWindow->SetBounds( 0, 0, GetWide(), GetTall() );
|
||||
//m_pContainer->SetPos( 30, 30 );
|
||||
}
|
||||
|
||||
void CKV_Editor::ApplySchemeSettings(vgui::IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
|
||||
m_pContainer->SetBgColor( Color( 0, 0, 0, 255 ) );
|
||||
}
|
||||
|
||||
CKV_Editor_Base_Panel* CKV_Editor::FindPanel( KeyValues *pKey )
|
||||
{
|
||||
if ( !pKey )
|
||||
return NULL;
|
||||
|
||||
for ( int i = 0; i < m_Panels.Count(); i++ )
|
||||
{
|
||||
if ( m_Panels[i]->GetKey() == pKey )
|
||||
{
|
||||
return m_Panels[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CKV_Editor::DeleteAllPanels()
|
||||
{
|
||||
for ( int i = 0; i < m_Panels.Count(); i++ )
|
||||
{
|
||||
m_Panels[i]->SetVisible( false );
|
||||
m_Panels[i]->MarkForDeletion();
|
||||
CKV_Fit_Children_Panel *pFit = dynamic_cast< CKV_Fit_Children_Panel* >( m_Panels[i]->GetParent() );
|
||||
if ( pFit )
|
||||
{
|
||||
pFit->RemoveAutoPositionPanel( m_Panels[i] );
|
||||
}
|
||||
}
|
||||
m_Panels.Purge();
|
||||
}
|
||||
|
||||
CKV_Editor_Base_Panel* CKV_Editor::CreatePanel( const char *szClassName, CKV_Editor_Base_Panel *pParent, KeyValues *pFileSpecNode, KeyValues *pKey )
|
||||
{
|
||||
CKV_Editor_Base_Panel *pPanel = dynamic_cast<CKV_Editor_Base_Panel *>( CreateControlByName( szClassName ) );
|
||||
if ( pPanel )
|
||||
{
|
||||
pPanel->SetParent( pParent );
|
||||
pPanel->SetAllowDeletion( m_bAllowDeletion );
|
||||
pPanel->SetFileSpecNode( pFileSpecNode );
|
||||
pPanel->SetEditor( this );
|
||||
pPanel->SetName( pKey->GetName() );
|
||||
pPanel->SetKey( pKey );
|
||||
pPanel->SetKeyParent( FindParentForKey( pKey ) );
|
||||
pPanel->SetSortOrder( pFileSpecNode->GetFloat( "SortOrder" ) );
|
||||
pPanel->AddActionSignalTarget( this );
|
||||
CKV_Fit_Children_Panel *pFit = dynamic_cast< CKV_Fit_Children_Panel* >( pParent );
|
||||
if ( pFit )
|
||||
{
|
||||
pFit->AddAutoPositionPanel( pPanel );
|
||||
}
|
||||
m_Panels.AddToTail( pPanel );
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "Failed to create panel %s\n", szClassName );
|
||||
}
|
||||
return pPanel;
|
||||
}
|
||||
|
||||
// creates panels for target key, all its siblings and all its children
|
||||
void CKV_Editor::UpdatePanels( KeyValues *pKV, CKV_Editor_Base_Panel *pParentPanel, bool bIncludeSiblings )
|
||||
{
|
||||
Assert( pParentPanel );
|
||||
// go through each key, making sure it has a panel
|
||||
for ( KeyValues *pKey = pKV; pKey != NULL; pKey = pKey->GetNextKey() )
|
||||
{
|
||||
CKV_Editor_Base_Panel *pPanel = FindPanel( pKey );
|
||||
KeyValues *pFileSpecNode = FindFileSpecNodeForKey( pKey );
|
||||
if ( !pFileSpecNode && m_bRequireFileSpec )
|
||||
{
|
||||
Warning( "Key %s:%s has no FileSpecNode!\n", pKey->GetName(), pKey->GetString() );
|
||||
return;
|
||||
}
|
||||
const char *szClassName = "CKV_Node_Panel";
|
||||
if ( !pFileSpecNode )
|
||||
{
|
||||
//Warning( "Failed to FindFileSpecNodeForKey for key %s\n", pKey->GetName() );
|
||||
|
||||
bool bHasChildren = ( pKey->GetFirstSubKey() != NULL );
|
||||
if ( bHasChildren )
|
||||
{
|
||||
szClassName = "CKV_Node_Panel";
|
||||
}
|
||||
else
|
||||
{
|
||||
szClassName = "CKV_Leaf_Panel";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
szClassName = pFileSpecNode->GetString( "Panel", "CKV_Node_Panel" );
|
||||
}
|
||||
if ( !pPanel )
|
||||
{
|
||||
// create a panel of the appropriate type (as a child of pParentPanel)
|
||||
pPanel = CreatePanel( szClassName, pParentPanel, pFileSpecNode, pKey );
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure the panel is the right type.
|
||||
if ( Q_stricmp( pPanel->GetClassName(), szClassName ) )
|
||||
{
|
||||
// destroy and recreate if not (as a child of pParentPanel)
|
||||
pPanel->SetVisible( false );
|
||||
pPanel->MarkForDeletion();
|
||||
CKV_Fit_Children_Panel *pFit = dynamic_cast< CKV_Fit_Children_Panel* >( pPanel->GetParent() );
|
||||
if ( pFit )
|
||||
{
|
||||
pFit->RemoveAutoPositionPanel( pPanel );
|
||||
}
|
||||
pPanel = CreatePanel( szClassName, pParentPanel, pFileSpecNode, pKey );
|
||||
}
|
||||
else
|
||||
{
|
||||
pPanel->SetKey( pKey );
|
||||
pPanel->SetKeyParent( FindParentForKey( pKey ) );
|
||||
}
|
||||
}
|
||||
|
||||
// if key has children
|
||||
if ( pKey->GetFirstSubKey() )
|
||||
{
|
||||
UpdatePanels( pKey->GetFirstSubKey(), pPanel, true );
|
||||
}
|
||||
|
||||
if ( !bIncludeSiblings )
|
||||
break;
|
||||
}
|
||||
m_pContainer->InvalidateLayout( true );
|
||||
}
|
||||
|
||||
KeyValues* CKV_Editor::FindParentForKey( KeyValues *pSearchChild )
|
||||
{
|
||||
for ( KeyValues *pKey = m_pKeys; pKey != NULL; pKey = pKey->GetNextKey() )
|
||||
{
|
||||
if ( pKey == pSearchChild )
|
||||
return NULL;
|
||||
|
||||
KeyValues *pResult = FindParentForKey( pKey, pSearchChild );
|
||||
if ( pResult )
|
||||
return pResult;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
KeyValues* CKV_Editor::FindParentForKey( KeyValues *pRoot, KeyValues *pSearchChild )
|
||||
{
|
||||
// see if pKV or any of our direct children are the search key
|
||||
for ( KeyValues *pKey = pRoot->GetFirstSubKey(); pKey != NULL; pKey = pKey->GetNextKey() )
|
||||
{
|
||||
if ( pKey == pSearchChild )
|
||||
return pRoot;
|
||||
}
|
||||
|
||||
// if not, then ask each of our children to search deeper
|
||||
for ( KeyValues *pKey = pRoot->GetFirstSubKey(); pKey != NULL; pKey = pKey->GetNextKey() )
|
||||
{
|
||||
KeyValues *pResult = FindParentForKey( pKey, pSearchChild );
|
||||
if ( pResult )
|
||||
return pResult;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
KeyValues* CKV_Editor::FindFileSpecNodeForKey( KeyValues *pKey )
|
||||
{
|
||||
if ( !m_pFileSpec )
|
||||
return NULL;
|
||||
// build a list of panels from us up to the parent
|
||||
CUtlVector<KeyValues*> chain;
|
||||
KeyValues *pSearchKey = pKey;
|
||||
while ( pSearchKey )
|
||||
{
|
||||
chain.AddToHead( pSearchKey );
|
||||
pSearchKey = FindParentForKey( pSearchKey );
|
||||
}
|
||||
|
||||
int iChainDepth = chain.Count();
|
||||
int iCurrentDepth = 0;
|
||||
|
||||
KeyValues *pKeySpec = m_pFileSpec;
|
||||
while ( pKeySpec )
|
||||
{
|
||||
const char *szNodeName = "_unnamed_node";
|
||||
|
||||
if ( !Q_stricmp( pKeySpec->GetName(), "_Node" ) || !Q_stricmp( pKeySpec->GetName(), "_Leaf" ) )
|
||||
{
|
||||
szNodeName = pKeySpec->GetString( "Name", "_unnamed_node" );
|
||||
}
|
||||
//const char *szChainName = chain[iCurrentDepth]->GetName();
|
||||
if ( !Q_stricmp( szNodeName, chain[iCurrentDepth]->GetName() )
|
||||
|| !Q_stricmp( szNodeName, "*" ) ) // at any level there can be a keyspec node with name "*" which will match any key
|
||||
{
|
||||
iCurrentDepth++;
|
||||
if ( iCurrentDepth >= iChainDepth ) // found appropriate file spec node that describes this key
|
||||
{
|
||||
return pKeySpec;
|
||||
}
|
||||
|
||||
// Go down a level
|
||||
pKeySpec = pKeySpec->GetFirstSubKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check the next key in the mission spec
|
||||
pKeySpec = pKeySpec->GetNextKey();
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CKV_Editor::SetFileSpec( const char *szFilename, const char *szPathID )
|
||||
{
|
||||
KeyValues *pKeys = new KeyValues( "FileSpec" );
|
||||
if ( !pKeys->LoadFromFile( g_pFullFileSystem, szFilename, szPathID ) )
|
||||
{
|
||||
Warning( "Failed to load file spec %s\n", szFilename );
|
||||
return;
|
||||
}
|
||||
SetFileSpec( pKeys );
|
||||
}
|
||||
|
||||
void CKV_Editor::SetFileSpec( KeyValues *pKeys )
|
||||
{
|
||||
m_pFileSpec = pKeys;
|
||||
DeleteAllPanels();
|
||||
UpdatePanels( m_pKeys, m_pContainer, m_bShowSiblings );
|
||||
}
|
||||
|
||||
void CKV_Editor::SetFileFilter( const char *szFilter, const char *szFilterName )
|
||||
{
|
||||
Q_snprintf( m_szFileFilter, sizeof( m_szFileFilter ), szFilter );
|
||||
Q_snprintf( m_szFileFilterName, sizeof( m_szFileFilterName ), szFilterName );
|
||||
}
|
||||
|
||||
void CKV_Editor::SetFileDirectory( const char *szDirName )
|
||||
{
|
||||
Q_snprintf( m_szFileDirectory, sizeof( m_szFileDirectory ), szDirName );
|
||||
}
|
||||
|
||||
void CKV_Editor::SetKeys( KeyValues *pKeys )
|
||||
{
|
||||
m_pKeys = pKeys;
|
||||
DeleteAllPanels();
|
||||
UpdatePanels( m_pKeys, m_pContainer, m_bShowSiblings );
|
||||
PostActionSignal( new KeyValues( "command", "command", "KeyValuesChanged" ) );
|
||||
}
|
||||
|
||||
void CKV_Editor::OnKeyDeleted()
|
||||
{
|
||||
DeleteAllPanels();
|
||||
UpdatePanels( m_pKeys, m_pContainer, m_bShowSiblings );
|
||||
PostActionSignal( new KeyValues( "command", "command", "KeyValuesChanged" ) );
|
||||
}
|
||||
|
||||
void CKV_Editor::OnKeyAdded()
|
||||
{
|
||||
DeleteAllPanels();
|
||||
UpdatePanels( m_pKeys, m_pContainer, m_bShowSiblings );
|
||||
PostActionSignal( new KeyValues( "command", "command", "KeyValuesChanged" ) );
|
||||
}
|
||||
|
||||
void CKV_Editor::AddToKey( KeyValues *pFileSpecNode, KeyValues *pKey, const char *szNewKeyName )
|
||||
{
|
||||
// go through all _Node or _Leaf children of our filespec node
|
||||
for ( KeyValues *pSubKey = pFileSpecNode->GetFirstSubKey(); pSubKey; pSubKey = pSubKey->GetNextKey() )
|
||||
{
|
||||
bool bNode = !Q_stricmp( pSubKey->GetName(), "_Node" );
|
||||
bool bLeaf = !Q_stricmp( pSubKey->GetName(), "_Leaf" );
|
||||
if ( !bLeaf && !bNode )
|
||||
continue;
|
||||
|
||||
if ( szNewKeyName && Q_stricmp( pSubKey->GetString( "Name" ), szNewKeyName ) )
|
||||
continue;
|
||||
|
||||
if ( !szNewKeyName && pSubKey->GetInt( "Autocreate" ) != 1 )
|
||||
continue;
|
||||
|
||||
if ( bLeaf )
|
||||
{
|
||||
bool bAlreadyExists = !!pKey->FindKey( pSubKey->GetString( "Name" ) );
|
||||
bool bUnique = pSubKey->GetInt( "Unique" ) == 1;
|
||||
if ( !bUnique || !bAlreadyExists )
|
||||
{
|
||||
KeyValues *pNewKey = new KeyValues( pSubKey->GetString( "Name" ) );
|
||||
Msg( "Added leaf %s\n", pSubKey->GetString( "Name" ) );
|
||||
pNewKey->SetStringValue( pSubKey->GetString( "DefaultValue", "" ) );
|
||||
pKey->AddSubKey( pNewKey );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyValues *pNewKey = new KeyValues( pSubKey->GetString( "Name" ) );
|
||||
Msg( "Added node %s\n", pSubKey->GetString( "Name" ) );
|
||||
pKey->AddSubKey( pNewKey );
|
||||
|
||||
// recursively create child _nodes and any _leafs they have
|
||||
KeyValues *pNewSpec = FindFileSpecNodeForKey( pNewKey );
|
||||
if ( pNewSpec )
|
||||
{
|
||||
AddToKey( pNewSpec, pNewKey, NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
OnKeyAdded();
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
#ifndef _INCLUDED_KV_EDITOR_H
|
||||
#define _INCLUDED_KV_EDITOR_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui_controls/EditablePanel.h>
|
||||
#include <vgui_controls/ImageList.h>
|
||||
#include <vgui_controls/SectionedListPanel.h>
|
||||
#include <vgui_controls/PHandle.h>
|
||||
#include <FileSystem.h>
|
||||
#include "vgui/mousecode.h"
|
||||
#include "vgui/IScheme.h"
|
||||
#include "ConfigManager.h"
|
||||
|
||||
class CScrollingWindow;
|
||||
class CKV_Editor_Base_Panel;
|
||||
class CKV_Fit_Children_Panel;
|
||||
namespace vgui
|
||||
{
|
||||
class PanelListPanel;
|
||||
class ImagePanel;
|
||||
class MenuBar;
|
||||
class CheckButton;
|
||||
class Button;
|
||||
class Menu;
|
||||
};
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Main panel for visualizing and editing keyvalues
|
||||
//-----------------------------------------------------------------------------
|
||||
class CKV_Editor : public vgui::EditablePanel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CKV_Editor, vgui::EditablePanel );
|
||||
|
||||
public:
|
||||
CKV_Editor( Panel *parent, const char *name );
|
||||
virtual ~CKV_Editor();
|
||||
|
||||
virtual void PerformLayout();
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
||||
|
||||
virtual void SetFileSpec( const char *szFilename, const char *szPathID );
|
||||
virtual void SetFileSpec( KeyValues *pKeys );
|
||||
KeyValues* GetFileSpec() { return m_pFileSpec; }
|
||||
|
||||
virtual void SetKeys( KeyValues *pKeys );
|
||||
KeyValues* GetKeys() { return m_pKeys; }
|
||||
void SetShowSiblingKeys( bool bShowSiblings ) { m_bShowSiblings = bShowSiblings; }
|
||||
|
||||
void SetFileFilter( const char *szFilter, const char *szFilterName );
|
||||
void SetFileDirectory( const char *szDirName );
|
||||
const char* GetFileFilter() { return m_szFileFilter; }
|
||||
const char* GetFileFilterName() { return m_szFileFilterName; }
|
||||
const char* GetFileDirectory() { return m_szFileDirectory; }
|
||||
|
||||
virtual void AddToKey( KeyValues *pFileSpecNode, KeyValues *pKey, const char *szNewKeyName );
|
||||
virtual void OnKeyDeleted();
|
||||
virtual void OnKeyAdded();
|
||||
|
||||
void SetRequiresFileSpec( bool bRequiresFileSpec ) { m_bRequireFileSpec = bRequiresFileSpec; }
|
||||
|
||||
protected:
|
||||
|
||||
// the keyvalues we're currently editing
|
||||
KeyValues *m_pKeys;
|
||||
|
||||
// kv view
|
||||
CScrollingWindow* m_pScrollingWindow;
|
||||
|
||||
char m_szFileDirectory[MAX_PATH];
|
||||
char m_szFileFilter[32];
|
||||
char m_szFileFilterName[32];
|
||||
|
||||
void DeleteAllPanels();
|
||||
void UpdatePanels( KeyValues *pKV, CKV_Editor_Base_Panel *pParentPanel, bool bIncludeSiblings );
|
||||
CKV_Editor_Base_Panel* FindPanel( KeyValues *pKey );
|
||||
CKV_Editor_Base_Panel* CreatePanel( const char *szClassName, CKV_Editor_Base_Panel *pParent, KeyValues *pFileSpecNode, KeyValues *pKey );
|
||||
|
||||
//const char* FindPanelClassForKey( KeyValues *pKey ); // finds the panel class a particular key is meant to have
|
||||
KeyValues* FindParentForKey( KeyValues *pSearchChild ); // searches m_pKeys for the parent
|
||||
KeyValues* FindParentForKey( KeyValues *pRoot, KeyValues *pSearchChild ); // searches pRoot for the parent
|
||||
KeyValues* FindFileSpecNodeForKey( KeyValues *pKey );
|
||||
|
||||
CKV_Fit_Children_Panel *m_pContainer;
|
||||
CUtlVector< CKV_Editor_Base_Panel* > m_Panels;
|
||||
|
||||
// keyvalues describing the file format of the KeyValues we're editing
|
||||
KeyValues* FindFileSpecNodeForKey( KeyValues *pKey, const char *szPathID );
|
||||
KeyValues *m_pFileSpec;
|
||||
bool m_bRequireFileSpec;
|
||||
bool m_bShowSiblings;
|
||||
bool m_bAllowDeletion;
|
||||
};
|
||||
|
||||
|
||||
#endif // _INCLUDED_KV_EDITOR_H
|
||||
@@ -0,0 +1,49 @@
|
||||
#include "kv_editor_base_panel.h"
|
||||
#include "KeyValues.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CKV_Editor_Base_Panel::CKV_Editor_Base_Panel( Panel *parent, const char *name ) : BaseClass( parent, name )
|
||||
{
|
||||
m_pKey = NULL;
|
||||
m_pKeyParent = NULL;
|
||||
m_flSortOrder = 0;
|
||||
m_pFileSpecNode = NULL;
|
||||
m_pEditor = NULL;
|
||||
m_bAllowDeletion = true;
|
||||
}
|
||||
|
||||
void CKV_Editor_Base_Panel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
}
|
||||
|
||||
void CKV_Editor_Base_Panel::SetKey( KeyValues *pKey )
|
||||
{
|
||||
if ( pKey == m_pKey )
|
||||
return;
|
||||
|
||||
m_pKey = pKey;
|
||||
UpdatePanel();
|
||||
}
|
||||
|
||||
void CKV_Editor_Base_Panel::SetKeyParent( KeyValues *pKey )
|
||||
{
|
||||
if ( pKey == m_pKeyParent )
|
||||
return;
|
||||
|
||||
m_pKeyParent = pKey;
|
||||
}
|
||||
|
||||
void CKV_Editor_Base_Panel::SetFileSpecNode( KeyValues *pKey )
|
||||
{
|
||||
m_pFileSpecNode = pKey;
|
||||
|
||||
ApplySettings( pKey );
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef _INCLUDED_KV_EDITOR_PANEL_H
|
||||
#define _INCLUDED_KV_EDITOR_PANEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui_controls/EditablePanel.h>
|
||||
|
||||
class CKV_Editor;
|
||||
|
||||
// a vgui panel that resizes to fit its children, with some border
|
||||
class CKV_Editor_Base_Panel : public vgui::EditablePanel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CKV_Editor_Base_Panel, vgui::EditablePanel );
|
||||
|
||||
public:
|
||||
CKV_Editor_Base_Panel( Panel *parent, const char *name);
|
||||
|
||||
virtual void PerformLayout();
|
||||
|
||||
virtual void UpdatePanel() { }
|
||||
void SetKey( KeyValues *pKey );
|
||||
KeyValues* GetKey() { return m_pKey; }
|
||||
void SetKeyParent( KeyValues *pKey );
|
||||
|
||||
void SetFileSpecNode( KeyValues *pKey );
|
||||
void SetEditor( CKV_Editor *pEditor ) { m_pEditor = pEditor; }
|
||||
void SetAllowDeletion( bool bCanDelete ) { m_bAllowDeletion = bCanDelete; }
|
||||
|
||||
float GetSortOrder() const { return m_flSortOrder; }
|
||||
void SetSortOrder( float flSortOrder ) { m_flSortOrder = flSortOrder; }
|
||||
|
||||
protected:
|
||||
KeyValues *m_pKey;
|
||||
KeyValues *m_pKeyParent;
|
||||
KeyValues *m_pFileSpecNode;
|
||||
CKV_Editor *m_pEditor;
|
||||
float m_flSortOrder;
|
||||
bool m_bAllowDeletion;
|
||||
};
|
||||
|
||||
|
||||
#endif // _INCLUDED_KV_EDITOR_PANEL_H
|
||||
@@ -0,0 +1,199 @@
|
||||
#include "kv_editor.h"
|
||||
#include "kv_editor_frame.h"
|
||||
#include "kv_editor_base_panel.h"
|
||||
#include "kv_fit_children_panel.h"
|
||||
#include "ScrollingWindow.h"
|
||||
#include "filesystem.h"
|
||||
#include <vgui/ILocalize.h>
|
||||
#include <vgui_controls/MenuBar.h>
|
||||
#include <vgui_controls/MenuButton.h>
|
||||
#include <vgui_controls/Menu.h>
|
||||
#include "vgui/ISurface.h"
|
||||
#include <vgui_controls/FileOpenDialog.h>
|
||||
#include <vgui_controls/MessageBox.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
extern char g_gamedir[1024];
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CKV_Editor_Frame::CKV_Editor_Frame( Panel *parent, const char *name ) : BaseClass( parent, name )
|
||||
{
|
||||
vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFile( "tilegen_scheme.res", NULL );
|
||||
SetScheme( scheme );
|
||||
|
||||
m_pEditor = new CKV_Editor( this, "KVEditor" );
|
||||
m_pEditor->SetFileFilter( "*.txt", "KeyValues files (*.txt)" );
|
||||
|
||||
m_szLastFileName[0] = '\0';
|
||||
|
||||
SetSize( 384, 420 );
|
||||
SetMinimumSize( 384, 420 );
|
||||
|
||||
// setup the menu
|
||||
m_pMenuBar = new MenuBar( this, "KV_Editor_MenuBar" );
|
||||
MenuButton *pFileMenuButton = new MenuButton( this, "KV_Editor_FileMenuButton", "&File" );
|
||||
m_pFileMenu = new Menu( pFileMenuButton, "KV_Editor_FileMenu" );
|
||||
//m_pFileMenu->AddMenuItem( "&New", "NewKeys", this );
|
||||
m_pFileMenu->AddMenuItem( "&Open...", "OpenKeys", this );
|
||||
m_pFileMenu->AddMenuItem( "&Save", "SaveKeys", this );
|
||||
m_pFileMenu->AddMenuItem( "&Save As...", "SaveKeysAs", this );
|
||||
pFileMenuButton->SetMenu( m_pFileMenu );
|
||||
m_pMenuBar->AddButton( pFileMenuButton );
|
||||
|
||||
// disable keyboard input on the menu, otherwise once you click there, this dialog never gets key input again (is there a better way to do this and maintain keyboard shortcuts for the menu?)
|
||||
pFileMenuButton->SetKeyBoardInputEnabled( false );
|
||||
m_pFileMenu->SetKeyBoardInputEnabled( false );
|
||||
|
||||
SetSizeable( true );
|
||||
SetMinimizeButtonVisible( false );
|
||||
SetMaximizeButtonVisible( false );
|
||||
SetMenuButtonVisible( false );
|
||||
m_bFirstPerformLayout = true;
|
||||
|
||||
|
||||
SetTitle( "KeyValues Editor", true );
|
||||
|
||||
// temp for mission editor
|
||||
//Q_snprintf( m_szFileDirectory, sizeof( m_szFileDirectory ), "infested/tilegen/missions" );
|
||||
char keys_dir[1024];
|
||||
Q_snprintf( keys_dir, sizeof( keys_dir ), "%s\\tilegen\\missions", g_gamedir );
|
||||
m_pEditor->SetFileDirectory( keys_dir );
|
||||
m_pEditor->SetFileSpec( "tilegen/mission_editor_spec.txt", "GAME" );
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CKV_Editor_Frame::~CKV_Editor_Frame()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Kills the whole app on close
|
||||
//-----------------------------------------------------------------------------
|
||||
void CKV_Editor_Frame::OnClose( void )
|
||||
{
|
||||
BaseClass::OnClose();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Parse commands coming in from the VGUI dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
void CKV_Editor_Frame::OnCommand( const char *command )
|
||||
{
|
||||
if ( Q_stricmp( command, "OpenKeys" ) == 0 )
|
||||
{
|
||||
DoFileOpen();
|
||||
return;
|
||||
}
|
||||
else if ( Q_stricmp( command, "SaveKeys" ) == 0 )
|
||||
{
|
||||
if ( Q_strlen( m_szLastFileName ) <= 0 )
|
||||
{
|
||||
DoFileSaveAs();
|
||||
}
|
||||
else if ( m_pEditor->GetKeys() )
|
||||
{
|
||||
m_pEditor->GetKeys()->SaveToFile( g_pFullFileSystem, m_szLastFileName, "GAME" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if ( Q_stricmp( command, "SaveKeysAs" ) == 0 )
|
||||
{
|
||||
DoFileSaveAs();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CKV_Editor_Frame::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
if ( m_bFirstPerformLayout )
|
||||
{
|
||||
int screenWide, screenTall;
|
||||
surface()->GetScreenSize(screenWide, screenTall);
|
||||
|
||||
m_bFirstPerformLayout = false;
|
||||
int inset_x = screenWide * 0.15f;
|
||||
int inset_y = screenWide * 0.04f;
|
||||
SetBounds( inset_x, inset_y, screenWide - inset_x * 3, screenTall - inset_y * 2 );
|
||||
}
|
||||
|
||||
m_pMenuBar->SetBounds( 20, 35, GetWide() - 40, 25 );
|
||||
m_pEditor->SetBounds( 20, 65, GetWide() - 40, GetTall() - 85 );
|
||||
}
|
||||
|
||||
void CKV_Editor_Frame::ApplySchemeSettings(vgui::IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
}
|
||||
|
||||
void CKV_Editor_Frame::DoFileOpen()
|
||||
{
|
||||
m_FileSelectType = KV_FST_LAYOUT_OPEN;
|
||||
// Pop up the dialog
|
||||
FileOpenDialog *pFileDialog = new FileOpenDialog( NULL, "Open....", true );
|
||||
|
||||
pFileDialog->SetStartDirectory( m_pEditor->GetFileDirectory() );
|
||||
pFileDialog->AddFilter( m_pEditor->GetFileFilter(), m_pEditor->GetFileFilterName(), true );
|
||||
pFileDialog->AddActionSignalTarget( this );
|
||||
|
||||
pFileDialog->DoModal( false );
|
||||
}
|
||||
|
||||
void CKV_Editor_Frame::DoFileSaveAs()
|
||||
{
|
||||
m_FileSelectType = KV_FST_LAYOUT_SAVE_AS;
|
||||
// Pop up the dialog
|
||||
FileOpenDialog *pFileDialog = new FileOpenDialog (NULL, "Save Map Layout", false);
|
||||
pFileDialog->SetStartDirectory( m_pEditor->GetFileDirectory() );
|
||||
pFileDialog->AddFilter( m_pEditor->GetFileFilter(), m_pEditor->GetFileFilterName(), true );
|
||||
pFileDialog->AddActionSignalTarget(this);
|
||||
|
||||
pFileDialog->DoModal(true);
|
||||
}
|
||||
|
||||
void CKV_Editor_Frame::OnFileSelected( const char *fullpath )
|
||||
{
|
||||
if ( m_FileSelectType == KV_FST_LAYOUT_SAVE_AS )
|
||||
{
|
||||
if ( m_pEditor->GetKeys() )
|
||||
{
|
||||
Q_snprintf( m_szLastFileName, sizeof( m_szLastFileName ), "%s", fullpath );
|
||||
m_pEditor->GetKeys()->SaveToFile( g_pFullFileSystem, fullpath, "GAME" );
|
||||
}
|
||||
}
|
||||
else if ( m_FileSelectType == KV_FST_LAYOUT_OPEN )
|
||||
{
|
||||
if ( m_pEditor->GetKeys() )
|
||||
{
|
||||
m_pEditor->GetKeys()->deleteThis();
|
||||
}
|
||||
|
||||
KeyValues *pKeys = new KeyValues( "Keys" );
|
||||
// load in the new one
|
||||
if ( !pKeys->LoadFromFile( g_pFullFileSystem, fullpath ) )
|
||||
{
|
||||
MessageBox *pMessage = new MessageBox ("Error", "Error loading KeyValues", this);
|
||||
pMessage->DoModal();
|
||||
return;
|
||||
}
|
||||
m_pEditor->SetKeys( pKeys );
|
||||
}
|
||||
}
|
||||
|
||||
MessageMapItem_t CKV_Editor_Frame::m_MessageMap[] =
|
||||
{
|
||||
MAP_MESSAGE_CONSTCHARPTR(CKV_Editor_Frame, "FileSelected", OnFileSelected, "fullpath"),
|
||||
};
|
||||
|
||||
IMPLEMENT_PANELMAP(CKV_Editor_Frame, Frame);
|
||||
@@ -0,0 +1,77 @@
|
||||
#ifndef _INCLUDED_KV_EDITOR_FRAME_H
|
||||
#define _INCLUDED_KV_EDITOR_FRAME_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui_controls/Frame.h>
|
||||
#include <vgui_controls/ImageList.h>
|
||||
#include <vgui_controls/SectionedListPanel.h>
|
||||
#include <vgui_controls/PHandle.h>
|
||||
#include <FileSystem.h>
|
||||
#include "vgui/mousecode.h"
|
||||
#include "vgui/IScheme.h"
|
||||
#include "ConfigManager.h"
|
||||
|
||||
class CScrollingWindow;
|
||||
class CKV_Editor_Base_Panel;
|
||||
class CKV_Fit_Children_Panel;
|
||||
class CKV_Editor;
|
||||
namespace vgui
|
||||
{
|
||||
class PanelListPanel;
|
||||
class ImagePanel;
|
||||
class MenuBar;
|
||||
class CheckButton;
|
||||
class Button;
|
||||
class Menu;
|
||||
};
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
enum KV_FileSelectType
|
||||
{
|
||||
KV_FST_LAYOUT_OPEN,
|
||||
KV_FST_LAYOUT_SAVE_AS
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Main dialog for visualizing and editing keyvalues
|
||||
//-----------------------------------------------------------------------------
|
||||
class CKV_Editor_Frame : public Frame
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CKV_Editor_Frame, Frame );
|
||||
|
||||
public:
|
||||
CKV_Editor_Frame( Panel *parent, const char *name );
|
||||
virtual ~CKV_Editor_Frame();
|
||||
|
||||
virtual void PerformLayout();
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
||||
|
||||
// main menu bar
|
||||
MenuBar *m_pMenuBar;
|
||||
vgui::Menu *m_pFileMenu;
|
||||
vgui::Menu *m_pToolsMenu;
|
||||
|
||||
// panel for editing keyvalues
|
||||
CKV_Editor* m_pEditor;
|
||||
|
||||
DECLARE_PANELMAP();
|
||||
|
||||
void DoFileSaveAs();
|
||||
void DoFileOpen();
|
||||
void OnFileSelected(const char *fullpath);
|
||||
KV_FileSelectType m_FileSelectType;
|
||||
|
||||
protected:
|
||||
virtual void OnClose();
|
||||
virtual void OnCommand( const char *command );
|
||||
|
||||
char m_szLastFileName[MAX_PATH];
|
||||
bool m_bFirstPerformLayout;
|
||||
};
|
||||
|
||||
|
||||
#endif // _INCLUDED_KV_EDITOR_FRAME_H
|
||||
@@ -0,0 +1,92 @@
|
||||
#include "kv_fit_children_panel.h"
|
||||
#include "KeyValues.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CKV_Fit_Children_Panel::CKV_Fit_Children_Panel( Panel *parent, const char *name ) :
|
||||
BaseClass( parent, name ),
|
||||
m_iAutoPositionStartY( 5 ),
|
||||
m_iBorder( 5 ),
|
||||
m_iSpacing( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
bool FitChildrenLessFunc::Less( CKV_Editor_Base_Panel* const &src1, CKV_Editor_Base_Panel* const &src2, void *pCtx )
|
||||
{
|
||||
const CKV_Editor_Base_Panel *pEditorPanel1 = dynamic_cast<const CKV_Editor_Base_Panel*>( src1 );
|
||||
const CKV_Editor_Base_Panel *pEditorPanel2 = dynamic_cast<const CKV_Editor_Base_Panel*>( src2 );
|
||||
if ( pEditorPanel1 && pEditorPanel2 )
|
||||
{
|
||||
return pEditorPanel1->GetSortOrder() < pEditorPanel2->GetSortOrder();
|
||||
}
|
||||
return src1->GetZPos() < src2->GetZPos();
|
||||
}
|
||||
|
||||
void CKV_Fit_Children_Panel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
if ( m_pFileSpecNode )
|
||||
{
|
||||
m_iAutoPositionStartY = m_pFileSpecNode->GetInt( "AutoPositionStartY", m_iAutoPositionStartY );
|
||||
m_iBorder = m_pFileSpecNode->GetInt( "Border", m_iBorder );
|
||||
m_iSpacing = m_pFileSpecNode->GetInt( "Spacing", m_iSpacing );
|
||||
}
|
||||
|
||||
// make sure all children are laid out and find the extents of them
|
||||
// lay out children in a vertical list
|
||||
int cursor_y = m_iAutoPositionStartY;
|
||||
int wide = 0, tall = cursor_y;
|
||||
|
||||
for ( int i = 0; i < m_AutoPositionPanels.Count(); i++ )
|
||||
{
|
||||
vgui::Panel *pPanel = m_AutoPositionPanels[i];
|
||||
bool bNode = IsNodePanel( pPanel );
|
||||
if ( bNode ) // extra gap before node panel
|
||||
{
|
||||
cursor_y += m_iSpacing * 2;
|
||||
}
|
||||
pPanel->SetPos( m_iBorder, cursor_y );
|
||||
pPanel->InvalidateLayout( true );
|
||||
int x, y;
|
||||
pPanel->GetPos( x, y );
|
||||
x += pPanel->GetWide();
|
||||
y += pPanel->GetTall();
|
||||
cursor_y += pPanel->GetTall() + m_iSpacing;
|
||||
if ( bNode ) // extra gap after node panel
|
||||
{
|
||||
cursor_y += m_iSpacing * 2;
|
||||
}
|
||||
wide = MAX( wide, x );
|
||||
tall = MAX( tall, y );
|
||||
}
|
||||
|
||||
SetSize( wide + m_iBorder, tall + m_iBorder );
|
||||
}
|
||||
|
||||
bool CKV_Fit_Children_Panel::IsNodePanel( vgui::Panel *pPanel )
|
||||
{
|
||||
return ( dynamic_cast< CKV_Fit_Children_Panel* > ( pPanel ) != NULL );
|
||||
}
|
||||
|
||||
void CKV_Fit_Children_Panel::AddAutoPositionPanel( CKV_Editor_Base_Panel *pPanel )
|
||||
{
|
||||
m_AutoPositionPanels.Insert( pPanel );
|
||||
}
|
||||
|
||||
void CKV_Fit_Children_Panel::RemoveAutoPositionPanel( CKV_Editor_Base_Panel *pPanel )
|
||||
{
|
||||
m_AutoPositionPanels.Remove( pPanel );
|
||||
}
|
||||
|
||||
void CKV_Fit_Children_Panel::ClearAutoPositionPanels()
|
||||
{
|
||||
m_AutoPositionPanels.RemoveAll();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef _INCLUDED_KV_FIT_CHILDREN_PANEL_H
|
||||
#define _INCLUDED_KV_FIT_CHILDREN_PANEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "kv_editor_base_panel.h"
|
||||
|
||||
class FitChildrenLessFunc
|
||||
{
|
||||
public:
|
||||
bool Less( CKV_Editor_Base_Panel* const &pRoomTemplateLHS, CKV_Editor_Base_Panel* const &pRoomTemplateRHS, void *pCtx );
|
||||
};
|
||||
|
||||
// a vgui panel that resizes to fit designated children, with some border
|
||||
class CKV_Fit_Children_Panel : public CKV_Editor_Base_Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CKV_Fit_Children_Panel, CKV_Editor_Base_Panel );
|
||||
|
||||
public:
|
||||
CKV_Fit_Children_Panel( Panel *parent, const char *name);
|
||||
|
||||
virtual void PerformLayout();
|
||||
|
||||
void AddAutoPositionPanel( CKV_Editor_Base_Panel *pPanel );
|
||||
void RemoveAutoPositionPanel( CKV_Editor_Base_Panel *pPanel );
|
||||
void ClearAutoPositionPanels();
|
||||
|
||||
bool IsNodePanel( vgui::Panel *pPanel );
|
||||
|
||||
// list of panels we should position in a list inside us
|
||||
CUtlSortVector<CKV_Editor_Base_Panel*, FitChildrenLessFunc> m_AutoPositionPanels;
|
||||
|
||||
int m_iAutoPositionStartY;
|
||||
CPanelAnimationVarAliasType( int, m_iBorder, "border", "5", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iSpacing, "spacing", "1", "proportional_int" );
|
||||
};
|
||||
|
||||
|
||||
#endif // _INCLUDED_KV_FIT_CHILDREN_PANEL_H
|
||||
@@ -0,0 +1,124 @@
|
||||
#include "kv_leaf_panel.h"
|
||||
#include <vgui_controls/TextEntry.h>
|
||||
#include <vgui_controls/Button.h>
|
||||
#include "KeyValues.h"
|
||||
#include "kv_editor.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
DECLARE_BUILD_FACTORY( CKV_Leaf_Panel )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CKV_Leaf_Panel::CKV_Leaf_Panel( Panel *parent, const char *name ) : BaseClass( parent, name )
|
||||
{
|
||||
m_pLabel = new vgui::Label( this, "Label", "" );
|
||||
m_pLabel->SetMouseInputEnabled( false );
|
||||
m_pTextEntry = new vgui::TextEntry( this, "TextEntry" );
|
||||
m_pTextEntry->SetAutoLocalize( false );
|
||||
m_pDeleteButton = new vgui::Button( this, "DeleteButton", "X", this, "Delete" );
|
||||
}
|
||||
|
||||
void CKV_Leaf_Panel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
m_pLabel->SetBounds( 0, 0, 100, 20 );
|
||||
m_pLabel->SizeToContents();
|
||||
m_pLabel->InvalidateLayout( true );
|
||||
int iLabelSpace = MAX( m_pLabel->GetWide() + 5, 100 );
|
||||
|
||||
int iExtraHeight = 0;
|
||||
int iTextEntryX = iLabelSpace;
|
||||
|
||||
if ( m_pFileSpecNode && m_pFileSpecNode->FindKey( "TextEntryNewLine" ) )
|
||||
{
|
||||
iExtraHeight = m_pLabel->GetTall();
|
||||
iTextEntryX = 0;
|
||||
}
|
||||
|
||||
if ( m_pFileSpecNode && m_pFileSpecNode->FindKey( "Tall" ) )
|
||||
{
|
||||
m_pTextEntry->SetBounds( iTextEntryX, iExtraHeight, 390 - iTextEntryX, m_pFileSpecNode->GetInt( "Tall" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pTextEntry->SetBounds( iTextEntryX, iExtraHeight, 390 - iTextEntryX, 20 );
|
||||
}
|
||||
|
||||
SetSize( 420, m_pTextEntry->GetTall() + iExtraHeight );
|
||||
|
||||
int iDeleteWidth = 20;
|
||||
m_pDeleteButton->SetBounds( GetWide() - (iDeleteWidth + 5), 2, iDeleteWidth, 16 );
|
||||
}
|
||||
|
||||
void CKV_Leaf_Panel::ApplySchemeSettings(vgui::IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
m_pLabel->SetPaintBackgroundEnabled( false );
|
||||
SetPaintBackgroundEnabled( false );
|
||||
|
||||
m_pDeleteButton->SetVisible( m_bAllowDeletion );
|
||||
}
|
||||
|
||||
void CKV_Leaf_Panel::UpdatePanel()
|
||||
{
|
||||
if ( m_pFileSpecNode )
|
||||
{
|
||||
m_pDeleteButton->SetVisible( !!m_pFileSpecNode->FindKey( "Deletable" ) );
|
||||
}
|
||||
if ( !m_pKey )
|
||||
{
|
||||
m_pLabel->SetText( "INVALID KEY" );
|
||||
m_pTextEntry->SetText( "INVALID KEY" );
|
||||
return;
|
||||
}
|
||||
if ( m_pFileSpecNode && m_pFileSpecNode->FindKey( "FriendlyName" ) )
|
||||
{
|
||||
m_pLabel->SetText( m_pFileSpecNode->GetString( "FriendlyName" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLabel->SetText( m_pKey->GetName() );
|
||||
}
|
||||
m_pTextEntry->SetText( m_pKey->GetString() );
|
||||
if ( m_pFileSpecNode->GetInt( "ReadOnly", 0 ) == 1 )
|
||||
{
|
||||
m_pTextEntry->SetEditable( false );
|
||||
m_pTextEntry->SetEnabled( false );
|
||||
}
|
||||
}
|
||||
|
||||
// update our key when the text entry changes
|
||||
void CKV_Leaf_Panel::TextEntryChanged( vgui::Panel* pTextEntry )
|
||||
{
|
||||
if ( pTextEntry != m_pTextEntry )
|
||||
return;
|
||||
|
||||
if ( !m_pKey )
|
||||
{
|
||||
return;
|
||||
}
|
||||
char buf[ 2048 ];
|
||||
m_pTextEntry->GetText( buf, 2048 );
|
||||
|
||||
m_pKey->SetStringValue( buf );
|
||||
|
||||
PostActionSignal( new KeyValues( "command", "command", "KeyValuesChanged" ) );
|
||||
}
|
||||
|
||||
void CKV_Leaf_Panel::OnCommand( const char *command )
|
||||
{
|
||||
if ( !Q_stricmp( command, "Delete" ) && m_pKeyParent && m_bAllowDeletion )
|
||||
{
|
||||
m_pKeyParent->RemoveSubKey( m_pKey );
|
||||
m_pKey->deleteThis();
|
||||
m_pEditor->OnKeyDeleted();
|
||||
return;
|
||||
}
|
||||
BaseClass::OnCommand( command );
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef _INCLUDED_KV_LEAF_PANEL_H
|
||||
#define _INCLUDED_KV_LEAF_PANEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "kv_editor_base_panel.h"
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class TextEntry;
|
||||
class Label;
|
||||
};
|
||||
|
||||
// a vgui panel for showing a generic leaf
|
||||
class CKV_Leaf_Panel : public CKV_Editor_Base_Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CKV_Leaf_Panel, CKV_Editor_Base_Panel );
|
||||
|
||||
public:
|
||||
CKV_Leaf_Panel( Panel *parent, const char *name);
|
||||
|
||||
virtual void PerformLayout();
|
||||
virtual void UpdatePanel();
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
||||
virtual void OnCommand( const char *command );
|
||||
|
||||
MESSAGE_FUNC_PTR( TextEntryChanged, "TextChanged", panel );
|
||||
vgui::TextEntry *m_pTextEntry;
|
||||
vgui::Label *m_pLabel;
|
||||
vgui::Button* m_pDeleteButton;
|
||||
};
|
||||
|
||||
|
||||
#endif // _INCLUDED_KV_LEAF_PANEL_H
|
||||
@@ -0,0 +1,167 @@
|
||||
#include "kv_node_panel.h"
|
||||
#include <vgui_controls/Label.h>
|
||||
#include <vgui_controls/Button.h>
|
||||
#include "kv_editor.h"
|
||||
#include "KeyValues.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
DECLARE_BUILD_FACTORY( CKV_Node_Panel )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CKV_Node_Panel::CKV_Node_Panel( Panel *parent, const char *name ) :
|
||||
BaseClass( parent, name ),
|
||||
m_iLabelInsetX( 2 ),
|
||||
m_iLabelInsetY( 2 )
|
||||
{
|
||||
m_pLabel = new vgui::Label( this, "Label", "" );
|
||||
m_pLabel->SetMouseInputEnabled( false );
|
||||
|
||||
m_pDeleteButton = new vgui::Button( this, "DeleteButton", "X", this, "Delete" );
|
||||
SetKeyBoardInputEnabled( false );
|
||||
|
||||
m_iAutoPositionStartY = 30;
|
||||
}
|
||||
|
||||
void CKV_Node_Panel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
if ( m_pFileSpecNode )
|
||||
{
|
||||
m_iLabelInsetX = m_pFileSpecNode->GetInt( "LabelInsetX", m_iLabelInsetX );
|
||||
m_iLabelInsetY = m_pFileSpecNode->GetInt( "LabelInsetY", m_iLabelInsetY );
|
||||
}
|
||||
|
||||
m_pLabel->SetBounds( m_iLabelInsetX * 2, m_iLabelInsetY, 300, 16 );
|
||||
|
||||
int iDeleteWidth = 20;
|
||||
m_pDeleteButton->SetBounds( GetWide() - (iDeleteWidth + 5), m_iLabelInsetY, iDeleteWidth, 16 );
|
||||
|
||||
int wide = GetWide();
|
||||
int cursor_y = GetTall();
|
||||
|
||||
cursor_y -= m_iSpacing;
|
||||
for ( int i = 0; i < m_pAddButtons.Count(); i++ )
|
||||
{
|
||||
vgui::Button *pPanel = m_pAddButtons[i];
|
||||
|
||||
if ( pPanel )
|
||||
{
|
||||
pPanel->SetPos( m_iBorder, cursor_y );
|
||||
pPanel->SetSize( 300, 25 );
|
||||
pPanel->InvalidateLayout( true );
|
||||
int x, y;
|
||||
pPanel->GetPos( x, y );
|
||||
x += pPanel->GetWide();
|
||||
y += pPanel->GetTall();
|
||||
cursor_y += pPanel->GetTall() + m_iSpacing;
|
||||
wide = MAX( wide, x );
|
||||
}
|
||||
}
|
||||
|
||||
cursor_y += m_iSpacing * 2;
|
||||
SetSize( wide, cursor_y );
|
||||
}
|
||||
|
||||
void CKV_Node_Panel::ApplySchemeSettings(vgui::IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
m_pLabel->SetPaintBackgroundEnabled( false );
|
||||
|
||||
m_pDeleteButton->SetVisible( m_bAllowDeletion );
|
||||
}
|
||||
|
||||
void CKV_Node_Panel::UpdatePanel()
|
||||
{
|
||||
if ( m_pFileSpecNode )
|
||||
{
|
||||
m_pDeleteButton->SetVisible( !m_pFileSpecNode->FindKey( "Autocreate" ) );
|
||||
}
|
||||
// clear out add buttons
|
||||
for ( int i = 0; i < m_pAddButtons.Count(); i++ )
|
||||
{
|
||||
m_pAddButtons[i]->SetVisible( false );
|
||||
m_pAddButtons[i]->MarkForDeletion();
|
||||
}
|
||||
m_pAddButtons.Purge();
|
||||
|
||||
if ( !m_pKey )
|
||||
{
|
||||
m_pLabel->SetText( "INVALID KEY" );
|
||||
return;
|
||||
}
|
||||
if ( m_pFileSpecNode && m_pFileSpecNode->FindKey( "FriendlyName" ) )
|
||||
{
|
||||
m_pLabel->SetText( m_pFileSpecNode->GetString( "FriendlyName" ) );
|
||||
m_pLabel->SetVisible( Q_strlen( m_pFileSpecNode->GetString( "FriendlyName" ) ) > 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLabel->SetText( m_pKey->GetName() );
|
||||
}
|
||||
|
||||
// add add buttons
|
||||
if ( m_pFileSpecNode )
|
||||
{
|
||||
// go through all _Node or _Leaf children of our filespec node
|
||||
for ( KeyValues *pSubKey = m_pFileSpecNode->GetFirstSubKey(); pSubKey; pSubKey = pSubKey->GetNextKey() )
|
||||
{
|
||||
if ( Q_stricmp( pSubKey->GetName(), "_Node" ) && Q_stricmp( pSubKey->GetName(), "_Leaf" ) )
|
||||
continue;
|
||||
|
||||
// If it's unique, then see if we already have one in our m_pKey.
|
||||
bool bMakeButton = true;
|
||||
if ( pSubKey->FindKey( "Unique" ) )
|
||||
{
|
||||
for ( KeyValues *pKeyChild = m_pKey->GetFirstSubKey(); pKeyChild; pKeyChild = pKeyChild->GetNextKey() )
|
||||
{
|
||||
if ( !Q_stricmp( pKeyChild->GetName(), pSubKey->GetString( "Name" ) ) )
|
||||
{
|
||||
bMakeButton = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( bMakeButton )
|
||||
{
|
||||
char buffer[256];
|
||||
if ( m_pFileSpecNode && pSubKey->FindKey( "FriendlyAddButtonText" ) )
|
||||
{
|
||||
Q_snprintf( buffer, sizeof( buffer ), "%s", pSubKey->GetString( "FriendlyAddButtonText", "ADD BUTTON ERROR" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( buffer, sizeof( buffer ), "Add %s", pSubKey->GetString( "FriendlyName", pSubKey->GetString( "Name", "Unknown key" ) ) );
|
||||
}
|
||||
vgui::Button *pAdd = new vgui::Button( this, "AddButton", buffer, this );
|
||||
pAdd->SetCommand( new KeyValues( "AddButtonPressed", "szKeyName", pSubKey->GetString( "Name", "Unknown key" ) ) );
|
||||
m_pAddButtons.AddToTail( pAdd );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CKV_Node_Panel::OnCommand( const char *command )
|
||||
{
|
||||
if ( !Q_stricmp( command, "Delete" ) && m_pKeyParent && m_bAllowDeletion )
|
||||
{
|
||||
m_pKeyParent->RemoveSubKey( m_pKey );
|
||||
m_pKey->deleteThis();
|
||||
m_pEditor->OnKeyDeleted();
|
||||
return;
|
||||
}
|
||||
BaseClass::OnCommand( command );
|
||||
}
|
||||
|
||||
void CKV_Node_Panel::OnAddButtonPressed( const char *szKeyName )
|
||||
{
|
||||
// Add new subkey of name matching button
|
||||
m_pEditor->AddToKey( m_pFileSpecNode, m_pKey, szKeyName );
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef _INCLUDED_KV_NODE_PANEL_H
|
||||
#define _INCLUDED_KV_NODE_PANEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "kv_fit_children_panel.h"
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class Label;
|
||||
class Button;
|
||||
};
|
||||
|
||||
// a vgui panel for showing a generic leaf
|
||||
class CKV_Node_Panel : public CKV_Fit_Children_Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CKV_Node_Panel, CKV_Fit_Children_Panel );
|
||||
|
||||
public:
|
||||
CKV_Node_Panel( Panel *parent, const char *name);
|
||||
|
||||
virtual void PerformLayout();
|
||||
virtual void UpdatePanel();
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
||||
virtual void OnCommand( const char *command );
|
||||
|
||||
vgui::Label *m_pLabel;
|
||||
|
||||
vgui::Button* m_pDeleteButton;
|
||||
CUtlVector<vgui::Button*> m_pAddButtons;
|
||||
|
||||
MESSAGE_FUNC_CHARPTR( OnAddButtonPressed, "AddButtonPressed", szKeyName );
|
||||
|
||||
CPanelAnimationVarAliasType( int, m_iLabelInsetX, "LabelInsetX", "2", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iLabelInsetY, "LabelInsetY", "2", "proportional_int" );
|
||||
};
|
||||
|
||||
|
||||
#endif // _INCLUDED_KV_NODE_PANEL_H
|
||||
Reference in New Issue
Block a user