diff options
Diffstat (limited to 'game/server/NavUI')
| -rw-r--r-- | game/server/NavUI/AttributeTool.cpp | 25 | ||||
| -rw-r--r-- | game/server/NavUI/AttributeTool.h | 23 | ||||
| -rw-r--r-- | game/server/NavUI/MeshTool.cpp | 25 | ||||
| -rw-r--r-- | game/server/NavUI/MeshTool.h | 24 | ||||
| -rw-r--r-- | game/server/NavUI/NavMenu.cpp | 48 | ||||
| -rw-r--r-- | game/server/NavUI/NavMenu.h | 30 | ||||
| -rw-r--r-- | game/server/NavUI/NavUI.cpp | 892 | ||||
| -rw-r--r-- | game/server/NavUI/NavUI.h | 220 | ||||
| -rw-r--r-- | game/server/NavUI/SelectionTool.cpp | 242 | ||||
| -rw-r--r-- | game/server/NavUI/SelectionTool.h | 48 |
10 files changed, 1577 insertions, 0 deletions
diff --git a/game/server/NavUI/AttributeTool.cpp b/game/server/NavUI/AttributeTool.cpp new file mode 100644 index 0000000..fecf251 --- /dev/null +++ b/game/server/NavUI/AttributeTool.cpp @@ -0,0 +1,25 @@ +//-------------------------------------------------------------------------------------------------------- +//========= Copyright Valve Corporation, All rights reserved. ============// + +#include "cbase.h" + +#include "AttributeTool.h" +#include "nav_mesh.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifdef SERVER_USES_VGUI + +using namespace vgui; + + +//-------------------------------------------------------------------------------------------------------- +AttributeToolPanel::AttributeToolPanel( vgui::Panel *parent, const char *toolName ) : CNavUIToolPanel( parent, toolName ) +{ + LoadControlSettings( "Resource/UI/NavTools/AttributeTool.res" ); +} + +#endif // SERVER_USES_VGUI + +//-------------------------------------------------------------------------------------------------------- diff --git a/game/server/NavUI/AttributeTool.h b/game/server/NavUI/AttributeTool.h new file mode 100644 index 0000000..c501fd8 --- /dev/null +++ b/game/server/NavUI/AttributeTool.h @@ -0,0 +1,23 @@ +//-------------------------------------------------------------------------------------------------------- +//========= Copyright Valve Corporation, All rights reserved. ============// + +#ifndef ATTRIBUTETOOL_H +#define ATTRIBUTETOOL_H + +#include "NavUI.h" +#include "nav.h" + +#ifdef SERVER_USES_VGUI + +//-------------------------------------------------------------------------------------------------------- +class AttributeToolPanel : public CNavUIToolPanel +{ + DECLARE_CLASS_SIMPLE( AttributeToolPanel, CNavUIToolPanel ); + +public: + AttributeToolPanel( vgui::Panel *parent, const char *toolName ); +}; + +#endif // SERVER_USES_VGUI + +#endif // ATTRIBUTETOOL_H diff --git a/game/server/NavUI/MeshTool.cpp b/game/server/NavUI/MeshTool.cpp new file mode 100644 index 0000000..0deea08 --- /dev/null +++ b/game/server/NavUI/MeshTool.cpp @@ -0,0 +1,25 @@ +//-------------------------------------------------------------------------------------------------------- +//========= Copyright Valve Corporation, All rights reserved. ============// + +#include "cbase.h" + +#include "MeshTool.h" +#include "nav_mesh.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifdef SERVER_USES_VGUI + +using namespace vgui; + + +//-------------------------------------------------------------------------------------------------------- +MeshToolPanel::MeshToolPanel( vgui::Panel *parent, const char *toolName ) : CNavUIToolPanel( parent, toolName ) +{ + LoadControlSettings( "Resource/UI/NavTools/MeshTool.res" ); +} + +#endif // SERVER_USES_VGUI + +//-------------------------------------------------------------------------------------------------------- diff --git a/game/server/NavUI/MeshTool.h b/game/server/NavUI/MeshTool.h new file mode 100644 index 0000000..7693b1a --- /dev/null +++ b/game/server/NavUI/MeshTool.h @@ -0,0 +1,24 @@ +//-------------------------------------------------------------------------------------------------------- +//========= Copyright Valve Corporation, All rights reserved. ============// + +#ifndef MESHTOOL_H +#define MESHTOOL_H + +#ifdef SERVER_USES_VGUI + +#include "NavUI.h" +#include "nav.h" + + +//-------------------------------------------------------------------------------------------------------- +class MeshToolPanel : public CNavUIToolPanel +{ + DECLARE_CLASS_SIMPLE( MeshToolPanel, CNavUIToolPanel ); + +public: + MeshToolPanel( vgui::Panel *parent, const char *toolName ); +}; + +#endif // SERVER_USES_VGUI + +#endif // MESHTOOL_H diff --git a/game/server/NavUI/NavMenu.cpp b/game/server/NavUI/NavMenu.cpp new file mode 100644 index 0000000..aafae32 --- /dev/null +++ b/game/server/NavUI/NavMenu.cpp @@ -0,0 +1,48 @@ +//-------------------------------------------------------------------------------------------------------- +//========= Copyright Valve Corporation, All rights reserved. ============// + +#include "cbase.h" + +#ifdef SERVER_USES_VGUI +#include <filesystem.h> +#include "NavMenu.h" +#include "vgui_controls/MenuItem.h" +#endif // SERVER_USES_VGUI + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifdef SERVER_USES_VGUI + +using namespace vgui; + + +//-------------------------------------------------------------------------------------------------------- +NavMenu::NavMenu( Panel *parent, const char *panelName ) : Menu( parent, panelName ) +{ +} + + +//-------------------------------------------------------------------------------------------------------- +bool NavMenu::LoadFromFile( const char * fileName) // load menu from KeyValues +{ + KeyValues * kv = new KeyValues(fileName); + + if ( !kv->LoadFromFile( filesystem, fileName, "GAME" ) ) + return false; + + bool ret = false;//LoadFromKeyValues( kv ); + + kv->deleteThis(); + return ret; +} + + +//-------------------------------------------------------------------------------------------------------- +NavMenu::~NavMenu() +{ +} + +#endif // SERVER_USES_VGUI + +//-------------------------------------------------------------------------------------------------------- diff --git a/game/server/NavUI/NavMenu.h b/game/server/NavUI/NavMenu.h new file mode 100644 index 0000000..e9e1597 --- /dev/null +++ b/game/server/NavUI/NavMenu.h @@ -0,0 +1,30 @@ +//-------------------------------------------------------------------------------------------------------- +//========= Copyright Valve Corporation, All rights reserved. ============// + +#ifndef NAV_MENU_H +#define NAV_MENU_H + +#ifdef SERVER_USES_VGUI + +#include <vgui_controls/Menu.h> +#include <game/client/iviewport.h> +#include <filesystem.h> +#include "utlstack.h" +#include "utlvector.h" +#include <KeyValues.h> + +class NavMenu : public vgui::Menu +{ +private: + DECLARE_CLASS_SIMPLE( NavMenu, vgui::Menu ); + +public: + NavMenu( vgui::Panel *parent, const char *panelName ); + ~NavMenu(); + + bool LoadFromFile( const char * fileName ); // load menu from file (via KeyValues) +}; + +#endif // SERVER_USES_VGUI + +#endif // NAV_MENU_H diff --git a/game/server/NavUI/NavUI.cpp b/game/server/NavUI/NavUI.cpp new file mode 100644 index 0000000..ce93f12 --- /dev/null +++ b/game/server/NavUI/NavUI.cpp @@ -0,0 +1,892 @@ +//-------------------------------------------------------------------------------------------------------- +//========= Copyright Valve Corporation, All rights reserved. ============// + +#include "cbase.h" + +#ifdef SERVER_USES_VGUI + +#include "NavUI.h" +#include "filesystem.h" +#include "tier0/icommandline.h" +#include "vgui_gamedll_int.h" +#include "ienginevgui.h" +#include "IGameUIFuncs.h" +#include "fmtstr.h" +#include "NavMenu.h" +#include <vgui_controls/MenuButton.h> + +#include "SelectionTool.h" +#include "MeshTool.h" +#include "AttributeTool.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +using namespace vgui; +class CNavUIBasePanel; +class CNavUIToolPanel; + +extern IGameUIFuncs *gameuifuncs; + + +//-------------------------------------------------------------------------------------------------------- +static CNavUIBasePanel *s_navUIPanel = NULL; +CNavUIBasePanel *TheNavUI( void ) +{ + return s_navUIPanel; +} + + +//-------------------------------------------------------------------------------------------------------- +ConVar NavGUIRebuild( "nav_gui_rebuild", "0", FCVAR_CHEAT, "Rebuilds the nav ui windows from scratch every time they're opened" ); + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIButton::LookupKey( void ) +{ + if ( m_hideKey == BUTTON_CODE_INVALID ) + m_hideKey = (gameuifuncs) ? gameuifuncs->GetButtonCodeForBind( "nav_gui" ) : BUTTON_CODE_INVALID; +} + + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIButton::OnKeyCodePressed( KeyCode code ) +{ + LookupKey(); + + if ( code == m_hideKey ) + { + m_hidePressedTimer.Start(); + return; + } + + BaseClass::OnKeyCodePressed( code ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIButton::OnKeyCodeReleased( KeyCode code ) +{ + LookupKey(); + + if ( code == m_hideKey ) + { + if ( m_hidePressedTimer.HasStarted() && m_hidePressedTimer.GetElapsedTime() < 0.5f ) + { + s_navUIPanel->ToggleVisibility(); + m_hidePressedTimer.Invalidate(); + } + return; + } + + BaseClass::OnKeyCodeReleased( code ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUITextEntry::LookupKey( void ) +{ + if ( m_hideKey == BUTTON_CODE_INVALID ) + m_hideKey = (gameuifuncs) ? gameuifuncs->GetButtonCodeForBind( "nav_gui" ) : BUTTON_CODE_INVALID; +} + + + +//-------------------------------------------------------------------------------------------------------- +void CNavUITextEntry::OnKeyCodePressed( KeyCode code ) +{ + LookupKey(); + + if ( code == m_hideKey ) + { + m_hidePressedTimer.Start(); + return; + } + + BaseClass::OnKeyCodePressed( code ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUITextEntry::OnKeyCodeReleased( KeyCode code ) +{ + LookupKey(); + + if ( code == m_hideKey ) + { + if ( m_hidePressedTimer.HasStarted() && m_hidePressedTimer.GetElapsedTime() < 0.5f ) + { + s_navUIPanel->ToggleVisibility(); + m_hidePressedTimer.Invalidate(); + } + return; + } + + BaseClass::OnKeyCodeReleased( code ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIComboBox::LookupKey( void ) +{ + if ( m_hideKey == BUTTON_CODE_INVALID ) + m_hideKey = (gameuifuncs) ? gameuifuncs->GetButtonCodeForBind( "nav_gui" ) : BUTTON_CODE_INVALID; +} + + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIComboBox::OnKeyCodePressed( KeyCode code ) +{ + LookupKey(); + + if ( code == m_hideKey ) + { + m_hidePressedTimer.Start(); + return; + } + + BaseClass::OnKeyCodePressed( code ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIComboBox::OnKeyCodeReleased( KeyCode code ) +{ + LookupKey(); + + if ( code == m_hideKey ) + { + if ( m_hidePressedTimer.HasStarted() && m_hidePressedTimer.GetElapsedTime() < 0.5f ) + { + s_navUIPanel->ToggleVisibility(); + m_hidePressedTimer.Invalidate(); + } + return; + } + + BaseClass::OnKeyCodeReleased( code ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUICheckButton::LookupKey( void ) +{ + if ( m_hideKey == BUTTON_CODE_INVALID ) + m_hideKey = (gameuifuncs) ? gameuifuncs->GetButtonCodeForBind( "nav_gui" ) : BUTTON_CODE_INVALID; +} + + + +//-------------------------------------------------------------------------------------------------------- +void CNavUICheckButton::OnKeyCodePressed( KeyCode code ) +{ + LookupKey(); + + if ( code == m_hideKey ) + { + m_hidePressedTimer.Start(); + return; + } + + BaseClass::OnKeyCodePressed( code ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUICheckButton::OnKeyCodeReleased( KeyCode code ) +{ + LookupKey(); + + if ( code == m_hideKey ) + { + if ( m_hidePressedTimer.HasStarted() && m_hidePressedTimer.GetElapsedTime() < 0.5f ) + { + s_navUIPanel->ToggleVisibility(); + m_hidePressedTimer.Invalidate(); + } + return; + } + + BaseClass::OnKeyCodeReleased( code ); +} + + +//-------------------------------------------------------------------------------------------------------- +CNavUIBasePanel::CNavUIBasePanel() : vgui::Frame( NULL, "NavUI" ) +{ + m_hideKey = BUTTON_CODE_INVALID; + SetScheme( "SourceScheme" ); + LoadControlSettings( "Resource/UI/NavUI.res" ); + SetAlpha( 0 ); + SetMouseInputEnabled( false ); + SetSizeable( false ); + SetMoveable( false ); + SetCloseButtonVisible( false ); + SetTitleBarVisible( false ); + + SetLeftClickAction( "", "" ); + + m_hidden = false; + m_toolPanel = NULL; + m_selectionPanel = NULL; + + SetTitle( "", true); + + m_dragSelecting = m_dragUnselecting = false; + + MenuButton *menuButton = dynamic_cast< MenuButton * >(FindChildByName( "FileMenuButton" )); + if ( menuButton ) + { + NavMenu * menu = new NavMenu( menuButton, "NavFileMenu" ); + menu->AddMenuItem( "Quit", "Quit", new KeyValues( "Command", "command", "StopEditing" ), this ); + menuButton->SetMenu( menu ); + menuButton->SetOpenDirection( Menu::DOWN ); + } + + menuButton = dynamic_cast< MenuButton * >(FindChildByName( "SelectionMenuButton" )); + if ( menuButton ) + { + NavMenu * menu = new NavMenu( menuButton, "NavSelectionMenu" ); + menu->AddMenuItem( "Flood Select", "Flood Select", new KeyValues( "Command", "command", "FloodSelect" ), this ); + menu->AddMenuItem( "Flood Select (fog)", "Flood Select (Fog)", new KeyValues( "Command", "command", "FloodSelect fog" ), this ); + menuButton->SetMenu( menu ); + menuButton->SetOpenDirection( Menu::DOWN ); + } +} + + +//-------------------------------------------------------------------------------------------------------- +CNavUIBasePanel::~CNavUIBasePanel() +{ + s_navUIPanel = NULL; +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::SetLeftClickAction( const char *action, const char *text ) +{ + if ( !action || !*action ) + { + action = "Selection::Select"; + } + + if ( !text || !*text ) + { + text = "Select"; + } + + V_strncpy( m_leftClickAction, action, sizeof( m_leftClickAction ) ); + m_performingLeftClickAction = false; + + vgui::Label *label = dynamic_cast< vgui::Label * >(FindChildByName( "LeftClick" ) ); + if ( label ) + { + label->SetText( UTIL_VarArgs( "Left Click: %s", text ) ); + } +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::ApplySchemeSettings( IScheme *pScheme ) +{ + BaseClass::ApplySchemeSettings( pScheme ); + SetBgColor( Color( 0, 0, 0, 0 ) ); + + Panel *panel = FindChildByName( "SidebarParent" ); + if ( panel ) + { + panel->SetBgColor( Color( 128, 128, 128, 255 ) ); + panel->SetPaintBackgroundType( 2 ); + } + + panel = FindChildByName( "MenuParent" ); + if ( panel ) + { + panel->SetBgColor( Color( 128, 128, 128, 255 ) ); + panel->SetPaintBackgroundType( 0 ); + } + + panel = FindChildByName( "ToolParent" ); + if ( panel ) + { + panel->SetBgColor( Color( 0, 0, 0, 128 ) ); + panel->SetPaintBackgroundType( 0 ); + } + + panel = FindChildByName( "SelectionParent" ); + if ( panel ) + { + panel->SetBgColor( Color( 0, 0, 0, 128 ) ); + panel->SetPaintBackgroundType( 0 ); + } + + panel = FindChildByName( "MouseFeedbackParent" ); + if ( panel ) + { + panel->SetBgColor( Color( 0, 0, 0, 128 ) ); + panel->SetPaintBackgroundType( 0 ); + } +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::PerformLayout( void ) +{ + int wide, tall; + vgui::surface()->GetScreenSize( wide, tall ); + SetBounds( 0, 0, wide, tall ); + + Panel *panel = FindChildByName( "MenuParent" ); + if ( panel ) + { + int oldWide, oldTall; + panel->GetSize( oldWide, oldTall ); + panel->SetSize( wide, oldTall ); + } + + BaseClass::PerformLayout(); +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::PaintBackground( void ) +{ + BaseClass::PaintBackground(); +} + + +//-------------------------------------------------------------------------------------------------------- +const char *CNavUIBasePanel::ActiveToolName( void ) const +{ + if ( m_toolPanel ) + return m_toolPanel->GetName(); + + return ""; +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::ActivateTool( const char *toolName ) +{ + if ( m_toolPanel && FStrEq( m_toolPanel->GetName(), toolName ) ) + { + m_toolPanel->Shutdown(); + m_toolPanel->MarkForDeletion(); + m_toolPanel = NULL; + } + else + { + if ( m_toolPanel ) + { + m_toolPanel->Shutdown(); + m_toolPanel->MarkForDeletion(); + m_toolPanel = NULL; + } + + Panel *toolParent = FindChildByName( "ToolParent" ); + if ( !toolParent ) + toolParent = this; + + m_toolPanel = CreateTool( toolName, toolParent ); + if ( m_toolPanel ) + { + m_toolPanel->Init(); + m_toolPanel->SetVisible( true ); + } + } +} + + +//-------------------------------------------------------------------------------------------------------- +CNavUIToolPanel *CNavUIBasePanel::CreateTool( const char *toolName, vgui::Panel *toolParent ) +{ + if ( FStrEq( toolName, "Selection" ) ) + { + return new SelectionToolPanel( toolParent, toolName ); + } + if ( FStrEq( toolName, "Mesh" ) ) + { + return new MeshToolPanel( toolParent, toolName ); + } + if ( FStrEq( toolName, "Attribute" ) ) + { + return new AttributeToolPanel( toolParent, toolName ); + } + return NULL; +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::OnCommand( const char *command ) +{ + CSplitString argv( command, " " ); + + if ( FStrEq( "Close", command ) ) + { + ToggleVisibility(); + } + else if ( FStrEq( "MeshTool", command ) ) + { + ActivateTool( "Mesh" ); + return; + } + else if ( FStrEq( "AttributesTool", command ) ) + { + ActivateTool( "Attribute" ); + return; + } + else if ( FStrEq( "StopEditing", command ) ) + { + MarkForDeletion(); + engine->ServerCommand( "nav_edit 0\n" ); + } + else + { + BaseClass::OnCommand( command ); + } + + // argv can't delete individual elements +} + + +//-------------------------------------------------------------------------------------------------------- +// GameUI panels are always visible by default, so here we hide ourselves if the GameUI is up. +void CNavUIBasePanel::OnTick( void ) +{ + CBasePlayer *player = UTIL_GetListenServerHost(); + if ( !player || !player->IsConnected() ) + { + m_hidden = true; + SetVisible( false ); + vgui::ivgui()->RemoveTickSignal( GetVPanel() ); + return; + } + + if ( enginevgui->IsGameUIVisible() ) + { + if ( GetAlpha() != 0 ) + { + SetAlpha( 0 ); + SetMouseInputEnabled( false ); + } + } + else + { + if ( m_hidden ) + { + if ( GetAlpha() > 0 ) + { + SetAlpha( 0 ); + SetMouseInputEnabled( false ); + } + + SetVisible( false ); + vgui::ivgui()->RemoveTickSignal( GetVPanel() ); + return; + } + else + { + if ( GetAlpha() < 255 ) + { + SetAlpha( 255 ); + SetMouseInputEnabled( true ); + + if ( !m_selectionPanel ) + { + Panel *selectionParent = FindChildByName( "SelectionParent" ); + if ( !selectionParent ) + selectionParent = this; + + m_selectionPanel = CreateTool( "Selection", selectionParent ); + if ( m_selectionPanel ) + { + m_selectionPanel->Init(); + m_selectionPanel->SetVisible( true ); + } + } + } + + CFmtStr str; + if ( m_toolPanel ) + { + str.sprintf( "%s - %s", STRING( gpGlobals->mapname ), m_toolPanel->GetName() ); + } + else + { + str.sprintf( "%s", STRING( gpGlobals->mapname ) ); + } + SetTitle( str.Access(), true ); + } + } +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::ToggleVisibility( void ) +{ + m_hidden = !m_hidden; + + if ( m_hidden && NavGUIRebuild.GetBool() ) + { + MarkForDeletion(); + s_navUIPanel = NULL; + } +} + + +//-------------------------------------------------------------------------------------------------------- +Panel *CNavUIBasePanel::CreateControlByName( const char *controlName ) +{ + if ( FStrEq( controlName, "Button" ) ) + { + return new CNavUIButton( this, "CNavUIButton" ); + } + + if ( FStrEq( controlName, "TextEntry" ) ) + { + return new CNavUITextEntry( this, "CNavUITextEntry" ); + } + + if ( FStrEq( controlName, "ComboBox" ) ) + { + return new CNavUIComboBox( this, "CNavUIComboBox", 5, false ); + } + + if ( FStrEq( controlName, "CheckButton" ) ) + { + return new CNavUICheckButton( this, "CNavUICheckButton", "" ); + } + + return BaseClass::CreateControlByName( controlName ); +} + + +//-------------------------------------------------------------------------------------------------------- +Panel *CNavUIToolPanel::CreateControlByName( const char *controlName ) +{ + if ( s_navUIPanel ) + { + return s_navUIPanel->CreateControlByName( controlName ); + } + + return BaseClass::CreateControlByName( controlName ); +} + + +//-------------------------------------------------------------------------------------------------------- +bool CNavUIToolPanel::IsCheckButtonChecked( const char *name ) +{ + vgui::CheckButton *checkButton = dynamic_cast< vgui::CheckButton * >( FindChildByName( name, true ) ); + if ( !checkButton ) + return false; + + return checkButton->IsSelected(); +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::LookupKey( void ) +{ + if ( m_hideKey == BUTTON_CODE_INVALID ) + m_hideKey = (gameuifuncs) ? gameuifuncs->GetButtonCodeForBind( "nav_gui" ) : BUTTON_CODE_INVALID; +} + + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::OnKeyCodePressed( KeyCode code ) +{ + LookupKey(); + + if ( code == m_hideKey ) + { + m_hidePressedTimer.Start(); + return; + } + + BaseClass::OnKeyCodePressed( code ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::OnKeyCodeReleased( KeyCode code ) +{ + LookupKey(); + + if ( code == m_hideKey ) + { + if ( m_hidePressedTimer.HasStarted() && m_hidePressedTimer.GetElapsedTime() < 0.5f ) + { + s_navUIPanel->ToggleVisibility(); + m_hidePressedTimer.Invalidate(); + } + return; + } + + BaseClass::OnKeyCodeReleased( code ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::OnCursorEntered( void ) +{ + BaseClass::OnCursorEntered(); + + if ( m_performingLeftClickAction ) + { + if ( m_toolPanel ) + { + m_toolPanel->FinishLeftClickAction( m_leftClickAction ); + } + if ( m_selectionPanel ) + { + m_selectionPanel->FinishLeftClickAction( m_leftClickAction ); + } + m_performingLeftClickAction = false; + } +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::OnCursorMoved( int x, int y ) +{ + if ( m_toolPanel ) + { + m_toolPanel->OnCursorMoved( x, y ); + } + if ( m_selectionPanel ) + { + m_selectionPanel->OnCursorMoved( x, y ); + } + + BaseClass::OnCursorMoved( x, y ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::OnCursorExited( void ) +{ + BaseClass::OnCursorExited(); + + if ( m_performingLeftClickAction ) + { + if ( m_toolPanel ) + { + m_toolPanel->FinishLeftClickAction( m_leftClickAction ); + } + if ( m_selectionPanel ) + { + m_selectionPanel->FinishLeftClickAction( m_leftClickAction ); + } + m_performingLeftClickAction = false; + } + /* + if ( m_dragSelecting || m_dragUnselecting ) + { + PlaySound( "EDIT_END_AREA.Creating" ); + } + m_dragSelecting = false; + m_dragUnselecting = false; + */ +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::OnMousePressed( MouseCode code ) +{ + /* + CNavArea *area = TheNavMesh->GetSelectedArea(); + */ + + switch ( code ) + { + case MOUSE_LEFT: + m_performingLeftClickAction = true; + if ( m_toolPanel ) + { + m_toolPanel->StartLeftClickAction( m_leftClickAction ); + } + if ( m_selectionPanel ) + { + m_selectionPanel->StartLeftClickAction( m_leftClickAction ); + } + break; + } + + BaseClass::OnMousePressed( code ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::OnMouseReleased( MouseCode code ) +{ + switch ( code ) + { + case MOUSE_LEFT: + if ( m_performingLeftClickAction ) + { + if ( m_toolPanel ) + { + m_toolPanel->FinishLeftClickAction( m_leftClickAction ); + } + if ( m_selectionPanel ) + { + m_selectionPanel->FinishLeftClickAction( m_leftClickAction ); + } + m_performingLeftClickAction = false; + } + break; + case MOUSE_RIGHT: + if ( m_toolPanel ) + { + m_toolPanel->StartRightClickAction( "Selection::ClearSelection" ); + } + if ( m_selectionPanel ) + { + m_selectionPanel->StartRightClickAction( "Selection::ClearSelection" ); + } + break; + } + + BaseClass::OnMousePressed( code ); +} + + +//-------------------------------------------------------------------------------------------------------- +void CNavUIBasePanel::PlaySound( const char *sound ) +{ + CBasePlayer *player = UTIL_GetListenServerHost(); + if ( player ) + { + player->EmitSound( sound ); + } +} + + +//-------------------------------------------------------------------------------------------------------- +// Taken from cl_dll/view.cpp +float ScaleFOVByWidthRatio( float fovDegrees, float ratio ) +{ + float halfAngleRadians = fovDegrees * ( 0.5f * M_PI / 180.0f ); + float t = tan( halfAngleRadians ); + t *= ratio; + float retDegrees = ( 180.0f / M_PI ) * atan( t ); + return retDegrees * 2.0f; +} + + +//-------------------------------------------------------------------------------------------------------- +// Purpose: +// Given a field of view and mouse/screen positions as well as the current +// render origin and angles, returns a unit vector through the mouse position +// that can be used to trace into the world under the mouse click pixel. +// Input : +// mousex - +// mousey - +// fov - +// vecRenderOrigin - +// vecRenderAngles - +// Output : +// vecPickingRay +// Adapted from cl_dll/c_vguiscreen.cpp +//-------------------------------------------------------------------------------------------------------- +void ScreenToWorld( int mousex, int mousey, float fov, + const Vector& vecRenderOrigin, + const QAngle& vecRenderAngles, + Vector& vecPickingRay ) +{ + float dx, dy; + float c_x, c_y; + float dist; + Vector vpn, vup, vright; + + int wide, tall; + vgui::surface()->GetScreenSize( wide, tall ); + c_x = wide / 2; + c_y = tall / 2; + + float scaled_fov = ScaleFOVByWidthRatio( fov, (float)wide / (float)tall * 0.75f ); + + dx = (float)mousex - c_x; + // Invert Y + dy = c_y - (float)mousey; + + // Convert view plane distance + dist = c_x / tan( M_PI * scaled_fov / 360.0 ); + + // Decompose view angles + AngleVectors( vecRenderAngles, &vpn, &vright, &vup ); + + // Offset forward by view plane distance, and then by pixel offsets + vecPickingRay = vpn * dist + vright * ( dx ) + vup * ( dy ); + + // Convert to unit vector + VectorNormalize( vecPickingRay ); +} + + +//-------------------------------------------------------------------------------------------------------- +void GetNavUIEditVectors( Vector *pos, Vector *forward ) +{ + CBasePlayer *player = UTIL_GetListenServerHost(); + if ( !player ) + { + return; + } + + if ( !s_navUIPanel ) + { + return; + } + + if ( s_navUIPanel->GetAlpha() < 255 ) + { + return; + } + + int x, y; + vgui::surface()->SurfaceGetCursorPos( x, y ); + + float fov = player->GetFOV(); + QAngle eyeAngles = player->EyeAngles(); + Vector eyePosition = player->EyePosition(); + + Vector pick; + ScreenToWorld( x, y, fov, eyePosition, eyeAngles, pick ); + + *forward = pick; +} + + +//-------------------------------------------------------------------------------------------------------- +void NavUICommand( void ) +{ + if ( engine->IsDedicatedServer() ) + return; + + if ( UTIL_GetCommandClient() != UTIL_GetListenServerHost() ) + return; + + engine->ServerCommand( "nav_edit 1\n" ); + bool created = false; + if ( !s_navUIPanel ) + { + created = true; + s_navUIPanel = CreateNavUI(); + } + + ShowGameDLLPanel( s_navUIPanel ); + vgui::ivgui()->AddTickSignal( s_navUIPanel->GetVPanel() ); + if ( !created ) + { + s_navUIPanel->ToggleVisibility(); + } +} +ConCommand nav_gui( "nav_gui", NavUICommand, "Opens the nav editing GUI", FCVAR_CHEAT ); + +#endif // SERVER_USES_VGUI + +//-------------------------------------------------------------------------------------------------------- diff --git a/game/server/NavUI/NavUI.h b/game/server/NavUI/NavUI.h new file mode 100644 index 0000000..e0976d3 --- /dev/null +++ b/game/server/NavUI/NavUI.h @@ -0,0 +1,220 @@ +//-------------------------------------------------------------------------------------------------------- +//========= Copyright Valve Corporation, All rights reserved. ============// + +#ifndef NAVUI_H +#define NAVUI_H + +#ifdef SERVER_USES_VGUI + +#include "KeyValues.h" +#include <vgui_controls/ImagePanel.h> +#include <vgui_controls/Button.h> +#include <vgui_controls/Frame.h> +#include <vgui_controls/ComboBox.h> +#include <vgui_controls/TextEntry.h> +#include <vgui_controls/CheckButton.h> +#include <vgui/ILocalize.h> +#include "vgui/ISurface.h" +#include "vgui/IVGui.h" +#include "fmtstr.h" +#include <vgui_controls/CheckButton.h> + + +//-------------------------------------------------------------------------------------------------------- +void GetNavUIEditVectors( Vector *pos, Vector *forward ); + + +//-------------------------------------------------------------------------------------------------------- +class CNavUIButton : public vgui::Button +{ + DECLARE_CLASS_SIMPLE( CNavUIButton, vgui::Button ); + +public: + CNavUIButton( Panel *parent, const char *name ) : vgui::Button( parent, name, "" ) + { + m_hideKey = BUTTON_CODE_INVALID; + } + + virtual void OnKeyCodePressed( vgui::KeyCode code ); + virtual void OnKeyCodeReleased( vgui::KeyCode code ); + +private: + void LookupKey( void ); + + ButtonCode_t m_hideKey; + IntervalTimer m_hidePressedTimer; +}; + + +//-------------------------------------------------------------------------------------------------------- +class CNavUITextEntry : public vgui::TextEntry +{ + DECLARE_CLASS_SIMPLE( CNavUIButton, vgui::TextEntry ); + +public: + CNavUITextEntry( Panel *parent, const char *name ) : vgui::TextEntry( parent, name ) + { + m_hideKey = BUTTON_CODE_INVALID; + } + + virtual void OnKeyCodePressed( vgui::KeyCode code ); + virtual void OnKeyCodeReleased( vgui::KeyCode code ); + +private: + void LookupKey( void ); + + ButtonCode_t m_hideKey; + IntervalTimer m_hidePressedTimer; +}; + + +//-------------------------------------------------------------------------------------------------------- +class CNavUIComboBox : public vgui::ComboBox +{ + DECLARE_CLASS_SIMPLE( CNavUIComboBox, vgui::ComboBox ); + +public: + CNavUIComboBox( Panel *parent, const char *name, int numLines, bool editable ) : vgui::ComboBox( parent, name, numLines, editable ) + { + m_hideKey = BUTTON_CODE_INVALID; + } + + virtual void OnKeyCodePressed( vgui::KeyCode code ); + virtual void OnKeyCodeReleased( vgui::KeyCode code ); + +private: + void LookupKey( void ); + + ButtonCode_t m_hideKey; + IntervalTimer m_hidePressedTimer; +}; + + +//-------------------------------------------------------------------------------------------------------- +class CNavUICheckButton : public vgui::CheckButton +{ + DECLARE_CLASS_SIMPLE( CNavUICheckButton, vgui::CheckButton ); + +public: + CNavUICheckButton( Panel *parent, const char *name, const char *text ) : vgui::CheckButton( parent, name, text ) + { + m_hideKey = BUTTON_CODE_INVALID; + } + + virtual void OnKeyCodePressed( vgui::KeyCode code ); + virtual void OnKeyCodeReleased( vgui::KeyCode code ); + +private: + void LookupKey( void ); + + ButtonCode_t m_hideKey; + IntervalTimer m_hidePressedTimer; +}; + + +//-------------------------------------------------------------------------------------------------------- +class CNavUIToolPanel : public vgui::EditablePanel +{ + DECLARE_CLASS_SIMPLE( CNavUIToolPanel, vgui::EditablePanel ); + +public: + CNavUIToolPanel( vgui::Panel *parent, const char *toolName ) : vgui::EditablePanel( parent, toolName ) + { + } + + virtual void Init( void ) + { + } + + virtual void Shutdown( void ) + { + } + + virtual vgui::Panel *CreateControlByName( const char *controlName ); + + virtual void StartLeftClickAction( const char *actionName ) + { + } + + virtual void FinishLeftClickAction( const char *actionName ) + { + } + + virtual void StartRightClickAction( const char *actionName ) + { + } + +protected: + bool IsCheckButtonChecked( const char *name ); +}; + + +//-------------------------------------------------------------------------------------------------------- +class CNavUIBasePanel : public vgui::Frame +{ + DECLARE_CLASS_SIMPLE( CNavUIBasePanel, vgui::Frame ); + +public: + CNavUIBasePanel(); + virtual ~CNavUIBasePanel(); + + virtual void ApplySchemeSettings( vgui::IScheme *pScheme ); + virtual void OnCommand( const char *command ); + virtual void PerformLayout( void ); + virtual void PaintBackground( void ); + + // GameUI panels are always visible by default, so here we hide ourselves if the GameUI is up. + virtual void OnTick( void ); + + void ToggleVisibility( void ); + virtual Panel *CreateControlByName( const char *controlName ); + + virtual void OnKeyCodePressed( vgui::KeyCode code ); + virtual void OnKeyCodeReleased( vgui::KeyCode code ); + virtual void OnMousePressed( vgui::MouseCode code ); + + virtual void OnCursorMoved( int x, int y ); + virtual void OnCursorEntered( void ); + virtual void OnCursorExited( void ); + virtual void OnMouseReleased( vgui::MouseCode code ); + + void SetLeftClickAction( const char *action, const char *text ); + const char *GetLeftClickAction( void ) const + { + return m_leftClickAction; + } + + void PlaySound( const char *sound ); + +protected: + const char *ActiveToolName( void ) const; + void ActivateTool( const char *toolName ); + virtual CNavUIToolPanel *CreateTool( const char *toolName, vgui::Panel *toolParent ); + +private: + bool m_hidden; + + bool m_dragSelecting; + bool m_dragUnselecting; + + CNavUIToolPanel *m_toolPanel; + CNavUIToolPanel *m_selectionPanel; + + void LookupKey( void ); + + ButtonCode_t m_hideKey; + IntervalTimer m_hidePressedTimer; + + CountdownTimer m_audioTimer; + + char m_leftClickAction[ 64 ]; + bool m_performingLeftClickAction; +}; + + +extern CNavUIBasePanel *CreateNavUI( void ); +extern CNavUIBasePanel *TheNavUI( void ); + +#endif // SERVER_USES_VGUI + +#endif // NAVUI_H diff --git a/game/server/NavUI/SelectionTool.cpp b/game/server/NavUI/SelectionTool.cpp new file mode 100644 index 0000000..1969fc5 --- /dev/null +++ b/game/server/NavUI/SelectionTool.cpp @@ -0,0 +1,242 @@ +//-------------------------------------------------------------------------------------------------------- +//========= Copyright Valve Corporation, All rights reserved. ============// + +#include "cbase.h" + +#include "SelectionTool.h" +#include "nav_mesh.h" +#include "nav_pathfind.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifdef SERVER_USES_VGUI + +using namespace vgui; + + +//-------------------------------------------------------------------------------------------------------- +SelectionToolPanel::SelectionToolPanel( vgui::Panel *parent, const char *toolName ) : CNavUIToolPanel( parent, toolName ) +{ + LoadControlSettings( "Resource/UI/NavTools/SelectionTool.res" ); +} + + +//-------------------------------------------------------------------------------------------------------- +void SelectionToolPanel::Init( void ) +{ + m_dragType = DRAG_NONE; +} + + +//-------------------------------------------------------------------------------------------------------- +void SelectionToolPanel::Shutdown( void ) +{ +} + + +//-------------------------------------------------------------------------------------------------------- +void SelectionToolPanel::PerformLayout( void ) +{ + Panel *parent = GetParent(); + if ( parent ) + { + int w, h; + parent->GetSize( w, h ); + SetBounds( 0, 0, w, h ); + } + + BaseClass::PerformLayout(); +} + + +//-------------------------------------------------------------------------------------------------------- +void SelectionToolPanel::OnCommand( const char *command ) +{ + if ( FStrEq( "FloodSelect", command ) ) + { + TheNavUI()->SetLeftClickAction( "Selection::Flood", "Flood Select" ); + } + + BaseClass::OnCommand( command ); +} + + +//-------------------------------------------------------------------------------------------------------- +void SelectionToolPanel::OnCursorMoved( int x, int y ) +{ + CNavArea *area = TheNavMesh->GetSelectedArea(); + if ( area ) + { + bool selected = TheNavMesh->IsInSelectedSet( area ); + + if ( selected && m_dragType == DRAG_UNSELECT ) + { + TheNavMesh->RemoveFromSelectedSet( area ); + TheNavUI()->PlaySound( "EDIT_END_AREA.Creating" ); + } + else if ( !selected && m_dragType == DRAG_SELECT ) + { + TheNavMesh->AddToSelectedSet( area ); + TheNavUI()->PlaySound( "EDIT_END_AREA.Creating" ); + } + } + + BaseClass::OnCursorMoved( x, y ); +} + + +//-------------------------------------------------------------------------------------------------------- +class FloodSelectionCollector +{ +public: + FloodSelectionCollector( SelectionToolPanel *panel ) + { + m_count = 0; + m_panel = panel; + } + + bool operator() ( CNavArea *area ) + { + // already selected areas terminate flood select + if ( TheNavMesh->IsInSelectedSet( area ) ) + return false; + + if ( !m_panel->IsFloodSelectable( area ) ) + return false; + + TheNavMesh->AddToSelectedSet( area ); + ++m_count; + + return true; + } + + int m_count; + +private: + SelectionToolPanel *m_panel; +}; + + +//-------------------------------------------------------------------------------------------------------- +bool SelectionToolPanel::IsFloodSelectable( CNavArea *area ) +{ + if ( IsCheckButtonChecked( "Place" ) ) + { + if ( m_floodStartArea->GetPlace() != area->GetPlace() ) + { + return false; + } + } + + if ( IsCheckButtonChecked( "Jump" ) ) + { + if ( (m_floodStartArea->GetAttributes() & NAV_MESH_JUMP) != (area->GetAttributes() & NAV_MESH_JUMP) ) + { + return false; + } + } + + return true; +} + + +//-------------------------------------------------------------------------------------------------------- +void SelectionToolPanel::FloodSelect( void ) +{ + m_floodStartArea = TheNavMesh->GetSelectedArea(); + if ( m_floodStartArea ) + { + TheNavUI()->PlaySound( "EDIT_DELETE" ); + + int connections = INCLUDE_BLOCKED_AREAS; + + if ( IsCheckButtonChecked( "Incoming" ) ) + { + connections = connections | INCLUDE_INCOMING_CONNECTIONS; + } + + if ( !IsCheckButtonChecked( "Outgoing" ) ) + { + connections = connections | EXCLUDE_OUTGOING_CONNECTIONS; + } + + // collect all areas connected to this area + FloodSelectionCollector collector( this ); + SearchSurroundingAreas( m_floodStartArea, m_floodStartArea->GetCenter(), collector, -1, connections ); + + Msg( "Selected %d areas.\n", collector.m_count ); + } + m_floodStartArea = NULL; + + TheNavMesh->SetMarkedArea( NULL ); // unmark the mark area +} + + +//-------------------------------------------------------------------------------------------------------- +void SelectionToolPanel::StartLeftClickAction( const char *actionName ) +{ + if ( FStrEq( actionName, "Selection::Flood" ) ) + { + TheNavUI()->SetLeftClickAction( "", "" ); + FloodSelect(); + } + else if ( FStrEq( actionName, "Selection::Select" ) ) + { + CNavArea *area = TheNavMesh->GetSelectedArea(); + if ( area ) + { + if ( TheNavMesh->IsInSelectedSet( area ) ) + { + TheNavMesh->RemoveFromSelectedSet( area ); + m_dragType = DRAG_UNSELECT; + } + else + { + TheNavMesh->AddToSelectedSet( area ); + m_dragType = DRAG_SELECT; + } + TheNavUI()->PlaySound( "EDIT_END_AREA.Creating" ); + } + } +} + + +//-------------------------------------------------------------------------------------------------------- +void SelectionToolPanel::FinishLeftClickAction( const char *actionName ) +{ + m_dragType = DRAG_NONE; +} + + +//-------------------------------------------------------------------------------------------------------- +void SelectionToolPanel::StartRightClickAction( const char *actionName ) +{ + if ( m_dragType != DRAG_NONE ) + { + TheNavUI()->PlaySound( "EDIT_END_AREA.Creating" ); + m_dragType = DRAG_NONE; + return; + } + + if ( FStrEq( actionName, "Selection::ClearSelection" ) ) + { + if ( FStrEq( TheNavUI()->GetLeftClickAction(), "Selection::Select" ) ) + { + if ( TheNavMesh->GetSelecteSetSize() > 0 ) + { + TheNavUI()->PlaySound( "EDIT_END_AREA.Creating" ); + } + TheNavMesh->ClearSelectedSet(); + } + else + { + TheNavUI()->SetLeftClickAction( "", "" ); + } + } +} + +#endif // SERVER_USES_VGUI + + +//-------------------------------------------------------------------------------------------------------- diff --git a/game/server/NavUI/SelectionTool.h b/game/server/NavUI/SelectionTool.h new file mode 100644 index 0000000..d5af70f --- /dev/null +++ b/game/server/NavUI/SelectionTool.h @@ -0,0 +1,48 @@ +//-------------------------------------------------------------------------------------------------------- +//========= Copyright Valve Corporation, All rights reserved. ============// + +#ifndef SELECTIONTOOL_H +#define SELECTIONTOOL_H + +#ifdef SERVER_USES_VGUI + +#include "NavUI.h" +#include "nav.h" + + +//-------------------------------------------------------------------------------------------------------- +class SelectionToolPanel : public CNavUIToolPanel +{ + DECLARE_CLASS_SIMPLE( SelectionToolPanel, CNavUIToolPanel ); + +public: + SelectionToolPanel( vgui::Panel *parent, const char *toolName ); + + virtual void Init( void ); + virtual void Shutdown( void ); + virtual void PerformLayout( void ); + virtual void OnCommand( const char *command ); + + virtual void StartLeftClickAction( const char *actionName ); + virtual void FinishLeftClickAction( const char *actionName ); + virtual void StartRightClickAction( const char *actionName ); + virtual void OnCursorMoved( int x, int y ); + + virtual bool IsFloodSelectable( CNavArea *area ); + +protected: + void FloodSelect( void ); + CNavArea *m_floodStartArea; + + enum DragSelectType + { + DRAG_NONE, + DRAG_SELECT, + DRAG_UNSELECT + }; + DragSelectType m_dragType; +}; + +#endif // SERVER_USES_VGUI + +#endif // SELECTIONTOOL_H |