diff --git a/src/gui/edittext.cc b/src/gui/edittext.cc index 9db1e7a07..8c54e3900 100644 --- a/src/gui/edittext.cc +++ b/src/gui/edittext.cc @@ -68,6 +68,9 @@ EditableText::EditableText(wxWindow *p_parent, int p_id, const wxString &p_value Connect(m_textCtrl->GetId(), wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(EditableText::OnAccept)); + m_textCtrl->Bind(wxEVT_KILL_FOCUS, &EditableText::OnTextKillFocus, this); + m_textCtrl->Bind(wxEVT_CHAR_HOOK, &EditableText::OnTextCharHook, this); + auto *topSizer = new wxBoxSizer(wxHORIZONTAL); topSizer->Add(m_staticText, 1, wxALIGN_CENTER, 0); topSizer->Add(m_textCtrl, 1, wxEXPAND, 0); @@ -97,6 +100,33 @@ void EditableText::EndEdit(bool p_accept) GetSizer()->Layout(); } +void EditableText::AcceptEdit() +{ + if (!IsEditing() || m_endingEdit) { + return; + } + + m_endingEdit = true; + EndEdit(true); + + wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER); + event.SetId(GetId()); + wxPostEvent(GetParent(), event); + + m_endingEdit = false; +} + +void EditableText::CancelEdit() +{ + if (!IsEditing() || m_endingEdit) { + return; + } + + m_endingEdit = true; + EndEdit(false); + m_endingEdit = false; +} + wxString EditableText::GetValue() const { @@ -142,11 +172,22 @@ void EditableText::OnClick(wxCommandEvent &) wxPostEvent(GetParent(), event); } -void EditableText::OnAccept(wxCommandEvent &) +void EditableText::OnAccept(wxCommandEvent &) { AcceptEdit(); } + +void EditableText::OnTextKillFocus(wxFocusEvent &p_event) { - EndEdit(true); - wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER); - event.SetId(GetId()); - wxPostEvent(GetParent(), event); + AcceptEdit(); + p_event.Skip(); } + +void EditableText::OnTextCharHook(wxKeyEvent &p_event) +{ + if (p_event.GetKeyCode() == WXK_ESCAPE && IsEditing()) { + CancelEdit(); + return; + } + + p_event.Skip(); +} + } // namespace Gambit::GUI diff --git a/src/gui/edittext.h b/src/gui/edittext.h index 688ff1962..2f7a62625 100644 --- a/src/gui/edittext.h +++ b/src/gui/edittext.h @@ -47,14 +47,23 @@ class EditableText : public wxPanel { StaticTextButton *m_staticText; wxTextCtrl *m_textCtrl; + bool m_endingEdit = false; + /// @name Event handlers //@{ /// Called when the static text is clicked void OnClick(wxCommandEvent &); /// Called when the text control is dismissed via enter void OnAccept(wxCommandEvent &); + /// Called when the text control loses focus + void OnTextKillFocus(wxFocusEvent &); + /// Called to intercept Escape while editing + void OnTextCharHook(wxKeyEvent &); //@} + void AcceptEdit(); + void CancelEdit(); + public: EditableText(wxWindow *p_parent, int p_id, const wxString &p_value, const wxPoint &p_position, const wxSize &p_size); @@ -66,12 +75,9 @@ class EditableText : public wxPanel { wxString GetValue() const; void SetValue(const wxString &p_value); - // @name Overriding wxWindow methods - //@{ bool SetForegroundColour(const wxColour &) override; bool SetBackgroundColour(const wxColour &) override; bool SetFont(const wxFont &) override; - //@} }; } // namespace Gambit::GUI diff --git a/src/gui/efgpanel.cc b/src/gui/efgpanel.cc index 555989bb5..767a49bb8 100644 --- a/src/gui/efgpanel.cc +++ b/src/gui/efgpanel.cc @@ -294,14 +294,17 @@ void gbtTreePlayerPanel::OnAcceptPlayerLabel(wxCommandEvent &) void gbtTreePlayerPanel::PostPendingChanges() { - if (m_playerLabel->IsEditing()) { - m_playerLabel->EndEdit(true); - try { - m_doc->DoSetPlayerLabel(m_doc->GetGame()->GetPlayer(m_player), m_playerLabel->GetValue()); - } - catch (std::exception &ex) { - ExceptionDialog(this, ex.what()).ShowModal(); - } + if (!m_playerLabel->IsEditing()) { + return; + } + m_playerLabel->EndEdit(true); + try { + m_doc->DoSetPlayerLabel(m_doc->GetGame()->GetPlayer(m_player), m_playerLabel->GetValue()); + } + catch (std::exception &ex) { + ExceptionDialog(this, ex.what()).ShowModal(); + m_playerLabel->SetValue( + wxString(m_doc->GetGame()->GetPlayer(m_player)->GetLabel().c_str(), *wxConvCurrent)); } } diff --git a/src/gui/nfgpanel.cc b/src/gui/nfgpanel.cc index f483c78e1..2fc3902d2 100644 --- a/src/gui/nfgpanel.cc +++ b/src/gui/nfgpanel.cc @@ -231,14 +231,17 @@ void TablePlayerPanel::OnAcceptPlayerLabel(wxCommandEvent &) void TablePlayerPanel::PostPendingChanges() { - if (m_playerLabel->IsEditing()) { - m_playerLabel->EndEdit(true); - try { - m_doc->DoSetPlayerLabel(m_doc->GetGame()->GetPlayer(m_player), m_playerLabel->GetValue()); - } - catch (std::exception &ex) { - ExceptionDialog(this, ex.what()).ShowModal(); - } + if (!m_playerLabel->IsEditing()) { + return; + } + m_playerLabel->EndEdit(true); + try { + m_doc->DoSetPlayerLabel(m_doc->GetGame()->GetPlayer(m_player), m_playerLabel->GetValue()); + } + catch (std::exception &ex) { + ExceptionDialog(this, ex.what()).ShowModal(); + m_playerLabel->SetValue( + wxString(m_doc->GetGame()->GetPlayer(m_player)->GetLabel().c_str(), *wxConvCurrent)); } }