Support for multi-stage keyboard sequences added

This commit is contained in:
Simon Rozman 2016-03-08 13:26:16 +01:00
parent 87b80bb8c4
commit 74d076861b
2 changed files with 25 additions and 6 deletions

View File

@ -61,21 +61,29 @@ bool wxZRColaKeyHandler::ProcessEvent(wxEvent& event)
bool found; bool found;
{ {
// Parse key event and save it at the end of the key sequence.
wxKeyEvent &e = (wxKeyEvent&)event; wxKeyEvent &e = (wxKeyEvent&)event;
ZRCola::keyseq_db::keyseq *ks = (ZRCola::keyseq_db::keyseq*)new char[sizeof(ZRCola::keyseq_db::keyseq) + sizeof(ZRCola::keyseq_db::keyseq::key_t)*1]; ZRCola::keyseq_db::keyseq::key_t key;
ks->chr = 0; key.key = wxToupper(e.m_uniChar);
ks->seq_len = 1; key.modifiers =
ks->seq[0].key = wxToupper(e.m_uniChar);
ks->seq[0].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);
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];
ks->chr = 0;
ks->seq_len = n;
memcpy(ks->seq, m_seq.data(), sizeof(ZRCola::keyseq_db::keyseq::key_t)*n);
found = m_ks_db.idxKey.find((const unsigned __int16&)*ks, start, end); found = m_ks_db.idxKey.find((const unsigned __int16&)*ks, start, end);
delete ks; delete ks;
} }
if (found) { if (found) {
// The exact key sequence found.
const ZRCola::keyseq_db::keyseq &ks = (const ZRCola::keyseq_db::keyseq&)m_ks_db.data[m_ks_db.idxKey[start]]; const ZRCola::keyseq_db::keyseq &ks = (const ZRCola::keyseq_db::keyseq&)m_ks_db.data[m_ks_db.idxKey[start]];
m_seq.clear();
wxObject *obj = event.GetEventObject(); wxObject *obj = event.GetEventObject();
if (obj && obj->IsKindOf(wxCLASSINFO(wxTextCtrl))) { if (obj && obj->IsKindOf(wxCLASSINFO(wxTextCtrl))) {
@ -86,6 +94,15 @@ bool wxZRColaKeyHandler::ProcessEvent(wxEvent& event)
event.StopPropagation(); event.StopPropagation();
return true; return true;
} }
} else if (start < m_ks_db.idxKey.size() &&
ZRCola::keyseq_db::keyseq::CompareSequence(m_seq.data(), m_seq.size(), ((const ZRCola::keyseq_db::keyseq&)m_ks_db.data[m_ks_db.idxKey[start]]).seq, std::min<unsigned __int16>(((const ZRCola::keyseq_db::keyseq&)m_ks_db.data[m_ks_db.idxKey[start]]).seq_len, m_seq.size())) == 0)
{
// The sequence is a partial match. Continue watching.
event.StopPropagation();
return true;
} else {
// The key sequence has no future chance to match. Start all over again.
m_seq.clear();
} }
} }

View File

@ -27,6 +27,7 @@ class wxZRColaKeyHandler;
#include <zrcolaui/keyboard.h> #include <zrcolaui/keyboard.h>
#include <wx/event.h> #include <wx/event.h>
#include <vector>
/// ///
@ -41,4 +42,5 @@ public:
protected: protected:
ZRCola::keyseq_db m_ks_db; ///< Key sequence database ZRCola::keyseq_db m_ks_db; ///< Key sequence database
std::vector<ZRCola::keyseq_db::keyseq::key_t> m_seq; ///< Key sequence
}; };