Files
nethack/win/Qt/qt_menu.h
PatR 5401d18c4b Qt menu overhaul
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.
2020-09-16 15:51:33 -07:00

197 lines
4.7 KiB
C++

// Copyright (c) Warwick Allison, 1999.
// Qt4 conversion copyright (c) Ray Chason, 2012-2014.
// NetHack may be freely redistributed. See license for details.
// qt_menu.cpp -- a menu or text-list widget
#ifndef QT4MENU_H
#define QT4MENU_H
#include "qt_win.h"
#include "qt_rip.h"
// some menu fields aren't wide enough even though sized for measured text
#define MENU_WIDTH_SLOP 10 /* this should not be necessary */
namespace nethack_qt_ {
class NetHackQtTextListBox : public QListWidget {
public:
NetHackQtTextListBox(QWidget* parent = NULL) : QListWidget(parent) { }
int TotalWidth() const
{
int width = 0;
QFontMetrics fm(font());
for (int i = 0; i < count(); i++) {
int lwidth = fm.width(item(i)->text());
width = std::max(width, lwidth);
}
return width;
}
int TotalHeight() const
{
QFontMetrics fm(font());
return fm.height() * count();
}
virtual QSize sizeHint() const;
};
class NetHackQtMenuListBox : public QTableWidget {
public:
NetHackQtMenuListBox(QWidget* parent = NULL) : QTableWidget(parent) { }
int TotalWidth() const;
int TotalHeight() const;
virtual QSize sizeHint() const;
};
class NetHackQtMenuWindow : public QDialog, public NetHackQtWindow {
Q_OBJECT
public:
NetHackQtMenuWindow(QWidget *parent = NULL);
~NetHackQtMenuWindow();
virtual QWidget* Widget();
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 EndMenu(const QString& prompt);
virtual int SelectMenu(int how, MENU_ITEM_P **menu_list);
public slots:
void All();
void ChooseNone();
void Invert();
void Search();
void ToggleSelect(int row, bool alyready_checked);
void TableCellClicked(int row, int col);
void CheckboxClicked(bool on_off);
protected:
virtual void keyPressEvent(QKeyEvent*);
private:
struct MenuItem {
MenuItem();
~MenuItem();
int glyph;
ANY_P identifier;
int attr;
QString str;
long count;
char ch;
char gch;
bool selected; // True if checkbox is set
bool preselected; // True if caller told us to set checkbox
unsigned itemflags;
unsigned color;
bool Selectable() const { return identifier.a_void!=0; }
};
QVector<MenuItem> itemlist;
int itemcount;
int next_accel;
QTableWidget* table;
QPushButton* ok;
QPushButton* cancel;
QPushButton* all;
QPushButton* none;
QPushButton* invert;
QPushButton* search;
QLabel prompt;
// Count replaces prompt while it is being input
QString promptstr;
QString countstr;
long biggestcount; // determines width of field #0
int countdigits; // number of digits to format biggestcount
bool counting; // in midst of entering a count
bool searching; // in midst of entering a search string
void InputCount(char key);
void ClearCount(void);
int how; // pick-none, pick-one, pick-any
bool has_glyphs; // at least one item specified a glyph
bool isSelected(int row);
long count(int row);
void AddRow(int row, const MenuItem& mi);
void WidenColumn(int column, int width);
void PadMenuColumns(bool split_descr);
void UpdateCountColumn(long newcount);
void ClearSearch();
};
class NetHackQtTextWindow : public QDialog, public NetHackQtWindow {
Q_OBJECT
public:
NetHackQtTextWindow(QWidget *parent = NULL);
~NetHackQtTextWindow();
virtual QWidget* Widget();
virtual void Clear();
virtual bool Destroy();
virtual void Display(bool block);
virtual void PutStr(int attr, const QString& text);
virtual void UseRIP(int how, time_t when);
public slots:
void Search();
private slots:
void doUpdate();
private:
bool use_rip;
bool str_fixed;
QPushButton ok;
QPushButton search;
NetHackQtTextListBox* lines;
NetHackQtRIP rip;
};
class NetHackQtMenuOrTextWindow : public NetHackQtWindow {
private:
NetHackQtWindow* actual;
QWidget *parent;
public:
NetHackQtMenuOrTextWindow(QWidget *parent = NULL);
virtual QWidget* Widget();
// Text
virtual void Clear();
virtual bool Destroy();
virtual void Display(bool block);
virtual void PutStr(int attr, const QString& text);
// Menu
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 EndMenu(const QString& prompt);
virtual int SelectMenu(int how, MENU_ITEM_P **menu_list);
};
} // namespace nethack_qt_
#endif