1//	SCCS Id: @(#)qt_win.h	3.4	1999/11/19
2// Copyright (c) Warwick Allison, 1999.
3// NetHack may be freely redistributed.  See license for details.
4//
5// Qt Binding for NetHack 3.4
6//
7// Unfortunately, this doesn't use Qt as well as I would like,
8// primarily because NetHack is fundamentally a getkey-type
9// program rather than being event driven (hence the ugly key
10// and click buffer rather), but also because this is my first
11// major application of Qt.
12//
13
14#ifndef qt_win_h
15#define qt_win_h
16
17#define QT_CLEAN_NAMESPACE
18
19#include <qdialog.h>
20#include <qpushbutton.h>
21#include <qbuttongroup.h>
22#include <qlabel.h>
23#include <qlineedit.h>
24#if defined(QWS)
25#include <qpe/qpeapplication.h>
26#else
27#include <qapplication.h>
28#endif
29#include <qspinbox.h>
30#include <qcheckbox.h>
31#include <qfile.h>
32#include <qlistbox.h>
33#include <qlistview.h>
34#include <qmessagebox.h>
35#include <qpixmap.h>
36#include <qimage.h>
37#include <qarray.h>
38#include <qcombobox.h>
39#include <qscrollview.h>
40#if QT_VERSION >= 300
41#include <qttableview.h>
42// Should stop using QTableView
43#define QTableView QtTableView
44#else
45#include <qtableview.h>
46#endif
47#include <qmainwindow.h>
48#include <qwidgetstack.h>
49
50#ifdef KDE
51#include <kapp.h>
52#include <ktopwidget.h>
53#endif
54
55#include "qt_clust.h"
56
57class QVBox;
58class QMenuBar;
59class QRadioButton;
60class NhPSListView;
61
62//////////////////////////////////////////////////////////////
63//
64//  The beautiful, abstracted and well-modelled classes...
65//
66//////////////////////////////////////////////////////////////
67
68class NetHackQtGlyphs;
69
70class NetHackQtLineEdit : public QLineEdit {
71public:
72	NetHackQtLineEdit();
73	NetHackQtLineEdit(QWidget* parent, const char* name);
74
75	void fakeEvent(int key, int ascii, int state);
76};
77
78class NetHackQtSettings : public QDialog {
79	Q_OBJECT
80public:
81	// Size of window - used to decide default sizes
82	NetHackQtSettings(int width, int height);
83
84	NetHackQtGlyphs& glyphs();
85	const QFont& normalFont();
86	const QFont& normalFixedFont();
87	const QFont& largeFont();
88
89	bool ynInMessages();
90
91signals:
92	void fontChanged();
93	void tilesChanged();
94
95public slots:
96	void toggleGlyphSize();
97	void setGlyphSize(bool);
98
99private:
100	QSpinBox tilewidth;
101	QSpinBox tileheight;
102	QLabel widthlbl;
103	QLabel heightlbl;
104	QCheckBox whichsize;
105	QSize othersize;
106
107	QComboBox fontsize;
108
109	QFont normal, normalfixed, large;
110
111	NetHackQtGlyphs* theglyphs;
112
113private slots:
114	void resizeTiles();
115};
116
117class NetHackQtKeyBuffer {
118public:
119	NetHackQtKeyBuffer();
120
121	bool Empty() const;
122	bool Full() const;
123
124	void Put(int k, int ascii, int state);
125	void Put(char a);
126	void Put(const char* str);
127	int GetKey();
128	int GetAscii();
129	int GetState();
130
131	int TopKey() const;
132	int TopAscii() const;
133	int TopState() const;
134
135private:
136	enum { maxkey=64 };
137	int key[maxkey];
138	int ascii[maxkey];
139	int state[maxkey];
140	int in,out;
141};
142
143class NetHackQtClickBuffer {
144public:
145	NetHackQtClickBuffer();
146
147	bool Empty() const;
148	bool Full() const;
149
150	void Put(int x, int y, int mod);
151
152	int NextX() const;
153	int NextY() const;
154	int NextMod() const;
155
156	void Get();
157
158private:
159	enum { maxclick=64 };
160	struct ClickRec {
161		int x,y,mod;
162	} click[maxclick];
163	int in,out;
164};
165
166
167class NetHackQtSavedGameSelector : public QDialog {
168public:
169	NetHackQtSavedGameSelector(const char** saved);
170
171	int choose();
172};
173
174class NetHackQtPlayerSelector : private QDialog {
175	Q_OBJECT
176public:
177	enum { R_None=-1, R_Quit=-2, R_Rand=-3 };
178
179	NetHackQtPlayerSelector(NetHackQtKeyBuffer&);
180
181protected:
182	virtual void done(int);
183
184public slots:
185	void Quit();
186	void Random();
187
188	void selectName(const QString& n);
189	void selectRole();
190	void selectRace();
191	void setupOthers();
192	void selectGender(int);
193	void selectAlignment(int);
194
195public:
196	bool Choose();
197
198private:
199	NetHackQtKeyBuffer& keysource;
200	NhPSListView* role;
201	NhPSListView* race;
202	QRadioButton **gender;
203	QRadioButton **alignment;
204	bool fully_specified_role;
205};
206
207class NetHackQtStringRequestor : QDialog {
208private:
209	QLabel prompt;
210	NetHackQtLineEdit input;
211	QPushButton* okay;
212	QPushButton* cancel;
213	NetHackQtKeyBuffer& keysource;
214
215	virtual void done(int);
216
217public:
218	NetHackQtStringRequestor(NetHackQtKeyBuffer&, const char* p,const char* cancelstr="Cancel");
219	void SetDefault(const char*);
220	bool Get(char* buffer, int maxchar=80);
221	virtual void resizeEvent(QResizeEvent*);
222};
223
224class NetHackQtExtCmdRequestor : public QDialog {
225    Q_OBJECT
226
227    NetHackQtKeyBuffer& keysource;
228
229public:
230    NetHackQtExtCmdRequestor(NetHackQtKeyBuffer& ks);
231    int get();
232
233private slots:
234    void cancel();
235    void done(int i);
236};
237
238
239class NetHackQtWindow {
240public:
241	NetHackQtWindow();
242	virtual ~NetHackQtWindow();
243
244	virtual QWidget* Widget() =0;
245
246	virtual void Clear();
247	virtual void Display(bool block);
248	virtual bool Destroy();
249	virtual void CursorTo(int x,int y);
250	virtual void PutStr(int attr, const char* text);
251	virtual void StartMenu();
252	virtual void AddMenu(int glyph, const ANY_P* identifier, char ch, char gch, int attr,
253			const char* str, bool presel);
254	virtual void EndMenu(const char* prompt);
255	virtual int SelectMenu(int how, MENU_ITEM_P **menu_list);
256	virtual void ClipAround(int x,int y);
257	virtual void PrintGlyph(int x,int y,int glyph);
258	virtual void UseRIP(int how);
259
260	int nhid;
261};
262
263class NetHackQtGlyphs {
264public:
265	NetHackQtGlyphs();
266
267	int width() const { return size.width(); }
268	int height() const { return size.height(); }
269	void toggleSize();
270	void setSize(int w, int h);
271
272	void drawGlyph(QPainter&, int glyph, int pixelx, int pixely);
273	void drawCell(QPainter&, int glyph, int cellx, int celly);
274
275private:
276	QImage img;
277	QPixmap pm,pm1, pm2;
278	QSize size;
279	int tiles_per_row;
280};
281
282class BlackScrollView : public QScrollView {
283public:
284    BlackScrollView()
285    {
286	viewport()->setBackgroundColor(black);
287    }
288};
289
290class NetHackQtMapWindow : public QWidget, public NetHackQtWindow {
291	Q_OBJECT
292private:
293	NetHackQtClickBuffer& clicksink;
294	unsigned short glyph[ROWNO][COLNO];
295	unsigned short& Glyph(int x, int y) { return glyph[y][x]; }
296	QPoint cursor;
297	BlackScrollView viewport;
298	QPixmap pet_annotation;
299	Clusterizer change;
300	QFont *rogue_font;
301	QString messages;
302	QRect messages_rect;
303
304	void Changed(int x,int y);
305
306signals:
307	void resized();
308
309private slots:
310	void updateTiles();
311	void moveMessages(int x, int y);
312
313protected:
314	virtual void paintEvent(QPaintEvent*);
315	virtual void mousePressEvent(QMouseEvent*);
316
317public:
318	NetHackQtMapWindow(NetHackQtClickBuffer& click_sink);
319	~NetHackQtMapWindow();
320
321	virtual QWidget* Widget();
322	virtual bool Destroy();
323
324	virtual void Clear();
325	virtual void Display(bool block);
326	virtual void CursorTo(int x,int y);
327	virtual void PutStr(int attr, const char* text);
328	virtual void ClipAround(int x,int y);
329	virtual void PrintGlyph(int x,int y,int glyph);
330
331	void Scroll(int dx, int dy);
332
333	// For messages
334	void displayMessages(bool block);
335	void putMessage(int attr, const char* text);
336	void clearMessages();
337
338	void clickCursor();
339};
340
341class NetHackQtScrollText;
342class NetHackQtMessageWindow : QObject, public NetHackQtWindow {
343	Q_OBJECT
344public:
345	NetHackQtMessageWindow();
346	~NetHackQtMessageWindow();
347
348	virtual QWidget* Widget();
349	virtual void Clear();
350	virtual void Display(bool block);
351	virtual void PutStr(int attr, const char* text);
352
353	void Scroll(int dx, int dy);
354
355	void setMap(NetHackQtMapWindow*);
356
357private:
358	NetHackQtScrollText* list;
359	bool changed;
360	NetHackQtMapWindow* map;
361
362private slots:
363	void updateFont();
364};
365
366class NetHackQtLabelledIcon : public QWidget {
367public:
368	NetHackQtLabelledIcon(QWidget* parent, const char* label);
369	NetHackQtLabelledIcon(QWidget* parent, const char* label, const QPixmap& icon);
370
371	enum { NoNum=-99999 };
372	void setLabel(const char*, bool lower=TRUE); // a string
373	void setLabel(const char*, long, const char* tail=""); // a number
374	void setLabel(const char*, long show_value, long comparative_value, const char* tail="");
375	void setIcon(const QPixmap&);
376	virtual void setFont(const QFont&);
377
378	void highlightWhenChanging();
379	void lowIsGood();
380	void dissipateHighlight();
381
382	virtual void show();
383
384protected:
385	void resizeEvent(QResizeEvent*);
386
387private:
388	void initHighlight();
389	void setAlignments();
390	void highlight(const QPalette& highlight);
391	void unhighlight();
392
393	bool low_is_good;
394	int prev_value;
395	int turn_count;		/* last time the value changed */
396	QPalette hl_good;
397	QPalette hl_bad;
398
399	QLabel* label;
400	QLabel* icon;
401};
402
403class NetHackQtStatusWindow : QWidget, public NetHackQtWindow {
404	Q_OBJECT
405public:
406	NetHackQtStatusWindow();
407
408	virtual QWidget* Widget();
409
410	virtual void Clear();
411	virtual void Display(bool block);
412	virtual void CursorTo(int x,int y);
413	virtual void PutStr(int attr, const char* text);
414
415	void fadeHighlighting();
416
417protected:
418	void resizeEvent(QResizeEvent*);
419
420private slots:
421	void doUpdate();
422
423private:
424	enum { hilight_time=1 };
425
426	QPixmap p_str;
427	QPixmap p_dex;
428	QPixmap p_con;
429	QPixmap p_int;
430	QPixmap p_wis;
431	QPixmap p_cha;
432
433	QPixmap p_chaotic;
434	QPixmap p_neutral;
435	QPixmap p_lawful;
436
437	QPixmap p_satiated;
438	QPixmap p_hungry;
439
440	QPixmap p_confused;
441	QPixmap p_sick_fp;
442	QPixmap p_sick_il;
443	QPixmap p_blind;
444	QPixmap p_stunned;
445	QPixmap p_hallu;
446
447	QPixmap p_encumber[5];
448
449	NetHackQtLabelledIcon name;
450	NetHackQtLabelledIcon dlevel;
451
452	NetHackQtLabelledIcon str;
453	NetHackQtLabelledIcon dex;
454	NetHackQtLabelledIcon con;
455	NetHackQtLabelledIcon intel;
456	NetHackQtLabelledIcon wis;
457	NetHackQtLabelledIcon cha;
458
459	NetHackQtLabelledIcon gold;
460	NetHackQtLabelledIcon hp;
461	NetHackQtLabelledIcon power;
462	NetHackQtLabelledIcon ac;
463	NetHackQtLabelledIcon level;
464	NetHackQtLabelledIcon exp;
465	NetHackQtLabelledIcon align;
466
467	NetHackQtLabelledIcon time;
468	NetHackQtLabelledIcon score;
469
470	NetHackQtLabelledIcon hunger;
471	NetHackQtLabelledIcon confused;
472	NetHackQtLabelledIcon sick_fp;
473	NetHackQtLabelledIcon sick_il;
474	NetHackQtLabelledIcon blind;
475	NetHackQtLabelledIcon stunned;
476	NetHackQtLabelledIcon hallu;
477	NetHackQtLabelledIcon encumber;
478
479	QFrame hline1;
480	QFrame hline2;
481	QFrame hline3;
482
483	int cursy;
484
485	bool first_set;
486
487	void nullOut();
488	void updateStats();
489	void checkTurnEvents();
490};
491
492class NetHackQtMenuDialog : public QDialog {
493	Q_OBJECT
494public:
495	NetHackQtMenuDialog();
496
497	void Accept();
498	void Reject();
499	void SetResult(int);
500
501	virtual void done(int);
502
503protected:
504	void resizeEvent(QResizeEvent*);
505
506signals:
507	void Resized();
508};
509
510
511class NetHackQtMenuWindow : public QTableView, public NetHackQtWindow {
512	Q_OBJECT
513public:
514	NetHackQtMenuWindow(NetHackQtKeyBuffer&);
515	~NetHackQtMenuWindow();
516
517	virtual QWidget* Widget();
518
519	virtual void StartMenu();
520	virtual void AddMenu(int glyph, const ANY_P* identifier, char ch, char gch, int attr,
521			const char* str, bool presel);
522	virtual void EndMenu(const char* prompt);
523	virtual int SelectMenu(int how, MENU_ITEM_P **menu_list);
524
525public slots:
526	void All();
527	void ChooseNone();
528	void Invert();
529	void Search();
530
531	void Layout();
532	void ToggleSelect(int);
533
534protected:
535	virtual void keyPressEvent(QKeyEvent*);
536	//virtual void mouseDoubleClickEvent(QMouseEvent*);
537	virtual void mousePressEvent(QMouseEvent*);
538	virtual void mouseReleaseEvent(QMouseEvent*);
539	virtual void mouseMoveEvent(QMouseEvent*);
540	virtual void focusOutEvent(QFocusEvent*);
541	virtual void focusInEvent(QFocusEvent*);
542
543	virtual void paintCell(QPainter*, int, int);
544	virtual int cellWidth(int col);
545
546private:
547	struct MenuItem {
548		MenuItem();
549		~MenuItem();
550
551		int glyph;
552		ANY_P identifier;
553		int attr;
554		const char* str;
555		int count;
556		char ch;
557		bool selected;
558
559		bool Selectable() const { return identifier.a_void!=0; }
560	};
561
562	QArray<MenuItem> item;
563
564	int itemcount;
565	int str_width;
566	bool str_fixed;
567	int next_accel;
568
569	NetHackQtKeyBuffer& keysource;
570
571	NetHackQtMenuDialog* dialog;
572
573	QPushButton* ok;
574	QPushButton* cancel;
575	QPushButton* all;
576	QPushButton* none;
577	QPushButton* invert;
578	QPushButton* search;
579	QLabel prompt;
580
581	int how;
582
583	bool has_glyphs;
584
585	int pressed;
586	bool was_sel;
587};
588
589class NetHackQtTextListBox;
590
591class NetHackQtRIP : public QWidget {
592private:
593	static QPixmap* pixmap;
594	char** line;
595	int riplines;
596
597public:
598	NetHackQtRIP(QWidget* parent);
599
600	void setLines(char** l, int n);
601
602protected:
603	virtual void paintEvent(QPaintEvent* event);
604	QSize sizeHint() const;
605};
606
607
608class NetHackQtTextWindow : public QDialog, public NetHackQtWindow {
609	Q_OBJECT
610public:
611	NetHackQtTextWindow(NetHackQtKeyBuffer&);
612	~NetHackQtTextWindow();
613
614	virtual QWidget* Widget();
615
616	virtual void Clear();
617	virtual bool Destroy();
618	virtual void Display(bool block);
619	virtual void PutStr(int attr, const char* text);
620	virtual void UseRIP(int how);
621
622public slots:
623	void Search();
624
625protected:
626	virtual void done(int);
627	virtual void keyPressEvent(QKeyEvent*);
628
629private slots:
630	void doUpdate();
631
632private:
633	NetHackQtKeyBuffer& keysource;
634
635	bool use_rip;
636	bool str_fixed;
637
638	QPushButton ok;
639	QPushButton search;
640	NetHackQtTextListBox* lines;
641
642	NetHackQtRIP rip;
643};
644
645class NetHackQtMenuOrTextWindow : public NetHackQtWindow {
646private:
647	NetHackQtWindow* actual;
648	NetHackQtKeyBuffer& keysource;
649
650public:
651	NetHackQtMenuOrTextWindow(NetHackQtKeyBuffer&);
652
653	virtual QWidget* Widget();
654
655	// Text
656	virtual void Clear();
657	virtual bool Destroy();
658	virtual void Display(bool block);
659	virtual void PutStr(int attr, const char* text);
660
661	// Menu
662	virtual void StartMenu();
663	virtual void AddMenu(int glyph, const ANY_P* identifier, char ch, char gch, int attr,
664			const char* str, bool presel);
665	virtual void EndMenu(const char* prompt);
666	virtual int SelectMenu(int how, MENU_ITEM_P **menu_list);
667
668};
669
670class NetHackQtDelay : QObject {
671private:
672	int msec;
673
674public:
675	NetHackQtDelay(int ms);
676	void wait();
677	virtual void timerEvent(QTimerEvent* timer);
678};
679
680
681class NetHackQtInvUsageWindow : public QWidget {
682public:
683	NetHackQtInvUsageWindow(QWidget* parent);
684	virtual void paintEvent(QPaintEvent*);
685private:
686	void drawWorn(QPainter& painter, obj*, int x, int y, bool canbe=TRUE);
687};
688
689// This class is the main widget for NetHack
690//
691// It is a collection of Message, Map, and Status windows.  In the current
692// version of nethack there is only one of each, and this class makes this
693// assumption, not showing itself until all are inserted.
694//
695// This class simply knows how to layout such children sensibly.
696//
697// Since it is only responsible for layout, the class does not
698// note the actual class of the windows.
699//
700#ifndef KDE
701#include "qt_kde0.h"
702#endif
703
704class NetHackQtMainWindow : public KTopLevelWidget {
705	Q_OBJECT
706public:
707	NetHackQtMainWindow(NetHackQtKeyBuffer&);
708
709	void AddMessageWindow(NetHackQtMessageWindow* window);
710	void AddMapWindow(NetHackQtMapWindow* window);
711	void AddStatusWindow(NetHackQtStatusWindow* window);
712	void RemoveWindow(NetHackQtWindow* window);
713	void updateInventory();
714
715	void fadeHighlighting();
716
717public slots:
718	void doMenuItem(int);
719	void doKeys(const QString&);
720
721protected:
722	virtual void resizeEvent(QResizeEvent*);
723	virtual void keyPressEvent(QKeyEvent*);
724	virtual void keyReleaseEvent(QKeyEvent* event);
725	virtual void closeEvent(QCloseEvent*);
726
727private slots:
728	void layout();
729	void raiseMap();
730	void zoomMap();
731	void raiseMessages();
732	void raiseStatus();
733
734private:
735	void ShowIfReady();
736
737#ifdef KDE
738	KMenuBar* menubar;
739#else
740	QMenuBar* menubar;
741#endif
742	NetHackQtMessageWindow* message;
743	NetHackQtMapWindow* map;
744	NetHackQtStatusWindow* status;
745	NetHackQtInvUsageWindow* invusage;
746
747	NetHackQtKeyBuffer& keysink;
748	QWidgetStack* stack;
749	int dirkey;
750
751	const char* *macro;
752};
753
754class NetHackQtYnDialog : QDialog {
755	Q_OBJECT
756private:
757	const char* question;
758	const char* choices;
759	char def;
760	NetHackQtKeyBuffer& keysource;
761
762protected:
763	virtual void keyPressEvent(QKeyEvent*);
764	virtual void done(int);
765
766private slots:
767	void doneItem(int);
768
769public:
770	NetHackQtYnDialog(NetHackQtKeyBuffer& keysource,const char*,const char*,char);
771
772	char Exec();
773};
774
775#ifdef KDE
776#define NetHackQtBindBase KApplication
777#elif defined(QWS)
778#define NetHackQtBindBase QPEApplication
779#else
780#define NetHackQtBindBase QApplication
781#endif
782
783class NetHackQtBind : NetHackQtBindBase {
784private:
785	// Single-instance preservation...
786	NetHackQtBind(int& argc, char** argv);
787
788	static NetHackQtBind* instance;
789
790	static NetHackQtKeyBuffer keybuffer;
791	static NetHackQtClickBuffer clickbuffer;
792
793	static QWidget* splash;
794	static NetHackQtMainWindow* main;
795
796public:
797	static void qt_init_nhwindows(int* argc, char** argv);
798	static void qt_player_selection();
799	static void qt_askname();
800	static void qt_get_nh_event();
801	static void qt_exit_nhwindows(const char *);
802	static void qt_suspend_nhwindows(const char *);
803	static void qt_resume_nhwindows();
804	static winid qt_create_nhwindow(int type);
805	static void qt_clear_nhwindow(winid wid);
806	static void qt_display_nhwindow(winid wid, BOOLEAN_P block);
807	static void qt_destroy_nhwindow(winid wid);
808	static void qt_curs(winid wid, int x, int y);
809	static void qt_putstr(winid wid, int attr, const char *text);
810	static void qt_display_file(const char *filename, BOOLEAN_P must_exist);
811	static void qt_start_menu(winid wid);
812	static void qt_add_menu(winid wid, int glyph,
813		const ANY_P * identifier, CHAR_P ch, CHAR_P gch, int attr,
814		const char *str, BOOLEAN_P presel);
815	static void qt_end_menu(winid wid, const char *prompt);
816	static int qt_select_menu(winid wid, int how, MENU_ITEM_P **menu_list);
817	static void qt_update_inventory();
818	static void qt_mark_synch();
819	static void qt_wait_synch();
820
821	static void qt_cliparound(int x, int y);
822	static void qt_cliparound_window(winid wid, int x, int y);
823	static void qt_print_glyph(winid wid,XCHAR_P x,XCHAR_P y,int glyph);
824	static void qt_raw_print(const char *str);
825	static void qt_raw_print_bold(const char *str);
826	static int qt_nhgetch();
827	static int qt_nh_poskey(int *x, int *y, int *mod);
828	static void qt_nhbell();
829	static int qt_doprev_message();
830	static char qt_yn_function(const char *question, const char *choices, CHAR_P def);
831	static void qt_getlin(const char *prompt, char *line);
832	static int qt_get_ext_cmd();
833	static void qt_number_pad(int);
834	static void qt_delay_output();
835	static void qt_start_screen();
836	static void qt_end_screen();
837
838	static void qt_outrip(winid wid, int how);
839	static int qt_kbhit();
840
841private:
842	virtual bool notify(QObject *receiver, QEvent *event);
843};
844
845#endif
846