Qt menu hack

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.
This commit is contained in:
PatR
2020-10-08 10:18:44 -07:00
parent 1b0a9f8e31
commit 342323eb15
5 changed files with 59 additions and 22 deletions

View File

@@ -396,7 +396,7 @@ void NetHackQtBind::qt_display_file(const char *filename, BOOLEAN_P must_exist)
void NetHackQtBind::qt_start_menu(winid wid, unsigned long mbehavior UNUSED)
{
NetHackQtWindow* window=id_to_window[(int)wid];
window->StartMenu();
window->StartMenu(wid == WIN_INVEN);
}
void NetHackQtBind::qt_add_menu(winid wid, int glyph,

View File

@@ -8,6 +8,13 @@
// TODO:
// inventory menus reuse the same menu window over and over (in the core);
// it isn't resizing properly to reflect each new instance's content;
// [temporary 'fix' allocates at least 15 lines in case a really short
// subset is displayed before a full inventory; but all inventory menus
// will be padded to that length when they might otherwise show all the
// entries with less, and inventories which have more will need to be
// scrolled to see the excess even if a taller menu would fit on the
// screen; code now has to distinguish between inventory menu and
// 'other' menu so that the latter isn't padded too]
// implement next_page, prev_page, first_page, and last_page to work
// like they do for X11: scroll menu window as if it were paginated;
// entering a count that uses more digits than the previous biggest count
@@ -67,22 +74,44 @@ int NetHackQtMenuListBox::TotalWidth() const
int NetHackQtMenuListBox::TotalHeight() const
{
int row, height = 0;
int row, rowheight, height = 0;
for (row = 0; row < rowCount(); ++row) {
height += rowHeight(row);
}
// 20: arbitrary; should always have at least 1 row so it shouldn't matter
rowheight = (row > 0) ? rowHeight(row - 1) : 20;
//
// FIXME:
// The core reuses one window for inventory displays and this
// part of sizeHint() is working for the initial size but is
// ineffective for later resizes.
//
// TEMPORARY:
// in case first inventory menu displayed is a short one pad it
// with blank lines so later long ones won't be far too short
if ((dynamic_cast <NetHackQtMenuWindow *> (parent()))->is_invent) {
if (row < 15)
height += (15 - row) * rowheight;
}
// include extra height so that there will be a blank gap after the
// last entry to show that there is nothing to scroll forward too
height += (row > 0) ? (rowHeight(row - 1) / 2) : 7;
height += rowheight / 2;
return height;
}
QSize NetHackQtMenuListBox::sizeHint() const
{
QScrollBar *hscroll = horizontalScrollBar();
int hsize = hscroll ? hscroll->height() : 0;
return QSize(TotalWidth()+hsize, TotalHeight()+hsize);
QScrollBar *hscroll = horizontalScrollBar(),
*vscroll = verticalScrollBar();
int hsize = (hscroll && hscroll->isVisible()) ? hscroll->height() : 0,
vsize = (vscroll && vscroll->isVisible()) ? vscroll->width() : 0;
hsize += MENU_WIDTH_SLOP, vsize += MENU_WIDTH_SLOP;
// note: a vertical scrollbar affects widget width, a horizontal one height
return QSize(TotalWidth() + vsize, TotalHeight() + hsize);
}
//
@@ -125,12 +154,13 @@ void NetHackQtMenuWindow::MenuResize()
//
NetHackQtMenuWindow::NetHackQtMenuWindow(QWidget *parent) :
QDialog(parent),
is_invent(false), // reset to True when window is core's WIN_INVEN
table(new NetHackQtMenuListBox()),
prompt(0),
biggestcount(0L), // largest subset amount that user has entered
countdigits(0), // number of digits needed by biggestcount
counting(false), // user has typed a digit and more might follow
searching(false)
searching(false) // user has begun entering a search target string
{
// setFont() was in SelectMenu(), in time to be rendered but too late
// when measuring the width and height that will be needed
@@ -198,7 +228,7 @@ QWidget* NetHackQtMenuWindow::Widget() { return this; }
// can't rely on the MenuWindow constructor for initialization.
//
void NetHackQtMenuWindow::StartMenu()
void NetHackQtMenuWindow::StartMenu(bool using_WIN_INVEN)
{
itemcount = 0;
table->setRowCount(itemcount);
@@ -208,6 +238,8 @@ void NetHackQtMenuWindow::StartMenu()
countdigits = 0;
ClearCount(); // reset 'counting' flag and digit string 'countstr'
ClearSearch(); // reset 'searching' flag
is_invent = using_WIN_INVEN;
}
NetHackQtMenuWindow::MenuItem::MenuItem() :
@@ -1149,10 +1181,10 @@ void NetHackQtMenuOrTextWindow::PutStr(int attr, const QString& text)
}
// Menu
void NetHackQtMenuOrTextWindow::StartMenu()
void NetHackQtMenuOrTextWindow::StartMenu(bool using_WIN_INVEN)
{
if (!actual) actual=new NetHackQtMenuWindow(parent);
actual->StartMenu();
actual->StartMenu(using_WIN_INVEN);
}
void NetHackQtMenuOrTextWindow::AddMenu(int glyph, const ANY_P* identifier,
char ch, char gch, int attr,

View File

@@ -56,13 +56,15 @@ public:
virtual QWidget* Widget();
virtual void StartMenu();
virtual void StartMenu(bool using_WIN_INVEN = false);
virtual void AddMenu(int glyph, const ANY_P *identifier,
char ch, char gch, int attr,
const QString& str, unsigned itemflags);
virtual void EndMenu(const QString& prompt);
virtual int SelectMenu(int how, MENU_ITEM_P **menu_list);
bool is_invent; // using core's WIN_INVEN
public slots:
void All();
void ChooseNone();
@@ -169,7 +171,7 @@ private:
class NetHackQtMenuOrTextWindow : public NetHackQtWindow {
private:
NetHackQtWindow* actual;
QWidget *parent;
QWidget *parent;
public:
NetHackQtMenuOrTextWindow(QWidget *parent = NULL);
@@ -183,7 +185,7 @@ public:
virtual void PutStr(int attr, const QString& text);
// Menu
virtual void StartMenu();
virtual void StartMenu(bool using_WIN_INVENT = false);
virtual void AddMenu(int glyph, const ANY_P *identifier,
char ch, char gch, int attr,
const QString& str, unsigned itemflags);

View File

@@ -99,7 +99,8 @@ void NetHackQtWindow::Display(bool block UNUSED) { puts("unexpected Display"); }
bool NetHackQtWindow::Destroy() { return true; }
void NetHackQtWindow::CursorTo(int x UNUSED,int y UNUSED) { puts("unexpected CursorTo"); }
void NetHackQtWindow::PutStr(int attr UNUSED, const QString& text UNUSED) { puts("unexpected PutStr"); }
void NetHackQtWindow::StartMenu() { puts("unexpected StartMenu"); }
void NetHackQtWindow::StartMenu(bool using_WIN_INVEN UNUSED)
{ puts("unexpected StartMenu"); }
void NetHackQtWindow::AddMenu(int glyph UNUSED, const ANY_P* identifier UNUSED,
char ch UNUSED, char gch UNUSED, int attr UNUSED,
const QString& str UNUSED, unsigned itemflags UNUSED)

View File

@@ -2,8 +2,9 @@
// Qt4 conversion copyright (c) Ray Chason, 2012-2014.
// NetHack may be freely redistributed. See license for details.
// Qt Binding for NetHack 3.4
// Qt Binding for NetHack 3.7
//
// [original comment from Warwick]
// Unfortunately, this doesn't use Qt as well as I would like,
// primarily because NetHack is fundamentally a getkey-type
// program rather than being event driven (hence the ugly key
@@ -21,24 +22,25 @@ public:
NetHackQtWindow();
virtual ~NetHackQtWindow();
virtual QWidget* Widget() =0;
virtual QWidget* Widget() = 0;
virtual void Clear();
virtual void Display(bool block);
virtual bool Destroy();
virtual void CursorTo(int x,int y);
virtual void CursorTo(int x, int y);
virtual void PutStr(int attr, const QString& text);
void PutStr(int attr, const char *text)
{
PutStr(attr, QString::fromUtf8(text).replace(QChar(0x200B), ""));
}
virtual void StartMenu();
virtual void AddMenu(int glyph, const ANY_P* identifier, char ch, char gch, int attr,
const QString& str, unsigned itemflags);
virtual void StartMenu(bool using_WIN_INVEN = false);
virtual void AddMenu(int glyph, const ANY_P* identifier,
char ch, char gch, int attr,
const QString& str, unsigned itemflags);
virtual void EndMenu(const QString& prompt);
virtual int SelectMenu(int how, MENU_ITEM_P **menu_list);
virtual void ClipAround(int x,int y);
virtual void PrintGlyph(int x,int y,int glyph);
virtual void ClipAround(int x, int y);
virtual void PrintGlyph(int x, int y, int glyph);
virtual void UseRIP(int how, time_t when);
int nhid;