mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-07 17:29:36 +00:00
1
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,59 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeBasePickerPanel.h"
|
||||
#include "filesystem.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "vgui_controls/FileOpenDialog.h"
|
||||
#include "dme_controls/AttributeTextEntry.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAttributeBasePickerPanel::CAttributeBasePickerPanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
m_pOpen = new vgui::Button( this, "Open", "...", this, "open" );
|
||||
}
|
||||
|
||||
void CAttributeBasePickerPanel::OnCommand( char const *cmd )
|
||||
{
|
||||
if ( !Q_stricmp( cmd, "open" ) )
|
||||
{
|
||||
ShowPickerDialog();
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnCommand( cmd );
|
||||
}
|
||||
}
|
||||
|
||||
void CAttributeBasePickerPanel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
int x, y, w, h;
|
||||
m_pType->GetBounds( x, y, w, h );
|
||||
|
||||
int inset = 25;
|
||||
m_pType->SetWide( w - inset );
|
||||
|
||||
x += w;
|
||||
x -= inset;
|
||||
|
||||
h -= 2;
|
||||
|
||||
m_pOpen->SetBounds( x, y, inset, h );
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeBoolChoicePanel.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "movieobjects/dmeeditortypedictionary.h"
|
||||
#include "datamodel/dmelementfactoryhelper.h"
|
||||
#include "dme_controls/inotifyui.h"
|
||||
#include "dme_controls/dmecontrols.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Expose DmeEditorAttributeInfo to the scene database
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_ELEMENT_FACTORY( DmeEditorBoolChoicesInfo, CDmeEditorBoolChoicesInfo );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeEditorBoolChoicesInfo::OnConstruction()
|
||||
{
|
||||
// Add a true + false method, default
|
||||
CreateChoice( "false" );
|
||||
CreateChoice( "true" );
|
||||
}
|
||||
|
||||
void CDmeEditorBoolChoicesInfo::OnDestruction()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Add a choice
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeEditorBoolChoicesInfo::SetFalseChoice( const char *pChoiceString )
|
||||
{
|
||||
m_Choices[0]->SetValue<CUtlString>( "string", pChoiceString );
|
||||
}
|
||||
|
||||
void CDmeEditorBoolChoicesInfo::SetTrueChoice( const char *pChoiceString )
|
||||
{
|
||||
m_Choices[1]->SetValue<CUtlString>( "string", pChoiceString );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the choices
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CDmeEditorBoolChoicesInfo::GetFalseChoiceString( ) const
|
||||
{
|
||||
return GetChoiceString( 0 );
|
||||
}
|
||||
|
||||
const char *CDmeEditorBoolChoicesInfo::GetTrueChoiceString( ) const
|
||||
{
|
||||
return GetChoiceString( 1 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CAttributeBoolChoicePanel::CAttributeBoolChoicePanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Derived classes can re-implement this to fill the combo box however they like
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeBoolChoicePanel::PopulateComboBox( vgui::ComboBox *pComboBox )
|
||||
{
|
||||
pComboBox->DeleteAllItems();
|
||||
|
||||
CDmeEditorBoolChoicesInfo *pInfo = CastElement<CDmeEditorBoolChoicesInfo>( GetEditorInfo() );
|
||||
if ( !pInfo )
|
||||
return;
|
||||
|
||||
// Fill in the choices
|
||||
const char *pFalseChoice = pInfo->GetFalseChoiceString( );
|
||||
const char *pTrueChoice = pInfo->GetTrueChoiceString( );
|
||||
|
||||
// Add the dynamic choices next
|
||||
if ( pInfo->HasChoiceType() )
|
||||
{
|
||||
const char *choices[2];
|
||||
if ( ElementPropertiesChoices()->GetBoolChoiceList( pInfo->GetChoiceType(), GetPanelElement(), GetAttributeName(), IsArrayEntry(), choices ) )
|
||||
{
|
||||
pFalseChoice = choices[0];
|
||||
pTrueChoice = choices[1];
|
||||
}
|
||||
}
|
||||
|
||||
KeyValues *kv = new KeyValues( "entry" );
|
||||
kv->SetInt( "value", false );
|
||||
pComboBox->AddItem( pFalseChoice, kv );
|
||||
|
||||
kv = new KeyValues( "entry" );
|
||||
kv->SetInt( "value", true );
|
||||
pComboBox->AddItem( pTrueChoice, kv );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the attribute based on the combo box
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeBoolChoicePanel::SetAttributeFromComboBox( vgui::ComboBox *pComboBox, KeyValues *pKeyValues )
|
||||
{
|
||||
bool bOldValue = GetAttributeValue<bool>();
|
||||
bool bValue = pKeyValues->GetInt( "value", 0 ) != 0;
|
||||
if ( bOldValue == bValue )
|
||||
return;
|
||||
|
||||
CUndoScopeGuard guard( NOTIFY_SOURCE_PROPERTIES_TREE, NOTIFY_SETDIRTYFLAG, "Set Attribute Value", "Set Attribute Value" );
|
||||
SetAttributeValue( bValue );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the combo box from the attribute
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeBoolChoicePanel::SetComboBoxFromAttribute( vgui::ComboBox *pComboBox )
|
||||
{
|
||||
CDmeEditorBoolChoicesInfo *pInfo = CastElement<CDmeEditorBoolChoicesInfo>( GetEditorInfo() );
|
||||
if ( !pInfo )
|
||||
return;
|
||||
|
||||
bool bValue = GetAttributeValue<bool>();
|
||||
|
||||
// Check the dynamic choices next
|
||||
if ( pInfo->HasChoiceType() )
|
||||
{
|
||||
const char *choices[2];
|
||||
if ( ElementPropertiesChoices()->GetBoolChoiceList( pInfo->GetChoiceType(), GetPanelElement(), GetAttributeName(), IsArrayEntry(), choices ) )
|
||||
{
|
||||
pComboBox->SetText( choices[ bValue ] );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pComboBox->SetText( pInfo->GetChoiceString( bValue ) );
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeColorPickerPanel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "dme_controls/AttributeTextEntry.h"
|
||||
#include "matsys_controls/colorpickerpanel.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "dme_controls/inotifyui.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAttributeColorPickerPanel::CAttributeColorPickerPanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
m_pOpen = new vgui::Button( this, "Open", "", this, "open" );
|
||||
}
|
||||
|
||||
void CAttributeColorPickerPanel::OnCommand( char const *cmd )
|
||||
{
|
||||
if ( !Q_stricmp( cmd, "open" ) )
|
||||
{
|
||||
m_InitialColor = GetAttributeValue<Color>();
|
||||
CColorPickerFrame *pColorPickerDialog = new CColorPickerFrame( this, "Select Color" );
|
||||
pColorPickerDialog->AddActionSignalTarget( this );
|
||||
pColorPickerDialog->DoModal( m_InitialColor );
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnCommand( cmd );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Update button color
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeColorPickerPanel::UpdateButtonColor()
|
||||
{
|
||||
Color clr = GetAttributeValue<Color>();
|
||||
m_pOpen->SetDefaultColor( clr, clr );
|
||||
m_pOpen->SetArmedColor( clr, clr );
|
||||
m_pOpen->SetDepressedColor( clr, clr );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Used to set the current color on the picker button
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeColorPickerPanel::Refresh()
|
||||
{
|
||||
BaseClass::Refresh();
|
||||
UpdateButtonColor();
|
||||
}
|
||||
|
||||
void CAttributeColorPickerPanel::ApplySchemeSettings(IScheme *pScheme)
|
||||
{
|
||||
// Need to override the scheme settings for this button
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
UpdateButtonColor();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the picker gets a new color but apply hasn't happened yet
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeColorPickerPanel::OnPreview( KeyValues *data )
|
||||
{
|
||||
{
|
||||
CDisableUndoScopeGuard guard;
|
||||
Color c = data->GetColor( "color" );
|
||||
SetAttributeValue( c );
|
||||
}
|
||||
|
||||
Refresh( );
|
||||
if ( IsAutoApply() )
|
||||
{
|
||||
// NOTE: Don't call Apply since that generates an undo record
|
||||
CElementTreeNotifyScopeGuard guard( "CAttributeColorPickerPanel::OnPreview", NOTIFY_CHANGE_ATTRIBUTE_VALUE, GetNotify() );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDirty( true );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when cancel is hit in the picker
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeColorPickerPanel::OnCancelled( )
|
||||
{
|
||||
// Restore the initial color
|
||||
CDisableUndoScopeGuard guard;
|
||||
SetAttributeValue( m_InitialColor );
|
||||
Refresh( );
|
||||
CElementTreeNotifyScopeGuard notify( "CAttributeColorPickerPanel::OnCancelled", NOTIFY_CHANGE_ATTRIBUTE_VALUE, GetNotify() );
|
||||
SetDirty( false );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the picker gets a new color
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeColorPickerPanel::OnPicked( KeyValues *data )
|
||||
{
|
||||
Color c = data->GetColor( "color" );
|
||||
if ( c == m_InitialColor )
|
||||
{
|
||||
SetDirty( false );
|
||||
return;
|
||||
}
|
||||
|
||||
// Kind of an evil hack, but "undo" copies the "old value" off for doing undo, and that value is the new value because
|
||||
// we haven't been tracking undo while manipulating this. So we'll turn off undo and set the value to the original value.
|
||||
|
||||
// In effect, all of the wheeling will drop out and it'll look just like we started at the original value and ended up at the
|
||||
// final value...
|
||||
{
|
||||
CDisableUndoScopeGuard guard;
|
||||
SetAttributeValue( m_InitialColor );
|
||||
}
|
||||
|
||||
{
|
||||
CElementTreeUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, GetNotify(), "Set Attribute Value", "Set Attribute Value" );
|
||||
SetAttributeValue( c );
|
||||
}
|
||||
|
||||
if ( IsAutoApply() )
|
||||
{
|
||||
Refresh();
|
||||
SetDirty( false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Lays out the button position
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeColorPickerPanel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
int x, y, w, h;
|
||||
m_pType->GetBounds( x, y, w, h );
|
||||
|
||||
int inset = 25;
|
||||
m_pType->SetWide( w - inset );
|
||||
|
||||
x += w;
|
||||
x -= inset;
|
||||
|
||||
h -= 2;
|
||||
|
||||
m_pOpen->SetBounds( x, y, inset, h );
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeElementPanel.h"
|
||||
#include "dme_controls/AttributeTextEntry.h"
|
||||
#include "dme_controls/AttributeWidgetFactory.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "movieobjects/dmeeditortypedictionary.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
CAttributeElementPanel::CAttributeElementPanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info ), m_pData( 0 )
|
||||
{
|
||||
m_pData = new CAttributeTextEntry( this, "AttributeValue" );
|
||||
m_pData->SetEnabled( !HasFlag( READONLY ) );
|
||||
m_pData->AddActionSignalTarget(this);
|
||||
m_pType->SetText( "element" );
|
||||
|
||||
m_bShowMemoryUsage = info.m_bShowMemoryUsage;
|
||||
}
|
||||
|
||||
void CAttributeElementPanel::Apply()
|
||||
{
|
||||
// FIXME: Implement when needed
|
||||
Assert( 0 );
|
||||
}
|
||||
|
||||
vgui::Panel *CAttributeElementPanel::GetDataPanel()
|
||||
{
|
||||
return static_cast< vgui::Panel * >( m_pData );
|
||||
}
|
||||
|
||||
void CAttributeElementPanel::OnCreateDragData( KeyValues *msg )
|
||||
{
|
||||
if ( GetPanelElement() )
|
||||
{
|
||||
char txt[ 256 ];
|
||||
m_pData->GetText( txt, sizeof( txt ) );
|
||||
|
||||
msg->SetString( "text", txt );
|
||||
CDmElement *element = NULL;
|
||||
if ( GetPanelElement()->HasAttribute( GetAttributeName() ) )
|
||||
{
|
||||
element = GetElement<CDmElement>( GetAttributeValue<DmElementHandle_t>( ) );
|
||||
msg->SetInt( "dmeelement", element->GetHandle() );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void CAttributeElementPanel::Refresh()
|
||||
{
|
||||
char elemText[ 512 ];
|
||||
elemText[0] = 0;
|
||||
|
||||
CDmElement *element = NULL;
|
||||
if ( !GetEditorInfo() || !GetEditorInfo()->GetValue<bool>( "hideText" ) )
|
||||
{
|
||||
if ( HasAttribute( ) )
|
||||
{
|
||||
element = GetAttributeValueElement( );
|
||||
}
|
||||
else
|
||||
{
|
||||
element = GetPanelElement();
|
||||
}
|
||||
}
|
||||
|
||||
if ( element )
|
||||
{
|
||||
char idstr[ 37 ];
|
||||
UniqueIdToString( element->GetId(), idstr, sizeof( idstr ) );
|
||||
if ( m_bShowMemoryUsage )
|
||||
{
|
||||
Q_snprintf( elemText, sizeof( elemText ), "%s %s %.3fMB", element->GetTypeString(), idstr, element->EstimateMemoryUsage() / float( 1 << 20 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( elemText, sizeof( elemText ), "%s %s", element->GetTypeString(), idstr );
|
||||
}
|
||||
}
|
||||
|
||||
m_pData->SetText( elemText );
|
||||
m_pData->SetEnabled(false);
|
||||
}
|
||||
|
||||
void CAttributeElementPanel::PostConstructor()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,174 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeElementPickerPanel.h"
|
||||
#include "dme_controls/AttributeTextEntry.h"
|
||||
#include "dme_controls/AttributeWidgetFactory.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "dme_controls/dmepicker.h"
|
||||
#include "movieobjects/dmeeditortypedictionary.h"
|
||||
#include "dme_controls/inotifyui.h"
|
||||
#include "dme_controls/dmecontrols.h"
|
||||
#include "dme_controls/dmecontrols_utils.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
CAttributeElementPickerPanel::CAttributeElementPickerPanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
m_hEdit = new vgui::Button( this, "Open", "...", this, "open" );
|
||||
|
||||
m_pData = new CAttributeTextEntry( this, "AttributeValue" );
|
||||
m_pData->SetEnabled( !HasFlag( READONLY ) );
|
||||
m_pData->AddActionSignalTarget(this);
|
||||
m_pType->SetText( "element" );
|
||||
|
||||
m_bShowMemoryUsage = info.m_bShowMemoryUsage;
|
||||
}
|
||||
|
||||
void CAttributeElementPickerPanel::PostConstructor()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
vgui::Panel *CAttributeElementPickerPanel::GetDataPanel()
|
||||
{
|
||||
return static_cast< vgui::Panel * >( m_pData );
|
||||
}
|
||||
|
||||
void CAttributeElementPickerPanel::Apply()
|
||||
{
|
||||
// FIXME: Implement when needed
|
||||
Assert( 0 );
|
||||
}
|
||||
|
||||
void CAttributeElementPickerPanel::Refresh()
|
||||
{
|
||||
char elemText[ 512 ];
|
||||
elemText[0] = 0;
|
||||
|
||||
CDmElement *element = NULL;
|
||||
if ( !GetEditorInfo() || !GetEditorInfo()->GetValue<bool>( "hideText" ) )
|
||||
{
|
||||
if ( HasAttribute( ) )
|
||||
{
|
||||
element = GetAttributeValueElement( );
|
||||
}
|
||||
else
|
||||
{
|
||||
element = GetPanelElement();
|
||||
}
|
||||
}
|
||||
|
||||
if ( element )
|
||||
{
|
||||
char idstr[ 37 ];
|
||||
UniqueIdToString( element->GetId(), idstr, sizeof( idstr ) );
|
||||
if ( m_bShowMemoryUsage )
|
||||
{
|
||||
Q_snprintf( elemText, sizeof( elemText ), "%s %s %.3fMB", element->GetTypeString(), idstr, element->EstimateMemoryUsage() / float( 1 << 20 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( elemText, sizeof( elemText ), "%s %s", element->GetTypeString(), idstr );
|
||||
}
|
||||
}
|
||||
|
||||
m_pData->SetText( elemText );
|
||||
m_pData->SetEditable( false );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it's time to show the Dme picker
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeElementPickerPanel::ShowPickerDialog()
|
||||
{
|
||||
CDmeEditorChoicesInfo *pInfo = CastElement<CDmeEditorChoicesInfo>( GetEditorInfo() );
|
||||
if ( !pInfo )
|
||||
return;
|
||||
|
||||
// FIXME: Sucky. Should we make GetElementChoiceList return a DmeHandleVec_t?
|
||||
ElementChoiceList_t choices;
|
||||
CUtlVector< DmePickerInfo_t > vec;
|
||||
if ( ElementPropertiesChoices()->GetElementChoiceList( pInfo->GetChoiceType(), GetPanelElement(), GetAttributeName(), IsArrayEntry(), choices ) )
|
||||
{
|
||||
int c = choices.Count();
|
||||
vec.EnsureCapacity( c );
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
int j = vec.AddToTail( );
|
||||
vec[j].m_hElement = choices[i].m_pValue->GetHandle();
|
||||
vec[j].m_pChoiceString = choices[i].m_pChoiceString;
|
||||
}
|
||||
}
|
||||
|
||||
CDmePickerFrame *pDmePickerDialog = new CDmePickerFrame( this, "Select DME Element" );
|
||||
pDmePickerDialog->AddActionSignalTarget( this );
|
||||
pDmePickerDialog->DoModal( vec );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called by the dme picker dialog if a dme was selected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeElementPickerPanel::OnDmeSelected( KeyValues *pKeyValues )
|
||||
{
|
||||
// We're either going to get an activity or sequence name
|
||||
CDmElement *pElement = GetElementKeyValue< CDmElement >( pKeyValues, "dme" );
|
||||
SetAttributeValueElement( pElement );
|
||||
Refresh( );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handle commands
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeElementPickerPanel::OnCommand( char const *cmd )
|
||||
{
|
||||
if ( !Q_stricmp( cmd, "open" ) )
|
||||
{
|
||||
ShowPickerDialog();
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnCommand( cmd );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Lay out the panel
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeElementPickerPanel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
int x, y, w, h;
|
||||
m_pType->GetBounds( x, y, w, h );
|
||||
|
||||
int inset = 25;
|
||||
m_pType->SetWide( w - inset );
|
||||
|
||||
x += w;
|
||||
x -= inset;
|
||||
|
||||
h -= 2;
|
||||
|
||||
m_hEdit->SetBounds( x, y, inset, h );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeFilePickerPanel.h"
|
||||
#include "filesystem.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "vgui_controls/FileOpenDialog.h"
|
||||
#include "dme_controls/AttributeTextEntry.h"
|
||||
#include "vgui/IInput.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Various file picker types
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_ATTRIBUTE_FILE_PICKER( CAttributeTgaFilePickerPanel, "Choose TGA file", "TGA", "tga" );
|
||||
IMPLEMENT_ATTRIBUTE_FILE_PICKER( CAttributeDmeFilePickerPanel, "Choose DmE .xml file", "DmE XML", "xml" );
|
||||
IMPLEMENT_ATTRIBUTE_FILE_PICKER( CAttributeAviFilePickerPanel, "Choose AVI file", "AVI", "avi" );
|
||||
IMPLEMENT_ATTRIBUTE_FILE_PICKER( CAttributeShtFilePickerPanel, "Choose Sheet file", "SHT", "sht" );
|
||||
IMPLEMENT_ATTRIBUTE_FILE_PICKER( CAttributeRawFilePickerPanel, "Choose RAW file", "RAW", "raw" );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAttributeFilePickerPanel::CAttributeFilePickerPanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
}
|
||||
|
||||
CAttributeFilePickerPanel::~CAttributeFilePickerPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shows the picker dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeFilePickerPanel::ShowPickerDialog()
|
||||
{
|
||||
FileOpenDialog *pFileOpenDialog = new FileOpenDialog( this, "Choose file", true );
|
||||
SetupFileOpenDialog( pFileOpenDialog );
|
||||
pFileOpenDialog->AddActionSignalTarget( this );
|
||||
pFileOpenDialog->SetDeleteSelfOnClose( true );
|
||||
pFileOpenDialog->DoModal( true );
|
||||
input()->SetAppModalSurface( pFileOpenDialog->GetVPanel() );
|
||||
}
|
||||
|
||||
void CAttributeFilePickerPanel::OnFileSelected( char const *fullpath )
|
||||
{
|
||||
if ( !fullpath || !fullpath[ 0 ] )
|
||||
return;
|
||||
|
||||
char relativepath[ 512 ];
|
||||
g_pFullFileSystem->FullPathToRelativePath( fullpath, relativepath, sizeof( relativepath ) );
|
||||
|
||||
// Apply to text panel
|
||||
m_pData->SetText( relativepath );
|
||||
SetDirty(true);
|
||||
if ( IsAutoApply() )
|
||||
{
|
||||
Apply();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeIntChoicePanel.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "movieobjects/dmeeditortypedictionary.h"
|
||||
#include "datamodel/dmelementfactoryhelper.h"
|
||||
#include "dme_controls/inotifyui.h"
|
||||
#include "dme_controls/dmecontrols.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Expose DmeEditorAttributeInfo to the scene database
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_ELEMENT_FACTORY( DmeEditorIntChoicesInfo, CDmeEditorIntChoicesInfo );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeEditorIntChoicesInfo::OnConstruction()
|
||||
{
|
||||
}
|
||||
|
||||
void CDmeEditorIntChoicesInfo::OnDestruction()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Add a choice
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeEditorIntChoicesInfo::AddChoice( int nValue, const char *pChoiceString )
|
||||
{
|
||||
CDmElement *pChoice = CreateChoice( pChoiceString );
|
||||
pChoice->SetValue( "value", nValue );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the choices
|
||||
//-----------------------------------------------------------------------------
|
||||
int CDmeEditorIntChoicesInfo::GetChoiceValue( int nIndex ) const
|
||||
{
|
||||
Assert( ( nIndex < GetChoiceCount() ) && ( nIndex >= 0 ) );
|
||||
CDmElement *pChoice = m_Choices[nIndex];
|
||||
if ( !pChoice )
|
||||
return 0;
|
||||
|
||||
return pChoice->GetValue<int>( "value" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CAttributeIntChoicePanel::CAttributeIntChoicePanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Derived classes can re-implement this to fill the combo box however they like
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeIntChoicePanel::PopulateComboBox( vgui::ComboBox *pComboBox )
|
||||
{
|
||||
pComboBox->DeleteAllItems();
|
||||
|
||||
CDmeEditorIntChoicesInfo *pInfo = CastElement<CDmeEditorIntChoicesInfo>( GetEditorInfo() );
|
||||
if ( !pInfo )
|
||||
return;
|
||||
|
||||
// Fill in the choices
|
||||
int c = pInfo->GetChoiceCount();
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
KeyValues *kv = new KeyValues( "entry" );
|
||||
kv->SetInt( "value", pInfo->GetChoiceValue( i ) );
|
||||
pComboBox->AddItem( pInfo->GetChoiceString( i ) , kv );
|
||||
}
|
||||
|
||||
// Add the dynamic choices next
|
||||
if ( pInfo->HasChoiceType() )
|
||||
{
|
||||
IntChoiceList_t choices;
|
||||
if ( ElementPropertiesChoices()->GetIntChoiceList( pInfo->GetChoiceType(), GetPanelElement(), GetAttributeName(), IsArrayEntry(), choices ) )
|
||||
{
|
||||
c = choices.Count();
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
KeyValues *kv = new KeyValues( "entry" );
|
||||
kv->SetInt( "value", choices[i].m_nValue );
|
||||
pComboBox->AddItem( choices[i].m_pChoiceString, kv );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the attribute based on the combo box
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeIntChoicePanel::SetAttributeFromComboBox( vgui::ComboBox *pComboBox, KeyValues *pKeyValues )
|
||||
{
|
||||
int nOldValue = GetAttributeValue<int>();
|
||||
int nValue = pKeyValues->GetInt( "value", 0 );
|
||||
if ( nOldValue == nValue )
|
||||
return;
|
||||
|
||||
CUndoScopeGuard guard( NOTIFY_SOURCE_PROPERTIES_TREE, NOTIFY_SETDIRTYFLAG, "Set Attribute Value", "Set Attribute Value" );
|
||||
SetAttributeValue( nValue );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the combo box from the attribute
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeIntChoicePanel::SetComboBoxFromAttribute( vgui::ComboBox *pComboBox )
|
||||
{
|
||||
CDmeEditorIntChoicesInfo *pInfo = CastElement<CDmeEditorIntChoicesInfo>( GetEditorInfo() );
|
||||
if ( !pInfo )
|
||||
return;
|
||||
|
||||
int nValue = GetAttributeValue<int>();
|
||||
int c = pInfo->GetChoiceCount();
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
if ( nValue == pInfo->GetChoiceValue( i ) )
|
||||
{
|
||||
pComboBox->SetText( pInfo->GetChoiceString( i ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the dynamic choices next
|
||||
if ( pInfo->HasChoiceType() )
|
||||
{
|
||||
IntChoiceList_t choices;
|
||||
if ( ElementPropertiesChoices()->GetIntChoiceList( pInfo->GetChoiceType(), GetPanelElement(), GetAttributeName(), IsArrayEntry(), choices ) )
|
||||
{
|
||||
c = choices.Count();
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
if ( nValue == choices[i].m_nValue )
|
||||
{
|
||||
pComboBox->SetText( choices[i].m_pChoiceString );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pComboBox->SetText( "Unknown value" );
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeInterpolatorChoicePanel.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "movieobjects/dmeeditortypedictionary.h"
|
||||
#include "datamodel/dmelementfactoryhelper.h"
|
||||
#include "dme_controls/inotifyui.h"
|
||||
#include "interpolatortypes.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CAttributeInterpolatorChoicePanel::CAttributeInterpolatorChoicePanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Derived classes can re-implement this to fill the combo box however they like
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeInterpolatorChoicePanel::PopulateComboBoxes( vgui::ComboBox *pComboBox[ 2 ] )
|
||||
{
|
||||
pComboBox[ 0 ]->DeleteAllItems();
|
||||
pComboBox[ 1 ]->DeleteAllItems();
|
||||
|
||||
// Fill in the choices
|
||||
int c = NUM_INTERPOLATE_TYPES;
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
KeyValues *kv = new KeyValues( "entry" );
|
||||
kv->SetInt( "value", i );
|
||||
pComboBox[ 0 ]->AddItem( Interpolator_NameForInterpolator( i, true ) , kv );
|
||||
|
||||
kv = new KeyValues( "entry" );
|
||||
kv->SetInt( "value", i );
|
||||
pComboBox[ 1 ]->AddItem( Interpolator_NameForInterpolator( i, true ) , kv );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the attribute based on the combo box
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeInterpolatorChoicePanel::SetAttributeFromComboBoxes( vgui::ComboBox *pComboBox[ 2 ], KeyValues *pKeyValues[ 2 ] )
|
||||
{
|
||||
int nOldValue = GetAttributeValue<int>();
|
||||
int nValueLeft = pKeyValues[ 0 ]->GetInt( "value", 0 );
|
||||
int nValueRight= pKeyValues[ 1 ]->GetInt( "value" , 0 );
|
||||
|
||||
int nValue = MAKE_CURVE_TYPE( nValueLeft, nValueRight );
|
||||
|
||||
// No change
|
||||
if ( nOldValue == nValue )
|
||||
return;
|
||||
|
||||
CElementTreeUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, GetNotify(), "Set Attribute Value", "Set Attribute Value" );
|
||||
SetAttributeValue( nValue );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the combo box from the attribute
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeInterpolatorChoicePanel::SetComboBoxesFromAttribute( vgui::ComboBox *pComboBox[ 2 ] )
|
||||
{
|
||||
int nValue = GetAttributeValue<int>();
|
||||
|
||||
// Decompose
|
||||
int leftPart = GET_LEFT_CURVE( nValue );
|
||||
int rightPart = GET_RIGHT_CURVE( nValue );
|
||||
|
||||
pComboBox[ 0 ]->SetText( Interpolator_NameForInterpolator( leftPart, true ) );
|
||||
pComboBox[ 1 ]->SetText( Interpolator_NameForInterpolator( rightPart, true ) );
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "dme_controls/AttributeMDLPickerPanel.h"
|
||||
#include "filesystem.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "vgui_controls/FileOpenDialog.h"
|
||||
#include "dme_controls/AttributeTextEntry.h"
|
||||
#include "matsys_controls/MDLPicker.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAttributeMDLPickerPanel::CAttributeMDLPickerPanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
}
|
||||
|
||||
CAttributeMDLPickerPanel::~CAttributeMDLPickerPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it's time to show the MDL picker
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeMDLPickerPanel::ShowPickerDialog()
|
||||
{
|
||||
// Open file
|
||||
CMDLPickerFrame *pMDLPickerDialog = new CMDLPickerFrame( this, "Select .MDL File" );
|
||||
pMDLPickerDialog->AddActionSignalTarget( this );
|
||||
pMDLPickerDialog->DoModal( );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it's time to show the MDL picker
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeMDLPickerPanel::OnMDLSelected( KeyValues *pKeyValues )
|
||||
{
|
||||
const char *pMDLName = pKeyValues->GetString( "mdl", NULL );
|
||||
if ( !pMDLName || !pMDLName[ 0 ] )
|
||||
return;
|
||||
|
||||
// Apply to text panel
|
||||
m_pData->SetText( pMDLName );
|
||||
SetDirty(true);
|
||||
if ( IsAutoApply() )
|
||||
{
|
||||
Apply();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "dme_controls/AttributeSequencePickerPanel.h"
|
||||
#include "filesystem.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "vgui_controls/FileOpenDialog.h"
|
||||
#include "dme_controls/AttributeTextEntry.h"
|
||||
#include "matsys_controls/MDLPicker.h"
|
||||
#include "matsys_controls/sequencepicker.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAttributeSequencePickerPanel::CAttributeSequencePickerPanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
}
|
||||
|
||||
CAttributeSequencePickerPanel::~CAttributeSequencePickerPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it's time to show the MDL picker
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeSequencePickerPanel::ShowPickerDialog()
|
||||
{
|
||||
CMDLPickerFrame *pMDLPickerDialog = new CMDLPickerFrame( this, "Select .MDL File" );
|
||||
pMDLPickerDialog->AddActionSignalTarget( this );
|
||||
pMDLPickerDialog->DoModal( );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it's time to show the MDL picker
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeSequencePickerPanel::OnMDLSelected( KeyValues *pKeyValues )
|
||||
{
|
||||
const char *pMDLName = pKeyValues->GetString( "asset", NULL );
|
||||
|
||||
char pRelativePath[MAX_PATH];
|
||||
Q_snprintf( pRelativePath, sizeof(pRelativePath), "models\\%s", pMDLName );
|
||||
ShowSequencePickerDialog( pRelativePath );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it's time to show the sequence picker
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeSequencePickerPanel::ShowSequencePickerDialog( const char *pMDLName )
|
||||
{
|
||||
if ( !pMDLName || !pMDLName[ 0 ] )
|
||||
return;
|
||||
|
||||
// Open file
|
||||
CSequencePicker::PickType_t pickType = CSequencePicker::PICK_ALL;
|
||||
const char *pTextType = GetTextType();
|
||||
if ( pTextType )
|
||||
{
|
||||
if ( !Q_stricmp( pTextType, "activityName" ) )
|
||||
{
|
||||
pickType = CSequencePicker::PICK_ACTIVITIES;
|
||||
}
|
||||
else if ( !Q_stricmp( pTextType, "sequenceName" ) )
|
||||
{
|
||||
pickType = CSequencePicker::PICK_SEQUENCES;
|
||||
}
|
||||
}
|
||||
|
||||
CSequencePickerFrame *pSequencePickerDialog = new CSequencePickerFrame( this, pickType );
|
||||
pSequencePickerDialog->AddActionSignalTarget( this );
|
||||
pSequencePickerDialog->DoModal( pMDLName );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it's time to show the MDL picker
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeSequencePickerPanel::OnSequenceSelected( KeyValues *pKeyValues )
|
||||
{
|
||||
// We're either going to get an activity or sequence name
|
||||
const char *pActivityName = pKeyValues->GetString( "activity", NULL );
|
||||
const char *pSequenceName = pKeyValues->GetString( "sequence", pActivityName );
|
||||
if ( !pSequenceName || !pSequenceName[ 0 ] )
|
||||
return;
|
||||
|
||||
// Apply to text panel
|
||||
m_pData->SetText( pSequenceName );
|
||||
SetDirty(true);
|
||||
if ( IsAutoApply() )
|
||||
{
|
||||
Apply();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeSoundPickerPanel.h"
|
||||
#include "dme_controls/soundpicker.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "dme_controls/AttributeTextEntry.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAttributeSoundPickerPanel::CAttributeSoundPickerPanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
}
|
||||
|
||||
CAttributeSoundPickerPanel::~CAttributeSoundPickerPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it's time to show the sound picker
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeSoundPickerPanel::ShowPickerDialog()
|
||||
{
|
||||
// Open file
|
||||
CSoundPicker::PickType_t pickType = CSoundPicker::PICK_ALL;
|
||||
const char *pTextType = GetTextType();
|
||||
if ( pTextType )
|
||||
{
|
||||
if ( !Q_stricmp( pTextType, "gamesoundName" ) )
|
||||
{
|
||||
pickType = CSoundPicker::PICK_GAMESOUNDS;
|
||||
}
|
||||
else if ( !Q_stricmp( pTextType, "wavName" ) )
|
||||
{
|
||||
pickType = CSoundPicker::PICK_WAVFILES;
|
||||
}
|
||||
}
|
||||
|
||||
const char *pCurrentSound = GetAttributeValue<CUtlString>().Get();
|
||||
CSoundPickerFrame *pSoundPickerDialog = new CSoundPickerFrame( this, "Select sound", pickType );
|
||||
pSoundPickerDialog->AddActionSignalTarget( this );
|
||||
|
||||
if ( pickType == CSoundPicker::PICK_ALL )
|
||||
{
|
||||
pickType = CSoundPicker::PICK_NONE;
|
||||
}
|
||||
pSoundPickerDialog->DoModal( pickType, pCurrentSound );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the sound picker has picked a sound
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeSoundPickerPanel::OnSoundSelected( KeyValues *pKeyValues )
|
||||
{
|
||||
// We're either going to get an activity or sequence name
|
||||
const char *pGameSoundName = pKeyValues->GetString( "gamesound", NULL );
|
||||
const char *pSoundName = pKeyValues->GetString( "wav", pGameSoundName );
|
||||
if ( !pSoundName || !pSoundName[ 0 ] )
|
||||
return;
|
||||
|
||||
// Apply to text panel
|
||||
m_pData->SetText( pSoundName );
|
||||
SetDirty(true);
|
||||
if ( IsAutoApply() )
|
||||
{
|
||||
Apply();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeStringChoicePanel.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmelementfactoryhelper.h"
|
||||
#include "dme_controls/inotifyui.h"
|
||||
#include "dme_controls/dmecontrols.h"
|
||||
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Expose DmeEditorAttributeInfo to the scene database
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_ELEMENT_FACTORY( DmeEditorStringChoicesInfo, CDmeEditorStringChoicesInfo );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeEditorStringChoicesInfo::OnConstruction()
|
||||
{
|
||||
}
|
||||
|
||||
void CDmeEditorStringChoicesInfo::OnDestruction()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Add a choice
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmElement *CDmeEditorStringChoicesInfo::AddChoice( const char *pValueString, const char *pChoiceString )
|
||||
{
|
||||
CDmElement *pChoice = CreateChoice( pChoiceString );
|
||||
pChoice->SetValue<CUtlString>( "value", pValueString );
|
||||
return pChoice;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the choices
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CDmeEditorStringChoicesInfo::GetChoiceValue( int nIndex ) const
|
||||
{
|
||||
Assert( ( nIndex < GetChoiceCount() ) && ( nIndex >= 0 ) );
|
||||
CDmElement *pChoice = m_Choices[nIndex];
|
||||
if ( !pChoice )
|
||||
return 0;
|
||||
|
||||
return pChoice->GetValue<CUtlString>( "value" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAttributeStringChoicePanel::CAttributeStringChoicePanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Derived classes can re-implement this to fill the combo box however they like
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeStringChoicePanel::PopulateComboBox( vgui::ComboBox *pComboBox )
|
||||
{
|
||||
pComboBox->DeleteAllItems();
|
||||
|
||||
CDmeEditorStringChoicesInfo *pInfo = CastElement<CDmeEditorStringChoicesInfo>( GetEditorInfo() );
|
||||
if ( !pInfo )
|
||||
return;
|
||||
|
||||
// Fill in the standard choices first
|
||||
int c = pInfo->GetChoiceCount();
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
KeyValues *kv = new KeyValues( "entry" );
|
||||
kv->SetString( "value", pInfo->GetChoiceValue( i ) );
|
||||
pComboBox->AddItem( pInfo->GetChoiceString( i ) , kv );
|
||||
}
|
||||
|
||||
// Add the dynamic choices next
|
||||
if ( pInfo->HasChoiceType() )
|
||||
{
|
||||
StringChoiceList_t choices;
|
||||
if ( ElementPropertiesChoices()->GetStringChoiceList( pInfo->GetChoiceType(), GetPanelElement(), GetAttributeName(), IsArrayEntry(), choices ) )
|
||||
{
|
||||
c = choices.Count();
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
KeyValues *kv = new KeyValues( "entry" );
|
||||
kv->SetString( "value", choices[i].m_pValue );
|
||||
pComboBox->AddItem( choices[i].m_pChoiceString, kv );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the attribute based on the combo box
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeStringChoicePanel::SetAttributeFromComboBox( vgui::ComboBox *pComboBox, KeyValues *pKeyValues )
|
||||
{
|
||||
const char *pOldString = GetAttributeValue<CUtlString>();
|
||||
const char *pNewString = pKeyValues->GetString( "value", "" );
|
||||
if ( pOldString == pNewString )
|
||||
return;
|
||||
|
||||
CElementTreeUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, GetNotify(), "Set Attribute Value", "Set Attribute Value" );
|
||||
SetAttributeValue( pNewString );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the combo box from the attribute
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeStringChoicePanel::SetComboBoxFromAttribute( vgui::ComboBox *pComboBox )
|
||||
{
|
||||
CDmeEditorStringChoicesInfo *pInfo = CastElement<CDmeEditorStringChoicesInfo>( GetEditorInfo() );
|
||||
if ( !pInfo )
|
||||
return;
|
||||
|
||||
const char *pValue = GetAttributeValue<CUtlString>();
|
||||
int c = pInfo->GetChoiceCount();
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
if ( !Q_stricmp( pValue, pInfo->GetChoiceValue( i ) ) )
|
||||
{
|
||||
pComboBox->SetText( pInfo->GetChoiceString( i ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the dynamic choices next
|
||||
if ( pInfo->HasChoiceType() )
|
||||
{
|
||||
StringChoiceList_t choices;
|
||||
if ( ElementPropertiesChoices()->GetStringChoiceList( pInfo->GetChoiceType(), GetPanelElement(), GetAttributeName(), IsArrayEntry(), choices ) )
|
||||
{
|
||||
c = choices.Count();
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
if ( !Q_stricmp( pValue, choices[i].m_pValue ) )
|
||||
{
|
||||
pComboBox->SetText( choices[i].m_pChoiceString );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pComboBox->SetText( "Unknown value" );
|
||||
}
|
||||
@@ -0,0 +1,500 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeTextEntry.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui_controls/Menu.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "dme_controls/AttributeTextPanel.h"
|
||||
#include "vgui/MouseCode.h"
|
||||
#include "vgui/KeyCode.h"
|
||||
#include "vgui/IInput.h"
|
||||
#include "movieobjects/dmeeditortypedictionary.h"
|
||||
#include "dme_controls/inotifyui.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// CAttributeTextEntry
|
||||
|
||||
CAttributeTextEntry::CAttributeTextEntry( Panel *parent, const char *panelName ) :
|
||||
BaseClass( parent, panelName ),
|
||||
m_bValueStored( false ),
|
||||
m_flOriginalValue( 0.0f )
|
||||
{
|
||||
SetDragEnabled( true );
|
||||
SetDropEnabled( true, 0.5f );
|
||||
m_szOriginalText[ 0 ] = 0;
|
||||
AddActionSignalTarget( this );
|
||||
}
|
||||
|
||||
void CAttributeTextEntry::ApplySchemeSettings( IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
SetBorder(NULL);
|
||||
|
||||
//HFont font = pScheme->GetFont( "DmePropertyVerySmall", IsProportional() );
|
||||
//SetFont(font);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the parent panel
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CAttributeTextPanel *CAttributeTextEntry::GetParentAttributePanel()
|
||||
{
|
||||
return static_cast< CAttributeTextPanel * >( GetParent() );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Drag + drop
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CAttributeTextEntry::GetDropContextMenu( Menu *menu, CUtlVector< KeyValues * >& msglist )
|
||||
{
|
||||
menu->AddMenuItem( "Drop as Text", "#BxDropText", "droptext", this );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAttributeTextEntry::IsDroppable( CUtlVector< KeyValues * >& msglist )
|
||||
{
|
||||
if ( !IsEnabled() )
|
||||
return false;
|
||||
|
||||
if ( msglist.Count() != 1 )
|
||||
return false;
|
||||
|
||||
KeyValues *msg = msglist[ 0 ];
|
||||
|
||||
Panel *draggedPanel = ( Panel * )msg->GetPtr( "panel", NULL );
|
||||
if ( draggedPanel == GetParent() )
|
||||
return false;
|
||||
|
||||
CAttributeTextPanel *pPanel = GetParentAttributePanel();
|
||||
if ( !pPanel )
|
||||
return false;
|
||||
|
||||
// If a specific text type is specified, then filter if it doesn't match
|
||||
const char *pTextType = pPanel->GetTextType();
|
||||
if ( pTextType[0] )
|
||||
{
|
||||
const char *pMsgTextType = msg->GetString( "texttype" );
|
||||
if ( Q_stricmp( pTextType, pMsgTextType ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
DmAttributeType_t t = pPanel->GetAttributeType();
|
||||
switch ( t )
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case AT_ELEMENT:
|
||||
{
|
||||
CDmElement *ptr = reinterpret_cast< CDmElement * >( g_pDataModel->GetElement( DmElementHandle_t( msg->GetInt( "root" ) ) ) );
|
||||
if ( ptr )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_ELEMENT_ARRAY:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CAttributeTextEntry::OnPanelDropped( CUtlVector< KeyValues * >& msglist )
|
||||
{
|
||||
if ( msglist.Count() != 1 )
|
||||
return;
|
||||
|
||||
KeyValues *data = msglist[ 0 ];
|
||||
Panel *draggedPanel = ( Panel * )data->GetPtr( "panel", NULL );
|
||||
if ( draggedPanel == GetParent() )
|
||||
return;
|
||||
|
||||
CAttributeTextPanel *pPanel = GetParentAttributePanel();
|
||||
if ( !pPanel )
|
||||
return;
|
||||
|
||||
// If a specific text type is specified, then filter if it doesn't match
|
||||
const char *pTextType = pPanel->GetTextType();
|
||||
if ( pTextType[0] )
|
||||
{
|
||||
const char *pMsgTextType = data->GetString( "texttype" );
|
||||
if ( Q_stricmp( pTextType, pMsgTextType ) )
|
||||
return;
|
||||
}
|
||||
|
||||
const char *cmd = data->GetString( "command" );
|
||||
if ( !Q_stricmp( cmd, "droptext" ) || !Q_stricmp( cmd, "default" ) )
|
||||
{
|
||||
DmAttributeType_t t = pPanel->GetAttributeType();
|
||||
switch ( t )
|
||||
{
|
||||
default:
|
||||
{
|
||||
pPanel->SetDirty( true );
|
||||
SetText( data->GetString( "text" ) );
|
||||
if ( pPanel->IsAutoApply() )
|
||||
{
|
||||
pPanel->Apply();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_ELEMENT:
|
||||
{
|
||||
CDmElement *ptr = reinterpret_cast< CDmElement * >( g_pDataModel->GetElement( DmElementHandle_t( data->GetInt( "root" ) ) ) );
|
||||
if ( !ptr )
|
||||
{
|
||||
break;
|
||||
}
|
||||
pPanel->SetDirty( true );
|
||||
SetText( data->GetString( "text" ) );
|
||||
if ( pPanel->IsAutoApply() )
|
||||
{
|
||||
pPanel->Apply();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AT_ELEMENT_ARRAY:
|
||||
Assert( 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
StoreInitialValue( true );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Enter causes changes to be applied
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeTextEntry::OnKeyCodeTyped(KeyCode code)
|
||||
{
|
||||
bool bCtrl = (input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL));
|
||||
|
||||
switch ( code )
|
||||
{
|
||||
case KEY_ENTER:
|
||||
{
|
||||
CAttributeTextPanel *pPanel = GetParentAttributePanel();
|
||||
if ( !pPanel->IsAutoApply() )
|
||||
{
|
||||
pPanel->Apply();
|
||||
StoreInitialValue( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteValueToAttribute();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Override the base class undo feature, it behaves poorly when typing in data
|
||||
case KEY_Z:
|
||||
if ( bCtrl )
|
||||
{
|
||||
WriteInitialValueToAttribute( );
|
||||
break;
|
||||
}
|
||||
|
||||
// NOTE: Fall through to default if it's not Ctrl-Z
|
||||
|
||||
default:
|
||||
BaseClass::OnKeyCodeTyped(code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAttributeTextEntry::OnTextChanged( KeyValues *data )
|
||||
{
|
||||
m_bValueStored = true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// We'll only create an "undo" record if the values differ upon focus change
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeTextEntry::StoreInitialValue( bool bForce )
|
||||
{
|
||||
// Already storing value???
|
||||
if ( m_bValueStored && !bForce )
|
||||
return;
|
||||
|
||||
m_bValueStored = true;
|
||||
|
||||
CAttributeTextPanel *pPanel = GetParentAttributePanel();
|
||||
Assert( pPanel );
|
||||
|
||||
switch ( pPanel->GetAttributeType() )
|
||||
{
|
||||
case AT_FLOAT:
|
||||
m_flOriginalValue = pPanel->GetAttributeValue<float>( );
|
||||
break;
|
||||
case AT_INT:
|
||||
m_nOriginalValue = pPanel->GetAttributeValue<int>( );
|
||||
break;
|
||||
case AT_BOOL:
|
||||
m_bOriginalValue = pPanel->GetAttributeValue<bool>( );
|
||||
break;
|
||||
default:
|
||||
GetText( m_szOriginalText, sizeof( m_szOriginalText ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Performs undo
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeTextEntry::WriteInitialValueToAttribute( )
|
||||
{
|
||||
// Already storing value???
|
||||
if ( !m_bValueStored )
|
||||
return;
|
||||
|
||||
CDisableUndoScopeGuard guard;
|
||||
|
||||
CAttributeTextPanel *pPanel = GetParentAttributePanel();
|
||||
Assert( pPanel );
|
||||
|
||||
switch ( pPanel->GetAttributeType() )
|
||||
{
|
||||
case AT_FLOAT:
|
||||
pPanel->SetAttributeValue( m_flOriginalValue );
|
||||
break;
|
||||
case AT_INT:
|
||||
pPanel->SetAttributeValue( m_nOriginalValue );
|
||||
break;
|
||||
case AT_BOOL:
|
||||
pPanel->SetAttributeValue<bool>( m_bOriginalValue );
|
||||
break;
|
||||
default:
|
||||
pPanel->SetAttributeValueFromString( m_szOriginalText );
|
||||
break;
|
||||
}
|
||||
|
||||
pPanel->SetDirty( false );
|
||||
pPanel->Refresh();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// We'll only create an "undo" record if the values differ upon focus change
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeTextEntry::OnSetFocus()
|
||||
{
|
||||
BaseClass::OnSetFocus();
|
||||
StoreInitialValue();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when focus is lost
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void CAttributeTextEntry::ApplyMouseWheel( T newValue, T originalValue )
|
||||
{
|
||||
CAttributeTextPanel *pPanel = GetParentAttributePanel();
|
||||
|
||||
// Kind of an evil hack, but "undo" copies the "old value" off for doing undo, and that value is the new value because
|
||||
// we haven't been tracking undo while manipulating this. So we'll turn off undo and set the value to the original value.
|
||||
|
||||
// In effect, all of the wheeling will drop out and it'll look just like we started at the original value and ended up at the
|
||||
// final value...
|
||||
{
|
||||
CDisableUndoScopeGuard guard;
|
||||
pPanel->SetAttributeValue( originalValue );
|
||||
}
|
||||
|
||||
if ( pPanel->IsAutoApply() )
|
||||
{
|
||||
pPanel->Apply();
|
||||
}
|
||||
else
|
||||
{
|
||||
CElementTreeUndoScopeGuard guard( 0, pPanel->GetNotify(), "Set Attribute Value", "Set Attribute Value" );
|
||||
pPanel->SetAttributeValue( newValue );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAttributeTextEntry::WriteValueToAttribute()
|
||||
{
|
||||
if ( !m_bValueStored )
|
||||
return;
|
||||
|
||||
m_bValueStored = false;
|
||||
|
||||
char newText[ MAX_TEXT_LENGTH ];
|
||||
GetText( newText, sizeof( newText ) );
|
||||
|
||||
CAttributeTextPanel *pPanel = GetParentAttributePanel();
|
||||
Assert( pPanel );
|
||||
switch (pPanel->GetAttributeType() )
|
||||
{
|
||||
case AT_FLOAT:
|
||||
ApplyMouseWheel( (float)atof(newText), m_flOriginalValue );
|
||||
break;
|
||||
case AT_INT:
|
||||
ApplyMouseWheel( atoi(newText), m_nOriginalValue );
|
||||
break;
|
||||
case AT_BOOL:
|
||||
ApplyMouseWheel( atoi(newText) != 0, m_bOriginalValue );
|
||||
break;
|
||||
default:
|
||||
if ( Q_strcmp( newText, m_szOriginalText ) )
|
||||
{
|
||||
pPanel->SetDirty( true );
|
||||
if ( pPanel->IsAutoApply() )
|
||||
{
|
||||
pPanel->Apply();
|
||||
StoreInitialValue( true );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pPanel->SetDirty( false );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when focus is lost
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeTextEntry::OnKillFocus()
|
||||
{
|
||||
BaseClass::OnKillFocus();
|
||||
WriteValueToAttribute();
|
||||
StoreInitialValue();
|
||||
}
|
||||
|
||||
void CAttributeTextEntry::OnMouseWheeled( int delta )
|
||||
{
|
||||
// Must have *keyboard* focus for it to work
|
||||
if ( !HasFocus() )
|
||||
{
|
||||
// Otherwise, let the base class scroll up + down
|
||||
BaseClass::OnMouseWheeled( delta );
|
||||
return;
|
||||
}
|
||||
|
||||
CAttributeTextPanel *pPanel = GetParentAttributePanel();
|
||||
if ( pPanel->GetDirty() )
|
||||
{
|
||||
if ( pPanel->IsAutoApply() )
|
||||
{
|
||||
pPanel->Apply();
|
||||
StoreInitialValue( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: Make this work for non-auto-apply panels
|
||||
}
|
||||
}
|
||||
|
||||
switch ( pPanel->GetAttributeType() )
|
||||
{
|
||||
case AT_FLOAT:
|
||||
{
|
||||
float deltaFactor;
|
||||
if ( input()->IsKeyDown(KEY_LSHIFT) )
|
||||
{
|
||||
deltaFactor = ((float)delta) * 10.0f;
|
||||
}
|
||||
else if ( input()->IsKeyDown(KEY_LCONTROL) )
|
||||
{
|
||||
deltaFactor = ((float)delta) / 100.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
deltaFactor = ((float)delta) / 10.0;
|
||||
}
|
||||
|
||||
float val = pPanel->GetAttributeValue<float>() + deltaFactor;
|
||||
|
||||
if ( input()->IsKeyDown(KEY_LALT) )
|
||||
{
|
||||
//val = clamp(val, 0.0, 1.0);
|
||||
val = (val > 1) ? 1 : ((val < 0) ? 0 : val);
|
||||
}
|
||||
|
||||
{
|
||||
// Note, these calls to Set won't create Undo Records,
|
||||
// since we'll check the value in SetFocus/KillFocus so that we
|
||||
// don't gum up the undo system with hundreds of records...
|
||||
CDisableUndoScopeGuard guard;
|
||||
pPanel->SetAttributeValue( val );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_INT:
|
||||
{
|
||||
if ( input()->IsKeyDown(KEY_LSHIFT) )
|
||||
{
|
||||
delta *= 10;
|
||||
}
|
||||
|
||||
int val = pPanel->GetAttributeValue<int>() + delta;
|
||||
|
||||
{
|
||||
// Note, these calls to Set won't create Undo Records,
|
||||
// since we'll check the value in SetFocus/KillFocus so that we
|
||||
// don't gum up the undo system with hundreds of records...
|
||||
CDisableUndoScopeGuard guard;
|
||||
pPanel->SetAttributeValue( val );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_BOOL:
|
||||
{
|
||||
bool val = !pPanel->GetAttributeValue<bool>();
|
||||
|
||||
{
|
||||
// Note, these calls to Set won't create Undo Records,
|
||||
// since we'll check the value in SetFocus/KillFocus so that we
|
||||
// don't gum up the undo system with hundreds of records...
|
||||
CDisableUndoScopeGuard guard;
|
||||
pPanel->SetAttributeValue( val );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
pPanel->Refresh();
|
||||
if ( pPanel->IsAutoApply() )
|
||||
{
|
||||
// NOTE: Don't call Apply since that generates an undo record
|
||||
CElementTreeNotifyScopeGuard notify( "CAttributeTextEntry::OnMouseWheeled", NOTIFY_CHANGE_ATTRIBUTE_VALUE | NOTIFY_SETDIRTYFLAG, pPanel->GetNotify() );
|
||||
}
|
||||
else
|
||||
{
|
||||
pPanel->SetDirty( true );
|
||||
}
|
||||
|
||||
//SetDirty(true);
|
||||
//UpdateTime( m_flLastMouseTime );
|
||||
//UpdateZoom( -10.0f * delta );
|
||||
//UpdateTransform();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,119 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeTextPanel.h"
|
||||
#include "dme_controls/AttributeTextEntry.h"
|
||||
#include "dme_controls/AttributeWidgetFactory.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "movieobjects/dmeeditortypedictionary.h"
|
||||
#include "dme_controls/inotifyui.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CAttributeTextPanel constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAttributeTextPanel::CAttributeTextPanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info ), m_pData( 0 ), m_bShowMemoryUsage( info.m_bShowMemoryUsage )
|
||||
{
|
||||
m_pData = new CAttributeTextEntry( this, "AttributeValue" );
|
||||
m_pData->SetEnabled( !HasFlag( READONLY ) );
|
||||
|
||||
m_pData->AddActionSignalTarget(this);
|
||||
SetAllowKeyBindingChainToParent( false );
|
||||
}
|
||||
|
||||
void CAttributeTextPanel::SetFont( HFont font )
|
||||
{
|
||||
BaseClass::SetFont( font );
|
||||
m_pData->SetFont( font );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the text type
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CAttributeTextPanel::GetTextType()
|
||||
{
|
||||
// If a specific text type is specified, then filter if it doesn't match
|
||||
CDmeEditorAttributeInfo *pInfo = GetEditorInfo();
|
||||
const char *pTextType = pInfo ? pInfo->GetValueString( "texttype" ) : NULL;
|
||||
return pTextType ? pTextType : "";
|
||||
}
|
||||
|
||||
|
||||
void CAttributeTextPanel::Apply()
|
||||
{
|
||||
char txt[ 256 ];
|
||||
m_pData->GetText( txt, sizeof( txt ) );
|
||||
|
||||
// Apply means we no longer look blue
|
||||
SetDirty( false );
|
||||
|
||||
if ( GetAttributeType( ) == AT_UNKNOWN )
|
||||
{
|
||||
CElementTreeUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, GetNotify(), "Set Attribute Value", "Set Attribute Value" );
|
||||
SetAttributeValue( "" );
|
||||
return;
|
||||
}
|
||||
|
||||
char curvalue[ 256 ];
|
||||
GetAttributeValueAsString( curvalue, sizeof( curvalue ) );
|
||||
|
||||
// Only if differnt
|
||||
if ( Q_strcmp( curvalue, txt ) )
|
||||
{
|
||||
CElementTreeUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, GetNotify(), "Set Attribute Value", "Set Attribute Value" );
|
||||
SetAttributeValueFromString( txt );
|
||||
}
|
||||
}
|
||||
|
||||
vgui::Panel *CAttributeTextPanel::GetDataPanel()
|
||||
{
|
||||
return static_cast< vgui::Panel * >( m_pData );
|
||||
}
|
||||
|
||||
void CAttributeTextPanel::Refresh()
|
||||
{
|
||||
char buf[ 512 ];
|
||||
if ( IsArrayType( GetAttributeType() ) )
|
||||
{
|
||||
int count = GetAttributeArrayCount();
|
||||
if ( m_bShowMemoryUsage )
|
||||
{
|
||||
CDmAttribute *pAttr = GetPanelElement()->GetAttribute( GetAttributeName() );
|
||||
Q_snprintf( buf, sizeof( buf ), "%d items %.3fMB", count, pAttr->EstimateMemoryUsage( TD_DEEP ) / float( 1 << 20 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( buf, sizeof( buf ), "%d items", count );
|
||||
}
|
||||
m_pData->SetText( buf );
|
||||
m_pData->SetEnabled(false);
|
||||
}
|
||||
else if ( GetAttributeType() == AT_ELEMENT )
|
||||
{
|
||||
m_pData->SetText( "" );
|
||||
}
|
||||
else
|
||||
{
|
||||
GetAttributeValueAsString( buf, sizeof( buf ) );
|
||||
m_pData->SetText( buf );
|
||||
}
|
||||
}
|
||||
|
||||
void CAttributeTextPanel::PostConstructor()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,370 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeWidgetFactory.h"
|
||||
#include "tier1/utldict.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "movieobjects/dmeeditortypedictionary.h"
|
||||
#include "dme_controls/AttributeTextEntry.h"
|
||||
#include "dme_controls/AttributeFilePickerPanel.h"
|
||||
#include "dme_controls/AttributeBoolChoicePanel.h"
|
||||
#include "dme_controls/AttributeIntChoicePanel.h"
|
||||
#include "dme_controls/AttributeStringChoicePanel.h"
|
||||
#include "dme_controls/AttributeElementPanel.h"
|
||||
#include "dme_controls/AttributeElementPickerPanel.h"
|
||||
#include "dme_controls/AttributeMDLPickerPanel.h"
|
||||
#include "dme_controls/AttributeSequencePickerPanel.h"
|
||||
#include "dme_controls/AttributeSoundPickerPanel.h"
|
||||
#include "dme_controls/AttributeAssetPickerPanel.h"
|
||||
#include "dme_controls/AttributeShaderPickerPanel.h"
|
||||
#include "dme_controls/AttributeSurfacePropertyPickerPanel.h"
|
||||
#include "dme_controls/AttributeDetailTypePickerPanel.h"
|
||||
#include "dme_controls/AttributeColorPickerPanel.h"
|
||||
#include "dme_controls/AttributeInterpolatorChoicePanel.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
class CAttributeWidgetFactoryList;
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CAttributeWidgetFactoryList class definition
|
||||
//-----------------------------------------------------------------------------
|
||||
class CAttributeWidgetFactoryList : public IAttributeWidgetFactoryList
|
||||
{
|
||||
public:
|
||||
// Inherited from IAttributeWidgetFactoryList
|
||||
virtual IAttributeWidgetFactory *GetWidgetFactory( const char *pWidgetName );
|
||||
virtual IAttributeWidgetFactory *GetWidgetFactory( CDmElement *object, CDmAttribute *pAttribute, CDmeEditorTypeDictionary *pTypeDictionary );
|
||||
virtual IAttributeWidgetFactory *GetArrayWidgetFactory( CDmElement *object, CDmAttribute *pAttribute, CDmeEditorTypeDictionary *pTypeDictionary );
|
||||
virtual void ApplyChanges( vgui::Panel *pWidget, vgui::Panel *pSender = NULL );
|
||||
virtual void Refresh( vgui::Panel *pWidget, vgui::Panel *pSender = NULL );
|
||||
|
||||
// Adds a widget to the factory
|
||||
void AddWidgetFactory( IAttributeWidgetFactory *pFactory, const char *pWidgetName );
|
||||
|
||||
// Finds a widget factory by name
|
||||
IAttributeWidgetFactory *FindWidgetFactory( const char *pWidgetName );
|
||||
|
||||
// Creates a widget using editor attribute info
|
||||
// vgui::Panel *CreateWidget( vgui::Panel *parent, CDmElement *obj, INotifyUI *pNotify, CDmeEditorAttributeInfo *pWidgetInfo, bool bAutoApply );
|
||||
|
||||
private:
|
||||
CUtlDict< IAttributeWidgetFactory*, unsigned short > m_Factories;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CAttributeWidgetFactoryList *g_pWidgetFactoryFactoryList;
|
||||
IAttributeWidgetFactoryList *attributewidgetfactorylist;
|
||||
|
||||
CAttributeWidgetFactoryList *GetWidgetFactoryManager()
|
||||
{
|
||||
if ( !g_pWidgetFactoryFactoryList )
|
||||
{
|
||||
g_pWidgetFactoryFactoryList = new CAttributeWidgetFactoryList;
|
||||
attributewidgetfactorylist = g_pWidgetFactoryFactoryList;
|
||||
}
|
||||
return g_pWidgetFactoryFactoryList;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Standard implementation of a widget factory
|
||||
//-----------------------------------------------------------------------------
|
||||
template < class T >
|
||||
class CAttributeWidgetFactory : public IAttributeWidgetFactory
|
||||
{
|
||||
public:
|
||||
CAttributeWidgetFactory( const char *pWidgetName )
|
||||
{
|
||||
GetWidgetFactoryManager()->AddWidgetFactory( this, pWidgetName );
|
||||
}
|
||||
|
||||
// Backward compat
|
||||
virtual vgui::Panel *Create( vgui::Panel *pParent, const AttributeWidgetInfo_t &info )
|
||||
{
|
||||
CBaseAttributePanel *newPanel = new T( pParent, info );
|
||||
if ( newPanel )
|
||||
{
|
||||
newPanel->PostConstructor();
|
||||
}
|
||||
return newPanel;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// create all the AttributeWidgetFactorys
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// An Attribute Widget Factory for: text entry
|
||||
static CAttributeWidgetFactory<CAttributeTextPanel> g_AttributeTextWidgetFactory( "text" );
|
||||
|
||||
// An Attribute Widget Factory for: picking files
|
||||
static CAttributeWidgetFactory<CAttributeDmeFilePickerPanel> g_AttributeFilePickerWidgetFactory( "filepicker" );
|
||||
|
||||
// An Attribute Widget Factory for: choosing integers
|
||||
static CAttributeWidgetFactory<CAttributeBoolChoicePanel> g_AttributeBoolChoiceWidgetFactory( "boolchoice" );
|
||||
|
||||
// An Attribute Widget Factory for: choosing integers
|
||||
static CAttributeWidgetFactory<CAttributeIntChoicePanel> g_AttributeIntChoiceWidgetFactory( "intchoice" );
|
||||
|
||||
// An Attribute Widget Factory for: choosing strings
|
||||
static CAttributeWidgetFactory<CAttributeStringChoicePanel> g_AttributeStringChoiceWidgetFactory( "stringchoice" );
|
||||
|
||||
// An Attribute Widget Factory for: elements
|
||||
static CAttributeWidgetFactory<CAttributeElementPanel> g_AttributeElementWidgetFactory( "element" );
|
||||
|
||||
// An Attribute Widget Factory for: picking elements
|
||||
static CAttributeWidgetFactory<CAttributeElementPickerPanel> g_AttributeElementPickerWidgetFactory( "elementchoice" );
|
||||
|
||||
// An Attribute Widget Factory for: picking MDLs
|
||||
static CAttributeWidgetFactory<CAttributeMDLPickerPanel> g_AttributeMDLPickerWidgetFactory( "mdlpicker" );
|
||||
|
||||
// An Attribute Widget Factory for: picking sequences
|
||||
static CAttributeWidgetFactory<CAttributeSequencePickerPanel> g_AttributeSequencePickerWidgetFactory( "sequencepicker" );
|
||||
|
||||
// An Attribute Widget Factory for: picking sounds
|
||||
static CAttributeWidgetFactory<CAttributeSoundPickerPanel> g_AttributeSoundPickerWidgetFactory( "soundpicker" );
|
||||
|
||||
// An Attribute Widget Factory for: picking bsps
|
||||
static CAttributeWidgetFactory<CAttributeBspPickerPanel> g_AttributeBspPickerWidgetFactory( "bsppicker" );
|
||||
|
||||
// An Attribute Widget Factory for: picking vmts
|
||||
static CAttributeWidgetFactory<CAttributeVmtPickerPanel> g_AttributeVmtPickerWidgetFactory( "vmtpicker" );
|
||||
|
||||
// An Attribute Widget Factory for: picking vtfs
|
||||
static CAttributeWidgetFactory<CAttributeVtfPickerPanel> g_AttributeVtfPickerWidgetFactory( "vtfpicker" );
|
||||
|
||||
// An Attribute Widget Factory for: picking tgas
|
||||
static CAttributeWidgetFactory<CAttributeTgaFilePickerPanel> g_AttributeTgaPickerWidgetFactory( "tgapicker" );
|
||||
|
||||
// An Attribute Widget Factory for: picking shaders
|
||||
static CAttributeWidgetFactory<CAttributeShaderPickerPanel> g_AttributeShaderPickerWidgetFactory( "shaderpicker" );
|
||||
|
||||
// An Attribute Widget Factory for: picking surface properties
|
||||
static CAttributeWidgetFactory<CAttributeSurfacePropertyPickerPanel> g_AttributeSurfacePropertyPickerWidgetFactory( "surfacepropertypicker" );
|
||||
|
||||
// An Attribute Widget Factory for: picking surface properties
|
||||
static CAttributeWidgetFactory<CAttributeColorPickerPanel> g_AttributeColorPickerWidgetFactory( "colorpicker" );
|
||||
|
||||
// An Attribute Widget Factory for: picking avis
|
||||
static CAttributeWidgetFactory<CAttributeAviFilePickerPanel> g_AttributeAviPickerWidgetFactory( "avipicker" );
|
||||
|
||||
// An Attribute Widget Factory for: picking sht
|
||||
static CAttributeWidgetFactory<CAttributeShtFilePickerPanel> g_AttributeShtPickerWidgetFactory( "shtpicker" );
|
||||
|
||||
// An Attribute Widget Factory for: picking detail types
|
||||
static CAttributeWidgetFactory<CAttributeDetailTypePickerPanel> g_AttributeDetailTypePickerWidgetFactory( "detailtypepicker" );
|
||||
|
||||
// An Attribute Widget Factory for: picking color correction lookup files
|
||||
static CAttributeWidgetFactory<CAttributeRawFilePickerPanel> g_AttributeRawPickerWidgetFactory( "rawpicker" );
|
||||
|
||||
// An Attribute Widget Factory for: choosing interpolator types (left and right)
|
||||
static CAttributeWidgetFactory<CAttributeInterpolatorChoicePanel> g_AttributeInterpolatorChoiceWidgetFactory( "interpolatorchoice" );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name-based widget factories
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// g_AttributeWidgetFactories
|
||||
// Purpose: a mapping of all attribute types to AttributeWidgetFactories
|
||||
|
||||
struct DefaultAttributeFactoryEntry_t
|
||||
{
|
||||
int attributeType;
|
||||
IAttributeWidgetFactory *factory;
|
||||
};
|
||||
|
||||
static DefaultAttributeFactoryEntry_t g_AttributeWidgetFactories[] =
|
||||
{
|
||||
|
||||
{ AT_UNKNOWN, NULL },
|
||||
|
||||
{ AT_ELEMENT, &g_AttributeElementWidgetFactory },
|
||||
{ AT_INT, &g_AttributeTextWidgetFactory },
|
||||
{ AT_FLOAT, &g_AttributeTextWidgetFactory },
|
||||
{ AT_BOOL, &g_AttributeTextWidgetFactory },
|
||||
{ AT_STRING, &g_AttributeTextWidgetFactory },
|
||||
{ AT_VOID, &g_AttributeTextWidgetFactory },
|
||||
{ AT_OBJECTID, &g_AttributeTextWidgetFactory },
|
||||
{ AT_COLOR, &g_AttributeColorPickerWidgetFactory },
|
||||
{ AT_VECTOR2, &g_AttributeTextWidgetFactory },
|
||||
{ AT_VECTOR3, &g_AttributeTextWidgetFactory },
|
||||
{ AT_VECTOR4, &g_AttributeTextWidgetFactory },
|
||||
{ AT_QANGLE, &g_AttributeTextWidgetFactory },
|
||||
{ AT_QUATERNION, &g_AttributeTextWidgetFactory },
|
||||
{ AT_VMATRIX, &g_AttributeTextWidgetFactory },
|
||||
|
||||
{ AT_ELEMENT_ARRAY, &g_AttributeTextWidgetFactory },
|
||||
{ AT_INT_ARRAY, &g_AttributeTextWidgetFactory },
|
||||
{ AT_FLOAT_ARRAY, &g_AttributeTextWidgetFactory },
|
||||
{ AT_BOOL_ARRAY, &g_AttributeTextWidgetFactory },
|
||||
{ AT_STRING_ARRAY, &g_AttributeTextWidgetFactory },
|
||||
{ AT_VOID_ARRAY, &g_AttributeTextWidgetFactory },
|
||||
{ AT_ELEMENT_ARRAY, &g_AttributeTextWidgetFactory },
|
||||
{ AT_OBJECTID_ARRAY, &g_AttributeTextWidgetFactory },
|
||||
{ AT_COLOR_ARRAY, &g_AttributeColorPickerWidgetFactory },
|
||||
{ AT_VECTOR2_ARRAY, &g_AttributeTextWidgetFactory },
|
||||
{ AT_VECTOR3_ARRAY, &g_AttributeTextWidgetFactory },
|
||||
{ AT_VECTOR4_ARRAY, &g_AttributeTextWidgetFactory },
|
||||
{ AT_QANGLE_ARRAY, &g_AttributeTextWidgetFactory },
|
||||
{ AT_QUATERNION_ARRAY, &g_AttributeTextWidgetFactory },
|
||||
{ AT_VMATRIX_ARRAY, &g_AttributeTextWidgetFactory },
|
||||
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// CAttributeWidgetFactoryList
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Adds a widget to the factory
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeWidgetFactoryList::AddWidgetFactory( IAttributeWidgetFactory *pFactory, const char *pWidgetName )
|
||||
{
|
||||
m_Factories.Insert( pWidgetName, pFactory );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Finds a widget factory by name
|
||||
//-----------------------------------------------------------------------------
|
||||
IAttributeWidgetFactory *CAttributeWidgetFactoryList::FindWidgetFactory( const char *pWidgetName )
|
||||
{
|
||||
unsigned short i = m_Factories.Find( pWidgetName );
|
||||
if ( i != m_Factories.InvalidIndex() )
|
||||
return m_Factories[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns a factory requested by name
|
||||
//-----------------------------------------------------------------------------
|
||||
IAttributeWidgetFactory *CAttributeWidgetFactoryList::GetWidgetFactory( const char *pWidgetName )
|
||||
{
|
||||
return FindWidgetFactory( pWidgetName );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns a factory used to create widget for the attribute passed in
|
||||
//-----------------------------------------------------------------------------
|
||||
IAttributeWidgetFactory *CAttributeWidgetFactoryList::GetWidgetFactory( CDmElement *object,
|
||||
CDmAttribute *pAttribute, CDmeEditorTypeDictionary *pTypeDictionary )
|
||||
{
|
||||
if ( !object )
|
||||
return NULL;
|
||||
|
||||
DmAttributeType_t attributeType = pAttribute->GetType();
|
||||
IAttributeWidgetFactory *pFactory = g_AttributeWidgetFactories[ attributeType ].factory;
|
||||
|
||||
// Override behavior with editor info, if it exists
|
||||
if ( pTypeDictionary )
|
||||
{
|
||||
const char *pAttributeName = pAttribute->GetName();
|
||||
CDmeEditorAttributeInfo *pEditorInfo = pTypeDictionary->GetAttributeInfo( object, pAttributeName );
|
||||
if ( pEditorInfo )
|
||||
{
|
||||
if ( !pEditorInfo->m_bIsVisible )
|
||||
return NULL;
|
||||
|
||||
if ( pEditorInfo->GetWidgetName() )
|
||||
{
|
||||
IAttributeWidgetFactory *pOverriddenFactory = g_pWidgetFactoryFactoryList->FindWidgetFactory( pEditorInfo->GetWidgetName() );
|
||||
if ( pOverriddenFactory )
|
||||
{
|
||||
pFactory = pOverriddenFactory;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return pFactory;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns a factory used to create widgets for entries in an attribute array
|
||||
//-----------------------------------------------------------------------------
|
||||
IAttributeWidgetFactory *CAttributeWidgetFactoryList::GetArrayWidgetFactory( CDmElement *object,
|
||||
CDmAttribute *pAttribute, CDmeEditorTypeDictionary *pTypeDictionary )
|
||||
{
|
||||
if ( !object )
|
||||
return NULL;
|
||||
|
||||
DmAttributeType_t attributeType = ArrayTypeToValueType( pAttribute->GetType() );
|
||||
IAttributeWidgetFactory *pFactory = g_AttributeWidgetFactories[ attributeType ].factory;
|
||||
|
||||
// Override behavior with editor info, if it exists
|
||||
if ( pTypeDictionary )
|
||||
{
|
||||
CDmeEditorAttributeInfo *pEditorInfo = pTypeDictionary->GetAttributeArrayInfo( object, pAttribute->GetName() );
|
||||
if ( pEditorInfo )
|
||||
{
|
||||
if ( !pEditorInfo->m_bIsVisible )
|
||||
return NULL;
|
||||
|
||||
if ( pEditorInfo->GetWidgetName() )
|
||||
{
|
||||
IAttributeWidgetFactory *pOverriddenFactory = g_pWidgetFactoryFactoryList->FindWidgetFactory( pEditorInfo->GetWidgetName() );
|
||||
if ( pOverriddenFactory )
|
||||
{
|
||||
pFactory = pOverriddenFactory;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pFactory;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Applies changes to a widget
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeWidgetFactoryList::ApplyChanges( vgui::Panel *pWidget, vgui::Panel *pSender )
|
||||
{
|
||||
CBaseAttributePanel *pPanel = dynamic_cast< CBaseAttributePanel *>( pWidget );
|
||||
if ( pPanel && pPanel->GetDirty() )
|
||||
{
|
||||
Assert( !pPanel->IsAutoApply() );
|
||||
vgui::ipanel()->SendMessage( pWidget->GetVPanel(), new KeyValues( "ApplyChanges" ), pSender ? pSender->GetVPanel() : NULL );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Refreshes a widget when attributes change
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeWidgetFactoryList::Refresh( vgui::Panel *pWidget, vgui::Panel *pSender )
|
||||
{
|
||||
if ( pWidget )
|
||||
{
|
||||
vgui::ipanel()->SendMessage( pWidget->GetVPanel(), new KeyValues( "Refresh" ), pSender ? pWidget->GetVPanel() : NULL );
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,523 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
#include "dme_controls/BaseAnimSetControlGroupPanel.h"
|
||||
#include "vgui_controls/TreeView.h"
|
||||
#include "vgui_controls/Menu.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "movieobjects/dmeanimationset.h"
|
||||
#include "dme_controls/BaseAnimSetAttributeSliderPanel.h"
|
||||
#include "dme_controls/BaseAnimationSetEditor.h"
|
||||
#include "dme_controls/dmecontrols_utils.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shows the tree view of the animation groups
|
||||
//-----------------------------------------------------------------------------
|
||||
class CAnimGroupTree : public TreeView
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CAnimGroupTree, TreeView );
|
||||
public:
|
||||
CAnimGroupTree( Panel *parent, const char *panelName, CBaseAnimSetControlGroupPanel *groupPanel );
|
||||
virtual ~CAnimGroupTree();
|
||||
|
||||
virtual bool IsItemDroppable( int itemIndex, CUtlVector< KeyValues * >& msglist );
|
||||
virtual void OnItemDropped( int itemIndex, CUtlVector< KeyValues * >& msglist );
|
||||
virtual void GenerateContextMenu( int itemIndex, int x, int y );
|
||||
|
||||
private:
|
||||
MESSAGE_FUNC( OnImportAnimation, "ImportAnimation" );
|
||||
|
||||
void CleanupContextMenu();
|
||||
|
||||
vgui::DHANDLE< vgui::Menu > m_hContextMenu;
|
||||
CBaseAnimSetControlGroupPanel *m_pGroupPanel;
|
||||
};
|
||||
|
||||
CAnimGroupTree::CAnimGroupTree( Panel *parent, const char *panelName, CBaseAnimSetControlGroupPanel *groupPanel ) :
|
||||
BaseClass( parent, panelName ),
|
||||
m_pGroupPanel( groupPanel )
|
||||
{
|
||||
}
|
||||
|
||||
CAnimGroupTree::~CAnimGroupTree()
|
||||
{
|
||||
CleanupContextMenu();
|
||||
}
|
||||
|
||||
void CAnimGroupTree::CleanupContextMenu()
|
||||
{
|
||||
if ( m_hContextMenu.Get() )
|
||||
{
|
||||
delete m_hContextMenu.Get();
|
||||
m_hContextMenu = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool CAnimGroupTree::IsItemDroppable( int itemIndex, CUtlVector< KeyValues * >& msglist )
|
||||
{
|
||||
if ( msglist.Count() != 1 )
|
||||
return false;
|
||||
|
||||
KeyValues *data = msglist[ 0 ];
|
||||
if ( !data )
|
||||
return false;
|
||||
|
||||
if ( !data->FindKey( "color" ) )
|
||||
return false;
|
||||
|
||||
KeyValues *itemData = GetItemData( itemIndex );
|
||||
if ( !itemData->FindKey( "handle" ) )
|
||||
return false;
|
||||
DmElementHandle_t handle = (DmElementHandle_t)itemData->GetInt( "handle" );
|
||||
if ( handle == DMELEMENT_HANDLE_INVALID )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CAnimGroupTree::OnItemDropped( int itemIndex, CUtlVector< KeyValues * >& msglist )
|
||||
{
|
||||
if ( !IsItemDroppable( itemIndex, msglist ) )
|
||||
return;
|
||||
|
||||
KeyValues *data = msglist[ 0 ];
|
||||
if ( !data )
|
||||
return;
|
||||
|
||||
KeyValues *itemData = GetItemData( itemIndex );
|
||||
|
||||
CDmElement *group = GetElementKeyValue< CDmElement >( itemData, "handle" );
|
||||
Assert( m_pGroupPanel );
|
||||
Color clr = data->GetColor( "color" );
|
||||
SetItemFgColor( itemIndex, clr );
|
||||
SetItemSelectionTextColor( itemIndex, clr );
|
||||
|
||||
if ( group )
|
||||
{
|
||||
CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Change Group Color" );
|
||||
group->SetValue< Color >( "treeColor", clr );
|
||||
}
|
||||
}
|
||||
|
||||
void CAnimGroupTree::OnImportAnimation()
|
||||
{
|
||||
PostMessage( m_pGroupPanel->m_hEditor, new KeyValues( "ImportAnimation", "visibleOnly", "1" ), 0.0f );
|
||||
}
|
||||
|
||||
// override to open a custom context menu on a node being selected and right-clicked
|
||||
void CAnimGroupTree::GenerateContextMenu( int itemIndex, int x, int y )
|
||||
{
|
||||
CleanupContextMenu();
|
||||
m_hContextMenu = new Menu( this, "ActionMenu" );
|
||||
m_hContextMenu->AddMenuItem( "#ImportAnimation", new KeyValues( "ImportAnimation" ), this );
|
||||
Menu::PlaceContextMenu( this, m_hContextMenu.Get() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
CBaseAnimSetControlGroupPanel::CBaseAnimSetControlGroupPanel( vgui::Panel *parent, const char *className, CBaseAnimationSetEditor *editor ) :
|
||||
BaseClass( parent, className ),
|
||||
m_bStartItemWasSelected( false ),
|
||||
m_SliderNames( 0, 0, true )
|
||||
{
|
||||
m_hEditor = editor;
|
||||
m_hGroups = new CAnimGroupTree( this, "AnimSetGroups", this );
|
||||
m_hGroups->SetMultipleItemDragEnabled( true );
|
||||
m_hGroups->SetAutoResize
|
||||
(
|
||||
Panel::PIN_TOPLEFT,
|
||||
Panel::AUTORESIZE_DOWNANDRIGHT,
|
||||
0, 0,
|
||||
0, 0
|
||||
);
|
||||
m_hGroups->SetAllowMultipleSelections( true );
|
||||
}
|
||||
|
||||
CBaseAnimSetControlGroupPanel::~CBaseAnimSetControlGroupPanel()
|
||||
{
|
||||
}
|
||||
|
||||
static int AddItemToTree( TreeView *tv, const char *label, int parentIndex, const Color& fg, int groupNumber, int handle )
|
||||
{
|
||||
Color bgColor( 128, 128, 128, 128 );
|
||||
|
||||
KeyValues *kv = new KeyValues( "item", "text", label );
|
||||
kv->SetInt( "groupNumber", groupNumber );
|
||||
kv->SetInt( "droppable", 1 );
|
||||
kv->SetInt( "handle", handle );
|
||||
int idx = tv->AddItem( kv, parentIndex );
|
||||
tv->SetItemFgColor( idx, fg );
|
||||
tv->SetItemSelectionTextColor( idx, fg );
|
||||
tv->SetItemSelectionBgColor( idx, bgColor );
|
||||
tv->SetItemSelectionUnfocusedBgColor( idx, bgColor );
|
||||
|
||||
tv->RemoveSelectedItem( idx );
|
||||
tv->ExpandItem( idx, false );
|
||||
|
||||
kv->deleteThis();
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
void CBaseAnimSetControlGroupPanel::ApplySchemeSettings( IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
m_hGroups->SetFont( pScheme->GetFont( "DefaultBold", IsProportional() ) );
|
||||
}
|
||||
|
||||
void CBaseAnimSetControlGroupPanel::OnTreeViewItemSelectionCleared()
|
||||
{
|
||||
// We check the entire group manually
|
||||
OnTreeViewItemSelected( -1 );
|
||||
}
|
||||
|
||||
void CBaseAnimSetControlGroupPanel::OnTreeViewItemDeselected( int itemIndex )
|
||||
{
|
||||
OnTreeViewItemSelected( -1 );
|
||||
}
|
||||
|
||||
void CBaseAnimSetControlGroupPanel::OnTreeViewItemSelected( int itemIndex )
|
||||
{
|
||||
if ( !m_AnimSet.Get() )
|
||||
return;
|
||||
|
||||
// Build the list of selected groups, and notify the attribute slider panel
|
||||
CUtlVector< int > selection;
|
||||
m_hGroups->GetSelectedItems( selection );
|
||||
|
||||
const CDmaElementArray<> &groups = m_AnimSet->GetSelectionGroups();
|
||||
int groupCount = groups.Count();
|
||||
|
||||
int i;
|
||||
int rootIndex = m_hGroups->GetRootItemIndex();
|
||||
|
||||
bool selectionHasRoot = false;
|
||||
for ( i = 0 ; i < selection.Count(); ++i )
|
||||
{
|
||||
if ( selection[ i ] == rootIndex )
|
||||
{
|
||||
selectionHasRoot = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_SliderNames.RemoveAll();
|
||||
|
||||
if ( selectionHasRoot )
|
||||
{
|
||||
for ( i = 0; i < groups.Count(); ++i )
|
||||
{
|
||||
CDmElement *element = groups[ i ];
|
||||
if ( !element )
|
||||
continue;
|
||||
|
||||
const CDmrStringArray array( element, "selectedControls" );
|
||||
if ( array.IsValid() )
|
||||
{
|
||||
for ( int j = 0 ; j < array.Count(); ++j )
|
||||
{
|
||||
const char *sliderName = array[ j ];
|
||||
if ( sliderName && *sliderName )
|
||||
{
|
||||
m_SliderNames.AddString( sliderName );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0 ; i < selection.Count(); ++i )
|
||||
{
|
||||
if ( selection[ i ] == rootIndex )
|
||||
continue;
|
||||
|
||||
KeyValues *kv = m_hGroups->GetItemData( selection[ i ] );
|
||||
if ( !kv )
|
||||
continue;
|
||||
|
||||
int groupNumber = kv->GetInt( "groupNumber" );
|
||||
if ( groupNumber < 0 || groupNumber >= groupCount )
|
||||
{
|
||||
const char *sliderName = kv->GetString( "text" );
|
||||
if ( sliderName && *sliderName )
|
||||
{
|
||||
m_SliderNames.AddString( sliderName );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
CDmElement *element = groups[ groupNumber ];
|
||||
if ( !element )
|
||||
continue;
|
||||
|
||||
const CDmrStringArray array( element, "selectedControls" );
|
||||
if ( array.IsValid() )
|
||||
{
|
||||
for ( int j = 0 ; j < array.Count(); ++j )
|
||||
{
|
||||
const char *sliderName = array[ j ];
|
||||
if ( sliderName && *sliderName )
|
||||
{
|
||||
m_SliderNames.AddString( sliderName );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now notify the attribute slider panel
|
||||
CBaseAnimSetAttributeSliderPanel *attSliders = m_hEditor->GetAttributeSlider();
|
||||
if ( attSliders )
|
||||
{
|
||||
attSliders->SetVisibleControlsForSelectionGroup( m_SliderNames );
|
||||
}
|
||||
}
|
||||
|
||||
void CBaseAnimSetControlGroupPanel::ChangeAnimationSet( CDmeAnimationSet *newAnimSet )
|
||||
{
|
||||
bool changed = m_AnimSet.Get() != newAnimSet ? true : false;
|
||||
|
||||
m_AnimSet = newAnimSet;
|
||||
|
||||
if ( !m_AnimSet.Get() )
|
||||
{
|
||||
m_hGroups->RemoveAll();
|
||||
m_hSelectableIndices.RemoveAll();
|
||||
m_GroupList.RemoveAll();
|
||||
return;
|
||||
}
|
||||
|
||||
// Compare groups
|
||||
bool bRebuildGroups = false;
|
||||
const CDmaElementArray< CDmElement > &groups = m_AnimSet->GetSelectionGroups();
|
||||
int c = groups.Count();
|
||||
if ( c != m_GroupList.Count() )
|
||||
{
|
||||
bRebuildGroups = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
CDmElement *group = groups[ i ];
|
||||
if ( group == m_GroupList[ i ].Get() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bRebuildGroups = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( bRebuildGroups )
|
||||
{
|
||||
m_hGroups->SetFont( scheme()->GetIScheme( GetScheme() )->GetFont( "DefaultBold", IsProportional() ) );
|
||||
|
||||
// Build a tree of every open item in the tree view
|
||||
OpenItemTree_t openItems;
|
||||
int nRootIndex = m_hGroups->GetRootItemIndex();
|
||||
if ( nRootIndex != -1 )
|
||||
{
|
||||
BuildOpenItemList( openItems, openItems.InvalidIndex(), nRootIndex );
|
||||
}
|
||||
|
||||
m_hGroups->RemoveAll();
|
||||
m_hSelectableIndices.RemoveAll();
|
||||
m_GroupList.RemoveAll();
|
||||
|
||||
|
||||
// Create root
|
||||
int rootIndex = AddItemToTree( m_hGroups, "root", -1, Color( 128, 128, 128, 255 ), -1, (int)DMELEMENT_HANDLE_INVALID );
|
||||
|
||||
Color defaultColor( 0, 128, 255, 255 );
|
||||
|
||||
CAppUndoScopeGuard *guard = NULL;
|
||||
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
CDmElement *group = groups[ i ];
|
||||
|
||||
if ( !group->HasAttribute( "treeColor" ) )
|
||||
{
|
||||
if ( !guard )
|
||||
{
|
||||
guard = new CAppUndoScopeGuard( NOTIFY_SETDIRTYFLAG, "Set Default Colors" );
|
||||
}
|
||||
group->SetValue< Color >( "treeColor", defaultColor );
|
||||
}
|
||||
int groupIndex = AddItemToTree( m_hGroups, group->GetName(), rootIndex, group->GetValue< Color >( "treeColor" ), i, (int)group->GetHandle() );
|
||||
|
||||
const CDmrStringArray array( group, "selectedControls" );
|
||||
if ( array.IsValid() )
|
||||
{
|
||||
for ( int j = 0 ; j < array.Count(); ++j )
|
||||
{
|
||||
AddItemToTree( m_hGroups, array[ j ], groupIndex, Color( 200, 200, 200, 255 ), -1, (int)DMELEMENT_HANDLE_INVALID );
|
||||
}
|
||||
}
|
||||
m_hSelectableIndices.AddToTail( groupIndex );
|
||||
|
||||
m_GroupList.AddToTail( group->GetHandle() );
|
||||
}
|
||||
|
||||
if ( ( nRootIndex >= 0 ) && ( rootIndex >= 0 ) && !changed )
|
||||
{
|
||||
// Iterate through all previously open items and expand them if they exist
|
||||
if ( openItems.Root() != openItems.InvalidIndex() )
|
||||
{
|
||||
ExpandOpenItems( openItems, openItems.Root(), rootIndex, true );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hGroups->ExpandItem( rootIndex, true );
|
||||
}
|
||||
|
||||
if ( guard )
|
||||
{
|
||||
delete guard;
|
||||
}
|
||||
}
|
||||
|
||||
if ( changed )
|
||||
{
|
||||
for ( int i = 0; i < m_hSelectableIndices.Count(); ++i )
|
||||
{
|
||||
|
||||
m_hGroups->AddSelectedItem( m_hSelectableIndices[ i ],
|
||||
false, // don't clear selection
|
||||
true, // put focus on tree
|
||||
false ); // don't expand tree to make all of these visible...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Expands all items in the open item tree if they exist
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAnimSetControlGroupPanel::ExpandOpenItems( OpenItemTree_t &tree, int nOpenTreeIndex, int nItemIndex, bool makeVisible )
|
||||
{
|
||||
int i = tree.FirstChild( nOpenTreeIndex );
|
||||
if ( nOpenTreeIndex != tree.InvalidIndex() )
|
||||
{
|
||||
TreeInfo_t& info = tree[ nOpenTreeIndex ];
|
||||
if ( info.m_nFlags & EP_EXPANDED )
|
||||
{
|
||||
// Expand the item
|
||||
m_hGroups->ExpandItem( nItemIndex , true );
|
||||
}
|
||||
if ( info.m_nFlags & EP_SELECTED )
|
||||
{
|
||||
m_hGroups->AddSelectedItem( nItemIndex, false, false );
|
||||
if ( makeVisible )
|
||||
{
|
||||
m_hGroups->MakeItemVisible( nItemIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while ( i != tree.InvalidIndex() )
|
||||
{
|
||||
TreeInfo_t& info = tree[ i ];
|
||||
// Look for a match
|
||||
int nChildIndex = FindTreeItem( nItemIndex, info.m_Item );
|
||||
if ( nChildIndex != -1 )
|
||||
{
|
||||
ExpandOpenItems( tree, i, nChildIndex, makeVisible );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( info.m_nFlags & EP_SELECTED )
|
||||
{
|
||||
// Look for preserved item
|
||||
nChildIndex = FindTreeItem( nItemIndex, info.m_Item );
|
||||
if ( nChildIndex != -1 )
|
||||
{
|
||||
m_hGroups->AddSelectedItem( nChildIndex, false, false );
|
||||
if ( makeVisible )
|
||||
{
|
||||
m_hGroups->MakeItemVisible( nChildIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
i = tree.NextSibling( i );
|
||||
}
|
||||
}
|
||||
|
||||
void CBaseAnimSetControlGroupPanel::FillInDataForItem( TreeItem_t &item, int nItemIndex )
|
||||
{
|
||||
KeyValues *data = m_hGroups->GetItemData( nItemIndex );
|
||||
if ( !data )
|
||||
return;
|
||||
|
||||
item.m_pAttributeName = data->GetString( "text" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Builds a list of open items
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAnimSetControlGroupPanel::BuildOpenItemList( OpenItemTree_t &tree, int nParent, int nItemIndex )
|
||||
{
|
||||
KeyValues *data = m_hGroups->GetItemData( nItemIndex );
|
||||
if ( !data )
|
||||
return;
|
||||
|
||||
bool expanded = m_hGroups->IsItemExpanded( nItemIndex );
|
||||
bool selected = m_hGroups->IsItemSelected( nItemIndex );
|
||||
|
||||
int flags = 0;
|
||||
if ( expanded )
|
||||
{
|
||||
flags |= EP_EXPANDED;
|
||||
}
|
||||
if ( selected )
|
||||
{
|
||||
flags |= EP_SELECTED;
|
||||
}
|
||||
|
||||
int nChild = tree.InsertChildAfter( nParent, tree.InvalidIndex() );
|
||||
TreeInfo_t &info = tree[nChild];
|
||||
FillInDataForItem( info.m_Item, nItemIndex );
|
||||
info.m_nFlags = flags;
|
||||
|
||||
// Deal with children
|
||||
int nCount = m_hGroups->GetNumChildren( nItemIndex );
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
int nChildIndex = m_hGroups->GetChild( nItemIndex, i );
|
||||
BuildOpenItemList( tree, nChild, nChildIndex );
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Finds the tree index of a child matching the particular element + attribute
|
||||
//-----------------------------------------------------------------------------
|
||||
int CBaseAnimSetControlGroupPanel::FindTreeItem( int nParentIndex, const TreeItem_t &info )
|
||||
{
|
||||
// Look for a match
|
||||
int nCount = m_hGroups->GetNumChildren( nParentIndex );
|
||||
for ( int i = nCount; --i >= 0; )
|
||||
{
|
||||
int nChildIndex = m_hGroups->GetChild( nParentIndex, i );
|
||||
KeyValues *data = m_hGroups->GetItemData( nChildIndex );
|
||||
Assert( data );
|
||||
|
||||
const char *pAttributeName = data->GetString( "text" );
|
||||
if ( !Q_stricmp( pAttributeName, info.m_pAttributeName ) )
|
||||
{
|
||||
return nChildIndex;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,91 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/BaseAttributeChoicePanel.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CBaseAttributeChoicePanel::CBaseAttributeChoicePanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info ), m_pData( 0 )
|
||||
{
|
||||
SetDropEnabled( false );
|
||||
m_pData = new vgui::ComboBox( this, "AttributeValue", 10, false );
|
||||
m_pData->SetEnabled( !HasFlag( FATTRIB_READONLY ) );
|
||||
m_pData->AddActionSignalTarget( this );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called after the constructor is finished
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAttributeChoicePanel::PostConstructor()
|
||||
{
|
||||
BaseClass::PostConstructor();
|
||||
PopulateComboBox( m_pData );
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
void CBaseAttributeChoicePanel::ApplySchemeSettings( IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
HFont font = pScheme->GetFont( "DmePropertyVerySmall", IsProportional() );
|
||||
m_pData->SetFont(font);
|
||||
}
|
||||
|
||||
vgui::Panel *CBaseAttributeChoicePanel::GetDataPanel()
|
||||
{
|
||||
return static_cast< vgui::Panel * >( m_pData );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it is time to set the attribute from the combo box state
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAttributeChoicePanel::Apply( )
|
||||
{
|
||||
KeyValues *kv = m_pData->GetActiveItemUserData();
|
||||
SetAttributeFromComboBox( m_pData, kv );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it is time to set the combo box from the attribute
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAttributeChoicePanel::Refresh()
|
||||
{
|
||||
SetComboBoxFromAttribute( m_pData );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the text in the panel changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAttributeChoicePanel::OnTextChanged( Panel *panel )
|
||||
{
|
||||
if ( IsAutoApply() )
|
||||
{
|
||||
Apply();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDirty(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/BaseAttributeDoubleChoicePanel.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
CDoubleComboBoxContainerPanel::CDoubleComboBoxContainerPanel( vgui::Panel *parent, char const *name ) :
|
||||
BaseClass( parent, name )
|
||||
{
|
||||
m_pBoxes[ 0 ] = m_pBoxes[ 1 ] = NULL;
|
||||
}
|
||||
|
||||
void CDoubleComboBoxContainerPanel::AddComboBox( int slot, vgui::ComboBox *box )
|
||||
{
|
||||
m_pBoxes[ slot ] = box;
|
||||
}
|
||||
|
||||
void CDoubleComboBoxContainerPanel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
if ( m_pBoxes[ 0 ] )
|
||||
{
|
||||
m_pBoxes[ 0 ]->SetBounds( 0, 0, w/2, h );
|
||||
}
|
||||
if ( m_pBoxes[ 1 ] )
|
||||
{
|
||||
m_pBoxes[ 1 ]->SetBounds( w/2, 0, w/2, h );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CBaseAttributeDoubleChoicePanel::CBaseAttributeDoubleChoicePanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
SetDropEnabled( false );
|
||||
|
||||
m_pContainerPanel = new CDoubleComboBoxContainerPanel( this, "Container" );
|
||||
m_pData[0] = new vgui::ComboBox( m_pContainerPanel, "AttributeValue", 10, false );
|
||||
m_pData[0]->SetEnabled( !HasFlag( FATTRIB_READONLY ) );
|
||||
m_pData[0]->AddActionSignalTarget( this );
|
||||
m_pContainerPanel->AddComboBox( 0, m_pData[ 0 ] );
|
||||
m_pData[1] = new vgui::ComboBox( m_pContainerPanel, "AttributeValue", 10, false );
|
||||
m_pData[1]->SetEnabled( !HasFlag( FATTRIB_READONLY ) );
|
||||
m_pData[1]->AddActionSignalTarget( this );
|
||||
m_pContainerPanel->AddComboBox( 1, m_pData[ 1 ] );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called after the constructor is finished
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAttributeDoubleChoicePanel::PostConstructor()
|
||||
{
|
||||
BaseClass::PostConstructor();
|
||||
PopulateComboBoxes( m_pData );
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
void CBaseAttributeDoubleChoicePanel::ApplySchemeSettings( IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
HFont font = pScheme->GetFont( "DmePropertyVerySmall", IsProportional() );
|
||||
m_pData[0]->SetFont(font);
|
||||
m_pData[1]->SetFont(font);
|
||||
}
|
||||
|
||||
vgui::Panel *CBaseAttributeDoubleChoicePanel::GetDataPanel()
|
||||
{
|
||||
return static_cast< vgui::Panel * >( m_pContainerPanel );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it is time to set the attribute from the combo box state
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAttributeDoubleChoicePanel::Apply( )
|
||||
{
|
||||
Assert( m_pData[ 0 ] && m_pData[ 1 ] );
|
||||
|
||||
KeyValues *kv[ 2 ];
|
||||
kv[ 0 ] = m_pData[ 0 ]->GetActiveItemUserData();
|
||||
kv[ 1 ] = m_pData[ 1 ]->GetActiveItemUserData();
|
||||
|
||||
SetAttributeFromComboBoxes( m_pData, kv );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it is time to set the combo box from the attribute
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAttributeDoubleChoicePanel::Refresh()
|
||||
{
|
||||
SetComboBoxesFromAttribute( m_pData );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the text in the panel changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAttributeDoubleChoicePanel::OnTextChanged( Panel *panel )
|
||||
{
|
||||
SetDirty(true);
|
||||
if ( IsAutoApply() )
|
||||
{
|
||||
Apply();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,365 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: base class for all element attribute panels
|
||||
// An attribute panel is a one line widget that can be used by a list
|
||||
// or tree control.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/BaseAttributePanel.h"
|
||||
#include "dme_controls/attributewidgetfactory.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui_controls/Label.h"
|
||||
#include "movieobjects/dmeeditortypedictionary.h"
|
||||
#include "dme_controls/inotifyui.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Lessfunc for columns.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBaseAttributePanel::ColInfoLessFunc( const CBaseAttributePanel::colinfo_t& lhs, const CBaseAttributePanel::colinfo_t& rhs )
|
||||
{
|
||||
return lhs.panel < rhs.panel;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CBaseAttributePanel constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CBaseAttributePanel::CBaseAttributePanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info.m_pAttributeName ),
|
||||
m_pType( 0 ),
|
||||
m_hObject( info.m_pElement ),
|
||||
m_hEditorInfo( info.m_pEditorInfo ),
|
||||
m_hEditorTypeDict( info.m_pEditorTypeDictionary ),
|
||||
m_pNotify( info.m_pNotify ),
|
||||
m_nArrayIndex( info.m_nArrayIndex ),
|
||||
m_ColumnSize( 0, 0, ColInfoLessFunc )
|
||||
{
|
||||
Assert( info.m_pElement );
|
||||
|
||||
InitializeFlags( info );
|
||||
|
||||
Assert( info.m_pAttributeName );
|
||||
Q_strncpy( m_szAttributeName, info.m_pAttributeName, sizeof( m_szAttributeName ) );
|
||||
|
||||
m_pType = new Label( this, "AttributeType", "" );
|
||||
SetColumnSize( m_pType, 100 );
|
||||
|
||||
CDmAttribute *pAttribute = info.m_pElement->GetAttribute( info.m_pAttributeName );
|
||||
m_AttributeType = pAttribute ? pAttribute->GetType() : AT_UNKNOWN;
|
||||
if ( m_nArrayIndex >= 0 )
|
||||
{
|
||||
m_AttributeType = ArrayTypeToValueType( m_AttributeType );
|
||||
}
|
||||
|
||||
m_pType->SetText( g_pDataModel->GetAttributeNameForType( m_AttributeType ) );
|
||||
|
||||
m_hFont = NULL;
|
||||
|
||||
// These are draggable
|
||||
SetDragEnabled( true );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This only exists so every class always can chain PostConstructors
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAttributePanel::PostConstructor()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initializes flags from the attribute editor info
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAttributePanel::InitializeFlags( const AttributeWidgetInfo_t &info )
|
||||
{
|
||||
m_nFlags = 0;
|
||||
if ( info.m_pEditorInfo )
|
||||
{
|
||||
if ( info.m_pEditorInfo->m_bHideType )
|
||||
{
|
||||
m_nFlags |= HIDETYPE;
|
||||
}
|
||||
if ( info.m_pEditorInfo->m_bHideValue )
|
||||
{
|
||||
m_nFlags |= HIDEVALUE;
|
||||
}
|
||||
if ( info.m_pEditorInfo->m_bIsReadOnly )
|
||||
{
|
||||
m_nFlags |= READONLY;
|
||||
}
|
||||
}
|
||||
|
||||
CDmAttribute *pAttribute = info.m_pElement->GetAttribute( info.m_pAttributeName );
|
||||
if ( pAttribute && pAttribute->IsFlagSet( FATTRIB_READONLY ) )
|
||||
{
|
||||
m_nFlags |= READONLY;
|
||||
}
|
||||
|
||||
if ( info.m_bAutoApply )
|
||||
{
|
||||
m_nFlags |= AUTOAPPLY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the editor info
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmeEditorTypeDictionary *CBaseAttributePanel::GetEditorTypeDictionary()
|
||||
{
|
||||
return m_hEditorTypeDict;
|
||||
}
|
||||
|
||||
CDmeEditorAttributeInfo *CBaseAttributePanel::GetEditorInfo()
|
||||
{
|
||||
return m_hEditorInfo;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Does the element have the attribute we're attempting to reference?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBaseAttributePanel::HasAttribute() const
|
||||
{
|
||||
return GetPanelElement()->HasAttribute( m_szAttributeName );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the attribute array count
|
||||
//-----------------------------------------------------------------------------
|
||||
int CBaseAttributePanel::GetAttributeArrayCount() const
|
||||
{
|
||||
CDmrGenericArrayConst array( GetPanelElement(), m_szAttributeName );
|
||||
return array.IsValid() ? array.Count() : -1;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the font
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAttributePanel::SetFont( HFont font )
|
||||
{
|
||||
m_hFont = font;
|
||||
m_pType->SetFont(font);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Applies scheme settings
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAttributePanel::ApplySchemeSettings( IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
// set the color of the "type" column
|
||||
m_pType->SetFgColor( Color ( 160, 160, 160, 255 ) );
|
||||
|
||||
if ( GetDirty() )
|
||||
{
|
||||
SetBgColor( pScheme->GetColor( "AttributeWidget.DirtyBgColor", Color( 100, 100, 200, 63 ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBgColor( pScheme->GetColor( "Panel.BgColor", Color( 0, 0, 0, 0 ) ) );
|
||||
}
|
||||
HFont font = pScheme->GetFont( "DmePropertyVerySmall", IsProportional() );
|
||||
// m_pType->SetFont(font);
|
||||
|
||||
if ( !m_hFont )
|
||||
{
|
||||
m_hFont = font;
|
||||
}
|
||||
SetFont( m_hFont );
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the panel element
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmElement *CBaseAttributePanel::GetPanelElement()
|
||||
{
|
||||
return m_hObject;
|
||||
}
|
||||
|
||||
const CDmElement *CBaseAttributePanel::GetPanelElement() const
|
||||
{
|
||||
return m_hObject;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets/Sets the attribute value from a string
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAttributePanel::SetAttributeValueFromString( const char *pString )
|
||||
{
|
||||
if ( m_nArrayIndex < 0 )
|
||||
{
|
||||
GetPanelElement()->SetValueFromString( m_szAttributeName, pString );
|
||||
}
|
||||
else
|
||||
{
|
||||
CDmrGenericArray array( GetPanelElement(), m_szAttributeName );
|
||||
array.SetFromString( m_nArrayIndex, pString );
|
||||
}
|
||||
}
|
||||
|
||||
const char *CBaseAttributePanel::GetAttributeValueAsString( char *pBuf, int nLength )
|
||||
{
|
||||
if ( m_nArrayIndex < 0 )
|
||||
{
|
||||
GetPanelElement()->GetValueAsString( m_szAttributeName, pBuf, nLength );
|
||||
}
|
||||
else
|
||||
{
|
||||
CDmrGenericArray array( GetPanelElement(), m_szAttributeName );
|
||||
array.GetAsString( m_nArrayIndex, pBuf, nLength );
|
||||
}
|
||||
return pBuf;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper to get/set the attribute value for elements
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmElement *CBaseAttributePanel::GetAttributeValueElement()
|
||||
{
|
||||
return GetElement< CDmElement >( GetAttributeValue<DmElementHandle_t>( ) );
|
||||
}
|
||||
|
||||
void CBaseAttributePanel::SetAttributeValueElement( CDmElement *pElement )
|
||||
{
|
||||
return SetAttributeValue( pElement->GetHandle() );
|
||||
}
|
||||
|
||||
|
||||
void CBaseAttributePanel::SetDirty( bool dirty )
|
||||
{
|
||||
SetFlag( DIRTY, dirty );
|
||||
InvalidateLayout( false, true );
|
||||
}
|
||||
|
||||
void CBaseAttributePanel::SetColumnSize( Panel *panel, int width )
|
||||
{
|
||||
colinfo_t search;
|
||||
search.panel = panel;
|
||||
int idx = m_ColumnSize.Find( search );
|
||||
if ( idx == m_ColumnSize.InvalidIndex() )
|
||||
{
|
||||
idx = m_ColumnSize.Insert( search );
|
||||
}
|
||||
m_ColumnSize[ idx ].width = width;
|
||||
}
|
||||
|
||||
int CBaseAttributePanel::GetSizeForColumn( Panel *panel )
|
||||
{
|
||||
colinfo_t search;
|
||||
search.panel = panel;
|
||||
int idx = m_ColumnSize.Find( search );
|
||||
if ( idx == m_ColumnSize.InvalidIndex() )
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
return m_ColumnSize[ idx ].width;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates a widget using editor attribute info
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAttributePanel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
CUtlVector< Panel * > vispanels;
|
||||
|
||||
if ( HasFlag( HIDETYPE ) )
|
||||
{
|
||||
m_pType->SetVisible( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
vispanels.AddToTail( m_pType );
|
||||
}
|
||||
|
||||
vgui::Panel *dataPanel = GetDataPanel();
|
||||
if ( dataPanel )
|
||||
{
|
||||
if ( HasFlag( HIDEVALUE ) )
|
||||
{
|
||||
dataPanel->SetVisible( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
vispanels.AddToTail( dataPanel );
|
||||
}
|
||||
}
|
||||
|
||||
int c = vispanels.Count();
|
||||
|
||||
Assert( c >= 0 );
|
||||
if ( c == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
int x = 1;
|
||||
int y = 0;
|
||||
w-= 2;
|
||||
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
Panel *panel = vispanels[ i ];
|
||||
int width = GetSizeForColumn( panel );
|
||||
if ( i == c - 1 )
|
||||
{
|
||||
width = w - x;
|
||||
}
|
||||
|
||||
panel->SetBounds( x, y, width, h );
|
||||
x += width;
|
||||
}
|
||||
}
|
||||
|
||||
void CBaseAttributePanel::OnApplyChanges()
|
||||
{
|
||||
Assert( !IsAutoApply() );
|
||||
|
||||
Apply();
|
||||
SetDirty(false);
|
||||
}
|
||||
|
||||
void CBaseAttributePanel::OnRefresh()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void CBaseAttributePanel::OnCreateDragData( KeyValues *msg )
|
||||
{
|
||||
if ( GetPanelElement() )
|
||||
{
|
||||
msg->SetInt( "root", GetPanelElement() ? GetPanelElement()->GetHandle() : DMELEMENT_HANDLE_INVALID );
|
||||
msg->SetString( "type", g_pDataModel->GetAttributeNameForType( m_AttributeType ) );
|
||||
msg->SetString( "attributename", m_szAttributeName );
|
||||
if ( m_nArrayIndex >= 0 )
|
||||
{
|
||||
msg->SetInt( "arrayIndex", m_nArrayIndex );
|
||||
}
|
||||
|
||||
if ( m_AttributeType != AT_ELEMENT && m_AttributeType != AT_ELEMENT_ARRAY )
|
||||
{
|
||||
char pTemp[512];
|
||||
GetAttributeValueAsString( pTemp, sizeof( pTemp ) );
|
||||
msg->SetString( "text", pTemp );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,368 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <dme_controls/ChannelGraphPanel.h>
|
||||
#include <vgui/IScheme.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/IVGui.h>
|
||||
#include "vgui/IInput.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
DECLARE_BUILD_FACTORY( CChannelGraphPanel );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CChannelGraphPanel::CChannelGraphPanel( Panel *parent, const char *name )
|
||||
: BaseClass( parent, name ), m_font( 0 ),
|
||||
m_graphMinTime( 0 ), m_graphMaxTime( 0 ),
|
||||
m_graphMinValue( 0.0f ), m_graphMaxValue( 0.0f ),
|
||||
m_nMouseStartX( -1 ), m_nMouseStartY( -1 ),
|
||||
m_nMouseLastX( -1 ), m_nMouseLastY( -1 ),
|
||||
m_nTextBorder( 2 ), m_nGraphOriginX( 40 ), m_nGraphOriginY( 10 )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CChannelGraphPanel::SetChannel( CDmeChannel *pChannel )
|
||||
{
|
||||
m_hChannel = pChannel;
|
||||
CDmeLog *pLog = m_hChannel->GetLog();
|
||||
m_graphMinTime = pLog->GetBeginTime();
|
||||
m_graphMaxTime = pLog->GetEndTime();
|
||||
|
||||
m_graphMinValue = FLT_MAX;
|
||||
m_graphMaxValue = -FLT_MAX;
|
||||
|
||||
int nComponents = NumComponents( pLog->GetDataType() );
|
||||
int nKeys = pLog->GetKeyCount();
|
||||
for ( int k = 0; k < nKeys; ++k )
|
||||
{
|
||||
DmeTime_t t = pLog->GetKeyTime( k );
|
||||
for ( int i = 0; i < nComponents; ++i )
|
||||
{
|
||||
float f = pLog->GetComponent( t, i );
|
||||
m_graphMinValue = min( m_graphMinValue, f );
|
||||
m_graphMaxValue = max( m_graphMaxValue, f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// input methods
|
||||
//-----------------------------------------------------------------------------
|
||||
void CChannelGraphPanel::OnSizeChanged( int newWide, int newTall ) // called after the size of a panel has been changed
|
||||
{
|
||||
int wide = newWide - m_nGraphOriginX;
|
||||
int tall = newTall - m_nGraphOriginY;
|
||||
m_flTimeToPixel = wide / ( m_graphMaxTime - m_graphMinTime ).GetSeconds();
|
||||
m_flValueToPixel = tall / ( m_graphMaxValue - m_graphMinValue );
|
||||
}
|
||||
|
||||
void CChannelGraphPanel::OnMousePressed( MouseCode code )
|
||||
{
|
||||
BaseClass::OnMousePressed( code );
|
||||
if ( code != MOUSE_LEFT )
|
||||
return;
|
||||
|
||||
vgui::input()->GetCursorPos( m_nMouseStartX, m_nMouseStartY );
|
||||
ScreenToLocal( m_nMouseStartX, m_nMouseStartY );
|
||||
m_nMouseLastX = m_nMouseStartX;
|
||||
m_nMouseLastY = m_nMouseStartY;
|
||||
|
||||
input()->SetMouseCapture( GetVPanel() );
|
||||
}
|
||||
|
||||
void CChannelGraphPanel::OnMouseReleased( MouseCode code )
|
||||
{
|
||||
BaseClass::OnMouseReleased( code );
|
||||
if ( code != MOUSE_LEFT )
|
||||
return;
|
||||
|
||||
m_nMouseStartX = m_nMouseStartY = -1;
|
||||
m_nMouseLastX = m_nMouseLastY = -1;
|
||||
|
||||
input()->SetMouseCapture( NULL );
|
||||
}
|
||||
|
||||
void CChannelGraphPanel::OnCursorMoved( int mx, int my )
|
||||
{
|
||||
BaseClass::OnCursorMoved( mx, my );
|
||||
if ( !vgui::input()->IsMouseDown( MOUSE_LEFT ) )
|
||||
return;
|
||||
|
||||
bool bInValueLegend = m_nMouseStartX < m_nGraphOriginX;
|
||||
bool bInTimeLegend = m_nMouseStartY > GetTall() - m_nGraphOriginY - 1;
|
||||
if ( bInTimeLegend && bInValueLegend )
|
||||
{
|
||||
bInTimeLegend = bInValueLegend = false;
|
||||
}
|
||||
|
||||
int dx = mx - m_nMouseLastX;
|
||||
int dy = my - m_nMouseLastY;
|
||||
|
||||
if ( bInTimeLegend )
|
||||
{
|
||||
if ( abs( dy ) > abs( dx ) )
|
||||
{
|
||||
m_graphMinTime -= DmeTime_t( dy / m_flTimeToPixel );
|
||||
m_graphMaxTime += DmeTime_t( dy / m_flTimeToPixel );
|
||||
m_flTimeToPixel = ( GetWide() - m_nGraphOriginX ) / ( m_graphMaxTime - m_graphMinTime ).GetSeconds();
|
||||
|
||||
int x = mx = m_nMouseLastX;
|
||||
int y = my = m_nMouseLastY;
|
||||
LocalToScreen( x, y );
|
||||
vgui::input()->SetCursorPos( x, y );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_graphMinTime -= DmeTime_t( dx / m_flTimeToPixel );
|
||||
m_graphMaxTime -= DmeTime_t( dx / m_flTimeToPixel );
|
||||
}
|
||||
}
|
||||
else if ( bInValueLegend )
|
||||
{
|
||||
if ( abs( dx ) > abs( dy ) )
|
||||
{
|
||||
m_graphMinValue += dx / m_flValueToPixel;
|
||||
m_graphMaxValue -= dx / m_flValueToPixel;
|
||||
m_flValueToPixel = ( GetTall() - m_nGraphOriginY ) / ( m_graphMaxValue - m_graphMinValue );
|
||||
|
||||
int x = mx = m_nMouseLastX;
|
||||
int y = my = m_nMouseLastY;
|
||||
LocalToScreen( x, y );
|
||||
vgui::input()->SetCursorPos( x, y );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_graphMinValue += dy / m_flValueToPixel;
|
||||
m_graphMaxValue += dy / m_flValueToPixel;
|
||||
}
|
||||
}
|
||||
|
||||
m_nMouseLastX = mx;
|
||||
m_nMouseLastY = my;
|
||||
}
|
||||
|
||||
void CChannelGraphPanel::OnMouseWheeled( int delta )
|
||||
{
|
||||
// TODO - zoom in around current time?
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: lays out the graph
|
||||
//-----------------------------------------------------------------------------
|
||||
void CChannelGraphPanel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
}
|
||||
|
||||
|
||||
float GetDisplayIncrement( int windowpixels, int fontpixels, float valuerange, int *pDecimalPlaces = NULL )
|
||||
{
|
||||
float ratio = valuerange * fontpixels / ( windowpixels );
|
||||
int nPower = ( int )ceil( log10( ratio ) );
|
||||
if ( pDecimalPlaces )
|
||||
{
|
||||
*pDecimalPlaces = max( 0, -nPower );
|
||||
}
|
||||
return pow( 10.0f, nPower );
|
||||
}
|
||||
|
||||
int CChannelGraphPanel::TimeToPixel( DmeTime_t time )
|
||||
{
|
||||
return m_nGraphOriginX + ( int )floor( m_flTimeToPixel * ( time - m_graphMinTime ).GetSeconds() + 0.5f );
|
||||
}
|
||||
|
||||
int CChannelGraphPanel::ValueToPixel( float flValue )
|
||||
{
|
||||
return m_nGraphOriginY + ( int )floor( m_flValueToPixel * ( flValue - m_graphMinValue ) + 0.5f );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: draws the graph
|
||||
//-----------------------------------------------------------------------------
|
||||
void CChannelGraphPanel::Paint()
|
||||
{
|
||||
// estimate the size of the graph marker text
|
||||
int wide = GetWide() - m_nGraphOriginX;
|
||||
int tall = GetTall() - m_nGraphOriginY;
|
||||
|
||||
int textwidth = 40, textheight = 10;
|
||||
surface()->GetTextSize( m_font, L"999.9", textwidth, textheight );
|
||||
|
||||
// draw current time marker
|
||||
DmeTime_t curtime = m_hChannel->GetCurrentTime();
|
||||
if ( curtime >= m_graphMinTime && curtime <= m_graphMaxTime )
|
||||
{
|
||||
Color cyan( 0, 255, 255, 255 );
|
||||
surface()->DrawSetColor( cyan );
|
||||
int x = TimeToPixel( curtime );
|
||||
surface()->DrawLine( x, 0, x, GetTall() - m_nGraphOriginY - 1 );
|
||||
}
|
||||
|
||||
// draw left/bottom graph border
|
||||
Color black( 0, 0, 0, 255 );
|
||||
surface()->DrawSetColor( black );
|
||||
surface()->DrawLine( m_nGraphOriginX, GetTall() - m_nGraphOriginY - 1, GetWide(), GetTall() - m_nGraphOriginY - 1 );
|
||||
surface()->DrawLine( m_nGraphOriginX, GetTall() - m_nGraphOriginY - 1, m_nGraphOriginX, 0 );
|
||||
|
||||
surface()->DrawSetTextColor( black );
|
||||
surface()->DrawSetTextFont( m_font );
|
||||
|
||||
// draw graph tickmarks and values along the left border
|
||||
int nDecimalPlaces = 0;
|
||||
float flValueIncrement = GetDisplayIncrement( tall, ( int )( 1.5f * textheight ), m_graphMaxValue - m_graphMinValue, &nDecimalPlaces );
|
||||
int nMinValueIndex = ( int )ceil ( m_graphMinValue / flValueIncrement );
|
||||
int nMaxValueIndex = ( int )floor( m_graphMaxValue / flValueIncrement );
|
||||
float flValue = nMinValueIndex * flValueIncrement;
|
||||
for ( int i = nMinValueIndex; i <= nMaxValueIndex; ++i, flValue += flValueIncrement )
|
||||
{
|
||||
wchar_t pFormat[ 32 ];
|
||||
V_swprintf_safe( pFormat, L"%%.%df", nDecimalPlaces );
|
||||
|
||||
wchar_t wstring[ 32 ];
|
||||
V_swprintf_safe( wstring, pFormat, flValue );
|
||||
|
||||
int tw = 0, th = 0;
|
||||
surface()->GetTextSize( m_font, wstring, tw, th );
|
||||
|
||||
int y = GetTall() - ValueToPixel( flValue ) - 1;
|
||||
surface()->DrawSetTextPos( m_nGraphOriginX - m_nTextBorder - tw, y - textheight / 2 );
|
||||
surface()->DrawPrintText( wstring, wcslen( wstring ) );
|
||||
|
||||
surface()->DrawLine( m_nGraphOriginX - m_nTextBorder, y, m_nGraphOriginX, y );
|
||||
}
|
||||
|
||||
// draw graph tickmarks and times along the bottom border
|
||||
float flTimeIncrement = GetDisplayIncrement( wide, textwidth, ( m_graphMaxTime - m_graphMinTime ).GetSeconds(), &nDecimalPlaces );
|
||||
int nMinTimeIndex = ( int )ceil ( m_graphMinTime.GetSeconds() / flTimeIncrement );
|
||||
int nMaxTimeIndex = ( int )floor( m_graphMaxTime.GetSeconds() / flTimeIncrement );
|
||||
float flTime = nMinTimeIndex * flTimeIncrement;
|
||||
for ( int i = nMinTimeIndex; i <= nMaxTimeIndex; ++i, flTime += flTimeIncrement )
|
||||
{
|
||||
wchar_t pFormat[ 32 ];
|
||||
V_swprintf_safe( pFormat, L"%%.%df", nDecimalPlaces );
|
||||
|
||||
wchar_t wstring[ 32 ];
|
||||
V_swprintf_safe( wstring, pFormat, flTime );
|
||||
|
||||
int tw = 0, th = 0;
|
||||
surface()->GetTextSize( m_font, wstring, tw, th );
|
||||
|
||||
int x = TimeToPixel( DmeTime_t( flTime ) );
|
||||
surface()->DrawSetTextPos( x - tw / 2, GetTall() - m_nGraphOriginY + m_nTextBorder - 1 );
|
||||
surface()->DrawPrintText( wstring, wcslen( wstring ) );
|
||||
|
||||
surface()->DrawLine( x, GetTall() - m_nGraphOriginY + m_nTextBorder - 1, x, GetTall() - m_nGraphOriginY - 1 );
|
||||
}
|
||||
|
||||
static Color s_componentColors[] =
|
||||
{
|
||||
Color( 255, 0, 0, 255 ),
|
||||
Color( 0, 255, 0, 255 ),
|
||||
Color( 0, 0, 255, 255 ),
|
||||
Color( 0, 0, 0, 255 ),
|
||||
};
|
||||
|
||||
CDmeLog *pLog = m_hChannel->GetLog();
|
||||
int nComponents = NumComponents( pLog->GetDataType() );
|
||||
int nKeys = pLog->GetKeyCount();
|
||||
|
||||
// draw plotted graph
|
||||
for ( int i = 0; i < nComponents; ++i )
|
||||
{
|
||||
Color &color = s_componentColors[ i % ARRAYSIZE( s_componentColors ) ];
|
||||
surface()->DrawSetColor( color );
|
||||
|
||||
int lastx = -1;
|
||||
int lasty = -1;
|
||||
for ( int k = 0; k < nKeys; ++k )
|
||||
{
|
||||
DmeTime_t t = pLog->GetKeyTime( k );
|
||||
float f = pLog->GetComponent( t, i );
|
||||
int x = TimeToPixel( t );
|
||||
int y = GetTall() - ValueToPixel( f ) - 1;
|
||||
if ( k )
|
||||
{
|
||||
surface()->DrawLine( lastx, lasty, x, y );
|
||||
}
|
||||
lastx = x;
|
||||
lasty = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets up colors
|
||||
//-----------------------------------------------------------------------------
|
||||
void CChannelGraphPanel::ApplySchemeSettings(IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
|
||||
m_font = pScheme->GetFont( "DefaultVerySmall" );
|
||||
|
||||
surface()->GetTextSize( m_font, L"999.9", m_nGraphOriginX, m_nGraphOriginY );
|
||||
m_nGraphOriginX += 2 * m_nTextBorder;
|
||||
m_nGraphOriginY += 2 * m_nTextBorder;
|
||||
|
||||
SetFgColor(GetSchemeColor("CChannelGraphPanel.FgColor", pScheme));
|
||||
SetBgColor(GetSchemeColor("CChannelGraphPanel.BgColor", pScheme));
|
||||
SetBorder(pScheme->GetBorder("ButtonDepressedBorder"));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// CChannelGraphFrame methods
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CChannelGraphFrame::CChannelGraphFrame( Panel *parent, const char *pTitle )
|
||||
: BaseClass( parent, "CChannelGraphFrame" )
|
||||
{
|
||||
SetTitle( pTitle, true );
|
||||
|
||||
SetSizeable( true );
|
||||
SetCloseButtonVisible( true );
|
||||
SetMinimumSize( 200, 100 );
|
||||
|
||||
SetVisible( true );
|
||||
|
||||
SetSize( 400, 200 );
|
||||
SetPos( 100, 100 );
|
||||
|
||||
m_pChannelGraph = new CChannelGraphPanel( this, "ChannelGraph" );
|
||||
|
||||
SetScheme( vgui::scheme()->LoadSchemeFromFile( "Resource/BoxRocket.res", "BoxRocket" ) );
|
||||
}
|
||||
|
||||
void CChannelGraphFrame::SetChannel( CDmeChannel *pChannel )
|
||||
{
|
||||
m_pChannelGraph->SetChannel( pChannel );
|
||||
}
|
||||
|
||||
void CChannelGraphFrame::OnCommand( const char *cmd )
|
||||
{
|
||||
BaseClass::OnCommand( cmd );
|
||||
m_pChannelGraph->OnCommand( cmd );
|
||||
}
|
||||
|
||||
void CChannelGraphFrame::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
int border = 5;
|
||||
int iWidth, iHeight;
|
||||
GetSize( iWidth, iHeight );
|
||||
m_pChannelGraph->SetPos( border, GetCaptionHeight() + border );
|
||||
m_pChannelGraph->SetSize( iWidth - 2 * border, iHeight - GetCaptionHeight() - 2 * border );
|
||||
}
|
||||
@@ -0,0 +1,488 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dme_controls/DmeSourceDCCFilePanel.h"
|
||||
#include "dme_controls/DmePanel.h"
|
||||
#include "movieobjects/dmedccmakefile.h"
|
||||
#include "vgui_controls/TextEntry.h"
|
||||
#include "vgui_controls/ListPanel.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "vgui_controls/InputDialog.h"
|
||||
#include "vgui_controls/MessageBox.h"
|
||||
#include "vgui/keycode.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Hook into the dme panel editor system
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_DMEPANEL_FACTORY( CDmeSourceDCCFilePanel, DmeSourceDCCFile, "DmeSourceDCCFileDefault", "Maya/XSI Source File Editor", true );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sort by MDL name
|
||||
//-----------------------------------------------------------------------------
|
||||
static int __cdecl DccObjectSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 )
|
||||
{
|
||||
const char *string1 = item1.kv->GetString( "dccobject" );
|
||||
const char *string2 = item2.kv->GetString( "dccobject" );
|
||||
return Q_stricmp( string1, string2 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmeSourceDCCFilePanel::CDmeSourceDCCFilePanel( vgui::Panel *pParent, const char *pPanelName ) :
|
||||
BaseClass( pParent, pPanelName )
|
||||
{
|
||||
m_pRootDCCObjects = new vgui::ListPanel( this, "DCCObjectList" );
|
||||
m_pRootDCCObjects->AddColumnHeader( 0, "dccobject", "Maya/XSI Object Name", 100, 0 );
|
||||
m_pRootDCCObjects->AddActionSignalTarget( this );
|
||||
m_pRootDCCObjects->SetSortFunc( 0, DccObjectSortFunc );
|
||||
m_pRootDCCObjects->SetSortColumn( 0 );
|
||||
// m_pRootDCCObjects->SetSelectIndividualCells( true );
|
||||
m_pRootDCCObjects->SetEmptyListText("No sources");
|
||||
// m_pRootDCCObjects->SetDragEnabled( true );
|
||||
|
||||
m_pDCCObjectBrowser = new vgui::Button( this, "DCCObjectBrowser", "...", this, "OnBrowseDCCObject" );
|
||||
m_pDCCObjectName = new vgui::TextEntry( this, "DCCObjectName" );
|
||||
m_pDCCObjectName->SendNewLine( true );
|
||||
m_pDCCObjectName->AddActionSignalTarget( this );
|
||||
|
||||
m_pAddDCCObject = new vgui::Button( this, "AddDCCObjectButton", "Add", this, "OnAddDCCObject" );
|
||||
m_pRemoveDCCObject = new vgui::Button( this, "RemoveDCCObjectButton", "Remove", this, "OnRemoveDCCObject" );
|
||||
|
||||
m_pApplyChanges = new vgui::Button( this, "ApplyChangesButton", "Apply", this, "OnApplyChanges" );
|
||||
|
||||
// Load layout settings; has to happen before pinning occurs in code
|
||||
LoadControlSettings( "resource/DmeSourceDCCFilePanel.res" );
|
||||
}
|
||||
|
||||
CDmeSourceDCCFilePanel::~CDmeSourceDCCFilePanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Marks the file as dirty (or not)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::SetDirty()
|
||||
{
|
||||
PostActionSignal( new KeyValues( "DmeElementChanged" ) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Refresh the source list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::RefreshDCCObjectList( )
|
||||
{
|
||||
m_pRootDCCObjects->RemoveAll();
|
||||
if ( !m_hSourceDCCFile.Get() )
|
||||
return;
|
||||
|
||||
int nCount = m_hSourceDCCFile->m_RootDCCObjects.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
KeyValues *pItemKeys = new KeyValues( "node", "dccobject", m_hSourceDCCFile->m_RootDCCObjects.Get(i) );
|
||||
pItemKeys->SetInt( "dccObjectIndex", i );
|
||||
m_pRootDCCObjects->AddItem( pItemKeys, 0, false, false );
|
||||
}
|
||||
|
||||
m_pRootDCCObjects->SortList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Resets the state
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::SetDmeElement( CDmeSourceDCCFile *pSourceDCCFile )
|
||||
{
|
||||
m_hSourceDCCFile = pSourceDCCFile;
|
||||
|
||||
bool bEnabled = ( pSourceDCCFile != NULL );
|
||||
m_pDCCObjectBrowser->SetEnabled( bEnabled );
|
||||
m_pAddDCCObject->SetEnabled( bEnabled );
|
||||
m_pRemoveDCCObject->SetEnabled( bEnabled );
|
||||
m_pApplyChanges->SetEnabled( bEnabled );
|
||||
if ( !bEnabled )
|
||||
{
|
||||
m_pRootDCCObjects->RemoveAll();
|
||||
m_pDCCObjectName->SetText( "" );
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshDCCObjectList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when a list panel's selection changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::OnItemSelectionChanged( )
|
||||
{
|
||||
int nCount = m_pRootDCCObjects->GetSelectedItemsCount();
|
||||
bool bEnabled = ( nCount > 0 );
|
||||
bool bMultiselect = ( nCount > 1 );
|
||||
m_pDCCObjectBrowser->SetEnabled( bEnabled && !bMultiselect );
|
||||
m_pDCCObjectName->SetEnabled( bEnabled && !bMultiselect );
|
||||
m_pApplyChanges->SetEnabled( bEnabled && !bMultiselect );
|
||||
m_pRemoveDCCObject->SetEnabled( bEnabled );
|
||||
if ( !bEnabled || bMultiselect )
|
||||
{
|
||||
m_pDCCObjectName->SetText( "" );
|
||||
return;
|
||||
}
|
||||
|
||||
int nItemID = m_pRootDCCObjects->GetSelectedItem( 0 );
|
||||
KeyValues *pKeyValues = m_pRootDCCObjects->GetItem( nItemID );
|
||||
m_pDCCObjectName->SetText( pKeyValues->GetString( "dccobject" ) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when a list panel's selection changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::OnItemSelected( KeyValues *kv )
|
||||
{
|
||||
Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL );
|
||||
if ( pPanel == m_pRootDCCObjects )
|
||||
{
|
||||
OnItemSelectionChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when a list panel's selection changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::OnItemDeselected( KeyValues *kv )
|
||||
{
|
||||
Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL );
|
||||
if ( pPanel == m_pRootDCCObjects )
|
||||
{
|
||||
OnItemSelectionChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when return is hit in a text entry field
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::OnTextNewLine( KeyValues *kv )
|
||||
{
|
||||
if ( !m_hSourceDCCFile.Get() )
|
||||
return;
|
||||
|
||||
Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL );
|
||||
if ( pPanel == m_pDCCObjectName )
|
||||
{
|
||||
OnDCCObjectNameChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Selects a particular DCC object
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::SelectDCCObject( int nDCCObjectIndex )
|
||||
{
|
||||
if ( nDCCObjectIndex < 0 )
|
||||
{
|
||||
m_pRootDCCObjects->ClearSelectedItems();
|
||||
return;
|
||||
}
|
||||
|
||||
int nItemID = m_pRootDCCObjects->FirstItem();
|
||||
for ( ; nItemID != m_pRootDCCObjects->InvalidItemID(); nItemID = m_pRootDCCObjects->NextItem( nItemID ) )
|
||||
{
|
||||
KeyValues *kv = m_pRootDCCObjects->GetItem( nItemID );
|
||||
if ( kv->GetInt( "dccObjectIndex", -1 ) != nDCCObjectIndex )
|
||||
continue;
|
||||
|
||||
m_pRootDCCObjects->SetSingleSelectedItem( nItemID );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when we're browsing for a DCC object and one was selected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::OnDCCObjectAdded( const char *pDCCObjectName, KeyValues *pContextKeys )
|
||||
{
|
||||
if ( !m_hSourceDCCFile.Get() )
|
||||
return;
|
||||
|
||||
if ( CheckForDuplicateNames( pDCCObjectName ) )
|
||||
return;
|
||||
|
||||
int nIndex = -1;
|
||||
{
|
||||
CDisableUndoScopeGuard guard;
|
||||
nIndex = m_hSourceDCCFile->m_RootDCCObjects.AddToTail( pDCCObjectName );
|
||||
}
|
||||
SetDirty( );
|
||||
RefreshDCCObjectList( );
|
||||
SelectDCCObject( nIndex );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the file open dialog for browsing source files selects something
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::OnInputCompleted( KeyValues *kv )
|
||||
{
|
||||
const char *pDCCObjectName = kv->GetString( "text", NULL );
|
||||
if ( !pDCCObjectName )
|
||||
return;
|
||||
|
||||
KeyValues *pDialogKeys = kv->FindKey( "ChangeDCCObject" );
|
||||
if ( pDialogKeys )
|
||||
{
|
||||
m_pDCCObjectName->SetText( pDCCObjectName );
|
||||
OnDCCObjectNameChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
pDialogKeys = kv->FindKey( "AddDCCObject" );
|
||||
if ( pDialogKeys )
|
||||
{
|
||||
OnDCCObjectAdded( pDCCObjectName, pDialogKeys );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shows the DCC object browser (once we have one)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::ShowDCCObjectBrowser( const char *pTitle, const char *pPrompt, KeyValues *pDialogKeys )
|
||||
{
|
||||
InputDialog *pInput = new InputDialog( this, pTitle, pPrompt );
|
||||
pInput->SetMultiline( false );
|
||||
pInput->DoModal( pDialogKeys );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the button to add a file is clicked
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::OnAddDCCObject( )
|
||||
{
|
||||
if ( m_hSourceDCCFile.Get() )
|
||||
{
|
||||
KeyValues *pDialogKeys = new KeyValues( "AddDCCObject" );
|
||||
ShowDCCObjectBrowser( "Add DCC Object", "Enter DCC object name to add", pDialogKeys );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the button to browse for a source file is clicked
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::OnBrowseDCCObject( )
|
||||
{
|
||||
int nCount = m_pRootDCCObjects->GetSelectedItemsCount();
|
||||
if ( nCount == 0 || !m_hSourceDCCFile.Get() )
|
||||
return;
|
||||
|
||||
int nItemID = m_pRootDCCObjects->GetSelectedItem( 0 );
|
||||
KeyValues *pKeyValues = m_pRootDCCObjects->GetItem( nItemID );
|
||||
int nDCCObjectIndex = pKeyValues->GetInt( "dccObjectIndex", -1 );
|
||||
|
||||
KeyValues *pDialogKeys = new KeyValues( "ChangeDCCObject", "dccObjectIndex", nDCCObjectIndex );
|
||||
ShowDCCObjectBrowser( "Edit Maya/XSI Object", "Enter new name of Maya/XSI object", pDialogKeys );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the source file name changes
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CDmeSourceDCCFilePanel::CheckForDuplicateNames( const char *pDCCObjectName, int nDCCObjectSkipIndex )
|
||||
{
|
||||
// Look for the existence of this source already
|
||||
if ( pDCCObjectName[0] )
|
||||
{
|
||||
int nCount = m_hSourceDCCFile->m_RootDCCObjects.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
if ( i == nDCCObjectSkipIndex )
|
||||
continue;
|
||||
|
||||
if ( !Q_stricmp( pDCCObjectName, m_hSourceDCCFile->m_RootDCCObjects[i] ) )
|
||||
{
|
||||
vgui::MessageBox *pError = new vgui::MessageBox( "#DmeSourceDCCFile_DuplicateSourceTitle", "#DmeSourceDCCFile_DuplicateSourceText", GetParent() );
|
||||
pError->DoModal();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the source file name changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::OnDCCObjectNameChanged()
|
||||
{
|
||||
int nCount = m_pRootDCCObjects->GetSelectedItemsCount();
|
||||
if ( nCount == 0 || !m_hSourceDCCFile.Get() )
|
||||
return;
|
||||
|
||||
int nItemID = m_pRootDCCObjects->GetSelectedItem( 0 );
|
||||
KeyValues *pKeyValues = m_pRootDCCObjects->GetItem( nItemID );
|
||||
int nDCCObjectIndex = pKeyValues->GetInt( "dccObjectIndex", -1 );
|
||||
if ( nDCCObjectIndex < 0 )
|
||||
return;
|
||||
|
||||
char pDCCObjectName[MAX_PATH];
|
||||
m_pDCCObjectName->GetText( pDCCObjectName, sizeof(pDCCObjectName) );
|
||||
|
||||
if ( CheckForDuplicateNames( pDCCObjectName, nDCCObjectIndex ) )
|
||||
return;
|
||||
|
||||
{
|
||||
CDisableUndoScopeGuard guard;
|
||||
m_hSourceDCCFile->m_RootDCCObjects.Set( nDCCObjectIndex, pDCCObjectName );
|
||||
}
|
||||
|
||||
pKeyValues->SetString( "dccobject", pDCCObjectName );
|
||||
m_pRootDCCObjects->ApplyItemChanges( nItemID );
|
||||
m_pRootDCCObjects->SortList();
|
||||
|
||||
SetDirty( );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Used for sorting below
|
||||
//-----------------------------------------------------------------------------
|
||||
static int IntCompare( const void *pSrc1, const void *pSrc2 )
|
||||
{
|
||||
int i1 = *(int*)pSrc1;
|
||||
int i2 = *(int*)pSrc2;
|
||||
return i1 - i2;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the button to remove a DCC object is clicked
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::OnRemoveDCCObject( )
|
||||
{
|
||||
int nCount = m_pRootDCCObjects->GetSelectedItemsCount();
|
||||
if ( nCount == 0 || !m_hSourceDCCFile.Get() )
|
||||
return;
|
||||
|
||||
int nSelectedCount = 0;
|
||||
int *pDCCObjectIndex = (int*)alloca( nCount*sizeof(int) );
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
int nItemID = m_pRootDCCObjects->GetSelectedItem( i );
|
||||
KeyValues *pKeyValues = m_pRootDCCObjects->GetItem( nItemID );
|
||||
int nDCCObjectIndex = pKeyValues->GetInt( "dccObjectIndex", -1 );
|
||||
if ( nDCCObjectIndex < 0 )
|
||||
continue;
|
||||
pDCCObjectIndex[nSelectedCount++] = nDCCObjectIndex;
|
||||
}
|
||||
|
||||
if ( nSelectedCount == 0 )
|
||||
return;
|
||||
|
||||
// Sort the object indices so we can remove them all
|
||||
qsort( pDCCObjectIndex, nSelectedCount, sizeof(int), IntCompare );
|
||||
|
||||
// Update the selection to be reasonable after deletion
|
||||
int nItemID = m_pRootDCCObjects->GetSelectedItem( 0 );
|
||||
int nRow = m_pRootDCCObjects->GetItemCurrentRow( nItemID );
|
||||
Assert( nRow >= 0 );
|
||||
|
||||
{
|
||||
CDisableUndoScopeGuard guard;
|
||||
// Because we sorted it above, removes will occur properly
|
||||
for ( int i = nSelectedCount; --i >= 0; )
|
||||
{
|
||||
m_hSourceDCCFile->m_RootDCCObjects.Remove( pDCCObjectIndex[i] );
|
||||
}
|
||||
SetDirty( );
|
||||
}
|
||||
RefreshDCCObjectList();
|
||||
|
||||
int nVisibleRowCount = m_pRootDCCObjects->GetItemCount();
|
||||
if ( nVisibleRowCount == 0 )
|
||||
return;
|
||||
|
||||
if ( nRow >= nVisibleRowCount )
|
||||
{
|
||||
nRow = nVisibleRowCount - 1;
|
||||
}
|
||||
|
||||
int nNewItemID = m_pRootDCCObjects->GetItemIDFromRow( nRow );
|
||||
m_pRootDCCObjects->SetSingleSelectedItem( nNewItemID );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when a key is typed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::OnKeyCodeTyped( vgui::KeyCode code )
|
||||
{
|
||||
if ( code == KEY_DELETE )
|
||||
{
|
||||
OnRemoveDCCObject();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnKeyCodeTyped( code );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Command handler
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceDCCFilePanel::OnCommand( const char *pCommand )
|
||||
{
|
||||
if ( !Q_stricmp( pCommand, "OnBrowseDCCObject" ) )
|
||||
{
|
||||
OnBrowseDCCObject();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "OnAddDCCObject" ) )
|
||||
{
|
||||
OnAddDCCObject();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "OnRemoveDCCObject" ) )
|
||||
{
|
||||
OnRemoveDCCObject();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "OnApplyChanges" ) )
|
||||
{
|
||||
OnDCCObjectNameChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( pCommand );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dme_controls/DmeSourceSkinPanel.h"
|
||||
#include "dme_controls/DmePanel.h"
|
||||
#include "movieobjects/dmemdlmakefile.h"
|
||||
#include "vgui_controls/TextEntry.h"
|
||||
#include "vgui_controls/CheckButton.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Hook into the dme panel editor system
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_DMEPANEL_FACTORY( CDmeSourceSkinPanel, DmeSourceSkin, "DmeSourceSkinDefault", "MDL Skin Editor", true );
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmeSourceSkinPanel::CDmeSourceSkinPanel( vgui::Panel *pParent, const char *pPanelName ) :
|
||||
BaseClass( pParent, pPanelName )
|
||||
{
|
||||
m_pSkinName = new vgui::TextEntry( this, "SkinName" );
|
||||
m_pSkinName->AddActionSignalTarget( this );
|
||||
|
||||
m_pScale = new vgui::TextEntry( this, "Scale" );
|
||||
m_pScale->AddActionSignalTarget( this );
|
||||
|
||||
m_pFlipTriangles = new vgui::CheckButton( this, "FlipTriangles", "" );
|
||||
m_pFlipTriangles->AddActionSignalTarget( this );
|
||||
|
||||
// Load layout settings; has to happen before pinning occurs in code
|
||||
LoadControlSettings( "resource/DmeSourceSkinPanel.res" );
|
||||
}
|
||||
|
||||
CDmeSourceSkinPanel::~CDmeSourceSkinPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Marks the file as dirty (or not)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceSkinPanel::SetDirty()
|
||||
{
|
||||
PostActionSignal( new KeyValues( "DmeElementChanged" ) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Resets the state
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceSkinPanel::SetDmeElement( CDmeSourceSkin *pSourceSkin )
|
||||
{
|
||||
m_hSourceSkin = pSourceSkin;
|
||||
|
||||
bool bEnabled = (pSourceSkin != NULL);
|
||||
m_pSkinName->SetEnabled( bEnabled );
|
||||
m_pScale->SetEnabled( bEnabled );
|
||||
m_pFlipTriangles->SetEnabled( bEnabled );
|
||||
if ( !bEnabled )
|
||||
{
|
||||
m_pSkinName->SetText( "" );
|
||||
m_pScale->SetText( "" );
|
||||
m_pFlipTriangles->SetSelected( false );
|
||||
return;
|
||||
}
|
||||
|
||||
char pBuf[32];
|
||||
Q_snprintf( pBuf, sizeof(pBuf), "%.3f", pSourceSkin->m_flScale.Get() );
|
||||
m_pSkinName->SetText( pSourceSkin->m_SkinName );
|
||||
m_pScale->SetText( pBuf );
|
||||
m_pFlipTriangles->SetSelected( pSourceSkin->m_bFlipTriangles );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Command handler
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceSkinPanel::OnCheckButtonChecked( int nChecked )
|
||||
{
|
||||
if ( !m_hSourceSkin.Get() )
|
||||
return;
|
||||
|
||||
bool bFlipTriangles = ( nChecked != 0 );
|
||||
if ( bFlipTriangles != m_hSourceSkin->m_bFlipTriangles )
|
||||
{
|
||||
m_hSourceSkin->m_bFlipTriangles = bFlipTriangles;
|
||||
SetDirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when something is typed in a text entry field
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSourceSkinPanel::OnTextChanged( KeyValues *kv )
|
||||
{
|
||||
if ( !m_hSourceSkin.Get() )
|
||||
return;
|
||||
|
||||
Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL );
|
||||
if ( pPanel == m_pSkinName )
|
||||
{
|
||||
char pTextBuf[256];
|
||||
m_pSkinName->GetText( pTextBuf, sizeof( pTextBuf) );
|
||||
if ( Q_stricmp( pTextBuf, m_hSourceSkin->m_SkinName ) )
|
||||
{
|
||||
m_hSourceSkin->m_SkinName = pTextBuf;
|
||||
SetDirty();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pPanel == m_pScale )
|
||||
{
|
||||
char pTextBuf[256];
|
||||
m_pScale->GetText( pTextBuf, sizeof( pTextBuf) );
|
||||
float flScale = atoi( pTextBuf );
|
||||
if ( flScale != m_hSourceSkin->m_flScale )
|
||||
{
|
||||
m_hSourceSkin->m_flScale = flScale;
|
||||
SetDirty();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,58 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "KeyValues.h"
|
||||
#include "dme_controls/ElementPropertiesTree.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
|
||||
#include "vgui_controls/TextEntry.h"
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "vgui_controls/PanelListPanel.h"
|
||||
|
||||
#include "FactoryOverloads.h"
|
||||
|
||||
void CFactoryOverloads::AddOverload(
|
||||
char const *attributeName,
|
||||
IAttributeWidgetFactory *newFactory,
|
||||
IAttributeElementChoiceList *newChoiceList )
|
||||
{
|
||||
Assert( attributeName );
|
||||
Assert( newFactory || newChoiceList );
|
||||
|
||||
if ( !newFactory )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Entry_t e;
|
||||
e.factory = newFactory;
|
||||
e.choices = newChoiceList;
|
||||
|
||||
m_Overloads.Insert( attributeName, e );
|
||||
}
|
||||
|
||||
int CFactoryOverloads::Count()
|
||||
{
|
||||
return m_Overloads.Count();
|
||||
}
|
||||
|
||||
char const *CFactoryOverloads::Name( int index )
|
||||
{
|
||||
return m_Overloads.GetElementName( index );
|
||||
}
|
||||
|
||||
IAttributeWidgetFactory *CFactoryOverloads::Factory( int index )
|
||||
{
|
||||
return m_Overloads[ index ].factory;
|
||||
}
|
||||
|
||||
IAttributeElementChoiceList *CFactoryOverloads::ChoiceList( int index )
|
||||
{
|
||||
return m_Overloads[ index ].choices;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef FACTORYOVERLOADS_H
|
||||
#define FACTORYOVERLOADS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "utldict.h"
|
||||
|
||||
class IAttributeWidgetFactory;
|
||||
class IAttributeElementChoiceList;
|
||||
|
||||
class CFactoryOverloads : public IFactoryOverloads
|
||||
{
|
||||
public:
|
||||
virtual void AddOverload
|
||||
(
|
||||
char const *attributeName,
|
||||
IAttributeWidgetFactory *newFactory,
|
||||
IAttributeElementChoiceList *newChoiceList
|
||||
);
|
||||
int Count();
|
||||
char const *Name( int index );
|
||||
IAttributeWidgetFactory *Factory( int index );
|
||||
IAttributeElementChoiceList *ChoiceList( int index );
|
||||
|
||||
private:
|
||||
struct Entry_t
|
||||
{
|
||||
Entry_t() :
|
||||
factory( 0 ),
|
||||
choices( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
IAttributeWidgetFactory *factory;
|
||||
IAttributeElementChoiceList *choices;
|
||||
};
|
||||
|
||||
CUtlDict< Entry_t, int > m_Overloads;
|
||||
};
|
||||
|
||||
#endif // FACTORYOVERLOADS_H
|
||||
@@ -0,0 +1,618 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/filelistmanager.h"
|
||||
#include "vgui_controls/FileOpenDialog.h"
|
||||
#include "vgui_controls/menu.h"
|
||||
#include "vgui_controls/messagebox.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattribute.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include <vgui/IInput.h>
|
||||
#include "vgui/mousecode.h"
|
||||
#include "tier1/strtools.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier2/tier2.h"
|
||||
#include "p4lib/ip4.h"
|
||||
#include "filesystem.h"
|
||||
#include "dme_controls/INotifyUI.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
template < int C >
|
||||
int ListPanelStringSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 );
|
||||
|
||||
struct ColumnInfo_t
|
||||
{
|
||||
char const *columnName;
|
||||
char const *columnText;
|
||||
int startingWidth;
|
||||
int flags;
|
||||
vgui::SortFunc *pfnSort;
|
||||
vgui::Label::Alignment alignment;
|
||||
};
|
||||
|
||||
enum ColumnIndex_t
|
||||
{
|
||||
CI_FILENAME,
|
||||
CI_PATH,
|
||||
CI_LOADED,
|
||||
CI_NUMELEMENTS,
|
||||
CI_CHANGED,
|
||||
CI_INPERFORCE,
|
||||
CI_OPENFOREDIT,
|
||||
};
|
||||
|
||||
const int baseflags = vgui::ListPanel::COLUMN_UNHIDABLE;
|
||||
const int fixedflags = vgui::ListPanel::COLUMN_UNHIDABLE | vgui::ListPanel::COLUMN_FIXEDSIZE;
|
||||
|
||||
static ColumnInfo_t g_ColInfo[] =
|
||||
{
|
||||
{ "filename", "#BxFileManager_Filename", 150, baseflags, ListPanelStringSortFunc< CI_FILENAME >, vgui::Label::a_west },
|
||||
{ "path", "#BxFileManager_Path", 240, baseflags, ListPanelStringSortFunc< CI_PATH >, vgui::Label::a_west },
|
||||
{ "loaded", "#BxFileManager_Loaded", 40, fixedflags, ListPanelStringSortFunc< CI_LOADED >, vgui::Label::a_center },
|
||||
{ "numelements", "#BxFileManager_NumElements", 60, fixedflags, ListPanelStringSortFunc< CI_NUMELEMENTS >, vgui::Label::a_east },
|
||||
{ "changed", "#BxFileManager_Changed", 50, fixedflags, ListPanelStringSortFunc< CI_CHANGED >, vgui::Label::a_center },
|
||||
{ "in_perforce", "#BxFileManager_P4Exists", 35, fixedflags, ListPanelStringSortFunc< CI_INPERFORCE >, vgui::Label::a_center },
|
||||
{ "open_for_edit", "#BxFileManager_P4Edit", 40, fixedflags, ListPanelStringSortFunc< CI_OPENFOREDIT >, vgui::Label::a_center },
|
||||
};
|
||||
|
||||
const char *GetKey( ColumnIndex_t ci )
|
||||
{
|
||||
return g_ColInfo[ ci ].columnName;
|
||||
}
|
||||
|
||||
template < int C >
|
||||
int ListPanelStringSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
|
||||
{
|
||||
NOTE_UNUSED( pPanel );
|
||||
|
||||
const char *pKey = GetKey( ( ColumnIndex_t )C );
|
||||
const char *string1 = item1.kv->GetString( pKey );
|
||||
const char *string2 = item2.kv->GetString( pKey );
|
||||
|
||||
return Q_stricmp( string1, string2 );
|
||||
}
|
||||
|
||||
void AddColumn( CFileListManager *pFileManager, ColumnIndex_t ci )
|
||||
{
|
||||
pFileManager->AddColumnHeader( ci, g_ColInfo[ ci ].columnName, g_ColInfo[ ci ].columnText, g_ColInfo[ ci ].startingWidth, g_ColInfo[ ci ].flags );
|
||||
pFileManager->SetSortFunc( ci, g_ColInfo[ ci ].pfnSort );
|
||||
pFileManager->SetColumnTextAlignment( ci, g_ColInfo[ ci ].alignment );
|
||||
}
|
||||
|
||||
|
||||
CFileListManager::CFileListManager( vgui::Panel *parent ) : BaseClass( parent, "FileListManager" )
|
||||
{
|
||||
SetMultiselectEnabled( true );
|
||||
SetVisible( true );
|
||||
m_bRefreshRequired = false;
|
||||
|
||||
SetSize( 800, 200 );
|
||||
SetPos( 100, 100 );
|
||||
|
||||
AddColumn( this, CI_FILENAME );
|
||||
AddColumn( this, CI_PATH );
|
||||
AddColumn( this, CI_LOADED );
|
||||
AddColumn( this, CI_NUMELEMENTS );
|
||||
AddColumn( this, CI_CHANGED );
|
||||
AddColumn( this, CI_INPERFORCE );
|
||||
AddColumn( this, CI_OPENFOREDIT );
|
||||
|
||||
SetSortColumn( 0 );
|
||||
|
||||
Refresh();
|
||||
|
||||
SetScheme( vgui::scheme()->LoadSchemeFromFile( "Resource/BoxRocket.res", "BoxRocket" ) );
|
||||
// LoadControlSettings( "resource/BxFileListManager.res" );
|
||||
}
|
||||
|
||||
int CFileListManager::AddItem( DmFileId_t fileid, const char *pFilename, const char *pPath, bool bLoaded, int nElements, bool bChanged, bool bInPerforce, bool bOpenForEdit )
|
||||
{
|
||||
KeyValues *kv = new KeyValues( "", GetKey( CI_FILENAME ), pFilename, GetKey( CI_PATH ), pPath );
|
||||
kv->SetInt ( GetKey( CI_NUMELEMENTS ), nElements );
|
||||
kv->SetString( GetKey( CI_LOADED ), bLoaded ? "Y" : "N" );
|
||||
kv->SetString( GetKey( CI_CHANGED ), bChanged ? "Y" : "N" );
|
||||
kv->SetString( GetKey( CI_INPERFORCE ), bInPerforce ? "Y" : "N" );
|
||||
kv->SetString( GetKey( CI_OPENFOREDIT ), bOpenForEdit ? "Y" : "N" );
|
||||
int itemID = BaseClass::AddItem( kv, fileid, false, false );
|
||||
kv->deleteThis();
|
||||
return itemID;
|
||||
}
|
||||
|
||||
void CFileListManager::SetLoaded( DmFileId_t fileid, bool bLoaded )
|
||||
{
|
||||
CNotifyScopeGuard notify( "CFileListManager::SetLoaded", NOTIFY_SOURCE_FILE_LIST_MANAGER, NOTIFY_SETDIRTYFLAG );
|
||||
|
||||
if ( bLoaded )
|
||||
{
|
||||
const char *pFilename = g_pDataModel->GetFileName( fileid );
|
||||
Assert( pFilename );
|
||||
if ( !pFilename )
|
||||
return;
|
||||
|
||||
CDisableUndoScopeGuard guard;
|
||||
CDmElement *pRoot = NULL;
|
||||
g_pDataModel->RestoreFromFile( pFilename, NULL, NULL, &pRoot, CR_DELETE_NEW );
|
||||
}
|
||||
else
|
||||
{
|
||||
CDisableUndoScopeGuard guard;
|
||||
g_pDataModel->UnloadFile( fileid );
|
||||
}
|
||||
}
|
||||
|
||||
void CFileListManager::OnMousePressed( vgui::MouseCode code )
|
||||
{
|
||||
// determine where we were pressed
|
||||
int x, y, row, column;
|
||||
vgui::input()->GetCursorPos( x, y );
|
||||
GetCellAtPos( x, y, row, column );
|
||||
|
||||
if ( code == MOUSE_LEFT )
|
||||
{
|
||||
bool bIsFakeToggleButton = column == CI_LOADED;
|
||||
if ( bIsFakeToggleButton && row >= 0 && row < GetItemCount() )
|
||||
{
|
||||
int itemID = GetItemIDFromRow( row );
|
||||
KeyValues *kv = GetItem( itemID );
|
||||
|
||||
const char *pStr = kv->GetString( GetKey( ( ColumnIndex_t )column ), "" );
|
||||
Assert( *pStr == 'Y' || *pStr == 'N' );
|
||||
bool bSet = *pStr == 'N'; // bSet is the NEW state, not the old one
|
||||
kv->SetString( GetKey( ( ColumnIndex_t )column ), bSet ? "Y" : "N" );
|
||||
|
||||
SetLoaded( ( DmFileId_t )GetItemUserData( itemID ), bSet );
|
||||
|
||||
// get the key focus
|
||||
RequestFocus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ( code == MOUSE_RIGHT )
|
||||
{
|
||||
int itemID = -1;
|
||||
if ( row >= 0 && row < GetItemCount() )
|
||||
{
|
||||
itemID = GetItemIDFromRow( row );
|
||||
|
||||
if ( !IsItemSelected( itemID ) )
|
||||
{
|
||||
SetSingleSelectedItem( itemID );
|
||||
}
|
||||
}
|
||||
|
||||
KeyValues *kv = new KeyValues( "OpenContextMenu", "itemID", itemID );
|
||||
OnOpenContextMenu( kv );
|
||||
kv->deleteThis();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnMousePressed( code );
|
||||
}
|
||||
|
||||
int AddMenuItemHelper( vgui::Menu *pMenu, const char *pItemName, const char *pKVName, vgui::Panel *pTarget, bool bEnabled )
|
||||
{
|
||||
int id = pMenu->AddMenuItem( pItemName, new KeyValues( pKVName ), pTarget );
|
||||
pMenu->SetItemEnabled( id, bEnabled );
|
||||
return id;
|
||||
}
|
||||
|
||||
void CFileListManager::OnOpenContextMenu( KeyValues *pParams )
|
||||
{
|
||||
if ( m_hContextMenu.Get() )
|
||||
{
|
||||
delete m_hContextMenu.Get();
|
||||
m_hContextMenu = NULL;
|
||||
}
|
||||
|
||||
m_hContextMenu = new vgui::Menu( this, "ContextMenu" );
|
||||
|
||||
int itemID = pParams->GetInt( "itemID", -1 );
|
||||
if ( itemID < 0 )
|
||||
{
|
||||
AddMenuItemHelper( m_hContextMenu, "Open File...", "open", this, true ); // Is this how we should load other files???
|
||||
}
|
||||
else
|
||||
{
|
||||
bool bP4Connected = p4->IsConnectedToServer();
|
||||
|
||||
int nSelected = GetSelectedItemsCount();
|
||||
int nLoaded = 0;
|
||||
int nChanged = 0;
|
||||
int nOnDisk = 0;
|
||||
int nInPerforce = 0;
|
||||
int nOpenForEdit = 0;
|
||||
for ( int i = 0; i < nSelected; ++i )
|
||||
{
|
||||
int itemId = GetSelectedItem( i );
|
||||
DmFileId_t fileid = ( DmFileId_t )GetItemUserData( itemId );
|
||||
if ( g_pDataModel->IsFileLoaded( fileid ) )
|
||||
{
|
||||
++nLoaded;
|
||||
++nChanged; // TODO - find out for real
|
||||
}
|
||||
const char *pFilename = g_pDataModel->GetFileName( fileid );
|
||||
if ( g_pFullFileSystem->FileExists( pFilename ) )
|
||||
{
|
||||
++nOnDisk;
|
||||
}
|
||||
|
||||
if ( bP4Connected )
|
||||
{
|
||||
if ( p4->IsFileInPerforce( pFilename ) )
|
||||
{
|
||||
++nInPerforce;
|
||||
if ( p4->GetFileState( pFilename ) != P4FILE_UNOPENED )
|
||||
{
|
||||
++nOpenForEdit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AddMenuItemHelper( m_hContextMenu, "Load", "load", this, nLoaded < nSelected && nOnDisk > 0 );
|
||||
AddMenuItemHelper( m_hContextMenu, "Unload", "unload", this, nLoaded > 0 );
|
||||
AddMenuItemHelper( m_hContextMenu, "Save", "save", this, nChanged > 0 && nOnDisk == nSelected );
|
||||
AddMenuItemHelper( m_hContextMenu, "Save As...", "saveas", this, nLoaded == 1 && nSelected == 1 );
|
||||
AddMenuItemHelper( m_hContextMenu, "Add To Perforce", "p4add", this, nInPerforce < nSelected && nOnDisk > 0 );
|
||||
AddMenuItemHelper( m_hContextMenu, "Open For Edit", "p4edit", this, nOpenForEdit < nSelected && nOnDisk > 0 );
|
||||
}
|
||||
|
||||
vgui::Menu::PlaceContextMenu( this, m_hContextMenu.Get() );
|
||||
}
|
||||
|
||||
void CFileListManager::OnLoadFiles( KeyValues *pParams )
|
||||
{
|
||||
CNotifyScopeGuard notify( "CFileListManager::OnLoadFiles", NOTIFY_SOURCE_FILE_LIST_MANAGER, NOTIFY_SETDIRTYFLAG );
|
||||
|
||||
int nSelected = GetSelectedItemsCount();
|
||||
for ( int i = 0; i < nSelected; ++i )
|
||||
{
|
||||
int itemId = GetSelectedItem( i );
|
||||
DmFileId_t fileid = ( DmFileId_t )GetItemUserData( itemId );
|
||||
if ( !g_pDataModel->IsFileLoaded( fileid ) )
|
||||
{
|
||||
SetLoaded( fileid, true );
|
||||
}
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void CFileListManager::OnUnloadFiles( KeyValues *pParams )
|
||||
{
|
||||
CNotifyScopeGuard notify( "CFileListManager::OnUnloadFiles", NOTIFY_SOURCE_FILE_LIST_MANAGER, NOTIFY_SETDIRTYFLAG );
|
||||
|
||||
int nSelected = GetSelectedItemsCount();
|
||||
for ( int i = 0; i < nSelected; ++i )
|
||||
{
|
||||
int itemId = GetSelectedItem( i );
|
||||
DmFileId_t fileid = ( DmFileId_t )GetItemUserData( itemId );
|
||||
if ( g_pDataModel->IsFileLoaded( fileid ) )
|
||||
{
|
||||
SetLoaded( fileid, false );
|
||||
}
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void CFileListManager::OnSaveFiles( KeyValues *pParams )
|
||||
{
|
||||
int nSelected = GetSelectedItemsCount();
|
||||
for ( int i = 0; i < nSelected; ++i )
|
||||
{
|
||||
int itemId = GetSelectedItem( i );
|
||||
DmFileId_t fileid = ( DmFileId_t )GetItemUserData( itemId );
|
||||
if ( !g_pDataModel->IsFileLoaded( fileid ) )
|
||||
continue;
|
||||
|
||||
const char *pFilename = g_pDataModel->GetFileName( fileid );
|
||||
Assert( pFilename );
|
||||
if ( !pFilename )
|
||||
continue;
|
||||
|
||||
CDmElement *pRoot = GetElement< CDmElement >( g_pDataModel->GetFileRoot( fileid ) );
|
||||
Assert( pRoot );
|
||||
if ( !pRoot )
|
||||
continue;
|
||||
|
||||
const char *pFileFormat = g_pDataModel->GetFileFormat( fileid );
|
||||
const char *pEncoding = g_pDataModel->GetDefaultEncoding( pFileFormat );
|
||||
g_pDataModel->SaveToFile( pFilename, NULL, pEncoding, pFileFormat, pRoot );
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void CFileListManager::OnOpenFile( KeyValues *pParams )
|
||||
{
|
||||
KeyValues *pContextKeyValues = new KeyValues( "OnOpen" );
|
||||
vgui::FileOpenDialog *pFileOpenDialog = new vgui::FileOpenDialog( this, "Save .dmx File As", false, pContextKeyValues );
|
||||
pFileOpenDialog->AddFilter( "*.dmx", "DmElements File (*.dmx)", true );
|
||||
pFileOpenDialog->AddActionSignalTarget( this );
|
||||
pFileOpenDialog->SetDeleteSelfOnClose( true );
|
||||
pFileOpenDialog->DoModal( false );
|
||||
}
|
||||
|
||||
void CFileListManager::OnSaveFileAs( KeyValues *pParams )
|
||||
{
|
||||
int nSelected = GetSelectedItemsCount();
|
||||
Assert( nSelected == 1 );
|
||||
if ( nSelected != 1 )
|
||||
return;
|
||||
|
||||
KeyValues *pContextKeyValues = new KeyValues( "OnSaveAs" );
|
||||
pContextKeyValues->SetInt( "itemId", GetSelectedItem( 0 ) );
|
||||
DmFileId_t fileid = ( DmFileId_t )GetItemUserData( GetSelectedItem( 0 ) );
|
||||
const char *pFileFormat = g_pDataModel->GetFileFormat( fileid );
|
||||
|
||||
vgui::FileOpenDialog *pFileOpenDialog = new vgui::FileOpenDialog( this, "Save .dmx File As", false, pContextKeyValues );
|
||||
// if this control is moved to vgui_controls, change the default format to "dmx", the generic dmx format
|
||||
pFileOpenDialog->AddFilter( "*.dmx", "Generic MovieObjects File (*.dmx)", false, "movieobjects" );
|
||||
if ( V_strcmp( pFileFormat, "movieobjects" ) != 0 )
|
||||
{
|
||||
char description[ 256 ];
|
||||
V_snprintf( description, sizeof( description ), "%s (*.dmx)", g_pDataModel->GetFormatDescription( pFileFormat ) );
|
||||
pFileOpenDialog->AddFilter( "*.dmx", description, true, pFileFormat );
|
||||
}
|
||||
pFileOpenDialog->AddActionSignalTarget( this );
|
||||
pFileOpenDialog->SetDeleteSelfOnClose( true );
|
||||
pFileOpenDialog->DoModal( false );
|
||||
}
|
||||
|
||||
void CFileListManager::OnFileSelected( KeyValues *pParams )
|
||||
{
|
||||
const char *pFullPath = pParams->GetString( "fullpath" );
|
||||
if ( !pFullPath || !pFullPath[ 0 ] )
|
||||
return;
|
||||
|
||||
KeyValues *pSaveAsKey = pParams->FindKey( "OnSaveAs" );
|
||||
if ( pSaveAsKey )
|
||||
{
|
||||
int itemId = pSaveAsKey->GetInt( "itemId", -1 );
|
||||
Assert( itemId != -1 );
|
||||
if ( itemId == -1 )
|
||||
return;
|
||||
|
||||
DmFileId_t fileid = ( DmFileId_t )GetItemUserData( itemId );
|
||||
Assert( fileid != DMFILEID_INVALID );
|
||||
if ( fileid == DMFILEID_INVALID )
|
||||
return;
|
||||
|
||||
CDmElement *pRoot = GetElement< CDmElement >( g_pDataModel->GetFileRoot( fileid ) );
|
||||
Assert( pRoot );
|
||||
if ( !pRoot )
|
||||
return;
|
||||
|
||||
const char *pFormat = pParams->GetString( "filterinfo" );
|
||||
Assert( pFormat );
|
||||
if ( !pFormat )
|
||||
return;
|
||||
|
||||
g_pDataModel->SetFileName( fileid, pFullPath );
|
||||
g_pDataModel->SaveToFile( pFullPath, NULL, g_pDataModel->GetDefaultEncoding( pFormat ), pFormat, pRoot );
|
||||
|
||||
Refresh();
|
||||
return;
|
||||
}
|
||||
|
||||
KeyValues *pOpenKey = pParams->FindKey( "OnOpen" );
|
||||
if ( pOpenKey )
|
||||
{
|
||||
CDmElement *pRoot = NULL;
|
||||
g_pDataModel->RestoreFromFile( pFullPath, NULL, NULL, &pRoot );
|
||||
|
||||
Refresh();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CFileListManager::OnAddToPerforce( KeyValues *pParams )
|
||||
{
|
||||
int nFileCount = 0;
|
||||
int nSelected = GetSelectedItemsCount();
|
||||
const char **ppFileNames = ( const char** )_alloca( nSelected * sizeof( char* ) );
|
||||
for ( int i = 0; i < nSelected; ++i )
|
||||
{
|
||||
int itemId = GetSelectedItem( i );
|
||||
DmFileId_t fileid = ( DmFileId_t )GetItemUserData( itemId );
|
||||
const char *pFilename = g_pDataModel->GetFileName( fileid );
|
||||
Assert( pFilename );
|
||||
if ( !pFilename )
|
||||
continue;
|
||||
|
||||
++nFileCount;
|
||||
ppFileNames[ i ] = pFilename;
|
||||
}
|
||||
|
||||
bool bSuccess = p4->OpenFilesForAdd( nFileCount, ppFileNames );
|
||||
if ( !bSuccess )
|
||||
{
|
||||
vgui::MessageBox *pError = new vgui::MessageBox( "Perforce Error!", p4->GetLastError(), GetParent() );
|
||||
pError->SetSmallCaption( true );
|
||||
pError->DoModal();
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void CFileListManager::OnOpenForEdit( KeyValues *pParams )
|
||||
{
|
||||
int nFileCount = 0;
|
||||
int nSelected = GetSelectedItemsCount();
|
||||
const char **ppFileNames = ( const char** )_alloca( nSelected * sizeof( char* ) );
|
||||
for ( int i = 0; i < nSelected; ++i )
|
||||
{
|
||||
int itemId = GetSelectedItem( i );
|
||||
DmFileId_t fileid = ( DmFileId_t )GetItemUserData( itemId );
|
||||
const char *pFilename = g_pDataModel->GetFileName( fileid );
|
||||
Assert( pFilename );
|
||||
if ( !pFilename )
|
||||
continue;
|
||||
|
||||
++nFileCount;
|
||||
ppFileNames[ i ] = pFilename;
|
||||
}
|
||||
|
||||
bool bSuccess = p4->OpenFilesForEdit( nFileCount, ppFileNames );
|
||||
if ( !bSuccess )
|
||||
{
|
||||
vgui::MessageBox *pError = new vgui::MessageBox( "Perforce Error!", p4->GetLastError(), GetParent() );
|
||||
pError->SetSmallCaption( true );
|
||||
pError->DoModal();
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void CFileListManager::OnDataChanged( KeyValues *pParams )
|
||||
{
|
||||
int nNotifyFlags = pParams->GetInt( "notifyFlags" );
|
||||
if ( ( nNotifyFlags & NOTIFY_CHANGE_TOPOLOGICAL ) == 0 )
|
||||
return;
|
||||
|
||||
int nNotifySource = pParams->GetInt( "source" );
|
||||
if ( nNotifySource == NOTIFY_SOURCE_FILE_LIST_MANAGER )
|
||||
return;
|
||||
|
||||
if ( !IsVisible() )
|
||||
{
|
||||
m_bRefreshRequired = true;
|
||||
return;
|
||||
}
|
||||
|
||||
int nCount = GetItemCount();
|
||||
int nFiles = g_pDataModel->NumFileIds();
|
||||
bool bPerformFullRefresh = ( nCount != nFiles );
|
||||
if ( !bPerformFullRefresh )
|
||||
{
|
||||
const char *pNameKey = GetKey( CI_FILENAME );
|
||||
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
DmFileId_t fileid = g_pDataModel->GetFileId( i );
|
||||
const char *pFileName = g_pDataModel->GetFileName( fileid );
|
||||
if ( !pFileName || !*pFileName )
|
||||
{
|
||||
bPerformFullRefresh = true;
|
||||
break;
|
||||
}
|
||||
pFileName = V_UnqualifiedFileName( pFileName );
|
||||
|
||||
KeyValues *pKeyValues = GetItem( i );
|
||||
bPerformFullRefresh = ( fileid != (DmFileId_t)GetItemUserData(i) ) || Q_stricmp( pFileName, pKeyValues->GetString( pNameKey ) );
|
||||
if ( bPerformFullRefresh )
|
||||
break;
|
||||
|
||||
pKeyValues->SetInt ( GetKey( CI_NUMELEMENTS ), g_pDataModel->NumElementsInFile( fileid ) );
|
||||
pKeyValues->SetString( GetKey( CI_LOADED ), g_pDataModel->IsFileLoaded( fileid ) ? "Y" : "N" );
|
||||
pKeyValues->SetString( GetKey( CI_CHANGED ), false ? "Y" : "N" );
|
||||
ApplyItemChanges( i );
|
||||
}
|
||||
}
|
||||
|
||||
if ( bPerformFullRefresh )
|
||||
{
|
||||
Refresh();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CFileListManager::Refresh()
|
||||
{
|
||||
m_bRefreshRequired = false;
|
||||
RemoveAll();
|
||||
|
||||
const bool bP4Connected = p4 ? p4->IsConnectedToServer() : false;
|
||||
|
||||
int nFiles = g_pDataModel->NumFileIds();
|
||||
for ( int i = 0; i < nFiles; ++i )
|
||||
{
|
||||
DmFileId_t fileid = g_pDataModel->GetFileId( i );
|
||||
const char *pFileName = g_pDataModel->GetFileName( fileid );
|
||||
if ( !pFileName || !*pFileName )
|
||||
continue; // skip DMFILEID_INVALID and the default fileid ""
|
||||
|
||||
bool bLoaded = g_pDataModel->IsFileLoaded( fileid );
|
||||
int nElements = g_pDataModel->NumElementsInFile( fileid );
|
||||
bool bChanged = false; // TODO - find out for real
|
||||
bool bInPerforce = bP4Connected && p4->IsFileInPerforce( pFileName );
|
||||
bool bOpenForEdit = bInPerforce && p4->GetFileState( pFileName ) != P4FILE_UNOPENED;
|
||||
|
||||
char path[ 256 ];
|
||||
V_ExtractFilePath( pFileName, path, sizeof( path ) );
|
||||
|
||||
AddItem( fileid, V_UnqualifiedFileName( pFileName ), path, bLoaded, nElements, bChanged, bInPerforce, bOpenForEdit );
|
||||
}
|
||||
}
|
||||
|
||||
void CFileListManager::OnThink( )
|
||||
{
|
||||
BaseClass::OnThink();
|
||||
if ( m_bRefreshRequired && IsVisible() )
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void CFileListManager::OnCommand( const char *cmd )
|
||||
{
|
||||
// if ( !Q_stricmp( cmd, "foo" ) ) ...
|
||||
BaseClass::OnCommand( cmd );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// CFileManagerFrame methods
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CFileManagerFrame::CFileManagerFrame( vgui::Panel *parent ) : BaseClass( parent, "FileManagerFrame" )
|
||||
{
|
||||
SetTitle( "#BxFileManagerFrame", true );
|
||||
|
||||
SetSizeable( true );
|
||||
SetCloseButtonVisible( false );
|
||||
SetMinimumSize( 200, 200 );
|
||||
|
||||
SetVisible( true );
|
||||
|
||||
SetSize( 800, 200 );
|
||||
SetPos( 100, 100 );
|
||||
|
||||
m_pFileListManager = new CFileListManager( this );
|
||||
Refresh();
|
||||
|
||||
SetScheme( vgui::scheme()->LoadSchemeFromFile( "Resource/BoxRocket.res", "BoxRocket" ) );
|
||||
}
|
||||
|
||||
void CFileManagerFrame::Refresh()
|
||||
{
|
||||
m_pFileListManager->Refresh();
|
||||
}
|
||||
|
||||
void CFileManagerFrame::OnCommand( const char *cmd )
|
||||
{
|
||||
BaseClass::OnCommand( cmd );
|
||||
m_pFileListManager->OnCommand( cmd );
|
||||
}
|
||||
|
||||
void CFileManagerFrame::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
int iWidth, iHeight;
|
||||
GetSize( iWidth, iHeight );
|
||||
m_pFileListManager->SetPos( 0, GetCaptionHeight() );
|
||||
m_pFileListManager->SetSize( iWidth, iHeight - GetCaptionHeight() );
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeAssetPickerPanel.h"
|
||||
#include "dme_controls/AttributeTextEntry.h"
|
||||
#include "matsys_controls/AssetPicker.h"
|
||||
#include "matsys_controls/VtfPicker.h"
|
||||
#include "matsys_controls/VMTPicker.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Assets
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_ATTRIBUTE_ASSET_PICKER( CAttributeBspPickerPanel, "Select .BSP file", "BSP Files", "bsp", "maps", "bspName" );
|
||||
IMPLEMENT_ATTRIBUTE_ASSET_PREVIEW_PICKER( CAttributeVmtPickerPanel, CVMTPickerFrame, "Select .VMT file" );
|
||||
IMPLEMENT_ATTRIBUTE_ASSET_PREVIEW_PICKER( CAttributeVtfPickerPanel, CVTFPickerFrame, "Select .VTF file" );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAttributeAssetPickerPanel::CAttributeAssetPickerPanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
}
|
||||
|
||||
CAttributeAssetPickerPanel::~CAttributeAssetPickerPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it's time to show the BSP picker
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeAssetPickerPanel::ShowPickerDialog()
|
||||
{
|
||||
CBaseAssetPickerFrame *pAssetPickerDialog = CreateAssetPickerFrame( );
|
||||
pAssetPickerDialog->AddActionSignalTarget( this );
|
||||
pAssetPickerDialog->DoModal( );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called by the asset picker dialog if a asset was selected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeAssetPickerPanel::OnAssetSelected( KeyValues *pKeyValues )
|
||||
{
|
||||
// Get the asset name back
|
||||
const char *pAssetName = pKeyValues->GetString( "asset", NULL );
|
||||
if ( !pAssetName || !pAssetName[ 0 ] )
|
||||
return;
|
||||
|
||||
// Apply to text panel
|
||||
m_pData->SetText( pAssetName );
|
||||
SetDirty(true);
|
||||
if ( IsAutoApply() )
|
||||
{
|
||||
Apply();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeDetailTypePickerPanel.h"
|
||||
#include "dme_controls/AttributeTextEntry.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
const char *DETAILTYPE_FILE = "detail.vbsp";
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAttributeDetailTypePickerPanel::CAttributeDetailTypePickerPanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
}
|
||||
|
||||
CAttributeDetailTypePickerPanel::~CAttributeDetailTypePickerPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Reads the detail types
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeDetailTypePickerPanel::AddDetailTypesToList( PickerList_t &list )
|
||||
{
|
||||
KeyValues *pDetailTypes = new KeyValues( DETAILTYPE_FILE );
|
||||
if ( pDetailTypes->LoadFromFile( g_pFullFileSystem, DETAILTYPE_FILE, "GAME" ) )
|
||||
{
|
||||
for ( KeyValues *sub = pDetailTypes->GetFirstTrueSubKey(); sub != NULL; sub = sub->GetNextTrueSubKey() )
|
||||
{
|
||||
int i = list.AddToTail( );
|
||||
list[i].m_pChoiceString = sub->GetName();
|
||||
list[i].m_pChoiceValue = sub->GetName();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "Unable to load detail prop file '%s'\n", DETAILTYPE_FILE );
|
||||
}
|
||||
|
||||
pDetailTypes->deleteThis();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it's time to show the picker
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeDetailTypePickerPanel::ShowPickerDialog()
|
||||
{
|
||||
CPickerFrame *pDetailTypePickerDialog = new CPickerFrame( this, "Select Detail Type", "Detail Type", "detailTypeName" );
|
||||
PickerList_t detailTypeList;
|
||||
AddDetailTypesToList( detailTypeList );
|
||||
pDetailTypePickerDialog->AddActionSignalTarget( this );
|
||||
pDetailTypePickerDialog->DoModal( detailTypeList );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called by the picker dialog if a asset was selected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeDetailTypePickerPanel::OnPicked( KeyValues *pKeyValues )
|
||||
{
|
||||
// Get the detail type name back
|
||||
const char *pDetailTypeName = pKeyValues->GetString( "choice", NULL );
|
||||
if ( !pDetailTypeName || !pDetailTypeName[ 0 ] )
|
||||
return;
|
||||
|
||||
// Apply to text panel
|
||||
m_pData->SetText( pDetailTypeName );
|
||||
SetDirty(true);
|
||||
if ( IsAutoApply() )
|
||||
{
|
||||
Apply();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeShaderPickerPanel.h"
|
||||
#include "dme_controls/AttributeTextEntry.h"
|
||||
#include "matsys_controls/Picker.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/IShader.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAttributeShaderPickerPanel::CAttributeShaderPickerPanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
}
|
||||
|
||||
CAttributeShaderPickerPanel::~CAttributeShaderPickerPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it's time to show the picker
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeShaderPickerPanel::ShowPickerDialog()
|
||||
{
|
||||
CPickerFrame *pShaderPickerDialog = new CPickerFrame( this, "Select Shader", "Shader", "shaderName" );
|
||||
|
||||
int nCount = vgui::MaterialSystem()->ShaderCount();
|
||||
IShader** ppShaderList = (IShader**)_alloca( nCount * sizeof(IShader) );
|
||||
vgui::MaterialSystem()->GetShaders( 0, nCount, ppShaderList );
|
||||
PickerList_t shaderList( 0, nCount );
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
if ( ( ppShaderList[i]->GetFlags() & SHADER_NOT_EDITABLE ) == 0 )
|
||||
{
|
||||
int j = shaderList.AddToTail( );
|
||||
shaderList[j].m_pChoiceString = ppShaderList[i]->GetName();
|
||||
shaderList[j].m_pChoiceValue = ppShaderList[i]->GetName();
|
||||
}
|
||||
}
|
||||
|
||||
pShaderPickerDialog->AddActionSignalTarget( this );
|
||||
pShaderPickerDialog->DoModal( shaderList );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called by the picker dialog if a asset was selected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeShaderPickerPanel::OnPicked( KeyValues *pKeyValues )
|
||||
{
|
||||
// Get the asset name back
|
||||
const char *pShaderName = pKeyValues->GetString( "choice", NULL );
|
||||
if ( !pShaderName || !pShaderName[ 0 ] )
|
||||
return;
|
||||
|
||||
// Apply to text panel
|
||||
m_pData->SetText( pShaderName );
|
||||
SetDirty(true);
|
||||
if ( IsAutoApply() )
|
||||
{
|
||||
Apply();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,103 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "dme_controls/AttributeSurfacePropertyPickerPanel.h"
|
||||
#include "dme_controls/AttributeTextEntry.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
const char *SURFACEPROP_MANIFEST_FILE = "scripts/surfaceproperties_manifest.txt";
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAttributeSurfacePropertyPickerPanel::CAttributeSurfacePropertyPickerPanel( vgui::Panel *parent, const AttributeWidgetInfo_t &info ) :
|
||||
BaseClass( parent, info )
|
||||
{
|
||||
}
|
||||
|
||||
CAttributeSurfacePropertyPickerPanel::~CAttributeSurfacePropertyPickerPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Reads the surface properties
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeSurfacePropertyPickerPanel::AddSurfacePropertiesToList( PickerList_t &list )
|
||||
{
|
||||
KeyValues *manifest = new KeyValues( SURFACEPROP_MANIFEST_FILE );
|
||||
if ( manifest->LoadFromFile( g_pFullFileSystem, SURFACEPROP_MANIFEST_FILE, "GAME" ) )
|
||||
{
|
||||
for ( KeyValues *sub = manifest->GetFirstSubKey(); sub != NULL; sub = sub->GetNextKey() )
|
||||
{
|
||||
if ( Q_stricmp( sub->GetName(), "file" ) )
|
||||
continue;
|
||||
|
||||
KeyValues *file = new KeyValues( SURFACEPROP_MANIFEST_FILE );
|
||||
if ( file->LoadFromFile( g_pFullFileSystem, sub->GetString(), "GAME" ) )
|
||||
{
|
||||
for ( KeyValues *pTrav = file; pTrav; pTrav = pTrav->GetNextKey() )
|
||||
{
|
||||
int i = list.AddToTail();
|
||||
list[i].m_pChoiceString = pTrav->GetName();
|
||||
list[i].m_pChoiceValue = pTrav->GetName();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "Unable to load surface properties file '%s'\n", sub->GetString() );
|
||||
}
|
||||
file->deleteThis();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "Unable to load manifest file '%s'\n", SURFACEPROP_MANIFEST_FILE );
|
||||
}
|
||||
|
||||
manifest->deleteThis();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when it's time to show the picker
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeSurfacePropertyPickerPanel::ShowPickerDialog()
|
||||
{
|
||||
CPickerFrame *pSurfacePropPickerDialog = new CPickerFrame( this, "Select Surface Property", "Surface Property", "surfacePropertyName" );
|
||||
PickerList_t surfacePropList;
|
||||
AddSurfacePropertiesToList( surfacePropList );
|
||||
pSurfacePropPickerDialog->AddActionSignalTarget( this );
|
||||
pSurfacePropPickerDialog->DoModal( surfacePropList );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called by the picker dialog if a asset was selected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAttributeSurfacePropertyPickerPanel::OnPicked( KeyValues *pKeyValues )
|
||||
{
|
||||
// Get the asset name back
|
||||
const char *pSurfacePropertyName = pKeyValues->GetString( "choice", NULL );
|
||||
if ( !pSurfacePropertyName || !pSurfacePropertyName[ 0 ] )
|
||||
return;
|
||||
|
||||
// Apply to text panel
|
||||
m_pData->SetText( pSurfacePropertyName );
|
||||
SetDirty(true);
|
||||
if ( IsAutoApply() )
|
||||
{
|
||||
Apply();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// DME_CONTROLS.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$PreprocessorDefinitions "$BASE;DMECONTROLS_LIB"
|
||||
$PrecompiledHeaderFile "Debug/dme_controls.pch"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Dme_controls"
|
||||
{
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\dme_controls\AttributeSlider.h"
|
||||
$File "$SRCDIR\public\dme_controls\AssetBuilder.h"
|
||||
$File "$SRCDIR\public\dme_controls\attributeassetpickerpanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\AttributeBasePickerPanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\AttributeBoolChoicePanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\AttributeColorPickerPanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\attributedetailtypepickerpanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\AttributeElementPanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\AttributeElementPickerPanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\AttributeFilePickerPanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\AttributeIntChoicePanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\AttributeInterpolatorChoicePanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\AttributeMDLPickerPanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\AttributeSequencePickerPanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\attributeshaderpickerpanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\AttributeSoundPickerPanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\AttributeStringChoicePanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\attributesurfacepropertypickerpanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\AttributeTextEntry.h"
|
||||
$File "$SRCDIR\public\dme_controls\AttributeTextPanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\AttributeWidgetFactory.h"
|
||||
$File "$SRCDIR\public\dme_controls\BaseAttributeChoicePanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\BaseAttributeDoubleChoicePanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\BaseAttributePanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\ChannelGraphPanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\dmecombinationsystemeditorpanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\dmecontrols.h"
|
||||
$File "$SRCDIR\public\dme_controls\dmecontrols_utils.h"
|
||||
$File "$SRCDIR\public\dme_controls\dmedageditpanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\dmedagrenderpanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\dmemdlpanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\dmepanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\dmepicker.h"
|
||||
$File "$SRCDIR\public\dme_controls\dmepresetgroupeditorpanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\DmeSourceDCCFilePanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\DmeSourceSkinPanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\ElementPropertiesTree.h"
|
||||
$File "$SRCDIR\public\dme_controls\FileListManager.h"
|
||||
$File "$SRCDIR\public\dme_controls\filtercombobox.h"
|
||||
$File "$SRCDIR\public\dme_controls\inotifyui.h"
|
||||
$File "$SRCDIR\public\dme_controls\particlesystempanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\particlesystempropertiespanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\soundpicker.h"
|
||||
$File "$SRCDIR\public\dme_controls\soundrecordpanel.h"
|
||||
}
|
||||
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "AttributeSlider.cpp"
|
||||
$File "AssetBuilder.cpp"
|
||||
$File "attributeassetpickerpanel.cpp"
|
||||
$File "AttributeBasePickerPanel.cpp"
|
||||
$File "AttributeBoolChoicePanel.cpp"
|
||||
$File "AttributeColorPickerPanel.cpp"
|
||||
$File "attributedetailtypepickerpanel.cpp"
|
||||
$File "AttributeElementPanel.cpp"
|
||||
$File "AttributeElementPickerPanel.cpp"
|
||||
$File "AttributeFilePickerPanel.cpp"
|
||||
$File "AttributeIntChoicePanel.cpp"
|
||||
$File "AttributeInterpolatorChoicePanel.cpp"
|
||||
$File "AttributeMDLPickerPanel.cpp"
|
||||
$File "AttributeSequencePickerPanel.cpp"
|
||||
$File "attributeshaderpickerpanel.cpp"
|
||||
$File "AttributeSoundPickerPanel.cpp"
|
||||
$File "AttributeStringChoicePanel.cpp"
|
||||
$File "attributesurfacepropertypickerpanel.cpp"
|
||||
$File "AttributeTextEntry.cpp"
|
||||
$File "AttributeTextPanel.cpp"
|
||||
$File "AttributeWidgetFactory.cpp"
|
||||
$File "BaseAttributeChoicePanel.cpp"
|
||||
$File "BaseAttributeDoubleChoicePanel.cpp"
|
||||
$File "BaseAttributePanel.cpp"
|
||||
$File "ChannelGraphPanel.cpp"
|
||||
$File "dmecombinationsystemeditorpanel.cpp"
|
||||
$File "dmecontrols.cpp"
|
||||
$File "dmedageditpanel.cpp"
|
||||
$File "dmedagrenderpanel.cpp"
|
||||
$File "dmelogeditpanel.cpp"
|
||||
$File "dmemdlpanel.cpp"
|
||||
$File "dmepanel.cpp"
|
||||
$File "dmepicker.cpp"
|
||||
$File "dmepresetgroupeditorpanel.cpp"
|
||||
$File "DmeSourceDCCFilePanel.cpp"
|
||||
$File "DmeSourceSkinPanel.cpp"
|
||||
$File "ElementPropertiesTree.cpp"
|
||||
$File "FileListManager.cpp"
|
||||
$File "filtercombobox.cpp"
|
||||
$File "particlesystempanel.cpp"
|
||||
$File "particlesystempropertiespanel.cpp"
|
||||
$File "soundpicker.cpp"
|
||||
$File "soundrecordpanel.cpp"
|
||||
|
||||
$Folder "Animation Set Editor"
|
||||
{
|
||||
$File "$SRCDIR\public\dme_controls\AnimSetAttributeValue.h"
|
||||
$File "BaseAnimationSetEditor.cpp"
|
||||
$File "$SRCDIR\public\dme_controls\BaseAnimationSetEditor.h"
|
||||
$File "BaseAnimSetAttributeSliderPanel.cpp"
|
||||
$File "$SRCDIR\public\dme_controls\BaseAnimSetAttributeSliderPanel.h"
|
||||
$File "BaseAnimSetControlGroupPanel.cpp"
|
||||
$File "$SRCDIR\public\dme_controls\BaseAnimSetControlGroupPanel.h"
|
||||
$File "BaseAnimSetPresetFaderPanel.cpp"
|
||||
$File "$SRCDIR\public\dme_controls\BaseAnimSetPresetFaderPanel.h"
|
||||
$File "$SRCDIR\public\dme_controls\LogPreview.h"
|
||||
$File "presetpicker.cpp"
|
||||
$File "$SRCDIR\public\dme_controls\presetpicker.h"
|
||||
$File "$SRCDIR\public\dme_controls\RecordingState.h"
|
||||
$File "$SRCDIR\public\phonemeconverter.cpp"
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,102 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "dme_controls/dmecontrols.h"
|
||||
#include "soundemittersystem/isoundemittersystembase.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "toolframework/ienginetool.h"
|
||||
#include "vphysics_interface.h"
|
||||
#include "dme_controls/inotifyui.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
|
||||
ISoundEmitterSystemBase *g_pSoundEmitterSystem = NULL;
|
||||
ISoundEmitterSystemBase *SoundEmitterSystem()
|
||||
{
|
||||
return g_pSoundEmitterSystem;
|
||||
}
|
||||
|
||||
IEngineTool *enginetools = NULL;
|
||||
IEngineTool *EngineTool()
|
||||
{
|
||||
return enginetools;
|
||||
}
|
||||
|
||||
IPhysicsCollision *g_pPhysicsCollision = NULL;
|
||||
IPhysicsCollision *PhysicsCollision()
|
||||
{
|
||||
return g_pPhysicsCollision;
|
||||
}
|
||||
|
||||
class CDefaultElementPropertiesChoices : public CBaseElementPropertiesChoices
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
static CDefaultElementPropertiesChoices s_DefaultChoices;
|
||||
IElementPropertiesChoices *g_pElementPropertiesChoices = &s_DefaultChoices;
|
||||
IElementPropertiesChoices *ElementPropertiesChoices()
|
||||
{
|
||||
return g_pElementPropertiesChoices;
|
||||
}
|
||||
|
||||
void SetElementPropertiesChoices( IElementPropertiesChoices *pElementPropertiesChoices )
|
||||
{
|
||||
g_pElementPropertiesChoices = pElementPropertiesChoices ? pElementPropertiesChoices : &s_DefaultChoices;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: finds a particular interface in the factory set
|
||||
//-----------------------------------------------------------------------------
|
||||
static void *InitializeInterface( char const *interfaceName, CreateInterfaceFn *factoryList, int numFactories )
|
||||
{
|
||||
void *retval;
|
||||
|
||||
for ( int i = 0; i < numFactories; i++ )
|
||||
{
|
||||
CreateInterfaceFn factory = factoryList[ i ];
|
||||
if ( !factory )
|
||||
continue;
|
||||
|
||||
retval = factory( interfaceName, NULL );
|
||||
if ( retval )
|
||||
return retval;
|
||||
}
|
||||
|
||||
// No provider for requested interface!!!
|
||||
// Assert( !"No provider for requested interface!!!" );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Initializes the controls
|
||||
//-----------------------------------------------------------------------------
|
||||
bool VGui_InitDmeInterfacesList( const char *moduleName, CreateInterfaceFn *factoryList, int numFactories )
|
||||
{
|
||||
if ( !vgui::VGui_InitMatSysInterfacesList( moduleName, factoryList, numFactories ) )
|
||||
return false;
|
||||
|
||||
g_pSoundEmitterSystem = (ISoundEmitterSystemBase*)InitializeInterface( SOUNDEMITTERSYSTEM_INTERFACE_VERSION, factoryList, numFactories );
|
||||
enginetools = (IEngineTool*)InitializeInterface( VENGINETOOL_INTERFACE_VERSION, factoryList, numFactories );
|
||||
g_pPhysicsCollision = (IPhysicsCollision*)InitializeInterface( VPHYSICS_COLLISION_INTERFACE_VERSION, factoryList, numFactories );
|
||||
|
||||
// Can function without either of these
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace vgui
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,739 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "dme_controls/dmedagrenderpanel.h"
|
||||
#include "movieobjects/dmedag.h"
|
||||
#include "movieobjects/dmemodel.h"
|
||||
#include "movieobjects/timeutils.h"
|
||||
#include "movieobjects/dmeanimationlist.h"
|
||||
#include "movieobjects/dmeclip.h"
|
||||
#include "movieobjects/dmechannel.h"
|
||||
#include "movieobjects/dmemdlmakefile.h"
|
||||
#include "movieobjects/dmedccmakefile.h"
|
||||
#include "movieobjects/dmemesh.h"
|
||||
#include "movieobjects/dmedrawsettings.h"
|
||||
#include "dme_controls/dmepanel.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "tier3/tier3.h"
|
||||
#include "materialsystem/imaterialsystemhardwareconfig.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "vgui_controls/Menu.h"
|
||||
#include "vgui_controls/MenuBar.h"
|
||||
#include "vgui_controls/MenuButton.h"
|
||||
#include "vgui/IVGui.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Hook into the dme panel editor system
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeDag, "DmeDagRenderer", "DmeDag Preview Renderer", false );
|
||||
IMPLEMENT_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeSourceSkin, "DmeSourceSkinPreview", "MDL Skin Previewer", false );
|
||||
IMPLEMENT_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeSourceAnimation, "DmeSourceAnimationPreview", "MDL Animation Previewer", false );
|
||||
IMPLEMENT_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeDCCMakefile, "DmeMakeFileOutputPreview", "DCC MakeFile Output Preview", false );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmeDagRenderPanel::CDmeDagRenderPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
|
||||
{
|
||||
// Used to poll input
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||||
|
||||
m_bDrawJointNames = false;
|
||||
m_bDrawJoints = false;
|
||||
m_bDrawGrid = true;
|
||||
|
||||
// Deal with the default cubemap
|
||||
ITexture *pCubemapTexture = g_pMaterialSystem->FindTexture( "editor/cubemap", NULL, true );
|
||||
m_DefaultEnvCubemap.Init( pCubemapTexture );
|
||||
pCubemapTexture = g_pMaterialSystem->FindTexture( "editor/cubemap.hdr", NULL, true );
|
||||
m_DefaultHDREnvCubemap.Init( pCubemapTexture );
|
||||
|
||||
m_pDrawSettings = CreateElement< CDmeDrawSettings >( "drawSettings", g_pDataModel->FindOrCreateFileId( "DagRenderPanelDrawSettings" ) );
|
||||
m_hDrawSettings = m_pDrawSettings;
|
||||
|
||||
m_pMenuBar = new vgui::MenuBar( this, "Dag Render Panel Menu Bar" );
|
||||
|
||||
m_pShadingMenu = new vgui::Menu( NULL, "Shading Menu" );
|
||||
m_nMenuSmoothShade = m_pShadingMenu->AddCheckableMenuItem( "&Smooth Shade", new KeyValues( "SmoothShade" ), this );
|
||||
m_nMenuFlatShade = m_pShadingMenu->AddCheckableMenuItem( "&Flat Shade", new KeyValues( "FlatShade" ), this );
|
||||
m_nMenuWireframe = m_pShadingMenu->AddCheckableMenuItem( "&Wireframe", new KeyValues( "Wireframe" ), this );
|
||||
m_pShadingMenu->AddSeparator();
|
||||
m_nMenuBoundingBox = m_pShadingMenu->AddCheckableMenuItem( "&Bounding Box", new KeyValues( "BoundingBox" ), this );
|
||||
m_pShadingMenu->AddSeparator(); // Bug is visibility
|
||||
m_nMenuNormals = m_pShadingMenu->AddCheckableMenuItem( "&Normals", new KeyValues( "Normals" ), this );
|
||||
m_nMenuWireframeOnShaded = m_pShadingMenu->AddCheckableMenuItem( "WireFrame &On Shaded", new KeyValues( "WireframeOnShaded" ), this );
|
||||
m_nMenuBackfaceCulling = m_pShadingMenu->AddCheckableMenuItem( "&Backface Culling", new KeyValues( "BackfaceCulling" ), this );
|
||||
m_nMenuXRay = m_pShadingMenu->AddCheckableMenuItem( "&X-Ray", new KeyValues( "XRay" ), this );
|
||||
m_nMenuGrayShade = m_pShadingMenu->AddCheckableMenuItem( "&Gray Shade", new KeyValues( "GrayShade" ), this );
|
||||
|
||||
// For now...
|
||||
m_pShadingMenu->SetItemVisible( m_nMenuFlatShade, false );
|
||||
m_pShadingMenu->SetItemEnabled( m_nMenuFlatShade, false );
|
||||
m_pShadingMenu->SetItemVisible( m_nMenuBoundingBox, false );
|
||||
m_pShadingMenu->SetItemEnabled( m_nMenuBoundingBox, false );
|
||||
m_pShadingMenu->SetItemVisible( m_nMenuBackfaceCulling, false );
|
||||
m_pShadingMenu->SetItemEnabled( m_nMenuBackfaceCulling, false );
|
||||
m_pShadingMenu->SetItemVisible( m_nMenuXRay, false );
|
||||
m_pShadingMenu->SetItemEnabled( m_nMenuXRay, false );
|
||||
|
||||
m_pMenuBar->AddMenu( "&Shading", m_pShadingMenu );
|
||||
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmeDagRenderPanel::~CDmeDagRenderPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scheme settings
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
SetBorder( pScheme->GetBorder( "MenuBorder") );
|
||||
m_hFont = pScheme->GetFont( "DmePropertyVerySmall", IsProportional() );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set the scene
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::SetDmeElement( CDmeDag *pScene )
|
||||
{
|
||||
m_hDag = pScene;
|
||||
ComputeDefaultTangentData( m_hDag, false );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Other methods which hook into DmePanel
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::SetDmeElement( CDmeSourceSkin *pSkin )
|
||||
{
|
||||
// First, try to grab the dependent makefile
|
||||
CDmeMakefile *pSourceMakefile = pSkin->GetDependentMakefile();
|
||||
if ( !pSourceMakefile )
|
||||
{
|
||||
m_hDag = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Next, try to grab the output of that makefile
|
||||
CDmElement *pOutput = pSourceMakefile->GetOutputElement( true );
|
||||
if ( !pOutput )
|
||||
{
|
||||
m_hDag = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Finally, grab the 'skin' attribute of that makefile
|
||||
m_hDag = pOutput->GetValueElement< CDmeDag >( "model" );
|
||||
ComputeDefaultTangentData( m_hDag, false );
|
||||
DrawJoints( false );
|
||||
DrawJointNames( false );
|
||||
}
|
||||
|
||||
void CDmeDagRenderPanel::SetDmeElement( CDmeSourceAnimation *pAnimation )
|
||||
{
|
||||
// First, try to grab the dependent makefile
|
||||
CDmeMakefile *pSourceMakefile = pAnimation->GetDependentMakefile();
|
||||
if ( !pSourceMakefile )
|
||||
{
|
||||
m_hDag = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Next, try to grab the output of that makefile
|
||||
CDmElement *pOutput = pSourceMakefile->GetOutputElement( true );
|
||||
if ( !pOutput )
|
||||
{
|
||||
m_hDag = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Finally, grab the 'model' or 'skeleton' attribute of that makefile
|
||||
CDmeDag *pDag = pOutput->GetValueElement< CDmeDag >( "model" );
|
||||
if ( !pDag )
|
||||
{
|
||||
pDag = pOutput->GetValueElement< CDmeDag >( "skeleton" );
|
||||
}
|
||||
if ( !pDag )
|
||||
return;
|
||||
|
||||
CDmeAnimationList *pAnimationList = pOutput->GetValueElement< CDmeAnimationList >( "animationList" );
|
||||
if ( !pAnimationList )
|
||||
return;
|
||||
|
||||
if ( pAnimationList->FindAnimation( pAnimation->m_SourceAnimationName ) < 0 )
|
||||
return;
|
||||
|
||||
m_hDag = pDag;
|
||||
ComputeDefaultTangentData( m_hDag, false );
|
||||
m_hAnimationList = pAnimationList;
|
||||
SelectAnimation( pAnimation->m_SourceAnimationName );
|
||||
DrawJoints( true );
|
||||
DrawJointNames( true );
|
||||
}
|
||||
|
||||
void CDmeDagRenderPanel::SetDmeElement( CDmeDCCMakefile *pDCCMakefile )
|
||||
{
|
||||
// First, try to grab the dependent makefile
|
||||
CDmElement *pOutputElement = pDCCMakefile->GetOutputElement( true );
|
||||
if ( !pOutputElement )
|
||||
{
|
||||
m_hDag = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Finally, grab the 'model' or 'skeleton' attribute of that makefile
|
||||
CDmeDag *pDag = pOutputElement->GetValueElement< CDmeDag >( "model" );
|
||||
if ( !pDag )
|
||||
{
|
||||
pDag = pOutputElement->GetValueElement< CDmeDag >( "skeleton" );
|
||||
}
|
||||
if ( !pDag )
|
||||
return;
|
||||
|
||||
CDmeAnimationList *pAnimationList = pOutputElement->GetValueElement< CDmeAnimationList >( "animationList" );
|
||||
|
||||
m_hDag = pDag;
|
||||
ComputeDefaultTangentData( m_hDag, false );
|
||||
m_hAnimationList = pAnimationList;
|
||||
SelectAnimation( 0 );
|
||||
DrawJoints( pAnimationList != NULL );
|
||||
DrawJointNames( pAnimationList != NULL );
|
||||
}
|
||||
|
||||
CDmeDag *CDmeDagRenderPanel::GetDmeElement()
|
||||
{
|
||||
return m_hDag;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw joint names
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::DrawJointNames( CDmeDag *pRoot, CDmeDag *pDag, const matrix3x4_t& parentToWorld )
|
||||
{
|
||||
CDmeTransform *pJointTransform = pDag->GetTransform();
|
||||
int nJointIndex = -1;
|
||||
|
||||
CDmeModel *pRootModel = CastElement<CDmeModel>( pRoot );
|
||||
if ( pRootModel )
|
||||
{
|
||||
nJointIndex = pRootModel->GetJointTransformIndex( pJointTransform );
|
||||
if ( nJointIndex < 0 && pRootModel != pDag )
|
||||
return;
|
||||
}
|
||||
|
||||
matrix3x4_t jointToParent, jointToWorld;
|
||||
pJointTransform->GetTransform( jointToParent );
|
||||
ConcatTransforms( parentToWorld, jointToParent, jointToWorld );
|
||||
|
||||
CDmeJoint *pJoint = CastElement< CDmeJoint >( pDag );
|
||||
if ( pJoint )
|
||||
{
|
||||
Vector vecJointOrigin;
|
||||
MatrixGetColumn( jointToWorld, 3, &vecJointOrigin );
|
||||
|
||||
Vector2D vecPanelPos;
|
||||
ComputePanelPosition( vecJointOrigin, &vecPanelPos );
|
||||
|
||||
char pJointName[512];
|
||||
if ( nJointIndex >= 0 )
|
||||
{
|
||||
Q_snprintf( pJointName, sizeof(pJointName), "%d : %s", nJointIndex, pJoint->GetName() );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( pJointName, sizeof(pJointName), "%s", pJoint->GetName() );
|
||||
}
|
||||
g_pMatSystemSurface->DrawColoredText( m_hFont, vecPanelPos.x + 5, vecPanelPos.y, 255, 255, 255, 255, pJointName );
|
||||
}
|
||||
|
||||
int nCount = pDag->GetChildCount();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmeDag *pChild = pDag->GetChild(i);
|
||||
if ( !pChild )
|
||||
continue;
|
||||
|
||||
DrawJointNames( pRoot, pChild, jointToWorld );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::OnSmoothShade()
|
||||
{
|
||||
if ( m_pShadingMenu->IsChecked( m_nMenuSmoothShade ) )
|
||||
{
|
||||
m_pDrawSettings->SetDrawType( CDmeDrawSettings::DRAW_SMOOTH );
|
||||
}
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::OnFlatShade()
|
||||
{
|
||||
if ( m_pShadingMenu->IsChecked( m_nMenuFlatShade ) )
|
||||
{
|
||||
m_pDrawSettings->SetDrawType( CDmeDrawSettings::DRAW_FLAT );
|
||||
}
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::OnWireframe()
|
||||
{
|
||||
if ( m_pShadingMenu->IsChecked( m_nMenuWireframe ) )
|
||||
{
|
||||
m_pDrawSettings->SetDrawType( CDmeDrawSettings::DRAW_WIREFRAME );
|
||||
}
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::OnBoundingBox()
|
||||
{
|
||||
if ( m_pShadingMenu->IsChecked( m_nMenuBoundingBox ) )
|
||||
{
|
||||
m_pDrawSettings->SetDrawType( CDmeDrawSettings::DRAW_BOUNDINGBOX );
|
||||
}
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::OnNormals()
|
||||
{
|
||||
m_pDrawSettings->SetNormals( m_pShadingMenu->IsChecked( m_nMenuNormals ) );
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::OnWireframeOnShaded()
|
||||
{
|
||||
m_pDrawSettings->SetWireframeOnShaded( m_pShadingMenu->IsChecked( m_nMenuWireframeOnShaded ) );
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::OnBackfaceCulling()
|
||||
{
|
||||
m_pDrawSettings->SetBackfaceCulling( m_pShadingMenu->IsChecked( m_nMenuBackfaceCulling ) );
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::OnXRay()
|
||||
{
|
||||
m_pDrawSettings->SetXRay( m_pShadingMenu->IsChecked( m_nMenuXRay ) );
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::OnGrayShade()
|
||||
{
|
||||
m_pDrawSettings->SetGrayShade( m_pShadingMenu->IsChecked( m_nMenuGrayShade ) );
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::OnFrame()
|
||||
{
|
||||
if ( !m_hDag )
|
||||
return;
|
||||
|
||||
float flRadius;
|
||||
Vector vecCenter, vecWorldCenter;
|
||||
m_hDag->GetBoundingSphere( vecCenter, flRadius );
|
||||
|
||||
matrix3x4_t dmeToEngine;
|
||||
CDmeDag::DmeToEngineMatrix( dmeToEngine );
|
||||
VectorTransform( vecCenter, dmeToEngine, vecWorldCenter );
|
||||
LookAt( vecWorldCenter, flRadius );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
if ( m_pMenuBar->IsVisible() )
|
||||
{
|
||||
int iWidth;
|
||||
int iHeight;
|
||||
GetSize( iWidth, iHeight );
|
||||
|
||||
int iMenuWidth; // Unused
|
||||
int iMenuHeight;
|
||||
m_pMenuBar->GetSize( iMenuWidth, iMenuHeight );
|
||||
m_pMenuBar->SetSize( iWidth, iMenuHeight );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// paint it!
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::Paint()
|
||||
{
|
||||
if ( m_hCurrentAnimation.Get() )
|
||||
{
|
||||
DmeTime_t currentTime( Plat_FloatTime() - m_flStartTime );
|
||||
if ( m_hCurrentAnimation->GetDuration() != DMETIME_ZERO )
|
||||
{
|
||||
currentTime = currentTime % m_hCurrentAnimation->GetDuration();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentTime = DMETIME_ZERO;
|
||||
}
|
||||
currentTime += m_hCurrentAnimation->GetStartTime();
|
||||
DmeTime_t mediaTime = m_hCurrentAnimation->ToChildMediaTime( currentTime, true );
|
||||
|
||||
int nChannelCount = m_hCurrentAnimation->m_Channels.Count();
|
||||
for ( int i = 0; i < nChannelCount; ++i )
|
||||
{
|
||||
m_hCurrentAnimation->m_Channels[i]->SetCurrentTime( mediaTime );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_hCurrentVertexAnimation.Get() )
|
||||
{
|
||||
DmeTime_t currentTime( Plat_FloatTime() - m_flStartTime );
|
||||
currentTime = currentTime % m_hCurrentVertexAnimation->GetDuration();
|
||||
currentTime += m_hCurrentVertexAnimation->GetStartTime();
|
||||
DmeTime_t mediaTime = m_hCurrentVertexAnimation->ToChildMediaTime( currentTime, true );
|
||||
|
||||
int nChannelCount = m_hCurrentVertexAnimation->m_Channels.Count();
|
||||
for ( int i = 0; i < nChannelCount; ++i )
|
||||
{
|
||||
m_hCurrentVertexAnimation->m_Channels[i]->SetCurrentTime( mediaTime );
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Shouldn't this happen at the application level?
|
||||
// run the machinery - apply, resolve, dependencies, operate, resolve
|
||||
{
|
||||
CDisableUndoScopeGuard guard;
|
||||
g_pDmElementFramework->SetOperators( m_operators );
|
||||
g_pDmElementFramework->Operate( true );
|
||||
}
|
||||
|
||||
// allow elements and attributes to be edited again
|
||||
g_pDmElementFramework->BeginEdit();
|
||||
|
||||
BaseClass::Paint();
|
||||
|
||||
// Overlay the joint names
|
||||
if ( m_bDrawJointNames && m_hDag )
|
||||
{
|
||||
matrix3x4_t modelToWorld;
|
||||
CDmeDag::DmeToEngineMatrix( modelToWorld );
|
||||
DrawJointNames( m_hDag, m_hDag, modelToWorld );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Indicate we should draw joint names
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::DrawJointNames( bool bDrawJointNames )
|
||||
{
|
||||
m_bDrawJointNames = bDrawJointNames;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Indicate we should draw joints
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::DrawJoints( bool bDrawJoint )
|
||||
{
|
||||
m_bDrawJoints = bDrawJoint;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Indicate we should draw the grid
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::DrawGrid( bool bDrawGrid )
|
||||
{
|
||||
m_bDrawGrid = bDrawGrid;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// paint it!
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::OnPaint3D()
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
||||
ITexture *pLocalCube = pRenderContext->GetLocalCubemap();
|
||||
if ( g_pMaterialSystemHardwareConfig->GetHDRType() == HDR_TYPE_NONE )
|
||||
{
|
||||
pRenderContext->BindLocalCubemap( m_DefaultEnvCubemap );
|
||||
}
|
||||
else
|
||||
{
|
||||
pRenderContext->BindLocalCubemap( m_DefaultHDREnvCubemap );
|
||||
}
|
||||
|
||||
if ( m_bDrawGrid )
|
||||
{
|
||||
BaseClass::DrawGrid();
|
||||
}
|
||||
|
||||
if ( m_bDrawJoints )
|
||||
{
|
||||
CDmeJoint::DrawJointHierarchy( true );
|
||||
}
|
||||
|
||||
pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
|
||||
CDmeDag::DrawUsingEngineCoordinates( true );
|
||||
m_pDrawSettings->DrawDag( m_hDag );
|
||||
CDmeDag::DrawUsingEngineCoordinates( false );
|
||||
|
||||
pRenderContext->Flush();
|
||||
pRenderContext->BindLocalCubemap( pLocalCube );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// input
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::OnMouseDoublePressed( vgui::MouseCode code )
|
||||
{
|
||||
OnFrame();
|
||||
|
||||
BaseClass::OnMouseDoublePressed( code );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// TODO: Have a whole groovy keybinding thingy like SFM
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::OnKeyCodePressed( vgui::KeyCode code )
|
||||
{
|
||||
BaseClass::OnKeyCodePressed( code );
|
||||
|
||||
if ( code == KEY_F )
|
||||
{
|
||||
OnFrame();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Rebuilds the list of operators
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::RebuildOperatorList( )
|
||||
{
|
||||
m_operators.RemoveAll();
|
||||
|
||||
if ( m_hCurrentAnimation.Get() )
|
||||
{
|
||||
int nChannelCount = m_hCurrentAnimation->m_Channels.Count();
|
||||
for ( int i = 0; i < nChannelCount; ++i )
|
||||
{
|
||||
m_hCurrentAnimation->m_Channels[i]->SetMode( CM_PLAY );
|
||||
m_operators.AddToTail( m_hCurrentAnimation->m_Channels[i] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_hCurrentVertexAnimation.Get() )
|
||||
{
|
||||
int nChannelCount = m_hCurrentVertexAnimation->m_Channels.Count();
|
||||
for ( int i = 0; i < nChannelCount; ++i )
|
||||
{
|
||||
m_hCurrentVertexAnimation->m_Channels[i]->SetMode( CM_PLAY );
|
||||
m_operators.AddToTail( m_hCurrentVertexAnimation->m_Channels[i] );
|
||||
}
|
||||
}
|
||||
|
||||
m_flStartTime = Plat_FloatTime();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Select animation by index
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::SelectAnimation( int nIndex )
|
||||
{
|
||||
m_hCurrentAnimation = NULL;
|
||||
if ( m_hAnimationList.Get() && ( nIndex >= 0 ) )
|
||||
{
|
||||
// FIXME: How is this actually going to work?
|
||||
m_hCurrentAnimation = m_hAnimationList->GetAnimation( nIndex );
|
||||
}
|
||||
RebuildOperatorList();
|
||||
}
|
||||
|
||||
void CDmeDagRenderPanel::SelectVertexAnimation( int nIndex )
|
||||
{
|
||||
m_hCurrentVertexAnimation = NULL;
|
||||
if ( m_hVertexAnimationList.Get() && ( nIndex >= 0 ) )
|
||||
{
|
||||
// FIXME: How is this actually going to work?
|
||||
m_hCurrentVertexAnimation = m_hVertexAnimationList->GetAnimation( nIndex );
|
||||
}
|
||||
RebuildOperatorList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Select animation by name
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::SelectAnimation( const char *pAnimName )
|
||||
{
|
||||
if ( !pAnimName[0] )
|
||||
{
|
||||
SelectAnimation( -1 );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_hAnimationList )
|
||||
{
|
||||
int nIndex = m_hAnimationList->FindAnimation( pAnimName );
|
||||
if ( nIndex >= 0 )
|
||||
{
|
||||
SelectAnimation( nIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDmeDagRenderPanel::SelectVertexAnimation( const char *pAnimName )
|
||||
{
|
||||
if ( !pAnimName[0] )
|
||||
{
|
||||
SelectVertexAnimation( -1 );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_hVertexAnimationList )
|
||||
{
|
||||
int nIndex = m_hVertexAnimationList->FindAnimation( pAnimName );
|
||||
if ( nIndex >= 0 )
|
||||
{
|
||||
SelectVertexAnimation( nIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets animation
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::SetAnimationList( CDmeAnimationList *pAnimationList )
|
||||
{
|
||||
m_hAnimationList = pAnimationList;
|
||||
int nCount = pAnimationList ? pAnimationList->GetAnimationCount() : 0;
|
||||
if ( nCount == 0 )
|
||||
{
|
||||
m_hCurrentAnimation = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
SelectAnimation( 0 );
|
||||
}
|
||||
|
||||
|
||||
void CDmeDagRenderPanel::SetVertexAnimationList( CDmeAnimationList *pAnimationList )
|
||||
{
|
||||
m_hVertexAnimationList = pAnimationList;
|
||||
int nCount = pAnimationList ? pAnimationList->GetAnimationCount() : 0;
|
||||
if ( nCount == 0 )
|
||||
{
|
||||
m_hCurrentVertexAnimation = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
SelectVertexAnimation( 0 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeDagRenderPanel::UpdateMenu()
|
||||
{
|
||||
switch ( m_pDrawSettings->GetDrawType() )
|
||||
{
|
||||
case CDmeDrawSettings::DRAW_FLAT:
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuSmoothShade, false );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuFlatShade, true );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuWireframe, false );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuBoundingBox, false );
|
||||
break;
|
||||
case CDmeDrawSettings::DRAW_WIREFRAME:
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuSmoothShade, false );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuFlatShade, false );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuWireframe, true );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuBoundingBox, false );
|
||||
break;
|
||||
case CDmeDrawSettings::DRAW_BOUNDINGBOX:
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuSmoothShade, false );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuFlatShade, false );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuWireframe, false );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuBoundingBox, true );
|
||||
break;
|
||||
default:
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuSmoothShade, true );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuFlatShade, false );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuWireframe, false );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuBoundingBox, false );
|
||||
break;
|
||||
}
|
||||
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuNormals, m_pDrawSettings->GetNormals() );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuWireframeOnShaded, m_pDrawSettings->GetWireframeOnShaded() );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuBackfaceCulling, m_pDrawSettings->GetBackfaceCulling() );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuXRay, m_pDrawSettings->GetXRay() );
|
||||
m_pShadingMenu->SetMenuItemChecked( m_nMenuGrayShade, m_pDrawSettings->GetGrayShade() );
|
||||
}
|
||||
@@ -0,0 +1,542 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "dme_controls/dmelogeditpanel.h"
|
||||
#include "movieobjects/dmelog.h"
|
||||
#include "vgui_controls/button.h"
|
||||
#include "vgui_controls/combobox.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmeLogEditPanel::CDmeLogEditPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
|
||||
{
|
||||
SetVisible( false );
|
||||
m_flMinVertical = 0;
|
||||
m_flMaxVertical = 256;
|
||||
}
|
||||
|
||||
CDmeLogEditPanel::~CDmeLogEditPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Converts normalized values to int time
|
||||
//-----------------------------------------------------------------------------
|
||||
DmeTime_t CDmeLogEditPanel::NormalizedToTime( float flIn )
|
||||
{
|
||||
return m_minTime + NormalizedToDuration( flIn );
|
||||
}
|
||||
|
||||
DmeTime_t CDmeLogEditPanel::NormalizedToDuration( float flDuration )
|
||||
{
|
||||
flDuration = clamp( flDuration, 0.0f, 1.0f );
|
||||
return flDuration * ( m_maxTime - m_minTime );
|
||||
}
|
||||
|
||||
float CDmeLogEditPanel::TimeToNormalized( DmeTime_t time )
|
||||
{
|
||||
if ( m_maxTime == m_minTime )
|
||||
return 0.0f;
|
||||
return GetFractionOfTimeBetween( time, m_minTime, m_maxTime, true );
|
||||
}
|
||||
|
||||
float CDmeLogEditPanel::NormalizedToValue( float flValue )
|
||||
{
|
||||
return Lerp( flValue, m_flMinVertical, m_flMaxVertical );
|
||||
}
|
||||
|
||||
float CDmeLogEditPanel::ValueToNormalized( float flNormalized )
|
||||
{
|
||||
if ( m_flMaxVertical == m_flMinVertical )
|
||||
return 0.0f;
|
||||
return (flNormalized - m_flMinVertical) / ( m_flMaxVertical - m_flMinVertical );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Control points + values...
|
||||
//-----------------------------------------------------------------------------
|
||||
int CDmeLogEditPanel::FindOrAddControlPoint( float flIn, float flTolerance, float flOut )
|
||||
{
|
||||
Assert( m_hLog.Get() );
|
||||
DmeTime_t time = NormalizedToTime( flIn );
|
||||
DmeTime_t tolerance = ( flTolerance >= 0 ) ? NormalizedToDuration( flTolerance ) : DmeTime_t( 0 );
|
||||
float flValue = NormalizedToValue( flOut );
|
||||
|
||||
int nKeyIndex = -1;
|
||||
|
||||
Assert( m_hLog.Get() );
|
||||
switch( m_hLog->GetDataType() )
|
||||
{
|
||||
case AT_BOOL:
|
||||
nKeyIndex = CastElement<CDmeBoolLog >( m_hLog )->FindOrAddKey( time, tolerance, (bool)(flValue >= 0.5f) );
|
||||
break;
|
||||
|
||||
case AT_INT:
|
||||
nKeyIndex = CastElement<CDmeIntLog >( m_hLog )->FindOrAddKey( time, tolerance, (int)(flValue + 0.5f) );
|
||||
break;
|
||||
|
||||
case AT_FLOAT:
|
||||
nKeyIndex = CastElement<CDmeFloatLog >( m_hLog )->FindOrAddKey( time, tolerance, flValue );
|
||||
break;
|
||||
|
||||
case AT_COLOR:
|
||||
{
|
||||
Color c = CastElement<CDmeColorLog >( m_hLog )->GetValue( time );
|
||||
int nComp = (int)( flValue + 0.5f );
|
||||
nComp = clamp( nComp, 0, 255 );
|
||||
for ( int i = 0; i < 4; ++i )
|
||||
{
|
||||
if ( m_LogFieldMask & (1 << i) )
|
||||
{
|
||||
c[i] = (unsigned char)nComp;
|
||||
}
|
||||
}
|
||||
nKeyIndex = CastElement<CDmeColorLog >( m_hLog )->FindOrAddKey( time, tolerance, c );
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_VECTOR2:
|
||||
nKeyIndex = FindOrAddKey< Vector2D >( time, tolerance, 2, flValue );
|
||||
break;
|
||||
|
||||
case AT_VECTOR3:
|
||||
nKeyIndex = FindOrAddKey< Vector >( time, tolerance, 3, flValue );
|
||||
break;
|
||||
|
||||
case AT_VECTOR4:
|
||||
nKeyIndex = FindOrAddKey< Vector4D >( time, tolerance, 4, flValue );
|
||||
break;
|
||||
|
||||
case AT_QANGLE:
|
||||
nKeyIndex = FindOrAddKey< QAngle >( time, tolerance, 3, flValue );
|
||||
break;
|
||||
|
||||
case AT_QUATERNION:
|
||||
nKeyIndex = FindOrAddKey< Quaternion >( time, tolerance, 4, flValue );
|
||||
break;
|
||||
}
|
||||
return nKeyIndex;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Finds a control point within tolerance
|
||||
//-----------------------------------------------------------------------------
|
||||
int CDmeLogEditPanel::FindControlPoint( float flIn, float flTolerance )
|
||||
{
|
||||
Assert( m_hLog.Get() );
|
||||
DmeTime_t time = NormalizedToTime( flIn );
|
||||
DmeTime_t tolerance = NormalizedToDuration( flTolerance );
|
||||
return m_hLog->FindKeyWithinTolerance( time, tolerance );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Modifies an existing control point
|
||||
//-----------------------------------------------------------------------------
|
||||
int CDmeLogEditPanel::ModifyControlPoint( int nPoint, float flIn, float flOut )
|
||||
{
|
||||
Assert( m_hLog.Get() );
|
||||
DmeTime_t time = NormalizedToTime( flIn );
|
||||
DmeTime_t initialTime = m_hLog->GetKeyTime( nPoint );
|
||||
float flValue = NormalizedToValue( flOut );
|
||||
|
||||
int nKeyIndex = -1;
|
||||
|
||||
Assert( m_hLog.Get() );
|
||||
switch( m_hLog->GetDataType() )
|
||||
{
|
||||
case AT_BOOL:
|
||||
RemoveControlPoint( nPoint );
|
||||
nKeyIndex = CastElement<CDmeBoolLog >( m_hLog )->FindOrAddKey( time, DmeTime_t( 0 ), (bool)(flValue >= 0.5f) );
|
||||
break;
|
||||
|
||||
case AT_INT:
|
||||
RemoveControlPoint( nPoint );
|
||||
nKeyIndex = CastElement<CDmeIntLog >( m_hLog )->FindOrAddKey( time, DmeTime_t( 0 ), (int)(flValue + 0.5f) );
|
||||
break;
|
||||
|
||||
case AT_FLOAT:
|
||||
RemoveControlPoint( nPoint );
|
||||
nKeyIndex = CastElement<CDmeFloatLog >( m_hLog )->FindOrAddKey( time, DmeTime_t( 0 ), flValue );
|
||||
break;
|
||||
|
||||
case AT_COLOR:
|
||||
{
|
||||
Color c = CastElement<CDmeColorLog >( m_hLog )->GetValue( initialTime );
|
||||
int nComp = (int)( flValue + 0.5f );
|
||||
nComp = clamp( nComp, 0, 255 );
|
||||
for ( int i = 0; i < 4; ++i )
|
||||
{
|
||||
if ( m_LogFieldMask & (1 << i) )
|
||||
{
|
||||
c[i] = (unsigned char)nComp;
|
||||
}
|
||||
}
|
||||
RemoveControlPoint( nPoint );
|
||||
nKeyIndex = CastElement<CDmeColorLog >( m_hLog )->FindOrAddKey( time, DmeTime_t( 0 ), c );
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_VECTOR2:
|
||||
nKeyIndex = ModifyKey< Vector2D >( nPoint, initialTime, time, 2, flValue );
|
||||
break;
|
||||
|
||||
case AT_VECTOR3:
|
||||
nKeyIndex = ModifyKey< Vector >( nPoint, initialTime, time, 3, flValue );
|
||||
break;
|
||||
|
||||
case AT_VECTOR4:
|
||||
nKeyIndex = ModifyKey< Vector4D >( nPoint, initialTime, time, 4, flValue );
|
||||
break;
|
||||
|
||||
case AT_QANGLE:
|
||||
nKeyIndex = ModifyKey< QAngle >( nPoint, initialTime, time, 3, flValue );
|
||||
break;
|
||||
|
||||
case AT_QUATERNION:
|
||||
nKeyIndex = ModifyKey< Quaternion >( nPoint, initialTime, time, 4, flValue );
|
||||
break;
|
||||
}
|
||||
return nKeyIndex;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Removes a single control point
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeLogEditPanel::RemoveControlPoint( int nPoint )
|
||||
{
|
||||
Assert( m_hLog.Get() );
|
||||
m_hLog->RemoveKey( nPoint );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the interpolated value of the log based on normalized time
|
||||
//-----------------------------------------------------------------------------
|
||||
float CDmeLogEditPanel::GetValue( float flIn )
|
||||
{
|
||||
DmeTime_t time = NormalizedToTime( flIn );
|
||||
|
||||
float flValue = 0.0f;
|
||||
|
||||
Assert( m_hLog.Get() );
|
||||
switch( m_hLog->GetDataType() )
|
||||
{
|
||||
case AT_BOOL:
|
||||
flValue = CastElement<CDmeBoolLog >( m_hLog )->GetValue( time );
|
||||
break;
|
||||
|
||||
case AT_INT:
|
||||
flValue = CastElement<CDmeIntLog >( m_hLog )->GetValue( time );
|
||||
break;
|
||||
|
||||
case AT_FLOAT:
|
||||
flValue = CastElement<CDmeFloatLog >( m_hLog )->GetValue( time );
|
||||
break;
|
||||
|
||||
case AT_COLOR:
|
||||
{
|
||||
Color c = CastElement<CDmeColorLog >( m_hLog )->GetValue( time );
|
||||
flValue = c[m_nFieldIndex];
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_VECTOR2:
|
||||
flValue = CastElement<CDmeVector2Log >( m_hLog )->GetValue( time )[m_nFieldIndex];
|
||||
break;
|
||||
|
||||
case AT_VECTOR3:
|
||||
flValue = CastElement<CDmeVector3Log >( m_hLog )->GetValue( time )[m_nFieldIndex];
|
||||
break;
|
||||
|
||||
case AT_VECTOR4:
|
||||
flValue = CastElement<CDmeVector2Log >( m_hLog )->GetValue( time )[m_nFieldIndex];
|
||||
break;
|
||||
|
||||
case AT_QANGLE:
|
||||
flValue = CastElement<CDmeQAngleLog >( m_hLog )->GetValue( time )[m_nFieldIndex];
|
||||
break;
|
||||
|
||||
case AT_QUATERNION:
|
||||
flValue = CastElement<CDmeQuaternionLog >( m_hLog )->GetValue( time )[m_nFieldIndex];
|
||||
break;
|
||||
}
|
||||
|
||||
return ValueToNormalized( flValue );
|
||||
}
|
||||
|
||||
int CDmeLogEditPanel::ControlPointCount()
|
||||
{
|
||||
Assert( m_hLog.Get() );
|
||||
return m_hLog->GetKeyCount( );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets a particular control point's value
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeLogEditPanel::GetControlPoint( int nPoint, float *pIn, float *pOut )
|
||||
{
|
||||
Assert( m_hLog.Get() );
|
||||
DmeTime_t time = m_hLog->GetKeyTime( nPoint );
|
||||
*pIn = TimeToNormalized( time );
|
||||
|
||||
float flValue = 0.0f;
|
||||
|
||||
Assert( m_hLog.Get() );
|
||||
switch( m_hLog->GetDataType() )
|
||||
{
|
||||
case AT_BOOL:
|
||||
flValue = CastElement<CDmeBoolLog >( m_hLog )->GetKeyValue( nPoint );
|
||||
break;
|
||||
|
||||
case AT_INT:
|
||||
flValue = CastElement<CDmeIntLog >( m_hLog )->GetKeyValue( nPoint );
|
||||
break;
|
||||
|
||||
case AT_FLOAT:
|
||||
flValue = CastElement<CDmeFloatLog >( m_hLog )->GetKeyValue( nPoint );
|
||||
break;
|
||||
|
||||
case AT_COLOR:
|
||||
{
|
||||
Color c = CastElement<CDmeColorLog >( m_hLog )->GetKeyValue( nPoint );
|
||||
flValue = c[m_nFieldIndex];
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_VECTOR2:
|
||||
flValue = CastElement<CDmeVector2Log >( m_hLog )->GetKeyValue( nPoint )[m_nFieldIndex];
|
||||
break;
|
||||
|
||||
case AT_VECTOR3:
|
||||
flValue = CastElement<CDmeVector3Log >( m_hLog )->GetKeyValue( nPoint )[m_nFieldIndex];
|
||||
break;
|
||||
|
||||
case AT_VECTOR4:
|
||||
flValue = CastElement<CDmeVector2Log >( m_hLog )->GetKeyValue( nPoint )[m_nFieldIndex];
|
||||
break;
|
||||
|
||||
case AT_QANGLE:
|
||||
flValue = CastElement<CDmeQAngleLog >( m_hLog )->GetKeyValue( nPoint )[m_nFieldIndex];
|
||||
break;
|
||||
|
||||
case AT_QUATERNION:
|
||||
flValue = CastElement<CDmeQuaternionLog >( m_hLog )->GetKeyValue( nPoint )[m_nFieldIndex];
|
||||
break;
|
||||
}
|
||||
|
||||
*pOut = ValueToNormalized( flValue );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the log to edit
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeLogEditPanel::SetDmeLog( CDmeLog *pLog )
|
||||
{
|
||||
bool bValid = pLog && ( pLog->GetDataType() == AT_INT || pLog->GetDataType() == AT_FLOAT || pLog->GetDataType() == AT_COLOR );
|
||||
if ( bValid )
|
||||
{
|
||||
m_hLog = pLog;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_minTime.SetSeconds( 0.0f );
|
||||
m_maxTime.SetSeconds( 0.0f );
|
||||
}
|
||||
SetVisible( bValid );
|
||||
}
|
||||
|
||||
|
||||
void CDmeLogEditPanel::SetMask( int nMask )
|
||||
{
|
||||
m_LogFieldMask = nMask;
|
||||
m_nFieldIndex = 0;
|
||||
for ( int i = 0; i < 4; ++i )
|
||||
{
|
||||
if ( m_LogFieldMask & (1 << i) )
|
||||
{
|
||||
m_nFieldIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the time range on the view in ms
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeLogEditPanel::SetTimeRange( DmeTime_t startTime, DmeTime_t endTime )
|
||||
{
|
||||
m_minTime = startTime;
|
||||
m_maxTime = endTime;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the vertical range on the view
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeLogEditPanel::SetVerticalRange( float flMin, float flMax )
|
||||
{
|
||||
m_flMinVertical = flMin;
|
||||
m_flMaxVertical = flMax;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: Modal picker frame
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmeLogEditFrame::CDmeLogEditFrame( vgui::Panel *pParent, const char *pTitle ) :
|
||||
BaseClass( pParent, "DmeLogEditFrame" )
|
||||
{
|
||||
m_pContextKeyValues = NULL;
|
||||
SetDeleteSelfOnClose( true );
|
||||
m_pCurveEditor = new CDmeLogEditPanel( this, "DmeLogEditPanel" );
|
||||
m_pOkButton = new Button( this, "OkButton", "#GameUI_OK", this, "Ok" );
|
||||
m_pCancelButton = new Button( this, "CancelButton", "#GameUI_Cancel", this, "Cancel" );
|
||||
m_pFilter = new ComboBox( this, "LogFilter", 5, false );
|
||||
SetBlockDragChaining( true );
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/dmelogeditframe.res" );
|
||||
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
CDmeLogEditFrame::~CDmeLogEditFrame()
|
||||
{
|
||||
CleanUpMessage();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Deletes the message
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeLogEditFrame::CleanUpMessage()
|
||||
{
|
||||
if ( m_pContextKeyValues )
|
||||
{
|
||||
m_pContextKeyValues->deleteThis();
|
||||
m_pContextKeyValues = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called when the combo box changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeLogEditFrame::OnTextChanged( )
|
||||
{
|
||||
KeyValues *pKeyValues = m_pFilter->GetActiveItemUserData();
|
||||
int nMask = pKeyValues->GetInt( "Value", CDmeLogEditPanel::FIELD_ALL );
|
||||
m_pCurveEditor->SetMask( nMask );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Activate the dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeLogEditFrame::DoModal( CDmeLog *pLog, DmeTime_t startTime, DmeTime_t endTime, KeyValues *pKeyValues )
|
||||
{
|
||||
CleanUpMessage();
|
||||
m_pContextKeyValues = pKeyValues;
|
||||
m_pCurveEditor->SetDmeLog( pLog );
|
||||
m_pCurveEditor->SetTimeRange( startTime, endTime );
|
||||
|
||||
m_pFilter->SetVisible( true );
|
||||
m_pFilter->RemoveAll();
|
||||
|
||||
switch( pLog->GetDataType() )
|
||||
{
|
||||
case AT_BOOL:
|
||||
case AT_INT:
|
||||
case AT_FLOAT:
|
||||
m_pFilter->SetVisible( false );
|
||||
break;
|
||||
|
||||
case AT_COLOR:
|
||||
m_pFilter->AddItem( "RGB Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_R | CDmeLogEditPanel::FIELD_G | CDmeLogEditPanel::FIELD_B ) );
|
||||
m_pFilter->AddItem( "Red Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_R ) );
|
||||
m_pFilter->AddItem( "Green Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_G ) );
|
||||
m_pFilter->AddItem( "Blue Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_B ) );
|
||||
m_pFilter->AddItem( "Alpha Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_A ) );
|
||||
break;
|
||||
|
||||
case AT_VECTOR2:
|
||||
m_pFilter->AddItem( "X Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_X ) );
|
||||
m_pFilter->AddItem( "Y Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_Y ) );
|
||||
break;
|
||||
|
||||
case AT_VECTOR3:
|
||||
case AT_QANGLE:
|
||||
m_pFilter->AddItem( "X Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_X ) );
|
||||
m_pFilter->AddItem( "Y Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_Y ) );
|
||||
m_pFilter->AddItem( "Z Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_Z ) );
|
||||
break;
|
||||
|
||||
case AT_VECTOR4:
|
||||
case AT_QUATERNION:
|
||||
m_pFilter->AddItem( "X Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_X ) );
|
||||
m_pFilter->AddItem( "Y Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_Y ) );
|
||||
m_pFilter->AddItem( "Z Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_Z ) );
|
||||
m_pFilter->AddItem( "W Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_W ) );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( m_pFilter->IsVisible() )
|
||||
{
|
||||
// Will cause the mask to be set
|
||||
m_pFilter->ActivateItemByRow( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pCurveEditor->SetMask( CDmeLogEditPanel::FIELD_ALL );
|
||||
}
|
||||
BaseClass::DoModal();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On command
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeLogEditFrame::OnCommand( const char *pCommand )
|
||||
{
|
||||
if ( !Q_stricmp( pCommand, "Ok" ) )
|
||||
{
|
||||
KeyValues *pActionKeys = new KeyValues( "LogEdited" );
|
||||
if ( m_pContextKeyValues )
|
||||
{
|
||||
pActionKeys->AddSubKey( m_pContextKeyValues );
|
||||
|
||||
// This prevents them from being deleted later
|
||||
m_pContextKeyValues = NULL;
|
||||
}
|
||||
|
||||
PostActionSignal( pActionKeys );
|
||||
CloseModal();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "Cancel" ) )
|
||||
{
|
||||
CloseModal();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( pCommand );
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dme_controls/dmemdlpanel.h"
|
||||
#include "dme_controls/dmecontrols.h"
|
||||
#include "dme_controls/dmepanel.h"
|
||||
#include "movieobjects/dmemdl.h"
|
||||
#include "movieobjects/dmemdlmakefile.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
IMPLEMENT_DMEPANEL_FACTORY( CDmeMDLPanel, DmeMDLMakefile, "DmeMakeFileOutputPreview", "MDL MakeFile Output Preview", false );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmeMDLPanel::CDmeMDLPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
|
||||
{
|
||||
}
|
||||
|
||||
CDmeMDLPanel::~CDmeMDLPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// DMEPanel..
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeMDLPanel::SetDmeElement( CDmeMDLMakefile *pMDLMakefile )
|
||||
{
|
||||
if ( pMDLMakefile != NULL )
|
||||
{
|
||||
CDmeMDL *pMDL = CastElement< CDmeMDL >( pMDLMakefile->GetOutputElement( true ) );
|
||||
if ( pMDL )
|
||||
{
|
||||
SetMDL( pMDL->GetMDL() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,656 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dme_controls/dmepanel.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "dme_controls/dmecontrols.h"
|
||||
#include "vgui_controls/combobox.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "dme_controls/dmecontrols_utils.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// All DmePanels used by the system must be listed here to link them in
|
||||
//-----------------------------------------------------------------------------
|
||||
USING_DMEPANEL_FACTORY( CDmeElementPanel, DmElement );
|
||||
USING_DMEPANEL_FACTORY( CDmeSourceSkinPanel, DmeSourceSkin );
|
||||
USING_DMEPANEL_FACTORY( CAssetBuilder, DmeMakefile );
|
||||
USING_DMEPANEL_FACTORY( CDmeSourceDCCFilePanel, DmeSourceDCCFile );
|
||||
USING_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeDag );
|
||||
USING_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeSourceAnimation );
|
||||
USING_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeSourceSkin );
|
||||
USING_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeDCCMakefile );
|
||||
USING_DMEPANEL_FACTORY( CDmeDagEditPanel, DmeDag );
|
||||
USING_DMEPANEL_FACTORY( CDmeDagEditPanel, DmeSourceAnimation );
|
||||
USING_DMEPANEL_FACTORY( CDmeDagEditPanel, DmeSourceSkin );
|
||||
USING_DMEPANEL_FACTORY( CDmeDagEditPanel, DmeDCCMakefile );
|
||||
USING_DMEPANEL_FACTORY( CDmeMDLPanel, DmeMDLMakefile );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmePanel::CDmePanel( vgui::Panel *pParent, const char *pPanelName, bool bComboBoxVisible ) :
|
||||
BaseClass( pParent, pPanelName )
|
||||
{
|
||||
m_pEditorNames = new vgui::ComboBox( this, "EditorDisplayNames", 6, false );
|
||||
if ( bComboBoxVisible )
|
||||
{
|
||||
m_pEditorNames->AddActionSignalTarget( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pEditorNames->SetVisible( false );
|
||||
}
|
||||
m_pDmeEditorPanel = NULL;
|
||||
m_hElement = NULL;
|
||||
|
||||
SetDropEnabled( true );
|
||||
}
|
||||
|
||||
CDmePanel::~CDmePanel()
|
||||
{
|
||||
DeleteCachedPanels();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scheme
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePanel::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
m_pEditorNames->SetFont( pScheme->GetFont( "DefaultVerySmall" ) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Layout
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePanel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
if ( m_pEditorNames->IsVisible() )
|
||||
{
|
||||
m_pEditorNames->SetBounds( 1, 1, w-2, 20 );
|
||||
if ( m_pDmeEditorPanel )
|
||||
{
|
||||
m_pDmeEditorPanel->SetBounds( 0, 24, w, h-24 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_pDmeEditorPanel )
|
||||
{
|
||||
m_pDmeEditorPanel->SetBounds( 0, 0, w, h );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Drag/drop
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CDmePanel::IsDroppable( CUtlVector< KeyValues * >& msglist )
|
||||
{
|
||||
if ( msglist.Count() != 1 )
|
||||
return false;
|
||||
|
||||
KeyValues *data = msglist[ 0 ];
|
||||
CDmElement *ptr = GetElementKeyValue<CDmElement>( data, "dmeelement" );
|
||||
if ( !ptr )
|
||||
return false;
|
||||
|
||||
if ( ptr == m_hElement.Get() )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDmePanel::OnPanelDropped( CUtlVector< KeyValues * >& msglist )
|
||||
{
|
||||
if ( msglist.Count() != 1 )
|
||||
return;
|
||||
|
||||
KeyValues *data = msglist[ 0 ];
|
||||
CDmElement *ptr = GetElementKeyValue<CDmElement>( data, "dmeelement" );
|
||||
if ( !ptr )
|
||||
return;
|
||||
|
||||
// Already browsing
|
||||
if ( ptr == m_hElement.Get() )
|
||||
return;
|
||||
|
||||
SetDmeElement( ptr );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the default editor type
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePanel::SetDefaultEditorType( const char *pEditorType )
|
||||
{
|
||||
m_DefaultEditorType = pEditorType;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populate editor name combo box
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePanel::PopulateEditorNames( const char *pPanelName )
|
||||
{
|
||||
m_pEditorNames->RemoveAll();
|
||||
m_pEditorNames->SetText( "" );
|
||||
if ( !m_pEditorNames->IsVisible() )
|
||||
{
|
||||
SetEditor( pPanelName );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !m_hElement.Get() )
|
||||
{
|
||||
OnTextChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
const char *pPreferredEditor = NULL;
|
||||
if ( m_LastUsedEditorType.Defined( m_hElement->GetTypeString() ) )
|
||||
{
|
||||
pPreferredEditor = m_LastUsedEditorType[ m_hElement->GetTypeString() ].Get();
|
||||
}
|
||||
else
|
||||
{
|
||||
pPreferredEditor = m_DefaultEditorType;
|
||||
}
|
||||
|
||||
int nBestInheritanceDepth = -1;
|
||||
int nActiveItemID = -1;
|
||||
bool bFoundPanelName = false;
|
||||
DmeFactoryHandle_t h = DmePanelFirstFactory( m_hElement.Get() );
|
||||
for ( ; h != DMEFACTORY_HANDLE_INVALID; h = DmePanelNextFactory( h, m_hElement.Get() ) )
|
||||
{
|
||||
const char *pDisplayName = DmePanelFactoryDisplayName( h );
|
||||
const char *pEditorName = DmePanelFactoryName( h );
|
||||
KeyValues *pKeyValues = new KeyValues( "entry", "editorName", pEditorName );
|
||||
|
||||
int nItemID = m_pEditorNames->AddItem( pDisplayName, pKeyValues );
|
||||
|
||||
if ( pPanelName && !Q_stricmp( pPanelName, pEditorName ) )
|
||||
{
|
||||
nBestInheritanceDepth = 0;
|
||||
nActiveItemID = nItemID;
|
||||
bFoundPanelName = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( pPreferredEditor && !bFoundPanelName && !Q_stricmp( pPreferredEditor, pEditorName ) )
|
||||
{
|
||||
nBestInheritanceDepth = 0;
|
||||
nActiveItemID = nItemID;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't select this as the default if it's not a default factory
|
||||
if ( !DmePanelFactoryIsDefault(h) )
|
||||
continue;
|
||||
|
||||
// Choose this factory if it's more derived than the previous best
|
||||
const char *pElementType = DmePanelFactoryElementType( h );
|
||||
int nInheritanceDepth = m_hElement->GetInheritanceDepth( pElementType );
|
||||
Assert( nInheritanceDepth >= 0 );
|
||||
if ( nBestInheritanceDepth >= 0 && ( nInheritanceDepth >= nBestInheritanceDepth ) )
|
||||
continue;
|
||||
|
||||
nBestInheritanceDepth = nInheritanceDepth;
|
||||
nActiveItemID = nItemID;
|
||||
}
|
||||
|
||||
if ( m_pEditorNames->GetItemCount() == 0 )
|
||||
{
|
||||
// ItemCount == 0;
|
||||
m_pEditorNames->SetText( "" );
|
||||
m_CurrentEditorName = NULL;
|
||||
OnTextChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( nActiveItemID >= 0 )
|
||||
{
|
||||
m_pEditorNames->ActivateItem( nActiveItemID );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pEditorNames->ActivateItemByRow( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the dme element was changed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePanel::OnDmeElementChanged()
|
||||
{
|
||||
PostActionSignal( new KeyValues( "DmeElementChanged" ) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Context menu support
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePanel::OnOpenContextMenu( KeyValues *params )
|
||||
{
|
||||
// Forward the context menu message to the DME panel
|
||||
KeyValues *pMsg = params->MakeCopy();
|
||||
if ( m_pDmeEditorPanel )
|
||||
{
|
||||
PostMessage( m_pDmeEditorPanel->GetVPanel(), pMsg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copy/paste support
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePanel::PostMessageToDmePanel( const char *pMessage )
|
||||
{
|
||||
if ( m_pDmeEditorPanel )
|
||||
{
|
||||
PostMessage( m_pDmeEditorPanel->GetVPanel(), new KeyValues( pMessage ) );
|
||||
}
|
||||
}
|
||||
|
||||
void CDmePanel::OnCut()
|
||||
{
|
||||
PostMessageToDmePanel( "OnCut" );
|
||||
}
|
||||
|
||||
void CDmePanel::OnCopy()
|
||||
{
|
||||
PostMessageToDmePanel( "OnCopy" );
|
||||
}
|
||||
|
||||
void CDmePanel::OnPaste()
|
||||
{
|
||||
PostMessageToDmePanel( "OnPaste" );
|
||||
}
|
||||
|
||||
void CDmePanel::OnPasteInsert()
|
||||
{
|
||||
PostMessageToDmePanel( "OnPasteInsert" );
|
||||
}
|
||||
|
||||
void CDmePanel::OnPasteReference()
|
||||
{
|
||||
PostMessageToDmePanel( "OnPasteReference" );
|
||||
}
|
||||
|
||||
void CDmePanel::OnEditDelete()
|
||||
{
|
||||
PostMessageToDmePanel( "OnEditDelete" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when a child of the dme panel switches the thing it's looking at
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePanel::OnViewedElementChanged( KeyValues *kv )
|
||||
{
|
||||
// This is kind of tricky. It's called by the element properties tree
|
||||
// when doing the back/forward searching. Just calling the normal SetDmeElement
|
||||
// doesn't work because it reorders the history. What we want is to
|
||||
// populate the combo box without causing the OnTextChanged message to get sent.
|
||||
|
||||
// FIXME: Perhaps it would be better to extract the back/forward/search
|
||||
// out of the element properties tree and put it into the dme panel?
|
||||
CDmElement *pElement = GetElementKeyValue<CDmElement>( kv, "dmeelement" );
|
||||
if ( pElement == m_hElement )
|
||||
return;
|
||||
|
||||
// If the current editor isn't supported by this new element, then just reset. Too bad.
|
||||
bool bFound = false;
|
||||
if ( m_CurrentEditorName.Length() && pElement )
|
||||
{
|
||||
DmeFactoryHandle_t h = DmePanelFirstFactory( pElement );
|
||||
for ( ; h != DMEFACTORY_HANDLE_INVALID; h = DmePanelNextFactory( h, pElement ) )
|
||||
{
|
||||
const char *pEditorName = DmePanelFactoryName( h );
|
||||
if ( !Q_stricmp( m_CurrentEditorName, pEditorName ) )
|
||||
{
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !bFound )
|
||||
{
|
||||
SetDmeElement( pElement );
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove obsolete items
|
||||
int nCount = m_pEditorNames->GetItemCount();
|
||||
while ( --nCount >= 0 )
|
||||
{
|
||||
int nItemID = m_pEditorNames->GetItemIDFromRow( nCount );
|
||||
KeyValues *kv = m_pEditorNames->GetItemUserData( nItemID );
|
||||
if ( Q_stricmp( m_CurrentEditorName, kv->GetString( "editorName" ) ) )
|
||||
{
|
||||
m_pEditorNames->DeleteItem( nItemID );
|
||||
}
|
||||
}
|
||||
|
||||
// Just want to populate the combo box with new items
|
||||
DmeFactoryHandle_t h = DmePanelFirstFactory( pElement );
|
||||
for ( ; h != DMEFACTORY_HANDLE_INVALID; h = DmePanelNextFactory( h, pElement ) )
|
||||
{
|
||||
const char *pEditorName = DmePanelFactoryName( h );
|
||||
if ( Q_stricmp( pEditorName, m_CurrentEditorName ) )
|
||||
{
|
||||
const char *pDisplayName = DmePanelFactoryDisplayName( h );
|
||||
KeyValues *pKeyValues = new KeyValues( "entry", "editorName", pEditorName );
|
||||
m_pEditorNames->AddItem( pDisplayName, pKeyValues );
|
||||
}
|
||||
}
|
||||
|
||||
m_hElement = pElement;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Delete cached panels
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePanel::DeleteCachedPanels()
|
||||
{
|
||||
int nCount = m_EditorPanelCache.GetNumStrings();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
int nEditorCount = m_EditorPanelCache[ i ].Count();
|
||||
for ( int j = 0; j < nEditorCount; ++j )
|
||||
{
|
||||
m_EditorPanelCache[ i ][ j ].m_pEditorPanel->MarkForDeletion();
|
||||
}
|
||||
}
|
||||
m_EditorPanelCache.Clear();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Refreshes the current panel owing to external change
|
||||
// Values only means no topological change
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePanel::Refresh( bool bValuesOnly )
|
||||
{
|
||||
if ( m_pDmeEditorPanel )
|
||||
{
|
||||
KeyValues *pKeyValues = new KeyValues( "ElementChangedExternally", "valuesOnly", bValuesOnly );
|
||||
PostMessage( m_pDmeEditorPanel, pKeyValues );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Deactivates the current editor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePanel::DeactivateCurrentEditor()
|
||||
{
|
||||
if ( m_pDmeEditorPanel )
|
||||
{
|
||||
m_pDmeEditorPanel->SetParent( (vgui::Panel*)NULL );
|
||||
m_pDmeEditorPanel = NULL;
|
||||
m_CurrentEditorName = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Switch to a new editor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePanel::SetEditor( const char *pEditorName )
|
||||
{
|
||||
if ( pEditorName && !Q_stricmp( m_CurrentEditorName, pEditorName ) )
|
||||
return;
|
||||
|
||||
DeactivateCurrentEditor();
|
||||
|
||||
if ( !m_hElement.Get() || !pEditorName )
|
||||
return;
|
||||
|
||||
if ( m_EditorPanelCache.Defined( pEditorName ) )
|
||||
{
|
||||
CUtlVector< EditorPanelMap_t > &entries = m_EditorPanelCache[ pEditorName ];
|
||||
int nCount = entries.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
EditorPanelMap_t &entry = entries[i];
|
||||
if ( !m_hElement->IsA( entry.m_pFactory->m_pElementType ) )
|
||||
continue;
|
||||
|
||||
m_pDmeEditorPanel = entry.m_pEditorPanel;
|
||||
m_pDmeEditorPanel->SetParent( this );
|
||||
entry.m_pFactory->SetDmeElement( m_pDmeEditorPanel, m_hElement );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !m_pDmeEditorPanel )
|
||||
{
|
||||
EditorPanelMap_t entry;
|
||||
if ( CreateDmePanel( this, "DmePanelEditor", m_hElement, pEditorName, &entry ) )
|
||||
{
|
||||
m_EditorPanelCache[ pEditorName ].AddToTail( entry );
|
||||
m_pDmeEditorPanel = entry.m_pEditorPanel;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_pDmeEditorPanel )
|
||||
{
|
||||
// Store the last selected type of editor
|
||||
m_LastUsedEditorType[ m_hElement->GetTypeString() ] = pEditorName;
|
||||
m_CurrentEditorName = pEditorName;
|
||||
m_pDmeEditorPanel->AddActionSignalTarget( this );
|
||||
}
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when a new element in the combo box has been selected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePanel::OnTextChanged()
|
||||
{
|
||||
KeyValues *kv = m_pEditorNames->GetActiveItemUserData();
|
||||
const char *pEditorName = kv ? kv->GetString( "editorName", NULL ) : NULL;
|
||||
SetEditor( pEditorName );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Setting a new element
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePanel::SetDmeElement( CDmElement *pDmeElement, bool bForce, const char *pPanelName )
|
||||
{
|
||||
if ( ( m_hElement == pDmeElement ) && !bForce )
|
||||
{
|
||||
if ( !pPanelName || !Q_stricmp( pPanelName, m_CurrentEditorName.Get() ) )
|
||||
return;
|
||||
}
|
||||
|
||||
m_hElement = pDmeElement;
|
||||
m_CurrentEditorName = NULL;
|
||||
|
||||
// Populate the editor type list
|
||||
PopulateEditorNames( pPanelName );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Statics for the panel factory
|
||||
//-----------------------------------------------------------------------------
|
||||
CBaseDmePanelFactory* CBaseDmePanelFactory::s_pFirstDmePanelFactory;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CBaseDmePanelFactory::CBaseDmePanelFactory( const char *pElementType, const char *pEditorName,
|
||||
const char *pEditorDisplayName, bool bIsDefault, bool bIsOverride )
|
||||
{
|
||||
// Prior to linking this in, look to see if this has been overridden
|
||||
CBaseDmePanelFactory *pPrevFactory = NULL;
|
||||
for( CBaseDmePanelFactory* pFactory = s_pFirstDmePanelFactory; pFactory;
|
||||
pPrevFactory = pFactory, pFactory = pFactory->m_pNext )
|
||||
{
|
||||
if ( !Q_stricmp( pFactory->m_pElementType, pElementType ) &&
|
||||
!Q_stricmp( pFactory->m_pEditorDisplayName, pEditorDisplayName ) )
|
||||
{
|
||||
// Collision found! If this is not an override, then we've been overridden
|
||||
if ( !bIsOverride )
|
||||
{
|
||||
AssertMsg( pFactory->m_bIsOverride, ( "Two DmePanel factories have the same name (\"%s\") + type (\"%s\")!\n", pElementType, pEditorName ) );
|
||||
return;
|
||||
}
|
||||
|
||||
// If this *is* an override, replace the previous version
|
||||
AssertMsg( !pFactory->m_bIsOverride, ( "Two DmePanel factories have the same name (\"%s\") + type (\"%s\")!\n", pElementType, pEditorName ) );
|
||||
if ( pPrevFactory )
|
||||
{
|
||||
pPrevFactory->m_pNext = pFactory->m_pNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_pFirstDmePanelFactory = pFactory->m_pNext;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_pNext = s_pFirstDmePanelFactory;
|
||||
s_pFirstDmePanelFactory = this;
|
||||
|
||||
m_pElementType = pElementType;
|
||||
m_pEditorName = pEditorName;
|
||||
m_pEditorDisplayName = pEditorDisplayName;
|
||||
m_bIsDefault = bIsDefault;
|
||||
m_bIsOverride = bIsOverride;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Dme Panel factory iteration methods
|
||||
//-----------------------------------------------------------------------------
|
||||
DmeFactoryHandle_t DmePanelFirstFactory( CDmElement *pElement )
|
||||
{
|
||||
CBaseDmePanelFactory *pFactory = CBaseDmePanelFactory::s_pFirstDmePanelFactory;
|
||||
for ( ; pFactory; pFactory = pFactory->m_pNext )
|
||||
{
|
||||
if ( !pElement || pElement->IsA( pFactory->m_pElementType ) )
|
||||
return (DmeFactoryHandle_t)pFactory;
|
||||
}
|
||||
|
||||
return DMEFACTORY_HANDLE_INVALID;
|
||||
}
|
||||
|
||||
|
||||
DmeFactoryHandle_t DmePanelNextFactory( DmeFactoryHandle_t h, CDmElement *pElement )
|
||||
{
|
||||
CBaseDmePanelFactory *pFactory = (CBaseDmePanelFactory*)h;
|
||||
if ( !pFactory )
|
||||
return DMEFACTORY_HANDLE_INVALID;
|
||||
|
||||
for ( pFactory = pFactory->m_pNext; pFactory; pFactory = pFactory->m_pNext )
|
||||
{
|
||||
if ( !pElement || pElement->IsA( pFactory->m_pElementType ) )
|
||||
return (DmeFactoryHandle_t)pFactory;
|
||||
}
|
||||
|
||||
return DMEFACTORY_HANDLE_INVALID;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Dme Panel factory info methods
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *DmePanelFactoryName( DmeFactoryHandle_t h )
|
||||
{
|
||||
CBaseDmePanelFactory *pFactory = (CBaseDmePanelFactory*)h;
|
||||
return pFactory ? pFactory->m_pEditorName : NULL;
|
||||
}
|
||||
|
||||
const char *DmePanelFactoryDisplayName( DmeFactoryHandle_t h )
|
||||
{
|
||||
CBaseDmePanelFactory *pFactory = (CBaseDmePanelFactory*)h;
|
||||
return pFactory ? pFactory->m_pEditorDisplayName : NULL;
|
||||
}
|
||||
|
||||
const char *DmePanelFactoryElementType( DmeFactoryHandle_t h )
|
||||
{
|
||||
CBaseDmePanelFactory *pFactory = (CBaseDmePanelFactory*)h;
|
||||
return pFactory ? pFactory->m_pElementType : NULL;
|
||||
}
|
||||
|
||||
bool DmePanelFactoryIsDefault( DmeFactoryHandle_t h )
|
||||
{
|
||||
CBaseDmePanelFactory *pFactory = (CBaseDmePanelFactory*)h;
|
||||
return pFactory ? pFactory->m_bIsDefault : false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Dme Panel factory methods
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CDmePanel::CreateDmePanel( vgui::Panel *pParent, const char *pPanelName, CDmElement *pElement, const char *pEditorName, EditorPanelMap_t *pMap )
|
||||
{
|
||||
int nBestInheritanceDepth = -1;
|
||||
CBaseDmePanelFactory *pBestFactory = NULL;
|
||||
CBaseDmePanelFactory *pFactory = CBaseDmePanelFactory::s_pFirstDmePanelFactory;
|
||||
for ( ; pFactory; pFactory = pFactory->m_pNext )
|
||||
{
|
||||
if ( !pElement->IsA( pFactory->m_pElementType ) )
|
||||
continue;
|
||||
|
||||
if ( pEditorName )
|
||||
{
|
||||
if ( !Q_stricmp( pEditorName, pFactory->m_pEditorName ) )
|
||||
{
|
||||
pBestFactory = pFactory;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// No editor name specified? Only use default factories
|
||||
if ( !pFactory->m_bIsDefault )
|
||||
continue;
|
||||
|
||||
// Choose this factory if it's more derived than the previous best
|
||||
int nInheritanceDepth = pElement->GetInheritanceDepth( pFactory->m_pElementType );
|
||||
Assert( nInheritanceDepth >= 0 );
|
||||
if ( nBestInheritanceDepth >= 0 && ( nInheritanceDepth > nBestInheritanceDepth ) )
|
||||
continue;
|
||||
|
||||
nBestInheritanceDepth = nInheritanceDepth;
|
||||
pBestFactory = pFactory;
|
||||
}
|
||||
|
||||
if ( pBestFactory )
|
||||
{
|
||||
pMap->m_pFactory = pBestFactory;
|
||||
pMap->m_pEditorPanel = pBestFactory->CreateDmePanel( pParent, pPanelName, pElement );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dme_controls/DmePicker.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui_controls/TextEntry.h"
|
||||
#include "vgui_controls/ListPanel.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/iinput.h"
|
||||
#include "dme_controls/dmecontrols_utils.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Dme Picker
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sort by MDL name
|
||||
//-----------------------------------------------------------------------------
|
||||
static int __cdecl DmeBrowserSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 )
|
||||
{
|
||||
const char *string1 = item1.kv->GetString("dme");
|
||||
const char *string2 = item2.kv->GetString("dme");
|
||||
return stricmp( string1, string2 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmePicker::CDmePicker( vgui::Panel *pParent ) : BaseClass( pParent, "DmePicker" )
|
||||
{
|
||||
// FIXME: Make this an image browser
|
||||
m_pDmeBrowser = new vgui::ListPanel( this, "DmeBrowser" );
|
||||
m_pDmeBrowser->AddColumnHeader( 0, "dme", "Dme Elements", 52, 0 );
|
||||
m_pDmeBrowser->SetSelectIndividualCells( true );
|
||||
m_pDmeBrowser->SetEmptyListText( "No Dme Elements" );
|
||||
m_pDmeBrowser->SetDragEnabled( true );
|
||||
m_pDmeBrowser->AddActionSignalTarget( this );
|
||||
m_pDmeBrowser->SetSortFunc( 0, DmeBrowserSortFunc );
|
||||
m_pDmeBrowser->SetSortColumn( 0 );
|
||||
|
||||
// filter selection
|
||||
m_pFilterList = new TextEntry( this, "FilterList" );
|
||||
m_pFilterList->AddActionSignalTarget( this );
|
||||
m_pFilterList->RequestFocus();
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/dmepicker.res" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmePicker::~CDmePicker()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called to open
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePicker::Activate( const CUtlVector< DmePickerInfo_t >&vec )
|
||||
{
|
||||
m_pDmeBrowser->RemoveAll();
|
||||
|
||||
int nCount = vec.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pElement = GetElement<CDmElement>( vec[i].m_hElement );
|
||||
const char *pElementName = pElement ? pElement->GetName() : "<null element>";
|
||||
const char *pItemName = vec[i].m_pChoiceString ? vec[i].m_pChoiceString : pElementName;
|
||||
|
||||
KeyValues *kv = new KeyValues( "node", "dme", pItemName );
|
||||
kv->SetInt( "dmeHandle", vec[i].m_hElement );
|
||||
int nItemID = m_pDmeBrowser->AddItem( kv, 0, false, false );
|
||||
|
||||
KeyValues *pDrag = new KeyValues( "drag", "text", pElementName );
|
||||
pDrag->SetString( "texttype", "dmeName" );
|
||||
pDrag->SetInt( "dmeelement", vec[i].m_hElement );
|
||||
m_pDmeBrowser->SetItemDragData( nItemID, pDrag );
|
||||
}
|
||||
|
||||
RefreshDmeList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePicker::OnKeyCodePressed( KeyCode code )
|
||||
{
|
||||
if (( code == KEY_UP ) || ( code == KEY_DOWN ) || ( code == KEY_PAGEUP ) || ( code == KEY_PAGEDOWN ))
|
||||
{
|
||||
KeyValues *pMsg = new KeyValues("KeyCodePressed", "code", code);
|
||||
vgui::ipanel()->SendMessage( m_pDmeBrowser->GetVPanel(), pMsg, GetVPanel());
|
||||
pMsg->deleteThis();
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnKeyCodePressed( code );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes the file list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePicker::RefreshDmeList()
|
||||
{
|
||||
// Check the filter matches
|
||||
int nMatchingElements = 0;
|
||||
int nTotalCount = 0;
|
||||
for ( int nItemID = m_pDmeBrowser->FirstItem(); nItemID != m_pDmeBrowser->InvalidItemID(); nItemID = m_pDmeBrowser->NextItem( nItemID ) )
|
||||
{
|
||||
KeyValues *kv = m_pDmeBrowser->GetItem( nItemID );
|
||||
const char *pElementName = kv->GetString( "dme" );
|
||||
bool bIsVisible = !m_Filter.Length() || Q_stristr( pElementName, m_Filter.Get() );
|
||||
m_pDmeBrowser->SetItemVisible( nItemID, bIsVisible );
|
||||
if ( bIsVisible )
|
||||
{
|
||||
++nMatchingElements;
|
||||
}
|
||||
++nTotalCount;
|
||||
}
|
||||
m_pDmeBrowser->SortList();
|
||||
|
||||
char pColumnTitle[512];
|
||||
Q_snprintf( pColumnTitle, sizeof(pColumnTitle), "%s (%d/%d)",
|
||||
"Dme Elements", nMatchingElements, nTotalCount );
|
||||
m_pDmeBrowser->SetColumnHeaderText( 0, pColumnTitle );
|
||||
|
||||
if ( ( m_pDmeBrowser->GetItemCount() > 0 ) && ( m_pDmeBrowser->GetSelectedItemsCount() == 0 ) )
|
||||
{
|
||||
int nItemID = m_pDmeBrowser->GetItemIDFromRow( 0 );
|
||||
m_pDmeBrowser->SetSelectedCell( nItemID, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes dialog on text changing
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePicker::OnTextChanged( )
|
||||
{
|
||||
int nLength = m_pFilterList->GetTextLength();
|
||||
m_Filter.SetLength( nLength );
|
||||
if ( nLength > 0 )
|
||||
{
|
||||
m_pFilterList->GetText( m_Filter.GetForModify(), nLength+1 );
|
||||
}
|
||||
RefreshDmeList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the selceted model name
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmElement *CDmePicker::GetSelectedDme( )
|
||||
{
|
||||
if ( m_pDmeBrowser->GetSelectedItemsCount() == 0 )
|
||||
return NULL;
|
||||
|
||||
int nIndex = m_pDmeBrowser->GetSelectedItem( 0 );
|
||||
KeyValues *pItemKeyValues = m_pDmeBrowser->GetItem( nIndex );
|
||||
return GetElementKeyValue< CDmElement >( pItemKeyValues, "dmeHandle" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: Modal picker frame
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmePickerFrame::CDmePickerFrame( vgui::Panel *pParent, const char *pTitle ) :
|
||||
BaseClass( pParent, "DmePickerFrame" )
|
||||
{
|
||||
m_pContextKeyValues = NULL;
|
||||
SetDeleteSelfOnClose( true );
|
||||
m_pPicker = new CDmePicker( this );
|
||||
m_pPicker->AddActionSignalTarget( this );
|
||||
m_pOpenButton = new Button( this, "OpenButton", "#FileOpenDialog_Open", this, "Open" );
|
||||
m_pCancelButton = new Button( this, "CancelButton", "#FileOpenDialog_Cancel", this, "Cancel" );
|
||||
SetBlockDragChaining( true );
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/dmepickerframe.res" );
|
||||
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
CDmePickerFrame::~CDmePickerFrame()
|
||||
{
|
||||
CleanUpMessage();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Deletes the message
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePickerFrame::CleanUpMessage()
|
||||
{
|
||||
if ( m_pContextKeyValues )
|
||||
{
|
||||
m_pContextKeyValues->deleteThis();
|
||||
m_pContextKeyValues = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Activate the dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePickerFrame::DoModal( const CUtlVector< DmePickerInfo_t >& vec, KeyValues *pKeyValues )
|
||||
{
|
||||
CleanUpMessage();
|
||||
m_pContextKeyValues = pKeyValues;
|
||||
m_pPicker->Activate( vec );
|
||||
m_pOpenButton->SetEnabled( vec.Count() != 0 );
|
||||
BaseClass::DoModal();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On command
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmePickerFrame::OnCommand( const char *pCommand )
|
||||
{
|
||||
if ( !Q_stricmp( pCommand, "Open" ) )
|
||||
{
|
||||
CDmElement *pElement = m_pPicker->GetSelectedDme( );
|
||||
|
||||
KeyValues *pActionKeys = new KeyValues( "DmeSelected" );
|
||||
SetElementKeyValue( pActionKeys, "dme", pElement );
|
||||
if ( m_pContextKeyValues )
|
||||
{
|
||||
pActionKeys->AddSubKey( m_pContextKeyValues );
|
||||
|
||||
// This prevents them from being deleted later
|
||||
m_pContextKeyValues = NULL;
|
||||
}
|
||||
|
||||
PostActionSignal( pActionKeys );
|
||||
CloseModal();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "Cancel" ) )
|
||||
{
|
||||
KeyValues *pActionKeys = new KeyValues( "DmeSelectionCancelled" );
|
||||
if ( m_pContextKeyValues )
|
||||
{
|
||||
pActionKeys->AddSubKey( m_pContextKeyValues );
|
||||
|
||||
// This prevents them from being deleted later
|
||||
m_pContextKeyValues = NULL;
|
||||
}
|
||||
|
||||
PostActionSignal( pActionKeys );
|
||||
CloseModal();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( pCommand );
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,53 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dme_controls/filtercombobox.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CFilterComboBox::CFilterComboBox( Panel *parent, const char *panelName, int numLines, bool allowEdit ) :
|
||||
BaseClass( parent, panelName, numLines, allowEdit )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: panel lost focus message
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFilterComboBox::OnKillFocus()
|
||||
{
|
||||
int nLength = GetTextLength();
|
||||
char *pFilterText = (char*)_alloca( (nLength+1) * sizeof(char) );
|
||||
GetText( pFilterText, nLength+1 );
|
||||
|
||||
// Remove the existing version in the list
|
||||
char pItemText[512];
|
||||
int nItemCount = GetItemCount();
|
||||
int i;
|
||||
for ( i = 0; i < nItemCount; ++i )
|
||||
{
|
||||
GetItemText( i, pItemText, sizeof(pItemText) );
|
||||
if ( !Q_stricmp( pFilterText, pItemText ) )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( i != nItemCount )
|
||||
{
|
||||
// Remove the existing copy
|
||||
DeleteItem( i );
|
||||
}
|
||||
|
||||
AddItem( pFilterText, NULL );
|
||||
|
||||
BaseClass::OnKillFocus( );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,676 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "dme_controls/particlesystempanel.h"
|
||||
#include "dme_controls/dmepanel.h"
|
||||
#include "movieobjects/dmeparticlesystemdefinition.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "vgui_controls/propertypage.h"
|
||||
#include "vgui_controls/propertysheet.h"
|
||||
#include "vgui_controls/textentry.h"
|
||||
#include "vgui_controls/splitter.h"
|
||||
#include "vgui_controls/checkbutton.h"
|
||||
#include "matsys_controls/colorpickerpanel.h"
|
||||
#include "particles/particles.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier2/renderutils.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Enums
|
||||
//-----------------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
SCROLLBAR_SIZE=18, // the width of a scrollbar
|
||||
WINDOW_BORDER_WIDTH=2 // the width of the window's border
|
||||
};
|
||||
|
||||
#define SPHERE_RADIUS 10.0f
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CParticleSystemPanel::CParticleSystemPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
|
||||
{
|
||||
m_pParticleSystem = NULL;
|
||||
m_flLastTime = FLT_MAX;
|
||||
m_bRenderBounds = false;
|
||||
m_bRenderCullBounds = false;
|
||||
m_bRenderHelpers = false;
|
||||
m_bPerformNameBasedLookup = true;
|
||||
m_ParticleSystemName = NULL;
|
||||
InvalidateUniqueId( &m_ParticleSystemId );
|
||||
InvalidateUniqueId( &m_RenderHelperId );
|
||||
|
||||
LookAt( SPHERE_RADIUS );
|
||||
|
||||
m_pLightmapTexture.Init( "//platform/materials/debug/defaultlightmap", "editor" );
|
||||
m_DefaultEnvCubemap.Init( "editor/cubemap", "editor", true );
|
||||
for ( int i = 0; i < MAX_PARTICLE_CONTROL_POINTS; ++i )
|
||||
{
|
||||
SetControlPointValue( i, Vector( 0, 0, 10.0f * i ) );
|
||||
}
|
||||
}
|
||||
|
||||
CParticleSystemPanel::~CParticleSystemPanel()
|
||||
{
|
||||
m_pLightmapTexture.Shutdown();
|
||||
m_DefaultEnvCubemap.Shutdown();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scheme
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
SetBorder( pScheme->GetBorder( "MenuBorder") );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Indicates that bounds should be drawn
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPanel::RenderBounds( bool bEnable )
|
||||
{
|
||||
m_bRenderBounds = bEnable;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Indicates that cull sphere should be drawn
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPanel::RenderCullBounds( bool bEnable )
|
||||
{
|
||||
m_bRenderCullBounds = bEnable;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Indicates that bounds should be drawn
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPanel::RenderHelpers( bool bEnable )
|
||||
{
|
||||
m_bRenderHelpers = bEnable;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Indicates which helper to draw
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPanel::SetRenderedHelper( CDmeParticleFunction *pOp )
|
||||
{
|
||||
if ( !pOp )
|
||||
{
|
||||
InvalidateUniqueId( &m_RenderHelperId );
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyUniqueId( pOp->GetId(), &m_RenderHelperId );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool IsValidHierarchy( CParticleCollection *pCollection )
|
||||
{
|
||||
if ( !pCollection->IsValid() )
|
||||
return false;
|
||||
|
||||
for( CParticleCollection *pChild = pCollection->m_Children.m_pHead; pChild; pChild = pChild->m_pNext )
|
||||
{
|
||||
if ( !IsValidHierarchy( pChild ) )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Simulate the particle system
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPanel::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
if ( !m_pParticleSystem )
|
||||
return;
|
||||
|
||||
float flTime = Plat_FloatTime();
|
||||
if ( m_flLastTime == FLT_MAX )
|
||||
{
|
||||
m_flLastTime = flTime;
|
||||
}
|
||||
|
||||
float flDt = flTime - m_flLastTime;
|
||||
m_flLastTime = flTime;
|
||||
|
||||
for ( int i = 0; i < MAX_PARTICLE_CONTROL_POINTS; ++i )
|
||||
{
|
||||
if ( !m_pParticleSystem->ReadsControlPoint( i ) )
|
||||
continue;
|
||||
|
||||
m_pParticleSystem->SetControlPoint( i, m_pControlPointValue[i] );
|
||||
m_pParticleSystem->SetControlPointOrientation( i, Vector( 1, 0, 0 ), Vector( 0, -1, 0 ), Vector( 0, 0, 1 ) );
|
||||
m_pParticleSystem->SetControlPointParent( i, i );
|
||||
}
|
||||
|
||||
// Restart the particle system if it's finished
|
||||
bool bIsInvalid = !IsValidHierarchy( m_pParticleSystem );
|
||||
|
||||
if ( !bIsInvalid )
|
||||
{
|
||||
m_pParticleSystem->Simulate( flDt, false );
|
||||
}
|
||||
|
||||
if ( m_pParticleSystem->IsFinished() || bIsInvalid )
|
||||
{
|
||||
delete m_pParticleSystem;
|
||||
m_pParticleSystem = NULL;
|
||||
|
||||
if ( m_bPerformNameBasedLookup )
|
||||
{
|
||||
if ( m_ParticleSystemName.Length() )
|
||||
{
|
||||
CParticleCollection *pNewParticleSystem = g_pParticleSystemMgr->CreateParticleCollection( m_ParticleSystemName );
|
||||
m_pParticleSystem = pNewParticleSystem;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( IsUniqueIdValid( m_ParticleSystemId ) )
|
||||
{
|
||||
CParticleCollection *pNewParticleSystem = g_pParticleSystemMgr->CreateParticleCollection( m_ParticleSystemId );
|
||||
m_pParticleSystem = pNewParticleSystem;
|
||||
}
|
||||
}
|
||||
|
||||
if ( bIsInvalid )
|
||||
{
|
||||
PostActionSignal( new KeyValues( "ParticleSystemReconstructed" ) );
|
||||
}
|
||||
m_flLastTime = FLT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Startup, shutdown particle collection
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPanel::StartupParticleCollection()
|
||||
{
|
||||
if ( m_pParticleSystem )
|
||||
{
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel(), 0 );
|
||||
}
|
||||
m_flLastTime = FLT_MAX;
|
||||
}
|
||||
|
||||
void CParticleSystemPanel::ShutdownParticleCollection()
|
||||
{
|
||||
if ( m_pParticleSystem )
|
||||
{
|
||||
vgui::ivgui()->RemoveTickSignal( GetVPanel() );
|
||||
delete m_pParticleSystem;
|
||||
m_pParticleSystem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set the particle system to draw
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPanel::SetParticleSystem( CDmeParticleSystemDefinition *pDef )
|
||||
{
|
||||
ShutdownParticleCollection();
|
||||
if ( pDef )
|
||||
{
|
||||
m_bPerformNameBasedLookup = pDef->UseNameBasedLookup();
|
||||
if ( m_bPerformNameBasedLookup )
|
||||
{
|
||||
m_ParticleSystemName = pDef->GetName();
|
||||
Assert( g_pParticleSystemMgr->IsParticleSystemDefined( m_ParticleSystemName ) );
|
||||
m_pParticleSystem = g_pParticleSystemMgr->CreateParticleCollection( m_ParticleSystemName );
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyUniqueId( pDef->GetId(), &m_ParticleSystemId );
|
||||
Assert( g_pParticleSystemMgr->IsParticleSystemDefined( m_ParticleSystemId ) );
|
||||
m_pParticleSystem = g_pParticleSystemMgr->CreateParticleCollection( m_ParticleSystemId );
|
||||
}
|
||||
PostActionSignal( new KeyValues( "ParticleSystemReconstructed" ) );
|
||||
}
|
||||
StartupParticleCollection();
|
||||
}
|
||||
|
||||
void CParticleSystemPanel::SetDmeElement( CDmeParticleSystemDefinition *pDef )
|
||||
{
|
||||
SetParticleSystem( pDef );
|
||||
}
|
||||
|
||||
CParticleCollection *CParticleSystemPanel::GetParticleSystem()
|
||||
{
|
||||
return m_pParticleSystem;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw bounds
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPanel::DrawBounds()
|
||||
{
|
||||
Vector vecMins, vecMaxs;
|
||||
m_pParticleSystem->GetBounds( &vecMins, &vecMaxs );
|
||||
RenderWireframeBox( vec3_origin, vec3_angle, vecMins, vecMaxs, Color( 0, 255, 255, 255 ), true );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw cull bounds
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPanel::DrawCullBounds()
|
||||
{
|
||||
Vector vecCenter;
|
||||
m_pParticleSystem->GetControlPointAtTime( m_pParticleSystem->m_pDef->GetCullControlPoint(), m_pParticleSystem->m_flCurTime, &vecCenter );
|
||||
RenderWireframeSphere( vecCenter, m_pParticleSystem->m_pDef->GetCullRadius(), 32, 16, Color( 0, 255, 255, 255 ), true );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// paint it!
|
||||
//-----------------------------------------------------------------------------
|
||||
#define AXIS_SIZE 5.0f
|
||||
|
||||
void CParticleSystemPanel::OnPaint3D()
|
||||
{
|
||||
if ( !m_pParticleSystem )
|
||||
return;
|
||||
|
||||
// This needs calling to reset various counters.
|
||||
g_pParticleSystemMgr->SetLastSimulationTime( m_pParticleSystem->m_flCurTime );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
pRenderContext->BindLightmapTexture( m_pLightmapTexture );
|
||||
pRenderContext->BindLocalCubemap( m_DefaultEnvCubemap );
|
||||
|
||||
// Draw axes
|
||||
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
||||
pRenderContext->PushMatrix();
|
||||
pRenderContext->LoadIdentity( );
|
||||
|
||||
if ( m_bRenderBounds )
|
||||
{
|
||||
DrawBounds();
|
||||
Vector vP1;
|
||||
Vector vP2;
|
||||
m_pParticleSystem->GetControlPointAtTime( 0, m_pParticleSystem->m_flCurTime, &vP1 );
|
||||
m_pParticleSystem->GetControlPointAtTime( 1, m_pParticleSystem->m_flCurTime, &vP2 );
|
||||
RenderLine( vP1, vP2, Color( 0, 255, 255, 255 ), true );
|
||||
}
|
||||
|
||||
if ( m_bRenderCullBounds )
|
||||
{
|
||||
DrawCullBounds();
|
||||
}
|
||||
|
||||
if ( m_bRenderHelpers && IsUniqueIdValid( m_RenderHelperId ) )
|
||||
{
|
||||
m_pParticleSystem->VisualizeOperator( &m_RenderHelperId );
|
||||
}
|
||||
m_pParticleSystem->Render( pRenderContext );
|
||||
m_pParticleSystem->VisualizeOperator( );
|
||||
RenderAxes( vec3_origin, AXIS_SIZE, true );
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
||||
pRenderContext->PopMatrix();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Control point page
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
class CControlPointPage : public vgui::PropertyPage
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CControlPointPage, vgui::PropertyPage );
|
||||
|
||||
public:
|
||||
// constructor, destructor
|
||||
CControlPointPage( vgui::Panel *pParent, const char *pName, CParticleSystemPanel *pParticleSystemPanel );
|
||||
|
||||
virtual void PerformLayout();
|
||||
|
||||
void CreateControlPointControls( );
|
||||
|
||||
private:
|
||||
MESSAGE_FUNC_PARAMS( OnTextChanged, "TextChanged", params );
|
||||
MESSAGE_FUNC_PARAMS( OnNewLine, "TextNewLine", params );
|
||||
|
||||
void LayoutControlPointControls();
|
||||
void CleanUpControlPointControls();
|
||||
|
||||
vgui::Label *m_pControlPointName[MAX_PARTICLE_CONTROL_POINTS];
|
||||
vgui::TextEntry *m_pControlPointValue[MAX_PARTICLE_CONTROL_POINTS];
|
||||
CParticleSystemPanel *m_pParticleSystemPanel;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Contstructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CControlPointPage::CControlPointPage( vgui::Panel *pParent, const char *pName, CParticleSystemPanel *pParticleSystemPanel ) :
|
||||
BaseClass( pParent, pName )
|
||||
{
|
||||
for ( int i = 0; i < MAX_PARTICLE_CONTROL_POINTS; ++i )
|
||||
{
|
||||
m_pControlPointName[i] = NULL;
|
||||
m_pControlPointValue[i] = NULL;
|
||||
}
|
||||
|
||||
m_pParticleSystemPanel = pParticleSystemPanel;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the text entry for a control point is changed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CControlPointPage::OnTextChanged( KeyValues *pParams )
|
||||
{
|
||||
vgui::Panel *pPanel = (vgui::Panel *)pParams->GetPtr( "panel" );
|
||||
for ( int i = 0; i < MAX_PARTICLE_CONTROL_POINTS; ++i )
|
||||
{
|
||||
if ( pPanel != m_pControlPointValue[i] )
|
||||
continue;
|
||||
|
||||
char pBuf[512];
|
||||
m_pControlPointValue[i]->GetText( pBuf, sizeof(pBuf) );
|
||||
|
||||
Vector vecValue( 0, 0, 0 );
|
||||
sscanf( pBuf, "%f %f %f", &vecValue.x, &vecValue.y, &vecValue.z );
|
||||
m_pParticleSystemPanel->SetControlPointValue( i, vecValue );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the text entry for a control point is changed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CControlPointPage::OnNewLine( KeyValues *pParams )
|
||||
{
|
||||
vgui::Panel *pPanel = (vgui::Panel *)pParams->GetPtr( "panel" );
|
||||
for ( int i = 0; i < MAX_PARTICLE_CONTROL_POINTS; ++i )
|
||||
{
|
||||
if ( pPanel != m_pControlPointValue[i] )
|
||||
continue;
|
||||
|
||||
char pBuf[512];
|
||||
m_pControlPointValue[i]->GetText( pBuf, sizeof(pBuf) );
|
||||
|
||||
Vector vecValue( 0, 0, 0 );
|
||||
sscanf( pBuf, "%f %f %f", &vecValue.x, &vecValue.y, &vecValue.z );
|
||||
m_pParticleSystemPanel->SetControlPointValue( i, vecValue );
|
||||
|
||||
vecValue = m_pParticleSystemPanel->GetControlPointValue( i );
|
||||
Q_snprintf( pBuf, sizeof(pBuf), "%.3f %.3f %.3f", vecValue.x, vecValue.y, vecValue.z );
|
||||
m_pControlPointValue[i]->SetText( pBuf );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the particle system changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CControlPointPage::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
LayoutControlPointControls();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates controls used to modify control point values
|
||||
//-----------------------------------------------------------------------------
|
||||
void CControlPointPage::CreateControlPointControls()
|
||||
{
|
||||
CleanUpControlPointControls();
|
||||
CParticleCollection* pParticleSystem = m_pParticleSystemPanel->GetParticleSystem();
|
||||
if ( !pParticleSystem )
|
||||
return;
|
||||
|
||||
for ( int i = 0; i < MAX_PARTICLE_CONTROL_POINTS; ++i )
|
||||
{
|
||||
if ( !pParticleSystem->ReadsControlPoint( i ) )
|
||||
continue;
|
||||
|
||||
char pName[512];
|
||||
Q_snprintf( pName, sizeof(pName), "Pt #%d:", i );
|
||||
m_pControlPointName[i] = new Label( this, pName, pName );
|
||||
|
||||
Q_snprintf( pName, sizeof(pName), "Entry #%d:", i );
|
||||
m_pControlPointValue[i] = new TextEntry( this, pName );
|
||||
m_pControlPointValue[i]->AddActionSignalTarget( this );
|
||||
m_pControlPointValue[i]->SendNewLine( true );
|
||||
m_pControlPointValue[i]->SetMultiline( false );
|
||||
|
||||
const Vector &vecValue = m_pParticleSystemPanel->GetControlPointValue( i );
|
||||
Q_snprintf( pName, sizeof(pName), "%.3f %.3f %.3f", vecValue.x, vecValue.y, vecValue.z );
|
||||
m_pControlPointValue[i]->SetText( pName );
|
||||
}
|
||||
|
||||
LayoutControlPointControls();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Lays out the controls
|
||||
//-----------------------------------------------------------------------------
|
||||
void CControlPointPage::LayoutControlPointControls()
|
||||
{
|
||||
int nFoundControlCount = 0;
|
||||
for ( int i = 0; i < MAX_PARTICLE_CONTROL_POINTS; ++i )
|
||||
{
|
||||
if ( !m_pControlPointName[i] )
|
||||
continue;
|
||||
|
||||
int yVal = 8 + nFoundControlCount * 28;
|
||||
m_pControlPointName[i]->SetBounds( 8, yVal, 48, 24 );
|
||||
m_pControlPointValue[i]->SetBounds( 64, yVal, 160, 24 );
|
||||
++nFoundControlCount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Cleans up controls used to modify control point values
|
||||
//-----------------------------------------------------------------------------
|
||||
void CControlPointPage::CleanUpControlPointControls( )
|
||||
{
|
||||
for ( int i = 0; i < MAX_PARTICLE_CONTROL_POINTS; ++i )
|
||||
{
|
||||
if ( m_pControlPointName[i] )
|
||||
{
|
||||
delete m_pControlPointName[i];
|
||||
m_pControlPointName[i] = NULL;
|
||||
}
|
||||
|
||||
if ( m_pControlPointValue[i] )
|
||||
{
|
||||
delete m_pControlPointValue[i];
|
||||
m_pControlPointValue[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// CParticleSystemPreviewPanel
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Dme panel connection
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_DMEPANEL_FACTORY( CParticleSystemPreviewPanel, DmeParticleSystemDefinition, "DmeParticleSystemDefinitionViewer", "Particle System Viewer", false );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CParticleSystemPreviewPanel::CParticleSystemPreviewPanel( vgui::Panel *pParent, const char *pName ) :
|
||||
BaseClass( pParent, pName )
|
||||
{
|
||||
m_Splitter = new vgui::Splitter( this, "Splitter", SPLITTER_MODE_VERTICAL, 1 );
|
||||
vgui::Panel *pSplitterLeftSide = m_Splitter->GetChild( 0 );
|
||||
vgui::Panel *pSplitterRightSide = m_Splitter->GetChild( 1 );
|
||||
|
||||
m_pParticleSystemPanel = new CParticleSystemPanel( pSplitterRightSide, "ParticlePreview" );
|
||||
m_pParticleSystemPanel->AddActionSignalTarget( this );
|
||||
m_pParticleSystemPanel->SetBackgroundColor( 0, 0, 0 );
|
||||
|
||||
m_pParticleCount = new vgui::Label( pSplitterRightSide, "ParticleCountLabel", "" );
|
||||
m_pParticleCount->SetZPos( 1 );
|
||||
|
||||
m_pControlSheet = new vgui::PropertySheet( pSplitterLeftSide, "ControlSheet" );
|
||||
|
||||
m_pRenderPage = new vgui::PropertyPage( m_pControlSheet, "RenderPage" );
|
||||
|
||||
m_pRenderBounds = new vgui::CheckButton( m_pRenderPage, "RenderBounds", "Render Bounding Box" );
|
||||
m_pRenderBounds->AddActionSignalTarget( this );
|
||||
|
||||
m_pRenderCullBounds = new vgui::CheckButton( m_pRenderPage, "RenderCullBounds", "Render Culling Bounds" );
|
||||
m_pRenderCullBounds->AddActionSignalTarget( this );
|
||||
|
||||
m_pRenderHelpers = new vgui::CheckButton( m_pRenderPage, "RenderHelpers", "Render Helpers" );
|
||||
m_pRenderHelpers->AddActionSignalTarget( this );
|
||||
|
||||
m_pBackgroundColor = new CColorPickerButton( m_pRenderPage, "BackgroundColor", this );
|
||||
m_pBackgroundColor->SetColor( m_pParticleSystemPanel->GetBackgroundColor() );
|
||||
|
||||
m_pRenderPage->LoadControlSettingsAndUserConfig( "resource/particlesystempreviewpanel_renderpage.res" );
|
||||
|
||||
m_pControlPointPage = new CControlPointPage( m_pControlSheet, "ControlPointPage", m_pParticleSystemPanel );
|
||||
|
||||
// Load layout settings; has to happen before pinning occurs in code
|
||||
LoadControlSettingsAndUserConfig( "resource/particlesystempreviewpanel.res" );
|
||||
|
||||
// NOTE: Page adding happens *after* LoadControlSettingsAndUserConfig
|
||||
// because the layout of the sheet is correct at this point.
|
||||
m_pControlSheet->AddPage( m_pRenderPage, "Render" );
|
||||
m_pControlSheet->AddPage( m_pControlPointPage, "Ctrl Pts" );
|
||||
}
|
||||
|
||||
CParticleSystemPreviewPanel::~CParticleSystemPreviewPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set the particle system to draw
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPreviewPanel::OnThink()
|
||||
{
|
||||
BaseClass::OnThink();
|
||||
CParticleCollection* pParticleSystem = m_pParticleSystemPanel->GetParticleSystem();
|
||||
if ( !pParticleSystem )
|
||||
{
|
||||
m_pParticleCount->SetText( "" );
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[256];
|
||||
Q_snprintf( buf, sizeof(buf), "Particle Count: %5d/%5d",
|
||||
pParticleSystem->m_nActiveParticles, pParticleSystem->m_nAllocatedParticles );
|
||||
m_pParticleCount->SetText( buf );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the particle system changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPreviewPanel::OnParticleSystemReconstructed()
|
||||
{
|
||||
m_pControlPointPage->CreateControlPointControls();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set the particle system to draw
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPreviewPanel::SetParticleSystem( CDmeParticleSystemDefinition *pDef )
|
||||
{
|
||||
m_pParticleSystemPanel->SetParticleSystem( pDef );
|
||||
}
|
||||
|
||||
void CParticleSystemPreviewPanel::SetDmeElement( CDmeParticleSystemDefinition *pDef )
|
||||
{
|
||||
m_pParticleSystemPanel->SetDmeElement( pDef );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Indicates which helper to draw
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPreviewPanel::SetParticleFunction( CDmeParticleFunction *pFunction )
|
||||
{
|
||||
m_pParticleSystemPanel->SetRenderedHelper( pFunction );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when the check button is checked
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPreviewPanel::OnCheckButtonChecked( KeyValues *pParams )
|
||||
{
|
||||
int state = pParams->GetInt( "state", 0 );
|
||||
vgui::Panel *pPanel = (vgui::Panel*)pParams->GetPtr( "panel" );
|
||||
if ( pPanel == m_pRenderBounds )
|
||||
{
|
||||
m_pParticleSystemPanel->RenderBounds( state );
|
||||
return;
|
||||
}
|
||||
if ( pPanel == m_pRenderCullBounds )
|
||||
{
|
||||
m_pParticleSystemPanel->RenderCullBounds( state );
|
||||
return;
|
||||
}
|
||||
if ( pPanel == m_pRenderHelpers )
|
||||
{
|
||||
m_pParticleSystemPanel->RenderHelpers( state );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when a new background color is picked
|
||||
//-----------------------------------------------------------------------------
|
||||
void CParticleSystemPreviewPanel::OnBackgroundColorChanged( KeyValues *pParams )
|
||||
{
|
||||
m_pParticleSystemPanel->SetBackgroundColor( pParams->GetColor( "color" ) );
|
||||
}
|
||||
|
||||
void CParticleSystemPreviewPanel::OnBackgroundColorPreview( KeyValues *pParams )
|
||||
{
|
||||
m_pParticleSystemPanel->SetBackgroundColor( pParams->GetColor( "color" ) );
|
||||
}
|
||||
|
||||
void CParticleSystemPreviewPanel::OnBackgroundColorCancel( KeyValues *pParams )
|
||||
{
|
||||
m_pParticleSystemPanel->SetBackgroundColor( pParams->GetColor( "startingColor" ) );
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,194 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Dialog allowing users to select presets from within a preset group
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "dme_controls/presetpicker.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "vgui_controls/button.h"
|
||||
#include "vgui_controls/listpanel.h"
|
||||
#include "vgui_controls/splitter.h"
|
||||
#include "vgui_controls/messagebox.h"
|
||||
#include "movieobjects/dmeanimationset.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "matsys_controls/picker.h"
|
||||
#include "dme_controls/dmecontrols_utils.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
static int __cdecl PresetNameSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
|
||||
{
|
||||
const char *string1 = item1.kv->GetString( "name" );
|
||||
const char *string2 = item2.kv->GetString( "name" );
|
||||
return Q_stricmp( string1, string2 );
|
||||
}
|
||||
|
||||
CPresetPickerFrame::CPresetPickerFrame( vgui::Panel *pParent, const char *pTitle, bool bAllowMultiSelect ) :
|
||||
BaseClass( pParent, "PresetPickerFrame" )
|
||||
{
|
||||
SetDeleteSelfOnClose( true );
|
||||
m_pContextKeyValues = NULL;
|
||||
|
||||
m_pPresetList = new vgui::ListPanel( this, "PresetList" );
|
||||
m_pPresetList->AddColumnHeader( 0, "name", "Preset Name", 52, 0 );
|
||||
m_pPresetList->SetSelectIndividualCells( false );
|
||||
m_pPresetList->SetMultiselectEnabled( bAllowMultiSelect );
|
||||
m_pPresetList->SetEmptyListText( "No presets" );
|
||||
m_pPresetList->AddActionSignalTarget( this );
|
||||
m_pPresetList->SetSortFunc( 0, PresetNameSortFunc );
|
||||
m_pPresetList->SetSortColumn( 0 );
|
||||
|
||||
m_pOpenButton = new vgui::Button( this, "OkButton", "#MessageBox_OK", this, "Ok" );
|
||||
m_pCancelButton = new vgui::Button( this, "CancelButton", "#MessageBox_Cancel", this, "Cancel" );
|
||||
SetBlockDragChaining( true );
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/presetpicker.res" );
|
||||
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
CPresetPickerFrame::~CPresetPickerFrame()
|
||||
{
|
||||
CleanUpMessage();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Refreshes the list of presets
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPresetPickerFrame::RefreshPresetList( CDmElement *pPresetGroup, bool bSelectAll )
|
||||
{
|
||||
m_pPresetList->RemoveAll();
|
||||
|
||||
const CDmrElementArray< CDmePreset > presets( pPresetGroup, "presets" );
|
||||
if ( !presets.IsValid() )
|
||||
return;
|
||||
|
||||
int nCount = presets.Count();
|
||||
if ( nCount == 0 )
|
||||
return;
|
||||
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmePreset *pPreset = presets[i];
|
||||
|
||||
const char *pName = pPreset->GetName();
|
||||
if ( !pName || !pName[0] )
|
||||
{
|
||||
pName = "<no name>";
|
||||
}
|
||||
|
||||
KeyValues *kv = new KeyValues( "node" );
|
||||
kv->SetString( "name", pName );
|
||||
SetElementKeyValue( kv, "preset", pPreset );
|
||||
|
||||
int nItemID = m_pPresetList->AddItem( kv, 0, false, false );
|
||||
if ( bSelectAll )
|
||||
{
|
||||
m_pPresetList->AddSelectedItem( nItemID );
|
||||
}
|
||||
}
|
||||
m_pPresetList->SortList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Deletes the message
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPresetPickerFrame::CleanUpMessage()
|
||||
{
|
||||
if ( m_pContextKeyValues )
|
||||
{
|
||||
m_pContextKeyValues->deleteThis();
|
||||
m_pContextKeyValues = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the current scene + animation list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPresetPickerFrame::DoModal( CDmElement *pPresetGroup, bool bSelectAll, KeyValues *pContextKeyValues )
|
||||
{
|
||||
CleanUpMessage();
|
||||
RefreshPresetList( pPresetGroup, bSelectAll );
|
||||
m_pContextKeyValues = pContextKeyValues;
|
||||
BaseClass::DoModal();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On command
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPresetPickerFrame::OnCommand( const char *pCommand )
|
||||
{
|
||||
if ( !Q_stricmp( pCommand, "Ok" ) )
|
||||
{
|
||||
int nSelectedItemCount = m_pPresetList->GetSelectedItemsCount();
|
||||
if ( nSelectedItemCount == 0 )
|
||||
return;
|
||||
|
||||
KeyValues *pActionKeys = new KeyValues( "PresetPicked" );
|
||||
|
||||
if ( m_pPresetList->IsMultiselectEnabled() )
|
||||
{
|
||||
pActionKeys->SetInt( "count", nSelectedItemCount );
|
||||
|
||||
// Adds them in selection order
|
||||
for ( int i = 0; i < nSelectedItemCount; ++i )
|
||||
{
|
||||
char pBuf[32];
|
||||
Q_snprintf( pBuf, sizeof(pBuf), "%d", i );
|
||||
|
||||
int nItemID = m_pPresetList->GetSelectedItem( i );
|
||||
KeyValues *pKeyValues = m_pPresetList->GetItem( nItemID );
|
||||
CDmePreset *pPreset = GetElementKeyValue<CDmePreset>( pKeyValues, "preset" );
|
||||
|
||||
SetElementKeyValue( pActionKeys, pBuf, pPreset );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int nItemID = m_pPresetList->GetSelectedItem( 0 );
|
||||
KeyValues *pKeyValues = m_pPresetList->GetItem( nItemID );
|
||||
CDmePreset *pPreset = GetElementKeyValue<CDmePreset>( pKeyValues, "preset" );
|
||||
SetElementKeyValue( pActionKeys, "preset", pPreset );
|
||||
}
|
||||
|
||||
if ( m_pContextKeyValues )
|
||||
{
|
||||
pActionKeys->AddSubKey( m_pContextKeyValues );
|
||||
|
||||
// This prevents them from being deleted later
|
||||
m_pContextKeyValues = NULL;
|
||||
}
|
||||
|
||||
PostActionSignal( pActionKeys );
|
||||
CloseModal();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "Cancel" ) )
|
||||
{
|
||||
KeyValues *pActionKeys = new KeyValues( "PresetPickCancelled" );
|
||||
if ( m_pContextKeyValues )
|
||||
{
|
||||
pActionKeys->AddSubKey( m_pContextKeyValues );
|
||||
|
||||
// This prevents them from being deleted later
|
||||
m_pContextKeyValues = NULL;
|
||||
}
|
||||
PostActionSignal( pActionKeys );
|
||||
CloseModal();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( pCommand );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,602 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include <windows.h>
|
||||
#undef PropertySheet
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "dme_controls/soundpicker.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui_controls/ListPanel.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "vgui_controls/PropertySheet.h"
|
||||
#include "vgui_controls/PropertyPage.h"
|
||||
#include "dme_controls/filtercombobox.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/iinput.h"
|
||||
#include "dme_controls/dmecontrols.h"
|
||||
#include "soundemittersystem/isoundemittersystembase.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
|
||||
// FIXME: Move sound code out of the engine + into a library!
|
||||
#include "toolframework/ienginetool.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Sound Picker
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sort by sound name
|
||||
//-----------------------------------------------------------------------------
|
||||
static int __cdecl GameSoundSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 )
|
||||
{
|
||||
bool bRoot1 = item1.kv->GetInt("root") != 0;
|
||||
bool bRoot2 = item2.kv->GetInt("root") != 0;
|
||||
if ( bRoot1 != bRoot2 )
|
||||
return bRoot1 ? -1 : 1;
|
||||
const char *string1 = item1.kv->GetString("gamesound");
|
||||
const char *string2 = item2.kv->GetString("gamesound");
|
||||
return Q_stricmp( string1, string2 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CSoundPicker::CSoundPicker( vgui::Panel *pParent, int nFlags ) :
|
||||
BaseClass( pParent, "Sound Files", "wav", "sound", "wavName" )
|
||||
{
|
||||
m_nSoundSuppressionCount = 0;
|
||||
m_nPlayingSound = 0;
|
||||
|
||||
// Connection problem if this failed
|
||||
Assert( SoundEmitterSystem() );
|
||||
|
||||
m_pViewsSheet = new vgui::PropertySheet( this, "ViewsSheet" );
|
||||
m_pViewsSheet->AddActionSignalTarget( this );
|
||||
|
||||
// game sounds
|
||||
m_pGameSoundPage = NULL;
|
||||
m_pGameSoundList = NULL;
|
||||
if ( nFlags & PICK_GAMESOUNDS )
|
||||
{
|
||||
m_pGameSoundPage = new PropertyPage( m_pViewsSheet, "GameSoundPage" );
|
||||
m_pGameSoundList = new ListPanel( m_pGameSoundPage, "GameSoundsList" );
|
||||
m_pGameSoundList->AddColumnHeader( 0, "GameSound", "Game Sound", 52, 0 );
|
||||
m_pGameSoundList->AddActionSignalTarget( this );
|
||||
m_pGameSoundList->SetSelectIndividualCells( true );
|
||||
m_pGameSoundList->SetEmptyListText("No game sounds");
|
||||
m_pGameSoundList->SetDragEnabled( true );
|
||||
m_pGameSoundList->SetAutoResize( Panel::PIN_TOPLEFT, Panel::AUTORESIZE_DOWNANDRIGHT, 0, 0, 0, 0 );
|
||||
m_pGameSoundList->SetSortFunc( 0, GameSoundSortFunc );
|
||||
m_pGameSoundList->SetSortColumn( 0 );
|
||||
m_pGameSoundList->SetMultiselectEnabled( ( nFlags & ALLOW_MULTISELECT ) != 0 );
|
||||
|
||||
// filter selection
|
||||
m_pGameSoundFilter = new TextEntry( m_pGameSoundPage, "GameSoundFilter" );
|
||||
m_pGameSoundFilter->AddActionSignalTarget( this );
|
||||
|
||||
m_pGameSoundPage->LoadControlSettings( "resource/soundpickergamesoundpage.res" );
|
||||
|
||||
m_pViewsSheet->AddPage( m_pGameSoundPage, "Game Sounds" );
|
||||
}
|
||||
|
||||
// wav files
|
||||
m_pWavPage = NULL;
|
||||
if ( nFlags & PICK_WAVFILES )
|
||||
{
|
||||
m_pWavPage = new PropertyPage( m_pViewsSheet, "WavPage" );
|
||||
bool bAllowMultiselect = ( nFlags & ALLOW_MULTISELECT ) != 0;
|
||||
CreateStandardControls( m_pWavPage, bAllowMultiselect );
|
||||
AddExtension( "mp3" );
|
||||
|
||||
m_pWavPage->LoadControlSettings( "resource/soundpickerwavpage.res" );
|
||||
m_pViewsSheet->AddPage( m_pWavPage, "WAVs" );
|
||||
}
|
||||
|
||||
LoadControlSettings( "resource/soundpicker.res" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CSoundPicker::~CSoundPicker()
|
||||
{
|
||||
StopSoundPreview();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called to open
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::Activate()
|
||||
{
|
||||
BaseClass::Activate();
|
||||
if ( m_pGameSoundPage )
|
||||
{
|
||||
BuildGameSoundList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the current sound choice
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::SetSelectedSound( PickType_t type, const char *pSoundName )
|
||||
{
|
||||
if ( type == PICK_NONE || !pSoundName )
|
||||
return;
|
||||
|
||||
if ( m_pGameSoundPage && ( type == PICK_GAMESOUNDS ) )
|
||||
{
|
||||
m_pViewsSheet->SetActivePage( m_pGameSoundPage );
|
||||
m_pGameSoundFilter->SetText( pSoundName );
|
||||
}
|
||||
|
||||
if ( m_pWavPage && ( type == PICK_WAVFILES ) )
|
||||
{
|
||||
m_pViewsSheet->SetActivePage( m_pWavPage );
|
||||
SetInitialSelection( pSoundName );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::OnKeyCodePressed( KeyCode code )
|
||||
{
|
||||
if ( m_pGameSoundPage && ( m_pViewsSheet->GetActivePage() == m_pGameSoundPage ) )
|
||||
{
|
||||
if (( code == KEY_UP ) || ( code == KEY_DOWN ) || ( code == KEY_PAGEUP ) || ( code == KEY_PAGEDOWN ))
|
||||
{
|
||||
KeyValues *pMsg = new KeyValues( "KeyCodePressed", "code", code );
|
||||
vgui::ipanel()->SendMessage( m_pGameSoundList->GetVPanel(), pMsg, GetVPanel() );
|
||||
pMsg->deleteThis();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::OnKeyCodePressed( code );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: builds the gamesound list
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSoundPicker::IsGameSoundVisible( int hGameSound )
|
||||
{
|
||||
const char *pSoundName = SoundEmitterSystem()->GetSoundName( hGameSound );
|
||||
return ( !m_GameSoundFilter.Length() || Q_stristr( pSoundName, m_GameSoundFilter.Get() ) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Updates the column header in the chooser
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::UpdateGameSoundColumnHeader( int nMatchCount, int nTotalCount )
|
||||
{
|
||||
char pColumnTitle[512];
|
||||
Q_snprintf( pColumnTitle, sizeof(pColumnTitle), "%s (%d/%d)",
|
||||
"Game Sound", nMatchCount, nTotalCount );
|
||||
m_pGameSoundList->SetColumnHeaderText( 0, pColumnTitle );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: builds the gamesound list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::BuildGameSoundList()
|
||||
{
|
||||
if ( !m_pGameSoundList )
|
||||
return;
|
||||
|
||||
m_pGameSoundList->RemoveAll();
|
||||
|
||||
int nTotalCount = 0;
|
||||
int i = SoundEmitterSystem()->First();
|
||||
while ( i != SoundEmitterSystem()->InvalidIndex() )
|
||||
{
|
||||
const char *pSoundName = SoundEmitterSystem()->GetSoundName( i );
|
||||
|
||||
bool bInRoot = !strchr( pSoundName, '\\' ) && !strchr( pSoundName, '/' );
|
||||
KeyValues *kv = new KeyValues( "node", "gamesound", pSoundName );
|
||||
kv->SetInt( "gameSoundHandle", i );
|
||||
kv->SetInt( "root", bInRoot );
|
||||
|
||||
int nItemID = m_pGameSoundList->AddItem( kv, 0, false, false );
|
||||
m_pGameSoundList->SetItemVisible( nItemID, IsGameSoundVisible( i ) );
|
||||
KeyValues *pDrag = new KeyValues( "drag", "text", pSoundName );
|
||||
pDrag->SetString( "texttype", "gamesoundName" );
|
||||
m_pGameSoundList->SetItemDragData( nItemID, pDrag );
|
||||
++nTotalCount;
|
||||
|
||||
i = SoundEmitterSystem()->Next( i );
|
||||
}
|
||||
|
||||
m_pGameSoundList->SortList();
|
||||
if ( m_pGameSoundList->GetItemCount() > 0 )
|
||||
{
|
||||
int nItemID = m_pGameSoundList->GetItemIDFromRow( 0 );
|
||||
|
||||
// This prevents the refreshing of the sound list from playing the sound
|
||||
++m_nSoundSuppressionCount;
|
||||
m_pGameSoundList->SetSelectedCell( nItemID, 0 );
|
||||
}
|
||||
|
||||
UpdateGameSoundColumnHeader( nTotalCount, nTotalCount );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes the gamesound list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::RefreshGameSoundList()
|
||||
{
|
||||
if ( !m_pGameSoundList )
|
||||
return;
|
||||
|
||||
// Check the filter matches
|
||||
int nMatchingGameSounds = 0;
|
||||
int nTotalCount = 0;
|
||||
for ( int nItemID = m_pGameSoundList->FirstItem(); nItemID != m_pGameSoundList->InvalidItemID(); nItemID = m_pGameSoundList->NextItem( nItemID ) )
|
||||
{
|
||||
KeyValues *kv = m_pGameSoundList->GetItem( nItemID );
|
||||
int hGameSound = kv->GetInt( "gameSoundHandle", SoundEmitterSystem()->InvalidIndex() );
|
||||
if ( hGameSound == SoundEmitterSystem()->InvalidIndex() )
|
||||
continue;
|
||||
bool bIsVisible = IsGameSoundVisible( hGameSound );
|
||||
m_pGameSoundList->SetItemVisible( nItemID, bIsVisible );
|
||||
if ( bIsVisible )
|
||||
{
|
||||
++nMatchingGameSounds;
|
||||
}
|
||||
++nTotalCount;
|
||||
}
|
||||
|
||||
UpdateGameSoundColumnHeader( nMatchingGameSounds, nTotalCount );
|
||||
|
||||
if ( ( m_pGameSoundList->GetSelectedItemsCount() == 0 ) && ( m_pGameSoundList->GetItemCount() > 0 ) )
|
||||
{
|
||||
int nItemID = m_pGameSoundList->GetItemIDFromRow( 0 );
|
||||
// This prevents the refreshing of the sound list from playing the sound
|
||||
++m_nSoundSuppressionCount;
|
||||
m_pGameSoundList->SetSelectedCell( nItemID, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Update filter when text changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::OnGameSoundFilterTextChanged( )
|
||||
{
|
||||
int nLength = m_pGameSoundFilter->GetTextLength();
|
||||
m_GameSoundFilter.SetLength( nLength );
|
||||
if ( nLength > 0 )
|
||||
{
|
||||
m_pGameSoundFilter->GetText( m_GameSoundFilter.GetForModify(), nLength+1 );
|
||||
}
|
||||
RefreshGameSoundList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes dialog on filter changing
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::OnTextChanged( KeyValues *pKeyValues )
|
||||
{
|
||||
vgui::Panel *pSource = (vgui::Panel*)pKeyValues->GetPtr( "panel" );
|
||||
if ( pSource == m_pGameSoundFilter )
|
||||
{
|
||||
OnGameSoundFilterTextChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnTextChanged( pKeyValues );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called when a page is shown
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::RequestGameSoundFilterFocus( )
|
||||
{
|
||||
m_pGameSoundFilter->SelectAllOnFirstFocus( true );
|
||||
m_pGameSoundFilter->RequestFocus();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called when a page is shown
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::OnPageChanged( )
|
||||
{
|
||||
StopSoundPreview();
|
||||
if ( m_pGameSoundPage && ( m_pViewsSheet->GetActivePage() == m_pGameSoundPage ) )
|
||||
{
|
||||
RequestGameSoundFilterFocus();
|
||||
}
|
||||
if ( m_pWavPage && ( m_pViewsSheet->GetActivePage() == m_pWavPage ) )
|
||||
{
|
||||
RequestFilterFocus();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Stop sound preview
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::StopSoundPreview( )
|
||||
{
|
||||
if ( m_nPlayingSound != 0 )
|
||||
{
|
||||
EngineTool()->StopSoundByGuid( m_nPlayingSound );
|
||||
m_nPlayingSound = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Plays a gamesound
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::PlayGameSound( const char *pSoundName )
|
||||
{
|
||||
StopSoundPreview();
|
||||
|
||||
CSoundParameters params;
|
||||
if ( SoundEmitterSystem()->GetParametersForSound( pSoundName, params, GENDER_NONE ) )
|
||||
{
|
||||
m_nPlayingSound = EngineTool()->StartSound( 0, true, -1, CHAN_STATIC, params.soundname,
|
||||
params.volume, params.soundlevel, vec3_origin, vec3_origin, 0,
|
||||
params.pitch, false, params.delay_msec / 1000.0f );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Plays a wav file
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::PlayWavSound( const char *pSoundName )
|
||||
{
|
||||
StopSoundPreview();
|
||||
m_nPlayingSound = EngineTool()->StartSound( 0, true, -1, CHAN_STATIC, pSoundName,
|
||||
VOL_NORM, SNDLVL_NONE, vec3_origin, vec3_origin, 0, PITCH_NORM, false, 0 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Don't play a sound when the next selection is a default selection
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::OnNextSelectionIsDefault()
|
||||
{
|
||||
++m_nSoundSuppressionCount;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Derived classes have this called when the previewed asset changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::OnSelectedAssetPicked( const char *pAssetName )
|
||||
{
|
||||
bool bPlaySounds = true;
|
||||
if ( m_nSoundSuppressionCount > 0 )
|
||||
{
|
||||
--m_nSoundSuppressionCount;
|
||||
bPlaySounds = false;
|
||||
}
|
||||
|
||||
if ( pAssetName && bPlaySounds )
|
||||
{
|
||||
PlayWavSound( pAssetName );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes dialog on text changing
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPicker::OnItemSelected( KeyValues *kv )
|
||||
{
|
||||
Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL );
|
||||
if ( m_pGameSoundList && (pPanel == m_pGameSoundList ) )
|
||||
{
|
||||
bool bPlaySounds = true;
|
||||
if ( m_nSoundSuppressionCount > 0 )
|
||||
{
|
||||
--m_nSoundSuppressionCount;
|
||||
bPlaySounds = false;
|
||||
}
|
||||
|
||||
const char *pGameSoundName = GetSelectedSoundName();
|
||||
if ( pGameSoundName && bPlaySounds )
|
||||
{
|
||||
int len = V_strlen( pGameSoundName );
|
||||
char *soundname = ( char* )stackalloc( len + 2 );
|
||||
soundname[ 0 ] = '#'; // mark sound to bypass the dsp
|
||||
V_strncpy( soundname + 1, pGameSoundName, len + 1 );
|
||||
|
||||
PlayGameSound( soundname );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnItemSelected( kv );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the selected sound type
|
||||
//-----------------------------------------------------------------------------
|
||||
CSoundPicker::PickType_t CSoundPicker::GetSelectedSoundType( )
|
||||
{
|
||||
if ( m_pGameSoundPage && ( m_pViewsSheet->GetActivePage() == m_pGameSoundPage ) )
|
||||
return PICK_GAMESOUNDS;
|
||||
if ( m_pWavPage && ( m_pViewsSheet->GetActivePage() == m_pWavPage ) )
|
||||
return PICK_WAVFILES;
|
||||
return PICK_NONE;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the selected sound count
|
||||
//-----------------------------------------------------------------------------
|
||||
int CSoundPicker::GetSelectedSoundCount()
|
||||
{
|
||||
if ( m_pGameSoundPage && ( m_pViewsSheet->GetActivePage() == m_pGameSoundPage ) )
|
||||
return m_pGameSoundList->GetSelectedItemsCount();
|
||||
|
||||
if ( m_pWavPage && ( m_pViewsSheet->GetActivePage() == m_pWavPage ) )
|
||||
return GetSelectedAssetCount();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the selected sound
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CSoundPicker::GetSelectedSoundName( int nSelectionIndex )
|
||||
{
|
||||
if ( m_pGameSoundPage && ( m_pViewsSheet->GetActivePage() == m_pGameSoundPage ) )
|
||||
{
|
||||
int nCount = m_pGameSoundList->GetSelectedItemsCount();
|
||||
if ( nCount == 0 )
|
||||
return NULL;
|
||||
|
||||
if ( nSelectionIndex < 0 )
|
||||
{
|
||||
nSelectionIndex = nCount - 1;
|
||||
}
|
||||
int nIndex = m_pGameSoundList->GetSelectedItem( nSelectionIndex );
|
||||
if ( nIndex >= 0 )
|
||||
{
|
||||
KeyValues *pkv = m_pGameSoundList->GetItem( nIndex );
|
||||
return pkv->GetString( "gamesound", NULL );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( m_pWavPage && ( m_pViewsSheet->GetActivePage() == m_pWavPage ) )
|
||||
return GetSelectedAsset( nSelectionIndex );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: Modal picker frame
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CSoundPickerFrame::CSoundPickerFrame( vgui::Panel *pParent, const char *pTitle, int nFlags ) :
|
||||
BaseClass( pParent )
|
||||
{
|
||||
SetAssetPicker( new CSoundPicker( this, nFlags ) );
|
||||
LoadControlSettingsAndUserConfig( "resource/soundpickerframe.res" );
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
CSoundPickerFrame::~CSoundPickerFrame()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Activate the dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPickerFrame::DoModal( CSoundPicker::PickType_t initialType, const char *pInitialValue, KeyValues *pContextKeyValues )
|
||||
{
|
||||
vgui::surface()->SetCursor( dc_hourglass );
|
||||
CSoundPicker *pPicker = static_cast <CSoundPicker*>( GetAssetPicker() );
|
||||
if ( initialType != CSoundPicker::PICK_NONE && pInitialValue )
|
||||
{
|
||||
pPicker->SetSelectedSound( initialType, pInitialValue );
|
||||
}
|
||||
BaseClass::DoModal( pContextKeyValues );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On command
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundPickerFrame::OnCommand( const char *pCommand )
|
||||
{
|
||||
CSoundPicker *pPicker = static_cast <CSoundPicker*>( GetAssetPicker() );
|
||||
if ( !Q_stricmp( pCommand, "Open" ) )
|
||||
{
|
||||
CSoundPicker::PickType_t type = pPicker->GetSelectedSoundType( );
|
||||
if (( type == CSoundPicker::PICK_GAMESOUNDS ) || ( type == CSoundPicker::PICK_WAVFILES ))
|
||||
{
|
||||
const char *pSoundName = pPicker->GetSelectedSoundName();
|
||||
|
||||
int len = V_strlen( pSoundName );
|
||||
char *soundname = ( char* )stackalloc( len + 2 );
|
||||
soundname[ 0 ] = '#'; // mark sound to bypass the dsp
|
||||
V_strncpy( soundname + 1, pSoundName, len + 1 );
|
||||
|
||||
int nSoundCount = pPicker->GetSelectedSoundCount();
|
||||
|
||||
KeyValues *pActionKeys = new KeyValues( "SoundSelected" );
|
||||
pActionKeys->SetInt( "count", nSoundCount );
|
||||
KeyValues *pSoundList = NULL;
|
||||
if ( type == CSoundPicker::PICK_GAMESOUNDS )
|
||||
{
|
||||
pActionKeys->SetString( "gamesound", soundname );
|
||||
if ( pPicker->IsMultiselectEnabled() )
|
||||
{
|
||||
pSoundList = pActionKeys->FindKey( "gamesounds", true );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pActionKeys->SetString( "wav", soundname );
|
||||
if ( pPicker->IsMultiselectEnabled() )
|
||||
{
|
||||
pSoundList = pActionKeys->FindKey( "wavs", true );
|
||||
}
|
||||
}
|
||||
|
||||
if ( pSoundList )
|
||||
{
|
||||
// Adds them in selection order
|
||||
for ( int i = 0; i < nSoundCount; ++i )
|
||||
{
|
||||
char pBuf[32];
|
||||
Q_snprintf( pBuf, sizeof(pBuf), "%d", i );
|
||||
pSoundName = pPicker->GetSelectedSoundName( i );
|
||||
|
||||
len = V_strlen( pSoundName );
|
||||
soundname = ( char* )malloc( len + 2 );
|
||||
soundname[ 0 ] = '#'; // mark sound to bypass the dsp
|
||||
V_strncpy( soundname + 1, pSoundName, len + 1 );
|
||||
|
||||
pSoundList->SetString( pBuf, soundname );
|
||||
free( soundname );
|
||||
}
|
||||
}
|
||||
|
||||
PostMessageAndClose( pActionKeys );
|
||||
CloseModal();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( pCommand );
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dme_controls/soundrecordpanel.h"
|
||||
#include "filesystem.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "vgui_controls/TextEntry.h"
|
||||
#include "dme_controls/dmecontrols.h"
|
||||
#include "vgui_controls/messagebox.h"
|
||||
#include "soundemittersystem/isoundemittersystembase.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
|
||||
// FIXME: Move sound code out of the engine + into a library!
|
||||
#include "toolframework/ienginetool.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Sound Record Dialog
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CSoundRecordPanel::CSoundRecordPanel( vgui::Panel *pParent, const char *pTitle ) :
|
||||
BaseClass( pParent, "SoundRecordPanel" )
|
||||
{
|
||||
m_bIsRecording = false;
|
||||
m_nPlayingSound = 0;
|
||||
SetDeleteSelfOnClose( true );
|
||||
m_pOkButton = new Button( this, "OkButton", "#FileOpenDialog_Open", this, "Ok" );
|
||||
m_pCancelButton = new Button( this, "CancelButton", "#FileOpenDialog_Cancel", this, "Cancel" );
|
||||
m_pPlayButton = new Button( this, "PlayButton", "Play", this, "Play" );
|
||||
m_pRecordButton = new Button( this, "Record", "Record", this, "ToggleRecord" );
|
||||
m_pRecordTime = new TextEntry( this, "RecordTime" );
|
||||
m_pFileName = new TextEntry( this, "FileName" );
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/soundrecordpanel.res" );
|
||||
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
CSoundRecordPanel::~CSoundRecordPanel()
|
||||
{
|
||||
StopSoundPreview();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Activate the dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundRecordPanel::DoModal( const char *pFileName )
|
||||
{
|
||||
Assert( EngineTool() );
|
||||
|
||||
char pRelativeWAVPath[MAX_PATH];
|
||||
g_pFullFileSystem->FullPathToRelativePath( pFileName, pRelativeWAVPath, sizeof(pRelativeWAVPath) );
|
||||
|
||||
// Check to see if this file is not hidden owing to search paths
|
||||
bool bBadDirectory = false;
|
||||
char pRelativeDir[MAX_PATH];
|
||||
Q_strncpy( pRelativeDir, pRelativeWAVPath, sizeof( pRelativeDir ) );
|
||||
Q_StripFilename( pRelativeDir );
|
||||
char pFoundFullPath[MAX_PATH];
|
||||
g_pFullFileSystem->RelativePathToFullPath( pRelativeDir, "MOD", pFoundFullPath, sizeof( pFoundFullPath ) );
|
||||
if ( StringHasPrefix( pFileName, pFoundFullPath ) )
|
||||
{
|
||||
// Strip 'sound/' prefix
|
||||
m_FileName = pRelativeWAVPath;
|
||||
const char *pSoundName = StringAfterPrefix( pRelativeWAVPath, "sound\\" );
|
||||
if ( !pSoundName )
|
||||
{
|
||||
pSoundName = pRelativeWAVPath;
|
||||
bBadDirectory = true;
|
||||
}
|
||||
m_EngineFileName = pSoundName;
|
||||
}
|
||||
else
|
||||
{
|
||||
bBadDirectory = true;
|
||||
}
|
||||
|
||||
if ( bBadDirectory )
|
||||
{
|
||||
char pBuf[1024];
|
||||
Q_snprintf( pBuf, sizeof(pBuf), "File %s is in a bad directory!\nAudio must be recorded into your mod's sound/ directory.\n", pFileName );
|
||||
vgui::MessageBox *pMessageBox = new vgui::MessageBox( "Bad Save Directory!\n", pBuf, GetParent() );
|
||||
pMessageBox->DoModal( );
|
||||
return;
|
||||
}
|
||||
|
||||
m_pFileName->SetText( pFileName );
|
||||
m_pOkButton->SetEnabled( false );
|
||||
m_pPlayButton->SetEnabled( false );
|
||||
BaseClass::DoModal();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Stop sound preview
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundRecordPanel::StopSoundPreview( )
|
||||
{
|
||||
if ( m_nPlayingSound != 0 )
|
||||
{
|
||||
EngineTool()->StopSoundByGuid( m_nPlayingSound );
|
||||
m_nPlayingSound = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Plays a wav file
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundRecordPanel::PlaySoundPreview( )
|
||||
{
|
||||
StopSoundPreview();
|
||||
m_nPlayingSound = EngineTool()->StartSound( 0, true, -1, CHAN_STATIC, m_EngineFileName,
|
||||
VOL_NORM, SNDLVL_NONE, vec3_origin, vec3_origin, 0, PITCH_NORM, false, 0 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Updates sound record time during recording
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundRecordPanel::UpdateTimeRecorded()
|
||||
{
|
||||
float flTime = Plat_FloatTime() - m_flRecordStartTime;
|
||||
char pTimeBuf[64];
|
||||
Q_snprintf( pTimeBuf, sizeof(pTimeBuf), "%.3f", flTime );
|
||||
m_pRecordTime->SetText( pTimeBuf );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Updates sound record time during recording
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundRecordPanel::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
|
||||
// Update the amount of time recorded
|
||||
UpdateTimeRecorded();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On command
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundRecordPanel::OnCommand( const char *pCommand )
|
||||
{
|
||||
if ( !Q_stricmp( pCommand, "ToggleRecord" ) )
|
||||
{
|
||||
if ( !m_bIsRecording )
|
||||
{
|
||||
StopSoundPreview();
|
||||
g_pFullFileSystem->RemoveFile( m_FileName, "MOD" );
|
||||
EngineTool()->StartRecordingVoiceToFile( m_FileName, "MOD" );
|
||||
m_pRecordButton->SetText( "Stop Recording" );
|
||||
m_pPlayButton->SetEnabled( false );
|
||||
m_pOkButton->SetEnabled( false );
|
||||
m_pCancelButton->SetEnabled( true );
|
||||
m_flRecordStartTime = Plat_FloatTime();
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel(), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
EngineTool()->StopRecordingVoiceToFile();
|
||||
EngineTool()->ReloadSound( m_EngineFileName );
|
||||
ivgui()->RemoveTickSignal( GetVPanel() );
|
||||
UpdateTimeRecorded();
|
||||
m_pOkButton->SetEnabled( true );
|
||||
m_pCancelButton->SetEnabled( true );
|
||||
m_pPlayButton->SetEnabled( true );
|
||||
m_pRecordButton->SetText( "Record" );
|
||||
}
|
||||
m_bIsRecording = !m_bIsRecording;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "Play" ) )
|
||||
{
|
||||
PlaySoundPreview();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "Ok" ) )
|
||||
{
|
||||
PostActionSignal( new KeyValues( "SoundRecorded", "relativepath", m_EngineFileName.Get() ) );
|
||||
CloseModal();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "Cancel" ) )
|
||||
{
|
||||
g_pFullFileSystem->RemoveFile( m_FileName, "MOD" );
|
||||
CloseModal();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( pCommand );
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,723 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#if defined(WIN32) && !defined( _X360 )
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include "filesystem.h"
|
||||
#include "filesystem_init.h"
|
||||
#include "appframework/IAppSystemGroup.h"
|
||||
#include "appframework/IAppSystem.h"
|
||||
#include "appframework/AppFramework.h"
|
||||
#include "filesystem_helpers.h"
|
||||
|
||||
#include "matsys_controls/QCGenerator.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier2/vconfig.h"
|
||||
#include "vgui_controls/ListPanel.h"
|
||||
#include "vgui_controls/TextEntry.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "vgui_controls/FileOpenDialog.h"
|
||||
#include "vgui_controls/DirectorySelectDialog.h"
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "vgui_controls/CheckButton.h"
|
||||
#include "vgui_controls/MessageBox.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/IInput.h"
|
||||
#include "vgui/Cursor.h"
|
||||
#include "vgui_controls/KeyBoardEditorDialog.h"
|
||||
|
||||
#if defined( _X360 )
|
||||
#include "xbox/xbox_win32stubs.h"
|
||||
#endif
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
#define MAX_KEYVALUE 1024
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns a pointer to the 'count' occurence of a character from the end of a string
|
||||
// returns 0 of there aren't 'count' number of the character in the string
|
||||
//-----------------------------------------------------------------------------
|
||||
char *strrchrcount(char *string, int character, int count )
|
||||
{
|
||||
int j = count;
|
||||
int numChars = strlen( string );
|
||||
for( int i = numChars; i > 0; i-- )
|
||||
{
|
||||
if( string[i-1] == character )
|
||||
{
|
||||
j--;
|
||||
}
|
||||
if( j == 0 )
|
||||
{
|
||||
return string + i-1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CModalPreserveMessageBox : public vgui::MessageBox
|
||||
{
|
||||
public:
|
||||
CModalPreserveMessageBox(const char *title, const char *text, vgui::Panel *parent)
|
||||
: vgui::MessageBox( title, text, parent )
|
||||
{
|
||||
m_PrevAppFocusPanel = vgui::input()->GetAppModalSurface();
|
||||
}
|
||||
|
||||
~CModalPreserveMessageBox()
|
||||
{
|
||||
vgui::input()->SetAppModalSurface( m_PrevAppFocusPanel );
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
vgui::VPANEL m_PrevAppFocusPanel;
|
||||
};
|
||||
|
||||
void VGUIMessageBox( vgui::Panel *pParent, const char *pTitle, const char *pMsg, ... )
|
||||
{
|
||||
char msg[4096];
|
||||
va_list marker;
|
||||
va_start( marker, pMsg );
|
||||
Q_vsnprintf( msg, sizeof( msg ), pMsg, marker );
|
||||
va_end( marker );
|
||||
|
||||
vgui::MessageBox *dlg = new CModalPreserveMessageBox( pTitle, msg, pParent );
|
||||
dlg->DoModal();
|
||||
dlg->Activate();
|
||||
dlg->RequestFocus();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Places all the info from the vgui controls into the QCInfo struct
|
||||
//-----------------------------------------------------------------------------
|
||||
void QCInfo::SyncFromControls()
|
||||
{
|
||||
char tempText[MAX_PATH];
|
||||
|
||||
vgui::Panel *pTargetField = pQCGenerator->FindChildByName( "staticPropCheck" );
|
||||
bStaticProp = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "mostlyOpaqueCheck" );
|
||||
bMostlyOpaque = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "disableCollisionsCheck" );
|
||||
bDisableCollision = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "referencePhysicsCheck" );
|
||||
bReferenceAsPhys = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "concaveCheck" );
|
||||
bConcave = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "automassCheck" );
|
||||
bAutomass = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "massField" );
|
||||
((TextEntry *)pTargetField)->GetText(tempText, MAX_PATH);
|
||||
fMass = atof(tempText);
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "scaleField" );
|
||||
((TextEntry *)pTargetField)->GetText(tempText, MAX_PATH);
|
||||
fScale = atof(tempText);
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "collisionSMDField" );
|
||||
((TextEntry *)pTargetField)->GetText( tempText, MAX_PATH );
|
||||
V_strcpy_safe( pszCollisionPath, tempText );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "surfacePropertyDropDown" );
|
||||
((ComboBox *)pTargetField)->GetText( tempText, MAX_PATH );
|
||||
V_strcpy_safe( pszSurfaceProperty, tempText );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "materialsField" );
|
||||
((TextEntry *)pTargetField)->GetText( tempText, MAX_PATH );
|
||||
V_strcpy_safe( pszMaterialPath, tempText );
|
||||
|
||||
LODs.RemoveAll();
|
||||
pTargetField = pQCGenerator->FindChildByName( "LODList" );
|
||||
int numLOD = ((ListPanel *)pTargetField)->GetItemCount();
|
||||
for ( int i = 0; i < numLOD; i++ )
|
||||
{
|
||||
KeyValues *key = ((ListPanel *)pTargetField)->GetItem( i );
|
||||
LODInfo newLOD;
|
||||
|
||||
V_strcpy_safe( newLOD.pszFilename, key->GetString( "SMD" ) );
|
||||
newLOD.iLOD = key->GetInt( "LOD" );
|
||||
LODs.AddToTail( newLOD );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called during intialization to setup the initial state of the VGUI controls
|
||||
//-----------------------------------------------------------------------------
|
||||
void QCInfo::SyncToControls()
|
||||
{
|
||||
char tempText[MAX_PATH];
|
||||
|
||||
vgui::Panel *pTargetField = pQCGenerator->FindChildByName( "staticPropCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bStaticProp );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "mostlyOpaqueCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bMostlyOpaque );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "disableCollisionsCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bDisableCollision );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "referencePhysicsCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bReferenceAsPhys );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "concaveCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bConcave );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "automassCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bAutomass );
|
||||
|
||||
Q_snprintf( tempText, 10, "%d", (int)fMass );
|
||||
pTargetField = pQCGenerator->FindChildByName( "massField" );
|
||||
((TextEntry *)pTargetField)->SetText( tempText );
|
||||
|
||||
Q_snprintf( tempText, 10, "%d", (int)fScale );
|
||||
pTargetField = pQCGenerator->FindChildByName( "scaleField" );
|
||||
((TextEntry *)pTargetField)->SetText( tempText );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "collisionSMDField" );
|
||||
((TextEntry *)pTargetField)->SetText( pszCollisionPath );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "materialsField" );
|
||||
((TextEntry *)pTargetField)->SetText( pszMaterialPath );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "surfacePropertyDropDown" );
|
||||
int numItems = ((ComboBox *)pTargetField)->GetItemCount();
|
||||
for( int i = 0; i < numItems; i++ )
|
||||
{
|
||||
((ComboBox *)pTargetField)->GetItemText( i, tempText, MAX_PATH );
|
||||
if ( !Q_strcmp( tempText, pszSurfaceProperty ) )
|
||||
{
|
||||
((ComboBox *)pTargetField)->SetItemEnabled( i, true );
|
||||
((ComboBox *)pTargetField)->SetText( tempText );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CBrowseButton::CBrowseButton( vgui::Panel *pParent ) : BaseClass( pParent, "Browse Button", "...", pParent, "browse" )
|
||||
{
|
||||
SetParent( pParent );
|
||||
pszStartingDirectory = NULL;
|
||||
pszFileFilter = NULL;
|
||||
pszTargetField = NULL;
|
||||
}
|
||||
|
||||
CBrowseButton::~CBrowseButton()
|
||||
{
|
||||
}
|
||||
|
||||
void CBrowseButton::SetCharVar( char **pVar, const char *pszNewText )
|
||||
{
|
||||
if ( *pVar && pszNewText && !Q_strcmp( *pVar, pszNewText ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( *pVar )
|
||||
{
|
||||
delete [] *pVar;
|
||||
*pVar = NULL;
|
||||
}
|
||||
|
||||
if ( pszNewText )
|
||||
{
|
||||
int len = Q_strlen( pszNewText ) + 1;
|
||||
*pVar = new char[ len ];
|
||||
Q_strncpy( *pVar, pszNewText, len );
|
||||
}
|
||||
}
|
||||
|
||||
void CBrowseButton::InitBrowseInfo( int x, int y, const char *pszName, const char *pszDir, const char *pszFilter, const char *pszField )
|
||||
{
|
||||
SetSize( 24, 24 );
|
||||
SetPos( x, y );
|
||||
SetName( pszName );
|
||||
SetCharVar( GetStartingDirectory(), pszDir );
|
||||
SetCharVar( GetFileFilter(), pszFilter );
|
||||
SetCharVar( GetTargetField(), pszField );
|
||||
SetActionMessage();
|
||||
}
|
||||
|
||||
void CBrowseButton::SetActionMessage()
|
||||
{
|
||||
KeyValues *newActionMessage = new KeyValues( "browse", "directory", pszStartingDirectory, "filter", pszFileFilter);
|
||||
newActionMessage->SetString( "targetField", pszTargetField );
|
||||
SetCommand( newActionMessage );
|
||||
}
|
||||
|
||||
const char *ParseKeyvalue( const char *pBuffer, char *key, char *value )
|
||||
{
|
||||
char com_token[1024];
|
||||
|
||||
pBuffer = (const char *)ParseFile( pBuffer, com_token, NULL );
|
||||
if ( Q_strlen( com_token ) < MAX_KEYVALUE )
|
||||
{
|
||||
Q_strncpy( key, com_token, MAX_KEYVALUE );
|
||||
Q_strlower( key );
|
||||
}
|
||||
// no value on a close brace
|
||||
if ( !Q_strcmp( key, "}" ) )
|
||||
{
|
||||
value[0] = 0;
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
pBuffer = (const char *)ParseFile( pBuffer, com_token, NULL );
|
||||
if ( Q_strlen( com_token ) < MAX_KEYVALUE )
|
||||
{
|
||||
Q_strncpy( value, com_token, MAX_KEYVALUE );
|
||||
Q_strlower( value );
|
||||
}
|
||||
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CQCGenerator::CQCGenerator( vgui::Panel *pParent, const char *pszPath, const char *pszScene ) : BaseClass( pParent, "QCGenerator" )
|
||||
{
|
||||
m_QCInfo_t.Init( this );
|
||||
|
||||
SetMinimumSize(846, 770);
|
||||
|
||||
m_pLODPanel = new ListPanel(this, "LODList");
|
||||
m_pLODPanel->SetSelectIndividualCells( true );
|
||||
m_pLODPanel->AddColumnHeader(0, "SMD", "LOD SMD", 450, 0);
|
||||
m_pLODPanel->AddColumnHeader(1, "LOD", "LOD Distance", 50, 0);
|
||||
m_pLODPanel->AddActionSignalTarget( this );
|
||||
m_pLODPanel->SetMouseInputEnabled( true );
|
||||
|
||||
LoadControlSettings( "QCGenerator.res" );
|
||||
|
||||
m_pCollisionBrowseButton = new CBrowseButton( this );
|
||||
m_pCollisionBrowseButton->InitBrowseInfo( 808, 158, "collisionBrowseButton", pszPath, "*.smd", "collisionSMDField" );
|
||||
|
||||
char szTerminatedPath[1024] = "\0";
|
||||
sprintf( szTerminatedPath, "%s\\", pszPath );
|
||||
|
||||
InitializeSMDPaths( szTerminatedPath, pszScene );
|
||||
|
||||
char *pszMaterialsStart = strrchrcount( szTerminatedPath, '\\', 3 ) + 1;
|
||||
char *pszMaterialsEnd = strrchr( szTerminatedPath, '\\');
|
||||
Q_strncpy( m_QCInfo_t.pszMaterialPath, pszMaterialsStart, pszMaterialsEnd - pszMaterialsStart + 1 );
|
||||
|
||||
SetParent( pParent );
|
||||
|
||||
char szGamePath[1024] = "\0";
|
||||
char szSearchPath[1024] = "\0";
|
||||
|
||||
// Get the currently set game configuration
|
||||
GetVConfigRegistrySetting( GAMEDIR_TOKEN, szGamePath, sizeof( szGamePath ) );
|
||||
static const char *pSurfacePropFilename = "\\scripts\\surfaceproperties.txt";
|
||||
|
||||
sprintf( szSearchPath, "%s%s", szGamePath, pSurfacePropFilename );
|
||||
|
||||
FileHandle_t fp = g_pFullFileSystem->Open( szSearchPath, "rb" );
|
||||
|
||||
if ( !fp )
|
||||
{
|
||||
//the set game configuration didn't have a surfaceproperties file; we are grabbing it from hl2
|
||||
//TODO: This only works if they are in a subdirectory that is a peer to an hl2 directory
|
||||
// that contains the file. It potentially needs to search the entire drive or prompt for the location
|
||||
char *pszEndGamePath = Q_strrchr( szGamePath, '\\' );
|
||||
pszEndGamePath[0] = 0;
|
||||
V_strcat_safe( szGamePath, "\\hl2" );
|
||||
sprintf( szSearchPath, "%s%s", szGamePath, pSurfacePropFilename );
|
||||
fp = g_pFullFileSystem->Open( szSearchPath, "rb" );
|
||||
}
|
||||
|
||||
int len = g_pFullFileSystem->Size( fp );
|
||||
|
||||
const char *szSurfacePropContents = new char[len+1];
|
||||
g_pFullFileSystem->Read( (void *)szSurfacePropContents, len, fp );
|
||||
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
vgui::Panel *pSurfacePropDropDown = FindChildByName( "surfacePropertyDropDown" );
|
||||
|
||||
//filling up the surface property dropdown
|
||||
while ( szSurfacePropContents )
|
||||
{
|
||||
szSurfacePropContents = ParseKeyvalue( szSurfacePropContents, key, value );
|
||||
((ComboBox *)pSurfacePropDropDown)->AddItem( key, NULL );
|
||||
while ( szSurfacePropContents )
|
||||
{
|
||||
szSurfacePropContents = ParseKeyvalue( szSurfacePropContents, key, value );
|
||||
if (!stricmp( key, "}" ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_QCInfo_t.SyncToControls();
|
||||
|
||||
m_pLODEdit = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CQCGenerator::~CQCGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
void CQCGenerator::OnCommand( const char *command )
|
||||
{
|
||||
if ( Q_stricmp( command, "createQC" ) == 0 )
|
||||
{
|
||||
m_QCInfo_t.SyncFromControls();
|
||||
GenerateQCFile();
|
||||
}
|
||||
if ( Q_stricmp( command, "deleteSeq" ) == 0 )
|
||||
{
|
||||
//delete it
|
||||
DeleteLOD();
|
||||
}
|
||||
if ( Q_stricmp( command, "editSeq" ) == 0 )
|
||||
{
|
||||
//edit
|
||||
EditLOD();
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( command );
|
||||
}
|
||||
|
||||
|
||||
void CQCGenerator::OnKeyCodeTyped( KeyCode code )
|
||||
{
|
||||
switch ( code )
|
||||
{
|
||||
case KEY_ENTER:
|
||||
EditLOD();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CQCGenerator::OnBrowse( KeyValues *data )
|
||||
{
|
||||
V_strcpy_safe( m_szTargetField, data->GetString( "targetField" ) );
|
||||
const char *filter = data->GetString( "filter" );
|
||||
|
||||
if ( Q_strlen( filter ) == 0 )
|
||||
{
|
||||
// BrowseDirectory( data );
|
||||
}
|
||||
else
|
||||
{
|
||||
BrowseFile( data );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
//This function is no longer used in the current version of the program.
|
||||
void CQCGenerator::BrowseDirectory( KeyValues *data )
|
||||
{
|
||||
DirectorySelectDialog *pDialog = new DirectorySelectDialog( this, "Select Directory" );
|
||||
pDialog->AddActionSignalTarget( this );
|
||||
pDialog->DoModal();
|
||||
pDialog->SetStartDirectory( data->GetString( "directory" ) );
|
||||
}
|
||||
*/
|
||||
|
||||
void CQCGenerator::BrowseFile( KeyValues *data )
|
||||
{
|
||||
const char *filter = data->GetString( "filter" );
|
||||
|
||||
FileOpenDialog *pDialog = new FileOpenDialog( this, "Select File", true );
|
||||
pDialog->AddFilter( filter, filter, true );
|
||||
pDialog->AddActionSignalTarget(this);
|
||||
pDialog->SetStartDirectory( data->GetString( "directory" ) );
|
||||
pDialog->DoModal( true );
|
||||
}
|
||||
|
||||
void CQCGenerator::OnFileSelected( KeyValues *data )
|
||||
{
|
||||
if ( m_szTargetField )
|
||||
{
|
||||
vgui::Panel *pTargetField = FindChildByName( m_szTargetField );
|
||||
((TextEntry *)pTargetField)->SetText( data->GetString( "fullpath" ) );
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void CQCGenerator::OnDirectorySelected( KeyValues *data )
|
||||
{
|
||||
if ( m_szTargetField )
|
||||
{
|
||||
vgui::Panel *pTargetField = FindChildByName( m_szTargetField );
|
||||
((TextEntry *)pTargetField)->SetText( data->GetString( "dir" ) );
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
bool CQCGenerator::GenerateQCFile()
|
||||
{
|
||||
//TODO: clean this up. Consider creating a datatype that includes the string to write out when the QC file is created
|
||||
char *nameBegin = strrchr( m_QCInfo_t.pszSMDPath, '\\' );
|
||||
|
||||
char szPath[MAX_PATH];
|
||||
char szName[MAX_PATH];
|
||||
Q_strncpy( szPath, m_QCInfo_t.pszSMDPath, nameBegin - m_QCInfo_t.pszSMDPath + 2 );
|
||||
V_strcpy_safe( szName, szPath);
|
||||
V_strcat_safe( szName, m_QCInfo_t.pszSceneName);
|
||||
V_strcat_safe( szName, ".qc" );
|
||||
FileHandle_t pSaveFile = g_pFullFileSystem->Open( szName, "wt" );
|
||||
if (!pSaveFile)
|
||||
{
|
||||
char szSaveError[1024] = "";
|
||||
Q_snprintf( szSaveError, 1024, "Save failed: invalid file name '%s'\n\nDirectory '%s' must exist.", szName, szPath );
|
||||
VGUIMessageBox( this, "QC Generator error", szSaveError );
|
||||
return 0;
|
||||
}
|
||||
|
||||
//write qc header
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "//\n// .qc file version 1.0\n\n");
|
||||
//write out modelname info
|
||||
char szModelName[MAX_PATH];
|
||||
char *modelStart = strrchrcount( szName, '\\', 2) + 1;
|
||||
char *modelEnd = strrchr( szName, '.' );
|
||||
Q_strncpy( szModelName, modelStart, modelEnd - modelStart + 1 );
|
||||
V_strcat_safe( szModelName, ".mdl" );
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$modelname %s\n\n", szModelName );
|
||||
//write out scale info
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$scale %f\n", m_QCInfo_t.fScale );
|
||||
//write out body info
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$body \"Body\" \"%s\"\n", strrchr( m_QCInfo_t.pszSMDPath, '\\' ) + 1 );
|
||||
|
||||
if ( m_QCInfo_t.bStaticProp == true )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$staticprop\n" );
|
||||
}
|
||||
|
||||
if ( m_QCInfo_t.bMostlyOpaque == true )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$mostlyopaque\n" );
|
||||
}
|
||||
|
||||
//write out surfaceprop info
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$surfaceprop \"%s\"\n\n", m_QCInfo_t.pszSurfaceProperty );
|
||||
//write materials
|
||||
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$cdmaterials %s\n\n", m_QCInfo_t.pszMaterialPath);
|
||||
|
||||
if ( m_QCInfo_t.bStaticProp || m_QCInfo_t.bNoAnimation )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "// --------- Animation sequences -------\n");
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$sequence \"idle\" \"%s\" fps 30\n\n", strrchr(m_QCInfo_t.pszSMDPath, '\\')+1);
|
||||
}
|
||||
|
||||
//write out lod info
|
||||
for( int i = 0; i < m_QCInfo_t.LODs.Count(); i++ )
|
||||
{
|
||||
LODInfo thisLOD = m_QCInfo_t.LODs.Element( i );
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$lod %d\n{\n\treplacemodel \"%s\" \"%s\"\n}\n\n", thisLOD.iLOD, strrchr(m_QCInfo_t.pszSMDPath, '\\')+1, thisLOD.pszFilename );
|
||||
}
|
||||
|
||||
if ( m_QCInfo_t.bDisableCollision != true )
|
||||
{
|
||||
//write out collision header
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "\n" );
|
||||
//write out collision info
|
||||
if ( m_QCInfo_t.bReferenceAsPhys == true )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$collisionmodel \"%s\"", strrchr( m_QCInfo_t.pszSMDPath, '\\' ) + 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( Q_strcmp( m_QCInfo_t.pszCollisionPath, "" ) )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$collisionmodel \"%s\"", strrchr( m_QCInfo_t.pszCollisionPath, '\\' ) + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, " {\n\t// Mass in kilograms\n ");
|
||||
|
||||
if ( m_QCInfo_t.bAutomass == true )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "\t$automass\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "\t$mass %f\n", m_QCInfo_t.fMass );
|
||||
}
|
||||
|
||||
if ( m_QCInfo_t.bConcave == true )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "\t$concave\n" );
|
||||
}
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "}\n\n");
|
||||
}
|
||||
|
||||
g_pFullFileSystem->Close( pSaveFile );
|
||||
|
||||
char szCommand[MAX_PATH];
|
||||
char szGamePath[MAX_PATH];
|
||||
|
||||
char studiomdlPath[512];
|
||||
g_pFullFileSystem->RelativePathToFullPath( "studiomdl.bat", NULL, studiomdlPath, sizeof( studiomdlPath ));
|
||||
|
||||
GetVConfigRegistrySetting( GAMEDIR_TOKEN, szGamePath, sizeof( szGamePath ) );
|
||||
|
||||
#ifdef WIN32
|
||||
STARTUPINFO startup;
|
||||
PROCESS_INFORMATION process;
|
||||
|
||||
|
||||
memset(&startup, 0, sizeof(startup));
|
||||
startup.cb = sizeof(startup);
|
||||
|
||||
|
||||
sprintf( szCommand, "%s -game %s %s", studiomdlPath, szGamePath, szName);
|
||||
bool bReturn = CreateProcess( NULL, szCommand, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &startup, &process);
|
||||
#else
|
||||
Assert( !"Implement me, why aren't we using a thread tool abstraction?" );
|
||||
bool bReturn = false;
|
||||
#endif
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
void CQCGenerator::InitializeSMDPaths( const char *pszPath, const char *pszScene )
|
||||
{
|
||||
V_strcpy_safe( m_QCInfo_t.pszSceneName, pszScene );
|
||||
|
||||
FileFindHandle_t *pFileHandle = new FileFindHandle_t();
|
||||
|
||||
g_pFullFileSystem->AddSearchPath( pszPath, "SMD_DIR" );
|
||||
|
||||
const char *filename = g_pFullFileSystem->FindFirst( "*.smd", pFileHandle );
|
||||
|
||||
bool bFoundReference = false;
|
||||
bool bFoundCollision = false;
|
||||
bool bFoundLOD = false;
|
||||
|
||||
//iterate through .smd files
|
||||
const char *startName = pszScene;
|
||||
|
||||
int nSearchLength = Q_strlen( pszScene );
|
||||
|
||||
int currentLOD = 1;
|
||||
|
||||
while( filename )
|
||||
{
|
||||
if ( !strncmp( startName, filename, nSearchLength ) )
|
||||
{
|
||||
const char *filenameEnd = filename + nSearchLength;
|
||||
if ( !strncmp( filenameEnd, "_ref", 4 ) || !strncmp( filenameEnd, ".smd", 4 ) )
|
||||
{
|
||||
bFoundReference = true;
|
||||
//we have found the reference smd.
|
||||
V_strcpy_safe( m_QCInfo_t.pszSMDPath, pszPath );
|
||||
V_strcat_safe( m_QCInfo_t.pszSMDPath, filename );
|
||||
}
|
||||
if ( !strncmp( filenameEnd, "_phy", 4) || !strncmp( filenameEnd, "_col", 4 ) )
|
||||
{
|
||||
bFoundCollision = true;
|
||||
//we have found the collision smd.
|
||||
V_strcpy_safe( m_QCInfo_t.pszCollisionPath, pszPath );
|
||||
V_strcat_safe( m_QCInfo_t.pszCollisionPath, filename );
|
||||
}
|
||||
if ( !strncmp( filenameEnd, "_lod", 4) )
|
||||
{
|
||||
bFoundLOD = true;
|
||||
//we found an LOD smd.
|
||||
char lodName[255];
|
||||
Q_snprintf( lodName, Q_strlen( lodName ), "lod%d", currentLOD );
|
||||
//we found an LOD
|
||||
KeyValues *newKv = new KeyValues( lodName, "SMD", filename, "LOD", "10" );
|
||||
m_pLODPanel->AddItem( newKv, currentLOD, false, false );
|
||||
currentLOD++;
|
||||
}
|
||||
}
|
||||
filename = g_pFullFileSystem->FindNext( *pFileHandle );
|
||||
}
|
||||
char pszMessage[2048] = "";
|
||||
char pszRefMessage[1024] = "";
|
||||
char pszColMessage[1024] = "";
|
||||
if (!bFoundReference )
|
||||
{
|
||||
V_strcat_safe( m_QCInfo_t.pszSMDPath, pszPath );
|
||||
V_strcat_safe( m_QCInfo_t.pszSMDPath, pszScene );
|
||||
V_strcat_safe( m_QCInfo_t.pszSMDPath, ".smd" );
|
||||
Q_snprintf( pszRefMessage, 1024, "Reference SMD not found.\n\nValid default reference SMDs are %s%s_ref*.smd and %s%s.smd\nUsing default of %s. Model will not compile.\n\n", pszPath, pszScene, pszPath, pszScene, m_QCInfo_t.pszSMDPath );
|
||||
}
|
||||
if ( !bFoundCollision )
|
||||
{
|
||||
Q_snprintf( pszColMessage, 1024, "Collision SMD not found.\n\nThe valid default collision SMD is %s%s_phy*.smd.\nUsing reference SMD as default.\n", pszPath, pszScene );
|
||||
V_strcpy_safe( m_QCInfo_t.pszCollisionPath, m_QCInfo_t.pszSMDPath );
|
||||
m_QCInfo_t.bReferenceAsPhys = true;
|
||||
}
|
||||
if ( !bFoundReference || !bFoundCollision)
|
||||
{
|
||||
V_strcpy_safe( pszMessage, pszRefMessage );
|
||||
V_strcat_safe( pszMessage, pszColMessage );
|
||||
VGUIMessageBox( this, "Error Initializing Paths", pszMessage );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CQCGenerator::DeleteLOD()
|
||||
{
|
||||
int numSelected = m_pLODPanel->GetSelectedItemsCount();
|
||||
int selected;
|
||||
for ( int i = numSelected-1; i >= 0; i-- )
|
||||
{
|
||||
selected = m_pLODPanel->GetSelectedItem( i );
|
||||
m_pLODPanel->RemoveItem( selected );
|
||||
}
|
||||
}
|
||||
|
||||
void CQCGenerator::EditLOD()
|
||||
{
|
||||
int numSelected = m_pLODPanel->GetSelectedItemsCount();
|
||||
if ( numSelected == 1 && !m_pLODPanel->IsInEditMode() )
|
||||
{
|
||||
if ( m_pLODEdit )
|
||||
{
|
||||
m_pLODEdit->MarkForDeletion();
|
||||
m_pLODEdit = NULL;
|
||||
}
|
||||
m_pLODEdit = new vgui::TextEntry( this, "Edit" );
|
||||
m_pLODEdit->SendNewLine( true );
|
||||
m_nSelectedSequence = m_pLODPanel->GetSelectedItem( 0 );
|
||||
m_nSelectedColumn = m_pLODPanel->GetSelectedColumn();
|
||||
m_pLODPanel->EnterEditMode( m_nSelectedSequence, m_nSelectedColumn, m_pLODEdit );
|
||||
}
|
||||
}
|
||||
|
||||
void CQCGenerator::OnNewLODText()
|
||||
{
|
||||
KeyValues *pEditItem = m_pLODPanel->GetItem( m_nSelectedSequence );
|
||||
KeyValues *pListItem = pEditItem;
|
||||
wchar_t szEditText[MAX_PATH];
|
||||
|
||||
pEditItem = pEditItem->GetFirstValue();
|
||||
const char *name = pEditItem->GetName();
|
||||
for( int i = 0; i < m_nSelectedColumn; i++ )
|
||||
{
|
||||
pEditItem = pEditItem->GetNextValue();
|
||||
name = pEditItem->GetName();
|
||||
}
|
||||
m_pLODEdit->GetText( szEditText, MAX_PATH );
|
||||
|
||||
pListItem->SetWString( name, szEditText );
|
||||
|
||||
m_pLODPanel->LeaveEditMode();
|
||||
m_pLODPanel->InvalidateLayout();
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "matsys_controls/assetpicker.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Asset Picker with no preview
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAssetPicker::CAssetPicker( vgui::Panel *pParent, const char *pAssetType,
|
||||
const char *pExt, const char *pSubDir, const char *pTextType ) :
|
||||
BaseClass( pParent, pAssetType, pExt, pSubDir, pTextType )
|
||||
{
|
||||
CreateStandardControls( this );
|
||||
LoadControlSettingsAndUserConfig( "resource/assetpicker.res" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: Modal picker frame
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CAssetPickerFrame::CAssetPickerFrame( vgui::Panel *pParent, const char *pTitle,
|
||||
const char *pAssetType, const char *pExt, const char *pSubDir, const char *pTextType ) :
|
||||
BaseClass( pParent )
|
||||
{
|
||||
SetAssetPicker( new CAssetPicker( this, pAssetType, pExt, pSubDir, pTextType ) );
|
||||
LoadControlSettingsAndUserConfig( "resource/assetpickerframe.res" );
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,200 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "matsys_controls/curveeditorpanel.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/IInput.h"
|
||||
#include "vgui/MouseCode.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CCurveEditorPanel::CCurveEditorPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
|
||||
{
|
||||
m_nSelectedPoint = -1;
|
||||
SetMouseInputEnabled( true );
|
||||
SetKeyBoardInputEnabled( true );
|
||||
m_nHighlightedPoint = -1;
|
||||
}
|
||||
|
||||
CCurveEditorPanel::~CCurveEditorPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Converts screen location to normalized values
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCurveEditorPanel::ScreenToValue( int x, int y, float *pIn, float *pOut )
|
||||
{
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
*pIn = (float)x / (w-1);
|
||||
*pOut = 1.0f - ((float)y / (h-1));
|
||||
}
|
||||
|
||||
void CCurveEditorPanel::ValueToScreen( float flIn, float flOut, int *x, int *y )
|
||||
{
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
*x = (int)(flIn * (w-1) + 0.5f);
|
||||
*y = (h-1) - (int)(flOut * (h-1) + 0.5f);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handle input
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCurveEditorPanel::OnMousePressed( vgui::MouseCode code )
|
||||
{
|
||||
BaseClass::OnMousePressed( code );
|
||||
|
||||
int x, y;
|
||||
input()->GetCursorPos( x, y );
|
||||
ScreenToLocal( x, y );
|
||||
|
||||
if ( code == MOUSE_LEFT )
|
||||
{
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
float flIn, flOut;
|
||||
ScreenToValue( x, y, &flIn, &flOut );
|
||||
float flTolerance = 5.0f / (w-1); // +/- 3 pixels to select the point
|
||||
m_nSelectedPoint = FindOrAddControlPoint( flIn, flTolerance, flOut );
|
||||
}
|
||||
}
|
||||
|
||||
void CCurveEditorPanel::OnMouseReleased( vgui::MouseCode code )
|
||||
{
|
||||
BaseClass::OnMouseReleased( code );
|
||||
|
||||
if ( code == MOUSE_LEFT )
|
||||
{
|
||||
m_nSelectedPoint = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void CCurveEditorPanel::OnCursorMoved( int x, int y )
|
||||
{
|
||||
BaseClass::OnCursorMoved( x, y );
|
||||
|
||||
float flIn, flOut;
|
||||
ScreenToValue( x, y, &flIn, &flOut );
|
||||
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
float flTolerance = 5.0f / (w-1); // +/- 3 pixels to select the point
|
||||
m_nHighlightedPoint = FindControlPoint( flIn, flTolerance );
|
||||
|
||||
if ( m_nSelectedPoint < 0 )
|
||||
return;
|
||||
m_nSelectedPoint = ModifyControlPoint( m_nSelectedPoint, flIn, flOut );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handles keypresses
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCurveEditorPanel::OnKeyCodePressed( vgui::KeyCode code )
|
||||
{
|
||||
BaseClass::OnKeyCodePressed( code );
|
||||
|
||||
if ( m_nSelectedPoint >= 0 )
|
||||
{
|
||||
RemoveControlPoint( m_nSelectedPoint );
|
||||
m_nSelectedPoint = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This paints the grid behind the curves
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCurveEditorPanel::PaintBackground( void )
|
||||
{
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
vgui::surface()->DrawSetColor( 255, 255, 255, 255 );
|
||||
vgui::surface()->DrawFilledRect( 0, 0, w, h );
|
||||
|
||||
vgui::surface()->DrawSetColor( 128, 128, 128, 255 );
|
||||
vgui::surface()->DrawLine( 0, h/4, w, h/4 );
|
||||
vgui::surface()->DrawLine( 0, h/2, w, h/2 );
|
||||
vgui::surface()->DrawLine( 0, 3*h/4, w, 3*h/4 );
|
||||
|
||||
vgui::surface()->DrawLine( w/4, 0, w/4, h );
|
||||
vgui::surface()->DrawLine( w/2, 0, w/2, h );
|
||||
vgui::surface()->DrawLine( 3*w/4, 0, 3*w/4, h );
|
||||
|
||||
vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
|
||||
vgui::surface()->DrawLine( 0, 0, w, 0 );
|
||||
vgui::surface()->DrawLine( w, 0, w, h );
|
||||
vgui::surface()->DrawLine( w, h, 0, h );
|
||||
vgui::surface()->DrawLine( 0, h, 0, 0 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the color curves operation to edit
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCurveEditorPanel::Paint( void )
|
||||
{
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
int x0 = 0, y0 = 0;
|
||||
|
||||
// FIXME: Add method to draw multiple lines DrawPolyLine connects the 1st and last points... bleah
|
||||
vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
|
||||
for ( int i = 0; i < w; ++i )
|
||||
{
|
||||
float flIn = (float)i / (w-1);
|
||||
float flOut = GetValue( flIn );
|
||||
int x = i;
|
||||
int y = (h-1) - (int)(flOut * (h-1) + 0.5f);
|
||||
y = clamp( y, 0, h-1 );
|
||||
|
||||
if ( i != 0 )
|
||||
{
|
||||
vgui::surface()->DrawLine( x0, y0, x, y );
|
||||
}
|
||||
|
||||
x0 = x; y0 = y;
|
||||
}
|
||||
|
||||
|
||||
// This will paint the control points
|
||||
// The currently selected one will be painted red and filled.
|
||||
for ( int i = ControlPointCount(); --i >= 0; )
|
||||
{
|
||||
float flIn, flOut;
|
||||
GetControlPoint( i, &flIn, &flOut );
|
||||
|
||||
int cx, cy;
|
||||
ValueToScreen( flIn, flOut, &cx, &cy );
|
||||
|
||||
if ( (i == m_nSelectedPoint) || ((m_nSelectedPoint == -1) && (i == m_nHighlightedPoint)) )
|
||||
{
|
||||
vgui::surface()->DrawSetColor( 255, 0, 0, 255 );
|
||||
vgui::surface()->DrawFilledRect( cx-3, cy-3, cx+3, cy+3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
|
||||
vgui::surface()->DrawOutlinedRect( cx-3, cy-3, cx+3, cy+3 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#if defined(WIN32) && !defined( _X360 )
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#undef PropertySheet
|
||||
|
||||
#include "matsys_controls/gamefiletreeview.h"
|
||||
#include "filesystem.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/Cursor.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// list of all tree view icons
|
||||
//-----------------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
IMAGE_FOLDER = 1,
|
||||
IMAGE_OPENFOLDER,
|
||||
IMAGE_FILE,
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CGameFileTreeView::CGameFileTreeView( Panel *parent, const char *name, const char *pRootFolderName, const char *pRootDir, const char *pExtension ) : BaseClass(parent, name), m_Images( false )
|
||||
{
|
||||
m_RootDir = pRootDir;
|
||||
|
||||
m_Ext = pExtension;
|
||||
m_bUseExt = ( pExtension != NULL );
|
||||
|
||||
m_RootFolderName = pRootFolderName;
|
||||
|
||||
// build our list of images
|
||||
m_Images.AddImage( scheme()->GetImage( "resource/icon_folder", false ) );
|
||||
m_Images.AddImage( scheme()->GetImage( "resource/icon_folder_selected", false ) );
|
||||
m_Images.AddImage( scheme()->GetImage( "resource/icon_file", false ) );
|
||||
SetImageList( &m_Images, false );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Refreshes the active file list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::RefreshFileList()
|
||||
{
|
||||
RemoveAll();
|
||||
SetFgColor(Color(216, 222, 211, 255));
|
||||
|
||||
// add the base node
|
||||
KeyValues *pkv = new KeyValues( "root" );
|
||||
pkv->SetString( "text", m_RootFolderName );
|
||||
pkv->SetInt( "root", 1 );
|
||||
pkv->SetInt( "expand", 1 );
|
||||
int iRoot = AddItem( pkv, GetRootItemIndex() );
|
||||
pkv->deleteThis();
|
||||
ExpandItem( iRoot, true );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Selects the root folder
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::SelectRoot()
|
||||
{
|
||||
AddSelectedItem( GetRootItemIndex(), true );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the number of root directories
|
||||
//-----------------------------------------------------------------------------
|
||||
int CGameFileTreeView::GetRootDirectoryCount()
|
||||
{
|
||||
return GetNumChildren( GetRootItemIndex() );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the ith root directory
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CGameFileTreeView::GetRootDirectory( int nIndex )
|
||||
{
|
||||
int nItemIndex = GetChild( GetRootItemIndex(), nIndex );
|
||||
KeyValues *kv = GetItemData( nItemIndex );
|
||||
if ( !kv )
|
||||
return NULL;
|
||||
return kv->GetString( "path", NULL );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populate the root node (necessary since tree view can't have multiple roots)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::PopulateRootNode( int itemIndex )
|
||||
{
|
||||
AddDirectoriesOfNode( itemIndex, m_RootDir );
|
||||
|
||||
if ( m_bUseExt )
|
||||
{
|
||||
AddFilesOfNode( itemIndex, m_RootDir, m_Ext );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populate the root node with directories
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CGameFileTreeView::DoesDirectoryHaveSubdirectories( const char *pFilePath )
|
||||
{
|
||||
char pSearchString[MAX_PATH];
|
||||
Q_snprintf( pSearchString, MAX_PATH, "%s\\*", pFilePath );
|
||||
|
||||
// get the list of files
|
||||
FileFindHandle_t findHandle;
|
||||
|
||||
// generate children
|
||||
// add all the items
|
||||
const char *pszFileName = g_pFullFileSystem->FindFirstEx( pSearchString, "GAME", &findHandle );
|
||||
while ( pszFileName )
|
||||
{
|
||||
bool bIsDirectory = g_pFullFileSystem->FindIsDirectory( findHandle );
|
||||
if ( bIsDirectory && Q_strnicmp( pszFileName, ".", 2 ) && Q_strnicmp( pszFileName, "..", 3 ) )
|
||||
return true;
|
||||
|
||||
pszFileName = g_pFullFileSystem->FindNext( findHandle );
|
||||
}
|
||||
|
||||
g_pFullFileSystem->FindClose( findHandle );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populate the root node with directories
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::AddDirectoriesOfNode( int itemIndex, const char *pFilePath )
|
||||
{
|
||||
char pSearchString[MAX_PATH];
|
||||
Q_snprintf( pSearchString, MAX_PATH, "%s\\*", pFilePath );
|
||||
|
||||
// get the list of files
|
||||
FileFindHandle_t findHandle;
|
||||
|
||||
// generate children
|
||||
// add all the items
|
||||
const char *pszFileName = g_pFullFileSystem->FindFirstEx( pSearchString, "GAME", &findHandle );
|
||||
while ( pszFileName )
|
||||
{
|
||||
bool bIsDirectory = g_pFullFileSystem->FindIsDirectory( findHandle );
|
||||
if ( bIsDirectory && Q_strnicmp( pszFileName, ".", 2 ) && Q_strnicmp( pszFileName, "..", 3 ) )
|
||||
{
|
||||
KeyValues *kv = new KeyValues( "node", "text", pszFileName );
|
||||
|
||||
char pFullPath[MAX_PATH];
|
||||
Q_snprintf( pFullPath, sizeof(pFullPath), "%s/%s", pFilePath, pszFileName );
|
||||
Q_FixSlashes( pFullPath );
|
||||
Q_strlower( pFullPath );
|
||||
bool bHasSubdirectories = DoesDirectoryHaveSubdirectories( pFullPath );
|
||||
kv->SetString( "path", pFullPath );
|
||||
|
||||
kv->SetInt( "expand", bHasSubdirectories );
|
||||
kv->SetInt( "dir", 1 );
|
||||
kv->SetInt( "image", IMAGE_FOLDER );
|
||||
|
||||
int itemID = AddItem(kv, itemIndex);
|
||||
kv->deleteThis();
|
||||
|
||||
// mark directories in orange
|
||||
SetItemColorForDirectories( itemID );
|
||||
}
|
||||
|
||||
pszFileName = g_pFullFileSystem->FindNext( findHandle );
|
||||
}
|
||||
|
||||
g_pFullFileSystem->FindClose( findHandle );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populate the root node with files
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::AddFilesOfNode( int itemIndex, const char *pFilePath, const char *pExt )
|
||||
{
|
||||
char pSearchString[MAX_PATH];
|
||||
Q_snprintf( pSearchString, MAX_PATH, "%s\\*.%s", pFilePath, pExt );
|
||||
|
||||
// get the list of files
|
||||
FileFindHandle_t findHandle;
|
||||
|
||||
// generate children
|
||||
// add all the items
|
||||
const char *pszFileName = g_pFullFileSystem->FindFirst( pSearchString, &findHandle );
|
||||
while ( pszFileName )
|
||||
{
|
||||
if ( !g_pFullFileSystem->FindIsDirectory( findHandle ) )
|
||||
{
|
||||
KeyValues *kv = new KeyValues( "node", "text", pszFileName );
|
||||
|
||||
char pFullPath[MAX_PATH];
|
||||
Q_snprintf( pFullPath, MAX_PATH, "%s\\%s", pFilePath, pszFileName );
|
||||
kv->SetString( "path", pFullPath );
|
||||
kv->SetInt( "image", IMAGE_FILE );
|
||||
|
||||
AddItem(kv, itemIndex);
|
||||
kv->deleteThis();
|
||||
}
|
||||
|
||||
pszFileName = g_pFullFileSystem->FindNext( findHandle );
|
||||
}
|
||||
|
||||
g_pFullFileSystem->FindClose( findHandle );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// override to incremental request and show p4 directories
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::GenerateChildrenOfNode(int itemIndex)
|
||||
{
|
||||
KeyValues *pkv = GetItemData(itemIndex);
|
||||
if ( pkv->GetInt("root") )
|
||||
{
|
||||
PopulateRootNode( itemIndex );
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pkv->GetInt("dir"))
|
||||
return;
|
||||
|
||||
const char *pFilePath = pkv->GetString("path", "");
|
||||
if (!pFilePath[0])
|
||||
return;
|
||||
|
||||
surface()->SetCursor(dc_waitarrow);
|
||||
|
||||
AddDirectoriesOfNode( itemIndex, pFilePath );
|
||||
|
||||
if ( m_bUseExt )
|
||||
{
|
||||
AddFilesOfNode( itemIndex, pFilePath, m_Ext );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// setup a context menu whenever a directory is clicked on
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::GenerateContextMenu( int itemIndex, int x, int y )
|
||||
{
|
||||
return;
|
||||
|
||||
/*
|
||||
KeyValues *pkv = GetItemData(itemIndex);
|
||||
const char *pFilePath = pkv->GetString("path", "");
|
||||
if (!pFilePath[0])
|
||||
return;
|
||||
|
||||
Menu *pContext = new Menu(this, "FileContext");
|
||||
pContext->AddMenuItem("Cloak folder", new KeyValues("CloakFolder", "item", itemIndex), GetParent(), NULL);
|
||||
|
||||
// show the context menu
|
||||
pContext->SetPos(x, y);
|
||||
pContext->SetVisible(true);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets an item to be colored as if its a menu
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::SetItemColorForDirectories( int itemID )
|
||||
{
|
||||
// mark directories in orange
|
||||
SetItemFgColor( itemID, Color(224, 192, 0, 255) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// setup a smaller font
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::ApplySchemeSettings(IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
SetFont( pScheme->GetFont("DefaultSmall") );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "matsys_controls/manipulator.h"
|
||||
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
|
||||
#include "vgui/IVGui.h"
|
||||
#include "vgui/IInput.h"
|
||||
#include "vgui/ISystem.h"
|
||||
#include "vgui/MouseCode.h"
|
||||
|
||||
#include "mathlib/vector.h"
|
||||
#include "mathlib/vmatrix.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// local helper functions
|
||||
//-----------------------------------------------------------------------------
|
||||
static float UpdateTime( float &flLastTime )
|
||||
{
|
||||
float flTime = vgui::system()->GetFrameTime();
|
||||
float dt = flTime - flLastTime;
|
||||
flLastTime = flTime;
|
||||
return dt;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Base class for manipulators which operate on transforms
|
||||
//-----------------------------------------------------------------------------
|
||||
CTransformManipulator::CTransformManipulator( matrix3x4_t *pTransform ) :
|
||||
m_pTransform( pTransform )
|
||||
{
|
||||
}
|
||||
|
||||
void CTransformManipulator::SetTransform( matrix3x4_t *pTransform )
|
||||
{
|
||||
m_pTransform = pTransform;
|
||||
}
|
||||
|
||||
matrix3x4_t *CTransformManipulator::GetTransform( void )
|
||||
{
|
||||
return m_pTransform;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CPotteryWheelManip - nendo-style camera manipulator
|
||||
//-----------------------------------------------------------------------------
|
||||
CPotteryWheelManip::CPotteryWheelManip( matrix3x4_t *pTransform ) :
|
||||
CTransformManipulator( pTransform ),
|
||||
m_lastx( -1 ), m_lasty( -1 ),
|
||||
m_zoom( 100.0f ), m_altitude( 0.0f ), m_azimuth( 0.0f ),
|
||||
m_prevZoom( 100.0f ), m_prevAltitude( 0.0f ), m_prevAzimuth( 0.0f ),
|
||||
m_flLastMouseTime( 0.0f ), m_flLastTickTime( 0.0f ),
|
||||
m_flSpin( 0.0f ), m_bSpin( false )
|
||||
{
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnBeginManipulation( void )
|
||||
{
|
||||
m_prevZoom = m_zoom;
|
||||
m_prevAltitude = m_altitude;
|
||||
m_prevAzimuth = m_azimuth;
|
||||
m_flLastMouseTime = m_flLastTickTime = vgui::system()->GetFrameTime();
|
||||
m_flSpin = 0.0f;
|
||||
m_bSpin = false;
|
||||
}
|
||||
|
||||
// Sets the zoom level
|
||||
void CPotteryWheelManip::SetZoom( float flZoom )
|
||||
{
|
||||
m_prevZoom = m_zoom = flZoom;
|
||||
}
|
||||
|
||||
|
||||
void CPotteryWheelManip::OnAcceptManipulation( void )
|
||||
{
|
||||
m_flSpin = 0.0f;
|
||||
m_bSpin = false;
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnCancelManipulation( void )
|
||||
{
|
||||
m_zoom = m_prevZoom;
|
||||
m_altitude = m_prevAltitude;
|
||||
m_azimuth = m_prevAzimuth;
|
||||
m_flSpin = 0.0f;
|
||||
m_bSpin = false;
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
|
||||
void CPotteryWheelManip::OnTick( void )
|
||||
{
|
||||
float dt = UpdateTime( m_flLastTickTime );
|
||||
|
||||
if ( m_bSpin )
|
||||
{
|
||||
m_azimuth += dt * m_flSpin;
|
||||
UpdateTransform();
|
||||
}
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnCursorMoved( int x, int y )
|
||||
{
|
||||
float dt = UpdateTime( m_flLastMouseTime );
|
||||
|
||||
if ( m_bSpin )
|
||||
{
|
||||
m_lastx = x;
|
||||
m_lasty = y;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( input()->IsMouseDown( MOUSE_MIDDLE ) )
|
||||
{
|
||||
int dy = y - m_lasty;
|
||||
int dx = x - m_lastx;
|
||||
|
||||
if ( abs( dx ) < 2 * abs( dy ) )
|
||||
{
|
||||
UpdateZoom( 0.2f * dy );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flSpin = (dt != 0.0f) ? 0.002f * dx / dt : 0.0f;
|
||||
m_azimuth += 0.002f * dx;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_azimuth += 0.002f * ( x - m_lastx );
|
||||
m_altitude -= 0.002f * ( y - m_lasty );
|
||||
m_altitude = max( (float)-M_PI/2, min( (float)M_PI/2, m_altitude ) );
|
||||
}
|
||||
m_lastx = x;
|
||||
m_lasty = y;
|
||||
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnMousePressed( vgui::MouseCode code, int x, int y )
|
||||
{
|
||||
UpdateTime( m_flLastMouseTime );
|
||||
m_lastx = x;
|
||||
m_lasty = y;
|
||||
m_bSpin = false;
|
||||
m_flSpin = 0.0f;
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnMouseReleased( vgui::MouseCode code, int x, int y )
|
||||
{
|
||||
UpdateTime( m_flLastMouseTime );
|
||||
|
||||
if ( code == MOUSE_MIDDLE )
|
||||
{
|
||||
m_bSpin = ( fabs( m_flSpin ) > 1.0f );
|
||||
}
|
||||
|
||||
m_lastx = x;
|
||||
m_lasty = y;
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnMouseWheeled( int delta )
|
||||
{
|
||||
UpdateTime( m_flLastMouseTime );
|
||||
|
||||
UpdateZoom( -10.0f * delta );
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::UpdateTransform()
|
||||
{
|
||||
if ( !m_pTransform )
|
||||
return;
|
||||
|
||||
float y = m_zoom * sin( m_altitude );
|
||||
float xz = m_zoom * cos( m_altitude );
|
||||
float x = xz * sin( m_azimuth );
|
||||
float z = xz * cos( m_azimuth );
|
||||
|
||||
Vector position(x, y, z);
|
||||
AngleMatrix( RadianEuler( -m_altitude, m_azimuth, 0 ), position, *m_pTransform );
|
||||
}
|
||||
|
||||
|
||||
void CPotteryWheelManip::UpdateZoom( float delta )
|
||||
{
|
||||
m_zoom *= pow( 1.01f, delta );
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// MATSYS_CONTROLS.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$macro SRCDIR "..\.."
|
||||
|
||||
$include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
|
||||
|
||||
$Project "matsys_controls"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "assetpicker.cpp"
|
||||
$File "baseassetpicker.cpp"
|
||||
$File "colorpickerpanel.cpp"
|
||||
$File "curveeditorpanel.cpp"
|
||||
$File "gamefiletreeview.cpp"
|
||||
$File "manipulator.cpp"
|
||||
$File "matsyscontrols.cpp"
|
||||
$File "mdlpanel.cpp"
|
||||
$File "mdlpicker.cpp"
|
||||
$File "mdlsequencepicker.cpp"
|
||||
$File "picker.cpp"
|
||||
$File "potterywheelpanel.cpp"
|
||||
$File "proceduraltexturepanel.cpp"
|
||||
$File "QCGenerator.cpp"
|
||||
$File "sequencepicker.cpp"
|
||||
$File "tgapreviewpanel.cpp"
|
||||
$File "vmtpicker.cpp"
|
||||
$File "vmtpreviewpanel.cpp"
|
||||
$File "vtfpicker.cpp"
|
||||
$File "vtfpreviewpanel.cpp"
|
||||
$File "vmtpanel.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\matsys_controls\assetpicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\baseassetpicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\colorpickerpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\gamefiletreeview.h"
|
||||
$File "$SRCDIR\public\matsys_controls\manipulator.h"
|
||||
$File "$SRCDIR\public\matsys_controls\matsyscontrols.h"
|
||||
$File "$SRCDIR\public\matsys_controls\mdlpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\mdlpicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\mdlsequencepicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\picker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\potterywheelpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\proceduraltexturepanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\QCGenerator.h"
|
||||
$File "$SRCDIR\public\matsys_controls\sequencepicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\tgapreviewpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\vmtpicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\vmtpreviewpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\vtfpicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\vtfpreviewpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\vmtpanel.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib bitmap [$WIN32]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include <materialsystem/imaterialsystem.h>
|
||||
#include <materialsystem/imaterialsystemhardwareconfig.h>
|
||||
#include <datacache/imdlcache.h>
|
||||
#include <VGuiMatSurface/IMatSystemSurface.h>
|
||||
#include <istudiorender.h>
|
||||
#include "vgui_controls/Controls.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
|
||||
IMaterialSystem *g_pMaterialSystem = NULL;
|
||||
IMaterialSystem *MaterialSystem()
|
||||
{
|
||||
return g_pMaterialSystem;
|
||||
}
|
||||
|
||||
IMaterialSystemHardwareConfig *g_pMaterialSystemHardwareConfig = NULL;
|
||||
IMaterialSystemHardwareConfig *MaterialSystemHardwareConfig()
|
||||
{
|
||||
return g_pMaterialSystemHardwareConfig;
|
||||
}
|
||||
|
||||
IMDLCache *g_pMDLCache = NULL;
|
||||
IMDLCache *MDLCache()
|
||||
{
|
||||
return g_pMDLCache;
|
||||
}
|
||||
|
||||
IMatSystemSurface *g_pMatSystemSurface = NULL;
|
||||
IMatSystemSurface *MatSystemSurface()
|
||||
{
|
||||
return g_pMatSystemSurface;
|
||||
}
|
||||
|
||||
IStudioRender *g_pStudioRender = NULL;
|
||||
IStudioRender *StudioRender()
|
||||
{
|
||||
return g_pStudioRender;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: finds a particular interface in the factory set
|
||||
//-----------------------------------------------------------------------------
|
||||
static void *InitializeInterface( char const *interfaceName, CreateInterfaceFn *factoryList, int numFactories )
|
||||
{
|
||||
void *retval;
|
||||
|
||||
for ( int i = 0; i < numFactories; i++ )
|
||||
{
|
||||
CreateInterfaceFn factory = factoryList[ i ];
|
||||
if ( !factory )
|
||||
continue;
|
||||
|
||||
retval = factory( interfaceName, NULL );
|
||||
if ( retval )
|
||||
return retval;
|
||||
}
|
||||
|
||||
// No provider for requested interface!!!
|
||||
// Assert( !"No provider for requested interface!!!" );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Initializes the controls
|
||||
//-----------------------------------------------------------------------------
|
||||
bool VGui_InitMatSysInterfacesList( const char *moduleName, CreateInterfaceFn *factoryList, int numFactories )
|
||||
{
|
||||
if ( !vgui::VGui_InitInterfacesList( moduleName, factoryList, numFactories ) )
|
||||
return false;
|
||||
|
||||
g_pMaterialSystem = (IMaterialSystem *)InitializeInterface( MATERIAL_SYSTEM_INTERFACE_VERSION, factoryList, numFactories );
|
||||
g_pMatSystemSurface = (IMatSystemSurface *)InitializeInterface( MAT_SYSTEM_SURFACE_INTERFACE_VERSION, factoryList, numFactories );
|
||||
g_pMDLCache = (IMDLCache *)InitializeInterface( MDLCACHE_INTERFACE_VERSION, factoryList, numFactories );
|
||||
g_pStudioRender = (IStudioRender *)InitializeInterface( STUDIO_RENDER_INTERFACE_VERSION, factoryList, numFactories );
|
||||
g_pMaterialSystemHardwareConfig = (IMaterialSystemHardwareConfig *)InitializeInterface( MATERIALSYSTEM_HARDWARECONFIG_INTERFACE_VERSION, factoryList, numFactories );
|
||||
|
||||
// MDL cache + studiorender are optional
|
||||
return ( g_pMaterialSystem && g_pMatSystemSurface && g_pMaterialSystemHardwareConfig );
|
||||
}
|
||||
|
||||
|
||||
} // namespace vgui
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,902 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "matsys_controls/mdlpanel.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/imaterialsystemhardwareconfig.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui_controls/Frame.h"
|
||||
#include "tier1/convar.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier1/fmtstr.h"
|
||||
#include "istudiorender.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "vcollide.h"
|
||||
#include "vcollide_parse.h"
|
||||
#include "bone_setup.h"
|
||||
#include "vphysics_interface.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
DECLARE_BUILD_FACTORY( CMDLPanel );
|
||||
|
||||
static const int THUMBNAIL_SAFE_ZONE_SIZE = 512;
|
||||
static const int THUMBNAIL_SAFE_ZONE_HEIGHT = 92;
|
||||
static const float THUMBNAIL_SAFE_ZONE_HEIGHT_SCALE = (float)THUMBNAIL_SAFE_ZONE_HEIGHT / THUMBNAIL_SAFE_ZONE_SIZE;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Keeps a global clock to autoplay sequences to run from
|
||||
// Also deals with speedScale changes
|
||||
//-----------------------------------------------------------------------------
|
||||
float GetAutoPlayTime( void )
|
||||
{
|
||||
static int g_prevTicks;
|
||||
static float g_time;
|
||||
|
||||
int ticks = Plat_MSTime();
|
||||
|
||||
// limit delta so that float time doesn't overflow
|
||||
if (g_prevTicks == 0)
|
||||
{
|
||||
g_prevTicks = ticks;
|
||||
}
|
||||
|
||||
g_time += ( ticks - g_prevTicks ) / 1000.0f;
|
||||
g_prevTicks = ticks;
|
||||
|
||||
return g_time;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMDLPanel::CMDLPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
|
||||
{
|
||||
SetVisible( true );
|
||||
|
||||
// Used to poll input
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||||
|
||||
// Deal with the default cubemap
|
||||
ITexture *pCubemapTexture = vgui::MaterialSystem()->FindTexture( "editor/cubemap", NULL, true );
|
||||
m_DefaultEnvCubemap.Init( pCubemapTexture );
|
||||
pCubemapTexture = vgui::MaterialSystem()->FindTexture( "editor/cubemap.hdr", NULL, true );
|
||||
m_DefaultHDREnvCubemap.Init( pCubemapTexture );
|
||||
|
||||
SetIdentityMatrix( m_RootMDL.m_MDLToWorld );
|
||||
m_bDrawCollisionModel = false;
|
||||
m_bWireFrame = false;
|
||||
m_bGroundGrid = false;
|
||||
m_bLockView = false;
|
||||
m_bLookAtCamera = true;
|
||||
m_bThumbnailSafeZone = false;
|
||||
m_nNumSequenceLayers = 0;
|
||||
ResetAnimationEventState( &m_EventState );
|
||||
}
|
||||
|
||||
CMDLPanel::~CMDLPanel()
|
||||
{
|
||||
m_aMergeMDLs.Purge();
|
||||
m_DefaultEnvCubemap.Shutdown( );
|
||||
m_DefaultHDREnvCubemap.Shutdown();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scheme settings
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
SetBackgroundColor( GetBgColor() );
|
||||
SetBorder( pScheme->GetBorder( "MenuBorder") );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Rendering options
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::SetCollsionModel( bool bVisible )
|
||||
{
|
||||
m_bDrawCollisionModel = bVisible;
|
||||
}
|
||||
|
||||
void CMDLPanel::SetGroundGrid( bool bVisible )
|
||||
{
|
||||
m_bGroundGrid = bVisible;
|
||||
}
|
||||
|
||||
void CMDLPanel::SetWireFrame( bool bVisible )
|
||||
{
|
||||
m_bWireFrame = bVisible;
|
||||
}
|
||||
|
||||
void CMDLPanel::SetLockView( bool bLocked )
|
||||
{
|
||||
m_bLockView = bLocked;
|
||||
}
|
||||
|
||||
void CMDLPanel::SetLookAtCamera( bool bLookAtCamera )
|
||||
{
|
||||
m_bLookAtCamera = bLookAtCamera;
|
||||
}
|
||||
|
||||
void CMDLPanel::SetIgnoreDoubleClick( bool bState )
|
||||
{
|
||||
m_bIgnoreDoubleClick = bState;
|
||||
}
|
||||
|
||||
void CMDLPanel::SetThumbnailSafeZone( bool bVisible )
|
||||
{
|
||||
m_bThumbnailSafeZone = bVisible;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Stores the clip
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::SetMDL( MDLHandle_t handle, void *pProxyData )
|
||||
{
|
||||
m_RootMDL.m_MDL.SetMDL( handle );
|
||||
m_RootMDL.m_MDL.m_pProxyData = pProxyData;
|
||||
|
||||
Vector vecMins, vecMaxs;
|
||||
GetMDLBoundingBox( &vecMins, &vecMaxs, handle, m_RootMDL.m_MDL.m_nSequence );
|
||||
|
||||
m_RootMDL.m_MDL.m_bWorldSpaceViewTarget = false;
|
||||
m_RootMDL.m_MDL.m_vecViewTarget.Init( 100.0f, 0.0f, vecMaxs.z );
|
||||
|
||||
m_RootMDL.m_flCycleStartTime = 0.f;
|
||||
|
||||
// Set the pose parameters to the default for the mdl
|
||||
SetPoseParameters( NULL, 0 );
|
||||
|
||||
// Clear any sequence layers
|
||||
SetSequenceLayers( NULL, 0 );
|
||||
|
||||
ResetAnimationEventState( &m_EventState );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// An MDL was selected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::SetMDL( const char *pMDLName, void *pProxyData )
|
||||
{
|
||||
MDLHandle_t hMDLFindResult = vgui::MDLCache()->FindMDL( pMDLName );
|
||||
MDLHandle_t hMDL = pMDLName ? hMDLFindResult : MDLHANDLE_INVALID;
|
||||
if ( vgui::MDLCache()->IsErrorModel( hMDL ) )
|
||||
{
|
||||
hMDL = MDLHANDLE_INVALID;
|
||||
}
|
||||
|
||||
SetMDL( hMDL, pProxyData );
|
||||
|
||||
// FindMDL takes a reference and the the CMDL will also hold a reference for as long as it sticks around. Release the FindMDL reference.
|
||||
int nRef = vgui::MDLCache()->Release( hMDLFindResult );
|
||||
(void)nRef; // Avoid unreferenced variable warning
|
||||
AssertMsg( hMDL == MDLHANDLE_INVALID || nRef > 0, "CMDLPanel::SetMDL referenced a model that has a zero ref count." );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns a model bounding box.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMDLPanel::GetBoundingBox( Vector &vecBoundsMin, Vector &vecBoundsMax )
|
||||
{
|
||||
// Check to see if we have a valid model to look at.
|
||||
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID )
|
||||
return false;
|
||||
|
||||
GetMDLBoundingBox( &vecBoundsMin, &vecBoundsMax, m_RootMDL.m_MDL.GetMDL(), m_RootMDL.m_MDL.m_nSequence );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns a more accurate bounding sphere
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMDLPanel::GetBoundingSphere( Vector &vecCenter, float &flRadius )
|
||||
{
|
||||
// Check to see if we have a valid model to look at.
|
||||
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID )
|
||||
return false;
|
||||
|
||||
Vector vecEngineCenter;
|
||||
GetMDLBoundingSphere( &vecEngineCenter, &flRadius, m_RootMDL.m_MDL.GetMDL(), m_RootMDL.m_MDL.m_nSequence );
|
||||
VectorTransform( vecEngineCenter, m_RootMDL.m_MDLToWorld, vecCenter );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::SetModelAnglesAndPosition( const QAngle &angRot, const Vector &vecPos )
|
||||
{
|
||||
SetIdentityMatrix( m_RootMDL.m_MDLToWorld );
|
||||
AngleMatrix( angRot, vecPos, m_RootMDL.m_MDLToWorld );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the camera to look at the model
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::LookAtMDL()
|
||||
{
|
||||
// Check to see if we have a valid model to look at.
|
||||
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID )
|
||||
return;
|
||||
|
||||
if ( m_bLockView )
|
||||
return;
|
||||
|
||||
float flRadius;
|
||||
Vector vecCenter;
|
||||
GetBoundingSphere( vecCenter, flRadius );
|
||||
LookAt( vecCenter, flRadius );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FIXME: This should be moved into studiorender
|
||||
//-----------------------------------------------------------------------------
|
||||
static ConVar r_showenvcubemap( "r_showenvcubemap", "0", FCVAR_CHEAT );
|
||||
static ConVar r_eyegloss ( "r_eyegloss", "1", FCVAR_ARCHIVE ); // wet eyes
|
||||
static ConVar r_eyemove ( "r_eyemove", "1", FCVAR_ARCHIVE ); // look around
|
||||
static ConVar r_eyeshift_x ( "r_eyeshift_x", "0", FCVAR_ARCHIVE ); // eye X position
|
||||
static ConVar r_eyeshift_y ( "r_eyeshift_y", "0", FCVAR_ARCHIVE ); // eye Y position
|
||||
static ConVar r_eyeshift_z ( "r_eyeshift_z", "0", FCVAR_ARCHIVE ); // eye Z position
|
||||
static ConVar r_eyesize ( "r_eyesize", "0", FCVAR_ARCHIVE ); // adjustment to iris textures
|
||||
static ConVar mat_softwareskin( "mat_softwareskin", "0", FCVAR_CHEAT );
|
||||
static ConVar r_nohw ( "r_nohw", "0", FCVAR_CHEAT );
|
||||
static ConVar r_nosw ( "r_nosw", "0", FCVAR_CHEAT );
|
||||
static ConVar r_teeth ( "r_teeth", "1" );
|
||||
static ConVar r_drawentities ( "r_drawentities", "1", FCVAR_CHEAT );
|
||||
static ConVar r_flex ( "r_flex", "1" );
|
||||
static ConVar r_eyes ( "r_eyes", "1" );
|
||||
static ConVar r_skin ( "r_skin","0", FCVAR_CHEAT );
|
||||
static ConVar r_maxmodeldecal ( "r_maxmodeldecal", "50" );
|
||||
static ConVar r_modelwireframedecal ( "r_modelwireframedecal", "0", FCVAR_CHEAT );
|
||||
static ConVar mat_normals ( "mat_normals", "0", FCVAR_CHEAT );
|
||||
static ConVar r_eyeglintlodpixels ( "r_eyeglintlodpixels", "0", FCVAR_CHEAT );
|
||||
static ConVar r_rootlod ( "r_rootlod", "0" );
|
||||
|
||||
static StudioRenderConfig_t s_StudioRenderConfig;
|
||||
|
||||
void CMDLPanel::UpdateStudioRenderConfig( void )
|
||||
{
|
||||
memset( &s_StudioRenderConfig, 0, sizeof(s_StudioRenderConfig) );
|
||||
|
||||
s_StudioRenderConfig.bEyeMove = !!r_eyemove.GetInt();
|
||||
s_StudioRenderConfig.fEyeShiftX = r_eyeshift_x.GetFloat();
|
||||
s_StudioRenderConfig.fEyeShiftY = r_eyeshift_y.GetFloat();
|
||||
s_StudioRenderConfig.fEyeShiftZ = r_eyeshift_z.GetFloat();
|
||||
s_StudioRenderConfig.fEyeSize = r_eyesize.GetFloat();
|
||||
if( mat_softwareskin.GetInt() || m_bWireFrame )
|
||||
{
|
||||
s_StudioRenderConfig.bSoftwareSkin = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_StudioRenderConfig.bSoftwareSkin = false;
|
||||
}
|
||||
s_StudioRenderConfig.bNoHardware = !!r_nohw.GetInt();
|
||||
s_StudioRenderConfig.bNoSoftware = !!r_nosw.GetInt();
|
||||
s_StudioRenderConfig.bTeeth = !!r_teeth.GetInt();
|
||||
s_StudioRenderConfig.drawEntities = r_drawentities.GetInt();
|
||||
s_StudioRenderConfig.bFlex = !!r_flex.GetInt();
|
||||
s_StudioRenderConfig.bEyes = !!r_eyes.GetInt();
|
||||
s_StudioRenderConfig.bWireframe = m_bWireFrame;
|
||||
s_StudioRenderConfig.bDrawNormals = mat_normals.GetBool();
|
||||
s_StudioRenderConfig.skin = r_skin.GetInt();
|
||||
s_StudioRenderConfig.maxDecalsPerModel = r_maxmodeldecal.GetInt();
|
||||
s_StudioRenderConfig.bWireframeDecals = r_modelwireframedecal.GetInt() != 0;
|
||||
|
||||
s_StudioRenderConfig.fullbright = false;
|
||||
s_StudioRenderConfig.bSoftwareLighting = false;
|
||||
|
||||
s_StudioRenderConfig.bShowEnvCubemapOnly = r_showenvcubemap.GetInt() ? true : false;
|
||||
s_StudioRenderConfig.fEyeGlintPixelWidthLODThreshold = r_eyeglintlodpixels.GetFloat();
|
||||
|
||||
StudioRender()->UpdateConfig( s_StudioRenderConfig );
|
||||
}
|
||||
|
||||
void CMDLPanel::DrawCollisionModel()
|
||||
{
|
||||
vcollide_t *pCollide = MDLCache()->GetVCollide( m_RootMDL.m_MDL.GetMDL() );
|
||||
|
||||
if ( !pCollide || pCollide->solidCount <= 0 )
|
||||
return;
|
||||
|
||||
static color32 color = {255,0,0,0};
|
||||
|
||||
IVPhysicsKeyParser *pParser = g_pPhysicsCollision->VPhysicsKeyParserCreate( pCollide->pKeyValues );
|
||||
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_RootMDL.m_MDL.GetMDL() ), g_pMDLCache );
|
||||
|
||||
matrix3x4_t pBoneToWorld[MAXSTUDIOBONES];
|
||||
m_RootMDL.m_MDL.SetUpBones( m_RootMDL.m_MDLToWorld, MAXSTUDIOBONES, pBoneToWorld );
|
||||
|
||||
// PERFORMANCE: Just parse the script each frame. It's fast enough for tools. If you need
|
||||
// this to go faster then cache off the bone index mapping in an array like HLMV does
|
||||
while ( !pParser->Finished() )
|
||||
{
|
||||
const char *pBlock = pParser->GetCurrentBlockName();
|
||||
if ( !stricmp( pBlock, "solid" ) )
|
||||
{
|
||||
solid_t solid;
|
||||
|
||||
pParser->ParseSolid( &solid, NULL );
|
||||
int boneIndex = Studio_BoneIndexByName( &studioHdr, solid.name );
|
||||
Vector *outVerts;
|
||||
int vertCount = g_pPhysicsCollision->CreateDebugMesh( pCollide->solids[solid.index], &outVerts );
|
||||
|
||||
if ( vertCount )
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
||||
pRenderContext->CullMode( MATERIAL_CULLMODE_CCW );
|
||||
// NOTE: assumes these have been set up already by the model render code
|
||||
// So this is a little bit of a back door to a cache of the bones
|
||||
// this code wouldn't work unless you draw the model this frame before calling
|
||||
// this routine. CMDLPanel always does this, but it's worth noting.
|
||||
// A better solution would be to move the ragdoll visulization into the CDmeMdl
|
||||
// and either draw it there or make it queryable and query/draw here.
|
||||
matrix3x4_t xform;
|
||||
SetIdentityMatrix( xform );
|
||||
if ( boneIndex >= 0 )
|
||||
{
|
||||
MatrixCopy( pBoneToWorld[ boneIndex ], xform );
|
||||
}
|
||||
IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_Wireframe );
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, vertCount/3 );
|
||||
|
||||
for ( int j = 0; j < vertCount; j++ )
|
||||
{
|
||||
Vector out;
|
||||
VectorTransform( outVerts[j].Base(), xform, out.Base() );
|
||||
meshBuilder.Position3fv( out.Base() );
|
||||
meshBuilder.Color4ub( color.r, color.g, color.b, color.a );
|
||||
meshBuilder.TexCoord2f( 0, 0, 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
g_pPhysicsCollision->DestroyDebugMesh( vertCount, outVerts );
|
||||
}
|
||||
else
|
||||
{
|
||||
pParser->SkipBlock();
|
||||
}
|
||||
}
|
||||
g_pPhysicsCollision->VPhysicsKeyParserDestroy( pParser );
|
||||
}
|
||||
|
||||
void CMDLPanel::SetupRenderState( int nDisplayWidth, int nDisplayHeight )
|
||||
{
|
||||
int iWidth = nDisplayWidth;
|
||||
int iHeight = nDisplayHeight;
|
||||
if ( m_bThumbnailSafeZone )
|
||||
{
|
||||
iWidth = THUMBNAIL_SAFE_ZONE_SIZE;
|
||||
iHeight = THUMBNAIL_SAFE_ZONE_SIZE;
|
||||
}
|
||||
BaseClass::SetupRenderState( iWidth, iHeight );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// paint it!
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::OnPaint3D()
|
||||
{
|
||||
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID )
|
||||
return;
|
||||
|
||||
// FIXME: Move this call into DrawModel in StudioRender
|
||||
StudioRenderConfig_t oldStudioRenderConfig;
|
||||
StudioRender()->GetCurrentConfig( oldStudioRenderConfig );
|
||||
|
||||
UpdateStudioRenderConfig();
|
||||
|
||||
CMatRenderContextPtr pRenderContext( vgui::MaterialSystem() );
|
||||
if ( vgui::MaterialSystemHardwareConfig()->GetHDRType() == HDR_TYPE_NONE )
|
||||
{
|
||||
ITexture *pMyCube = HasLightProbe() ? GetLightProbeCubemap( false ) : m_DefaultEnvCubemap;
|
||||
pRenderContext->BindLocalCubemap( pMyCube );
|
||||
}
|
||||
else
|
||||
{
|
||||
ITexture *pMyCube = HasLightProbe() ? GetLightProbeCubemap( true ) : m_DefaultHDREnvCubemap;
|
||||
pRenderContext->BindLocalCubemap( pMyCube );
|
||||
}
|
||||
|
||||
PrePaint3D( pRenderContext );
|
||||
|
||||
if ( m_bGroundGrid )
|
||||
{
|
||||
DrawGrid();
|
||||
}
|
||||
|
||||
if ( m_bLookAtCamera )
|
||||
{
|
||||
matrix3x4_t worldToCamera;
|
||||
ComputeCameraTransform( &worldToCamera );
|
||||
|
||||
Vector vecPosition;
|
||||
MatrixGetColumn( worldToCamera, 3, vecPosition );
|
||||
m_RootMDL.m_MDL.m_bWorldSpaceViewTarget = true;
|
||||
m_RootMDL.m_MDL.m_vecViewTarget = vecPosition;
|
||||
}
|
||||
|
||||
// Draw the MDL
|
||||
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_RootMDL.m_MDL.GetMDL() ), g_pMDLCache );
|
||||
|
||||
SetupFlexWeights();
|
||||
|
||||
matrix3x4_t *pBoneToWorld = g_pStudioRender->LockBoneMatrices( studioHdr.numbones() );
|
||||
m_RootMDL.m_MDL.SetUpBones( m_RootMDL.m_MDLToWorld, studioHdr.numbones(), pBoneToWorld, m_PoseParameters, m_SequenceLayers, m_nNumSequenceLayers );
|
||||
g_pStudioRender->UnlockBoneMatrices();
|
||||
|
||||
IMaterial* pOverrideMaterial = GetOverrideMaterial( m_RootMDL.m_MDL.GetMDL() );
|
||||
if ( pOverrideMaterial != NULL )
|
||||
g_pStudioRender->ForcedMaterialOverride( pOverrideMaterial );
|
||||
|
||||
m_RootMDL.m_MDL.Draw( m_RootMDL.m_MDLToWorld, pBoneToWorld );
|
||||
|
||||
if ( pOverrideMaterial != NULL )
|
||||
g_pStudioRender->ForcedMaterialOverride( NULL );
|
||||
|
||||
pOverrideMaterial = NULL;
|
||||
|
||||
// Draw the merge MDLs.
|
||||
matrix3x4_t matMergeBoneToWorld[MAXSTUDIOBONES];
|
||||
int nMergeCount = m_aMergeMDLs.Count();
|
||||
for ( int iMerge = 0; iMerge < nMergeCount; ++iMerge )
|
||||
{
|
||||
if ( m_aMergeMDLs[iMerge].m_bDisabled )
|
||||
continue;
|
||||
|
||||
// Get the merge studio header.
|
||||
studiohdr_t *pStudioHdr = g_pMDLCache->GetStudioHdr( m_aMergeMDLs[iMerge].m_MDL.GetMDL() );
|
||||
matrix3x4_t *pMergeBoneToWorld = &matMergeBoneToWorld[0];
|
||||
|
||||
// If we have a valid mesh, bonemerge it. If we have an invalid mesh we can't bonemerge because
|
||||
// it'll crash trying to pull data from the missing header.
|
||||
if ( pStudioHdr != NULL )
|
||||
{
|
||||
CStudioHdr mergeHdr( pStudioHdr, g_pMDLCache );
|
||||
m_aMergeMDLs[iMerge].m_MDL.SetupBonesWithBoneMerge( &mergeHdr, pMergeBoneToWorld, &studioHdr, pBoneToWorld, m_RootMDL.m_MDLToWorld );
|
||||
|
||||
pOverrideMaterial = GetOverrideMaterial( m_aMergeMDLs[iMerge].m_MDL.GetMDL() );
|
||||
if ( pOverrideMaterial != NULL )
|
||||
g_pStudioRender->ForcedMaterialOverride( pOverrideMaterial );
|
||||
|
||||
m_aMergeMDLs[iMerge].m_MDL.Draw( m_aMergeMDLs[iMerge].m_MDLToWorld, pMergeBoneToWorld );
|
||||
|
||||
if ( pOverrideMaterial != NULL )
|
||||
g_pStudioRender->ForcedMaterialOverride( NULL );
|
||||
|
||||
// Notify of model render
|
||||
RenderingMergedModel( pRenderContext, &mergeHdr, m_aMergeMDLs[iMerge].m_MDL.GetMDL(), pMergeBoneToWorld );
|
||||
}
|
||||
}
|
||||
|
||||
RenderingRootModel( pRenderContext, &studioHdr, m_RootMDL.m_MDL.GetMDL(), pBoneToWorld );
|
||||
|
||||
PostPaint3D( pRenderContext );
|
||||
|
||||
if ( m_bDrawCollisionModel )
|
||||
{
|
||||
DrawCollisionModel();
|
||||
}
|
||||
|
||||
pRenderContext->Flush();
|
||||
StudioRender()->UpdateConfig( oldStudioRenderConfig );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the current LOD
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::SetLOD( int nLOD )
|
||||
{
|
||||
m_RootMDL.m_MDL.m_nLOD = nLOD;
|
||||
|
||||
int nMergeCount = m_aMergeMDLs.Count();
|
||||
for ( int iMerge = 0; iMerge < nMergeCount; ++iMerge )
|
||||
{
|
||||
m_aMergeMDLs[iMerge].m_MDL.m_nLOD = nLOD;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the current sequence
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::SetSequence( int nSequence, bool bResetSequence )
|
||||
{
|
||||
m_RootMDL.m_MDL.m_nSequence = nSequence;
|
||||
|
||||
if ( bResetSequence )
|
||||
{
|
||||
m_RootMDL.m_flCycleStartTime = GetAutoPlayTime();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set the current pose parameters. If NULL the pose parameters will be reset
|
||||
// to the default values.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::SetPoseParameters( const float *pPoseParameters, int nCount )
|
||||
{
|
||||
if ( pPoseParameters )
|
||||
{
|
||||
int nParameters = MIN( MAXSTUDIOPOSEPARAM, nCount );
|
||||
for ( int iParam = 0; iParam < nParameters; ++iParam )
|
||||
{
|
||||
m_PoseParameters[ iParam ] = pPoseParameters[ iParam ];
|
||||
}
|
||||
}
|
||||
else if ( m_RootMDL.m_MDL.GetMDL() != MDLHANDLE_INVALID )
|
||||
{
|
||||
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_RootMDL.m_MDL.GetMDL() ), g_pMDLCache );
|
||||
Studio_CalcDefaultPoseParameters( &studioHdr, m_PoseParameters, MAXSTUDIOPOSEPARAM );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set a pose parameter by name
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMDLPanel::SetPoseParameterByName( const char *pszName, float fValue )
|
||||
{
|
||||
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_RootMDL.m_MDL.GetMDL() ), g_pMDLCache );
|
||||
int nPoseCount = studioHdr.GetNumPoseParameters();
|
||||
|
||||
for ( int i = 0; i < nPoseCount; ++i )
|
||||
{
|
||||
const mstudioposeparamdesc_t &Pose = studioHdr.pPoseParameter( i );
|
||||
if ( V_strcasecmp( pszName, Pose.pszName() ) == 0 )
|
||||
{
|
||||
m_PoseParameters[ i ] = fValue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set the overlay sequence layers
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::SetSequenceLayers( const MDLSquenceLayer_t *pSequenceLayers, int nCount )
|
||||
{
|
||||
if ( pSequenceLayers )
|
||||
{
|
||||
m_nNumSequenceLayers = MIN( MAX_SEQUENCE_LAYERS, nCount );
|
||||
for ( int iLayer = 0; iLayer < m_nNumSequenceLayers; ++iLayer )
|
||||
{
|
||||
m_SequenceLayers[ iLayer ] = pSequenceLayers[ iLayer ];
|
||||
ResetAnimationEventState( &m_SequenceLayerEventState[ iLayer ] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nNumSequenceLayers = 0;
|
||||
V_memset( m_SequenceLayers, 0, sizeof( m_SequenceLayers ) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set the current skin
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::SetSkin( int nSkin )
|
||||
{
|
||||
m_RootMDL.m_MDL.m_nSkin = nSkin;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// called when we're ticked...
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
if ( m_RootMDL.m_MDL.GetMDL() != MDLHANDLE_INVALID )
|
||||
{
|
||||
m_RootMDL.m_MDL.m_flTime = ( GetAutoPlayTime() - m_RootMDL.m_flCycleStartTime );
|
||||
|
||||
DoAnimationEvents();
|
||||
}
|
||||
}
|
||||
|
||||
void CMDLPanel::Paint()
|
||||
{
|
||||
BaseClass::Paint();
|
||||
|
||||
if ( m_bThumbnailSafeZone )
|
||||
{
|
||||
int iWidth, iHeight;
|
||||
GetSize( iWidth, iHeight );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( vgui::MaterialSystem() );
|
||||
|
||||
IMaterial *safezone = materials->FindMaterial( "vgui/thumbnails_safezone", TEXTURE_GROUP_VGUI, true );
|
||||
if ( safezone )
|
||||
{
|
||||
safezone->IncrementReferenceCount();
|
||||
}
|
||||
|
||||
int screenposx = 0;
|
||||
int screenposy = 0;
|
||||
LocalToScreen( screenposx, screenposy );
|
||||
|
||||
int iScaledHeight = THUMBNAIL_SAFE_ZONE_HEIGHT_SCALE * iHeight;
|
||||
int iRemappedHeight = RemapVal( iScaledHeight, 0, THUMBNAIL_SAFE_ZONE_HEIGHT, 0, iScaledHeight );
|
||||
|
||||
pRenderContext->DrawScreenSpaceRectangle( safezone, screenposx, screenposy, iWidth, iRemappedHeight,
|
||||
0, 0,
|
||||
THUMBNAIL_SAFE_ZONE_SIZE, THUMBNAIL_SAFE_ZONE_HEIGHT,
|
||||
THUMBNAIL_SAFE_ZONE_SIZE, THUMBNAIL_SAFE_ZONE_SIZE );
|
||||
|
||||
screenposx = 0;
|
||||
screenposy = iHeight - iRemappedHeight;
|
||||
LocalToScreen( screenposx, screenposy );
|
||||
pRenderContext->DrawScreenSpaceRectangle( safezone, screenposx, screenposy, iWidth, iRemappedHeight,
|
||||
0, 0,
|
||||
THUMBNAIL_SAFE_ZONE_SIZE, THUMBNAIL_SAFE_ZONE_HEIGHT,
|
||||
THUMBNAIL_SAFE_ZONE_SIZE, THUMBNAIL_SAFE_ZONE_SIZE );
|
||||
|
||||
if ( safezone )
|
||||
{
|
||||
safezone->DecrementReferenceCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::DoAnimationEvents()
|
||||
{
|
||||
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_RootMDL.m_MDL.GetMDL() ), g_pMDLCache );
|
||||
|
||||
// If we don't have any sequences, don't do anything
|
||||
if ( studioHdr.GetNumSeq() < 1 )
|
||||
{
|
||||
Assert( studioHdr.GetNumSeq() >= 1 );
|
||||
return;
|
||||
}
|
||||
|
||||
DoAnimationEvents( &studioHdr, m_RootMDL.m_MDL.m_nSequence, m_RootMDL.m_MDL.m_flTime, false, &m_EventState );
|
||||
|
||||
for ( int i = 0; i < m_nNumSequenceLayers; ++i )
|
||||
{
|
||||
float flTime = m_RootMDL.m_MDL.m_flTime - m_SequenceLayers[ i ].m_flCycleBeganAt;
|
||||
//Plat_DebugString( CFmtStr("Animation: time = %f, started = %f, delta = %f\n",m_RootMDL.m_MDL.m_flTime,m_SequenceLayers[ i ].m_flCycleBeganAt,flTime ) );
|
||||
DoAnimationEvents( &studioHdr, m_SequenceLayers[ i ].m_nSequenceIndex, flTime, m_SequenceLayers[ i ].m_bNoLoop, &m_SequenceLayerEventState[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::DoAnimationEvents( CStudioHdr *pStudioHdr, int nSeqNum, float flTime, bool bNoLoop, MDLAnimEventState_t *pEventState )
|
||||
{
|
||||
if ( nSeqNum < 0 || nSeqNum >= pStudioHdr->GetNumSeq() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( nSeqNum );
|
||||
if ( seqdesc.numevents == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mstudioevent_t *pevent = seqdesc.pEvent( 0 );
|
||||
|
||||
int nFrameCount = Studio_MaxFrame( pStudioHdr, nSeqNum, m_PoseParameters );
|
||||
if ( nFrameCount == 0 )
|
||||
{
|
||||
nFrameCount = 1;
|
||||
}
|
||||
float flEventCycle = ( flTime * m_RootMDL.m_MDL.m_flPlaybackRate ) / nFrameCount;
|
||||
//Plat_DebugString( CFmtStr("Event cycle: %f, playback rate: %f, frame count: %d\n", flEventCycle, m_RootMDL.m_MDL.m_flPlaybackRate, nFrameCount ) );
|
||||
if ( bNoLoop )
|
||||
{
|
||||
flEventCycle = MIN(flEventCycle, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
flEventCycle -= (int)(flEventCycle);
|
||||
}
|
||||
|
||||
if ( pEventState->m_nEventSequence != nSeqNum )
|
||||
{
|
||||
pEventState->m_nEventSequence = nSeqNum;
|
||||
flEventCycle = 0.0f;
|
||||
pEventState->m_flPrevEventCycle = -0.01f; // back up to get 0'th frame animations
|
||||
}
|
||||
|
||||
if ( flEventCycle == pEventState->m_flPrevEventCycle )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// check for looping
|
||||
BOOL bLooped = (flEventCycle < pEventState->m_flPrevEventCycle);
|
||||
|
||||
// This makes sure events that occur at the end of a sequence occur are
|
||||
// sent before events that occur at the beginning of a sequence.
|
||||
if (bLooped)
|
||||
{
|
||||
for (int i = 0; i < (int)seqdesc.numevents; i++)
|
||||
{
|
||||
if ( pevent[i].cycle <= pEventState->m_flPrevEventCycle )
|
||||
continue;
|
||||
|
||||
FireEvent( pevent[ i ].pszEventName(), pevent[ i ].pszOptions() );
|
||||
}
|
||||
|
||||
// Necessary to get the next loop working
|
||||
pEventState->m_flPrevEventCycle = -0.01f;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)seqdesc.numevents; i++)
|
||||
{
|
||||
if ( (pevent[i].cycle > pEventState->m_flPrevEventCycle && pevent[i].cycle <= flEventCycle) )
|
||||
{
|
||||
FireEvent( pevent[ i ].pszEventName(), pevent[ i ].pszOptions() );
|
||||
}
|
||||
}
|
||||
|
||||
pEventState->m_flPrevEventCycle = flEventCycle;
|
||||
}
|
||||
|
||||
void CMDLPanel::FireEvent( const char *pszEventName, const char *pszEventOptions )
|
||||
{
|
||||
KeyValues* pKVEvent = new KeyValues( "AnimEvent" );
|
||||
pKVEvent->SetString( "name", pszEventName );
|
||||
pKVEvent->SetString( "options", pszEventOptions );
|
||||
PostActionSignal( pKVEvent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::ResetAnimationEventState( MDLAnimEventState_t *pEventState )
|
||||
{
|
||||
pEventState->m_nEventSequence = -1;
|
||||
pEventState->m_flPrevEventCycle = -0.01f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// input
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::OnMouseDoublePressed( vgui::MouseCode code )
|
||||
{
|
||||
if ( m_bIgnoreDoubleClick )
|
||||
return;
|
||||
|
||||
float flRadius;
|
||||
Vector vecCenter;
|
||||
GetBoundingSphere( vecCenter, flRadius );
|
||||
LookAt( vecCenter, flRadius );
|
||||
|
||||
BaseClass::OnMouseDoublePressed( code );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::SetMergeMDL( MDLHandle_t handle, void *pProxyData, int nSkin /*= -1 */ )
|
||||
{
|
||||
// Verify that we have a root model to merge to.
|
||||
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID )
|
||||
return;
|
||||
|
||||
int iIndex = m_aMergeMDLs.AddToTail();
|
||||
if ( !m_aMergeMDLs.IsValidIndex( iIndex ) )
|
||||
return;
|
||||
|
||||
m_aMergeMDLs[iIndex].m_MDL.SetMDL( handle );
|
||||
|
||||
if ( nSkin != -1 )
|
||||
{
|
||||
m_aMergeMDLs[iIndex].m_MDL.m_nSkin = nSkin;
|
||||
}
|
||||
|
||||
m_aMergeMDLs[iIndex].m_MDL.m_nLOD = m_RootMDL.m_MDL.m_nLOD;
|
||||
|
||||
m_aMergeMDLs[iIndex].m_MDL.m_pProxyData = pProxyData;
|
||||
SetIdentityMatrix( m_aMergeMDLs[iIndex].m_MDLToWorld );
|
||||
|
||||
m_aMergeMDLs[iIndex].m_bDisabled = false;
|
||||
|
||||
// Need to invalidate the layout so the panel will adjust is LookAt for the new model.
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
MDLHandle_t CMDLPanel::SetMergeMDL( const char *pMDLName, void *pProxyData, int nSkin /*= -1 */ )
|
||||
{
|
||||
MDLHandle_t hMDLFindResult = vgui::MDLCache()->FindMDL( pMDLName );
|
||||
MDLHandle_t hMDL = pMDLName ? hMDLFindResult : MDLHANDLE_INVALID;
|
||||
if ( vgui::MDLCache()->IsErrorModel( hMDL ) )
|
||||
{
|
||||
hMDL = MDLHANDLE_INVALID;
|
||||
}
|
||||
|
||||
SetMergeMDL( hMDL, pProxyData, nSkin );
|
||||
|
||||
// FindMDL takes a reference and the the CMDL will also hold a reference for as long as it sticks around. Release the FindMDL reference.
|
||||
int nRef = vgui::MDLCache()->Release( hMDLFindResult );
|
||||
(void)nRef; // Avoid unreferenced variable warning
|
||||
AssertMsg( hMDL == MDLHANDLE_INVALID || nRef > 0, "CMDLPanel::SetMergeMDL referenced a model that has a zero ref count." );
|
||||
|
||||
return hMDL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMDLPanel::GetMergeMDLIndex( void *pProxyData )
|
||||
{
|
||||
int nMergeCount = m_aMergeMDLs.Count();
|
||||
for ( int iMerge = 0; iMerge < nMergeCount; ++iMerge )
|
||||
{
|
||||
if ( m_aMergeMDLs[iMerge].m_MDL.m_pProxyData == pProxyData )
|
||||
return iMerge;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMDLPanel::GetMergeMDLIndex( MDLHandle_t handle )
|
||||
{
|
||||
int nMergeCount = m_aMergeMDLs.Count();
|
||||
for ( int iMerge = 0; iMerge < nMergeCount; ++iMerge )
|
||||
{
|
||||
if ( m_aMergeMDLs[iMerge].m_MDL.GetMDL() == handle )
|
||||
return iMerge;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMDL *CMDLPanel::GetMergeMDL( MDLHandle_t handle )
|
||||
{
|
||||
int nMergeCount = m_aMergeMDLs.Count();
|
||||
for ( int iMerge = 0; iMerge < nMergeCount; ++iMerge )
|
||||
{
|
||||
if ( m_aMergeMDLs[iMerge].m_MDL.GetMDL() == handle )
|
||||
return (&m_aMergeMDLs[iMerge].m_MDL);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::ClearMergeMDLs( void )
|
||||
{
|
||||
m_aMergeMDLs.Purge();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,539 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "matsys_controls/mdlsequencepicker.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utldict.h"
|
||||
#include "datacache/imdlcache.h"
|
||||
#include "filesystem.h"
|
||||
#include "studio.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "vgui/Cursor.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui_controls/Splitter.h"
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "vgui_controls/PropertySheet.h"
|
||||
#include "vgui_controls/PropertyPage.h"
|
||||
#include "vgui_controls/ToolWindow.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "matsys_controls/gamefiletreeview.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// MDL Sequence Picker
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMDLSequencePicker::CMDLSequencePicker( vgui::Panel *pParent ) : BaseClass(pParent, "MDLSequencePicker"), m_Images(false)
|
||||
{
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||||
|
||||
m_hSelectedMDL = MDLHANDLE_INVALID;
|
||||
|
||||
// Horizontal splitter for mdls
|
||||
m_pMDLSplitter = new Splitter( this, "MDLSplitter", SPLITTER_MODE_VERTICAL, 1 );
|
||||
|
||||
vgui::Panel *pSplitterLeftSide = m_pMDLSplitter->GetChild( 0 );
|
||||
vgui::Panel *pSplitterRightSide = m_pMDLSplitter->GetChild( 1 );
|
||||
|
||||
// filter selection
|
||||
m_pFilterList = new ComboBox( pSplitterLeftSide, "FilterList", 16, true );
|
||||
m_pFilterList->AddActionSignalTarget( this );
|
||||
|
||||
// file browser tree controls
|
||||
m_pFileTree = new CGameFileTreeView( pSplitterLeftSide, "FileTree", "All .MDLs", "models", "mdl" );
|
||||
|
||||
// build our list of images
|
||||
m_Images.AddImage( scheme()->GetImage( "resource/icon_folder", false ) );
|
||||
m_Images.AddImage( scheme()->GetImage( "resource/icon_folder_selected", false ) );
|
||||
m_Images.AddImage( scheme()->GetImage( "resource/icon_file", false ) );
|
||||
m_pFileTree->SetImageList( &m_Images, false );
|
||||
m_pFileTree->AddActionSignalTarget( this );
|
||||
|
||||
// property sheet - revisions, changes, etc.
|
||||
m_pSequenceSplitter = new Splitter( pSplitterRightSide, "SequenceSplitter", SPLITTER_MODE_HORIZONTAL, 1 );
|
||||
|
||||
vgui::Panel *pSplitterTopSide = m_pSequenceSplitter->GetChild( 0 );
|
||||
vgui::Panel *pSplitterBottomSide = m_pSequenceSplitter->GetChild( 1 );
|
||||
|
||||
// MDL preview
|
||||
m_pMDLPreview = new CMDLPanel( pSplitterTopSide, "MDLPreview" );
|
||||
SetSkipChildDuringPainting( m_pMDLPreview );
|
||||
|
||||
m_pViewsSheet = new vgui::PropertySheet( pSplitterBottomSide, "ViewsSheet" );
|
||||
m_pViewsSheet->AddActionSignalTarget( this );
|
||||
|
||||
// sequences
|
||||
m_pSequencesPage = new PropertyPage( m_pViewsSheet, "SequencesPage" );
|
||||
m_pViewsSheet->AddPage( m_pSequencesPage, "Sequences" );
|
||||
m_pSequencesList = new ListPanel( m_pSequencesPage, "SequencesList" );
|
||||
m_pSequencesList->AddColumnHeader( 0, "sequence", "sequence", 52, 0 );
|
||||
m_pSequencesList->AddActionSignalTarget( this );
|
||||
m_pSequencesList->SetSelectIndividualCells( true );
|
||||
m_pSequencesList->SetEmptyListText("No .MDL file currently selected.");
|
||||
m_pSequencesList->SetDragEnabled( true );
|
||||
m_pSequencesList->SetAutoResize( Panel::PIN_TOPLEFT, Panel::AUTORESIZE_DOWNANDRIGHT, 0, 0, 0, 0 );
|
||||
|
||||
// Activities
|
||||
m_pActivitiesPage = new PropertyPage( m_pViewsSheet, "ActivitiesPage" );
|
||||
m_pViewsSheet->AddPage( m_pActivitiesPage, "Activities" );
|
||||
m_pActivitiesList = new ListPanel( m_pActivitiesPage, "ActivitiesList" );
|
||||
m_pActivitiesList->AddColumnHeader( 0, "activity", "activity", 52, 0 );
|
||||
m_pActivitiesList->AddActionSignalTarget( this );
|
||||
m_pActivitiesList->SetSelectIndividualCells( true );
|
||||
m_pActivitiesList->SetEmptyListText( "No .MDL file currently selected." );
|
||||
m_pActivitiesList->SetDragEnabled( true );
|
||||
m_pActivitiesList->SetAutoResize( Panel::PIN_TOPLEFT, Panel::AUTORESIZE_DOWNANDRIGHT, 0, 0, 0, 0 );
|
||||
|
||||
// Load layout settings; has to happen before pinning occurs in code
|
||||
LoadControlSettingsAndUserConfig( "resource/mdlsequencepicker.res" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMDLSequencePicker::~CMDLSequencePicker()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This is a bit of a hack to make sure that the ToolWindow containing this picker punches
|
||||
// a hold for the rendering viewport, too
|
||||
// Input : -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
if ( GetParent() )
|
||||
{
|
||||
ToolWindow *tw = dynamic_cast< ToolWindow * >( GetParent()->GetParent() );
|
||||
|
||||
if ( tw )
|
||||
{
|
||||
tw->SetSkipChildDuringPainting( IsVisible() ? m_pMDLPreview : NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: stops app on close
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::OnClose()
|
||||
{
|
||||
BaseClass::OnClose();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called to open
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::Activate()
|
||||
{
|
||||
RefreshFileList();
|
||||
RefreshActivitiesAndSequencesList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Performs layout
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::PerformLayout()
|
||||
{
|
||||
// NOTE: This call should cause auto-resize to occur
|
||||
// which should fix up the width of the panels
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
// Layout the mdl splitter
|
||||
m_pMDLSplitter->SetBounds( 0, 0, w, h );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Refreshes the active file list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::RefreshFileList()
|
||||
{
|
||||
m_pFileTree->RefreshFileList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: rebuilds the list of activities
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::RefreshActivitiesAndSequencesList()
|
||||
{
|
||||
m_pActivitiesList->RemoveAll();
|
||||
m_pSequencesList->RemoveAll();
|
||||
m_pMDLPreview->SetSequence( 0 );
|
||||
|
||||
if ( m_hSelectedMDL == MDLHANDLE_INVALID )
|
||||
{
|
||||
m_pActivitiesList->SetEmptyListText("No .MDL file currently selected");
|
||||
m_pSequencesList->SetEmptyListText("No .MDL file currently selected");
|
||||
return;
|
||||
}
|
||||
|
||||
m_pActivitiesList->SetEmptyListText(".MDL file contains no activities");
|
||||
m_pSequencesList->SetEmptyListText(".MDL file contains no sequences");
|
||||
|
||||
studiohdr_t *hdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
|
||||
|
||||
CUtlDict<int, unsigned short> activityNames( true, 0, hdr->GetNumSeq() );
|
||||
|
||||
for (int j = 0; j < hdr->GetNumSeq(); j++)
|
||||
{
|
||||
if ( /*g_viewerSettings.showHidden ||*/ !(hdr->pSeqdesc(j).flags & STUDIO_HIDDEN))
|
||||
{
|
||||
const char *pActivityName = hdr->pSeqdesc(j).pszActivityName();
|
||||
if ( pActivityName && pActivityName[0] )
|
||||
{
|
||||
// Multiple sequences can have the same activity name; only add unique activity names
|
||||
if ( activityNames.Find( pActivityName ) == activityNames.InvalidIndex() )
|
||||
{
|
||||
KeyValues *pkv = new KeyValues("node", "activity", pActivityName );
|
||||
int nItemID = m_pActivitiesList->AddItem( pkv, 0, false, false );
|
||||
|
||||
KeyValues *pDrag = new KeyValues( "drag", "text", pActivityName );
|
||||
pDrag->SetString( "texttype", "activityName" );
|
||||
pDrag->SetString( "mdl", vgui::MDLCache()->GetModelName( m_hSelectedMDL ) );
|
||||
m_pActivitiesList->SetItemDragData( nItemID, pDrag );
|
||||
|
||||
activityNames.Insert( pActivityName, j );
|
||||
}
|
||||
}
|
||||
|
||||
const char *pSequenceName = hdr->pSeqdesc(j).pszLabel();
|
||||
if ( pSequenceName && pSequenceName[0] )
|
||||
{
|
||||
KeyValues *pkv = new KeyValues("node", "sequence", pSequenceName);
|
||||
pkv->SetInt( "seqindex", j );
|
||||
|
||||
int nItemID = m_pSequencesList->AddItem( pkv, 0, false, false );
|
||||
|
||||
KeyValues *pDrag = new KeyValues( "drag", "text", pSequenceName );
|
||||
pDrag->SetString( "texttype", "sequenceName" );
|
||||
pDrag->SetString( "mdl", vgui::MDLCache()->GetModelName( m_hSelectedMDL ) );
|
||||
m_pSequencesList->SetItemDragData( nItemID, pDrag );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes dialog on text changing
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::OnTextChanged( vgui::Panel *pPanel, const char *pText )
|
||||
{
|
||||
// m_pFileTree->SetFilter( pText );
|
||||
RefreshFileList();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Selects an sequence based on an activity
|
||||
//-----------------------------------------------------------------------------
|
||||
int SelectWeightedSequence( studiohdr_t *pstudiohdr, int activity, int curSequence )
|
||||
{
|
||||
if (! pstudiohdr)
|
||||
return 0;
|
||||
|
||||
VerifySequenceIndex( pstudiohdr );
|
||||
|
||||
int weighttotal = 0;
|
||||
int seq = ACTIVITY_NOT_AVAILABLE;
|
||||
int weight = 0;
|
||||
for (int i = 0; i < pstudiohdr->GetNumSeq(); i++)
|
||||
{
|
||||
int curActivity = GetSequenceActivity( pstudiohdr, i, &weight );
|
||||
if (curActivity == activity)
|
||||
{
|
||||
if ( curSequence == i && weight < 0 )
|
||||
{
|
||||
seq = i;
|
||||
break;
|
||||
}
|
||||
weighttotal += iabs(weight);
|
||||
|
||||
int randomValue;
|
||||
if ( IsInPrediction() )
|
||||
randomValue = SharedRandomInt( "SelectWeightedSequence", 0, weighttotal - 1, i );
|
||||
else
|
||||
randomValue = RandomInt( 0, weighttotal - 1 );
|
||||
|
||||
if (!weighttotal || randomValue < iabs(weight))
|
||||
seq = i;
|
||||
}
|
||||
}
|
||||
|
||||
return seq;
|
||||
}
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Plays the selected activity
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::PlaySelectedActivity( )
|
||||
{
|
||||
int nIndex = m_pActivitiesList->GetSelectedItem( 0 );
|
||||
if ( nIndex < 0 )
|
||||
return;
|
||||
|
||||
KeyValues *pkv = m_pActivitiesList->GetItem( nIndex );
|
||||
const char *pActivityName = pkv->GetString( "activity", NULL );
|
||||
if ( !pActivityName )
|
||||
return;
|
||||
|
||||
studiohdr_t *pstudiohdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
|
||||
for ( int i = 0; i < pstudiohdr->GetNumSeq(); i++ )
|
||||
{
|
||||
mstudioseqdesc_t &seqdesc = pstudiohdr->pSeqdesc( i );
|
||||
if ( stricmp( seqdesc.pszActivityName(), pActivityName ) == 0 )
|
||||
{
|
||||
// FIXME: Add weighted sequence selection logic?
|
||||
m_pMDLPreview->SetSequence( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Plays the selected sequence
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::PlaySelectedSequence( )
|
||||
{
|
||||
int nIndex = m_pSequencesList->GetSelectedItem( 0 );
|
||||
if ( nIndex < 0 )
|
||||
return;
|
||||
|
||||
KeyValues *pkv = m_pSequencesList->GetItem( nIndex );
|
||||
const char *pSequenceName = pkv->GetString( "sequence", NULL );
|
||||
if ( !pSequenceName )
|
||||
return;
|
||||
|
||||
studiohdr_t *pstudiohdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
|
||||
for (int i = 0; i < pstudiohdr->GetNumSeq(); i++)
|
||||
{
|
||||
mstudioseqdesc_t &seqdesc = pstudiohdr->pSeqdesc( i );
|
||||
if ( !Q_stricmp( seqdesc.pszLabel(), pSequenceName ) )
|
||||
{
|
||||
m_pMDLPreview->SetSequence( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called when a page is shown
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::OnPageChanged( )
|
||||
{
|
||||
if ( m_pViewsSheet->GetActivePage() == m_pSequencesPage )
|
||||
{
|
||||
PlaySelectedSequence();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_pViewsSheet->GetActivePage() == m_pActivitiesPage )
|
||||
{
|
||||
PlaySelectedActivity();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes dialog on text changing
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::OnItemSelected( KeyValues *kv )
|
||||
{
|
||||
Panel *pPanel = (Panel *)kv->GetPtr("panel", NULL);
|
||||
if ( pPanel == m_pSequencesList )
|
||||
{
|
||||
PlaySelectedSequence();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pPanel == m_pActivitiesList )
|
||||
{
|
||||
PlaySelectedActivity();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// An MDL was selected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::SelectMDL( const char *pMDLName )
|
||||
{
|
||||
m_hSelectedMDL = pMDLName ? vgui::MDLCache()->FindMDL( pMDLName ) : MDLHANDLE_INVALID;
|
||||
if ( vgui::MDLCache()->IsErrorModel( m_hSelectedMDL ) )
|
||||
{
|
||||
m_hSelectedMDL = MDLHANDLE_INVALID;
|
||||
}
|
||||
m_pMDLPreview->SetMDL( m_hSelectedMDL );
|
||||
m_pMDLPreview->LookAtMDL();
|
||||
RefreshActivitiesAndSequencesList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: updates revision view on a file being selected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::OnFileSelected()
|
||||
{
|
||||
// update list
|
||||
int iItem = m_pFileTree->GetFirstSelectedItem();
|
||||
if ( iItem < 0 )
|
||||
return;
|
||||
|
||||
// Don't bother to change if a directory was selected
|
||||
KeyValues *pkv = m_pFileTree->GetItemData(iItem);
|
||||
if ( pkv->GetInt("dir") || pkv->GetInt("root") )
|
||||
return;
|
||||
|
||||
surface()->SetCursor(dc_waitarrow);
|
||||
|
||||
const char *pFullPathName = pkv->GetString( "path" );
|
||||
|
||||
char pRelativePathName[MAX_PATH];
|
||||
g_pFullFileSystem->FullPathToRelativePath( pFullPathName, pRelativePathName, sizeof(pRelativePathName) );
|
||||
|
||||
// FIXME: Check that we're not actually opening the wrong file!!
|
||||
SelectMDL( pRelativePathName );
|
||||
}
|
||||
|
||||
char const *CMDLSequencePicker::GetModelName()
|
||||
{
|
||||
if ( MDLHANDLE_INVALID == m_hSelectedMDL )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return vgui::MDLCache()->GetModelName( m_hSelectedMDL );
|
||||
}
|
||||
|
||||
char const *CMDLSequencePicker::GetSequenceName()
|
||||
{
|
||||
int nIndex = m_pSequencesList->GetSelectedItem( 0 );
|
||||
if ( nIndex < 0 )
|
||||
return "";
|
||||
|
||||
KeyValues *pkv = m_pSequencesList->GetItem( nIndex );
|
||||
const char *pSequenceName = pkv->GetString( "sequence", NULL );
|
||||
if ( !pSequenceName )
|
||||
return "";
|
||||
|
||||
return pSequenceName;
|
||||
}
|
||||
|
||||
int CMDLSequencePicker::GetSequenceNumber()
|
||||
{
|
||||
int nIndex = m_pSequencesList->GetSelectedItem( 0 );
|
||||
if ( nIndex < 0 )
|
||||
return -1;
|
||||
KeyValues *pkv = m_pSequencesList->GetItem( nIndex );
|
||||
return pkv->GetInt( "seqindex", -1 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sequence picker frame
|
||||
//-----------------------------------------------------------------------------
|
||||
CMDLSequencePickerFrame::CMDLSequencePickerFrame( vgui::Panel *parent, char const *title ) :
|
||||
BaseClass( parent, "MDLSequencePickerFrame" )
|
||||
{
|
||||
m_pMDLSequencePicker = new CMDLSequencePicker( this );
|
||||
SetTitle( title, true );
|
||||
SetSizeable( false );
|
||||
SetCloseButtonVisible( false );
|
||||
SetMoveable( true );
|
||||
SetMinimumSize( 640, 480 );
|
||||
Activate();
|
||||
m_pMDLSequencePicker->Activate();
|
||||
|
||||
m_pOK = new Button( this, "OK", "#vgui_ok", this );
|
||||
m_pOK->SetCommand( new KeyValues( "OnOK" ) );
|
||||
m_pCancel= new Button( this, "Cancel", "#vgui_cancel", this );
|
||||
m_pOK->SetCommand( new KeyValues( "OnCancel" ) );
|
||||
m_pOK->SetEnabled( false );
|
||||
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel(), 0 );
|
||||
}
|
||||
|
||||
CMDLSequencePickerFrame::~CMDLSequencePickerFrame()
|
||||
{
|
||||
}
|
||||
|
||||
void CMDLSequencePickerFrame::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
|
||||
bool bHasModel = m_pMDLSequencePicker->GetModelName()[ 0 ] != 0 ? true : false;
|
||||
bool bHasSequence = m_pMDLSequencePicker->GetSequenceNumber() != -1 ? true : false;
|
||||
|
||||
m_pOK->SetEnabled( bHasModel && bHasSequence );
|
||||
}
|
||||
|
||||
void CMDLSequencePickerFrame::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
int x, y, w, h;
|
||||
GetClientArea( x, y, w, h );
|
||||
h -= 24;
|
||||
m_pMDLSequencePicker->SetBounds( x, y, w, h );
|
||||
|
||||
h += 5;
|
||||
|
||||
|
||||
int bw = 120;
|
||||
int bwwithGap = 2 * bw + 10;
|
||||
|
||||
x = ( w - bwwithGap ) / 2;
|
||||
m_pOK->SetBounds( x, y + h, bw, 16 );
|
||||
x += bw + 10;
|
||||
m_pCancel->SetBounds( x, y + h, bw, 16 );
|
||||
}
|
||||
|
||||
void CMDLSequencePickerFrame::OnCancel()
|
||||
{
|
||||
KeyValues *pActionKeys = new KeyValues( "AssetSelected" );
|
||||
pActionKeys->SetString( "ModelName", m_pMDLSequencePicker->GetModelName() );
|
||||
pActionKeys->SetString( "SequenceName", m_pMDLSequencePicker->GetSequenceName() );
|
||||
pActionKeys->SetInt( "SequenceNumber", m_pMDLSequencePicker->GetSequenceNumber() );
|
||||
|
||||
PostActionSignal( pActionKeys );
|
||||
|
||||
CloseModal();
|
||||
}
|
||||
|
||||
void CMDLSequencePickerFrame::OnOK()
|
||||
{
|
||||
CloseModal();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,318 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "matsys_controls/picker.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vgui_controls/ListPanel.h"
|
||||
#include "vgui_controls/TextEntry.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/IInput.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Base asset Picker
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sort by asset name
|
||||
//-----------------------------------------------------------------------------
|
||||
static int __cdecl PickerBrowserSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 )
|
||||
{
|
||||
const char *string1 = item1.kv->GetString("choice");
|
||||
const char *string2 = item2.kv->GetString("choice");
|
||||
return stricmp( string1, string2 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CPicker::CPicker( vgui::Panel *pParent, const char *pColumnHeader, const char *pTextType ) :
|
||||
BaseClass( pParent, "Picker" )
|
||||
{
|
||||
m_pPickerType = pColumnHeader;
|
||||
m_pPickerTextType = pTextType;
|
||||
|
||||
// FIXME: Make this an image browser
|
||||
m_pPickerBrowser = new vgui::ListPanel( this, "Browser" );
|
||||
m_pPickerBrowser->AddColumnHeader( 0, "choice", m_pPickerType, 52, 0 );
|
||||
m_pPickerBrowser->SetSelectIndividualCells( true );
|
||||
m_pPickerBrowser->SetEmptyListText( "Nothing to pick" );
|
||||
m_pPickerBrowser->SetDragEnabled( true );
|
||||
m_pPickerBrowser->AddActionSignalTarget( this );
|
||||
m_pPickerBrowser->SetSortFunc( 0, PickerBrowserSortFunc );
|
||||
m_pPickerBrowser->SetSortColumn( 0 );
|
||||
|
||||
// filter selection
|
||||
m_pFilterList = new TextEntry( this, "FilterList" );
|
||||
m_pFilterList->AddActionSignalTarget( this );
|
||||
m_pFilterList->RequestFocus();
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/picker.res" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CPicker::~CPicker()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPicker::OnKeyCodePressed( KeyCode code )
|
||||
{
|
||||
if (( code == KEY_UP ) || ( code == KEY_DOWN ) || ( code == KEY_PAGEUP ) || ( code == KEY_PAGEDOWN ))
|
||||
{
|
||||
KeyValues *pMsg = new KeyValues("KeyCodePressed", "code", code);
|
||||
vgui::ipanel()->SendMessage( m_pPickerBrowser->GetVPanel(), pMsg, GetVPanel());
|
||||
pMsg->deleteThis();
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnKeyCodePressed( code );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes the asset list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPicker::SetStringList( const PickerList_t &list )
|
||||
{
|
||||
m_Type = list.m_Type;
|
||||
m_pPickerBrowser->RemoveAll();
|
||||
|
||||
int nCount = list.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
const char *pPickerName = list[i].m_pChoiceString;
|
||||
KeyValues *kv = new KeyValues( "node", "choice", pPickerName );
|
||||
if ( m_Type == PICKER_CHOICE_STRING )
|
||||
{
|
||||
kv->SetString( "value", list[i].m_pChoiceValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
kv->SetPtr( "value", list[i].m_pChoiceValuePtr );
|
||||
}
|
||||
int nItemID = m_pPickerBrowser->AddItem( kv, 0, false, false );
|
||||
|
||||
if ( m_Type == PICKER_CHOICE_STRING )
|
||||
{
|
||||
KeyValues *pDrag = new KeyValues( "drag", "text", list[i].m_pChoiceValue );
|
||||
if ( m_pPickerTextType )
|
||||
{
|
||||
pDrag->SetString( "texttype", m_pPickerTextType );
|
||||
}
|
||||
m_pPickerBrowser->SetItemDragData( nItemID, pDrag );
|
||||
}
|
||||
}
|
||||
RefreshChoiceList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes the choice list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPicker::RefreshChoiceList( )
|
||||
{
|
||||
// Check the filter matches
|
||||
int nMatchingCount = 0;
|
||||
int nTotalCount = 0;
|
||||
for ( int nItemID = m_pPickerBrowser->FirstItem(); nItemID != m_pPickerBrowser->InvalidItemID(); nItemID = m_pPickerBrowser->NextItem( nItemID ) )
|
||||
{
|
||||
KeyValues *kv = m_pPickerBrowser->GetItem( nItemID );
|
||||
const char *pPickerName = kv->GetString( "choice" );
|
||||
bool bVisible = !m_Filter.Length() || Q_stristr( pPickerName, m_Filter.Get() );
|
||||
m_pPickerBrowser->SetItemVisible( nItemID, bVisible );
|
||||
if ( bVisible )
|
||||
{
|
||||
++nMatchingCount;
|
||||
}
|
||||
++nTotalCount;
|
||||
}
|
||||
|
||||
char pColumnTitle[512];
|
||||
Q_snprintf( pColumnTitle, sizeof(pColumnTitle), "%s (%d/%d)",
|
||||
m_pPickerType, nMatchingCount, nTotalCount );
|
||||
m_pPickerBrowser->SetColumnHeaderText( 0, pColumnTitle );
|
||||
|
||||
m_pPickerBrowser->SortList();
|
||||
if ( ( m_pPickerBrowser->GetSelectedItemsCount() == 0 ) && ( m_pPickerBrowser->GetItemCount() > 0 ) )
|
||||
{
|
||||
int nItemID = m_pPickerBrowser->GetItemIDFromRow( 0 );
|
||||
m_pPickerBrowser->SetSelectedCell( nItemID, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes dialog on text changing
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPicker::OnTextChanged( )
|
||||
{
|
||||
int nLength = m_pFilterList->GetTextLength();
|
||||
m_Filter.SetLength( nLength );
|
||||
if ( nLength > 0 )
|
||||
{
|
||||
m_pFilterList->GetText( m_Filter.GetForModify(), nLength+1 );
|
||||
}
|
||||
RefreshChoiceList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the selected string
|
||||
//-----------------------------------------------------------------------------
|
||||
PickerChoiceType_t CPicker::GetSelectionType() const
|
||||
{
|
||||
return m_Type;
|
||||
}
|
||||
|
||||
const char *CPicker::GetSelectedString( ) const
|
||||
{
|
||||
if ( m_pPickerBrowser->GetSelectedItemsCount() == 0 )
|
||||
return NULL;
|
||||
|
||||
if ( m_Type != PICKER_CHOICE_STRING )
|
||||
return NULL;
|
||||
|
||||
int nIndex = m_pPickerBrowser->GetSelectedItem( 0 );
|
||||
KeyValues *pItemKeyValues = m_pPickerBrowser->GetItem( nIndex );
|
||||
return pItemKeyValues->GetString( "value" );
|
||||
}
|
||||
|
||||
void *CPicker::GetSelectedPtr( ) const
|
||||
{
|
||||
if ( m_pPickerBrowser->GetSelectedItemsCount() == 0 )
|
||||
return NULL;
|
||||
|
||||
if ( m_Type != PICKER_CHOICE_PTR )
|
||||
return NULL;
|
||||
|
||||
int nIndex = m_pPickerBrowser->GetSelectedItem( 0 );
|
||||
KeyValues *pItemKeyValues = m_pPickerBrowser->GetItem( nIndex );
|
||||
return pItemKeyValues->GetPtr( "value" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the index of the selected string
|
||||
//-----------------------------------------------------------------------------
|
||||
int CPicker::GetSelectedIndex()
|
||||
{
|
||||
if ( m_pPickerBrowser->GetSelectedItemsCount() == 0 )
|
||||
return -1;
|
||||
|
||||
return m_pPickerBrowser->GetSelectedItem( 0 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: Modal picker frame
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CPickerFrame::CPickerFrame( vgui::Panel *pParent, const char *pTitle, const char *pPickerType, const char *pTextType ) :
|
||||
BaseClass( pParent, "PickerFrame" )
|
||||
{
|
||||
m_pContextKeyValues = NULL;
|
||||
SetDeleteSelfOnClose( true );
|
||||
m_pPicker = new CPicker( this, pPickerType, pTextType );
|
||||
m_pPicker->AddActionSignalTarget( this );
|
||||
m_pOpenButton = new Button( this, "OpenButton", "#FileOpenDialog_Open", this, "Open" );
|
||||
m_pCancelButton = new Button( this, "CancelButton", "#FileOpenDialog_Cancel", this, "Cancel" );
|
||||
SetBlockDragChaining( true );
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/pickerframe.res" );
|
||||
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
CPickerFrame::~CPickerFrame()
|
||||
{
|
||||
CleanUpMessage();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Deletes the message
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPickerFrame::CleanUpMessage()
|
||||
{
|
||||
if ( m_pContextKeyValues )
|
||||
{
|
||||
m_pContextKeyValues->deleteThis();
|
||||
m_pContextKeyValues = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Activate the dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPickerFrame::DoModal( const PickerList_t &list, KeyValues *pContextKeyValues )
|
||||
{
|
||||
CleanUpMessage();
|
||||
m_pContextKeyValues = pContextKeyValues;
|
||||
m_pPicker->SetStringList( list );
|
||||
BaseClass::DoModal();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On command
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPickerFrame::OnCommand( const char *pCommand )
|
||||
{
|
||||
if ( !Q_stricmp( pCommand, "Open" ) )
|
||||
{
|
||||
KeyValues *pActionKeys = new KeyValues( "Picked" );
|
||||
pActionKeys->SetInt( "choiceIndex", m_pPicker->GetSelectedIndex( ) );
|
||||
|
||||
if ( m_pPicker->GetSelectionType() == PICKER_CHOICE_STRING )
|
||||
{
|
||||
const char *pPickerName = m_pPicker->GetSelectedString( );
|
||||
pActionKeys->SetString( "choice", pPickerName );
|
||||
}
|
||||
else
|
||||
{
|
||||
void *pPickerPtr = m_pPicker->GetSelectedPtr( );
|
||||
pActionKeys->SetPtr( "choice", pPickerPtr );
|
||||
}
|
||||
|
||||
if ( m_pContextKeyValues )
|
||||
{
|
||||
pActionKeys->AddSubKey( m_pContextKeyValues );
|
||||
m_pContextKeyValues = NULL;
|
||||
}
|
||||
PostActionSignal( pActionKeys );
|
||||
CloseModal();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "Cancel" ) )
|
||||
{
|
||||
CloseModal();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( pCommand );
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,239 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "matsys_controls/proceduraltexturepanel.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "pixelwriter.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CProceduralTexturePanel::CProceduralTexturePanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
|
||||
{
|
||||
m_pImageBuffer = NULL;
|
||||
m_bMaintainProportions = false;
|
||||
m_bUsePaintRect = false;
|
||||
m_PaintRect.x = m_PaintRect.y = 0;
|
||||
m_PaintRect.width = m_PaintRect.height = 0;
|
||||
}
|
||||
|
||||
CProceduralTexturePanel::~CProceduralTexturePanel()
|
||||
{
|
||||
CleanUp();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// initialization, shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CProceduralTexturePanel::Init( int nWidth, int nHeight, bool bAllocateImageBuffer )
|
||||
{
|
||||
m_nWidth = nWidth;
|
||||
m_nHeight = nHeight;
|
||||
if ( bAllocateImageBuffer )
|
||||
{
|
||||
m_pImageBuffer = new BGRA8888_t[nWidth * nHeight];
|
||||
}
|
||||
|
||||
m_TextureSubRect.x = m_TextureSubRect.y = 0;
|
||||
m_TextureSubRect.width = nWidth;
|
||||
m_TextureSubRect.height = nHeight;
|
||||
|
||||
char pTemp[512];
|
||||
Q_snprintf( pTemp, 512, "__%s", GetName() );
|
||||
|
||||
ITexture *pTex = MaterialSystem()->CreateProceduralTexture( pTemp, TEXTURE_GROUP_VGUI,
|
||||
m_nWidth, m_nHeight, IMAGE_FORMAT_BGRX8888,
|
||||
TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT | TEXTUREFLAGS_NOMIP |
|
||||
TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_PROCEDURAL | TEXTUREFLAGS_SINGLECOPY );
|
||||
pTex->SetTextureRegenerator( this );
|
||||
m_ProceduralTexture.Init( pTex );
|
||||
|
||||
KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
|
||||
pVMTKeyValues->SetString( "$basetexture", pTemp );
|
||||
pVMTKeyValues->SetInt( "$nocull", 1 );
|
||||
pVMTKeyValues->SetInt( "$nodebug", 1 );
|
||||
m_ProceduralMaterial.Init( MaterialSystem()->CreateMaterial( pTemp, pVMTKeyValues ));
|
||||
|
||||
m_nTextureID = MatSystemSurface()->CreateNewTextureID( false );
|
||||
MatSystemSurface()->DrawSetTextureMaterial( m_nTextureID, m_ProceduralMaterial );
|
||||
return true;
|
||||
}
|
||||
|
||||
void CProceduralTexturePanel::Shutdown()
|
||||
{
|
||||
CleanUp();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Maintain proportions when drawing
|
||||
//-----------------------------------------------------------------------------
|
||||
void CProceduralTexturePanel::MaintainProportions( bool bEnable )
|
||||
{
|
||||
m_bMaintainProportions = bEnable;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the image buffer + dimensions
|
||||
//-----------------------------------------------------------------------------
|
||||
void CProceduralTexturePanel::CleanUp()
|
||||
{
|
||||
if ( (ITexture*)m_ProceduralTexture )
|
||||
{
|
||||
m_ProceduralTexture->SetTextureRegenerator( NULL );
|
||||
}
|
||||
m_ProceduralTexture.Shutdown();
|
||||
m_ProceduralMaterial.Shutdown();
|
||||
|
||||
if ( m_pImageBuffer )
|
||||
{
|
||||
delete[] m_pImageBuffer;
|
||||
m_pImageBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Default implementation of regenerate texture bits
|
||||
//-----------------------------------------------------------------------------
|
||||
void CProceduralTexturePanel::RegenerateTextureBits( ITexture *pTexture, IVTFTexture *pVTFTexture, Rect_t *pRect )
|
||||
{
|
||||
Assert( m_pImageBuffer );
|
||||
Assert( pVTFTexture->FrameCount() == 1 );
|
||||
Assert( pVTFTexture->FaceCount() == 1 );
|
||||
Assert( !pTexture->IsMipmapped() );
|
||||
|
||||
int nWidth, nHeight, nDepth;
|
||||
pVTFTexture->ComputeMipLevelDimensions( 0, &nWidth, &nHeight, &nDepth );
|
||||
Assert( nDepth == 1 );
|
||||
Assert( nWidth == m_nWidth && nHeight == m_nHeight );
|
||||
|
||||
CPixelWriter pixelWriter;
|
||||
pixelWriter.SetPixelMemory( pVTFTexture->Format(),
|
||||
pVTFTexture->ImageData( 0, 0, 0 ), pVTFTexture->RowSizeInBytes( 0 ) );
|
||||
|
||||
for ( int y = 0; y < nHeight; ++y )
|
||||
{
|
||||
pixelWriter.Seek( 0, y );
|
||||
BGRA8888_t *pTexel = &m_pImageBuffer[y * m_nWidth];
|
||||
for ( int x = 0; x < nWidth; ++x, ++pTexel )
|
||||
{
|
||||
pixelWriter.WritePixel( pTexel->r, pTexel->g, pTexel->b, pTexel->a );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the image buffer + dimensions
|
||||
//-----------------------------------------------------------------------------
|
||||
BGRA8888_t *CProceduralTexturePanel::GetImageBuffer()
|
||||
{
|
||||
Assert( m_pImageBuffer );
|
||||
return m_pImageBuffer;
|
||||
}
|
||||
|
||||
int CProceduralTexturePanel::GetImageWidth() const
|
||||
{
|
||||
return m_nWidth;
|
||||
}
|
||||
|
||||
int CProceduralTexturePanel::GetImageHeight() const
|
||||
{
|
||||
return m_nHeight;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the paint rect
|
||||
//-----------------------------------------------------------------------------
|
||||
void CProceduralTexturePanel::SetPaintRect( const Rect_t *pPaintRect )
|
||||
{
|
||||
m_bUsePaintRect = ( pPaintRect != NULL );
|
||||
if ( m_bUsePaintRect )
|
||||
{
|
||||
m_PaintRect = *pPaintRect;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the draw rect
|
||||
//-----------------------------------------------------------------------------
|
||||
void CProceduralTexturePanel::SetTextureSubRect( const Rect_t &subRect )
|
||||
{
|
||||
m_TextureSubRect = subRect;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redownloads the procedural texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CProceduralTexturePanel::DownloadTexture()
|
||||
{
|
||||
m_ProceduralTexture->Download();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints the texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CProceduralTexturePanel::Paint( void )
|
||||
{
|
||||
vgui::surface()->DrawSetTexture( m_nTextureID );
|
||||
vgui::surface()->DrawSetColor( 255, 255, 255, 255 );
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
if ( m_bUsePaintRect )
|
||||
{
|
||||
x = m_PaintRect.x;
|
||||
y = m_PaintRect.y;
|
||||
w = m_PaintRect.width;
|
||||
h = m_PaintRect.height;
|
||||
}
|
||||
|
||||
if ( m_bMaintainProportions )
|
||||
{
|
||||
if ( m_TextureSubRect.width > m_TextureSubRect.height )
|
||||
{
|
||||
h = w * m_TextureSubRect.height / m_TextureSubRect.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = h * m_TextureSubRect.width / m_TextureSubRect.height;
|
||||
}
|
||||
}
|
||||
|
||||
// Rotated version of the bitmap!
|
||||
// Rotate about the center of the bitmap
|
||||
vgui::Vertex_t verts[4];
|
||||
verts[0].m_Position.Init( x, y );
|
||||
verts[0].m_TexCoord.Init( (float)m_TextureSubRect.x / m_nWidth, (float)m_TextureSubRect.y / m_nHeight );
|
||||
|
||||
verts[1].m_Position.Init( w+x, y );
|
||||
verts[1].m_TexCoord.Init( (float)(m_TextureSubRect.x + m_TextureSubRect.width) / m_nWidth, (float)m_TextureSubRect.y / m_nHeight );
|
||||
|
||||
verts[2].m_Position.Init( w+x, h+y );
|
||||
verts[2].m_TexCoord.Init( (float)(m_TextureSubRect.x + m_TextureSubRect.width) / m_nWidth, (float)(m_TextureSubRect.y + m_TextureSubRect.height) / m_nHeight );
|
||||
|
||||
verts[3].m_Position.Init( x, h+y );
|
||||
verts[3].m_TexCoord.Init( (float)m_TextureSubRect.x / m_nWidth, (float)(m_TextureSubRect.y + m_TextureSubRect.height) / m_nHeight );
|
||||
|
||||
vgui::surface()->DrawTexturedPolygon( 4, verts );
|
||||
}
|
||||
@@ -0,0 +1,485 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "matsys_controls/sequencepicker.h"
|
||||
|
||||
#include "tier1/utldict.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "studio.h"
|
||||
#include "vgui/IInput.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui_controls/Splitter.h"
|
||||
#include "vgui_controls/PropertyPage.h"
|
||||
#include "vgui_controls/PropertySheet.h"
|
||||
#include "vgui_controls/ListPanel.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Sequence Picker
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sort by sequence name
|
||||
//-----------------------------------------------------------------------------
|
||||
static int __cdecl SequenceSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 )
|
||||
{
|
||||
const char *string1 = item1.kv->GetString("sequence");
|
||||
const char *string2 = item2.kv->GetString("sequence");
|
||||
return stricmp( string1, string2 );
|
||||
}
|
||||
|
||||
static int __cdecl ActivitySortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 )
|
||||
{
|
||||
const char *string1 = item1.kv->GetString("activity");
|
||||
const char *string2 = item2.kv->GetString("activity");
|
||||
return stricmp( string1, string2 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CSequencePicker::CSequencePicker( vgui::Panel *pParent, int nFlags ) : BaseClass( pParent, "SequencePicker" )
|
||||
{
|
||||
m_hSelectedMDL = MDLHANDLE_INVALID;
|
||||
|
||||
// property sheet - revisions, changes, etc.
|
||||
m_pPreviewSplitter = new Splitter( this, "PreviewSplitter", SPLITTER_MODE_HORIZONTAL, 1 );
|
||||
|
||||
vgui::Panel *pSplitterTopSide = m_pPreviewSplitter->GetChild( 0 );
|
||||
vgui::Panel *pSplitterBottomSide = m_pPreviewSplitter->GetChild( 1 );
|
||||
|
||||
// MDL preview
|
||||
m_pMDLPreview = new CMDLPanel( pSplitterTopSide, "MDLPreview" );
|
||||
SetSkipChildDuringPainting( m_pMDLPreview );
|
||||
|
||||
m_pViewsSheet = new vgui::PropertySheet( pSplitterBottomSide, "ViewsSheet" );
|
||||
m_pViewsSheet->AddActionSignalTarget( this );
|
||||
|
||||
// sequences
|
||||
m_pSequencesPage = NULL;
|
||||
m_pSequencesList = NULL;
|
||||
if ( nFlags & PICK_SEQUENCES )
|
||||
{
|
||||
m_pSequencesPage = new PropertyPage( m_pViewsSheet, "SequencesPage" );
|
||||
m_pViewsSheet->AddPage( m_pSequencesPage, "Sequences" );
|
||||
m_pSequencesList = new ListPanel( m_pSequencesPage, "SequencesList" );
|
||||
m_pSequencesList->AddColumnHeader( 0, "sequence", "sequence", 52, 0 );
|
||||
m_pSequencesList->AddActionSignalTarget( this );
|
||||
m_pSequencesList->SetSelectIndividualCells( true );
|
||||
m_pSequencesList->SetEmptyListText(".MDL file contains no activities");
|
||||
m_pSequencesList->SetDragEnabled( true );
|
||||
m_pSequencesList->SetAutoResize( Panel::PIN_TOPLEFT, Panel::AUTORESIZE_DOWNANDRIGHT, 0, 0, 0, 0 );
|
||||
m_pSequencesList->SetSortFunc( 0, SequenceSortFunc );
|
||||
m_pSequencesList->SetSortColumn( 0 );
|
||||
}
|
||||
|
||||
// Activities
|
||||
m_pActivitiesPage = NULL;
|
||||
m_pActivitiesList = NULL;
|
||||
if ( nFlags & PICK_ACTIVITIES )
|
||||
{
|
||||
m_pActivitiesPage = new PropertyPage( m_pViewsSheet, "ActivitiesPage" );
|
||||
m_pViewsSheet->AddPage( m_pActivitiesPage, "Activities" );
|
||||
m_pActivitiesList = new ListPanel( m_pActivitiesPage, "ActivitiesList" );
|
||||
m_pActivitiesList->AddColumnHeader( 0, "activity", "activity", 52, 0 );
|
||||
m_pActivitiesList->AddActionSignalTarget( this );
|
||||
m_pActivitiesList->SetSelectIndividualCells( true );
|
||||
m_pActivitiesList->SetEmptyListText( ".MDL file contains no activities" );
|
||||
m_pActivitiesList->SetDragEnabled( true );
|
||||
m_pActivitiesList->SetAutoResize( Panel::PIN_TOPLEFT, Panel::AUTORESIZE_DOWNANDRIGHT, 0, 0, 0, 0 );
|
||||
m_pActivitiesList->SetSortFunc( 0, ActivitySortFunc );
|
||||
m_pActivitiesList->SetSortColumn( 0 );
|
||||
}
|
||||
|
||||
// Load layout settings; has to happen before pinning occurs in code
|
||||
LoadControlSettingsAndUserConfig( "resource/sequencepicker.res" );
|
||||
|
||||
SETUP_PANEL( this );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CSequencePicker::~CSequencePicker()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Performs layout
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSequencePicker::PerformLayout()
|
||||
{
|
||||
// NOTE: This call should cause auto-resize to occur
|
||||
// which should fix up the width of the panels
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
// Layout the mdl splitter
|
||||
m_pPreviewSplitter->SetBounds( 0, 0, w, h );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: rebuilds the list of activities + sequences
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSequencePicker::RefreshActivitiesAndSequencesList()
|
||||
{
|
||||
if ( m_pActivitiesList )
|
||||
{
|
||||
m_pActivitiesList->RemoveAll();
|
||||
}
|
||||
|
||||
if ( m_pSequencesList )
|
||||
{
|
||||
m_pSequencesList->RemoveAll();
|
||||
}
|
||||
|
||||
m_pMDLPreview->SetSequence( 0 );
|
||||
|
||||
if ( m_hSelectedMDL == MDLHANDLE_INVALID )
|
||||
return;
|
||||
|
||||
studiohdr_t *hdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
|
||||
|
||||
CUtlDict<int, unsigned short> activityNames( true, 0, hdr->GetNumSeq() );
|
||||
|
||||
for (int j = 0; j < hdr->GetNumSeq(); j++)
|
||||
{
|
||||
if ( /*g_viewerSettings.showHidden ||*/ !(hdr->pSeqdesc(j).flags & STUDIO_HIDDEN))
|
||||
{
|
||||
const char *pActivityName = hdr->pSeqdesc(j).pszActivityName();
|
||||
if ( m_pActivitiesList && pActivityName && pActivityName[0] )
|
||||
{
|
||||
// Multiple sequences can have the same activity name; only add unique activity names
|
||||
if ( activityNames.Find( pActivityName ) == activityNames.InvalidIndex() )
|
||||
{
|
||||
KeyValues *pkv = new KeyValues("node", "activity", pActivityName );
|
||||
int nItemID = m_pActivitiesList->AddItem( pkv, 0, false, false );
|
||||
|
||||
KeyValues *pDrag = new KeyValues( "drag", "text", pActivityName );
|
||||
pDrag->SetString( "texttype", "activityName" );
|
||||
pDrag->SetString( "mdl", vgui::MDLCache()->GetModelName( m_hSelectedMDL ) );
|
||||
m_pActivitiesList->SetItemDragData( nItemID, pDrag );
|
||||
|
||||
activityNames.Insert( pActivityName, j );
|
||||
}
|
||||
}
|
||||
|
||||
const char *pSequenceName = hdr->pSeqdesc(j).pszLabel();
|
||||
if ( m_pSequencesList && pSequenceName && pSequenceName[0] )
|
||||
{
|
||||
KeyValues *pkv = new KeyValues("node", "sequence", pSequenceName);
|
||||
int nItemID = m_pSequencesList->AddItem( pkv, 0, false, false );
|
||||
|
||||
KeyValues *pDrag = new KeyValues( "drag", "text", pSequenceName );
|
||||
pDrag->SetString( "texttype", "sequenceName" );
|
||||
pDrag->SetString( "mdl", vgui::MDLCache()->GetModelName( m_hSelectedMDL ) );
|
||||
m_pSequencesList->SetItemDragData( nItemID, pDrag );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_pSequencesList )
|
||||
{
|
||||
m_pSequencesList->SortList();
|
||||
}
|
||||
|
||||
if ( m_pActivitiesList )
|
||||
{
|
||||
m_pActivitiesList->SortList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Selects an sequence based on an activity
|
||||
//-----------------------------------------------------------------------------
|
||||
int SelectWeightedSequence( studiohdr_t *pstudiohdr, int activity, int curSequence )
|
||||
{
|
||||
if (! pstudiohdr)
|
||||
return 0;
|
||||
|
||||
VerifySequenceIndex( pstudiohdr );
|
||||
|
||||
int weighttotal = 0;
|
||||
int seq = ACTIVITY_NOT_AVAILABLE;
|
||||
int weight = 0;
|
||||
for (int i = 0; i < pstudiohdr->GetNumSeq(); i++)
|
||||
{
|
||||
int curActivity = GetSequenceActivity( pstudiohdr, i, &weight );
|
||||
if (curActivity == activity)
|
||||
{
|
||||
if ( curSequence == i && weight < 0 )
|
||||
{
|
||||
seq = i;
|
||||
break;
|
||||
}
|
||||
weighttotal += iabs(weight);
|
||||
|
||||
int randomValue;
|
||||
if ( IsInPrediction() )
|
||||
randomValue = SharedRandomInt( "SelectWeightedSequence", 0, weighttotal - 1, i );
|
||||
else
|
||||
randomValue = RandomInt( 0, weighttotal - 1 );
|
||||
|
||||
if (!weighttotal || randomValue < iabs(weight))
|
||||
seq = i;
|
||||
}
|
||||
}
|
||||
|
||||
return seq;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the selected activity/sequence
|
||||
//-----------------------------------------------------------------------------
|
||||
CSequencePicker::PickType_t CSequencePicker::GetSelectedSequenceType( )
|
||||
{
|
||||
if ( m_pSequencesPage && ( m_pViewsSheet->GetActivePage() == m_pSequencesPage ) )
|
||||
return PICK_SEQUENCES;
|
||||
if ( m_pActivitiesPage && ( m_pViewsSheet->GetActivePage() == m_pActivitiesPage ) )
|
||||
return PICK_ACTIVITIES;
|
||||
return PICK_NONE;
|
||||
}
|
||||
|
||||
const char *CSequencePicker::GetSelectedSequenceName( )
|
||||
{
|
||||
if ( m_pSequencesPage && ( m_pViewsSheet->GetActivePage() == m_pSequencesPage ) )
|
||||
{
|
||||
int nIndex = m_pSequencesList->GetSelectedItem( 0 );
|
||||
if ( nIndex >= 0 )
|
||||
{
|
||||
KeyValues *pkv = m_pSequencesList->GetItem( nIndex );
|
||||
return pkv->GetString( "sequence", NULL );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( m_pActivitiesPage && ( m_pViewsSheet->GetActivePage() == m_pActivitiesPage ) )
|
||||
{
|
||||
int nIndex = m_pActivitiesList->GetSelectedItem( 0 );
|
||||
if ( nIndex >= 0 )
|
||||
{
|
||||
KeyValues *pkv = m_pActivitiesList->GetItem( nIndex );
|
||||
return pkv->GetString( "activity", NULL );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Plays the selected activity
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSequencePicker::PlayActivity( const char *pActivityName )
|
||||
{
|
||||
studiohdr_t *pstudiohdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
|
||||
for ( int i = 0; i < pstudiohdr->GetNumSeq(); i++ )
|
||||
{
|
||||
mstudioseqdesc_t &seqdesc = pstudiohdr->pSeqdesc( i );
|
||||
if ( stricmp( seqdesc.pszActivityName(), pActivityName ) == 0 )
|
||||
{
|
||||
// FIXME: Add weighted sequence selection logic?
|
||||
m_pMDLPreview->SetSequence( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Plays the selected sequence
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSequencePicker::PlaySequence( const char *pSequenceName )
|
||||
{
|
||||
studiohdr_t *pstudiohdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
|
||||
for (int i = 0; i < pstudiohdr->GetNumSeq(); i++)
|
||||
{
|
||||
mstudioseqdesc_t &seqdesc = pstudiohdr->pSeqdesc( i );
|
||||
if ( !Q_stricmp( seqdesc.pszLabel(), pSequenceName ) )
|
||||
{
|
||||
m_pMDLPreview->SetSequence( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called when a page is shown
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSequencePicker::OnPageChanged( )
|
||||
{
|
||||
if ( m_pSequencesPage && ( m_pViewsSheet->GetActivePage() == m_pSequencesPage ) )
|
||||
{
|
||||
const char *pSequenceName = GetSelectedSequenceName();
|
||||
if ( pSequenceName )
|
||||
{
|
||||
PlaySequence( pSequenceName );
|
||||
PostActionSignal( new KeyValues( "SequencePreviewChanged", "sequence", pSequenceName ) );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_pActivitiesPage && ( m_pViewsSheet->GetActivePage() == m_pActivitiesPage ) )
|
||||
{
|
||||
const char *pActivityName = GetSelectedSequenceName();
|
||||
if ( pActivityName )
|
||||
{
|
||||
PlayActivity( pActivityName );
|
||||
PostActionSignal( new KeyValues( "SequencePreviewChanged", "activity", pActivityName ) );
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes dialog on text changing
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSequencePicker::OnItemSelected( KeyValues *kv )
|
||||
{
|
||||
Panel *pPanel = (Panel *)kv->GetPtr("panel", NULL);
|
||||
if ( m_pSequencesList && (pPanel == m_pSequencesList ) )
|
||||
{
|
||||
const char *pSequenceName = GetSelectedSequenceName();
|
||||
if ( pSequenceName )
|
||||
{
|
||||
PlaySequence( pSequenceName );
|
||||
PostActionSignal( new KeyValues( "SequencePreviewChanged", "sequence", pSequenceName ) );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_pActivitiesList && ( pPanel == m_pActivitiesList ) )
|
||||
{
|
||||
const char *pActivityName = GetSelectedSequenceName();
|
||||
if ( pActivityName )
|
||||
{
|
||||
PlayActivity( pActivityName );
|
||||
PostActionSignal( new KeyValues( "SequencePreviewChanged", "activity", pActivityName ) );
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the MDL to select sequences in
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSequencePicker::SetMDL( const char *pMDLName )
|
||||
{
|
||||
m_hSelectedMDL = pMDLName ? vgui::MDLCache()->FindMDL( pMDLName ) : MDLHANDLE_INVALID;
|
||||
if ( vgui::MDLCache()->IsErrorModel( m_hSelectedMDL ) )
|
||||
{
|
||||
m_hSelectedMDL = MDLHANDLE_INVALID;
|
||||
}
|
||||
m_pMDLPreview->SetMDL( m_hSelectedMDL );
|
||||
m_pMDLPreview->LookAtMDL();
|
||||
RefreshActivitiesAndSequencesList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: Modal picker frame
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CSequencePickerFrame::CSequencePickerFrame( vgui::Panel *pParent, int nFlags ) : BaseClass( pParent, "SequencePickerFrame" )
|
||||
{
|
||||
SetDeleteSelfOnClose( true );
|
||||
m_pPicker = new CSequencePicker( this, nFlags );
|
||||
m_pPicker->AddActionSignalTarget( this );
|
||||
m_pOpenButton = new Button( this, "OpenButton", "#FileOpenDialog_Open", this, "Open" );
|
||||
m_pCancelButton = new Button( this, "CancelButton", "#FileOpenDialog_Cancel", this, "Cancel" );
|
||||
SetBlockDragChaining( true );
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/sequencepickerframe.res" );
|
||||
|
||||
m_pOpenButton->SetEnabled( false );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Activate the dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSequencePickerFrame::DoModal( const char *pMDLName )
|
||||
{
|
||||
m_pPicker->SetMDL( pMDLName );
|
||||
BaseClass::DoModal();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On mdl preview changed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSequencePickerFrame::OnSequencePreviewChanged( KeyValues *pKeyValues )
|
||||
{
|
||||
const char *pSequence = pKeyValues->GetString( "sequence", NULL );
|
||||
const char *pActivity = pKeyValues->GetString( "activity", NULL );
|
||||
m_pOpenButton->SetEnabled( pSequence || pActivity );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On command
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSequencePickerFrame::OnCommand( const char *pCommand )
|
||||
{
|
||||
if ( !Q_stricmp( pCommand, "Open" ) )
|
||||
{
|
||||
CSequencePicker::PickType_t type = m_pPicker->GetSelectedSequenceType( );
|
||||
if (( type == CSequencePicker::PICK_SEQUENCES ) || ( type == CSequencePicker::PICK_ACTIVITIES ))
|
||||
{
|
||||
const char *pSequenceName = m_pPicker->GetSelectedSequenceName();
|
||||
if ( pSequenceName )
|
||||
{
|
||||
if ( type == CSequencePicker::PICK_SEQUENCES )
|
||||
{
|
||||
PostActionSignal( new KeyValues("SequenceSelected", "sequence", pSequenceName ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
PostActionSignal( new KeyValues("SequenceSelected", "activity", pSequenceName ) );
|
||||
}
|
||||
CloseModal();
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "Cancel" ) )
|
||||
{
|
||||
CloseModal();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( pCommand );
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "matsys_controls/tgapreviewpanel.h"
|
||||
#include "bitmap/tgaloader.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// TGA Preview panel
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CTGAPreviewPanel::CTGAPreviewPanel( vgui::Panel *pParent, const char *pName ) :
|
||||
BaseClass( pParent, pName )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the current TGA
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTGAPreviewPanel::SetTGA( const char *pFullPath )
|
||||
{
|
||||
int nWidth, nHeight;
|
||||
ImageFormat format;
|
||||
float flGamma;
|
||||
|
||||
CUtlBuffer buf;
|
||||
if ( !g_pFullFileSystem->ReadFile( pFullPath, NULL, buf ) )
|
||||
{
|
||||
Warning( "Can't open TGA file: %s\n", pFullPath );
|
||||
return;
|
||||
}
|
||||
|
||||
TGALoader::GetInfo( buf, &nWidth, &nHeight, &format, &flGamma );
|
||||
|
||||
Shutdown();
|
||||
Init( nWidth, nHeight, true );
|
||||
m_TGAName = pFullPath;
|
||||
|
||||
buf.SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
|
||||
if ( !TGALoader::Load( (unsigned char*)GetImageBuffer(), buf,
|
||||
nWidth, nHeight, IMAGE_FORMAT_BGRA8888, flGamma, false ) )
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
else
|
||||
{
|
||||
DownloadTexture();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the current TGA
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CTGAPreviewPanel::GetTGA() const
|
||||
{
|
||||
return m_TGAName;
|
||||
}
|
||||
@@ -0,0 +1,458 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "matsys_controls/vmtpanel.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "vgui_controls/ScrollBar.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "vgui_controls/ToolWindow.h"
|
||||
#include "tier2/renderutils.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Enums
|
||||
//-----------------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
SCROLLBAR_SIZE=18, // the width of a scrollbar
|
||||
WINDOW_BORDER_WIDTH=2 // the width of the window's border
|
||||
};
|
||||
|
||||
#define SPHERE_RADIUS 10.0f
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVMTPanel::CVMTPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
|
||||
{
|
||||
m_bUseActualSize = true;
|
||||
m_pMaterial = NULL;
|
||||
|
||||
m_pHorizontalBar = new ScrollBar( this, "HorizScrollBar", false );
|
||||
m_pHorizontalBar->AddActionSignalTarget(this);
|
||||
m_pHorizontalBar->SetVisible(false);
|
||||
|
||||
m_pVerticalBar = new ScrollBar( this, "VertScrollBar", true );
|
||||
m_pVerticalBar->AddActionSignalTarget(this);
|
||||
m_pVerticalBar->SetVisible(false);
|
||||
|
||||
LookAt( SPHERE_RADIUS );
|
||||
|
||||
m_pLightmapTexture.Init( "//platform/materials/debug/defaultlightmap", "editor" );
|
||||
m_DefaultEnvCubemap.Init( "editor/cubemap", "editor", true );
|
||||
}
|
||||
|
||||
CVMTPanel::~CVMTPanel()
|
||||
{
|
||||
m_pLightmapTexture.Shutdown();
|
||||
m_DefaultEnvCubemap.Shutdown();
|
||||
if (m_pMaterial)
|
||||
{
|
||||
m_pMaterial->DecrementReferenceCount();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scheme
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
SetBorder( pScheme->GetBorder( "MenuBorder") );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set the material to draw
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::SetMaterial( IMaterial *pMaterial )
|
||||
{
|
||||
if (pMaterial)
|
||||
{
|
||||
pMaterial->IncrementReferenceCount();
|
||||
}
|
||||
if (m_pMaterial)
|
||||
{
|
||||
m_pMaterial->DecrementReferenceCount();
|
||||
}
|
||||
m_pMaterial = pMaterial;
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set rendering mode (stretch to full screen, or use actual size)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::RenderUsingActualSize( bool bEnable )
|
||||
{
|
||||
m_bUseActualSize = bEnable;
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: relayouts out the panel after any internal changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
return;
|
||||
|
||||
// Get the current size, see if it's big enough to view the entire thing
|
||||
int iWidth, iHeight;
|
||||
GetSize( iWidth, iHeight );
|
||||
|
||||
// In the case of stretching, just stretch to the size and blow off
|
||||
// the scrollbars. Same holds true if there's no material
|
||||
if (!m_bUseActualSize || !m_pMaterial)
|
||||
{
|
||||
m_iViewableWidth = iWidth;
|
||||
m_iViewableHeight = iHeight;
|
||||
m_pHorizontalBar->SetVisible(false);
|
||||
m_pVerticalBar->SetVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the size of the material...
|
||||
int iMaterialWidth = m_pMaterial->GetMappingWidth();
|
||||
int iMaterialHeight = m_pMaterial->GetMappingHeight();
|
||||
|
||||
// Check if the scroll bars are visible
|
||||
bool bHorizScrollVisible = (iMaterialWidth > iWidth);
|
||||
bool bVertScrollVisible = (iMaterialHeight > iHeight);
|
||||
|
||||
m_pHorizontalBar->SetVisible(bHorizScrollVisible);
|
||||
m_pVerticalBar->SetVisible(bVertScrollVisible);
|
||||
|
||||
// Shrink the bars if both are visible
|
||||
m_iViewableWidth = bVertScrollVisible ? iWidth - SCROLLBAR_SIZE - WINDOW_BORDER_WIDTH : iWidth;
|
||||
m_iViewableHeight = bHorizScrollVisible ? iHeight - SCROLLBAR_SIZE - WINDOW_BORDER_WIDTH : iHeight;
|
||||
|
||||
// Set the position of the horizontal bar...
|
||||
if (bHorizScrollVisible)
|
||||
{
|
||||
m_pHorizontalBar->SetPos(0, iHeight - SCROLLBAR_SIZE);
|
||||
m_pHorizontalBar->SetSize( m_iViewableWidth, SCROLLBAR_SIZE );
|
||||
|
||||
m_pHorizontalBar->SetRangeWindow( m_iViewableWidth );
|
||||
m_pHorizontalBar->SetRange( 0, iMaterialWidth );
|
||||
|
||||
// FIXME: Change scroll amount based on how much is not visible?
|
||||
m_pHorizontalBar->SetButtonPressedScrollValue( 5 );
|
||||
}
|
||||
|
||||
// Set the position of the vertical bar...
|
||||
if (bVertScrollVisible)
|
||||
{
|
||||
m_pVerticalBar->SetPos(iWidth - SCROLLBAR_SIZE, 0);
|
||||
m_pVerticalBar->SetSize(SCROLLBAR_SIZE, m_iViewableHeight);
|
||||
|
||||
m_pVerticalBar->SetRangeWindow( m_iViewableHeight );
|
||||
m_pVerticalBar->SetRange( 0, iMaterialHeight);
|
||||
m_pVerticalBar->SetButtonPressedScrollValue( 5 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// paint it stretched to the window size
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::DrawStretchedToPanel( CMeshBuilder &meshBuilder )
|
||||
{
|
||||
// Draw a polygon the size of the panel
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( 0, 0, 0 );
|
||||
meshBuilder.TexCoord2f( 0, 0, 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( 0, m_iViewableHeight, 0 );
|
||||
meshBuilder.TexCoord2f( 0, 0, 1 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( m_iViewableWidth, m_iViewableHeight, 0 );
|
||||
meshBuilder.TexCoord2f( 0, 1, 1 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( m_iViewableWidth, 0, 0 );
|
||||
meshBuilder.TexCoord2f( 0, 0, 1 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// paint it actual size
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::DrawActualSize( CMeshBuilder &meshBuilder )
|
||||
{
|
||||
// Check the size of the material...
|
||||
int iMaterialWidth = m_pMaterial->GetMappingWidth();
|
||||
int iMaterialHeight = m_pMaterial->GetMappingHeight();
|
||||
|
||||
Vector2D ul;
|
||||
Vector2D lr;
|
||||
Vector2D tul;
|
||||
Vector2D tlr;
|
||||
|
||||
if (m_iViewableWidth >= iMaterialWidth)
|
||||
{
|
||||
// Center the material if we've got enough horizontal space
|
||||
ul.x = (m_iViewableWidth - iMaterialWidth) * 0.5f;
|
||||
lr.x = ul.x + iMaterialWidth;
|
||||
tul.x = 0.0f; tlr.x = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the scrollbars here...
|
||||
int val = m_pHorizontalBar->GetValue();
|
||||
tul.x = (float)val / (float)iMaterialWidth;
|
||||
tlr.x = tul.x + (float)m_iViewableWidth / (float)iMaterialWidth;
|
||||
|
||||
ul.x = 0;
|
||||
lr.x = m_iViewableWidth;
|
||||
}
|
||||
|
||||
if (m_iViewableHeight >= iMaterialHeight)
|
||||
{
|
||||
// Center the material if we've got enough vertical space
|
||||
ul.y = (m_iViewableHeight - iMaterialHeight) * 0.5f;
|
||||
lr.y = ul.y + iMaterialHeight;
|
||||
tul.y = 0.0f; tlr.y = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the scrollbars here...
|
||||
int val = m_pVerticalBar->GetValue();
|
||||
|
||||
tul.y = (float)val / (float)iMaterialHeight;
|
||||
tlr.y = tul.y + (float)m_iViewableHeight / (float)iMaterialHeight;
|
||||
|
||||
ul.y = 0;
|
||||
lr.y = m_iViewableHeight;
|
||||
}
|
||||
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( ul.x, ul.y, 0 );
|
||||
meshBuilder.TexCoord2f( 0, tul.x, tul.y );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( lr.x, ul.y, 0 );
|
||||
meshBuilder.TexCoord2f( 0, tlr.x, tul.y );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( lr.x, lr.y, 0 );
|
||||
meshBuilder.TexCoord2f( 0, tlr.x, tlr.y );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( ul.x, lr.y, 0 );
|
||||
meshBuilder.TexCoord2f( 0, tul.x, tlr.y );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw it on a sphere
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::RenderSphere( const Vector &vCenter, float flRadius, int nTheta, int nPhi )
|
||||
{
|
||||
int nVertices = nTheta * nPhi;
|
||||
int nIndices = 2 * ( nTheta + 1 ) * ( nPhi - 1 );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
pRenderContext->FogMode( MATERIAL_FOG_NONE );
|
||||
pRenderContext->SetNumBoneWeights( 0 );
|
||||
pRenderContext->Bind( m_pMaterial );
|
||||
pRenderContext->BindLightmapTexture( m_pLightmapTexture );
|
||||
pRenderContext->BindLocalCubemap( m_DefaultEnvCubemap );
|
||||
|
||||
IMesh* pMesh = pRenderContext->GetDynamicMesh();
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, nVertices, nIndices );
|
||||
|
||||
bool bIsUsingLightmap = m_pMaterial->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_LIGHTMAP );
|
||||
bool bIsUsingBumpedLightmap = m_pMaterial->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS );
|
||||
|
||||
int nLightmapWidth = m_pLightmapTexture->GetActualWidth();
|
||||
float flHalfLuxel = 0.5f / nLightmapWidth;
|
||||
|
||||
//
|
||||
// Build the index buffer.
|
||||
//
|
||||
int i, j;
|
||||
for ( i = 0; i < nPhi; ++i )
|
||||
{
|
||||
for ( j = 0; j < nTheta; ++j )
|
||||
{
|
||||
float u = j / ( float )(nTheta - 1);
|
||||
float v = i / ( float )(nPhi - 1);
|
||||
float theta = ( j != nTheta-1 ) ? 2.0f * M_PI * u : 0.0f;
|
||||
float phi = M_PI * v;
|
||||
|
||||
Vector vecPos;
|
||||
vecPos.x = flRadius * sin(phi) * cos(theta);
|
||||
vecPos.y = flRadius * sin(phi) * sin(theta);
|
||||
vecPos.z = flRadius * cos(phi);
|
||||
|
||||
Vector vecNormal = vecPos;
|
||||
VectorNormalize( vecNormal );
|
||||
|
||||
Vector4D vecTangentS;
|
||||
Vector vecTangentT;
|
||||
vecTangentS.Init( -vecPos.y, vecPos.x, 0.0f, 1.0f );
|
||||
if ( VectorNormalize( vecTangentS.AsVector3D() ) == 0.0f )
|
||||
{
|
||||
vecTangentS.Init( 1.0f, 0.0f, 0.0f, 1.0f );
|
||||
}
|
||||
|
||||
CrossProduct( vecNormal, vecTangentS.AsVector3D(), vecTangentT );
|
||||
|
||||
unsigned char red = (int)( u * 255.0f );
|
||||
unsigned char green = (int)( v * 255.0f );
|
||||
unsigned char blue = (int)( v * 255.0f );
|
||||
unsigned char alpha = (int)( v * 255.0f );
|
||||
|
||||
vecPos += vCenter;
|
||||
|
||||
float u1, u2, v1, v2;
|
||||
u1 = u2 = u;
|
||||
v1 = v2 = v;
|
||||
|
||||
if ( bIsUsingLightmap )
|
||||
{
|
||||
u1 = RemapVal( u1, 0.0f, 1.0f, flHalfLuxel, 0.25 - flHalfLuxel );
|
||||
|
||||
if ( bIsUsingBumpedLightmap )
|
||||
{
|
||||
u2 = 0.25f;
|
||||
v2 = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.Position3fv( vecPos.Base() );
|
||||
meshBuilder.Normal3fv( vecNormal.Base() );
|
||||
meshBuilder.Color4ub( red, green, blue, alpha );
|
||||
meshBuilder.TexCoord2f( 0, u, v );
|
||||
meshBuilder.TexCoord2f( 1, u1, v1 );
|
||||
meshBuilder.TexCoord2f( 2, u2, v2 );
|
||||
meshBuilder.TangentS3fv( vecTangentS.Base() );
|
||||
meshBuilder.TangentT3fv( vecTangentT.Base() );
|
||||
meshBuilder.UserData( vecTangentS.Base() );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Emit the triangle strips.
|
||||
//
|
||||
int idx = 0;
|
||||
for ( i = 0; i < nPhi - 1; ++i )
|
||||
{
|
||||
for ( j = 0; j < nTheta; ++j )
|
||||
{
|
||||
idx = nTheta * i + j;
|
||||
|
||||
meshBuilder.FastIndex( idx );
|
||||
meshBuilder.FastIndex( idx + nTheta );
|
||||
}
|
||||
|
||||
//
|
||||
// Emit a degenerate triangle to skip to the next row without
|
||||
// a connecting triangle.
|
||||
//
|
||||
if ( i < nPhi - 2 )
|
||||
{
|
||||
meshBuilder.FastIndex( idx + 1 );
|
||||
meshBuilder.FastIndex( idx + 1 + nTheta );
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Power of two FB texture
|
||||
//-----------------------------------------------------------------------------
|
||||
static CTextureReference s_pPowerOfTwoFrameBufferTexture;
|
||||
|
||||
static ITexture *GetPowerOfTwoFrameBufferTexture( void )
|
||||
{
|
||||
if( !s_pPowerOfTwoFrameBufferTexture )
|
||||
{
|
||||
s_pPowerOfTwoFrameBufferTexture.Init( materials->FindTexture( "_rt_PowerOfTwoFB", TEXTURE_GROUP_RENDER_TARGET ) );
|
||||
}
|
||||
|
||||
return s_pPowerOfTwoFrameBufferTexture;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// paint it!
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::OnPaint3D()
|
||||
{
|
||||
if (!m_pMaterial)
|
||||
return;
|
||||
|
||||
// Deal with refraction
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
if ( m_pMaterial->NeedsPowerOfTwoFrameBufferTexture() )
|
||||
{
|
||||
ITexture *pTexture = GetPowerOfTwoFrameBufferTexture();
|
||||
if ( pTexture && !pTexture->IsError() )
|
||||
{
|
||||
pRenderContext->CopyRenderTargetToTexture( pTexture );
|
||||
pRenderContext->SetFrameBufferCopyTexture( pTexture );
|
||||
}
|
||||
}
|
||||
|
||||
// Draw a background (translucent objects will appear that way)
|
||||
|
||||
// FIXME: Draw the outline of this panel?
|
||||
|
||||
pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
|
||||
|
||||
RenderSphere( vec3_origin, SPHERE_RADIUS, 20, 20 );
|
||||
/*
|
||||
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
||||
pRenderContext->LoadIdentity();
|
||||
pRenderContext->Ortho( 0, 0, m_iViewableWidth, m_iViewableHeight, 0, 1 );
|
||||
|
||||
pRenderContext->Bind( m_pMaterial );
|
||||
IMesh *pMesh = pRenderContext->GetDynamicMesh();
|
||||
CMeshBuilder meshBuilder;
|
||||
|
||||
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
|
||||
|
||||
if (!m_bUseActualSize)
|
||||
{
|
||||
DrawStretchedToPanel( meshBuilder );
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawActualSize( meshBuilder );
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "matsys_controls/vmtpicker.h"
|
||||
#include "matsys_controls/vmtpreviewpanel.h"
|
||||
#include "vgui_controls/Splitter.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Asset Picker with no preview
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVMTPicker::CVMTPicker( vgui::Panel *pParent, bool bAllowMultiselect ) :
|
||||
BaseClass( pParent, "VMT Files", "vmt", "materials", "vmtName" )
|
||||
{
|
||||
// Horizontal splitter for preview
|
||||
m_pPreviewSplitter = new Splitter( this, "PreviewSplitter", SPLITTER_MODE_VERTICAL, 1 );
|
||||
vgui::Panel *pSplitterLeftSide = m_pPreviewSplitter->GetChild( 0 );
|
||||
vgui::Panel *pSplitterRightSide = m_pPreviewSplitter->GetChild( 1 );
|
||||
|
||||
m_p2D3DSplitter = new Splitter( pSplitterRightSide, "2D3DSplitter", SPLITTER_MODE_HORIZONTAL, 1 );
|
||||
vgui::Panel *pSplitterTopSide = m_p2D3DSplitter->GetChild( 0 );
|
||||
vgui::Panel *pSplitterBottomSide = m_p2D3DSplitter->GetChild( 1 );
|
||||
|
||||
// VMT preview
|
||||
m_pVMTPreview2D = new CVMTPreviewPanel( pSplitterTopSide, "VMTPreview2D" );
|
||||
m_pVMTPreview3D = new CVMTPreviewPanel( pSplitterBottomSide, "VMTPreview3D" );
|
||||
m_pVMTPreview3D->DrawIn3DMode( true );
|
||||
|
||||
// Standard browser controls
|
||||
CreateStandardControls( pSplitterLeftSide, bAllowMultiselect );
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/vmtpicker.res" );
|
||||
}
|
||||
|
||||
CVMTPicker::~CVMTPicker()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Derived classes have this called when the previewed asset changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPicker::OnSelectedAssetPicked( const char *pAssetName )
|
||||
{
|
||||
m_pVMTPreview2D->SetVMT( pAssetName );
|
||||
m_pVMTPreview3D->SetVMT( pAssetName );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: Modal picker frame
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CVMTPickerFrame::CVMTPickerFrame( vgui::Panel *pParent, const char *pTitle, bool bAllowMultiselect ) :
|
||||
BaseClass( pParent )
|
||||
{
|
||||
SetAssetPicker( new CVMTPicker( this, bAllowMultiselect ) );
|
||||
LoadControlSettingsAndUserConfig( "resource/vmtpickerframe.res" );
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,625 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "matsys_controls/vmtpreviewpanel.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "materialsystem/MaterialSystemUtil.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
#define FOV 90.0f
|
||||
#define ZNEAR 0.1f
|
||||
#define ZFAR 2000.0f
|
||||
#define ROTATION_SPEED 40.0f // degrees/sec
|
||||
#define VIEW_DISTANCE 12.0f
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// VMT Preview panel
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVMTPreviewPanel::CVMTPreviewPanel( vgui::Panel *pParent, const char *pName ) :
|
||||
BaseClass( pParent, pName )
|
||||
{
|
||||
SetVMT( "//platform/materials/vgui/vtfnotloaded" );
|
||||
|
||||
m_pLightmapTexture.Init( "//platform/materials/debug/defaultlightmap", "editor" );
|
||||
m_DefaultEnvCubemap.Init( "editor/cubemap", "editor", true );
|
||||
m_LightDirection.Init( 0.0f, 1.0f, -1.0f );
|
||||
m_LightColor.SetColor( 255, 255, 255, 255 );
|
||||
m_flLightIntensity = 2.0f;
|
||||
m_bDrawIn3DMode = false;
|
||||
|
||||
// Reset the camera direction
|
||||
m_vecCameraDirection.Init( 1.0f, 0.0f, 0.0f );
|
||||
m_flLastRotationTime = Plat_FloatTime();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the current VMT
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::SetVMT( const char *pMaterialName )
|
||||
{
|
||||
m_Material.Init( pMaterialName, "editor material" );
|
||||
m_VMTName = pMaterialName;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the current VMT
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CVMTPreviewPanel::GetVMT() const
|
||||
{
|
||||
return m_VMTName;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// View it in 3D or 2D mode
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::DrawIn3DMode( bool b3DMode )
|
||||
{
|
||||
m_bDrawIn3DMode = b3DMode;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets up lighting state
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::SetupLightingState()
|
||||
{
|
||||
LightDesc_t desc;
|
||||
memset( &desc, 0, sizeof(desc) );
|
||||
|
||||
desc.m_Type = MATERIAL_LIGHT_DIRECTIONAL;
|
||||
|
||||
desc.m_Color[0] = m_LightColor.r();
|
||||
desc.m_Color[1] = m_LightColor.g();
|
||||
desc.m_Color[2] = m_LightColor.b();
|
||||
desc.m_Color *= m_flLightIntensity / 255.0f;
|
||||
|
||||
desc.m_Attenuation0 = 1.0f;
|
||||
desc.m_Attenuation1 = 0.0f;
|
||||
desc.m_Attenuation2 = 0.0f;
|
||||
desc.m_Flags = LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION0;
|
||||
|
||||
desc.m_Direction = m_LightDirection;
|
||||
VectorNormalize( desc.m_Direction );
|
||||
|
||||
desc.m_Theta = 0.0f;
|
||||
desc.m_Phi = 0.0f;
|
||||
desc.m_Falloff = 1.0f;
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
|
||||
pRenderContext->SetLight( 0, desc );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw a sphere
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::RenderSphere( const Vector &vCenter, float flRadius, int nTheta, int nPhi )
|
||||
{
|
||||
int nVertices = nTheta * nPhi;
|
||||
int nIndices = 2 * ( nTheta + 1 ) * ( nPhi - 1 );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
|
||||
IMesh* pMesh = pRenderContext->GetDynamicMesh();
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, nVertices, nIndices );
|
||||
|
||||
bool bIsUsingLightmap = m_Material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_LIGHTMAP );
|
||||
bool bIsUsingBumpedLightmap = m_Material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS );
|
||||
|
||||
int nLightmapWidth = m_pLightmapTexture->GetActualWidth();
|
||||
float flHalfLuxel = 0.5f / nLightmapWidth;
|
||||
|
||||
//
|
||||
// Build the index buffer.
|
||||
//
|
||||
int i, j;
|
||||
for ( i = 0; i < nPhi; ++i )
|
||||
{
|
||||
for ( j = 0; j < nTheta; ++j )
|
||||
{
|
||||
float u = j / ( float )(nTheta - 1);
|
||||
float v = i / ( float )(nPhi - 1);
|
||||
float theta = ( j != nTheta-1 ) ? 2.0f * M_PI * u : 0.0f;
|
||||
float phi = M_PI * v;
|
||||
|
||||
Vector vecPos;
|
||||
vecPos.x = flRadius * sin(phi) * cos(theta);
|
||||
vecPos.y = flRadius * sin(phi) * sin(theta);
|
||||
vecPos.z = flRadius * cos(phi);
|
||||
|
||||
Vector vecNormal = vecPos;
|
||||
VectorNormalize( vecNormal );
|
||||
|
||||
Vector4D vecTangentS;
|
||||
Vector vecTangentT;
|
||||
vecTangentS.Init( vecPos.z, -vecPos.x, 0.0f, 1.0f );
|
||||
if ( VectorNormalize( vecTangentS.AsVector3D() ) == 0.0f )
|
||||
{
|
||||
vecTangentS.Init( 1.0f, 0.0f, 0.0f, 1.0f );
|
||||
}
|
||||
|
||||
CrossProduct( vecNormal, vecTangentS.AsVector3D(), vecTangentT );
|
||||
|
||||
unsigned char red = (int)( u * 255.0f );
|
||||
unsigned char green = (int)( v * 255.0f );
|
||||
unsigned char blue = (int)( v * 255.0f );
|
||||
unsigned char alpha = (int)( v * 255.0f );
|
||||
|
||||
vecPos += vCenter;
|
||||
|
||||
float u1, u2, v1, v2;
|
||||
u1 = u2 = u;
|
||||
v1 = v2 = v;
|
||||
|
||||
if ( bIsUsingLightmap )
|
||||
{
|
||||
u1 = RemapVal( u1, 0.0f, 1.0f, flHalfLuxel, 0.25 - flHalfLuxel );
|
||||
|
||||
if ( bIsUsingBumpedLightmap )
|
||||
{
|
||||
u2 = 0.25f;
|
||||
v2 = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.Position3fv( vecPos.Base() );
|
||||
meshBuilder.Normal3fv( vecNormal.Base() );
|
||||
meshBuilder.Color4ub( red, green, blue, alpha );
|
||||
meshBuilder.TexCoord2f( 0, 2.0f * u, v );
|
||||
meshBuilder.TexCoord2f( 1, u1, v1 );
|
||||
meshBuilder.TexCoord2f( 2, u2, v2 );
|
||||
meshBuilder.TangentS3fv( vecTangentS.Base() );
|
||||
meshBuilder.TangentT3fv( vecTangentT.Base() );
|
||||
meshBuilder.BoneWeight( 0, 1.0f );
|
||||
meshBuilder.BoneMatrix( 0, 0 );
|
||||
meshBuilder.UserData( vecTangentS.Base() );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Emit the triangle strips.
|
||||
//
|
||||
int idx = 0;
|
||||
for ( i = 0; i < nPhi - 1; ++i )
|
||||
{
|
||||
for ( j = 0; j < nTheta; ++j )
|
||||
{
|
||||
idx = nTheta * i + j;
|
||||
|
||||
meshBuilder.FastIndex( idx );
|
||||
meshBuilder.FastIndex( idx + nTheta );
|
||||
}
|
||||
|
||||
//
|
||||
// Emit a degenerate triangle to skip to the next row without
|
||||
// a connecting triangle.
|
||||
//
|
||||
if ( i < nPhi - 2 )
|
||||
{
|
||||
meshBuilder.FastIndex( idx + 1 );
|
||||
meshBuilder.FastIndex( idx + 1 + nTheta );
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw sprite-card based materials
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::RenderSpriteCard( const Vector &vCenter, float flRadius )
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
IMesh *pMesh = pRenderContext->GetDynamicMesh();
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
|
||||
|
||||
// Draw a polygon the size of the panel
|
||||
meshBuilder.Position3fv( vCenter.Base() );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.TexCoord4f( 0, 0.0f, 0.0f, 1.0f, 1.0f );
|
||||
meshBuilder.TexCoord4f( 1, 0.0f, 0.0f, 1.0f, 1.0f );
|
||||
meshBuilder.TexCoord4f( 2, 0.0f, 0.0f, flRadius, 0.0f );
|
||||
meshBuilder.TexCoord2f( 3, 0, 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( vCenter.Base() );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.TexCoord4f( 0, 0.0f, 0.0f, 1.0f, 1.0f );
|
||||
meshBuilder.TexCoord4f( 1, 0.0f, 0.0f, 1.0f, 1.0f );
|
||||
meshBuilder.TexCoord4f( 2, 0.0f, 0.0f, flRadius, 0.0f );
|
||||
meshBuilder.TexCoord2f( 3, 0, 1 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( vCenter.Base() );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.TexCoord4f( 0, 0.0f, 0.0f, 1.0f, 1.0f );
|
||||
meshBuilder.TexCoord4f( 1, 0.0f, 0.0f, 1.0f, 1.0f );
|
||||
meshBuilder.TexCoord4f( 2, 0.0f, 0.0f, flRadius, 0.0f );
|
||||
meshBuilder.TexCoord2f( 3, 1, 1 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( vCenter.Base() );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.TexCoord4f( 0, 0.0f, 0.0f, 1.0f, 1.0f );
|
||||
meshBuilder.TexCoord4f( 1, 0.0f, 0.0f, 1.0f, 1.0f );
|
||||
meshBuilder.TexCoord4f( 2, 0.0f, 0.0f, flRadius, 0.0f );
|
||||
meshBuilder.TexCoord2f( 3, 1, 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints a regular texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::DrawRectangle( void )
|
||||
{
|
||||
// Get the aspect ratio of the material
|
||||
int tw = m_Material->GetMappingWidth();
|
||||
int th = m_Material->GetMappingHeight();
|
||||
|
||||
if ( tw <= 0 || th <= 0 )
|
||||
return;
|
||||
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
if ( w == 0 || h == 0 )
|
||||
return;
|
||||
|
||||
SetupOrthoMatrix( w, h );
|
||||
SetupLightingState();
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_VIEW );
|
||||
pRenderContext->LoadIdentity();
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
||||
pRenderContext->LoadIdentity();
|
||||
|
||||
IMesh* pMesh = pRenderContext->GetDynamicMesh();
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 4, 4 );
|
||||
|
||||
bool bIsUsingLightmap = m_Material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_LIGHTMAP );
|
||||
bool bIsUsingBumpedLightmap = m_Material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS );
|
||||
|
||||
int nLightmapWidth = m_pLightmapTexture->GetActualWidth();
|
||||
float flHalfLuxel = 0.5f / nLightmapWidth;
|
||||
Vector2D halfTexel( 0.5f / tw, 0.5f / th );
|
||||
|
||||
Vector vecNormal( 0.0f, 0.0f, 1.0f );
|
||||
Vector4D vecTangentS( 1.0f, 0.0f, 0.0f, 1.0f );
|
||||
Vector vecTangentT;
|
||||
CrossProduct( vecNormal, vecTangentS.AsVector3D(), vecTangentT );
|
||||
|
||||
float screenaspect = (float)tw / (float)th;
|
||||
float aspect = (float)w / (float)h;
|
||||
|
||||
float ratio = screenaspect / aspect;
|
||||
|
||||
// Screen is wider, need bars at top and bottom
|
||||
int x2, y2;
|
||||
int x, y;
|
||||
x = y = 0;
|
||||
int nXBorder = w > 15 ? 5 : w / 3;
|
||||
int nYBorder = h > 15 ? 5 : h / 3;
|
||||
w -= 2 * nXBorder;
|
||||
h -= 2 * nYBorder;
|
||||
if ( ratio > 1.0f )
|
||||
{
|
||||
int usetall = (float)w / screenaspect;
|
||||
y = ( h - usetall ) / 2;
|
||||
h = usetall;
|
||||
}
|
||||
// Screen is narrower, need bars at left/right
|
||||
else
|
||||
{
|
||||
int usewide = (float)h * screenaspect;
|
||||
x = ( w - usewide ) / 2;
|
||||
w = usewide;
|
||||
}
|
||||
x += nXBorder;
|
||||
y += nYBorder;
|
||||
|
||||
x2 = x+w; y2 = y+h;
|
||||
|
||||
float u = halfTexel.x;
|
||||
float v = halfTexel.y;
|
||||
|
||||
float u1_l, u1_r, v1_t, v1_b;
|
||||
float u2_l, u2_r, v2_t, v2_b;
|
||||
|
||||
u1_l = u2_l = u;
|
||||
u1_r = u2_r = 1.0f - u;
|
||||
v1_t = v2_t = v;
|
||||
v1_b = v2_b = 1.0f - v;
|
||||
|
||||
if ( bIsUsingLightmap )
|
||||
{
|
||||
u1_l = v1_t = flHalfLuxel;
|
||||
u1_r = v1_b = 0.25 - flHalfLuxel;
|
||||
if ( bIsUsingBumpedLightmap )
|
||||
{
|
||||
u2_l = u2_r = 0.25f;
|
||||
v2_t = v2_b = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.Position3f( x, y2, 0.0f );
|
||||
meshBuilder.Normal3fv( vecNormal.Base() );
|
||||
meshBuilder.Color4ub( 255, 0, 0, 255 );
|
||||
meshBuilder.TexCoord2f( 0, u, v );
|
||||
meshBuilder.TexCoord2f( 1, u1_l, v1_t );
|
||||
meshBuilder.TexCoord2f( 2, u2_l, v2_t );
|
||||
meshBuilder.TangentS3fv( vecTangentS.Base() );
|
||||
meshBuilder.TangentT3fv( vecTangentT.Base() );
|
||||
meshBuilder.BoneWeight( 0, 1.0f );
|
||||
meshBuilder.BoneMatrix( 0, 0 );
|
||||
meshBuilder.UserData( vecTangentS.Base() );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3f( x, y, 0.0f );
|
||||
meshBuilder.Normal3fv( vecNormal.Base() );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 64 );
|
||||
meshBuilder.TexCoord2f( 0, u, 1.0f - v );
|
||||
meshBuilder.TexCoord2f( 1, u1_l, v1_b );
|
||||
meshBuilder.TexCoord2f( 2, u2_l, v2_b );
|
||||
meshBuilder.TangentS3fv( vecTangentS.Base() );
|
||||
meshBuilder.TangentT3fv( vecTangentT.Base() );
|
||||
meshBuilder.BoneWeight( 0, 1.0f );
|
||||
meshBuilder.BoneMatrix( 0, 0 );
|
||||
meshBuilder.UserData( vecTangentS.Base() );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3f( x2, y2, 0.0f );
|
||||
meshBuilder.Normal3fv( vecNormal.Base() );
|
||||
meshBuilder.Color4ub( 0, 0, 255, 255 );
|
||||
meshBuilder.TexCoord2f( 0, 1.0f - u, v );
|
||||
meshBuilder.TexCoord2f( 1, u1_r, v1_t );
|
||||
meshBuilder.TexCoord2f( 2, u2_r, v2_t );
|
||||
meshBuilder.TangentS3fv( vecTangentS.Base() );
|
||||
meshBuilder.TangentT3fv( vecTangentT.Base() );
|
||||
meshBuilder.BoneWeight( 0, 1.0f );
|
||||
meshBuilder.BoneMatrix( 0, 0 );
|
||||
meshBuilder.UserData( vecTangentS.Base() );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3f( x2, y, 0.0f );
|
||||
meshBuilder.Normal3fv( vecNormal.Base() );
|
||||
meshBuilder.Color4ub( 0, 255, 0, 64 );
|
||||
meshBuilder.TexCoord2f( 0, 1.0f - u, 1.0f - v );
|
||||
meshBuilder.TexCoord2f( 1, u1_r, v1_b );
|
||||
meshBuilder.TexCoord2f( 2, u2_r, v2_b );
|
||||
meshBuilder.TangentS3fv( vecTangentS.Base() );
|
||||
meshBuilder.TangentT3fv( vecTangentT.Base() );
|
||||
meshBuilder.BoneWeight( 0, 1.0f );
|
||||
meshBuilder.BoneMatrix( 0, 0 );
|
||||
meshBuilder.UserData( vecTangentS.Base() );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.FastIndex( 0 );
|
||||
meshBuilder.FastIndex( 1 );
|
||||
meshBuilder.FastIndex( 2 );
|
||||
meshBuilder.FastIndex( 3 );
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints a cubemap texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::DrawSphere( void )
|
||||
{
|
||||
float flNewTime = Plat_FloatTime();
|
||||
|
||||
// Circle the camera around the origin
|
||||
VMatrix rot;
|
||||
MatrixBuildRotateZ( rot, ROTATION_SPEED * (flNewTime - m_flLastRotationTime ) );
|
||||
Vector vecTemp;
|
||||
Vector3DMultiply( rot, m_vecCameraDirection, vecTemp );
|
||||
m_vecCameraDirection = vecTemp;
|
||||
m_flLastRotationTime = flNewTime;
|
||||
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
SetupProjectionMatrix( w, h );
|
||||
SetupLightingState();
|
||||
|
||||
LookAt( vec3_origin, VIEW_DISTANCE );
|
||||
|
||||
// Draw a sphere at the origin
|
||||
if ( !m_Material->IsSpriteCard() )
|
||||
{
|
||||
RenderSphere( vec3_origin, 10.0f, 20, 20 );
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderSpriteCard( vec3_origin, 10.0f );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the camera to look at the the thing we're spinning around
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::LookAt( const Vector &vecLookAt, float flRadius )
|
||||
{
|
||||
// Compute the distance to the camera for the object based on its
|
||||
// radius and fov.
|
||||
|
||||
// since tan( fov/2 ) = f/d
|
||||
// cos( fov/2 ) = r / r' where r = sphere radius, r' = perp distance from sphere center to max extent of camera
|
||||
// d/f = r'/d' where d' is distance of camera to sphere
|
||||
// d' = r' / tan( fov/2 ) * r' = r / ( cos (fov/2) * tan( fov/2 ) ) = r / sin( fov/2 )
|
||||
float flFOVx = FOV;
|
||||
|
||||
// Compute fov/2 in radians
|
||||
flFOVx *= M_PI / 360.0f;
|
||||
|
||||
// Compute an effective fov based on the aspect ratio
|
||||
// if the height is smaller than the width
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
if ( h < w )
|
||||
{
|
||||
flFOVx = atan( h * tan( flFOVx ) / w );
|
||||
}
|
||||
|
||||
float flDistance = flRadius / sin( flFOVx );
|
||||
|
||||
Vector vecMDLOrigin = vecLookAt;
|
||||
Vector vecCameraOrigin;
|
||||
VectorMA( vecMDLOrigin, -flDistance, m_vecCameraDirection, vecCameraOrigin );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
QAngle angles;
|
||||
VectorAngles( m_vecCameraDirection, angles );
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_VIEW );
|
||||
pRenderContext->LoadIdentity();
|
||||
|
||||
// convert from a right handed system to a left handed system
|
||||
// since dx for wants it that way.
|
||||
// pRenderContext->Scale( 1.0f, 1.0f, -1.0f );
|
||||
|
||||
pRenderContext->Rotate( -90, 1, 0, 0 ); // put Z going up
|
||||
pRenderContext->Rotate( 90, 0, 0, 1 ); // put Z going up
|
||||
pRenderContext->Rotate( -angles[2], 1, 0, 0 );
|
||||
pRenderContext->Rotate( -angles[0], 0, 1, 0 );
|
||||
pRenderContext->Rotate( -angles[1], 0, 0, 1 );
|
||||
pRenderContext->Translate( -vecCameraOrigin[0], -vecCameraOrigin[1], -vecCameraOrigin[2] );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set up a projection matrix for a 90 degree fov
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::SetupProjectionMatrix( int nWidth, int nHeight )
|
||||
{
|
||||
VMatrix proj;
|
||||
float flFOV = FOV;
|
||||
float flZNear = ZNEAR;
|
||||
float flZFar = ZFAR;
|
||||
float flApsectRatio = (nHeight != 0.0f) ? (float)nWidth / (float)nHeight : 100.0f;
|
||||
|
||||
float halfWidth = tan( flFOV * M_PI / 360.0 );
|
||||
float halfHeight = halfWidth / flApsectRatio;
|
||||
|
||||
memset( proj.Base(), 0, sizeof( proj ) );
|
||||
proj[0][0] = 1.0f / halfWidth;
|
||||
proj[1][1] = 1.0f / halfHeight;
|
||||
proj[2][2] = flZFar / ( flZNear - flZFar );
|
||||
proj[3][2] = -1.0f;
|
||||
proj[2][3] = flZNear * flZFar / ( flZNear - flZFar );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
||||
pRenderContext->LoadMatrix( proj );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set up a orthographic projection matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::SetupOrthoMatrix( int nWidth, int nHeight )
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
||||
pRenderContext->LoadIdentity();
|
||||
pRenderContext->Ortho( 0, 0, nWidth, nHeight, -1.0f, 1.0f );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Power of two FB texture
|
||||
//-----------------------------------------------------------------------------
|
||||
static CTextureReference s_pPowerOfTwoFrameBufferTexture;
|
||||
|
||||
static ITexture *GetPowerOfTwoFrameBufferTexture( void )
|
||||
{
|
||||
if( !s_pPowerOfTwoFrameBufferTexture )
|
||||
{
|
||||
s_pPowerOfTwoFrameBufferTexture.Init( vgui::MaterialSystem()->FindTexture( "_rt_PowerOfTwoFB", TEXTURE_GROUP_RENDER_TARGET ) );
|
||||
}
|
||||
|
||||
return s_pPowerOfTwoFrameBufferTexture;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints the texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::Paint( void )
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
vgui::MatSystemSurface()->Begin3DPaint( 0, 0, w, h );
|
||||
|
||||
// Deal with refraction
|
||||
if ( m_Material->NeedsPowerOfTwoFrameBufferTexture() )
|
||||
{
|
||||
ITexture *pTexture = GetPowerOfTwoFrameBufferTexture();
|
||||
if ( pTexture && !pTexture->IsError() )
|
||||
{
|
||||
pRenderContext->CopyRenderTargetToTexture( pTexture );
|
||||
pRenderContext->SetFrameBufferCopyTexture( pTexture );
|
||||
}
|
||||
}
|
||||
|
||||
pRenderContext->ClearColor4ub( 76, 88, 68, 255 );
|
||||
pRenderContext->ClearBuffers( true, true );
|
||||
|
||||
pRenderContext->FogMode( MATERIAL_FOG_NONE );
|
||||
pRenderContext->SetNumBoneWeights( 0 );
|
||||
pRenderContext->Bind( m_Material );
|
||||
pRenderContext->BindLightmapTexture( m_pLightmapTexture );
|
||||
pRenderContext->BindLocalCubemap( m_DefaultEnvCubemap );
|
||||
|
||||
if ( m_bDrawIn3DMode || m_Material->IsSpriteCard() )
|
||||
{
|
||||
DrawSphere();
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawRectangle();
|
||||
}
|
||||
|
||||
vgui::MatSystemSurface()->End3DPaint( );
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "matsys_controls/vtfpicker.h"
|
||||
#include "matsys_controls/vtfpreviewpanel.h"
|
||||
#include "vgui_controls/Splitter.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Asset Picker with no preview
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVTFPicker::CVTFPicker( vgui::Panel *pParent ) :
|
||||
BaseClass( pParent, "VTF Files", "vtf", "materials", "vtfName" )
|
||||
{
|
||||
// Horizontal splitter for preview
|
||||
m_pPreviewSplitter = new Splitter( this, "PreviewSplitter", SPLITTER_MODE_VERTICAL, 1 );
|
||||
vgui::Panel *pSplitterLeftSide = m_pPreviewSplitter->GetChild( 0 );
|
||||
vgui::Panel *pSplitterRightSide = m_pPreviewSplitter->GetChild( 1 );
|
||||
|
||||
// VTF preview
|
||||
m_pVTFPreview = new CVTFPreviewPanel( pSplitterRightSide, "VTFPreview" );
|
||||
|
||||
// Standard browser controls
|
||||
CreateStandardControls( pSplitterLeftSide );
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/vtfpicker.res" );
|
||||
}
|
||||
|
||||
CVTFPicker::~CVTFPicker()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Derived classes have this called when the previewed asset changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPicker::OnSelectedAssetPicked( const char *pAssetName )
|
||||
{
|
||||
m_pVTFPreview->SetVTF( pAssetName );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: Modal picker frame
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CVTFPickerFrame::CVTFPickerFrame( vgui::Panel *pParent, const char *pTitle ) :
|
||||
BaseClass( pParent )
|
||||
{
|
||||
SetAssetPicker( new CVTFPicker( this ) );
|
||||
LoadControlSettingsAndUserConfig( "resource/vtfpickerframe.res" );
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,398 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "matsys_controls/vtfpreviewpanel.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "materialsystem/MaterialSystemUtil.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
#define FOV 90.0f
|
||||
#define ZNEAR 0.1f
|
||||
#define ZFAR 2000.0f
|
||||
#define ROTATION_SPEED 120.0f // degrees/sec
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// VTF Preview panel
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVTFPreviewPanel::CVTFPreviewPanel( vgui::Panel *pParent, const char *pName ) :
|
||||
BaseClass( pParent, pName )
|
||||
{
|
||||
SetVTF( "//platform/materials/vgui/vtfnotloaded", true );
|
||||
m_nTextureID = MatSystemSurface()->CreateNewTextureID( false );
|
||||
}
|
||||
|
||||
CVTFPreviewPanel::~CVTFPreviewPanel()
|
||||
{
|
||||
if ( vgui::surface() && m_nTextureID != -1 )
|
||||
{
|
||||
vgui::surface()->DestroyTextureID( m_nTextureID );
|
||||
m_nTextureID = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the current VTF
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::SetVTF( const char *pFullPath, bool bLoadImmediately )
|
||||
{
|
||||
m_PreviewTexture.Init( pFullPath, "editor texture" );
|
||||
m_VTFName = pFullPath;
|
||||
|
||||
KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
|
||||
if ( m_PreviewTexture->IsCubeMap() )
|
||||
{
|
||||
pVMTKeyValues->SetString( "$envmap", pFullPath );
|
||||
}
|
||||
else if ( m_PreviewTexture->IsNormalMap() )
|
||||
{
|
||||
pVMTKeyValues->SetString( "$bumpmap", pFullPath );
|
||||
}
|
||||
else
|
||||
{
|
||||
pVMTKeyValues->SetString( "$basetexture", pFullPath );
|
||||
}
|
||||
pVMTKeyValues->SetInt( "$nocull", 1 );
|
||||
pVMTKeyValues->SetInt( "$nodebug", 1 );
|
||||
m_PreviewMaterial.Init( MaterialSystem()->CreateMaterial( pFullPath, pVMTKeyValues ));
|
||||
|
||||
MatSystemSurface()->DrawSetTextureMaterial( m_nTextureID, m_PreviewMaterial );
|
||||
|
||||
// Reset the camera direction
|
||||
m_vecCameraDirection.Init( 1.0f, 0.0f, 0.0f );
|
||||
m_flLastRotationTime = Plat_FloatTime();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the current VTF
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CVTFPreviewPanel::GetVTF() const
|
||||
{
|
||||
return m_VTFName;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw a sphere
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::RenderSphere( const Vector &vCenter, float flRadius, int nTheta, int nPhi )
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
|
||||
int nVertices = nTheta * nPhi;
|
||||
int nIndices = 2 * ( nTheta + 1 ) * ( nPhi - 1 );
|
||||
|
||||
pRenderContext->FogMode( MATERIAL_FOG_NONE );
|
||||
pRenderContext->SetNumBoneWeights( 0 );
|
||||
pRenderContext->Bind( m_PreviewMaterial );
|
||||
|
||||
IMesh* pMesh = pRenderContext->GetDynamicMesh();
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, nVertices, nIndices );
|
||||
|
||||
//
|
||||
// Build the index buffer.
|
||||
//
|
||||
int i, j;
|
||||
for ( i = 0; i < nPhi; ++i )
|
||||
{
|
||||
for ( j = 0; j < nTheta; ++j )
|
||||
{
|
||||
float u = j / ( float )(nTheta - 1);
|
||||
float v = i / ( float )(nPhi - 1);
|
||||
float theta = ( j != nTheta-1 ) ? 2.0f * M_PI * u : 0.0f;
|
||||
float phi = M_PI * v;
|
||||
|
||||
Vector vecPos;
|
||||
vecPos.x = flRadius * sin(phi) * cos(theta);
|
||||
vecPos.y = flRadius * cos(phi);
|
||||
vecPos.z = -flRadius * sin(phi) * sin(theta);
|
||||
|
||||
Vector vecNormal = vecPos;
|
||||
VectorNormalize( vecNormal );
|
||||
|
||||
Vector4D vecTangentS;
|
||||
Vector vecTangentT;
|
||||
vecTangentS.Init( vecPos.z, -vecPos.x, 0.0f, 1.0f );
|
||||
if ( VectorNormalize( vecTangentS.AsVector3D() ) == 0.0f )
|
||||
{
|
||||
vecTangentS.Init( 1.0f, 0.0f, 0.0f, 1.0f );
|
||||
}
|
||||
|
||||
CrossProduct( vecNormal, vecTangentS.AsVector3D(), vecTangentT );
|
||||
|
||||
unsigned char red = (int)( u * 255.0f );
|
||||
unsigned char green = (int)( v * 255.0f );
|
||||
unsigned char blue = (int)( v * 255.0f );
|
||||
unsigned char alpha = (int)( v * 255.0f );
|
||||
|
||||
vecPos += vCenter;
|
||||
|
||||
float u1, u2, v1, v2;
|
||||
u1 = u2 = u;
|
||||
v1 = v2 = v;
|
||||
|
||||
meshBuilder.Position3fv( vecPos.Base() );
|
||||
meshBuilder.Normal3fv( vecNormal.Base() );
|
||||
meshBuilder.Color4ub( red, green, blue, alpha );
|
||||
meshBuilder.TexCoord2f( 0, u, v );
|
||||
meshBuilder.TexCoord2f( 1, u1, v1 );
|
||||
meshBuilder.TexCoord2f( 2, u2, v2 );
|
||||
meshBuilder.TangentS3fv( vecTangentS.Base() );
|
||||
meshBuilder.TangentT3fv( vecTangentT.Base() );
|
||||
meshBuilder.BoneWeight( 0, 1.0f );
|
||||
meshBuilder.BoneMatrix( 0, 0 );
|
||||
meshBuilder.UserData( vecTangentS.Base() );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Emit the triangle strips.
|
||||
//
|
||||
int idx = 0;
|
||||
for ( i = 0; i < nPhi - 1; ++i )
|
||||
{
|
||||
for ( j = 0; j < nTheta; ++j )
|
||||
{
|
||||
idx = nTheta * i + j;
|
||||
|
||||
meshBuilder.FastIndex( idx );
|
||||
meshBuilder.FastIndex( idx + nTheta );
|
||||
}
|
||||
|
||||
//
|
||||
// Emit a degenerate triangle to skip to the next row without
|
||||
// a connecting triangle.
|
||||
//
|
||||
if ( i < nPhi - 2 )
|
||||
{
|
||||
meshBuilder.FastIndex( idx + 1 );
|
||||
meshBuilder.FastIndex( idx + 1 + nTheta );
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints a regular texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::PaintStandardTexture( void )
|
||||
{
|
||||
int x, y, w, h;
|
||||
x = y = 0;
|
||||
GetSize( w, h );
|
||||
vgui::surface()->DrawSetTexture( m_nTextureID );
|
||||
vgui::surface()->DrawSetColor( 255, 255, 255, 255 );
|
||||
|
||||
// Get the aspect ratio of the texture
|
||||
int tw = m_PreviewTexture->GetActualWidth();
|
||||
int th = m_PreviewTexture->GetActualHeight();
|
||||
|
||||
if ( th > 0 && h > 0 )
|
||||
{
|
||||
float screenaspect = (float)tw / (float)th;
|
||||
float aspect = (float)w / (float)h;
|
||||
|
||||
float ratio = screenaspect / aspect;
|
||||
|
||||
// Screen is wider, need bars at top and bottom
|
||||
if ( ratio > 1.0f )
|
||||
{
|
||||
int usetall = (float)w / screenaspect;
|
||||
y = ( h - usetall ) / 2;
|
||||
h = usetall;
|
||||
}
|
||||
// Screen is narrower, need bars at left/right
|
||||
else
|
||||
{
|
||||
int usewide = (float)h * screenaspect;
|
||||
x = ( w - usewide ) / 2;
|
||||
w = usewide;
|
||||
}
|
||||
}
|
||||
|
||||
vgui::surface()->DrawTexturedRect( x, y, x+w, y+h );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints a normalmap texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::PaintNormalMapTexture( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints a volume texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::PaintVolumeTexture( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints a cubemap texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::PaintCubeTexture( void )
|
||||
{
|
||||
float flNewTime = Plat_FloatTime();
|
||||
|
||||
// Circle the camera around the origin
|
||||
VMatrix rot;
|
||||
MatrixBuildRotateZ( rot, ROTATION_SPEED * (flNewTime - m_flLastRotationTime ) );
|
||||
Vector vecTemp;
|
||||
Vector3DMultiply( rot, m_vecCameraDirection, vecTemp );
|
||||
m_vecCameraDirection = vecTemp;
|
||||
m_flLastRotationTime = flNewTime;
|
||||
|
||||
LookAt( vec3_origin, 12.0f );
|
||||
|
||||
// Draw a sphere at the origin
|
||||
RenderSphere( vec3_origin, 10.0f, 20, 20 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the camera to look at the the thing we're spinning around
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::LookAt( const Vector &vecLookAt, float flRadius )
|
||||
{
|
||||
// Compute the distance to the camera for the object based on its
|
||||
// radius and fov.
|
||||
|
||||
// since tan( fov/2 ) = f/d
|
||||
// cos( fov/2 ) = r / r' where r = sphere radius, r' = perp distance from sphere center to max extent of camera
|
||||
// d/f = r'/d' where d' is distance of camera to sphere
|
||||
// d' = r' / tan( fov/2 ) * r' = r / ( cos (fov/2) * tan( fov/2 ) ) = r / sin( fov/2 )
|
||||
float flFOVx = FOV;
|
||||
|
||||
// Compute fov/2 in radians
|
||||
flFOVx *= M_PI / 360.0f;
|
||||
|
||||
// Compute an effective fov based on the aspect ratio
|
||||
// if the height is smaller than the width
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
if ( h < w )
|
||||
{
|
||||
flFOVx = atan( h * tan( flFOVx ) / w );
|
||||
}
|
||||
|
||||
float flDistance = flRadius / sin( flFOVx );
|
||||
|
||||
Vector vecMDLOrigin = vecLookAt;
|
||||
Vector vecCameraOrigin;
|
||||
VectorMA( vecMDLOrigin, -flDistance, m_vecCameraDirection, vecCameraOrigin );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
QAngle angles;
|
||||
VectorAngles( m_vecCameraDirection, angles );
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_VIEW );
|
||||
pRenderContext->LoadIdentity();
|
||||
|
||||
// convert from a right handed system to a left handed system
|
||||
// since dx for wants it that way.
|
||||
// pRenderContext->Scale( 1.0f, 1.0f, -1.0f );
|
||||
|
||||
pRenderContext->Rotate( -90, 1, 0, 0 ); // put Z going up
|
||||
pRenderContext->Rotate( 90, 0, 0, 1 ); // put Z going up
|
||||
pRenderContext->Rotate( -angles[2], 1, 0, 0 );
|
||||
pRenderContext->Rotate( -angles[0], 0, 1, 0 );
|
||||
pRenderContext->Rotate( -angles[1], 0, 0, 1 );
|
||||
pRenderContext->Translate( -vecCameraOrigin[0], -vecCameraOrigin[1], -vecCameraOrigin[2] );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set up a projection matrix for a 90 degree fov
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::SetupProjectionMatrix( int nWidth, int nHeight )
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
VMatrix proj;
|
||||
float flFOV = FOV;
|
||||
float flZNear = ZNEAR;
|
||||
float flZFar = ZFAR;
|
||||
float flApsectRatio = (nHeight != 0.0f) ? (float)nWidth / (float)nHeight : 100.0f;
|
||||
|
||||
#if 1
|
||||
float halfWidth = tan( flFOV * M_PI / 360.0 );
|
||||
float halfHeight = halfWidth / flApsectRatio;
|
||||
#else
|
||||
float halfHeight = tan( flFOV * M_PI / 360.0 );
|
||||
float halfWidth = flApsectRatio * halfHeight;
|
||||
#endif
|
||||
memset( proj.Base(), 0, sizeof( proj ) );
|
||||
proj[0][0] = 1.0f / halfWidth;
|
||||
proj[1][1] = 1.0f / halfHeight;
|
||||
proj[2][2] = flZFar / ( flZNear - flZFar );
|
||||
proj[3][2] = -1.0f;
|
||||
proj[2][3] = flZNear * flZFar / ( flZNear - flZFar );
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
||||
pRenderContext->LoadMatrix( proj );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints the texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::Paint( void )
|
||||
{
|
||||
if ( !m_PreviewTexture->IsCubeMap() && /*!m_PreviewTexture->IsNormalMap() &&*/ !m_PreviewTexture->IsVolumeTexture() )
|
||||
{
|
||||
PaintStandardTexture();
|
||||
return;
|
||||
}
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
vgui::MatSystemSurface()->Begin3DPaint( 0, 0, w, h );
|
||||
|
||||
pRenderContext->ClearColor4ub( 76, 88, 68, 255 );
|
||||
pRenderContext->ClearBuffers( true, true );
|
||||
|
||||
SetupProjectionMatrix( w, h );
|
||||
|
||||
if ( m_PreviewTexture->IsCubeMap() )
|
||||
{
|
||||
PaintCubeTexture();
|
||||
}
|
||||
else if ( m_PreviewTexture->IsNormalMap() )
|
||||
{
|
||||
PaintNormalMapTexture();
|
||||
}
|
||||
else if ( m_PreviewTexture->IsVolumeTexture() )
|
||||
{
|
||||
PaintVolumeTexture();
|
||||
}
|
||||
|
||||
vgui::MatSystemSurface()->End3DPaint( );
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include "bitmap.h"
|
||||
#include "vgui_internal.h"
|
||||
#include "filesystem.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include <tier0/dbg.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
// Input : *filename - image file to load
|
||||
//-----------------------------------------------------------------------------
|
||||
Bitmap::Bitmap(const char *filename, bool hardwareFiltered)
|
||||
{
|
||||
_filtered = hardwareFiltered;
|
||||
|
||||
int size = strlen(filename) + 1;
|
||||
_filename = (char *)malloc( size );
|
||||
Assert( _filename );
|
||||
|
||||
Q_snprintf( _filename, size, "%s", filename );
|
||||
|
||||
_bProcedural = false;
|
||||
|
||||
if ( Q_stristr( filename, ".pic" ) )
|
||||
{
|
||||
_bProcedural = true;
|
||||
}
|
||||
|
||||
_id = 0;
|
||||
_uploaded = false;
|
||||
_color = Color(255, 255, 255, 255);
|
||||
_pos[0] = _pos[1] = 0;
|
||||
_valid = true;
|
||||
_wide = 0;
|
||||
_tall = 0;
|
||||
nFrameCache = 0;
|
||||
_rotation = 0;
|
||||
|
||||
ForceUpload();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
Bitmap::~Bitmap()
|
||||
{
|
||||
Evict();
|
||||
|
||||
if ( _filename )
|
||||
{
|
||||
free( _filename );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void Bitmap::GetSize(int &wide, int &tall)
|
||||
{
|
||||
wide = 0;
|
||||
tall = 0;
|
||||
|
||||
if ( !_valid )
|
||||
return;
|
||||
|
||||
// if a size has not been set, get it from the texture
|
||||
if ( 0 == _wide && 0 ==_tall )
|
||||
{
|
||||
g_pSurface->DrawGetTextureSize(_id, _wide, _tall);
|
||||
|
||||
}
|
||||
wide = _wide;
|
||||
tall = _tall;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: size of the bitmap
|
||||
//-----------------------------------------------------------------------------
|
||||
void Bitmap::GetContentSize(int &wide, int &tall)
|
||||
{
|
||||
GetSize(wide, tall);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: ignored
|
||||
//-----------------------------------------------------------------------------
|
||||
void Bitmap::SetSize(int x, int y)
|
||||
{
|
||||
// AssertMsg( _filtered, "Bitmap::SetSize called on non-hardware filtered texture. Bitmap can't be scaled; you don't want to be calling this." );
|
||||
_wide = x;
|
||||
_tall = y;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void Bitmap::SetPos(int x, int y)
|
||||
{
|
||||
_pos[0] = x;
|
||||
_pos[1] = y;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void Bitmap::SetColor(Color col)
|
||||
{
|
||||
_color = col;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the file name of the bitmap
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *Bitmap::GetName()
|
||||
{
|
||||
return _filename;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Renders the loaded image, uploading it if necessary
|
||||
// Assumes a valid image is always returned from uploading
|
||||
//-----------------------------------------------------------------------------
|
||||
void Bitmap::Paint()
|
||||
{
|
||||
if ( !_valid )
|
||||
return;
|
||||
|
||||
// if we don't have an _id then lets make one
|
||||
if ( !_id )
|
||||
{
|
||||
_id = g_pSurface->CreateNewTextureID();
|
||||
}
|
||||
|
||||
// if we have not uploaded yet, lets go ahead and do so
|
||||
if ( !_uploaded )
|
||||
{
|
||||
ForceUpload();
|
||||
}
|
||||
|
||||
// set the texture current, set the color, and draw the biatch
|
||||
g_pSurface->DrawSetColor( _color[0], _color[1], _color[2], _color[3] );
|
||||
g_pSurface->DrawSetTexture( _id );
|
||||
|
||||
if ( _wide == 0 )
|
||||
{
|
||||
GetSize( _wide, _tall);
|
||||
}
|
||||
|
||||
if ( _rotation == ROTATED_UNROTATED )
|
||||
{
|
||||
g_pSurface->DrawTexturedRect(_pos[0], _pos[1], _pos[0] + _wide, _pos[1] + _tall);
|
||||
}
|
||||
else
|
||||
{
|
||||
vgui::Vertex_t verts[4];
|
||||
verts[0].m_Position.Init( 0, 0 );
|
||||
verts[1].m_Position.Init( _wide, 0 );
|
||||
verts[2].m_Position.Init( _wide, _tall );
|
||||
verts[3].m_Position.Init( 0, _tall );
|
||||
|
||||
switch ( _rotation )
|
||||
{
|
||||
case ROTATED_CLOCKWISE_90:
|
||||
verts[0].m_TexCoord.Init( 1, 0 );
|
||||
verts[1].m_TexCoord.Init( 1, 1 );
|
||||
verts[2].m_TexCoord.Init( 0, 1 );
|
||||
verts[3].m_TexCoord.Init( 0, 0 );
|
||||
break;
|
||||
|
||||
case ROTATED_ANTICLOCKWISE_90:
|
||||
verts[0].m_TexCoord.Init( 0, 1 );
|
||||
verts[1].m_TexCoord.Init( 0, 0 );
|
||||
verts[2].m_TexCoord.Init( 1, 0 );
|
||||
verts[3].m_TexCoord.Init( 1, 1 );
|
||||
break;
|
||||
|
||||
case ROTATED_FLIPPED:
|
||||
verts[0].m_TexCoord.Init( 1, 1 );
|
||||
verts[1].m_TexCoord.Init( 0, 1 );
|
||||
verts[2].m_TexCoord.Init( 0, 0 );
|
||||
verts[3].m_TexCoord.Init( 1, 0 );
|
||||
break;
|
||||
|
||||
default:
|
||||
case ROTATED_UNROTATED:
|
||||
break;
|
||||
}
|
||||
|
||||
g_pSurface->DrawTexturedPolygon( 4, verts );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: ensures the bitmap has been uploaded
|
||||
//-----------------------------------------------------------------------------
|
||||
void Bitmap::ForceUpload()
|
||||
{
|
||||
if ( !_valid || _uploaded )
|
||||
return;
|
||||
|
||||
if ( !_id )
|
||||
{
|
||||
_id = g_pSurface->CreateNewTextureID( _bProcedural );
|
||||
}
|
||||
|
||||
if ( !_bProcedural )
|
||||
{
|
||||
g_pSurface->DrawSetTextureFile( _id, _filename, _filtered, false );
|
||||
}
|
||||
|
||||
_uploaded = true;
|
||||
_valid = g_pSurface->IsTextureIDValid( _id );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
HTexture Bitmap::GetID()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
bool Bitmap::Evict()
|
||||
{
|
||||
if ( _id != 0 )
|
||||
{
|
||||
g_pSurface->DestroyTextureID( _id );
|
||||
// purposely not resetting _valid to match existing silly logic
|
||||
// either a Paint() or ForceUpload() will re-establish
|
||||
_id = 0;
|
||||
_uploaded = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int Bitmap::GetNumFrames()
|
||||
{
|
||||
if ( !_valid )
|
||||
return 0;
|
||||
|
||||
return g_pSurface->GetTextureNumFrames( _id );
|
||||
}
|
||||
|
||||
void Bitmap::SetFrame( int nFrame )
|
||||
{
|
||||
if ( !_valid )
|
||||
return;
|
||||
|
||||
// the frame cache is critical to cheapen the cost of this call
|
||||
g_pSurface->DrawSetTextureFrame( _id, nFrame, &nFrameCache );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "vgui/IPanel.h"
|
||||
#include "vgui/IScheme.h"
|
||||
#include "vgui/ISurface.h"
|
||||
|
||||
#include "VGUI_Border.h"
|
||||
#include "vgui_internal.h"
|
||||
#include "VPanel.h"
|
||||
#include "KeyValues.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
Border::Border()
|
||||
{
|
||||
_inset[0]=0;
|
||||
_inset[1]=0;
|
||||
_inset[2]=0;
|
||||
_inset[3]=0;
|
||||
_name = NULL;
|
||||
m_eBackgroundType = IBorder::BACKGROUND_FILLED;
|
||||
|
||||
memset(_sides, 0, sizeof(_sides));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
Border::~Border()
|
||||
{
|
||||
delete [] _name;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
delete [] _sides[i].lines;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void Border::SetInset(int left,int top,int right,int bottom)
|
||||
{
|
||||
_inset[SIDE_LEFT] = left;
|
||||
_inset[SIDE_TOP] = top;
|
||||
_inset[SIDE_RIGHT] = right;
|
||||
_inset[SIDE_BOTTOM] = bottom;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void Border::GetInset(int& left,int& top,int& right,int& bottom)
|
||||
{
|
||||
left = _inset[SIDE_LEFT];
|
||||
top = _inset[SIDE_TOP];
|
||||
right = _inset[SIDE_RIGHT];
|
||||
bottom = _inset[SIDE_BOTTOM];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void Border::Paint(int x, int y, int wide, int tall)
|
||||
{
|
||||
Paint(x, y, wide, tall, -1, 0, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Draws the border with the specified size
|
||||
//-----------------------------------------------------------------------------
|
||||
void Border::Paint(int x, int y, int wide, int tall, int breakSide, int breakStart, int breakEnd)
|
||||
{
|
||||
// iterate through and draw all lines
|
||||
// draw left
|
||||
int i;
|
||||
for (i = 0; i < _sides[SIDE_LEFT].count; i++)
|
||||
{
|
||||
line_t *line = &(_sides[SIDE_LEFT].lines[i]);
|
||||
g_pSurface->DrawSetColor(line->col[0], line->col[1], line->col[2], line->col[3]);
|
||||
|
||||
if (breakSide == SIDE_LEFT)
|
||||
{
|
||||
// split into two section
|
||||
if (breakStart > 0)
|
||||
{
|
||||
// draw before the break Start
|
||||
g_pSurface->DrawFilledRect(x + i, y + line->startOffset, x + i + 1, y + breakStart);
|
||||
}
|
||||
|
||||
if (breakEnd < (tall - line->endOffset))
|
||||
{
|
||||
// draw after break end
|
||||
g_pSurface->DrawFilledRect(x + i, y + breakEnd + 1, x + i + 1, tall - line->endOffset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pSurface->DrawFilledRect(x + i, y + line->startOffset, x + i + 1, tall - line->endOffset);
|
||||
}
|
||||
}
|
||||
|
||||
// draw top
|
||||
for (i = 0; i < _sides[SIDE_TOP].count; i++)
|
||||
{
|
||||
line_t *line = &(_sides[SIDE_TOP].lines[i]);
|
||||
g_pSurface->DrawSetColor(line->col[0], line->col[1], line->col[2], line->col[3]);
|
||||
|
||||
if (breakSide == SIDE_TOP)
|
||||
{
|
||||
// split into two section
|
||||
if (breakStart > 0)
|
||||
{
|
||||
// draw before the break Start
|
||||
g_pSurface->DrawFilledRect(x + line->startOffset, y + i, x + breakStart, y + i + 1);
|
||||
}
|
||||
|
||||
if (breakEnd < (wide - line->endOffset))
|
||||
{
|
||||
// draw after break end
|
||||
g_pSurface->DrawFilledRect(x + breakEnd + 1, y + i, wide - line->endOffset, y + i + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pSurface->DrawFilledRect(x + line->startOffset, y + i, wide - line->endOffset, y + i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// draw right
|
||||
for (i = 0; i < _sides[SIDE_RIGHT].count; i++)
|
||||
{
|
||||
line_t *line = &(_sides[SIDE_RIGHT].lines[i]);
|
||||
g_pSurface->DrawSetColor(line->col[0], line->col[1], line->col[2], line->col[3]);
|
||||
g_pSurface->DrawFilledRect(wide - (i+1), y + line->startOffset, (wide - (i+1)) + 1, tall - line->endOffset);
|
||||
}
|
||||
|
||||
// draw bottom
|
||||
for (i = 0; i < _sides[SIDE_BOTTOM].count; i++)
|
||||
{
|
||||
line_t *line = &(_sides[SIDE_BOTTOM].lines[i]);
|
||||
g_pSurface->DrawSetColor(line->col[0], line->col[1], line->col[2], line->col[3]);
|
||||
g_pSurface->DrawFilledRect(x + line->startOffset, tall - (i+1), wide - line->endOffset, (tall - (i+1)) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void Border::Paint(VPANEL panel)
|
||||
{
|
||||
// get panel size
|
||||
int wide, tall;
|
||||
((VPanel *)panel)->GetSize(wide, tall);
|
||||
Paint(0, 0, wide, tall, -1, 0, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void Border::ApplySchemeSettings(IScheme *pScheme, KeyValues *inResourceData)
|
||||
{
|
||||
// load inset information
|
||||
const char *insetString = inResourceData->GetString("inset", "0 0 0 0");
|
||||
|
||||
int left, top, right, bottom;
|
||||
GetInset(left, top, right, bottom);
|
||||
sscanf(insetString, "%d %d %d %d", &left, &top, &right, &bottom);
|
||||
SetInset(left, top, right, bottom);
|
||||
|
||||
// get the border information from the scheme
|
||||
ParseSideSettings(SIDE_LEFT, inResourceData->FindKey("Left"),pScheme);
|
||||
ParseSideSettings(SIDE_TOP, inResourceData->FindKey("Top"),pScheme);
|
||||
ParseSideSettings(SIDE_RIGHT, inResourceData->FindKey("Right"),pScheme);
|
||||
ParseSideSettings(SIDE_BOTTOM, inResourceData->FindKey("Bottom"),pScheme);
|
||||
|
||||
m_eBackgroundType = (backgroundtype_e)inResourceData->GetInt("backgroundtype");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: parses scheme data
|
||||
//-----------------------------------------------------------------------------
|
||||
void Border::ParseSideSettings(int side_index, KeyValues *inResourceData, IScheme *pScheme)
|
||||
{
|
||||
if (!inResourceData)
|
||||
return;
|
||||
|
||||
// count the numeber of lines in the side
|
||||
int count = 0;
|
||||
KeyValues *kv;
|
||||
for (kv = inResourceData->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey())
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
// allocate memory
|
||||
_sides[side_index].count = count;
|
||||
_sides[side_index].lines = new line_t[count];
|
||||
|
||||
// iterate through the keys
|
||||
//!! this loads in order, ignoring key names
|
||||
int index = 0;
|
||||
for (kv = inResourceData->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey())
|
||||
{
|
||||
line_t *line = &(_sides[side_index].lines[index]);
|
||||
|
||||
// this is the color name, get that from the color table
|
||||
const char *col = kv->GetString("color", NULL);
|
||||
line->col = pScheme->GetColor(col, Color(0, 0, 0, 0));
|
||||
|
||||
col = kv->GetString("offset", NULL);
|
||||
int Start = 0, end = 0;
|
||||
if (col)
|
||||
{
|
||||
sscanf(col, "%d %d", &Start, &end);
|
||||
}
|
||||
line->startOffset = Start;
|
||||
line->endOffset = end;
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *Border::GetName()
|
||||
{
|
||||
if (_name)
|
||||
return _name;
|
||||
return "";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void Border::SetName(const char *name)
|
||||
{
|
||||
if (_name)
|
||||
{
|
||||
delete [] _name;
|
||||
}
|
||||
|
||||
int len = Q_strlen(name) + 1;
|
||||
_name = new char[ len ];
|
||||
Q_strncpy( _name, name, len );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
IBorder::backgroundtype_e Border::GetBackgroundType()
|
||||
{
|
||||
return m_eBackgroundType;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef IMESSAGELISTENER_H
|
||||
#define IMESSAGELISTENER_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui/VGUI.h>
|
||||
|
||||
class KeyValues;
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
|
||||
enum MessageSendType_t
|
||||
{
|
||||
MESSAGE_SENT = 0,
|
||||
MESSAGE_POSTED,
|
||||
MESSAGE_RECEIVED
|
||||
};
|
||||
|
||||
class VPanel;
|
||||
|
||||
|
||||
class IMessageListener
|
||||
{
|
||||
public:
|
||||
virtual void Message( VPanel* pSender, VPanel* pReceiver,
|
||||
KeyValues* pKeyValues, MessageSendType_t type ) = 0;
|
||||
};
|
||||
|
||||
IMessageListener* MessageListener();
|
||||
|
||||
}
|
||||
|
||||
#endif // IMESSAGELISTENER_H
|
||||
@@ -0,0 +1,223 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include "vgui/IPanel.h"
|
||||
#include "vgui/IScheme.h"
|
||||
#include "vgui/ISurface.h"
|
||||
|
||||
#include "vgui_internal.h"
|
||||
#include "ImageBorder.h"
|
||||
#include "KeyValues.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
ImageBorder::ImageBorder()
|
||||
{
|
||||
_name = NULL;
|
||||
m_eBackgroundType = IBorder::BACKGROUND_TEXTURED;
|
||||
|
||||
m_pszImageName = NULL;
|
||||
m_iTextureID = g_pSurface->CreateNewTextureID();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
ImageBorder::~ImageBorder()
|
||||
{
|
||||
if ( vgui::surface() && m_iTextureID != -1 )
|
||||
{
|
||||
vgui::surface()->DestroyTextureID( m_iTextureID );
|
||||
m_iTextureID = -1;
|
||||
}
|
||||
|
||||
delete [] _name;
|
||||
if ( m_pszImageName )
|
||||
{
|
||||
delete [] m_pszImageName;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ImageBorder::SetImage(const char *imageName)
|
||||
{
|
||||
if ( m_pszImageName )
|
||||
{
|
||||
delete [] m_pszImageName;
|
||||
m_pszImageName = NULL;
|
||||
}
|
||||
|
||||
if (*imageName)
|
||||
{
|
||||
int len = Q_strlen(imageName) + 1 + 5; // 5 for "vgui/"
|
||||
delete [] m_pszImageName;
|
||||
m_pszImageName = new char[ len ];
|
||||
Q_snprintf( m_pszImageName, len, "vgui/%s", imageName );
|
||||
|
||||
g_pSurface->DrawSetTextureFile( m_iTextureID, m_pszImageName, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ImageBorder::SetInset(int left,int top,int right,int bottom)
|
||||
{
|
||||
_inset[SIDE_LEFT] = left;
|
||||
_inset[SIDE_TOP] = top;
|
||||
_inset[SIDE_RIGHT] = right;
|
||||
_inset[SIDE_BOTTOM] = bottom;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ImageBorder::GetInset(int& left,int& top,int& right,int& bottom)
|
||||
{
|
||||
left = _inset[SIDE_LEFT];
|
||||
top = _inset[SIDE_TOP];
|
||||
right = _inset[SIDE_RIGHT];
|
||||
bottom = _inset[SIDE_BOTTOM];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ImageBorder::Paint(int x, int y, int wide, int tall)
|
||||
{
|
||||
Paint(x, y, wide, tall, -1, 0, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Draws the border with the specified size
|
||||
//-----------------------------------------------------------------------------
|
||||
void ImageBorder::Paint(int x, int y, int wide, int tall, int breakSide, int breakStart, int breakEnd)
|
||||
{
|
||||
if ( !m_pszImageName || !m_pszImageName[0] )
|
||||
return;
|
||||
|
||||
g_pSurface->DrawSetColor( 255, 255, 255, 255 );
|
||||
g_pSurface->DrawSetTexture( m_iTextureID );
|
||||
|
||||
float uvx = 0;
|
||||
float uvy = 0;
|
||||
float uvw = 1.0;
|
||||
float uvh = 1.0;
|
||||
Vector2D uv11( uvx, uvy );
|
||||
Vector2D uv21( uvx+uvw, uvy );
|
||||
Vector2D uv22( uvx+uvw, uvy+uvh );
|
||||
Vector2D uv12( uvx, uvy+uvh );
|
||||
|
||||
if ( m_bTiled )
|
||||
{
|
||||
int imageWide, imageTall;
|
||||
g_pSurface->DrawGetTextureSize( m_iTextureID, imageWide, imageTall );
|
||||
|
||||
int y = 0;
|
||||
while ( y < tall )
|
||||
{
|
||||
int x = 0;
|
||||
while (x < wide)
|
||||
{
|
||||
vgui::Vertex_t verts[4];
|
||||
verts[0].Init( Vector2D( x, y ), uv11 );
|
||||
verts[1].Init( Vector2D( x+imageWide, y ), uv21 );
|
||||
verts[2].Init( Vector2D( x+imageWide, y+imageTall ), uv22 );
|
||||
verts[3].Init( Vector2D( x, y+imageTall ), uv12 );
|
||||
|
||||
g_pSurface->DrawTexturedPolygon( 4, verts );
|
||||
|
||||
x += imageWide;
|
||||
}
|
||||
|
||||
y += imageTall;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vgui::Vertex_t verts[4];
|
||||
verts[0].Init( Vector2D( x, y ), uv11 );
|
||||
verts[1].Init( Vector2D( x+wide, y ), uv21 );
|
||||
verts[2].Init( Vector2D( x+wide, y+tall ), uv22 );
|
||||
verts[3].Init( Vector2D( x, y+tall ), uv12 );
|
||||
|
||||
g_pSurface->DrawTexturedPolygon( 4, verts );
|
||||
}
|
||||
|
||||
g_pSurface->DrawSetTexture(0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ImageBorder::Paint(VPANEL panel)
|
||||
{
|
||||
// get panel size
|
||||
int wide, tall;
|
||||
ipanel()->GetSize( panel, wide, tall );
|
||||
Paint(0, 0, wide, tall, -1, 0, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ImageBorder::ApplySchemeSettings(IScheme *pScheme, KeyValues *inResourceData)
|
||||
{
|
||||
m_eBackgroundType = (backgroundtype_e)inResourceData->GetInt("backgroundtype");
|
||||
m_bTiled = inResourceData->GetInt( "tiled" );
|
||||
|
||||
const char *imageName = inResourceData->GetString("image", "");
|
||||
SetImage( imageName );
|
||||
|
||||
m_bPaintFirst = inResourceData->GetInt("paintfirst", true );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *ImageBorder::GetName()
|
||||
{
|
||||
if (_name)
|
||||
return _name;
|
||||
return "";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void ImageBorder::SetName(const char *name)
|
||||
{
|
||||
if (_name)
|
||||
{
|
||||
delete [] _name;
|
||||
}
|
||||
|
||||
int len = Q_strlen(name) + 1;
|
||||
_name = new char[ len ];
|
||||
Q_strncpy( _name, name, len );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
IBorder::backgroundtype_e ImageBorder::GetBackgroundType()
|
||||
{
|
||||
return m_eBackgroundType;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Core implementation of vgui
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef IMAGE_BORDER_H
|
||||
#define IMAGE_BORDER_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui/VGUI.h>
|
||||
#include <vgui/IBorder.h>
|
||||
#include <vgui/IScheme.h>
|
||||
#include <vgui/IPanel.h>
|
||||
#include <Color.h>
|
||||
|
||||
class KeyValues;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Custom border that renders itself with images
|
||||
//-----------------------------------------------------------------------------
|
||||
class ImageBorder : public vgui::IBorder
|
||||
{
|
||||
public:
|
||||
ImageBorder();
|
||||
~ImageBorder();
|
||||
|
||||
virtual void Paint(vgui::VPANEL panel);
|
||||
virtual void Paint(int x0, int y0, int x1, int y1);
|
||||
virtual void Paint(int x0, int y0, int x1, int y1, int breakSide, int breakStart, int breakStop);
|
||||
virtual void SetInset(int left, int top, int right, int bottom);
|
||||
virtual void GetInset(int &left, int &top, int &right, int &bottom);
|
||||
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme, KeyValues *inResourceData);
|
||||
|
||||
virtual const char *GetName();
|
||||
virtual void SetName(const char *name);
|
||||
virtual backgroundtype_e GetBackgroundType();
|
||||
|
||||
virtual bool PaintFirst( void ) { return m_bPaintFirst; }
|
||||
|
||||
protected:
|
||||
void SetImage(const char *imageName);
|
||||
|
||||
protected:
|
||||
int _inset[4];
|
||||
|
||||
private:
|
||||
// protected copy constructor to prevent use
|
||||
ImageBorder(ImageBorder&);
|
||||
|
||||
char *_name;
|
||||
|
||||
backgroundtype_e m_eBackgroundType;
|
||||
|
||||
friend class VPanel;
|
||||
|
||||
int m_iTextureID;
|
||||
bool m_bTiled;
|
||||
|
||||
char *m_pszImageName;
|
||||
bool m_bPaintFirst;
|
||||
};
|
||||
|
||||
#endif // IMAGE_BORDER_H
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,174 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
|
||||
#if !defined(_STATIC_LINKED) || defined(_VGUI_DLL)
|
||||
|
||||
#include <vgui/ISurface.h>
|
||||
|
||||
#include "Memorybitmap.h"
|
||||
#include "vgui_internal.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
// Input : *filename - image file to load
|
||||
//-----------------------------------------------------------------------------
|
||||
MemoryBitmap::MemoryBitmap(unsigned char *texture,int wide, int tall)
|
||||
{
|
||||
_texture=texture;
|
||||
_id = 0;
|
||||
_uploaded = false;
|
||||
_color = Color(255, 255, 255, 255);
|
||||
_pos[0] = _pos[1] = 0;
|
||||
_valid = true;
|
||||
_w = wide;
|
||||
_h = tall;
|
||||
ForceUpload(texture,wide,tall);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
MemoryBitmap::~MemoryBitmap()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void MemoryBitmap::GetSize(int &wide, int &tall)
|
||||
{
|
||||
wide = 0;
|
||||
tall = 0;
|
||||
|
||||
if (!_valid)
|
||||
return;
|
||||
|
||||
g_pSurface->DrawGetTextureSize(_id, wide, tall);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: size of the bitmap
|
||||
//-----------------------------------------------------------------------------
|
||||
void MemoryBitmap::GetContentSize(int &wide, int &tall)
|
||||
{
|
||||
GetSize(wide, tall);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: ignored
|
||||
//-----------------------------------------------------------------------------
|
||||
void MemoryBitmap::SetSize(int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void MemoryBitmap::SetPos(int x, int y)
|
||||
{
|
||||
_pos[0] = x;
|
||||
_pos[1] = y;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void MemoryBitmap::SetColor(Color col)
|
||||
{
|
||||
_color = col;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the file name of the bitmap
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *MemoryBitmap::GetName()
|
||||
{
|
||||
return "MemoryBitmap";
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Renders the loaded image, uploading it if necessary
|
||||
// Assumes a valid image is always returned from uploading
|
||||
//-----------------------------------------------------------------------------
|
||||
void MemoryBitmap::Paint()
|
||||
{
|
||||
if (!_valid)
|
||||
return;
|
||||
|
||||
// if we don't have an _id then lets make one
|
||||
if (!_id)
|
||||
{
|
||||
_id = g_pSurface->CreateNewTextureID( true );
|
||||
}
|
||||
|
||||
// if we have not uploaded yet, lets go ahead and do so
|
||||
if (!_uploaded)
|
||||
{
|
||||
ForceUpload(_texture,_w,_h);
|
||||
}
|
||||
|
||||
//set the texture current, set the color, and draw the biatch
|
||||
g_pSurface->DrawSetTexture(_id);
|
||||
g_pSurface->DrawSetColor(_color[0], _color[1], _color[2], _color[3]);
|
||||
|
||||
int wide, tall;
|
||||
GetSize(wide, tall);
|
||||
g_pSurface->DrawTexturedRect(_pos[0], _pos[1], _pos[0] + wide, _pos[1] + tall);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: ensures the bitmap has been uploaded
|
||||
//-----------------------------------------------------------------------------
|
||||
void MemoryBitmap::ForceUpload(unsigned char *texture,int wide, int tall)
|
||||
{
|
||||
_texture=texture;
|
||||
_w = wide;
|
||||
_h = tall;
|
||||
|
||||
if (!_valid)
|
||||
return;
|
||||
|
||||
// if (_uploaded)
|
||||
// return;
|
||||
|
||||
if(_w==0 || _h==0)
|
||||
return;
|
||||
|
||||
if (!_id)
|
||||
{
|
||||
_id = g_pSurface->CreateNewTextureID( true );
|
||||
}
|
||||
/* drawSetTextureRGBA(IE->textureID,static_cast<const char *>(lpvBits), w, h);
|
||||
*/
|
||||
g_pSurface->DrawSetTextureRGBA(_id, _texture, _w, _h, false, true);
|
||||
_uploaded = true;
|
||||
|
||||
_valid = g_pSurface->IsTextureIDValid(_id);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
HTexture MemoryBitmap::GetID()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
#endif // _STATIC_LINKED && _VGUI_DLL
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef MEMORYBITMAP_H
|
||||
#define MEMORYBITMAP_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui/VGUI.h>
|
||||
#include <vgui/IImage.h>
|
||||
#include <Color.h>
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
|
||||
typedef unsigned long HTexture;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Holds a single image created from a chunk of memory, internal to vgui only
|
||||
//-----------------------------------------------------------------------------
|
||||
class MemoryBitmap: public IImage
|
||||
{
|
||||
public:
|
||||
MemoryBitmap(unsigned char *texture,int wide, int tall);
|
||||
~MemoryBitmap();
|
||||
|
||||
// IImage implementation
|
||||
virtual void Paint();
|
||||
virtual void GetSize(int &wide, int &tall);
|
||||
virtual void GetContentSize(int &wide, int &tall);
|
||||
virtual void SetPos(int x, int y);
|
||||
virtual void SetSize(int x, int y);
|
||||
virtual void SetColor(Color col);
|
||||
|
||||
virtual bool Evict() { return false; }
|
||||
virtual int GetNumFrames() { return 0; }
|
||||
virtual void SetFrame( int nFrame ) {}
|
||||
virtual HTexture GetID(); // returns the texture id
|
||||
virtual void SetRotation( int iRotation ) { return; };
|
||||
|
||||
// methods
|
||||
void ForceUpload(unsigned char *texture,int wide, int tall); // ensures the bitmap has been uploaded
|
||||
const char *GetName();
|
||||
bool IsValid()
|
||||
{
|
||||
return _valid;
|
||||
}
|
||||
|
||||
private:
|
||||
HTexture _id;
|
||||
bool _uploaded;
|
||||
bool _valid;
|
||||
unsigned char *_texture;
|
||||
int _pos[2];
|
||||
Color _color;
|
||||
int _w,_h; // size of the texture
|
||||
};
|
||||
|
||||
} // namespace vgui
|
||||
|
||||
#endif // MEMORYBITMAP_H
|
||||
@@ -0,0 +1,112 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "IMessageListener.h"
|
||||
#include "VPanel.h"
|
||||
#include "vgui_internal.h"
|
||||
|
||||
#include <KeyValues.h>
|
||||
#include "vgui/IClientPanel.h"
|
||||
#include "vgui/IVGui.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Implementation of the message listener
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMessageListener : public IMessageListener
|
||||
{
|
||||
public:
|
||||
virtual void Message( VPanel* pSender, VPanel* pReceiver, KeyValues* pKeyValues, MessageSendType_t type );
|
||||
};
|
||||
|
||||
void CMessageListener::Message( VPanel* pSender, VPanel* pReceiver, KeyValues* pKeyValues, MessageSendType_t type )
|
||||
{
|
||||
char const *pSenderName = "NULL";
|
||||
if (pSender)
|
||||
pSenderName = pSender->Client()->GetName();
|
||||
|
||||
char const *pSenderClass = "NULL";
|
||||
if (pSender)
|
||||
pSenderClass = pSender->Client()->GetClassName();
|
||||
|
||||
char const *pReceiverName = "unknown name";
|
||||
if (pReceiver)
|
||||
pReceiverName = pReceiver->Client()->GetName();
|
||||
|
||||
char const *pReceiverClass = "unknown class";
|
||||
if (pReceiver)
|
||||
pReceiverClass = pReceiver->Client()->GetClassName();
|
||||
|
||||
// FIXME: Make a bunch of filters here
|
||||
|
||||
// filter out key focus messages
|
||||
if (!strcmp (pKeyValues->GetName(), "KeyFocusTicked"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// filter out mousefocus messages
|
||||
else if (!strcmp (pKeyValues->GetName(), "MouseFocusTicked"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// filter out cursor movement messages
|
||||
else if (!strcmp (pKeyValues->GetName(), "CursorMoved"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// filter out cursor entered messages
|
||||
else if (!strcmp (pKeyValues->GetName(), "CursorEntered"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// filter out cursor exited messages
|
||||
else if (!strcmp (pKeyValues->GetName(), "CursorExited"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// filter out MouseCaptureLost messages
|
||||
else if (!strcmp (pKeyValues->GetName(), "MouseCaptureLost"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// filter out MousePressed messages
|
||||
else if (!strcmp (pKeyValues->GetName(), "MousePressed"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// filter out MouseReleased messages
|
||||
else if (!strcmp (pKeyValues->GetName(), "MouseReleased"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// filter out Tick messages
|
||||
else if (!strcmp (pKeyValues->GetName(), "Tick"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Msg( "%s : (%s (%s) - > %s (%s)) )\n",
|
||||
pKeyValues->GetName(), pSenderClass, pSenderName, pReceiverClass, pReceiverName );
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CMessageListener s_MessageListener;
|
||||
IMessageListener *MessageListener()
|
||||
{
|
||||
return &s_MessageListener;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include "vgui/IPanel.h"
|
||||
#include "vgui/IScheme.h"
|
||||
#include "vgui/ISurface.h"
|
||||
|
||||
#include "vgui_internal.h"
|
||||
#include "ScalableImageBorder.h"
|
||||
#include "KeyValues.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
ScalableImageBorder::ScalableImageBorder()
|
||||
{
|
||||
_inset[0]=0;
|
||||
_inset[1]=0;
|
||||
_inset[2]=0;
|
||||
_inset[3]=0;
|
||||
_name = NULL;
|
||||
m_eBackgroundType = IBorder::BACKGROUND_TEXTURED;
|
||||
|
||||
m_iSrcCornerHeight = 0;
|
||||
m_iSrcCornerWidth = 0;
|
||||
m_iCornerHeight = 0;
|
||||
m_iCornerWidth = 0;
|
||||
m_pszImageName = NULL;
|
||||
m_iTextureID = g_pSurface->CreateNewTextureID();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
ScalableImageBorder::~ScalableImageBorder()
|
||||
{
|
||||
if ( vgui::surface() && m_iTextureID != -1 )
|
||||
{
|
||||
vgui::surface()->DestroyTextureID( m_iTextureID );
|
||||
m_iTextureID = -1;
|
||||
}
|
||||
|
||||
delete [] _name;
|
||||
if ( m_pszImageName )
|
||||
{
|
||||
delete [] m_pszImageName;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScalableImageBorder::SetImage(const char *imageName)
|
||||
{
|
||||
if ( m_pszImageName )
|
||||
{
|
||||
delete [] m_pszImageName;
|
||||
m_pszImageName = NULL;
|
||||
}
|
||||
|
||||
if (*imageName)
|
||||
{
|
||||
int len = Q_strlen(imageName) + 1 + 5; // 5 for "vgui/"
|
||||
delete [] m_pszImageName;
|
||||
m_pszImageName = new char[ len ];
|
||||
Q_snprintf( m_pszImageName, len, "vgui/%s", imageName );
|
||||
|
||||
g_pSurface->DrawSetTextureFile( m_iTextureID, m_pszImageName, true, false);
|
||||
|
||||
// get image dimensions, compare to m_iSrcCornerHeight, m_iSrcCornerWidth
|
||||
int wide,tall;
|
||||
g_pSurface->DrawGetTextureSize( m_iTextureID, wide, tall );
|
||||
|
||||
m_flCornerWidthPercent = ( wide > 0 ) ? ( (float)m_iSrcCornerWidth / (float)wide ) : 0;
|
||||
m_flCornerHeightPercent = ( tall > 0 ) ? ( (float)m_iSrcCornerHeight / (float)tall ) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScalableImageBorder::SetInset(int left,int top,int right,int bottom)
|
||||
{
|
||||
_inset[SIDE_LEFT] = left;
|
||||
_inset[SIDE_TOP] = top;
|
||||
_inset[SIDE_RIGHT] = right;
|
||||
_inset[SIDE_BOTTOM] = bottom;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScalableImageBorder::GetInset(int& left,int& top,int& right,int& bottom)
|
||||
{
|
||||
left = _inset[SIDE_LEFT];
|
||||
top = _inset[SIDE_TOP];
|
||||
right = _inset[SIDE_RIGHT];
|
||||
bottom = _inset[SIDE_BOTTOM];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScalableImageBorder::Paint(int x, int y, int wide, int tall)
|
||||
{
|
||||
Paint(x, y, wide, tall, -1, 0, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Draws the border with the specified size
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScalableImageBorder::Paint(int x, int y, int wide, int tall, int breakSide, int breakStart, int breakEnd)
|
||||
{
|
||||
if ( !m_pszImageName || !m_pszImageName[0] )
|
||||
return;
|
||||
|
||||
g_pSurface->DrawSetColor( m_Color );
|
||||
g_pSurface->DrawSetTexture( m_iTextureID );
|
||||
|
||||
float uvx = 0;
|
||||
float uvy = 0;
|
||||
float uvw, uvh;
|
||||
|
||||
float drawW, drawH;
|
||||
|
||||
int row, col;
|
||||
for ( row=0;row<3;row++ )
|
||||
{
|
||||
x = 0;
|
||||
uvx = 0;
|
||||
|
||||
if ( row == 0 || row == 2 )
|
||||
{
|
||||
//uvh - row 0 or 2, is src_corner_height
|
||||
uvh = m_flCornerHeightPercent;
|
||||
drawH = m_iCornerHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
//uvh - row 1, is tall - ( 2 * src_corner_height ) ( min 0 )
|
||||
uvh = max( 1.f - 2.f * m_flCornerHeightPercent, 0.0f );
|
||||
drawH = max( 0, ( tall - 2 * m_iCornerHeight ) );
|
||||
}
|
||||
|
||||
for ( col=0;col<3;col++ )
|
||||
{
|
||||
if ( col == 0 || col == 2 )
|
||||
{
|
||||
//uvw - col 0 or 2, is src_corner_width
|
||||
uvw = m_flCornerWidthPercent;
|
||||
drawW = m_iCornerWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
//uvw - col 1, is wide - ( 2 * src_corner_width ) ( min 0 )
|
||||
uvw = max( 1.f - 2.f * m_flCornerWidthPercent, 0.0f );
|
||||
drawW = max( 0, ( wide - 2 * m_iCornerWidth ) );
|
||||
}
|
||||
|
||||
Vector2D uv11( uvx, uvy );
|
||||
Vector2D uv21( uvx+uvw, uvy );
|
||||
Vector2D uv22( uvx+uvw, uvy+uvh );
|
||||
Vector2D uv12( uvx, uvy+uvh );
|
||||
|
||||
vgui::Vertex_t verts[4];
|
||||
verts[0].Init( Vector2D( x, y ), uv11 );
|
||||
verts[1].Init( Vector2D( x+drawW, y ), uv21 );
|
||||
verts[2].Init( Vector2D( x+drawW, y+drawH ), uv22 );
|
||||
verts[3].Init( Vector2D( x, y+drawH ), uv12 );
|
||||
|
||||
g_pSurface->DrawTexturedPolygon( 4, verts );
|
||||
|
||||
x += drawW;
|
||||
uvx += uvw;
|
||||
}
|
||||
|
||||
y += drawH;
|
||||
uvy += uvh;
|
||||
}
|
||||
|
||||
g_pSurface->DrawSetTexture(0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScalableImageBorder::Paint(VPANEL panel)
|
||||
{
|
||||
// get panel size
|
||||
int wide, tall;
|
||||
ipanel()->GetSize( panel, wide, tall );
|
||||
Paint(0, 0, wide, tall, -1, 0, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScalableImageBorder::ApplySchemeSettings(IScheme *pScheme, KeyValues *inResourceData)
|
||||
{
|
||||
m_eBackgroundType = (backgroundtype_e)inResourceData->GetInt("backgroundtype");
|
||||
|
||||
m_iSrcCornerHeight = inResourceData->GetInt( "src_corner_height" );
|
||||
m_iSrcCornerWidth = inResourceData->GetInt( "src_corner_width" );
|
||||
m_iCornerHeight = inResourceData->GetInt( "draw_corner_height" );
|
||||
m_iCornerWidth = inResourceData->GetInt( "draw_corner_width" );
|
||||
|
||||
// scale the x and y up to our screen co-ords
|
||||
m_iCornerHeight = scheme()->GetProportionalScaledValue( m_iCornerHeight);
|
||||
m_iCornerWidth = scheme()->GetProportionalScaledValue(m_iCornerWidth);
|
||||
|
||||
const char *imageName = inResourceData->GetString("image", "");
|
||||
SetImage( imageName );
|
||||
|
||||
m_bPaintFirst = inResourceData->GetInt("paintfirst", true );
|
||||
|
||||
const char *col = inResourceData->GetString("color", NULL);
|
||||
if ( col && col[0] )
|
||||
{
|
||||
m_Color = pScheme->GetColor(col, Color(255, 255, 255, 255));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Color = Color(255, 255, 255, 255);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *ScalableImageBorder::GetName()
|
||||
{
|
||||
if (_name)
|
||||
return _name;
|
||||
return "";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScalableImageBorder::SetName(const char *name)
|
||||
{
|
||||
if (_name)
|
||||
{
|
||||
delete [] _name;
|
||||
}
|
||||
|
||||
int len = Q_strlen(name) + 1;
|
||||
_name = new char[ len ];
|
||||
Q_strncpy( _name, name, len );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
IBorder::backgroundtype_e ScalableImageBorder::GetBackgroundType()
|
||||
{
|
||||
return m_eBackgroundType;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Core implementation of vgui
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SCALABLE_IMAGE_BORDER_H
|
||||
#define SCALABLE_IMAGE_BORDER_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui/VGUI.h>
|
||||
#include <vgui/IBorder.h>
|
||||
#include <vgui/IScheme.h>
|
||||
#include <vgui/IPanel.h>
|
||||
#include <Color.h>
|
||||
|
||||
class KeyValues;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Custom border that renders itself with images
|
||||
//-----------------------------------------------------------------------------
|
||||
class ScalableImageBorder : public vgui::IBorder
|
||||
{
|
||||
public:
|
||||
ScalableImageBorder();
|
||||
~ScalableImageBorder();
|
||||
|
||||
virtual void Paint(vgui::VPANEL panel);
|
||||
virtual void Paint(int x0, int y0, int x1, int y1);
|
||||
virtual void Paint(int x0, int y0, int x1, int y1, int breakSide, int breakStart, int breakStop);
|
||||
virtual void SetInset(int left, int top, int right, int bottom);
|
||||
virtual void GetInset(int &left, int &top, int &right, int &bottom);
|
||||
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme, KeyValues *inResourceData);
|
||||
|
||||
virtual const char *GetName();
|
||||
virtual void SetName(const char *name);
|
||||
virtual backgroundtype_e GetBackgroundType();
|
||||
|
||||
virtual bool PaintFirst( void ) { return m_bPaintFirst; }
|
||||
|
||||
protected:
|
||||
void SetImage(const char *imageName);
|
||||
|
||||
protected:
|
||||
int _inset[4];
|
||||
|
||||
private:
|
||||
// protected copy constructor to prevent use
|
||||
ScalableImageBorder(ScalableImageBorder&);
|
||||
|
||||
char *_name;
|
||||
|
||||
backgroundtype_e m_eBackgroundType;
|
||||
|
||||
friend class VPanel;
|
||||
|
||||
int m_iSrcCornerHeight; // in pixels, how tall is the corner inside the image
|
||||
int m_iSrcCornerWidth; // same for width
|
||||
int m_iCornerHeight; // output size of the corner height in pixels
|
||||
int m_iCornerWidth; // same for width
|
||||
|
||||
int m_iTextureID;
|
||||
|
||||
float m_flCornerWidthPercent; // corner width as percentage of image width
|
||||
float m_flCornerHeightPercent; // same for height
|
||||
|
||||
char *m_pszImageName;
|
||||
bool m_bPaintFirst;
|
||||
|
||||
Color m_Color;
|
||||
};
|
||||
|
||||
#endif // SCALABLE_IMAGE_BORDER_H
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,82 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Core implementation of vgui
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef VGUI_BORDER_H
|
||||
#define VGUI_BORDER_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui/VGUI.h>
|
||||
#include <vgui/IBorder.h>
|
||||
#include <vgui/IScheme.h>
|
||||
#include <Color.h>
|
||||
|
||||
class KeyValues;
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Interface to panel borders
|
||||
// Borders have a close relationship with panels
|
||||
//-----------------------------------------------------------------------------
|
||||
class Border : public IBorder
|
||||
{
|
||||
public:
|
||||
Border();
|
||||
~Border();
|
||||
|
||||
virtual void Paint(VPANEL panel);
|
||||
virtual void Paint(int x0, int y0, int x1, int y1);
|
||||
virtual void Paint(int x0, int y0, int x1, int y1, int breakSide, int breakStart, int breakStop);
|
||||
virtual void SetInset(int left, int top, int right, int bottom);
|
||||
virtual void GetInset(int &left, int &top, int &right, int &bottom);
|
||||
|
||||
virtual void ApplySchemeSettings(IScheme *pScheme, KeyValues *inResourceData);
|
||||
|
||||
virtual const char *GetName();
|
||||
virtual void SetName(const char *name);
|
||||
virtual backgroundtype_e GetBackgroundType();
|
||||
|
||||
virtual bool PaintFirst( void ) { return false; }
|
||||
|
||||
protected:
|
||||
int _inset[4];
|
||||
|
||||
private:
|
||||
// protected copy constructor to prevent use
|
||||
Border(Border&);
|
||||
|
||||
void ParseSideSettings(int side_index, KeyValues *inResourceData, IScheme *pScheme);
|
||||
|
||||
char *_name;
|
||||
|
||||
// border drawing description
|
||||
struct line_t
|
||||
{
|
||||
Color col;
|
||||
int startOffset;
|
||||
int endOffset;
|
||||
};
|
||||
|
||||
struct side_t
|
||||
{
|
||||
int count;
|
||||
line_t *lines;
|
||||
};
|
||||
|
||||
side_t _sides[4]; // left, top, right, bottom
|
||||
backgroundtype_e m_eBackgroundType;
|
||||
|
||||
friend class VPanel;
|
||||
};
|
||||
|
||||
} // namespace vgui
|
||||
|
||||
#endif // VGUI_BORDER_H
|
||||
@@ -0,0 +1,782 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <vgui/IPanel.h>
|
||||
#include <vgui/IClientPanel.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/IVGui.h>
|
||||
#include <vgui/Cursor.h>
|
||||
|
||||
#include "vgui_internal.h"
|
||||
#include "VPanel.h"
|
||||
|
||||
#include "tier0/minidump.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
// Lame copy from Panel
|
||||
enum PinCorner_e
|
||||
{
|
||||
PIN_TOPLEFT = 0,
|
||||
PIN_TOPRIGHT,
|
||||
PIN_BOTTOMLEFT,
|
||||
PIN_BOTTOMRIGHT,
|
||||
|
||||
// For sibling pinning
|
||||
PIN_CENTER_TOP,
|
||||
PIN_CENTER_RIGHT,
|
||||
PIN_CENTER_BOTTOM,
|
||||
PIN_CENTER_LEFT,
|
||||
|
||||
NUM_PIN_POINTS,
|
||||
};
|
||||
|
||||
float PinDeltas[NUM_PIN_POINTS][2] =
|
||||
{
|
||||
{ 0, 0 }, // PIN_TOPLEFT,
|
||||
{ 1, 0 }, // PIN_TOPRIGHT,
|
||||
{ 0, 1 }, // PIN_BOTTOMLEFT,
|
||||
{ 1, 1 }, // PIN_BOTTOMRIGHT,
|
||||
{ 0.5, 0 }, // PIN_CENTER_TOP,
|
||||
{ 1, 0.5 }, // PIN_CENTER_RIGHT,
|
||||
{ 0.5, 1 }, // PIN_CENTER_BOTTOM,
|
||||
{ 0, 0.5 }, // PIN_CENTER_LEFT,
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
VPanel::VPanel()
|
||||
{
|
||||
_pos[0] = _pos[1] = 0;
|
||||
_absPos[0] = _absPos[1] = 0;
|
||||
_size[0] = _size[1] = 0;
|
||||
|
||||
_minimumSize[0] = 0;
|
||||
_minimumSize[1] = 0;
|
||||
|
||||
_zpos = 0;
|
||||
|
||||
_inset[0] = _inset[1] = _inset[2] = _inset[3] = 0;
|
||||
_clipRect[0] = _clipRect[1] = _clipRect[2] = _clipRect[3] = 0;
|
||||
|
||||
_visible = true;
|
||||
_enabled = true;
|
||||
_clientPanel = NULL;
|
||||
_parent = NULL;
|
||||
_plat = NULL;
|
||||
_popup = false;
|
||||
_isTopmostPopup = false;
|
||||
_hPanel = INVALID_PANEL;
|
||||
|
||||
_mouseInput = true; // by default you want mouse and kb input to this panel
|
||||
_kbInput = true;
|
||||
|
||||
_pinsibling = NULL;
|
||||
_pinsibling_my_corner = PIN_TOPLEFT;
|
||||
_pinsibling_their_corner = PIN_TOPLEFT;
|
||||
|
||||
m_nThinkTraverseLevel = 0;
|
||||
_clientPanelHandle = vgui::INVALID_PANEL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
VPanel::~VPanel()
|
||||
{
|
||||
// Someone just deleted their parent Panel while it was being used in InternalSolveTraverse().
|
||||
// This will cause a difficult to debug crash, so we spew out the panel name here in hopes
|
||||
// it will help track down the offender.
|
||||
if ( m_nThinkTraverseLevel != 0 )
|
||||
{
|
||||
Warning( "Deleting in-use vpanel: %s/%s %p.\n", GetName(), GetClassName(), this );
|
||||
#ifdef STAGING_ONLY
|
||||
DebuggerBreak();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::TraverseLevel( int val )
|
||||
{
|
||||
// Bump up our traverse level.
|
||||
m_nThinkTraverseLevel += m_nThinkTraverseLevel;
|
||||
|
||||
// Bump up our client panel traverse level.
|
||||
if ( Client() )
|
||||
{
|
||||
VPANEL vp = g_pVGui->HandleToPanel( _clientPanelHandle );
|
||||
if ( vp == vgui::INVALID_PANEL )
|
||||
{
|
||||
// This is really bad - we have a Client() pointer that is invalid.
|
||||
Warning( "Panel '%s/%s' has invalid client: %p.\n", GetName(), GetClassName(), Client() );
|
||||
#ifdef STAGING_ONLY
|
||||
DebuggerBreak();
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( Client()->GetVPanel() )
|
||||
{
|
||||
VPanel *vpanel = (VPanel *)Client()->GetVPanel();
|
||||
vpanel->m_nThinkTraverseLevel += vpanel->m_nThinkTraverseLevel;
|
||||
}
|
||||
}
|
||||
|
||||
// This doesn't work. It appears we add all kinds of children to various panels in the
|
||||
// InternalThinkTraverse functions, and that means the refcount is 0 when added, and
|
||||
// then drops to -1 when we decrement the traverse level.
|
||||
#if 0
|
||||
// Bump up our children traverse levels.
|
||||
CUtlVector< VPanel * > &children = GetChildren();
|
||||
for ( int i = 0; i < children.Count(); ++i )
|
||||
{
|
||||
VPanel *child = children[ i ];
|
||||
if ( child )
|
||||
child->m_nThinkTraverseLevel = Max( child->m_nThinkTraverseLevel + val, 0 );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::Init(IClientPanel *attachedClientPanel)
|
||||
{
|
||||
_clientPanel = attachedClientPanel;
|
||||
_clientPanelHandle = g_pVGui->PanelToHandle( attachedClientPanel ? attachedClientPanel->GetVPanel() : 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::Solve()
|
||||
{
|
||||
short basePos[2];
|
||||
basePos[0] = _pos[0];
|
||||
basePos[1] = _pos[1];
|
||||
|
||||
int baseSize[2];
|
||||
GetSize( baseSize[0], baseSize[1] );
|
||||
|
||||
VPanel *parent = GetParent();
|
||||
if (IsPopup())
|
||||
{
|
||||
// if we're a popup, draw at the highest level
|
||||
parent = (VPanel *)g_pSurface->GetEmbeddedPanel();
|
||||
}
|
||||
|
||||
int pabs[2];
|
||||
if ( parent )
|
||||
{
|
||||
parent->GetAbsPos(pabs[0], pabs[1]);
|
||||
}
|
||||
|
||||
if ( _pinsibling )
|
||||
{
|
||||
_pinsibling->Solve();
|
||||
|
||||
int sibPos[2];
|
||||
int sibSize[2];
|
||||
_pinsibling->GetInternalAbsPos( sibPos[0], sibPos[1] );
|
||||
_pinsibling->GetSize( sibSize[0], sibSize[1] );
|
||||
|
||||
for ( int i = 0; i < 2; i++ )
|
||||
{
|
||||
if ( parent )
|
||||
{
|
||||
sibPos[i] -= pabs[i];
|
||||
}
|
||||
|
||||
// Determine which direction positive values move in. For center pins, we use screen relative signs.
|
||||
int iSign = 1;
|
||||
if ( i == 0 && (_pinsibling_their_corner == PIN_CENTER_LEFT || _pinsibling_their_corner == PIN_TOPLEFT || _pinsibling_their_corner == PIN_BOTTOMLEFT) )
|
||||
{
|
||||
iSign = -1;
|
||||
}
|
||||
else if ( i == 1 && (_pinsibling_their_corner == PIN_CENTER_TOP || _pinsibling_their_corner == PIN_TOPLEFT || _pinsibling_their_corner == PIN_TOPRIGHT) )
|
||||
{
|
||||
iSign = -1;
|
||||
}
|
||||
|
||||
int iPos = sibPos[i] + (sibSize[i] * PinDeltas[_pinsibling_their_corner][i]);
|
||||
iPos -= (baseSize[i] * PinDeltas[_pinsibling_my_corner][i]);
|
||||
iPos += basePos[i] * iSign;
|
||||
|
||||
basePos[i] = iPos;
|
||||
}
|
||||
}
|
||||
|
||||
int absX = basePos[0];
|
||||
int absY = basePos[1];
|
||||
_absPos[0] = basePos[0];
|
||||
_absPos[1] = basePos[1];
|
||||
|
||||
// put into parent space
|
||||
int pinset[4] = {0, 0, 0, 0};
|
||||
if ( parent )
|
||||
{
|
||||
parent->GetInset( pinset[0], pinset[1], pinset[2], pinset[3] );
|
||||
|
||||
absX += pabs[0] + pinset[0];
|
||||
absY += pabs[1] + pinset[1];
|
||||
|
||||
_absPos[0] = clamp( absX, -32767, 32767 );
|
||||
_absPos[1] = clamp( absY, -32767, 32767 );
|
||||
}
|
||||
|
||||
// set initial bounds
|
||||
_clipRect[0] = _absPos[0];
|
||||
_clipRect[1] = _absPos[1];
|
||||
|
||||
int absX2 = absX + baseSize[0];
|
||||
int absY2 = absY + baseSize[1];
|
||||
_clipRect[2] = clamp( absX2, -32767, 32767 );
|
||||
_clipRect[3] = clamp( absY2, -32767, 32767 );
|
||||
|
||||
// clip to parent, if we're not a popup
|
||||
if ( parent && !IsPopup() )
|
||||
{
|
||||
int pclip[4];
|
||||
parent->GetClipRect(pclip[0], pclip[1], pclip[2], pclip[3]);
|
||||
|
||||
if (_clipRect[0] < pclip[0])
|
||||
{
|
||||
_clipRect[0] = pclip[0];
|
||||
}
|
||||
|
||||
if (_clipRect[1] < pclip[1])
|
||||
{
|
||||
_clipRect[1] = pclip[1];
|
||||
}
|
||||
|
||||
if(_clipRect[2] > pclip[2])
|
||||
{
|
||||
_clipRect[2] = pclip[2] - pinset[2];
|
||||
}
|
||||
|
||||
if(_clipRect[3] > pclip[3])
|
||||
{
|
||||
_clipRect[3] = pclip[3] - pinset[3];
|
||||
}
|
||||
|
||||
if ( _clipRect[0] > _clipRect[2] )
|
||||
{
|
||||
_clipRect[2] = _clipRect[0];
|
||||
}
|
||||
|
||||
if ( _clipRect[1] > _clipRect[3] )
|
||||
{
|
||||
_clipRect[3] = _clipRect[1];
|
||||
}
|
||||
}
|
||||
|
||||
Assert( _clipRect[0] <= _clipRect[2] );
|
||||
Assert( _clipRect[1] <= _clipRect[3] );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::SetPos(int x, int y)
|
||||
{
|
||||
_pos[0] = x;
|
||||
_pos[1] = y;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::GetPos(int &x, int &y)
|
||||
{
|
||||
x = _pos[0];
|
||||
y = _pos[1];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::SetSize(int wide,int tall)
|
||||
{
|
||||
if (wide<_minimumSize[0])
|
||||
{
|
||||
wide=_minimumSize[0];
|
||||
}
|
||||
if (tall<_minimumSize[1])
|
||||
{
|
||||
tall=_minimumSize[1];
|
||||
}
|
||||
|
||||
if (_size[0] == wide && _size[1] == tall)
|
||||
return;
|
||||
|
||||
_size[0]=wide;
|
||||
_size[1]=tall;
|
||||
|
||||
Client()->OnSizeChanged(wide, tall);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::GetSize(int& wide,int& tall)
|
||||
{
|
||||
wide=_size[0];
|
||||
tall=_size[1];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::SetMinimumSize(int wide,int tall)
|
||||
{
|
||||
_minimumSize[0]=wide;
|
||||
_minimumSize[1]=tall;
|
||||
|
||||
// check if we're currently smaller than the new minimum size
|
||||
int currentWidth = _size[0];
|
||||
if (currentWidth < wide)
|
||||
{
|
||||
currentWidth = wide;
|
||||
}
|
||||
int currentHeight = _size[1];
|
||||
if (currentHeight < tall)
|
||||
{
|
||||
currentHeight = tall;
|
||||
}
|
||||
|
||||
// resize to new minimum size if necessary
|
||||
if (currentWidth != _size[0] || currentHeight != _size[1])
|
||||
{
|
||||
SetSize(currentWidth, currentHeight);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::GetMinimumSize(int &wide, int &tall)
|
||||
{
|
||||
wide = _minimumSize[0];
|
||||
tall = _minimumSize[1];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::SetVisible(bool state)
|
||||
{
|
||||
if (_visible == state)
|
||||
return;
|
||||
|
||||
// need to tell the surface (in case special window processing needs to occur)
|
||||
g_pSurface->SetPanelVisible((VPANEL)this, state);
|
||||
|
||||
_visible = state;
|
||||
|
||||
if( IsPopup() )
|
||||
{
|
||||
vgui::g_pSurface->CalculateMouseVisible();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::SetEnabled(bool state)
|
||||
{
|
||||
_enabled = state;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool VPanel::IsVisible()
|
||||
{
|
||||
return _visible;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool VPanel::IsEnabled()
|
||||
{
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::GetAbsPos(int &x, int &y)
|
||||
{
|
||||
x = _absPos[0];
|
||||
y = _absPos[1];
|
||||
|
||||
g_pSurface->OffsetAbsPos( x, y );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::GetInternalAbsPos(int &x, int &y)
|
||||
{
|
||||
x = _absPos[0];
|
||||
y = _absPos[1];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::GetClipRect(int &x0, int &y0, int &x1, int &y1)
|
||||
{
|
||||
x0 = _clipRect[0];
|
||||
y0 = _clipRect[1];
|
||||
x1 = _clipRect[2];
|
||||
y1 = _clipRect[3];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::SetInset(int left, int top, int right, int bottom)
|
||||
{
|
||||
_inset[0] = left;
|
||||
_inset[1] = top;
|
||||
_inset[2] = right;
|
||||
_inset[3] = bottom;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::GetInset(int &left, int &top, int &right, int &bottom)
|
||||
{
|
||||
left = _inset[0];
|
||||
top = _inset[1];
|
||||
right = _inset[2];
|
||||
bottom = _inset[3];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::SetParent(VPanel *newParent)
|
||||
{
|
||||
if (this == newParent)
|
||||
return;
|
||||
|
||||
if (_parent == newParent)
|
||||
return;
|
||||
|
||||
if (_parent != NULL)
|
||||
{
|
||||
_parent->_childDar.RemoveElement(this);
|
||||
_parent = null;
|
||||
}
|
||||
|
||||
if (newParent != NULL)
|
||||
{
|
||||
_parent = newParent;
|
||||
_parent->_childDar.PutElement(this);
|
||||
SetZPos(_zpos); // re-sort parent's panel order if necessary
|
||||
if (_parent->Client())
|
||||
{
|
||||
_parent->Client()->OnChildAdded((VPANEL)this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int VPanel::GetChildCount()
|
||||
{
|
||||
return _childDar.GetCount();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
VPanel *VPanel::GetChild(int index)
|
||||
{
|
||||
return _childDar[index];
|
||||
}
|
||||
|
||||
CUtlVector< VPanel *> &VPanel::GetChildren()
|
||||
{
|
||||
return _childDar;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
VPanel *VPanel::GetParent()
|
||||
{
|
||||
return _parent;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets the Z position of a panel and reorders it appropriately
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::SetZPos(int z)
|
||||
{
|
||||
_zpos = z;
|
||||
|
||||
if (_parent)
|
||||
{
|
||||
// find the child in the list
|
||||
int childCount = _parent->GetChildCount();
|
||||
int i;
|
||||
for (i = 0; i < childCount; i++)
|
||||
{
|
||||
if (_parent->GetChild(i) == this)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == childCount)
|
||||
return;
|
||||
|
||||
while (1)
|
||||
{
|
||||
VPanel *prevChild = NULL, *nextChild = NULL;
|
||||
|
||||
if ( i > 0 )
|
||||
{
|
||||
prevChild = _parent->GetChild( i - 1 );
|
||||
}
|
||||
if ( i <(childCount - 1) )
|
||||
{
|
||||
nextChild = _parent->GetChild( i + 1 );
|
||||
}
|
||||
|
||||
// check either side of the child to see if it should move
|
||||
if ( i > 0 && prevChild && ( prevChild->_zpos > _zpos ) )
|
||||
{
|
||||
// swap with the lower
|
||||
_parent->_childDar.SetElementAt(prevChild, i);
|
||||
_parent->_childDar.SetElementAt(this, i - 1);
|
||||
i--;
|
||||
}
|
||||
else if (i < (childCount - 1) && nextChild && ( nextChild->_zpos < _zpos ) )
|
||||
{
|
||||
// swap with the higher
|
||||
_parent->_childDar.SetElementAt(nextChild, i);
|
||||
_parent->_childDar.SetElementAt(this, i + 1);
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the z position of this panel
|
||||
//-----------------------------------------------------------------------------
|
||||
int VPanel::GetZPos()
|
||||
{
|
||||
return _zpos;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Moves the panel to the front of the z-order
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::MoveToFront(void)
|
||||
{
|
||||
g_pSurface->MovePopupToFront((VPANEL)this);
|
||||
|
||||
if (_parent)
|
||||
{
|
||||
// move this panel to the end of it's parents list
|
||||
_parent->_childDar.MoveElementToEnd(this);
|
||||
|
||||
// Validate the Z order
|
||||
int i = _parent->_childDar.GetCount() - 2;
|
||||
while (i >= 0)
|
||||
{
|
||||
if (_parent->_childDar[i]->_zpos > _zpos)
|
||||
{
|
||||
// we can't be in front of this; swap positions
|
||||
_parent->_childDar.SetElementAt(_parent->_childDar[i], i + 1);
|
||||
_parent->_childDar.SetElementAt(this, i);
|
||||
|
||||
// check the next value
|
||||
i--;
|
||||
}
|
||||
else
|
||||
{
|
||||
// order valid
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Moves the panel to the back of the z-order
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::MoveToBack()
|
||||
{
|
||||
if (_parent)
|
||||
{
|
||||
// move this panel to the end of it's parents list
|
||||
_parent->_childDar.RemoveElement(this);
|
||||
_parent->_childDar.InsertElementAt(this, 0);
|
||||
|
||||
// Validate the Z order
|
||||
int i = 1;
|
||||
while (i < _parent->_childDar.GetCount())
|
||||
{
|
||||
if (_parent->_childDar[i]->_zpos < _zpos)
|
||||
{
|
||||
// we can't be behind this; swap positions
|
||||
_parent->_childDar.SetElementAt(_parent->_childDar[i], i - 1);
|
||||
_parent->_childDar.SetElementAt(this, i);
|
||||
|
||||
// check the next value
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// order valid
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Iterates up the hierarchy looking to see if a panel has the specified ancestor
|
||||
//-----------------------------------------------------------------------------
|
||||
bool VPanel::HasParent(VPanel *potentialParent)
|
||||
{
|
||||
if (this == potentialParent)
|
||||
return true;
|
||||
|
||||
if (_parent)
|
||||
{
|
||||
return _parent->HasParent(potentialParent);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SurfacePlat *VPanel::Plat()
|
||||
{
|
||||
return _plat;
|
||||
}
|
||||
|
||||
void VPanel::SetPlat(SurfacePlat *Plat)
|
||||
{
|
||||
_plat = Plat;
|
||||
}
|
||||
|
||||
bool VPanel::IsPopup()
|
||||
{
|
||||
return _popup;
|
||||
}
|
||||
|
||||
void VPanel::SetPopup(bool state)
|
||||
{
|
||||
_popup = state;
|
||||
}
|
||||
|
||||
bool VPanel::IsTopmostPopup() const
|
||||
{
|
||||
return _isTopmostPopup;
|
||||
}
|
||||
|
||||
void VPanel::SetTopmostPopup( bool bEnable )
|
||||
{
|
||||
_isTopmostPopup = bEnable;
|
||||
}
|
||||
|
||||
bool VPanel::IsFullyVisible()
|
||||
{
|
||||
// recursively check to see if the panel and all it's parents are visible
|
||||
VPanel *panel = this;
|
||||
while (panel)
|
||||
{
|
||||
if (!panel->_visible)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
panel = panel->_parent;
|
||||
}
|
||||
|
||||
// we're visible all the way up the hierarchy
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *VPanel::GetName()
|
||||
{
|
||||
return Client()->GetName();
|
||||
}
|
||||
|
||||
const char *VPanel::GetClassName()
|
||||
{
|
||||
return Client()->GetClassName();
|
||||
}
|
||||
|
||||
HScheme VPanel::GetScheme()
|
||||
{
|
||||
return Client()->GetScheme();
|
||||
}
|
||||
|
||||
|
||||
void VPanel::SendMessage(KeyValues *params, VPANEL ifrompanel)
|
||||
{
|
||||
Client()->OnMessage(params, ifrompanel);
|
||||
}
|
||||
|
||||
|
||||
void VPanel::SetKeyBoardInputEnabled(bool state)
|
||||
{
|
||||
_kbInput = state;
|
||||
}
|
||||
|
||||
void VPanel::SetMouseInputEnabled(bool state)
|
||||
{
|
||||
_mouseInput = state;
|
||||
}
|
||||
|
||||
bool VPanel::IsKeyBoardInputEnabled()
|
||||
{
|
||||
return _kbInput;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool VPanel::IsMouseInputEnabled()
|
||||
{
|
||||
return _mouseInput;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sibling pins
|
||||
//-----------------------------------------------------------------------------
|
||||
void VPanel::SetSiblingPin(VPanel *newSibling, byte iMyCornerToPin, byte iSiblingCornerToPinTo )
|
||||
{
|
||||
_pinsibling = newSibling;
|
||||
_pinsibling_my_corner = iMyCornerToPin;
|
||||
_pinsibling_their_corner = iSiblingCornerToPinTo;
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef VPANEL_H
|
||||
#define VPANEL_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui/Dar.h>
|
||||
#include <vgui/IPanel.h>
|
||||
|
||||
#ifdef GetClassName
|
||||
#undef GetClassName
|
||||
#endif
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
|
||||
class SurfaceBase;
|
||||
class IClientPanel;
|
||||
struct SerialPanel_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: VGUI private implementation of panel
|
||||
//-----------------------------------------------------------------------------
|
||||
class VPanel
|
||||
{
|
||||
public:
|
||||
VPanel();
|
||||
virtual ~VPanel();
|
||||
|
||||
virtual void Init(IClientPanel *attachedClientPanel);
|
||||
|
||||
virtual SurfacePlat *Plat();
|
||||
virtual void SetPlat(SurfacePlat *pl);
|
||||
|
||||
virtual HPanel GetHPanel() { return _hPanel; } // safe pointer handling
|
||||
virtual void SetHPanel(HPanel hPanel) { _hPanel = hPanel; }
|
||||
|
||||
virtual bool IsPopup();
|
||||
virtual void SetPopup(bool state);
|
||||
virtual bool IsFullyVisible();
|
||||
|
||||
virtual void SetPos(int x, int y);
|
||||
virtual void GetPos(int &x, int &y);
|
||||
virtual void SetSize(int wide,int tall);
|
||||
virtual void GetSize(int& wide,int& tall);
|
||||
virtual void SetMinimumSize(int wide,int tall);
|
||||
virtual void GetMinimumSize(int& wide,int& tall);
|
||||
virtual void SetZPos(int z);
|
||||
virtual int GetZPos();
|
||||
|
||||
virtual void GetAbsPos(int &x, int &y);
|
||||
virtual void GetClipRect(int &x0, int &y0, int &x1, int &y1);
|
||||
virtual void SetInset(int left, int top, int right, int bottom);
|
||||
virtual void GetInset(int &left, int &top, int &right, int &bottom);
|
||||
|
||||
virtual void Solve();
|
||||
|
||||
virtual void SetVisible(bool state);
|
||||
virtual void SetEnabled(bool state);
|
||||
virtual bool IsVisible();
|
||||
virtual bool IsEnabled();
|
||||
virtual void SetParent(VPanel *newParent);
|
||||
virtual int GetChildCount();
|
||||
virtual VPanel *GetChild(int index);
|
||||
virtual VPanel *GetParent();
|
||||
virtual void MoveToFront();
|
||||
virtual void MoveToBack();
|
||||
virtual bool HasParent(VPanel *potentialParent);
|
||||
|
||||
virtual CUtlVector< VPanel * > &GetChildren();
|
||||
|
||||
// gets names of the object (for debugging purposes)
|
||||
virtual const char *GetName();
|
||||
virtual const char *GetClassName();
|
||||
|
||||
virtual HScheme GetScheme();
|
||||
|
||||
// handles a message
|
||||
virtual void SendMessage(KeyValues *params, VPANEL ifromPanel);
|
||||
|
||||
// wrapper to get Client panel interface
|
||||
virtual IClientPanel *Client() { return _clientPanel; }
|
||||
|
||||
// input interest
|
||||
virtual void SetKeyBoardInputEnabled(bool state);
|
||||
virtual void SetMouseInputEnabled(bool state);
|
||||
virtual bool IsKeyBoardInputEnabled();
|
||||
virtual bool IsMouseInputEnabled();
|
||||
|
||||
virtual bool IsTopmostPopup() const;
|
||||
virtual void SetTopmostPopup( bool bEnable );
|
||||
|
||||
// sibling pins
|
||||
virtual void SetSiblingPin(VPanel *newSibling, byte iMyCornerToPin = 0, byte iSiblingCornerToPinTo = 0 );
|
||||
|
||||
public:
|
||||
virtual void GetInternalAbsPos(int &x, int &y);
|
||||
virtual void TraverseLevel( int val );
|
||||
|
||||
private:
|
||||
Dar<VPanel*> _childDar;
|
||||
VPanel *_parent;
|
||||
SurfacePlat *_plat; // platform-specific data
|
||||
HPanel _hPanel;
|
||||
|
||||
// our companion Client panel
|
||||
IClientPanel *_clientPanel;
|
||||
|
||||
short _pos[2];
|
||||
short _size[2];
|
||||
short _minimumSize[2];
|
||||
|
||||
short _inset[4];
|
||||
short _clipRect[4];
|
||||
short _absPos[2];
|
||||
|
||||
short _zpos; // z-order position
|
||||
|
||||
bool _visible : 1;
|
||||
bool _enabled : 1;
|
||||
bool _popup : 1;
|
||||
bool _mouseInput : 1; // used for popups
|
||||
bool _kbInput : 1;
|
||||
bool _isTopmostPopup : 1;
|
||||
|
||||
VPanel *_pinsibling;
|
||||
byte _pinsibling_my_corner;
|
||||
byte _pinsibling_their_corner;
|
||||
|
||||
int m_nMessageContextId;
|
||||
int m_nThinkTraverseLevel;
|
||||
HPanel _clientPanelHandle; // Temp to check if _clientPanel is valid.
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // VPANEL_H
|
||||
@@ -0,0 +1,362 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "VPanel.h"
|
||||
#include "vgui_internal.h"
|
||||
|
||||
#include <vgui/IClientPanel.h>
|
||||
#include <vgui/IPanel.h>
|
||||
#include <vgui/ISurface.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Protects internal VPanel through the versionable interface IPanel
|
||||
//-----------------------------------------------------------------------------
|
||||
class VPanelWrapper : public vgui::IPanel
|
||||
{
|
||||
public:
|
||||
virtual void Init(VPANEL vguiPanel, IClientPanel *panel)
|
||||
{
|
||||
((VPanel *)vguiPanel)->Init(panel);
|
||||
}
|
||||
|
||||
// returns a pointer to the Client panel
|
||||
virtual IClientPanel *Client(VPANEL vguiPanel)
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->Client();
|
||||
}
|
||||
|
||||
// methods
|
||||
virtual void SetPos(VPANEL vguiPanel, int x, int y)
|
||||
{
|
||||
((VPanel *)vguiPanel)->SetPos(x, y);
|
||||
}
|
||||
|
||||
virtual void GetPos(VPANEL vguiPanel, int &x, int &y)
|
||||
{
|
||||
((VPanel *)vguiPanel)->GetPos(x, y);
|
||||
}
|
||||
|
||||
virtual void SetSize(VPANEL vguiPanel, int wide,int tall)
|
||||
{
|
||||
((VPanel *)vguiPanel)->SetSize(wide, tall);
|
||||
}
|
||||
|
||||
virtual void GetSize(VPANEL vguiPanel, int &wide, int &tall)
|
||||
{
|
||||
((VPanel *)vguiPanel)->GetSize(wide, tall);
|
||||
}
|
||||
|
||||
virtual void SetMinimumSize(VPANEL vguiPanel, int wide, int tall)
|
||||
{
|
||||
((VPanel *)vguiPanel)->SetMinimumSize(wide, tall);
|
||||
}
|
||||
|
||||
virtual void GetMinimumSize(VPANEL vguiPanel, int &wide, int &tall)
|
||||
{
|
||||
((VPanel *)vguiPanel)->GetMinimumSize(wide, tall);
|
||||
}
|
||||
|
||||
virtual void SetZPos(VPANEL vguiPanel, int z)
|
||||
{
|
||||
((VPanel *)vguiPanel)->SetZPos(z);
|
||||
}
|
||||
|
||||
virtual int GetZPos(VPANEL vguiPanel)
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->GetZPos();
|
||||
}
|
||||
|
||||
virtual void GetAbsPos(VPANEL vguiPanel, int &x, int &y)
|
||||
{
|
||||
((VPanel *)vguiPanel)->GetAbsPos(x, y);
|
||||
}
|
||||
|
||||
virtual void GetClipRect(VPANEL vguiPanel, int &x0, int &y0, int &x1, int &y1)
|
||||
{
|
||||
((VPanel *)vguiPanel)->GetClipRect(x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
virtual void SetInset(VPANEL vguiPanel, int left, int top, int right, int bottom)
|
||||
{
|
||||
((VPanel *)vguiPanel)->SetInset(left, top, right, bottom);
|
||||
}
|
||||
|
||||
virtual void GetInset(VPANEL vguiPanel, int &left, int &top, int &right, int &bottom)
|
||||
{
|
||||
((VPanel *)vguiPanel)->GetInset(left, top, right, bottom);
|
||||
}
|
||||
|
||||
virtual void SetVisible(VPANEL vguiPanel, bool state)
|
||||
{
|
||||
((VPanel *)vguiPanel)->SetVisible(state);
|
||||
}
|
||||
|
||||
virtual void SetEnabled(VPANEL vguiPanel, bool state)
|
||||
{
|
||||
((VPanel *)vguiPanel)->SetEnabled(state);
|
||||
}
|
||||
|
||||
virtual bool IsVisible(VPANEL vguiPanel)
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->IsVisible();
|
||||
}
|
||||
|
||||
virtual bool IsEnabled(VPANEL vguiPanel)
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->IsEnabled();
|
||||
}
|
||||
|
||||
// Used by the drag/drop manager to always draw on top
|
||||
virtual bool IsTopmostPopup( VPANEL vguiPanel )
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->IsTopmostPopup();
|
||||
}
|
||||
|
||||
virtual void SetTopmostPopup( VPANEL vguiPanel, bool state )
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->SetTopmostPopup( state );
|
||||
}
|
||||
|
||||
virtual void SetParent(VPANEL vguiPanel, VPANEL newParent)
|
||||
{
|
||||
((VPanel *)vguiPanel)->SetParent((VPanel *)newParent);
|
||||
}
|
||||
|
||||
virtual int GetChildCount(VPANEL vguiPanel)
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->GetChildCount();
|
||||
}
|
||||
|
||||
virtual VPANEL GetChild(VPANEL vguiPanel, int index)
|
||||
{
|
||||
return (VPANEL)((VPanel *)vguiPanel)->GetChild(index);
|
||||
}
|
||||
|
||||
virtual CUtlVector< VPANEL > &GetChildren( VPANEL vguiPanel )
|
||||
{
|
||||
return (CUtlVector< VPANEL > &)((VPanel *)vguiPanel)->GetChildren();
|
||||
}
|
||||
|
||||
virtual VPANEL GetParent(VPANEL vguiPanel)
|
||||
{
|
||||
return (VPANEL)((VPanel *)vguiPanel)->GetParent();
|
||||
}
|
||||
|
||||
virtual void MoveToFront(VPANEL vguiPanel)
|
||||
{
|
||||
((VPanel *)vguiPanel)->MoveToFront();
|
||||
}
|
||||
|
||||
virtual void MoveToBack(VPANEL vguiPanel)
|
||||
{
|
||||
((VPanel *)vguiPanel)->MoveToBack();
|
||||
}
|
||||
|
||||
virtual bool HasParent(VPANEL vguiPanel, VPANEL potentialParent)
|
||||
{
|
||||
if (!vguiPanel)
|
||||
return false;
|
||||
|
||||
return ((VPanel *)vguiPanel)->HasParent((VPanel *)potentialParent);
|
||||
}
|
||||
|
||||
virtual bool IsPopup(VPANEL vguiPanel)
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->IsPopup();
|
||||
}
|
||||
|
||||
virtual void SetPopup(VPANEL vguiPanel, bool state)
|
||||
{
|
||||
((VPanel *)vguiPanel)->SetPopup(state);
|
||||
}
|
||||
|
||||
virtual bool IsFullyVisible( VPANEL vguiPanel )
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->IsFullyVisible();
|
||||
}
|
||||
|
||||
// calculates the panels current position within the hierarchy
|
||||
virtual void Solve(VPANEL vguiPanel)
|
||||
{
|
||||
((VPanel *)vguiPanel)->Solve();
|
||||
}
|
||||
|
||||
// used by ISurface to store platform-specific data
|
||||
virtual SurfacePlat *Plat(VPANEL vguiPanel)
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->Plat();
|
||||
}
|
||||
|
||||
virtual void SetPlat(VPANEL vguiPanel, SurfacePlat *Plat)
|
||||
{
|
||||
((VPanel *)vguiPanel)->SetPlat(Plat);
|
||||
}
|
||||
|
||||
virtual const char *GetName(VPANEL vguiPanel)
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->GetName();
|
||||
}
|
||||
|
||||
virtual const char *GetClassName(VPANEL vguiPanel)
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->GetClassName();
|
||||
}
|
||||
|
||||
virtual HScheme GetScheme(VPANEL vguiPanel)
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->GetScheme();
|
||||
}
|
||||
|
||||
virtual bool IsProportional(VPANEL vguiPanel)
|
||||
{
|
||||
return Client(vguiPanel)->IsProportional();
|
||||
}
|
||||
|
||||
virtual bool IsAutoDeleteSet(VPANEL vguiPanel)
|
||||
{
|
||||
return Client(vguiPanel)->IsAutoDeleteSet();
|
||||
}
|
||||
|
||||
virtual void DeletePanel(VPANEL vguiPanel)
|
||||
{
|
||||
Client(vguiPanel)->DeletePanel();
|
||||
}
|
||||
|
||||
virtual void SendMessage(VPANEL vguiPanel, KeyValues *params, VPANEL ifrompanel)
|
||||
{
|
||||
((VPanel *)vguiPanel)->SendMessage(params, ifrompanel);
|
||||
}
|
||||
|
||||
virtual void Think(VPANEL vguiPanel)
|
||||
{
|
||||
Client(vguiPanel)->Think();
|
||||
}
|
||||
|
||||
virtual void PerformApplySchemeSettings(VPANEL vguiPanel)
|
||||
{
|
||||
Client(vguiPanel)->PerformApplySchemeSettings();
|
||||
}
|
||||
|
||||
virtual void PaintTraverse(VPANEL vguiPanel, bool forceRepaint, bool allowForce)
|
||||
{
|
||||
Client(vguiPanel)->PaintTraverse(forceRepaint, allowForce);
|
||||
}
|
||||
|
||||
virtual void Repaint(VPANEL vguiPanel)
|
||||
{
|
||||
Client(vguiPanel)->Repaint();
|
||||
}
|
||||
|
||||
virtual VPANEL IsWithinTraverse(VPANEL vguiPanel, int x, int y, bool traversePopups)
|
||||
{
|
||||
return Client(vguiPanel)->IsWithinTraverse(x, y, traversePopups);
|
||||
}
|
||||
|
||||
virtual void OnChildAdded(VPANEL vguiPanel, VPANEL child)
|
||||
{
|
||||
Client(vguiPanel)->OnChildAdded(child);
|
||||
}
|
||||
|
||||
virtual void OnSizeChanged(VPANEL vguiPanel, int newWide, int newTall)
|
||||
{
|
||||
Client(vguiPanel)->OnSizeChanged(newWide, newTall);
|
||||
}
|
||||
|
||||
virtual void InternalFocusChanged(VPANEL vguiPanel, bool lost)
|
||||
{
|
||||
Client(vguiPanel)->InternalFocusChanged(lost);
|
||||
}
|
||||
|
||||
virtual bool RequestInfo(VPANEL vguiPanel, KeyValues *outputData)
|
||||
{
|
||||
return Client(vguiPanel)->RequestInfo(outputData);
|
||||
}
|
||||
|
||||
virtual void RequestFocus(VPANEL vguiPanel, int direction = 0)
|
||||
{
|
||||
Client(vguiPanel)->RequestFocus(direction);
|
||||
}
|
||||
|
||||
virtual bool RequestFocusPrev(VPANEL vguiPanel, VPANEL existingPanel)
|
||||
{
|
||||
return Client(vguiPanel)->RequestFocusPrev(existingPanel);
|
||||
}
|
||||
|
||||
virtual bool RequestFocusNext(VPANEL vguiPanel, VPANEL existingPanel)
|
||||
{
|
||||
return Client(vguiPanel)->RequestFocusNext(existingPanel);
|
||||
}
|
||||
|
||||
virtual VPANEL GetCurrentKeyFocus(VPANEL vguiPanel)
|
||||
{
|
||||
return Client(vguiPanel)->GetCurrentKeyFocus();
|
||||
}
|
||||
|
||||
virtual int GetTabPosition(VPANEL vguiPanel)
|
||||
{
|
||||
return Client(vguiPanel)->GetTabPosition();
|
||||
}
|
||||
|
||||
virtual Panel *GetPanel(VPANEL vguiPanel, const char *moduleName)
|
||||
{
|
||||
if (!vguiPanel)
|
||||
return NULL;
|
||||
|
||||
if (vguiPanel == g_pSurface->GetEmbeddedPanel())
|
||||
return NULL;
|
||||
|
||||
// assert that the specified vpanel is from the same module as requesting the cast
|
||||
if ( !vguiPanel || V_stricmp(GetModuleName(vguiPanel), moduleName) )
|
||||
{
|
||||
// assert(!("GetPanel() used to retrieve a Panel * from a different dll than which which it was created. This is bad, you can't pass Panel * across dll boundaries else you'll break the versioning. Please only use a VPANEL."));
|
||||
// this is valid for now
|
||||
return NULL;
|
||||
}
|
||||
return Client(vguiPanel)->GetPanel();
|
||||
}
|
||||
|
||||
virtual const char *GetModuleName(VPANEL vguiPanel)
|
||||
{
|
||||
return Client(vguiPanel)->GetModuleName();
|
||||
}
|
||||
|
||||
virtual void SetKeyBoardInputEnabled( VPANEL vguiPanel, bool state )
|
||||
{
|
||||
((VPanel *)vguiPanel)->SetKeyBoardInputEnabled(state);
|
||||
}
|
||||
|
||||
virtual void SetMouseInputEnabled( VPANEL vguiPanel, bool state )
|
||||
{
|
||||
((VPanel *)vguiPanel)->SetMouseInputEnabled(state);
|
||||
}
|
||||
|
||||
virtual bool IsMouseInputEnabled( VPANEL vguiPanel )
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->IsMouseInputEnabled();
|
||||
}
|
||||
|
||||
virtual bool IsKeyBoardInputEnabled( VPANEL vguiPanel )
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->IsKeyBoardInputEnabled();
|
||||
}
|
||||
|
||||
virtual void SetSiblingPin(VPANEL vguiPanel, VPANEL newSibling, byte iMyCornerToPin = 0, byte iSiblingCornerToPinTo = 0 )
|
||||
{
|
||||
return ((VPanel *)vguiPanel)->SetSiblingPin( (VPanel *)newSibling, iMyCornerToPin, iSiblingCornerToPinTo );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
EXPOSE_SINGLE_INTERFACE(VPanelWrapper, IPanel, VGUI_PANEL_INTERFACE_VERSION);
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef BITMAP_H
|
||||
#define BITMAP_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui/IImage.h>
|
||||
#include <Color.h>
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Holds a single image, internal to vgui only
|
||||
//-----------------------------------------------------------------------------
|
||||
class Bitmap : public IImage
|
||||
{
|
||||
public:
|
||||
Bitmap( const char *filename, bool hardwareFiltered );
|
||||
~Bitmap();
|
||||
|
||||
// IImage implementation
|
||||
virtual void Paint();
|
||||
virtual void GetSize( int &wide, int &tall );
|
||||
virtual void GetContentSize( int &wide, int &tall );
|
||||
virtual void SetSize( int x, int y );
|
||||
virtual void SetPos( int x, int y );
|
||||
virtual void SetColor( Color col );
|
||||
virtual bool Evict();
|
||||
virtual int GetNumFrames();
|
||||
virtual void SetFrame( int nFrame );
|
||||
virtual HTexture GetID(); // returns the texture id
|
||||
virtual void SetRotation( int iRotation ) { _rotation = iRotation; }
|
||||
|
||||
// methods
|
||||
void ForceUpload(); // ensures the bitmap has been uploaded
|
||||
const char *GetName();
|
||||
bool IsValid() { return _valid; }
|
||||
|
||||
private:
|
||||
HTexture _id;
|
||||
bool _uploaded;
|
||||
bool _valid;
|
||||
char *_filename;
|
||||
int _pos[2];
|
||||
Color _color;
|
||||
bool _filtered;
|
||||
int _wide,_tall;
|
||||
bool _bProcedural;
|
||||
unsigned int nFrameCache;
|
||||
int _rotation;
|
||||
};
|
||||
|
||||
} // namespace vgui
|
||||
|
||||
#endif // BITMAP_H
|
||||
@@ -0,0 +1,211 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "fileimage.h"
|
||||
|
||||
#include "winlite.h"
|
||||
#include "vgui_internal.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// TGA header.
|
||||
#pragma pack(1)
|
||||
class TGAFileHeader
|
||||
{
|
||||
public:
|
||||
unsigned char m_IDLength;
|
||||
unsigned char m_ColorMapType;
|
||||
unsigned char m_ImageType;
|
||||
unsigned short m_CMapStart;
|
||||
unsigned short m_CMapLength;
|
||||
unsigned char m_CMapDepth;
|
||||
unsigned short m_XOffset;
|
||||
unsigned short m_YOffset;
|
||||
unsigned short m_Width;
|
||||
unsigned short m_Height;
|
||||
unsigned char m_PixelDepth;
|
||||
unsigned char m_ImageDescriptor;
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------- //
|
||||
// FileImageStream_Memory.
|
||||
// ---------------------------------------------------------------------------------------- //
|
||||
FileImageStream_Memory::FileImageStream_Memory(void *pData, int dataLen)
|
||||
{
|
||||
m_pData = (unsigned char*)pData;
|
||||
m_DataLen = dataLen;
|
||||
m_CurPos = 0;
|
||||
m_bError = false;
|
||||
}
|
||||
|
||||
void FileImageStream_Memory::Read(void *pData, int len)
|
||||
{
|
||||
unsigned char *pOut;
|
||||
int i;
|
||||
|
||||
pOut = (unsigned char*)pData;
|
||||
for(i=0; i < len; i++)
|
||||
{
|
||||
if(m_CurPos < m_DataLen)
|
||||
{
|
||||
pOut[i] = m_pData[m_CurPos];
|
||||
++m_CurPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
pOut[i] = 0;
|
||||
m_bError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FileImageStream_Memory::ErrorStatus()
|
||||
{
|
||||
bool ret=m_bError;
|
||||
m_bError=false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------- //
|
||||
// Encode/decode functions.
|
||||
// ---------------------------------------------------------------------------------------- //
|
||||
static void WriteRun(unsigned char *pColor, FileHandle_t fp, int runLength)
|
||||
{
|
||||
unsigned char runCount;
|
||||
|
||||
runCount = runLength - 1;
|
||||
runCount |= (1 << 7);
|
||||
g_pFullFileSystem->Write( &runCount, 1, fp );
|
||||
g_pFullFileSystem->Write( pColor, 4, fp );
|
||||
}
|
||||
|
||||
|
||||
// Load in a 32-bit TGA file.
|
||||
bool Load32BitTGA(
|
||||
FileImageStream *fp,
|
||||
FileImage *pImage)
|
||||
{
|
||||
TGAFileHeader hdr;
|
||||
char dummyChar;
|
||||
int i, x, y;
|
||||
long color;
|
||||
int runLength, curOut;
|
||||
unsigned char *pLine;
|
||||
unsigned char packetHeader;
|
||||
|
||||
|
||||
pImage->Term();
|
||||
|
||||
// Read and verify the header.
|
||||
fp->Read(&hdr, sizeof(hdr));
|
||||
if(hdr.m_PixelDepth != 32 || hdr.m_ImageType != 10)
|
||||
return false;
|
||||
|
||||
// Skip the ID area..
|
||||
for(i=0; i < hdr.m_IDLength; i++)
|
||||
fp->Read(&dummyChar, 1);
|
||||
|
||||
pImage->m_Width = hdr.m_Width;
|
||||
pImage->m_Height = hdr.m_Height;
|
||||
pImage->m_pData = new unsigned char[hdr.m_Width * hdr.m_Height * 4];
|
||||
if(!pImage->m_pData)
|
||||
return false;
|
||||
|
||||
// Read in the data..
|
||||
for(y=pImage->m_Height-1; y >= 0; y--)
|
||||
{
|
||||
pLine = &pImage->m_pData[y*pImage->m_Width*4];
|
||||
|
||||
curOut = 0;
|
||||
while(curOut < pImage->m_Width)
|
||||
{
|
||||
fp->Read(&packetHeader, 1);
|
||||
|
||||
runLength = (int)(packetHeader & ~(1 << 7)) + 1;
|
||||
if(curOut + runLength > pImage->m_Width)
|
||||
return false;
|
||||
|
||||
if(packetHeader & (1 << 7))
|
||||
{
|
||||
fp->Read(&color, 4);
|
||||
for(x=0; x < runLength; x++)
|
||||
{
|
||||
*((long*)pLine) = color;
|
||||
pLine += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(x=0; x < runLength; x++)
|
||||
{
|
||||
fp->Read(&color, 4);
|
||||
*((long*)pLine) = color;
|
||||
pLine += 4;
|
||||
}
|
||||
}
|
||||
|
||||
curOut += runLength;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Write a 32-bit TGA file.
|
||||
void Save32BitTGA(
|
||||
FileHandle_t fp,
|
||||
FileImage *pImage)
|
||||
{
|
||||
TGAFileHeader hdr;
|
||||
int y, runStart, x;
|
||||
unsigned char *pLine;
|
||||
|
||||
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
hdr.m_PixelDepth = 32;
|
||||
hdr.m_ImageType = 10; // Run-length encoded RGB.
|
||||
hdr.m_Width = pImage->m_Width;
|
||||
hdr.m_Height = pImage->m_Height;
|
||||
|
||||
g_pFullFileSystem->Write(&hdr, sizeof(hdr), fp );
|
||||
|
||||
// Lines are written bottom-up.
|
||||
for(y=pImage->m_Height-1; y >= 0; y--)
|
||||
{
|
||||
pLine = &pImage->m_pData[y*pImage->m_Width*4];
|
||||
|
||||
runStart = 0;
|
||||
for(x=0; x < pImage->m_Width; x++)
|
||||
{
|
||||
if((x - runStart) >= 128 ||
|
||||
*((long*)&pLine[runStart*4]) != *((long*)&pLine[x*4]))
|
||||
{
|
||||
// Encode this Run.
|
||||
WriteRun(&pLine[runStart*4], fp, x - runStart);
|
||||
runStart = x;
|
||||
}
|
||||
}
|
||||
|
||||
// Encode the last Run.
|
||||
if(x - runStart > 0)
|
||||
{
|
||||
WriteRun(&pLine[runStart*4], fp, x - runStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef __FILEIMAGE_H__
|
||||
#define __FILEIMAGE_H__
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef void *FileHandle_t;
|
||||
|
||||
class FileImageStream
|
||||
{
|
||||
public:
|
||||
virtual void Read(void *pOut, int len)=0;
|
||||
|
||||
// Returns true if there were any Read errors.
|
||||
// Clears error status.
|
||||
virtual bool ErrorStatus()=0;
|
||||
};
|
||||
|
||||
|
||||
// Use to read out of a memory buffer..
|
||||
class FileImageStream_Memory : public FileImageStream
|
||||
{
|
||||
public:
|
||||
FileImageStream_Memory(void *pData, int dataLen);
|
||||
|
||||
virtual void Read(void *pOut, int len);
|
||||
virtual bool ErrorStatus();
|
||||
|
||||
|
||||
private:
|
||||
unsigned char *m_pData;
|
||||
int m_DataLen;
|
||||
int m_CurPos;
|
||||
bool m_bError;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Generic image representation..
|
||||
class FileImage
|
||||
{
|
||||
public:
|
||||
FileImage()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
~FileImage()
|
||||
{
|
||||
Term();
|
||||
}
|
||||
|
||||
void Term()
|
||||
{
|
||||
if(m_pData)
|
||||
delete [] m_pData;
|
||||
|
||||
Clear();
|
||||
}
|
||||
|
||||
// Clear the structure without deallocating.
|
||||
void Clear()
|
||||
{
|
||||
m_Width = m_Height = 0;
|
||||
m_pData = NULL;
|
||||
}
|
||||
|
||||
int m_Width, m_Height;
|
||||
unsigned char *m_pData;
|
||||
};
|
||||
|
||||
|
||||
// Functions to load/save FileImages.
|
||||
bool Load32BitTGA(
|
||||
FileImageStream *fp,
|
||||
FileImage *pImage);
|
||||
|
||||
void Save32BitTGA(
|
||||
FileHandle_t fp,
|
||||
FileImage *pImage);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "inputsystem/InputEnums.h"
|
||||
|
||||
#include "vgui/KeyCode.h"
|
||||
#include "vgui/keyrepeat.h"
|
||||
#include "tier0/dbg.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//#define DEBUG_REPEATS
|
||||
|
||||
#ifdef DEBUG_REPEATS
|
||||
#define DbgRepeat(...) ConMsg( __VA_ARGS__ )
|
||||
#else
|
||||
#define DbgRepeat(...)
|
||||
#endif
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
vgui::KeyCode g_iCodesForAliases[FM_NUM_KEYREPEAT_ALIASES] =
|
||||
{
|
||||
KEY_XBUTTON_UP,
|
||||
KEY_XBUTTON_DOWN,
|
||||
KEY_XBUTTON_LEFT,
|
||||
KEY_XBUTTON_RIGHT
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Map joystick codes to our internal ones
|
||||
//-----------------------------------------------------------------------------
|
||||
static int GetIndexForCode( vgui::KeyCode code )
|
||||
{
|
||||
KeyCode localCode = GetBaseButtonCode( code );
|
||||
|
||||
switch ( localCode )
|
||||
{
|
||||
case KEY_XBUTTON_DOWN:
|
||||
case KEY_XSTICK1_DOWN:
|
||||
case KEY_XSTICK2_DOWN:
|
||||
return KR_ALIAS_DOWN; break;
|
||||
case KEY_XBUTTON_UP:
|
||||
case KEY_XSTICK1_UP:
|
||||
case KEY_XSTICK2_UP:
|
||||
return KR_ALIAS_UP; break;
|
||||
case KEY_XBUTTON_LEFT:
|
||||
case KEY_XSTICK1_LEFT:
|
||||
case KEY_XSTICK2_LEFT:
|
||||
return KR_ALIAS_LEFT; break;
|
||||
case KEY_XBUTTON_RIGHT:
|
||||
case KEY_XSTICK1_RIGHT:
|
||||
case KEY_XSTICK2_RIGHT:
|
||||
return KR_ALIAS_RIGHT; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
CKeyRepeatHandler::CKeyRepeatHandler()
|
||||
{
|
||||
Reset();
|
||||
for ( int i = 0; i < FM_NUM_KEYREPEAT_ALIASES; i++ )
|
||||
{
|
||||
m_flRepeatTimes[i] = 0.16;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Clear all state
|
||||
//-----------------------------------------------------------------------------
|
||||
void CKeyRepeatHandler::Reset()
|
||||
{
|
||||
DbgRepeat( "KeyRepeat: Reset\n" );
|
||||
|
||||
memset( m_bAliasDown, 0, sizeof( m_bAliasDown ) );
|
||||
m_bHaveKeyDown = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CKeyRepeatHandler::KeyDown( vgui::KeyCode code )
|
||||
{
|
||||
int joyStick = GetJoystickForCode( code );
|
||||
int iIndex = GetIndexForCode(code);
|
||||
if ( iIndex == -1 )
|
||||
return;
|
||||
|
||||
if ( m_bAliasDown[ joyStick ][ iIndex ] )
|
||||
return;
|
||||
|
||||
DbgRepeat( "KeyRepeat: KeyDown %d(%d)\n", joyStick, iIndex );
|
||||
|
||||
Reset();
|
||||
m_bAliasDown[ joyStick ][ iIndex ] = true;
|
||||
m_flNextKeyRepeat[ joyStick ] = Plat_FloatTime() + 0.4;
|
||||
m_bHaveKeyDown = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CKeyRepeatHandler::KeyUp( vgui::KeyCode code )
|
||||
{
|
||||
int joyStick = GetJoystickForCode( code );
|
||||
int iIndex = GetIndexForCode(code);
|
||||
if ( iIndex == -1 )
|
||||
return;
|
||||
|
||||
DbgRepeat( "KeyRepeat: KeyUp %d(%d)\n", joyStick, iIndex );
|
||||
|
||||
m_bAliasDown[ joyStick ][ iIndex ] = false;
|
||||
|
||||
m_bHaveKeyDown = false;
|
||||
for ( int i = 0; i < FM_NUM_KEYREPEAT_ALIASES; i++ )
|
||||
{
|
||||
for ( int j = 0; j < MAX_JOYSTICKS; j++ )
|
||||
{
|
||||
if ( m_bAliasDown[ j ][ i ] )
|
||||
{
|
||||
m_bHaveKeyDown = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
vgui::KeyCode CKeyRepeatHandler::KeyRepeated( void )
|
||||
{
|
||||
if ( IsPC() )
|
||||
return BUTTON_CODE_NONE;
|
||||
|
||||
if ( !m_bHaveKeyDown )
|
||||
return BUTTON_CODE_NONE;
|
||||
|
||||
float currentTime = Plat_FloatTime();
|
||||
|
||||
for ( int j = 0; j < MAX_JOYSTICKS; j++ )
|
||||
{
|
||||
if ( m_flNextKeyRepeat[ j ] < currentTime )
|
||||
{
|
||||
for ( int i = 0; i < FM_NUM_KEYREPEAT_ALIASES; i++ )
|
||||
{
|
||||
if ( m_bAliasDown[ j ][ i ] )
|
||||
{
|
||||
m_flNextKeyRepeat[ j ] = currentTime + m_flRepeatTimes[i];
|
||||
DbgRepeat( "KeyRepeat: Repeat %d(%d)\n", j, i );
|
||||
|
||||
return ButtonCodeToJoystickButtonCode( g_iCodesForAliases[i], j );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BUTTON_CODE_NONE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CKeyRepeatHandler::SetKeyRepeatTime( vgui::KeyCode code, float flRepeat )
|
||||
{
|
||||
int iIndex = GetIndexForCode(code);
|
||||
Assert( iIndex != -1 );
|
||||
m_flRepeatTimes[ iIndex ] = flRepeat;
|
||||
}
|
||||
@@ -0,0 +1,809 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <vgui/VGUI.h>
|
||||
#include <vgui/ISystem.h>
|
||||
#include <KeyValues.h>
|
||||
#include <vgui/IInputInternal.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include "tier0/vcrmode.h"
|
||||
#include "tier1/fmtstr.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
#include "vgui_internal.h"
|
||||
#include "filesystem_helpers.h"
|
||||
#include "vgui_key_translation.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
#ifdef OSX
|
||||
#include <Carbon/Carbon.h>
|
||||
#elif defined(LINUX)
|
||||
#include <sys/vfs.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDL
|
||||
#include "SDL_clipboard.h"
|
||||
#include "SDL_error.h"
|
||||
#endif
|
||||
|
||||
#define PROTECTED_THINGS_DISABLE
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
uint16 System_GetKeyState( int virtualKeyCode )
|
||||
{
|
||||
#ifndef _XBOX
|
||||
return g_pVCR->Hook_GetKeyState(virtualKeyCode);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
class CSystem : public ISystem
|
||||
{
|
||||
public:
|
||||
CSystem();
|
||||
~CSystem();
|
||||
|
||||
virtual void Shutdown();
|
||||
virtual void RunFrame();
|
||||
|
||||
virtual long GetTimeMillis();
|
||||
|
||||
// returns the time at the start of the frame
|
||||
virtual double GetFrameTime();
|
||||
|
||||
// returns the current time
|
||||
virtual double GetCurrentTime();
|
||||
|
||||
virtual void ShellExecute(const char *command, const char *file);
|
||||
|
||||
virtual int GetClipboardTextCount();
|
||||
virtual void SetClipboardText(const char *text, int textLen);
|
||||
virtual void SetClipboardText(const wchar_t *text, int textLen);
|
||||
virtual int GetClipboardText(int offset, char *buf, int bufLen);
|
||||
virtual int GetClipboardText(int offset, wchar_t *buf, int bufLen);
|
||||
|
||||
virtual void SetClipboardImage( void *pWnd, int x1, int y1, int x2, int y2 );
|
||||
|
||||
virtual bool SetRegistryString(const char *key, const char *value);
|
||||
virtual bool GetRegistryString(const char *key, char *value, int valueLen);
|
||||
virtual bool SetRegistryInteger(const char *key, int value);
|
||||
virtual bool GetRegistryInteger(const char *key, int &value);
|
||||
virtual bool DeleteRegistryKey(const char *keyName);
|
||||
|
||||
virtual bool SetWatchForComputerUse(bool state);
|
||||
virtual double GetTimeSinceLastUse();
|
||||
virtual int GetAvailableDrives(char *buf, int bufLen);
|
||||
virtual double GetFreeDiskSpace(const char *path);
|
||||
|
||||
virtual KeyValues *GetUserConfigFileData(const char *dialogName, int dialogID);
|
||||
virtual void SetUserConfigFile(const char *fileName, const char *pathName);
|
||||
virtual void SaveUserConfigFile();
|
||||
|
||||
virtual bool CommandLineParamExists(const char *commandName);
|
||||
virtual bool GetCommandLineParamValue(const char *paramName, char *value, int valueBufferSize);
|
||||
virtual const char *GetFullCommandLine();
|
||||
virtual bool GetCurrentTimeAndDate(int *year, int *month, int *dayOfWeek, int *day, int *hour, int *minute, int *second);
|
||||
|
||||
// shortcut (.lnk) modification functions
|
||||
virtual bool CreateShortcut(const char *linkFileName, const char *targetPath, const char *arguments, const char *workingDirectory, const char *iconFile);
|
||||
virtual bool GetShortcutTarget(const char *linkFileName, char *targetPath, char *arguments, int destBufferSizes);
|
||||
virtual bool ModifyShortcutTarget(const char *linkFileName, const char *targetPath, const char *arguments, const char *workingDirectory);
|
||||
|
||||
virtual KeyCode KeyCode_VirtualKeyToVGUI( int keyCode );
|
||||
virtual int KeyCode_VGUIToVirtualKey( KeyCode keyCode );
|
||||
// virtual MouseCode MouseCode_VirtualKeyToVGUI( int keyCode );
|
||||
// virtual int MouseCode_VGUIToVirtualKey( MouseCode keyCode );
|
||||
virtual const char *GetDesktopFolderPath();
|
||||
virtual const char *GetStartMenuFolderPath();
|
||||
virtual const char *GetAllUserDesktopFolderPath();
|
||||
virtual const char *GetAllUserStartMenuFolderPath();
|
||||
|
||||
virtual void ShellExecuteEx( const char *command, const char *file, const char *pParams );
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
virtual void Validate( CValidator &validator, char *pchName );
|
||||
#endif
|
||||
|
||||
private:
|
||||
void SaveRegistryToFile( bool bForce = false );
|
||||
bool m_bStaticWatchForComputerUse;
|
||||
double m_StaticLastComputerUseTime;
|
||||
int m_iStaticMouseOldX, m_iStaticMouseOldY;
|
||||
// timer data
|
||||
double m_flFrameTime;
|
||||
KeyValues *m_pUserConfigData;
|
||||
char m_szFileName[MAX_PATH];
|
||||
char m_szPathID[MAX_PATH];
|
||||
|
||||
KeyValues *m_pRegistry;
|
||||
double m_flRegistrySaveTime;
|
||||
bool m_bRegistryDirty;
|
||||
|
||||
char m_szRegistryPath[ MAX_PATH ];
|
||||
#ifdef OSX
|
||||
PasteboardRef m_PasteBoardRef;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
CSystem g_System;
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CSystem, ISystem, VGUI_SYSTEM_INTERFACE_VERSION, g_System);
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
vgui::ISystem *g_pSystem = &g_System;
|
||||
}
|
||||
|
||||
#define REGISTRY_NAME "cfg/registry.vdf"
|
||||
#define REGISTRY_SAVE_INTERVAL 30
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CSystem::CSystem()
|
||||
{
|
||||
m_bStaticWatchForComputerUse = false;
|
||||
m_flFrameTime = 0.0;
|
||||
m_flRegistrySaveTime = 0.0;
|
||||
m_bRegistryDirty = false;
|
||||
m_pUserConfigData = NULL;
|
||||
#ifdef OSX
|
||||
PasteboardCreate( kPasteboardClipboard, &m_PasteBoardRef );
|
||||
#endif
|
||||
|
||||
Q_snprintf( m_szRegistryPath, sizeof(m_szRegistryPath), "%s", REGISTRY_NAME );
|
||||
|
||||
m_pRegistry = new KeyValues( "registry" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CSystem::~CSystem()
|
||||
{
|
||||
SaveRegistryToFile( true );
|
||||
#ifdef OSX
|
||||
CFRelease( m_PasteBoardRef );
|
||||
#endif
|
||||
}
|
||||
|
||||
void CSystem::SaveRegistryToFile( bool bForce )
|
||||
{
|
||||
/*if ( m_pRegistry && ( m_bRegistryDirty || bForce ) && g_pFullFileSystem )
|
||||
{
|
||||
m_pRegistry->SaveToFile( g_pFullFileSystem, m_szRegistryPath, "MOD" );
|
||||
}*/
|
||||
m_bRegistryDirty = false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSystem::Shutdown()
|
||||
{
|
||||
if (m_pUserConfigData)
|
||||
{
|
||||
m_pUserConfigData->deleteThis();
|
||||
}
|
||||
SaveRegistryToFile( true );
|
||||
if ( m_pRegistry )
|
||||
{
|
||||
m_pRegistry->deleteThis();
|
||||
}
|
||||
m_pRegistry = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handles all the per frame actions
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSystem::RunFrame()
|
||||
{
|
||||
// record the current frame time
|
||||
m_flFrameTime = GetCurrentTime();
|
||||
|
||||
if (m_bStaticWatchForComputerUse)
|
||||
{
|
||||
// check for mouse movement
|
||||
int x, y;
|
||||
g_pInput->GetCursorPos(x, y);
|
||||
// allow a little slack for jittery mice, don't reset until it's moved more than fifty pixels
|
||||
if (abs((x + y) - (m_iStaticMouseOldX + m_iStaticMouseOldY)) > 50)
|
||||
{
|
||||
m_StaticLastComputerUseTime = Plat_MSTime();
|
||||
m_iStaticMouseOldX = x;
|
||||
m_iStaticMouseOldY = y;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_flFrameTime - m_flRegistrySaveTime > REGISTRY_SAVE_INTERVAL )
|
||||
{
|
||||
m_flRegistrySaveTime = m_flFrameTime;
|
||||
SaveRegistryToFile();
|
||||
// Registry_RunFrame();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the time at the start of the frame
|
||||
//-----------------------------------------------------------------------------
|
||||
double CSystem::GetFrameTime()
|
||||
{
|
||||
return m_flFrameTime;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the current time
|
||||
//-----------------------------------------------------------------------------
|
||||
double CSystem::GetCurrentTime()
|
||||
{
|
||||
return Plat_FloatTime();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the current time in milliseconds
|
||||
//-----------------------------------------------------------------------------
|
||||
long CSystem::GetTimeMillis()
|
||||
{
|
||||
return (long)(Plat_MSTime() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Legacy stub to allow ShellExecute( "open", "file" ) -- doesn't otherwise work
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSystem::ShellExecute(const char *command, const char *file)
|
||||
{
|
||||
if ( V_strcmp( command, "open" ) != 0 )
|
||||
{
|
||||
// Nope
|
||||
Assert( !"This legacy command is only supported in the form of open <foo>" );
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef OSX
|
||||
const char *szCommand = "open";
|
||||
#else
|
||||
const char *szCommand = "xdg-open";
|
||||
#endif
|
||||
|
||||
pid_t pid = fork();
|
||||
if ( pid == 0 )
|
||||
{
|
||||
// Child
|
||||
#ifdef LINUX
|
||||
// Escape steam runtime if necessary
|
||||
const char *szSteamRuntime = getenv( "STEAM_RUNTIME" );
|
||||
if ( szSteamRuntime )
|
||||
{
|
||||
unsetenv( "STEAM_RUNTIME" );
|
||||
|
||||
const char *szSystemLibraryPath = getenv( "SYSTEM_LD_LIBRARY_PATH" );
|
||||
const char *szSystemPath = getenv( "SYSTEM_PATH" );
|
||||
if ( szSystemLibraryPath )
|
||||
{
|
||||
setenv( "LD_LIBRARY_PATH", szSystemLibraryPath, 1 );
|
||||
}
|
||||
if ( szSystemPath )
|
||||
{
|
||||
setenv( "PATH", szSystemPath, 1 );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
execlp( szCommand, szCommand, file, (char *)0 );
|
||||
Assert( !"execlp failed" );
|
||||
}
|
||||
}
|
||||
|
||||
void CSystem::ShellExecuteEx( const char *command, const char *file, const char *pParams )
|
||||
{
|
||||
NOTE_UNUSED( pParams );
|
||||
ShellExecute( command, file );
|
||||
}
|
||||
|
||||
void CSystem::SetClipboardText(const char *text, int textLen)
|
||||
{
|
||||
#ifdef OSX
|
||||
PasteboardSynchronize( m_PasteBoardRef );
|
||||
PasteboardClear( m_PasteBoardRef );
|
||||
CFDataRef theData = CFDataCreate( kCFAllocatorDefault, (const UInt8*)text, textLen );
|
||||
PasteboardPutItemFlavor( m_PasteBoardRef, (PasteboardItemID)1, CFSTR("public.utf8-plain-text"), theData, 0 );
|
||||
CFRelease( theData );
|
||||
#elif defined( USE_SDL )
|
||||
if ( Q_strlen( text ) <= textLen )
|
||||
{
|
||||
if ( SDL_SetClipboardText( text ) )
|
||||
{
|
||||
Msg( "SDL_SetClipboardText failed: %s\n", SDL_GetError() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *ClipText = ( char *)malloc( textLen + 1 );
|
||||
if ( ClipText )
|
||||
{
|
||||
Q_strncpy( ClipText, text, textLen + 1 );
|
||||
if ( SDL_SetClipboardText( ClipText ) )
|
||||
{
|
||||
Msg( "SDL_SetClipboardText failed: %s\n", SDL_GetError() );
|
||||
}
|
||||
free( ClipText );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CSystem::SetClipboardImage( void *pWnd, int x1, int y1, int x2, int y2 )
|
||||
{
|
||||
Assert( false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Puts unicode text into the clipboard
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSystem::SetClipboardText(const wchar_t *text, int textLen)
|
||||
{
|
||||
char *charStr = (char *)malloc( textLen * 4 );
|
||||
|
||||
Q_UnicodeToUTF8( text, charStr, textLen*4 );
|
||||
|
||||
#ifdef OSX
|
||||
PasteboardSynchronize( m_PasteBoardRef );
|
||||
PasteboardClear( m_PasteBoardRef );
|
||||
|
||||
CFDataRef theData = CFDataCreate( kCFAllocatorDefault, (const UInt8*)charStr, Q_strlen(charStr) );
|
||||
PasteboardPutItemFlavor( m_PasteBoardRef, (PasteboardItemID)1, CFSTR("public.utf8-plain-text"), theData, 0 );
|
||||
CFRelease( theData );
|
||||
#elif defined( USE_SDL )
|
||||
SetClipboardText( charStr, Q_strlen( charStr ) );
|
||||
#endif
|
||||
|
||||
free( charStr );
|
||||
}
|
||||
|
||||
int CSystem::GetClipboardTextCount()
|
||||
{
|
||||
#ifdef OSX
|
||||
ItemCount count;
|
||||
PasteboardSynchronize( m_PasteBoardRef );
|
||||
|
||||
OSStatus err = PasteboardGetItemCount( m_PasteBoardRef, &count );
|
||||
if ( err != noErr )
|
||||
return 0;
|
||||
|
||||
if ( count <= 0 )
|
||||
return 0;
|
||||
|
||||
PasteboardItemID ItemID;
|
||||
// always use the last item on the clipboard for any cut and paste data
|
||||
err = PasteboardGetItemIdentifier( m_PasteBoardRef, count, &ItemID );
|
||||
if ( err != noErr )
|
||||
return 0;
|
||||
CFDataRef outData;
|
||||
err = PasteboardCopyItemFlavorData ( m_PasteBoardRef, ItemID, CFSTR ("public.utf8-plain-text"), &outData);
|
||||
if ( err != noErr )
|
||||
return 0;
|
||||
|
||||
int copyLen = CFDataGetLength( outData );
|
||||
CFRelease( outData );
|
||||
return (int)copyLen + 1;
|
||||
#elif defined( USE_SDL )
|
||||
int Count = 0;
|
||||
|
||||
if ( SDL_HasClipboardText() )
|
||||
{
|
||||
char *text = SDL_GetClipboardText();
|
||||
|
||||
if ( text )
|
||||
{
|
||||
Count = Q_strlen( text ) + 1;
|
||||
SDL_free( text );
|
||||
}
|
||||
}
|
||||
|
||||
return Count;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int CSystem::GetClipboardText(int offset, char *buf, int bufLen)
|
||||
{
|
||||
Assert( !offset );
|
||||
|
||||
#ifdef OSX
|
||||
ItemCount count;
|
||||
PasteboardSynchronize( m_PasteBoardRef );
|
||||
|
||||
OSStatus err = PasteboardGetItemCount( m_PasteBoardRef, &count );
|
||||
if ( err != noErr )
|
||||
return 0;
|
||||
|
||||
char *pchOutData;
|
||||
PasteboardItemID ItemID;
|
||||
// pull the last item from the clipboard
|
||||
err = PasteboardGetItemIdentifier( m_PasteBoardRef, count, &ItemID );
|
||||
if ( err != noErr )
|
||||
return 0;
|
||||
CFDataRef outData;
|
||||
err = PasteboardCopyItemFlavorData ( m_PasteBoardRef, ItemID, CFSTR ("public.utf8-plain-text"), &outData);
|
||||
if ( err != noErr )
|
||||
return 0;
|
||||
pchOutData = (char *)CFDataGetBytePtr(outData );
|
||||
int copyLen = MIN( CFDataGetLength( outData ), bufLen ) ;
|
||||
if ( pchOutData )
|
||||
memcpy( buf, pchOutData, copyLen );
|
||||
CFRelease( outData );
|
||||
return copyLen;
|
||||
#elif defined( USE_SDL )
|
||||
if( SDL_HasClipboardText() )
|
||||
{
|
||||
char *text = SDL_GetClipboardText();
|
||||
|
||||
if ( text )
|
||||
{
|
||||
Q_strncpy( buf, text, bufLen );
|
||||
SDL_free( text );
|
||||
return Q_strlen( buf );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Retrieves unicode text from the clipboard
|
||||
//-----------------------------------------------------------------------------
|
||||
int CSystem::GetClipboardText(int offset, wchar_t *buf, int bufLen)
|
||||
{
|
||||
Assert( !offset );
|
||||
|
||||
char *outputUTF8 = (char *)malloc( bufLen*4 );
|
||||
int ret = GetClipboardText( offset, outputUTF8, bufLen );
|
||||
|
||||
if ( ret )
|
||||
{
|
||||
Q_UTF8ToUnicode( outputUTF8, buf, bufLen );
|
||||
}
|
||||
else if( bufLen > 0 )
|
||||
{
|
||||
buf[ 0 ] = 0;
|
||||
}
|
||||
|
||||
free( outputUTF8 );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool CSystem::SetRegistryString(const char *key, const char *value)
|
||||
{
|
||||
m_bRegistryDirty = true;
|
||||
m_pRegistry->SetString( key, value );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSystem::GetRegistryString(const char *key, char *value, int valueLen)
|
||||
{
|
||||
const char *pchVal = m_pRegistry->GetString( key );
|
||||
if ( pchVal )
|
||||
Q_strncpy( value, pchVal, valueLen );
|
||||
return pchVal != NULL;
|
||||
}
|
||||
|
||||
bool CSystem::SetRegistryInteger(const char *key, int value)
|
||||
{
|
||||
m_bRegistryDirty = true;
|
||||
m_pRegistry->SetInt( key, value );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSystem::GetRegistryInteger(const char *key, int &value)
|
||||
{
|
||||
value = m_pRegistry->GetInt( key );
|
||||
return value != 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: recursively deletes a registry key and all it's subkeys
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSystem::DeleteRegistryKey(const char *key)
|
||||
{
|
||||
Assert( false );
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets whether or not the app watches for global computer use
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSystem::SetWatchForComputerUse(bool state)
|
||||
{
|
||||
if (state == m_bStaticWatchForComputerUse)
|
||||
return true;
|
||||
|
||||
m_bStaticWatchForComputerUse = state;
|
||||
|
||||
if (m_bStaticWatchForComputerUse)
|
||||
{
|
||||
// enable watching
|
||||
}
|
||||
else
|
||||
{
|
||||
// disable watching
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the time, in seconds, since the last computer use.
|
||||
//-----------------------------------------------------------------------------
|
||||
double CSystem::GetTimeSinceLastUse()
|
||||
{
|
||||
if (m_bStaticWatchForComputerUse)
|
||||
{
|
||||
return ( Plat_MSTime() - m_StaticLastComputerUseTime ) / 1000.0f;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Get the drives a user has available on thier system
|
||||
//-----------------------------------------------------------------------------
|
||||
int CSystem::GetAvailableDrives(char *buf, int bufLen)
|
||||
{
|
||||
Assert( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the amount of available disk space, in bytes, on the specified path
|
||||
//-----------------------------------------------------------------------------
|
||||
double CSystem::GetFreeDiskSpace(const char *path)
|
||||
{
|
||||
struct statfs64 buf;
|
||||
int ret = statfs64( path, &buf );
|
||||
if ( ret < 0 )
|
||||
return 0.0;
|
||||
return (double) ( buf.f_bsize * buf.f_bfree );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: user config
|
||||
//-----------------------------------------------------------------------------
|
||||
KeyValues *CSystem::GetUserConfigFileData(const char *dialogName, int dialogID)
|
||||
{
|
||||
if (!m_pUserConfigData)
|
||||
return NULL;
|
||||
|
||||
Assert(dialogName && *dialogName);
|
||||
|
||||
if (dialogID)
|
||||
{
|
||||
char buf[256];
|
||||
Q_snprintf(buf, sizeof(buf), "%s_%d", dialogName, dialogID);
|
||||
dialogName = buf;
|
||||
}
|
||||
|
||||
return m_pUserConfigData->FindKey(dialogName, true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the name of the config file to save/restore from. Settings are loaded immediately.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSystem::SetUserConfigFile(const char *fileName, const char *pathName)
|
||||
{
|
||||
//m_pRegistry->LoadFromFile( g_pFullFileSystem, m_szRegistryPath, NULL );
|
||||
|
||||
if (!m_pUserConfigData)
|
||||
{
|
||||
m_pUserConfigData = new KeyValues("UserConfigData");
|
||||
}
|
||||
else
|
||||
{
|
||||
// delete all the existing keys so when we reload from the new file we don't
|
||||
// get duplicate entries in our key value
|
||||
m_pUserConfigData->Clear();
|
||||
}
|
||||
|
||||
Q_strncpy(m_szFileName, fileName, sizeof(m_szFileName));
|
||||
Q_strncpy(m_szPathID, pathName, sizeof(m_szPathID));
|
||||
|
||||
// open
|
||||
m_pUserConfigData->UsesEscapeSequences( true ); // VGUI may use this
|
||||
m_pUserConfigData->LoadFromFile(g_pFullFileSystem, m_szFileName, m_szPathID);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: saves all the current settings to the user config file
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSystem::SaveUserConfigFile()
|
||||
{
|
||||
if (m_pUserConfigData)
|
||||
{
|
||||
m_pUserConfigData->SaveToFile(g_pFullFileSystem, m_szFileName, m_szPathID);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns whether or not the parameter was on the command line
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSystem::CommandLineParamExists(const char *paramName)
|
||||
{
|
||||
if ( Q_strstr( Plat_GetCommandLine(), paramName ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the string following a command line param
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSystem::GetCommandLineParamValue(const char *paramName, char *value, int valueBufferSize)
|
||||
{
|
||||
Assert( false );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the name of the currently running exe
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CSystem::GetFullCommandLine()
|
||||
{
|
||||
return VCRHook_GetCommandLine();
|
||||
}
|
||||
|
||||
|
||||
KeyCode CSystem::KeyCode_VirtualKeyToVGUI( int keyCode )
|
||||
{
|
||||
return ::KeyCode_VirtualKeyToVGUI( keyCode );
|
||||
}
|
||||
|
||||
int CSystem::KeyCode_VGUIToVirtualKey( KeyCode keyCode )
|
||||
{
|
||||
return ::KeyCode_VGUIToVirtualKey( keyCode );
|
||||
}
|
||||
|
||||
/*MouseCode CSystem::MouseCode_VirtualKeyToVGUI( int keyCode )
|
||||
{
|
||||
return ::MouseCode_VirtualKeyToVGUI( keyCode );
|
||||
}
|
||||
|
||||
int CSystem::MouseCode_VGUIToVirtualKey( MouseCode mouseCode )
|
||||
{
|
||||
return ::MouseCode_VGUIToVirtualKey( mouseCode );
|
||||
}*/
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the current local time and date
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSystem::GetCurrentTimeAndDate(int *year, int *month, int *dayOfWeek, int *day, int *hour, int *minute, int *second)
|
||||
{
|
||||
time_t t = time( NULL );
|
||||
struct tm *now = localtime( &t );
|
||||
if ( now )
|
||||
{
|
||||
if ( year ) *year = now->tm_year + 1900;
|
||||
if ( month ) *month = now->tm_mon + 1;
|
||||
if ( dayOfWeek ) *dayOfWeek = now->tm_wday;
|
||||
if ( day ) *day = now->tm_mday;
|
||||
if ( hour ) *hour = now->tm_hour;
|
||||
if ( minute ) *minute = now->tm_min;
|
||||
if ( second ) *second = now->tm_sec;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Creates a shortcut file
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSystem::CreateShortcut(const char *linkFileName, const char *targetPath, const char *arguments, const char *workingDirectory, const char *iconFile)
|
||||
{
|
||||
Assert( false );
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: retrieves shortcut (.lnk) information
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSystem::GetShortcutTarget(const char *linkFileName, char *targetPath, char *arguments, int destBufferSizes)
|
||||
{
|
||||
Assert( false );
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets shortcut (.lnk) information
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSystem::ModifyShortcutTarget(const char *linkFileName, const char *targetPath, const char *arguments, const char *workingDirectory)
|
||||
{
|
||||
Assert( false );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the full path of the current user's desktop folder
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CSystem::GetDesktopFolderPath()
|
||||
{
|
||||
Assert( false );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the full path of the all user's desktop folder
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CSystem::GetAllUserDesktopFolderPath()
|
||||
{
|
||||
Assert( false );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the full path of the current user's start->program files
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CSystem::GetStartMenuFolderPath()
|
||||
{
|
||||
Assert( false );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the full path of the all user's start->program files
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CSystem::GetAllUserStartMenuFolderPath()
|
||||
{
|
||||
Assert( false );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Ensure that all of our internal structures are consistent, and
|
||||
// account for all memory that we've allocated.
|
||||
// Input: validator - Our global validator object
|
||||
// pchName - Our name (typically a member var in our container)
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
void CSystem::Validate( CValidator &validator, char *pchName )
|
||||
{
|
||||
VALIDATE_SCOPE();
|
||||
ValidatePtr( m_pUserConfigData );
|
||||
}
|
||||
|
||||
|
||||
void Validate_System( CValidator &validator )
|
||||
{
|
||||
ValidateObj( g_System );
|
||||
}
|
||||
#endif
|
||||
+1195
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,125 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// VGUI_DLL.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
$Macro OUTBINNAME "vgui2"
|
||||
|
||||
$include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE;..\include"
|
||||
$AdditionalIncludeDirectories "$BASE;$SRCDIR\thirdparty"
|
||||
$PreprocessorDefinitions "$BASE;DONT_PROTECT_FILEIO_FUNCTIONS"
|
||||
// $TreatWchar_tAsBuiltinType "No"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE Imm32.lib Shlwapi.lib odbc32.lib odbccp32.lib winmm.lib" [$WIN32]
|
||||
$SystemLibraries "iconv" [$OSXALL] //||$LINUXALL]
|
||||
$SystemFrameworks "Carbon" [$OSXALL]
|
||||
}
|
||||
}
|
||||
|
||||
$Project "vgui2"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "Bitmap.cpp"
|
||||
$File "Border.cpp"
|
||||
$File "ScalableImageBorder.cpp"
|
||||
$File "ImageBorder.cpp"
|
||||
$File "fileimage.cpp"
|
||||
$File "$SRCDIR\public\filesystem_helpers.cpp"
|
||||
$File "$SRCDIR\public\filesystem_init.cpp"
|
||||
$File "InputWin32.cpp"
|
||||
$File "LocalizedStringTable.cpp"
|
||||
$File "MemoryBitmap.cpp"
|
||||
$File "Memorybitmap.h"
|
||||
$File "MessageListener.cpp"
|
||||
$File "Scheme.cpp"
|
||||
$File "Surface.cpp" [$WIN32]
|
||||
$File "System.cpp" [$WINDOWS||$X360]
|
||||
$File "system_posix.cpp" [$POSIX]
|
||||
$File "$SRCDIR\public\UnicodeFileHelpers.cpp"
|
||||
$File "vgui.cpp"
|
||||
$File "vgui_internal.cpp"
|
||||
$File "vgui_key_translation.cpp"
|
||||
$File "VPanel.cpp"
|
||||
$File "VPanelWrapper.cpp"
|
||||
$File "keyrepeat.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "bitmap.h"
|
||||
$File "fileimage.h"
|
||||
$File "IMessageListener.h"
|
||||
$File "vgui_internal.h"
|
||||
$File "vgui_key_translation.h"
|
||||
$File "VPanel.h"
|
||||
}
|
||||
|
||||
$Folder "Public Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\tier0\basetypes.h"
|
||||
$File "$SRCDIR\public\Color.h"
|
||||
$File "$SRCDIR\public\vgui\Cursor.h"
|
||||
$File "$SRCDIR\public\filesystem.h"
|
||||
$File "$SRCDIR\common\vgui_surfacelib\FontAmalgam.h"
|
||||
$File "$SRCDIR\common\vgui_surfacelib\FontManager.h"
|
||||
$File "$SRCDIR\public\tier1\interface.h"
|
||||
$File "$SRCDIR\public\vgui\KeyCode.h"
|
||||
$File "$SRCDIR\common\SteamBootStrapper.h"
|
||||
$File "$SRCDIR\public\tier1\strtools.h"
|
||||
$File "$SRCDIR\public\UnicodeFileHelpers.h"
|
||||
$File "$SRCDIR\public\tier1\utlbuffer.h"
|
||||
$File "$SRCDIR\public\tier1\utllinkedlist.h"
|
||||
$File "$SRCDIR\public\tier1\utlmemory.h"
|
||||
$File "$SRCDIR\public\tier1\utlpriorityqueue.h"
|
||||
$File "$SRCDIR\public\tier1\utlrbtree.h"
|
||||
$File "$SRCDIR\public\tier1\utlvector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector2d.h"
|
||||
$File "$SRCDIR\public\vgui\VGUI.h"
|
||||
$File "$SRCDIR\public\vstdlib\vstdlib.h"
|
||||
$File "$SRCDIR\common\vgui_surfacelib\Win32Font.h"
|
||||
$File "$SRCDIR\public\vgui\KeyRepeat.h"
|
||||
}
|
||||
|
||||
$Folder "Interfaces"
|
||||
{
|
||||
$File "$SRCDIR\public\appframework\IAppSystem.h"
|
||||
$File "$SRCDIR\public\vgui\IBorder.h"
|
||||
$File "$SRCDIR\public\vgui\IClientPanel.h"
|
||||
$File "$SRCDIR\public\vgui\IHTML.h"
|
||||
$File "$SRCDIR\public\vgui\IImage.h"
|
||||
$File "$SRCDIR\public\vgui\IInput.h"
|
||||
$File "$SRCDIR\public\vgui\ILocalize.h"
|
||||
$File "$SRCDIR\public\vgui\IPanel.h"
|
||||
$File "$SRCDIR\public\vgui\IScheme.h"
|
||||
$File "$SRCDIR\public\vgui\ISurface.h"
|
||||
$File "$SRCDIR\public\vgui\ISystem.h"
|
||||
$File "$SRCDIR\public\vgui\IVGui.h"
|
||||
$File "$SRCDIR\public\vgui\IVguiMatInfo.h"
|
||||
$File "$SRCDIR\public\vgui\IVguiMatInfoVar.h"
|
||||
$File "VGUI_Border.h"
|
||||
$File "ScalableImageBorder.h"
|
||||
$File "ImageBorder.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib vgui_surfacelib
|
||||
$Lib tier2
|
||||
$Lib tier3
|
||||
$ImpLib SDL2 [$SDL]
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Core implementation of vgui
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "vgui_internal.h"
|
||||
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/ILocalize.h>
|
||||
#include <vgui/IPanel.h>
|
||||
#include "filesystem.h"
|
||||
#include <vstdlib/IKeyValuesSystem.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
|
||||
ISurface *g_pSurface = NULL;
|
||||
IPanel *g_pIPanel = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
static void *InitializeInterface( char const *interfaceName, CreateInterfaceFn *factoryList, int numFactories )
|
||||
{
|
||||
void *retval;
|
||||
|
||||
for ( int i = 0; i < numFactories; i++ )
|
||||
{
|
||||
CreateInterfaceFn factory = factoryList[ i ];
|
||||
if ( !factory )
|
||||
continue;
|
||||
|
||||
retval = factory( interfaceName, NULL );
|
||||
if ( retval )
|
||||
return retval;
|
||||
}
|
||||
|
||||
// No provider for requested interface!!!
|
||||
// assert( !"No provider for requested interface!!!" );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool VGui_InternalLoadInterfaces( CreateInterfaceFn *factoryList, int numFactories )
|
||||
{
|
||||
// loads all the interfaces
|
||||
g_pSurface = (ISurface *)InitializeInterface(VGUI_SURFACE_INTERFACE_VERSION, factoryList, numFactories );
|
||||
// g_pKeyValues = (IKeyValues *)InitializeInterface(KEYVALUES_INTERFACE_VERSION, factoryList, numFactories );
|
||||
g_pIPanel = (IPanel *)InitializeInterface(VGUI_PANEL_INTERFACE_VERSION, factoryList, numFactories );
|
||||
|
||||
if (g_pSurface && /*g_pKeyValues &&*/ g_pIPanel)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace vgui
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user