Keyboard sequence monitoring upgraded not to react on modifier keys, canceling multi-key sequences when non-first key modifier pressed

This commit is contained in:
Simon Rozman 2016-04-07 14:49:28 +02:00
parent 834743c7dd
commit 426b7a6227

View File

@ -54,62 +54,64 @@ bool wxZRColaKeyHandler::ProcessEvent(wxEvent& event)
{ {
if (event.GetEventType() == wxEVT_KEY_DOWN) { if (event.GetEventType() == wxEVT_KEY_DOWN) {
// The character event occured. // The character event occured.
ZRCola::keyseq_db::indexKey::size_type start, end; wxKeyEvent &e = (wxKeyEvent&)event;
bool found; if (e.GetUnicodeKey() || !e.HasAnyModifiers()) {
wxFrame *pFrame = wxDynamicCast(wxTheApp->GetTopWindow(), wxFrame); ZRCola::keyseq_db::indexKey::size_type start, end;
bool found;
wxFrame *pFrame = wxDynamicCast(wxTheApp->GetTopWindow(), wxFrame);
{ {
// Parse key event and save it at the end of the key sequence. // Parse key event and save it at the end of the key sequence.
wxKeyEvent &e = (wxKeyEvent&)event; ZRCola::keyseq_db::keyseq::key_t key;
ZRCola::keyseq_db::keyseq::key_t key; key.key = e.GetKeyCode(); //wxToupper(e.m_uniChar);
key.key = e.GetKeyCode(); //wxToupper(e.m_uniChar); key.modifiers =
key.modifiers = (e.ShiftDown() ? ZRCola::keyseq_db::keyseq::SHIFT : 0) |
(e.ShiftDown() ? ZRCola::keyseq_db::keyseq::SHIFT : 0) | (e.ControlDown() ? ZRCola::keyseq_db::keyseq::CTRL : 0) |
(e.ControlDown() ? ZRCola::keyseq_db::keyseq::CTRL : 0) | (e.AltDown() ? ZRCola::keyseq_db::keyseq::ALT : 0);
(e.AltDown() ? ZRCola::keyseq_db::keyseq::ALT : 0); m_seq.push_back(key);
m_seq.push_back(key);
std::vector<ZRCola::keyseq_db::keyseq::key_t>::size_type n = m_seq.size(); std::vector<ZRCola::keyseq_db::keyseq::key_t>::size_type n = m_seq.size();
ZRCola::keyseq_db::keyseq *ks = (ZRCola::keyseq_db::keyseq*)new char[sizeof(ZRCola::keyseq_db::keyseq) + sizeof(ZRCola::keyseq_db::keyseq::key_t)*n]; ZRCola::keyseq_db::keyseq *ks = (ZRCola::keyseq_db::keyseq*)new char[sizeof(ZRCola::keyseq_db::keyseq) + sizeof(ZRCola::keyseq_db::keyseq::key_t)*n];
ks->chr = 0; ks->chr = 0;
ks->seq_len = n; ks->seq_len = n;
memcpy(ks->seq, m_seq.data(), sizeof(ZRCola::keyseq_db::keyseq::key_t)*n); memcpy(ks->seq, m_seq.data(), sizeof(ZRCola::keyseq_db::keyseq::key_t)*n);
found = m_ks_db.idxKey.find(*ks, start, end); found = m_ks_db.idxKey.find(*ks, start, end);
delete ks; delete ks;
} }
if (found) { if (found) {
// The exact key sequence found. // The exact key sequence found.
const ZRCola::keyseq_db::keyseq &ks = m_ks_db.idxKey[start]; const ZRCola::keyseq_db::keyseq &ks = m_ks_db.idxKey[start];
m_seq.clear(); m_seq.clear();
if (pFrame && pFrame->GetStatusBar()) if (pFrame && pFrame->GetStatusBar())
pFrame->SetStatusText(wxEmptyString); pFrame->SetStatusText(wxEmptyString);
wxObject *obj = event.GetEventObject(); wxObject *obj = event.GetEventObject();
if (obj && obj->IsKindOf(wxCLASSINFO(wxTextCtrl))) { if (obj && obj->IsKindOf(wxCLASSINFO(wxTextCtrl))) {
// Push text to source control. // Push text to source control.
((wxTextCtrl*)obj)->WriteText(ks.chr); ((wxTextCtrl*)obj)->WriteText(ks.chr);
// Event is fully processed now.
event.StopPropagation();
return true;
}
} else if (start < m_ks_db.idxKey.size() &&
ZRCola::keyseq_db::keyseq::CompareSequence(m_seq.data(), m_seq.size(), m_ks_db.idxKey[start].seq, std::min<unsigned __int16>(m_ks_db.idxKey[start].seq_len, m_seq.size())) == 0)
{
// The sequence is a partial match. Continue watching.
if (pFrame && pFrame->GetStatusBar())
pFrame->SetStatusText(ZRCola::keyseq_db::GetSequenceAsText(m_seq.data(), m_seq.size()));
// Event is fully processed now.
event.StopPropagation(); event.StopPropagation();
return true; return true;
} else {
// The key sequence has no future chance to match. Start all over again.
m_seq.clear();
if (pFrame && pFrame->GetStatusBar())
pFrame->SetStatusText(wxEmptyString);
} }
} else if (start < m_ks_db.idxKey.size() &&
ZRCola::keyseq_db::keyseq::CompareSequence(m_seq.data(), m_seq.size(), m_ks_db.idxKey[start].seq, std::min<unsigned __int16>(m_ks_db.idxKey[start].seq_len, m_seq.size())) == 0)
{
// The sequence is a partial match. Continue watching.
if (pFrame && pFrame->GetStatusBar())
pFrame->SetStatusText(ZRCola::keyseq_db::GetSequenceAsText(m_seq.data(), m_seq.size()));
event.StopPropagation();
return true;
} else {
// The key sequence has no future chance to match. Start all over again.
m_seq.clear();
if (pFrame && pFrame->GetStatusBar())
pFrame->SetStatusText(wxEmptyString);
} }
} }