1 Star 0 Fork 0

yoyojacky/CSMoE

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
PropertySheet.cpp 41.37 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596
//========= Copyright ?1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <vgui/IBorder.h>
#include <vgui/IInput.h>
#include <vgui/IInputInternal.h>
#include <vgui/IPanel.h>
#include <vgui/IScheme.h>
#include <vgui/ISystem.h>
#include <vgui/IVGUI.h>
#include <vgui/KeyCode.h>
#include <vgui/MouseCode.h>
#include <vgui/ISurface.h>
#include <tier1/KeyValues.h>
#include "Button.h"
#include "Controls.h"
#include "Label.h"
#include "PropertySheet.h"
#include "ComboBox.h"
#include "Panel.h"
#include "ToolWindow.h"
#include "TextImage.h"
#include "ImagePanel.h"
#include "PropertyPage.h"
#include "AnimationController.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui2;
namespace vgui2
{
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;
}
~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" ) );
PropertySheet *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", GetSchemeColor("BrightControlText", GetFgColor(), pScheme), pScheme);
_dimTextColor = GetSchemeColor("PropertySheet.TextColor", GetSchemeColor("FgColorDim", GetFgColor(), pScheme), 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 );
}
const char *enableImage = pScheme->GetResourceString("BigPropertyTab/LeftC");
if (enableImage[0])
{
_imageBackground = true;
_depressedImage[0] = scheme()->GetImage(enableImage, true);
_depressedImage[1] = scheme()->GetImage(pScheme->GetResourceString("BigPropertyTab/CenterC"), true);
_depressedImage[2] = scheme()->GetImage(pScheme->GetResourceString("BigPropertyTab/RightC"), true);
_defaultImage[0] = scheme()->GetImage(pScheme->GetResourceString("BigPropertyTab/LeftN"), true);
_defaultImage[1] = scheme()->GetImage(pScheme->GetResourceString("BigPropertyTab/CenterN"), true);
_defaultImage[2] = scheme()->GetImage(pScheme->GetResourceString("BigPropertyTab/RightN"), true);
_armedImage[0] = scheme()->GetImage(pScheme->GetResourceString("BigPropertyTab/LeftO"), true);
_armedImage[1] = scheme()->GetImage(pScheme->GetResourceString("BigPropertyTab/CenterO"), true);
_armedImage[2] = scheme()->GetImage(pScheme->GetResourceString("BigPropertyTab/RightO"), true);
}
}
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;
InvalidateLayout();
Repaint();
}
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 vgui2
//-----------------------------------------------------------------------------
// 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;
if ( m_bDraggableTabs )
{
SetDropEnabled( true );
}
m_bKBNavigationEnabled = true;
m_bImageBackground = false;
}
//-----------------------------------------------------------------------------
// 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;
}
//-----------------------------------------------------------------------------
// 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);
}
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)
{
_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;
}
//-----------------------------------------------------------------------------
// 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" );
const char *resourceString = pScheme->GetResourceString("PropertySheet/TopLeft");
if (resourceString[0])
{
m_bImageBackground = true;
m_pTopBackground[0] = scheme()->GetImage(resourceString, true);
m_pTopBackground[1] = scheme()->GetImage(pScheme->GetResourceString("PropertySheet/TopCenter"), true);
m_pTopBackground[2] = scheme()->GetImage(pScheme->GetResourceString("PropertySheet/TopRight"), true);
m_pCenterBackground[0] = scheme()->GetImage(pScheme->GetResourceString("PropertySheet/MiddleLeft"), true);
m_pCenterBackground[1] = scheme()->GetImage(pScheme->GetResourceString("PropertySheet/MiddleCenter"), true);
m_pCenterBackground[2] = scheme()->GetImage(pScheme->GetResourceString("PropertySheet/MiddleRight"), true);
m_pBottomBackground[0] = scheme()->GetImage(pScheme->GetResourceString("PropertySheet/BottomLeft"), true);
m_pBottomBackground[1] = scheme()->GetImage(pScheme->GetResourceString("PropertySheet/BottomCenter"), true);
m_pBottomBackground[2] = scheme()->GetImage(pScheme->GetResourceString("PropertySheet/BottomRight"), true);
}
}
//-----------------------------------------------------------------------------
// Purpose: Draws the text in the panel
//-----------------------------------------------------------------------------
void PropertySheet::PaintBackground()
{
if (m_bImageBackground)
{
int wide, tall;
GetSize(wide, tall);
const int iOffset = 0;
m_pTopBackground[0]->SetPos(0, 0);
m_pTopBackground[0]->SetSize(7, 7);
m_pTopBackground[0]->Paint();
m_pTopBackground[1]->SetPos(7, 0);
m_pTopBackground[1]->SetSize(wide - 14 - iOffset, 7);
m_pTopBackground[1]->Paint();
m_pTopBackground[2]->SetPos(wide - 7 - iOffset, 0);
m_pTopBackground[2]->SetSize(7, 7);
m_pTopBackground[2]->Paint();
m_pCenterBackground[0]->SetPos(0, 7);
m_pCenterBackground[0]->SetSize(7, tall - 14);
m_pCenterBackground[0]->Paint();
m_pCenterBackground[1]->SetPos(7, 7);
m_pCenterBackground[1]->SetSize(wide - 14 - iOffset, tall - 14);
m_pCenterBackground[1]->Paint();
m_pCenterBackground[2]->SetPos(wide - 7 - iOffset, 7);
m_pCenterBackground[2]->SetSize(7, tall - 14);
m_pCenterBackground[2]->Paint();
m_pBottomBackground[0]->SetPos(0, tall - 7);
m_pBottomBackground[0]->SetSize(7, 7);
m_pBottomBackground[0]->Paint();
m_pBottomBackground[1]->SetPos(7, tall - 7);
m_pBottomBackground[1]->SetSize(wide - 14 - iOffset, 7);
m_pBottomBackground[1]->Paint();
m_pBottomBackground[2]->SetPos(wide - 7, tall - 7);
m_pBottomBackground[2]->SetSize(7, 7);
m_pBottomBackground[2]->Paint();
}
else
{
BaseClass::PaintBackground();
}
}
//-----------------------------------------------------------------------------
// 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() ? 14 : 28;
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 = 0;
// draw the visible tabs
if (_showTabs)
{
for (int i = 0; i < limit; i++)
{
int tabHeight = IsSmallTabs() ? 13 : 27;
int width, tall;
m_PageTabs[i]->GetSize(width, tall);
if (m_PageTabs[i] == _activeTab)
{
// active tab is taller
_activeTab->SetBounds(xtab, 2, width, tabHeight);
}
else
{
m_PageTabs[i]->SetBounds(xtab, 4, width, tabHeight - 2);
}
m_PageTabs[i]->SetVisible(true);
xtab += (width + 1);
}
}
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 );
}
}
//-----------------------------------------------------------------------------
// 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;
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::OnKeyCodeTyped(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() )
{
switch (code)
{
// for now left and right arrows just open or close submenus if they are there.
case KEY_RIGHT:
{
ChangeActiveTab(_activeTabIndex+1);
break;
}
case KEY_LEFT:
{
ChangeActiveTab(_activeTabIndex-1);
break;
}
default:
BaseClass::OnKeyCodeTyped(code);
break;
}
}
else
{
BaseClass::OnKeyCodeTyped(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(Panel *defaultButton)
{
// forward the message up
if (GetVParent())
{
KeyValues *msg = new KeyValues("CurrentDefaultButtonSet");
msg->SetPtr("button", defaultButton);
PostMessage(GetVParent(), msg);
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void PropertySheet::OnDefaultButtonSet(Panel *defaultButton)
{
// forward the message up
if (GetVParent())
{
KeyValues *msg = new KeyValues("DefaultButtonSet");
msg->SetPtr("button", 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() ? 14 : 28;
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() ? 14 : 28;
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;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/yoyojacky/CSMoE.git
git@gitee.com:yoyojacky/CSMoE.git
yoyojacky
CSMoE
CSMoE
master

搜索帮助