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.
197 lines
4.7 KiB
C++
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
|