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