X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2b42a87073839b2b31c105f08080626ba32b40e3..81533a3af6ed598c32a35e1c1c2b60f4908f5541:/src/common/textentrycmn.cpp?ds=sidebyside diff --git a/src/common/textentrycmn.cpp b/src/common/textentrycmn.cpp index 4adca176b0..9dc8ca9461 100644 --- a/src/common/textentrycmn.cpp +++ b/src/common/textentrycmn.cpp @@ -33,10 +33,113 @@ #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); + + // we don't have any hint yet + m_showsHint = false; + } + + // default dtor is ok + + // are we showing the hint right now? + bool ShowsHint() const { return m_showsHint; } + + void SetHintString(const wxString& hint) + { + m_hint = hint; + + if ( m_showsHint ) + { + // update it immediately + m_entry->ChangeValue(hint); + } + //else: the new hint will be shown later + } + + const wxString& GetHintString() const { return m_hint; } + +private: + void OnSetFocus(wxFocusEvent& event) + { + // hide the hint if we were showing it + if ( m_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); + + m_showsHint = false; + } + + 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); + + m_showsHint = true; + } + + event.Skip(); + } + + // the text control we're associated with (as its interface and its window) + wxTextEntryBase * const m_entry; + wxWindow * const m_win; + + // the original foreground colour of m_win before we changed it + wxColour m_colFg; + + // the hint passed to wxTextEntry::SetHint() + wxString m_hint; + + // true if we're currently showing it, for this we must be empty and not + // have focus + bool m_showsHint; + + wxDECLARE_NO_COPY_CLASS(wxTextEntryHintData); +}; + // ============================================================================ // wxTextEntryBase implementation // ============================================================================ +wxTextEntryBase::~wxTextEntryBase() +{ + delete m_hintData; +} + +// ---------------------------------------------------------------------------- +// text accessors +// ---------------------------------------------------------------------------- + +wxString wxTextEntryBase::GetValue() const +{ + return m_hintData && m_hintData->ShowsHint() ? wxString() : DoGetValue(); +} + wxString wxTextEntryBase::GetRange(long from, long to) const { wxString sel; @@ -50,6 +153,10 @@ wxString wxTextEntryBase::GetRange(long from, long to) const return sel; } +// ---------------------------------------------------------------------------- +// text operations +// ---------------------------------------------------------------------------- + void wxTextEntryBase::AppendText(const wxString& text) { SetInsertionPointEnd(); @@ -62,6 +169,8 @@ void wxTextEntryBase::DoSetValue(const wxString& value, int flags) SelectAll(); WriteText(value); + + SetInsertionPoint(0); } void wxTextEntryBase::Replace(long from, long to, const wxString& value) @@ -71,9 +180,14 @@ void wxTextEntryBase::Replace(long from, long to, const wxString& value) Remove(from, to); } + SetInsertionPoint(from); WriteText(value); } +// ---------------------------------------------------------------------------- +// selection +// ---------------------------------------------------------------------------- + bool wxTextEntryBase::HasSelection() const { long from, to; @@ -98,6 +212,10 @@ wxString wxTextEntryBase::GetStringSelection() const return GetRange(from, to); } +// ---------------------------------------------------------------------------- +// clipboard +// ---------------------------------------------------------------------------- + bool wxTextEntryBase::CanCopy() const { return HasSelection(); @@ -128,4 +246,58 @@ bool wxTextEntryBase::CanPaste() const 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(); +} + +// ---------------------------------------------------------------------------- +// margins support +// ---------------------------------------------------------------------------- + +bool wxTextEntryBase::DoSetMargins(const wxPoint& WXUNUSED(pt)) +{ + return false; +} + +wxPoint wxTextEntryBase::DoGetMargins() const +{ + return wxPoint(-1, -1); +} + +// ---------------------------------------------------------------------------- +// events +// ---------------------------------------------------------------------------- + +/* static */ +bool wxTextEntryBase::SendTextUpdatedEvent(wxWindow *win) +{ + wxCHECK_MSG( win, false, "can't send an event without a window" ); + + wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, win->GetId()); + + // do not do this as it could be very inefficient if the text control + // contains a lot of text and we're not using ref-counted wxString + // implementation -- instead, event.GetString() will query the control for + // its current text if needed + //event.SetString(win->GetValue()); + + event.SetEventObject(win); + return win->HandleWindowEvent(event); +} + #endif // wxUSE_TEXTCTRL || wxUSE_COMBOBOX