OSDN Git Service

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