1 // Crimson Fields -- a game of tactical warfare
2 // Copyright (C) 2000-2007 Jens Granseuer
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 //
18 
19 ///////////////////////////////////////////////////////////////
20 // widget.h
21 ///////////////////////////////////////////////////////////////
22 
23 #ifndef _INCLUDE_WIDGET_H
24 #define _INCLUDE_WIDGET_H
25 
26 #include <string>
27 #include <vector>
28 using namespace std;
29 
30 #include "surface.h"
31 #include "font.h"
32 
33 class Window;
34 
35 // GUI return codes
36 enum GUI_Status { GUI_ERROR = -6, GUI_RESTART, GUI_QUIT, GUI_CLOSE, GUI_NONE, GUI_OK };
37 
38 // widget flags
39 #define WIDGET_DEFAULT        0x0001  // widget responds to RETURN key
40 #define WIDGET_HIDDEN         0x0002  // widget is not shown and does not receive event messages
41 #define WIDGET_DISABLED       0x0004  // widget is shown, but does not receive event messages
42 #define WIDGET_COMPOSITE      0x0008  // widget is part of a composite widget (not the
43                                       // CompositeWidget itself)
44 #define WIDGET_ALIGN_CENTER   0x0010
45 #define WIDGET_ALIGN_LEFT     0x0020
46 #define WIDGET_ALIGN_RIGHT    0x0040
47 #define WIDGET_ALIGN_TOP      0x0080
48 #define WIDGET_ALIGN_WITHIN   0x0100  // must be combined with _LEFT or _RIGHT to be useful
49 
50 // for buttons mostly; some combinations are not allowed (e.g. SUBMENU and GFX)
51 #define WIDGET_STYLE_STD       0x0000 // standard bevelled box
52 #define WIDGET_STYLE_NOBORDER  0x0200 // don't draw widget borders
53 #define WIDGET_STYLE_GFX       0x0400 // use images
54 #define WIDGET_STYLE_MENU      0x0800 // kind of combination of NOBORDER and STD
55 #define WIDGET_STYLE_SUBMENU   0x1000 // display sub-menu indicator
56 #define WIDGET_STYLE_HIGHLIGHT 0x2000 // use highlight instead of background color
57 
58 // for string widgets
59 #define WIDGET_STR_CONST      0x4000  // string in widget cannot be modified
60 #define WIDGET_STR_PASSWORD   0x8000  // display string as asterisks
61 
62 // for scrollers
63 #define WIDGET_HSCROLL        0x1000  // horizontal slider
64 #define WIDGET_VSCROLL        0x2000  // vertical slider
65 #define WIDGET_HSCROLLKEY     0x4000  // scroller supports left/right cursor keys
66 #define WIDGET_VSCROLLKEY     0x8000  // scroller supports up/down cursor keys
67 
68 
69 class WidgetHook;
70 
71 class Widget : public Rect {
72 public:
73   Widget( short id, short x, short y, unsigned short w, unsigned short h,
74      unsigned short flags, const char *title, Window *window );
~Widget(void)75   virtual ~Widget( void ) {}
76 
ID(void)77   short ID( void ) const { return id; }
Title(void)78   const char *Title( void ) const { return title.c_str(); }
GetWindow(void)79   Window *GetWindow( void ) const { return surface; }
SetFont(Font * font)80   void SetFont( Font *font ) { this->font = font; }
SetID(short id)81   void SetID( short id ) { this->id = id; }
SetHook(WidgetHook * hook)82   void SetHook( WidgetHook *hook ) { this->hook = hook; }
SetKey(short key)83   void SetKey( short key ) { this->key = key; }
84   void SetTitle( const char *title );
85 
86   void Show( void ) const;
87   virtual void Draw( void ) = 0;
88   void PrintTitle( short xoff, short yoff, const Color &hcol ) const;
89   void PrintTitle( const Color &hcol ) const;
90 
91   virtual void Push( void );
92   virtual void Release( void );
Disable(void)93   void Disable( void ) { SetFlags( WIDGET_DISABLED ); }
Enable(void)94   void Enable( void ) { UnsetFlags( WIDGET_DISABLED ); }
Hide(void)95   void Hide( void ) { SetFlags( WIDGET_HIDDEN ); }
Unhide(void)96   void Unhide( void ) { UnsetFlags( WIDGET_HIDDEN ); }
Clicked(void)97   bool Clicked( void ) const { return clicked; }
Hidden(void)98   bool Hidden( void ) const { return (flags & WIDGET_HIDDEN) != 0; }
Composite(void)99   bool Composite( void ) const { return (flags & WIDGET_COMPOSITE) != 0; }
Disabled(void)100   bool Disabled( void ) const { return (flags & WIDGET_DISABLED) != 0; }
SetFlags(unsigned short f)101   void SetFlags( unsigned short f ) { flags |= f; }
UnsetFlags(unsigned short f)102   void UnsetFlags( unsigned short f ) { flags &= ~f; }
103 
104   GUI_Status HandleEvent( const SDL_Event &event );
MouseDown(const SDL_MouseButtonEvent & button)105   virtual GUI_Status MouseDown( const SDL_MouseButtonEvent &button ) { return GUI_OK; }
MouseUp(const SDL_MouseButtonEvent & button)106   virtual GUI_Status MouseUp( const SDL_MouseButtonEvent &button ) { return GUI_OK; }
KeyDown(const SDL_keysym & key)107   virtual GUI_Status KeyDown( const SDL_keysym &key ) { return GUI_OK; }
KeyUp(const SDL_keysym & key)108   virtual GUI_Status KeyUp( const SDL_keysym &key ) { return GUI_OK; }
MouseMove(const SDL_MouseMotionEvent & motion)109   virtual GUI_Status MouseMove( const SDL_MouseMotionEvent &motion ) { return GUI_OK; }
110 
SetSize(short x,short y,unsigned short w,unsigned short h)111   void SetSize( short x, short y, unsigned short w, unsigned short h )
112               { this->x = x; this->y = y; this->w = w; this->h = h; }
113 
114   Widget *next;
115 
116 protected:
117   Window *surface;
118   unsigned short flags;
119   short id;
120   short key;      // keystroke to activate widget
121   short keypos;
122 
123   Font *font;
124   string title;
125   WidgetHook *hook;
126 
127   bool clicked;
128 };
129 
130 // Hook class for widgets. The activate method will be called
131 // whenever a widget is "activated". What this means is up to
132 // the widget
133 class WidgetHook {
134 public:
WidgetHook(void)135   WidgetHook( void ) {}
~WidgetHook(void)136   virtual ~WidgetHook( void ) {}
137 
138   virtual GUI_Status WidgetActivated( Widget *widget, Window *win ) = 0;
139 };
140 
141 // Hook class used to signal aborting in synchronous operations
142 class UserActionHook {
143 public:
144   virtual bool Cancelled( void ) = 0;
145 };
146 
147 // composite widgets encapsulate several widgets but look and act like
148 // a single widget to the outside
149 class CompositeWidget : public Widget {
150 public:
151   CompositeWidget( short id, short x, short y,  unsigned short w, unsigned short h,
152     unsigned short flags, const char *title, Window *window );
153   ~CompositeWidget( void );
154 
155   virtual void Draw( void );
156 
157   virtual GUI_Status MouseDown( const SDL_MouseButtonEvent &button );
158   virtual GUI_Status MouseUp( const SDL_MouseButtonEvent &button );
159   virtual GUI_Status KeyDown( const SDL_keysym &key );
160   virtual GUI_Status KeyUp( const SDL_keysym &key );
161   virtual GUI_Status MouseMove( const SDL_MouseMotionEvent &motion );
162 
163 protected:
AddWidget(Widget * w)164   void AddWidget( Widget *w ) { components.push_back( w ); }
165   void RemoveWidget( Widget *w );
166   Widget *GetWidget( short id ) const;
167 
168 private:
169   vector<Widget *> components;
170 };
171 
172 #include "window.h"
173 
174 #endif  /* _INCLUDE_WIDGET_H */
175 
176