You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
6.7 KiB
206 lines
6.7 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#ifndef FILTERED_COMBO_BOX_H |
|
#define FILTERED_COMBO_BOX_H |
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
|
|
#include "utlvector.h" |
|
|
|
|
|
#pragma warning( disable: 4355 ) |
|
|
|
// Flags for the SetSuggestions call. |
|
#define SETSUGGESTIONS_SELECTFIRST 0x0001 // Select the first item in the list. |
|
#define SETSUGGESTIONS_CALLBACK 0x0002 // Calls OnTextChanged for whatever it winds up selecting. |
|
|
|
// CFilteredComboBox is a glorified EDIT control. |
|
// The user can type stuff into the edit control, and it will provide autocomplete suggestions |
|
// in its combo box. The user of this class provides those suggestions. |
|
// |
|
// To use this class: |
|
// |
|
// 1. Implement CFilteredComboBox::ICallbacks |
|
// 2. Call SetSuggestions to set the list of autocomplete suggestions. |
|
// 3. Call SetOnlyProvideSuggestions to tell it how to behave. |
|
// |
|
// NOTE: Use CComboBox functions with caution! You could screw up the CFilteredComboBox's operation. |
|
class CFilteredComboBox : public CComboBox |
|
{ |
|
typedef CComboBox BaseClass; |
|
|
|
public: |
|
|
|
// Implement this to get updates about the state. |
|
class ICallbacks |
|
{ |
|
public: |
|
// Called when the text in the box changes. |
|
virtual void OnTextChanged( const char *pText ) = 0; |
|
|
|
// This is sort of a backdoor for "only provide suggestions" mode. Normally, it'll only call |
|
// OnTextChanged with entries that are in the suggestions list. But, it will call OnUnknownEntry |
|
// if they type in something that's not in your suggestion list first. If you return TRUE, it |
|
// will add that entry to the suggestions list. If you return FALSE (the default behavior), |
|
// it will find the closest match to what the user typed and use that. |
|
virtual bool OnUnknownEntry( const char *pText ) { return false; } |
|
}; |
|
|
|
|
|
CFilteredComboBox( CFilteredComboBox::ICallbacks *pCallbacks ); |
|
|
|
|
|
// The main functions to operate the filtered combo box are here. |
|
|
|
// This is the list of strings that is filtered into the dropdown combo box. |
|
// flags is a combination of the SETSUGGESTIONS_ flags. |
|
void SetSuggestions( CUtlVector<CString> &suggestions, int flags=SETSUGGESTIONS_SELECTFIRST|SETSUGGESTIONS_CALLBACK ); |
|
|
|
// Add a single suggestion (if it's unique). |
|
void AddSuggestion( const CString &suggestion ); |
|
|
|
// This clears all items from the combo and its textbox. |
|
void Clear(); |
|
|
|
// This will force the edit control text. It won't call OnTextChanged. |
|
void ForceEditControlText( const char *pStr ); |
|
|
|
// This sets the main mode that the box runs in. |
|
// |
|
// If you pass true, then it will only ever call ICallbacks::OnTextChanged with values that are in your suggestions, |
|
// and it does its best to autocomplete to those suggestions (so if the user types a partial string and closes |
|
// the box, it will find the first possible substring match OR it will revert to the last valid suggestion it was on). |
|
// |
|
// If you pass false, then it will call OnTextChanged for anything that gets entered into the textbox. This is used |
|
// for the entity properties targetname box, and the entity name changes right along as you type. |
|
// When the user presses enter, it does NOT automatically select the first suggestion. They have to use the arrow keys for that. |
|
void SetOnlyProvideSuggestions( bool bOnlyProvideSuggestions ); |
|
|
|
|
|
// These provide access to special behavior like font and color. |
|
|
|
// Puts this string in the edit control and selects it in the combo box. |
|
void SelectItem( const char *pStr ); |
|
|
|
// Returns the same value as the last call to OnTextChanged(). |
|
CString GetCurrentItem(); |
|
|
|
// Get/set the font in the edit control. |
|
void SetEditControlFont( HFONT hFont ); |
|
HFONT GetEditControlFont() const; |
|
|
|
// Get/set the color that the edit text is drawn in. |
|
void SetEditControlTextColor( COLORREF clr ); |
|
COLORREF GetEditControlTextColor() const; |
|
|
|
|
|
// General windows functions. |
|
|
|
// Enable/disable the window. |
|
bool IsWindowEnabled() const; |
|
void EnableWindow( bool bEnable ); |
|
|
|
|
|
// Helper functions. |
|
public: |
|
|
|
// This takes the string the user has entered (pStringToMatch passed into GetItemsMatchingString) |
|
// and returns true if pTestString matches it. It ignores underscores in both strings. |
|
bool MatchString( const char *pStringToMatch, const char *pTestString ); |
|
|
|
// Does this string match one of the suggestions? |
|
// Returns the suggestion index or -1. |
|
int FindSuggestion( const char *pTest ) const; |
|
|
|
// Returns the closest-matching suggestion (the first one that would appear |
|
// in the autocomplete list) or the last known good suggestion. |
|
CString GetBestSuggestion( const char *pTest ); |
|
|
|
void SubclassDlgItem(UINT nID, CWnd *pParent); |
|
|
|
|
|
protected: |
|
|
|
// Get the base font it's using. |
|
CFont& GetNormalFont(); |
|
|
|
// Get/set the text in the edit control. |
|
void SetEditControlText( const char *pText ); |
|
CString GetEditControlText() const; |
|
|
|
DECLARE_MESSAGE_MAP() |
|
|
|
bool m_bNotifyParent; // Whether we allow our parent to hook our notification messages. |
|
// This is necessary because CControlBar-derived classes result in multiple |
|
// message reflections unless we disable parent notification. |
|
|
|
protected: |
|
|
|
// Put all suggestions into the dropdown list. |
|
void FillDropdownList( const char *pInitialSel, bool bEnableRedraw=true ); |
|
|
|
// CBN_ notification handlers. |
|
virtual BOOL PreCreateWindow( CREATESTRUCT& cs ); |
|
BOOL OnDropDown(); |
|
BOOL OnSelEndOK(); |
|
BOOL OnCloseUp(); |
|
BOOL OnSelChange(); |
|
virtual BOOL OnEditChange(); |
|
afx_msg HBRUSH OnCtlColor(CDC *pDC, CWnd *pWnd, UINT nCtlColor); |
|
|
|
void OnEnterKeyPressed( const char *pForceText ); |
|
void OnEscapeKeyPressed(); |
|
|
|
void DoTextChangedCallback( const char *pText ); |
|
|
|
// Gets the items matching the string and sorts the list alphabetically. |
|
virtual void GetItemsMatchingString( const char *pStringToMatch, CUtlVector<CString> &matchingItems ); |
|
static int SortFn( const CString *pItem1, const CString *pItem2 ); |
|
|
|
virtual LRESULT DefWindowProc( |
|
UINT message, |
|
WPARAM wParam, |
|
LPARAM lParam ); |
|
|
|
// Overrides for owner draw. |
|
virtual void MeasureItem(LPMEASUREITEMSTRUCT pStruct); |
|
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); |
|
|
|
private: |
|
|
|
void InternalSetEditControlFont( HFONT hFont, const char *pEditText, DWORD sel ); |
|
void CreateFonts(); |
|
bool InternalSelectItemByName( const char *pName ); |
|
|
|
|
|
private: |
|
|
|
CUtlVector<CString> m_Suggestions; |
|
HFONT m_hEditControlFont; |
|
|
|
CFont m_NormalFont; |
|
|
|
CFilteredComboBox::ICallbacks *m_pCallbacks; |
|
bool m_bWasEditing; |
|
DWORD m_dwTextColor; |
|
|
|
bool m_bOnlyProvideSuggestions; |
|
bool m_bInEnterKeyPressedHandler; |
|
|
|
HFONT m_hQueuedFont; |
|
bool m_bInSelChange; |
|
|
|
// We go back here if they type text that we can't give a suggestion on and press enter (or lose focus). |
|
CString m_LastTextChangedValue; |
|
}; |
|
|
|
|
|
#endif // FILTERED_COMBO_BOX_H |
|
|
|
|
|
|