diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /mp/src/vgui2/vgui_controls/MenuItem.cpp | |
| parent | Mark some more files as text. (diff) | |
| download | source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip | |
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/vgui2/vgui_controls/MenuItem.cpp')
| -rw-r--r-- | mp/src/vgui2/vgui_controls/MenuItem.cpp | 1294 |
1 files changed, 647 insertions, 647 deletions
diff --git a/mp/src/vgui2/vgui_controls/MenuItem.cpp b/mp/src/vgui2/vgui_controls/MenuItem.cpp index 355bfaa4..49c39570 100644 --- a/mp/src/vgui2/vgui_controls/MenuItem.cpp +++ b/mp/src/vgui2/vgui_controls/MenuItem.cpp @@ -1,647 +1,647 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#include <vgui/IScheme.h>
-#include <vgui/IVGui.h>
-#include "vgui/ISurface.h"
-#include <KeyValues.h>
-
-#include <vgui_controls/Controls.h>
-#include <vgui_controls/Menu.h>
-#include <vgui_controls/MenuItem.h>
-#include <vgui_controls/TextImage.h>
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include <tier0/memdbgon.h>
-
-using namespace vgui;
-
-//-----------------------------------------------------------------------------
-// Purpose: Check box image
-//-----------------------------------------------------------------------------
-class MenuItemCheckImage : public TextImage
-{
-public:
- MenuItemCheckImage(MenuItem *item) : TextImage( "g" )
- {
- _menuItem = item;
-
- SetSize(20, 13);
- }
-
- virtual void Paint()
- {
- DrawSetTextFont(GetFont());
-
- // draw background
- DrawSetTextColor(_menuItem->GetBgColor());
- DrawPrintChar(0, 0, 'g');
-
- // draw check
- if (_menuItem->IsChecked())
- {
- if (_menuItem->IsEnabled())
- {
- DrawSetTextColor(_menuItem->GetButtonFgColor());
- DrawPrintChar(0, 2, 'a');
- }
- else if (!_menuItem->IsEnabled())
- {
- // draw disabled version, with embossed look
- // offset image
- DrawSetTextColor(_menuItem->GetDisabledFgColor1());
- DrawPrintChar(1, 3, 'a');
-
- // overlayed image
- DrawSetTextColor(_menuItem->GetDisabledFgColor2());
- DrawPrintChar(0, 2, 'a');
- }
- }
- }
-
-private:
- MenuItem *_menuItem;
-};
-
-DECLARE_BUILD_FACTORY_DEFAULT_TEXT( MenuItem, MenuItem );
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-// Input: parent - the parent of this menu item, usually a menu
-// text - the name of the menu item as it appears in the menu
-// cascadeMenu - if this item triggers the opening of a cascading menu
-// provide a pointer to it.
-// MenuItems cannot be both checkable and trigger a cascade menu.
-//-----------------------------------------------------------------------------
-MenuItem::MenuItem(Menu *parent, const char *panelName, const char *text, Menu *cascadeMenu, bool checkable) : Button(parent, panelName, text)
-{
- m_pCascadeMenu = cascadeMenu;
- m_bCheckable = checkable;
- SetButtonActivationType(ACTIVATE_ONRELEASED);
- m_pUserData = NULL;
- m_pCurrentKeyBinding = NULL;
-
- // only one arg should be passed in.
- Assert (!(cascadeMenu && checkable));
-
- Init();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-// Input: parent - the parent of this menu item, usually a menu
-// text - the name of the menu item as it appears in the menu
-// cascadeMenu - if this item triggers the opening of a cascading menu
-// provide a pointer to it.
-// MenuItems cannot be both checkable and trigger a cascade menu.
-//-----------------------------------------------------------------------------
-MenuItem::MenuItem(Menu *parent, const char *panelName, const wchar_t *wszText, Menu *cascadeMenu, bool checkable) : Button(parent, panelName, wszText)
-{
- m_pCascadeMenu = cascadeMenu;
- m_bCheckable = checkable;
- SetButtonActivationType(ACTIVATE_ONRELEASED);
- m_pUserData = NULL;
- m_pCurrentKeyBinding = NULL;
-
- // only one arg should be passed in.
- Assert (!(cascadeMenu && checkable));
-
- Init();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Destructor
-//-----------------------------------------------------------------------------
-MenuItem::~MenuItem()
-{
- delete m_pCascadeMenu;
- delete m_pCascadeArrow;
- delete m_pCheck;
- if (m_pUserData)
- {
- m_pUserData->deleteThis();
- }
- delete m_pCurrentKeyBinding;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Basic initializer
-//-----------------------------------------------------------------------------
-void MenuItem::Init( void )
-{
- m_pCascadeArrow = NULL;
- m_pCheck = NULL;
-
- if (m_pCascadeMenu)
- {
- m_pCascadeMenu->SetParent(this);
- m_pCascadeArrow = new TextImage("4"); // this makes a right pointing arrow.
-
- m_pCascadeMenu->AddActionSignalTarget(this);
- }
- else if (m_bCheckable)
- {
- // move the text image over so we have room for the check
- SetTextImageIndex(1);
- m_pCheck = new MenuItemCheckImage(this);
- SetImageAtIndex(0, m_pCheck, CHECK_INSET);
- SetChecked(false);
- }
-
- SetButtonBorderEnabled( false );
- SetUseCaptureMouse( false );
- SetContentAlignment( Label::a_west );
-
- // note menus handle all the sizing of menuItem panels
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-Menu *MenuItem::GetParentMenu()
-{
- return (Menu *)GetParent();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Layout the Textimage and the Arrow part of the menuItem
-//-----------------------------------------------------------------------------
-void MenuItem::PerformLayout()
-{
- Button::PerformLayout();
- // make the arrow image match the button layout.
- // this will make it brighten and dim like the menu buttons.
- if (m_pCascadeArrow)
- {
- m_pCascadeArrow->SetColor(GetButtonFgColor());
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Close the cascading menu if we have one.
-//-----------------------------------------------------------------------------
-void MenuItem::CloseCascadeMenu()
-{
- if (m_pCascadeMenu)
- {
- if (m_pCascadeMenu->IsVisible())
- {
- m_pCascadeMenu->SetVisible(false);
- }
- // disarm even if menu wasn't visible!
- SetArmed(false);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Handle cursor moving in a menuItem.
-//-----------------------------------------------------------------------------
-void MenuItem::OnCursorMoved(int x, int y)
-{
- // if menu is in keymode and we moved the mouse
- // highlight this item
- if (GetParentMenu()->GetMenuMode() == Menu::KEYBOARD)
- {
- OnCursorEntered();
- }
-
- // chain up to parent
- CallParentFunction(new KeyValues("OnCursorMoved", "x", x, "y", y));
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Handle mouse cursor entering a menuItem.
-//-----------------------------------------------------------------------------
-void MenuItem::OnCursorEntered()
-{
- // post a message to the parent menu.
- // forward the message on to the parent of this menu.
- KeyValues *msg = new KeyValues ("CursorEnteredMenuItem");
- // tell the parent this menuitem is the one that was entered so it can highlight it
- msg->SetInt("VPanel", GetVPanel());
-
- ivgui()->PostMessage(GetVParent(), msg, NULL);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Handle mouse cursor exiting a menuItem.
-//-----------------------------------------------------------------------------
-void MenuItem::OnCursorExited()
-{
- // post a message to the parent menu.
- // forward the message on to the parent of this menu.
- KeyValues *msg = new KeyValues ("CursorExitedMenuItem");
- // tell the parent this menuitem is the one that was entered so it can unhighlight it
- msg->SetInt("VPanel", GetVPanel());
-
- ivgui()->PostMessage(GetVParent(), msg, NULL);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Handle mouse cursor exiting a menuItem.
-//-----------------------------------------------------------------------------
-void MenuItem::OnKeyCodeReleased(KeyCode code)
-{
- if (GetParentMenu()->GetMenuMode() == Menu::KEYBOARD && m_pCascadeMenu)
- {
- return;
- }
- // only disarm if we are not opening a cascading menu using keys.
- Button::OnKeyCodeReleased(code);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Highlight a menu item
-// Menu item buttons highlight if disabled, but won't activate.
-//-----------------------------------------------------------------------------
-void MenuItem::ArmItem()
-{
- // close all other menus
- GetParentMenu()->CloseOtherMenus(this);
- // arm the menuItem.
- Button::SetArmed(true);
-
- // When you have a submenu with no scroll bar the menu
- // border will not be drawn correctly. This fixes it.
- Menu *parent = GetParentMenu();
- if ( parent )
- {
- parent->ForceCalculateWidth();
- }
-
- Repaint();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Unhighlight a menu item
-//-----------------------------------------------------------------------------
-void MenuItem::DisarmItem()
-{
- // normal behaviour is that the button becomes unarmed
- // do not unarm if there is a cascading menu. CloseCascadeMenu handles this.
- // and the menu handles it since we close at different times depending
- // on whether menu is handling mouse or key events.
- if (!m_pCascadeMenu)
- {
- Button::OnCursorExited();
- }
-
- // When you have a submenu with no scroll bar the menu
- // border will not be drawn correctly. This fixes it.
- Menu *parent = GetParentMenu();
- if ( parent )
- {
- parent->ForceCalculateWidth();
- }
- Repaint();
-}
-
-bool MenuItem::IsItemArmed()
-{
- return Button::IsArmed();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Pass kill focus events up to parent, This will tell all panels
-// in the hierarchy to hide themselves, and enables cascading menus to
-// all disappear on selecting an item at the end of the tree.
-//-----------------------------------------------------------------------------
-void MenuItem::OnKillFocus()
-{
- GetParentMenu()->OnKillFocus();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: fire the menu item as if it has been selected and
-// Tell the owner that it is closing
-//-----------------------------------------------------------------------------
-void MenuItem::FireActionSignal()
-{
- // cascading menus items don't trigger the parent menu to disappear
- // (they trigger the cascading menu to open/close when cursor is moved over/off them)
- if (!m_pCascadeMenu)
- {
- KeyValues *kv = new KeyValues("MenuItemSelected");
- kv->SetPtr("panel", this);
- ivgui()->PostMessage(GetVParent(), kv, GetVPanel());
-
- // ivgui()->PostMessage(GetVParent(), new KeyValues("MenuItemSelected"), GetVPanel());
- Button::FireActionSignal();
- // toggle the check next to the item if it is checkable
- if (m_bCheckable)
- {
- SetChecked( !m_bChecked );
- }
- }
- else
- {
- // if we are in keyboard mode, open the child menu.
- if (GetParentMenu()->GetMenuMode() == Menu::KEYBOARD)
- {
- OpenCascadeMenu();
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Opens the cascading menu.
-//-----------------------------------------------------------------------------
-void MenuItem::OpenCascadeMenu()
-{
- if (m_pCascadeMenu)
- {
- // perform layout on menu, this way it will open in the right spot
- // if the window's been moved
- m_pCascadeMenu->PerformLayout();
- m_pCascadeMenu->SetVisible(true);
- ArmItem();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpse: Return true if this item triggers a cascading menu
-//-----------------------------------------------------------------------------
-bool MenuItem::HasMenu()
-{
- return (m_pCascadeMenu != NULL);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Apply the resource scheme to the menu.
-//-----------------------------------------------------------------------------
-void MenuItem::ApplySchemeSettings(IScheme *pScheme)
-{
- // chain back first
- Button::ApplySchemeSettings(pScheme);
-
- // get color settings
- SetDefaultColor(GetSchemeColor("Menu.TextColor", GetFgColor(), pScheme), GetSchemeColor("Menu.BgColor", GetBgColor(), pScheme));
- SetArmedColor(GetSchemeColor("Menu.ArmedTextColor", GetFgColor(), pScheme), GetSchemeColor("Menu.ArmedBgColor", GetBgColor(), pScheme));
- SetDepressedColor(GetSchemeColor("Menu.ArmedTextColor", GetFgColor(), pScheme), GetSchemeColor("Menu.ArmedBgColor", GetBgColor(), pScheme));
-
- SetTextInset(atoi(pScheme->GetResourceString("Menu.TextInset")), 0);
-
- // reload images since applyschemesettings in label wipes them out.
- if ( m_pCascadeArrow )
- {
- m_pCascadeArrow->SetFont(pScheme->GetFont("Marlett", IsProportional() ));
- m_pCascadeArrow->ResizeImageToContent();
- AddImage(m_pCascadeArrow, 0);
- }
- else if (m_bCheckable)
- {
- ( static_cast<MenuItemCheckImage *>(m_pCheck) )->SetFont( pScheme->GetFont("Marlett", IsProportional()));
- SetImageAtIndex(0, m_pCheck, CHECK_INSET);
- ( static_cast<MenuItemCheckImage *>(m_pCheck) )->ResizeImageToContent();
- }
-
- if ( m_pCurrentKeyBinding )
- {
- m_pCurrentKeyBinding->SetFont(pScheme->GetFont("Default", IsProportional() ));
- m_pCurrentKeyBinding->ResizeImageToContent();
- }
-
- // Have the menu redo the layout
- // Get the parent to resize
- Menu * parent = GetParentMenu();
- if ( parent )
- {
- parent->ForceCalculateWidth();
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Return the size of the text portion of the label.
-// for normal menu items this is the same as the label size, but for
-// cascading menus it gives you the size of the text portion only, without
-// the arrow.
-//-----------------------------------------------------------------------------
-void MenuItem::GetTextImageSize(int &wide, int &tall)
-{
- GetTextImage()->GetSize(wide, tall);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Set the size of the text portion of the label.
-// For normal menu items this is the same as the label size, but for
-// cascading menus it sizes textImage portion only, without
-// the arrow.
-//-----------------------------------------------------------------------------
-void MenuItem::SetTextImageSize(int wide, int tall)
-{
- GetTextImage()->SetSize(wide, tall);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Return the size of the arrow portion of the label.
-// If the menuItem is not a cascading menu, 0 is returned.
-//-----------------------------------------------------------------------------
-void MenuItem::GetArrowImageSize(int &wide, int &tall)
-{
- wide = 0, tall = 0;
- if (m_pCascadeArrow)
- {
- m_pCascadeArrow->GetSize(wide, tall);
- return;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Return the size of the check portion of the label.
-//-----------------------------------------------------------------------------
-void MenuItem::GetCheckImageSize(int &wide, int &tall)
-{
- wide = 0, tall = 0;
- if (m_pCheck)
- {
- // resize the image to the contents size
- ( static_cast<MenuItemCheckImage *>(m_pCheck) )->ResizeImageToContent();
- m_pCheck->GetSize(wide, tall);
-
- // include the inset for the check, since nobody but us know about the inset
- wide += CHECK_INSET;
- return;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Return a the menu that this menuItem contains
-// This is useful when the parent menu's commands must be
-// sent through all menus that are open as well (like hotkeys)
-//-----------------------------------------------------------------------------
-Menu *MenuItem::GetMenu()
-{
- return m_pCascadeMenu;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Get the border style for the button. Menu items have no border so
-// return null.
-//-----------------------------------------------------------------------------
-IBorder *MenuItem::GetBorder(bool depressed, bool armed, bool selected, bool keyfocus)
-{
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Set the menu to key mode if a child menu goes into keymode
-//-----------------------------------------------------------------------------
-void MenuItem::OnKeyModeSet()
-{
- // send the message to this parent in case this is a cascading menu
- ivgui()->PostMessage(GetVParent(), new KeyValues("KeyModeSet"), GetVPanel());
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Return if this menuitem is checkable or not
-// This is used by menus to perform the layout properly.
-//-----------------------------------------------------------------------------
-bool MenuItem::IsCheckable()
-{
- return m_bCheckable;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Return if this menuitem is checked or not
-//-----------------------------------------------------------------------------
-bool MenuItem::IsChecked()
-{
- return m_bChecked;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Set the checked state of a checkable menuitem
-// Does nothing if item is not checkable
-//-----------------------------------------------------------------------------
-void MenuItem::SetChecked(bool state)
-{
- if (m_bCheckable)
- {
- m_bChecked = state;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool MenuItem::CanBeDefaultButton(void)
-{
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-KeyValues *MenuItem::GetUserData()
-{
- if ( HasMenu() )
- {
- return m_pCascadeMenu->GetItemUserData( m_pCascadeMenu->GetActiveItem() );
- }
- else
- {
- return m_pUserData;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: sets the user data
-//-----------------------------------------------------------------------------
-void MenuItem::SetUserData(const KeyValues *kv)
-{
- if (m_pUserData)
- {
- m_pUserData->deleteThis();
- m_pUserData = NULL;
- }
-
- if ( kv )
- {
- m_pUserData = kv->MakeCopy();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Passing in NULL removes this object
-// Input : *keyName -
-//-----------------------------------------------------------------------------
-void MenuItem::SetCurrentKeyBinding( char const *keyName )
-{
- if ( !keyName )
- {
- delete m_pCurrentKeyBinding;
- m_pCurrentKeyBinding = NULL;
- return;
- }
-
- if ( !m_pCurrentKeyBinding )
- {
- m_pCurrentKeyBinding = new TextImage( keyName );
- }
- else
- {
- char curtext[ 256 ];
- m_pCurrentKeyBinding->GetText( curtext, sizeof( curtext ) );
- if ( !Q_strcmp( curtext, keyName ) )
- return;
-
- m_pCurrentKeyBinding->SetText( keyName );
- }
-
- InvalidateLayout( false, true );
-}
-
-#define KEYBINDING_INSET 5
-
-void MenuItem::Paint()
-{
- BaseClass::Paint();
- if ( !m_pCurrentKeyBinding )
- return;
-
- int w, h;
- GetSize( w, h );
- int iw, ih;
- m_pCurrentKeyBinding->GetSize( iw, ih );
-
- int x = w - iw - KEYBINDING_INSET;
- int y = ( h - ih ) / 2;
-
- if ( IsEnabled() )
- {
- m_pCurrentKeyBinding->SetPos( x, y );
- m_pCurrentKeyBinding->SetColor( GetButtonFgColor() );
- m_pCurrentKeyBinding->Paint();
- }
- else
- {
- m_pCurrentKeyBinding->SetPos( x + 1 , y + 1 );
- m_pCurrentKeyBinding->SetColor( GetDisabledFgColor1() );
- m_pCurrentKeyBinding->Paint();
-
- surface()->DrawFlushText();
-
- m_pCurrentKeyBinding->SetPos( x, y );
- m_pCurrentKeyBinding->SetColor( GetDisabledFgColor2() );
- m_pCurrentKeyBinding->Paint();
- }
-}
-
-void MenuItem::GetContentSize( int& cw, int &ch )
-{
- BaseClass::GetContentSize( cw, ch );
- if ( !m_pCurrentKeyBinding )
- return;
-
- int iw, ih;
- m_pCurrentKeyBinding->GetSize( iw, ih );
-
- cw += iw + KEYBINDING_INSET;
- ch = max( ch, ih );
-}
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include <vgui/IScheme.h> +#include <vgui/IVGui.h> +#include "vgui/ISurface.h" +#include <KeyValues.h> + +#include <vgui_controls/Controls.h> +#include <vgui_controls/Menu.h> +#include <vgui_controls/MenuItem.h> +#include <vgui_controls/TextImage.h> + +// memdbgon must be the last include file in a .cpp file!!! +#include <tier0/memdbgon.h> + +using namespace vgui; + +//----------------------------------------------------------------------------- +// Purpose: Check box image +//----------------------------------------------------------------------------- +class MenuItemCheckImage : public TextImage +{ +public: + MenuItemCheckImage(MenuItem *item) : TextImage( "g" ) + { + _menuItem = item; + + SetSize(20, 13); + } + + virtual void Paint() + { + DrawSetTextFont(GetFont()); + + // draw background + DrawSetTextColor(_menuItem->GetBgColor()); + DrawPrintChar(0, 0, 'g'); + + // draw check + if (_menuItem->IsChecked()) + { + if (_menuItem->IsEnabled()) + { + DrawSetTextColor(_menuItem->GetButtonFgColor()); + DrawPrintChar(0, 2, 'a'); + } + else if (!_menuItem->IsEnabled()) + { + // draw disabled version, with embossed look + // offset image + DrawSetTextColor(_menuItem->GetDisabledFgColor1()); + DrawPrintChar(1, 3, 'a'); + + // overlayed image + DrawSetTextColor(_menuItem->GetDisabledFgColor2()); + DrawPrintChar(0, 2, 'a'); + } + } + } + +private: + MenuItem *_menuItem; +}; + +DECLARE_BUILD_FACTORY_DEFAULT_TEXT( MenuItem, MenuItem ); + +//----------------------------------------------------------------------------- +// Purpose: Constructor +// Input: parent - the parent of this menu item, usually a menu +// text - the name of the menu item as it appears in the menu +// cascadeMenu - if this item triggers the opening of a cascading menu +// provide a pointer to it. +// MenuItems cannot be both checkable and trigger a cascade menu. +//----------------------------------------------------------------------------- +MenuItem::MenuItem(Menu *parent, const char *panelName, const char *text, Menu *cascadeMenu, bool checkable) : Button(parent, panelName, text) +{ + m_pCascadeMenu = cascadeMenu; + m_bCheckable = checkable; + SetButtonActivationType(ACTIVATE_ONRELEASED); + m_pUserData = NULL; + m_pCurrentKeyBinding = NULL; + + // only one arg should be passed in. + Assert (!(cascadeMenu && checkable)); + + Init(); +} + +//----------------------------------------------------------------------------- +// Purpose: Constructor +// Input: parent - the parent of this menu item, usually a menu +// text - the name of the menu item as it appears in the menu +// cascadeMenu - if this item triggers the opening of a cascading menu +// provide a pointer to it. +// MenuItems cannot be both checkable and trigger a cascade menu. +//----------------------------------------------------------------------------- +MenuItem::MenuItem(Menu *parent, const char *panelName, const wchar_t *wszText, Menu *cascadeMenu, bool checkable) : Button(parent, panelName, wszText) +{ + m_pCascadeMenu = cascadeMenu; + m_bCheckable = checkable; + SetButtonActivationType(ACTIVATE_ONRELEASED); + m_pUserData = NULL; + m_pCurrentKeyBinding = NULL; + + // only one arg should be passed in. + Assert (!(cascadeMenu && checkable)); + + Init(); +} + +//----------------------------------------------------------------------------- +// Purpose: Destructor +//----------------------------------------------------------------------------- +MenuItem::~MenuItem() +{ + delete m_pCascadeMenu; + delete m_pCascadeArrow; + delete m_pCheck; + if (m_pUserData) + { + m_pUserData->deleteThis(); + } + delete m_pCurrentKeyBinding; +} + +//----------------------------------------------------------------------------- +// Purpose: Basic initializer +//----------------------------------------------------------------------------- +void MenuItem::Init( void ) +{ + m_pCascadeArrow = NULL; + m_pCheck = NULL; + + if (m_pCascadeMenu) + { + m_pCascadeMenu->SetParent(this); + m_pCascadeArrow = new TextImage("4"); // this makes a right pointing arrow. + + m_pCascadeMenu->AddActionSignalTarget(this); + } + else if (m_bCheckable) + { + // move the text image over so we have room for the check + SetTextImageIndex(1); + m_pCheck = new MenuItemCheckImage(this); + SetImageAtIndex(0, m_pCheck, CHECK_INSET); + SetChecked(false); + } + + SetButtonBorderEnabled( false ); + SetUseCaptureMouse( false ); + SetContentAlignment( Label::a_west ); + + // note menus handle all the sizing of menuItem panels +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +Menu *MenuItem::GetParentMenu() +{ + return (Menu *)GetParent(); +} + +//----------------------------------------------------------------------------- +// Purpose: Layout the Textimage and the Arrow part of the menuItem +//----------------------------------------------------------------------------- +void MenuItem::PerformLayout() +{ + Button::PerformLayout(); + // make the arrow image match the button layout. + // this will make it brighten and dim like the menu buttons. + if (m_pCascadeArrow) + { + m_pCascadeArrow->SetColor(GetButtonFgColor()); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Close the cascading menu if we have one. +//----------------------------------------------------------------------------- +void MenuItem::CloseCascadeMenu() +{ + if (m_pCascadeMenu) + { + if (m_pCascadeMenu->IsVisible()) + { + m_pCascadeMenu->SetVisible(false); + } + // disarm even if menu wasn't visible! + SetArmed(false); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Handle cursor moving in a menuItem. +//----------------------------------------------------------------------------- +void MenuItem::OnCursorMoved(int x, int y) +{ + // if menu is in keymode and we moved the mouse + // highlight this item + if (GetParentMenu()->GetMenuMode() == Menu::KEYBOARD) + { + OnCursorEntered(); + } + + // chain up to parent + CallParentFunction(new KeyValues("OnCursorMoved", "x", x, "y", y)); +} + +//----------------------------------------------------------------------------- +// Purpose: Handle mouse cursor entering a menuItem. +//----------------------------------------------------------------------------- +void MenuItem::OnCursorEntered() +{ + // post a message to the parent menu. + // forward the message on to the parent of this menu. + KeyValues *msg = new KeyValues ("CursorEnteredMenuItem"); + // tell the parent this menuitem is the one that was entered so it can highlight it + msg->SetInt("VPanel", GetVPanel()); + + ivgui()->PostMessage(GetVParent(), msg, NULL); +} + +//----------------------------------------------------------------------------- +// Purpose: Handle mouse cursor exiting a menuItem. +//----------------------------------------------------------------------------- +void MenuItem::OnCursorExited() +{ + // post a message to the parent menu. + // forward the message on to the parent of this menu. + KeyValues *msg = new KeyValues ("CursorExitedMenuItem"); + // tell the parent this menuitem is the one that was entered so it can unhighlight it + msg->SetInt("VPanel", GetVPanel()); + + ivgui()->PostMessage(GetVParent(), msg, NULL); +} + +//----------------------------------------------------------------------------- +// Purpose: Handle mouse cursor exiting a menuItem. +//----------------------------------------------------------------------------- +void MenuItem::OnKeyCodeReleased(KeyCode code) +{ + if (GetParentMenu()->GetMenuMode() == Menu::KEYBOARD && m_pCascadeMenu) + { + return; + } + // only disarm if we are not opening a cascading menu using keys. + Button::OnKeyCodeReleased(code); +} + +//----------------------------------------------------------------------------- +// Purpose: Highlight a menu item +// Menu item buttons highlight if disabled, but won't activate. +//----------------------------------------------------------------------------- +void MenuItem::ArmItem() +{ + // close all other menus + GetParentMenu()->CloseOtherMenus(this); + // arm the menuItem. + Button::SetArmed(true); + + // When you have a submenu with no scroll bar the menu + // border will not be drawn correctly. This fixes it. + Menu *parent = GetParentMenu(); + if ( parent ) + { + parent->ForceCalculateWidth(); + } + + Repaint(); +} + +//----------------------------------------------------------------------------- +// Purpose: Unhighlight a menu item +//----------------------------------------------------------------------------- +void MenuItem::DisarmItem() +{ + // normal behaviour is that the button becomes unarmed + // do not unarm if there is a cascading menu. CloseCascadeMenu handles this. + // and the menu handles it since we close at different times depending + // on whether menu is handling mouse or key events. + if (!m_pCascadeMenu) + { + Button::OnCursorExited(); + } + + // When you have a submenu with no scroll bar the menu + // border will not be drawn correctly. This fixes it. + Menu *parent = GetParentMenu(); + if ( parent ) + { + parent->ForceCalculateWidth(); + } + Repaint(); +} + +bool MenuItem::IsItemArmed() +{ + return Button::IsArmed(); +} + +//----------------------------------------------------------------------------- +// Purpose: Pass kill focus events up to parent, This will tell all panels +// in the hierarchy to hide themselves, and enables cascading menus to +// all disappear on selecting an item at the end of the tree. +//----------------------------------------------------------------------------- +void MenuItem::OnKillFocus() +{ + GetParentMenu()->OnKillFocus(); +} + +//----------------------------------------------------------------------------- +// Purpose: fire the menu item as if it has been selected and +// Tell the owner that it is closing +//----------------------------------------------------------------------------- +void MenuItem::FireActionSignal() +{ + // cascading menus items don't trigger the parent menu to disappear + // (they trigger the cascading menu to open/close when cursor is moved over/off them) + if (!m_pCascadeMenu) + { + KeyValues *kv = new KeyValues("MenuItemSelected"); + kv->SetPtr("panel", this); + ivgui()->PostMessage(GetVParent(), kv, GetVPanel()); + + // ivgui()->PostMessage(GetVParent(), new KeyValues("MenuItemSelected"), GetVPanel()); + Button::FireActionSignal(); + // toggle the check next to the item if it is checkable + if (m_bCheckable) + { + SetChecked( !m_bChecked ); + } + } + else + { + // if we are in keyboard mode, open the child menu. + if (GetParentMenu()->GetMenuMode() == Menu::KEYBOARD) + { + OpenCascadeMenu(); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Opens the cascading menu. +//----------------------------------------------------------------------------- +void MenuItem::OpenCascadeMenu() +{ + if (m_pCascadeMenu) + { + // perform layout on menu, this way it will open in the right spot + // if the window's been moved + m_pCascadeMenu->PerformLayout(); + m_pCascadeMenu->SetVisible(true); + ArmItem(); + } +} + +//----------------------------------------------------------------------------- +// Purpse: Return true if this item triggers a cascading menu +//----------------------------------------------------------------------------- +bool MenuItem::HasMenu() +{ + return (m_pCascadeMenu != NULL); +} + +//----------------------------------------------------------------------------- +// Purpose: Apply the resource scheme to the menu. +//----------------------------------------------------------------------------- +void MenuItem::ApplySchemeSettings(IScheme *pScheme) +{ + // chain back first + Button::ApplySchemeSettings(pScheme); + + // get color settings + SetDefaultColor(GetSchemeColor("Menu.TextColor", GetFgColor(), pScheme), GetSchemeColor("Menu.BgColor", GetBgColor(), pScheme)); + SetArmedColor(GetSchemeColor("Menu.ArmedTextColor", GetFgColor(), pScheme), GetSchemeColor("Menu.ArmedBgColor", GetBgColor(), pScheme)); + SetDepressedColor(GetSchemeColor("Menu.ArmedTextColor", GetFgColor(), pScheme), GetSchemeColor("Menu.ArmedBgColor", GetBgColor(), pScheme)); + + SetTextInset(atoi(pScheme->GetResourceString("Menu.TextInset")), 0); + + // reload images since applyschemesettings in label wipes them out. + if ( m_pCascadeArrow ) + { + m_pCascadeArrow->SetFont(pScheme->GetFont("Marlett", IsProportional() )); + m_pCascadeArrow->ResizeImageToContent(); + AddImage(m_pCascadeArrow, 0); + } + else if (m_bCheckable) + { + ( static_cast<MenuItemCheckImage *>(m_pCheck) )->SetFont( pScheme->GetFont("Marlett", IsProportional())); + SetImageAtIndex(0, m_pCheck, CHECK_INSET); + ( static_cast<MenuItemCheckImage *>(m_pCheck) )->ResizeImageToContent(); + } + + if ( m_pCurrentKeyBinding ) + { + m_pCurrentKeyBinding->SetFont(pScheme->GetFont("Default", IsProportional() )); + m_pCurrentKeyBinding->ResizeImageToContent(); + } + + // Have the menu redo the layout + // Get the parent to resize + Menu * parent = GetParentMenu(); + if ( parent ) + { + parent->ForceCalculateWidth(); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Return the size of the text portion of the label. +// for normal menu items this is the same as the label size, but for +// cascading menus it gives you the size of the text portion only, without +// the arrow. +//----------------------------------------------------------------------------- +void MenuItem::GetTextImageSize(int &wide, int &tall) +{ + GetTextImage()->GetSize(wide, tall); +} + +//----------------------------------------------------------------------------- +// Purpose: Set the size of the text portion of the label. +// For normal menu items this is the same as the label size, but for +// cascading menus it sizes textImage portion only, without +// the arrow. +//----------------------------------------------------------------------------- +void MenuItem::SetTextImageSize(int wide, int tall) +{ + GetTextImage()->SetSize(wide, tall); +} + +//----------------------------------------------------------------------------- +// Purpose: Return the size of the arrow portion of the label. +// If the menuItem is not a cascading menu, 0 is returned. +//----------------------------------------------------------------------------- +void MenuItem::GetArrowImageSize(int &wide, int &tall) +{ + wide = 0, tall = 0; + if (m_pCascadeArrow) + { + m_pCascadeArrow->GetSize(wide, tall); + return; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Return the size of the check portion of the label. +//----------------------------------------------------------------------------- +void MenuItem::GetCheckImageSize(int &wide, int &tall) +{ + wide = 0, tall = 0; + if (m_pCheck) + { + // resize the image to the contents size + ( static_cast<MenuItemCheckImage *>(m_pCheck) )->ResizeImageToContent(); + m_pCheck->GetSize(wide, tall); + + // include the inset for the check, since nobody but us know about the inset + wide += CHECK_INSET; + return; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Return a the menu that this menuItem contains +// This is useful when the parent menu's commands must be +// sent through all menus that are open as well (like hotkeys) +//----------------------------------------------------------------------------- +Menu *MenuItem::GetMenu() +{ + return m_pCascadeMenu; +} + +//----------------------------------------------------------------------------- +// Purpose: Get the border style for the button. Menu items have no border so +// return null. +//----------------------------------------------------------------------------- +IBorder *MenuItem::GetBorder(bool depressed, bool armed, bool selected, bool keyfocus) +{ + return NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: Set the menu to key mode if a child menu goes into keymode +//----------------------------------------------------------------------------- +void MenuItem::OnKeyModeSet() +{ + // send the message to this parent in case this is a cascading menu + ivgui()->PostMessage(GetVParent(), new KeyValues("KeyModeSet"), GetVPanel()); +} + + +//----------------------------------------------------------------------------- +// Purpose: Return if this menuitem is checkable or not +// This is used by menus to perform the layout properly. +//----------------------------------------------------------------------------- +bool MenuItem::IsCheckable() +{ + return m_bCheckable; +} + +//----------------------------------------------------------------------------- +// Purpose: Return if this menuitem is checked or not +//----------------------------------------------------------------------------- +bool MenuItem::IsChecked() +{ + return m_bChecked; +} + +//----------------------------------------------------------------------------- +// Purpose: Set the checked state of a checkable menuitem +// Does nothing if item is not checkable +//----------------------------------------------------------------------------- +void MenuItem::SetChecked(bool state) +{ + if (m_bCheckable) + { + m_bChecked = state; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool MenuItem::CanBeDefaultButton(void) +{ + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +KeyValues *MenuItem::GetUserData() +{ + if ( HasMenu() ) + { + return m_pCascadeMenu->GetItemUserData( m_pCascadeMenu->GetActiveItem() ); + } + else + { + return m_pUserData; + } +} + +//----------------------------------------------------------------------------- +// Purpose: sets the user data +//----------------------------------------------------------------------------- +void MenuItem::SetUserData(const KeyValues *kv) +{ + if (m_pUserData) + { + m_pUserData->deleteThis(); + m_pUserData = NULL; + } + + if ( kv ) + { + m_pUserData = kv->MakeCopy(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Passing in NULL removes this object +// Input : *keyName - +//----------------------------------------------------------------------------- +void MenuItem::SetCurrentKeyBinding( char const *keyName ) +{ + if ( !keyName ) + { + delete m_pCurrentKeyBinding; + m_pCurrentKeyBinding = NULL; + return; + } + + if ( !m_pCurrentKeyBinding ) + { + m_pCurrentKeyBinding = new TextImage( keyName ); + } + else + { + char curtext[ 256 ]; + m_pCurrentKeyBinding->GetText( curtext, sizeof( curtext ) ); + if ( !Q_strcmp( curtext, keyName ) ) + return; + + m_pCurrentKeyBinding->SetText( keyName ); + } + + InvalidateLayout( false, true ); +} + +#define KEYBINDING_INSET 5 + +void MenuItem::Paint() +{ + BaseClass::Paint(); + if ( !m_pCurrentKeyBinding ) + return; + + int w, h; + GetSize( w, h ); + int iw, ih; + m_pCurrentKeyBinding->GetSize( iw, ih ); + + int x = w - iw - KEYBINDING_INSET; + int y = ( h - ih ) / 2; + + if ( IsEnabled() ) + { + m_pCurrentKeyBinding->SetPos( x, y ); + m_pCurrentKeyBinding->SetColor( GetButtonFgColor() ); + m_pCurrentKeyBinding->Paint(); + } + else + { + m_pCurrentKeyBinding->SetPos( x + 1 , y + 1 ); + m_pCurrentKeyBinding->SetColor( GetDisabledFgColor1() ); + m_pCurrentKeyBinding->Paint(); + + surface()->DrawFlushText(); + + m_pCurrentKeyBinding->SetPos( x, y ); + m_pCurrentKeyBinding->SetColor( GetDisabledFgColor2() ); + m_pCurrentKeyBinding->Paint(); + } +} + +void MenuItem::GetContentSize( int& cw, int &ch ) +{ + BaseClass::GetContentSize( cw, ch ); + if ( !m_pCurrentKeyBinding ) + return; + + int iw, ih; + m_pCurrentKeyBinding->GetSize( iw, ih ); + + cw += iw + KEYBINDING_INSET; + ch = max( ch, ih ); +} |