#include "gamepadui_button.h" #include "gamepadui_interface.h" #include "gamepadui_util.h" #include "vgui/IVGui.h" #include "vgui/ISurface.h" #include "../../public/vgui_controls/Panel.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" #define DEFAULT_BTN_ARMED_SOUND "ui/buttonrollover.wav" #define DEFAULT_BTN_RELEASED_SOUND "ui/buttonclickrelease.wav" ConVar gamepadui_center_footer_buttons( "gamepadui_center_footer_buttons", "1", FCVAR_NONE, "Centers footer buttons when not using gamepad" ); GamepadUIButton::GamepadUIButton( vgui::Panel *pParent, vgui::Panel* pActionSignalTarget, const char *pSchemeFile, const char *pCommand, const char *pText, const char *pDescription ) : BaseClass( pParent, "", "", pActionSignalTarget, pCommand ) , m_strButtonText( pText ) , m_strButtonDescription( pDescription ) { SetScheme( vgui::scheme()->LoadSchemeFromFileEx( GamepadUI::GetInstance().GetSizingVPanel(), pSchemeFile, "SchemePanel" ) ); } GamepadUIButton::GamepadUIButton( vgui::Panel *pParent, vgui::Panel* pActionSignalTarget, const char *pSchemeFile, const char *pCommand, const wchar_t *pText, const wchar_t *pDescription ) : BaseClass( pParent, "", "", pActionSignalTarget, pCommand ) , m_strButtonText( pText ) , m_strButtonDescription( pDescription ) { SetScheme( vgui::scheme()->LoadSchemeFromFileEx( GamepadUI::GetInstance().GetSizingVPanel(), pSchemeFile, "SchemePanel" ) ); } void GamepadUIButton::ApplySchemeSettings(vgui::IScheme* pScheme) { BaseClass::ApplySchemeSettings(pScheme); const char *pButtonSound = pScheme->GetResourceString( "Button.Sound.Armed" ); if (pButtonSound && *pButtonSound) SetArmedSound( pButtonSound ); else SetArmedSound( DEFAULT_BTN_ARMED_SOUND ); pButtonSound = pScheme->GetResourceString( "Button.Sound.Released" ); if (pButtonSound && *pButtonSound) SetReleasedSound( pButtonSound ); else SetReleasedSound( DEFAULT_BTN_RELEASED_SOUND ); pButtonSound = pScheme->GetResourceString( "Button.Sound.Depressed" ); if (pButtonSound && *pButtonSound) SetDepressedSound( pButtonSound ); SetPaintBorderEnabled( false ); SetPaintBackgroundEnabled( false ); SetConsoleStylePanel( true ); UpdateSchemeProperties( this, pScheme ); m_hTextFont = pScheme->GetFont( "Button.Text.Font", true ); m_hTextFontOver = pScheme->GetFont( "Button.Text.Font.Over", true ); if (m_hTextFontOver == vgui::INVALID_FONT ) m_hTextFontOver = m_hTextFont; m_hDescriptionFont = pScheme->GetFont( "Button.Description.Font", true ); m_ePreviousState = ButtonStates::Out; m_flCachedExtraHeight = 0.0f; if (!m_strButtonDescription.IsEmpty()) { if ( m_bDescriptionWrap ) m_flCachedExtraHeight = DrawPrintWrappedText(m_hDescriptionFont, 0, 0, m_strButtonDescription.String(), m_strButtonDescription.Length(), m_flWidthAnimationValue[ButtonStates::Over] - 2 * (m_flDescriptionOffsetX + m_flTextOffsetX), false); else m_flCachedExtraHeight = 0.0f; } float flX, flY; if (GamepadUI::GetInstance().GetScreenRatio( flX, flY )) { if (flX != 1.0f) { m_flWidth *= flX; for (int i = 0; i < ButtonStates::Count; i++) m_flWidthAnimationValue[i] *= flX; } if (flY != 1.0f) { m_flHeight *= flY; for (int i = 0; i < ButtonStates::Count; i++) m_flHeightAnimationValue[i] *= flY; } } SetSize( m_flWidth, m_flHeight + m_flExtraHeight ); DoAnimations( true ); } void GamepadUIButton::RunAnimations( ButtonState state ) { GAMEPADUI_RUN_ANIMATION_COMMAND( m_flWidth, vgui::AnimationController::INTERPOLATOR_LINEAR ); GAMEPADUI_RUN_ANIMATION_COMMAND( m_flHeight, vgui::AnimationController::INTERPOLATOR_LINEAR ); GAMEPADUI_RUN_ANIMATION_COMMAND( m_flTextOffsetX, vgui::AnimationController::INTERPOLATOR_LINEAR ); GAMEPADUI_RUN_ANIMATION_COMMAND( m_flTextOffsetY, vgui::AnimationController::INTERPOLATOR_LINEAR ); GAMEPADUI_RUN_ANIMATION_COMMAND( m_flDescriptionOffsetX, vgui::AnimationController::INTERPOLATOR_LINEAR ); GAMEPADUI_RUN_ANIMATION_COMMAND( m_flDescriptionOffsetY, vgui::AnimationController::INTERPOLATOR_LINEAR ); GAMEPADUI_RUN_ANIMATION_COMMAND( m_colBackgroundColor, vgui::AnimationController::INTERPOLATOR_LINEAR ); GAMEPADUI_RUN_ANIMATION_COMMAND( m_colTextColor, vgui::AnimationController::INTERPOLATOR_LINEAR ); GAMEPADUI_RUN_ANIMATION_COMMAND( m_colDescriptionColor, vgui::AnimationController::INTERPOLATOR_LINEAR ); GAMEPADUI_RUN_ANIMATION_COMMAND( m_flGlyphFade, vgui::AnimationController::INTERPOLATOR_LINEAR ); GAMEPADUI_RUN_ANIMATION_COMMAND( m_bDescriptionHide, vgui::AnimationController::INTERPOLATOR_LINEAR ); GAMEPADUI_RUN_ANIMATION_COMMAND( m_flTextLeftBorder, vgui::AnimationController::INTERPOLATOR_LINEAR ); GAMEPADUI_RUN_ANIMATION_COMMAND( m_colLeftBorder, vgui::AnimationController::INTERPOLATOR_LINEAR ); GAMEPADUI_RUN_ANIMATION_COMMAND( m_flTextBottomBorder, vgui::AnimationController::INTERPOLATOR_LINEAR ); GAMEPADUI_RUN_ANIMATION_COMMAND( m_colBottomBorder, vgui::AnimationController::INTERPOLATOR_LINEAR ); } void GamepadUIButton::DoAnimations( bool bForce ) { ButtonState state = this->GetCurrentButtonState(); if (m_ePreviousState != state || bForce) { this->RunAnimations( state ); m_ePreviousState = state; } SetSize(m_flWidth, m_flHeight + m_flExtraHeight); } void GamepadUIButton::OnThink() { BaseClass::OnThink(); DoAnimations(); } void GamepadUIButton::PaintButton() { vgui::surface()->DrawSetColor(m_colBackgroundColor); vgui::surface()->DrawFilledRect(0, 0, m_flWidth, m_flHeight + m_flExtraHeight); PaintBorders(); } void GamepadUIButton::PaintBorders() { if ( m_flTextLeftBorder ) { vgui::surface()->DrawSetColor(m_colLeftBorder); vgui::surface()->DrawFilledRect(0, 0, m_flTextLeftBorder, m_flHeight + m_flExtraHeight); } if ( m_flTextBottomBorder ) { vgui::surface()->DrawSetColor( m_colBottomBorder ); vgui::surface()->DrawFilledRect( 0, m_flHeight + m_flExtraHeight - m_flTextBottomBorder, m_flWidth, m_flHeight + m_flExtraHeight ); } } int GamepadUIButton::PaintText() { ButtonState state = this->GetCurrentButtonState(); int nTextPosX = 0, nTextPosY = 0; int nTextSizeX = 0, nTextSizeY = 0; if (!m_strButtonText.IsEmpty()) { vgui::surface()->DrawSetTextFont(state == ButtonStates::Out ? m_hTextFont : m_hTextFontOver); vgui::surface()->GetTextSize(state == ButtonStates::Out ? m_hTextFont : m_hTextFontOver, m_strButtonText.String(), nTextSizeX, nTextSizeY); if (m_CenterX) nTextPosX = m_flWidth / 2 - nTextSizeX / 2 + m_flTextOffsetX; nTextPosX += m_flTextOffsetX; nTextPosY = m_flHeight / 2 - nTextSizeY / 2 + m_flTextOffsetY; } #if defined(HL2_RETAIL) || defined(STEAM_INPUT) #if defined(HL2_RETAIL) // Steam input and Steam Controller are not supported in SDK2013 (Madi) if ( g_pInputSystem->IsSteamControllerActive() ) #else if (GamepadUI::GetInstance().GetSteamInput()->IsEnabled() && GamepadUI::GetInstance().GetSteamInput()->UseGlyphs()) #endif { const int nGlyphSize = m_flHeight * 0.80f; if ( m_glyph.SetupGlyph( nGlyphSize, FooterButtons::GetButtonActionHandleString( m_eFooterButton ) ) ) { int nGlyphPosX = m_flTextOffsetX; if (m_CenterX) { nGlyphPosX = nTextPosX - m_flHeight / 2; nTextPosX += m_flHeight / 2; } else { nTextPosX += nGlyphSize + (m_flTextOffsetX / 2); } int nGlyphPosY = m_flHeight / 2 - nGlyphSize / 2; int nAlpha = 255 * (1.0f - m_flGlyphFade); m_glyph.PaintGlyph( nGlyphPosX, nGlyphPosY, nGlyphSize, nAlpha ); } } else #endif // HL2_RETAIL if (GetFooterButton() != FooterButtons::None && gamepadui_center_footer_buttons.GetBool() && !m_CenterX) { nTextPosX = m_flWidth / 2 - nTextSizeX / 2; } if (!m_strButtonText.IsEmpty()) { vgui::surface()->DrawSetTextColor(m_colTextColor); vgui::surface()->DrawSetTextFont(state == ButtonStates::Out ? m_hTextFont : m_hTextFontOver); vgui::surface()->DrawSetTextPos(nTextPosX, nTextPosY); vgui::surface()->DrawPrintText(m_strButtonText.String(), m_strButtonText.Length()); } float flCurTime = GamepadUI::GetInstance().GetTime(); const float flHeightTransTime = m_flHeightAnimationDuration; float flNewExtraHeight = 0.0f; if (!m_strButtonDescription.IsEmpty() && !m_bDescriptionHide) { vgui::surface()->DrawSetTextColor(m_colDescriptionColor); vgui::surface()->DrawSetTextFont(m_hDescriptionFont); if ( m_bDescriptionWrap ) { flNewExtraHeight = DrawPrintWrappedText(m_hDescriptionFont, nTextPosX + m_flDescriptionOffsetX, nTextPosY + nTextSizeY + m_flDescriptionOffsetY, m_strButtonDescription.String(), m_strButtonDescription.Length(), m_flWidth - 2 * (m_flDescriptionOffsetX + m_flTextOffsetX), true); } else { flNewExtraHeight = 0; vgui::surface()->DrawSetTextPos( nTextPosX + m_flDescriptionOffsetX, nTextPosY + nTextSizeY + m_flDescriptionOffsetY ); vgui::surface()->DrawPrintText( m_strButtonDescription.String(), m_strButtonDescription.Length() ); } } if ( m_flTargetExtraHeight != flNewExtraHeight) { m_flExtraHeightTime = flCurTime; m_flLastExtraHeight = m_flExtraHeight; m_flTargetExtraHeight = flNewExtraHeight; } m_flExtraHeight = Lerp( Clamp( ( flCurTime - m_flExtraHeightTime ) / flHeightTransTime, 0.0f, 1.0f ), m_flLastExtraHeight, m_flTargetExtraHeight ); return nTextSizeX; } void GamepadUIButton::Paint() { BaseClass::Paint(); PaintButton(); PaintText(); m_bNavigateTo = false; } void GamepadUIButton::OnKeyCodePressed( vgui::KeyCode code ) { ButtonCode_t buttonCode = GetBaseButtonCode( code ); switch ( buttonCode ) { #ifdef HL2_RETAIL // Steam input and Steam Controller are not supported in SDK2013 (Madi) case STEAMCONTROLLER_A: #endif case KEY_XBUTTON_A: case KEY_ENTER: if ( IsEnabled() ) { ForceDepressed( true ); m_bControllerPressed = true; } BaseClass::OnKeyCodePressed( code ); // Forward back up to parents for our buttons. if ( m_bForwardToParent ) vgui::Panel::OnKeyCodePressed( code ); break; default: if ( m_bControllerPressed ) { ForceDepressed( false ); m_bControllerPressed = false; } BaseClass::OnKeyCodePressed( code ); break; } } void GamepadUIButton::OnKeyCodeReleased( vgui::KeyCode code ) { ButtonCode_t buttonCode = GetBaseButtonCode(code); switch ( buttonCode ) { #ifdef HL2_RETAIL // Steam input and Steam Controller are not supported in SDK2013 (Madi) case STEAMCONTROLLER_A: #endif case KEY_XBUTTON_A: case KEY_ENTER: if ( IsEnabled() && IsDepressed() && m_bControllerPressed ) { ForceDepressed( false ); DoClick(); m_bControllerPressed = false; } // Forward back up to parents for our buttons. if ( m_bForwardToParent ) vgui::Panel::OnKeyCodeReleased( code ); break; default: BaseClass::OnKeyCodeReleased( code ); break; } } void GamepadUIButton::SetFooterButton( FooterButton button ) { m_eFooterButton = button; m_glyph.Cleanup(); } FooterButton GamepadUIButton::GetFooterButton() const { return m_eFooterButton; } void GamepadUIButton::SetForwardToParent( bool bForwardToParent ) { m_bForwardToParent = bForwardToParent; } bool GamepadUIButton::GetForwardToParent() const { return m_bForwardToParent; } bool GamepadUIButton::IsFooterButton() const { return m_eFooterButton != FooterButtons::None; } ButtonState GamepadUIButton::GetCurrentButtonState() { if ( IsDepressed() ) return ButtonStates::Pressed; else if ( HasFocus() && IsEnabled() ) return ButtonStates::Over; else if ( IsArmed() || m_bNavigateTo ) { if ( IsArmed() ) m_bNavigateTo = false; return ButtonStates::Over; } else return ButtonStates::Out; } void GamepadUIButton::NavigateTo() { BaseClass::NavigateTo(); if ( IsFooterButton() ) return; if ( GetVParent() ) { KeyValues* msg = new KeyValues( "OnGamepadUIButtonNavigatedTo" ); msg->SetInt( "button", ToHandle() ); vgui::ivgui()->PostMessage( GetVParent(), msg, GetVPanel() ); } m_bNavigateTo = true; RequestFocus( 0 ); } void GamepadUIButton::NavigateFrom() { BaseClass::NavigateFrom(); m_bNavigateTo = false; } void GamepadUIButton::OnCursorEntered() { #ifdef STEAM_INPUT if ( GamepadUI::GetInstance().GetSteamInput()->IsEnabled() || !IsEnabled() ) #elif defined(HL2_RETAIL) // Steam input and Steam Controller are not supported in SDK2013 (Madi) if ( g_pInputSystem->IsSteamControllerActive() || !IsEnabled() ) #else if ( !IsEnabled() ) #endif return; BaseClass::OnCursorEntered(); if ( IsFooterButton() || !m_bMouseNavigate ) return; if ( GetParent() ) GetParent()->NavigateToChild( this ); else NavigateTo(); } void GamepadUIButton::FireActionSignal() { BaseClass::FireActionSignal(); //PostMessageToAllSiblingsOfType< GamepadUIButton >( new KeyValues( "OnSiblingGamepadUIButtonOpened" ) ); } void GamepadUIButton::OnSiblingGamepadUIButtonOpened() { m_bNavigateTo = false; }