From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/vgui2/vgui_controls/BuildGroup.cpp | 2896 ++++++++++++++--------------- 1 file changed, 1448 insertions(+), 1448 deletions(-) (limited to 'mp/src/vgui2/vgui_controls/BuildGroup.cpp') diff --git a/mp/src/vgui2/vgui_controls/BuildGroup.cpp b/mp/src/vgui2/vgui_controls/BuildGroup.cpp index cf9cae8e..749a20c9 100644 --- a/mp/src/vgui2/vgui_controls/BuildGroup.cpp +++ b/mp/src/vgui2/vgui_controls/BuildGroup.cpp @@ -1,1448 +1,1448 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// - //========= Copyright © 1996-2003, Valve LLC, All rights reserved. ============ -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - - -#include -#define PROTECTED_THINGS_DISABLE - -#include "utldict.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include "filesystem.h" - -#if defined( _X360 ) -#include "xbox/xbox_win32stubs.h" -#endif - -// memdbgon must be the last include file in a .cpp file!!! -#include - -using namespace vgui; - -//----------------------------------------------------------------------------- -// Handle table -//----------------------------------------------------------------------------- -IMPLEMENT_HANDLES( BuildGroup, 20 ) - - -//----------------------------------------------------------------------------- -// Purpose: Constructor -//----------------------------------------------------------------------------- -BuildGroup::BuildGroup(Panel *parentPanel, Panel *contextPanel) -{ - CONSTRUCT_HANDLE( ); - - _enabled=false; - _snapX=1; - _snapY=1; - _cursor_sizenwse = dc_sizenwse; - _cursor_sizenesw = dc_sizenesw; - _cursor_sizewe = dc_sizewe; - _cursor_sizens = dc_sizens; - _cursor_sizeall = dc_sizeall; - _currentPanel=null; - _dragging=false; - m_pResourceName=NULL; - m_pResourcePathID = NULL; - m_hBuildDialog=NULL; - m_pParentPanel=parentPanel; - for (int i=0; i<4; ++i) - _rulerNumber[i] = NULL; - SetContextPanel(contextPanel); - _showRulers = false; - -} - -//----------------------------------------------------------------------------- -// Purpose: Destructor -//----------------------------------------------------------------------------- -BuildGroup::~BuildGroup() -{ - if (m_hBuildDialog) - delete m_hBuildDialog.Get(); - m_hBuildDialog = NULL; - - delete [] m_pResourceName; - delete [] m_pResourcePathID; - - for (int i=0; i <4; ++i) - { - if (_rulerNumber[i]) - { - delete _rulerNumber[i]; - _rulerNumber[i]= NULL; - } - } - - DESTRUCT_HANDLE(); -} - -//----------------------------------------------------------------------------- -// Purpose: Toggles build mode on/off -// Input : state - new state -//----------------------------------------------------------------------------- -void BuildGroup::SetEnabled(bool state) -{ - if(_enabled != state) - { - _enabled = state; - _currentPanel = NULL; - - if ( state ) - { - ActivateBuildDialog(); - } - else - { - // hide the build dialog - if ( m_hBuildDialog ) - { - m_hBuildDialog->OnCommand("Close"); - } - - // request focus for our main panel - m_pParentPanel->RequestFocus(); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: Check if buildgroup is enabled -//----------------------------------------------------------------------------- -bool BuildGroup::IsEnabled() -{ - return _enabled; -} - -//----------------------------------------------------------------------------- -// Purpose: Get the list of panels that are currently selected -//----------------------------------------------------------------------------- -CUtlVector *BuildGroup::GetControlGroup() -{ - return &_controlGroup; -} - -//----------------------------------------------------------------------------- -// Purpose: Check if ruler display is activated -//----------------------------------------------------------------------------- -bool BuildGroup::HasRulersOn() -{ - return _showRulers; -} - -//----------------------------------------------------------------------------- -// Purpose: Toggle ruler display -//----------------------------------------------------------------------------- -void BuildGroup::ToggleRulerDisplay() -{ - _showRulers = !_showRulers; - - if (_rulerNumber[0] == NULL) // rulers haven't been initialized - { - _rulerNumber[0] = new Label(m_pBuildContext, NULL, ""); - _rulerNumber[1] = new Label(m_pBuildContext, NULL, ""); - _rulerNumber[2] = new Label(m_pBuildContext, NULL, ""); - _rulerNumber[3] = new Label(m_pBuildContext, NULL, ""); - } - SetRulerLabelsVisible(_showRulers); - - m_pBuildContext->Repaint(); -} - - -//----------------------------------------------------------------------------- -// Purpose: Tobble visibility of ruler number labels -//----------------------------------------------------------------------------- -void BuildGroup::SetRulerLabelsVisible(bool state) -{ - _rulerNumber[0]->SetVisible(state); - _rulerNumber[1]->SetVisible(state); - _rulerNumber[2]->SetVisible(state); - _rulerNumber[3]->SetVisible(state); -} - -void BuildGroup::ApplySchemeSettings( IScheme *pScheme ) -{ - DrawRulers(); -} - -//----------------------------------------------------------------------------- -// Purpose: Draw Rulers on screen if conditions are right -//----------------------------------------------------------------------------- -void BuildGroup::DrawRulers() -{ - // don't draw if visibility is off - if (!_showRulers) - { - return; - } - - // no drawing if we selected the context panel - if (m_pBuildContext == _currentPanel) - { - SetRulerLabelsVisible(false); - return; - } - else - SetRulerLabelsVisible(true); - - int x, y, wide, tall; - // get base panel's postition - m_pBuildContext->GetBounds(x, y, wide, tall); - m_pBuildContext->ScreenToLocal(x,y); - - int cx, cy, cwide, ctall; - _currentPanel->GetBounds (cx, cy, cwide, ctall); - - surface()->PushMakeCurrent(m_pBuildContext->GetVPanel(), false); - - // draw rulers - surface()->DrawSetColor(255, 255, 255, 255); // white color - - surface()->DrawFilledRect(0, cy, cx, cy+1); //top horiz left - surface()->DrawFilledRect(cx+cwide, cy, wide, cy+1); //top horiz right - - surface()->DrawFilledRect(0, cy+ctall-1, cx, cy+ctall); //bottom horiz left - surface()->DrawFilledRect(cx+cwide, cy+ctall-1, wide, cy+ctall); //bottom horiz right - - surface()->DrawFilledRect(cx,0,cx+1,cy); //top vert left - surface()->DrawFilledRect(cx+cwide-1,0, cx+cwide, cy); //top vert right - - surface()->DrawFilledRect(cx,cy+ctall, cx+1, tall); //bottom vert left - surface()->DrawFilledRect(cx+cwide-1, cy+ctall, cx+cwide, tall); //bottom vert right - - surface()->PopMakeCurrent(m_pBuildContext->GetVPanel()); - - // now let's put numbers with the rulers - char textstring[20]; - Q_snprintf (textstring, sizeof( textstring ), "%d", cx); - _rulerNumber[0]->SetText(textstring); - int twide, ttall; - _rulerNumber[0]->GetContentSize(twide,ttall); - _rulerNumber[0]->SetSize(twide,ttall); - _rulerNumber[0]->SetPos(cx/2-twide/2, cy-ttall+3); - - Q_snprintf (textstring, sizeof( textstring ), "%d", cy); - _rulerNumber[1]->SetText(textstring); - _rulerNumber[1]->GetContentSize(twide,ttall); - _rulerNumber[1]->SetSize(twide,ttall); - _rulerNumber[1]->GetSize(twide,ttall); - _rulerNumber[1]->SetPos(cx-twide + 3, cy/2-ttall/2); - - Q_snprintf (textstring, sizeof( textstring ), "%d", cy); - _rulerNumber[2]->SetText(textstring); - _rulerNumber[2]->GetContentSize(twide,ttall); - _rulerNumber[2]->SetSize(twide,ttall); - _rulerNumber[2]->SetPos(cx+cwide+(wide-cx-cwide)/2 - twide/2, cy+ctall-3); - - Q_snprintf (textstring, sizeof( textstring ), "%d", cy); - _rulerNumber[3]->SetText(textstring); - _rulerNumber[3]->GetContentSize(twide,ttall); - _rulerNumber[3]->SetSize(twide,ttall); - _rulerNumber[3]->SetPos(cx+cwide, cy+ctall+(tall-cy-ctall)/2 - ttall/2); - -} - -//----------------------------------------------------------------------------- -// Purpose: respond to cursor movments -//----------------------------------------------------------------------------- -bool BuildGroup::CursorMoved(int x, int y, Panel *panel) -{ - Assert(panel); - - if ( !m_hBuildDialog.Get() ) - { - if ( panel->GetParent() ) - { - EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() ); - if ( ep ) - { - BuildGroup *bg = ep->GetBuildGroup(); - if ( bg && bg != this ) - { - bg->CursorMoved( x, y, panel ); - } - } - } - return false; - } - - // no moving uneditable panels - // commented out because this has issues with panels moving - // to front and obscuring other panels - //if (!panel->IsBuildModeEditable()) - // return; - - if (_dragging) - { - input()->GetCursorPos(x, y); - - if (_dragMouseCode == MOUSE_RIGHT) - { - int newW = max( 1, _dragStartPanelSize[ 0 ] + x - _dragStartCursorPos[0] ); - int newH = max( 1, _dragStartPanelSize[ 1 ] + y - _dragStartCursorPos[1] ); - - bool shift = ( input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT) ); - bool ctrl = ( input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL) ); - - if ( shift ) - { - newW = _dragStartPanelSize[ 0 ]; - } - if ( ctrl ) - { - newH = _dragStartPanelSize[ 1 ]; - } - - panel->SetSize( newW, newH ); - ApplySnap(panel); - } - else - { - for (int i=0; i < _controlGroup.Count(); ++i) - { - // now fix offset of member panels with respect to the one we are dragging - Panel *groupMember = _controlGroup[i].Get(); - groupMember->SetPos(_dragStartPanelPos[0] + _groupDeltaX[i] +(x-_dragStartCursorPos[0]), _dragStartPanelPos[1] + _groupDeltaY[i] +(y-_dragStartCursorPos[1])); - ApplySnap(groupMember); - } - } - - // update the build dialog - if (m_hBuildDialog) - { - KeyValues *keyval = new KeyValues("UpdateControlData"); - keyval->SetPtr("panel", GetCurrentPanel()); - ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL); - - keyval = new KeyValues("EnableSaveButton"); - ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL); - } - - panel->Repaint(); - panel->CallParentFunction(new KeyValues("Repaint")); - } - - return true; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool BuildGroup::MousePressed(MouseCode code, Panel *panel) -{ - Assert(panel); - - if ( !m_hBuildDialog.Get() ) - { - if ( panel->GetParent() ) - { - EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() ); - if ( ep ) - { - BuildGroup *bg = ep->GetBuildGroup(); - if ( bg && bg != this ) - { - bg->MousePressed( code, panel ); - } - } - } - return false; - } - - // if people click on the base build dialog panel. - if (panel == m_hBuildDialog) - { - // hide the click menu if its up - ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("HideNewControlMenu"), NULL); - return true; - } - - // don't select unnamed items - if (strlen(panel->GetName()) < 1) - return true; - - bool shift = ( input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT) ); - if (!shift) - { - _controlGroup.RemoveAll(); - } - - // Show new ctrl menu if they click on the bg (not on a subcontrol) - if ( code == MOUSE_RIGHT && panel == GetContextPanel()) - { - // trigger a drop down menu to create new controls - ivgui()->PostMessage (m_hBuildDialog->GetVPanel(), new KeyValues("ShowNewControlMenu"), NULL); - } - else - { - // don't respond if we click on ruler numbers - if (_showRulers) // rulers are visible - { - for ( int i=0; i < 4; i++) - { - if ( panel == _rulerNumber[i]) - return true; - } - } - - _dragging = true; - _dragMouseCode = code; - ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("HideNewControlMenu"), NULL); - - int x, y; - input()->GetCursorPos(x, y); - - _dragStartCursorPos[0] = x; - _dragStartCursorPos[1] = y; - - - input()->SetMouseCapture(panel->GetVPanel()); - - _groupDeltaX.RemoveAll(); - _groupDeltaY.RemoveAll(); - - // basepanel is the panel that all the deltas will be calculated from. - // it is the last panel we clicked in because if we move the panels as a group - // it would be from that one - Panel *basePanel = NULL; - // find the panel we clicked in, that is the base panel - // it might already be in the group - for (int i=0; i< _controlGroup.Count(); ++i) - { - if (panel == _controlGroup[i].Get()) - { - basePanel = panel; - break; - } - } - - // if its not in the group we just added this panel. get it in the group - if (basePanel == NULL) - { - PHandle temp; - temp = panel; - _controlGroup.AddToTail(temp); - basePanel = panel; - } - - basePanel->GetPos(x,y); - _dragStartPanelPos[0]=x; - _dragStartPanelPos[1]=y; - - basePanel->GetSize( _dragStartPanelSize[ 0 ], _dragStartPanelSize[ 1 ] ); - - // figure out the deltas of the other panels from the base panel - for (int i=0; i<_controlGroup.Count(); ++i) - { - int cx, cy; - _controlGroup[i].Get()->GetPos(cx, cy); - _groupDeltaX.AddToTail(cx - x); - _groupDeltaY.AddToTail(cy - y); - } - - // if this panel wasn't already selected update the buildmode dialog controls to show its info - if(_currentPanel != panel) - { - _currentPanel = panel; - - if ( m_hBuildDialog ) - { - // think this is taken care of by SetActiveControl. - //ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("ApplyDataToControls"), NULL); - - KeyValues *keyval = new KeyValues("SetActiveControl"); - keyval->SetPtr("PanelPtr", GetCurrentPanel()); - ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL); - } - } - - // store undo information upon panel selection. - ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("StoreUndo"), NULL); - - panel->RequestFocus(); - } - - return true; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool BuildGroup::MouseReleased(MouseCode code, Panel *panel) -{ - if ( !m_hBuildDialog.Get() ) - { - if ( panel->GetParent() ) - { - EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() ); - if ( ep ) - { - BuildGroup *bg = ep->GetBuildGroup(); - if ( bg && bg != this ) - { - bg->MouseReleased( code, panel ); - } - } - } - return false; - } - - Assert(panel); - - _dragging=false; - input()->SetMouseCapture(null); - return true; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool BuildGroup::MouseDoublePressed(MouseCode code, Panel *panel) -{ - Assert(panel); - return MousePressed( code, panel ); -} - -bool BuildGroup::KeyTyped( wchar_t unichar, Panel *panel ) -{ - if ( !m_hBuildDialog.Get() ) - { - if ( panel->GetParent() ) - { - EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() ); - if ( ep ) - { - BuildGroup *bg = ep->GetBuildGroup(); - if ( bg && bg != this ) - { - bg->KeyTyped( unichar, panel ); - } - } - } - return false; - } - - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool BuildGroup::KeyCodeTyped(KeyCode code, Panel *panel) -{ - if ( !m_hBuildDialog.Get() ) - { - if ( panel->GetParent() ) - { - EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() ); - if ( ep ) - { - BuildGroup *bg = ep->GetBuildGroup(); - if ( bg && bg != this ) - { - bg->KeyCodeTyped( code, panel ); - } - } - } - return false; - } - - Assert(panel); - - int dx=0; - int dy=0; - - 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 * >( panel ); - if ( ep ) - { - ep->ActivateBuildMode(); - } - return true; - } - - switch (code) - { - case KEY_LEFT: - { - dx-=_snapX; - break; - } - case KEY_RIGHT: - { - dx+=_snapX; - break; - } - case KEY_UP: - { - dy-=_snapY; - break; - } - case KEY_DOWN: - { - dy+=_snapY; - break; - } - case KEY_DELETE: - { - // delete the panel we have selected - ivgui()->PostMessage (m_hBuildDialog->GetVPanel(), new KeyValues ("DeletePanel"), NULL); - break; - } - - } - - if (ctrl) - { - switch (code) - { - case KEY_Z: - { - ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("Undo"), NULL); - break; - } - - case KEY_C: - { - ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("Copy"), NULL); - break; - } - case KEY_V: - { - ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("Paste"), NULL); - break; - } - } - } - - if(dx||dy) - { - //TODO: make this stuff actually snap - - int x,y,wide,tall; - - panel->GetBounds(x,y,wide,tall); - - if(shift) - { - panel->SetSize(wide+dx,tall+dy); - } - else - { - panel->SetPos(x+dx,y+dy); - } - - ApplySnap(panel); - - panel->Repaint(); - if (panel->GetVParent() != 0) - { - panel->PostMessage(panel->GetVParent(), new KeyValues("Repaint")); - } - - - // update the build dialog - if (m_hBuildDialog) - { - // post that it's active - KeyValues *keyval = new KeyValues("SetActiveControl"); - keyval->SetPtr("PanelPtr", GetCurrentPanel()); - ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL); - - // post that it's been changed - ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("PanelMoved"), NULL); - } - } - - // If holding key while dragging, simulate moving cursor so shift/ctrl key changes take effect - if ( _dragging && panel != GetContextPanel() ) - { - int x, y; - input()->GetCursorPos( x, y ); - CursorMoved( x, y, panel ); - } - - return true; -} - -bool BuildGroup::KeyCodeReleased(KeyCode code, Panel *panel ) -{ - if ( !m_hBuildDialog.Get() ) - { - if ( panel->GetParent() ) - { - EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() ); - if ( ep ) - { - BuildGroup *bg = ep->GetBuildGroup(); - if ( bg && bg != this ) - { - bg->KeyCodeTyped( code, panel ); - } - } - } - return false; - } - - // If holding key while dragging, simulate moving cursor so shift/ctrl key changes take effect - if ( _dragging && panel != GetContextPanel() ) - { - int x, y; - input()->GetCursorPos( x, y ); - CursorMoved( x, y, panel ); - } - - return true; -} - - -//----------------------------------------------------------------------------- -// Purpose: Searches for a BuildModeDialog in the hierarchy -//----------------------------------------------------------------------------- -Panel *BuildGroup::CreateBuildDialog( void ) -{ - // request the panel - Panel *buildDialog = NULL; - KeyValues *data = new KeyValues("BuildDialog"); - data->SetPtr("BuildGroupPtr", this); - if (m_pBuildContext->RequestInfo(data)) - { - buildDialog = (Panel *)data->GetPtr("PanelPtr"); - } - - // initialize the build dialog if found - if ( buildDialog ) - { - input()->ReleaseAppModalSurface(); - } - - return buildDialog; -} - -//----------------------------------------------------------------------------- -// Purpose: Activates the build mode settings dialog -//----------------------------------------------------------------------------- -void BuildGroup::ActivateBuildDialog( void ) -{ - // create the build mode dialog first time through - if (!m_hBuildDialog.Get()) - { - m_hBuildDialog = CreateBuildDialog(); - - if (!m_hBuildDialog.Get()) - return; - } - - m_hBuildDialog->SetVisible( true ); - - // send a message to set the initial dialog controls info - _currentPanel = m_pParentPanel; - KeyValues *keyval = new KeyValues("SetActiveControl"); - keyval->SetPtr("PanelPtr", GetCurrentPanel()); - ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -HCursor BuildGroup::GetCursor(Panel *panel) -{ - Assert(panel); - - int x,y,wide,tall; - input()->GetCursorPos(x,y); - panel->ScreenToLocal(x,y); - panel->GetSize(wide,tall); - - if(x < 2) - { - if(y < 4) - { - return _cursor_sizenwse; - } - else - if(y<(tall-4)) - { - return _cursor_sizewe; - } - else - { - return _cursor_sizenesw; - } - } - - return _cursor_sizeall; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void BuildGroup::ApplySnap(Panel *panel) -{ - Assert(panel); - - int x,y,wide,tall; - panel->GetBounds(x,y,wide,tall); - - x=(x/_snapX)*_snapX; - y=(y/_snapY)*_snapY; - panel->SetPos(x,y); - - int xx,yy; - xx=x+wide; - yy=y+tall; - - xx=(xx/_snapX)*_snapX; - yy=(yy/_snapY)*_snapY; - panel->SetSize(xx-x,yy-y); -} - -//----------------------------------------------------------------------------- -// Purpose: Return the currently selected panel -//----------------------------------------------------------------------------- -Panel *BuildGroup::GetCurrentPanel() -{ - return _currentPanel; -} - -//----------------------------------------------------------------------------- -// Purpose: Add panel the list of panels that are in the build group -//----------------------------------------------------------------------------- -void BuildGroup::PanelAdded(Panel *panel) -{ - Assert(panel); - - PHandle temp; - temp = panel; - int c = _panelDar.Count(); - for ( int i = 0; i < c; ++i ) - { - if ( _panelDar[ i ] == temp ) - { - return; - } - } - _panelDar.AddToTail(temp); -} - -//----------------------------------------------------------------------------- -// Purpose: loads the control settings from file -//----------------------------------------------------------------------------- -void BuildGroup::LoadControlSettings(const char *controlResourceName, const char *pathID, KeyValues *pPreloadedKeyValues, KeyValues *pConditions) -{ - // make sure the file is registered - RegisterControlSettingsFile(controlResourceName, pathID); - - // Use the keyvalues they passed in or load them. - KeyValues *rDat = pPreloadedKeyValues; - if ( !rDat ) - { - // load the resource data from the file - rDat = new KeyValues(controlResourceName); - - // check the skins directory first, if an explicit pathID hasn't been set - bool bSuccess = false; - if (!pathID) - { - bSuccess = rDat->LoadFromFile(g_pFullFileSystem, controlResourceName, "SKIN"); - } - if (!bSuccess) - { - bSuccess = rDat->LoadFromFile(g_pFullFileSystem, controlResourceName, pathID); - } - - if ( bSuccess ) - { - if ( IsX360() ) - { - rDat->ProcessResolutionKeys( surface()->GetResolutionKey() ); - } - if ( IsPC() ) - { - ConVarRef cl_hud_minmode( "cl_hud_minmode", true ); - if ( cl_hud_minmode.IsValid() && cl_hud_minmode.GetBool() ) - { - rDat->ProcessResolutionKeys( "_minmode" ); - } - } - - if ( pConditions && pConditions->GetFirstSubKey() ) - { - ProcessConditionalKeys( rDat, pConditions ); - } - } - } - - // save off the resource name - delete [] m_pResourceName; - m_pResourceName = new char[strlen(controlResourceName) + 1]; - strcpy(m_pResourceName, controlResourceName); - - if (pathID) - { - delete [] m_pResourcePathID; - m_pResourcePathID = new char[strlen(pathID) + 1]; - strcpy(m_pResourcePathID, pathID); - } - - // delete any controls not in both files - DeleteAllControlsCreatedByControlSettingsFile(); - - // loop through the resource data sticking info into controls - ApplySettings(rDat); - - if (m_pParentPanel) - { - m_pParentPanel->InvalidateLayout(); - m_pParentPanel->Repaint(); - } - - if ( rDat != pPreloadedKeyValues ) - { - rDat->deleteThis(); - } -} - -void BuildGroup::ProcessConditionalKeys( KeyValues *pData, KeyValues *pConditions ) -{ - // for each condition, look for it in keys - // if its a positive condition, promote all of its children, replacing values - - if ( pData ) - { - KeyValues *pSubKey = pData->GetFirstSubKey(); - if ( !pSubKey ) - { - // not a block - return; - } - - for ( ; pSubKey != NULL; pSubKey = pSubKey->GetNextKey() ) - { - // recursively descend each sub block - ProcessConditionalKeys( pSubKey, pConditions ); - - KeyValues *pCondition = pConditions->GetFirstSubKey(); - for ( ; pCondition != NULL; pCondition = pCondition->GetNextKey() ) - { - // if we match any conditions in this sub block, copy up - KeyValues *pConditionBlock = pSubKey->FindKey( pCondition->GetName() ); - if ( pConditionBlock ) - { - KeyValues *pOverridingKey; - for ( pOverridingKey = pConditionBlock->GetFirstSubKey(); pOverridingKey != NULL; pOverridingKey = pOverridingKey->GetNextKey() ) - { - KeyValues *pExistingKey = pSubKey->FindKey( pOverridingKey->GetName() ); - if ( pExistingKey ) - { - pExistingKey->SetStringValue( pOverridingKey->GetString() ); - } - else - { - KeyValues *copy = pOverridingKey->MakeCopy(); - pSubKey->AddSubKey( copy ); - } - } - } - } - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: registers that a control settings file may be loaded -// use when the dialog may have multiple states and the editor will need to be able to switch between them -//----------------------------------------------------------------------------- -void BuildGroup::RegisterControlSettingsFile(const char *controlResourceName, const char *pathID) -{ - // add the file into a list for build mode - CUtlSymbol sym(controlResourceName); - if (!m_RegisteredControlSettingsFiles.IsValidIndex(m_RegisteredControlSettingsFiles.Find(sym))) - { - m_RegisteredControlSettingsFiles.AddToTail(sym); - } -} - -//----------------------------------------------------------------------------- -// Purpose: data accessor / iterator -//----------------------------------------------------------------------------- -int BuildGroup::GetRegisteredControlSettingsFileCount() -{ - return m_RegisteredControlSettingsFiles.Count(); -} - -//----------------------------------------------------------------------------- -// Purpose: data accessor -//----------------------------------------------------------------------------- -const char *BuildGroup::GetRegisteredControlSettingsFileByIndex(int index) -{ - return m_RegisteredControlSettingsFiles[index].String(); -} - -//----------------------------------------------------------------------------- -// Purpose: reloads the control settings from file -//----------------------------------------------------------------------------- -void BuildGroup::ReloadControlSettings() -{ - delete m_hBuildDialog.Get(); - m_hBuildDialog = NULL; - - // loop though objects in the current control group and remove them all - // the 0th panel is always the contextPanel which is not deletable - for( int i = 1; i < _panelDar.Count(); i++ ) - { - if (!_panelDar[i].Get()) // this can happen if we had two of the same handle in the list - { - _panelDar.Remove(i); - --i; - continue; - } - - // only delete deletable panels, as the only deletable panels - // are the ones created using the resource file - if ( _panelDar[i].Get()->IsBuildModeDeletable()) - { - delete _panelDar[i].Get(); - _panelDar.Remove(i); - --i; - } - } - - if (m_pResourceName) - { - EditablePanel *edit = dynamic_cast(m_pParentPanel); - if (edit) - { - edit->LoadControlSettings(m_pResourceName, m_pResourcePathID); - } - else - { - LoadControlSettings(m_pResourceName, m_pResourcePathID); - } - } - - _controlGroup.RemoveAll(); - - ActivateBuildDialog(); -} - -//----------------------------------------------------------------------------- -// Purpose: changes which control settings are currently loaded -//----------------------------------------------------------------------------- -void BuildGroup::ChangeControlSettingsFile(const char *controlResourceName) -{ - // clear any current state - _controlGroup.RemoveAll(); - _currentPanel = m_pParentPanel; - - // load the new state, via the dialog if possible - EditablePanel *edit = dynamic_cast(m_pParentPanel); - if (edit) - { - edit->LoadControlSettings(controlResourceName, m_pResourcePathID); - } - else - { - LoadControlSettings(controlResourceName, m_pResourcePathID); - } - - // force it to update - KeyValues *keyval = new KeyValues("SetActiveControl"); - keyval->SetPtr("PanelPtr", GetCurrentPanel()); - ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL); -} - -//----------------------------------------------------------------------------- -// Purpose: saves control settings to file -//----------------------------------------------------------------------------- -bool BuildGroup::SaveControlSettings( void ) -{ - bool bSuccess = false; - if ( m_pResourceName ) - { - KeyValues *rDat = new KeyValues( m_pResourceName ); - - // get the data from our controls - GetSettings( rDat ); - - char fullpath[ 512 ]; - g_pFullFileSystem->RelativePathToFullPath( m_pResourceName, m_pResourcePathID, fullpath, sizeof( fullpath ) ); - - // save the data out to a file - bSuccess = rDat->SaveToFile( g_pFullFileSystem, fullpath, NULL ); - if (!bSuccess) - { - MessageBox *dlg = new MessageBox("BuildMode - Error saving file", "Error: Could not save changes. File is most likely read only."); - dlg->DoModal(); - } - - rDat->deleteThis(); - } - - return bSuccess; -} - -//----------------------------------------------------------------------------- -// Purpose: Deletes all the controls not created by the code -//----------------------------------------------------------------------------- -void BuildGroup::DeleteAllControlsCreatedByControlSettingsFile() -{ - // loop though objects in the current control group and remove them all - // the 0th panel is always the contextPanel which is not deletable - for ( int i = 1; i < _panelDar.Count(); i++ ) - { - if (!_panelDar[i].Get()) // this can happen if we had two of the same handle in the list - { - _panelDar.Remove(i); - --i; - continue; - } - - // only delete deletable panels, as the only deletable panels - // are the ones created using the resource file - if ( _panelDar[i].Get()->IsBuildModeDeletable()) - { - delete _panelDar[i].Get(); - _panelDar.Remove(i); - --i; - } - } - - _currentPanel = m_pBuildContext; - _currentPanel->InvalidateLayout(); - m_pBuildContext->Repaint(); -} - -//----------------------------------------------------------------------------- -// Purpose: serializes settings from a resource data container -//----------------------------------------------------------------------------- -void BuildGroup::ApplySettings( KeyValues *resourceData ) -{ - // loop through all the keys, applying them wherever - for (KeyValues *controlKeys = resourceData->GetFirstSubKey(); controlKeys != NULL; controlKeys = controlKeys->GetNextKey()) - { - bool bFound = false; - - // Skip keys that are atomic.. - if (controlKeys->GetDataType() != KeyValues::TYPE_NONE) - continue; - - char const *keyName = controlKeys->GetName(); - - // check to see if any buildgroup panels have this name - for ( int i = 0; i < _panelDar.Count(); i++ ) - { - Panel *panel = _panelDar[i].Get(); - - if (!panel) // this can happen if we had two of the same handle in the list - { - _panelDar.Remove(i); - --i; - continue; - } - - - Assert (panel); - - // make the control name match CASE INSENSITIVE! - char const *panelName = panel->GetName(); - - if (!Q_stricmp(panelName, keyName)) - { - // apply the settings - panel->ApplySettings(controlKeys); - bFound = true; - break; - } - } - - if ( !bFound ) - { - // the key was not found in the registered list, check to see if we should create it - if ( keyName /*controlKeys->GetInt("AlwaysCreate", false)*/ ) - { - // create the control even though it wasn't registered - NewControl( controlKeys ); - } - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: Create a new control in the context panel -// Input: name: class name of control to create -// controlKeys: keyvalues of settings for the panel. -// name OR controlKeys should be set, not both. -// x,y position relative to base panel -// Output: Panel *newPanel, NULL if failed to create new control. -//----------------------------------------------------------------------------- -Panel *BuildGroup::NewControl( const char *name, int x, int y) -{ - Assert (name); - - Panel *newPanel = NULL; - // returns NULL on failure - newPanel = static_cast(m_pParentPanel)->CreateControlByName(name); - - if (newPanel) - { - // panel successfully created - newPanel->SetParent(m_pParentPanel); - newPanel->SetBuildGroup(this); - newPanel->SetPos(x, y); - - char newFieldName[255]; - GetNewFieldName(newFieldName, sizeof(newFieldName), newPanel); - newPanel->SetName(newFieldName); - - newPanel->AddActionSignalTarget(m_pParentPanel); - newPanel->SetBuildModeEditable(true); - newPanel->SetBuildModeDeletable(true); - - // make sure it gets freed - newPanel->SetAutoDelete(true); - } - - return newPanel; -} - -//----------------------------------------------------------------------------- -// Purpose: Create a new control in the context panel -// Input: controlKeys: keyvalues of settings for the panel only works when applying initial settings. -// Output: Panel *newPanel, NULL if failed to create new control. -//----------------------------------------------------------------------------- -Panel *BuildGroup::NewControl( KeyValues *controlKeys, int x, int y) -{ - Assert (controlKeys); - - Panel *newPanel = NULL; - if (controlKeys) - { -// Warning( "Creating new control \"%s\" of type \"%s\"\n", controlKeys->GetString( "fieldName" ), controlKeys->GetString( "ControlName" ) ); - KeyValues *keyVal = new KeyValues("ControlFactory", "ControlName", controlKeys->GetString("ControlName")); - m_pBuildContext->RequestInfo(keyVal); - // returns NULL on failure - newPanel = (Panel *)keyVal->GetPtr("PanelPtr"); - keyVal->deleteThis(); - } - else - { - return NULL; - } - - if (newPanel) - { - // panel successfully created - newPanel->SetParent(m_pParentPanel); - newPanel->SetBuildGroup(this); - newPanel->SetPos(x, y); - - newPanel->SetName(controlKeys->GetName()); // name before applysettings :) - newPanel->ApplySettings(controlKeys); - - newPanel->AddActionSignalTarget(m_pParentPanel); - newPanel->SetBuildModeEditable(true); - newPanel->SetBuildModeDeletable(true); - - // make sure it gets freed - newPanel->SetAutoDelete(true); - } - - return newPanel; -} - -//----------------------------------------------------------------------------- -// Purpose: Get a new unique fieldname for a new control -//----------------------------------------------------------------------------- -void BuildGroup::GetNewFieldName(char *newFieldName, int newFieldNameSize, Panel *newPanel) -{ - int fieldNameNumber=1; - char defaultName[25]; - - Q_strncpy( defaultName, newPanel->GetClassName(), sizeof( defaultName ) ); - - while (1) - { - Q_snprintf (newFieldName, newFieldNameSize, "%s%d", defaultName, fieldNameNumber); - if ( FieldNameTaken(newFieldName) == NULL) - break; - ++fieldNameNumber; - } -} - -//----------------------------------------------------------------------------- -// Purpose: check to see if any buildgroup panels have this fieldname -// Input : fieldName, name to check -// Output : ptr to a panel that has the name if it is taken -//----------------------------------------------------------------------------- -Panel *BuildGroup::FieldNameTaken(const char *fieldName) -{ - for ( int i = 0; i < _panelDar.Count(); i++ ) - { - Panel *panel = _panelDar[i].Get(); - if ( !panel ) - continue; - - if (!stricmp(panel->GetName(), fieldName) ) - { - return panel; - } - } - return NULL; -} - -//----------------------------------------------------------------------------- -// Purpose: serializes settings to a resource data container -//----------------------------------------------------------------------------- -void BuildGroup::GetSettings( KeyValues *resourceData ) -{ - // loop through all the objects getting their settings - for( int i = 0; i < _panelDar.Count(); i++ ) - { - Panel *panel = _panelDar[i].Get(); - if (!panel) - continue; - - bool isRuler = false; - // do not get setting for ruler labels. - if (_showRulers) // rulers are visible - { - for (int i = 0; i < 4; i++) - { - if (panel == _rulerNumber[i]) - { - isRuler = true; - break; - } - } - if (isRuler) - { - isRuler = false; - continue; - } - } - - // Don't save the setting of the buildmodedialog - if (!stricmp(panel->GetName(), "BuildDialog")) - continue; - - // get the keys section from the data file - if (panel->GetName() && *panel->GetName()) - { - KeyValues *datKey = resourceData->FindKey(panel->GetName(), true); - - // get the settings - panel->GetSettings(datKey); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: loop though objects in the current control group and remove them all -//----------------------------------------------------------------------------- -void BuildGroup::RemoveSettings() -{ - // loop though objects in the current control group and remove them all - int i; - for( i = 0; i < _controlGroup.Count(); i++ ) - { - // only delete delatable panels - if ( _controlGroup[i].Get()->IsBuildModeDeletable()) - { - delete _controlGroup[i].Get(); - _controlGroup.Remove(i); - --i; - } - } - - // remove deleted panels from the handle list - for( i = 0; i < _panelDar.Count(); i++ ) - { - if ( !_panelDar[i].Get() ) - { - _panelDar.Remove(i); - --i; - } - } - - _currentPanel = m_pBuildContext; - _currentPanel->InvalidateLayout(); - m_pBuildContext->Repaint(); -} - -//----------------------------------------------------------------------------- -// Purpose: sets the panel from which the build group gets all it's object creation info -//----------------------------------------------------------------------------- -void BuildGroup::SetContextPanel(Panel *contextPanel) -{ - m_pBuildContext = contextPanel; -} - -//----------------------------------------------------------------------------- -// Purpose: gets the panel from which the build group gets all it's object creation info -//----------------------------------------------------------------------------- -Panel *BuildGroup::GetContextPanel() -{ - return m_pBuildContext; -} - -//----------------------------------------------------------------------------- -// Purpose: get the list of panels in the buildgroup -//----------------------------------------------------------------------------- -CUtlVector *BuildGroup::GetPanelList() -{ - return &_panelDar; -} - -//----------------------------------------------------------------------------- -// Purpose: dialog variables -//----------------------------------------------------------------------------- -KeyValues *BuildGroup::GetDialogVariables() -{ - EditablePanel *edit = dynamic_cast(m_pParentPanel); - if (edit) - { - return edit->GetDialogVariables(); - } - - return NULL; -} +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + //========= Copyright © 1996-2003, Valve LLC, All rights reserved. ============ +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + + +#include +#define PROTECTED_THINGS_DISABLE + +#include "utldict.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "filesystem.h" + +#if defined( _X360 ) +#include "xbox/xbox_win32stubs.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include + +using namespace vgui; + +//----------------------------------------------------------------------------- +// Handle table +//----------------------------------------------------------------------------- +IMPLEMENT_HANDLES( BuildGroup, 20 ) + + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +BuildGroup::BuildGroup(Panel *parentPanel, Panel *contextPanel) +{ + CONSTRUCT_HANDLE( ); + + _enabled=false; + _snapX=1; + _snapY=1; + _cursor_sizenwse = dc_sizenwse; + _cursor_sizenesw = dc_sizenesw; + _cursor_sizewe = dc_sizewe; + _cursor_sizens = dc_sizens; + _cursor_sizeall = dc_sizeall; + _currentPanel=null; + _dragging=false; + m_pResourceName=NULL; + m_pResourcePathID = NULL; + m_hBuildDialog=NULL; + m_pParentPanel=parentPanel; + for (int i=0; i<4; ++i) + _rulerNumber[i] = NULL; + SetContextPanel(contextPanel); + _showRulers = false; + +} + +//----------------------------------------------------------------------------- +// Purpose: Destructor +//----------------------------------------------------------------------------- +BuildGroup::~BuildGroup() +{ + if (m_hBuildDialog) + delete m_hBuildDialog.Get(); + m_hBuildDialog = NULL; + + delete [] m_pResourceName; + delete [] m_pResourcePathID; + + for (int i=0; i <4; ++i) + { + if (_rulerNumber[i]) + { + delete _rulerNumber[i]; + _rulerNumber[i]= NULL; + } + } + + DESTRUCT_HANDLE(); +} + +//----------------------------------------------------------------------------- +// Purpose: Toggles build mode on/off +// Input : state - new state +//----------------------------------------------------------------------------- +void BuildGroup::SetEnabled(bool state) +{ + if(_enabled != state) + { + _enabled = state; + _currentPanel = NULL; + + if ( state ) + { + ActivateBuildDialog(); + } + else + { + // hide the build dialog + if ( m_hBuildDialog ) + { + m_hBuildDialog->OnCommand("Close"); + } + + // request focus for our main panel + m_pParentPanel->RequestFocus(); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Check if buildgroup is enabled +//----------------------------------------------------------------------------- +bool BuildGroup::IsEnabled() +{ + return _enabled; +} + +//----------------------------------------------------------------------------- +// Purpose: Get the list of panels that are currently selected +//----------------------------------------------------------------------------- +CUtlVector *BuildGroup::GetControlGroup() +{ + return &_controlGroup; +} + +//----------------------------------------------------------------------------- +// Purpose: Check if ruler display is activated +//----------------------------------------------------------------------------- +bool BuildGroup::HasRulersOn() +{ + return _showRulers; +} + +//----------------------------------------------------------------------------- +// Purpose: Toggle ruler display +//----------------------------------------------------------------------------- +void BuildGroup::ToggleRulerDisplay() +{ + _showRulers = !_showRulers; + + if (_rulerNumber[0] == NULL) // rulers haven't been initialized + { + _rulerNumber[0] = new Label(m_pBuildContext, NULL, ""); + _rulerNumber[1] = new Label(m_pBuildContext, NULL, ""); + _rulerNumber[2] = new Label(m_pBuildContext, NULL, ""); + _rulerNumber[3] = new Label(m_pBuildContext, NULL, ""); + } + SetRulerLabelsVisible(_showRulers); + + m_pBuildContext->Repaint(); +} + + +//----------------------------------------------------------------------------- +// Purpose: Tobble visibility of ruler number labels +//----------------------------------------------------------------------------- +void BuildGroup::SetRulerLabelsVisible(bool state) +{ + _rulerNumber[0]->SetVisible(state); + _rulerNumber[1]->SetVisible(state); + _rulerNumber[2]->SetVisible(state); + _rulerNumber[3]->SetVisible(state); +} + +void BuildGroup::ApplySchemeSettings( IScheme *pScheme ) +{ + DrawRulers(); +} + +//----------------------------------------------------------------------------- +// Purpose: Draw Rulers on screen if conditions are right +//----------------------------------------------------------------------------- +void BuildGroup::DrawRulers() +{ + // don't draw if visibility is off + if (!_showRulers) + { + return; + } + + // no drawing if we selected the context panel + if (m_pBuildContext == _currentPanel) + { + SetRulerLabelsVisible(false); + return; + } + else + SetRulerLabelsVisible(true); + + int x, y, wide, tall; + // get base panel's postition + m_pBuildContext->GetBounds(x, y, wide, tall); + m_pBuildContext->ScreenToLocal(x,y); + + int cx, cy, cwide, ctall; + _currentPanel->GetBounds (cx, cy, cwide, ctall); + + surface()->PushMakeCurrent(m_pBuildContext->GetVPanel(), false); + + // draw rulers + surface()->DrawSetColor(255, 255, 255, 255); // white color + + surface()->DrawFilledRect(0, cy, cx, cy+1); //top horiz left + surface()->DrawFilledRect(cx+cwide, cy, wide, cy+1); //top horiz right + + surface()->DrawFilledRect(0, cy+ctall-1, cx, cy+ctall); //bottom horiz left + surface()->DrawFilledRect(cx+cwide, cy+ctall-1, wide, cy+ctall); //bottom horiz right + + surface()->DrawFilledRect(cx,0,cx+1,cy); //top vert left + surface()->DrawFilledRect(cx+cwide-1,0, cx+cwide, cy); //top vert right + + surface()->DrawFilledRect(cx,cy+ctall, cx+1, tall); //bottom vert left + surface()->DrawFilledRect(cx+cwide-1, cy+ctall, cx+cwide, tall); //bottom vert right + + surface()->PopMakeCurrent(m_pBuildContext->GetVPanel()); + + // now let's put numbers with the rulers + char textstring[20]; + Q_snprintf (textstring, sizeof( textstring ), "%d", cx); + _rulerNumber[0]->SetText(textstring); + int twide, ttall; + _rulerNumber[0]->GetContentSize(twide,ttall); + _rulerNumber[0]->SetSize(twide,ttall); + _rulerNumber[0]->SetPos(cx/2-twide/2, cy-ttall+3); + + Q_snprintf (textstring, sizeof( textstring ), "%d", cy); + _rulerNumber[1]->SetText(textstring); + _rulerNumber[1]->GetContentSize(twide,ttall); + _rulerNumber[1]->SetSize(twide,ttall); + _rulerNumber[1]->GetSize(twide,ttall); + _rulerNumber[1]->SetPos(cx-twide + 3, cy/2-ttall/2); + + Q_snprintf (textstring, sizeof( textstring ), "%d", cy); + _rulerNumber[2]->SetText(textstring); + _rulerNumber[2]->GetContentSize(twide,ttall); + _rulerNumber[2]->SetSize(twide,ttall); + _rulerNumber[2]->SetPos(cx+cwide+(wide-cx-cwide)/2 - twide/2, cy+ctall-3); + + Q_snprintf (textstring, sizeof( textstring ), "%d", cy); + _rulerNumber[3]->SetText(textstring); + _rulerNumber[3]->GetContentSize(twide,ttall); + _rulerNumber[3]->SetSize(twide,ttall); + _rulerNumber[3]->SetPos(cx+cwide, cy+ctall+(tall-cy-ctall)/2 - ttall/2); + +} + +//----------------------------------------------------------------------------- +// Purpose: respond to cursor movments +//----------------------------------------------------------------------------- +bool BuildGroup::CursorMoved(int x, int y, Panel *panel) +{ + Assert(panel); + + if ( !m_hBuildDialog.Get() ) + { + if ( panel->GetParent() ) + { + EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() ); + if ( ep ) + { + BuildGroup *bg = ep->GetBuildGroup(); + if ( bg && bg != this ) + { + bg->CursorMoved( x, y, panel ); + } + } + } + return false; + } + + // no moving uneditable panels + // commented out because this has issues with panels moving + // to front and obscuring other panels + //if (!panel->IsBuildModeEditable()) + // return; + + if (_dragging) + { + input()->GetCursorPos(x, y); + + if (_dragMouseCode == MOUSE_RIGHT) + { + int newW = max( 1, _dragStartPanelSize[ 0 ] + x - _dragStartCursorPos[0] ); + int newH = max( 1, _dragStartPanelSize[ 1 ] + y - _dragStartCursorPos[1] ); + + bool shift = ( input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT) ); + bool ctrl = ( input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL) ); + + if ( shift ) + { + newW = _dragStartPanelSize[ 0 ]; + } + if ( ctrl ) + { + newH = _dragStartPanelSize[ 1 ]; + } + + panel->SetSize( newW, newH ); + ApplySnap(panel); + } + else + { + for (int i=0; i < _controlGroup.Count(); ++i) + { + // now fix offset of member panels with respect to the one we are dragging + Panel *groupMember = _controlGroup[i].Get(); + groupMember->SetPos(_dragStartPanelPos[0] + _groupDeltaX[i] +(x-_dragStartCursorPos[0]), _dragStartPanelPos[1] + _groupDeltaY[i] +(y-_dragStartCursorPos[1])); + ApplySnap(groupMember); + } + } + + // update the build dialog + if (m_hBuildDialog) + { + KeyValues *keyval = new KeyValues("UpdateControlData"); + keyval->SetPtr("panel", GetCurrentPanel()); + ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL); + + keyval = new KeyValues("EnableSaveButton"); + ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL); + } + + panel->Repaint(); + panel->CallParentFunction(new KeyValues("Repaint")); + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool BuildGroup::MousePressed(MouseCode code, Panel *panel) +{ + Assert(panel); + + if ( !m_hBuildDialog.Get() ) + { + if ( panel->GetParent() ) + { + EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() ); + if ( ep ) + { + BuildGroup *bg = ep->GetBuildGroup(); + if ( bg && bg != this ) + { + bg->MousePressed( code, panel ); + } + } + } + return false; + } + + // if people click on the base build dialog panel. + if (panel == m_hBuildDialog) + { + // hide the click menu if its up + ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("HideNewControlMenu"), NULL); + return true; + } + + // don't select unnamed items + if (strlen(panel->GetName()) < 1) + return true; + + bool shift = ( input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT) ); + if (!shift) + { + _controlGroup.RemoveAll(); + } + + // Show new ctrl menu if they click on the bg (not on a subcontrol) + if ( code == MOUSE_RIGHT && panel == GetContextPanel()) + { + // trigger a drop down menu to create new controls + ivgui()->PostMessage (m_hBuildDialog->GetVPanel(), new KeyValues("ShowNewControlMenu"), NULL); + } + else + { + // don't respond if we click on ruler numbers + if (_showRulers) // rulers are visible + { + for ( int i=0; i < 4; i++) + { + if ( panel == _rulerNumber[i]) + return true; + } + } + + _dragging = true; + _dragMouseCode = code; + ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("HideNewControlMenu"), NULL); + + int x, y; + input()->GetCursorPos(x, y); + + _dragStartCursorPos[0] = x; + _dragStartCursorPos[1] = y; + + + input()->SetMouseCapture(panel->GetVPanel()); + + _groupDeltaX.RemoveAll(); + _groupDeltaY.RemoveAll(); + + // basepanel is the panel that all the deltas will be calculated from. + // it is the last panel we clicked in because if we move the panels as a group + // it would be from that one + Panel *basePanel = NULL; + // find the panel we clicked in, that is the base panel + // it might already be in the group + for (int i=0; i< _controlGroup.Count(); ++i) + { + if (panel == _controlGroup[i].Get()) + { + basePanel = panel; + break; + } + } + + // if its not in the group we just added this panel. get it in the group + if (basePanel == NULL) + { + PHandle temp; + temp = panel; + _controlGroup.AddToTail(temp); + basePanel = panel; + } + + basePanel->GetPos(x,y); + _dragStartPanelPos[0]=x; + _dragStartPanelPos[1]=y; + + basePanel->GetSize( _dragStartPanelSize[ 0 ], _dragStartPanelSize[ 1 ] ); + + // figure out the deltas of the other panels from the base panel + for (int i=0; i<_controlGroup.Count(); ++i) + { + int cx, cy; + _controlGroup[i].Get()->GetPos(cx, cy); + _groupDeltaX.AddToTail(cx - x); + _groupDeltaY.AddToTail(cy - y); + } + + // if this panel wasn't already selected update the buildmode dialog controls to show its info + if(_currentPanel != panel) + { + _currentPanel = panel; + + if ( m_hBuildDialog ) + { + // think this is taken care of by SetActiveControl. + //ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("ApplyDataToControls"), NULL); + + KeyValues *keyval = new KeyValues("SetActiveControl"); + keyval->SetPtr("PanelPtr", GetCurrentPanel()); + ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL); + } + } + + // store undo information upon panel selection. + ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("StoreUndo"), NULL); + + panel->RequestFocus(); + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool BuildGroup::MouseReleased(MouseCode code, Panel *panel) +{ + if ( !m_hBuildDialog.Get() ) + { + if ( panel->GetParent() ) + { + EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() ); + if ( ep ) + { + BuildGroup *bg = ep->GetBuildGroup(); + if ( bg && bg != this ) + { + bg->MouseReleased( code, panel ); + } + } + } + return false; + } + + Assert(panel); + + _dragging=false; + input()->SetMouseCapture(null); + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool BuildGroup::MouseDoublePressed(MouseCode code, Panel *panel) +{ + Assert(panel); + return MousePressed( code, panel ); +} + +bool BuildGroup::KeyTyped( wchar_t unichar, Panel *panel ) +{ + if ( !m_hBuildDialog.Get() ) + { + if ( panel->GetParent() ) + { + EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() ); + if ( ep ) + { + BuildGroup *bg = ep->GetBuildGroup(); + if ( bg && bg != this ) + { + bg->KeyTyped( unichar, panel ); + } + } + } + return false; + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool BuildGroup::KeyCodeTyped(KeyCode code, Panel *panel) +{ + if ( !m_hBuildDialog.Get() ) + { + if ( panel->GetParent() ) + { + EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() ); + if ( ep ) + { + BuildGroup *bg = ep->GetBuildGroup(); + if ( bg && bg != this ) + { + bg->KeyCodeTyped( code, panel ); + } + } + } + return false; + } + + Assert(panel); + + int dx=0; + int dy=0; + + 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 * >( panel ); + if ( ep ) + { + ep->ActivateBuildMode(); + } + return true; + } + + switch (code) + { + case KEY_LEFT: + { + dx-=_snapX; + break; + } + case KEY_RIGHT: + { + dx+=_snapX; + break; + } + case KEY_UP: + { + dy-=_snapY; + break; + } + case KEY_DOWN: + { + dy+=_snapY; + break; + } + case KEY_DELETE: + { + // delete the panel we have selected + ivgui()->PostMessage (m_hBuildDialog->GetVPanel(), new KeyValues ("DeletePanel"), NULL); + break; + } + + } + + if (ctrl) + { + switch (code) + { + case KEY_Z: + { + ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("Undo"), NULL); + break; + } + + case KEY_C: + { + ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("Copy"), NULL); + break; + } + case KEY_V: + { + ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("Paste"), NULL); + break; + } + } + } + + if(dx||dy) + { + //TODO: make this stuff actually snap + + int x,y,wide,tall; + + panel->GetBounds(x,y,wide,tall); + + if(shift) + { + panel->SetSize(wide+dx,tall+dy); + } + else + { + panel->SetPos(x+dx,y+dy); + } + + ApplySnap(panel); + + panel->Repaint(); + if (panel->GetVParent() != 0) + { + panel->PostMessage(panel->GetVParent(), new KeyValues("Repaint")); + } + + + // update the build dialog + if (m_hBuildDialog) + { + // post that it's active + KeyValues *keyval = new KeyValues("SetActiveControl"); + keyval->SetPtr("PanelPtr", GetCurrentPanel()); + ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL); + + // post that it's been changed + ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("PanelMoved"), NULL); + } + } + + // If holding key while dragging, simulate moving cursor so shift/ctrl key changes take effect + if ( _dragging && panel != GetContextPanel() ) + { + int x, y; + input()->GetCursorPos( x, y ); + CursorMoved( x, y, panel ); + } + + return true; +} + +bool BuildGroup::KeyCodeReleased(KeyCode code, Panel *panel ) +{ + if ( !m_hBuildDialog.Get() ) + { + if ( panel->GetParent() ) + { + EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() ); + if ( ep ) + { + BuildGroup *bg = ep->GetBuildGroup(); + if ( bg && bg != this ) + { + bg->KeyCodeTyped( code, panel ); + } + } + } + return false; + } + + // If holding key while dragging, simulate moving cursor so shift/ctrl key changes take effect + if ( _dragging && panel != GetContextPanel() ) + { + int x, y; + input()->GetCursorPos( x, y ); + CursorMoved( x, y, panel ); + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: Searches for a BuildModeDialog in the hierarchy +//----------------------------------------------------------------------------- +Panel *BuildGroup::CreateBuildDialog( void ) +{ + // request the panel + Panel *buildDialog = NULL; + KeyValues *data = new KeyValues("BuildDialog"); + data->SetPtr("BuildGroupPtr", this); + if (m_pBuildContext->RequestInfo(data)) + { + buildDialog = (Panel *)data->GetPtr("PanelPtr"); + } + + // initialize the build dialog if found + if ( buildDialog ) + { + input()->ReleaseAppModalSurface(); + } + + return buildDialog; +} + +//----------------------------------------------------------------------------- +// Purpose: Activates the build mode settings dialog +//----------------------------------------------------------------------------- +void BuildGroup::ActivateBuildDialog( void ) +{ + // create the build mode dialog first time through + if (!m_hBuildDialog.Get()) + { + m_hBuildDialog = CreateBuildDialog(); + + if (!m_hBuildDialog.Get()) + return; + } + + m_hBuildDialog->SetVisible( true ); + + // send a message to set the initial dialog controls info + _currentPanel = m_pParentPanel; + KeyValues *keyval = new KeyValues("SetActiveControl"); + keyval->SetPtr("PanelPtr", GetCurrentPanel()); + ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +HCursor BuildGroup::GetCursor(Panel *panel) +{ + Assert(panel); + + int x,y,wide,tall; + input()->GetCursorPos(x,y); + panel->ScreenToLocal(x,y); + panel->GetSize(wide,tall); + + if(x < 2) + { + if(y < 4) + { + return _cursor_sizenwse; + } + else + if(y<(tall-4)) + { + return _cursor_sizewe; + } + else + { + return _cursor_sizenesw; + } + } + + return _cursor_sizeall; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void BuildGroup::ApplySnap(Panel *panel) +{ + Assert(panel); + + int x,y,wide,tall; + panel->GetBounds(x,y,wide,tall); + + x=(x/_snapX)*_snapX; + y=(y/_snapY)*_snapY; + panel->SetPos(x,y); + + int xx,yy; + xx=x+wide; + yy=y+tall; + + xx=(xx/_snapX)*_snapX; + yy=(yy/_snapY)*_snapY; + panel->SetSize(xx-x,yy-y); +} + +//----------------------------------------------------------------------------- +// Purpose: Return the currently selected panel +//----------------------------------------------------------------------------- +Panel *BuildGroup::GetCurrentPanel() +{ + return _currentPanel; +} + +//----------------------------------------------------------------------------- +// Purpose: Add panel the list of panels that are in the build group +//----------------------------------------------------------------------------- +void BuildGroup::PanelAdded(Panel *panel) +{ + Assert(panel); + + PHandle temp; + temp = panel; + int c = _panelDar.Count(); + for ( int i = 0; i < c; ++i ) + { + if ( _panelDar[ i ] == temp ) + { + return; + } + } + _panelDar.AddToTail(temp); +} + +//----------------------------------------------------------------------------- +// Purpose: loads the control settings from file +//----------------------------------------------------------------------------- +void BuildGroup::LoadControlSettings(const char *controlResourceName, const char *pathID, KeyValues *pPreloadedKeyValues, KeyValues *pConditions) +{ + // make sure the file is registered + RegisterControlSettingsFile(controlResourceName, pathID); + + // Use the keyvalues they passed in or load them. + KeyValues *rDat = pPreloadedKeyValues; + if ( !rDat ) + { + // load the resource data from the file + rDat = new KeyValues(controlResourceName); + + // check the skins directory first, if an explicit pathID hasn't been set + bool bSuccess = false; + if (!pathID) + { + bSuccess = rDat->LoadFromFile(g_pFullFileSystem, controlResourceName, "SKIN"); + } + if (!bSuccess) + { + bSuccess = rDat->LoadFromFile(g_pFullFileSystem, controlResourceName, pathID); + } + + if ( bSuccess ) + { + if ( IsX360() ) + { + rDat->ProcessResolutionKeys( surface()->GetResolutionKey() ); + } + if ( IsPC() ) + { + ConVarRef cl_hud_minmode( "cl_hud_minmode", true ); + if ( cl_hud_minmode.IsValid() && cl_hud_minmode.GetBool() ) + { + rDat->ProcessResolutionKeys( "_minmode" ); + } + } + + if ( pConditions && pConditions->GetFirstSubKey() ) + { + ProcessConditionalKeys( rDat, pConditions ); + } + } + } + + // save off the resource name + delete [] m_pResourceName; + m_pResourceName = new char[strlen(controlResourceName) + 1]; + strcpy(m_pResourceName, controlResourceName); + + if (pathID) + { + delete [] m_pResourcePathID; + m_pResourcePathID = new char[strlen(pathID) + 1]; + strcpy(m_pResourcePathID, pathID); + } + + // delete any controls not in both files + DeleteAllControlsCreatedByControlSettingsFile(); + + // loop through the resource data sticking info into controls + ApplySettings(rDat); + + if (m_pParentPanel) + { + m_pParentPanel->InvalidateLayout(); + m_pParentPanel->Repaint(); + } + + if ( rDat != pPreloadedKeyValues ) + { + rDat->deleteThis(); + } +} + +void BuildGroup::ProcessConditionalKeys( KeyValues *pData, KeyValues *pConditions ) +{ + // for each condition, look for it in keys + // if its a positive condition, promote all of its children, replacing values + + if ( pData ) + { + KeyValues *pSubKey = pData->GetFirstSubKey(); + if ( !pSubKey ) + { + // not a block + return; + } + + for ( ; pSubKey != NULL; pSubKey = pSubKey->GetNextKey() ) + { + // recursively descend each sub block + ProcessConditionalKeys( pSubKey, pConditions ); + + KeyValues *pCondition = pConditions->GetFirstSubKey(); + for ( ; pCondition != NULL; pCondition = pCondition->GetNextKey() ) + { + // if we match any conditions in this sub block, copy up + KeyValues *pConditionBlock = pSubKey->FindKey( pCondition->GetName() ); + if ( pConditionBlock ) + { + KeyValues *pOverridingKey; + for ( pOverridingKey = pConditionBlock->GetFirstSubKey(); pOverridingKey != NULL; pOverridingKey = pOverridingKey->GetNextKey() ) + { + KeyValues *pExistingKey = pSubKey->FindKey( pOverridingKey->GetName() ); + if ( pExistingKey ) + { + pExistingKey->SetStringValue( pOverridingKey->GetString() ); + } + else + { + KeyValues *copy = pOverridingKey->MakeCopy(); + pSubKey->AddSubKey( copy ); + } + } + } + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: registers that a control settings file may be loaded +// use when the dialog may have multiple states and the editor will need to be able to switch between them +//----------------------------------------------------------------------------- +void BuildGroup::RegisterControlSettingsFile(const char *controlResourceName, const char *pathID) +{ + // add the file into a list for build mode + CUtlSymbol sym(controlResourceName); + if (!m_RegisteredControlSettingsFiles.IsValidIndex(m_RegisteredControlSettingsFiles.Find(sym))) + { + m_RegisteredControlSettingsFiles.AddToTail(sym); + } +} + +//----------------------------------------------------------------------------- +// Purpose: data accessor / iterator +//----------------------------------------------------------------------------- +int BuildGroup::GetRegisteredControlSettingsFileCount() +{ + return m_RegisteredControlSettingsFiles.Count(); +} + +//----------------------------------------------------------------------------- +// Purpose: data accessor +//----------------------------------------------------------------------------- +const char *BuildGroup::GetRegisteredControlSettingsFileByIndex(int index) +{ + return m_RegisteredControlSettingsFiles[index].String(); +} + +//----------------------------------------------------------------------------- +// Purpose: reloads the control settings from file +//----------------------------------------------------------------------------- +void BuildGroup::ReloadControlSettings() +{ + delete m_hBuildDialog.Get(); + m_hBuildDialog = NULL; + + // loop though objects in the current control group and remove them all + // the 0th panel is always the contextPanel which is not deletable + for( int i = 1; i < _panelDar.Count(); i++ ) + { + if (!_panelDar[i].Get()) // this can happen if we had two of the same handle in the list + { + _panelDar.Remove(i); + --i; + continue; + } + + // only delete deletable panels, as the only deletable panels + // are the ones created using the resource file + if ( _panelDar[i].Get()->IsBuildModeDeletable()) + { + delete _panelDar[i].Get(); + _panelDar.Remove(i); + --i; + } + } + + if (m_pResourceName) + { + EditablePanel *edit = dynamic_cast(m_pParentPanel); + if (edit) + { + edit->LoadControlSettings(m_pResourceName, m_pResourcePathID); + } + else + { + LoadControlSettings(m_pResourceName, m_pResourcePathID); + } + } + + _controlGroup.RemoveAll(); + + ActivateBuildDialog(); +} + +//----------------------------------------------------------------------------- +// Purpose: changes which control settings are currently loaded +//----------------------------------------------------------------------------- +void BuildGroup::ChangeControlSettingsFile(const char *controlResourceName) +{ + // clear any current state + _controlGroup.RemoveAll(); + _currentPanel = m_pParentPanel; + + // load the new state, via the dialog if possible + EditablePanel *edit = dynamic_cast(m_pParentPanel); + if (edit) + { + edit->LoadControlSettings(controlResourceName, m_pResourcePathID); + } + else + { + LoadControlSettings(controlResourceName, m_pResourcePathID); + } + + // force it to update + KeyValues *keyval = new KeyValues("SetActiveControl"); + keyval->SetPtr("PanelPtr", GetCurrentPanel()); + ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL); +} + +//----------------------------------------------------------------------------- +// Purpose: saves control settings to file +//----------------------------------------------------------------------------- +bool BuildGroup::SaveControlSettings( void ) +{ + bool bSuccess = false; + if ( m_pResourceName ) + { + KeyValues *rDat = new KeyValues( m_pResourceName ); + + // get the data from our controls + GetSettings( rDat ); + + char fullpath[ 512 ]; + g_pFullFileSystem->RelativePathToFullPath( m_pResourceName, m_pResourcePathID, fullpath, sizeof( fullpath ) ); + + // save the data out to a file + bSuccess = rDat->SaveToFile( g_pFullFileSystem, fullpath, NULL ); + if (!bSuccess) + { + MessageBox *dlg = new MessageBox("BuildMode - Error saving file", "Error: Could not save changes. File is most likely read only."); + dlg->DoModal(); + } + + rDat->deleteThis(); + } + + return bSuccess; +} + +//----------------------------------------------------------------------------- +// Purpose: Deletes all the controls not created by the code +//----------------------------------------------------------------------------- +void BuildGroup::DeleteAllControlsCreatedByControlSettingsFile() +{ + // loop though objects in the current control group and remove them all + // the 0th panel is always the contextPanel which is not deletable + for ( int i = 1; i < _panelDar.Count(); i++ ) + { + if (!_panelDar[i].Get()) // this can happen if we had two of the same handle in the list + { + _panelDar.Remove(i); + --i; + continue; + } + + // only delete deletable panels, as the only deletable panels + // are the ones created using the resource file + if ( _panelDar[i].Get()->IsBuildModeDeletable()) + { + delete _panelDar[i].Get(); + _panelDar.Remove(i); + --i; + } + } + + _currentPanel = m_pBuildContext; + _currentPanel->InvalidateLayout(); + m_pBuildContext->Repaint(); +} + +//----------------------------------------------------------------------------- +// Purpose: serializes settings from a resource data container +//----------------------------------------------------------------------------- +void BuildGroup::ApplySettings( KeyValues *resourceData ) +{ + // loop through all the keys, applying them wherever + for (KeyValues *controlKeys = resourceData->GetFirstSubKey(); controlKeys != NULL; controlKeys = controlKeys->GetNextKey()) + { + bool bFound = false; + + // Skip keys that are atomic.. + if (controlKeys->GetDataType() != KeyValues::TYPE_NONE) + continue; + + char const *keyName = controlKeys->GetName(); + + // check to see if any buildgroup panels have this name + for ( int i = 0; i < _panelDar.Count(); i++ ) + { + Panel *panel = _panelDar[i].Get(); + + if (!panel) // this can happen if we had two of the same handle in the list + { + _panelDar.Remove(i); + --i; + continue; + } + + + Assert (panel); + + // make the control name match CASE INSENSITIVE! + char const *panelName = panel->GetName(); + + if (!Q_stricmp(panelName, keyName)) + { + // apply the settings + panel->ApplySettings(controlKeys); + bFound = true; + break; + } + } + + if ( !bFound ) + { + // the key was not found in the registered list, check to see if we should create it + if ( keyName /*controlKeys->GetInt("AlwaysCreate", false)*/ ) + { + // create the control even though it wasn't registered + NewControl( controlKeys ); + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Create a new control in the context panel +// Input: name: class name of control to create +// controlKeys: keyvalues of settings for the panel. +// name OR controlKeys should be set, not both. +// x,y position relative to base panel +// Output: Panel *newPanel, NULL if failed to create new control. +//----------------------------------------------------------------------------- +Panel *BuildGroup::NewControl( const char *name, int x, int y) +{ + Assert (name); + + Panel *newPanel = NULL; + // returns NULL on failure + newPanel = static_cast(m_pParentPanel)->CreateControlByName(name); + + if (newPanel) + { + // panel successfully created + newPanel->SetParent(m_pParentPanel); + newPanel->SetBuildGroup(this); + newPanel->SetPos(x, y); + + char newFieldName[255]; + GetNewFieldName(newFieldName, sizeof(newFieldName), newPanel); + newPanel->SetName(newFieldName); + + newPanel->AddActionSignalTarget(m_pParentPanel); + newPanel->SetBuildModeEditable(true); + newPanel->SetBuildModeDeletable(true); + + // make sure it gets freed + newPanel->SetAutoDelete(true); + } + + return newPanel; +} + +//----------------------------------------------------------------------------- +// Purpose: Create a new control in the context panel +// Input: controlKeys: keyvalues of settings for the panel only works when applying initial settings. +// Output: Panel *newPanel, NULL if failed to create new control. +//----------------------------------------------------------------------------- +Panel *BuildGroup::NewControl( KeyValues *controlKeys, int x, int y) +{ + Assert (controlKeys); + + Panel *newPanel = NULL; + if (controlKeys) + { +// Warning( "Creating new control \"%s\" of type \"%s\"\n", controlKeys->GetString( "fieldName" ), controlKeys->GetString( "ControlName" ) ); + KeyValues *keyVal = new KeyValues("ControlFactory", "ControlName", controlKeys->GetString("ControlName")); + m_pBuildContext->RequestInfo(keyVal); + // returns NULL on failure + newPanel = (Panel *)keyVal->GetPtr("PanelPtr"); + keyVal->deleteThis(); + } + else + { + return NULL; + } + + if (newPanel) + { + // panel successfully created + newPanel->SetParent(m_pParentPanel); + newPanel->SetBuildGroup(this); + newPanel->SetPos(x, y); + + newPanel->SetName(controlKeys->GetName()); // name before applysettings :) + newPanel->ApplySettings(controlKeys); + + newPanel->AddActionSignalTarget(m_pParentPanel); + newPanel->SetBuildModeEditable(true); + newPanel->SetBuildModeDeletable(true); + + // make sure it gets freed + newPanel->SetAutoDelete(true); + } + + return newPanel; +} + +//----------------------------------------------------------------------------- +// Purpose: Get a new unique fieldname for a new control +//----------------------------------------------------------------------------- +void BuildGroup::GetNewFieldName(char *newFieldName, int newFieldNameSize, Panel *newPanel) +{ + int fieldNameNumber=1; + char defaultName[25]; + + Q_strncpy( defaultName, newPanel->GetClassName(), sizeof( defaultName ) ); + + while (1) + { + Q_snprintf (newFieldName, newFieldNameSize, "%s%d", defaultName, fieldNameNumber); + if ( FieldNameTaken(newFieldName) == NULL) + break; + ++fieldNameNumber; + } +} + +//----------------------------------------------------------------------------- +// Purpose: check to see if any buildgroup panels have this fieldname +// Input : fieldName, name to check +// Output : ptr to a panel that has the name if it is taken +//----------------------------------------------------------------------------- +Panel *BuildGroup::FieldNameTaken(const char *fieldName) +{ + for ( int i = 0; i < _panelDar.Count(); i++ ) + { + Panel *panel = _panelDar[i].Get(); + if ( !panel ) + continue; + + if (!stricmp(panel->GetName(), fieldName) ) + { + return panel; + } + } + return NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: serializes settings to a resource data container +//----------------------------------------------------------------------------- +void BuildGroup::GetSettings( KeyValues *resourceData ) +{ + // loop through all the objects getting their settings + for( int i = 0; i < _panelDar.Count(); i++ ) + { + Panel *panel = _panelDar[i].Get(); + if (!panel) + continue; + + bool isRuler = false; + // do not get setting for ruler labels. + if (_showRulers) // rulers are visible + { + for (int i = 0; i < 4; i++) + { + if (panel == _rulerNumber[i]) + { + isRuler = true; + break; + } + } + if (isRuler) + { + isRuler = false; + continue; + } + } + + // Don't save the setting of the buildmodedialog + if (!stricmp(panel->GetName(), "BuildDialog")) + continue; + + // get the keys section from the data file + if (panel->GetName() && *panel->GetName()) + { + KeyValues *datKey = resourceData->FindKey(panel->GetName(), true); + + // get the settings + panel->GetSettings(datKey); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: loop though objects in the current control group and remove them all +//----------------------------------------------------------------------------- +void BuildGroup::RemoveSettings() +{ + // loop though objects in the current control group and remove them all + int i; + for( i = 0; i < _controlGroup.Count(); i++ ) + { + // only delete delatable panels + if ( _controlGroup[i].Get()->IsBuildModeDeletable()) + { + delete _controlGroup[i].Get(); + _controlGroup.Remove(i); + --i; + } + } + + // remove deleted panels from the handle list + for( i = 0; i < _panelDar.Count(); i++ ) + { + if ( !_panelDar[i].Get() ) + { + _panelDar.Remove(i); + --i; + } + } + + _currentPanel = m_pBuildContext; + _currentPanel->InvalidateLayout(); + m_pBuildContext->Repaint(); +} + +//----------------------------------------------------------------------------- +// Purpose: sets the panel from which the build group gets all it's object creation info +//----------------------------------------------------------------------------- +void BuildGroup::SetContextPanel(Panel *contextPanel) +{ + m_pBuildContext = contextPanel; +} + +//----------------------------------------------------------------------------- +// Purpose: gets the panel from which the build group gets all it's object creation info +//----------------------------------------------------------------------------- +Panel *BuildGroup::GetContextPanel() +{ + return m_pBuildContext; +} + +//----------------------------------------------------------------------------- +// Purpose: get the list of panels in the buildgroup +//----------------------------------------------------------------------------- +CUtlVector *BuildGroup::GetPanelList() +{ + return &_panelDar; +} + +//----------------------------------------------------------------------------- +// Purpose: dialog variables +//----------------------------------------------------------------------------- +KeyValues *BuildGroup::GetDialogVariables() +{ + EditablePanel *edit = dynamic_cast(m_pParentPanel); + if (edit) + { + return edit->GetDialogVariables(); + } + + return NULL; +} -- cgit v1.2.3