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.
1676 lines
42 KiB
1676 lines
42 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#include <vgui/IBorder.h> |
|
#include <vgui/IInput.h> |
|
#include <vgui/IPanel.h> |
|
#include <vgui/IScheme.h> |
|
#include <vgui/ISystem.h> |
|
#include <vgui/IVGui.h> |
|
#include <vgui/KeyCode.h> |
|
#include <KeyValues.h> |
|
#include <vgui/MouseCode.h> |
|
#include <vgui/ISurface.h> |
|
#include <vgui_controls/Button.h> |
|
#include <vgui_controls/Controls.h> |
|
#include <vgui_controls/Label.h> |
|
#include <vgui_controls/PropertySheet.h> |
|
#include <vgui_controls/ComboBox.h> |
|
#include <vgui_controls/Panel.h> |
|
#include <vgui_controls/ToolWindow.h> |
|
#include <vgui_controls/TextImage.h> |
|
#include <vgui_controls/ImagePanel.h> |
|
#include <vgui_controls/PropertyPage.h> |
|
#include "vgui_controls/AnimationController.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include <tier0/memdbgon.h> |
|
|
|
using namespace vgui; |
|
|
|
namespace vgui |
|
{ |
|
|
|
class ContextLabel : public Label |
|
{ |
|
DECLARE_CLASS_SIMPLE( ContextLabel, Label ); |
|
public: |
|
|
|
ContextLabel( Button *parent, char const *panelName, char const *text ): |
|
BaseClass( (Panel *)parent, panelName, text ), |
|
m_pTabButton( parent ) |
|
{ |
|
SetBlockDragChaining( true ); |
|
} |
|
|
|
virtual void OnMousePressed( MouseCode code ) |
|
{ |
|
if ( m_pTabButton ) |
|
{ |
|
m_pTabButton->FireActionSignal(); |
|
} |
|
} |
|
|
|
virtual void OnMouseReleased( MouseCode code ) |
|
{ |
|
BaseClass::OnMouseReleased( code ); |
|
|
|
if ( GetParent() ) |
|
{ |
|
GetParent()->OnCommand( "ShowContextMenu" ); |
|
} |
|
} |
|
|
|
virtual void ApplySchemeSettings( IScheme *pScheme ) |
|
{ |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
HFont marlett = pScheme->GetFont( "Marlett" ); |
|
SetFont( marlett ); |
|
SetTextInset( 0, 0 ); |
|
SetContentAlignment( Label::a_northwest ); |
|
|
|
if ( GetParent() ) |
|
{ |
|
SetFgColor( pScheme->GetColor( "Button.TextColor", GetParent()->GetFgColor() ) ); |
|
SetBgColor( GetParent()->GetBgColor() ); |
|
} |
|
} |
|
private: |
|
|
|
Button *m_pTabButton; |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Helper for drag drop |
|
// Input : msglist - |
|
// Output : static PropertySheet |
|
//----------------------------------------------------------------------------- |
|
static PropertySheet *IsDroppingSheet( CUtlVector< KeyValues * >& msglist ) |
|
{ |
|
if ( msglist.Count() == 0 ) |
|
return NULL; |
|
|
|
KeyValues *data = msglist[ 0 ]; |
|
PropertySheet *sheet = reinterpret_cast< PropertySheet * >( data->GetPtr( "propertysheet" ) ); |
|
if ( sheet ) |
|
return sheet; |
|
|
|
return NULL; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: A single tab |
|
//----------------------------------------------------------------------------- |
|
class PageTab : public Button |
|
{ |
|
DECLARE_CLASS_SIMPLE( PageTab, Button ); |
|
|
|
private: |
|
bool _active; |
|
Color _textColor; |
|
Color _dimTextColor; |
|
int m_bMaxTabWidth; |
|
IBorder *m_pActiveBorder; |
|
IBorder *m_pNormalBorder; |
|
PropertySheet *m_pParent; |
|
Panel *m_pPage; |
|
ImagePanel *m_pImage; |
|
char *m_pszImageName; |
|
bool m_bShowContextLabel; |
|
bool m_bAttemptingDrop; |
|
ContextLabel *m_pContextLabel; |
|
long m_hoverActivatePageTime; |
|
long m_dropHoverTime; |
|
|
|
public: |
|
PageTab(PropertySheet *parent, const char *panelName, const char *text, char const *imageName, int maxTabWidth, Panel *page, bool showContextButton, long hoverActivatePageTime = -1 ) : |
|
Button( (Panel *)parent, panelName, text), |
|
m_pParent( parent ), |
|
m_pPage( page ), |
|
m_pImage( 0 ), |
|
m_pszImageName( 0 ), |
|
m_bShowContextLabel( showContextButton ), |
|
m_bAttemptingDrop( false ), |
|
m_hoverActivatePageTime( hoverActivatePageTime ), |
|
m_dropHoverTime( -1 ) |
|
{ |
|
SetCommand(new KeyValues("TabPressed")); |
|
_active = false; |
|
m_bMaxTabWidth = maxTabWidth; |
|
SetDropEnabled( true ); |
|
SetDragEnabled( m_pParent->IsDraggableTab() ); |
|
if ( imageName ) |
|
{ |
|
m_pImage = new ImagePanel( this, text ); |
|
int buflen = Q_strlen( imageName ) + 1; |
|
m_pszImageName = new char[ buflen ]; |
|
Q_strncpy( m_pszImageName, imageName, buflen ); |
|
|
|
} |
|
SetMouseClickEnabled( MOUSE_RIGHT, true ); |
|
m_pContextLabel = m_bShowContextLabel ? new ContextLabel( this, "Context", "9" ) : NULL; |
|
|
|
REGISTER_COLOR_AS_OVERRIDABLE( _textColor, "selectedcolor" ); |
|
REGISTER_COLOR_AS_OVERRIDABLE( _dimTextColor, "unselectedcolor" ); |
|
} |
|
|
|
~PageTab() |
|
{ |
|
delete[] m_pszImageName; |
|
} |
|
|
|
virtual void Paint() |
|
{ |
|
BaseClass::Paint(); |
|
} |
|
|
|
virtual void OnCursorEntered() |
|
{ |
|
m_dropHoverTime = system()->GetTimeMillis(); |
|
} |
|
|
|
virtual void OnCursorExited() |
|
{ |
|
m_dropHoverTime = -1; |
|
} |
|
|
|
virtual void OnThink() |
|
{ |
|
if ( m_bAttemptingDrop && m_hoverActivatePageTime >= 0 && m_dropHoverTime >= 0 ) |
|
{ |
|
long hoverTime = system()->GetTimeMillis() - m_dropHoverTime; |
|
if ( hoverTime > m_hoverActivatePageTime ) |
|
{ |
|
FireActionSignal(); |
|
SetSelected(true); |
|
Repaint(); |
|
} |
|
} |
|
m_bAttemptingDrop = false; |
|
|
|
BaseClass::OnThink(); |
|
} |
|
|
|
virtual bool IsDroppable( CUtlVector< KeyValues * >&msglist ) |
|
{ |
|
m_bAttemptingDrop = true; |
|
|
|
if ( !GetParent() ) |
|
return false; |
|
|
|
PropertySheet *sheet = IsDroppingSheet( msglist ); |
|
if ( sheet ) |
|
return GetParent()->IsDroppable( msglist ); |
|
|
|
return BaseClass::IsDroppable( msglist ); |
|
} |
|
|
|
virtual void OnDroppablePanelPaint( CUtlVector< KeyValues * >& msglist, CUtlVector< Panel * >& dragPanels ) |
|
{ |
|
PropertySheet *sheet = IsDroppingSheet( msglist ); |
|
if ( sheet ) |
|
{ |
|
Panel *target = GetParent()->GetDropTarget( msglist ); |
|
if ( target ) |
|
{ |
|
// Fixme, mouse pos could be wrong... |
|
target->OnDroppablePanelPaint( msglist, dragPanels ); |
|
return; |
|
} |
|
} |
|
|
|
// Just highlight the tab if dropping onto active page via the tab |
|
BaseClass::OnDroppablePanelPaint( msglist, dragPanels ); |
|
} |
|
|
|
virtual void OnPanelDropped( CUtlVector< KeyValues * >& msglist ) |
|
{ |
|
PropertySheet *sheet = IsDroppingSheet( msglist ); |
|
if ( sheet ) |
|
{ |
|
Panel *target = GetParent()->GetDropTarget( msglist ); |
|
if ( target ) |
|
{ |
|
// Fixme, mouse pos could be wrong... |
|
target->OnPanelDropped( msglist ); |
|
} |
|
} |
|
|
|
// Defer to active page... |
|
Panel *active = m_pParent->GetActivePage(); |
|
if ( !active || !active->IsDroppable( msglist ) ) |
|
return; |
|
|
|
active->OnPanelDropped( msglist ); |
|
} |
|
|
|
virtual void OnDragFailed( CUtlVector< KeyValues * >& msglist ) |
|
{ |
|
PropertySheet *sheet = IsDroppingSheet( msglist ); |
|
if ( !sheet ) |
|
return; |
|
|
|
// Create a new property sheet |
|
if ( m_pParent->IsDraggableTab() ) |
|
{ |
|
if ( msglist.Count() == 1 ) |
|
{ |
|
KeyValues *data = msglist[ 0 ]; |
|
int screenx = data->GetInt( "screenx" ); |
|
int screeny = data->GetInt( "screeny" ); |
|
|
|
// m_pParent->ScreenToLocal( screenx, screeny ); |
|
if ( !m_pParent->IsWithin( screenx, screeny ) ) |
|
{ |
|
Panel *page = reinterpret_cast< Panel * >( data->GetPtr( "propertypage" ) ); |
|
sheet = reinterpret_cast< PropertySheet * >( data->GetPtr( "propertysheet" ) ); |
|
char const *title = data->GetString( "tabname", "" ); |
|
if ( !page || !sheet ) |
|
return; |
|
|
|
// Can only create if sheet was part of a ToolWindow derived object |
|
ToolWindow *tw = dynamic_cast< ToolWindow * >( sheet->GetParent() ); |
|
if ( tw ) |
|
{ |
|
IToolWindowFactory *factory = tw->GetToolWindowFactory(); |
|
if ( factory ) |
|
{ |
|
bool hasContextMenu = sheet->PageHasContextMenu( page ); |
|
sheet->RemovePage( page ); |
|
factory->InstanceToolWindow( tw->GetParent(), sheet->ShouldShowContextButtons(), page, title, hasContextMenu ); |
|
|
|
if ( sheet->GetNumPages() == 0 ) |
|
{ |
|
tw->MarkForDeletion(); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
virtual void OnCreateDragData( KeyValues *msg ) |
|
{ |
|
Assert( m_pParent->IsDraggableTab() ); |
|
|
|
msg->SetPtr( "propertypage", m_pPage ); |
|
msg->SetPtr( "propertysheet", m_pParent ); |
|
char sz[ 256 ]; |
|
GetText( sz, sizeof( sz ) ); |
|
msg->SetString( "tabname", sz ); |
|
msg->SetString( "text", sz ); |
|
} |
|
|
|
virtual void ApplySchemeSettings(IScheme *pScheme) |
|
{ |
|
// set up the scheme settings |
|
Button::ApplySchemeSettings(pScheme); |
|
|
|
_textColor = GetSchemeColor("PropertySheet.SelectedTextColor", GetFgColor(), pScheme); |
|
_dimTextColor = GetSchemeColor("PropertySheet.TextColor", GetFgColor(), pScheme); |
|
m_pActiveBorder = pScheme->GetBorder("TabActiveBorder"); |
|
m_pNormalBorder = pScheme->GetBorder("TabBorder"); |
|
|
|
if ( m_pImage ) |
|
{ |
|
ClearImages(); |
|
m_pImage->SetImage(scheme()->GetImage(m_pszImageName, false)); |
|
AddImage( m_pImage->GetImage(), 2 ); |
|
int w, h; |
|
m_pImage->GetSize( w, h ); |
|
w += m_pContextLabel ? 10 : 0; |
|
if ( m_pContextLabel ) |
|
{ |
|
m_pImage->SetPos( 10, 0 ); |
|
} |
|
SetSize( w + 4, h + 2 ); |
|
} |
|
else |
|
{ |
|
int wide, tall; |
|
int contentWide, contentTall; |
|
GetSize(wide, tall); |
|
GetContentSize(contentWide, contentTall); |
|
|
|
wide = max(m_bMaxTabWidth, contentWide + 10); // 10 = 5 pixels margin on each side |
|
wide += m_pContextLabel ? 10 : 0; |
|
SetSize(wide, tall); |
|
} |
|
|
|
if ( m_pContextLabel ) |
|
{ |
|
SetTextInset( 12, 0 ); |
|
} |
|
} |
|
|
|
virtual void ApplySettings( KeyValues *inResourceData ) |
|
{ |
|
const char *pBorder = inResourceData->GetString("activeborder_override", ""); |
|
if (*pBorder) |
|
{ |
|
m_pActiveBorder = scheme()->GetIScheme(GetScheme())->GetBorder( pBorder ); |
|
} |
|
pBorder = inResourceData->GetString("normalborder_override", ""); |
|
if (*pBorder) |
|
{ |
|
m_pNormalBorder = scheme()->GetIScheme(GetScheme())->GetBorder( pBorder ); |
|
} |
|
BaseClass::ApplySettings(inResourceData); |
|
} |
|
|
|
virtual void OnCommand( char const *cmd ) |
|
{ |
|
if ( !Q_stricmp( cmd, "ShowContextMenu" ) ) |
|
{ |
|
KeyValues *kv = new KeyValues("OpenContextMenu"); |
|
kv->SetPtr( "page", m_pPage ); |
|
kv->SetPtr( "contextlabel", m_pContextLabel ); |
|
PostActionSignal( kv ); |
|
return; |
|
} |
|
BaseClass::OnCommand( cmd ); |
|
} |
|
|
|
IBorder *GetBorder(bool depressed, bool armed, bool selected, bool keyfocus) |
|
{ |
|
if (_active) |
|
{ |
|
return m_pActiveBorder; |
|
} |
|
return m_pNormalBorder; |
|
} |
|
|
|
virtual Color GetButtonFgColor() |
|
{ |
|
if (_active) |
|
{ |
|
return _textColor; |
|
} |
|
else |
|
{ |
|
return _dimTextColor; |
|
} |
|
} |
|
|
|
virtual void SetActive(bool state) |
|
{ |
|
_active = state; |
|
SetZPos( state ? 100 : 0 ); |
|
InvalidateLayout(); |
|
Repaint(); |
|
} |
|
|
|
virtual void SetTabWidth( int iWidth ) |
|
{ |
|
m_bMaxTabWidth = iWidth; |
|
InvalidateLayout(); |
|
} |
|
|
|
virtual bool CanBeDefaultButton(void) |
|
{ |
|
return false; |
|
} |
|
|
|
//Fire action signal when mouse is pressed down instead of on release. |
|
virtual void OnMousePressed(MouseCode code) |
|
{ |
|
// check for context menu open |
|
if (!IsEnabled()) |
|
return; |
|
|
|
if (!IsMouseClickEnabled(code)) |
|
return; |
|
|
|
if (IsUseCaptureMouseEnabled()) |
|
{ |
|
{ |
|
RequestFocus(); |
|
FireActionSignal(); |
|
SetSelected(true); |
|
Repaint(); |
|
} |
|
|
|
// lock mouse input to going to this button |
|
input()->SetMouseCapture(GetVPanel()); |
|
} |
|
} |
|
|
|
virtual void OnMouseReleased(MouseCode code) |
|
{ |
|
// ensure mouse capture gets released |
|
if (IsUseCaptureMouseEnabled()) |
|
{ |
|
input()->SetMouseCapture(NULL); |
|
} |
|
|
|
// make sure the button gets unselected |
|
SetSelected(false); |
|
Repaint(); |
|
|
|
if (code == MOUSE_RIGHT) |
|
{ |
|
KeyValues *kv = new KeyValues("OpenContextMenu"); |
|
kv->SetPtr( "page", m_pPage ); |
|
kv->SetPtr( "contextlabel", m_pContextLabel ); |
|
PostActionSignal( kv ); |
|
} |
|
} |
|
|
|
virtual void PerformLayout() |
|
{ |
|
BaseClass::PerformLayout(); |
|
|
|
if ( m_pContextLabel ) |
|
{ |
|
int w, h; |
|
GetSize( w, h ); |
|
m_pContextLabel->SetBounds( 0, 0, 10, h ); |
|
} |
|
} |
|
}; |
|
|
|
|
|
}; // namespace vgui |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor |
|
//----------------------------------------------------------------------------- |
|
PropertySheet::PropertySheet( |
|
Panel *parent, |
|
const char *panelName, |
|
bool draggableTabs /*= false*/ ) : BaseClass(parent, panelName) |
|
{ |
|
_activePage = NULL; |
|
_activeTab = NULL; |
|
_tabWidth = 64; |
|
_activeTabIndex = 0; |
|
_showTabs = true; |
|
_combo = NULL; |
|
_tabFocus = false; |
|
m_flPageTransitionEffectTime = 0.0f; |
|
m_bSmallTabs = false; |
|
m_tabFont = 0; |
|
m_bDraggableTabs = draggableTabs; |
|
m_pTabKV = NULL; |
|
m_iTabHeight = 0; |
|
m_iTabHeightSmall = 0; |
|
m_bContextButton = false; |
|
|
|
if ( m_bDraggableTabs ) |
|
{ |
|
SetDropEnabled( true ); |
|
} |
|
|
|
m_bKBNavigationEnabled = true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor, associates pages with a combo box |
|
//----------------------------------------------------------------------------- |
|
PropertySheet::PropertySheet(Panel *parent, const char *panelName, ComboBox *combo) : BaseClass(parent, panelName) |
|
{ |
|
_activePage = NULL; |
|
_activeTab = NULL; |
|
_tabWidth = 64; |
|
_activeTabIndex = 0; |
|
_combo=combo; |
|
_combo->AddActionSignalTarget(this); |
|
_showTabs = false; |
|
_tabFocus = false; |
|
m_flPageTransitionEffectTime = 0.0f; |
|
m_bSmallTabs = false; |
|
m_tabFont = 0; |
|
m_bDraggableTabs = false; |
|
m_pTabKV = NULL; |
|
m_iTabHeight = 0; |
|
m_iTabHeightSmall = 0; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Destructor |
|
//----------------------------------------------------------------------------- |
|
PropertySheet::~PropertySheet() |
|
{ |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: ToolWindow uses this to drag tools from container to container by dragging the tab |
|
// Input : - |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool PropertySheet::IsDraggableTab() const |
|
{ |
|
return m_bDraggableTabs; |
|
} |
|
|
|
void PropertySheet::SetDraggableTabs( bool state ) |
|
{ |
|
m_bDraggableTabs = state; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Lower profile tabs |
|
// Input : state - |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::SetSmallTabs( bool state ) |
|
{ |
|
m_bSmallTabs = state; |
|
m_tabFont = scheme()->GetIScheme( GetScheme() )->GetFont( m_bSmallTabs ? "DefaultVerySmall" : "Default" ); |
|
int c = m_PageTabs.Count(); |
|
for ( int i = 0; i < c ; ++i ) |
|
{ |
|
PageTab *tab = m_PageTabs[ i ]; |
|
Assert( tab ); |
|
tab->SetFont( m_tabFont ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : - |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool PropertySheet::IsSmallTabs() const |
|
{ |
|
return m_bSmallTabs; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : state - |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::ShowContextButtons( bool state ) |
|
{ |
|
m_bContextButton = state; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : - |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool PropertySheet::ShouldShowContextButtons() const |
|
{ |
|
return m_bContextButton; |
|
} |
|
|
|
int PropertySheet::FindPage( Panel *page ) const |
|
{ |
|
int c = m_Pages.Count(); |
|
for ( int i = 0; i < c; ++i ) |
|
{ |
|
if ( m_Pages[ i ].page == page ) |
|
return i; |
|
} |
|
|
|
return m_Pages.InvalidIndex(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: adds a page to the sheet |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::AddPage(Panel *page, const char *title, char const *imageName /*= NULL*/, bool bHasContextMenu /*= false*/ ) |
|
{ |
|
if (!page) |
|
return; |
|
|
|
// don't add the page if we already have it |
|
if ( FindPage( page ) != m_Pages.InvalidIndex() ) |
|
return; |
|
|
|
long hoverActivatePageTime = 250; |
|
PageTab *tab = new PageTab(this, "tab", title, imageName, _tabWidth, page, m_bContextButton && bHasContextMenu, hoverActivatePageTime ); |
|
if ( m_bDraggableTabs ) |
|
{ |
|
tab->SetDragEnabled( true ); |
|
} |
|
|
|
tab->SetFont( m_tabFont ); |
|
if(_showTabs) |
|
{ |
|
tab->AddActionSignalTarget(this); |
|
} |
|
else if (_combo) |
|
{ |
|
_combo->AddItem(title, NULL); |
|
} |
|
|
|
if ( m_pTabKV ) |
|
{ |
|
tab->ApplySettings( m_pTabKV ); |
|
} |
|
|
|
m_PageTabs.AddToTail(tab); |
|
|
|
Page_t info; |
|
info.page = page; |
|
info.contextMenu = m_bContextButton && bHasContextMenu; |
|
|
|
m_Pages.AddToTail( info ); |
|
|
|
page->SetParent(this); |
|
page->AddActionSignalTarget(this); |
|
PostMessage(page, new KeyValues("ResetData")); |
|
|
|
page->SetVisible(false); |
|
InvalidateLayout(); |
|
|
|
if (!_activePage) |
|
{ |
|
// first page becomes the active page |
|
ChangeActiveTab( 0 ); |
|
if ( _activePage ) |
|
{ |
|
_activePage->RequestFocus( 0 ); |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::SetActivePage(Panel *page) |
|
{ |
|
// walk the list looking for this page |
|
int index = FindPage( page ); |
|
if (!m_Pages.IsValidIndex(index)) |
|
return; |
|
|
|
ChangeActiveTab(index); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::SetTabWidth(int pixels) |
|
{ |
|
if ( pixels < 0 ) |
|
{ |
|
if( !_activeTab ) |
|
return; |
|
|
|
int nTall; |
|
_activeTab->GetContentSize( pixels, nTall ); |
|
} |
|
|
|
if ( _tabWidth == pixels ) |
|
return; |
|
|
|
_tabWidth = pixels; |
|
InvalidateLayout(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: reloads the data in all the property page |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::ResetAllData() |
|
{ |
|
// iterate all the dialogs resetting them |
|
for (int i = 0; i < m_Pages.Count(); i++) |
|
{ |
|
ipanel()->SendMessage(m_Pages[i].page->GetVPanel(), new KeyValues("ResetData"), GetVPanel()); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Applies any changes made by the dialog |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::ApplyChanges() |
|
{ |
|
// iterate all the dialogs resetting them |
|
for (int i = 0; i < m_Pages.Count(); i++) |
|
{ |
|
ipanel()->SendMessage(m_Pages[i].page->GetVPanel(), new KeyValues("ApplyChanges"), GetVPanel()); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: gets a pointer to the currently active page |
|
//----------------------------------------------------------------------------- |
|
Panel *PropertySheet::GetActivePage() |
|
{ |
|
return _activePage; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: gets a pointer to the currently active tab |
|
//----------------------------------------------------------------------------- |
|
Panel *PropertySheet::GetActiveTab() |
|
{ |
|
return _activeTab; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: returns the number of panels in the sheet |
|
//----------------------------------------------------------------------------- |
|
int PropertySheet::GetNumPages() |
|
{ |
|
return m_Pages.Count(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: returns the name contained in the active tab |
|
// Input : a text buffer to contain the output |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::GetActiveTabTitle (char *textOut, int bufferLen ) |
|
{ |
|
if(_activeTab) _activeTab->GetText(textOut, bufferLen); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: returns the name contained in the active tab |
|
// Input : a text buffer to contain the output |
|
//----------------------------------------------------------------------------- |
|
bool PropertySheet::GetTabTitle( int i, char *textOut, int bufferLen ) |
|
{ |
|
if ( i < 0 || i >= m_PageTabs.Count() ) |
|
{ |
|
return false; |
|
} |
|
|
|
m_PageTabs[i]->GetText(textOut, bufferLen); |
|
return true; |
|
} |
|
|
|
bool PropertySheet::SetTabTitle( int i, char *pchTitle ) |
|
{ |
|
if ( i < 0 || i >= m_PageTabs.Count() ) |
|
{ |
|
return false; |
|
} |
|
|
|
m_PageTabs[ i ]->SetText( pchTitle ); |
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Returns the index of the currently active page |
|
//----------------------------------------------------------------------------- |
|
int PropertySheet::GetActivePageNum() |
|
{ |
|
for (int i = 0; i < m_Pages.Count(); i++) |
|
{ |
|
if (m_Pages[i].page == _activePage) |
|
{ |
|
return i; |
|
} |
|
} |
|
return -1; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Forwards focus requests to current active page |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::RequestFocus(int direction) |
|
{ |
|
if (direction == -1 || direction == 0) |
|
{ |
|
if (_activePage) |
|
{ |
|
_activePage->RequestFocus(direction); |
|
_tabFocus = false; |
|
} |
|
} |
|
else |
|
{ |
|
if (_showTabs && _activeTab) |
|
{ |
|
_activeTab->RequestFocus(direction); |
|
_tabFocus = true; |
|
} |
|
else if (_activePage) |
|
{ |
|
_activePage->RequestFocus(direction); |
|
_tabFocus = false; |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: moves focus back |
|
//----------------------------------------------------------------------------- |
|
bool PropertySheet::RequestFocusPrev(VPANEL panel) |
|
{ |
|
if (_tabFocus || !_showTabs || !_activeTab) |
|
{ |
|
_tabFocus = false; |
|
return BaseClass::RequestFocusPrev(panel); |
|
} |
|
else |
|
{ |
|
if (GetVParent()) |
|
{ |
|
PostMessage(GetVParent(), new KeyValues("FindDefaultButton")); |
|
} |
|
_activeTab->RequestFocus(-1); |
|
_tabFocus = true; |
|
return true; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: moves focus forward |
|
//----------------------------------------------------------------------------- |
|
bool PropertySheet::RequestFocusNext(VPANEL panel) |
|
{ |
|
if (!_tabFocus || !_activePage) |
|
{ |
|
return BaseClass::RequestFocusNext(panel); |
|
} |
|
else |
|
{ |
|
if (!_activeTab) |
|
{ |
|
return BaseClass::RequestFocusNext(panel); |
|
} |
|
else |
|
{ |
|
_activePage->RequestFocus(1); |
|
_tabFocus = false; |
|
return true; |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Gets scheme settings |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::ApplySchemeSettings(IScheme *pScheme) |
|
{ |
|
BaseClass::ApplySchemeSettings(pScheme); |
|
|
|
// a little backwards-compatibility with old scheme files |
|
IBorder *pBorder = pScheme->GetBorder("PropertySheetBorder"); |
|
if (pBorder == pScheme->GetBorder("Default")) |
|
{ |
|
// get the old name |
|
pBorder = pScheme->GetBorder("RaisedBorder"); |
|
} |
|
|
|
SetBorder(pBorder); |
|
m_flPageTransitionEffectTime = atof(pScheme->GetResourceString("PropertySheet.TransitionEffectTime")); |
|
|
|
m_tabFont = pScheme->GetFont( m_bSmallTabs ? "DefaultVerySmall" : "Default" ); |
|
|
|
if ( m_pTabKV ) |
|
{ |
|
for (int i = 0; i < m_PageTabs.Count(); i++) |
|
{ |
|
m_PageTabs[i]->ApplySettings( m_pTabKV ); |
|
} |
|
} |
|
|
|
|
|
//============================================================================= |
|
// HPE_BEGIN: |
|
// [tj] Here, we used to use a single size variable and overwrite it when we scaled. |
|
// This led to problems when we changes resolutions, so now we recalcuate the absolute |
|
// size from the relative size each time (based on proportionality) |
|
//============================================================================= |
|
if ( IsProportional() ) |
|
{ |
|
m_iTabHeight = scheme()->GetProportionalScaledValueEx( GetScheme(), m_iSpecifiedTabHeight ); |
|
m_iTabHeightSmall = scheme()->GetProportionalScaledValueEx( GetScheme(), m_iSpecifiedTabHeightSmall ); |
|
} |
|
else |
|
{ |
|
m_iTabHeight = m_iSpecifiedTabHeight; |
|
m_iTabHeightSmall = m_iSpecifiedTabHeightSmall; |
|
} |
|
//============================================================================= |
|
// HPE_END |
|
//============================================================================= |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::ApplySettings(KeyValues *inResourceData) |
|
{ |
|
BaseClass::ApplySettings(inResourceData); |
|
|
|
KeyValues *pTabKV = inResourceData->FindKey( "tabskv" ); |
|
if ( pTabKV ) |
|
{ |
|
if ( m_pTabKV ) |
|
{ |
|
m_pTabKV->deleteThis(); |
|
} |
|
m_pTabKV = new KeyValues("tabkv"); |
|
pTabKV->CopySubkeys( m_pTabKV ); |
|
} |
|
|
|
KeyValues *pTabWidthKV = inResourceData->FindKey( "tabwidth" ); |
|
if ( pTabWidthKV ) |
|
{ |
|
_tabWidth = scheme()->GetProportionalScaledValueEx(GetScheme(), pTabWidthKV->GetInt()); |
|
for (int i = 0; i < m_PageTabs.Count(); i++) |
|
{ |
|
m_PageTabs[i]->SetTabWidth( _tabWidth ); |
|
} |
|
} |
|
|
|
KeyValues *pTransitionKV = inResourceData->FindKey( "transition_time" ); |
|
if ( pTransitionKV ) |
|
{ |
|
m_flPageTransitionEffectTime = pTransitionKV->GetFloat(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Paint our border specially, with the tabs in mind |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::PaintBorder() |
|
{ |
|
IBorder *border = GetBorder(); |
|
if (!border) |
|
return; |
|
|
|
// draw the border, but with a break at the active tab |
|
int px = 0, py = 0, pwide = 0, ptall = 0; |
|
if (_activeTab) |
|
{ |
|
_activeTab->GetBounds(px, py, pwide, ptall); |
|
ptall -= 1; |
|
} |
|
|
|
// draw the border underneath the buttons, with a break |
|
int wide, tall; |
|
GetSize(wide, tall); |
|
border->Paint(0, py + ptall, wide, tall, IBorder::SIDE_TOP, px + 1, px + pwide - 1); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Lays out the dialog |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::PerformLayout() |
|
{ |
|
BaseClass::PerformLayout(); |
|
|
|
int x, y, wide, tall; |
|
GetBounds(x, y, wide, tall); |
|
if (_activePage) |
|
{ |
|
int tabHeight = IsSmallTabs() ? m_iTabHeightSmall : m_iTabHeight; |
|
|
|
if(_showTabs) |
|
{ |
|
_activePage->SetBounds(0, tabHeight, wide, tall - tabHeight); |
|
} |
|
else |
|
{ |
|
_activePage->SetBounds(0, 0, wide, tall ); |
|
} |
|
_activePage->InvalidateLayout(); |
|
} |
|
|
|
|
|
int xtab; |
|
int limit = m_PageTabs.Count(); |
|
|
|
xtab = m_iTabXIndent; |
|
|
|
// draw the visible tabs |
|
if (_showTabs) |
|
{ |
|
for (int i = 0; i < limit; i++) |
|
{ |
|
int tabHeight = IsSmallTabs() ? (m_iTabHeightSmall-1) : (m_iTabHeight-1); |
|
|
|
m_PageTabs[i]->GetSize(wide, tall); |
|
|
|
if ( m_bTabFitText ) |
|
{ |
|
m_PageTabs[i]->SizeToContents(); |
|
wide = m_PageTabs[i]->GetWide(); |
|
|
|
int iXInset, iYInset; |
|
m_PageTabs[i]->GetTextInset( &iXInset, &iYInset ); |
|
wide += (iXInset * 2); |
|
} |
|
|
|
if (m_PageTabs[i] == _activeTab) |
|
{ |
|
// active tab is taller |
|
_activeTab->SetBounds(xtab, 2, wide, tabHeight); |
|
} |
|
else |
|
{ |
|
m_PageTabs[i]->SetBounds(xtab, 4, wide, tabHeight - 2); |
|
} |
|
m_PageTabs[i]->SetVisible(true); |
|
xtab += (wide + 1) + m_iTabXDelta; |
|
} |
|
} |
|
else |
|
{ |
|
for (int i = 0; i < limit; i++) |
|
{ |
|
m_PageTabs[i]->SetVisible(false); |
|
} |
|
} |
|
|
|
// ensure draw order (page drawing over all the tabs except one) |
|
if (_activePage) |
|
{ |
|
_activePage->MoveToFront(); |
|
_activePage->Repaint(); |
|
} |
|
if (_activeTab) |
|
{ |
|
_activeTab->MoveToFront(); |
|
_activeTab->Repaint(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Switches the active panel |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::OnTabPressed(Panel *panel) |
|
{ |
|
// look for the tab in the list |
|
for (int i = 0; i < m_PageTabs.Count(); i++) |
|
{ |
|
if (m_PageTabs[i] == panel) |
|
{ |
|
// flip to the new tab |
|
ChangeActiveTab(i); |
|
return; |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: returns the panel associated with index i |
|
// Input : the index of the panel to return |
|
//----------------------------------------------------------------------------- |
|
Panel *PropertySheet::GetPage(int i) |
|
{ |
|
if(i<0 || i>=m_Pages.Count()) |
|
{ |
|
return NULL; |
|
} |
|
|
|
return m_Pages[i].page; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: disables page by name |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::DisablePage(const char *title) |
|
{ |
|
SetPageEnabled(title, false); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: enables page by name |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::EnablePage(const char *title) |
|
{ |
|
SetPageEnabled(title, true); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: enabled or disables page by name |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::SetPageEnabled(const char *title, bool state) |
|
{ |
|
for (int i = 0; i < m_PageTabs.Count(); i++) |
|
{ |
|
if (_showTabs) |
|
{ |
|
char tmp[50]; |
|
m_PageTabs[i]->GetText(tmp,50); |
|
if (!strnicmp(title,tmp,strlen(tmp))) |
|
{ |
|
m_PageTabs[i]->SetEnabled(state); |
|
} |
|
} |
|
else |
|
{ |
|
_combo->SetItemEnabled(title,state); |
|
} |
|
} |
|
} |
|
|
|
void PropertySheet::RemoveAllPages() |
|
{ |
|
int c = m_Pages.Count(); |
|
for ( int i = c - 1; i >= 0 ; --i ) |
|
{ |
|
RemovePage( m_Pages[ i ].page ); |
|
} |
|
} |
|
|
|
void PropertySheet::DeleteAllPages() |
|
{ |
|
int c = m_Pages.Count(); |
|
for ( int i = c - 1; i >= 0 ; --i ) |
|
{ |
|
DeletePage( m_Pages[ i ].page ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: deletes the page associated with panel |
|
// Input : *panel - the panel of the page to remove |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::RemovePage(Panel *panel) |
|
{ |
|
int location = FindPage( panel ); |
|
if ( location == m_Pages.InvalidIndex() ) |
|
return; |
|
|
|
// Since it's being deleted, don't animate!!! |
|
m_hPreviouslyActivePage = NULL; |
|
_activeTab = NULL; |
|
|
|
// ASSUMPTION = that the number of pages equals number of tabs |
|
if( _showTabs ) |
|
{ |
|
m_PageTabs[location]->RemoveActionSignalTarget( this ); |
|
} |
|
// now remove the tab |
|
PageTab *tab = m_PageTabs[ location ]; |
|
m_PageTabs.Remove( location ); |
|
tab->MarkForDeletion(); |
|
|
|
// Remove from page list |
|
m_Pages.Remove( location ); |
|
|
|
// Unparent |
|
panel->SetParent( (Panel *)NULL ); |
|
|
|
if ( _activePage == panel ) |
|
{ |
|
_activePage = NULL; |
|
// if this page is currently active, backup to the page before this. |
|
ChangeActiveTab( max( location - 1, 0 ) ); |
|
} |
|
|
|
PerformLayout(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: deletes the page associated with panel |
|
// Input : *panel - the panel of the page to remove |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::DeletePage(Panel *panel) |
|
{ |
|
Assert( panel ); |
|
RemovePage( panel ); |
|
panel->MarkForDeletion(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: flips to the new tab, sending out all the right notifications |
|
// flipping to a tab activates the tab. |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::ChangeActiveTab( int index ) |
|
{ |
|
if ( !m_Pages.IsValidIndex( index ) ) |
|
{ |
|
_activeTab = NULL; |
|
if ( m_Pages.Count() > 0 ) |
|
{ |
|
_activePage = NULL; |
|
|
|
if ( index < 0 ) |
|
{ |
|
ChangeActiveTab( m_Pages.Count() - 1 ); |
|
} |
|
else |
|
{ |
|
ChangeActiveTab( 0 ); |
|
} |
|
} |
|
return; |
|
} |
|
|
|
if ( m_Pages[index].page == _activePage ) |
|
{ |
|
if ( _activeTab ) |
|
{ |
|
_activeTab->RequestFocus(); |
|
} |
|
_tabFocus = true; |
|
return; |
|
} |
|
|
|
int c = m_Pages.Count(); |
|
for ( int i = 0; i < c; ++i ) |
|
{ |
|
m_Pages[ i ].page->SetVisible( false ); |
|
} |
|
|
|
m_hPreviouslyActivePage = _activePage; |
|
// notify old page |
|
if (_activePage) |
|
{ |
|
ivgui()->PostMessage(_activePage->GetVPanel(), new KeyValues("PageHide"), GetVPanel()); |
|
KeyValues *msg = new KeyValues("PageTabActivated"); |
|
msg->SetPtr("panel", (Panel *)NULL); |
|
ivgui()->PostMessage(_activePage->GetVPanel(), msg, GetVPanel()); |
|
} |
|
if (_activeTab) |
|
{ |
|
//_activeTabIndex=index; |
|
_activeTab->SetActive(false); |
|
|
|
// does the old tab have the focus? |
|
_tabFocus = _activeTab->HasFocus(); |
|
} |
|
else |
|
{ |
|
_tabFocus = false; |
|
} |
|
|
|
// flip page |
|
_activePage = m_Pages[index].page; |
|
_activeTab = m_PageTabs[index]; |
|
_activeTabIndex = index; |
|
|
|
_activePage->SetVisible(true); |
|
_activePage->MoveToFront(); |
|
|
|
_activeTab->SetVisible(true); |
|
_activeTab->MoveToFront(); |
|
_activeTab->SetActive(true); |
|
|
|
if (_tabFocus) |
|
{ |
|
// if a tab already has focused,give the new tab the focus |
|
_activeTab->RequestFocus(); |
|
} |
|
else |
|
{ |
|
// otherwise, give the focus to the page |
|
_activePage->RequestFocus(); |
|
} |
|
|
|
if (!_showTabs) |
|
{ |
|
_combo->ActivateItemByRow(index); |
|
} |
|
|
|
_activePage->MakeReadyForUse(); |
|
|
|
// transition effect |
|
if (m_flPageTransitionEffectTime) |
|
{ |
|
if (m_hPreviouslyActivePage.Get()) |
|
{ |
|
// fade out the previous page |
|
GetAnimationController()->RunAnimationCommand(m_hPreviouslyActivePage, "Alpha", 0.0f, 0.0f, m_flPageTransitionEffectTime / 2, AnimationController::INTERPOLATOR_LINEAR); |
|
} |
|
|
|
// fade in the new page |
|
_activePage->SetAlpha(0); |
|
GetAnimationController()->RunAnimationCommand(_activePage, "Alpha", 255.0f, m_flPageTransitionEffectTime / 2, m_flPageTransitionEffectTime / 2, AnimationController::INTERPOLATOR_LINEAR); |
|
} |
|
else |
|
{ |
|
if (m_hPreviouslyActivePage.Get()) |
|
{ |
|
// no transition, just hide the previous page |
|
m_hPreviouslyActivePage->SetVisible(false); |
|
} |
|
_activePage->SetAlpha( 255 ); |
|
} |
|
|
|
// notify |
|
ivgui()->PostMessage(_activePage->GetVPanel(), new KeyValues("PageShow"), GetVPanel()); |
|
|
|
KeyValues *msg = new KeyValues("PageTabActivated"); |
|
msg->SetPtr("panel", (Panel *)_activeTab); |
|
ivgui()->PostMessage(_activePage->GetVPanel(), msg, GetVPanel()); |
|
|
|
// tell parent |
|
PostActionSignal(new KeyValues("PageChanged")); |
|
|
|
// Repaint |
|
InvalidateLayout(); |
|
Repaint(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Gets the panel with the specified hotkey, from the current page |
|
//----------------------------------------------------------------------------- |
|
Panel *PropertySheet::HasHotkey(wchar_t key) |
|
{ |
|
if (!_activePage) |
|
return NULL; |
|
|
|
for (int i = 0; i < _activePage->GetChildCount(); i++) |
|
{ |
|
Panel *hot = _activePage->GetChild(i)->HasHotkey(key); |
|
if (hot) |
|
{ |
|
return hot; |
|
} |
|
} |
|
|
|
return NULL; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: catches the opencontextmenu event |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::OnOpenContextMenu( KeyValues *params ) |
|
{ |
|
// tell parent |
|
KeyValues *kv = params->MakeCopy(); |
|
PostActionSignal( kv ); |
|
Panel *page = reinterpret_cast< Panel * >( params->GetPtr( "page" ) ); |
|
if ( page ) |
|
{ |
|
PostMessage( page->GetVPanel(), params->MakeCopy() ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Handle key presses, through tabs. |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::OnKeyCodePressed(KeyCode code) |
|
{ |
|
bool shift = (input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT)); |
|
bool ctrl = (input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL)); |
|
bool alt = (input()->IsKeyDown(KEY_LALT) || input()->IsKeyDown(KEY_RALT)); |
|
|
|
if ( ctrl && shift && alt && code == KEY_B ) |
|
{ |
|
// enable build mode |
|
EditablePanel *ep = dynamic_cast< EditablePanel * >( GetActivePage() ); |
|
if ( ep ) |
|
{ |
|
ep->ActivateBuildMode(); |
|
return; |
|
} |
|
} |
|
|
|
if ( IsKBNavigationEnabled() ) |
|
{ |
|
ButtonCode_t nButtonCode = GetBaseButtonCode( code ); |
|
|
|
switch ( nButtonCode ) |
|
{ |
|
// for now left and right arrows just open or close submenus if they are there. |
|
case KEY_RIGHT: |
|
case KEY_XBUTTON_RIGHT: |
|
case KEY_XSTICK1_RIGHT: |
|
case KEY_XSTICK2_RIGHT: |
|
case STEAMCONTROLLER_DPAD_RIGHT: |
|
{ |
|
ChangeActiveTab(_activeTabIndex+1); |
|
break; |
|
} |
|
case KEY_LEFT: |
|
case KEY_XBUTTON_LEFT: |
|
case KEY_XSTICK1_LEFT: |
|
case KEY_XSTICK2_LEFT: |
|
case STEAMCONTROLLER_DPAD_LEFT: |
|
{ |
|
ChangeActiveTab(_activeTabIndex-1); |
|
break; |
|
} |
|
default: |
|
BaseClass::OnKeyCodePressed(code); |
|
break; |
|
} |
|
} |
|
else |
|
{ |
|
BaseClass::OnKeyCodePressed(code); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Called by the associated combo box (if in that mode), changes the current panel |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::OnTextChanged(Panel *panel,const wchar_t *wszText) |
|
{ |
|
if ( panel == _combo ) |
|
{ |
|
wchar_t tabText[30]; |
|
for(int i = 0 ; i < m_PageTabs.Count() ; i++ ) |
|
{ |
|
tabText[0] = 0; |
|
m_PageTabs[i]->GetText(tabText,30); |
|
if ( !wcsicmp(wszText,tabText) ) |
|
{ |
|
ChangeActiveTab(i); |
|
} |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::OnCommand(const char *command) |
|
{ |
|
// propogate the close command to our parent |
|
if (!stricmp(command, "Close") && GetVParent()) |
|
{ |
|
CallParentFunction(new KeyValues("Command", "command", command)); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::OnApplyButtonEnable() |
|
{ |
|
// tell parent |
|
PostActionSignal(new KeyValues("ApplyButtonEnable")); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::OnCurrentDefaultButtonSet( vgui::VPANEL defaultButton ) |
|
{ |
|
// forward the message up |
|
if (GetVParent()) |
|
{ |
|
KeyValues *msg = new KeyValues("CurrentDefaultButtonSet"); |
|
msg->SetInt("button", ivgui()->PanelToHandle( defaultButton ) ); |
|
PostMessage(GetVParent(), msg); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::OnDefaultButtonSet( VPANEL defaultButton ) |
|
{ |
|
// forward the message up |
|
if (GetVParent()) |
|
{ |
|
KeyValues *msg = new KeyValues("DefaultButtonSet"); |
|
msg->SetInt("button", ivgui()->PanelToHandle( defaultButton ) ); |
|
PostMessage(GetVParent(), msg); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::OnFindDefaultButton() |
|
{ |
|
if (GetVParent()) |
|
{ |
|
PostMessage(GetVParent(), new KeyValues("FindDefaultButton")); |
|
} |
|
} |
|
|
|
bool PropertySheet::PageHasContextMenu( Panel *page ) const |
|
{ |
|
int pageNum = FindPage( page ); |
|
if ( pageNum == m_Pages.InvalidIndex() ) |
|
return false; |
|
|
|
return m_Pages[ pageNum ].contextMenu; |
|
} |
|
|
|
void PropertySheet::OnPanelDropped( CUtlVector< KeyValues * >& msglist ) |
|
{ |
|
if ( msglist.Count() != 1 ) |
|
{ |
|
return; |
|
} |
|
|
|
PropertySheet *sheet = IsDroppingSheet( msglist ); |
|
if ( !sheet ) |
|
{ |
|
// Defer to active page |
|
if ( _activePage && _activePage->IsDropEnabled() ) |
|
{ |
|
return _activePage->OnPanelDropped( msglist ); |
|
} |
|
return; |
|
} |
|
|
|
KeyValues *data = msglist[ 0 ]; |
|
|
|
Panel *page = reinterpret_cast< Panel * >( data->GetPtr( "propertypage" ) ); |
|
char const *title = data->GetString( "tabname", "" ); |
|
if ( !page || !sheet ) |
|
return; |
|
|
|
// Can only create if sheet was part of a ToolWindow derived object |
|
ToolWindow *tw = dynamic_cast< ToolWindow * >( sheet->GetParent() ); |
|
if ( tw ) |
|
{ |
|
IToolWindowFactory *factory = tw->GetToolWindowFactory(); |
|
if ( factory ) |
|
{ |
|
bool showContext = sheet->PageHasContextMenu( page ); |
|
sheet->RemovePage( page ); |
|
if ( sheet->GetNumPages() == 0 ) |
|
{ |
|
tw->MarkForDeletion(); |
|
} |
|
|
|
AddPage( page, title, NULL, showContext ); |
|
} |
|
} |
|
} |
|
|
|
bool PropertySheet::IsDroppable( CUtlVector< KeyValues * >& msglist ) |
|
{ |
|
if ( !m_bDraggableTabs ) |
|
return false; |
|
|
|
if ( msglist.Count() != 1 ) |
|
{ |
|
return false; |
|
} |
|
|
|
int mx, my; |
|
input()->GetCursorPos( mx, my ); |
|
ScreenToLocal( mx, my ); |
|
|
|
int tabHeight = IsSmallTabs() ? m_iTabHeightSmall : m_iTabHeight; |
|
if ( my > tabHeight ) |
|
return false; |
|
|
|
PropertySheet *sheet = IsDroppingSheet( msglist ); |
|
if ( !sheet ) |
|
{ |
|
return false; |
|
} |
|
|
|
if ( sheet == this ) |
|
return false; |
|
|
|
return true; |
|
} |
|
|
|
// Mouse is now over a droppable panel |
|
void PropertySheet::OnDroppablePanelPaint( CUtlVector< KeyValues * >& msglist, CUtlVector< Panel * >& dragPanels ) |
|
{ |
|
// Convert this panel's bounds to screen space |
|
int x, y, w, h; |
|
|
|
GetSize( w, h ); |
|
|
|
int tabHeight = IsSmallTabs() ? m_iTabHeightSmall : m_iTabHeight; |
|
h = tabHeight + 4; |
|
|
|
x = y = 0; |
|
LocalToScreen( x, y ); |
|
|
|
surface()->DrawSetColor( GetDropFrameColor() ); |
|
// Draw 2 pixel frame |
|
surface()->DrawOutlinedRect( x, y, x + w, y + h ); |
|
surface()->DrawOutlinedRect( x+1, y+1, x + w-1, y + h-1 ); |
|
|
|
if ( !IsDroppable( msglist ) ) |
|
{ |
|
return; |
|
} |
|
|
|
if ( !_showTabs ) |
|
{ |
|
return; |
|
} |
|
|
|
// Draw a fake new tab... |
|
|
|
x = 0; |
|
y = 2; |
|
w = 1; |
|
h = tabHeight; |
|
|
|
int last = m_PageTabs.Count(); |
|
if ( last != 0 ) |
|
{ |
|
m_PageTabs[ last - 1 ]->GetBounds( x, y, w, h ); |
|
} |
|
|
|
// Compute left edge of "fake" tab |
|
|
|
x += ( w + 1 ); |
|
|
|
// Compute size of new panel |
|
KeyValues *data = msglist[ 0 ]; |
|
char const *text = data->GetString( "tabname", "" ); |
|
Assert( text ); |
|
|
|
PageTab *fakeTab = new PageTab( this, "FakeTab", text, NULL, _tabWidth, NULL, false ); |
|
fakeTab->SetBounds( x, 4, w, tabHeight - 4 ); |
|
fakeTab->SetFont( m_tabFont ); |
|
SETUP_PANEL( fakeTab ); |
|
fakeTab->Repaint(); |
|
surface()->SolveTraverse( fakeTab->GetVPanel(), true ); |
|
surface()->PaintTraverse( fakeTab->GetVPanel() ); |
|
delete fakeTab; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : state - |
|
//----------------------------------------------------------------------------- |
|
void PropertySheet::SetKBNavigationEnabled( bool state ) |
|
{ |
|
m_bKBNavigationEnabled = state; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : - |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool PropertySheet::IsKBNavigationEnabled() const |
|
{ |
|
return m_bKBNavigationEnabled; |
|
}
|
|
|