|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#define PROTECTED_THINGS_DISABLE
#include <vgui/IPanel.h>
#include <vgui/IInput.h>
#include <vgui/ISurface.h>
#include <KeyValues.h>
#include <vgui/IVGui.h>
#include <vgui_controls/Controls.h>
#include <vgui_controls/MenuButton.h>
#include <vgui_controls/Menu.h>
#include <vgui_controls/TextImage.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
DECLARE_BUILD_FACTORY_DEFAULT_TEXT( MenuButton, MenuButton );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
MenuButton::MenuButton(Panel *parent, const char *panelName, const char *text) : Button(parent, panelName, text) { m_pMenu = NULL; m_iDirection = Menu::DOWN; m_pDropMenuImage = NULL; m_nImageIndex = -1; _openOffsetY = 0; m_bDropMenuButtonStyle = true; // set to true so SetDropMenuButtonStyle() forces real init.
SetDropMenuButtonStyle( false ); SetUseCaptureMouse( false ); SetButtonActivationType( ACTIVATE_ONPRESSED ); }
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
MenuButton::~MenuButton() { delete m_pDropMenuImage; }
//-----------------------------------------------------------------------------
// Purpose: attaches a menu to the menu button
//-----------------------------------------------------------------------------
void MenuButton::SetMenu(Menu *menu) { m_pMenu = menu;
if (menu) { m_pMenu->SetVisible(false); m_pMenu->AddActionSignalTarget(this); m_pMenu->SetParent(this); } }
//-----------------------------------------------------------------------------
// Purpose: Never draw a focus border
//-----------------------------------------------------------------------------
void MenuButton::DrawFocusBorder(int tx0, int ty0, int tx1, int ty1) { }
//-----------------------------------------------------------------------------
// Purpose: Sets the direction from the menu button the menu should open
//-----------------------------------------------------------------------------
void MenuButton::SetOpenDirection(Menu::MenuDirection_e direction) { m_iDirection = direction; }
//-----------------------------------------------------------------------------
// Purpose: hides the menu
//-----------------------------------------------------------------------------
void MenuButton::HideMenu(void) { if (!m_pMenu) return;
// hide the menu
m_pMenu->SetVisible(false);
// unstick the button
BaseClass::ForceDepressed(false); Repaint();
OnHideMenu(m_pMenu); }
//-----------------------------------------------------------------------------
// Purpose: Called when the menu button loses focus; hides the menu
//-----------------------------------------------------------------------------
void MenuButton::OnKillFocus( KeyValues *pParams ) { VPANEL hPanel = (VPANEL)pParams->GetPtr( "newPanel" ); if ( m_pMenu && !m_pMenu->HasFocus() && hPanel != m_pMenu->GetVPanel() ) { HideMenu(); } BaseClass::OnKillFocus(); }
//-----------------------------------------------------------------------------
// Purpose: Called when the menu is closed
//-----------------------------------------------------------------------------
void MenuButton::OnMenuClose() { HideMenu(); PostActionSignal(new KeyValues("MenuClose")); }
//-----------------------------------------------------------------------------
// Purpose: Sets the offset from where menu would normally be placed
// Only is used if menu is ALIGN_WITH_PARENT
//-----------------------------------------------------------------------------
void MenuButton::SetOpenOffsetY(int yOffset) { _openOffsetY = yOffset; }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool MenuButton::CanBeDefaultButton(void) { return false; }
//-----------------------------------------------------------------------------
// Purpose: Handles hotkey accesses
//-----------------------------------------------------------------------------
void MenuButton::DoClick() { if ( IsDropMenuButtonStyle() && m_pDropMenuImage ) { int mx, my; // force the menu to appear where the mouse button was pressed
input()->GetCursorPos( mx, my ); ScreenToLocal( mx, my );
int contentW, contentH; m_pDropMenuImage->GetContentSize( contentW, contentH ); int drawX = GetWide() - contentW - 2; if ( mx <= drawX || !OnCheckMenuItemCount() ) { // Treat it like a "regular" button click
BaseClass::DoClick(); return; } }
if ( !m_pMenu ) { return; }
// menu is already visible, hide the menu
if (m_pMenu->IsVisible()) { HideMenu(); return; }
// do nothing if menu is not enabled
if (!m_pMenu->IsEnabled()) { return; } // force the menu to compute required width/height
m_pMenu->PerformLayout();
// Now position it so it can fit in the workspace
m_pMenu->PositionRelativeToPanel(this, m_iDirection, _openOffsetY );
// make sure we're at the top of the draw order (and therefore our children as well)
MoveToFront();
// notify
OnShowMenu(m_pMenu);
// keep the button depressed
BaseClass::ForceDepressed(true);
// show the menu
m_pMenu->SetVisible(true);
// bring to focus
m_pMenu->RequestFocus(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void MenuButton::OnKeyCodeTyped(KeyCode code) { bool shift = (input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT)); bool ctrl = (input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL)); bool alt = (input()->IsKeyDown(KEY_LALT) || input()->IsKeyDown(KEY_RALT));
if (!shift && !ctrl && !alt) { switch (code) { case KEY_ENTER: { if ( !IsDropMenuButtonStyle() ) { DoClick(); } break; } } } BaseClass::OnKeyCodeTyped(code); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void MenuButton::OnCursorEntered() { Button::OnCursorEntered(); // post a message to the parent menu.
// forward the message on to the parent of this menu.
KeyValues *msg = new KeyValues ("CursorEnteredMenuButton"); // tell the parent this menuitem is the one that was entered so it can open the menu if it wants
msg->SetInt("VPanel", GetVPanel()); ivgui()->PostMessage(GetVParent(), msg, NULL); }
// This style is like the IE "back" button where the left side acts like a regular button, the the right side has a little
// combo box dropdown indicator and presents and submenu
void MenuButton::SetDropMenuButtonStyle( bool state ) { bool changed = m_bDropMenuButtonStyle != state; m_bDropMenuButtonStyle = state; if ( !changed ) return;
if ( state ) { m_pDropMenuImage = new TextImage( "u" ); IScheme *pScheme = scheme()->GetIScheme( GetScheme() ); m_pDropMenuImage->SetFont(pScheme->GetFont("Marlett", IsProportional())); // m_pDropMenuImage->SetContentAlignment(Label::a_west);
// m_pDropMenuImage->SetTextInset(3, 0);
m_nImageIndex = AddImage( m_pDropMenuImage, 0 ); } else { ResetToSimpleTextImage(); delete m_pDropMenuImage; m_pDropMenuImage = NULL; m_nImageIndex = -1; } }
void MenuButton::ApplySchemeSettings( IScheme *pScheme ) { BaseClass::ApplySchemeSettings( pScheme );
if ( m_pDropMenuImage ) { SetImageAtIndex( 1, m_pDropMenuImage, 0 ); } }
void MenuButton::PerformLayout() { BaseClass::PerformLayout(); if ( !IsDropMenuButtonStyle() ) return;
Assert( m_nImageIndex >= 0 ); if ( m_nImageIndex < 0 || !m_pDropMenuImage ) return;
int w, h; GetSize( w, h );
int contentW, contentH; m_pDropMenuImage->ResizeImageToContent(); m_pDropMenuImage->GetContentSize( contentW, contentH );
SetImageBounds( m_nImageIndex, w - contentW - 2, contentW ); }
bool MenuButton::IsDropMenuButtonStyle() const { return m_bDropMenuButtonStyle; }
void MenuButton::Paint(void) { BaseClass::Paint();
if ( !IsDropMenuButtonStyle() ) return;
int contentW, contentH; m_pDropMenuImage->GetContentSize( contentW, contentH ); m_pDropMenuImage->SetColor( IsEnabled() ? GetButtonFgColor() : GetDisabledFgColor1() ); int drawX = GetWide() - contentW - 2;
surface()->DrawSetColor( IsEnabled() ? GetButtonFgColor() : GetDisabledFgColor1() ); surface()->DrawFilledRect( drawX, 3, drawX + 1, GetTall() - 3 ); }
void MenuButton::OnCursorMoved( int x, int y ) { BaseClass::OnCursorMoved( x, y );
if ( !IsDropMenuButtonStyle() ) return;
int contentW, contentH; m_pDropMenuImage->GetContentSize( contentW, contentH ); int drawX = GetWide() - contentW - 2; if ( x <= drawX || !OnCheckMenuItemCount() ) { SetButtonActivationType(ACTIVATE_ONPRESSEDANDRELEASED); SetUseCaptureMouse(true); } else { SetButtonActivationType(ACTIVATE_ONPRESSED); SetUseCaptureMouse(false); } }
Menu *MenuButton::GetMenu() { Assert( m_pMenu ); return m_pMenu; }
|