From: PatR Date: Fri, 8 Jan 2021 21:47:34 +0000 (-0800) Subject: Qt key handling X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2c02d5daacf8d610cd34ce8b67cd56e212798201;p=nethack Qt key handling Fix the popup versions of qt_yn_function() to handle control characters by using the same key press event decoding routine and menus and extended commands. Moves 'keyValue()' to qt_key.cpp and its declaration to qt_key.h, requring several files to start using #include "qt_key.h". 'make depend' update to follow. --- diff --git a/win/Qt/qt_key.cpp b/win/Qt/qt_key.cpp index 060fc1eed..0fe959545 100644 --- a/win/Qt/qt_key.cpp +++ b/win/Qt/qt_key.cpp @@ -15,18 +15,51 @@ extern "C" { namespace nethack_qt_ { +// convert a Qt key event into a simple ASCII character +uchar keyValue(QKeyEvent *key_event) +{ + // key_event manipulation derived from NetHackQtBind::notify(); + // used for menus and text windows in qt_menu.cpp, also for + // extended commands in xcmd.cpp and popup yn_function in qt_yndlg.cpp + + const int k = key_event->key(); + Qt::KeyboardModifiers mod = key_event->modifiers(); + const QString &txt = key_event->text(); + QChar ch = !txt.isEmpty() ? txt.at(0) : 0; + + if (ch >= 128) + ch = 0; + // on OSX, ascii control codes are not sent, force them + if (ch == 0 && (mod & Qt::ControlModifier) != 0) { + if (k >= Qt::Key_A && k <= Qt::Key_Underscore) + ch = QChar((k - (Qt::Key_A - 1))); + } + + uchar result = (uchar) ch.cell(); + //raw_printf("kV: k=%d, ch=%u", k, (unsigned) result); + return result; +} + NetHackQtKeyBuffer::NetHackQtKeyBuffer() : in(0), out(0) { } -bool NetHackQtKeyBuffer::Empty() const { return in==out; } -bool NetHackQtKeyBuffer::Full() const { return (in+1)%maxkey==out; } +bool NetHackQtKeyBuffer::Empty() const +{ + return (in == out); +} + +bool NetHackQtKeyBuffer::Full() const +{ + return (((in + 1) % maxkey) == out); +} void NetHackQtKeyBuffer::Put(int k, int a, uint kbstate) { //raw_printf("k:%3d a:'%s' s:0x%08x", k, visctrl((char) a), kbstate); - if ( Full() ) return; // Safety + if (Full()) + return; // Safety key[in] = k; ascii[in] = a; state[in] = (Qt::KeyboardModifiers) kbstate; diff --git a/win/Qt/qt_key.h b/win/Qt/qt_key.h index a96c0a07f..f2e2c2084 100644 --- a/win/Qt/qt_key.h +++ b/win/Qt/qt_key.h @@ -9,6 +9,9 @@ namespace nethack_qt_ { +// not part of any class; used in qt_menu.cpp, qt_xcmd.cpp, qt_yndlg.cpp +extern uchar keyValue(QKeyEvent *key_event); + class NetHackQtKeyBuffer { public: NetHackQtKeyBuffer(); diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index e02cd3d40..b86e7484f 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -37,6 +37,7 @@ extern "C" { #include "qt_post.h" #include "qt_menu.h" #include "qt_menu.moc" +#include "qt_key.h" // for keyValue() #include "qt_glyph.h" #include "qt_set.h" #include "qt_streq.h" @@ -55,24 +56,6 @@ namespace nethack_qt_ { void centerOnMain( QWidget* w ); // end temporary -uchar keyValue(QKeyEvent *key_event) -{ - // key_event manipulation derived from NetHackQtBind::notify() - const int k = key_event->key(); - Qt::KeyboardModifiers mod = key_event->modifiers(); - QChar ch = !key_event->text().isEmpty() ? key_event->text().at(0) : 0; - if (ch >= 128) - ch = 0; - // on OSX, ascii control codes are not sent, force them - if (ch == 0 && (mod & Qt::ControlModifier) != 0) { - if (k >= Qt::Key_A && k <= Qt::Key_Underscore) - ch = QChar((k - (Qt::Key_A - 1))); - } - uchar result = (uchar) ch.cell(); - //raw_printf("kV: k=%d, ch=%d", k, result); - return result; -} - QSize NetHackQtTextListBox::sizeHint() const { QScrollBar *hscroll = horizontalScrollBar(); diff --git a/win/Qt/qt_menu.h b/win/Qt/qt_menu.h index 18be9e732..e69265a4f 100644 --- a/win/Qt/qt_menu.h +++ b/win/Qt/qt_menu.h @@ -15,8 +15,6 @@ namespace nethack_qt_ { -extern uchar keyValue(QKeyEvent *key_event); // also used in qt_xcmd.cpp - class NetHackQtTextListBox : public QListWidget { public: NetHackQtTextListBox(QWidget* parent = NULL) : QListWidget(parent) { } diff --git a/win/Qt/qt_xcmd.cpp b/win/Qt/qt_xcmd.cpp index 686ce0490..bd9aff6a1 100644 --- a/win/Qt/qt_xcmd.cpp +++ b/win/Qt/qt_xcmd.cpp @@ -90,6 +90,7 @@ extern "C" { #include "qt_post.h" #include "qt_xcmd.h" #include "qt_xcmd.moc" +#include "qt_key.h" // for keyValue() #include "qt_bind.h" #include "qt_set.h" #include "qt_str.h" diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index 836e13042..6d1941122 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -16,6 +16,7 @@ extern "C" { #include "qt_post.h" #include "qt_yndlg.h" #include "qt_yndlg.moc" +#include "qt_key.h" // for keyValue() #include "qt_str.h" // temporary @@ -369,14 +370,12 @@ void NetHackQtYnDialog::AltChoice(char ans, char res) } } -void NetHackQtYnDialog::keyPressEvent(QKeyEvent* event) +void NetHackQtYnDialog::keyPressEvent(QKeyEvent *event) { - keypress = '\0'; - QString text(event->text()); - if (text.isEmpty()) /* && event->modifiers()) */ + keypress = keyValue(event); + if (!keypress) return; - keypress = text.at(0).cell(); char *p = NULL; if (*alt_answer && (p = strchr(alt_answer, keypress)) != 0) keypress = alt_result[p - alt_answer]; @@ -388,13 +387,13 @@ void NetHackQtYnDialog::keyPressEvent(QKeyEvent* event) int where = QString::fromLatin1(choices).indexOf(QChar(keypress)); if (allow_count && strchr("#0123456789", keypress)) { - if (text == "#") { + if (keypress == '#') { // 0 will be preselected; typing anything replaces it le->setText(QString("0")); le->home(true); } else { // digit will not be preselected; typing another appends - le->setText(text); + le->setText(QChar(keypress)); le->end(false); } // (don't know whether this actually does anything useful)