- Added support for labels for toolbar controls (Vince Harron).
- Added wxMessageDialog::SetMessage() and SetExtendedMessage().
- Added wxListCtrl::Set/GetColumnsOrder() (Yury Voronov).
+- Added wxTextEntry::SetHint().
- Made wxLogWindow thread-safe (Barbara Maren Winkler).
- Added wxWindow::AlwaysShowScrollbars() (Julian Scheid).
- Added wxMouseEvent::GetClickCount() (Julian Scheid).
virtual void GetSelection(long *from, long *to) const;
virtual bool IsEditable() const;
virtual void SetEditable(bool editable);
+
+private:
+ // implement wxTextEntry pure virtual method
+ virtual wxWindow *GetEditableWindow() { return this; }
};
#endif // __WX_COCOA_COMBOBOX_H__
private:
// From wxTextEntry:
- virtual const wxWindow *GetEditableWindow() const { return this; }
+ virtual wxWindow *GetEditableWindow() { return this; }
virtual GtkEditable *GetEditable() const;
virtual void EnableTextChangedEvents(bool enable)
{
private:
// overridden wxTextEntry virtual methods
- virtual const wxWindow *GetEditableWindow() const { return this; }
virtual GtkEditable *GetEditable() const;
virtual void EnableTextChangedEvents(bool enable);
void SendMaxLenEvent();
private:
- // implement this to return the associated window, it will be used for
- // event generation
- virtual const wxWindow *GetEditableWindow() const = 0;
-
// implement this to return the associated GtkEntry or another widget
// implementing GtkEditable
virtual GtkEditable *GetEditable() const = 0;
virtual wxSize DoGetBestSize() const;
+ // implement wxTextEntry pure virtual method
+ virtual wxWindow *GetEditableWindow() { return this; }
+
// Widgets that use the style->base colour for the BG colour should
// override this and return true.
virtual bool UseGTKStyleBase() const { return true; }
int width, int height,
int sizeFlags = wxSIZE_AUTO);
+ // implement wxTextEntry pure virtual methods
+ virtual wxWindow *GetEditableWindow() { return this; }
virtual WXWidget GetTextWidget() const;
private:
virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const;
+#if wxUSE_UXTHEME
+ // override wxTextEntry method to work around Windows bug
+ virtual bool SetHint(const wxString& hint);
+#endif // wxUSE_UXTHEME
+
protected:
#if wxUSE_TOOLTIPS
virtual void DoSetToolTip(wxToolTip *tip);
}
private:
- // this is the overridden wxTextEntry method which should only be called
- // when we do have an edit control so it asserts if this is not the case
+ // there are the overridden wxTextEntry methods which should only be called
+ // when we do have an edit control so they assert if this is not the case
+ virtual wxWindow *GetEditableWindow();
virtual WXHWND GetEditHWND() const;
// common part of all ctors
virtual void SetMaxLength(unsigned long len);
+#if wxUSE_UXTHEME
+ virtual bool SetHint(const wxString& hint);
+ virtual wxString GetHint() const;
+#endif // wxUSE_UXTHEME
+
protected:
// this is really a hook for multiline text controls as the single line
// ones don't need to ever scroll to show the selection but having it here
);
private:
- // implement wxTextEntry pure virtual: it implements all the operations for
- // the simple EDIT controls
+ // implement wxTextEntry pure virtual methods
+ virtual wxWindow *GetEditableWindow() { return this; }
virtual WXHWND GetEditHWND() const { return m_hWnd; }
DECLARE_DYNAMIC_CLASS(wxComboBox)
virtual void SetClientDataType(wxClientDataType clientDataItemsType);
+ // implement wxTextEntry pure virtual method
+ virtual wxWindow *GetEditableWindow() { return this; }
+
// the subcontrols
wxComboBoxText* m_text;
wxComboBoxChoice* m_choice;
static const wxArrayString& GetAvailableFontNames();
static void ClearAvailableFontNames();
+ // FIXME: this does not work, it allows this code to compile but will fail
+ // during run-time
#ifdef __WXMSW__
virtual WXHWND GetEditHWND() const { return GetHWND(); }
#endif
#ifdef __WXGTK__
- // implement this to return the associated window, it will be used for
- // event generation
- virtual const wxWindow *GetEditableWindow() const { return NULL; }
-
- // implement this to return the associated GtkEntry or another widget
- // implementing GtkEditable
+ virtual const wxWindow *GetEditableWindow() { return this; }
virtual GtkEditable *GetEditable() const { return NULL; }
#endif
virtual void ShowCancelButton( bool show ) = 0;
virtual bool IsCancelButtonVisible() const = 0;
+
+private:
+ // implement wxTextEntry pure virtual method
+ virtual wxWindow *GetEditableWindow() { return this; }
};
virtual bool DoLoadFile(const wxString& file, int fileType);
virtual bool DoSaveFile(const wxString& file, int fileType);
+private:
+ // implement the wxTextEntry pure virtual method
+ virtual wxWindow *GetEditableWindow() { return this; }
wxDECLARE_NO_COPY_CLASS(wxTextCtrlBase);
DECLARE_ABSTRACT_CLASS(wxTextCtrlBase)
typedef long wxTextPos;
class WXDLLIMPEXP_FWD_BASE wxArrayString;
+class WXDLLIMPEXP_FWD_CORE wxTextEntryHintData;
// ----------------------------------------------------------------------------
// wxTextEntryBase
class WXDLLIMPEXP_CORE wxTextEntryBase
{
public:
- wxTextEntryBase() { m_eventsBlock = 0; }
- virtual ~wxTextEntryBase() { }
+ wxTextEntryBase() { m_eventsBlock = 0; m_hintData = NULL; }
+ virtual ~wxTextEntryBase();
// accessing the value
virtual void SetMaxLength(unsigned long WXUNUSED(len)) { }
+ // hints
+ // -----
+
+ // hint is the (usually greyed out) text shown in the control as long as
+ // it's empty and doesn't have focus, it is typically used in controls used
+ // for searching to let the user know what is supposed to be entered there
+
+ virtual bool SetHint(const wxString& hint);
+ virtual wxString GetHint() const;
+
+
protected:
// flags for DoSetValue(): common part of SetValue() and ChangeValue() and
// also used to implement WriteText() in wxMSW
bool EventsAllowed() const { return m_eventsBlock == 0; }
private:
+ // override this to return the associated window, it will be used for event
+ // generation and also by generic hints implementation
+ virtual wxWindow *GetEditableWindow() = 0;
+
+
// suppress or resume the text changed events generation: don't use these
// functions directly, use EventsSuppressor class above instead
void SuppressTextChangedEvents()
// if this counter is non-null, events are blocked
unsigned m_eventsBlock;
+
+ // hint-related stuff, only allocated if/when SetHint() is used
+ wxTextEntryHintData *m_hintData;
};
#ifdef __WXUNIVERSAL__
wxListBox *GetLBox() const { return m_lbox; }
private:
+ // implement wxTextEntry pure virtual method
+ virtual wxWindow *GetEditableWindow() { return this; }
+
// the popup listbox
wxListBox *m_lbox;
*/
virtual void SelectAll();
+ /**
+ Sets a hint shown in an empty unfocused text control.
+
+ The hints are usually used to indicate to the user what is supposed to
+ be entered into the given entry field, e.g. a common use of them is to
+ show an explanation of what can be entered in a wxSearchCtrl.
+
+ The hint is shown (usually greyed out) for an empty control until it
+ gets focus and is shown again if the control loses it and remains
+ empty. It won't be shown once the control has a non-empty value,
+ although it will be shown again if the control contents is cleared.
+ Because of this, it generally only makes sense to use hints with the
+ controls which are initially empty.
+
+ Notice that hints are known as <em>cue banners</em> under MSW or
+ <em>placeholder strings</em> under OS X.
+
+ @since 2.9.0
+ */
+ virtual void SetHint(const wxString& hint);
+
+ /**
+ Returns the current hint string.
+
+ See SetHint() for more information about hints.
+
+ @since 2.9.0
+ */
+ virtual wxString GetHint() const;
+
/**
Sets the new text control value.
TextEntry_DisableAutoComplete = TextEntry_Begin,
TextEntry_AutoCompleteFixed,
TextEntry_AutoCompleteFilenames,
+
+ TextEntry_SetHint,
TextEntry_End
};
void OnToggleGlobalBusyCursor(wxCommandEvent& event);
void OnToggleBusyCursor(wxCommandEvent& event);
+ // wxTextEntry-specific tests
void OnDisableAutoComplete(wxCommandEvent& event);
void OnAutoCompleteFixed(wxCommandEvent& event);
void OnAutoCompleteFilenames(wxCommandEvent& event);
+ void OnSetHint(wxCommandEvent& event);
+
void OnUpdateTextUI(wxUpdateUIEvent& event)
{
event.Enable( CurrentPage()->GetTextEntry() != NULL );
EVT_MENU(TextEntry_AutoCompleteFixed, WidgetsFrame::OnAutoCompleteFixed)
EVT_MENU(TextEntry_AutoCompleteFilenames, WidgetsFrame::OnAutoCompleteFilenames)
+ EVT_MENU(TextEntry_SetHint, WidgetsFrame::OnSetHint)
+
EVT_UPDATE_UI_RANGE(TextEntry_Begin, TextEntry_End - 1,
WidgetsFrame::OnUpdateTextUI)
_T("Fixed-&list auto-completion"));
menuTextEntry->AppendRadioItem(TextEntry_AutoCompleteFilenames,
_T("&Files names auto-completion"));
+ menuTextEntry->AppendSeparator();
+ menuTextEntry->Append(TextEntry_SetHint, "Set help &hint");
mbar->Append(menuTextEntry, _T("&Text"));
wxLogMessage("AutoCompleteFileNames() failed.");
}
+void WidgetsFrame::OnSetHint(wxCommandEvent& WXUNUSED(event))
+{
+ wxTextEntryBase *entry = CurrentPage()->GetTextEntry();
+ wxCHECK_RET( entry, "menu item should be disabled" );
+
+ static wxString s_hint("Type here");
+ wxString
+ hint = wxGetTextFromUser("Text hint:", "Widgets sample", s_hint, this);
+ if ( hint.empty() )
+ return;
+
+ s_hint = hint;
+
+ if ( entry->SetHint(hint) )
+ wxLogMessage("Set hint to \"%s\".", hint);
+ else
+ wxLogMessage("Text hints not supported.");
+}
+
#endif // wxUSE_MENUS
// ----------------------------------------------------------------------------
#include "wx/textentry.h"
#include "wx/clipbrd.h"
+// ----------------------------------------------------------------------------
+// wxTextEntryHintData
+// ----------------------------------------------------------------------------
+
+class WXDLLIMPEXP_CORE wxTextEntryHintData wxBIND_OR_CONNECT_HACK_ONLY_BASE_CLASS
+{
+public:
+ wxTextEntryHintData(wxTextEntryBase *entry, wxWindow *win)
+ : m_entry(entry),
+ m_win(win)
+ {
+ wxBIND_OR_CONNECT_HACK(win, wxEVT_SET_FOCUS, wxFocusEventHandler,
+ wxTextEntryHintData::OnSetFocus, this);
+ wxBIND_OR_CONNECT_HACK(win, wxEVT_KILL_FOCUS, wxFocusEventHandler,
+ wxTextEntryHintData::OnKillFocus, this);
+ }
+
+ // default dtor is ok
+
+ void SetHintString(const wxString& hint)
+ {
+ m_hint = hint;
+
+ if ( ShowsHint() )
+ {
+ // update it immediately
+ m_entry->ChangeValue(hint);
+ }
+ //else: the new hint will be shown later
+ }
+
+ const wxString& GetHintString() const { return m_hint; }
+
+private:
+ // are we showing the hint right now?
+ bool ShowsHint() const
+ {
+ return m_entry->GetValue() == m_hint;
+ }
+
+ void OnSetFocus(wxFocusEvent& event)
+ {
+ // hide the hint if we were showing it
+ if ( ShowsHint() )
+ {
+ // Clear() would send an event which we don't want, so do it like
+ // this
+ m_entry->ChangeValue(wxString());
+ m_win->SetForegroundColour(m_colFg);
+ }
+
+ event.Skip();
+ }
+
+ void OnKillFocus(wxFocusEvent& event)
+ {
+ // restore the hint if the user didn't do anything in the control
+ if ( m_entry->IsEmpty() )
+ {
+ m_entry->ChangeValue(m_hint);
+
+ m_colFg = m_win->GetForegroundColour();
+ m_win->SetForegroundColour(*wxLIGHT_GREY);
+ }
+
+ event.Skip();
+ }
+
+
+ wxTextEntryBase * const m_entry;
+ wxWindow * const m_win;
+
+ wxColour m_colFg;
+
+ wxString m_hint;
+
+ wxDECLARE_NO_COPY_CLASS(wxTextEntryHintData);
+};
+
// ============================================================================
// wxTextEntryBase implementation
// ============================================================================
+wxTextEntryBase::~wxTextEntryBase()
+{
+ delete m_hintData;
+}
+
+// ----------------------------------------------------------------------------
+// text operations
+// ----------------------------------------------------------------------------
+
wxString wxTextEntryBase::GetRange(long from, long to) const
{
wxString sel;
WriteText(value);
}
+// ----------------------------------------------------------------------------
+// selection
+// ----------------------------------------------------------------------------
+
bool wxTextEntryBase::HasSelection() const
{
long from, to;
return GetRange(from, to);
}
+// ----------------------------------------------------------------------------
+// clipboard
+// ----------------------------------------------------------------------------
+
bool wxTextEntryBase::CanCopy() const
{
return HasSelection();
return false;
}
+// ----------------------------------------------------------------------------
+// hints support
+// ----------------------------------------------------------------------------
+
+bool wxTextEntryBase::SetHint(const wxString& hint)
+{
+ if ( !m_hintData )
+ m_hintData = new wxTextEntryHintData(this, GetEditableWindow());
+
+ m_hintData->SetHintString(hint);
+
+ return true;
+}
+
+wxString wxTextEntryBase::GetHint() const
+{
+ return m_hintData ? m_hintData->GetHintString() : wxString();
+}
+
#endif // wxUSE_TEXTCTRL || wxUSE_COMBOBOX
#include "wx/wupdlock.h"
#include "wx/msw/private.h"
+#if wxUSE_UXTHEME
+ #include "wx/msw/uxtheme.h"
+#endif
+
#if wxUSE_TOOLTIPS
#include "wx/tooltip.h"
#endif // wxUSE_TOOLTIPS
return hWndEdit;
}
+wxWindow *wxComboBox::GetEditableWindow()
+{
+ wxASSERT_MSG( !HasFlag(wxCB_READONLY),
+ _T("read-only combobox doesn't have any edit control") );
+
+ return this;
+}
+
// ----------------------------------------------------------------------------
// wxComboBox creation
// ----------------------------------------------------------------------------
#endif // wxUSE_TOOLTIPS
+#if wxUSE_UXTHEME
+
+bool wxComboBox::SetHint(const wxString& hintOrig)
+{
+ wxString hint(hintOrig);
+ if ( wxUxThemeEngine::GetIfActive() )
+ {
+ // under XP (but not Vista) there is a bug in cue banners
+ // implementation for combobox edit control: the first character is
+ // partially chopped off, so prepend a space to make it fully visible
+ hint.insert(0, " ");
+ }
+
+ return wxTextEntry::SetHint(hint);
+}
+
+#endif // wxUSE_UXTHEME
+
#endif // wxUSE_COMBOBOX
#include "wx/msw/private.h"
+#if wxUSE_UXTHEME
+ #include "wx/msw/uxtheme.h"
+#endif
+
#define GetEditHwnd() ((HWND)(GetEditHWND()))
// ----------------------------------------------------------------------------
::SendMessage(GetEditHwnd(), EM_LIMITTEXT, len, 0);
}
+// ----------------------------------------------------------------------------
+// hints
+// ----------------------------------------------------------------------------
+
+#if wxUSE_UXTHEME
+
+#ifndef EM_SETCUEBANNER
+ #define EM_SETCUEBANNER 0x1501
+ #define EM_GETCUEBANNER 0x1502
+#endif
+
+bool wxTextEntry::SetHint(const wxString& hint)
+{
+ if ( wxUxThemeEngine::GetIfActive() )
+ {
+ // notice that this message always works with Unicode strings
+ if ( ::SendMessage(GetEditHwnd(), EM_SETCUEBANNER,
+ 0, (LPARAM)(const wchar_t *)hint.wc_str()) )
+ return true;
+ }
+
+ return wxTextEntryBase::SetHint(hint);
+}
+
+wxString wxTextEntry::GetHint() const
+{
+ if ( wxUxThemeEngine::GetIfActive() )
+ {
+ wchar_t buf[256];
+ if ( ::SendMessage(GetEditHwnd(), EM_GETCUEBANNER,
+ (WPARAM)buf, WXSIZEOF(buf)) )
+ return buf;
+ }
+
+ return wxTextEntryBase::GetHint();
+}
+
+
+#endif // wxUSE_UXTHEME
+
#endif // wxUSE_TEXTCTRL || wxUSE_COMBOBOX