1 /***************************************************************************
2                           blatt.h  -  description
3                              -------------------
4     begin                : Mit Jul 12 22:54:51 MEST 2000
5     copyright            : (C) 2006 by Immi
6     email                : cuyo@pcpool.mathematik.uni-freiburg.de
7 
8 Modified 2006,2008,2010,2011 by the cuyo developers
9 
10  ***************************************************************************/
11 
12 /***************************************************************************
13  *                                                                         *
14  *   This program is free software; you can redistribute it and/or modify  *
15  *   it under the terms of the GNU General Public License as published by  *
16  *   the Free Software Foundation; either version 2 of the License, or     *
17  *   (at your option) any later version.                                   *
18  *                                                                         *
19  ***************************************************************************/
20 
21 #ifndef BLATT_H
22 #define BLATT_H
23 
24 #include <vector>
25 #include <SDL.h>
26 
27 #include "stringzeug.h"
28 #include "inkompatibel.h"
29 #include "punktefeld.h"
30 
31 #include "leveldaten.h" // wegen grx, gry, max_spielerzahl; sollte woanders hin
32 
33 
34 
35 enum {
36   blattpic_pfeile,
37   blattpic_highlight,
38   blattpic_titel,
39   blattpic_scroll,
40   blattpic_scrollbright,
41   blattpic_scrolldimmed,
42   blattpic_border,
43   blattpic_borderh,
44   blattpic_borderv,
45   blattpic_infoicons,
46   anz_blattpics
47 };
48 
49 /* Men�punkte werden an verschiedenen Linien zentriert. Die Positionen
50    dieser Linien werden getrennt berechnet. Siehe BlattMenu::oeffnen */
51 enum ZentrierLinie {
52   zl_zentriert, zl_accel, zl_daten, zl_anzahl
53 };
54 
55 
56 class BlattMenu;
57 
58 
59 class Blatt {
60 
61 public:
~Blatt()62   virtual ~Blatt() {}
63 
64   virtual void doEvent(const SDL_Event & evt);
keyEvent(const SDL_keysym &)65   virtual void keyEvent(const SDL_keysym & ) {}
resizeEvent()66   virtual void resizeEvent() {}
mouseButtonEvent(bool,int,int)67   virtual void mouseButtonEvent(bool , int , int ) {}
mouseMotionEvent(bool,int,int,int,int)68   virtual void mouseMotionEvent(bool , int , int  , int , int) {}
69   virtual void anzeigen() = 0;
70 
zeitSchritt()71   virtual void zeitSchritt() {}
72 
73  /* Global-Zeug */
74   static Bilddatei * gBlattPics[anz_blattpics];
75 
76   static void initBlaetter();
77   static void destroyBlaetter();
78 };
79 
80 
81 
82 
83 class BlattSpiel: public Blatt {
84 
85   /** Die Punkte-Anzeigen */
86   Punktefeld * mPunktefeld[max_spielerzahl];
87   bool mDekoUpdaten;
88 
89  public:
90   BlattSpiel();
91   ~BlattSpiel();
92 
93   virtual void oeffnen(int lnr);
94   virtual void keyEvent(const SDL_keysym & taste);
95   virtual void resizeEvent();
96   virtual void anzeigen();
97   virtual void zeitSchritt();
98 
99   void randNeuMalen();
100   void setPunkte(int sp, int pt);
101 
102  private:
103   void malInfos(int sp, int x);
104 };
105 
106 
107 
108 
109 
110 class MenuEintrag;
111 
112 
113 /* Konstanten f�r mausbereich.mEintrag */
114 #define eintrag_keiner (-1)
115 #define eintrag_scrollleiste (-2)
116 
117 /* Der einzige Subbereich, der f�r Tastatur-User existiert. */
118 #define subbereich_default 0
119 /* Die folgenden Konstanten sind nur zur �bergabe von oder an
120    Funktionen und nicht zum Speichern in einem MausBereich. */
121 #define subbereich_hyperaktiv (-2)
122 #define subbereich_keiner (-1)
123 #define subbereich_keinStrom (-3)
124 #define subbereich_nichtInitialisiert (-4)
125 
126 struct MausBereich {
127 
128   int mEintrag;
129   /* Die Bedeutung von subbereich h�ngt von der Men�eintragart ab.
130      Subbereich ist nur f�r Maususer. Aus Sicht von Tastatur-Usern
131      gibt es nur den default-Subbereich. (Sobald eine Taste gedr�ckt
132      wird, sollte auch wieder dort hin geschaltet werden.) */
133   int mSubBereich;
134 
MausBereichMausBereich135   MausBereich(): mEintrag(eintrag_keiner) {}
MausBereichMausBereich136   explicit MausBereich(int e): mEintrag(e), mSubBereich(subbereich_default) {}
MausBereichMausBereich137   MausBereich(int e, int sb): mEintrag(e), mSubBereich(sb) {}
138 
139   bool operator==(const MausBereich & m) const {
140     if (mEintrag != m.mEintrag)
141       return false;
142     if (mEintrag == eintrag_keiner)
143       return true;
144     return mSubBereich == m.mSubBereich;
145   }
146 };
147 
148 
149 
150 class MenuEintragSubmenu;
151 
152 enum yneuwahl {   /* Zur �bergabe an calcScroll():
153 		     wo (vertikal) soll der mWahl-Eintrag stehen? */
154   ynw_mitte,
155   ynw_oben,
156   ynw_unten
157 };
158 
159 class BlattMenu: public Blatt {
160   friend struct DrawDing;
161   friend class MenuEintrag;  /* Damit Men�punkte doEscape() aufrufen k�nnen */
162 
163  protected:
164   /* Soll es auch dann eine Scrollleiste haben, wenn sie unn�tig ist?
165      (=> hat auch escape-button) */
166   bool mImmerScrollleiste;
167   std::vector<MenuEintrag*> mEintraege;
168   std::vector<int> mEintraegeY;  /* relativ zu mY0.
169 				    Geht eins weiter als mEintraege,
170 				    so da� es auch die Gesamth�he enth�lt. */
171   BlattMenu * mObermenu;    /* NULL f�r das Hauptmen� */
172 
173   /* Wenn der Eintrag, wo dies ein Untermen� ist, erfahren m�chte, wenn
174      das Men� verlassen wird, sollte er sich mit setObereintrag() hier
175      eintragen. */
176   MenuEintragSubmenu * mObereintrag;
177 
178   /* Wenn was Hyperaktiv ist, kann mWahl trotzdem ein anderer Men�punkt
179      sein: wenn sich die Maus �ber einem anderen Men�punkt befindet.
180      (Tastendr�cke gehen dann aber an den hyperaktiven Eintrag) */
181   MausBereich mWahl;
182   /* True, wenn Button unten; wird (im Moment) nur f�r Scrollleistenpfeile
183      gebraucht. */
184   bool mPress;
185   int mHyperaktiv;  // eintrag_keiner wenn nix hyperaktiv ist
186   Str mInfoText;
187   int mInfoW;       // negativ f�r "kein Scrollen", sonst Textbreite
188   int mInfoX;       /* current position of scrolling info text.
189 		       Can be negative. In fact, the scrolling text is drawn
190 		       twice: This is the left copy, the right one starts
191 		       at mInfox+mInfoW. */
192 
193   /* mX0 = x-Koordinate f�rs alignen... getrennt nach
194      mY0 = y-Koordinate vom oberen Rand von Men�punkt 0
195      (evtl. weit oberhalb vom Bildschirm) */
196   int mX0[zl_anzahl], mY0, mZeigVon, mZeigBis;
197   /* mAnimXX: Wie ohne Anim, aber tats�chliche Position w�hrend einer
198      Scroll-Animation (im Gegensatz zu: Zielposition) */
199   int mAnimY0, mAnimZeigVon, mAnimZeigBis;
200   /* Aktuelle Scrollgeschwindigkeit */
201   int mScrollGesch;
202 
203   bool mRahmenUpdaten;
204   bool mRaenderUpdaten;
205   bool mInfozeileUpdaten;
206 
207  public:
208   explicit BlattMenu(bool immerscrollleiste = false);
209   virtual ~BlattMenu();
210   /* Gleich nach dem Konstruktor aufrufen, wenn das Obermenu nicht NULL
211      sein soll. Schoener waers, obermenu direkt dem Konstruktor zu
212      uebergeben. Das wuerde aber bedeuten, dass man gezwungen ist, in
213      *jeder* Klasse, die von BlattMenu erbt, einen Konstruktor zu
214      schreiben. Liefert einfach this zurueck, damit man
215        (new BlattMenuXXX())->setObermenu(...)
216      schreiben kann */
217   BlattMenu * setObermenu(BlattMenu * obermenu);
218   void setObereintrag(MenuEintragSubmenu * obereintrag);
219 
220   void neuerEintrag(MenuEintrag*);
221 
222   virtual void oeffnen(bool durchMaus, int wahl = eintrag_keiner);
223   virtual void keyEvent(const SDL_keysym & taste);
224   virtual void mouseButtonEvent(bool press, int x, int y);
225   virtual void mouseMotionEvent(bool press, int x, int y, int x_alt, int y_alt);
226   virtual void resizeEvent();
227   virtual void anzeigen();
228   virtual void zeitSchritt();
229 
230  protected:
231   virtual void doEscape();
232   virtual void doReturn(bool durchMaus);
233 
234   void menuLoeschen();
235 
236   /* �ndert mWahl und k�mmert sich drum, dass Graphik geupdatet wird */
237   void setWahl(MausBereich wahl);
238   void setWahl(int eintrag, int subBereich = subbereich_default);
239 
240   /* �ndert mHyperaktiv und k�mmert sich drum, dass Graphik geupdatet wird */
241   void setHyperaktiv(int ha);
242 
243   /* K�mmert sich um mInfotext und mInfoY.
244      Wird aufgerufen, wenn sich mInfotext vielleicht �ndern soll.
245      Also unter anderem von setWahl() und setHyperaktiv() */
246   void updateInfo();
247 
248   /* Teilt dem Eintrag seinen neuen Subbereich mit. Der Eintrag k�mmert
249      sich dann um sein Graphik-Update */
250   void updateEintrag(int e);
251 
252   void sichtbaresUpdaten();
253 
254   bool istScrollbar() const;
255 
256   void scrollleisteScroll(int sgn);
257 
258   /* Gleicht mY0, mZeigVon und mZeigBis an mWahl an.
259      sprung = true => keine Animation, sondern direkt dort hin. */
260   void setScrollZielHigh(yneuwahl = ynw_mitte, bool sprung = false);
261 
262   /* Setzt mY0 und gleicht mZeigVon und mZeigBis an.
263      sprung = true => keine Animation, sondern direkt dort hin. */
264   void setScrollZielLow(int neuy, bool sprung = false);
265 
266   void scrollZeitSchritt();
267 
268   /* Berechnet zeigVon und zeigBis aus Y0... mit oder ohne anim */
269   void calcZeigVonBis(int y0, int & von, int & bis);
270 
271  private:
272   void navigiere(int d, int vorschlag = -1);
273 
274   MausBereich getMausPos(int x, int y);
275 
276   /* Wo befindet sich der Cursor aus Sicht von Tastatur-Usern? */
277   int getTastenCursorPos();
278 };
279 
280 
281 
282 
283 class BlattStartAt: public BlattMenu {
284 
285  public:
BlattStartAt()286   BlattStartAt(): BlattMenu(true) {}  /* true: Scrollleiste immer da... und esc-Button */
287 
288   virtual void oeffnen(bool durchMaus, int wahl = eintrag_keiner);
289     /* Hier wird der int ignoriert, da sich die Klasse selbst drum k�mmert */
290  protected:
291   virtual void doReturn(bool durchMaus);
292 };
293 
294 
295 
296 
297 
298 class BlattHauptmenu: public BlattMenu {
299 
300  public:
301   BlattHauptmenu();
302 };
303 
304 
305 
306 class BlattPrefs: public BlattMenu {
307 
308  public:
309   BlattPrefs();
310 
311  protected:
312   virtual void doEscape();
313 };
314 
315 
316 
317 
318 
319 
320 #endif
321