diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /mp/src/vgui2/vgui_controls/WizardPanel.cpp | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/vgui2/vgui_controls/WizardPanel.cpp')
| -rw-r--r-- | mp/src/vgui2/vgui_controls/WizardPanel.cpp | 720 |
1 files changed, 720 insertions, 0 deletions
diff --git a/mp/src/vgui2/vgui_controls/WizardPanel.cpp b/mp/src/vgui2/vgui_controls/WizardPanel.cpp new file mode 100644 index 00000000..9ce5f802 --- /dev/null +++ b/mp/src/vgui2/vgui_controls/WizardPanel.cpp @@ -0,0 +1,720 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include <vgui/IVGui.h>
+#include <KeyValues.h>
+
+#include <vgui_controls/BuildGroup.h>
+#include <vgui_controls/Button.h>
+#include <vgui_controls/Controls.h>
+#include <vgui_controls/WizardPanel.h>
+#include <vgui_controls/WizardSubPanel.h>
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include <tier0/memdbgon.h>
+
+using namespace vgui;
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+WizardPanel::WizardPanel(Panel *parent, const char *panelName) : Frame(parent, panelName)
+{
+ _currentSubPanel = NULL;
+ _currentData = new KeyValues("WizardData");
+ _showButtons = true;
+
+
+ SetSizeable(false);
+
+ CreateButtons();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor
+//-----------------------------------------------------------------------------
+WizardPanel::~WizardPanel()
+{
+ if (_currentData)
+ {
+ _currentData->deleteThis();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::PerformLayout()
+{
+ BaseClass::PerformLayout();
+
+ // resize the sub panel to fit in the Client area
+ int x, y, wide, tall;
+ GetClientArea(x, y, wide, tall);
+
+ if (_currentSubPanel && _currentSubPanel->isNonWizardPanel())
+ {
+ // just have the subpanel cover the full size
+ _currentSubPanel->SetBounds(x, y, wide, tall);
+ _cancelButton->SetVisible(false);
+ _prevButton->SetVisible(false);
+ _nextButton->SetVisible(false);
+ _finishButton->SetVisible(false);
+ }
+ else
+ {
+ // make room for the buttons at bottom
+ if (_currentSubPanel)
+ {
+ if( _showButtons )
+ {
+ _currentSubPanel->SetBounds(x, y, wide, tall - 35);
+ }
+ else
+ {
+ _currentSubPanel->SetBounds(x, y, wide, tall);
+ }
+ }
+
+ // align the buttons to the right hand side
+ GetSize(wide, tall);
+
+
+ int bwide, btall;
+ _cancelButton->GetSize(bwide, btall);
+
+ x = wide - (20 + bwide);
+ y = tall - (12 + btall);
+
+ _cancelButton->SetPos(x, y);
+ x -= (20 + bwide);
+
+ // only display one of the next or finish buttons (and only if both are visible)
+ if ( _showButtons )
+ {
+ if (_finishButton->IsEnabled() )
+ {
+ _nextButton->SetVisible(false);
+ _finishButton->SetVisible(true);
+ _finishButton->SetPos(x, y);
+ }
+ else
+ {
+ _nextButton->SetVisible(true);
+ _finishButton->SetVisible(false);
+ _nextButton->SetPos(x, y);
+ }
+ }
+
+ x -= (1 + bwide);
+ _prevButton->SetPos(x, y);
+
+ ResetDefaultButton();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: if we don't show buttons then let the sub panel occupy the whole screen
+//-----------------------------------------------------------------------------
+void WizardPanel::GetClientArea(int &x, int &y, int &wide, int &tall)
+{
+ if( _showButtons )
+ {
+ BaseClass::GetClientArea( x, y, wide, tall );
+ }
+ else
+ {
+ x = 0;
+ y = 0;
+ GetSize( wide, tall );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::ApplySchemeSettings(IScheme *pScheme)
+{
+ BaseClass::ApplySchemeSettings(pScheme);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::Run(WizardSubPanel *startPanel)
+{
+ // skip over sub panels if they don't want to be displayed
+ startPanel = FindNextValidSubPanel(startPanel);
+
+ // show it
+ ActivateNextSubPanel(startPanel);
+
+ // make sure we're set up and Run the first panel
+ Activate();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::ActivateBuildMode()
+{
+ // no subpanel, no build mode
+ if (!_currentSubPanel)
+ return;
+
+ _currentSubPanel->ActivateBuildMode();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::ResetDefaultButton()
+{
+ // work out which is the default button
+ if (_nextButton->IsEnabled())
+ {
+ _nextButton->SetAsDefaultButton(true);
+ }
+ else if (_finishButton->IsEnabled())
+ {
+ _finishButton->SetAsDefaultButton(true);
+ }
+ else if (_prevButton->IsEnabled())
+ {
+ _prevButton->SetAsDefaultButton(true);
+ }
+ /* Don't ever set the cancel button as the default, as it is too easy for users to quit the wizard without realizing
+ else if (_cancelButton->IsEnabled())
+ {
+ _cancelButton->SetAsDefaultButton(true);
+ }
+ */
+
+ // reset them all (this may not be necessary)
+ _nextButton->InvalidateLayout();
+ _prevButton->InvalidateLayout();
+ _cancelButton->InvalidateLayout();
+ _finishButton->InvalidateLayout();
+
+ Repaint();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::ResetKeyFocus()
+{
+ // set the focus on the default
+ FocusNavGroup &navGroup = GetFocusNavGroup();
+ Panel *def = navGroup.GetDefaultPanel();
+ if (def)
+ {
+ if (def->IsEnabled() && def->IsVisible())
+ {
+ def->RequestFocus();
+ }
+ else
+ {
+ def->RequestFocusNext();
+ }
+ }
+
+ ResetDefaultButton();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::CreateButtons()
+{
+ _prevButton = new Button(this, "PrevButton", "");
+ _nextButton = new Button(this, "NextButton", "");
+ _cancelButton = new Button(this, "CancelButton", "");
+ _finishButton = new Button(this, "FinishButton", "");
+
+ _prevButton->SetCommand(new KeyValues("PrevButton"));
+ _nextButton->SetCommand(new KeyValues("NextButton"));
+ _cancelButton->SetCommand(new KeyValues("CancelButton"));
+ _finishButton->SetCommand(new KeyValues("FinishButton"));
+
+ SetNextButtonText(NULL);
+ SetPrevButtonText(NULL);
+ SetFinishButtonText(NULL);
+ SetCancelButtonText(NULL);
+
+ _prevButton->SetSize(82, 24);
+ _nextButton->SetSize(82, 24);
+ _cancelButton->SetSize(82, 24);
+ _finishButton->SetSize(82, 24);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: clears all previous history
+//-----------------------------------------------------------------------------
+void WizardPanel::ResetHistory()
+{
+ _subPanelStack.RemoveAll();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::ActivateNextSubPanel(WizardSubPanel *subPanel)
+{
+ // get rid of previous panel
+ WizardSubPanel *prevPanel = _currentSubPanel;
+ if (prevPanel && prevPanel->ShouldDisplayPanel())
+ {
+ // hide
+ prevPanel->SetVisible(false);
+
+ // push onto history stack
+ _subPanelStack.AddElement(_currentSubPanel);
+ }
+
+ // reenable all buttons, returning them to their default state
+ _prevButton->SetEnabled(true);
+ _nextButton->SetEnabled(true);
+ _cancelButton->SetEnabled(true);
+ _finishButton->SetEnabled(true);
+ if ( _showButtons )
+ {
+ _prevButton->SetVisible(true);
+ _cancelButton->SetVisible(true);
+ }
+
+ // set up new subpanel
+ _currentSubPanel = subPanel;
+ _currentSubPanel->SetParent(this);
+ _currentSubPanel->SetVisible(true);
+
+ _currentSubPanel->SetWizardPanel(this);
+ _currentSubPanel->OnDisplayAsNext();
+ _currentSubPanel->OnDisplay();
+ _currentSubPanel->InvalidateLayout(false);
+
+ SETUP_PANEL( _currentSubPanel );
+ int wide, tall;
+ if ( _currentSubPanel->GetDesiredSize(wide, tall) )
+ {
+ SetSize(wide, tall);
+ }
+
+ if (!prevPanel)
+ {
+ // no previous panel, so disable the back button
+ _prevButton->SetEnabled(false);
+ }
+
+ _currentSubPanel->RequestFocus();
+
+ RecalculateTabOrdering();
+ InvalidateLayout(false);
+ Repaint();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Pops the last panel off the stack and runs it
+//-----------------------------------------------------------------------------
+void WizardPanel::ActivatePrevSubPanel()
+{
+ _currentSubPanel->SetVisible(false);
+
+ WizardSubPanel *prevPanel = NULL;
+ if (_subPanelStack.GetCount())
+ {
+ // check to see if we need to jump back to a previous sub panel
+ WizardSubPanel *searchPanel = _currentSubPanel->GetPrevSubPanel();
+ if (searchPanel && _subPanelStack.HasElement(searchPanel))
+ {
+ // keep poping the stack till we find it
+ while (_subPanelStack.GetCount() && prevPanel != searchPanel)
+ {
+ prevPanel = _subPanelStack[_subPanelStack.GetCount() - 1];
+ _subPanelStack.RemoveElementAt(_subPanelStack.GetCount() - 1);
+ }
+ }
+ else
+ {
+ // just get the last one
+ prevPanel = _subPanelStack[_subPanelStack.GetCount() - 1];
+ _subPanelStack.RemoveElementAt(_subPanelStack.GetCount() - 1);
+ }
+ }
+
+ if (!prevPanel)
+ {
+ ivgui()->DPrintf2("Error: WizardPanel::ActivatePrevSubPanel(): no previous panel to go back to\n");
+ return;
+ }
+
+ // hide old panel
+ _currentSubPanel->SetVisible(false);
+
+ // reenable all buttons, returning them to their default state
+ _prevButton->SetEnabled(true);
+ _nextButton->SetEnabled(true);
+ _cancelButton->SetEnabled(true);
+ _finishButton->SetEnabled(true);
+
+ // Activate new panel
+ _currentSubPanel = prevPanel;
+ _currentSubPanel->RequestFocus();
+ _currentSubPanel->SetWizardPanel(this);
+ _currentSubPanel->OnDisplayAsPrev();
+ _currentSubPanel->OnDisplay();
+ _currentSubPanel->InvalidateLayout(false);
+
+ SETUP_PANEL( _currentSubPanel );
+ int wide, tall;
+ if ( _currentSubPanel->GetDesiredSize(wide, tall) )
+ {
+ SetSize(wide, tall);
+ }
+
+ // show the previous panel, but don't Activate it (since it should show just what it was previously)
+ _currentSubPanel->SetVisible(true);
+
+ if (!_subPanelStack.GetCount())
+ {
+ // no previous panel, so disable the back button
+ _prevButton->SetEnabled(false);
+ }
+
+ RecalculateTabOrdering();
+ InvalidateLayout(false);
+ Repaint();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets up the new tab ordering
+//-----------------------------------------------------------------------------
+void WizardPanel::RecalculateTabOrdering()
+{
+ if (_currentSubPanel)
+ {
+ _currentSubPanel->SetTabPosition(1);
+ }
+ _prevButton->SetTabPosition(2);
+ _nextButton->SetTabPosition(3);
+ _finishButton->SetTabPosition(4);
+ _cancelButton->SetTabPosition(5);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::SetNextButtonEnabled(bool state)
+{
+ if (_nextButton->IsEnabled() != state)
+ {
+ _nextButton->SetEnabled(state);
+ InvalidateLayout(false);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::SetPrevButtonEnabled(bool state)
+{
+ if (_prevButton->IsEnabled() != state)
+ {
+ _prevButton->SetEnabled(state);
+ InvalidateLayout(false);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::SetFinishButtonEnabled(bool state)
+{
+ if (_finishButton->IsEnabled() != state)
+ {
+ _finishButton->SetEnabled(state);
+ InvalidateLayout(false);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::SetCancelButtonEnabled(bool state)
+{
+ if (_cancelButton->IsEnabled() != state)
+ {
+ _cancelButton->SetEnabled(state);
+ InvalidateLayout(false);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::SetNextButtonVisible(bool state)
+{
+ _nextButton->SetVisible(state);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::SetPrevButtonVisible(bool state)
+{
+ _prevButton->SetVisible(state);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::SetFinishButtonVisible(bool state)
+{
+ _finishButton->SetVisible(state);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::SetCancelButtonVisible(bool state)
+{
+ _cancelButton->SetVisible(state);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::SetNextButtonText(const char *text)
+{
+ if (text)
+ {
+ _nextButton->SetText(text);
+ }
+ else
+ {
+ _nextButton->SetText("#WizardPanel_Next");
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::SetPrevButtonText(const char *text)
+{
+ if (text)
+ {
+ _prevButton->SetText(text);
+ }
+ else
+ {
+ _prevButton->SetText("#WizardPanel_Back");
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::SetFinishButtonText(const char *text)
+{
+ if (text)
+ {
+ _finishButton->SetText(text);
+ }
+ else
+ {
+ _finishButton->SetText("#WizardPanel_Finish");
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::SetCancelButtonText(const char *text)
+{
+ if (text)
+ {
+ _cancelButton->SetText(text);
+ }
+ else
+ {
+ _cancelButton->SetText("#WizardPanel_Cancel");
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Finds the next panel that wants to be shown
+//-----------------------------------------------------------------------------
+WizardSubPanel *WizardPanel::FindNextValidSubPanel(WizardSubPanel *currentPanel)
+{
+ // skip over sub panels if they don't want to be displayed
+ while (currentPanel)
+ {
+ currentPanel->SetWizardPanel(this);
+ if (currentPanel->ShouldDisplayPanel())
+ break;
+
+ // ok the panel wants to be skipped, so skip ahead
+ currentPanel = currentPanel->GetNextSubPanel();
+ }
+
+ return currentPanel;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Advances to the next panel
+//-----------------------------------------------------------------------------
+void WizardPanel::OnNextButton()
+{
+ if (_currentSubPanel)
+ {
+ bool shouldAdvance = _currentSubPanel->OnNextButton();
+ if (shouldAdvance)
+ {
+ WizardSubPanel *nextPanel = FindNextValidSubPanel(_currentSubPanel->GetNextSubPanel());
+
+ if (nextPanel)
+ {
+ KeyValues *kv = new KeyValues("ActivateNextSubPanel");
+ kv->SetPtr("panel", nextPanel);
+ ivgui()->PostMessage(GetVPanel(), kv, GetVPanel());
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Retreats to the previous panel
+//-----------------------------------------------------------------------------
+void WizardPanel::OnPrevButton()
+{
+ bool shouldRetreat = true;
+ if (_currentSubPanel)
+ {
+ shouldRetreat = _currentSubPanel->OnPrevButton();
+ }
+
+ if (shouldRetreat)
+ {
+ ActivatePrevSubPanel();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::OnFinishButton()
+{
+ if (_currentSubPanel && _currentSubPanel->OnFinishButton())
+ {
+ // hide ourselves away
+ BaseClass::OnClose();
+
+ // automatically delete ourselves if marked to do so
+ if (IsAutoDeleteSet())
+ {
+ MarkForDeletion();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void WizardPanel::OnCancelButton()
+{
+ if (_currentSubPanel && _currentSubPanel->OnCancelButton())
+ {
+ // hide ourselves away
+ BaseClass::OnClose();
+ if (IsAutoDeleteSet())
+ {
+ MarkForDeletion();
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: command handler for catching escape key presses
+//-----------------------------------------------------------------------------
+void WizardPanel::OnCommand(const char *command)
+{
+ if (!stricmp(command, "Cancel"))
+ {
+ if (_cancelButton->IsEnabled())
+ {
+ _cancelButton->DoClick();
+ }
+ }
+ else
+ {
+ BaseClass::OnCommand(command);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Maps close button to cancel button
+//-----------------------------------------------------------------------------
+void WizardPanel::OnClose()
+{
+ if (_cancelButton->IsEnabled())
+ {
+ _cancelButton->DoClick();
+ }
+ else if (_finishButton->IsEnabled())
+ {
+ _finishButton->DoClick();
+ }
+
+ // don't chain back
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+KeyValues *WizardPanel::GetWizardData()
+{
+ return _currentData;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: whether to show the next,prev,finish and cancel buttons
+//-----------------------------------------------------------------------------
+void WizardPanel::ShowButtons(bool state)
+{
+ _showButtons = state; // hide the wizard panel buttons
+ SetNextButtonVisible( state );
+ SetPrevButtonVisible( state );
+ SetFinishButtonVisible( state );
+ SetCancelButtonVisible( state );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: filters close buttons
+//-----------------------------------------------------------------------------
+void WizardPanel::OnCloseFrameButtonPressed()
+{
+ // only allow close if the cancel button is enabled
+ if (_cancelButton->IsEnabled())
+ {
+ BaseClass::OnCloseFrameButtonPressed();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns a page by name
+//-----------------------------------------------------------------------------
+WizardSubPanel *WizardPanel::GetSubPanelByName(const char *pageName)
+{
+ return dynamic_cast<WizardSubPanel *>(FindChildByName(pageName));
+}
|