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 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 public: 72 NetHackQtLineEdit(); 73 NetHackQtLineEdit(QWidget* parent, const char* name); 74 75 void fakeEvent(int key, int ascii, int state); 76 }; 77 78 class NetHackQtSettings : public QDialog { 79 Q_OBJECT 80 public: 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 91 signals: 92 void fontChanged(); 93 void tilesChanged(); 94 95 public slots: 96 void toggleGlyphSize(); 97 void setGlyphSize(bool); 98 99 private: 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 113 private slots: 114 void resizeTiles(); 115 }; 116 117 class NetHackQtKeyBuffer { 118 public: 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 135 private: 136 enum { maxkey=64 }; 137 int key[maxkey]; 138 int ascii[maxkey]; 139 int state[maxkey]; 140 int in,out; 141 }; 142 143 class NetHackQtClickBuffer { 144 public: 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 158 private: 159 enum { maxclick=64 }; 160 struct ClickRec { 161 int x,y,mod; 162 } click[maxclick]; 163 int in,out; 164 }; 165 166 167 class NetHackQtSavedGameSelector : public QDialog { 168 public: 169 NetHackQtSavedGameSelector(const char** saved); 170 171 int choose(); 172 }; 173 174 class NetHackQtPlayerSelector : private QDialog { 175 Q_OBJECT 176 public: 177 enum { R_None=-1, R_Quit=-2, R_Rand=-3 }; 178 179 NetHackQtPlayerSelector(NetHackQtKeyBuffer&); 180 181 protected: 182 virtual void done(int); 183 184 public 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 195 public: 196 bool Choose(); 197 198 private: 199 NetHackQtKeyBuffer& keysource; 200 NhPSListView* role; 201 NhPSListView* race; 202 QRadioButton **gender; 203 QRadioButton **alignment; 204 bool fully_specified_role; 205 }; 206 207 class NetHackQtStringRequestor : QDialog { 208 private: 209 QLabel prompt; 210 NetHackQtLineEdit input; 211 QPushButton* okay; 212 QPushButton* cancel; 213 NetHackQtKeyBuffer& keysource; 214 215 virtual void done(int); 216 217 public: 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 224 class NetHackQtExtCmdRequestor : public QDialog { 225 Q_OBJECT 226 227 NetHackQtKeyBuffer& keysource; 228 229 public: 230 NetHackQtExtCmdRequestor(NetHackQtKeyBuffer& ks); 231 int get(); 232 233 private slots: 234 void cancel(); 235 void done(int i); 236 }; 237 238 239 class NetHackQtWindow { 240 public: 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 263 class NetHackQtGlyphs { 264 public: 265 NetHackQtGlyphs(); 266 width()267 int width() const { return size.width(); } height()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 275 private: 276 QImage img; 277 QPixmap pm,pm1, pm2; 278 QSize size; 279 int tiles_per_row; 280 }; 281 282 class BlackScrollView : public QScrollView { 283 public: BlackScrollView()284 BlackScrollView() 285 { 286 viewport()->setBackgroundColor(black); 287 } 288 }; 289 290 class NetHackQtMapWindow : public QWidget, public NetHackQtWindow { 291 Q_OBJECT 292 private: 293 NetHackQtClickBuffer& clicksink; 294 unsigned short glyph[ROWNO][COLNO]; Glyph(int x,int y)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 306 signals: 307 void resized(); 308 309 private slots: 310 void updateTiles(); 311 void moveMessages(int x, int y); 312 313 protected: 314 virtual void paintEvent(QPaintEvent*); 315 virtual void mousePressEvent(QMouseEvent*); 316 317 public: 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 341 class NetHackQtScrollText; 342 class NetHackQtMessageWindow : QObject, public NetHackQtWindow { 343 Q_OBJECT 344 public: 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 357 private: 358 NetHackQtScrollText* list; 359 bool changed; 360 NetHackQtMapWindow* map; 361 362 private slots: 363 void updateFont(); 364 }; 365 366 class NetHackQtLabelledIcon : public QWidget { 367 public: 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 384 protected: 385 void resizeEvent(QResizeEvent*); 386 387 private: 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 403 class NetHackQtStatusWindow : QWidget, public NetHackQtWindow { 404 Q_OBJECT 405 public: 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 417 protected: 418 void resizeEvent(QResizeEvent*); 419 420 private slots: 421 void doUpdate(); 422 423 private: 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 492 class NetHackQtMenuDialog : public QDialog { 493 Q_OBJECT 494 public: 495 NetHackQtMenuDialog(); 496 497 void Accept(); 498 void Reject(); 499 void SetResult(int); 500 501 virtual void done(int); 502 503 protected: 504 void resizeEvent(QResizeEvent*); 505 506 signals: 507 void Resized(); 508 }; 509 510 511 class NetHackQtMenuWindow : public QTableView, public NetHackQtWindow { 512 Q_OBJECT 513 public: 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 525 public slots: 526 void All(); 527 void ChooseNone(); 528 void Invert(); 529 void Search(); 530 531 void Layout(); 532 void ToggleSelect(int); 533 534 protected: 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 546 private: 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 SelectableMenuItem559 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 589 class NetHackQtTextListBox; 590 591 class NetHackQtRIP : public QWidget { 592 private: 593 static QPixmap* pixmap; 594 char** line; 595 int riplines; 596 597 public: 598 NetHackQtRIP(QWidget* parent); 599 600 void setLines(char** l, int n); 601 602 protected: 603 virtual void paintEvent(QPaintEvent* event); 604 QSize sizeHint() const; 605 }; 606 607 608 class NetHackQtTextWindow : public QDialog, public NetHackQtWindow { 609 Q_OBJECT 610 public: 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 622 public slots: 623 void Search(); 624 625 protected: 626 virtual void done(int); 627 virtual void keyPressEvent(QKeyEvent*); 628 629 private slots: 630 void doUpdate(); 631 632 private: 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 645 class NetHackQtMenuOrTextWindow : public NetHackQtWindow { 646 private: 647 NetHackQtWindow* actual; 648 NetHackQtKeyBuffer& keysource; 649 650 public: 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 670 class NetHackQtDelay : QObject { 671 private: 672 int msec; 673 674 public: 675 NetHackQtDelay(int ms); 676 void wait(); 677 virtual void timerEvent(QTimerEvent* timer); 678 }; 679 680 681 class NetHackQtInvUsageWindow : public QWidget { 682 public: 683 NetHackQtInvUsageWindow(QWidget* parent); 684 virtual void paintEvent(QPaintEvent*); 685 private: 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 704 class NetHackQtMainWindow : public KTopLevelWidget { 705 Q_OBJECT 706 public: 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 717 public slots: 718 void doMenuItem(int); 719 void doKeys(const QString&); 720 721 protected: 722 virtual void resizeEvent(QResizeEvent*); 723 virtual void keyPressEvent(QKeyEvent*); 724 virtual void keyReleaseEvent(QKeyEvent* event); 725 virtual void closeEvent(QCloseEvent*); 726 727 private slots: 728 void layout(); 729 void raiseMap(); 730 void zoomMap(); 731 void raiseMessages(); 732 void raiseStatus(); 733 734 private: 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 754 class NetHackQtYnDialog : QDialog { 755 Q_OBJECT 756 private: 757 const char* question; 758 const char* choices; 759 char def; 760 NetHackQtKeyBuffer& keysource; 761 762 protected: 763 virtual void keyPressEvent(QKeyEvent*); 764 virtual void done(int); 765 766 private slots: 767 void doneItem(int); 768 769 public: 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 783 class NetHackQtBind : NetHackQtBindBase { 784 private: 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 796 public: 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 841 private: 842 virtual bool notify(QObject *receiver, QEvent *event); 843 }; 844 845 #endif 846