You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
319 lines
9.3 KiB
319 lines
9.3 KiB
5 years ago
|
//========= 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 );
|
||
|
}
|
||
|
|
||
|
|