From 5ce74c7bd5d885e5b1d38a084b8a2c8032708e6a Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 29 Jul 2020 09:17:45 -0700 Subject: [PATCH] Qt extended command selection Qt's implementation of '#' puts up a rectangular grid of buttons containing command names from the alphabetized extcmdlist[]: | # ? adjust annotate | apply attributes autopickup call | cast ... When 3.6 put all commands into that list, the hardcoded 4 columns resulted in so many rows that the grid wouldn't fit on the screen (at least not on my smallish laptop screen). There's no scrollbar so the commands beyond "takeoff" were inaccessible off the bottom. Warning messages from within Qt were issued to stderr complaining about trying to render something off the screen (once each time the '#' command grid was generated). It was also including wizard mode commands when not in wizard mode. Suppress those when they're not applicable, and change the grid to use 6 columns then and 8 for wizard mode. The appropriate amount ought to be calculated on the fly but these values work ok with the current command list. (On my screen; if something smaller is used, the original problem could come back, just not as severe as before.) Having an alphabetized list go across rows instead of down columns feels counter-intuitive so transpose the grid. | # autopickup ... | ? call | adjust cast | annotate ... | apply [Having another button next to that lets the user switch back and forth between the two orientations could be worthwhile. A full-fledged wc/wc2 option for that doesn't seem warranted.] The commands can be selected by typing their names as an alternative to mouse click. The input widget supports but lacked handling for so add that. When typing a command by its name, a new grid showing only matching candidates gets displayed so that you can switch back to mouse input. It looks pretty bad but does work as intended. I didn't touch that; however, it looks different now due to the columns-vs-rows change. The menu after picking "?" looks worse. It assumes a fixed width font and tries to align things in two columns with spaces, but the result when using a variable width font is ugly. This makes no attempt to address that. --- doc/fixes37.0 | 9 +++++- win/Qt/qt_xcmd.cpp | 71 ++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 67 insertions(+), 13 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 351b66114..ec4a8f2b8 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.258 $ $NHDT-Date: 1595787211 2020/07/26 18:13:31 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.260 $ $NHDT-Date: 1596039461 2020/07/29 16:17:41 $ General Fixes and Modified Features ----------------------------------- @@ -322,6 +322,13 @@ curses: for vertical status, line up conditions in columns; usually two but msdos: add -DSTATUES_LOOK_LIKE_MONSTERS to Makefile1.cross so the VESA mode can display statue glyphs Qt: quit if can't load tiles file instead of continuing and then segfaulting +Qt: use more columns for extended command selection dialog so that the number + of rows needed doesn't result in some commands being unaccessible +Qt: suppress wizard mode commands from '#' handling when not in wizard mode +Qt: organize extended command selection grid by columns instead of by rows + (first N entries down left column, next N entries down 2nd column, &c) +Qt: when selecting an extended command by typing its name, support + (aka ) in addition to to go back a character tiles: add indicator of thonged portion to aklys tile tty: role and race selection menus weren't filtering out potential choices which got excluded by OPTIONS=align:!lawful or !neutral or !chaotic diff --git a/win/Qt/qt_xcmd.cpp b/win/Qt/qt_xcmd.cpp index 4eb9ac4a5..448f66dfe 100644 --- a/win/Qt/qt_xcmd.cpp +++ b/win/Qt/qt_xcmd.cpp @@ -34,6 +34,14 @@ namespace nethack_qt_ { void centerOnMain(QWidget *); // end temporary +static inline bool +interesting_command(unsigned indx) +{ + return (!(extcmdlist[indx].flags & CMD_NOT_AVAILABLE) + /* 'wizard' is #undef'd above [why?] so rely on its internals */ + && (flags.debug || !(extcmdlist[indx].flags & WIZMODECMD))); +} + NetHackQtExtCmdRequestor::NetHackQtExtCmdRequestor(QWidget *parent) : QDialog(parent) { @@ -51,24 +59,56 @@ NetHackQtExtCmdRequestor::NetHackQtExtCmdRequestor(QWidget *parent) : QGroupBox *grid=new QGroupBox("Extended commands",this); l->addWidget(grid); - int i; - int butw=50; + unsigned i, j, ncmds = 0; + int butw = 50; QFontMetrics fm = fontMetrics(); - for (i=0; extcmdlist[i].ef_txt; i++) { - butw = std::max(butw,30+fm.width(extcmdlist[i].ef_txt)); + for (i = 0; extcmdlist[i].ef_txt; ++i) { + if (interesting_command(i)) { + ++ncmds; + butw = std::max(butw, 30 + fm.width(extcmdlist[i].ef_txt)); + } } - int ncols=4; + + /* 'ncols' should be calculated to fit (or enable a vertical scrollbar + when its so big it forces too many rows, if GroupBox supports that); + it used to be hardcoded 4 but after every command became accessible + as an extended command, that resulted in so many rows that some of + the buttoms were chopped off at the bottom of the grid */ + unsigned ncols = !flags.debug ? 6 : 8, + nrows = (ncmds + ncols - 1) / ncols; + /* + * Choose grid layout. This ought to selected via a button that can + * be used to toggle the setting back and forth. + * + * by row vs by column + * a b a e + * c d b f + * e f c g + * g d + * + * Prior to 3.7, it was always by-row, but by-column is more natural + * for an alphabetized list. + */ + bool by_column = true; QVBoxLayout* bl = new QVBoxLayout(grid); bl->addSpacing(fm.height()); QGridLayout* gl = new QGridLayout(); bl->addLayout(gl); - for (i=0; extcmdlist[i].ef_txt; i++) { - QPushButton* pb=new QPushButton(extcmdlist[i].ef_txt, grid); - pb->setMinimumSize(butw,pb->sizeHint().height()); - group->addButton(pb, i+1); - gl->addWidget(pb,i/ncols,i%ncols); - buttons.append(pb); + for (i = j = 0; extcmdlist[i].ef_txt; ++i) { + if (interesting_command(i)) { + QPushButton *pb = new QPushButton(extcmdlist[i].ef_txt, grid); + pb->setMinimumSize(butw, pb->sizeHint().height()); + group->addButton(pb, i + 1); + if (by_column) + /* 0..R-1 down first column, R..2*R-1 down second column,...*/ + gl->addWidget(pb, j % nrows, j / nrows); + else + /* 0..C-1 across first row, C..2*C-1 across second row, ... */ + gl->addWidget(pb, j / ncols, j % ncols); + buttons.append(pb); + ++j; + } } group->addButton(can, 0); connect(group,SIGNAL(buttonPressed(int)),this,SLOT(done(int))); @@ -90,7 +130,7 @@ void NetHackQtExtCmdRequestor::keyPressEvent(QKeyEvent *event) { reject(); } - else if (text == "\b") + else if (text == "\b" || text == "\177") { QString promptstr = prompt->text(); if (promptstr != "#") @@ -104,6 +144,8 @@ void NetHackQtExtCmdRequestor::keyPressEvent(QKeyEvent *event) unsigned matches = 0; unsigned match = 0; for (unsigned i=0; extcmdlist[i].ef_txt; i++) { + if (!interesting_command(i)) + continue; if (QString(extcmdlist[i].ef_txt).startsWith(typedstr)) { ++matches; if (matches >= 2) @@ -136,6 +178,11 @@ int NetHackQtExtCmdRequestor::get() return result()-1; } +/* + * FIXME: + * This looks terrible. [Possibly a difference between initial + * implementation using Qt2 and the current Qt version?] + */ // Enable only buttons that match the current prompt string void NetHackQtExtCmdRequestor::enableButtons() {