diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 821772eef..0e1f362a8 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -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, diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 07834f7c0..3a6062ee1 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -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 (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, diff --git a/win/Qt/qt_menu.h b/win/Qt/qt_menu.h index 59720009e..b61a9305b 100644 --- a/win/Qt/qt_menu.h +++ b/win/Qt/qt_menu.h @@ -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); diff --git a/win/Qt/qt_win.cpp b/win/Qt/qt_win.cpp index 12d101496..3fd51edf9 100644 --- a/win/Qt/qt_win.cpp +++ b/win/Qt/qt_win.cpp @@ -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) diff --git a/win/Qt/qt_win.h b/win/Qt/qt_win.h index 486bf4ec6..daa6e0d1d 100644 --- a/win/Qt/qt_win.h +++ b/win/Qt/qt_win.h @@ -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;