Sidenote: The main window size calculations are getting stupid.
It would be better to find out the widget sizes and shift
the splitter up, instead of letting it just take up half of the main window.
Idea and part of the code by Richard Henschel
The g? structs had a mix of variables that were written to
the savefile, and those that were not.
For better clarity and to distinguish those that end up in
the savefile, relocate some g? variables that get written
directly to the savefile into different structs.
This updates EDITLEVEL, although technically it probably
didn't need to, since savefile contents are not changing.
Details:
gb.bases -> svb.bases
gb.bbubbles -> svb.bbubbles
gb.branches -> svb.branches
gc.context -> svc.context
gd.disco -> svd.disco
gd.dndest -> svd.dndest
gd.doors -> svd.doors
gd.doors_alloc -> svd.doors_alloc
gd.dungeon_topology -> svd.dungeon_topology
gd.dungeons -> svd.dungeons
ge.exclusion_zones -> sve.exclusion_zones
gh.hackpid -> svh.hackpid
gi.inv_pos -> svi.inv_pos
gk.killer -> svk.killer
gl.lastseentyp -> svl.lastseentyp
gl.level -> svl.level
gl.level_info -> svl.level_info
gm.mapseenchn -> svm.mapseenchn
gm.moves -> svm.moves
gm.mvitals -> svm.mvitals
gn.n_dgns -> svn.n_dgns
gn.n_regions -> svn.n_regions
gn.nroom -> svn.nroom
go.oracle_cnt -> svo.oracle_cnt
gp.pl_character -> svp.pl_character
gp.pl_fruit -> svp.pl_fruit
gp.plname -> svp.plname
gp.program_state -> svp.program_state
gq.quest_status -> svq.quest_status
gr.rooms -> svr.rooms
gs.sp_levchn -> svs.sp_levchn
gs.spl_book -> svs.spl_book
gt.timer_id -> svt.timer_id
gt.tune -> svt.tune
gu.updest -> svu.updest
gx.xmax -> svx.xmax
gx.xmin -> svx.xmin
gy.ymax -> svy.ymax
gy.ymin -> svy.ymin
Related note:
There are some pointer variables that are heads of chains that were not
moved from 'g?' to 'sv?', because they are not actually written to the
savefile directly, but the objects/monst/trap/lightsource/timer in the
chains they point to are. That can be changed, if desired.
Examples: gi.invent, gm.migrating_objs, gb.billobjs, gm.migrating_mons,
gf.ftrap, gl.light_base, gt.timer_base
This fixes a lot of problems where a menu or a text window was up
and the main window accepted input - for example you could move around,
making another window of the same type pop up ...
Remove menu_color support from the window port side of the interface.
The window port just has to honor the color parameter that was added
to the add_menu() interface definition in June 2022 commit
2770223d10, and let the core-side of
the interface handle things.
To that end, this does the following:
Removes the #define of add_menu() from include/winprocs.h and add a
real core-side add_menu() function to windows.c which acts as a
trampoline to the window port win_add_menu() function, while providing
a single location to adjust the parameters passed to the window port
function. get_menu_coloring() is now called in there.
Moves get_menu_coloring() from options.c into windows.c and makes it
static.
Removes all the calls to get_menu_coloring() from the tty, Qt, X11,
curses, and win32 interfaces and adjusts their code to simply honor
the color parameter in add_menu, similar to what the menu_headings
change from earlier today did.
Instead of just accepting an attribute, it's now possible to
use a color, or both color and attribute, for example:
OPTIONS=menu_headings:inverse
OPTIONS=menu_headings:red
OPTIONS=menu_headings:red&underline
Default is still just inverse.
This lets the player change the menu heading color without
needing to use menu colors for them.
Also makes it so the core uses NO_COLOR instead of 0, for all
the menu lines which don't have any prefedefined color.
Tested for tty, curses, x11, qt, and win32
Funnel all potential "<action> called before we know if Menu or Text"
warnings through a common routine. Aside from rephrasing a message
which no one should ever see, there's no change in behavior.
Noticed when working on the add_menu() crash earlier, using a mouse
rather than the keyboard to pick an entry in the sub-sub menus for
'm O' -> 'disclose' -> {any disclosure category} didn't work properly.
The problem was in post-3.6.x menu code for the Qt interface.
I temporarily reverted the fix for end-of-game disclosure of overview
in order to trigger the add_menu() crash under Qt. It came down to
if (!actual) impossible("AddMenu called before we know if Menu or Text");
actual->AddMenu(glyph,identifier,ch,gch,attr,str,itemflags);
where 'actual' happens to be Null. impossible() gets called, goes
through pline() calling putmesg() and putstr(WIN_MESSAGE), then the
output never shows up anywhere. I haven't figured our what's going
on with that, but changing the above to
if (!actual)
impossible("AddMenu called before we know if Menu or Text");
else
actual->AddMenu(glyph, identifier, ch, gch, attr, str, itemflags);
at least prevents the crash. The main window ends up becoming
minimized/iconified but the final popups which occur after disclosure
appear and accept responses and then a clean exit takes place.
Presumably it used panic() rather than impossible() at some point,
otherwise that code makes no sense: test for Null then deference it
regardless of the result of the test?
The consolidation of global variables from scattered source
files into decl.c and declared in decl.h was begun in 3.7.0.
Their placement in common files was done for centralized
initialization and potential re-initialization during a
"play again" scenario.
It wasn't really necessary for all of them to be housed in a
single huge structure to meet the "play again" requirement,
and the single huge structure has been a little unwieldy when
it comes to maintenance.
Following this commit, instead of one single extremely large structure
named 'g' to house all of the relocated global variables, they
are distributed into several ga through gz.
To make things easy for the developer, each variable is placed
into the struct corresponding to the starting letter of the variable.
That way, no lookup is required in order to know which struct houses
a particular variable, it is a simple match to the starting letter
for all the centralized global variables.
A global variable named 'amulets', would be found in ga.
ga.amulets
^ ^
A global varable named 'move', would be found in gm.
gm.moves
^ ^
A global variable named 'val_for_n_or_more' would be found in gv.
gv.val_for_n_or_more
^ ^
A global variable named 'youmonst' would be found in gy.
gy.youmonst
^ ^
The test system is Slackware 14.2, which uses Qt 4.8.7.
* WANT_WIN_QT4 is defined, and has the expected meaning. Qt 5 is still
the default.
* The QT_NO_SOUND macro now excludes all headers and declarations
relating to sound; the multimedia package is not needed to build
(on any Qt 4, 5 or 6).
* A new function, nh_qsprintf, replaces QString::asprintf, for Qt
older than 5.5. These versions do not have QString::asprintf.
* DYNAMIC_STATUSLINES is disabled for Qt older than 5.9. These versions
do not have QSplitter::replaceWidget.
I forced a test compile to -std=c++20 mostly to see what we would
be up against. There was only a small number of things and they
are corrected in this commit.
c++20 has some issues with comparisons and bit twiddling between
different enums.
The vendor-supplied Qt5 header files triggered some of those issues as
well, so the qt_pre.h and qt_post.h NetHack header files were adjusted
to make those new warnings go away. I have not tested Qt6 under the
new compiler and c++ version yet.
Because there are multiple pragmas in qt_pre.h now, the conditional
ifdef structure in there was modified a little to make maintenance
simpler and have a single pragma push at the top. The pragma pop
comes after the Qt vendor-supplied header files, and is done
in qt_post.h.
The display.h macro cmap_to_glyph() was used in
a Qt c++ file and triggered a series of warnings because of that.
Rather than write c++20-friendly versions of those macros, the
simple fix is to provide a function on the C side of things
to front the cmap_to_glyph() macro, so fn_cmap_to_glyph()
was added.
Also thrown into this commit, PatR picked up on the fact that for
yesterday's new warning in qt_menu.cpp, the compiler had correctly
picked up on the fact that the format range of the variable 'cash'
had been correctly upper-capped at 999999999L in the warning message
because of an assignment prior. He suggested that perhaps by also adding
if (cash < 0)
cash = 0;
the warning might be eliminated altogether.
After a test, that was proven to be correct, so yesterday's
more-kludgy change is reverted and replaced with that variable
variable restriction ahead of the snprintf().
A test build with gcc-12 cause two new warnings to appear.
mkmaze.c: In function ‘makemaz’:
mkmaze.c:983:44: warning: ‘sprintf’ may write a terminating nul past the end of the destination [-Wformat-overflow=]
983 | Sprintf(protofile, "%s%d-%d", g.dungeons[u.uz.dnum].proto,
| ^
In file included from ../include/config.h:665,
from ../include/hack.h:10,
from mkmaze.c:6:
../include/global.h:262:24: note: ‘sprintf’ output between 4 and 31 bytes into a destination of size 20
262 | #define Sprintf (void) sprintf
mkmaze.c:983:17: note: in expansion of macro ‘Sprintf’
983 | Sprintf(protofile, "%s%d-%d", g.dungeons[u.uz.dnum].proto,
| ^~~~~~~-+
As usual, that one can easily be rectified by replacing it with an Snprintf() call.
There were several Sprintf calls in the vicinity, targeting the same destination
buffer, so I figured that I might as well replace the several.
../win/Qt/qt_menu.cpp: In member function
‘virtual void nethack_qt_::NetHackQtTextWindow::UseRIP(int, time_t)’:
../win/Qt/qt_menu.cpp:1082:63: warning:
‘%ld’ directive output may be truncated writing between 1 and 20 bytes into a region
of size 17 [-Wformat-truncation=]
1082 | (void) snprintf(rip_line[GOLD_LINE], STONE_LINE_LEN + 1, "%ld Au", cash);
| ^~~
../win/Qt/qt_menu.cpp:1082:62: note: directive argument in the range [-9223372036854775808, 999999999]
1082 | (void) snprintf(rip_line[GOLD_LINE], STONE_LINE_LEN + 1, "%ld Au", cash);
| ^~~~~~~~
../win/Qt/qt_menu.cpp:1082:20: note: ‘snprintf’ output between 5 and 24 bytes into a destination of size 17
1082 | (void) snprintf(rip_line[GOLD_LINE], STONE_LINE_LEN + 1, "%ld Au", cash);
| ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
That one was a little different. It wasn't complaining about the destination buffer
size in the way -Wformat-overflow was on the previous warning from gcc, and it
was already using snprintf().
It looks like what the C++ compiler was warning about there, was that snprintf()
informs you after-the-call that the destination buffer was too small for the
result string to be fully written. It informs the developer of that by returning
the number of characters that would have been written if the buffer had been big
enough. Presumably, the C++ compiler picked up on the fact that the return value
was being cast to void, thus throwing away that truncation information from the
return value.
Worked around it by putting the return value into a variable, and flagging the
variable with nhUse(variable) so as not to exchange the -Wformat-truncation
warning with a variable-set-but-not-used warning.
Catch up with tty, curses, and X11. Items flagged as skip-invert
will not be toggled On by select-all. If menuinvertmode is 2, they
also won't be toggled Off by unselect-all.
Have Qt catch up with tty and X11: in a menu, when not already
entering a count and player types a digit, check whether it is the
group accelerator for any of the menu entries. If so, toggle their
selection state; if not, begin counting for the next item the player
eventually picks.
---------------------
win/curses/cursstat.c:
../win/curses/cursstat.c:301:9: warning: variable 'height' set but not used [-Wunused-but-set-variable]
height, width, w, xtra, clen, x, y, t, ex, ey,
^
1 warning generated.
---------------------
win/Qt/qt_menu.cpp:
../win/Qt/qt_menu.cpp:1123:9: warning: variable 'h' set but not used [-Wunused-but-set-variable]
int h=0;
^
1 warning generated.
---------------------
/win/Qt/qt_yndlg.cpp:
../win/Qt/qt_yndlg.cpp:170:6: warning: variable 'x' set but not used [-Wunused-but-set-variable]
int x=margin, y=extra+margin;
^
../win/Qt/qt_yndlg.cpp:170:16: warning: variable 'y' set but not used [-Wunused-but-set-variable]
int x=margin, y=extra+margin;
^
2 warnings generated.
Commenting out the x and y references, then leads to the following additional warnings,
so comment those out too:
../win/Qt/qt_yndlg.cpp:167:12: warning: unused variable 'margin' [-Wunused-variable]
const int margin=8;
^
../win/Qt/qt_yndlg.cpp:168:12: warning: unused variable 'gutter' [-Wunused-variable]
const int gutter=8;
^
../win/Qt/qt_yndlg.cpp:169:12: warning: unused variable 'extra' [-Wunused-variable]
const int extra=fontMetrics().height(); // Extra for group
^
3 warnings generated.
---------------------
Our C() macro conflicts with Qt6 usage, so #undef C has added. Move
that from nearly every qt_*.cpp into qt_pre.h where other similar
fixups are handled.
The walls for the mines, gehennom, knox, and sokoban had been
changed at the "tile"-level, with no awareness of the core game,
or non-tile interfaces.
- Expand the glyphs to include a set of walls for the main level
as well as each of those mentioned above.
Altars had been adjusted at the map_glyphinfo() level to substitute
some color variations on-the-fly for unaligned, chaotic, neutral,
lawful altars, and shrines. The tile interface had no awareness of
the feature.
- Expand the glyphs to include each of the altar variations that
had been implemented in the display code for tty-only. This required
the addition of four placeholder tiles in other.txt. Someone with
artistic skill will hopefully alter the additional tiles to better
reflect their intended purpose.
Explosions had unique tiles in the tile window port, and the display
code for tty tinkered with the colors, but the game had very little
awareness of the different types of explosions.
- Expand the glyphs to include each of the explosion types: dark,
noxious, muddy, wet, magical, fiery and frosty.
Pile-markers to represent a pile had been introduced at the
display-level, without little to no awareness by the core game.
- Expand the glyphs to include piletops, including objects,
bodys, and statues.
Recently male and female variations of tiles and monsters had been
had been introduced, but the mechanics had been mostly done at the
display-level through a marker flag. The window port interface then
had to increment the tile mapped to the glyph to get the female version
of the tile.
- Expand the glyphs to include the male and female versions of the
monsters, and their corresponding pet versions, ridden, detected
versions and statues of them.
Direct references to GLYPH_BODY_OFF and GLYPH_STATUE_OFF
in object_from_map() in pager.c were getting incomplete results.
- Add macros glyph_to_body_corpsenm(glyph) and
glyph_to_statue_corpsenm(glyph) macros for obtaining the corpsenm
value after passing the glyph_is_body() or glyph_is_statue() test.
Other relevant notes:
- The tile ordering in the win/share/*.txt tile files has been altered,
other.txt in particular.
- tilemap.c has had a lot of alterations to accommodate the expanded
glyphs. Output that is useful for troubleshooting will end up in
tilemappings.lst if OBTAIN_TILEMAP is defined during build.
It lists all of the glyphs and which tile it gets mapped to, and also
lists each tile and some of the references to it by various glyphs.
- An array glyphmap[MAXGLYPH] is now used. It has an entry for each
glyph, ordered by glyph, and once reset_glyphs(glyph) has been run, it
contains the mapped symindex, default color, glyphflags, and tile
index.
If USE_TILES is defined during build, the tile.c produced from the
tilemap utility populates the tileidx field of each array element with
a glyph-to-tile mapping for the glyph. Later on, when reset_glyphmap()
is run, the other fields of each element will get populated.
- The glyph-to-tile mapping is an added field available to a window
port via the glyphinfo struct passed in the documented interface. The
old glyph2tile[] array is gone. The various active window ports that
had been using glyph2tile[] have been updated to use the new interface
mechanism. Disclaimer: There may be some bug fixing or tidying
required in the window port code.
- reset_glyphmap() is called after config file options parsing
has finished, because some config file settings can impact the results
produced by reset_glyphmap().
- Everything that passes the glyph_is_cmap(glyph) test must
return a valid cmap value from glyph_to_cmap(glyph).
- An 'extern glyph_info glyphmap[MAX_GLYPH];' is inserted into the
top of only the files which need awareness of it, not inserted into
display.h. Presently, the only files that actually need to directly
reference the glyphmap[] array are display.c, o_init.c (for shuffling
the tiles), and the generated tile.c (if USE_TILES is defined).
- Added an MG_MALE glyphflag to complement the MG_FEMALE glyphflag.
- Provide an array for wall colorizations. reset_glyphmap() will draw
the colors from this array: int array wallcolors[sokoban_walls + 1];
The indices of the wallcolors array are main_walls (0), mines_walls
(1), gehennom_walls (2), knox_walls (3), and sokoban_walls (4).
In future, a config file option for adjusting the wall colors and/or
an 'O' option menu to do the same could be added. Right now, the
initializaton of the wallcolors[] array entries in display.c leaves the
walls at CLR_GRAY, matching the defsym color.
- Most of the display-level kludges for some of the on-the-fly
interface features have been removed from map_glyphinfo() as they
aren't needed any longer. These glyph expansions adhere more closely to
the original glyph mechanics of the game.
- Because the glyphs are re-ordered and expanded, an update to
editlevel will be required upon merge of these changes.
Mostly the warnings were about QString::sprintf and QFontMetrics::width.
sprintf replacement is asprintf, which annoyingly behaves differently
from sprintf - it seems to append to the string.
Not thoroughly tested, but seems to work.
For Qt, always render text windows with fixed width font instead
of switching from proportional to fixed when the text contains
any line(s) with four consecutive spaces. That was really meant
for menu lines without selector letters which want to be lined
up under or over ones with such, and wasn't a very good heuristic
for text windows.
Most of the text files for the '?' command happen to have such
lines so are already being shown with fixed-width font. data.base
entries were hit or miss; most have attribution lines indented by
four or more spaces but some don't, so display was inconsistent:
some were shown with fixed-width font and some with proportional.
Text windows only accept a few keys (<escape>, <return>, ':', now
<space>) and if they got other keys they passed those up the call
chain, arriving at the map where they were treated as commands
and were executed while the text window was still displayed. The
cited example was ',' for pickup while the "things that are here"
popup was shown. The 'foreign' key's command might be executed
successfully but the undismissed popup could become hung.
This fixes that ('foreign' keys will be ignored). It also lets
<space> be used to dismiss text windows.
Slightly better but far from perfect: if you perform a search,
then after it runs you need to type <escape> once, or <return>
or <space> twice, or else search again and pick [done] on the
search popup and then <return> or <space> once, to dismiss a
text window via keyboard. (Prior to this, typing <escape> or
searching again and picking [done] followed by <return> were the
only ways.) Also, searching for an empty string will now be
treated as if [done] had been picked.
Fixes#400
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.
Fix the strangeness where typing ':' in a menu window initiated
the menu search operation but typing ':' in a text window saw
the shift key be pressed but not the ';' that went with it, even
though they both called the same key decoding routine. That made
typing ':' to initiate text search be impossible. Menu windows
did more input focus manipulation in their constructor. Mimicking
that in text windows fixes the problem with keys not being seen by
the text window's keystroke handler.
About 5 weeks ago, commit e4106bb161
changed Qt's searching in text windows to be able to find a match
on the very first line. It assumed that the first line would be
the current line except when repeating the same search after a
match. But after a failed search the current line index is -1 and
starting a new search would crash trying to look that line up.
When responding to '#', the Qt interface puts up a grid of buttons
labelled with the names of commands. Then if the user types
instead of clicking on a button, buttons which can no longer match
are removed rather than grayed out. The remaining ones keep their
same relative positions. Once whole rows or whole columns were
gone, it looked awful. With rows gone, the size of the grid
shrank but the popup stayed the same size, so the one-line prompt
area expanded to fill up the vacated vertical space. That caused
the prompt and partial response to move as they stayed centered in
their growing area. With columns gone, the width of the buttons
in remaining columns expanded and they spread out to take up
vacated horizontal space. Once the candidate commands were all
in one column, the buttons spanned the width of the grid. (That's
mostly my fault due to changing the grid from being row-oriented
[a b c]
[d e ]
to column oriented
[a d]
[b e]
[c ]
which resulted in columns going away a lot faster and possibly down
to one when the old layout always had at least two. But old layout
could drop to one row; the current layout always has at least two.)
Also, accept ^[ as ESC. Typing ESC when partial input is present
kills that input but keeps prompting. Typing ESC when no input
is present (none entered yet or a second of two consecutive ESCs)
cancels the operation.
Allow ^U to kill partial input. If used when no input is present,
nothing happens, similar to backspace. Unlike tty and curses, it's
hardcoded here. That shouldn't be a problem because ESC can be
used as a substitute if ^U isn't what the player normally uses.
Text window search behaved very strangely: at some point after
selecting [Search], entering a search string, having the string
entry popup go away, and having the search performed, but before
the result could be shown, the text window got pushed behind the
main window (map+messages+paperdoll+status). Clicking on the
main window's minimize button hid the main window and gave access
to the text window behind it. That was still functional even
after having been inaccessible; another search could be performed
and/or it could be dismissed. I still don't know what causes
that or how to properly fix it, but using raise() is a workaround
to bring it to the front where it belongs. Unfortunately you can
see it go away and come back so searching for text is distracting.
Allow <return> (when not searching) to dismiss all text windows
including RIP. Accept ctrl+[ as ESC.
Make text window searching be case-insensitive.
Searching wouldn't find a match on the first line of text. Now
it will.
This also includes an attempt to fix github issue #400 (typing a
pickup command while "things that are here" popup text window is
displayed seems to hang the program), but since I can't reproduce
that, I can't tell whether the fix works. The issue description
says that pickup started executing and "things here" couldn't be
dismissed which is different from "things here" being behind the
map waiting for it to be dismissed. The attempted fix is for text
window handling to tell Qt that it wants control of the keyboard,
so nethack shouldn't see any attempted pickup command.
Prevent a small inventory menu as the first one shown from forcing
all subsequent ones from being the same short height by forcing it
to have room for at least 15 lines. Temporary hack until someone
figures out why resizing the reused WIN_INVEN isn't working.
Does not affect non-inventory menus which get created on demand and
destroyed when done so don't need to change size to fit different
contents.
Don't allow the user to construct a count value when operating on
a pick-none menu where counts aren't meaningful. Unfortunately
that can still be done on pick-one or pick-any menus which don't
happen to have any entries where a count is applicable.
Allow a count to be optionally started with '#'. Note that if
there is an entry using '#' for the selector letter (probably
inventory that has something in the overflow slot), typing '#'
will select the entry instead of initiating a count.
Flail about a bit trying to get menu size correct--failed on this
front.
Remove a 'TODO' for once. Have the popup that's used to accept the
target string--after clicking on [search] or typing ':' to initiate
menu search+select operation--force keyboard focus to itself. Menu
searching worked without this, but only if you manually clicked on
the search popup prior to typing the target string. Failure to do
so resulted in typed characters being used to select menu entries.
The #enhance menu revealed a couple of menu problems for Qt.
Items flagged with "*" or "#" were showing tiny "..." instead of
the flag character. An existing problem rather than something
caused by yesterday's overhaul patch.
The "(Skills flagged by "*" may be enhanced when you're more
experienced.)" legend line was causing the regular entries to be
formatted strangely (their skill name column was much too wide).
That was caused by me dropping something (special case for header
lines during tab-separation handling) in yesterday's patch that
I mistakenly thought wasn't needed.
handle preselected item in pick-one menu; picking it returns that
item rather than toggling it off and returning nothing, picking
something else only returns the other thing (was returning first
of the chosen item or the preselected item, foiling core's attempt
to deal with both and giving wrong result whenever the preselected
one came first--like pick-an-attribute for menu colors);
when handling typed input, check selector letters before menu
command keys so that special "letters" '-' (fingers, hands, self)
and ':' (look inside container) that are specified by a few menus
can be chosen by keyboard;
menus were using default line heights which are excessively tall,
effectively making them be double spaced and using more screen
space than should have been needed; reduce height to 60% of what
it was, still a bit taller than regular spacing; look at ^X--which
is rendered via menu--before and after to see the difference;
start with count column empty instead of 6 spaces; grow it as counts
get entered; reset to empty if [all], [none], or [invert] is used;
treat intermediate counts as long rather than int; right justify
formatted count values;
simplify creating menu return data (pick-one doesn't need separate
handling);
for pick-one menus,
enable [ok] button if there is one preselected item,
enable [all] button if there is only one item (may never happen),
enable [none] if there is a preselected item (menu remains active
if [none] is used to clear the preselection);
enable [invert] if there is one item (may never happen; should
allow two items if one of them is preselected--definitely does
happen--but that wouldn't work as intended without code changes);
honor pending count if an item is selected by clicking its checkbox
(already done for typing its letter or for clicking another part
of item's menu line);
accept <delete>/<rubout> in addition to <backspace> when backing out
a digit as a count is being typed;
accept ^[ as well as ESC key for cancelling count or entire menu;
honor 'menucolors'=false to ignore any defined menu color patterns.
Menus have [ok], [cancel], [all], [none], [invert], and [search]
buttons across their top but the [all], [none], and [invert] choices
didn't redraw the menu after making changes to the pending selections
so it seemed as if they weren't doing anything. Subsequently picking
[ok] revealed otherwise.
[search] is broken (instead of accepting a search string, the letters
I type are being used to toggle individual entries as I type). This
doesn't attempt to address that.
Infrastructure bits: Qt tombstone uses a short buffer; make sure that
the plname value fits instead of relying on snprintf() to truncate it.
A warning about gold, if any, was iffy but this should guarantee no
reason for future complaint. Year was safe but a compiler sensitive
to buffer overflows wouldn't know that.
Actual bugs: Qt used money in inventory for gold amount on tombstone;
that overlooks gold in containers and will be 0 by tombstone stage if
bones get saved. Year was recalculated from current date+time instead
of using the value that gets passed in--blindly flagging that variable
as UNUSED was a mistake.
Move the nine #undef's common to all qt_*.cpp sources into qt_pre.h.
Make "hack.h" usage consistent; always enclose withing 'extern "C {'
and '}' even though only some of the sources care.
An earlier tweak worked to prevent unnecessary line wrapping
for ^X output in a menu, but #enhance and '+' both had problems
with their last column. This seems to work better but is still
based on thrashing about rather than knowledge of how things are
supposed to operate.
The change to use fixed-width fonts for menus wasn't working
optimally because the font got changed after menu construction
had measured the necessary width and height amounts. ^X output,
which uses a menu instead of a text window for tty's benefit
(probably curses too; I don't remember), had a couple of lines
which were wrapping unnecessarily.
This fix avoids that, but the extra '+20' shouldn't be needed.
Unfortunately lines in menus are effectively double-spaced, which
looks bad, and I've no idea how to fix that.
Qt menus have [ok][cancel][all][none][other stuff] buttons across
the top but it was disabling [cancel] for inventory viewing and
other pick-none menus. Enable that so that [cancel] is a viable
alternative to typing ESC or clicking on [ok] for dismissing the
menu without picking anything.
This greatly improves the '?' choice when using the '#' prefix
to select an extended command. It isn't perfect, because the
<text><spaces><more text> layout (using spaces to pad the first
column so that the second one lines up) produces at least one
line where <more text> is so long that it wraps, and instead of
| <text><spaces><start of more text>
| <blank><spaces><rest of more text>
that selectable menu entries have, the continuation is
| <text><spaces><start of more text>
|<rest of more text>
(made slightly worse by the fact that <text> is indented a little
and <rest...> isn't.
This affects the aesthetics of all NHW_MENU windows, not just the
one that desparately needed help. Maybe the core should send some
hint on a menu or text window by menu or text window basis about
whether or not fixed-width font is preferable to variable one.
In file included from ../win/Qt/qt_bind.cpp:20:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGui:3:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGuiDepends:3:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtCore.framework/Headers/QtCore:4:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtCore.framework/Headers/qglobal.h:1302:
/usr/local/Cellar/qt/5.15.0/lib/QtCore.framework/Headers/qflags.h:121:41: warning: declaration shadows a
variable in the global namespace [-Wshadow]
Q_DECL_CONSTEXPR inline QFlags(Enum flags) noexcept : i(Int(flags)) {}
^
[…]
../include/flag.h:390:29: note: previous declaration is here
extern NEARDATA struct flag flags;
^
In file included from ../win/Qt/qt_click.cpp:18:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGui:3:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGuiDepends:3:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtCore.framework/Headers/QtCore:36:
/usr/local/Cellar/qt/5.15.0/lib/QtCore.framework/Headers/qcache.h:191:15: warning: declaration shadows a
variable in the global namespace [-Wshadow]
Node *u = n;
^
../include/decl.h:219:23: note: previous declaration is here
E NEARDATA struct you u;
^
[…]
In file included from ../win/Qt/qt_click.cpp:18:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGui:5:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qabstracttextdocumentlayout.h:45:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qtextlayout.h:47:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qcolor.h:44:
/usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qrgb.h:66:46: warning: declaration shadows a
variable in the global namespace [-Wshadow]
inline Q_DECL_CONSTEXPR QRgb qRgb(int r, int g, int b)// set RGB value
^
../include/decl.h:1208:27: note: previous declaration is here
E struct instance_globals g;
^
[…]
In file included from ../win/Qt/qt_glyph.cpp:21:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGui:5:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qabstracttextdocumentlayout.h:48:
/usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qpalette.h:107:49: warning: declaration shadows a
variable in the global namespace [-Wshadow]
inline void setCurrentColorGroup(ColorGroup cg) { data.current_group = cg; }
^
../include/decl.h:1216:30: note: previous declaration is here
E const struct const_globals cg;
^